From owner-svn-src-stable-8@FreeBSD.ORG Tue Apr 19 17:01:06 2011 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 16A07106564A; Tue, 19 Apr 2011 17:01:06 +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 03F1B8FC0A; Tue, 19 Apr 2011 17:01:06 +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 p3JH15OX015563; Tue, 19 Apr 2011 17:01:05 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p3JH15sw015560; Tue, 19 Apr 2011 17:01:05 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201104191701.p3JH15sw015560@svn.freebsd.org> From: Alexander Motin Date: Tue, 19 Apr 2011 17:01:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r220855 - stable/8/sys/dev/ata X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Apr 2011 17:01:06 -0000 Author: mav Date: Tue Apr 19 17:01:05 2011 New Revision: 220855 URL: http://svn.freebsd.org/changeset/base/220855 Log: MFC r220563: Implement automatic SCSI sense fetching for ata(4) in ATA_CAM mode. Modified: stable/8/sys/dev/ata/ata-all.c stable/8/sys/dev/ata/ata-all.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/dev/ata/ata-all.c ============================================================================== --- stable/8/sys/dev/ata/ata-all.c Tue Apr 19 16:52:36 2011 (r220854) +++ stable/8/sys/dev/ata/ata-all.c Tue Apr 19 17:01:05 2011 (r220855) @@ -1474,6 +1474,72 @@ ata_cam_begin_transaction(device_t dev, } } +static void +ata_cam_request_sense(device_t dev, struct ata_request *request) +{ + struct ata_channel *ch = device_get_softc(dev); + union ccb *ccb = request->ccb; + + ch->requestsense = 1; + + bzero(request, sizeof(&request)); + request->dev = NULL; + request->parent = dev; + request->unit = ccb->ccb_h.target_id; + request->data = (void *)&ccb->csio.sense_data; + request->bytecount = ccb->csio.sense_len; + request->u.atapi.ccb[0] = ATAPI_REQUEST_SENSE; + request->u.atapi.ccb[4] = ccb->csio.sense_len; + request->flags |= ATA_R_ATAPI; + if (ch->curr[ccb->ccb_h.target_id].atapi == 16) + request->flags |= ATA_R_ATAPI16; + if (ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA) + request->flags |= ATA_R_DMA; + request->flags |= ATA_R_READ; + request->transfersize = min(request->bytecount, + ch->curr[ccb->ccb_h.target_id].bytecount); + request->retries = 0; + request->timeout = (ccb->ccb_h.timeout + 999) / 1000; + callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED); + request->ccb = ccb; + + ch->running = request; + ch->state = ATA_ACTIVE; + if (ch->hw.begin_transaction(request) == ATA_OP_FINISHED) { + ch->running = NULL; + ch->state = ATA_IDLE; + ata_cam_end_transaction(dev, request); + return; + } +} + +static void +ata_cam_process_sense(device_t dev, struct ata_request *request) +{ + struct ata_channel *ch = device_get_softc(dev); + union ccb *ccb = request->ccb; + int fatalerr = 0; + + ch->requestsense = 0; + + if (request->flags & ATA_R_TIMEOUT) + fatalerr = 1; + if ((request->flags & ATA_R_TIMEOUT) == 0 && + (request->status & ATA_S_ERROR) == 0 && + request->result == 0) { + ccb->ccb_h.status |= CAM_AUTOSNS_VALID; + } else { + ccb->ccb_h.status &= ~CAM_STATUS_MASK; + ccb->ccb_h.status |= CAM_AUTOSENSE_FAIL; + } + + ata_free_request(request); + xpt_done(ccb); + /* Do error recovery if needed. */ + if (fatalerr) + ata_reinit(dev); +} + void ata_cam_end_transaction(device_t dev, struct ata_request *request) { @@ -1481,6 +1547,11 @@ ata_cam_end_transaction(device_t dev, st union ccb *ccb = request->ccb; int fatalerr = 0; + if (ch->requestsense) { + ata_cam_process_sense(dev, request); + return; + } + ccb->ccb_h.status &= ~CAM_STATUS_MASK; if (request->flags & ATA_R_TIMEOUT) { xpt_freeze_simq(ch->sim, 1); @@ -1530,8 +1601,13 @@ ata_cam_end_transaction(device_t dev, st ccb->csio.dxfer_len - request->donecount; } } - ata_free_request(request); - xpt_done(ccb); + if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR && + (ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) + ata_cam_request_sense(dev, request); + else { + ata_free_request(request); + xpt_done(ccb); + } /* Do error recovery if needed. */ if (fatalerr) ata_reinit(dev); Modified: stable/8/sys/dev/ata/ata-all.h ============================================================================== --- stable/8/sys/dev/ata/ata-all.h Tue Apr 19 16:52:36 2011 (r220854) +++ stable/8/sys/dev/ata/ata-all.h Tue Apr 19 17:01:05 2011 (r220855) @@ -585,8 +585,9 @@ struct ata_channel { #ifdef ATA_CAM struct cam_sim *sim; struct cam_path *path; - struct ata_cam_device user[16]; /* User-specified settings */ - struct ata_cam_device curr[16]; /* Current settings */ + struct ata_cam_device user[16]; /* User-specified settings */ + struct ata_cam_device curr[16]; /* Current settings */ + int requestsense; /* CCB waiting for SENSE. */ #endif struct callout poll_callout; /* Periodic status poll. */ };