diff options
| author | Luoqi Chen <luoqi@FreeBSD.org> | 2003-09-05 07:29:10 +0000 |
|---|---|---|
| committer | Luoqi Chen <luoqi@FreeBSD.org> | 2003-09-05 07:29:10 +0000 |
| commit | e15f945effd4fe56ef9e394dca79ecbd88c4acdc (patch) | |
| tree | c08df99355bad991047ae145eb2911b9eb9f0c84 /sys/dev/ata | |
| parent | 55f2eed34626b4488ac113dfd5d09972d5bc0520 (diff) | |
Notes
Diffstat (limited to 'sys/dev/ata')
| -rw-r--r-- | sys/dev/ata/ata-all.c | 3 | ||||
| -rw-r--r-- | sys/dev/ata/ata-all.h | 26 | ||||
| -rw-r--r-- | sys/dev/ata/ata-disk.c | 43 | ||||
| -rw-r--r-- | sys/dev/ata/ata-disk.h | 1 | ||||
| -rw-r--r-- | sys/dev/ata/ata-dma.c | 637 | ||||
| -rw-r--r-- | sys/dev/ata/ata-isa.c | 27 | ||||
| -rw-r--r-- | sys/dev/ata/atapi-all.c | 33 | ||||
| -rw-r--r-- | sys/dev/ata/atapi-all.h | 1 | ||||
| -rw-r--r-- | sys/dev/ata/atapi-cd.c | 1 | ||||
| -rw-r--r-- | sys/dev/ata/atapi-fd.c | 1 | ||||
| -rw-r--r-- | sys/dev/ata/atapi-tape.c | 1 |
11 files changed, 479 insertions, 295 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 207c555be2aa..4dcae36b27b5 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -271,6 +271,7 @@ ata_detach(device_t dev) ch->device[MASTER].mode = ATA_PIO; ch->device[SLAVE].mode = ATA_PIO; ch->devices = 0; + ata_dmafreetags(ch); bus_teardown_intr(dev, ch->r_irq, ch->ih); bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); @@ -1350,7 +1351,7 @@ ata_change_mode(struct ata_device *atadev, int mode) } ATA_SLEEPLOCK_CH(atadev->channel, ATA_ACTIVE); - ata_dmainit(atadev->channel, atadev->unit, pmode, wmode, umode); + ata_dmainit(atadev, pmode, wmode, umode); ATA_UNLOCK_CH(atadev->channel); ata_start(atadev->channel); /* XXX SOS */ } diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index e6bd48118e7d..18fdbe0fea4c 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -158,6 +158,18 @@ struct ata_dmaentry { u_int32_t count; }; +struct ata_dmastate { + bus_dma_tag_t ddmatag; /* data DMA tag */ + bus_dmamap_t ddmamap; /* data DMA map */ + bus_dma_tag_t cdmatag; /* control DMA tag */ + bus_dmamap_t cdmamap; /* control DMA map */ + struct ata_dmaentry *dmatab; /* DMA transfer table */ + bus_addr_t mdmatab; /* bus address of dmatab */ + int flags; /* debugging */ +#define ATA_DS_ACTIVE 0x01 /* debugging */ +#define ATA_DS_READ 0x02 /* transaction is a read */ +}; + /* structure describing an ATA/ATAPI device */ struct ata_device { struct ata_channel *channel; @@ -177,6 +189,7 @@ struct ata_device { int mode; /* transfermode */ int cmd; /* last cmd executed */ void *result; /* misc data */ + struct ata_dmastate dmastate; /* dma state */ }; /* structure describing an ATA channel */ @@ -186,6 +199,7 @@ struct ata_channel { struct resource *r_io; /* io addr resource handle */ struct resource *r_altio; /* altio addr resource handle */ struct resource *r_bmio; /* bmio addr resource handle */ + bus_dma_tag_t dmatag; /* parent dma tag */ struct resource *r_irq; /* interrupt of this channel */ void *ih; /* interrupt handle */ int (*intr_func)(struct ata_channel *); /* interrupt function */ @@ -262,12 +276,14 @@ int ata_wmode(struct ata_params *); int ata_umode(struct ata_params *); int ata_find_dev(device_t, u_int32_t, u_int32_t); -void *ata_dmaalloc(struct ata_channel *, int); -void ata_dmainit(struct ata_channel *, int, int, int, int); -int ata_dmasetup(struct ata_channel *, int, struct ata_dmaentry *, caddr_t, int); -void ata_dmastart(struct ata_channel *, int, struct ata_dmaentry *, int); +int ata_dmaalloc(struct ata_device *); +void ata_dmafree(struct ata_device *); +void ata_dmafreetags(struct ata_channel *); +void ata_dmainit(struct ata_device *, int, int, int); +int ata_dmasetup(struct ata_device *, caddr_t, int32_t); +int ata_dmastart(struct ata_device *, caddr_t, int32_t, int); int ata_dmastatus(struct ata_channel *); -int ata_dmadone(struct ata_channel *); +int ata_dmadone(struct ata_device *); /* macros for locking a channel */ #define ATA_LOCK_CH(ch, value)\ diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index 0ff8801ffe35..1a99e19c5379 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -171,11 +171,10 @@ ad_attach(struct ata_device *atadev) /* use DMA if allowed and if drive/controller supports it */ if (ata_dma) - ata_dmainit(atadev->channel, atadev->unit, ata_pmode(atadev->param), + ata_dmainit(atadev, ata_pmode(atadev->param), ata_wmode(atadev->param), ata_umode(atadev->param)); else - ata_dmainit(atadev->channel, atadev->unit, - ata_pmode(atadev->param), -1, -1); + ata_dmainit(atadev, ata_pmode(atadev->param), -1, -1); /* use tagged queueing if allowed and supported */ if (ata_tags && ad_tagsupported(adp)) { @@ -244,6 +243,7 @@ ad_detach(struct ata_device *atadev, int flush) /* get rid of flush XXX SOS */ biodone(request->bp); ad_free(request); } + ata_dmafree(atadev); while ((bp = bufq_first(&adp->queue))) { bufq_remove(&adp->queue, bp); bp->b_error = ENXIO; @@ -407,7 +407,7 @@ ad_start(struct ata_device *atadev) if (bp->b_flags & B_READ) request->flags |= ADR_F_READ; if (adp->device->mode >= ATA_DMA) { - if (!(request->dmatab = ata_dmaalloc(atadev->channel, atadev->unit))) + if (ata_dmaalloc(atadev)) adp->device->mode = ATA_PIO; } @@ -471,8 +471,7 @@ ad_transfer(struct ad_request *request) /* does this drive & transfer work with DMA ? */ request->flags &= ~ADR_F_DMA_USED; if (adp->device->mode >= ATA_DMA && - !ata_dmasetup(adp->device->channel, adp->device->unit, - request->dmatab, request->data, request->bytecount)) { + !ata_dmasetup(adp->device, request->data, request->bytecount)) { request->flags |= ADR_F_DMA_USED; request->currentsize = request->bytecount; @@ -521,8 +520,8 @@ ad_transfer(struct ad_request *request) } /* start transfer, return and wait for interrupt */ - ata_dmastart(adp->device->channel, adp->device->unit, - request->dmatab, request->flags & ADR_F_READ); + ata_dmastart(adp->device, request->data, request->bytecount, + request->flags & ADR_F_READ); return ATA_OP_CONTINUES; } @@ -593,7 +592,7 @@ ad_interrupt(struct ad_request *request) /* finish DMA transfer */ if (request->flags & ADR_F_DMA_USED) - dma_stat = ata_dmadone(adp->device->channel); + dma_stat = ata_dmadone(adp->device); /* do we have a corrected soft error ? */ if (adp->device->channel->status & ATA_S_CORR) @@ -620,8 +619,7 @@ ad_interrupt(struct ad_request *request) if (request->retries++ < AD_MAX_RETRIES) printf(" retrying\n"); else { - ata_dmainit(adp->device->channel, adp->device->unit, - ata_pmode(adp->device->param), -1, -1); + ata_dmainit(adp->device, ata_pmode(adp->device->param), -1, -1); printf(" falling back to PIO mode\n"); } TAILQ_INSERT_HEAD(&adp->device->channel->ata_queue, request, chain); @@ -632,8 +630,7 @@ ad_interrupt(struct ad_request *request) if (request->flags & ADR_F_DMA_USED) { untimeout((timeout_t *)ad_timeout, request,request->timeout_handle); ad_invalidatequeue(adp, request); - ata_dmainit(adp->device->channel, adp->device->unit, - ata_pmode(adp->device->param), -1, -1); + ata_dmainit(adp->device, ata_pmode(adp->device->param), -1, -1); request->flags |= ADR_F_FORCE_PIO; printf(" trying PIO mode\n"); TAILQ_INSERT_HEAD(&adp->device->channel->ata_queue, request, chain); @@ -786,8 +783,8 @@ ad_service(struct ad_softc *adp, int change) ad_invalidatequeue(adp, NULL); return ATA_OP_FINISHED; } - ata_dmastart(adp->device->channel, adp->device->unit, - request->dmatab, request->flags & ADR_F_READ); + ata_dmastart(adp->device, request->data, request->bytecount, + request->flags & ADR_F_READ); return ATA_OP_CONTINUES; } return ATA_OP_FINISHED; @@ -796,13 +793,8 @@ ad_service(struct ad_softc *adp, int change) static void ad_free(struct ad_request *request) { - int s = splbio(); - - if (request->dmatab) - free(request->dmatab, M_DEVBUF); request->softc->tags[request->tag] = NULL; free(request, M_AD); - splx(s); } static void @@ -875,11 +867,10 @@ ad_timeout(struct ad_request *request) request->tag, request->serv); if (request->flags & ADR_F_DMA_USED) { - ata_dmadone(adp->device->channel); + ata_dmadone(adp->device); ad_invalidatequeue(adp, request); if (request->retries == AD_MAX_RETRIES) { - ata_dmainit(adp->device->channel, adp->device->unit, - ata_pmode(adp->device->param), -1, -1); + ata_dmainit(adp->device, ata_pmode(adp->device->param), -1, -1); ata_prtdev(adp->device, "trying fallback to PIO mode\n"); request->retries = 0; } @@ -910,13 +901,11 @@ ad_reinit(struct ata_device *atadev) ata_command(atadev, ATA_C_SET_MULTI, 0, adp->transfersize / DEV_BSIZE, 0, ATA_WAIT_READY); if (adp->device->mode >= ATA_DMA) - ata_dmainit(atadev->channel, atadev->unit, - ata_pmode(adp->device->param), + ata_dmainit(atadev, ata_pmode(adp->device->param), ata_wmode(adp->device->param), ata_umode(adp->device->param)); else - ata_dmainit(atadev->channel, atadev->unit, - ata_pmode(adp->device->param), -1, -1); + ata_dmainit(atadev, ata_pmode(adp->device->param), -1, -1); } void diff --git a/sys/dev/ata/ata-disk.h b/sys/dev/ata/ata-disk.h index 698edb6500cb..36a3ad9383c5 100644 --- a/sys/dev/ata/ata-disk.h +++ b/sys/dev/ata/ata-disk.h @@ -48,7 +48,6 @@ struct ad_request { struct buf *bp; /* associated bio ptr */ u_int8_t tag; /* tag ID of this request */ int serv; /* request had service */ - struct ata_dmaentry *dmatab; /* DMA transfer table */ TAILQ_ENTRY(ad_request) chain; /* list management */ }; diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index cc6f9c43cd64..cae80345033c 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -35,81 +35,186 @@ #include <sys/malloc.h> #include <sys/bus.h> #include <sys/disk.h> +#include <sys/endian.h> #include <sys/devicestat.h> -#include <vm/vm.h> -#include <vm/pmap.h> #include <pci/pcivar.h> #include <machine/bus.h> #include <sys/rman.h> #include <dev/ata/ata-all.h> /* prototypes */ -static void cyrix_timing(struct ata_channel *, int, int); -static void promise_timing(struct ata_channel *, int, int); -static void hpt_timing(struct ata_channel *, int, int); -static int hpt_cable80(struct ata_channel *); +static void ata_dmacreate(struct ata_device *, int, int); +static void ata_dmasetupd_cb(void *, bus_dma_segment_t *, int, int); +static void ata_dmasetupc_cb(void *, bus_dma_segment_t *, int, int); +static void cyrix_timing(struct ata_device *, int, int); +static void promise_timing(struct ata_device *, int, int); +static void hpt_timing(struct ata_device *, int, int); +static int hpt_cable80(struct ata_device *); /* misc defines */ -#ifdef __alpha__ -#undef vtophys -#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) -#endif -#define ATAPI_DEVICE(ch, device) \ - ((device == ATA_MASTER && ch->devices & ATA_ATAPI_MASTER) || \ - (device == ATA_SLAVE && ch->devices & ATA_ATAPI_SLAVE)) +#define ATAPI_DEVICE(atadev) \ + ((atadev->unit == ATA_MASTER && \ + atadev->channel->devices & ATA_ATAPI_MASTER) || \ + (atadev->unit == ATA_SLAVE && \ + atadev->channel->devices & ATA_ATAPI_SLAVE)) + +#define MAXSEGSZ PAGE_SIZE +#define MAXTABSZ PAGE_SIZE +#define MAXCTLDMASZ (2 * (MAXTABSZ + MAXPHYS)) + +struct ata_dc_cb_args { + bus_addr_t maddr; + int error; +}; + +static void +ata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) +{ + struct ata_dc_cb_args *cba = (struct ata_dc_cb_args *)xsc; + + if (!(cba->error = error)) + cba->maddr = segs[0].ds_addr; +} + +int +ata_dmaalloc(struct ata_device *atadev) +{ + struct ata_channel *ch; + struct ata_dc_cb_args ccba; + struct ata_dmastate *ds; + int error; + + ch = atadev->channel; + ds = &atadev->dmastate; + if (!ds->cdmatag) { + if ((error = bus_dma_tag_create(ch->dmatag, 1, PAGE_SIZE, + BUS_SPACE_MAXADDR_32BIT, + BUS_SPACE_MAXADDR, NULL, NULL, + MAXTABSZ, 1, MAXTABSZ, + BUS_DMA_ALLOCNOW, &ds->cdmatag))) + return error; + } + if (!ds->ddmatag) { + if ((error = bus_dma_tag_create(ch->dmatag, ch->alignment + 1, 0, + BUS_SPACE_MAXADDR_32BIT, + BUS_SPACE_MAXADDR, NULL, NULL, + MAXPHYS, ATA_DMA_ENTRIES, MAXSEGSZ, + BUS_DMA_ALLOCNOW, &ds->ddmatag))) + return error; + } + if (!ds->mdmatab) { + if ((error = bus_dmamem_alloc(ds->cdmatag, (void **)&ds->dmatab, 0, + &ds->cdmamap))) + return error; + + if ((error = bus_dmamap_load(ds->cdmatag, ds->cdmamap, ds->dmatab, + MAXTABSZ, ata_dmasetupc_cb, &ccba, + 0)) != 0 || ccba.error != 0) { + bus_dmamem_free(ds->cdmatag, ds->dmatab, ds->cdmamap); + return error; + } + ds->mdmatab = ccba.maddr; + } + if (!ds->ddmamap) { + if ((error = bus_dmamap_create(ds->ddmatag, 0, &ds->ddmamap)) != 0) + return error; + } + return 0; +} + +void +ata_dmafree(struct ata_device *atadev) +{ + struct ata_dmastate *ds; + + ds = &atadev->dmastate; + if (ds->mdmatab) { + bus_dmamap_unload(ds->cdmatag, ds->cdmamap); + bus_dmamem_free(ds->cdmatag, ds->dmatab, ds->cdmamap); + ds->mdmatab = 0; + ds->cdmamap = NULL; + ds->dmatab = NULL; + } + if (ds->ddmamap) { + bus_dmamap_destroy(ds->ddmatag, ds->ddmamap); + ds->ddmamap = NULL; + } + if (ds->cdmatag) { + bus_dma_tag_destroy(ds->cdmatag); + ds->cdmatag = NULL; + } + if (ds->ddmatag) { + bus_dma_tag_destroy(ds->ddmatag); + ds->ddmatag = NULL; + } +} + +void +ata_dmafreetags(struct ata_channel *ch) +{ + + if (ch->dmatag) { + bus_dma_tag_destroy(ch->dmatag); + ch->dmatag = NULL; + } +} -void * -ata_dmaalloc(struct ata_channel *ch, int device) +static void +ata_dmacreate(struct ata_device *atadev, int apiomode, int mode) { - void *dmatab; - if ((dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT))) { - if (((uintptr_t)dmatab >> PAGE_SHIFT) ^ - (((uintptr_t)dmatab + PAGE_SIZE - 1) >> PAGE_SHIFT)) { - ata_printf(ch, device, "dmatab crosses page boundary, no DMA\n"); - free(dmatab, M_DEVBUF); - dmatab = NULL; + atadev->mode = mode; + if (!atadev->channel->dmatag) { + if (bus_dma_tag_create(NULL, 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, + NULL, NULL, MAXCTLDMASZ, ATA_DMA_ENTRIES, + BUS_SPACE_MAXSIZE_32BIT, 0, + &atadev->channel->dmatag)) { + ata_prtdev(atadev, "DMA tag allocation failed, disabling DMA\n"); + ata_dmainit(atadev, apiomode, -1, -1); } } - return dmatab; } void -ata_dmainit(struct ata_channel *ch, int device, - int apiomode, int wdmamode, int udmamode) +ata_dmainit(struct ata_device *atadev, int apiomode, int wdmamode, int udmamode) { - struct ata_device *atadev = &ch->device[ATA_DEV(device)]; - device_t parent = device_get_parent(ch->dev); - int devno = (ch->unit << 1) + ATA_DEV(device); + device_t parent = device_get_parent(atadev->channel->dev); + int chiptype = atadev->channel->chiptype; + int chiprev = pci_get_revid(parent); + int channel = atadev->channel->unit; + int device = ATA_DEV(atadev->unit); + int devno = (channel << 1) + device; int error; /* set our most pessimistic default mode */ atadev->mode = ATA_PIO; - if (!ch->r_bmio) + if (!atadev->channel->r_bmio) return; /* if simplex controller, only allow DMA on primary channel */ - if (ch->unit == 1) { - ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, - ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & + if (channel == 1) { + ATA_OUTB(atadev->channel->r_bmio, ATA_BMSTAT_PORT, + ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE)); - if (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) { + if (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & + ATA_BMSTAT_DMA_SIMPLEX) { ata_prtdev(atadev, "simplex device, DMA on primary only\n"); return; } } /* DMA engine address alignment is usually 1 word (2 bytes) */ - ch->alignment = 0x1; + atadev->channel->alignment = 0x1; #if 1 - if (udmamode > 2 && !ch->device[ATA_DEV(device)].param->hwres_cblid) { + if (udmamode > 2 && !atadev->param->hwres_cblid) { ata_prtdev(atadev,"DMA limited to UDMA33, non-ATA66 cable or device\n"); udmamode = 2; } #endif - switch (ch->chiptype) { + switch (chiptype) { case 0x24db8086: /* Intel ICH5 */ case 0x24cb8086: /* Intel ICH4 */ @@ -135,7 +240,7 @@ ata_dmainit(struct ata_channel *ch, int device, (pci_read_config(parent, 0x48, 4) & ~mask48) | new48, 4); pci_write_config(parent, 0x54, word54 | (0x1000<<devno), 2); - atadev->mode = ATA_UDMA5; + ata_dmacreate(atadev, apiomode, ATA_UDMA5); return; } } @@ -165,7 +270,7 @@ ata_dmainit(struct ata_channel *ch, int device, (pci_read_config(parent, 0x48, 4) & ~mask48) | new48, 4); pci_write_config(parent, 0x54, word54 | (1 << devno), 2); - atadev->mode = ATA_UDMA4; + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } @@ -193,7 +298,7 @@ ata_dmainit(struct ata_channel *ch, int device, pci_write_config(parent, 0x48, (pci_read_config(parent, 0x48, 4) & ~mask48) | new48, 4); - atadev->mode = ATA_UDMA2; + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } @@ -207,7 +312,7 @@ ata_dmainit(struct ata_channel *ch, int device, int32_t mask40, new40, mask44, new44; /* if SITRE not set doit for both channels */ - if (!((pci_read_config(parent,0x40,4)>>(ch->unit<<8))&0x4000)) { + if (!((pci_read_config(parent, 0x40, 4) >> (channel<<8)) & 0x4000)){ new40 = pci_read_config(parent, 0x40, 4); new44 = pci_read_config(parent, 0x44, 4); if (!(new40 & 0x00004000)) { @@ -240,7 +345,7 @@ ata_dmainit(struct ata_channel *ch, int device, mask44 = 0x0000000f; new44 = 0x0000000b; } - if (ch->unit) { + if (channel) { mask40 <<= 16; new40 <<= 16; mask44 <<= 4; @@ -252,7 +357,7 @@ ata_dmainit(struct ata_channel *ch, int device, pci_write_config(parent, 0x44, (pci_read_config(parent, 0x44, 4) & ~mask44)| new44, 4); - atadev->mode = ATA_WDMA2; + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -264,11 +369,11 @@ ata_dmainit(struct ata_channel *ch, int device, int32_t word40; word40 = pci_read_config(parent, 0x40, 4); - word40 >>= ch->unit * 16; + word40 >>= channel * 16; /* Check for timing config usable for DMA on controller */ if (!((word40 & 0x3300) == 0x2300 && - ((word40 >> (device == ATA_MASTER ? 0 : 4)) & 1) == 1)) + ((word40 >> (device ? 4 : 0)) & 1) == 1)) break; error = ata_command(atadev, ATA_C_SETFEATURES, 0, @@ -277,7 +382,7 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting WDMA2 on Intel chip\n", (error) ? "failed" : "success"); if (!error) { - atadev->mode = ATA_WDMA2; + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -285,12 +390,14 @@ ata_dmainit(struct ata_channel *ch, int device, case 0x522910b9: /* AcerLabs Aladdin IV/V */ /* the older Aladdin doesn't support ATAPI DMA on both master & slave */ - if (pci_get_revid(parent) < 0xc2 && - ch->devices & ATA_ATAPI_MASTER && ch->devices & ATA_ATAPI_SLAVE) { + if (chiprev < 0xc2 && + atadev->channel->devices & ATA_ATAPI_MASTER && + atadev->channel->devices & ATA_ATAPI_SLAVE) { ata_prtdev(atadev, "two atapi devices on this channel, no DMA\n"); break; } - if (udmamode >= 5 && pci_get_revid(parent) >= 0xc4) { + pci_write_config(parent, 0x58 + (channel << 2), 0x00310001, 4); + if (udmamode >= 5 && chiprev >= 0xc4) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -306,11 +413,11 @@ ata_dmainit(struct ata_channel *ch, int device, pci_write_config(parent, 0x54, word54, 4); pci_write_config(parent, 0x53, pci_read_config(parent, 0x53, 1) | 0x03, 1); - atadev->mode = ATA_UDMA5; + ata_dmacreate(atadev, apiomode, ATA_UDMA5); return; } } - if (udmamode >= 4 && pci_get_revid(parent) >= 0xc2) { + if (udmamode >= 4 && chiprev >= 0xc2) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -326,11 +433,11 @@ ata_dmainit(struct ata_channel *ch, int device, pci_write_config(parent, 0x54, word54, 4); pci_write_config(parent, 0x53, pci_read_config(parent, 0x53, 1) | 0x03, 1); - atadev->mode = ATA_UDMA4; + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } - if (udmamode >= 2 && pci_get_revid(parent) >= 0x20) { + if (udmamode >= 2 && chiprev >= 0x20) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -344,8 +451,8 @@ ata_dmainit(struct ata_channel *ch, int device, pci_write_config(parent, 0x54, word54, 4); pci_write_config(parent, 0x53, pci_read_config(parent, 0x53, 1) | 0x03, 1); - ch->flags |= ATA_ATAPI_DMA_RO; - atadev->mode = ATA_UDMA2; + atadev->channel->flags |= ATA_ATAPI_DMA_RO; + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } @@ -363,14 +470,39 @@ ata_dmainit(struct ata_channel *ch, int device, if (!error) { pci_write_config(parent, 0x53, pci_read_config(parent, 0x53, 1) | 0x03, 1); - ch->flags |= ATA_ATAPI_DMA_RO; - atadev->mode = ATA_WDMA2; + atadev->channel->flags |= ATA_ATAPI_DMA_RO; + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } pci_write_config(parent, 0x53, (pci_read_config(parent, 0x53, 1) & ~0x01) | 0x02, 1); - /* we could set PIO mode timings, but we assume the BIOS did that */ + error = ata_command(atadev, ATA_C_SETFEATURES, 0, + ATA_PIO0 + apiomode, + ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_prtdev(atadev, "%s setting PIO%d on Acer chip\n", + (error) ? "failed" : "success", + (apiomode >= 0) ? apiomode : 0); + if (!error) { + int32_t word54 = pci_read_config(parent, 0x54, 4); + int32_t timing; + + switch(ATA_PIO0 + apiomode) { + case ATA_PIO0: timing = 0x006d0003; + case ATA_PIO1: timing = 0x00580002; + case ATA_PIO2: timing = 0x00440001; + case ATA_PIO3: timing = 0x00330001; + case ATA_PIO4: timing = 0x00310001; + default: timing = 0x006d0003; + } + pci_write_config(parent, 0x58 + (channel << 2), timing, 4); + word54 &= ~(0x000f000f << (devno << 2)); + word54 |= (0x00000004 << (devno << 2)); + pci_write_config(parent, 0x54, word54, 4); + atadev->mode = ATA_PIO0 + apiomode; + return; + } break; case 0x01bc10de: /* nVIDIA nForce */ @@ -380,11 +512,11 @@ ata_dmainit(struct ata_channel *ch, int device, case 0x05711106: /* VIA 82C571, 82C586, 82C596, 82C686, 8231,8233,8235 */ { int via_modes[5][7] = { - { 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* ATA33 */ - { 0x00, 0x00, 0xea, 0x00, 0xe8, 0x00, 0x00 }, /* ATA66 */ - { 0x00, 0x00, 0xf4, 0x00, 0xf1, 0xf0, 0x00 }, /* ATA100 */ - { 0x00, 0x00, 0xf6, 0x00, 0xf2, 0xf1, 0xf0 }, /* VIA ATA133 */ - { 0x00, 0x00, 0xc0, 0x00, 0xc5, 0xc6, 0x00 }}; /* AMD/nVIDIA */ + { 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* VIA ATA33 */ + { 0x00, 0x00, 0xea, 0x00, 0xe8, 0x00, 0x00 }, /* VIA ATA66 */ + { 0x00, 0x00, 0xf4, 0x00, 0xf1, 0xf0, 0x00 }, /* VIA ATA100 */ + { 0x00, 0x00, 0xf6, 0x00, 0xf2, 0xf1, 0xf0 }, /* VIA ATA133 */ + { 0x00, 0x00, 0xc0, 0x00, 0xc5, 0xc6, 0x00 }}; /* AMD/nVIDIA */ int *reg_val = NULL; char *chip = "VIA"; @@ -414,18 +546,18 @@ ata_dmainit(struct ata_channel *ch, int device, udmamode = imin(udmamode, 2); reg_val = via_modes[0]; } - else if (ch->chiptype == 0x74411022 || /* AMD 768 */ - ch->chiptype == 0x74111022) { /* AMD 766 */ + else if (chiptype == 0x74411022 || /* AMD 768 */ + chiptype == 0x74111022) { /* AMD 766 */ udmamode = imin(udmamode, 5); reg_val = via_modes[4]; chip = "AMD"; } - else if (ch->chiptype == 0x74091022) { /* AMD 756 */ + else if (chiptype == 0x74091022) { /* AMD 756 */ udmamode = imin(udmamode, 4); reg_val = via_modes[4]; chip = "AMD"; } - else if (ch->chiptype == 0x01bc10de) { /* nVIDIA */ + else if (chiptype == 0x01bc10de) { /* nVIDIA */ udmamode = imin(udmamode, 5); reg_val = via_modes[4]; chip = "nVIDIA"; @@ -441,7 +573,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success", chip); if (!error) { pci_write_config(parent, 0x53 - devno, reg_val[6], 1); - atadev->mode = ATA_UDMA6; + ata_dmacreate(atadev, apiomode, ATA_UDMA6); return; } } @@ -453,7 +585,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success", chip); if (!error) { pci_write_config(parent, 0x53 - devno, reg_val[5], 1); - atadev->mode = ATA_UDMA5; + ata_dmacreate(atadev, apiomode, ATA_UDMA5); return; } } @@ -465,7 +597,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success", chip); if (!error) { pci_write_config(parent, 0x53 - devno, reg_val[4], 1); - atadev->mode = ATA_UDMA4; + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } @@ -477,7 +609,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success", chip); if (!error) { pci_write_config(parent, 0x53 - devno, reg_val[2], 1); - atadev->mode = ATA_UDMA2; + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } @@ -490,7 +622,7 @@ ata_dmainit(struct ata_channel *ch, int device, if (!error) { pci_write_config(parent, 0x53 - devno, 0x0b, 1); pci_write_config(parent, 0x4b - devno, 0x31, 1); - atadev->mode = ATA_WDMA2; + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -522,7 +654,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, reg, val | 0x8000, 2); - atadev->mode = ATA_UDMA5; + ata_dmacreate(atadev, apiomode, ATA_UDMA5); return; } } @@ -534,7 +666,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, reg, val | 0x9000, 2); - atadev->mode = ATA_UDMA4; + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } @@ -546,7 +678,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, reg, val | 0xb000, 2); - atadev->mode = ATA_UDMA2; + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } @@ -565,7 +697,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, reg, val | 0x9000, 2); - atadev->mode = ATA_UDMA4; + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } @@ -577,11 +709,11 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, reg, val | 0xa000, 2); - atadev->mode = ATA_UDMA2; + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } - } else if (udmamode >= 2 && pci_get_revid(parent) > 0xc1) { + } else if (udmamode >= 2 && chiprev > 0xc1) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -589,7 +721,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2); - atadev->mode = ATA_UDMA2; + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } @@ -601,7 +733,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2); - atadev->mode = ATA_WDMA2; + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -610,10 +742,10 @@ ata_dmainit(struct ata_channel *ch, int device, case 0x06801095: /* SiI 0680 ATA133 controller */ { - u_int8_t ureg = 0xac + (ATA_DEV(device) * 0x02) + (ch->unit * 0x10); + u_int8_t ureg = 0xac + (device * 0x02) + (channel * 0x10); u_int8_t uval = pci_read_config(parent, ureg, 1); - u_int8_t mreg = ch->unit ? 0x84 : 0x80; - u_int8_t mask = ATA_DEV(device) ? 0x30 : 0x03; + u_int8_t mreg = channel ? 0x84 : 0x80; + u_int8_t mask = device ? 0x30 : 0x03; u_int8_t mode = pci_read_config(parent, mreg, 1); /* enable UDMA mode */ @@ -627,7 +759,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, ureg, (uval & ~0x3f) | 0x01, 1); - atadev->mode = ATA_UDMA6; + ata_dmacreate(atadev, apiomode, ATA_UDMA6); return; } } @@ -639,7 +771,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, ureg, (uval & ~0x3f) | 0x02, 1); - atadev->mode = ATA_UDMA5; + ata_dmacreate(atadev, apiomode, ATA_UDMA5); return; } } @@ -651,7 +783,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, ureg, (uval & ~0x3f) | 0x03, 1); - atadev->mode = ATA_UDMA4; + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } @@ -663,7 +795,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, ureg, (uval & ~0x3f) | 0x07, 1); - atadev->mode = ATA_UDMA2; + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } @@ -679,7 +811,7 @@ ata_dmainit(struct ata_channel *ch, int device, (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, ureg - 0x4, 0x10c1, 2); - atadev->mode = ATA_WDMA2; + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -701,11 +833,11 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting UDMA5 on CMD chip\n", (error) ? "failed" : "success"); if (!error) { - umode = pci_read_config(parent, ch->unit ? 0x7b : 0x73, 1); - umode &= ~(device == ATA_MASTER ? 0x35 : 0xca); - umode |= (device == ATA_MASTER ? 0x05 : 0x0a); - pci_write_config(parent, ch->unit ? 0x7b : 0x73, umode, 1); - atadev->mode = ATA_UDMA5; + umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1); + umode &= ~(device ? 0xca : 0x35); + umode |= (device ? 0x0a : 0x05); + pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1); + ata_dmacreate(atadev, apiomode, ATA_UDMA5); return; } } @@ -721,11 +853,11 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting UDMA4 on CMD chip\n", (error) ? "failed" : "success"); if (!error) { - umode = pci_read_config(parent, ch->unit ? 0x7b : 0x73, 1); - umode &= ~(device == ATA_MASTER ? 0x35 : 0xca); - umode |= (device == ATA_MASTER ? 0x15 : 0x4a); - pci_write_config(parent, ch->unit ? 0x7b : 0x73, umode, 1); - atadev->mode = ATA_UDMA4; + umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1); + umode &= ~(device ? 0xca : 0x35); + umode |= (device ? 0x4a : 0x15); + pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1); + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } @@ -738,18 +870,18 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting UDMA2 on CMD chip\n", (error) ? "failed" : "success"); if (!error) { - umode = pci_read_config(parent, ch->unit ? 0x7b : 0x73, 1); - umode &= ~(device == ATA_MASTER ? 0x35 : 0xca); - umode |= (device == ATA_MASTER ? 0x11 : 0x42); - pci_write_config(parent, ch->unit ? 0x7b : 0x73, umode, 1); - atadev->mode = ATA_UDMA2; + umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1); + umode &= ~(device ? 0xca : 0x35); + umode |= (device ? 0x42 : 0x11); + pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1); + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } /* make sure eventual UDMA mode from the BIOS is disabled */ - pci_write_config(parent, ch->unit ? 0x7b : 0x73, - pci_read_config(parent, ch->unit ? 0x7b : 0x73, 1)& - ~(device == ATA_MASTER ? 0x35 : 0xca), 1); + pci_write_config(parent, channel ? 0x7b : 0x73, + pci_read_config(parent, channel ? 0x7b : 0x73, 1) & + ~(device ? 0xca : 0x53), 1); /* FALLTHROUGH */ case 0x06461095: /* CMD 646 ATA controller */ @@ -763,7 +895,7 @@ ata_dmainit(struct ata_channel *ch, int device, int32_t offset = (devno < 3) ? (devno << 1) : 7; pci_write_config(parent, 0x54 + offset, 0x3f, 1); - atadev->mode = ATA_WDMA2; + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -778,8 +910,9 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting WDMA2 on Cypress chip\n", error ? "failed" : "success"); if (!error) { - pci_write_config(ch->dev, ch->unit ? 0x4e:0x4c, 0x2020, 2); - atadev->mode = ATA_WDMA2; + pci_write_config(atadev->channel->dev, + channel ? 0x4e:0x4c, 0x2020, 2); + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -787,7 +920,7 @@ ata_dmainit(struct ata_channel *ch, int device, break; case 0x01021078: /* Cyrix 5530 ATA33 controller */ - ch->alignment = 0xf; /* DMA engine requires 16 byte alignment */ + atadev->channel->alignment = 0xf; if (udmamode >= 2) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); @@ -795,8 +928,8 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting UDMA2 on Cyrix chip\n", (error) ? "failed" : "success"); if (!error) { - cyrix_timing(ch, devno, ATA_UDMA2); - atadev->mode = ATA_UDMA2; + cyrix_timing(atadev, devno, ATA_UDMA2); + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } @@ -807,8 +940,8 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting WDMA2 on Cyrix chip\n", (error) ? "failed" : "success"); if (!error) { - cyrix_timing(ch, devno, ATA_WDMA2); - atadev->mode = ATA_WDMA2; + cyrix_timing(atadev, devno, ATA_WDMA2); + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -819,12 +952,12 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting %s on Cyrix chip\n", (error) ? "failed" : "success", ata_mode2str(ATA_PIO0 + apiomode)); - cyrix_timing(ch, devno, ATA_PIO0 + apiomode); + cyrix_timing(atadev, devno, ATA_PIO0 + apiomode); atadev->mode = ATA_PIO0 + apiomode; return; case 0x02121166: /* ServerWorks CSB5 ATA66/100 controller */ - if (udmamode >= 5 && pci_get_revid(parent) >= 0x92) { + if (udmamode >= 5 && chiprev >= 0x92) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -840,7 +973,7 @@ ata_dmainit(struct ata_channel *ch, int device, reg56 &= ~(0xf << (devno * 4)); reg56 |= (0x5 << (devno * 4)); pci_write_config(parent, 0x56, reg56, 2); - atadev->mode = ATA_UDMA5; + ata_dmacreate(atadev, apiomode, ATA_UDMA5); return; } } @@ -860,7 +993,7 @@ ata_dmainit(struct ata_channel *ch, int device, reg56 &= ~(0xf << (devno * 4)); reg56 |= (0x4 << (devno * 4)); pci_write_config(parent, 0x56, reg56, 2); - atadev->mode = ATA_UDMA4; + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } @@ -883,7 +1016,7 @@ ata_dmainit(struct ata_channel *ch, int device, reg56 &= ~(0xf << (devno * 4)); reg56 |= (0x2 << (devno * 4)); pci_write_config(parent, 0x56, reg56, 2); - atadev->mode = ATA_UDMA2; + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } @@ -894,7 +1027,7 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting WDMA2 on ServerWorks chip\n", (error) ? "failed" : "success"); if (!error) { - int offset = (ch->unit * 2) + (device == ATA_MASTER); + int offset = devno ^ 0x01; int word44 = pci_read_config(parent, 0x44, 4); pci_write_config(parent, 0x54, @@ -903,7 +1036,7 @@ ata_dmainit(struct ata_channel *ch, int device, word44 &= ~(0xff << (offset << 8)); word44 |= (0x20 << (offset << 8)); pci_write_config(parent, 0x44, 0x20, 4); - atadev->mode = ATA_WDMA2; + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -914,15 +1047,16 @@ ata_dmainit(struct ata_channel *ch, int device, case 0x5275105a: /* Promise TX2 ATA133 controllers */ case 0x6269105a: /* Promise TX2 ATA133 controllers */ case 0x7275105a: /* Promise TX2 ATA133 controllers */ - ATA_OUTB(ch->r_bmio, ATA_BMDEVSPEC_0, 0x0b); - if (udmamode >= 6 && !(ATA_INB(ch->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { + ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b); + if (udmamode >= 6 && + !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting UDMA6 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - atadev->mode = ATA_UDMA6; + ata_dmacreate(atadev, apiomode, ATA_UDMA6); return; } } @@ -930,27 +1064,29 @@ ata_dmainit(struct ata_channel *ch, int device, case 0x4d68105a: /* Promise TX2 ATA100 controllers */ case 0x6268105a: /* Promise TX2 ATA100 controllers */ - ATA_OUTB(ch->r_bmio, ATA_BMDEVSPEC_0, 0x0b); - if (udmamode >= 5 && !(ATA_INB(ch->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { + ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b); + if (udmamode >= 5 && + !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting UDMA5 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - atadev->mode = ATA_UDMA5; + ata_dmacreate(atadev, apiomode, ATA_UDMA5); return; } } - ATA_OUTB(ch->r_bmio, ATA_BMDEVSPEC_0, 0x0b); - if (udmamode >= 4 && !(ATA_INB(ch->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { + ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b); + if (udmamode >= 4 && + !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting UDMA4 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - atadev->mode = ATA_UDMA4; + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } @@ -961,7 +1097,7 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting UDMA on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - atadev->mode = ATA_UDMA2; + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } @@ -972,7 +1108,7 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting WDMA2 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - atadev->mode = ATA_WDMA2; + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -980,16 +1116,16 @@ ata_dmainit(struct ata_channel *ch, int device, case 0x0d30105a: /* Promise OEM ATA100 controllers */ case 0x4d30105a: /* Promise Ultra/FastTrak 100 controllers */ - if (!ATAPI_DEVICE(ch, device) && udmamode >= 5 && - !(pci_read_config(parent, 0x50, 2)&(ch->unit ? 1<<11 : 1<<10))){ + if (!ATAPI_DEVICE(atadev) && udmamode >= 5 && + !(pci_read_config(parent, 0x50, 2) & (channel ? 1<<11 : 1<<10))) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting UDMA5 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - promise_timing(ch, devno, ATA_UDMA5); - atadev->mode = ATA_UDMA5; + promise_timing(atadev, devno, ATA_UDMA5); + ata_dmacreate(atadev, apiomode, ATA_UDMA5); return; } } @@ -997,43 +1133,43 @@ ata_dmainit(struct ata_channel *ch, int device, case 0x0d38105a: /* Promise FastTrak 66 controllers */ case 0x4d38105a: /* Promise Ultra/FastTrak 66 controllers */ - if (!ATAPI_DEVICE(ch, device) && udmamode >= 4 && - !(pci_read_config(parent, 0x50, 2)&(ch->unit ? 1<<11 : 1<<10))){ + if (!ATAPI_DEVICE(atadev) && udmamode >= 4 && + !(pci_read_config(parent, 0x50, 2) & (channel ? 1<<11 : 1<<10))) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting UDMA4 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - promise_timing(ch, devno, ATA_UDMA4); - atadev->mode = ATA_UDMA4; + promise_timing(atadev, devno, ATA_UDMA4); + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } /* FALLTHROUGH */ case 0x4d33105a: /* Promise Ultra/FastTrak 33 controllers */ - if (!ATAPI_DEVICE(ch, device) && udmamode >= 2) { + if (!ATAPI_DEVICE(atadev) && udmamode >= 2) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting UDMA2 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - promise_timing(ch, devno, ATA_UDMA2); - atadev->mode = ATA_UDMA2; + promise_timing(atadev, devno, ATA_UDMA2); + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } - if (!ATAPI_DEVICE(ch, device) && wdmamode >= 2 && apiomode >= 4) { + if (!ATAPI_DEVICE(atadev) && wdmamode >= 2 && apiomode >= 4) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting WDMA2 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - promise_timing(ch, devno, ATA_WDMA2); - atadev->mode = ATA_WDMA2; + promise_timing(atadev, devno, ATA_WDMA2); + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -1044,76 +1180,76 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting PIO%d on Promise chip\n", (error) ? "failed" : "success", (apiomode >= 0) ? apiomode : 0); - promise_timing(ch, devno, ATA_PIO0 + apiomode); + promise_timing(atadev, devno, ATA_PIO0 + apiomode); atadev->mode = ATA_PIO0 + apiomode; return; case 0x00041103: /* HighPoint HPT366/368/370/372 controllers */ case 0x00051103: /* HighPoint HPT372 controllers */ case 0x00081103: /* HighPoint HPT374 controllers */ - if (!ATAPI_DEVICE(ch, device) && udmamode >= 6 && hpt_cable80(ch) && - ((ch->chiptype == 0x00041103 && pci_get_revid(parent) >= 0x05) || - (ch->chiptype == 0x00051103 && pci_get_revid(parent) >= 0x01) || - (ch->chiptype == 0x00081103 && pci_get_revid(parent) >= 0x07))) { + if (!ATAPI_DEVICE(atadev) && udmamode >= 6 && hpt_cable80(atadev) && + ((chiptype == 0x00041103 && chiprev >= 0x05) || + (chiptype == 0x00051103 && chiprev >= 0x01) || + (chiptype == 0x00081103 && chiprev >= 0x07))) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting UDMA6 on HighPoint chip\n", (error) ? "failed" : "success"); if (!error) { - hpt_timing(ch, devno, ATA_UDMA6); - atadev->mode = ATA_UDMA6; + hpt_timing(atadev, devno, ATA_UDMA6); + ata_dmacreate(atadev, apiomode, ATA_UDMA6); return; } } - if (!ATAPI_DEVICE(ch, device) && udmamode >= 5 && hpt_cable80(ch) && - ((ch->chiptype == 0x00041103 && pci_get_revid(parent) >= 0x03) || - (ch->chiptype == 0x00051103 && pci_get_revid(parent) >= 0x01) || - (ch->chiptype == 0x00081103 && pci_get_revid(parent) >= 0x07))) { + if (!ATAPI_DEVICE(atadev) && udmamode >= 5 && hpt_cable80(atadev) && + ((chiptype == 0x00041103 && chiprev >= 0x03) || + (chiptype == 0x00051103 && chiprev >= 0x01) || + (chiptype == 0x00081103 && chiprev >= 0x07))) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting UDMA5 on HighPoint chip\n", (error) ? "failed" : "success"); if (!error) { - hpt_timing(ch, devno, ATA_UDMA5); - atadev->mode = ATA_UDMA5; + hpt_timing(atadev, devno, ATA_UDMA5); + ata_dmacreate(atadev, apiomode, ATA_UDMA5); return; } } - if (!ATAPI_DEVICE(ch, device) && udmamode >= 4 && hpt_cable80(ch)) { + if (!ATAPI_DEVICE(atadev) && udmamode >= 4 && hpt_cable80(atadev)) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting UDMA4 on HighPoint chip\n", (error) ? "failed" : "success"); if (!error) { - hpt_timing(ch, devno, ATA_UDMA4); - atadev->mode = ATA_UDMA4; + hpt_timing(atadev, devno, ATA_UDMA4); + ata_dmacreate(atadev, apiomode, ATA_UDMA4); return; } } - if (!ATAPI_DEVICE(ch, device) && udmamode >= 2) { + if (!ATAPI_DEVICE(atadev) && udmamode >= 2) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting UDMA2 on HighPoint chip\n", (error) ? "failed" : "success"); if (!error) { - hpt_timing(ch, devno, ATA_UDMA2); - atadev->mode = ATA_UDMA2; + hpt_timing(atadev, devno, ATA_UDMA2); + ata_dmacreate(atadev, apiomode, ATA_UDMA2); return; } } - if (!ATAPI_DEVICE(ch, device) && wdmamode >= 2 && apiomode >= 4) { + if (!ATAPI_DEVICE(atadev) && wdmamode >= 2 && apiomode >= 4) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting WDMA2 on HighPoint chip\n", (error) ? "failed" : "success"); if (!error) { - hpt_timing(ch, devno, ATA_WDMA2); - atadev->mode = ATA_WDMA2; + hpt_timing(atadev, devno, ATA_WDMA2); + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -1124,44 +1260,42 @@ ata_dmainit(struct ata_channel *ch, int device, ata_prtdev(atadev, "%s setting PIO%d on HighPoint chip\n", (error) ? "failed" : "success", (apiomode >= 0) ? apiomode : 0); - hpt_timing(ch, devno, ATA_PIO0 + apiomode); + hpt_timing(atadev, devno, ATA_PIO0 + apiomode); atadev->mode = ATA_PIO0 + apiomode; return; case 0x000116ca: /* Cenatek Rocket Drive controller */ if (wdmamode >= 0 && - (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & - ((device==ATA_MASTER)?ATA_BMSTAT_DMA_MASTER:ATA_BMSTAT_DMA_SLAVE))) - atadev->mode = ATA_DMA; + (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & + (device ? ATA_BMSTAT_DMA_SLAVE : ATA_BMSTAT_DMA_MASTER))) + ata_dmacreate(atadev, apiomode, ATA_DMA); else atadev->mode = ATA_PIO; return; default: /* unknown controller chip */ /* better not try generic DMA on ATAPI devices it almost never works */ - if ((device == ATA_MASTER && ch->devices & ATA_ATAPI_MASTER) || - (device == ATA_SLAVE && ch->devices & ATA_ATAPI_SLAVE)) + if (ATAPI_DEVICE(atadev)) break; /* if controller says its setup for DMA take the easy way out */ /* the downside is we dont know what DMA mode we are in */ if ((udmamode >= 0 || wdmamode >= 2) && - (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & - ((device==ATA_MASTER) ? - ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) { - atadev->mode = ATA_DMA; + (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & + (device ? ATA_BMSTAT_DMA_SLAVE : ATA_BMSTAT_DMA_MASTER))) { + ata_dmacreate(atadev, apiomode, ATA_DMA); return; } /* well, we have no support for this, but try anyways */ - if ((wdmamode >= 2 && apiomode >= 4) && ch->r_bmio) { + if ((wdmamode >= 2 && apiomode >= 4) && atadev->channel->r_bmio) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) ata_prtdev(atadev, "%s setting WDMA2 on generic chip\n", (error) ? "failed" : "success"); if (!error) { - atadev->mode = ATA_WDMA2; + ata_dmacreate(atadev, apiomode, ATA_WDMA2); return; } } @@ -1180,72 +1314,111 @@ ata_dmainit(struct ata_channel *ch, int device, } } +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) +{ + 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) + 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); + } + } + cba->dmatab[j - 1].count = htole32(lastcount | ATA_DMA_EOT); +} + int -ata_dmasetup(struct ata_channel *ch, int device, struct ata_dmaentry *dmatab, - caddr_t data, int32_t count) +ata_dmasetup(struct ata_device *atadev, caddr_t data, int32_t count) { - u_int32_t dma_count, dma_base; - int i = 0; + struct ata_channel *ch = atadev->channel; if (((uintptr_t)data & ch->alignment) || (count & ch->alignment)) { - ata_printf(ch, device, "non aligned DMA transfer attempted\n"); + ata_prtdev(atadev, "non aligned DMA transfer attempted\n"); return -1; } if (!count) { - ata_printf(ch, device, "zero length DMA transfer attempted\n"); + ata_prtdev(atadev, "zero length DMA transfer attempted\n"); return -1; } - - dma_base = vtophys(data); - dma_count = imin(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK))); - data += dma_count; - count -= dma_count; - - while (count) { - dmatab[i].base = dma_base; - dmatab[i].count = (dma_count & 0xffff); - i++; - if (i >= ATA_DMA_ENTRIES) { - ata_printf(ch, device, "too many segments in DMA table\n"); - return -1; - } - dma_base = vtophys(data); - dma_count = imin(count, PAGE_SIZE); - data += imin(count, PAGE_SIZE); - count -= imin(count, PAGE_SIZE); - } - dmatab[i].base = dma_base; - dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; return 0; } -void -ata_dmastart(struct ata_channel *ch, int device, - struct ata_dmaentry *dmatab, int dir) +int +ata_dmastart(struct ata_device *atadev, caddr_t data, int32_t count, int dir) { + struct ata_channel *ch = atadev->channel; + struct ata_dmastate *ds = &atadev->dmastate; + struct ata_dmasetup_data_cb_args cba; + + if (ds->flags & ATA_DS_ACTIVE) + panic("ata_dmasetup: transfer active on this device!"); + + cba.dmatab = ds->dmatab; + bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_PREWRITE); + if (bus_dmamap_load(ds->ddmatag, ds->ddmamap, data, count, + ata_dmasetupd_cb, &cba, 0) || cba.error) + return -1; + + bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_POSTWRITE); + bus_dmamap_sync(ds->ddmatag, ds->ddmamap, dir ? BUS_DMASYNC_PREREAD : + BUS_DMASYNC_PREWRITE); + ch->flags |= ATA_DMA_ACTIVE; - ATA_OUTL(ch->r_bmio, ATA_BMDTP_PORT, vtophys(dmatab)); + ds->flags = ATA_DS_ACTIVE; + if (dir) + ds->flags |= ATA_DS_READ; + + ATA_OUTL(ch->r_bmio, ATA_BMDTP_PORT, ds->mdmatab); ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0); ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) | (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP); + return 0; } int -ata_dmadone(struct ata_channel *ch) +ata_dmadone(struct ata_device *atadev) { + struct ata_channel *ch; + struct ata_dmastate *ds; int error; + ch = atadev->channel; + ds = &atadev->dmastate; + bus_dmamap_sync(ds->ddmatag, ds->ddmamap, (ds->flags & ATA_DS_READ) != 0 ? + BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(ds->ddmatag, ds->ddmamap); + ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); - ch->flags &= ~ATA_DMA_ACTIVE; error = ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT); ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, error | ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR); - return error & ATA_BMSTAT_MASK; + ch->flags &= ~ATA_DMA_ACTIVE; + ds->flags = 0; + return (error & ATA_BMSTAT_MASK); } int @@ -1255,7 +1428,7 @@ ata_dmastatus(struct ata_channel *ch) } static void -cyrix_timing(struct ata_channel *ch, int devno, int mode) +cyrix_timing(struct ata_device *atadev, int devno, int mode) { u_int32_t reg20 = 0x0000e132; u_int32_t reg24 = 0x00017771; @@ -1269,14 +1442,15 @@ cyrix_timing(struct ata_channel *ch, int devno, int mode) case ATA_WDMA2: reg24 = 0x00002020; break; case ATA_UDMA2: reg24 = 0x00911030; break; } - ATA_OUTL(ch->r_bmio, (devno << 3) + 0x20, reg20); - ATA_OUTL(ch->r_bmio, (devno << 3) + 0x24, reg24); + ATA_OUTL(atadev->channel->r_bmio, (devno << 3) + 0x20, reg20); + ATA_OUTL(atadev->channel->r_bmio, (devno << 3) + 0x24, reg24); } static void -promise_timing(struct ata_channel *ch, int devno, int mode) +promise_timing(struct ata_device *atadev, int devno, int mode) { u_int32_t timing = 0; + /* XXX: Endianess */ struct promise_timing { u_int8_t pa:4; u_int8_t prefetch:1; @@ -1298,7 +1472,7 @@ promise_timing(struct ata_channel *ch, int devno, int mode) t->prefetch = 1; t->errdy = 1; t->syncin = 1; } - switch (ch->chiptype) { + switch (atadev->channel->chiptype) { case 0x4d33105a: /* Promise Ultra/Fasttrak 33 */ switch (mode) { default: @@ -1329,16 +1503,19 @@ promise_timing(struct ata_channel *ch, int devno, int mode) } break; } - pci_write_config(device_get_parent(ch->dev), 0x60 + (devno<<2), timing, 4); + pci_write_config(device_get_parent(atadev->channel->dev), + 0x60 + (devno << 2), timing, 4); } static void -hpt_timing(struct ata_channel *ch, int devno, int mode) +hpt_timing(struct ata_device *atadev, int devno, int mode) { - device_t parent = device_get_parent(ch->dev); + device_t parent = device_get_parent(atadev->channel->dev); + u_int32_t chiptype = atadev->channel->chiptype; + int chiprev = pci_get_revid(parent); u_int32_t timing; - if (ch->chiptype == 0x00081103 && pci_get_revid(parent) >= 0x07) { + if (chiptype == 0x00081103 && chiprev >= 0x07) { switch (mode) { /* HPT374 */ case ATA_PIO0: timing = 0x0ac1f48a; break; case ATA_PIO1: timing = 0x0ac1f465; break; @@ -1353,8 +1530,8 @@ hpt_timing(struct ata_channel *ch, int devno, int mode) default: timing = 0x0d029d5e; } } - else if ((ch->chiptype == 0x00041103 && pci_get_revid(parent) >= 0x05) || - (ch->chiptype == 0x00051103 && pci_get_revid(parent) >= 0x01)) { + else if ((chiptype == 0x00041103 && chiprev >= 0x05) || + (chiptype == 0x00051103 && chiprev >= 0x01)) { switch (mode) { /* HPT372 */ case ATA_PIO0: timing = 0x0d029d5e; break; case ATA_PIO1: timing = 0x0d029d26; break; @@ -1369,7 +1546,7 @@ hpt_timing(struct ata_channel *ch, int devno, int mode) default: timing = 0x0d029d5e; } } - else if (ch->chiptype == 0x00041103 && pci_get_revid(parent) >= 0x03) { + else if (chiptype == 0x00041103 && chiprev >= 0x03) { switch (mode) { /* HPT370 */ case ATA_PIO0: timing = 0x06914e57; break; case ATA_PIO1: timing = 0x06914e43; break; @@ -1431,13 +1608,13 @@ hpt_timing(struct ata_channel *ch, int devno, int mode) } static int -hpt_cable80(struct ata_channel *ch) +hpt_cable80(struct ata_device *atadev) { - device_t parent = device_get_parent(ch->dev); + device_t parent = device_get_parent(atadev->channel->dev); u_int8_t reg, val, res; - if (ch->chiptype == 0x00081103 && pci_get_function(parent) == 1) { - reg = ch->unit ? 0x57 : 0x53; + if (atadev->channel->chiptype==0x00081103 && pci_get_function(parent)==1) { + reg = atadev->channel->unit ? 0x57 : 0x53; val = pci_read_config(parent, reg, 1); pci_write_config(parent, reg, val | 0x80, 1); } @@ -1446,7 +1623,7 @@ hpt_cable80(struct ata_channel *ch) val = pci_read_config(parent, reg, 1); pci_write_config(parent, reg, val & 0xfe, 1); } - res = pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x01 : 0x02); + res = pci_read_config(parent, 0x5a, 1) & (atadev->channel->unit ? 0x1:0x2); pci_write_config(parent, reg, val, 1); return !res; } diff --git a/sys/dev/ata/ata-isa.c b/sys/dev/ata/ata-isa.c index 02467364cf4d..e6a16f24f2f6 100644 --- a/sys/dev/ata/ata-isa.c +++ b/sys/dev/ata/ata-isa.c @@ -107,33 +107,40 @@ DRIVER_MODULE(ata, isa, ata_isa_driver, ata_devclass, 0, 0); */ #include "pci.h" #if NPCI == 0 -void * -ata_dmaalloc(struct ata_channel *ch, int device) +int +ata_dmaalloc(struct ata_device *atadev) +{ + return ENXIO; +} + +void +ata_dmafree(struct ata_device *atadev) +{ +} + +void +ata_dmafreetags(struct ata_channel *ch) { - return 0; } void -ata_dmainit(struct ata_channel *ch, int device, - int piomode, int wdmamode, int udmamode) +ata_dmainit(struct ata_device *atadev, int piomode, int wdmamode, int udmamode) { } int -ata_dmasetup(struct ata_channel *ch, int device, struct ata_dmaentry *dmatab, - caddr_t data, int32_t count) +ata_dmasetup(struct ata_device *atadev, caddr_t data, int32_t count) { return -1; } void -ata_dmastart(struct ata_channel *ch, int device, - struct ata_dmaentry *dmatab, int dir) +ata_dmastart(struct ata_device *atadev, caddr_t data, int32_t count, int dir) { } int -ata_dmadone(struct ata_channel *ch) +ata_dmadone(struct ata_device *atadev) { return -1; } diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index 28538bdf33b3..7bb31eb9ccc9 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -78,7 +78,7 @@ atapi_attach(struct ata_device *atadev) ATA_SLEEPLOCK_CH(atadev->channel, ATA_CONTROL); if (atapi_dma && !(atadev->param->drq_type == ATAPI_DRQT_INTR)) { - ata_dmainit(atadev->channel, atadev->unit, + ata_dmainit(atadev, (ata_pmode(atadev->param) < 0) ? (atadev->param->support_dma ? 4:0):ata_pmode(atadev->param), (ata_wmode(atadev->param) < 0) ? @@ -86,7 +86,7 @@ atapi_attach(struct ata_device *atadev) ata_umode(atadev->param)); } else - ata_dmainit(atadev->channel, atadev->unit, + ata_dmainit(atadev, ata_pmode(atadev->param) < 0 ? 0 : ata_pmode(atadev->param), -1, -1); ATA_UNLOCK_CH(atadev->channel); @@ -159,10 +159,9 @@ atapi_detach(struct ata_device *atadev) bp->b_error = ENXIO; biodone(bp); } - if (request->dmatab) - free(request->dmatab, M_DEVBUF); free(request, M_ATAPI); } + ata_dmafree(atadev); free(atadev->result, M_ATAPI); atadev->driver = NULL; atadev->flags = 0; @@ -194,7 +193,7 @@ atapi_queue_cmd(struct ata_device *atadev, int8_t *ccb, caddr_t data, request->driver = driver; } if (atadev->mode >= ATA_DMA) { - if (!(request->dmatab = ata_dmaalloc(atadev->channel, atadev->unit))) + if (ata_dmaalloc(atadev)) atadev->mode = ATA_PIO; } @@ -223,8 +222,6 @@ atapi_queue_cmd(struct ata_device *atadev, int8_t *ccb, caddr_t data, error = request->error; if (error) bcopy(&request->sense, atadev->result, sizeof(struct atapi_reqsense)); - if (request->dmatab) - free(request->dmatab, M_DEVBUF); free(request, M_ATAPI); return error; } @@ -292,8 +289,7 @@ atapi_transfer(struct atapi_request *request) ((request->ccb[0] == ATAPI_WRITE || request->ccb[0] == ATAPI_WRITE_BIG) && !(atadev->channel->flags & ATA_ATAPI_DMA_RO))) && - !ata_dmasetup(atadev->channel, atadev->unit, request->dmatab, - (void *)request->data, request->bytecount)) { + !ata_dmasetup(atadev, (void *)request->data, request->bytecount)) { request->flags |= ATPR_F_DMA_USED; } @@ -305,8 +301,8 @@ atapi_transfer(struct atapi_request *request) ata_prtdev(atadev, "failure to send ATAPI packet command\n"); if (request->flags & ATPR_F_DMA_USED) - ata_dmastart(atadev->channel, atadev->unit, - request->dmatab, request->flags & ATPR_F_READ); + ata_dmastart(atadev, request->data, request->bytecount, + request->flags & ATPR_F_READ); /* command interrupt device ? just return */ if (atadev->param->drq_type == ATAPI_DRQT_INTR) @@ -363,7 +359,7 @@ atapi_interrupt(struct atapi_request *request) } if (request->flags & ATPR_F_DMA_USED) { - dma_stat = ata_dmadone(atadev->channel); + dma_stat = ata_dmadone(atadev); if ((atadev->channel->status & (ATA_S_ERROR | ATA_S_DWF)) || dma_stat & ATA_BMSTAT_ERROR) { request->result = ATA_INB(atadev->channel->r_io, ATA_ERROR); @@ -485,14 +481,14 @@ atapi_reinit(struct ata_device *atadev) { /* reinit device parameters */ if (atadev->mode >= ATA_DMA) - ata_dmainit(atadev->channel, atadev->unit, + ata_dmainit(atadev, (ata_pmode(atadev->param) < 0) ? (atadev->param->support_dma ? 4:0):ata_pmode(atadev->param), (ata_wmode(atadev->param) < 0) ? (atadev->param->support_dma ? 2:0):ata_wmode(atadev->param), ata_umode(atadev->param)); else - ata_dmainit(atadev->channel, atadev->unit, + ata_dmainit(atadev, ata_pmode(atadev->param)<0 ? 0 : ata_pmode(atadev->param), -1, -1); } @@ -602,11 +598,8 @@ atapi_finish(struct atapi_request *request) atapi_cmd2str(request->ccb[0])); #endif if (request->callback) { - if (!((request->callback)(request))) { - if (request->dmatab) - free(request->dmatab, M_DEVBUF); + if (!((request->callback)(request))) free(request, M_ATAPI); - } } else wakeup((caddr_t)request); @@ -622,9 +615,9 @@ atapi_timeout(struct atapi_request *request) atapi_cmd2str(request->ccb[0])); if (request->flags & ATPR_F_DMA_USED) { - ata_dmadone(atadev->channel); + ata_dmadone(atadev); if (request->retries == ATAPI_MAX_RETRIES) { - ata_dmainit(atadev->channel, atadev->unit, + ata_dmainit(atadev, (ata_pmode(atadev->param) < 0) ? 0 : ata_pmode(atadev->param), -1, -1); ata_prtdev(atadev, "trying fallback to PIO mode\n"); diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h index 0f9fb59d8d54..4ab6d11f7349 100644 --- a/sys/dev/ata/atapi-all.h +++ b/sys/dev/ata/atapi-all.h @@ -166,7 +166,6 @@ struct atapi_request { caddr_t data; /* pointer to data buf */ atapi_callback_t *callback; /* ptr to callback func */ - struct ata_dmaentry *dmatab; /* DMA transfer table */ void *driver; /* driver specific */ TAILQ_ENTRY(atapi_request) chain; /* list management */ }; diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 162951b6214e..f86c592bbad0 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -45,6 +45,7 @@ #include <sys/fcntl.h> #include <sys/conf.h> #include <sys/ctype.h> +#include <machine/bus.h> #include <dev/ata/ata-all.h> #include <dev/ata/atapi-all.h> #include <dev/ata/atapi-cd.h> diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c index b89facce976e..b66faab21f24 100644 --- a/sys/dev/ata/atapi-fd.c +++ b/sys/dev/ata/atapi-fd.c @@ -39,6 +39,7 @@ #include <sys/disk.h> #include <sys/devicestat.h> #include <sys/cdio.h> +#include <machine/bus.h> #include <dev/ata/ata-all.h> #include <dev/ata/atapi-all.h> #include <dev/ata/atapi-fd.h> diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index bda32ced9fee..7c2eb21c64f2 100644 --- a/sys/dev/ata/atapi-tape.c +++ b/sys/dev/ata/atapi-tape.c @@ -40,6 +40,7 @@ #include <sys/mtio.h> #include <sys/disklabel.h> #include <sys/devicestat.h> +#include <machine/bus.h> #include <dev/ata/ata-all.h> #include <dev/ata/atapi-all.h> #include <dev/ata/atapi-tape.h> |
