svn commit: r220855 - stable/8/sys/dev/ata
Alexander Motin
mav at FreeBSD.org
Tue Apr 19 17:01:06 UTC 2011
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. */
};
More information about the svn-src-stable
mailing list