From nobody@FreeBSD.org  Wed Feb 24 00:59:17 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id E09A1106568B
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 24 Feb 2010 00:59:01 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id CD5A38FC08
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 24 Feb 2010 00:59:01 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o1NNPPT5010760
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 23 Feb 2010 23:25:25 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o1NNPPVx010759;
	Tue, 23 Feb 2010 23:25:25 GMT
	(envelope-from nobody)
Message-Id: <201002232325.o1NNPPVx010759@www.freebsd.org>
Date: Tue, 23 Feb 2010 23:25:25 GMT
From: Charles DeBardeleben <debardeleben@aol.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: isp(4) broken for non-fibre channel cards with change r203444
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         144250
>Category:       kern
>Synopsis:       [isp] isp(4) broken for non-fibre channel cards with change r203444
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    mjacob
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb 24 01:00:11 UTC 2010
>Closed-Date:    Sat Feb 27 05:55:17 UTC 2010
>Last-Modified:  Sat Feb 27 05:55:17 UTC 2010
>Originator:     Charles DeBardeleben
>Release:        CURRENT
>Organization:
>Environment:
FreeBSD nat.cfdhome.com 9.0-CURRENT FreeBSD 9.0-CURRENT #167 r204107M: Fri Feb 19 19:57:05 PST 2010     cfd@nat.cfdhome.com:/usr/obj/usr/src/sys/CFDHOME  amd64

>Description:
r203444 added sequincing of command handles in the isp driver, and used the
upper 16 bits of the handle to store the sequince number of the handle.
Unfortunately if the driver is set to use "fast post" replies for commands,
the cards have been set to only pass 16 bit handles in the replies. This results
in any fast post reply being ignored because the handle cannot be found.

I am attaching a patch that I have found to work on my ISP12160 based card.
However, I have no fiber channel cards, or documentation, so I do not know
for sure that my patch does not break support for these cards. An area that
needs to be looked at are IP over fiber channel, and target mode support as
some of the changes affected these areas due to common return status from
the interrupt code (the etype variable in the driver).

I have been running for about a week with these patches, but have not done
an exhaustive QA test where I verified all of the code paths that I changed.
However without these changes I am unable to boot, and with them I have
run with no issues for the past week.
>How-To-Repeat:
Try to use an ISP12160 based card with any driver including r203444. Notice
the handle invalid errors, and the timeout of all commands. Eventually the
system will boot without having enumerated any attached scsi drives.
>Fix:
Change the fast post mode of the card from 16 bit to 32 bit and make all changes
needed since the card replies differently in a number of ways when posting
32 bit handle replies than it does for 16 bit handles. See the patch for details.

Patch attached with submission follows:

Index: isp_library.c
===================================================================
--- isp_library.c	(revision 204266)
+++ isp_library.c	(working copy)
@@ -1132,6 +1132,22 @@
 
 
 void
+isp_get_rio1(ispsoftc_t *isp, isp_rio1_t *r1src, isp_rio1_t *r1dst)
+{
+	int i;
+	isp_get_hdr(isp, &r1src->req_header, &r1dst->req_header);
+	if (r1dst->req_header.rqs_seqno > 15) {
+		r1dst->req_header.rqs_seqno = 15;
+	}
+	for (i = 0; i < r1dst->req_header.rqs_seqno; i++) {
+		ISP_IOXGET_32(isp, &r1src->req_handles[i], r1dst->req_handles[i]);
+	}
+	while (i < 15) {
+		r1dst->req_handles[i++] = 0;
+	}
+}
+
+void
 isp_get_rio2(ispsoftc_t *isp, isp_rio2_t *r2src, isp_rio2_t *r2dst)
 {
 	int i;
Index: isp_library.h
===================================================================
--- isp_library.h	(revision 204266)
+++ isp_library.h	(working copy)
@@ -108,6 +108,7 @@
 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 *);
Index: isp_freebsd.c
===================================================================
--- isp_freebsd.c	(revision 204266)
+++ isp_freebsd.c	(working copy)
@@ -1672,12 +1672,9 @@
 	if (IS_24XX(isp)) {
 		ct7_entry_t *cto = (ct7_entry_t *) local;
 		cto->ct_syshandle = handle;
-	} else if (IS_FC(isp)) {
+	} else {
 		ct2_entry_t *cto = (ct2_entry_t *) local;
 		cto->ct_syshandle = handle;
-	} else {
-		ct_entry_t *cto = (ct_entry_t *) local;
-		cto->ct_syshandle = handle;
 	}
 
 	dmaresult = ISP_DMASETUP(isp, cso, (ispreq_t *) local);
@@ -2307,11 +2304,7 @@
 	 * CTIO, CTIO2 and CTIO7 are close enough....
 	 */
 
-	if (IS_SCSI(isp)) {
-		handle = ((ct_entry_t *)arg)->ct_syshandle;
-	} else {
-		handle = ((ct2_entry_t *)arg)->ct_syshandle;
-	}
+	handle = ((ct2_entry_t *)arg)->ct_syshandle;
 	ccb = isp_find_xs_tgt(isp, handle);
 	if (ccb == NULL) {
 		isp_print_bytes(isp, "null ccb in isp_handle_platform_ctio", QENTRY_LEN, arg);
Index: ispmbox.h
===================================================================
--- ispmbox.h	(revision 204266)
+++ ispmbox.h	(working copy)
@@ -223,6 +223,7 @@
 #define	ASYNC_SECURITY_UPDATE		0x801B
 #define	ASYNC_CMD_CMPLT			0x8020
 #define	ASYNC_CTIO_DONE			0x8021
+#define	ASYNC_RIO1_2			0x8022
 #define	ASYNC_IP_XMIT_DONE		0x8022
 #define	ASYNC_IP_RECV_DONE		0x8023
 #define	ASYNC_IP_BROADCAST		0x8024
Index: isp.c
===================================================================
--- isp.c	(revision 204266)
+++ isp.c	(working copy)
@@ -111,7 +111,7 @@
 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);
@@ -1347,7 +1347,7 @@
 		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;
+		mbs.param[1] |= FW_FEATURE_RIO_32BIT;
 #else
 	if (IS_ULTRA2(isp) || IS_1240(isp))
 		mbs.param[1] |= FW_FEATURE_FAST_POST;
@@ -1612,7 +1612,7 @@
 			 */
 #if	0
 			if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
-				icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
+				icbp->icb_xfwoptions |= ICBXOPT_RIO_32BIT;
 				icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
 				icbp->icb_racctimer = 4;
 				icbp->icb_idelaytimer = 8;
@@ -1620,7 +1620,7 @@
 				icbp->icb_fwoptions |= ICBOPT_FAST_POST;
 			}
 #else
-			icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT;
+			icbp->icb_xfwoptions &= ~ICBXOPT_RIO_32BIT;
 			icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
 #endif
 		} else {
@@ -5068,9 +5068,9 @@
 			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);
 			}
@@ -5609,24 +5609,14 @@
 		pattern = 0x06;	/* outgoing mailbox regs 1-2 */
 		break;
 
-	case ASYNC_RIO1:
-	case ASYNC_CMD_CMPLT:
-		pattern = 0x02;	/* outgoing mailbox regs 1 */
-		break;
-
 	case ASYNC_RIO_RESP:
 		return (rval);
 
+	case ASYNC_CMD_CMPLT:
 	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));
@@ -5637,17 +5627,48 @@
 			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;
+		uint32_t handle;
+		if (IS_SCSI(isp)) {
+			handle =
+			    (ISP_READ(isp, OUTMAILBOX2) << 16) |
+			    (ISP_READ(isp, OUTMAILBOX1));
+			isp_fastpost_complete(isp, handle);
+			isp_prt(isp,  ISP_LOGDEBUG3,
+			    "fast post completion of %u", handle);
+			if (!isp->isp_fpcchiwater) {
+				isp->isp_fpcchiwater = 1;
+			}
+			isp_prt(isp,  ISP_LOGDEBUG3,
+			    "fast post completion of %u", handle);
+		} else {
+			isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
 		}
-		isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
 		isp->isp_fphccmplt++;	/* count it as a fast posting intr */
 #endif
 		break;
 	}
+
+	case ASYNC_RIO1_2:
+	{
+		uint32_t handle1, handle2;
+
+		handle1 = (ISP_READ(isp, OUTMAILBOX2) << 16) |
+		    (ISP_READ(isp, OUTMAILBOX1));
+		handle2 = (ISP_READ(isp, OUTMAILBOX7) << 16) |
+		    (ISP_READ(isp, OUTMAILBOX6));
+		isp_fastpost_complete(isp, handle1);
+		isp_prt(isp,  ISP_LOGDEBUG3,
+		    "fast post completion of %u", handle1);
+		isp_fastpost_complete(isp, handle2);
+		isp_prt(isp,  ISP_LOGDEBUG3,
+		    "fast post completion of %u", handle2);
+		if (isp->isp_fpcchiwater < 2) {
+			isp->isp_fpcchiwater = 2;
+		}
+		isp->isp_fphccmplt++;	/* count it as a fast posting intr */
+		break;
+	}
+
 	case ASYNC_LIP_ERROR:
 	case ASYNC_LIP_F8:
 	case ASYNC_LIP_OCCURRED:
@@ -5940,28 +5961,6 @@
 		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 {
-		isp->isp_intoasync++;
-	}
 	return (rval);
 }
 
@@ -6594,7 +6593,7 @@
 }
 
 static void
-isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph)
+isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph)
 {
 	XS_T *xs;
 


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->mjacob 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Wed Feb 24 02:33:21 UTC 2010 
Responsible-Changed-Why:  
Matt, it looks like this may be for you. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=144250 

From: Matthew Jacob <mj@feral.com>
To: bug-followup@FreeBSD.org, debardeleben@aol.com
Cc:  
Subject: Re: kern/144250: isp(4) broken for non-fibre channel cards with change
 r203444
Date: Tue, 23 Feb 2010 18:46:00 -0800

 cool. Thanks for the patch. I'll try and get this banged  into shape 
 with some testing in the next week or so!
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/144250: commit references a PR
Date: Sat, 27 Feb 2010 05:41:40 +0000 (UTC)

 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
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->closed 
State-Changed-By: mjacob 
State-Changed-When: Sat Feb 27 05:54:42 UTC 2010 
State-Changed-Why:  
Fixed at change 204397. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=144250 
>Unformatted:
