Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 Dec 2002 15:12:40 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        John Baldwin <jhb@FreeBSD.ORG>, Bernd Walter <ticso@cicely8.cicely.de>, "Brian F. Feldman" <green@FreeBSD.ORG>, Josef Karthauser <joe@FreeBSD.ORG>, freebsd-current@FreeBSD.ORG
Subject:   Re: UMASS USB bug? (getting the Sony disk-on-key device working)
Message-ID:  <200212192312.gBJNCe0w008663@apollo.backplane.com>
References:  <20021219172844.GJ29286@cicely8.cicely.de> <XFMail.20021219124916.jhb@FreeBSD.org> <20021219180144.GK29286@cicely8.cicely.de> <200212191848.gBJImgOq099846@apollo.backplane.com>

next in thread | previous in thread | raw e-mail | index | archive | help
    This is a real mess but I finally got it to work.  (Note
    to John:  both quirk entries are absolutely necessary,
    everything stalls and dies without them).

    Problem #1: RA_NO_CLEAR_UA quirk required in umass.c.

    Problem #2: RA_NO_CLEAR_UA quirk code is broken, 
		causes CAM to think that the READ_CAPACITY
		command succeed when it actually failed due
		to the umass_cam_quirk_cb() function
		changing the return status.

		(Machine crashes on bogus capacity data,
		junk that was sitting in the malloc'd
		buffer which the machine thinks is real).

    Problem #3: After fixing RA_NO_CLEAR_UA, CAM still
		retries four times quickly and fails.

		But at least it doesn't crash and burn.

		This is odd... in this state /dev/da2
		exists and if I run 'fdisk da2' it 
		does in fact work, as does dd'ing.

		If I run 'fdisk da2' manually CAM
		tries to do a READ CAPACITY and
		gets a sense key indicating that the
		media changed, and recovers from there,
		except disklabel still doesn't work 
		(/dev only has da2, it doesn't have any
		of the slice entries for some reason).

    I tried bumping the number of CAM retries from 4
    to 10.  No joy.

    I tried adding the NO_TEST_UNIT_READY quirk to
    force UMASS to issue a start-unit command instead
    of a test-unit-ready command.

    That didn't work.

    I tried adding a 0.3-second DELAY(300000) between
    retries.

    Ahhh... THAT WORKED!  The device takes over a 
    second before it TEST_UNIT_READY returns TRUE.

    Ok, so here is the patch.  I need help with two things.

>>>  First, are my RA_NO_CLEAR_UA bug fixes correct? 

>>>  Second, does anyone have any ideas on how we can
    make CAM/UMASS friendlier to devices which take
    longer to get themselves going?    Obviously
    sticking a DELAY(300000) in the middle of an
    interrupt routine is not a good thing to do.
    Is there any way to get CAM to poll the
    device every once in a while to see if the 
    media is ready?

    Note that 'camcontrol rescan <correct_bus>'
    does not work.  It does not cause cam to rescan
    the USB device, it does not cause geom to pick
    up on the fact that da2 is good.  It doesn't seem
    to do anything in fact :-(

					-Matt

Index: sys/cam/scsi/scsi_da.c
===================================================================
RCS file: /home/ncvs/src/sys/cam/scsi/scsi_da.c,v
retrieving revision 1.118
diff -u -r1.118 scsi_da.c
--- sys/cam/scsi/scsi_da.c	18 Dec 2002 21:47:52 -0000	1.118
+++ sys/cam/scsi/scsi_da.c	19 Dec 2002 21:56:31 -0000
@@ -271,6 +271,16 @@
 	},
 	{
 		/*
+		 * Sony Key-Storage media fails in terrible ways without
+		 * both quirks.  The auto 6->10 code doesn't do the job.
+		 * (note: The Sony diskkey is actually the MSYSTEMS 
+		 * disk-on-key device).
+		 */
+		{T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Storage Media", "*"},
+		/*quirks*/ DA_Q_NO_6_BYTE|DA_Q_NO_SYNC_CACHE
+	},
+	{
+		/*
 		 * Sony DSC cameras (DSC-S30, DSC-S50, DSC-S70)
 		 */
 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Sony DSC", "*"},
Index: sys/dev/usb/umass.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/umass.c,v
retrieving revision 1.67
diff -u -r1.67 umass.c
--- sys/dev/usb/umass.c	8 Nov 2002 07:57:42 -0000	1.67
+++ sys/dev/usb/umass.c	19 Dec 2002 23:05:13 -0000
@@ -345,6 +345,10 @@
 	  UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
 	  NO_TEST_UNIT_READY | NO_START_STOP
 	},
+	{ USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY, RID_WILDCARD,
+	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+	  IGNORE_RESIDUE | NO_GETMAXLUN | RS_NO_CLEAR_UA
+	},
 	{ USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1, RID_WILDCARD,
 	  UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
 	  WRONG_CSWSIG
@@ -2606,7 +2610,7 @@
 		/* Getting sense data always succeeds (apart from wire
 		 * failures).
 		 */
-		if (sc->quirks & RS_NO_CLEAR_UA
+		if ((sc->quirks & RS_NO_CLEAR_UA)
 		    && csio->cdb_io.cdb_bytes[0] == INQUIRY
 		    && (csio->sense_data.flags & SSD_KEY)
 		    				== SSD_KEY_UNIT_ATTENTION) {
@@ -2622,21 +2626,24 @@
 			 * CCI)
 			 */
 			ccb->ccb_h.status = CAM_REQ_CMP;
-		} else if ((sc->quirks & RS_NO_CLEAR_UA) && /* XXX */
+		} else if ((sc->quirks & RS_NO_CLEAR_UA) &&
 			   (csio->cdb_io.cdb_bytes[0] == READ_CAPACITY) &&
 			   ((csio->sense_data.flags & SSD_KEY)
 			    == SSD_KEY_UNIT_ATTENTION)) {
-
-			/* Some devices do not clear the unit attention error
+			/*
+			 * Some devices do not clear the unit attention error
 			 * on request sense. We insert a test unit ready
 			 * command to make sure we clear the unit attention
-			 * condition.
+			 * condition, then allow the retry to proceed as
+			 * usual.
 			 */
 
 			ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
 					    | CAM_AUTOSNS_VALID;
 			csio->scsi_status = SCSI_STATUS_CHECK_COND;
 
+			DELAY(300000);
+
 			DPRINTF(UDMASS_SCSI,("%s: Doing a sneaky"
 					     "TEST_UNIT_READY\n",
 				USBDEVNAME(sc->sc_dev)));
@@ -2675,6 +2682,11 @@
 	}
 }
 
+/*
+ * This completion code just handles the fact that we sent a test-unit-ready
+ * after having previously failed a READ CAPACITY with CHECK_COND.  Even
+ * though this command succeeded, we have to tell CAM to retry.
+ */
 Static void
 umass_cam_quirk_cb(struct umass_softc *sc, void *priv, int residue, int status)
 {
@@ -2682,7 +2694,12 @@
 
 	DPRINTF(UDMASS_SCSI, ("%s: Test unit ready returned status %d\n",
 	USBDEVNAME(sc->sc_dev), status));
+#if 0
 	ccb->ccb_h.status = CAM_REQ_CMP;
+#endif
+	ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
+			    | CAM_AUTOSNS_VALID;
+	ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
 	xpt_done(ccb);
 }
 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212192312.gBJNCe0w008663>