Date: Wed, 21 Oct 2009 12:47:40 +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: r198321 - head/sys/dev/siis Message-ID: <200910211247.n9LCleHj099476@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910211247.n9LCleHj099476>