Index: sys/dev/ofw/ofwbus.c =================================================================== --- sys/dev/ofw/ofwbus.c +++ sys/dev/ofw/ofwbus.c @@ -66,20 +66,11 @@ * */ -struct ofwbus_softc { - struct simplebus_softc simplebus_sc; - struct rman sc_intr_rman; - struct rman sc_mem_rman; -}; - #ifndef __aarch64__ static device_identify_t ofwbus_identify; #endif static device_probe_t ofwbus_probe; static device_attach_t ofwbus_attach; -static bus_alloc_resource_t ofwbus_alloc_resource; -static bus_adjust_resource_t ofwbus_adjust_resource; -static bus_release_resource_t ofwbus_release_resource; static device_method_t ofwbus_methods[] = { /* Device interface */ @@ -89,16 +80,11 @@ DEVMETHOD(device_probe, ofwbus_probe), DEVMETHOD(device_attach, ofwbus_attach), - /* Bus interface */ - DEVMETHOD(bus_alloc_resource, ofwbus_alloc_resource), - DEVMETHOD(bus_adjust_resource, ofwbus_adjust_resource), - DEVMETHOD(bus_release_resource, ofwbus_release_resource), - DEVMETHOD_END }; DEFINE_CLASS_1(ofwbus, ofwbus_driver, ofwbus_methods, - sizeof(struct ofwbus_softc), simplebus_driver); + sizeof(struct simplebus_softc), simplebus_driver); static devclass_t ofwbus_devclass; EARLY_DRIVER_MODULE(ofwbus, nexus, ofwbus_driver, ofwbus_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); @@ -134,12 +120,9 @@ static int ofwbus_attach(device_t dev) { - struct ofwbus_softc *sc; phandle_t node; struct ofw_bus_devinfo obd; - sc = device_get_softc(dev); - node = OF_peer(0); /* @@ -153,15 +136,6 @@ * ofw_bus_devinfo from it. Pass node to simplebus_init directly. */ simplebus_init(dev, node); - sc->sc_intr_rman.rm_type = RMAN_ARRAY; - sc->sc_intr_rman.rm_descr = "Interrupts"; - sc->sc_mem_rman.rm_type = RMAN_ARRAY; - sc->sc_mem_rman.rm_descr = "Device Memory"; - if (rman_init(&sc->sc_intr_rman) != 0 || - rman_init(&sc->sc_mem_rman) != 0 || - rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0 || - rman_manage_region(&sc->sc_mem_rman, 0, BUS_SPACE_MAXADDR) != 0) - panic("%s: failed to set up rmans.", __func__); /* * Allow devices to identify. @@ -178,118 +152,3 @@ } return (bus_generic_attach(dev)); } - -static struct resource * -ofwbus_alloc_resource(device_t bus, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) -{ - struct ofwbus_softc *sc; - struct rman *rm; - struct resource *rv; - struct resource_list_entry *rle; - int isdefault, passthrough; - - isdefault = RMAN_IS_DEFAULT_RANGE(start, end); - passthrough = (device_get_parent(child) != bus); - sc = device_get_softc(bus); - rle = NULL; - if (!passthrough && isdefault) { - rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child), - type, *rid); - if (rle == NULL) { - if (bootverbose) - device_printf(bus, "no default resources for " - "rid = %d, type = %d\n", *rid, type); - return (NULL); - } - start = rle->start; - count = ummax(count, rle->count); - end = ummax(rle->end, start + count - 1); - } - - switch (type) { - case SYS_RES_IRQ: - rm = &sc->sc_intr_rman; - break; - case SYS_RES_MEMORY: - rm = &sc->sc_mem_rman; - break; - default: - return (NULL); - } - - rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, - child); - if (rv == NULL) - return (NULL); - rman_set_rid(rv, *rid); - - if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type, - *rid, rv) != 0) { - rman_release_resource(rv); - return (NULL); - } - - if (!passthrough && rle != NULL) { - rle->res = rv; - rle->start = rman_get_start(rv); - rle->end = rman_get_end(rv); - rle->count = rle->end - rle->start + 1; - } - - return (rv); -} - -static int -ofwbus_adjust_resource(device_t bus, device_t child __unused, int type, - struct resource *r, rman_res_t start, rman_res_t end) -{ - struct ofwbus_softc *sc; - struct rman *rm; - device_t ofwbus; - - ofwbus = bus; - while (strcmp(device_get_name(device_get_parent(ofwbus)), "root") != 0) - ofwbus = device_get_parent(ofwbus); - sc = device_get_softc(ofwbus); - switch (type) { - case SYS_RES_IRQ: - rm = &sc->sc_intr_rman; - break; - case SYS_RES_MEMORY: - rm = &sc->sc_mem_rman; - break; - default: - return (EINVAL); - } - if (rm == NULL) - return (ENXIO); - if (rman_is_region_manager(r, rm) == 0) - return (EINVAL); - return (rman_adjust_resource(r, start, end)); -} - -static int -ofwbus_release_resource(device_t bus, device_t child, int type, - int rid, struct resource *r) -{ - struct resource_list_entry *rle; - int passthrough; - int error; - - passthrough = (device_get_parent(child) != bus); - if (!passthrough) { - /* Clean resource list entry */ - rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child), - type, rid); - if (rle != NULL) - rle->res = NULL; - } - - if ((rman_get_flags(r) & RF_ACTIVE) != 0) { - error = bus_deactivate_resource(child, type, rid, r); - if (error) - return (error); - } - return (rman_release_resource(r)); -} Index: sys/powerpc/powerpc/nexus.c =================================================================== --- sys/powerpc/powerpc/nexus.c +++ sys/powerpc/powerpc/nexus.c @@ -63,12 +63,18 @@ * mapping. All direct subdevices of nexus are attached by DEVICE_IDENTIFY(). */ +static struct rman intr_rman; +static struct rman mem_rman; + static device_probe_t nexus_probe; static device_attach_t nexus_attach; static bus_setup_intr_t nexus_setup_intr; static bus_teardown_intr_t nexus_teardown_intr; +static bus_alloc_resource_t nexus_alloc_resource; static bus_activate_resource_t nexus_activate_resource; static bus_deactivate_resource_t nexus_deactivate_resource; +static bus_adjust_resource_t nexus_adjust_resource; +static bus_release_resource_t nexus_release_resource; static int nexus_map_resource(device_t bus, device_t child, int type, struct resource *r, struct resource_map_request *argsp, @@ -92,8 +98,11 @@ /* Bus interface */ DEVMETHOD(bus_add_child, bus_generic_add_child), + DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_activate_resource, nexus_activate_resource), DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), + DEVMETHOD(bus_adjust_resource, nexus_adjust_resource), + DEVMETHOD(bus_release_resource, nexus_release_resource), DEVMETHOD(bus_map_resource, nexus_map_resource), DEVMETHOD(bus_unmap_resource, nexus_unmap_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), @@ -131,6 +140,16 @@ nexus_attach(device_t dev) { + intr_rman.rm_type = RMAN_ARRAY; + intr_rman.rm_descr = "Interrupts"; + mem_rman.rm_type = RMAN_ARRAY; + mem_rman.rm_descr = "Device Memory"; + if (rman_init(&intr_rman) != 0 || + rman_init(&mem_rman) != 0 || + rman_manage_region(&intr_rman, 0, 1UL << 16) != 0 || + rman_manage_region(&mem_rman, 0, ~0 >> 1) != 0) + panic("%s: failed to set up rmans.", __func__); + bus_generic_probe(dev); bus_generic_attach(dev); @@ -236,6 +255,65 @@ return (intr); } +static struct resource * +nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, + rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) +{ + struct rman *rm; + struct resource *rv; + struct resource_list_entry *rle; + int isdefault, passthrough; + + isdefault = RMAN_IS_DEFAULT_RANGE(start, end); + passthrough = (device_get_parent(child) != bus); + rle = NULL; + if (!passthrough && isdefault) { + rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child), + type, *rid); + if (rle == NULL) { + if (bootverbose) + device_printf(bus, "no default resources for " + "rid = %d, type = %d\n", *rid, type); + return (NULL); + } + start = rle->start; + count = ummax(count, rle->count); + end = ummax(rle->end, start + count - 1); + } + + switch (type) { + case SYS_RES_IRQ: + rm = &intr_rman; + break; + case SYS_RES_MEMORY: + rm = &mem_rman; + break; + default: + return (NULL); + } + + rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, + child); + if (rv == NULL) + return (NULL); + rman_set_rid(rv, *rid); + + if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type, + *rid, rv) != 0) { + rman_release_resource(rv); + return (NULL); + } + + if (!passthrough && rle != NULL) { + rle->res = rv; + rle->start = rman_get_start(rv); + rle->end = rman_get_end(rv); + rle->count = rle->end - rle->start + 1; + } + + return (rv); +} + static int nexus_activate_resource(device_t bus __unused, device_t child __unused, int type, int rid __unused, struct resource *r) @@ -278,6 +356,57 @@ return (rman_deactivate_resource(r)); } +static int +nexus_adjust_resource(device_t bus, device_t child __unused, int type, + struct resource *r, rman_res_t start, rman_res_t end) +{ + struct rman *rm; + device_t ofwbus; + + ofwbus = bus; + while (strcmp(device_get_name(device_get_parent(ofwbus)), "root") != 0) + ofwbus = device_get_parent(ofwbus); + switch (type) { + case SYS_RES_IRQ: + rm = &intr_rman; + break; + case SYS_RES_MEMORY: + rm = &mem_rman; + break; + default: + return (EINVAL); + } + if (rm == NULL) + return (ENXIO); + if (rman_is_region_manager(r, rm) == 0) + return (EINVAL); + return (rman_adjust_resource(r, start, end)); +} + +static int +nexus_release_resource(device_t bus, device_t child, int type, + int rid, struct resource *r) +{ + struct resource_list_entry *rle; + int passthrough; + int error; + + passthrough = (device_get_parent(child) != bus); + if (!passthrough) { + /* Clean resource list entry */ + rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child), + type, rid); + if (rle != NULL) + rle->res = NULL; + } + + if ((rman_get_flags(r) & RF_ACTIVE) != 0) { + error = bus_deactivate_resource(child, type, rid, r); + if (error) + return (error); + } + return (rman_release_resource(r)); +} static int nexus_map_resource(device_t bus, device_t child, int type, struct resource *r,