summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>2006-10-07 23:40:09 +0000
committerBob Beck <beck@cvs.openbsd.org>2006-10-07 23:40:09 +0000
commit495e52be679ec3d4d6d39cb2f307455aa5db47ff (patch)
treebbec97bed837b1bc51308c561a7c276f3cdeaa59 /sys
parent3dabbc85753d59433925bc3aac8ca0b6bc702b30 (diff)
make cd-roms retry forever while the device indicates that it is
"becoming ready" - this is done in the exact same way that it was done for tape in st.c. This commit adds a cd specific interpret_sense routine to cd.c that will catch the becoming ready case and handle it. This also removes the need to use crazy timeouts to catch this case. ok krw@
Diffstat (limited to 'sys')
-rw-r--r--sys/scsi/cd.c55
-rw-r--r--sys/scsi/ch.c5
-rw-r--r--sys/scsi/scsiconf.c6
-rw-r--r--sys/scsi/scsiconf.h6
-rw-r--r--sys/scsi/sd.c6
-rw-r--r--sys/scsi/ss.c4
-rw-r--r--sys/scsi/st.c6
7 files changed, 67 insertions, 21 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c
index b99bfac1f06..76ff53d6145 100644
--- a/sys/scsi/cd.c
+++ b/sys/scsi/cd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cd.c,v 1.111 2006/09/26 23:33:04 krw Exp $ */
+/* $OpenBSD: cd.c,v 1.112 2006/10/07 23:40:07 beck Exp $ */
/* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */
/*
@@ -124,6 +124,7 @@ int cd_read_subchannel(struct cd_softc *, int, int, int,
int cd_read_toc(struct cd_softc *, int, int, void *, int, int);
int cd_get_parms(struct cd_softc *, int);
int cd_load_toc(struct cd_softc *, struct cd_toc *, int);
+int cd_interpret_sense(struct scsi_xfer *);
int dvd_auth(struct cd_softc *, union dvd_authinfo *);
int dvd_read_physical(struct cd_softc *, union dvd_struct *);
@@ -147,7 +148,7 @@ struct cfdriver cd_cd = {
struct dkdriver cddkdriver = { cdstrategy };
struct scsi_device cd_switch = {
- NULL, /* use default error handler */
+ cd_interpret_sense,
cdstart, /* we have a queue, which is started by this */
NULL, /* we do not have an async handler */
cddone, /* deal with stats at interrupt time */
@@ -340,7 +341,11 @@ cdopen(dev, flag, fmt, p)
* progress of loading media so use increased retries number
* and don't ignore NOT_READY.
*/
- error = scsi_test_unit_ready(sc_link, TEST_READY_RETRIES_CD,
+
+ /* Use cd_interpret_sense() now. */
+ sc_link->flags |= SDEV_OPEN;
+
+ error = scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
(rawopen ? SCSI_SILENT : 0) | SCSI_IGNORE_ILLEGAL_REQUEST |
SCSI_IGNORE_MEDIA_CHANGE);
@@ -2017,3 +2022,47 @@ cd_powerhook(int why, void *arg)
scsi_prevent(cd->sc_link, PR_PREVENT,
SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
}
+
+int
+cd_interpret_sense(xs)
+ struct scsi_xfer *xs;
+{
+ struct scsi_sense_data *sense = &xs->sense;
+ struct scsi_link *sc_link = xs->sc_link;
+ u_int8_t skey = sense->flags & SSD_KEY;
+ u_int8_t serr = sense->error_code & SSD_ERRCODE;
+
+ if (((sc_link->flags & SDEV_OPEN) == 0) ||
+ (serr != 0x70 && serr != 0x71))
+ return (EJUSTRETURN); /* let the generic code handle it */
+
+ /*
+ * We do custom processing in cd for the unit becoming ready case.
+ * in this case we do not allow xs->retries to be decremented
+ * only on the "Unit Becoming Ready" case. This is because CD
+ * drives report "Unit Becoming Ready" when loading media, etc.
+ * and can take a long time. Rather than having a massive timeout
+ * for all operations (which would cause other problems) we allow
+ * operations to wait (but be interruptable with Ctrl-C) forever
+ * as long as the drive is reporting that it is becoming ready.
+ * all other cases of not being ready are handled as per the default.
+ */
+ switch(skey) {
+ case SKEY_NOT_READY:
+ if ((xs->flags & SCSI_IGNORE_NOT_READY) != 0)
+ return (0);
+ if (sense->add_sense_code == 0x04 && /* Not ready */
+ sense->add_sense_code_qual == 0x01) { /* Becoming ready */
+ SC_DEBUG(sc_link, SDEV_DB1, ("not ready: busy (%#x)\n",
+ sense->add_sense_code_qual));
+ /* don't count this as a retry */
+ xs->retries++;
+ return (scsi_delay(xs, 1));
+ }
+ break;
+ /* XXX more to come here for a few other cases */
+ default:
+ break;
+ }
+ return (EJUSTRETURN); /* use generic handler in scsi_base */
+}
diff --git a/sys/scsi/ch.c b/sys/scsi/ch.c
index 193897a9f69..d57f25bda3e 100644
--- a/sys/scsi/ch.c
+++ b/sys/scsi/ch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ch.c,v 1.28 2006/06/15 15:02:31 beck Exp $ */
+/* $OpenBSD: ch.c,v 1.29 2006/10/07 23:40:07 beck Exp $ */
/* $NetBSD: ch.c,v 1.26 1997/02/21 22:06:52 thorpej Exp $ */
/*
@@ -210,8 +210,7 @@ chopen(dev, flags, fmt, p)
* process of getting ready" any time it must rescan
* itself to determine the state of the changer.
*/
- error = scsi_test_unit_ready(sc->sc_link,
- TEST_READY_RETRIES_TAPE,
+ error = scsi_test_unit_ready(sc->sc_link, TEST_READY_RETRIES,
SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
if (error)
goto bad;
diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c
index 0f45be2fa7c..1aa76c9c005 100644
--- a/sys/scsi/scsiconf.c
+++ b/sys/scsi/scsiconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.c,v 1.115 2006/10/02 09:06:26 dlg Exp $ */
+/* $OpenBSD: scsiconf.c,v 1.116 2006/10/07 23:40:07 beck Exp $ */
/* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */
/*
@@ -627,7 +627,7 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun)
#if defined(mvme68k)
if (lun == 0) {
/* XXX some drivers depend on this */
- scsi_test_unit_ready(sc_link, TEST_READY_RETRIES_DEFAULT,
+ scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST |
SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
}
@@ -743,7 +743,7 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun)
* Do this now so that any messages generated by config_attach() do not
* have negotiation messages inserted into their midst.
*/
- scsi_test_unit_ready(sc_link, TEST_READY_RETRIES_DEFAULT,
+ scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST |
SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h
index 8c48c53a9c7..a04d6299027 100644
--- a/sys/scsi/scsiconf.h
+++ b/sys/scsi/scsiconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.h,v 1.74 2006/10/02 09:06:26 dlg Exp $ */
+/* $OpenBSD: scsiconf.h,v 1.75 2006/10/07 23:40:07 beck Exp $ */
/* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */
/*
@@ -298,9 +298,7 @@ struct scsi_xfer {
/*
* Possible retries numbers for scsi_test_unit_ready()
*/
-#define TEST_READY_RETRIES_DEFAULT 5
-#define TEST_READY_RETRIES_CD 10
-#define TEST_READY_RETRIES_TAPE 60
+#define TEST_READY_RETRIES 5
const void *scsi_inqmatch(struct scsi_inquiry_data *, const void *, int,
int, int *);
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index b8839fc426a..0e3bca0a547 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sd.c,v 1.110 2006/07/29 02:40:46 krw Exp $ */
+/* $OpenBSD: sd.c,v 1.111 2006/10/07 23:40:07 beck Exp $ */
/* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */
/*-
@@ -214,7 +214,7 @@ sdattach(parent, self, aux)
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_DEFAULT,
+ error = scsi_test_unit_ready(sd->sc_link, TEST_READY_RETRIES,
scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST |
SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT);
@@ -377,7 +377,7 @@ sdopen(dev, flag, fmt, p)
/* Check that it is still responding and ok. */
error = scsi_test_unit_ready(sc_link,
- TEST_READY_RETRIES_DEFAULT, (rawopen ? SCSI_SILENT : 0) |
+ TEST_READY_RETRIES, (rawopen ? SCSI_SILENT : 0) |
SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
if (error) {
diff --git a/sys/scsi/ss.c b/sys/scsi/ss.c
index 6f04fb644eb..3e1bf16b49c 100644
--- a/sys/scsi/ss.c
+++ b/sys/scsi/ss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ss.c,v 1.55 2006/05/18 21:27:25 miod Exp $ */
+/* $OpenBSD: ss.c,v 1.56 2006/10/07 23:40:07 beck Exp $ */
/* $NetBSD: ss.c,v 1.10 1996/05/05 19:52:55 christos Exp $ */
/*
@@ -436,7 +436,7 @@ ssopen(dev, flag, mode, p)
* consider paper to be a changeable media
*
*/
- error = scsi_test_unit_ready(sc_link, TEST_READY_RETRIES_DEFAULT,
+ error = scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
SCSI_IGNORE_MEDIA_CHANGE | SCSI_IGNORE_ILLEGAL_REQUEST |
(ssmode == MODE_CONTROL ? SCSI_IGNORE_NOT_READY : 0));
if (error)
diff --git a/sys/scsi/st.c b/sys/scsi/st.c
index f825a76ab95..27c5ebceca2 100644
--- a/sys/scsi/st.c
+++ b/sys/scsi/st.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: st.c,v 1.64 2006/10/02 09:06:26 dlg Exp $ */
+/* $OpenBSD: st.c,v 1.65 2006/10/07 23:40:08 beck Exp $ */
/* $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $ */
/*
@@ -431,7 +431,7 @@ stopen(dev, flags, fmt, p)
* Check the unit status. This clears any outstanding errors and
* will ensure that media is present.
*/
- error = scsi_test_unit_ready(sc_link, TEST_READY_RETRIES_TAPE,
+ error = scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
SCSI_SILENT | SCSI_IGNORE_MEDIA_CHANGE |
SCSI_IGNORE_ILLEGAL_REQUEST);
@@ -542,7 +542,7 @@ st_mount_tape(dev, flags)
* (noteably some DAT drives)
*/
/* XXX */
- scsi_test_unit_ready(sc_link, TEST_READY_RETRIES_TAPE, SCSI_SILENT);
+ scsi_test_unit_ready(sc_link, TEST_READY_RETRIES, SCSI_SILENT);
/*
* Some devices can't tell you much until they have been