summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2013-02-22 21:43:21 +0000
committermav <mav@FreeBSD.org>2013-02-22 21:43:21 +0000
commit3c85c4e0a01f81b81007aca4f3ee4562755f34ba (patch)
tree822b420ebfe76cff86a96451536cbd010a4623b7
parent7df9c10e32d38c32b3d44b634f30395ae3860312 (diff)
downloadFreeBSD-src-3c85c4e0a01f81b81007aca4f3ee4562755f34ba.zip
FreeBSD-src-3c85c4e0a01f81b81007aca4f3ee4562755f34ba.tar.gz
Fix command timeout caused by data underrun during fetching ATAPI sense
data, introduced by r246713. There are two places where ata_request is filled in ATA_CAM: ata_cam_begin_transaction() and ata_cam_request_sense(). In the first case DMA should be done for addresses from the CCB. In second case, DMA should be done to the different address, the address of the sense buffer inside the CCB structure itself.
-rw-r--r--sys/dev/ata/ata-all.c1
-rw-r--r--sys/dev/ata/ata-all.h1
-rw-r--r--sys/dev/ata/ata-dma.c2
3 files changed, 3 insertions, 1 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 440db71..bfd49c7 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -1532,6 +1532,7 @@ ata_cam_begin_transaction(device_t dev, union ccb *ccb)
request->timeout = (ccb->ccb_h.timeout + 999) / 1000;
callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED);
request->ccb = ccb;
+ request->flags |= ATA_R_DATA_IN_CCB;
ch->running = request;
ch->state = ATA_ACTIVE;
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 28c93f9..be166df 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -398,6 +398,7 @@ struct ata_request {
#define ATA_R_THREAD 0x00000800
#define ATA_R_DIRECT 0x00001000
#define ATA_R_NEEDRESULT 0x00002000
+#define ATA_R_DATA_IN_CCB 0x00004000
#define ATA_R_ATAPI16 0x00010000
#define ATA_R_ATAPI_INTR 0x00020000
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 9aea845..5695bc8 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -305,7 +305,7 @@ ata_dmaload(struct ata_request *request, void *addr, int *entries)
dspa.dmatab = request->dma->sg;
#ifdef ATA_CAM
- if (request->ccb)
+ if (request->flags & ATA_R_DATA_IN_CCB)
error = bus_dmamap_load_ccb(request->dma->data_tag,
request->dma->data_map, request->ccb,
ch->dma.setprd, &dspa, BUS_DMA_NOWAIT);
OpenPOWER on IntegriCloud