diff options
author | mjacob <mjacob@cvs.openbsd.org> | 2001-10-24 18:31:16 +0000 |
---|---|---|
committer | mjacob <mjacob@cvs.openbsd.org> | 2001-10-24 18:31:16 +0000 |
commit | 7fc6981cc9fcf51e119b92c877767f150dd930e0 (patch) | |
tree | 6cba97fa169717c09a35bfd710460243484d94f3 /sys/dev/ic/isp.c | |
parent | 3f748c5670534374035e0849501c242330e962e4 (diff) |
Protect against deranged fabric name servers.
Correct the # of output mailboxes for EXECUTE IOCB A64.
Comment out some redundant initialization to zero.
If we get ISP_QUEUES_FULL status, remember to actually set SCSI_QFULL
since the QLogic f/w, on some cards, doesn't do so. Grumble.
Diffstat (limited to 'sys/dev/ic/isp.c')
-rw-r--r-- | sys/dev/ic/isp.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c index 53deaf4244e..aa7be6eb073 100644 --- a/sys/dev/ic/isp.c +++ b/sys/dev/ic/isp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isp.c,v 1.23 2001/10/06 22:45:52 mjacob Exp $ */ +/* $OpenBSD: isp.c,v 1.24 2001/10/24 18:31:15 mjacob Exp $ */ /* * Machine and OS Independent (well, as best as possible) * code for the Qlogic ISP SCSI adapters. @@ -2263,11 +2263,11 @@ static int isp_scan_fabric(struct ispsoftc *isp) { fcparam *fcp = isp->isp_param; - u_int32_t portid, first_portid; + u_int32_t portid, first_portid, last_portid; sns_screq_t *reqp; sns_scrsp_t *resp; mbreg_t mbs; - int hicap, first_portid_seen; + int hicap, first_portid_seen, last_port_same; if (fcp->isp_onfabric == 0) { fcp->isp_loopstate = LOOP_FSCAN_DONE; @@ -2280,6 +2280,8 @@ isp_scan_fabric(struct ispsoftc *isp) * Since Port IDs are 24 bits, we can check against having seen * anything yet with this value. */ + last_port_same = 0; + last_portid = 0xffffffff; /* not a port */ first_portid = portid = fcp->isp_portid; fcp->isp_loopstate = LOOP_SCANNING_FABRIC; @@ -2358,9 +2360,20 @@ isp_scan_fabric(struct ispsoftc *isp) fcp->isp_loopstate = LOOP_FSCAN_DONE; return (0); } + if (portid == last_portid) { + if (last_port_same++ > 20) { + isp_prt(isp, ISP_LOGWARN, + "tangled fabric database detected"); + break; + } + } else { + last_portid = portid; + } } - isp_prt(isp, ISP_LOGWARN, "broken fabric nameserver...*wheeze*..."); + if (hicap >= 65535) { + isp_prt(isp, ISP_LOGWARN, "fabric too big (> 65535)"); + } /* * We either have a broken name server or a huge fabric if we get here. @@ -2701,13 +2714,13 @@ isp_start(XS_T *xs) else reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST; } - reqp->req_header.rqs_flags = 0; - reqp->req_header.rqs_seqno = 0; + /* reqp->req_header.rqs_flags = 0; */ + /* reqp->req_header.rqs_seqno = 0; */ if (IS_FC(isp)) { /* * See comment in isp_intr */ - XS_RESID(xs) = 0; + /* XS_RESID(xs) = 0; */ /* * Fibre Channel always requires some kind of tag. @@ -2758,7 +2771,7 @@ isp_start(XS_T *xs) reqp->req_time = 5; } if (isp_save_xs(isp, xs, &handle)) { - isp_prt(isp, ISP_LOGDEBUG1, "out of xflist pointers"); + isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers"); XS_SETERR(xs, HBA_BOTCH); return (CMD_EAGAIN); } @@ -3270,6 +3283,11 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox) *XS_STSP(xs) = SCSI_QFULL; XS_SETERR(xs, HBA_NOERROR); } else if (XS_NOERR(xs)) { + /* + * ???? + */ + isp_prt(isp, ISP_LOGDEBUG0, + "Request Queue Entry bounced back"); XS_SETERR(xs, HBA_BOTCH); } XS_RESID(xs) = XS_XFRLEN(xs); @@ -3889,18 +3907,30 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs) break; case RQCS_QUEUE_FULL: - isp_prt(isp, ISP_LOGDEBUG1, + isp_prt(isp, ISP_LOGDEBUG0, "internal queues full for %d.%d.%d status 0x%x", XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs), *XS_STSP(xs)); + /* * If QFULL or some other status byte is set, then this * isn't an error, per se. - */ + * + * Unfortunately, some QLogic f/w writers have, in + * some cases, ommitted to *set* status to QFULL. + * + if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) { XS_SETERR(xs, HBA_NOERROR); return; } - break; + + * + * + */ + + *XS_STSP(xs) = SCSI_QFULL; + XS_SETERR(xs, HBA_NOERROR); + return; case RQCS_PHASE_SKIPPED: isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs), @@ -4118,7 +4148,7 @@ static u_int16_t mbpscsi[] = { ISPOPMAP(0xdf, 0xdf), /* 0x51: DUMP RAM A64 */ ISPOPMAP(0xdf, 0xdf), /* 0x52: INITIALIZE REQUEST QUEUE A64 */ ISPOPMAP(0xff, 0xff), /* 0x53: INITIALIZE RESPONSE QUEUE A64 */ - ISPOPMAP(0xcf, 0xff), /* 0x54: EXECUTE IOCB A64 */ + ISPOPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */ ISPOPMAP(0x07, 0x01), /* 0x55: ENABLE TARGET MODE */ ISPOPMAP(0x03, 0x0f), /* 0x56: GET TARGET STATUS */ ISPOPMAP(0x00, 0x00), /* 0x57: */ |