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:
parent
db72e05829
commit
50711c71c9
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user