summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/ata-dma.c
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2004-08-13 08:14:27 +0000
committersos <sos@FreeBSD.org>2004-08-13 08:14:27 +0000
commit6f119c28ba61f81a0e2ea748fc004d673774ff13 (patch)
tree1ac4d7a898e454167b2fcaa2c819798ddc954f8c /sys/dev/ata/ata-dma.c
parent482b6818afd4db4c0be3027d637df4d534bc9eee (diff)
downloadFreeBSD-src-6f119c28ba61f81a0e2ea748fc004d673774ff13.zip
FreeBSD-src-6f119c28ba61f81a0e2ea748fc004d673774ff13.tar.gz
Allow the use of a supplied function to set the PRD table. This is
needed for new chips that supports 64bit addressing.
Diffstat (limited to 'sys/dev/ata/ata-dma.c')
-rw-r--r--sys/dev/ata/ata-dma.c46
1 files changed, 15 insertions, 31 deletions
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 903dca1..cd719ee 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
/* prototypes */
static void ata_dmaalloc(struct ata_channel *);
static void ata_dmafree(struct ata_channel *);
-static void ata_dmasetupd_cb(void *, bus_dma_segment_t *, int, int);
+static void ata_dmasetprd(void *, bus_dma_segment_t *, int, int);
static int ata_dmaload(struct ata_device *, caddr_t, int32_t, int);
static int ata_dmaunload(struct ata_channel *);
@@ -57,7 +57,6 @@ static int ata_dmaunload(struct ata_channel *);
static MALLOC_DEFINE(M_ATADMA, "ATA DMA", "ATA driver DMA");
/* misc defines */
-#define MAXSEGSZ PAGE_SIZE
#define MAXTABSZ PAGE_SIZE
#define MAXWSPCSZ PAGE_SIZE
#define MAXCTLDMASZ (2 * (MAXTABSZ + MAXPHYS))
@@ -73,6 +72,7 @@ ata_dmainit(struct ata_channel *ch)
if ((ch->dma = malloc(sizeof(struct ata_dma), M_ATADMA, M_NOWAIT|M_ZERO))) {
ch->dma->alloc = ata_dmaalloc;
ch->dma->free = ata_dmafree;
+ ch->dma->setprd = ata_dmasetprd;
ch->dma->load = ata_dmaload;
ch->dma->unload = ata_dmaunload;
ch->dma->alignment = 2;
@@ -81,7 +81,6 @@ ata_dmainit(struct ata_channel *ch)
}
}
-
static void
ata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
{
@@ -195,45 +194,30 @@ ata_dmafree(struct ata_channel *ch)
}
}
-struct ata_dmasetup_data_cb_args {
- struct ata_dmaentry *dmatab;
- int error;
-};
-
static void
-ata_dmasetupd_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
+ata_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
{
- struct ata_dmasetup_data_cb_args *cba =
- (struct ata_dmasetup_data_cb_args *)xsc;
- bus_size_t cnt;
- u_int32_t lastcount;
- int i, j;
-
- cba->error = error;
- if (error != 0)
+ struct ata_dmasetprd_args *args = xsc;
+ struct ata_dma_prdentry *prd = args->dmatab;
+ int i;
+
+ if ((args->error = error))
return;
- lastcount = j = 0;
+
for (i = 0; i < nsegs; i++) {
- /*
- * A maximum segment size was specified for bus_dma_tag_create, but
- * some busdma code does not seem to honor this, so fix up if needed.
- */
- for (cnt = 0; cnt < segs[i].ds_len; cnt += MAXSEGSZ, j++) {
- cba->dmatab[j].base = htole32(segs[i].ds_addr + cnt);
- lastcount = ulmin(segs[i].ds_len - cnt, MAXSEGSZ) & 0xffff;
- cba->dmatab[j].count = htole32(lastcount);
- }
+ prd[i].addr = htole32(segs[i].ds_addr);
+ prd[i].count = htole32(segs[i].ds_len);
}
- cba->dmatab[j - 1].count = htole32(lastcount | ATA_DMA_EOT);
+ prd[i - 1].count |= htole32(ATA_DMA_EOT);
}
static int
ata_dmaload(struct ata_device *atadev, caddr_t data, int32_t count, int dir)
{
struct ata_channel *ch = atadev->channel;
- struct ata_dmasetup_data_cb_args cba;
+ struct ata_dmasetprd_args cba;
- if (ch->dma->flags & ATA_DMA_ACTIVE) {
+ if (ch->dma->flags & ATA_DMA_LOADED) {
ata_prtdev(atadev, "FAILURE - already active DMA on this device\n");
return -1;
}
@@ -258,7 +242,7 @@ ata_dmaload(struct ata_device *atadev, caddr_t data, int32_t count, int dir)
bus_dmamap_sync(ch->dma->cdmatag, ch->dma->cdmamap, BUS_DMASYNC_PREWRITE);
if (bus_dmamap_load(ch->dma->ddmatag, ch->dma->ddmamap, data, count,
- ata_dmasetupd_cb, &cba, 0) || cba.error)
+ ch->dma->setprd, &cba, 0) || cba.error)
return -1;
bus_dmamap_sync(ch->dma->ddmatag, ch->dma->ddmamap,
OpenPOWER on IntegriCloud