From 537b4a46ccabb1f2e4c4c19a4a221797d8f8b9f6 Mon Sep 17 00:00:00 2001 From: Kenneth R Westerback <krw@cvs.openbsd.org> Date: Fri, 9 May 2008 06:19:34 +0000 Subject: Lock in removable media while trying to determine the disk parameters. This should fix a number of 'drive offline' situations where the device claims it has no media loaded until the lock in occurs. Like a Blackberry Pearl Todd Fries found and probably other USB devices. Move the lock in during device open to before the test unit ready to eliminate similar spurious rejections of the device. Feedback from marco@, tests by todd@ and miod@. ok deraadt@ beck@ dlg@ miod@ --- sys/scsi/sd.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'sys') diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index 0242673d9ca..471acce7187 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sd.c,v 1.142 2008/03/21 19:57:44 krw Exp $ */ +/* $OpenBSD: sd.c,v 1.143 2008/05/09 06:19:33 krw Exp $ */ /* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */ /*- @@ -209,6 +209,14 @@ sdattach(struct device *parent, struct device *self, void *aux) scsi_start(sc_link, SSS_START, scsi_autoconf | SCSI_SILENT | SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE); + /* + * Some devices (e.g. Blackberry Pearl) won't admit they have + * media loaded unless its been locked in. + */ + if ((sc_link->flags & SDEV_REMOVABLE) != 0) + scsi_prevent(sc_link, PR_PREVENT, SCSI_IGNORE_ILLEGAL_REQUEST | + SCSI_IGNORE_MEDIA_CHANGE); + /* Check that it is still responding and ok. */ error = scsi_test_unit_ready(sd->sc_link, TEST_READY_RETRIES, scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST | @@ -220,6 +228,11 @@ sdattach(struct device *parent, struct device *self, void *aux) result = sd_get_parms(sd, &sd->params, scsi_autoconf | SCSI_SILENT | SCSI_IGNORE_MEDIA_CHANGE); + if ((sc_link->flags & SDEV_REMOVABLE) != 0) + scsi_prevent(sc_link, PR_ALLOW, + SCSI_IGNORE_ILLEGAL_REQUEST | + SCSI_IGNORE_MEDIA_CHANGE); + printf("%s: ", sd->sc_dev.dv_xname); switch (result) { case SDGP_RESULT_OK: @@ -361,6 +374,16 @@ sdopen(dev_t dev, int flag, int fmt, struct proc *p) */ sc_link->flags |= SDEV_OPEN; + /* + * Try to prevent the unloading of a removable device while + * it's open. But allow the open to proceed if the device can't + * be locked in. + */ + if ((sc_link->flags & SDEV_REMOVABLE) != 0) + scsi_prevent(sc_link, PR_PREVENT, + SCSI_IGNORE_ILLEGAL_REQUEST | + SCSI_IGNORE_MEDIA_CHANGE); + /* Check that it is still responding and ok. */ error = scsi_test_unit_ready(sc_link, TEST_READY_RETRIES, (rawopen ? SCSI_SILENT : 0) | @@ -374,16 +397,6 @@ sdopen(dev_t dev, int flag, int fmt, struct proc *p) goto bad; } - /* - * Try to prevent the unloading of a removable device while - * it's open. But allow the open to proceed if the device can't - * be locked in. - */ - if ((sc_link->flags & SDEV_REMOVABLE) != 0) - scsi_prevent(sc_link, PR_PREVENT, - SCSI_IGNORE_ILLEGAL_REQUEST | - SCSI_IGNORE_MEDIA_CHANGE); - /* Load the physical device parameters. */ sc_link->flags |= SDEV_MEDIA_LOADED; if (sd_get_parms(sd, &sd->params, (rawopen ? SCSI_SILENT : 0)) -- cgit v1.2.3