From c25fb06d921a770f65a0f6e25dc1e92e4e1b5227 Mon Sep 17 00:00:00 2001 From: jmg Date: Sun, 3 Sep 2006 00:27:42 +0000 Subject: [PATCH] add a newbus method for obtaining the bus's bus_dma_tag_t... This is required by arches like sparc64 (not yet implemented) and sun4v where there are seperate IOMMU's for each PCI bus... For all other arches, it will end up returning NULL, which makes it a no-op... Convert a few drivers (the ones we've been working w/ on sun4v) to the new convection... Eventually all drivers will need to replace the parent tag of NULL, w/ bus_get_dma_tag(dev), though dev is usually different for each driver, and will require hand inspection... Reviewed by: scottl (earlier version) --- sys/dev/aic7xxx/ahc_eisa.c | 4 ++-- sys/dev/aic7xxx/ahc_isa.c | 4 ++-- sys/dev/aic7xxx/ahc_pci.c | 4 ++-- sys/dev/aic7xxx/ahd_pci.c | 4 ++-- sys/dev/ata/ata-dma.c | 2 +- sys/dev/bge/if_bge.c | 2 +- sys/dev/em/if_em.c | 6 +++--- sys/dev/gem/if_gem.c | 7 ++++--- sys/dev/isp/isp_pci.c | 5 +++-- sys/dev/usb/ohci_pci.c | 8 ++++---- sys/kern/bus_if.m | 11 +++++++++++ sys/kern/subr_bus.c | 33 +++++++++++++++++++++++++++++++++ sys/sys/bus.h | 5 +++++ 13 files changed, 73 insertions(+), 22 deletions(-) diff --git a/sys/dev/aic7xxx/ahc_eisa.c b/sys/dev/aic7xxx/ahc_eisa.c index f98059f69016..8c6e4df444d8 100644 --- a/sys/dev/aic7xxx/ahc_eisa.c +++ b/sys/dev/aic7xxx/ahc_eisa.c @@ -131,8 +131,8 @@ aic7770_attach(device_t dev) /* Allocate a dmatag for our SCB DMA maps */ /* XXX Should be a child of the PCI bus dma tag */ - error = aic_dma_tag_create(ahc, /*parent*/NULL, /*alignment*/1, - /*boundary*/0, + error = aic_dma_tag_create(ahc, /*parent*/bus_get_dma_tag(dev), + /*alignment*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, diff --git a/sys/dev/aic7xxx/ahc_isa.c b/sys/dev/aic7xxx/ahc_isa.c index d01ffc96d3f8..0bf0f537274e 100644 --- a/sys/dev/aic7xxx/ahc_isa.c +++ b/sys/dev/aic7xxx/ahc_isa.c @@ -254,8 +254,8 @@ ahc_isa_attach(device_t dev) /* Allocate a dmatag for our SCB DMA maps */ /* XXX Should be a child of the VLB/ISA bus dma tag */ - error = aic_dma_tag_create(ahc, /*parent*/NULL, /*alignment*/1, - /*boundary*/0, + error = aic_dma_tag_create(ahc, /*parent*/bus_get_dma_tag(dev), + /*alignment*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, diff --git a/sys/dev/aic7xxx/ahc_pci.c b/sys/dev/aic7xxx/ahc_pci.c index 4a4889c49707..50297269d1b7 100644 --- a/sys/dev/aic7xxx/ahc_pci.c +++ b/sys/dev/aic7xxx/ahc_pci.c @@ -107,8 +107,8 @@ ahc_pci_attach(device_t dev) /* Allocate a dmatag for our SCB DMA maps */ /* XXX Should be a child of the PCI bus dma tag */ - error = aic_dma_tag_create(ahc, /*parent*/NULL, /*alignment*/1, - /*boundary*/0, + error = aic_dma_tag_create(ahc, /*parent*/bus_get_dma_tag(dev), + /*alignment*/1, /*boundary*/0, (ahc->flags & AHC_39BIT_ADDRESSING) ? 0x7FFFFFFFFFLL : BUS_SPACE_MAXADDR_32BIT, diff --git a/sys/dev/aic7xxx/ahd_pci.c b/sys/dev/aic7xxx/ahd_pci.c index 8f2e65e61dad..03b136349cf3 100644 --- a/sys/dev/aic7xxx/ahd_pci.c +++ b/sys/dev/aic7xxx/ahd_pci.c @@ -109,8 +109,8 @@ ahd_pci_attach(device_t dev) /* Allocate a dmatag for our SCB DMA maps */ /* XXX Should be a child of the PCI bus dma tag */ - error = aic_dma_tag_create(ahd, /*parent*/NULL, /*alignment*/1, - /*boundary*/0, + error = aic_dma_tag_create(ahd, /*parent*/bus_get_dma_tag(dev), + /*alignment*/1, /*boundary*/0, (ahd->flags & AHD_39BIT_ADDRESSING) ? 0x7FFFFFFFFF : BUS_SPACE_MAXADDR_32BIT, diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index 6f94084d3b66..87f49cd7c093 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -96,7 +96,7 @@ ata_dmaalloc(device_t dev) struct ata_channel *ch = device_get_softc(dev); struct ata_dc_cb_args ccba; - if (bus_dma_tag_create(NULL, ch->dma->alignment, 0, + if (bus_dma_tag_create(bus_get_dma_tag(dev), ch->dma->alignment, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, ch->dma->max_iosize, ATA_DMA_ENTRIES, ch->dma->segsize, diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index d137b05683f1..229e81c1d771 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -1702,7 +1702,7 @@ bge_dma_alloc(device_t dev) /* * Allocate the parent bus DMA tag appropriate for PCI. */ - error = bus_dma_tag_create(NULL, /* parent */ + error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev),/* parent */ PAGE_SIZE, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c index 66ab3cc3e5c2..8fbdf22f2ab4 100644 --- a/sys/dev/em/if_em.c +++ b/sys/dev/em/if_em.c @@ -2389,7 +2389,7 @@ em_dma_malloc(struct adapter *adapter, bus_size_t size, struct em_dma_alloc *dma { int error; - error = bus_dma_tag_create(NULL, /* parent */ + error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */ EM_DBA_ALIGN, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -2493,7 +2493,7 @@ em_setup_transmit_structures(struct adapter *adapter) * Setup DMA descriptor areas. */ size = roundup2(adapter->hw.max_frame_size, MCLBYTES); - if ((error = bus_dma_tag_create(NULL, /* parent */ + if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -2905,7 +2905,7 @@ em_allocate_receive_structures(struct adapter *adapter) bzero(adapter->rx_buffer_area, sizeof(struct em_buffer) * adapter->num_rx_desc); - error = bus_dma_tag_create(NULL, /* parent */ + error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ diff --git a/sys/dev/gem/if_gem.c b/sys/dev/gem/if_gem.c index 3efe0ed711a1..ed9fd56488f1 100644 --- a/sys/dev/gem/if_gem.c +++ b/sys/dev/gem/if_gem.c @@ -153,9 +153,10 @@ gem_attach(sc) gem_reset(sc); GEM_UNLOCK(sc); - error = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, - BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, GEM_NSEGS, - BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, &sc->sc_pdmatag); + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + MCLBYTES, GEM_NSEGS, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, + &sc->sc_pdmatag); if (error) goto fail_ifnet; diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 7ea7dbf5bc7c..749ca3345d99 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -1442,8 +1442,9 @@ isp_pci_mbxdma(ispsoftc_t *isp) #endif ISP_UNLOCK(isp); - if (isp_dma_tag_create(NULL, 1, slim, llim, hlim, - NULL, NULL, BUS_SPACE_MAXSIZE, ISP_NSEGS, slim, 0, &pcs->dmat)) { + if (isp_dma_tag_create(bus_get_dma_tag(pcs->pci_dev), 1, slim, llim, + hlim, NULL, NULL, BUS_SPACE_MAXSIZE, ISP_NSEGS, slim, 0, + &pcs->dmat)) { isp_prt(isp, ISP_LOGERR, "could not create master dma tag"); ISP_LOCK(isp); return (1); diff --git a/sys/dev/usb/ohci_pci.c b/sys/dev/usb/ohci_pci.c index 1401a4b0316f..78bc401a8efa 100644 --- a/sys/dev/usb/ohci_pci.c +++ b/sys/dev/usb/ohci_pci.c @@ -307,10 +307,10 @@ ohci_pci_attach(device_t self) } /* Allocate a parent dma tag for DMA maps */ - err = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, - BUS_SPACE_MAXADDR, NULL, NULL, BUS_SPACE_MAXSIZE_32BIT, - USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, - &sc->sc_bus.parent_dmatag); + err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0, + NULL, NULL, &sc->sc_bus.parent_dmatag); if (err) { device_printf(self, "Could not allocate parent DMA tag (%d)\n", err); diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m index 05aad097c735..529b506f1b68 100644 --- a/sys/kern/bus_if.m +++ b/sys/kern/bus_if.m @@ -529,3 +529,14 @@ METHOD void hinted_child { const char * _dname; int _dunit; }; + +/** + * @brief Returns bus_dma_tag_t for use w/ devices on the bus. + * + * @param _dev the parent device of @p _child + * @param _child the device to which the tag will belong + */ +METHOD bus_dma_tag_t get_dma_tag { + device_t _dev; + device_t _child; +} DEFAULT bus_generic_get_dma_tag; diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index ad2764de019e..3f0a9e21934e 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -3198,6 +3198,22 @@ bus_generic_config_intr(device_t dev, int irq, enum intr_trigger trig, return (EINVAL); } +/** + * @brief Helper function for implementing BUS_GET_DMA_TAG(). + * + * This simple implementation of BUS_GET_DMA_TAG() simply calls the + * BUS_GET_DMA_TAG() method of the parent of @p dev. + */ +bus_dma_tag_t +bus_generic_get_dma_tag(device_t dev, device_t child) +{ + + /* Propagate up the bus hierarchy until someone handles it. */ + if (dev->parent != NULL) + return (BUS_GET_DMA_TAG(dev->parent, child)); + return (NULL); +} + /** * @brief Helper function for implementing BUS_GET_RESOURCE(). * @@ -3599,6 +3615,23 @@ bus_child_location_str(device_t child, char *buf, size_t buflen) return (BUS_CHILD_LOCATION_STR(parent, child, buf, buflen)); } +/** + * @brief Wrapper function for BUS_GET_DMA_TAG(). + * + * This function simply calls the BUS_GET_DMA_TAG() method of the + * parent of @p dev. + */ +bus_dma_tag_t +bus_get_dma_tag(device_t dev) +{ + device_t parent; + + parent = device_get_parent(dev); + if (parent == NULL) + return (NULL); + return (BUS_GET_DMA_TAG(parent, dev)); +} + /* Resume all devices and then notify userland that we're up again. */ static int root_resume(device_t dev) diff --git a/sys/sys/bus.h b/sys/sys/bus.h index eccf10c03494..17cbda0eae5f 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -29,6 +29,8 @@ #ifndef _SYS_BUS_H_ #define _SYS_BUS_H_ +#include + /** * @defgroup NEWBUS newbus - a generic framework for managing devices * @{ @@ -252,6 +254,8 @@ int bus_generic_deactivate_resource(device_t dev, device_t child, int type, int rid, struct resource *r); int bus_generic_detach(device_t dev); void bus_generic_driver_added(device_t dev, driver_t *driver); +bus_dma_tag_t + bus_generic_get_dma_tag(device_t dev, device_t child); struct resource_list * bus_generic_get_resource_list (device_t, device_t); int bus_print_child_header(device_t dev, device_t child); @@ -306,6 +310,7 @@ int bus_activate_resource(device_t dev, int type, int rid, struct resource *r); int bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r); +bus_dma_tag_t bus_get_dma_tag(device_t dev); int bus_release_resource(device_t dev, int type, int rid, struct resource *r); int bus_free_resource(device_t dev, int type, struct resource *r);