Date: Sat, 28 Jan 2012 23:53:07 +0000 (UTC) From: Marius Strobl <marius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r230687 - in stable/9/sys: dev/ata dev/ata/chipsets dev/fb dev/le sparc64/central sparc64/conf sparc64/ebus sparc64/fhc sparc64/include sparc64/pci sparc64/sbus sparc64/sparc64 Message-ID: <201201282353.q0SNr7e6005493@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: marius Date: Sat Jan 28 23:53:06 2012 New Revision: 230687 URL: http://svn.freebsd.org/changeset/base/230687 Log: MFC: r225931, r225932, r227000 Make sparc64 compatible with NEW_PCIB and enable it: - Implement bus_adjust_resource() methods as far as necessary and in non-PCI bridge drivers as far as feasible without rototilling them. - As NEW_PCIB does a layering violation by activating resources at layers above pci(4) without previously bubbling up their allocation there, move the assignment of bus tags and handles from the bus_alloc_resource() to the bus_activate_resource() methods like at least the other NEW_PCIB enabled architectures do. This is somewhat unfortunate as previously sparc64 (ab)used resource activation to indicate whether SYS_RES_MEMORY resources should be mapped into KVA, which is only necessary if their going to be accessed via the pointer returned from rman_get_virtual() but not for bus_space(9) as the later always uses physical access on sparc64. Besides wasting KVA if we always map in SYS_RES_MEMORY resources, a driver also may deliberately not map them in if the firmware already has done so, possibly in a special way. So in order to still allow a driver to decide whether a SYS_RES_MEMORY resource should be mapped into KVA we let it indicate that by calling bus_space_map(9) with BUS_SPACE_MAP_LINEAR as actually documented in the bus_space(9) page. This is implemented by allocating a separate bus tag per SYS_RES_MEMORY resource and passing the resource via the previously unused bus tag cookie so we later on can call rman_set_virtual() in sparc64_bus_mem_map(). As a side effect this now also allows to actually indicate that a SYS_RES_MEMORY resource should be mapped in as cacheable and/or read-only via BUS_SPACE_MAP_CACHEABLE and BUS_SPACE_MAP_READONLY respectively. - Do some minor cleanup like taking advantage of rman_init_from_resource(), factor out the common part of bus tag allocation into a newly added sparc64_alloc_bus_tag(), hook up some missing newbus methods and replace some homegrown versions with the generic counterparts etc. - While at it, let apb_attach() (which can't use the generic NEW_PCIB code as APB bridges just don't have the base and limit registers implemented) regarding the config space registers cached in pcib_softc and the SYSCTL reporting nodes set up. Modified: stable/9/sys/dev/ata/ata-pci.c stable/9/sys/dev/ata/chipsets/ata-promise.c stable/9/sys/dev/ata/chipsets/ata-siliconimage.c stable/9/sys/dev/fb/machfb.c stable/9/sys/dev/le/lebuffer_sbus.c stable/9/sys/sparc64/central/central.c stable/9/sys/sparc64/conf/DEFAULTS stable/9/sys/sparc64/ebus/ebus.c stable/9/sys/sparc64/fhc/fhc.c stable/9/sys/sparc64/include/bus.h stable/9/sys/sparc64/include/bus_private.h stable/9/sys/sparc64/pci/apb.c stable/9/sys/sparc64/pci/fire.c stable/9/sys/sparc64/pci/firevar.h stable/9/sys/sparc64/pci/ofw_pcib_subr.c stable/9/sys/sparc64/pci/psycho.c stable/9/sys/sparc64/pci/psychovar.h stable/9/sys/sparc64/pci/sbbc.c stable/9/sys/sparc64/pci/schizo.c stable/9/sys/sparc64/pci/schizovar.h stable/9/sys/sparc64/sbus/dma_sbus.c stable/9/sys/sparc64/sbus/sbus.c stable/9/sys/sparc64/sparc64/bus_machdep.c stable/9/sys/sparc64/sparc64/nexus.c stable/9/sys/sparc64/sparc64/upa.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/amd64/include/xen/ (props changed) stable/9/sys/boot/ (props changed) stable/9/sys/boot/i386/efi/ (props changed) stable/9/sys/boot/ia64/efi/ (props changed) stable/9/sys/boot/ia64/ski/ (props changed) stable/9/sys/boot/powerpc/boot1.chrp/ (props changed) stable/9/sys/boot/powerpc/ofw/ (props changed) stable/9/sys/cddl/contrib/opensolaris/ (props changed) stable/9/sys/conf/ (props changed) stable/9/sys/contrib/dev/acpica/ (props changed) stable/9/sys/contrib/octeon-sdk/ (props changed) stable/9/sys/contrib/pf/ (props changed) stable/9/sys/contrib/x86emu/ (props changed) Modified: stable/9/sys/dev/ata/ata-pci.c ============================================================================== --- stable/9/sys/dev/ata/ata-pci.c Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/dev/ata/ata-pci.c Sat Jan 28 23:53:06 2012 (r230687) @@ -148,10 +148,20 @@ ata_pci_detach(device_t dev) } if (ctlr->chipdeinit != NULL) ctlr->chipdeinit(dev); - if (ctlr->r_res2) + if (ctlr->r_res2) { +#ifdef __sparc64__ + bus_space_unmap(rman_get_bustag(ctlr->r_res2), + rman_get_bushandle(ctlr->r_res2), rman_get_size(ctlr->r_res2)); +#endif bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, ctlr->r_res2); - if (ctlr->r_res1) + } + if (ctlr->r_res1) { +#ifdef __sparc64__ + bus_space_unmap(rman_get_bustag(ctlr->r_res1), + rman_get_bushandle(ctlr->r_res1), rman_get_size(ctlr->r_res1)); +#endif bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1, ctlr->r_res1); + } return 0; } @@ -770,7 +780,6 @@ driver_t ata_pcichannel_driver = { DRIVER_MODULE(ata, atapci, ata_pcichannel_driver, ata_devclass, 0, 0); - /* * misc support fucntions */ @@ -931,4 +940,3 @@ ata_mode2idx(int mode) return (mode & ATA_MODE_MASK) + 5; return (mode & ATA_MODE_MASK) - ATA_PIO0; } - Modified: stable/9/sys/dev/ata/chipsets/ata-promise.c ============================================================================== --- stable/9/sys/dev/ata/chipsets/ata-promise.c Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/dev/ata/chipsets/ata-promise.c Sat Jan 28 23:53:06 2012 (r230687) @@ -94,7 +94,6 @@ static void ata_promise_next_hpkt(struct #define PR_SATA 0x40 #define PR_SATA2 0x80 - /* * Promise chipset support functions */ @@ -250,6 +249,14 @@ ata_promise_chipinit(device_t dev) &ctlr->r_rid1, RF_ACTIVE))) goto failnfree; +#ifdef __sparc64__ + if (ctlr->chip->cfg2 == PR_SX4X && + !bus_space_map(rman_get_bustag(ctlr->r_res1), + rman_get_bushandle(ctlr->r_res1), rman_get_size(ctlr->r_res1), + BUS_SPACE_MAP_LINEAR, NULL)) + goto failnfree; +#endif + ctlr->r_type2 = SYS_RES_MEMORY; ctlr->r_rid2 = PCIR_BAR(3); if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, Modified: stable/9/sys/dev/ata/chipsets/ata-siliconimage.c ============================================================================== --- stable/9/sys/dev/ata/chipsets/ata-siliconimage.c Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/dev/ata/chipsets/ata-siliconimage.c Sat Jan 28 23:53:06 2012 (r230687) @@ -80,7 +80,6 @@ static void ata_siiprb_dmainit(device_t #define SII_BUG 0x04 #define SII_4CH 0x08 - /* * Silicon Image Inc. (SiI) (former CMD) chipset support functions */ @@ -141,6 +140,17 @@ ata_sii_chipinit(device_t dev) bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1,ctlr->r_res1); return ENXIO; } +#ifdef __sparc64__ + if (!bus_space_map(rman_get_bustag(ctlr->r_res2), + rman_get_bushandle(ctlr->r_res2), rman_get_size(ctlr->r_res2), + BUS_SPACE_MAP_LINEAR, NULL)) { + bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1, + ctlr->r_res1); + bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, + ctlr->r_res2); + return (ENXIO); + } +#endif ctlr->ch_attach = ata_siiprb_ch_attach; ctlr->ch_detach = ata_siiprb_ch_detach; ctlr->reset = ata_siiprb_reset; @@ -432,7 +442,6 @@ ata_sii_setmode(device_t dev, int target return (mode); } - struct ata_siiprb_dma_prdentry { u_int64_t addr; u_int32_t count; Modified: stable/9/sys/dev/fb/machfb.c ============================================================================== --- stable/9/sys/dev/fb/machfb.c Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/dev/fb/machfb.c Sat Jan 28 23:53:06 2012 (r230687) @@ -87,7 +87,9 @@ struct machfb_softc { struct resource *sc_vmemres; bus_space_tag_t sc_memt; bus_space_tag_t sc_regt; + bus_space_tag_t sc_vmemt; bus_space_handle_t sc_memh; + bus_space_handle_t sc_vmemh; bus_space_handle_t sc_regh; u_long sc_mem; u_long sc_vmem; @@ -1175,68 +1177,52 @@ machfb_pci_attach(device_t dev) adp = &sc->sc_va; vi = &adp->va_info; - /* - * Allocate resources regardless of whether we are the console - * and already obtained the bus tag and handle for the framebuffer - * in machfb_configure() or not so the resources are marked as - * taken in the respective RMAN. - */ - - /* Enable memory and IO access. */ - pci_write_config(dev, PCIR_COMMAND, - pci_read_config(dev, PCIR_COMMAND, 2) | PCIM_CMD_PORTEN | - PCIM_CMD_MEMEN, 2); - - /* - * NB: we need to take care that the framebuffer isn't mapped - * in twice as besides wasting resources this isn't possible with - * all MMUs. - */ rid = PCIR_BAR(0); - if ((sc->sc_memres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &rid, 0)) == NULL) { + if ((sc->sc_memres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate memory resources\n"); return (ENXIO); } + sc->sc_memt = rman_get_bustag(sc->sc_memres); + sc->sc_memh = rman_get_bushandle(sc->sc_memres); + sc->sc_mem = rman_get_start(sc->sc_memres); + vi->vi_buffer = sc->sc_memh; + vi->vi_buffer_size = rman_get_size(sc->sc_memres); if (OF_getprop(sc->sc_node, "address", &u32, sizeof(u32)) > 0 && - vtophys(u32) == rman_get_bushandle(sc->sc_memres)) + vtophys(u32) == sc->sc_memh) adp->va_mem_base = u32; else { - bus_release_resource(dev, SYS_RES_MEMORY, - rman_get_rid(sc->sc_memres), sc->sc_memres); - rid = PCIR_BAR(0); - if ((sc->sc_memres = bus_alloc_resource_any(dev, - SYS_RES_MEMORY, &rid, RF_ACTIVE)) == NULL) { - device_printf(dev, - "cannot allocate memory resources\n"); - return (ENXIO); + if (bus_space_map(sc->sc_memt, vi->vi_buffer, + vi->vi_buffer_size, BUS_SPACE_MAP_LINEAR, + &sc->sc_memh) != 0) { + device_printf(dev, "cannot map memory resources\n"); + error = ENXIO; + goto fail_memres; } adp->va_mem_base = (vm_offset_t)rman_get_virtual(sc->sc_memres); } - sc->sc_memt = rman_get_bustag(sc->sc_memres); - sc->sc_memh = rman_get_bushandle(sc->sc_memres); - sc->sc_regt = sc->sc_memt; - bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF, - MACH64_REG_SIZE, &sc->sc_regh); - adp->va_mem_size = rman_get_size(sc->sc_memres); + adp->va_mem_size = vi->vi_buffer_size; adp->va_buffer = adp->va_mem_base; adp->va_buffer_size = adp->va_mem_size; - sc->sc_mem = rman_get_start(sc->sc_memres); - vi->vi_buffer = sc->sc_memh; - vi->vi_buffer_size = adp->va_buffer_size; + sc->sc_regt = sc->sc_memt; + if (bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF, + MACH64_REG_SIZE, &sc->sc_regh) != 0) { + device_printf(dev, "cannot allocate register resources\n"); + error = ENXIO; + goto fail_memmap; + } /* * Depending on the firmware version the VGA I/O and/or memory - * resources of the Mach64 chips come up disabled. We generally - * enable them above (pci(4) actually already did this unless - * pci_enable_io_modes is not set) but this doesn't necessarily - * mean that we get valid ones. Invalid resources seem to have - * in common that they start at address 0. We don't allocate - * them in this case in order to avoid warnings in apb(4) and - * crashes when using these invalid resources. X.Org is aware - * of this and doesn't use the VGA resources in this case (but - * demands them if they are valid). + * resources of the Mach64 chips come up disabled. These will be + * enabled by pci(4) when activating the resource in question but + * this doesn't necessarily mean that the resource is valid. + * Invalid resources seem to have in common that they start at + * address 0. We don't allocate the VGA memory in this case in + * order to avoid warnings in apb(4) and crashes when using this + * invalid resources. X.Org is aware of this and doesn't use the + * VGA memory resource in this case (but demands it if it's valid). */ rid = PCIR_BAR(2); if (bus_get_resource_start(dev, SYS_RES_MEMORY, rid) != 0) { @@ -1245,21 +1231,31 @@ machfb_pci_attach(device_t dev) device_printf(dev, "cannot allocate VGA memory resources\n"); error = ENXIO; - goto fail_memres; + goto fail_memmap; + } + sc->sc_vmemt = rman_get_bustag(sc->sc_vmemres); + sc->sc_vmemh = rman_get_bushandle(sc->sc_vmemres); + sc->sc_vmem = rman_get_start(sc->sc_vmemres); + vi->vi_registers = sc->sc_vmemh; + vi->vi_registers_size = rman_get_size(sc->sc_vmemres); + if (bus_space_map(sc->sc_vmemt, vi->vi_registers, + vi->vi_registers_size, BUS_SPACE_MAP_LINEAR, + &sc->sc_vmemh) != 0) { + device_printf(dev, + "cannot map VGA memory resources\n"); + error = ENXIO; + goto fail_vmemres; } adp->va_registers = (vm_offset_t)rman_get_virtual(sc->sc_vmemres); - adp->va_registers_size = rman_get_size(sc->sc_vmemres); - sc->sc_vmem = rman_get_start(sc->sc_vmemres); - vi->vi_registers = rman_get_bushandle(sc->sc_vmemres); - vi->vi_registers_size = adp->va_registers_size; + adp->va_registers_size = vi->vi_registers_size; } if (!(sc->sc_flags & MACHFB_CONSOLE)) { if ((sw = vid_get_switch(MACHFB_DRIVER_NAME)) == NULL) { device_printf(dev, "cannot get video switch\n"); error = ENODEV; - goto fail_vmemres; + goto fail_vmemmap; } /* * During device configuration we don't necessarily probe @@ -1275,7 +1271,7 @@ machfb_pci_attach(device_t dev) break; if ((error = sw->init(i, adp, 0)) != 0) { device_printf(dev, "cannot initialize adapter\n"); - goto fail_vmemres; + goto fail_vmemmap; } } @@ -1283,8 +1279,8 @@ machfb_pci_attach(device_t dev) * Test whether the aperture is byte swapped or not, set * va_window and va_window_size as appropriate. Note that * the aperture could be mapped either big or little endian - * on independently of the endianess of the host so this - * has to be a runtime test. + * independently of the endianess of the host so this has + * to be a runtime test. */ p32 = (uint32_t *)adp->va_buffer; u32 = *p32; @@ -1346,10 +1342,16 @@ machfb_pci_attach(device_t dev) return (0); + fail_vmemmap: + if (adp->va_registers != 0) + bus_space_unmap(sc->sc_vmemt, sc->sc_vmemh, + vi->vi_registers_size); fail_vmemres: if (sc->sc_vmemres != NULL) bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_vmemres), sc->sc_vmemres); + fail_memmap: + bus_space_unmap(sc->sc_memt, sc->sc_memh, vi->vi_buffer_size); fail_memres: bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_memres), sc->sc_memres); Modified: stable/9/sys/dev/le/lebuffer_sbus.c ============================================================================== --- stable/9/sys/dev/le/lebuffer_sbus.c Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/dev/le/lebuffer_sbus.c Sat Jan 28 23:53:06 2012 (r230687) @@ -81,6 +81,7 @@ static device_method_t lebuffer_methods[ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), + DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), Modified: stable/9/sys/sparc64/central/central.c ============================================================================== --- stable/9/sys/sparc64/central/central.c Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/sparc64/central/central.c Sat Jan 28 23:53:06 2012 (r230687) @@ -60,6 +60,7 @@ static device_attach_t central_attach; static bus_print_child_t central_print_child; static bus_probe_nomatch_t central_probe_nomatch; static bus_alloc_resource_t central_alloc_resource; +static bus_adjust_resource_t central_adjust_resource; static bus_get_resource_list_t central_get_resource_list; static ofw_bus_get_devinfo_t central_get_devinfo; @@ -79,6 +80,7 @@ static device_method_t central_methods[] DEVMETHOD(bus_alloc_resource, central_alloc_resource), DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_adjust_resource, central_adjust_resource), DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), @@ -180,6 +182,15 @@ central_attach(device_t dev) } static int +central_adjust_resource(device_t bus __unused, device_t child __unused, + int type __unused, struct resource *r __unused, u_long start __unused, + u_long end __unused) +{ + + return (ENXIO); +} + +static int central_print_child(device_t dev, device_t child) { int rv; Modified: stable/9/sys/sparc64/conf/DEFAULTS ============================================================================== --- stable/9/sys/sparc64/conf/DEFAULTS Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/sparc64/conf/DEFAULTS Sat Jan 28 23:53:06 2012 (r230687) @@ -19,3 +19,5 @@ options GEOM_PART_VTOC8 # Let sunkbd emulate an AT keyboard by default. options SUNKBD_EMULATE_ATKBD + +options NEW_PCIB Modified: stable/9/sys/sparc64/ebus/ebus.c ============================================================================== --- stable/9/sys/sparc64/ebus/ebus.c Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/sparc64/ebus/ebus.c Sat Jan 28 23:53:06 2012 (r230687) @@ -136,6 +136,8 @@ static device_attach_t ebus_pci_attach; static bus_print_child_t ebus_print_child; static bus_probe_nomatch_t ebus_probe_nomatch; static bus_alloc_resource_t ebus_alloc_resource; +static bus_activate_resource_t ebus_activate_resource; +static bus_adjust_resource_t ebus_adjust_resource; static bus_release_resource_t ebus_release_resource; static bus_setup_intr_t ebus_setup_intr; static bus_get_resource_list_t ebus_get_resource_list; @@ -161,8 +163,9 @@ static device_method_t ebus_nexus_method DEVMETHOD(bus_print_child, ebus_print_child), DEVMETHOD(bus_probe_nomatch, ebus_probe_nomatch), DEVMETHOD(bus_alloc_resource, ebus_alloc_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_activate_resource, ebus_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_adjust_resource, ebus_adjust_resource), DEVMETHOD(bus_release_resource, ebus_release_resource), DEVMETHOD(bus_setup_intr, ebus_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), @@ -342,16 +345,10 @@ ebus_pci_attach(device_t dev) eri->eri_res = res; eri->eri_rman.rm_type = RMAN_ARRAY; eri->eri_rman.rm_descr = "EBus range"; - if (rman_init(&eri->eri_rman) != 0) { + if (rman_init_from_resource(&eri->eri_rman, res) != 0) { printf("%s: failed to initialize rman!", __func__); goto fail; } - if (rman_manage_region(&eri->eri_rman, rman_get_start(res), - rman_get_end(res)) != 0) { - printf("%s: failed to register region!", __func__); - rman_fini(&eri->eri_rman); - goto fail; - } } return (ebus_attach(dev, sc, node)); @@ -423,12 +420,10 @@ ebus_alloc_resource(device_t bus, device struct resource_list *rl; struct resource_list_entry *rle = NULL; struct resource *res; - struct ebus_rinfo *ri; + struct ebus_rinfo *eri; struct ebus_nexus_ranges *enr; - bus_space_tag_t bt; - bus_space_handle_t bh; uint64_t cend, cstart, offset; - int i, isdefault, passthrough, ridx, rv; + int i, isdefault, passthrough, ridx; isdefault = (start == 0UL && end == ~0UL); passthrough = (device_get_parent(child) != bus); @@ -459,23 +454,17 @@ ebus_alloc_resource(device_t bus, device */ (void)ofw_isa_range_map(sc->sc_range, sc->sc_nrange, &start, &end, &ridx); - ri = &sc->sc_rinfo[ridx]; - res = rman_reserve_resource(&ri->eri_rman, start, end, - count, flags, child); + eri = &sc->sc_rinfo[ridx]; + res = rman_reserve_resource(&eri->eri_rman, start, + end, count, flags & ~RF_ACTIVE, child); if (res == NULL) return (NULL); rman_set_rid(res, *rid); - bt = rman_get_bustag(ri->eri_res); - rman_set_bustag(res, bt); - rv = bus_space_subregion(bt, - rman_get_bushandle(ri->eri_res), - rman_get_start(res) - rman_get_start(ri->eri_res), - count, &bh); - if (rv != 0) { + if ((flags & RF_ACTIVE) != 0 && bus_activate_resource( + child, type, *rid, res) != 0) { rman_release_resource(res); return (NULL); } - rman_set_bushandle(res, bh); } else { /* Map EBus ranges to nexus ranges. */ for (i = 0; i < sc->sc_nrange; i++) { @@ -496,7 +485,6 @@ ebus_alloc_resource(device_t bus, device break; } } - } if (!passthrough) rle->res = res; @@ -509,6 +497,48 @@ ebus_alloc_resource(device_t bus, device } static int +ebus_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *res) +{ + struct ebus_softc *sc; + struct ebus_rinfo *eri; + bus_space_tag_t bt; + bus_space_handle_t bh; + int i, rv; + + sc = device_get_softc(bus); + if ((sc->sc_flags & EBUS_PCI) != 0 && type == SYS_RES_MEMORY) { + for (i = 0; i < sc->sc_nrange; i++) { + eri = &sc->sc_rinfo[i]; + if (rman_is_region_manager(res, &eri->eri_rman) != 0) { + bt = rman_get_bustag(eri->eri_res); + rv = bus_space_subregion(bt, + rman_get_bushandle(eri->eri_res), + rman_get_start(res) - + rman_get_start(eri->eri_res), + rman_get_size(res), &bh); + if (rv != 0) + return (rv); + rman_set_bustag(res, bt); + rman_set_bushandle(res, bh); + return (rman_activate_resource(res)); + } + } + return (EINVAL); + } + return (bus_generic_activate_resource(bus, child, type, rid, res)); +} + +static int +ebus_adjust_resource(device_t bus __unused, device_t child __unused, + int type __unused, struct resource *res __unused, u_long start __unused, + u_long end __unused) +{ + + return (ENXIO); +} + +static int ebus_release_resource(device_t bus, device_t child, int type, int rid, struct resource *res) { @@ -519,13 +549,15 @@ ebus_release_resource(device_t bus, devi passthrough = (device_get_parent(child) != bus); rl = BUS_GET_RESOURCE_LIST(bus, child); - switch (type) { - case SYS_RES_MEMORY: - sc = device_get_softc(bus); - if ((sc->sc_flags & EBUS_PCI) == 0) - return (resource_list_release(rl, bus, child, type, - rid, res)); - if ((rv = rman_release_resource(res)) != 0) + sc = device_get_softc(bus); + if ((sc->sc_flags & EBUS_PCI) != 0 && type == SYS_RES_MEMORY) { + if ((rman_get_flags(res) & RF_ACTIVE) != 0 ){ + rv = bus_deactivate_resource(child, type, rid, res); + if (rv != 0) + return (rv); + } + rv = rman_release_resource(res); + if (rv != 0) return (rv); if (!passthrough) { rle = resource_list_find(rl, type, rid); @@ -535,13 +567,9 @@ ebus_release_resource(device_t bus, devi ("%s: resource entry is not busy", __func__)); rle->res = NULL; } - break; - case SYS_RES_IRQ: - return (resource_list_release(rl, bus, child, type, rid, res)); - default: - panic("%s: unsupported resource type %d", __func__, type); + return (0); } - return (0); + return (resource_list_release(rl, bus, child, type, rid, res)); } static int Modified: stable/9/sys/sparc64/fhc/fhc.c ============================================================================== --- stable/9/sys/sparc64/fhc/fhc.c Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/sparc64/fhc/fhc.c Sat Jan 28 23:53:06 2012 (r230687) @@ -69,6 +69,7 @@ static bus_print_child_t fhc_print_child static bus_probe_nomatch_t fhc_probe_nomatch; static bus_setup_intr_t fhc_setup_intr; static bus_alloc_resource_t fhc_alloc_resource; +static bus_adjust_resource_t fhc_adjust_resource; static bus_get_resource_list_t fhc_get_resource_list; static ofw_bus_get_devinfo_t fhc_get_devinfo; @@ -93,6 +94,7 @@ static device_method_t fhc_methods[] = { DEVMETHOD(bus_alloc_resource, fhc_alloc_resource), DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_adjust_resource, fhc_adjust_resource), DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), DEVMETHOD(bus_setup_intr, fhc_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), @@ -475,6 +477,15 @@ fhc_alloc_resource(device_t bus, device_ return (res); } +static int +fhc_adjust_resource(device_t bus __unused, device_t child __unused, + int type __unused, struct resource *r __unused, u_long start __unused, + u_long end __unused) +{ + + return (ENXIO); +} + static struct resource_list * fhc_get_resource_list(device_t bus, device_t child) { Modified: stable/9/sys/sparc64/include/bus.h ============================================================================== --- stable/9/sys/sparc64/include/bus.h Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/sparc64/include/bus.h Sat Jan 28 23:53:06 2012 (r230687) @@ -122,32 +122,15 @@ static int bus_space_subregion(bus_space /* * Map a region of device bus space into CPU virtual address space. */ - -static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr, - bus_size_t size, int flags, bus_space_handle_t *bshp); - -static __inline int -bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr, - bus_size_t size __unused, int flags __unused, bus_space_handle_t *bshp) -{ - - *bshp = addr; - return (0); -} +int bus_space_map(bus_space_tag_t tag, bus_addr_t address, bus_size_t size, + int flags, bus_space_handle_t *handlep); /* * Unmap a region of device bus space. */ -static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, +void bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size); -static __inline void -bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused, - bus_size_t size __unused) -{ - -} - /* This macro finds the first "upstream" implementation of method `f' */ #define _BS_CALL(t,f) \ while (t->f == NULL) \ Modified: stable/9/sys/sparc64/include/bus_private.h ============================================================================== --- stable/9/sys/sparc64/include/bus_private.h Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/sparc64/include/bus_private.h Sat Jan 28 23:53:06 2012 (r230687) @@ -36,10 +36,14 @@ /* * Helpers */ -int sparc64_bus_mem_map(bus_space_tag_t, bus_space_handle_t, bus_size_t, - int, vm_offset_t, void **); -int sparc64_bus_mem_unmap(void *, bus_size_t); -bus_space_handle_t sparc64_fake_bustag(int, bus_addr_t, struct bus_space_tag *); +int sparc64_bus_mem_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size, + int flags, vm_offset_t vaddr, bus_space_handle_t *hp); +int sparc64_bus_mem_unmap(bus_space_tag_t tag, bus_space_handle_t handle, + bus_size_t size); +bus_space_tag_t sparc64_alloc_bus_tag(void *cookie, + struct bus_space_tag *ptag, int type, void *barrier); +bus_space_handle_t sparc64_fake_bustag(int space, bus_addr_t addr, + struct bus_space_tag *ptag); struct bus_dmamap_res { struct resource *dr_res; Modified: stable/9/sys/sparc64/pci/apb.c ============================================================================== --- stable/9/sys/sparc64/pci/apb.c Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/sparc64/pci/apb.c Sat Jan 28 23:53:06 2012 (r230687) @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/bus.h> #include <sys/rman.h> +#include <sys/sysctl.h> #include <dev/ofw/ofw_bus.h> #include <dev/ofw/openfirm.h> @@ -77,6 +78,7 @@ struct apb_softc { static device_probe_t apb_probe; static device_attach_t apb_attach; static bus_alloc_resource_t apb_alloc_resource; +static bus_adjust_resource_t apb_adjust_resource; static device_method_t apb_methods[] = { /* Device interface */ @@ -85,6 +87,8 @@ static device_method_t apb_methods[] = { /* Bus interface */ DEVMETHOD(bus_alloc_resource, apb_alloc_resource), + DEVMETHOD(bus_adjust_resource, apb_adjust_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), /* pcib interface */ DEVMETHOD(pcib_route_interrupt, ofw_pcib_gen_route_interrupt), @@ -158,6 +162,8 @@ static int apb_attach(device_t dev) { struct apb_softc *sc; + struct sysctl_ctx_list *sctx; + struct sysctl_oid *soid; sc = device_get_softc(dev); @@ -165,12 +171,41 @@ apb_attach(device_t dev) * Get current bridge configuration. */ sc->sc_bsc.ops_pcib_sc.domain = pci_get_domain(dev); + sc->sc_bsc.ops_pcib_sc.secstat = + pci_read_config(dev, PCIR_SECSTAT_1, 2); + sc->sc_bsc.ops_pcib_sc.command = + pci_read_config(dev, PCIR_COMMAND, 2); + sc->sc_bsc.ops_pcib_sc.pribus = + pci_read_config(dev, PCIR_PRIBUS_1, 1); sc->sc_bsc.ops_pcib_sc.secbus = pci_read_config(dev, PCIR_SECBUS_1, 1); sc->sc_bsc.ops_pcib_sc.subbus = pci_read_config(dev, PCIR_SUBBUS_1, 1); + sc->sc_bsc.ops_pcib_sc.bridgectl = + pci_read_config(dev, PCIR_BRIDGECTL_1, 2); + sc->sc_bsc.ops_pcib_sc.seclat = + pci_read_config(dev, PCIR_SECLAT_1, 1); sc->sc_iomap = pci_read_config(dev, APBR_IOMAP, 1); sc->sc_memmap = pci_read_config(dev, APBR_MEMMAP, 1); + + /* + * Setup SYSCTL reporting nodes. + */ + sctx = device_get_sysctl_ctx(dev); + soid = device_get_sysctl_tree(dev); + SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "domain", + CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.domain, 0, + "Domain number"); + SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "pribus", + CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.pribus, 0, + "Primary bus number"); + SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "secbus", + CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.secbus, 0, + "Secondary bus number"); + SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "subbus", + CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.subbus, 0, + "Subordinate bus number"); + ofw_pcib_gen_setup(dev); if (bootverbose) { @@ -233,9 +268,9 @@ apb_alloc_resource(device_t dev, device_ "%s requested decoded I/O range 0x%lx-0x%lx\n", device_get_nameunit(child), start, end); break; - case SYS_RES_MEMORY: - if (!apb_checkrange(sc->sc_memmap, APB_MEM_SCALE, start, end)) { + if (!apb_checkrange(sc->sc_memmap, APB_MEM_SCALE, start, + end)) { device_printf(dev, "device %s requested unsupported " "memory range 0x%lx-0x%lx\n", device_get_nameunit(child), start, end); @@ -246,9 +281,6 @@ apb_alloc_resource(device_t dev, device_ "%s requested decoded memory range 0x%lx-0x%lx\n", device_get_nameunit(child), start, end); break; - - default: - break; } passup: @@ -258,3 +290,23 @@ apb_alloc_resource(device_t dev, device_ return (bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags)); } + +static int +apb_adjust_resource(device_t dev, device_t child, int type, + struct resource *r, u_long start, u_long end) +{ + struct apb_softc *sc; + + sc = device_get_softc(dev); + switch (type) { + case SYS_RES_IOPORT: + if (!apb_checkrange(sc->sc_iomap, APB_IO_SCALE, start, end)) + return (ENXIO); + break; + case SYS_RES_MEMORY: + if (!apb_checkrange(sc->sc_memmap, APB_MEM_SCALE, start, end)) + return (ENXIO); + break; + } + return (bus_generic_adjust_resource(dev, child, type, r, start, end)); +} Modified: stable/9/sys/sparc64/pci/fire.c ============================================================================== --- stable/9/sys/sparc64/pci/fire.c Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/sparc64/pci/fire.c Sat Jan 28 23:53:06 2012 (r230687) @@ -85,7 +85,6 @@ __FBSDID("$FreeBSD$"); struct fire_msiqarg; -static bus_space_tag_t fire_alloc_bus_tag(struct fire_softc *sc, int type); static const struct fire_desc *fire_get_desc(device_t dev); static void fire_dmamap_sync(bus_dma_tag_t dt __unused, bus_dmamap_t map, bus_dmasync_op_t op); @@ -113,11 +112,11 @@ static driver_filter_t fire_xcb; * Methods */ static bus_activate_resource_t fire_activate_resource; +static bus_adjust_resource_t fire_adjust_resource; static pcib_alloc_msi_t fire_alloc_msi; static pcib_alloc_msix_t fire_alloc_msix; static bus_alloc_resource_t fire_alloc_resource; static device_attach_t fire_attach; -static bus_deactivate_resource_t fire_deactivate_resource; static bus_get_dma_tag_t fire_get_dma_tag; static ofw_bus_get_node_t fire_get_node; static pcib_map_msi_t fire_map_msi; @@ -127,7 +126,6 @@ static pcib_read_config_t fire_read_conf static bus_read_ivar_t fire_read_ivar; static pcib_release_msi_t fire_release_msi; static pcib_release_msix_t fire_release_msix; -static bus_release_resource_t fire_release_resource; static pcib_route_interrupt_t fire_route_interrupt; static bus_setup_intr_t fire_setup_intr; static bus_teardown_intr_t fire_teardown_intr; @@ -146,9 +144,10 @@ static device_method_t fire_methods[] = DEVMETHOD(bus_setup_intr, fire_setup_intr), DEVMETHOD(bus_teardown_intr, fire_teardown_intr), DEVMETHOD(bus_alloc_resource, fire_alloc_resource), - DEVMETHOD(bus_activate_resource, fire_activate_resource), - DEVMETHOD(bus_deactivate_resource, fire_deactivate_resource), - DEVMETHOD(bus_release_resource, fire_release_resource), + DEVMETHOD(bus_activate_resource, fire_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_adjust_resource, fire_adjust_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), DEVMETHOD(bus_get_dma_tag, fire_get_dma_tag), /* pcib interface */ @@ -756,13 +755,19 @@ fire_attach(device_t dev) free(range, M_OFWPROP); /* Allocate our tags. */ - sc->sc_pci_memt = fire_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE); - sc->sc_pci_iot = fire_alloc_bus_tag(sc, PCI_IO_BUS_SPACE); - sc->sc_pci_cfgt = fire_alloc_bus_tag(sc, PCI_CONFIG_BUS_SPACE); + sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag( + sc->sc_mem_res[FIRE_PCI]), PCI_IO_BUS_SPACE, NULL); + if (sc->sc_pci_iot == NULL) + panic("%s: could not allocate PCI I/O tag", __func__); + sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag( + sc->sc_mem_res[FIRE_PCI]), PCI_CONFIG_BUS_SPACE, NULL); + if (sc->sc_pci_cfgt == NULL) + panic("%s: could not allocate PCI configuration space tag", + __func__); if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0, sc->sc_is.is_pmaxaddr, ~0, NULL, NULL, sc->sc_is.is_pmaxaddr, 0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0) - panic("%s: bus_dma_tag_create failed", __func__); + panic("%s: could not create PCI DMA tag", __func__); /* Customize the tag. */ sc->sc_pci_dmat->dt_cookie = &sc->sc_is; sc->sc_pci_dmat->dt_mt = &sc->sc_dma_methods; @@ -2014,14 +2019,10 @@ fire_alloc_resource(device_t bus, device struct fire_softc *sc; struct resource *rv; struct rman *rm; - bus_space_tag_t bt; - bus_space_handle_t bh; - int needactivate = flags & RF_ACTIVE; - - flags &= ~RF_ACTIVE; sc = device_get_softc(bus); - if (type == SYS_RES_IRQ) { + switch (type) { + case SYS_RES_IRQ: /* * XXX: Don't accept blank ranges for now, only single * interrupts. The other case should not happen with @@ -2033,38 +2034,28 @@ fire_alloc_resource(device_t bus, device panic("%s: XXX: interrupt range", __func__); if (*rid == 0) start = end = INTMAP_VEC(sc->sc_ign, end); - return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, - type, rid, start, end, count, flags)); - } - switch (type) { + return (bus_generic_alloc_resource(bus, child, type, rid, + start, end, count, flags)); case SYS_RES_MEMORY: rm = &sc->sc_pci_mem_rman; - bt = sc->sc_pci_memt; - bh = sc->sc_pci_bh[OFW_PCI_CS_MEM32]; break; case SYS_RES_IOPORT: rm = &sc->sc_pci_io_rman; - bt = sc->sc_pci_iot; - bh = sc->sc_pci_bh[OFW_PCI_CS_IO]; break; default: return (NULL); - /* NOTREACHED */ } - 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); - bh += rman_get_start(rv); - rman_set_bustag(rv, bt); - rman_set_bushandle(rv, bh); - - if (needactivate) { - if (bus_activate_resource(child, type, *rid, rv)) { - rman_release_resource(rv); - return (NULL); - } + + if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type, + *rid, rv) != 0) { + rman_release_resource(rv); + return (NULL); } return (rv); } @@ -2073,56 +2064,56 @@ static int fire_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { - void *p; - int error; + struct fire_softc *sc; + struct bus_space_tag *tag; - if (type == SYS_RES_IRQ) - return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child, - type, rid, r)); - if (type == SYS_RES_MEMORY) { - /* - * Need to memory-map the device space, as some drivers - * depend on the virtual address being set and usable. - */ - error = sparc64_bus_mem_map(rman_get_bustag(r), - rman_get_bushandle(r), rman_get_size(r), 0, 0, &p); - if (error != 0) - return (error); - rman_set_virtual(r, p); + sc = device_get_softc(bus); + switch (type) { + case SYS_RES_IRQ: + return (bus_generic_activate_resource(bus, child, type, rid, + r)); + case SYS_RES_MEMORY: + tag = sparc64_alloc_bus_tag(r, rman_get_bustag( + sc->sc_mem_res[FIRE_PCI]), PCI_MEMORY_BUS_SPACE, NULL); + if (tag == NULL) + return (ENOMEM); + rman_set_bustag(r, tag); + rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] + + rman_get_start(r)); + break; + case SYS_RES_IOPORT: + rman_set_bustag(r, sc->sc_pci_iot); + rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] + + rman_get_start(r)); + break; } return (rman_activate_resource(r)); } static int -fire_deactivate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) +fire_adjust_resource(device_t bus, device_t child, int type, + struct resource *r, u_long start, u_long end) { + struct fire_softc *sc; + struct rman *rm; - if (type == SYS_RES_IRQ) - return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus), child, - type, rid, r)); - if (type == SYS_RES_MEMORY) { - sparc64_bus_mem_unmap(rman_get_virtual(r), rman_get_size(r)); - rman_set_virtual(r, NULL); - } - return (rman_deactivate_resource(r)); -} - -static int -fire_release_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) -{ - int error; - - if (type == SYS_RES_IRQ) - return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child, - type, rid, r)); - if (rman_get_flags(r) & RF_ACTIVE) { - error = bus_deactivate_resource(child, type, rid, r); - if (error) - return (error); + sc = device_get_softc(bus); + switch (type) { + case SYS_RES_IRQ: + return (bus_generic_adjust_resource(bus, child, type, r, + start, end)); + case SYS_RES_MEMORY: + rm = &sc->sc_pci_mem_rman; + break; + case SYS_RES_IOPORT: + rm = &sc->sc_pci_io_rman; + break; + default: + return (EINVAL); } - return (rman_release_resource(r)); + if (rman_is_region_manager(r, rm) == 0) + return (EINVAL); + return (rman_adjust_resource(r, start, end)); } static bus_dma_tag_t @@ -2144,22 +2135,6 @@ fire_get_node(device_t bus, device_t chi return (sc->sc_node); } -static bus_space_tag_t -fire_alloc_bus_tag(struct fire_softc *sc, int type) -{ - bus_space_tag_t bt; - - bt = malloc(sizeof(struct bus_space_tag), M_DEVBUF, - M_NOWAIT | M_ZERO); - if (bt == NULL) - panic("%s: out of memory", __func__); - - bt->bst_cookie = sc; - bt->bst_parent = rman_get_bustag(sc->sc_mem_res[FIRE_PCI]); - bt->bst_type = type; - return (bt); -} - static u_int fire_get_timecount(struct timecounter *tc) { Modified: stable/9/sys/sparc64/pci/firevar.h ============================================================================== --- stable/9/sys/sparc64/pci/firevar.h Sat Jan 28 23:46:36 2012 (r230686) +++ stable/9/sys/sparc64/pci/firevar.h Sat Jan 28 23:53:06 2012 (r230687) @@ -47,7 +47,6 @@ struct fire_softc { bus_space_handle_t sc_pci_bh[FIRE_NRANGE]; bus_space_tag_t sc_pci_cfgt; bus_space_tag_t sc_pci_iot; - bus_space_tag_t sc_pci_memt; bus_dma_tag_t sc_pci_dmat; device_t sc_dev; Modified: stable/9/sys/sparc64/pci/ofw_pcib_subr.c ============================================================================== --- stable/9/sys/sparc64/pci/ofw_pcib_subr.c Sat Jan 28 23:46:36 2012 (r230686) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201282353.q0SNr7e6005493>