svn commit: r204397 - head/sys/dev/isp

Matt Jacob mjacob at FreeBSD.org
Sat Feb 27 05:41:24 UTC 2010


Author: mjacob
Date: Sat Feb 27 05:41:23 2010
New Revision: 204397
URL: http://svn.freebsd.org/changeset/base/204397

Log:
  Revamp the pieces of some of the stuff I forgot to do when shifting to
  32 bit handles. The RIO (reduced interrupt operation) and fast posting
  for the parallel SCSI cards were all 16 bit handles. Furthermore,
  target mode parallel SCSI only can have 16 bit handles.
  
  Use part of a supplied patch to switch over to using 32 bit handles.
  Be a bit more conservative here and only do this for parallel SCSI
  for the 12160 (Ultra3) cards. There were a lot of marginal Ultra2
  cards, and, frankly, few are findable now for testing.
  
  Fix the target handle routine to only do 16 bit handles for parallel
  SCSI cards. This is okay because the upper sixteen bits of the new
  32 bit handles is a sequence number to help protect against duplicate
  completions. This would be very unlikely to happen with parallel
  SCSI target mode, and wasn't present before, so we're no worse off
  than we used to be.
  
  While we're at it, finally split the async mailbox completion handlers
  into FC and parallel SCSI functions. This makes it much cleaner and
  easier to figure out what is or isn't a legal async mailbox completion
  code for different card classes.
  
  PR:		kern/144250
  Submitted partially by:	Charles D
  MFC after:	1 week

Modified:
  head/sys/dev/isp/isp.c
  head/sys/dev/isp/isp_freebsd.c
  head/sys/dev/isp/isp_library.c
  head/sys/dev/isp/isp_library.h
  head/sys/dev/isp/isp_pci.c
  head/sys/dev/isp/isp_target.c
  head/sys/dev/isp/ispmbox.h
  head/sys/dev/isp/ispreg.h

Modified: head/sys/dev/isp/isp.c
==============================================================================
--- head/sys/dev/isp/isp.c	Sat Feb 27 04:33:24 2010	(r204396)
+++ head/sys/dev/isp/isp.c	Sat Feb 27 05:41:23 2010	(r204397)
@@ -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: head/sys/dev/isp/isp_freebsd.c
==============================================================================
--- head/sys/dev/isp/isp_freebsd.c	Sat Feb 27 04:33:24 2010	(r204396)
+++ head/sys/dev/isp/isp_freebsd.c	Sat Feb 27 05:41:23 2010	(r204397)
@@ -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: head/sys/dev/isp/isp_library.c
==============================================================================
--- head/sys/dev/isp/isp_library.c	Sat Feb 27 04:33:24 2010	(r204396)
+++ head/sys/dev/isp/isp_library.c	Sat Feb 27 05:41:23 2010	(r204397)
@@ -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: head/sys/dev/isp/isp_library.h
==============================================================================
--- head/sys/dev/isp/isp_library.h	Sat Feb 27 04:33:24 2010	(r204396)
+++ head/sys/dev/isp/isp_library.h	Sat Feb 27 05:41:23 2010	(r204397)
@@ -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: head/sys/dev/isp/isp_pci.c
==============================================================================
--- head/sys/dev/isp/isp_pci.c	Sat Feb 27 04:33:24 2010	(r204396)
+++ head/sys/dev/isp/isp_pci.c	Sat Feb 27 05:41:23 2010	(r204397)
@@ -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: head/sys/dev/isp/isp_target.c
==============================================================================
--- head/sys/dev/isp/isp_target.c	Sat Feb 27 04:33:24 2010	(r204396)
+++ head/sys/dev/isp/isp_target.c	Sat Feb 27 05:41:23 2010	(r204397)
@@ -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: head/sys/dev/isp/ispmbox.h
==============================================================================
--- head/sys/dev/isp/ispmbox.h	Sat Feb 27 04:33:24 2010	(r204396)
+++ head/sys/dev/isp/ispmbox.h	Sat Feb 27 05:41:23 2010	(r204397)
@@ -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: head/sys/dev/isp/ispreg.h
==============================================================================
--- head/sys/dev/isp/ispreg.h	Sat Feb 27 04:33:24 2010	(r204396)
+++ head/sys/dev/isp/ispreg.h	Sat Feb 27 05:41:23 2010	(r204397)
@@ -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


More information about the svn-src-all mailing list