summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/ata-dma.c
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2004-04-13 09:44:20 +0000
committersos <sos@FreeBSD.org>2004-04-13 09:44:20 +0000
commitcc41608d4e67f6e2919d309171c9b38962c9a12c (patch)
tree509ff87c6422cd772b614eb0062b3b035846ddf6 /sys/dev/ata/ata-dma.c
parentcd7289137550ab613eca97a70cb90837c0842873 (diff)
downloadFreeBSD-src-cc41608d4e67f6e2919d309171c9b38962c9a12c.zip
FreeBSD-src-cc41608d4e67f6e2919d309171c9b38962c9a12c.tar.gz
Add support for the Promise command sequencer present on all modern Promise
controllers (PDC203** PDC206**). This also adds preliminary support for the Promise SX4/SX4000 but *only* as a "normal" Promise ATA controller (ATA RAID's are supported though but only RAID0, RAID1 and RAID0+1). This cuts off yet another 5-8% of the command overhead on promise controllers, making them the fastest we have ever had support for. Work is now continuing to add support for this in ATA RAID, to accellerate ATA RAID quite a bit on these controllers, and especially the SX4/SX4000 series as they have quite a few tricks in there.. This commit also adds a few fixes to the SATA code needed for proper support.
Diffstat (limited to 'sys/dev/ata/ata-dma.c')
-rw-r--r--sys/dev/ata/ata-dma.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 26e9c2d..d140d7d 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -59,6 +59,7 @@ static MALLOC_DEFINE(M_ATADMA, "ATA DMA", "ATA driver DMA");
/* misc defines */
#define MAXSEGSZ PAGE_SIZE
#define MAXTABSZ PAGE_SIZE
+#define MAXWSPCSZ 256
#define MAXCTLDMASZ (2 * (MAXTABSZ + MAXPHYS))
struct ata_dc_cb_args {
@@ -121,16 +122,35 @@ ata_dmaalloc(struct ata_channel *ch)
if (bus_dmamap_load(ch->dma->cdmatag, ch->dma->cdmamap, ch->dma->dmatab,
MAXTABSZ, ata_dmasetupc_cb, &ccba, 0) || ccba.error) {
- bus_dmamem_free(ch->dma->cdmatag, ch->dma->dmatab,ch->dma->cdmamap);
+ bus_dmamem_free(ch->dma->cdmatag, ch->dma->dmatab, ch->dma->cdmamap);
goto error;
}
ch->dma->mdmatab = ccba.maddr;
+
if (bus_dmamap_create(ch->dma->ddmatag, 0, &ch->dma->ddmamap))
goto error;
+
+ if (bus_dma_tag_create(ch->dma->dmatag, PAGE_SIZE, PAGE_SIZE,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
+ NULL, NULL, MAXWSPCSZ, 1, MAXWSPCSZ,
+ BUS_DMA_ALLOCNOW, NULL, NULL, &ch->dma->wdmatag))
+ goto error;
+
+ if (bus_dmamem_alloc(ch->dma->wdmatag, (void **)&ch->dma->workspace, 0,
+ &ch->dma->wdmamap))
+ goto error;
+
+ if (bus_dmamap_load(ch->dma->wdmatag, ch->dma->wdmamap, ch->dma->workspace,
+ MAXWSPCSZ, ata_dmasetupc_cb, &ccba, 0) || ccba.error) {
+ bus_dmamem_free(ch->dma->wdmatag, ch->dma->workspace, ch->dma->wdmamap);
+ goto error;
+ }
+ ch->dma->wdmatab = ccba.maddr;
+
return;
error:
- ata_printf(ch, -1, "WARNING - DMA tag allocation failed, disabling DMA\n");
+ ata_printf(ch, -1, "WARNING - DMA allocation failed, disabling DMA\n");
ata_dmafree(ch);
free(ch->dma, M_ATADMA);
ch->dma = NULL;
@@ -139,6 +159,17 @@ error:
static void
ata_dmafree(struct ata_channel *ch)
{
+ if (ch->dma->wdmatab) {
+ bus_dmamap_unload(ch->dma->wdmatag, ch->dma->wdmamap);
+ bus_dmamem_free(ch->dma->wdmatag, ch->dma->workspace, ch->dma->wdmamap);
+ ch->dma->wdmatab = 0;
+ ch->dma->wdmamap = NULL;
+ ch->dma->workspace = NULL;
+ }
+ if (ch->dma->wdmatag) {
+ bus_dma_tag_destroy(ch->dma->wdmatag);
+ ch->dma->wdmatag = NULL;
+ }
if (ch->dma->mdmatab) {
bus_dmamap_unload(ch->dma->cdmatag, ch->dma->cdmamap);
bus_dmamem_free(ch->dma->cdmatag, ch->dma->dmatab, ch->dma->cdmamap);
OpenPOWER on IntegriCloud