PATCH: Disable 6 byte commands for USB, firewire, ATAPICAM

Nate Lawson nate at root.org
Thu Jul 24 19:00:08 PDT 2003


Attached is a patch that disables ever sending 6 byte commands to buses
that do not support them.  Numerous USB devices hang when receiving a 6
byte command.  For testing, this patch comments out the scsi_da quirks for
devices that I believe are addressed by this patch and no longer need the
quirk.

Please test devices such as USB keys, USB cameras, Firewire hard disks,
and ATAPICAM cd drives to be sure they still work with this patch.
Especially if you've needed a quirk before, it is important to see if this
patch does not break your device.  I hope to get this into the tree early
so there is plenty of testing before 5.2.

Thanks,
Nate
-------------- next part --------------
Index: /sys/cam/cam_ccb.h
===================================================================
RCS file: /home/ncvs/src/sys/cam/cam_ccb.h,v
retrieving revision 1.25
diff -u -r1.25 cam_ccb.h
--- /sys/cam/cam_ccb.h	14 Jun 2003 22:17:38 -0000	1.25
+++ /sys/cam/cam_ccb.h	25 Jul 2003 01:01:45 -0000
@@ -513,7 +513,8 @@
 	PIM_SCANHILO	= 0x80,	/* Bus scans from high ID to low ID */
 	PIM_NOREMOVE	= 0x40,	/* Removeable devices not included in scan */
 	PIM_NOINITIATOR	= 0x20,	/* Initiator role not supported. */
-	PIM_NOBUSRESET  = 0x10  /* User has disabled initial BUS RESET */
+	PIM_NOBUSRESET	= 0x10,	/* User has disabled initial BUS RESET */
+	PIM_NO_6_BYTE	= 0x08	/* Do not send 6-byte commands */
 } pi_miscflag;
 
 #ifdef CAM_NEW_TRAN_CODE
Index: /sys/cam/scsi/scsi_da.c
===================================================================
RCS file: /home/ncvs/src/sys/cam/scsi/scsi_da.c,v
retrieving revision 1.146
diff -u -r1.146 scsi_da.c
--- /sys/cam/scsi/scsi_da.c	18 Jul 2003 16:26:36 -0000	1.146
+++ /sys/cam/scsi/scsi_da.c	25 Jul 2003 01:54:34 -0000
@@ -145,6 +145,7 @@
 
 static struct da_quirk_entry da_quirk_table[] =
 {
+#ifndef DA_OLD_QUIRKS
 	/*
 	 * Logitec USB/Firewire LHD-P30FU
 	 */
@@ -158,6 +159,7 @@
 		{T_DIRECT, SIP_MEDIA_FIXED, "LSILogic", "SYM13FW*", "*"},
 		/*quirks*/ DA_Q_NO_6_BYTE
 	},
+#endif /* !DA_OLD_QUIRKS */
 	{
 		/*
 		 * Fujitsu M2513A MO drives.
@@ -257,6 +259,7 @@
 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "MATSHITA", "FDD CF-VFDU*","*"},
 		/*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
 	},
+#ifndef DA_OLD_QUIRKS
 	{
 		/*
 		 * Sony Memory Stick adapter MSAC-US1 and
@@ -517,6 +520,7 @@
 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "OTi", "Flash Disk", "*"},
 		/*quirks*/ DA_Q_NO_6_BYTE
 	}
+#endif /* !DA_OLD_QUIRKS */
 };
 
 static	disk_strategy_t	dastrategy;
@@ -1087,6 +1091,7 @@
 	int s;
 	struct da_softc *softc;
 	struct ccb_setasync csa;
+	struct ccb_pathinq cpi;
 	struct ccb_getdev *cgd;
 	char tmpstr[80], tmpstr2[80];
 	caddr_t match;
@@ -1133,6 +1138,15 @@
 		softc->quirks = ((struct da_quirk_entry *)match)->quirks;
 	else
 		softc->quirks = DA_Q_NONE;
+
+	/* Check if the SIM does not want 6 byte commands */
+	xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
+	cpi.ccb_h.func_code = XPT_PATH_INQ;
+	xpt_action((union ccb *)&cpi);
+	if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE)) {
+		printf("daregister: setting no 6 byte\n");
+		softc->quirks |= DA_Q_NO_6_BYTE;
+	}
 
 	snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
 	snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
Index: /sys/cam/scsi/scsi_cd.c
===================================================================
RCS file: /home/ncvs/src/sys/cam/scsi/scsi_cd.c,v
retrieving revision 1.79
diff -u -r1.79 scsi_cd.c
--- /sys/cam/scsi/scsi_cd.c	10 Jun 2003 18:14:04 -0000	1.79
+++ /sys/cam/scsi/scsi_cd.c	25 Jul 2003 01:13:08 -0000
@@ -640,6 +640,7 @@
 {
 	struct cd_softc *softc;
 	struct ccb_setasync csa;
+	struct ccb_pathinq cpi;
 	struct ccb_getdev *cgd;
 	char tmpstr[80], tmpstr2[80];
 	caddr_t match;
@@ -687,6 +688,15 @@
 		softc->quirks = ((struct cd_quirk_entry *)match)->quirks;
 	else
 		softc->quirks = CD_Q_NONE;
+
+	/* Check if the SIM does not want 6 byte commands */
+	xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
+	cpi.ccb_h.func_code = XPT_PATH_INQ;
+	xpt_action((union ccb *)&cpi);
+	if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE)) {
+		printf("cdregister: setting no 6 byte\n");
+		softc->quirks |= CD_Q_10_BYTE_ONLY;
+	}
 
 	snprintf(tmpstr, sizeof(tmpstr), "CAM CD unit %d", periph->unit_number);
 	snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
Index: /sys/dev/ata/atapi-cam.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/atapi-cam.c,v
retrieving revision 1.17
diff -u -r1.17 atapi-cam.c
--- /sys/dev/ata/atapi-cam.c	14 Jun 2003 22:17:39 -0000	1.17
+++ /sys/dev/ata/atapi-cam.c	25 Jul 2003 01:13:41 -0000
@@ -238,7 +238,7 @@
 	cpi->version_num = 1;
 	cpi->hba_inquiry = 0;
 	cpi->target_sprt = 0;
-	cpi->hba_misc = 0;
+	cpi->hba_misc = PIM_NO_6_BYTE;
 	cpi->hba_eng_cnt = 0;
 	bzero(cpi->vuhba_flags, sizeof(cpi->vuhba_flags));
 	cpi->max_target = 1;
Index: /sys/dev/usb/umass.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/umass.c,v
retrieving revision 1.87
diff -u -r1.87 umass.c
--- /sys/dev/usb/umass.c	4 Jul 2003 23:11:13 -0000	1.87
+++ /sys/dev/usb/umass.c	25 Jul 2003 01:01:17 -0000
@@ -2393,7 +2393,7 @@
 		cpi->version_num = 1;
 		cpi->hba_inquiry = 0;
 		cpi->target_sprt = 0;
-		cpi->hba_misc = 0;
+		cpi->hba_misc = PIM_NO_6_BYTE;
 		cpi->hba_eng_cnt = 0;
 		cpi->max_target = UMASS_SCSIID_MAX;	/* one target */
 		cpi->initiator_id = UMASS_SCSIID_HOST;
Index: /sys/dev/firewire/sbp.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/firewire/sbp.c,v
retrieving revision 1.57
diff -u -r1.57 sbp.c
--- /sys/dev/firewire/sbp.c	18 Jul 2003 14:31:16 -0000	1.57
+++ /sys/dev/firewire/sbp.c	25 Jul 2003 01:10:59 -0000
@@ -2369,7 +2369,7 @@
 		cpi->version_num = 1; /* XXX??? */
 		cpi->hba_inquiry = PI_TAG_ABLE;
 		cpi->target_sprt = 0;
-		cpi->hba_misc = PIM_NOBUSRESET;
+		cpi->hba_misc = PIM_NOBUSRESET | PIM_NO_6_BYTE;
 		cpi->hba_eng_cnt = 0;
 		cpi->max_target = SBP_NUM_TARGETS - 1;
 		cpi->max_lun = SBP_NUM_LUNS - 1;


More information about the freebsd-current mailing list