Skip site navigation (1)Skip section navigation (2)
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>