svn commit: r233393 - in stable/9/sys: dev/acpica dev/cardbus
dev/pci i386/conf powerpc/ofw sparc64/pci
John Baldwin
jhb at FreeBSD.org
Fri Mar 23 20:47:26 UTC 2012
Author: jhb
Date: Fri Mar 23 20:47:25 2012
New Revision: 233393
URL: http://svn.freebsd.org/changeset/base/233393
Log:
MFC 232403,232667:
- Add a bus_dma tag to each PCI bus that is a child of a Host-PCI bridge.
The tag enforces a single restriction that all DMA transactions must not
cross a 4GB boundary. Note that while this restriction technically only
applies to PCI-express, this change applies it to all PCI devices as it
is simpler to implement that way and errs on the side of caution.
- Add a softc structure for PCI bus devices to hold the bus_dma tag and
a new pci_attach_common() routine that performs actions common to the
attach phase of all PCI bus drivers. Right now this only consists of
a bootverbose printf and the allocate of a bus_dma tag if necessary.
- Adjust all PCI bus drivers to allocate a PCI bus softc and to call
pci_attach_common() from their attach routines.
Modified:
stable/9/sys/dev/acpica/acpi_pci.c
stable/9/sys/dev/cardbus/cardbus.c
stable/9/sys/dev/pci/pci.c
stable/9/sys/dev/pci/pci_private.h
stable/9/sys/powerpc/ofw/ofw_pcibus.c
stable/9/sys/sparc64/pci/ofw_pcibus.c
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
stable/9/sys/fs/ (props changed)
stable/9/sys/fs/ntfs/ (props changed)
stable/9/sys/i386/conf/XENHVM (props changed)
Modified: stable/9/sys/dev/acpica/acpi_pci.c
==============================================================================
--- stable/9/sys/dev/acpica/acpi_pci.c Fri Mar 23 20:18:48 2012 (r233392)
+++ stable/9/sys/dev/acpica/acpi_pci.c Fri Mar 23 20:47:25 2012 (r233393)
@@ -99,7 +99,8 @@ static device_method_t acpi_pci_methods[
static devclass_t pci_devclass;
-DEFINE_CLASS_1(pci, acpi_pci_driver, acpi_pci_methods, 0, pci_driver);
+DEFINE_CLASS_1(pci, acpi_pci_driver, acpi_pci_methods, sizeof(struct pci_softc),
+ pci_driver);
DRIVER_MODULE(acpi_pci, pcib, acpi_pci_driver, pci_devclass, 0, 0);
MODULE_DEPEND(acpi_pci, acpi, 1, 1, 1);
MODULE_DEPEND(acpi_pci, pci, 1, 1, 1);
@@ -276,7 +277,11 @@ acpi_pci_probe(device_t dev)
static int
acpi_pci_attach(device_t dev)
{
- int busno, domain;
+ int busno, domain, error;
+
+ error = pci_attach_common(dev);
+ if (error)
+ return (error);
/*
* Since there can be multiple independantly numbered PCI
@@ -286,9 +291,6 @@ acpi_pci_attach(device_t dev)
*/
domain = pcib_get_domain(dev);
busno = pcib_get_bus(dev);
- if (bootverbose)
- device_printf(dev, "domain=%d, physical bus=%d\n",
- domain, busno);
/*
* First, PCI devices are added as in the normal PCI bus driver.
Modified: stable/9/sys/dev/cardbus/cardbus.c
==============================================================================
--- stable/9/sys/dev/cardbus/cardbus.c Fri Mar 23 20:18:48 2012 (r233392)
+++ stable/9/sys/dev/cardbus/cardbus.c Fri Mar 23 20:47:25 2012 (r233393)
@@ -316,6 +316,7 @@ static device_method_t cardbus_methods[]
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),
Modified: stable/9/sys/dev/pci/pci.c
==============================================================================
--- stable/9/sys/dev/pci/pci.c Fri Mar 23 20:18:48 2012 (r233392)
+++ stable/9/sys/dev/pci/pci.c Fri Mar 23 20:47:25 2012 (r233393)
@@ -70,6 +70,21 @@ __FBSDID("$FreeBSD$");
#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.
+ */
+#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
+#ifdef PAE
+#define PCI_DMA_BOUNDARY 0x80000000
+#else
+#define PCI_DMA_BOUNDARY 0x100000000
+#endif
+#endif
+
#define PCIR_IS_BIOS(cfg, reg) \
(((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \
((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1))
@@ -95,6 +110,7 @@ static void pci_load_vendor_data(void);
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);
@@ -137,6 +153,7 @@ static device_method_t pci_methods[] = {
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),
@@ -173,7 +190,7 @@ static device_method_t pci_methods[] = {
DEVMETHOD_END
};
-DEFINE_CLASS_0(pci, pci_driver, pci_methods, 0);
+DEFINE_CLASS_0(pci, pci_driver, pci_methods, sizeof(struct pci_softc));
static devclass_t pci_devclass;
DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0);
@@ -3160,10 +3177,49 @@ pci_probe(device_t dev)
return (BUS_PROBE_GENERIC);
}
+int
+pci_attach_common(device_t dev)
+{
+ struct pci_softc *sc;
+ int busno, domain;
+#ifdef PCI_DMA_BOUNDARY
+ int error, tag_valid;
+#endif
+
+ sc = device_get_softc(dev);
+ domain = pcib_get_domain(dev);
+ busno = pcib_get_bus(dev);
+ if (bootverbose)
+ device_printf(dev, "domain=%d, physical bus=%d\n",
+ domain, busno);
+#ifdef PCI_DMA_BOUNDARY
+ tag_valid = 0;
+ if (device_get_devclass(device_get_parent(device_get_parent(dev))) !=
+ devclass_find("pci")) {
+ 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
+ tag_valid = 1;
+ }
+ if (!tag_valid)
+#endif
+ sc->sc_dma_tag = bus_get_dma_tag(dev);
+ return (0);
+}
+
static int
pci_attach(device_t dev)
{
- int busno, domain;
+ int busno, domain, error;
+
+ error = pci_attach_common(dev);
+ if (error)
+ return (error);
/*
* Since there can be multiple independantly numbered PCI
@@ -3173,9 +3229,6 @@ pci_attach(device_t dev)
*/
domain = pcib_get_domain(dev);
busno = pcib_get_bus(dev);
- if (bootverbose)
- device_printf(dev, "domain=%d, physical bus=%d\n",
- domain, busno);
pci_add_children(dev, domain, busno, sizeof(struct pci_devinfo));
return (bus_generic_attach(dev));
}
@@ -4262,6 +4315,14 @@ pci_get_resource_list (device_t dev, dev
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);
+
+ return (sc->sc_dma_tag);
+}
+
uint32_t
pci_read_config_method(device_t dev, device_t child, int reg, int width)
{
Modified: stable/9/sys/dev/pci/pci_private.h
==============================================================================
--- stable/9/sys/dev/pci/pci_private.h Fri Mar 23 20:18:48 2012 (r233392)
+++ stable/9/sys/dev/pci/pci_private.h Fri Mar 23 20:47:25 2012 (r233393)
@@ -38,6 +38,10 @@
*/
DECLARE_CLASS(pci_driver);
+struct pci_softc {
+ bus_dma_tag_t sc_dma_tag;
+};
+
extern int pci_do_power_resume;
extern int pci_do_power_suspend;
@@ -46,6 +50,7 @@ void pci_add_children(device_t dev, int
void pci_add_child(device_t bus, struct pci_devinfo *dinfo);
void pci_add_resources(device_t bus, device_t dev, int force,
uint32_t prefetchmask);
+int pci_attach_common(device_t dev);
void pci_delete_child(device_t dev, device_t child);
void pci_driver_added(device_t dev, driver_t *driver);
int pci_print_child(device_t dev, device_t child);
Modified: stable/9/sys/powerpc/ofw/ofw_pcibus.c
==============================================================================
--- stable/9/sys/powerpc/ofw/ofw_pcibus.c Fri Mar 23 20:18:48 2012 (r233392)
+++ stable/9/sys/powerpc/ofw/ofw_pcibus.c Fri Mar 23 20:47:25 2012 (r233393)
@@ -95,8 +95,8 @@ struct ofw_pcibus_devinfo {
static devclass_t pci_devclass;
-DEFINE_CLASS_1(pci, ofw_pcibus_driver, ofw_pcibus_methods, 1 /* no softc */,
- pci_driver);
+DEFINE_CLASS_1(pci, ofw_pcibus_driver, ofw_pcibus_methods,
+ sizeof(struct pci_softc), pci_driver);
DRIVER_MODULE(ofw_pcibus, pcib, ofw_pcibus_driver, pci_devclass, 0, 0);
MODULE_VERSION(ofw_pcibus, 1);
MODULE_DEPEND(ofw_pcibus, pci, 1, 1, 1);
@@ -116,12 +116,13 @@ static int
ofw_pcibus_attach(device_t dev)
{
u_int busno, domain;
+ int error;
+ error = pci_attach_common(dev);
+ if (error)
+ return (error);
domain = pcib_get_domain(dev);
busno = pcib_get_bus(dev);
- if (bootverbose)
- device_printf(dev, "domain=%d, physical bus=%d\n",
- domain, busno);
/*
* Attach those children represented in the device tree.
Modified: stable/9/sys/sparc64/pci/ofw_pcibus.c
==============================================================================
--- stable/9/sys/sparc64/pci/ofw_pcibus.c Fri Mar 23 20:18:48 2012 (r233392)
+++ stable/9/sys/sparc64/pci/ofw_pcibus.c Fri Mar 23 20:47:25 2012 (r233393)
@@ -100,8 +100,8 @@ struct ofw_pcibus_devinfo {
static devclass_t pci_devclass;
-DEFINE_CLASS_1(pci, ofw_pcibus_driver, ofw_pcibus_methods, 1 /* no softc */,
- pci_driver);
+DEFINE_CLASS_1(pci, ofw_pcibus_driver, ofw_pcibus_methods,
+ sizeof(struct pci_softc), pci_driver);
EARLY_DRIVER_MODULE(ofw_pcibus, pcib, ofw_pcibus_driver, pci_devclass, 0, 0,
BUS_PASS_BUS);
MODULE_VERSION(ofw_pcibus, 1);
@@ -230,13 +230,14 @@ ofw_pcibus_attach(device_t dev)
phandle_t node, child;
uint32_t clock;
u_int busno, domain, func, slot;
+ int error;
+ error = pci_attach_common(dev);
+ if (error)
+ return (error);
pcib = device_get_parent(dev);
domain = pcib_get_domain(dev);
busno = pcib_get_bus(dev);
- if (bootverbose)
- device_printf(dev, "domain=%d, physical bus=%d\n",
- domain, busno);
node = ofw_bus_get_node(dev);
/*
More information about the svn-src-stable-9
mailing list