summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthomas <thomas@FreeBSD.org>2007-04-30 09:33:57 +0000
committerthomas <thomas@FreeBSD.org>2007-04-30 09:33:57 +0000
commit0660149596b7c7b0fb256d808586bea44cfecef2 (patch)
tree3c89a3975c0f12d4a328356d57a5469f7d83f8a0
parent334e2e141a4465d79d8ca95774e37453e5b7528d (diff)
downloadFreeBSD-src-0660149596b7c7b0fb256d808586bea44cfecef2.zip
FreeBSD-src-0660149596b7c7b0fb256d808586bea44cfecef2.tar.gz
(atapi_action, case XPT_SCSI_IO): Enable DMA only for READ and WRITE commands
as some combinations of chipset, controller and target do not behave correctly when DMA is enabled for other commands. PR: kern/103602 MFC after: 2 weeks
-rw-r--r--sys/dev/ata/atapi-cam.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c
index a6e580a..9391e73 100644
--- a/sys/dev/ata/atapi-cam.c
+++ b/sys/dev/ata/atapi-cam.c
@@ -516,10 +516,10 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
switch (ccb_h->flags & CAM_DIR_MASK) {
case CAM_DIR_IN:
- request_flags |= ATA_R_READ|ATA_R_DMA;
+ request_flags |= ATA_R_READ;
break;
case CAM_DIR_OUT:
- request_flags |= ATA_R_WRITE|ATA_R_DMA;
+ request_flags |= ATA_R_WRITE;
break;
case CAM_DIR_NONE:
/* No flags need to be set */
@@ -528,8 +528,6 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
device_printf(softc->dev, "unknown IO operation\n");
goto action_invalid;
}
- if (softc->atadev[tid]->mode < ATA_DMA)
- request_flags &= ~ATA_R_DMA;
if ((hcb = allocate_hcb(softc, unit, bus, ccb)) == NULL) {
printf("cannot allocate ATAPI/CAM hcb\n");
@@ -594,7 +592,24 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
request->u.atapi.ccb[3] = request->u.atapi.ccb[1] & 0x1f;
request->u.atapi.ccb[2] = 0;
request->u.atapi.ccb[1] = 0;
+ /* FALLTHROUGH */
+
+ case READ_10:
+ /* FALLTHROUGH */
+ case WRITE_10:
+ /* FALLTHROUGH */
+ case READ_12:
+ /* FALLTHROUGH */
+ case WRITE_12:
+ /*
+ * Enable DMA (if target supports it) for READ and WRITE commands
+ * only, as some combinations of drive, controller and chipset do
+ * not behave correctly when DMA is enabled for other commands.
+ */
+ if (softc->atadev[tid]->mode >= ATA_DMA)
+ request_flags |= ATA_R_DMA;
break;
+
}
if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_IN && (len & 1)) {
OpenPOWER on IntegriCloud