svn commit: r198321 - head/sys/dev/siis
Alexander Motin
mav at FreeBSD.org
Wed Oct 21 12:47:40 UTC 2009
Author: mav
Date: Wed Oct 21 12:47:39 2009
New Revision: 198321
URL: http://svn.freebsd.org/changeset/base/198321
Log:
MFp4:
Freeze device queue on error to permit periph driver to do proper recovery.
Modified:
head/sys/dev/siis/siis.c
Modified: head/sys/dev/siis/siis.c
==============================================================================
--- head/sys/dev/siis/siis.c Wed Oct 21 12:47:09 2009 (r198320)
+++ head/sys/dev/siis/siis.c Wed Oct 21 12:47:39 2009 (r198321)
@@ -752,7 +752,12 @@ siis_ch_intr(void *data)
if (ch->frozen) {
union ccb *fccb = ch->frozen;
ch->frozen = NULL;
- fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+ fccb->ccb_h.status &= ~CAM_STATUS_MASK;
+ fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+ if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
+ xpt_freeze_devq(fccb->ccb_h.path, 1);
+ fccb->ccb_h.status |= CAM_DEV_QFRZN;
+ }
xpt_done(fccb);
}
if (estatus == SIIS_P_CMDERR_DEV ||
@@ -986,7 +991,12 @@ device_printf(dev, "%s is %08x ss %08x r
if (ch->frozen) {
union ccb *fccb = ch->frozen;
ch->frozen = NULL;
- fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+ fccb->ccb_h.status &= ~CAM_STATUS_MASK;
+ fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+ if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
+ xpt_freeze_devq(fccb->ccb_h.path, 1);
+ fccb->ccb_h.status |= CAM_DEV_QFRZN;
+ }
xpt_done(fccb);
}
/* Handle command with timeout. */
@@ -1044,11 +1054,17 @@ siis_end_transaction(struct siis_slot *s
bus_dmamap_unload(ch->dma.data_tag, slot->dma.data_map);
}
/* Set proper result status. */
- ccb->ccb_h.status &= ~CAM_STATUS_MASK;
if (et != SIIS_ERR_NONE || ch->recovery) {
ch->eslots |= (1 << slot->slot);
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
}
+ /* In case of error, freeze device for proper recovery. */
+ if (et != SIIS_ERR_NONE &&
+ !(ccb->ccb_h.status & CAM_DEV_QFRZN)) {
+ xpt_freeze_devq(ccb->ccb_h.path, 1);
+ ccb->ccb_h.status |= CAM_DEV_QFRZN;
+ }
+ ccb->ccb_h.status &= ~CAM_STATUS_MASK;
switch (et) {
case SIIS_ERR_NONE:
ccb->ccb_h.status |= CAM_REQ_CMP;
@@ -1062,6 +1078,7 @@ siis_end_transaction(struct siis_slot *s
ccb->ccb_h.status |= CAM_REQUEUE_REQ;
break;
case SIIS_ERR_TFE:
+ case SIIS_ERR_NCQ:
if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
@@ -1075,9 +1092,6 @@ siis_end_transaction(struct siis_slot *s
case SIIS_ERR_TIMEOUT:
ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
break;
- case SIIS_ERR_NCQ:
- ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR;
- break;
default:
ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
}
@@ -1281,7 +1295,12 @@ siis_reset(device_t dev)
if (ch->frozen) {
union ccb *fccb = ch->frozen;
ch->frozen = NULL;
- fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+ fccb->ccb_h.status &= ~CAM_STATUS_MASK;
+ fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
+ if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
+ xpt_freeze_devq(fccb->ccb_h.path, 1);
+ fccb->ccb_h.status |= CAM_DEV_QFRZN;
+ }
xpt_done(fccb);
}
/* Disable port interrupts */
More information about the svn-src-all
mailing list