diff options
author | ken <ken@FreeBSD.org> | 1999-05-09 01:25:34 +0000 |
---|---|---|
committer | ken <ken@FreeBSD.org> | 1999-05-09 01:25:34 +0000 |
commit | fce282444d186f06f7656d21a2a2ffea2ce7ed9c (patch) | |
tree | ccc2498874709e9c885bfb9185013d6bf5a0d116 /sys/cam | |
parent | 4a4467575d5f4db43a083085e049267cfaf6ebeb (diff) | |
download | FreeBSD-src-fce282444d186f06f7656d21a2a2ffea2ce7ed9c.zip FreeBSD-src-fce282444d186f06f7656d21a2a2ffea2ce7ed9c.tar.gz |
Add a facility in the CAM error handling code to retry selection timeouts.
If the client requests that the error recovery code retry a selection
timeout, it will be retried after half a second. The delay is to give the
device time to recover.
For most of these drivers, I only added selection timeout retries where
they were also retrying unit attention type errors. The sa(4) driver calls
saerror() in a number of places, but most of them don't request retrying
unit attentions.
Also, bump the default minimum CD changer timeout from 2 to 5 seconds and
the maximum timeout from 10 to 15 seconds. Some Pioneer changers seem to
have trouble with the shorter timeout.
Reviewed by: gibbs
Diffstat (limited to 'sys/cam')
-rw-r--r-- | sys/cam/cam_periph.c | 20 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_all.h | 3 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_cd.c | 38 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_ch.c | 32 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_da.c | 11 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_pass.c | 4 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_pt.c | 4 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_sa.c | 6 |
8 files changed, 76 insertions, 42 deletions
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 02c8785..d365a12 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam_periph.c,v 1.11 1999/04/06 03:05:36 peter Exp $ + * $Id: cam_periph.c,v 1.12 1999/04/19 21:26:07 gibbs Exp $ */ #include <sys/param.h> @@ -1505,7 +1505,23 @@ cam_periph_error(union ccb *ccb, cam_flags camflags, xpt_async(AC_LOST_DEVICE, newpath, NULL); xpt_free_path(newpath); #endif - error = ENXIO; + if ((sense_flags & SF_RETRY_SELTO) != 0) { + retry = ccb->ccb_h.retry_count > 0; + if (retry) { + ccb->ccb_h.retry_count--; + error = ERESTART; + /* + * Wait half a second to give the device + * time to recover before we try again. + */ + relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT; + timeout = 500; + } else { + error = ENXIO; + } + } else { + error = ENXIO; + } break; } case CAM_REQ_INVALID: diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h index ccbab9d..bedd144 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -14,7 +14,7 @@ * * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 * - * $Id: scsi_all.h,v 1.5 1998/10/15 19:08:58 ken Exp $ + * $Id: scsi_all.h,v 1.6 1998/12/05 22:10:14 mjacob Exp $ */ /* @@ -712,6 +712,7 @@ int scsi_interpret_sense(struct cam_device *device, #define SF_NO_PRINT 0x02 #define SF_QUIET_IR 0x04 /* Be quiet about Illegal Request reponses */ #define SF_PRINT_ALWAYS 0x08 +#define SF_RETRY_SELTO 0x10 /* Retry selection timeouts */ const char * scsi_op_desc(u_int16_t opcode, diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index eb7fd99..8779545 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_cd.c,v 1.18 1999/05/06 20:16:03 ken Exp $ + * $Id: scsi_cd.c,v 1.19 1999/05/07 07:02:57 phk Exp $ */ /* * Portions of this driver taken from the original FreeBSD cd driver. @@ -270,10 +270,10 @@ static struct extend_array *cdperiphs; static int num_changers; #ifndef CHANGER_MIN_BUSY_SECONDS -#define CHANGER_MIN_BUSY_SECONDS 2 +#define CHANGER_MIN_BUSY_SECONDS 5 #endif #ifndef CHANGER_MAX_BUSY_SECONDS -#define CHANGER_MAX_BUSY_SECONDS 10 +#define CHANGER_MAX_BUSY_SECONDS 15 #endif static int changer_min_busy_seconds = CHANGER_MIN_BUSY_SECONDS; @@ -1583,7 +1583,10 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) sf = SF_RETRY_UA; else sf = 0; - + + /* Retry selection timeouts */ + sf |= SF_RETRY_SELTO; + if ((error = cderror(done_ccb, 0, sf)) == ERESTART) { /* * A retry was scheuled, so @@ -1688,7 +1691,8 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) * Retry any UNIT ATTENTION type errors. They * are expected at boot. */ - error = cderror(done_ccb, 0, SF_RETRY_UA|SF_NO_PRINT); + error = cderror(done_ccb, 0, SF_RETRY_UA | + SF_NO_PRINT | SF_RETRY_SELTO); if (error == ERESTART) { /* * A retry was scheuled, so @@ -2512,7 +2516,7 @@ cdprevent(struct cam_periph *periph, int action) /* timeout */60000); error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA|SF_NO_PRINT); + /*sense_flags*/SF_RETRY_UA|SF_NO_PRINT|SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -2556,7 +2560,7 @@ cdsize(dev_t dev, u_int32_t *size) /* timeout */20000); error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA|SF_NO_PRINT); + /*sense_flags*/SF_RETRY_UA|SF_NO_PRINT|SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -2633,7 +2637,7 @@ cdreadtoc(struct cam_periph *periph, u_int32_t mode, u_int32_t start, scsi_cmd->op_code = READ_TOC; error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA); + /*sense_flags*/SF_RETRY_UA|SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -2680,7 +2684,7 @@ cdreadsubchannel(struct cam_periph *periph, u_int32_t mode, scsi_cmd->control = 0; error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA); + /*sense_flags*/SF_RETRY_UA|SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -2720,7 +2724,7 @@ cdgetmode(struct cam_periph *periph, struct cd_mode_data *data, u_int32_t page) scsi_cmd->opcode = MODE_SENSE; error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA); + /*sense_flags*/SF_RETRY_UA|SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -2767,7 +2771,7 @@ cdsetmode(struct cam_periph *periph, struct cd_mode_data *data) data->header.medium_type = 0; error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA); + /*sense_flags*/SF_RETRY_UA | SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -2823,7 +2827,7 @@ cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len) /*timeout*/50 * 1000); error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA); + /*sense_flags*/SF_RETRY_UA | SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -2868,7 +2872,7 @@ cdplaymsf(struct cam_periph *periph, u_int32_t startm, u_int32_t starts, scsi_cmd->end_f = endf; error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA); + /*sense_flags*/SF_RETRY_UA | SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -2912,7 +2916,7 @@ cdplaytracks(struct cam_periph *periph, u_int32_t strack, u_int32_t sindex, scsi_cmd->end_index = eindex; error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA); + /*sense_flags*/SF_RETRY_UA | SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -2951,7 +2955,7 @@ cdpause(struct cam_periph *periph, u_int32_t go) scsi_cmd->resume = go; error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA); + /*sense_flags*/SF_RETRY_UA |SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -2979,7 +2983,7 @@ cdstartunit(struct cam_periph *periph) /* timeout */ 50000); error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA); + /*sense_flags*/SF_RETRY_UA | SF_RETRY_SELTO); xpt_release_ccb(ccb); @@ -3007,7 +3011,7 @@ cdstopunit(struct cam_periph *periph, u_int32_t eject) /* timeout */ 50000); error = cdrunccb(ccb, cderror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA); + /*sense_flags*/SF_RETRY_UA | SF_RETRY_SELTO); xpt_release_ccb(ccb); diff --git a/sys/cam/scsi/scsi_ch.c b/sys/cam/scsi/scsi_ch.c index 384e9b4..418426f 100644 --- a/sys/cam/scsi/scsi_ch.c +++ b/sys/cam/scsi/scsi_ch.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_ch.c,v 1.9 1998/12/22 20:05:23 eivind Exp $ + * $Id: scsi_ch.c,v 1.10 1999/02/10 00:03:15 ken Exp $ */ /* * Derived from the NetBSD SCSI changer driver. @@ -634,7 +634,8 @@ chdone(struct cam_periph *periph, union ccb *done_ccb) } else { int error; - error = cherror(done_ccb, 0, SF_RETRY_UA|SF_NO_PRINT); + error = cherror(done_ccb, 0, SF_RETRY_UA | + SF_NO_PRINT | SF_RETRY_SELTO); /* * Retry any UNIT ATTENTION type errors. They * are expected at boot. @@ -874,7 +875,7 @@ chmove(struct cam_periph *periph, struct changer_move *cm) /* timeout */ CH_TIMEOUT_MOVE_MEDIUM); error = cam_periph_runccb(ccb, cherror, /*cam_flags*/0, - /*sense_flags*/ SF_RETRY_UA, + /*sense_flags*/ SF_RETRY_UA | SF_RETRY_SELTO, &softc->device_stats); xpt_release_ccb(ccb); @@ -937,7 +938,7 @@ chexchange(struct cam_periph *periph, struct changer_exchange *ce) /* timeout */ CH_TIMEOUT_EXCHANGE_MEDIUM); error = cam_periph_runccb(ccb, cherror, /*cam_flags*/0, - /*sense_flags*/ SF_RETRY_UA, + /*sense_flags*/ SF_RETRY_UA | SF_RETRY_SELTO, &softc->device_stats); xpt_release_ccb(ccb); @@ -983,7 +984,7 @@ chposition(struct cam_periph *periph, struct changer_position *cp) /* timeout */ CH_TIMEOUT_POSITION_TO_ELEMENT); error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ 0, - /*sense_flags*/ SF_RETRY_UA, + /*sense_flags*/ SF_RETRY_UA | SF_RETRY_SELTO, &softc->device_stats); xpt_release_ccb(ccb); @@ -1139,7 +1140,7 @@ chgetelemstatus(struct cam_periph *periph, /* timeout */ CH_TIMEOUT_READ_ELEMENT_STATUS); error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ 0, - /* sense_flags */ SF_RETRY_UA, + /*sense_flags*/ SF_RETRY_UA | SF_RETRY_SELTO, &softc->device_stats); if (error) @@ -1175,7 +1176,7 @@ chgetelemstatus(struct cam_periph *periph, /* timeout */ CH_TIMEOUT_READ_ELEMENT_STATUS); error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ 0, - /* sense_flags */ SF_RETRY_UA, + /*sense_flags*/ SF_RETRY_UA | SF_RETRY_SELTO, &softc->device_stats); if (error) @@ -1254,7 +1255,7 @@ chielem(struct cam_periph *periph, /* timeout */ timeout); error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ 0, - /* sense_flags */ SF_RETRY_UA, + /*sense_flags*/ SF_RETRY_UA | SF_RETRY_SELTO, &softc->device_stats); xpt_release_ccb(ccb); @@ -1341,7 +1342,7 @@ chsetvoltag(struct cam_periph *periph, /* timeout */ CH_TIMEOUT_SEND_VOLTAG); error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ 0, - /*sense_flags*/ SF_RETRY_UA, + /*sense_flags*/ SF_RETRY_UA | SF_RETRY_SELTO, &softc->device_stats); xpt_release_ccb(ccb); @@ -1405,7 +1406,8 @@ chgetparams(struct cam_periph *periph) /* timeout */ CH_TIMEOUT_MODE_SENSE); error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ 0, - /* sense_flags */ SF_RETRY_UA |SF_NO_PRINT, + /* sense_flags */ SF_RETRY_UA | + SF_NO_PRINT | SF_RETRY_SELTO, &softc->device_stats); if (error) { @@ -1417,7 +1419,8 @@ chgetparams(struct cam_periph *periph) sms->byte2 &= ~SMS_DBD; error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ 0, - /* sense_flags */ SF_RETRY_UA, + /*sense_flags*/ SF_RETRY_UA | + SF_RETRY_SELTO, &softc->device_stats); } else { /* @@ -1467,8 +1470,8 @@ chgetparams(struct cam_periph *periph) /* timeout */ CH_TIMEOUT_MODE_SENSE); error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ 0, - /* sense_flags */ SF_RETRY_UA|SF_NO_PRINT, - &softc->device_stats); + /* sense_flags */ SF_RETRY_UA | SF_NO_PRINT | + SF_RETRY_SELTO, &softc->device_stats); if (error) { if (dbd) { @@ -1479,7 +1482,8 @@ chgetparams(struct cam_periph *periph) sms->byte2 &= ~SMS_DBD; error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ 0, - /* sense_flags */ SF_RETRY_UA, + /*sense_flags*/ SF_RETRY_UA | + SF_RETRY_SELTO, &softc->device_stats); } else { /* diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index faf2760..980911e 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_da.c,v 1.22 1999/05/06 20:16:04 ken Exp $ + * $Id: scsi_da.c,v 1.23 1999/05/07 07:02:59 phk Exp $ */ #include "opt_hw_wdog.h" @@ -333,7 +333,8 @@ daopen(dev_t dev, int flags, int fmt, struct proc *p) ccb->ccb_h.ccb_bp = NULL; error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0, - /*sense_flags*/SF_RETRY_UA, + /*sense_flags*/SF_RETRY_UA | + SF_RETRY_SELTO, &softc->device_stats); xpt_release_ccb(ccb); @@ -1217,6 +1218,9 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) else sf = 0; + /* Retry selection timeouts */ + sf |= SF_RETRY_SELTO; + if ((error = daerror(done_ccb, 0, sf)) == ERESTART) { /* * A retry was scheuled, so @@ -1323,7 +1327,8 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) * Retry any UNIT ATTENTION type errors. They * are expected at boot. */ - error = daerror(done_ccb, 0, SF_RETRY_UA|SF_NO_PRINT); + error = daerror(done_ccb, 0, SF_RETRY_UA | + SF_RETRY_SELTO | SF_NO_PRINT); if (error == ERESTART) { /* * A retry was scheuled, so diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index ab8a7fd..897a49f 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_pass.c,v 1.7 1999/05/06 20:16:05 ken Exp $ + * $Id: scsi_pass.c,v 1.8 1999/05/07 07:03:00 phk Exp $ */ #include <sys/param.h> @@ -819,7 +819,7 @@ passsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb) (ccb->ccb_h.flags & CAM_PASS_ERR_RECOVER) ? passerror : NULL, /* cam_flags */ 0, - /* sense_flags */SF_RETRY_UA, + /* sense_flags */SF_RETRY_UA | SF_RETRY_SELTO, &softc->device_stats); if (need_unmap != 0) diff --git a/sys/cam/scsi/scsi_pt.c b/sys/cam/scsi/scsi_pt.c index 50469c2..7762b64 100644 --- a/sys/cam/scsi/scsi_pt.c +++ b/sys/cam/scsi/scsi_pt.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_pt.c,v 1.5 1999/02/10 00:03:15 ken Exp $ + * $Id: scsi_pt.c,v 1.6 1999/05/07 07:03:01 phk Exp $ */ #include <sys/param.h> @@ -606,6 +606,8 @@ ptdone(struct cam_periph *periph, union ccb *done_ccb) else sf = 0; + sf |= SF_RETRY_SELTO; + if ((error = pterror(done_ccb, 0, sf)) == ERESTART) { /* * A retry was scheuled, so diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c index 1a1e840..4ba4d07 100644 --- a/sys/cam/scsi/scsi_sa.c +++ b/sys/cam/scsi/scsi_sa.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_sa.c,v 1.21 1999/04/18 01:05:03 mjacob Exp $ + * $Id: scsi_sa.c,v 1.22 1999/05/07 07:03:02 phk Exp $ */ #include <sys/param.h> @@ -1589,7 +1589,7 @@ samount(struct cam_periph *periph, int oflags, dev_t dev) rblim, SSD_FULL_SIZE, 5000); error = cam_periph_runccb(ccb, saerror, 0, - SF_RETRY_UA, &softc->device_stats); + SF_RETRY_UA | SF_RETRY_SELTO, &softc->device_stats); xpt_release_ccb(ccb); @@ -2774,6 +2774,8 @@ sareservereleaseunit(struct cam_periph *periph, int reserve) else sflag = SF_RETRY_UA|SF_QUIET_IR; + sflag |= SF_RETRY_SELTO; + ccb = cam_periph_getccb(periph, 1); /* It is safe to retry this operation */ |