From owner-freebsd-arm@FreeBSD.ORG Fri Dec 21 21:45:03 2007 Return-Path: Delivered-To: arm@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AA24616A41A for ; Fri, 21 Dec 2007 21:45:03 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from speedfactory.net (mail6.speedfactory.net [66.23.216.219]) by mx1.freebsd.org (Postfix) with ESMTP id 41F4B13C46B for ; Fri, 21 Dec 2007 21:45:03 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from server.baldwin.cx (unverified [66.23.211.162]) by speedfactory.net (SurgeMail 3.8q) with ESMTP id 225475449-1834499 for ; Fri, 21 Dec 2007 16:27:05 -0500 Received: from localhost.corp.yahoo.com (john@localhost [127.0.0.1]) (authenticated bits=0) by server.baldwin.cx (8.13.8/8.13.8) with ESMTP id lBLLSphS089941 for ; Fri, 21 Dec 2007 16:28:52 -0500 (EST) (envelope-from jhb@freebsd.org) From: John Baldwin To: arm@freebsd.org Date: Fri, 21 Dec 2007 16:08:16 -0500 User-Agent: KMail/1.9.6 MIME-Version: 1.0 Content-Disposition: inline X-Length: 1130 X-UID: 7 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Message-Id: <200712211608.16557.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-2.0.2 (server.baldwin.cx [127.0.0.1]); Fri, 21 Dec 2007 16:28:52 -0500 (EST) X-Virus-Scanned: ClamAV 0.91.2/5211/Fri Dec 21 14:05:46 2007 on server.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-4.4 required=4.2 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.1.3 X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on server.baldwin.cx Cc: Subject: Only set bus tag/handles in activate_resource() methods X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to the StrongARM Processor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Dec 2007 21:45:03 -0000 This patch (untested) tries to fix an issue on arm I fixed on the ACPI-using platforms a while back. It fixes the top-level bus drivers to activate resources (assign bus tags and handles so you can use bus_space_*()) in bus_activate_resource() methods instead of in bus_alloc_resource(). This is important for any drivers that want do what ACPI does: allocate a resource and then subdivide it to hand it out to child devices. A driver that does this can still pass the bus_activate_resource() request up the tree to actually get bus_space properly set up with this fix. Note that i80321_pci still has a hack to deal with the variant base address for the PCI memory region, but the rest of the drivers should be correct now. Please test, thanks. --- //depot/vendor/freebsd/src/sys/arm/arm/nexus.c 2007/02/23 12:24:01 +++ //depot/user/jhb/acpipci/arm/arm/nexus.c 2007/03/05 17:04:36 @@ -206,6 +206,8 @@ struct rman *rm; int needactivate = flags & RF_ACTIVE; + flags &= ~RF_ACTIVE; + switch (type) { case SYS_RES_MEMORY: rm = &mem_rman; @@ -220,8 +222,6 @@ return 0; rman_set_rid(rv, *rid); - rman_set_bustag(rv, (void*)ARM_BUS_SPACE_MEM); - rman_set_bushandle(rv, rman_get_start(rv)); if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { @@ -241,7 +241,7 @@ /* * If this is a memory resource, map it into the kernel. */ - if (rman_get_bustag(r) == (void*)ARM_BUS_SPACE_MEM) { + if (type == SYS_RES_MEMORY) { caddr_t vaddr = 0; u_int32_t paddr; u_int32_t psize; @@ -252,6 +252,7 @@ poffs = paddr - trunc_page(paddr); vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs; rman_set_virtual(r, vaddr); + rman_set_bustag(r, (void*)ARM_BUS_SPACE_MEM); rman_set_bushandle(r, (bus_space_handle_t) vaddr); } return (rman_activate_resource(r)); --- //depot/vendor/freebsd/src/sys/arm/at91/at91.c 2007/12/19 17:36:50 +++ //depot/user/jhb/acpipci/arm/at91/at91.c 2007/12/20 18:42:26 @@ -511,11 +511,14 @@ struct resource_list_entry *rle; struct at91_ivar *ivar = device_get_ivars(child); struct resource_list *rl = &ivar->resources; + int needactivate = flags & RF_ACTIVE; if (device_get_parent(child) != dev) return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); + flags &= ~RF_ACTIVE; + rle = resource_list_find(rl, type, *rid); if (rle == NULL) return (NULL); @@ -541,8 +544,6 @@ #endif rle->res = rman_reserve_resource(&sc->sc_mem_rman, start, end, count, flags, child); - rman_set_bustag(rle->res, &at91_bs_tag); - rman_set_bushandle(rle->res, start); break; } if (rle->res) { @@ -550,6 +551,12 @@ rle->end = rman_get_end(rle->res); rle->count = count; rman_set_rid(rle->res, *rid); + if (needactivate) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } + } } return (rle->res); } @@ -576,6 +583,11 @@ rle = resource_list_find(rl, type, rid); if (rle == NULL) return (EINVAL); + if (rman_get_flags(r) & RF_ACTIVE) { + int error = bus_deactivate_resource(child, type, rid, r); + if (error) + return (error); + } rman_release_resource(r); rle->res = NULL; return (0); @@ -615,15 +627,19 @@ #if 0 u_long p; int error; +#endif if (type == SYS_RES_MEMORY) { + rman_set_bustag(r, &at91_bs_tag); + rman_set_bushandle(r, start); +#if 0 error = bus_space_map(rman_get_bustag(r), rman_get_bushandle(r), rman_get_size(r), 0, &p); if (error) return (error); rman_set_bushandle(r, p); +#endif } -#endif return (rman_activate_resource(r)); } --- //depot/vendor/freebsd/src/sys/arm/xscale/i80321/i80321_pci.c 2007/09/30 11:08:30 +++ //depot/user/jhb/acpipci/arm/xscale/i80321/i80321_pci.c 2007/12/20 23:43:49 @@ -283,8 +283,7 @@ struct i80321_pci_softc *sc = device_get_softc(bus); struct resource *rv; struct rman *rm; - bus_space_tag_t bt = NULL; - bus_space_handle_t bh = 0; + bus_handle_t bh = 0; switch (type) { case SYS_RES_IRQ: @@ -292,7 +291,6 @@ break; case SYS_RES_MEMORY: rm = &sc->sc_mem_rman; - bt = sc->sc_pcimem; bh = (start >= 0x80000000 && start < 0x84000000) ? 0x80000000 : sc->sc_mem; start &= (0x1000000 - 1); @@ -300,8 +298,6 @@ break; case SYS_RES_IOPORT: rm = &sc->sc_io_rman; - bt = sc->sc_pciio; - bh = sc->sc_io; if (start < sc->sc_io) { start = start - 0x90000000 + sc->sc_io; end = end - 0x90000000 + sc->sc_io; @@ -311,21 +307,22 @@ return (NULL); } - rv = rman_reserve_resource(rm, start, end, count, flags, child); + rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, + child); if (rv == NULL) return (NULL); rman_set_rid(rv, *rid); - if (type != SYS_RES_IRQ) { - if (type == SYS_RES_MEMORY) - bh += (rman_get_start(rv)); - rman_set_bustag(rv, bt); + if (type == SYS_RES_MEMORY) + /* + * XXX: This isn't quite right but we don't have a better way + * to pass this on to our activate_resource() routine. + */ rman_set_bushandle(rv, bh); - if (flags & RF_ACTIVE) { - if (bus_activate_resource(child, type, *rid, rv)) { - rman_release_resource(rv); - return (NULL); - } - } + if (flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } } return (rv); } @@ -334,16 +331,27 @@ i80321_pci_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { + struct i80321_pci_softc *sc = device_get_softc(bus); u_long p; int error; - - if (type == SYS_RES_MEMORY) { - error = bus_space_map(rman_get_bustag(r), - rman_get_bushandle(r), rman_get_size(r), 0, &p); + + switch (type) { + case SYS_RES_MEMORY: + /* + * XXX: We rely on having the bushandle initially set to the + * start of the PCI memio window above. + */ + error = bus_space_map(sc->sc_pcimem, rman_get_bushandle(r) + + rman_get_start(r), rman_get_size(r), 0, &p); if (error) return (error); + rman_set_bustag(r, sc->sc_pcimem); rman_set_bushandle(r, p); - + break; + case SYS_RES_IOPORT: + rman_set_bustag(r, sc->sc_pciio); + rman_set_bushandle(r, sc->sc_io); + break; } return (rman_activate_resource(r)); } --- //depot/vendor/freebsd/src/sys/arm/xscale/i80321/obio.c 2007/07/27 14:57:30 +++ //depot/user/jhb/acpipci/arm/xscale/i80321/obio.c 2007/09/24 17:24:13 @@ -98,8 +98,6 @@ { struct resource *rv; struct rman *rm; - bus_space_tag_t bt = NULL; - bus_space_handle_t bh = 0; struct obio_softc *sc = device_get_softc(bus); switch (type) { @@ -110,24 +108,24 @@ return (NULL); case SYS_RES_IOPORT: rm = &sc->oba_rman; - bt = sc->oba_st; - bh = sc->oba_addr; - start = bh; + start = sc->oba_addr; break; default: return (NULL); } - - rv = rman_reserve_resource(rm, start, end, count, flags, child); + rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, + child); if (rv == NULL) return (NULL); - if (type == SYS_RES_IRQ) - return (rv); rman_set_rid(rv, *rid); - rman_set_bustag(rv, bt); - rman_set_bushandle(rv, bh); + if (flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } + } return (rv); } @@ -136,8 +134,15 @@ obio_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { - return (0); + struct obio_softc *sc = device_get_softc(bus); + + if (type == SYS_RES_IOPORT) { + rman_set_bustag(r, sc->oba_st); + rman_set_bushandle(r, sc->oba_addr); + } + return (rman_activate_resource(r)); } + static device_method_t obio_methods[] = { DEVMETHOD(device_probe, obio_probe), DEVMETHOD(device_attach, obio_attach), --- //depot/vendor/freebsd/src/sys/arm/xscale/i8134x/i81342_pci.c 2007/09/30 11:08:30 +++ //depot/user/jhb/acpipci/arm/xscale/i8134x/i81342_pci.c 2007/12/20 23:44:30 @@ -334,8 +334,7 @@ struct i81342_pci_softc *sc = device_get_softc(bus); struct resource *rv; struct rman *rm; - bus_space_tag_t bt = NULL; - bus_space_handle_t bh = 0; + u_long off; switch (type) { case SYS_RES_IRQ: @@ -343,41 +342,30 @@ break; case SYS_RES_MEMORY: rm = &sc->sc_mem_rman; - bt = &sc->sc_pcimem; - bh = 0; break; case SYS_RES_IOPORT: rm = &sc->sc_io_rman; - bt = &sc->sc_pciio; - bh = sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : + off = sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : IOP34X_PCIE_OIOBAR_VADDR; - start += bh; - end += bh; + start += off; + end += off; break; default: return (NULL); } - rv = rman_reserve_resource(rm, start, end, count, flags, child); + rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, + child); if (rv == NULL) return (NULL); rman_set_rid(rv, *rid); - if (type != SYS_RES_IRQ) { - if (type == SYS_RES_MEMORY) - bh += (rman_get_start(rv)); - rman_set_bustag(rv, bt); - rman_set_bushandle(rv, bh); - if (flags & RF_ACTIVE) { - if (bus_activate_resource(child, type, *rid, rv)) { - rman_release_resource(rv); - return (NULL); - } - } - } + if (flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } + } return (rv); - - - return (NULL); } static int @@ -386,14 +374,23 @@ { u_long p; int error; - - if (type == SYS_RES_MEMORY) { - error = bus_space_map(rman_get_bustag(r), - rman_get_bushandle(r), rman_get_size(r), 0, &p); + + switch (type) { + case SYS_RES_MEMORY: + error = bus_space_map(&sc->sc_pcimem, rman_get_start(r), + rman_get_size(r), 0, &p); if (error) return (error); + rman_set_bustag(r, &sc->sc_pcimem); rman_set_bushandle(r, p); - + break; + case SYS_RES_IOPORT: + rman_set_bus_tag(r, &sc->sc_pciio); + if (sc->sc_is_atux) + rman_set_bushandle(r, IOP34X_PCIX_OIOBAR_VADDR); + else + rman_set_bushandle(r, IOP34X_PCIE_OIOBAR_VADDR); + break; } return (rman_activate_resource(r)); } --- //depot/vendor/freebsd/src/sys/arm/xscale/i8134x/obio.c 2007/07/27 14:57:30 +++ //depot/user/jhb/acpipci/arm/xscale/i8134x/obio.c 2007/12/20 23:44:30 @@ -93,8 +93,6 @@ { struct resource *rv; struct rman *rm; - bus_space_tag_t bt = NULL; - bus_space_handle_t bh = 0; struct obio_softc *sc = device_get_softc(bus); int unit = device_get_unit(child); @@ -110,14 +108,11 @@ return (NULL); case SYS_RES_IOPORT: rm = &sc->oba_rman; - bt = sc->oba_st; if (unit == 0) { - bh = IOP34X_UART0_VADDR; - start = bh; + start = IOP34X_UART0_VADDR; end = IOP34X_UART1_VADDR; } else { - bh = IOP34X_UART1_VADDR; - start = bh; + start = IOP34X_UART1_VADDR; end = start + 0x40; } break; @@ -126,15 +121,18 @@ } - rv = rman_reserve_resource(rm, start, end, count, flags, child); + rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, + child); if (rv == NULL) return (NULL); - if (type == SYS_RES_IRQ) - return (rv); rman_set_rid(rv, *rid); - rman_set_bustag(rv, bt); - rman_set_bushandle(rv, bh); - + if (flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } + } + return (rv); } @@ -143,8 +141,16 @@ obio_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { - return (0); + + switch (type) { + case SYS_RES_IOPORT: + rman_set_bustag(r, sc->oba_st); + rman_set_bushandle(r, rman_get_start(r)); + break; + } + return (rman_activate_resource(r)); } + static device_method_t obio_methods[] = { DEVMETHOD(device_probe, obio_probe), DEVMETHOD(device_attach, obio_attach), --- //depot/vendor/freebsd/src/sys/arm/xscale/ixp425/ixp425.c 2007/05/29 18:18:31 +++ //depot/user/jhb/acpipci/arm/xscale/ixp425/ixp425.c 2007/09/24 17:24:13 @@ -319,7 +319,7 @@ struct ixp425_softc *sc = device_get_softc(dev); struct rman *rmanp; struct resource *rv; - uint32_t vbase, addr; + uint32_t addr; int irq; switch (type) { @@ -329,7 +329,7 @@ if (BUS_READ_IVAR(dev, child, IXP425_IVAR_IRQ, &irq) == 0) start = end = irq; rv = rman_reserve_resource(rmanp, start, end, count, - flags, child); + flags & ~RF_ACTIVE, child); if (rv != NULL) rman_set_rid(rv, *rid); break; @@ -344,21 +344,45 @@ if (getvbase(start, end - start, &vbase)) return NULL; rv = rman_reserve_resource(rmanp, start, end, count, - flags, child); - if (rv != NULL) { + flags & ~RF_ACTIVE, child); + if (rv != NULL) rman_set_rid(rv, *rid); - if (strcmp(device_get_name(child), "uart") == 0) - rman_set_bustag(rv, &ixp425_a4x_bs_tag); - else - rman_set_bustag(rv, sc->sc_iot); - rman_set_bushandle(rv, vbase); - } break; default: rv = NULL; break; } - return rv; + + if (rv != NULL && flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } + } + + return (rv); +} + +static int +ixp425_activate_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + struct ixp425_softc *sc = device_get_softc(dev); + int error; + uint32_t vbase; + + if (type == SYS_RES_MEMORY) { + error = getvbase(rman_get_start(r), rman_get_size(r), &vbase); + if (error) + return (error); + if (strcmp(device_get_name(child), "uart") == 0) + rman_set_bustag(rv, &ixp425_a4x_bs_tag); + else + rman_set_bustag(rv, sc->sc_iot); + rman_set_bushandle(rv, vbase); + } + + return (rman_activate_resource(r)); } static int @@ -409,6 +433,7 @@ DEVMETHOD(bus_read_ivar, ixp425_read_ivar), DEVMETHOD(bus_alloc_resource, ixp425_alloc_resource), + DEVMETHOD(bus_activate_resource, ixp425_activate_resource), DEVMETHOD(bus_setup_intr, ixp425_setup_intr), DEVMETHOD(bus_teardown_intr, ixp425_teardown_intr), --- //depot/vendor/freebsd/src/sys/arm/xscale/ixp425/ixp425_pci.c 2007/09/30 11:08:30 +++ //depot/user/jhb/acpipci/arm/xscale/ixp425/ixp425_pci.c 2007/10/08 16:52:09 @@ -279,12 +279,10 @@ ixppcib_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - bus_space_tag_t tag; struct ixppcib_softc *sc = device_get_softc(bus); struct rman *rmanp; struct resource *rv; - tag = NULL; /* shut up stupid gcc */ rv = NULL; switch (type) { case SYS_RES_IRQ: @@ -293,28 +291,25 @@ case SYS_RES_IOPORT: rmanp = &sc->sc_io_rman; - tag = &sc->sc_pci_iot; break; case SYS_RES_MEMORY: rmanp = &sc->sc_mem_rman; - tag = &sc->sc_pci_memt; break; default: return (rv); } - rv = rman_reserve_resource(rmanp, start, end, count, flags, child); - if (rv != NULL) { - rman_set_rid(rv, *rid); - if (type == SYS_RES_IOPORT) { - rman_set_bustag(rv, tag); - rman_set_bushandle(rv, rman_get_start(rv)); - } else if (type == SYS_RES_MEMORY) { - rman_set_bustag(rv, tag); - rman_set_bushandle(rv, rman_get_bushandle(sc->sc_mem) + - (rman_get_start(rv) - IXP425_PCI_MEM_HWBASE)); + rv = rman_reserve_resource(rmanp, start, end, count, flags & ~RF_ACTIVE, + child); + if (rv == NULL) + return (NULL); + rman_set_rid(rv, *rid); + if (flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); } } @@ -325,9 +320,21 @@ ixppcib_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { + struct ixppcib_softc *sc = device_get_softc(bus); - device_printf(bus, "%s called activate_resource\n", device_get_nameunit(child)); - return (ENXIO); + switch (type) { + case SYS_RES_IOPORT: + rman_set_bustag(r, &sc->sc_pci_iot); + rman_set_bushandle(r, rman_get_start(r)); + break; + case SYS_RES_MEMORY: + rman_set_bustag(r, &sc->sc_pci_memt); + rman_set_bushandle(r, rman_get_bushandle(sc->sc_mem) + + (rman_get_start(r) - IXP425_PCI_MEM_HWBASE)); + break; + } + + return (rman_activate_resource(r)); } static int -- John Baldwin