summaryrefslogtreecommitdiffstats
path: root/sys/sparc64/fhc/fhc.c
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2005-11-22 16:39:44 +0000
committermarius <marius@FreeBSD.org>2005-11-22 16:39:44 +0000
commitab72721aedbbd4b9e7ff5a6a29f9b086a07fdc85 (patch)
tree8749168ecb1e9fa530996b26a2b5088675fd8c90 /sys/sparc64/fhc/fhc.c
parentfa92f23f1819b63d981e32c4aa232f819e0a2dc9 (diff)
downloadFreeBSD-src-ab72721aedbbd4b9e7ff5a6a29f9b086a07fdc85.zip
FreeBSD-src-ab72721aedbbd4b9e7ff5a6a29f9b086a07fdc85.tar.gz
- Convert these bus drivers to make use of the newly introduced set of
ofw_bus_gen_get_*() for providing the ofw_bus KOBJ interface in order to reduce code duplication. - While here sync the various sparc64 bus drivers a bit (handle failure to attach a child gracefully instead of panicing, move the printing of child resources common to bus_print_child() and bus_probe_nomatch() implementations of a bus into a <bus>_print_res() function, ...) and fix some minor bugs and nits (plug memory leaks present when attaching a bus or child device fails, remove unused struct members, ...). Additional testing by: kris (central(4) and fhc(4))
Diffstat (limited to 'sys/sparc64/fhc/fhc.c')
-rw-r--r--sys/sparc64/fhc/fhc.c164
1 files changed, 65 insertions, 99 deletions
diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c
index 8559040..53497a7 100644
--- a/sys/sparc64/fhc/fhc.c
+++ b/sys/sparc64/fhc/fhc.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <dev/led/led.h>
#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
#include <machine/bus.h>
@@ -57,16 +58,13 @@ struct fhc_clr {
};
struct fhc_devinfo {
- char *fdi_compat;
- char *fdi_model;
- char *fdi_name;
- char *fdi_type;
- phandle_t fdi_node;
+ struct ofw_bus_devinfo fdi_obdinfo;
struct resource_list fdi_rl;
};
static void fhc_intr_stub(void *);
static void fhc_led_func(void *, int);
+static int fhc_print_res(struct fhc_devinfo *);
int
fhc_probe(device_t dev)
@@ -84,8 +82,6 @@ fhc_attach(device_t dev)
struct fhc_softc *sc;
phandle_t child;
phandle_t node;
- bus_addr_t size;
- bus_addr_t off;
device_t cdev;
uint32_t ctrl;
uint32_t *intr;
@@ -139,48 +135,47 @@ fhc_attach(device_t dev)
}
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
- if ((OF_getprop_alloc(child, "name", 1, (void **)&name)) == -1)
+ fdi = malloc(sizeof(*fdi), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (ofw_bus_gen_setup_devinfo(&fdi->fdi_obdinfo, child) != 0) {
+ free(fdi, M_DEVBUF);
continue;
- cdev = device_add_child(dev, NULL, -1);
- if (cdev != NULL) {
- fdi = malloc(sizeof(*fdi), M_DEVBUF, M_WAITOK | M_ZERO);
- if (fdi == NULL)
- continue;
- fdi->fdi_name = name;
- fdi->fdi_node = child;
- OF_getprop_alloc(child, "compatible", 1,
- (void **)&fdi->fdi_compat);
- OF_getprop_alloc(child, "device_type", 1,
- (void **)&fdi->fdi_type);
- OF_getprop_alloc(child, "model", 1,
- (void **)&fdi->fdi_model);
- resource_list_init(&fdi->fdi_rl);
- nreg = OF_getprop_alloc(child, "reg", sizeof(*reg),
- (void **)&reg);
- if (nreg != -1) {
- for (i = 0; i < nreg; i++) {
- off = reg[i].sbr_offset;
- size = reg[i].sbr_size;
- resource_list_add(&fdi->fdi_rl,
- SYS_RES_MEMORY, i, off, off + size,
- size);
- }
- free(reg, M_OFWPROP);
- }
- nintr = OF_getprop_alloc(child, "interrupts",
- sizeof(*intr), (void **)&intr);
- if (nintr != -1) {
- for (i = 0; i < nintr; i++) {
- iv = INTINO(intr[i]) |
- (sc->sc_ign << INTMAP_IGN_SHIFT);
- resource_list_add(&fdi->fdi_rl,
- SYS_RES_IRQ, i, iv, iv, 1);
- }
- free(intr, M_OFWPROP);
+ }
+ nreg = OF_getprop_alloc(child, "reg", sizeof(*reg),
+ (void **)&reg);
+ if (nreg == -1) {
+ device_printf(dev, "<%s>: incomplete\n",
+ fdi->fdi_obdinfo.obd_name);
+ ofw_bus_gen_destroy_devinfo(&fdi->fdi_obdinfo);
+ free(fdi, M_DEVBUF);
+ continue;
+ }
+ resource_list_init(&fdi->fdi_rl);
+ for (i = 0; i < nreg; i++)
+ resource_list_add(&fdi->fdi_rl, SYS_RES_MEMORY, i,
+ reg[i].sbr_offset, reg[i].sbr_offset +
+ reg[i].sbr_size, reg[i].sbr_size);
+ free(reg, M_OFWPROP);
+ nintr = OF_getprop_alloc(child, "interrupts", sizeof(*intr),
+ (void **)&intr);
+ if (nintr != -1) {
+ for (i = 0; i < nintr; i++) {
+ iv = INTINO(intr[i]) |
+ (sc->sc_ign << INTMAP_IGN_SHIFT);
+ resource_list_add(&fdi->fdi_rl, SYS_RES_IRQ, i,
+ iv, iv, 1);
}
- device_set_ivars(cdev, fdi);
- } else
- free(name, M_OFWPROP);
+ free(intr, M_OFWPROP);
+ }
+ cdev = device_add_child(dev, NULL, -1);
+ if (cdev == NULL) {
+ device_printf(dev, "<%s>: device_add_child failed\n",
+ fdi->fdi_obdinfo.obd_name);
+ resource_list_free(&fdi->fdi_rl);
+ ofw_bus_gen_destroy_devinfo(&fdi->fdi_obdinfo);
+ free(fdi, M_DEVBUF);
+ continue;
+ }
+ device_set_ivars(cdev, fdi);
}
return (bus_generic_attach(dev));
@@ -189,14 +184,10 @@ fhc_attach(device_t dev)
int
fhc_print_child(device_t dev, device_t child)
{
- struct fhc_devinfo *fdi;
int rv;
- fdi = device_get_ivars(child);
rv = bus_print_child_header(dev, child);
- rv += resource_list_print_type(&fdi->fdi_rl, "mem",
- SYS_RES_MEMORY, "%#lx");
- rv += resource_list_print_type(&fdi->fdi_rl, "irq", SYS_RES_IRQ, "%ld");
+ rv += fhc_print_res(device_get_ivars(child));
rv += bus_print_child_footer(dev, child);
return (rv);
}
@@ -204,14 +195,13 @@ fhc_print_child(device_t dev, device_t child)
void
fhc_probe_nomatch(device_t dev, device_t child)
{
- struct fhc_devinfo *fdi;
+ const char *type;
- fdi = device_get_ivars(child);
- device_printf(dev, "<%s>", fdi->fdi_name);
- resource_list_print_type(&fdi->fdi_rl, "mem", SYS_RES_MEMORY, "%#lx");
- resource_list_print_type(&fdi->fdi_rl, "irq", SYS_RES_IRQ, "%ld");
+ device_printf(dev, "<%s>", ofw_bus_get_name(child));
+ fhc_print_res(device_get_ivars(child));
+ type = ofw_bus_get_type(child);
printf(" type %s (no driver attached)\n",
- fdi->fdi_type != NULL ? fdi->fdi_type : "unknown");
+ type != NULL ? type : "unknown");
}
int
@@ -365,6 +355,15 @@ fhc_get_resource_list(device_t bus, device_t child)
return (&fdi->fdi_rl);
}
+const struct ofw_bus_devinfo *
+fhc_get_devinfo(device_t bus, device_t child)
+{
+ struct fhc_devinfo *fdi;
+
+ fdi = device_get_ivars(child);
+ return (&fdi->fdi_obdinfo);
+}
+
static void
fhc_led_func(void *arg, int onoff)
{
@@ -386,47 +385,14 @@ fhc_led_func(void *arg, int onoff)
FHC_CTRL);
}
-const char *
-fhc_get_compat(device_t bus, device_t dev)
-{
- struct fhc_devinfo *dinfo;
-
- dinfo = device_get_ivars(dev);
- return (dinfo->fdi_compat);
-}
-
-const char *
-fhc_get_model(device_t bus, device_t dev)
-{
- struct fhc_devinfo *dinfo;
-
- dinfo = device_get_ivars(dev);
- return (dinfo->fdi_model);
-}
-
-const char *
-fhc_get_name(device_t bus, device_t dev)
+static int
+fhc_print_res(struct fhc_devinfo *fdi)
{
- struct fhc_devinfo *dinfo;
-
- dinfo = device_get_ivars(dev);
- return (dinfo->fdi_name);
-}
-
-phandle_t
-fhc_get_node(device_t bus, device_t dev)
-{
- struct fhc_devinfo *dinfo;
-
- dinfo = device_get_ivars(dev);
- return (dinfo->fdi_node);
-}
-
-const char *
-fhc_get_type(device_t bus, device_t dev)
-{
- struct fhc_devinfo *dinfo;
+ int rv;
- dinfo = device_get_ivars(dev);
- return (dinfo->fdi_type);
+ rv = 0;
+ rv += resource_list_print_type(&fdi->fdi_rl, "mem", SYS_RES_MEMORY,
+ "%#lx");
+ rv += resource_list_print_type(&fdi->fdi_rl, "irq", SYS_RES_IRQ, "%ld");
+ return (rv);
}
OpenPOWER on IntegriCloud