Date: Sat, 14 Nov 2009 20:13:38 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r199279 - in head/sys/cam: . scsi Message-ID: <200911142013.nAEKDcJt012198@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Sat Nov 14 20:13:38 2009 New Revision: 199279 URL: http://svn.freebsd.org/changeset/base/199279 Log: MFp4: Fix several device freeze counting bugs. Modified: head/sys/cam/cam_periph.c head/sys/cam/scsi/scsi_cd.c head/sys/cam/scsi/scsi_ch.c Modified: head/sys/cam/cam_periph.c ============================================================================== --- head/sys/cam/cam_periph.c Sat Nov 14 20:06:04 2009 (r199278) +++ head/sys/cam/cam_periph.c Sat Nov 14 20:13:38 2009 (r199279) @@ -981,16 +981,21 @@ camperiphdone(struct cam_periph *periph, { 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, 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, */ 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); + } + } } /* Modified: head/sys/cam/scsi/scsi_cd.c ============================================================================== --- head/sys/cam/scsi/scsi_cd.c Sat Nov 14 20:06:04 2009 (r199278) +++ head/sys/cam/scsi/scsi_cd.c Sat Nov 14 20:13:38 2009 (r199279) @@ -1570,7 +1570,8 @@ cddone(struct cam_periph *periph, union 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 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, Modified: head/sys/cam/scsi/scsi_ch.c ============================================================================== --- head/sys/cam/scsi/scsi_ch.c Sat Nov 14 20:06:04 2009 (r199278) +++ head/sys/cam/scsi/scsi_ch.c Sat Nov 14 20:13:38 2009 (r199279) @@ -606,7 +606,8 @@ chdone(struct cam_periph *periph, union 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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911142013.nAEKDcJt012198>