From owner-svn-src-head@FreeBSD.ORG Wed Oct 21 12:47:40 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 44D7C106568B; Wed, 21 Oct 2009 12:47:40 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 299268FC1A; Wed, 21 Oct 2009 12:47:40 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n9LCleMd099478; Wed, 21 Oct 2009 12:47:40 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n9LCleHj099476; Wed, 21 Oct 2009 12:47:40 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <200910211247.n9LCleHj099476@svn.freebsd.org> From: Alexander Motin Date: Wed, 21 Oct 2009 12:47:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r198321 - head/sys/dev/siis X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Oct 2009 12:47:40 -0000 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 */