From owner-FreeBSD-users-jp@jp.FreeBSD.org Tue Mar  5 13:30:26 2002
Received: (from daemon@localhost)
	by castle.jp.FreeBSD.org (8.11.6+3.4W/8.11.3) id g254UQZ29662;
	Tue, 5 Mar 2002 13:30:26 +0900 (JST)
	(envelope-from owner-FreeBSD-users-jp@jp.FreeBSD.org)
Received: from mail.sat.t.u-tokyo.ac.jp (nat.keisu.t.u-tokyo.ac.jp [133.11.68.2])
	by castle.jp.FreeBSD.org (8.11.6+3.4W/8.11.3) with ESMTP/inet id g254UQP29645
	for <FreeBSD-users-jp@jp.FreeBSD.org>; Tue, 5 Mar 2002 13:30:26 +0900 (JST)
	(envelope-from simokawa@sat.t.u-tokyo.ac.jp)
Received: from ett.sat.t.u-tokyo.ac.jp (ett.sat.t.u-tokyo.ac.jp [10.6.1.30])
	by mail.sat.t.u-tokyo.ac.jp (Postfix) with ESMTP id DF7C02DABB
	for <FreeBSD-users-jp@jp.FreeBSD.org>; Tue,  5 Mar 2002 13:30:25 +0900 (JST)
Date: Tue, 05 Mar 2002 13:30:25 +0900
Message-ID: <ybsd6yjhc0u.wl@ett.sat.t.u-tokyo.ac.jp>
From: Hidetoshi Shimokawa <simokawa@sat.t.u-tokyo.ac.jp>
To: FreeBSD-users-jp@jp.FreeBSD.org
In-Reply-To: <ybslmdch3za.wl@ett.sat.t.u-tokyo.ac.jp>
References: <200202281702.g1SH2SI00447@please.readme.jp>
	<ybslmdch3za.wl@ett.sat.t.u-tokyo.ac.jp>
User-Agent: Wanderlust/2.4.1 (Stand By Me) REMI/1.14.3 (Matsudai) FLIM/1.13.2 (Kasanui) APEL/10.3 MULE XEmacs/21.2 (beta19) (Shinjuku) (i386-unknown-freebsd3.2)
X-Face: OE([KxWyJI0r[R~S/>7ia}SJ)i%a,$-9%7{*yihQk|]gl}2p#"oXmX/fT}Bn7:#j7i14gu$
 jgR\S*&C3R/pJX<mI-4Z8'mqt1R'CjWdw-xqVoilv`\JgZcquM5oVuO^<vt/~051rCDM(`{rM~?{Ok
 r,XC+}Ycm9IJO)odT*-0nyJjBJYzL{GsZ
MIME-Version: 1.0 (generated by REMI 1.14.3 - "Matsudai")
Content-Type: text/plain; charset=ISO-2022-JP
Reply-To: FreeBSD-users-jp@jp.FreeBSD.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+011218
X-Sequence: FreeBSD-users-jp 67357
Subject: [FreeBSD-users-jp 67357] Re: DA_Q_NO6_BYTE quirk (Re: umass device configuration)
Errors-To: owner-FreeBSD-users-jp@jp.FreeBSD.org
Sender: owner-FreeBSD-users-jp@jp.FreeBSD.org
X-Originator: simokawa@sat.t.u-tokyo.ac.jp

At Fri, 01 Mar 2002 21:22:49 +0900,
Hidetoshi Shimokawa wrote:
> 
> > $B!!;DG0$J$,$i;d$N4D6-(B(4.4-Release)$B$G$O!"$3$N%Q%C%A$OM-8z$G$O$J$$$h$&$G(B
> > $B$9!#%Q%C%A$r$"$F$k$3$H!"%+!<%M%k$N%3%s%Q%$%k$G$OLdBj$O$"$j$^$;$s$G$7$?!#(B
> > $B$7$+$7!"%^%&%s%H$G$-$^$;$s!#(B
<$BN,(B>
> $BA0$N%Q%C%A$G$O=&$$$-$l$J$$M}M3$G$9$,(B,
> SCSI$BE*$K$O(B error $B$rJV$5$J$$$G(B, $B@.8y$7$F$$$k$h$&$K8+$($F(B,
> $B<B$O(B, transfer length $B$O(B 0 $B$H$$$&>u67$N$h$&$G$9(B.
> 
> $BMh=5$^$?%Q%C%A$rN.$9$D$b$j$J$N$G(B, $B$^$?$=$N$H$-$*4j$$$7$^$9(B. _o_

$B$3$l$G$I$&$G$7$g$&$+(B?
$B$3$l$G$b%@%a$G$"$l$P(B, patch $B$rEv$F$?>uBV$G(B,

sysctl -w kern.cam.da.no_6_byte=1

$B$H$7$F$_$F$/$@$5$$(B.

/\ Hidetoshi Shimokawa
\/  simokawa@sat.t.u-tokyo.ac.jp
PGP public key: http://www.sat.t.u-tokyo.ac.jp/~simokawa/pgp.html

Index: scsi_da.c
===================================================================
RCS file: /pub/FreeBSD-CVS/src/sys/cam/scsi/scsi_da.c,v
retrieving revision 1.42.2.22
diff -u -r1.42.2.22 scsi_da.c
--- scsi_da.c	23 Feb 2002 02:37:02 -0000	1.42.2.22
+++ scsi_da.c	5 Mar 2002 04:17:12 -0000
@@ -394,6 +394,7 @@
 
 static int da_retry_count = DA_DEFAULT_RETRY;
 static int da_default_timeout = DA_DEFAULT_TIMEOUT;
+static int da_no_6_byte = 0;
 
 SYSCTL_NODE(_kern, OID_AUTO, cam, CTLFLAG_RD, 0, "CAM Subsystem");
 SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
@@ -402,6 +403,8 @@
            &da_retry_count, 0, "Normal I/O retry count");
 SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
            &da_default_timeout, 0, "Normal I/O timeout (in seconds)");
+SYSCTL_INT(_kern_cam_da, OID_AUTO, no_6_byte, CTLFLAG_RW,
+           &da_no_6_byte, 0, "No 6 bytes commands");
 
 /*
  * DA_ORDEREDTAG_INTERVAL determines how often, relative
@@ -1242,6 +1246,8 @@
 			} else {
 				tag_code = MSG_SIMPLE_Q_TAG;
 			}
+			if (da_no_6_byte && softc->minimum_cmd_size == 6)
+				softc->minimum_cmd_size = 10;
 			scsi_read_write(&start_ccb->csio,
 					/*retries*/da_retry_count,
 					dadone,
@@ -1314,6 +1320,48 @@
 	}
 }
 
+static int
+cmd6workaround(union ccb *ccb)
+{
+	struct scsi_rw_6 cmd6;
+	struct scsi_rw_10 *cmd10;
+	struct da_softc *softc;
+	struct ccb_scsiio *csio;
+	u_int8_t opcode;
+
+	csio = &ccb->csio;
+ 	opcode = ((struct scsi_rw_6 *)csio->cdb_io.cdb_bytes)->opcode; 
+
+	if (opcode != READ_6 && opcode != WRITE_6)
+		return 0;
+
+	xpt_print_path(ccb->ccb_h.path);
+ 	printf("READ(6)/WRITE(6) failed, "
+		"minimum_cmd_size is increased to 10.\n");
+ 	softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
+	softc->minimum_cmd_size = 10;
+
+	bcopy(&csio->cdb_io.cdb_bytes, &cmd6, sizeof(struct scsi_rw_6));
+	cmd10 = (struct scsi_rw_10 *) &csio->cdb_io.cdb_bytes;
+	cmd10->opcode = (cmd6.opcode == READ_6) ? READ_10 : WRITE_10;
+	cmd10->byte2 = 0;
+	scsi_ulto4b(scsi_3btoul(cmd6.addr), cmd10->addr);
+	cmd10->reserved = 0;
+	scsi_ulto2b(cmd6.length, cmd10->length);
+	cmd10->control = cmd6.control;
+	csio->cdb_len = sizeof(*cmd10);
+
+	/* requeue */
+ 	ccb->ccb_h.status = CAM_REQUEUE_REQ;
+	xpt_action(ccb);
+	if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
+		cam_release_devq(ccb->ccb_h.path,
+				 /*relsim_flags*/0,
+				 /*reduction*/0,
+				 /*timeout*/0,
+				 /*getcount_only*/0);
+	return (ERESTART);
+}
 
 static void
 dadone(struct cam_periph *periph, union ccb *done_ccb)
@@ -1390,6 +1438,8 @@
 				bp->b_error = 0;
 				if (bp->b_resid != 0) {
 					/* Short transfer ??? */
+					if (cmd6workaround(done_ccb) == ERESTART)
+						return;
 					bp->b_flags |= B_ERROR;
 				}
 			}
@@ -1401,8 +1451,11 @@
 						 /*getcount_only*/0);
 		} else {
 			bp->b_resid = csio->resid;
-			if (csio->resid > 0)
+			if (csio->resid > 0) {
+				if (cmd6workaround(done_ccb) == ERESTART)
+					return;
 				bp->b_flags |= B_ERROR;
+			}
 		}
 
 		/*
@@ -1563,9 +1616,27 @@
 {
 	struct da_softc	  *softc;
 	struct cam_periph *periph;
+	int error, sense_key, error_code, asc, ascq;
 
 	periph = xpt_path_periph(ccb->ccb_h.path);
 	softc = (struct da_softc *)periph->softc;
+
+ 	/*
+	 * XXX 
+	 * Work around for broken direct access device
+ 	 * which doesn't support READ(6)/WRITE(6).
+ 	 */
+	error = 0;
+	switch (ccb->ccb_h.status & CAM_STATUS_MASK) {
+	case CAM_SCSI_STATUS_ERROR:
+ 		scsi_extract_sense(&ccb->csio.sense_data,
+				&error_code, &sense_key, &asc, &ascq);
+		if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
+ 			error = cmd6workaround(ccb);
+		break;
+	}
+	if (error == ERESTART)
+		return ERESTART;
 
 	/*
 	 * XXX

