Some USB devices reports themselves as removable, but have no door and

so don't support the SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL command.
When an "Illegal field in CDB" is reported for this command, mark the
device as non-removable (which is always true for USB keys from the SCSI
point of view), print a message and ignore the error.
For DIOCLOCK, return ENOTTY if the device is not removable instead of
trying a command which will fail.

Fix a problem reported by Hubert Feyrer for some USB umass devices, patch
tested by him.
This commit is contained in:
bouyer 2005-12-08 22:14:19 +00:00
parent e4adbdcd56
commit dd5eb5979f

View File

@ -1,4 +1,4 @@
/* $NetBSD: sd.c,v 1.241 2005/10/15 17:29:25 yamt Exp $ */
/* $NetBSD: sd.c,v 1.242 2005/12/08 22:14:19 bouyer Exp $ */
/*-
* Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
@ -54,7 +54,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.241 2005/10/15 17:29:25 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.242 2005/12/08 22:14:19 bouyer Exp $");
#include "opt_scsi.h"
#include "rnd.h"
@ -1128,8 +1128,12 @@ bad:
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)
@ -1352,6 +1356,23 @@ sd_interpret_sense(struct scsipi_xfer *xs)
if (periph->periph_flags & PERIPH_RECOVERING)
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 &&
(sense->flags & SSD_KEY) == SKEY_ILLEGAL_REQUEST &&
sense->add_sense_code == 0x24 &&
sense->add_sense_code_qual == 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.
*/