Subject: Re: umass woe: sd0(umass0:0:0): readonly device & drive offline
To: Manuel Bouyer <bouyer@antioche.eu.org>
From: Hubert Feyrer <feyrer@cs.stevens.edu>
List: tech-kern
Date: 11/23/2005 02:18:38
OK, I figured it out, apparently a few things were changed in -current... 
I'll append the updated patch below. A full dmesg output including 
SCSI_VERBOSE is also available, see 
http://www.feyrer.de/Misc/usb-debug-manuel-1.txt

Output I get via dmesg is
1) after plugging the cam in:

 	umass0 at uhub0 port 1 configuration 1 interface 0
 	umass0: DSC DIGITAL CAMERA USB, rev 1.00/1.00, addr 2
 	umass0: using ATAPI over Bulk-Only
 	atapibus0 at umass0: 2 targets
 	scsipi_inqmatch: 2/0/1 <, , >
 	sd0 at atapibus0 drive 0: <DIGITAL, CAMERA, 1.00> disk removable
 	sd0(umass0:0:0): readonly device
 	sd0: drive offline

2) After accessing:

 	sd0(umass0:0:0): no door lock
 	sd0: fabricating a geometry

Hm, still readonly device & drive offline...
And what's that scsipi_inqmatch?

Anyways, maybe I should point out that I've tried this on -current with no 
other patches, and I got the camera mounted fine.


  - Hubert


Index: sd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/sd.c,v
retrieving revision 1.241
diff -u -r1.241 sd.c
--- sd.c	15 Oct 2005 17:29:25 -0000	1.241
+++ sd.c	23 Nov 2005 01:11:43 -0000
@@ -1128,8 +1128,12 @@
  		return (0);

  	case DIOCLOCK:
-		return (scsipi_prevent(periph,
-		    (*(int *)addr) ? SPAMR_PREVENT_DT : SPAMR_ALLOW, 0));
+		if (periph->periph_flags & PERIPH_REMOVABLE)
+			return (scsipi_prevent(periph,
+			    (*(int *)addr) ?
+			    SPAMR_PREVENT_DT : SPAMR_ALLOW, 0));
+		else
+			return (ENOTTY);

  	case DIOCEJECT:
  		if ((periph->periph_flags & PERIPH_REMOVABLE) == 0)
@@ -1353,6 +1357,23 @@
  		return (retval);

  	/*
+	 * Ignore errors from accessing illegal fields (e.g. trying to
+	 * lock the door of a digicam, which doesn't have a door that
+	 * can be locked) for the SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL command.
+	 */
+	if (xs->cmd->opcode == SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL &&
+	    SSD_SENSE_KEY(sense->flags) == SKEY_ILLEGAL_REQUEST &&
+	    sense->asc == 0x24 &&
+	    sense->ascq == 0x00) { /* Illegal field in CDB */
+		scsipi_printaddr(periph);
+		printf("no door lock\n");
+		periph->periph_flags &= ~PERIPH_REMOVABLE;
+		return 0;
+	}
+
+
+
+	/*
  	 * If the device is not open yet, let the generic code handle it.
  	 */
  	if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0)