Date: Tue, 28 Feb 2012 19:40:58 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 207043 for review Message-ID: <201202281940.q1SJewKa062213@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@207043?ac=10 Change 207043 by jhb@jhb_jhbbsd on 2012/02/28 19:40:26 Add a bus dma tag to PCI to enforce a 4GB boundary on all transactions. Affected files ... .. //depot/projects/pci/sys/dev/cardbus/cardbus.c#5 edit .. //depot/projects/pci/sys/dev/pci/pci.c#27 edit .. //depot/projects/pci/sys/dev/pci/pci_private.h#7 edit Differences ... ==== //depot/projects/pci/sys/dev/cardbus/cardbus.c#5 (text+ko) ==== @@ -316,6 +316,7 @@ DEVMETHOD(device_resume, cardbus_resume), /* Bus interface */ + DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), DEVMETHOD(bus_read_ivar, cardbus_read_ivar), DEVMETHOD(bus_driver_added, cardbus_driver_added), ==== //depot/projects/pci/sys/dev/pci/pci.c#27 (text+ko) ==== @@ -70,6 +70,19 @@ #include "pcib_if.h" #include "pci_if.h" +/* + * XXX: Due to a limitation of the bus_dma_tag_create() API, we cannot + * specify a 4GB boundary on 32-bit targets. Usually this does not + * matter as it is ok to use a boundary of 0 on these systems. + * However, in the case of PAE, DMA addresses can cross a 4GB + * boundary, so as a workaround use a 2GB boundary. + */ +#ifdef PAE +#define PCI_DMA_BOUNDARY (1u << 31) +#else +#define PCI_DMA_BOUNDARY ((bus_size_t)((bus_addr_t)1 << 32)) +#endif + #define PCIR_IS_BIOS(cfg, reg) \ (((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \ ((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1)) @@ -98,6 +111,7 @@ static int pci_describe_parse_line(char **ptr, int *vendor, int *device, char **desc); static char *pci_describe_device(device_t dev); +static bus_dma_tag_t pci_get_dma_tag(device_t bus, device_t dev); static int pci_modevent(module_t mod, int what, void *arg); static void pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg); @@ -144,6 +158,7 @@ DEVMETHOD(bus_setup_intr, pci_setup_intr), DEVMETHOD(bus_teardown_intr, pci_teardown_intr), + DEVMETHOD(bus_get_dma_tag, pci_get_dma_tag), DEVMETHOD(bus_get_resource_list,pci_get_resource_list), DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), @@ -3139,16 +3154,16 @@ int pci_attach_common(device_t dev) { + struct pci_softc *sc; + int busno, domain, error; #ifdef PCI_RES_BUS - struct pci_softc *sc; int rid; #endif - int busno, domain; + sc = device_get_softc(dev); domain = pcib_get_domain(dev); busno = pcib_get_bus(dev); #ifdef PCI_RES_BUS - sc = device_get_softc(dev); rid = 0; sc->sc_bus = bus_alloc_resource(dev, PCI_RES_BUS, &rid, busno, busno, 1, 0); @@ -3160,6 +3175,15 @@ if (bootverbose) device_printf(dev, "domain=%d, physical bus=%d\n", domain, busno); + error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, PCI_DMA_BOUNDARY, + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, BUS_SPACE_MAXSIZE, + BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE, 0, NULL, NULL, + &sc->sc_dma_tag); + if (error) + device_printf(dev, "Failed to create DMA tag: %d\n", error); + else + sc->sc_dma_tag_valid = 1; + return (0); } @@ -4281,6 +4305,16 @@ return (&dinfo->resources); } +bus_dma_tag_t +pci_get_dma_tag(device_t bus, device_t dev) +{ + struct pci_softc *sc = device_get_softc(bus); + + if (sc->sc_dma_tag_valid) + return (sc->sc_dma_tag); + return (bus_generic_get_dma_tag(bus, dev)); +} + uint32_t pci_read_config_method(device_t dev, device_t child, int reg, int width) { ==== //depot/projects/pci/sys/dev/pci/pci_private.h#7 (text+ko) ==== @@ -39,6 +39,8 @@ DECLARE_CLASS(pci_driver); struct pci_softc { + bus_dma_tag_t sc_dma_tag; + int sc_dma_tag_valid; #ifdef PCI_RES_BUS struct resource *sc_bus; #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202281940.q1SJewKa062213>