svn commit: r262225 - in stable: 10/sys/dev/pci 9/sys/dev/pci

John Baldwin jhb at FreeBSD.org
Wed Feb 19 18:34:48 UTC 2014


Author: jhb
Date: Wed Feb 19 18:34:47 2014
New Revision: 262225
URL: http://svnweb.freebsd.org/changeset/base/262225

Log:
  MFC 261524,261526,261527:
  - Properly set the alignment flags when allocating the initial range for a
    BAR.  This only really matters when pci_do_realloc_bars is enabled and
    the initial allocation of a specific range fails.
  - Simplify pci_reserve_map() by calling resource_list_reserve() to allocate
    the resource after creating a resource list entry rather than reimplementing
    it by hand.
  - Add two tunables to ignore certain firmware-assigned resources.  These
    are mostly useful for debugging.
    - hw.pci.clear_bars ignores all firmware-assigned ranges for BARs when
      set.
    - hw.pci.clear_pcib ignores all firmware-assigned ranges for PCI-PCI
      bridge I/O windows when set.

Modified:
  stable/10/sys/dev/pci/pci.c
  stable/10/sys/dev/pci/pci_pci.c
Directory Properties:
  stable/10/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/9/sys/dev/pci/pci.c
  stable/9/sys/dev/pci/pci_pci.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/10/sys/dev/pci/pci.c
==============================================================================
--- stable/10/sys/dev/pci/pci.c	Wed Feb 19 17:44:59 2014	(r262224)
+++ stable/10/sys/dev/pci/pci.c	Wed Feb 19 18:34:47 2014	(r262225)
@@ -332,6 +332,11 @@ SYSCTL_INT(_hw_pci, OID_AUTO, usb_early_
 Disable this if you depend on BIOS emulation of USB devices, that is\n\
 you use USB devices (like keyboard or mouse) but do not load USB drivers");
 
+static int pci_clear_bars;
+TUNABLE_INT("hw.pci.clear_bars", &pci_clear_bars);
+SYSCTL_INT(_hw_pci, OID_AUTO, clear_bars, CTLFLAG_RDTUN, &pci_clear_bars, 0,
+    "Ignore firmware-assigned resources for BARs.");
+
 static int
 pci_has_quirk(uint32_t devid, int quirk)
 {
@@ -2742,7 +2747,7 @@ pci_add_map(device_t bus, device_t dev, 
 	struct pci_map *pm;
 	pci_addr_t base, map, testval;
 	pci_addr_t start, end, count;
-	int barlen, basezero, maprange, mapsize, type;
+	int barlen, basezero, flags, maprange, mapsize, type;
 	uint16_t cmd;
 	struct resource *res;
 
@@ -2848,7 +2853,10 @@ pci_add_map(device_t bus, device_t dev, 
 	}
 
 	count = (pci_addr_t)1 << mapsize;
-	if (basezero || base == pci_mapbase(testval)) {
+	flags = RF_ALIGNMENT_LOG2(mapsize);
+	if (prefetch)
+		flags |= RF_PREFETCHABLE;
+	if (basezero || base == pci_mapbase(testval) || pci_clear_bars) {
 		start = 0;	/* Let the parent decide. */
 		end = ~0ul;
 	} else {
@@ -2864,7 +2872,7 @@ pci_add_map(device_t bus, device_t dev, 
 	 * pci_alloc_resource().
 	 */
 	res = resource_list_reserve(rl, bus, dev, type, &reg, start, end, count,
-	    prefetch ? RF_PREFETCHABLE : 0);
+	    flags);
 	if (pci_do_realloc_bars && res == NULL && (start != 0 || end != ~0ul)) {
 		/*
 		 * If the allocation fails, try to allocate a resource for
@@ -2875,7 +2883,7 @@ pci_add_map(device_t bus, device_t dev, 
 		resource_list_delete(rl, type, reg);
 		resource_list_add(rl, type, reg, 0, ~0ul, count);
 		res = resource_list_reserve(rl, bus, dev, type, &reg, 0, ~0ul,
-		    count, prefetch ? RF_PREFETCHABLE : 0);
+		    count, flags);
 	}
 	if (res == NULL) {
 		/*
@@ -4174,7 +4182,6 @@ pci_reserve_map(device_t dev, device_t c
 {
 	struct pci_devinfo *dinfo = device_get_ivars(child);
 	struct resource_list *rl = &dinfo->resources;
-	struct resource_list_entry *rle;
 	struct resource *res;
 	struct pci_map *pm;
 	pci_addr_t map, testval;
@@ -4247,23 +4254,16 @@ pci_reserve_map(device_t dev, device_t c
 	 * Allocate enough resource, and then write back the
 	 * appropriate BAR for that resource.
 	 */
-	res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid,
-	    start, end, count, flags & ~RF_ACTIVE);
+	resource_list_add(rl, type, *rid, start, end, count);
+	res = resource_list_reserve(rl, dev, child, type, rid, start, end,
+	    count, flags & ~RF_ACTIVE);
 	if (res == NULL) {
+		resource_list_delete(rl, type, *rid);
 		device_printf(child,
 		    "%#lx bytes of rid %#x res %d failed (%#lx, %#lx).\n",
 		    count, *rid, type, start, end);
 		goto out;
 	}
-	resource_list_add(rl, type, *rid, start, end, count);
-	rle = resource_list_find(rl, type, *rid);
-	if (rle == NULL)
-		panic("pci_reserve_map: unexpectedly can't find resource.");
-	rle->res = res;
-	rle->start = rman_get_start(res);
-	rle->end = rman_get_end(res);
-	rle->count = count;
-	rle->flags = RLE_RESERVED;
 	if (bootverbose)
 		device_printf(child,
 		    "Lazy allocation of %#lx bytes rid %#x type %d at %#lx\n",

Modified: stable/10/sys/dev/pci/pci_pci.c
==============================================================================
--- stable/10/sys/dev/pci/pci_pci.c	Wed Feb 19 17:44:59 2014	(r262224)
+++ stable/10/sys/dev/pci/pci_pci.c	Wed Feb 19 18:34:47 2014	(r262225)
@@ -103,6 +103,12 @@ DEFINE_CLASS_0(pcib, pcib_driver, pcib_m
 DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, NULL, NULL);
 
 #ifdef NEW_PCIB
+SYSCTL_DECL(_hw_pci);
+
+static int pci_clear_pcib;
+TUNABLE_INT("hw.pci.clear_pcib", &pci_clear_pcib);
+SYSCTL_INT(_hw_pci, OID_AUTO, clear_pcib, CTLFLAG_RDTUN, &pci_clear_pcib, 0,
+    "Clear firmware-assigned resources for PCI-PCI bridge I/O windows.");
 
 /*
  * Is a resource from a child device sub-allocated from one of our
@@ -416,6 +422,19 @@ pcib_probe_windows(struct pcib_softc *sc
 
 	dev = sc->dev;
 
+	if (pci_clear_pcib) {
+		pci_write_config(dev, PCIR_IOBASEL_1, 0xff, 1);
+		pci_write_config(dev, PCIR_IOBASEH_1, 0xffff, 2);
+		pci_write_config(dev, PCIR_IOLIMITL_1, 0, 1);
+		pci_write_config(dev, PCIR_IOLIMITH_1, 0, 2);
+		pci_write_config(dev, PCIR_MEMBASE_1, 0xffff, 2);
+		pci_write_config(dev, PCIR_MEMLIMIT_1, 0, 2);
+		pci_write_config(dev, PCIR_PMBASEL_1, 0xffff, 2);
+		pci_write_config(dev, PCIR_PMBASEH_1, 0xffffffff, 4);
+		pci_write_config(dev, PCIR_PMLIMITL_1, 0, 2);
+		pci_write_config(dev, PCIR_PMLIMITH_1, 0, 4);
+	}
+
 	/* Determine if the I/O port window is implemented. */
 	val = pci_read_config(dev, PCIR_IOBASEL_1, 1);
 	if (val == 0) {


More information about the svn-src-all mailing list