From f5b77cf9df9992b19e9ee5e6941f970537bcc598 Mon Sep 17 00:00:00 2001 From: mjacob Date: Sun, 16 Jun 2002 05:18:22 +0000 Subject: [PATCH] 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 --- sys/dev/isp/isp.c | 193 ++++++++++++++++++++++++++++++---------------- 1 file changed, 126 insertions(+), 67 deletions(-) diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 6bdacd827aa1..6d9e5d344df3 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); @@ -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