svn commit: r251700 - stable/9/sys/dev/pci

John Baldwin jhb at FreeBSD.org
Thu Jun 13 20:29:07 UTC 2013


Author: jhb
Date: Thu Jun 13 20:29:06 2013
New Revision: 251700
URL: http://svnweb.freebsd.org/changeset/base/251700

Log:
  MFC 249315:
  Proxy allocation requests for the PCI ROM BAR from child devices similar
  to how the VGA bus driver currently proxies allocation requests for other
  PCI BARs.

Modified:
  stable/9/sys/dev/pci/vga_pci.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/pci/vga_pci.c
==============================================================================
--- stable/9/sys/dev/pci/vga_pci.c	Thu Jun 13 19:35:56 2013	(r251699)
+++ stable/9/sys/dev/pci/vga_pci.c	Thu Jun 13 20:29:06 2013	(r251700)
@@ -56,7 +56,8 @@ struct vga_resource {
 
 struct vga_pci_softc {
 	device_t	vga_msi_child;	/* Child driver using MSI. */
-	struct vga_resource vga_res[PCIR_MAX_BAR_0 + 1];
+	struct vga_resource vga_bars[PCIR_MAX_BAR_0 + 1];
+	struct vga_resource vga_bios;
 };
 
 SYSCTL_DECL(_hw_pci);
@@ -156,12 +157,24 @@ vga_pci_teardown_intr(device_t dev, devi
 	return (BUS_TEARDOWN_INTR(device_get_parent(dev), dev, irq, cookie));
 }
 
+static struct vga_resource *
+lookup_res(struct vga_pci_softc *sc, int rid)
+{
+	int bar;
+
+	if (rid == PCIR_BIOS)
+		return (&sc->vga_bios);
+	bar = PCI_RID2BAR(rid);
+	if (bar >= 0 && bar <= PCIR_MAX_BAR_0)
+		return (&sc->vga_bars[bar]);
+	return (NULL);
+}
+
 static struct resource *
 vga_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
     u_long start, u_long end, u_long count, u_int flags)
 {
-	struct vga_pci_softc *sc;
-	int bar;
+	struct vga_resource *vr;
 
 	switch (type) {
 	case SYS_RES_MEMORY:
@@ -170,16 +183,15 @@ vga_pci_alloc_resource(device_t dev, dev
 		 * For BARs, we cache the resource so that we only allocate it
 		 * from the PCI bus once.
 		 */
-		bar = PCI_RID2BAR(*rid);
-		if (bar < 0 || bar > PCIR_MAX_BAR_0)
+		vr = lookup_res(device_get_softc(dev), *rid);
+		if (vr == NULL)
 			return (NULL);
-		sc = device_get_softc(dev);
-		if (sc->vga_res[bar].vr_res == NULL)
-			sc->vga_res[bar].vr_res = bus_alloc_resource(dev, type,
-			    rid, start, end, count, flags);
-		if (sc->vga_res[bar].vr_res != NULL)
-			sc->vga_res[bar].vr_refs++;
-		return (sc->vga_res[bar].vr_res);
+		if (vr->vr_res == NULL)
+			vr->vr_res = bus_alloc_resource(dev, type, rid, start,
+			    end, count, flags);
+		if (vr->vr_res != NULL)
+			vr->vr_refs++;
+		return (vr->vr_res);
 	}
 	return (bus_alloc_resource(dev, type, rid, start, end, count, flags));
 }
@@ -188,8 +200,8 @@ static int
 vga_pci_release_resource(device_t dev, device_t child, int type, int rid,
     struct resource *r)
 {
-	struct vga_pci_softc *sc;
-	int bar, error;
+	struct vga_resource *vr;
+	int error;
 
 	switch (type) {
 	case SYS_RES_MEMORY:
@@ -198,24 +210,22 @@ vga_pci_release_resource(device_t dev, d
 		 * For BARs, we release the resource from the PCI bus
 		 * when the last child reference goes away.
 		 */
-		bar = PCI_RID2BAR(rid);
-		if (bar < 0 || bar > PCIR_MAX_BAR_0)
+		vr = lookup_res(device_get_softc(dev), rid);
+		if (vr == NULL)
 			return (EINVAL);
-		sc = device_get_softc(dev);
-		if (sc->vga_res[bar].vr_res == NULL)
+		if (vr->vr_res == NULL)
 			return (EINVAL);
-		KASSERT(sc->vga_res[bar].vr_res == r,
-		    ("vga_pci resource mismatch"));
-		if (sc->vga_res[bar].vr_refs > 1) {
-			sc->vga_res[bar].vr_refs--;
+		KASSERT(vr->vr_res == r, ("vga_pci resource mismatch"));
+		if (vr->vr_refs > 1) {
+			vr->vr_refs--;
 			return (0);
 		}
-		KASSERT(sc->vga_res[bar].vr_refs > 0,
+		KASSERT(vr->vr_refs > 0,
 		    ("vga_pci resource reference count underflow"));
 		error = bus_release_resource(dev, type, rid, r);
 		if (error == 0) {
-			sc->vga_res[bar].vr_res = NULL;
-			sc->vga_res[bar].vr_refs = 0;
+			vr->vr_res = NULL;
+			vr->vr_refs = 0;
 		}
 		return (error);
 	}


More information about the svn-src-stable-9 mailing list