From 771997501fec5e297ef917537b0208dd1876ad82 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sat, 19 Mar 2005 00:50:28 +0000 Subject: [PATCH] - Add a device interface method for bus_get_resource_list() and use bus_generic_rl_release_resource() for the bus_release_resource() method instead of a local copy. - Correctly handle pass-through allocations in fhc_alloc_resource(). - In case the board model can't be determined just print "unknown model" so the physical slot number is reported in any case. - Add support for blinking the 'Cycling' LED of boards on a fhc(4) hanging of off the nexus (i.e. all boards except the clock board) via led(4). All boards have at least 3 controllable status LEDs, 'Power', 'Failure' and 'Cycling'. While the 'Cycling' LED is suitable for signaling from the OS the others are better off being controlled by the firmware. The device name for the 'Cycling' LED of each board is /dev/led/boardX where X is the physical slot number of the board. [1] Obtained from: OpenBSD [1] Tested by: joerg [1] --- sys/sparc64/fhc/fhc.c | 93 ++++++++++++++++++++++------------- sys/sparc64/fhc/fhc_central.c | 3 +- sys/sparc64/fhc/fhc_nexus.c | 3 +- sys/sparc64/fhc/fhcvar.h | 5 +- 4 files changed, 66 insertions(+), 38 deletions(-) diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c index 196f3fe80ca7..ed95970eb914 100644 --- a/sys/sparc64/fhc/fhc.c +++ b/sys/sparc64/fhc/fhc.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -65,6 +66,7 @@ struct fhc_devinfo { }; static void fhc_intr_stub(void *); +static void fhc_led_func(void *, int); int fhc_probe(device_t dev) @@ -76,6 +78,7 @@ fhc_probe(device_t dev) int fhc_attach(device_t dev) { + char ledname[sizeof("boardXX")]; struct fhc_devinfo *fdi; struct sbus_regs *reg; struct fhc_softc *sc; @@ -95,10 +98,12 @@ fhc_attach(device_t dev) sc = device_get_softc(dev); node = sc->sc_node; + device_printf(dev, "board %d, ", sc->sc_board); if (OF_getprop_alloc(node, "board-model", 1, (void **)&name) != -1) { - device_printf(dev, "board %d, %s\n", sc->sc_board, name); + printf("model %s\n", name); free(name, M_OFWPROP); - } + } else + printf("model unknown\n"); for (i = FHC_FANFAIL; i <= FHC_TOD; i++) { bus_space_write_4(sc->sc_bt[i], sc->sc_bh[i], FHC_ICLR, 0x0); @@ -118,8 +123,8 @@ fhc_attach(device_t dev) ctrl &= ~(FHC_CTRL_AOFF | FHC_CTRL_BOFF | FHC_CTRL_SLINE); bus_space_write_4(sc->sc_bt[FHC_INTERNAL], sc->sc_bh[FHC_INTERNAL], FHC_CTRL, ctrl); - ctrl = bus_space_read_4(sc->sc_bt[FHC_INTERNAL], - sc->sc_bh[FHC_INTERNAL], FHC_CTRL); + bus_space_read_4(sc->sc_bt[FHC_INTERNAL], sc->sc_bh[FHC_INTERNAL], + FHC_CTRL); sc->sc_nrange = OF_getprop_alloc(node, "ranges", sizeof(*sc->sc_ranges), (void **)&sc->sc_ranges); @@ -128,6 +133,11 @@ fhc_attach(device_t dev) return (ENXIO); } + if ((sc->sc_flags & FHC_CENTRAL) == 0) { + snprintf(ledname, sizeof(ledname), "board%d", sc->sc_board); + sc->sc_led_dev = led_create(fhc_led_func, sc, ledname); + } + for (child = OF_child(node); child != 0; child = OF_peer(child)) { if ((OF_getprop_alloc(child, "name", 1, (void **)&name)) == -1) continue; @@ -291,36 +301,41 @@ struct resource * fhc_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { + struct resource_list *rl; struct resource_list_entry *rle; - struct fhc_devinfo *fdi; struct fhc_softc *sc; struct resource *res; bus_addr_t coffset; bus_addr_t cend; bus_addr_t phys; int isdefault; + int passthrough; int i; isdefault = (start == 0UL && end == ~0UL); + passthrough = (device_get_parent(child) != bus); res = NULL; + rle = NULL; + rl = BUS_GET_RESOURCE_LIST(bus, child); sc = device_get_softc(bus); - fdi = device_get_ivars(child); - rle = resource_list_find(&fdi->fdi_rl, type, *rid); - if (rle == NULL) - return (NULL); - if (rle->res != NULL) - panic("%s: resource entry is busy", __func__); - if (isdefault) { - start = rle->start; - count = ulmax(count, rle->count); - end = ulmax(rle->end, start + count - 1); - } + rle = resource_list_find(rl, type, *rid); switch (type) { case SYS_RES_IRQ: - res = bus_generic_alloc_resource(bus, child, type, rid, - start, end, count, flags); + return (resource_list_alloc(rl, bus, child, type, rid, start, + end, count, flags)); break; case SYS_RES_MEMORY: + if (!passthrough) { + if (rle == NULL) + return (NULL); + if (rle->res != NULL) + panic("%s: resource entry is busy", __func__); + if (isdefault) { + start = rle->start; + count = ulmax(count, rle->count); + end = ulmax(rle->end, start + count - 1); + } + } for (i = 0; i < sc->sc_nrange; i++) { coffset = sc->sc_ranges[i].coffset; cend = coffset + sc->sc_ranges[i].size - 1; @@ -332,7 +347,8 @@ fhc_alloc_resource(device_t bus, device_t child, int type, int *rid, res = bus_generic_alloc_resource(bus, child, type, rid, phys + start, phys + end, count, flags); - rle->res = res; + if (!passthrough) + rle->res = res; break; } } @@ -343,25 +359,34 @@ fhc_alloc_resource(device_t bus, device_t child, int type, int *rid, return (res); } -int -fhc_release_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) +struct resource_list * +fhc_get_resource_list(device_t bus, device_t child) { - struct resource_list_entry *rle; struct fhc_devinfo *fdi; - int error; - error = bus_generic_release_resource(bus, child, type, rid, r); - if (error != 0) - return (error); fdi = device_get_ivars(child); - rle = resource_list_find(&fdi->fdi_rl, type, rid); - if (rle == NULL) - panic("%s: can't find resource", __func__); - if (rle->res == NULL) - panic("%s: resource entry is not busy", __func__); - rle->res = NULL; - return (error); + return (&fdi->fdi_rl); +} + +static void +fhc_led_func(void *arg, int onoff) +{ + struct fhc_softc *sc; + uint32_t ctrl; + + sc = (struct fhc_softc *)arg; + + ctrl = bus_space_read_4(sc->sc_bt[FHC_INTERNAL], + sc->sc_bh[FHC_INTERNAL], FHC_CTRL); + if (onoff) + ctrl |= FHC_CTRL_RLED; + else + ctrl &= ~FHC_CTRL_RLED; + ctrl &= ~(FHC_CTRL_AOFF | FHC_CTRL_BOFF | FHC_CTRL_SLINE); + bus_space_write_4(sc->sc_bt[FHC_INTERNAL], sc->sc_bh[FHC_INTERNAL], + FHC_CTRL, ctrl); + bus_space_read_4(sc->sc_bt[FHC_INTERNAL], sc->sc_bh[FHC_INTERNAL], + FHC_CTRL); } const char * diff --git a/sys/sparc64/fhc/fhc_central.c b/sys/sparc64/fhc/fhc_central.c index 1d698ea11bdc..a9487b459c0d 100644 --- a/sys/sparc64/fhc/fhc_central.c +++ b/sys/sparc64/fhc/fhc_central.c @@ -58,9 +58,10 @@ static device_method_t fhc_central_methods[] = { DEVMETHOD(bus_setup_intr, fhc_setup_intr), DEVMETHOD(bus_teardown_intr, fhc_teardown_intr), DEVMETHOD(bus_alloc_resource, fhc_alloc_resource), - DEVMETHOD(bus_release_resource, fhc_release_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), + DEVMETHOD(bus_get_resource_list, fhc_get_resource_list), /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_compat, fhc_get_compat), diff --git a/sys/sparc64/fhc/fhc_nexus.c b/sys/sparc64/fhc/fhc_nexus.c index 0ed97513278e..dd09d116a0d3 100644 --- a/sys/sparc64/fhc/fhc_nexus.c +++ b/sys/sparc64/fhc/fhc_nexus.c @@ -61,9 +61,10 @@ static device_method_t fhc_nexus_methods[] = { DEVMETHOD(bus_setup_intr, fhc_setup_intr), DEVMETHOD(bus_teardown_intr, fhc_teardown_intr), DEVMETHOD(bus_alloc_resource, fhc_alloc_resource), - DEVMETHOD(bus_release_resource, fhc_release_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), + DEVMETHOD(bus_get_resource_list, fhc_get_resource_list), /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_compat, fhc_get_compat), diff --git a/sys/sparc64/fhc/fhcvar.h b/sys/sparc64/fhc/fhcvar.h index af8539d90eda..299a93300cae 100644 --- a/sys/sparc64/fhc/fhcvar.h +++ b/sys/sparc64/fhc/fhcvar.h @@ -41,6 +41,7 @@ struct fhc_softc { int sc_board; int sc_ign; int sc_flags; + struct cdev *sc_led_dev; }; device_probe_t fhc_probe; @@ -51,7 +52,7 @@ bus_probe_nomatch_t fhc_probe_nomatch; bus_setup_intr_t fhc_setup_intr; bus_teardown_intr_t fhc_teardown_intr; bus_alloc_resource_t fhc_alloc_resource; -bus_release_resource_t fhc_release_resource; +bus_get_resource_list_t fhc_get_resource_list; ofw_bus_get_compat_t fhc_get_compat; ofw_bus_get_model_t fhc_get_model; @@ -59,4 +60,4 @@ ofw_bus_get_name_t fhc_get_name; ofw_bus_get_node_t fhc_get_node; ofw_bus_get_type_t fhc_get_type; -#endif +#endif /* !_SPARC64_FHC_FHCVAR_H_ */