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)