diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2006-10-07 23:40:09 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2006-10-07 23:40:09 +0000 |
commit | 495e52be679ec3d4d6d39cb2f307455aa5db47ff (patch) | |
tree | bbec97bed837b1bc51308c561a7c276f3cdeaa59 | |
parent | 3dabbc85753d59433925bc3aac8ca0b6bc702b30 (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@
-rw-r--r-- | sys/scsi/cd.c | 55 | ||||
-rw-r--r-- | sys/scsi/ch.c | 5 | ||||
-rw-r--r-- | sys/scsi/scsiconf.c | 6 | ||||
-rw-r--r-- | sys/scsi/scsiconf.h | 6 | ||||
-rw-r--r-- | sys/scsi/sd.c | 6 | ||||
-rw-r--r-- | sys/scsi/ss.c | 4 | ||||
-rw-r--r-- | sys/scsi/st.c | 6 |
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 |