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
This commit is contained in:
mjacob 2002-06-16 05:18:22 +00:00
parent 06e71a13c0
commit f5b77cf9df

View File

@ -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);
@ -2423,6 +2432,10 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
(((u_int32_t) rs1->snscb_port_id[1]) << 8) |
(((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
@ -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 in xflist",
sp->req_handle);
"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 (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;
} 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");
}
}
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");
}
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