summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2002-06-16 05:18:22 +0000
committermjacob <mjacob@FreeBSD.org>2002-06-16 05:18:22 +0000
commitf5b77cf9df9992b19e9ee5e6941f970537bcc598 (patch)
treea06926e8249c62cbc18c8b8b7102ccad0b5d37cc /sys/dev/isp
parent06e71a13c094d792afc07bac76d188c778ee263a (diff)
downloadFreeBSD-src-f5b77cf9df9992b19e9ee5e6941f970537bcc598.zip
FreeBSD-src-f5b77cf9df9992b19e9ee5e6941f970537bcc598.tar.gz
If the HBA is already 'touched', still set maxluns. Othewise for
CAM_QUIRK_HILUN devices we loop thru 32bits of lun. Oops. Switch to using USEC_DELAY rather than USEC_SLEEP at isp_reset time. Try to paper around a defect in clients that don't correctly registers themeselves with the fabric nameserver. Minor updates for Mirapoint support- they still use code that is not HANDLE_LOOPSTATE_IN_OUTER_LAYERS, and, surprise surprise, this old stuff had some bugs in it. Clean up some target mode stuff. MFC after: 1 week
Diffstat (limited to 'sys/dev/isp')
-rw-r--r--sys/dev/isp/isp.c193
1 files changed, 126 insertions, 67 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 6bdacd8..6d9e5d3 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -161,7 +161,7 @@ isp_reset(struct ispsoftc *isp)
{
mbreg_t mbs;
u_int16_t code_org;
- int loops, i, touched, dodnld = 1;
+ int loops, i, dodnld = 1;
char *btype = "????";
isp->isp_state = ISP_NILSTATE;
@@ -184,7 +184,7 @@ isp_reset(struct ispsoftc *isp)
* case, we don't really use this yet, but we may in
* the future.
*/
- if ((touched = isp->isp_touched) == 0) {
+ if (isp->isp_touched == 0) {
/*
* First see whether or not we're sitting in the ISP PROM.
* If we've just been reset, we'll have the string "ISP "
@@ -676,8 +676,10 @@ again:
mbs.param[0] = MBOX_EXEC_FIRMWARE;
mbs.param[1] = code_org;
isp_mboxcmd(isp, &mbs, MBLOGNONE);
- /* give it a chance to start */
- USEC_SLEEP(isp, 500);
+ /*
+ * Give it a chance to start.
+ */
+ USEC_DELAY(500);
if (IS_SCSI(isp)) {
/*
@@ -789,19 +791,21 @@ again:
* because we may be called again after firmware has been loaded once
* and released.
*/
- if (touched == 0) {
- if (IS_SCSI(isp)) {
- if (dodnld) {
+ if (IS_SCSI(isp)) {
+ if (dodnld) {
+ if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
isp->isp_maxluns = 32;
} else {
isp->isp_maxluns = 8;
}
} else {
- if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
- isp->isp_maxluns = 16384;
- } else {
- isp->isp_maxluns = 16;
- }
+ isp->isp_maxluns = 8;
+ }
+ } else {
+ if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
+ isp->isp_maxluns = 16384;
+ } else {
+ isp->isp_maxluns = 16;
}
}
}
@@ -1177,7 +1181,6 @@ isp_fibre_init(struct ispsoftc *isp)
*/
fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
-
/*
* Make sure that target role reflects into fwoptions.
*/
@@ -2411,7 +2414,13 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
rs0 = (sns_ga_nxt_rsp_t *) ((u_int8_t *)fcp->isp_scratch+0x100);
isp_get_ga_nxt_response(isp, rs0, rs1);
if (rs1->snscb_cthdr.ct_response != FS_ACC) {
- isp_prt(isp, ISP_LOGWARN, swrej, "GA_NXT",
+ int level;
+ if (rs1->snscb_cthdr.ct_reason == 9 &&
+ rs1->snscb_cthdr.ct_explanation == 7)
+ level = ISP_LOGDEBUG0;
+ else
+ level = ISP_LOGWARN;
+ isp_prt(isp, level, swrej, "GA_NXT",
rs1->snscb_cthdr.ct_reason,
rs1->snscb_cthdr.ct_explanation, portid);
FC_SCRATCH_RELEASE(isp);
@@ -2424,6 +2433,10 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
(((u_int32_t) rs1->snscb_port_id[2]));
/*
+ * XXX: We should check to make sure that this entry
+ * XXX: supports the type(s) we are interested in.
+ */
+ /*
* Okay, we now have information about a fabric object.
* If it is the type we're interested in, tell the outer layers
* about it. The outer layer needs to know: Port ID, WWNN,
@@ -2556,7 +2569,13 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF);
isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
if (rs1->snscb_cthdr.ct_response != FS_ACC) {
- isp_prt(isp, ISP_LOGWARN, swrej, "GID_FT",
+ int level;
+ if (rs1->snscb_cthdr.ct_reason == 9 &&
+ rs1->snscb_cthdr.ct_explanation == 7)
+ level = ISP_LOGDEBUG0;
+ else
+ level = ISP_LOGWARN;
+ isp_prt(isp, level, swrej, "GID_FT",
rs1->snscb_cthdr.ct_reason,
rs1->snscb_cthdr.ct_explanation, 0);
FC_SCRATCH_RELEASE(isp);
@@ -2791,6 +2810,12 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
}
FC_SCRATCH_RELEASE(isp);
+ /*
+ * XXX: Workaround for some bogus fabric registrants
+ */
+ if (ftype) {
+ (void) isp_scan_fabric(isp, 0);
+ }
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
}
@@ -3023,7 +3048,7 @@ isp_start(XS_T *xs)
return (CMD_RQLATER);
}
if (fcp->isp_fwstate != FW_READY ||
- fcp->isp_loopstate < LOOP_PDB_RCVD) {
+ fcp->isp_loopstate < LOOP_FSCAN_DONE) {
return (CMD_RQLATER);
}
}
@@ -3199,7 +3224,7 @@ isp_start(XS_T *xs)
XS_SETERR(xs, HBA_NOERROR);
isp_prt(isp, ISP_LOGDEBUG2,
"START cmd for %d.%d.%d cmd 0x%x datalen %ld",
- XS_CHANNEL(xs), target, XS_LUN(xs), XS_CDBP(xs)[0],
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0],
(long) XS_XFRLEN(xs));
ISP_ADD_REQUEST(isp, nxti);
isp->isp_nactive++;
@@ -3665,11 +3690,15 @@ again:
* Only whine if this isn't the expected fallout of
* aborting the command.
*/
- if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE ||
- ts != RQCS_ABORTED) {
+ if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
+ isp_prt(isp, ISP_LOGERR,
+ "cannot find handle 0x%x (type 0x%x)",
+ sp->req_handle,
+ sp->req_header.rqs_entry_type);
+ } else if (ts != RQCS_ABORTED) {
isp_prt(isp, ISP_LOGERR,
- "cannot find handle 0x%x in xflist",
- sp->req_handle);
+ "cannot find handle 0x%x (status 0x%x)",
+ sp->req_handle, ts);
}
WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
continue;
@@ -3839,6 +3868,7 @@ again:
static int
isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
{
+ int rval = 0;
int bus;
if (IS_DUALBUS(isp)) {
@@ -3852,14 +3882,17 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
case ASYNC_BUS_RESET:
isp->isp_sendmarker |= (1 << bus);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, mbox);
+ if (isp_target_async(isp, bus, mbox))
+ rval = -1;
#endif
isp_async(isp, ISPASYNC_BUS_RESET, &bus);
break;
case ASYNC_SYSTEM_ERROR:
isp_async(isp, ISPASYNC_FW_CRASH, NULL);
- /* no point continuing after this */
- return (-1);
+ isp_reinit(isp);
+ isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
+ rval = -1;
+ break;
case ASYNC_RQS_XFER_ERR:
isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
@@ -3883,7 +3916,8 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
"timeout initiated SCSI bus reset of bus %d", bus);
isp->isp_sendmarker |= (1 << bus);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, mbox);
+ if (isp_target_async(isp, bus, mbox))
+ rval = -1;
#endif
break;
@@ -3891,7 +3925,8 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
isp->isp_sendmarker |= (1 << bus);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, mbox);
+ if (isp_target_async(isp, bus, mbox))
+ rval = -1;
#endif
break;
@@ -3977,19 +4012,19 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
break;
case ASYNC_CTIO_DONE:
+ {
#ifdef ISP_TARGET_MODE
- /*
- * Bus gets overloaded with the handle. Dual bus
- * cards don't put bus# into the handle.
- */
- isp_target_async(isp, ((ISP_READ(isp, OUTMAILBOX2) << 16) |
- ISP_READ(isp, OUTMAILBOX1)), mbox);
+ int handle =
+ (ISP_READ(isp, OUTMAILBOX2) << 16) |
+ (ISP_READ(isp, OUTMAILBOX1));
+ if (isp_target_async(isp, handle, mbox))
+ rval = -1;
#else
isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
#endif
isp->isp_fphccmplt++; /* count it as a fast posting intr */
- return (0);
-
+ break;
+ }
case ASYNC_LIP_F8:
case ASYNC_LIP_OCCURRED:
FCPARAM(isp)->isp_lipseq =
@@ -4000,7 +4035,8 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
isp_mark_getpdb_all(isp);
isp_async(isp, ISPASYNC_LIP, NULL);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, mbox);
+ if (isp_target_async(isp, bus, mbox))
+ rval = -1;
#endif
/*
* We've had problems with data corruption occuring on
@@ -4034,7 +4070,8 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
isp_mark_getpdb_all(isp);
isp_async(isp, ISPASYNC_LOOP_UP, NULL);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, mbox);
+ if (isp_target_async(isp, bus, mbox))
+ rval = -1;
#endif
break;
@@ -4045,7 +4082,8 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
isp_mark_getpdb_all(isp);
isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, mbox);
+ if (isp_target_async(isp, bus, mbox))
+ rval = -1;
#endif
break;
@@ -4056,7 +4094,8 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
isp_mark_getpdb_all(isp);
isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, mbox);
+ if (isp_target_async(isp, bus, mbox))
+ rval = -1;
#endif
break;
@@ -4087,7 +4126,8 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, mbox);
+ if (isp_target_async(isp, bus, mbox))
+ rval = -1;
#endif
isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
break;
@@ -4110,11 +4150,9 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
break;
case ISP_CONN_FATAL:
isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
+ isp_async(isp, ISPASYNC_FW_CRASH, NULL);
isp_reinit(isp);
-#ifdef ISP_TARGET_MODE
- isp_target_async(isp, bus, ASYNC_SYSTEM_ERROR);
-#endif
- /* no point continuing after this */
+ isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
return (-1);
case ISP_CONN_LOOPBACK:
isp_prt(isp, ISP_LOGWARN,
@@ -4156,7 +4194,7 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
} else {
isp->isp_intoasync++;
}
- return (0);
+ return (rval);
}
/*
@@ -4312,6 +4350,16 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
case RQCS_TIMEOUT:
isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ /*
+ * Check to see if we logged out the device.
+ */
+ if (IS_FC(isp)) {
+ if ((sp->req_completion_status & RQSTF_LOGOUT) &&
+ FCPARAM(isp)->portdb[XS_TGT(xs)].valid &&
+ FCPARAM(isp)->portdb[XS_TGT(xs)].fabric_dev) {
+ FCPARAM(isp)->portdb[XS_TGT(xs)].relogin = 1;
+ }
+ }
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_CMDTIMEOUT);
}
@@ -5457,6 +5505,13 @@ isp_update_bus(struct ispsoftc *isp, int bus)
}
}
+#ifndef DEFAULT_FRAMESIZE
+#define DEFAULT_FRAMESIZE(isp) ICB_DFLT_FRMLEN
+#endif
+#ifndef DEFAULT_EXEC_THROTTLE
+#define DEFAULT_EXEC_THROTTLE(isp) ISP_EXEC_THROTTLE
+#endif
+
static void
isp_setdfltparm(struct ispsoftc *isp, int channel)
{
@@ -5473,9 +5528,9 @@ isp_setdfltparm(struct ispsoftc *isp, int channel)
return;
}
fcp->isp_gotdparms = 1;
- fcp->isp_maxfrmlen = ICB_DFLT_FRMLEN;
+ fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
fcp->isp_maxalloc = ICB_DFLT_ALLOC;
- fcp->isp_execthrottle = ISP_EXEC_THROTTLE;
+ fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
fcp->isp_retry_delay = ICB_DFLT_RDELAY;
fcp->isp_retry_count = ICB_DFLT_RCOUNT;
/* Platform specific.... */
@@ -5692,19 +5747,16 @@ isp_reinit(struct ispsoftc *isp)
isp_reset(isp);
if (isp->isp_state != ISP_RESETSTATE) {
isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
- goto skip;
- }
- isp_init(isp);
- if (isp->isp_role == ISP_ROLE_NONE) {
- goto skip;
- }
- if (isp->isp_state == ISP_INITSTATE) {
- isp->isp_state = ISP_RUNSTATE;
- }
- if (isp->isp_state != ISP_RUNSTATE) {
- isp_prt(isp, ISP_LOGERR, "isp_reinit cannot restart card");
+ } else if (isp->isp_role != ISP_ROLE_NONE) {
+ isp_init(isp);
+ if (isp->isp_state == ISP_INITSTATE) {
+ isp->isp_state = ISP_RUNSTATE;
+ }
+ if (isp->isp_state != ISP_RUNSTATE) {
+ isp_prt(isp, ISP_LOGERR,
+ "isp_reinit cannot restart card");
+ }
}
-skip:
isp->isp_nactive = 0;
for (handle = 1; (int) handle <= isp->isp_maxcmds; handle++) {
@@ -6239,22 +6291,29 @@ isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
}
}
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x loopid %x",
+ ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data),
+ ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
+ ISP2100_NVRAM_OPTIONS(nvram_data),
+ ISP2100_NVRAM_HARDLOOPID(nvram_data));
+
fcp->isp_maxalloc =
ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
- fcp->isp_maxfrmlen =
- ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
+ if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0)
+ fcp->isp_maxfrmlen =
+ ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
fcp->isp_retry_delay =
ISP2100_NVRAM_RETRY_DELAY(nvram_data);
fcp->isp_retry_count =
ISP2100_NVRAM_RETRY_COUNT(nvram_data);
- fcp->isp_loopid =
- ISP2100_NVRAM_HARDLOOPID(nvram_data);
- fcp->isp_execthrottle =
- ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
+ if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
+ fcp->isp_loopid =
+ ISP2100_NVRAM_HARDLOOPID(nvram_data);
+ if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0)
+ fcp->isp_execthrottle =
+ ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
- isp_prt(isp, ISP_LOGDEBUG0,
- "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x",
- fcp->isp_maxfrmlen, fcp->isp_execthrottle, fcp->isp_fwoptions);
}
#ifdef ISP_FW_CRASH_DUMP
OpenPOWER on IntegriCloud