MFp4:
Fix several device freeze counting bugs.
This commit is contained in:
parent
49b96d25da
commit
d84c90a6cb
@ -981,16 +981,21 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
{
|
||||
union ccb *saved_ccb;
|
||||
cam_status status;
|
||||
int frozen;
|
||||
int frozen = 0;
|
||||
int sense;
|
||||
struct scsi_start_stop_unit *scsi_cmd;
|
||||
u_int32_t relsim_flags, timeout;
|
||||
u_int32_t qfrozen_cnt;
|
||||
int xpt_done_ccb;
|
||||
int xpt_done_ccb = FALSE;
|
||||
|
||||
xpt_done_ccb = FALSE;
|
||||
status = done_ccb->ccb_h.status;
|
||||
frozen = (status & CAM_DEV_QFRZN) != 0;
|
||||
if (status & CAM_DEV_QFRZN) {
|
||||
frozen = 1;
|
||||
/*
|
||||
* Clear freeze flag now for case of retry,
|
||||
* freeze will be dropped later.
|
||||
*/
|
||||
done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
|
||||
}
|
||||
sense = (status & CAM_AUTOSNS_VALID) != 0;
|
||||
status &= CAM_STATUS_MASK;
|
||||
|
||||
@ -998,17 +1003,6 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
relsim_flags = 0;
|
||||
saved_ccb = (union ccb *)done_ccb->ccb_h.saved_ccb_ptr;
|
||||
|
||||
/*
|
||||
* Unfreeze the queue once if it is already frozen..
|
||||
*/
|
||||
if (frozen != 0) {
|
||||
qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path,
|
||||
/*relsim_flags*/0,
|
||||
/*openings*/0,
|
||||
/*timeout*/0,
|
||||
/*getcount_only*/0);
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case CAM_REQ_CMP:
|
||||
{
|
||||
@ -1185,14 +1179,33 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
*/
|
||||
if (done_ccb->ccb_h.retry_count > 0)
|
||||
done_ccb->ccb_h.retry_count--;
|
||||
|
||||
qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path,
|
||||
/*relsim_flags*/relsim_flags,
|
||||
/*openings*/0,
|
||||
/*timeout*/timeout,
|
||||
/*getcount_only*/0);
|
||||
if (xpt_done_ccb == TRUE)
|
||||
/*
|
||||
* Drop freeze taken due to CAM_DEV_QFREEZE flag set on recovery
|
||||
* request.
|
||||
*/
|
||||
cam_release_devq(done_ccb->ccb_h.path,
|
||||
/*relsim_flags*/relsim_flags,
|
||||
/*openings*/0,
|
||||
/*timeout*/timeout,
|
||||
/*getcount_only*/0);
|
||||
if (xpt_done_ccb == TRUE) {
|
||||
/*
|
||||
* Copy frozen flag from recovery request if it is set there
|
||||
* for some reason.
|
||||
*/
|
||||
if (frozen != 0)
|
||||
done_ccb->ccb_h.status |= CAM_DEV_QFRZN;
|
||||
(*done_ccb->ccb_h.cbfcnp)(periph, done_ccb);
|
||||
} else {
|
||||
/* Drop freeze taken, if this recovery request got error. */
|
||||
if (frozen != 0) {
|
||||
cam_release_devq(done_ccb->ccb_h.path,
|
||||
/*relsim_flags*/0,
|
||||
/*openings*/0,
|
||||
/*timeout*/0,
|
||||
/*getcount_only*/0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1570,7 +1570,8 @@ cddone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
bp->bio_resid = bp->bio_bcount;
|
||||
bp->bio_error = error;
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
cam_release_devq(done_ccb->ccb_h.path,
|
||||
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
||||
cam_release_devq(done_ccb->ccb_h.path,
|
||||
/*relsim_flags*/0,
|
||||
/*reduction*/0,
|
||||
/*timeout*/0,
|
||||
@ -1658,7 +1659,8 @@ cddone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
struct ccb_getdev cgd;
|
||||
|
||||
/* Don't wedge this device's queue */
|
||||
cam_release_devq(done_ccb->ccb_h.path,
|
||||
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
||||
cam_release_devq(done_ccb->ccb_h.path,
|
||||
/*relsim_flags*/0,
|
||||
/*reduction*/0,
|
||||
/*timeout*/0,
|
||||
|
@ -606,7 +606,8 @@ chdone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
retry_scheduled = 0;
|
||||
|
||||
/* Don't wedge this device's queue */
|
||||
cam_release_devq(done_ccb->ccb_h.path,
|
||||
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
||||
cam_release_devq(done_ccb->ccb_h.path,
|
||||
/*relsim_flags*/0,
|
||||
/*reduction*/0,
|
||||
/*timeout*/0,
|
||||
|
Loading…
x
Reference in New Issue
Block a user