From owner-svn-src-stable-7@FreeBSD.ORG Mon Mar 1 17:42:06 2010 Return-Path: Delivered-To: svn-src-stable-7@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C4FC2106564A; Mon, 1 Mar 2010 17:42:06 +0000 (UTC) (envelope-from mjacob@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B34378FC15; Mon, 1 Mar 2010 17:42:06 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o21Hg6JE068243; Mon, 1 Mar 2010 17:42:06 GMT (envelope-from mjacob@svn.freebsd.org) Received: (from mjacob@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o21Hg6lR068230; Mon, 1 Mar 2010 17:42:06 GMT (envelope-from mjacob@svn.freebsd.org) Message-Id: <201003011742.o21Hg6lR068230@svn.freebsd.org> From: Matt Jacob Date: Mon, 1 Mar 2010 17:42:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r204525 - stable/7/sys/dev/isp X-BeenThere: svn-src-stable-7@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 7-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Mar 2010 17:42:06 -0000 Author: mjacob Date: Mon Mar 1 17:42:06 2010 New Revision: 204525 URL: http://svn.freebsd.org/changeset/base/204525 Log: MFC of 204397: fix problems with fast posting handles Modified: stable/7/sys/dev/isp/isp.c stable/7/sys/dev/isp/isp_freebsd.c stable/7/sys/dev/isp/isp_library.c stable/7/sys/dev/isp/isp_library.h stable/7/sys/dev/isp/isp_pci.c stable/7/sys/dev/isp/isp_target.c stable/7/sys/dev/isp/ispmbox.h stable/7/sys/dev/isp/ispreg.h Modified: stable/7/sys/dev/isp/isp.c ============================================================================== --- stable/7/sys/dev/isp/isp.c Mon Mar 1 17:36:45 2010 (r204524) +++ stable/7/sys/dev/isp/isp.c Mon Mar 1 17:42:06 2010 (r204525) @@ -108,10 +108,11 @@ static const uint8_t alpa_map[] = { * Local function prototypes. */ static int isp_parse_async(ispsoftc_t *, uint16_t); +static int isp_parse_async_fc(ispsoftc_t *, uint16_t); static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *); static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *); -static void isp_fastpost_complete(ispsoftc_t *, uint16_t); +static void isp_fastpost_complete(ispsoftc_t *, uint32_t); static int isp_mbox_continue(ispsoftc_t *); static void isp_scsi_init(ispsoftc_t *); static void isp_scsi_channel_init(ispsoftc_t *, int); @@ -1334,23 +1335,24 @@ isp_scsi_init(ispsoftc_t *isp) } /* - * Turn on Fast Posting, LVD transitions + * Turn on LVD transitions for ULTRA2 or better and other features * - * Ultra2 F/W always has had fast posting (and LVD transitions) - * - * Ultra and older (i.e., SBus) cards may not. It's just safer - * to assume not for them. + * Now that we have 32 bit handles, don't do any fast posting + * any more. For Ultra2/Ultra3 cards, we can turn on 32 bit RIO + * operation or use fast posting. To be conservative, we'll only + * do this for Ultra3 cards now because the other cards are so + * rare for this author to find and test with. */ MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0); if (IS_ULTRA2(isp)) mbs.param[1] |= FW_FEATURE_LVD_NOTIFY; -#ifndef ISP_NO_RIO - if (IS_ULTRA2(isp) || IS_1240(isp)) - mbs.param[1] |= FW_FEATURE_RIO_16BIT; -#else - if (IS_ULTRA2(isp) || IS_1240(isp)) +#ifdef ISP_NO_RIO + if (IS_ULTRA3(isp)) mbs.param[1] |= FW_FEATURE_FAST_POST; +#else + if (IS_ULTRA3(isp)) + mbs.param[1] |= FW_FEATURE_RIO_32BIT; #endif if (mbs.param[1] != 0) { uint16_t sfeat = mbs.param[1]; @@ -1604,25 +1606,15 @@ isp_fibre_init(ispsoftc_t *isp) } if (IS_2200(isp)) { /* - * There seems to just be too much breakage here - * with RIO and Fast Posting- it probably actually - * works okay but this driver is messing it up. - * This card is really ancient by now, so let's - * just opt for safety and not use the feature. + * We can't have Fast Posting any more- we now + * have 32 bit handles. + * + * RIO seemed to have to much breakage. + * + * Just opt for safety. */ -#if 0 - if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) { - icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT; - icbp->icb_fwoptions &= ~ICBOPT_FAST_POST; - icbp->icb_racctimer = 4; - icbp->icb_idelaytimer = 8; - } else { - icbp->icb_fwoptions |= ICBOPT_FAST_POST; - } -#else icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT; icbp->icb_fwoptions &= ~ICBOPT_FAST_POST; -#endif } else { /* * QLogic recommends that FAST Posting be turned @@ -4863,7 +4855,7 @@ again: */ if (sema) { fmbox: - if (mbox & 0x4000) { + if (mbox & MBOX_COMMAND_COMPLETE) { isp->isp_intmboxc++; if (isp->isp_mboxbsy) { int obits = isp->isp_obits; @@ -4883,10 +4875,13 @@ again: } else { isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", mbox); } - } else if (isp_parse_async(isp, mbox) < 0) { - return; + } else { + i = IS_FC(isp)? isp_parse_async_fc(isp, mbox) : isp_parse_async(isp, mbox); + if (i < 0) { + return; + } } - if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || isp->isp_state != ISP_RUNSTATE) { + if ((IS_FC(isp) && mbox != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) { goto out; } } @@ -5068,9 +5063,9 @@ again: req_status_flags = sp->req_status_flags; req_state_flags = sp->req_state_flags; resid = sp->req_resid; - } else if (etype == RQSTYPE_RIO2) { - isp_rio2_t *rio = (isp_rio2_t *)qe; - isp_get_rio2(isp, (isp_rio2_t *) hp, rio); + } else if (etype == RQSTYPE_RIO1) { + isp_rio1_t *rio = (isp_rio1_t *) qe; + isp_get_rio1(isp, (isp_rio1_t *) hp, rio); if (isp->isp_dblev & ISP_LOGDEBUG1) { isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio); } @@ -5082,6 +5077,10 @@ again: } ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ continue; + } else if (etype == RQSTYPE_RIO2) { + isp_prt(isp, ISP_LOGERR, "dropping RIO2 response\n"); + ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ + continue; } else { /* * Somebody reachable via isp_handle_other_response @@ -5394,40 +5393,35 @@ out: * Support routines. */ -#define GET_24XX_BUS(isp, chan, msg) \ - if (IS_24XX(isp)) { \ - chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; \ - if (chan >= isp->isp_nchan) { \ - isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d", chan, msg, __LINE__); \ - break; \ - } \ - } - +/* + * Parse an ASYNC mailbox complete + * + * Return non-zero if the event has been acknowledged. + */ static int isp_parse_async(ispsoftc_t *isp, uint16_t mbox) { - int rval = 0; - int pattern = 0; - uint16_t chan; + int acked = 0; + uint32_t h1 = 0, h2 = 0; + uint16_t chan = 0; - if (IS_DUALBUS(isp)) { - chan = ISP_READ(isp, OUTMAILBOX6); - } else { - chan = 0; + /* + * Pick up the channel, but not if this is a ASYNC_RIO32_2, + * where Mailboxes 6/7 have the second handle. + */ + if (mbox != ASYNC_RIO32_2) { + if (IS_DUALBUS(isp)) { + chan = ISP_READ(isp, OUTMAILBOX6); + } } isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox); switch (mbox) { case ASYNC_BUS_RESET: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_BUS_RESET for FC card"); - break; - } ISP_SET_SENDMARKER(isp, chan, 1); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif isp_async(isp, ISPASYNC_BUS_RESET, chan); @@ -5435,10 +5429,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_ case ASYNC_SYSTEM_ERROR: isp->isp_dead = 1; isp->isp_state = ISP_CRASHED; - if (IS_FC(isp)) { - FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL; - FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT; - } /* * Were we waiting for a mailbox command to complete? * If so, it's dead, so wake up the waiter. @@ -5453,7 +5443,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_ * restart the firmware */ isp_async(isp, ISPASYNC_FW_CRASH); - rval = -1; + acked = 1; break; case ASYNC_RQS_XFER_ERR: @@ -5465,17 +5455,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_ break; case ASYNC_QWAKEUP: -#ifdef ISP_TARGET_MODE - if (IS_24XX(isp)) { - isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error"); - break; - } -#endif - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_QWAKEUP for FC card"); - break; - } /* * We've just been notified that the Queue has woken up. * We don't need to be chatty about this- just unlatch things @@ -5485,82 +5464,45 @@ isp_parse_async(ispsoftc_t *isp, uint16_ break; case ASYNC_TIMEOUT_RESET: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_TIMEOUT_RESET for FC card"); - break; - } - isp_prt(isp, ISP_LOGWARN, - "timeout initiated SCSI bus reset of chan %d", chan); + isp_prt(isp, ISP_LOGWARN, "timeout initiated SCSI bus reset of chan %d", chan); ISP_SET_SENDMARKER(isp, chan, 1); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif break; case ASYNC_DEVICE_RESET: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL DEVICE_RESET for FC card"); - break; - } isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan); ISP_SET_SENDMARKER(isp, chan, 1); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif break; case ASYNC_EXTMSG_UNDERRUN: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_EXTMSG_UNDERRUN for FC card"); - break; - } isp_prt(isp, ISP_LOGWARN, "extended message underrun"); break; case ASYNC_SCAM_INT: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_SCAM_INT for FC card"); - break; - } isp_prt(isp, ISP_LOGINFO, "SCAM interrupt"); break; case ASYNC_HUNG_SCSI: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_HUNG_SCSI for FC card"); - break; - } - isp_prt(isp, ISP_LOGERR, - "stalled SCSI Bus after DATA Overrun"); + isp_prt(isp, ISP_LOGERR, "stalled SCSI Bus after DATA Overrun"); /* XXX: Need to issue SCSI reset at this point */ break; case ASYNC_KILLED_BUS: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_KILLED_BUS for FC card"); - break; - } isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun"); break; case ASYNC_BUS_TRANSIT: - if (IS_FC(isp)) { - isp_prt(isp, ISP_LOGWARN, - "ILLEGAL ASYNC_BUS_TRANSIT for FC card"); - break; - } mbox = ISP_READ(isp, OUTMAILBOX2); - switch (mbox & 0x1c00) { + switch (mbox & SXP_PINS_MODE_MASK) { case SXP_PINS_LVD_MODE: isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode"); SDPARAM(isp, chan)->isp_diffmode = 0; @@ -5593,70 +5535,142 @@ isp_parse_async(ispsoftc_t *isp, uint16_ ISP_SET_SENDMARKER(isp, chan, 1); break; - case ASYNC_RIO5: - pattern = 0xce; /* outgoing mailbox regs 1-3, 6-7 */ + case ASYNC_CMD_CMPLT: + case ASYNC_RIO32_1: + if (!IS_ULTRA3(isp)) { + isp_prt(isp, ISP_LOGERR, "unexpected fast posting completion"); + break; + } + /* FALLTHROUGH */ + h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1); + break; + + case ASYNC_RIO32_2: + h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1); + h2 = (ISP_READ(isp, OUTMAILBOX7) << 16) | ISP_READ(isp, OUTMAILBOX6); + break; + + case ASYNC_RIO16_5: + case ASYNC_RIO16_4: + case ASYNC_RIO16_3: + case ASYNC_RIO16_2: + case ASYNC_RIO16_1: + isp_prt(isp, ISP_LOGERR, "unexpected 16 bit RIO handle"); + break; + default: + isp_prt(isp, ISP_LOGWARN, "%s: unhandled async code 0x%x", __func__, mbox); + break; + } + + if (h1 || h2) { + isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h1); + isp_fastpost_complete(isp, h1); + if (h2) { + isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2); + isp_fastpost_complete(isp, h2); + if (isp->isp_fpcchiwater < 2) { + isp->isp_fpcchiwater = 2; + } + } else { + if (isp->isp_fpcchiwater < 1) { + isp->isp_fpcchiwater = 1; + } + } + } else { + isp->isp_intoasync++; + } + return (acked); +} + +#define GET_24XX_BUS(isp, chan, msg) \ + if (IS_24XX(isp)) { \ + chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; \ + if (chan >= isp->isp_nchan) { \ + isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d", chan, msg, __LINE__); \ + break; \ + } \ + } + + +static int +isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox) +{ + int acked = 0; + uint16_t chan; + + if (IS_DUALBUS(isp)) { + chan = ISP_READ(isp, OUTMAILBOX6); + } else { + chan = 0; + } + isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox); + + switch (mbox) { + case ASYNC_SYSTEM_ERROR: + isp->isp_dead = 1; + isp->isp_state = ISP_CRASHED; + FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL; + FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT; + /* + * Were we waiting for a mailbox command to complete? + * If so, it's dead, so wake up the waiter. + */ + if (isp->isp_mboxbsy) { + isp->isp_obits = 1; + isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR; + MBOX_NOTIFY_COMPLETE(isp); + } + /* + * It's up to the handler for isp_async to reinit stuff and + * restart the firmware + */ + isp_async(isp, ISPASYNC_FW_CRASH); + acked = 1; break; - case ASYNC_RIO4: - pattern = 0x4e; /* outgoing mailbox regs 1-3, 6 */ + case ASYNC_RQS_XFER_ERR: + isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error"); break; - case ASYNC_RIO3: - pattern = 0x0e; /* outgoing mailbox regs 1-3 */ + case ASYNC_RSP_XFER_ERR: + isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error"); break; - case ASYNC_RIO2: - pattern = 0x06; /* outgoing mailbox regs 1-2 */ + case ASYNC_QWAKEUP: +#ifdef ISP_TARGET_MODE + if (IS_24XX(isp)) { + isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error"); + break; + } +#endif + isp_prt(isp, ISP_LOGERR, "%s: unexpected ASYNC_QWAKEUP code", __func__); break; - case ASYNC_RIO1: case ASYNC_CMD_CMPLT: - pattern = 0x02; /* outgoing mailbox regs 1 */ + isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1)); + if (isp->isp_fpcchiwater < 1) { + isp->isp_fpcchiwater = 1; + } break; - case ASYNC_RIO_RESP: - return (rval); + case ASYNC_RIOZIO_STALL: + break; case ASYNC_CTIO_DONE: - { #ifdef ISP_TARGET_MODE - int handle; - if (IS_SCSI(isp) || IS_24XX(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad ASYNC_CTIO_DONE for %s cards", - IS_SCSI(isp)? "SCSI" : "24XX"); - break; - } - handle = - (ISP_READ(isp, OUTMAILBOX2) << 16) | - (ISP_READ(isp, OUTMAILBOX1)); - if (isp_target_async(isp, handle, mbox)) { - rval = -1; + if (isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1), mbox)) { + acked = 1; } else { - /* count it as a fast posting intr */ isp->isp_fphccmplt++; } #else - if (IS_SCSI(isp) || IS_24XX(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad ASYNC_CTIO_DONE for %s cards", - IS_SCSI(isp)? "SCSI" : "24XX"); - break; - } - isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done"); - isp->isp_fphccmplt++; /* count it as a fast posting intr */ + isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done"); #endif break; - } case ASYNC_LIP_ERROR: case ASYNC_LIP_F8: case ASYNC_LIP_OCCURRED: case ASYNC_PTPMODE: - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad LIP event for SCSI cards"); - break; - } /* * These are broadcast events that have to be sent across * all active channels. @@ -5676,7 +5690,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_ isp_async(isp, ISPASYNC_LIP, chan); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif /* @@ -5711,11 +5725,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_ break; case ASYNC_LOOP_UP: - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad LOOP UP event for SCSI cards"); - break; - } /* * This is a broadcast event that has to be sent across * all active channels. @@ -5735,18 +5744,13 @@ isp_parse_async(ispsoftc_t *isp, uint16_ isp_async(isp, ISPASYNC_LOOP_UP, chan); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif } break; case ASYNC_LOOP_DOWN: - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad LOOP DOWN event for SCSI cards"); - break; - } /* * This is a broadcast event that has to be sent across * all active channels. @@ -5765,18 +5769,13 @@ isp_parse_async(ispsoftc_t *isp, uint16_ isp_async(isp, ISPASYNC_LOOP_DOWN, chan); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif } break; case ASYNC_LOOP_RESET: - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad LIP RESET event for SCSI cards"); - break; - } /* * This is a broadcast event that has to be sent across * all active channels. @@ -5795,7 +5794,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_ isp_async(isp, ISPASYNC_LOOP_RESET, chan); #ifdef ISP_TARGET_MODE if (isp_target_async(isp, chan, mbox)) { - rval = -1; + acked = 1; } #endif } @@ -5804,11 +5803,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_ case ASYNC_PDB_CHANGED: { int nphdl, nlstate, reason; - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad PDB CHANGED event for SCSI cards"); - break; - } /* * We *should* get a channel out of the 24XX, but we don't seem * to get more than a PDB CHANGED on channel 0, so turn it into @@ -5831,8 +5825,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_ ISP_SET_SENDMARKER(isp, chan, 1); fcp->isp_loopstate = LOOP_PDB_RCVD; ISP_MARK_PORTDB(isp, chan, 1); - isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, - ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason); + isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason); } break; } @@ -5840,11 +5833,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_ { int lochan, hichan; - if (IS_SCSI(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad CHANGE NOTIFY event for SCSI cards"); - break; - } if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) { GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY"); lochan = chan; @@ -5866,8 +5854,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_ fcp->isp_loopstate = LOOP_PDB_RCVD; } ISP_MARK_PORTDB(isp, chan, 1); - isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, - ISPASYNC_CHANGE_SNS); + isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_SNS); } break; } @@ -5877,8 +5864,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_ * This only applies to 2100 amd 2200 cards */ if (!IS_2200(isp) && !IS_2100(isp)) { - isp_prt(isp, ISP_LOGWARN, - "bad card for ASYNC_CONNMODE event"); + isp_prt(isp, ISP_LOGWARN, "bad card for ASYNC_CONNMODE event"); break; } chan = 0; @@ -5912,8 +5898,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_ "Unknown connection mode (0x%x)", mbox); break; } - isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, - ISPASYNC_CHANGE_OTHER); + isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_OTHER); FCPARAM(isp, chan)->sendmarker = 1; FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT; FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD; @@ -5923,8 +5908,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_ if (IS_24XX(isp)) { isp_prt(isp, ISP_LOGWARN, "Receive Error"); } else { - isp_prt(isp, ISP_LOGWARN, - "Unknown Async Code 0x%x", mbox); + isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC_RCV_ERR"); } break; case ASYNC_RJT_SENT: /* same as ASYNC_QFULL_SENT */ @@ -5940,29 +5924,10 @@ isp_parse_async(ispsoftc_t *isp, uint16_ isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox); break; } - - if (pattern) { - int i, nh; - uint16_t handles[16]; - - for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) { - if ((pattern & (1 << i)) == 0) { - continue; - } - handles[nh++] = ISP_READ(isp, MBOX_OFF(i)); - } - for (i = 0; i < nh; i++) { - isp_fastpost_complete(isp, handles[i]); - isp_prt(isp, ISP_LOGDEBUG3, - "fast post completion of %u", handles[i]); - } - if (isp->isp_fpcchiwater < nh) { - isp->isp_fpcchiwater = nh; - } - } else { + if (mbox != ASYNC_CTIO_DONE && mbox != ASYNC_CMD_CMPLT) { isp->isp_intoasync++; } - return (rval); + return (acked); } /* @@ -6594,7 +6559,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, i } static void -isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph) +isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph) { XS_T *xs; @@ -7682,7 +7647,6 @@ isp_setdfltfcparm(ispsoftc_t *isp, int c fcp->isp_fwoptions |= ICBOPT_FAIRNESS; fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE; fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS; - fcp->isp_fwoptions |= ICBOPT_FAST_POST; if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) { fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX; } Modified: stable/7/sys/dev/isp/isp_freebsd.c ============================================================================== --- stable/7/sys/dev/isp/isp_freebsd.c Mon Mar 1 17:36:45 2010 (r204524) +++ stable/7/sys/dev/isp/isp_freebsd.c Mon Mar 1 17:42:06 2010 (r204525) @@ -2304,7 +2304,8 @@ isp_handle_platform_ctio(ispsoftc_t *isp uint32_t tval, handle; /* - * CTIO, CTIO2 and CTIO7 are close enough.... + * CTIO handles are 16 bits. + * CTIO2 and CTIO7 are 32 bits. */ if (IS_SCSI(isp)) { Modified: stable/7/sys/dev/isp/isp_library.c ============================================================================== --- stable/7/sys/dev/isp/isp_library.c Mon Mar 1 17:36:45 2010 (r204524) +++ stable/7/sys/dev/isp/isp_library.c Mon Mar 1 17:42:06 2010 (r204525) @@ -668,7 +668,7 @@ isp_clear_commands(ispsoftc_t *isp) ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO2; } else { ct_entry_t *ctio = (ct_entry_t *) local; - ctio->ct_syshandle = hdp->handle & 0xffff; + ctio->ct_syshandle = hdp->handle; ctio->ct_status = CT_HBA_RESET & 0xff;; ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO; } @@ -1132,17 +1132,36 @@ isp_get_24xx_abrt(ispsoftc_t *isp, isp24 void +isp_get_rio1(ispsoftc_t *isp, isp_rio1_t *r1src, isp_rio1_t *r1dst) +{ + const int lim = sizeof (r1dst->req_handles) / sizeof (r1dst->req_handles[0]); + int i; + isp_get_hdr(isp, &r1src->req_header, &r1dst->req_header); + if (r1dst->req_header.rqs_seqno > lim) { + r1dst->req_header.rqs_seqno = lim; + } + for (i = 0; i < r1dst->req_header.rqs_seqno; i++) { + ISP_IOXGET_32(isp, &r1src->req_handles[i], r1dst->req_handles[i]); + } + while (i < lim) { + r1dst->req_handles[i++] = 0; + } +} + +void isp_get_rio2(ispsoftc_t *isp, isp_rio2_t *r2src, isp_rio2_t *r2dst) { + const int lim = sizeof (r2dst->req_handles) / sizeof (r2dst->req_handles[0]); int i; + isp_get_hdr(isp, &r2src->req_header, &r2dst->req_header); - if (r2dst->req_header.rqs_seqno > 30) { - r2dst->req_header.rqs_seqno = 30; + if (r2dst->req_header.rqs_seqno > lim) { + r2dst->req_header.rqs_seqno = lim; } for (i = 0; i < r2dst->req_header.rqs_seqno; i++) { ISP_IOXGET_16(isp, &r2src->req_handles[i], r2dst->req_handles[i]); } - while (i < 30) { + while (i < lim) { r2dst->req_handles[i++] = 0; } } @@ -2240,7 +2259,13 @@ isp_allocate_xs_tgt(ispsoftc_t *isp, voi hdp->cmd = xs; hdp->handle = (hdp - isp->isp_tgtlist); hdp->handle |= (ISP_HANDLE_TARGET << ISP_HANDLE_USAGE_SHIFT); - hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT); + /* + * Target handles for SCSI cards are only 16 bits, so + * sequence number protection will be ommitted. + */ + if (IS_FC(isp)) { + hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT); + } *handlep = hdp->handle; return (0); } Modified: stable/7/sys/dev/isp/isp_library.h ============================================================================== --- stable/7/sys/dev/isp/isp_library.h Mon Mar 1 17:36:45 2010 (r204524) +++ stable/7/sys/dev/isp/isp_library.h Mon Mar 1 17:42:06 2010 (r204525) @@ -108,6 +108,7 @@ void isp_put_cont64_req(ispsoftc_t *, is void isp_get_response(ispsoftc_t *, ispstatusreq_t *, ispstatusreq_t *); void isp_get_24xx_response(ispsoftc_t *, isp24xx_statusreq_t *, isp24xx_statusreq_t *); void isp_get_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *); +void isp_get_rio1(ispsoftc_t *, isp_rio1_t *, isp_rio1_t *); void isp_get_rio2(ispsoftc_t *, isp_rio2_t *, isp_rio2_t *); void isp_put_icb(ispsoftc_t *, isp_icb_t *, isp_icb_t *); void isp_put_icb_2400(ispsoftc_t *, isp_icb_2400_t *, isp_icb_2400_t *); Modified: stable/7/sys/dev/isp/isp_pci.c ============================================================================== --- stable/7/sys/dev/isp/isp_pci.c Mon Mar 1 17:36:45 2010 (r204524) +++ stable/7/sys/dev/isp/isp_pci.c Mon Mar 1 17:42:06 2010 (r204525) @@ -1068,8 +1068,7 @@ isp_pci_rd_isr(ispsoftc_t *isp, uint32_t } static int -isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp, - uint16_t *semap, uint16_t *mbox0p) +isp_pci_rd_isr_2300(ispsoftc_t *isp, uint32_t *isrp, uint16_t *semap, uint16_t *mbox0p) { uint32_t hccr; uint32_t r2hisr; @@ -1096,7 +1095,7 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uin return (1); case ISPR2HST_RIO_16: *isrp = r2hisr & 0xffff; - *mbox0p = ASYNC_RIO1; + *mbox0p = ASYNC_RIO16_1; *semap = 1; return (1); case ISPR2HST_FPOST: @@ -1118,21 +1117,17 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uin hccr = ISP_READ(isp, HCCR); if (hccr & HCCR_PAUSE) { ISP_WRITE(isp, HCCR, HCCR_RESET); - isp_prt(isp, ISP_LOGERR, - "RISC paused at interrupt (%x->%x)", hccr, - ISP_READ(isp, HCCR)); + isp_prt(isp, ISP_LOGERR, "RISC paused at interrupt (%x->%x)", hccr, ISP_READ(isp, HCCR)); ISP_WRITE(isp, BIU_ICR, 0); } else { - isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", - r2hisr); + isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr); } return (0); } } static int -isp_pci_rd_isr_2400(ispsoftc_t *isp, uint32_t *isrp, - uint16_t *semap, uint16_t *mbox0p) +isp_pci_rd_isr_2400(ispsoftc_t *isp, uint32_t *isrp, uint16_t *semap, uint16_t *mbox0p) { uint32_t r2hisr; @@ -1177,8 +1172,7 @@ isp_pci_rd_reg(ispsoftc_t *isp, int rego * We will assume that someone has paused the RISC processor. */ oldconf = BXR2(isp, IspVirt2Off(isp, BIU_CONF1)); - BXW2(isp, IspVirt2Off(isp, BIU_CONF1), - oldconf | BIU_PCI_CONF1_SXP); + BXW2(isp, IspVirt2Off(isp, BIU_CONF1), oldconf | BIU_PCI_CONF1_SXP); MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2); } rv = BXR2(isp, IspVirt2Off(isp, regoff)); Modified: stable/7/sys/dev/isp/isp_target.c ============================================================================== --- stable/7/sys/dev/isp/isp_target.c Mon Mar 1 17:36:45 2010 (r204524) +++ stable/7/sys/dev/isp/isp_target.c Mon Mar 1 17:42:06 2010 (r204525) @@ -826,7 +826,9 @@ isp_target_async(ispsoftc_t *isp, int bu ct_entry_t *ct = (ct_entry_t *) storage; ct->ct_header.rqs_entry_type = RQSTYPE_CTIO; ct->ct_status = CT_OK; - ct->ct_fwhandle = bus; + ct->ct_syshandle = bus; + /* we skip fwhandle here */ + ct->ct_fwhandle = 0; ct->ct_flags = CT_SENDSTATUS; } isp_async(isp, ISPASYNC_TARGET_ACTION, storage); Modified: stable/7/sys/dev/isp/ispmbox.h ============================================================================== --- stable/7/sys/dev/isp/ispmbox.h Mon Mar 1 17:36:45 2010 (r204524) +++ stable/7/sys/dev/isp/ispmbox.h Mon Mar 1 17:42:06 2010 (r204525) @@ -223,6 +223,8 @@ #define ASYNC_SECURITY_UPDATE 0x801B #define ASYNC_CMD_CMPLT 0x8020 #define ASYNC_CTIO_DONE 0x8021 +#define ASYNC_RIO32_1 0x8021 +#define ASYNC_RIO32_2 0x8022 #define ASYNC_IP_XMIT_DONE 0x8022 #define ASYNC_IP_RECV_DONE 0x8023 #define ASYNC_IP_BROADCAST 0x8024 @@ -230,19 +232,19 @@ #define ASYNC_IP_RCVQ_EMPTY 0x8026 #define ASYNC_IP_RECV_DONE_ALIGNED 0x8027 #define ASYNC_PTPMODE 0x8030 -#define ASYNC_RIO1 0x8031 -#define ASYNC_RIO2 0x8032 -#define ASYNC_RIO3 0x8033 -#define ASYNC_RIO4 0x8034 -#define ASYNC_RIO5 0x8035 +#define ASYNC_RIO16_1 0x8031 +#define ASYNC_RIO16_2 0x8032 +#define ASYNC_RIO16_3 0x8033 +#define ASYNC_RIO16_4 0x8034 +#define ASYNC_RIO16_5 0x8035 #define ASYNC_CONNMODE 0x8036 #define ISP_CONN_LOOP 1 #define ISP_CONN_PTP 2 #define ISP_CONN_BADLIP 3 #define ISP_CONN_FATAL 4 #define ISP_CONN_LOOPBACK 5 -#define ASYNC_RIO_RESP 0x8040 -#define ASYNC_RIO_COMP 0x8042 +#define ASYNC_RIOZIO_STALL 0x8040 /* there's a RIO/ZIO entry that hasn't been serviced */ +#define ASYNC_RIO32_2_2200 0x8042 /* same as ASYNC_RIO32_2, but for 2100/2200 */ #define ASYNC_RCV_ERR 0x8048 /* @@ -860,7 +862,7 @@ typedef struct { (ISP_CAP_MULTI_ID(isp) ? tag : 0) /* - * Reduced Interrupt Operation Response Queue Entreis + * Reduced Interrupt Operation Response Queue Entries */ typedef struct { Modified: stable/7/sys/dev/isp/ispreg.h ============================================================================== --- stable/7/sys/dev/isp/ispreg.h Mon Mar 1 17:36:45 2010 (r204524) +++ stable/7/sys/dev/isp/ispreg.h Mon Mar 1 17:42:06 2010 (r204525) @@ -677,13 +677,13 @@ typedef struct { #define SXP_PINS_LVD_MODE 0x1000 #define SXP_PINS_HVD_MODE 0x0800 #define SXP_PINS_SE_MODE 0x0400 +#define SXP_PINS_MODE_MASK (SXP_PINS_LVD_MODE|SXP_PINS_HVD_MODE|SXP_PINS_SE_MODE) /* The above have to be put together with the DIFFM pin to make sense */ #define ISP1080_LVD_MODE (SXP_PINS_LVD_MODE) #define ISP1080_HVD_MODE (SXP_PINS_HVD_MODE|SXP_PINS_DIFF_MODE) #define ISP1080_SE_MODE (SXP_PINS_SE_MODE) -#define ISP1080_MODE_MASK \ - (SXP_PINS_LVD_MODE|SXP_PINS_HVD_MODE|SXP_PINS_SE_MODE|SXP_PINS_DIFF_MODE) +#define ISP1080_MODE_MASK (SXP_PINS_MODE_MASK|SXP_PINS_DIFF_MODE) /* * RISC and Host Command and Control Block Register Offsets