kern/144250: isp(4) broken for non-fibre channel cards with change r203444

Charles DeBardeleben debardeleben at aol.com
Wed Feb 24 01:00:12 UTC 2010


>Number:         144250
>Category:       kern
>Synopsis:       isp(4) broken for non-fibre channel cards with change r203444
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb 24 01:00:11 UTC 2010
>Closed-Date:
>Last-Modified:
>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 at 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:
>Unformatted:


More information about the freebsd-bugs mailing list