From owner-svn-src-head@FreeBSD.ORG Tue Apr 9 19:36:35 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 8FEB4E45; Tue, 9 Apr 2013 19:36:35 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 82AF47E1; Tue, 9 Apr 2013 19:36:35 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r39JaYuj020789; Tue, 9 Apr 2013 19:36:34 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r39JaYxJ020788; Tue, 9 Apr 2013 19:36:34 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201304091936.r39JaYxJ020788@svn.freebsd.org> From: John Baldwin Date: Tue, 9 Apr 2013 19:36:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r249315 - head/sys/dev/pci X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Apr 2013 19:36:35 -0000 Author: jhb Date: Tue Apr 9 19:36:34 2013 New Revision: 249315 URL: http://svnweb.freebsd.org/changeset/base/249315 Log: 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. MFC after: 1 week Modified: head/sys/dev/pci/vga_pci.c Modified: head/sys/dev/pci/vga_pci.c ============================================================================== --- head/sys/dev/pci/vga_pci.c Tue Apr 9 17:55:39 2013 (r249314) +++ head/sys/dev/pci/vga_pci.c Tue Apr 9 19:36:34 2013 (r249315) @@ -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); }