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
This commit is contained in:
Kenneth D. Merry 1999-05-09 01:25:34 +00:00
parent db72e05829
commit 50711c71c9
8 changed files with 76 additions and 42 deletions

View File

@ -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:

View File

@ -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,

View File

@ -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);

View File

@ -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 {
/*

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 */