Fix several device freeze counting bugs.
This commit is contained in:
Alexander Motin 2009-11-14 20:13:38 +00:00
parent 49b96d25da
commit d84c90a6cb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=199279
3 changed files with 42 additions and 26 deletions

View File

@ -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);
}
}
}
/*

View File

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

View File

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