From 2251888d9900832cd7eb382ff2ce527557ff48a4 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 18 Feb 2004 02:47:38 +0000 Subject: [PATCH] ATAng stage 5: sync additional function API changes from FBsd-4. We now have everything except the dma chipset changes and the busdma changes. Note that we retain our MPIPE code as it is far superior to what is in 4.x and 5.x. --- sys/dev/disk/ata/ata-all.h | 23 +++++++++++--- sys/dev/disk/ata/ata-disk.c | 21 ++++++------- sys/dev/disk/ata/ata-disk.h | 3 +- sys/dev/disk/ata/ata-dma.c | 61 ++++++++++++++++++++++-------------- sys/dev/disk/ata/ata-isa.c | 9 +++--- sys/dev/disk/ata/atapi-all.c | 25 ++++++--------- 6 files changed, 79 insertions(+), 63 deletions(-) diff --git a/sys/dev/disk/ata/ata-all.h b/sys/dev/disk/ata/ata-all.h index b38afbc2a5..fa724701f0 100644 --- a/sys/dev/disk/ata/ata-all.h +++ b/sys/dev/disk/ata/ata-all.h @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-all.h,v 1.26.2.12 2003/01/30 07:19:59 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/ata-all.h,v 1.6 2004/02/18 02:01:37 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/ata-all.h,v 1.7 2004/02/18 02:47:38 dillon Exp $ */ #ifndef _SYS_MPIPE_H_ @@ -163,6 +163,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; @@ -182,6 +194,7 @@ struct ata_device { int mode; /* transfermode */ int cmd; /* last cmd executed */ void *result; /* misc data */ + struct ata_dmastate dmastate; }; /* structure describing an ATA channel */ @@ -270,12 +283,12 @@ 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, int); -void ata_dmafree(struct ata_channel *, void *buf); +int ata_dmaalloc(struct ata_device *, int); +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_channel *, int, struct ata_dmaentry *, caddr_t, int); -void ata_dmastart(struct ata_channel *, int, struct ata_dmaentry *, int); +int ata_dmasetup(struct ata_device *, caddr_t, 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/disk/ata/ata-disk.c b/sys/dev/disk/ata/ata-disk.c index 07be2e17b6..2815e311b7 100644 --- a/sys/dev/disk/ata/ata-disk.c +++ b/sys/dev/disk/ata/ata-disk.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-disk.c,v 1.60.2.24 2003/01/30 07:19:59 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/ata-disk.c,v 1.12 2004/02/18 01:35:59 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/ata-disk.c,v 1.13 2004/02/18 02:47:38 dillon Exp $ */ #include "opt_ata.h" @@ -252,6 +252,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; @@ -421,8 +422,7 @@ ad_start(struct ata_device *atadev) if (bp->b_flags & B_READ) request->flags |= ADR_F_READ; if (adp->device->mode >= ATA_DMA) { - request->dmatab = ata_dmaalloc(atadev->channel, atadev->unit, M_NOWAIT); - if (request->dmatab == NULL) { + if (ata_dmaalloc(atadev, M_NOWAIT) != 0) { mpipe_free(&atadev->channel->req_mpipe, request); ata_prtdev(atadev, "pipeline full allocated dmabuf in ad_start\n"); /* do not revert to PIO, wait for ad_start after I/O completion */ @@ -490,8 +490,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; @@ -540,8 +539,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; } @@ -802,8 +801,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; @@ -813,9 +812,7 @@ static void ad_free(struct ad_request *request) { int s = splbio(); - - if (request->dmatab) - ata_dmafree(request->softc->device->channel, request->dmatab); + ata_dmafree(request->softc->device); request->softc->tags[request->tag] = NULL; mpipe_free(&request->softc->device->channel->req_mpipe, request); splx(s); diff --git a/sys/dev/disk/ata/ata-disk.h b/sys/dev/disk/ata/ata-disk.h index ba19f65514..4bdae1a175 100644 --- a/sys/dev/disk/ata/ata-disk.h +++ b/sys/dev/disk/ata/ata-disk.h @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-disk.h,v 1.22.2.7 2002/03/18 08:37:33 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/ata-disk.h,v 1.3 2004/02/18 00:37:08 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/ata-disk.h,v 1.4 2004/02/18 02:47:38 dillon Exp $ */ /* structure describing an ATA disk request */ @@ -49,7 +49,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/disk/ata/ata-dma.c b/sys/dev/disk/ata/ata-dma.c index 9533742965..2fec25215c 100644 --- a/sys/dev/disk/ata/ata-dma.c +++ b/sys/dev/disk/ata/ata-dma.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-dma.c,v 1.35.2.31 2003/05/07 16:46:11 jhb Exp $ - * $DragonFly: src/sys/dev/disk/ata/ata-dma.c,v 1.13 2004/02/18 02:01:37 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/ata-dma.c,v 1.14 2004/02/18 02:47:38 dillon Exp $ */ #include @@ -62,22 +62,28 @@ static int hpt_cable80(struct ata_device *); (atadev->unit == ATA_SLAVE && \ atadev->channel->devices & ATA_ATAPI_SLAVE)) -void * -ata_dmaalloc(struct ata_channel *ch, int device, int flags) +int +ata_dmaalloc(struct ata_device *atadev, int flags) { - void *dmatab; + struct ata_channel *ch = atadev->channel; KKASSERT(ch->dma_mpipe.max_count != 0); - dmatab = mpipe_alloc(&ch->dma_mpipe, flags); - KKASSERT(((uintptr_t)dmatab & PAGE_MASK) == 0); - return (dmatab); + atadev->dmastate.dmatab = mpipe_alloc(&ch->dma_mpipe, flags); + KKASSERT(((uintptr_t)atadev->dmastate.dmatab & PAGE_MASK) == 0); + if (atadev->dmastate.dmatab) + return(0); + return(ENOBUFS); } void -ata_dmafree(struct ata_channel *ch, void *dmatab) +ata_dmafree(struct ata_device *atadev) { - if (dmatab) - mpipe_free(&ch->dma_mpipe, dmatab); + struct ata_channel *ch = atadev->channel; + + if (atadev->dmastate.dmatab) { + mpipe_free(&ch->dma_mpipe, atadev->dmastate.dmatab); + atadev->dmastate.dmatab = NULL; + } } void @@ -1220,19 +1226,20 @@ ata_dmainit(struct ata_device *atadev, int apiomode, 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) { + struct ata_channel *ch = atadev->channel; + struct ata_dmastate *ds = &atadev->dmastate; u_int32_t dma_count, dma_base; int i = 0; 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; } @@ -1242,11 +1249,11 @@ ata_dmasetup(struct ata_channel *ch, int device, struct ata_dmaentry *dmatab, count -= dma_count; while (count) { - dmatab[i].base = dma_base; - dmatab[i].count = (dma_count & 0xffff); + ds->dmatab[i].base = dma_base; + ds->dmatab[i].count = (dma_count & 0xffff); i++; if (i >= ATA_DMA_ENTRIES) { - ata_printf(ch, device, "too many segments in DMA table\n"); + ata_prtdev(atadev, "too many segments in DMA table\n"); return -1; } dma_base = vtophys(data); @@ -1254,39 +1261,45 @@ ata_dmasetup(struct ata_channel *ch, int device, struct ata_dmaentry *dmatab, data += imin(count, PAGE_SIZE); count -= imin(count, PAGE_SIZE); } - dmatab[i].base = dma_base; - dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; + ds->dmatab[i].base = dma_base; + ds->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; + ch->flags |= ATA_DMA_ACTIVE; - ATA_OUTL(ch->r_bmio, ATA_BMDTP_PORT, vtophys(dmatab)); + ATA_OUTL(ch->r_bmio, ATA_BMDTP_PORT, vtophys(ds->dmatab)); 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_device *atadev) { struct ata_channel *ch; + struct ata_dmastate *ds; int error; ch = atadev->channel; + ds = &atadev->dmastate; 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; } diff --git a/sys/dev/disk/ata/ata-isa.c b/sys/dev/disk/ata/ata-isa.c index ca78dcebbc..dce96deea7 100644 --- a/sys/dev/disk/ata/ata-isa.c +++ b/sys/dev/disk/ata/ata-isa.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-isa.c,v 1.4.2.1 2002/03/18 08:37:33 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/ata-isa.c,v 1.6 2004/02/18 02:01:37 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/ata-isa.c,v 1.7 2004/02/18 02:47:38 dillon Exp $ */ #include @@ -109,13 +109,13 @@ DRIVER_MODULE(ata, isa, ata_isa_driver, ata_devclass, 0, 0); #include "use_pci.h" #if NPCI == 0 void * -ata_dmaalloc(struct ata_channel *ch, int device, int flags) +ata_dmaalloc(struct ata_device *atadev, int flags) { return 0; } void -ata_dmafree(struct ata_channel *ch, void *dmatab) +ata_dmafree(struct ata_device *atadev) { } @@ -137,8 +137,7 @@ ata_dmasetup(struct ata_channel *ch, int device, struct ata_dmaentry *dmatab, } 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) { } diff --git a/sys/dev/disk/ata/atapi-all.c b/sys/dev/disk/ata/atapi-all.c index 07d959cf65..72547f4736 100644 --- a/sys/dev/disk/ata/atapi-all.c +++ b/sys/dev/disk/ata/atapi-all.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/atapi-all.c,v 1.46.2.18 2002/10/31 23:10:33 thomas Exp $ - * $DragonFly: src/sys/dev/disk/ata/atapi-all.c,v 1.7 2004/02/18 00:50:00 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/atapi-all.c,v 1.8 2004/02/18 02:47:38 dillon Exp $ */ #include "opt_ata.h" @@ -162,8 +162,7 @@ atapi_detach(struct ata_device *atadev) bp->b_error = ENXIO; biodone(bp); } - if (request->dmatab) - ata_dmafree(atadev->channel, request->dmatab); + ata_dmafree(atadev); free(request, M_ATAPI); } free(atadev->result, M_ATAPI); @@ -199,11 +198,10 @@ atapi_queue_cmd(struct ata_device *atadev, int8_t *ccb, caddr_t data, request->driver = driver; } if (atadev->mode >= ATA_DMA) { - request->dmatab = ata_dmaalloc(atadev->channel, atadev->unit, M_NOWAIT); - if (request->dmatab == NULL) { + if (ata_dmaalloc(atadev, M_NOWAIT) != 0) { printf("WARNING: atapi_queue_cmd: ata_dmaalloc() would block\n"); - request->dmatab = ata_dmaalloc(atadev->channel, - atadev->unit, M_WAITOK); + error = ata_dmaalloc(atadev, M_WAITOK); + KKASSERT(error != 0); } } @@ -232,8 +230,7 @@ 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) - ata_dmafree(atadev->channel, request->dmatab); + ata_dmafree(atadev); free(request, M_ATAPI); return error; } @@ -301,8 +298,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; } @@ -314,8 +310,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) @@ -612,8 +608,7 @@ atapi_finish(struct atapi_request *request) #endif if (request->callback) { if (!((request->callback)(request))) { - if (request->dmatab) - ata_dmafree(request->device->channel, request->dmatab); + ata_dmafree(request->device); free(request, M_ATAPI); } } -- 2.41.0