diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index a5681f143d7d..37cbbea8c056 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -278,7 +278,7 @@ 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); -void ata_dmastart(struct ata_device *, int); +int ata_dmastart(struct ata_device *, caddr_t, int32_t, int); int ata_dmastatus(struct ata_channel *); int ata_dmadone(struct ata_device *); diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index 5a72220058a1..d7ac0698f5a9 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -487,7 +487,8 @@ ad_transfer(struct ad_request *request) } /* start transfer, return and wait for interrupt */ - ata_dmastart(adp->device, request->flags & ADR_F_READ); + ata_dmastart(adp->device, request->data, request->bytecount, + request->flags & ADR_F_READ); return ATA_OP_CONTINUES; } @@ -749,7 +750,8 @@ ad_service(struct ad_softc *adp, int change) ad_invalidatequeue(adp, NULL); return ATA_OP_FINISHED; } - ata_dmastart(adp->device, 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; diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index 89384d0e847c..40bd87197826 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -794,7 +794,7 @@ ata_dmainit(struct ata_device *atadev, int apiomode, int wdmamode, int udmamode) /* make sure eventual UDMA mode from the BIOS is disabled */ pci_write_config(parent, channel ? 0x7b : 0x73, pci_read_config(parent, channel ? 0x7b : 0x73, 1) & - ~(device ? 0xca : 0x53), 1); + ~(device ? 0xca : 0x53), 1); /* FALLTHROUGH */ case 0x06461095: /* CMD 646 ATA controller */ @@ -1261,11 +1261,6 @@ int ata_dmasetup(struct ata_device *atadev, caddr_t data, int32_t count) { 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!"); if (((uintptr_t)data & ch->alignment) || (count & ch->alignment)) { ata_prtdev(atadev, "non aligned DMA transfer attempted\n"); @@ -1276,29 +1271,34 @@ ata_dmasetup(struct ata_device *atadev, caddr_t data, int32_t count) ata_prtdev(atadev, "zero length DMA transfer attempted\n"); return -1; } - - cba.dmatab = ds->dmatab; - if (bus_dmamap_load(ds->ddmatag, ds->ddmamap, data, count, - ata_dmasetupd_cb, &cba, 0) || cba.error) - ds->flags = ATA_DS_ACTIVE; - bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_PREWRITE); - return 0; } -void -ata_dmastart(struct ata_device *atadev, int dir) +int +ata_dmastart(struct ata_device *atadev, caddr_t data, int32_t count, int dir) { - struct ata_channel *ch; - struct ata_dmastate *ds; + struct ata_channel *ch = atadev->channel; + struct ata_dmastate *ds = &atadev->dmastate; + struct ata_dmasetup_data_cb_args cba; - ch = atadev->channel; - ds = &atadev->dmastate; + 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; + ds->flags = ATA_DS_ACTIVE; if (dir) ds->flags |= ATA_DS_READ; - ch->flags |= ATA_DMA_ACTIVE; + 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, @@ -1306,6 +1306,7 @@ ata_dmastart(struct ata_device *atadev, int dir) (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 @@ -1320,14 +1321,15 @@ ata_dmadone(struct ata_device *atadev) 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); + ch->flags &= ~ATA_DMA_ACTIVE; ds->flags = 0; - return error & ATA_BMSTAT_MASK; + return (error & ATA_BMSTAT_MASK); } int diff --git a/sys/dev/ata/ata-isa.c b/sys/dev/ata/ata-isa.c index 244f3ad0885e..fef7c8a445f9 100644 --- a/sys/dev/ata/ata-isa.c +++ b/sys/dev/ata/ata-isa.c @@ -135,7 +135,7 @@ ata_dmasetup(struct ata_device *atadev, caddr_t data, int32_t count) } void -ata_dmastart(struct ata_device *atadev, int dir) +ata_dmastart(struct ata_device *atadev, caddr_t data, int32_t count, int dir) { } diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index a48d79ec8dca..2b47ef4ac094 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -287,7 +287,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, 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)