summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2011-04-20 13:27:50 +0000
committermav <mav@FreeBSD.org>2011-04-20 13:27:50 +0000
commit20478cf0e9f9b9835817a0895234f8e47460d9e7 (patch)
tree8de9ce678c02934bf00cbff6baec9b3ea9af4530 /sys/cam
parent2542a7137fee4edaf21da449b1716abb01a1846d (diff)
downloadFreeBSD-src-20478cf0e9f9b9835817a0895234f8e47460d9e7.zip
FreeBSD-src-20478cf0e9f9b9835817a0895234f8e47460d9e7.tar.gz
Add basic support for DMA-capable ATA disks on DMA-incapable controller.
This is really rare situation these days, but still may happen in embedded.
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ata/ata_all.h2
-rw-r--r--sys/cam/ata/ata_da.c5
-rw-r--r--sys/cam/ata/ata_xpt.c5
3 files changed, 10 insertions, 2 deletions
diff --git a/sys/cam/ata/ata_all.h b/sys/cam/ata/ata_all.h
index 2e838fd..526fc19 100644
--- a/sys/cam/ata/ata_all.h
+++ b/sys/cam/ata/ata_all.h
@@ -35,6 +35,8 @@ struct ccb_ataio;
struct cam_periph;
union ccb;
+#define SID_DMA 0x10 /* Abuse inq_flags bit to track enabled DMA. */
+
struct ata_cmd {
u_int8_t flags; /* ATA command flags */
#define CAM_ATAIO_48BIT 0x01 /* Command has 48-bit format */
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 0c1a6f7..0e8b273 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -751,7 +751,8 @@ adaregister(struct cam_periph *periph, void *arg)
bioq_init(&softc->bio_queue);
bioq_init(&softc->trim_queue);
- if (cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA)
+ if (cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA &&
+ (cgd->inq_flags & SID_DMA))
softc->flags |= ADA_FLAG_CAN_DMA;
if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48)
softc->flags |= ADA_FLAG_CAN_48BIT;
@@ -760,7 +761,7 @@ adaregister(struct cam_periph *periph, void *arg)
if (cgd->ident_data.support.command1 & ATA_SUPPORT_POWERMGT)
softc->flags |= ADA_FLAG_CAN_POWERMGT;
if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ &&
- cgd->inq_flags & SID_CmdQue)
+ (cgd->inq_flags & SID_DMA) && (cgd->inq_flags & SID_CmdQue))
softc->flags |= ADA_FLAG_CAN_NCQ;
if (cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) {
softc->flags |= ADA_FLAG_CAN_TRIM;
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index b836485..9e236a4 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -388,6 +388,11 @@ negotiate:
/* If SIM disagree - renegotiate. */
if (mode != wantmode)
goto negotiate;
+ /* Remember what transport thinks about DMA. */
+ if (mode < ATA_DMA)
+ path->device->inq_flags &= ~SID_DMA;
+ else
+ path->device->inq_flags |= SID_DMA;
cam_fill_ataio(ataio,
1,
probedone,
OpenPOWER on IntegriCloud