summaryrefslogtreecommitdiffstats
path: root/sys/sparc64/fhc
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2005-03-19 00:50:28 +0000
committermarius <marius@FreeBSD.org>2005-03-19 00:50:28 +0000
commita00235b7fa0c3e0bdc0a074cc96e9f9053c7d93e (patch)
treea8263737ebda2578e97f8682019047e2064ec801 /sys/sparc64/fhc
parent37b9c24b7b4fa9f627a9db8df6b483a3e551baf9 (diff)
downloadFreeBSD-src-a00235b7fa0c3e0bdc0a074cc96e9f9053c7d93e.zip
FreeBSD-src-a00235b7fa0c3e0bdc0a074cc96e9f9053c7d93e.tar.gz
- 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]
Diffstat (limited to 'sys/sparc64/fhc')
-rw-r--r--sys/sparc64/fhc/fhc.c93
-rw-r--r--sys/sparc64/fhc/fhc_central.c3
-rw-r--r--sys/sparc64/fhc/fhc_nexus.c3
-rw-r--r--sys/sparc64/fhc/fhcvar.h5
4 files changed, 66 insertions, 38 deletions
diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c
index 196f3fe..ed95970 100644
--- a/sys/sparc64/fhc/fhc.c
+++ b/sys/sparc64/fhc/fhc.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/pcpu.h>
+#include <dev/led/led.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/openfirm.h>
@@ -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 1d698ea..a9487b4 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 0ed9751..dd09d11 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 af8539d..299a933 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_ */
OpenPOWER on IntegriCloud