summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authormjacob <mjacob@NetBSD.org>2002-03-22 02:34:05 +0000
committermjacob <mjacob@NetBSD.org>2002-03-22 02:34:05 +0000
commitd76d04685a89ce7c8f6eb69a3a080f399a6537ba (patch)
tree30f3ac20a443463e06a69c4dd0bc2590fb6d6f5c /sys/dev
parent2c3c2f2ca08112e4572f273c2862773f7421ca44 (diff)
Handle Port Unavailable the same as Port Logout (i.e., send a LIP).
Unconst pointer to f/w in the ispdv structure. Too many compilers get unhappy over our walking the array. Make casts as appropriate so that initialization in structure is still happy. Limit length of fabric to 256. This will all go away soon. Do a cleaner case of keeping multiple CPUs/threads from reading the same response queue entries.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/isp.c52
-rw-r--r--sys/dev/ic/ispvar.h6
-rw-r--r--sys/dev/pci/isp_pci.c16
3 files changed, 42 insertions, 32 deletions
diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c
index ab1073361b5..12e6311aff2 100644
--- a/sys/dev/ic/isp.c
+++ b/sys/dev/ic/isp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: isp.c,v 1.89 2002/03/07 00:14:04 mjacob Exp $ */
+/* $NetBSD: isp.c,v 1.90 2002/03/22 02:34:06 mjacob Exp $ */
/*
* This driver, which is contained in NetBSD in the files:
*
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: isp.c,v 1.89 2002/03/07 00:14:04 mjacob Exp $");
+__KERNEL_RCSID(0, "$NetBSD: isp.c,v 1.90 2002/03/22 02:34:06 mjacob Exp $");
#ifdef __NetBSD__
#include <dev/ic/isp_netbsd.h>
@@ -2329,6 +2329,9 @@ isp_scan_loop(struct ispsoftc *isp)
return (0);
}
+#ifndef HICAP_MAX
+#define HICAP_MAX 256
+#endif
static int
isp_scan_fabric(struct ispsoftc *isp)
{
@@ -2351,7 +2354,7 @@ isp_scan_fabric(struct ispsoftc *isp)
first_portid = portid = fcp->isp_portid;
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
- for (first_portid_seen = hicap = 0; hicap < 65535; hicap++) {
+ for (first_portid_seen = hicap = 0; hicap < HICAP_MAX; hicap++) {
mbreg_t mbs;
sns_screq_t *rq;
sns_ganrsp_t *rs0, *rs1;
@@ -3164,6 +3167,7 @@ again:
} else {
iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
}
+ isp->isp_resodx = iptr;
if (optr == iptr && sema == 0) {
@@ -3198,9 +3202,15 @@ again:
isr, junk, iptr, optr);
}
}
+ isp->isp_resodx = iptr;
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
ISP_WRITE(isp, BIU_SEMA, 0);
+ if (isp->isp_rspbsy) {
+ return;
+ }
+ isp->isp_rspbsy = 1;
+
while (optr != iptr) {
ispstatusreq_t local, *sp = &local;
isphdr_t *hp;
@@ -3229,19 +3239,17 @@ again:
}
if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno)
isp->isp_fpcchiwater = rio.req_header.rqs_seqno;
+ MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
} else {
/*
* Somebody reachable via isp_handle_other_response
* may have updated the response queue pointers for
- * us.
+ * us, so we reload our goal index.
*/
- oop = optr;
- if (!isp_handle_other_response(isp, type, hp, &optr)) {
+ if (isp_handle_other_response(isp, type, hp, &optr)) {
+ iptr = isp->isp_resodx;
MEMZERO(hp, QENTRY_LEN); /* PERF */
- if (oop != optr) {
- goto out;
- }
continue;
}
@@ -3469,7 +3477,7 @@ again:
}
isp->isp_residx = optr;
-out:
+ isp->isp_rspbsy = 0;
for (i = 0; i < ndone; i++) {
xs = complist[i];
if (xs) {
@@ -3819,7 +3827,7 @@ isp_handle_other_response(struct ispsoftc *isp, int type,
switch (type) {
case RQSTYPE_STATUS_CONT:
isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
- return (0);
+ return (1);
case RQSTYPE_ATIO:
case RQSTYPE_CTIO:
case RQSTYPE_ENABLE_LUN:
@@ -3832,7 +3840,9 @@ isp_handle_other_response(struct ispsoftc *isp, int type,
case RQSTYPE_CTIO3:
isp->isp_rsltccmplt++; /* count as a response completion */
#ifdef ISP_TARGET_MODE
- return (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp));
+ if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
+ return (1);
+ }
#else
optrp = optrp;
/* FALLTHROUGH */
@@ -3840,11 +3850,11 @@ isp_handle_other_response(struct ispsoftc *isp, int type,
case RQSTYPE_REQUEST:
default:
if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
- return (0);
+ return (1);
}
isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
isp_get_response_type(isp, hp));
- return (-1);
+ return (0);
}
}
@@ -4148,18 +4158,16 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
/*
* No such port on the loop. Moral equivalent of SELTIMEO
*/
- isp_prt(isp, ISP_LOGINFO,
- "Port Unavailable for target %d", XS_TGT(xs));
- if (XS_NOERR(xs)) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
- }
- return;
case RQCS_PORT_LOGGED_OUT:
/*
* It was there (maybe)- treat as a selection timeout.
*/
- isp_prt(isp, ISP_LOGINFO,
- "port logout for target %d", XS_TGT(xs));
+ if ((sp->req_completion_status & 0xff) == RQCS_PORT_UNAVAILABLE)
+ isp_prt(isp, ISP_LOGINFO,
+ "Port Unavailable for target %d", XS_TGT(xs));
+ else
+ isp_prt(isp, ISP_LOGINFO,
+ "port logout for target %d", XS_TGT(xs));
/*
* If we're on a local loop, force a LIP (which is overkill)
* to force a re-login of this unit.
diff --git a/sys/dev/ic/ispvar.h b/sys/dev/ic/ispvar.h
index 78e01ac470c..5dc10791e51 100644
--- a/sys/dev/ic/ispvar.h
+++ b/sys/dev/ic/ispvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: ispvar.h,v 1.53 2002/02/21 22:32:43 mjacob Exp $ */
+/* $NetBSD: ispvar.h,v 1.54 2002/03/22 02:34:08 mjacob Exp $ */
/*
* This driver, which is contained in NetBSD in the files:
*
@@ -103,7 +103,7 @@ struct ispmdvec {
void (*dv_reset0) (struct ispsoftc *);
void (*dv_reset1) (struct ispsoftc *);
void (*dv_dregs) (struct ispsoftc *, const char *);
- const u_int16_t *dv_ispfw; /* ptr to f/w */
+ u_int16_t *dv_ispfw; /* ptr to f/w */
u_int16_t dv_conf1;
u_int16_t dv_clock; /* clock frequency */
};
@@ -426,6 +426,8 @@ typedef struct ispsoftc {
volatile u_int16_t isp_reqodx; /* index of last ISP pickup */
volatile u_int16_t isp_reqidx; /* index of next request */
volatile u_int16_t isp_residx; /* index of next result */
+ volatile u_int16_t isp_resodx; /* index of next result */
+ volatile u_int16_t isp_rspbsy;
volatile u_int16_t isp_lasthdls; /* last handle seed */
volatile u_int16_t isp_mboxtmp[MAX_MAILBOX];
volatile u_int16_t isp_lastmbxcmd; /* last mbox command sent */
diff --git a/sys/dev/pci/isp_pci.c b/sys/dev/pci/isp_pci.c
index b50c2e89f0b..e349c0622a5 100644
--- a/sys/dev/pci/isp_pci.c
+++ b/sys/dev/pci/isp_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: isp_pci.c,v 1.76 2002/02/21 22:32:43 mjacob Exp $ */
+/* $NetBSD: isp_pci.c,v 1.77 2002/03/22 02:34:05 mjacob Exp $ */
/*
* This driver, which is contained in NetBSD in the files:
*
@@ -57,7 +57,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: isp_pci.c,v 1.76 2002/02/21 22:32:43 mjacob Exp $");
+__KERNEL_RCSID(0, "$NetBSD: isp_pci.c,v 1.77 2002/03/22 02:34:05 mjacob Exp $");
#include <dev/ic/isp_netbsd.h>
#include <dev/pci/pcireg.h>
@@ -87,42 +87,42 @@ static int isp_pci_intr(void *);
#if defined(ISP_DISABLE_1020_SUPPORT)
#define ISP_1040_RISC_CODE NULL
#else
-#define ISP_1040_RISC_CODE isp_1040_risc_code
+#define ISP_1040_RISC_CODE (u_int16_t *) isp_1040_risc_code
#include <dev/microcode/isp/asm_1040.h>
#endif
#if defined(ISP_DISABLE_1080_SUPPORT)
#define ISP_1080_RISC_CODE NULL
#else
-#define ISP_1080_RISC_CODE isp_1080_risc_code
+#define ISP_1080_RISC_CODE (u_int16_t *) isp_1080_risc_code
#include <dev/microcode/isp/asm_1080.h>
#endif
#if defined(ISP_DISABLE_12160_SUPPORT)
#define ISP_12160_RISC_CODE NULL
#else
-#define ISP_12160_RISC_CODE isp_12160_risc_code
+#define ISP_12160_RISC_CODE (u_int16_t *) isp_12160_risc_code
#include <dev/microcode/isp/asm_12160.h>
#endif
#if defined(ISP_DISABLE_2100_SUPPORT)
#define ISP_2100_RISC_CODE NULL
#else
-#define ISP_2100_RISC_CODE isp_2100_risc_code
+#define ISP_2100_RISC_CODE (u_int16_t *) isp_2100_risc_code
#include <dev/microcode/isp/asm_2100.h>
#endif
#if defined(ISP_DISABLE_2200_SUPPORT)
#define ISP_2200_RISC_CODE NULL
#else
-#define ISP_2200_RISC_CODE isp_2200_risc_code
+#define ISP_2200_RISC_CODE (u_int16_t *) isp_2200_risc_code
#include <dev/microcode/isp/asm_2200.h>
#endif
#if defined(ISP_DISABLE_2300_SUPPORT)
#define ISP_2300_RISC_CODE NULL
#else
-#define ISP_2300_RISC_CODE isp_2300_risc_code
+#define ISP_2300_RISC_CODE (u_int16_t *) isp_2300_risc_code
#include <dev/microcode/isp/asm_2300.h>
#endif