Module Name:    src
Committed By:   riz
Date:           Sun Nov 21 21:02:49 UTC 2010

Modified Files:
        src/sys/dev/ic [netbsd-5]: ciss.c

Log Message:
Pull up following revision(s) (requested by pettai in ticket #1452):
        sys/dev/ic/ciss.c: revision 1.23
Fix a performance problem with the ciss(4) driver.  NetBSD does common
queueing at the scsipi midlayer, and if the midlayer is not requested to
enable tagged queueing, the midlayer will only queue one command to the
adapter driver for each device.  The SmartArray adapter is capable of
handling multiple commands, and in the rather common case where there is
no battery backup and no write cache, doing single write commands is very
slow.  The SmartArray adapter runs much better when several commands can
be issued to a device.
This has been observed and discussed in several list threads, notably:
http://mail-index.NetBSD.org/netbsd-users/2008/10/01/msg002083.html
http://mail-index.NetBSD.org/tech-kern/2008/11/30/msg003704.html
This also addresses PR kern/39686.
To enable tagged queueing, the adapter driver responds to the midlayer
request to set the transfer mode.  However, the SmartArray does not respond
to the SCSI INQUIRY command with an ANSII field of 2 or more, so the
scsipi midlayer will ignore the CmdQue bit in the flags3 field of the
inquiry data.  This fix will patch the inquiry data so set the ANSII field
to 2, and responds to the midlayer request to set the transfer mode by
requesting tagged queueing.
In addition, the original port of the driver did not set up the adapter
parameters correctly as mentioned in the second list thread mentioned
above.  The adapt_openings is the total number of commands that the
adapter will accept rather than the number of commands divided by the
number of logical drives.  Also, the adapt_max_periph is the maximum number
of commands which can be queued per peripheral device, not the number of
logical drives [which in the case of a single logical drive limited the
number of commands queued to 1].
I'm also suppressing an error message for invalid commands if the error
was due to the SCSI_SYNCHRONIZE_CACHE_10 command, since that command is
not supported by the SmartArray adapter, but used with wapbl(4) meta-data
journaling.  Setting the ANSII version to 2 to allow enabling tagged queueing
also enables the use of the SCSI_SYNCHRONIZE_CACHE_10 command.


To generate a diff of this commit:
cvs rdiff -u -r1.14.4.1 -r1.14.4.2 src/sys/dev/ic/ciss.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ic/ciss.c
diff -u src/sys/dev/ic/ciss.c:1.14.4.1 src/sys/dev/ic/ciss.c:1.14.4.2
--- src/sys/dev/ic/ciss.c:1.14.4.1	Sun Jul 26 18:33:35 2009
+++ src/sys/dev/ic/ciss.c	Sun Nov 21 21:02:49 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ciss.c,v 1.14.4.1 2009/07/26 18:33:35 snj Exp $	*/
+/*	$NetBSD: ciss.c,v 1.14.4.2 2010/11/21 21:02:49 riz Exp $	*/
 /*	$OpenBSD: ciss.c,v 1.14 2006/03/13 16:02:23 mickey Exp $	*/
 
 /*
@@ -19,7 +19,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ciss.c,v 1.14.4.1 2009/07/26 18:33:35 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ciss.c,v 1.14.4.2 2010/11/21 21:02:49 riz Exp $");
 
 #include "bio.h"
 
@@ -41,6 +41,7 @@
 #include <dev/scsipi/scsi_all.h>
 #include <dev/scsipi/scsi_disk.h>
 #include <dev/scsipi/scsiconf.h>
+#include <dev/scsipi/scsipi_all.h>
 
 #include <dev/ic/cissreg.h>
 #include <dev/ic/cissvar.h>
@@ -363,7 +364,7 @@
 	sc->sc_channel.chan_channel = 0;
 	sc->sc_channel.chan_ntargets = sc->maxunits;
 	sc->sc_channel.chan_nluns = 1;	/* ciss doesn't really have SCSI luns */
-	sc->sc_channel.chan_openings = sc->maxcmd / (sc->maxunits? sc->maxunits : 1);
+	sc->sc_channel.chan_openings = sc->maxcmd;
 #if NBIO > 0
 	/* XXX Reserve some ccb's for sensor and bioctl. */
 	if (sc->sc_channel.chan_openings > 2)
@@ -374,7 +375,7 @@
 
 	sc->sc_adapter.adapt_dev = (struct device *) sc;
 	sc->sc_adapter.adapt_openings = sc->sc_channel.chan_openings;
-	sc->sc_adapter.adapt_max_periph = sc->maxunits;
+	sc->sc_adapter.adapt_max_periph = sc->sc_channel.chan_openings;
 	sc->sc_adapter.adapt_request = ciss_scsi_cmd;
 	sc->sc_adapter.adapt_minphys = cissminphys;
 	sc->sc_adapter.adapt_ioctl = ciss_scsi_ioctl;
@@ -618,6 +619,14 @@
 	if (xs) {
 		xs->resid = 0;
 		CISS_DPRINTF(CISS_D_CMD, ("scsipi_done(%p) ", xs));
+		if (xs->cmd->opcode == INQUIRY) {
+			struct scsipi_inquiry_data *inq;
+			inq = (struct scsipi_inquiry_data *)xs->data;
+			if ((inq->version & SID_ANSII) == 0 &&
+			    (inq->flags3 & SID_CmdQue) != 0) {
+				inq->version |= 2;
+			}
+		}
 		scsipi_done(xs);
 	}
 
@@ -637,9 +646,11 @@
 		break;
 
 	case CISS_ERR_INVCMD:
-		printf("%s: invalid cmd 0x%x: 0x%x is not valid @ 0x%x[%d]\n",
-		    device_xname(&sc->sc_dev), ccb->ccb_cmd.id,
-		    err->err_info, err->err_type[3], err->err_type[2]);
+		if (xs == NULL ||
+		    xs->cmd->opcode != SCSI_SYNCHRONIZE_CACHE_10)
+			printf("%s: invalid cmd 0x%x: 0x%x is not valid @ 0x%x[%d]\n",
+			    device_xname(&sc->sc_dev), ccb->ccb_cmd.id,
+			    err->err_info, err->err_type[3], err->err_type[2]);
 		if (xs) {
 			bzero(&xs->sense, sizeof(xs->sense));
 			xs->sense.scsi_sense.response_code =
@@ -1003,7 +1014,8 @@
 ciss_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req,
 	void *arg)
 {
-	struct scsipi_xfer *xs = (struct scsipi_xfer *) arg;
+	struct scsipi_xfer *xs;
+	struct scsipi_xfer_mode *xm;
 	struct ciss_softc *sc =
 		(struct ciss_softc *) chan->chan_adapter->adapt_dev;
 	u_int8_t target;
@@ -1016,6 +1028,7 @@
 	switch (req)
 	{
 	case ADAPTER_REQ_RUN_XFER:
+		xs = (struct scsipi_xfer *) arg;
 		target = xs->xs_periph->periph_target;
 		CISS_DPRINTF(CISS_D_CMD, ("targ=%d ", target));
 		if (xs->cmdlen > CISS_MAX_CDB) {
@@ -1073,7 +1086,9 @@
 		 * We can't change the transfer mode, but at least let
 		 * scsipi know what the adapter has negociated.
 		 */
-		/* FIXME: get xfer mode and write it into arg */
+		xm = (struct scsipi_xfer_mode *)arg;
+		xm->xm_mode |= PERIPH_CAP_TQING;
+		scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm);
 		break;
 	}
 }

Reply via email to