From owner-p4-projects@FreeBSD.ORG Tue Oct 13 07:42:14 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B1D6F1065676; Tue, 13 Oct 2009 07:42:14 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 765661065670 for ; Tue, 13 Oct 2009 07:42:14 +0000 (UTC) (envelope-from mav@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 49D0D8FC12 for ; Tue, 13 Oct 2009 07:42:14 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n9D7gElE067209 for ; Tue, 13 Oct 2009 07:42:14 GMT (envelope-from mav@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n9D7gEpX067207 for perforce@freebsd.org; Tue, 13 Oct 2009 07:42:14 GMT (envelope-from mav@freebsd.org) Date: Tue, 13 Oct 2009 07:42:14 GMT Message-Id: <200910130742.n9D7gEpX067207@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mav@freebsd.org using -f From: Alexander Motin To: Perforce Change Reviews Cc: Subject: PERFORCE change 169445 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Oct 2009 07:42:14 -0000 http://perforce.freebsd.org/chv.cgi?CH=169445 Change 169445 by mav@mav_mavtest on 2009/10/13 07:42:01 Freeze devices CCB queues on errors. Previos approach with just SIM freeze is not enough for proper recovery, as it dropped just before recovery, not after, creating window for another request to run between. Affected files ... .. //depot/projects/scottl-camlock/src/sys/dev/siis/siis.c#8 edit Differences ... ==== //depot/projects/scottl-camlock/src/sys/dev/siis/siis.c#8 (text+ko) ==== @@ -752,7 +752,12 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 */