From a1a074b6b322dc645c49948f79f7960308978b2f Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 22 Nov 2005 16:39:44 +0000 Subject: [PATCH] - 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 _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)) --- sys/sparc64/central/central.c | 147 +++++++++++----------------- sys/sparc64/ebus/ebus.c | 149 +++++++++------------------- sys/sparc64/fhc/fhc.c | 164 +++++++++++++------------------ sys/sparc64/fhc/fhc_central.c | 12 ++- sys/sparc64/fhc/fhc_nexus.c | 12 ++- sys/sparc64/fhc/fhcvar.h | 6 +- sys/sparc64/pci/ofw_pcibus.c | 107 ++++++-------------- sys/sparc64/sbus/dma_sbus.c | 171 +++++++++++--------------------- sys/sparc64/sbus/sbus.c | 177 ++++++++++++++-------------------- 9 files changed, 334 insertions(+), 611 deletions(-) diff --git a/sys/sparc64/central/central.c b/sys/sparc64/central/central.c index ef3ef3701899..aef9ed0d42ca 100644 --- a/sys/sparc64/central/central.c +++ b/sys/sparc64/central/central.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -47,11 +48,7 @@ __FBSDID("$FreeBSD$"); #include struct central_devinfo { - char *cdi_compat; - char *cdi_model; - char *cdi_name; - char *cdi_type; - phandle_t cdi_node; + struct ofw_bus_devinfo cdi_obdinfo; struct resource_list cdi_rl; }; @@ -67,11 +64,9 @@ 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_get_resource_list_t central_get_resource_list; -static ofw_bus_get_compat_t central_get_compat; -static ofw_bus_get_model_t central_get_model; -static ofw_bus_get_name_t central_get_name; -static ofw_bus_get_node_t central_get_node; -static ofw_bus_get_type_t central_get_type; +static ofw_bus_get_devinfo_t central_get_devinfo; + +static int central_print_res(struct central_devinfo *); static device_method_t central_methods[] = { /* Device interface. */ @@ -91,11 +86,12 @@ static device_method_t central_methods[] = { DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_compat, central_get_compat), - DEVMETHOD(ofw_bus_get_model, central_get_model), - DEVMETHOD(ofw_bus_get_name, central_get_name), - DEVMETHOD(ofw_bus_get_node, central_get_node), - DEVMETHOD(ofw_bus_get_type, central_get_type), + DEVMETHOD(ofw_bus_get_devinfo, central_get_devinfo), + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), { NULL, NULL } }; @@ -129,10 +125,7 @@ central_attach(device_t dev) struct central_softc *sc; phandle_t child; phandle_t node; - bus_addr_t size; - bus_addr_t off; device_t cdev; - char *name; int nreg; int i; @@ -148,37 +141,36 @@ central_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) + cdi = malloc(sizeof(*cdi), M_DEVBUF, M_WAITOK | M_ZERO); + if (ofw_bus_gen_setup_devinfo(&cdi->cdi_obdinfo, child) != 0) { + free(cdi, M_DEVBUF); continue; + } + nreg = OF_getprop_alloc(child, "reg", sizeof(*reg), + (void **)®); + if (nreg == -1) { + device_printf(dev, "<%s>: incomplete\n", + cdi->cdi_obdinfo.obd_name); + ofw_bus_gen_destroy_devinfo(&cdi->cdi_obdinfo); + free(cdi, M_DEVBUF); + continue; + } + resource_list_init(&cdi->cdi_rl); + for (i = 0; i < nreg; i++) + resource_list_add(&cdi->cdi_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); cdev = device_add_child(dev, NULL, -1); - if (cdev != NULL) { - cdi = malloc(sizeof(*cdi), M_DEVBUF, M_WAITOK | M_ZERO); - if (cdi == NULL) - continue; - cdi->cdi_name = name; - cdi->cdi_node = child; - OF_getprop_alloc(child, "compatible", 1, - (void **)&cdi->cdi_compat); - OF_getprop_alloc(child, "device_type", 1, - (void **)&cdi->cdi_type); - OF_getprop_alloc(child, "model", 1, - (void **)&cdi->cdi_model); - resource_list_init(&cdi->cdi_rl); - nreg = OF_getprop_alloc(child, "reg", sizeof(*reg), - (void **)®); - if (nreg != -1) { - for (i = 0; i < nreg; i++) { - off = reg[i].sbr_offset; - size = reg[i].sbr_size; - resource_list_add(&cdi->cdi_rl, - SYS_RES_MEMORY, i, off, off + size, - size); - } - free(reg, M_OFWPROP); - } - device_set_ivars(cdev, cdi); - } else - free(name, M_OFWPROP); + if (cdev == NULL) { + device_printf(dev, "<%s>: device_add_child failed\n", + cdi->cdi_obdinfo.obd_name); + resource_list_free(&cdi->cdi_rl); + ofw_bus_gen_destroy_devinfo(&cdi->cdi_obdinfo); + free(cdi, M_DEVBUF); + continue; + } + device_set_ivars(cdev, cdi); } return (bus_generic_attach(dev)); @@ -187,13 +179,10 @@ central_attach(device_t dev) static int central_print_child(device_t dev, device_t child) { - struct central_devinfo *cdi; int rv; - cdi = device_get_ivars(child); rv = bus_print_child_header(dev, child); - rv += resource_list_print_type(&cdi->cdi_rl, "mem", - SYS_RES_MEMORY, "%#lx"); + rv += central_print_res(device_get_ivars(child)); rv += bus_print_child_footer(dev, child); return (rv); } @@ -201,13 +190,13 @@ central_print_child(device_t dev, device_t child) static void central_probe_nomatch(device_t dev, device_t child) { - struct central_devinfo *cdi; + const char *type; - cdi = device_get_ivars(child); - device_printf(dev, "<%s>", cdi->cdi_name); - resource_list_print_type(&cdi->cdi_rl, "mem", SYS_RES_MEMORY, "%#lx"); + device_printf(dev, "<%s>", ofw_bus_get_name(child)); + central_print_res(device_get_ivars(child)); + type = ofw_bus_get_type(child); printf(" type %s (no driver attached)\n", - cdi->cdi_type != NULL ? cdi->cdi_type : "unknown"); + type != NULL ? type : "unknown"); } static struct resource * @@ -278,47 +267,19 @@ central_get_resource_list(device_t bus, device_t child) return (&cdi->cdi_rl); } -static const char * -central_get_compat(device_t bus, device_t dev) +static const struct ofw_bus_devinfo * +central_get_devinfo(device_t bus, device_t child) { - struct central_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->cdi_compat); -} - -static const char * -central_get_model(device_t bus, device_t dev) -{ - struct central_devinfo *dinfo; + struct central_devinfo *cdi; - dinfo = device_get_ivars(dev); - return (dinfo->cdi_model); + cdi = device_get_ivars(child); + return (&cdi->cdi_obdinfo); } -static const char * -central_get_name(device_t bus, device_t dev) +static int +central_print_res(struct central_devinfo *cdi) { - struct central_devinfo *dinfo; - dinfo = device_get_ivars(dev); - return (dinfo->cdi_name); -} - -static phandle_t -central_get_node(device_t bus, device_t dev) -{ - struct central_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->cdi_node); -} - -static const char * -central_get_type(device_t bus, device_t dev) -{ - struct central_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->cdi_type); + return (resource_list_print_type(&cdi->cdi_rl, "mem", SYS_RES_MEMORY, + "%#lx")); } diff --git a/sys/sparc64/ebus/ebus.c b/sys/sparc64/ebus/ebus.c index 73f83379dd32..6825c7c72050 100644 --- a/sys/sparc64/ebus/ebus.c +++ b/sys/sparc64/ebus/ebus.c @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -76,12 +77,7 @@ __FBSDID("$FreeBSD$"); #include struct ebus_devinfo { - char *edi_compat; /* PROM compatible */ - char *edi_model; /* PROM model */ - char *edi_name; /* PROM name */ - char *edi_type; /* PROM device_type */ - phandle_t edi_node; /* PROM node */ - + struct ofw_bus_devinfo edi_obdinfo; struct resource_list edi_rl; }; @@ -98,7 +94,6 @@ struct ebus_softc { struct ebus_rinfo *sc_rinfo; int sc_nrange; - int sc_nimap; struct ofw_bus_iinfo sc_iinfo; }; @@ -110,14 +105,10 @@ static bus_probe_nomatch_t ebus_probe_nomatch; static bus_alloc_resource_t ebus_alloc_resource; static bus_release_resource_t ebus_release_resource; static bus_get_resource_list_t ebus_get_resource_list; -static ofw_bus_get_compat_t ebus_get_compat; -static ofw_bus_get_model_t ebus_get_model; -static ofw_bus_get_name_t ebus_get_name; -static ofw_bus_get_node_t ebus_get_node; -static ofw_bus_get_type_t ebus_get_type; +static ofw_bus_get_devinfo_t ebus_get_devinfo; static struct ebus_devinfo *ebus_setup_dinfo(device_t, struct ebus_softc *, - phandle_t, char *); + phandle_t); static void ebus_destroy_dinfo(struct ebus_devinfo *); static int ebus_print_res(struct ebus_devinfo *); @@ -139,11 +130,12 @@ static device_method_t ebus_methods[] = { DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_compat, ebus_get_compat), - DEVMETHOD(ofw_bus_get_model, ebus_get_model), - DEVMETHOD(ofw_bus_get_name, ebus_get_name), - DEVMETHOD(ofw_bus_get_node, ebus_get_node), - DEVMETHOD(ofw_bus_get_type, ebus_get_type), + DEVMETHOD(ofw_bus_get_devinfo, ebus_get_devinfo), + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), { 0, 0 } }; @@ -185,7 +177,6 @@ ebus_attach(device_t dev) struct resource *res; device_t cdev; phandle_t node; - char *cname; int i, rnum, rid; sc = device_get_softc(dev); @@ -234,16 +225,14 @@ ebus_attach(device_t dev) * Now attach our children. */ for (node = OF_child(node); node > 0; node = OF_peer(node)) { - if ((OF_getprop_alloc(node, "name", 1, (void **)&cname)) == -1) + if ((edi = ebus_setup_dinfo(dev, sc, node)) == NULL) continue; - - if ((edi = ebus_setup_dinfo(dev, sc, node, cname)) == NULL) { - device_printf(dev, "<%s>: incomplete\n", cname); - free(cname, M_OFWPROP); + if ((cdev = device_add_child(dev, NULL, -1)) == NULL) { + device_printf(dev, "<%s>: device_add_child failed\n", + edi->edi_obdinfo.obd_name); + ebus_destroy_dinfo(edi); continue; } - if ((cdev = device_add_child(dev, NULL, -1)) == NULL) - panic("ebus_attach: device_add_child failed"); device_set_ivars(cdev, edi); } return (bus_generic_attach(dev)); @@ -258,6 +247,7 @@ fail: PCIR_BAR(rnum), eri->eri_res); } } + free(sc->sc_rinfo, M_DEVBUF); free(sc->sc_range, M_OFWPROP); return (ENXIO); } @@ -265,12 +255,10 @@ fail: static int ebus_print_child(device_t dev, device_t child) { - struct ebus_devinfo *edi; int retval; - edi = device_get_ivars(child); retval = bus_print_child_header(dev, child); - retval += ebus_print_res(edi); + retval += ebus_print_res(device_get_ivars(child)); retval += bus_print_child_footer(dev, child); return (retval); } @@ -278,11 +266,9 @@ ebus_print_child(device_t dev, device_t child) static void ebus_probe_nomatch(device_t dev, device_t child) { - struct ebus_devinfo *edi; - edi = device_get_ivars(child); - device_printf(dev, "<%s>", edi->edi_name); - ebus_print_res(edi); + device_printf(dev, "<%s>", ofw_bus_get_name(child)); + ebus_print_res(device_get_ivars(child)); printf(" (no driver attached)\n"); } @@ -394,9 +380,17 @@ ebus_get_resource_list(device_t dev, device_t child) return (&edi->edi_rl); } +static const struct ofw_bus_devinfo * +ebus_get_devinfo(device_t bus, device_t dev) +{ + struct ebus_devinfo *edi; + + edi = device_get_ivars(dev); + return (&edi->edi_obdinfo); +} + static struct ebus_devinfo * -ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node, - char *name) +ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node) { struct ebus_devinfo *edi; struct isa_regs *reg; @@ -406,19 +400,16 @@ ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node, int nreg, nintr, i; edi = malloc(sizeof(*edi), M_DEVBUF, M_ZERO | M_WAITOK); - if (edi == NULL) + if (ofw_bus_gen_setup_devinfo(&edi->edi_obdinfo, node) != 0) { + free(edi, M_DEVBUF); return (NULL); + } resource_list_init(&edi->edi_rl); - edi->edi_name = name; - edi->edi_node = node; - - OF_getprop_alloc(node, "compatible", 1, (void **)&edi->edi_compat); - OF_getprop_alloc(node, "device_type", 1, (void **)&edi->edi_type); - OF_getprop_alloc(node, "model", 1, (void **)&edi->edi_model); nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)®); if (nreg == -1) { - ebus_destroy_dinfo(edi); - return (NULL); + device_printf(dev, "<%s>: incomplete\n", + edi->edi_obdinfo.obd_name); + goto fail; } for (i = 0; i < nreg; i++) { start = ISA_REG_PHYS(reg + i); @@ -431,32 +422,31 @@ ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node, (void **)&intrs); for (i = 0; i < nintr; i++) { rintr = ofw_isa_route_intr(dev, node, &sc->sc_iinfo, intrs[i]); - if (rintr == PCI_INVALID_IRQ) - panic("ebus_setup_dinfo: could not map ebus " - "interrupt %d", intrs[i]); + if (rintr == PCI_INVALID_IRQ) { + device_printf(dev, + "<%s>: could not map EBus interrupt %d\n", + edi->edi_obdinfo.obd_name, intrs[i]); + free(reg, M_OFWPROP); + goto fail; + } resource_list_add(&edi->edi_rl, SYS_RES_IRQ, i, rintr, rintr, 1); } free(intrs, M_OFWPROP); return (edi); + +fail: + ebus_destroy_dinfo(edi); + return (NULL); } -/* - * NOTE: This does not free the name member (it is needed afterwards in some - * cases). - */ static void ebus_destroy_dinfo(struct ebus_devinfo *edi) { - if (edi->edi_compat != NULL) - free(edi->edi_compat, M_OFWPROP); - if (edi->edi_type != NULL) - free(edi->edi_type, M_OFWPROP); - if (edi->edi_model != NULL) - free(edi->edi_model, M_OFWPROP); resource_list_free(&edi->edi_rl); + ofw_bus_gen_destroy_devinfo(&edi->edi_obdinfo); free(edi, M_DEVBUF); } @@ -472,48 +462,3 @@ ebus_print_res(struct ebus_devinfo *edi) "%ld"); return (retval); } - -static const char * -ebus_get_compat(device_t bus, device_t dev) -{ - struct ebus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->edi_compat); -} - -static const char * -ebus_get_model(device_t bus, device_t dev) -{ - struct ebus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->edi_model); -} - -static const char * -ebus_get_name(device_t bus, device_t dev) -{ - struct ebus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->edi_name); -} - -static phandle_t -ebus_get_node(device_t bus, device_t dev) -{ - struct ebus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->edi_node); -} - -static const char * -ebus_get_type(device_t bus, device_t dev) -{ - struct ebus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->edi_type); -} diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c index 8559040aa6b4..53497a7d34ad 100644 --- a/sys/sparc64/fhc/fhc.c +++ b/sys/sparc64/fhc/fhc.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -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; + } + nreg = OF_getprop_alloc(child, "reg", sizeof(*reg), + (void **)®); + 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); + } + free(intr, M_OFWPROP); + } 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 **)®); - 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); - } - device_set_ivars(cdev, fdi); - } else - free(name, M_OFWPROP); + 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) +static int +fhc_print_res(struct fhc_devinfo *fdi) { - struct fhc_devinfo *dinfo; + int rv; - dinfo = device_get_ivars(dev); - return (dinfo->fdi_model); -} - -const char * -fhc_get_name(device_t bus, device_t dev) -{ - 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; - - 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); } diff --git a/sys/sparc64/fhc/fhc_central.c b/sys/sparc64/fhc/fhc_central.c index a63fb3e7a8b3..78a27e11f3e2 100644 --- a/sys/sparc64/fhc/fhc_central.c +++ b/sys/sparc64/fhc/fhc_central.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -65,11 +66,12 @@ static device_method_t fhc_central_methods[] = { DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_compat, fhc_get_compat), - DEVMETHOD(ofw_bus_get_model, fhc_get_model), - DEVMETHOD(ofw_bus_get_name, fhc_get_name), - DEVMETHOD(ofw_bus_get_node, fhc_get_node), - DEVMETHOD(ofw_bus_get_type, fhc_get_type), + DEVMETHOD(ofw_bus_get_devinfo, fhc_get_devinfo), + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), { NULL, NULL } }; diff --git a/sys/sparc64/fhc/fhc_nexus.c b/sys/sparc64/fhc/fhc_nexus.c index c6c286005387..705c5c3dfb70 100644 --- a/sys/sparc64/fhc/fhc_nexus.c +++ b/sys/sparc64/fhc/fhc_nexus.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -68,11 +69,12 @@ static device_method_t fhc_nexus_methods[] = { DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_compat, fhc_get_compat), - DEVMETHOD(ofw_bus_get_model, fhc_get_model), - DEVMETHOD(ofw_bus_get_name, fhc_get_name), - DEVMETHOD(ofw_bus_get_node, fhc_get_node), - DEVMETHOD(ofw_bus_get_type, fhc_get_type), + DEVMETHOD(ofw_bus_get_devinfo, fhc_get_devinfo), + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), { NULL, NULL } }; diff --git a/sys/sparc64/fhc/fhcvar.h b/sys/sparc64/fhc/fhcvar.h index 299a93300cae..a79b8473f9a0 100644 --- a/sys/sparc64/fhc/fhcvar.h +++ b/sys/sparc64/fhc/fhcvar.h @@ -54,10 +54,6 @@ bus_teardown_intr_t fhc_teardown_intr; bus_alloc_resource_t fhc_alloc_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; -ofw_bus_get_name_t fhc_get_name; -ofw_bus_get_node_t fhc_get_node; -ofw_bus_get_type_t fhc_get_type; +ofw_bus_get_devinfo_t fhc_get_devinfo; #endif /* !_SPARC64_FHC_FHCVAR_H_ */ diff --git a/sys/sparc64/pci/ofw_pcibus.c b/sys/sparc64/pci/ofw_pcibus.c index a9b9ad99581f..6928de66d754 100644 --- a/sys/sparc64/pci/ofw_pcibus.c +++ b/sys/sparc64/pci/ofw_pcibus.c @@ -25,10 +25,11 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ +#include +__FBSDID("$FreeBSD$"); + #include "opt_ofw_pci.h" #include @@ -39,6 +40,7 @@ #include #include +#include #include #include @@ -64,11 +66,7 @@ static void ofw_pcibus_setup_device(device_t, u_int, u_int, u_int); static device_probe_t ofw_pcibus_probe; static device_attach_t ofw_pcibus_attach; static pci_assign_interrupt_t ofw_pcibus_assign_interrupt; -static ofw_bus_get_compat_t ofw_pcibus_get_compat; -static ofw_bus_get_model_t ofw_pcibus_get_model; -static ofw_bus_get_name_t ofw_pcibus_get_name; -static ofw_bus_get_node_t ofw_pcibus_get_node; -static ofw_bus_get_type_t ofw_pcibus_get_type; +static ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo; static device_method_t ofw_pcibus_methods[] = { /* Device interface */ @@ -110,22 +108,19 @@ static device_method_t ofw_pcibus_methods[] = { DEVMETHOD(pci_assign_interrupt, ofw_pcibus_assign_interrupt), /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_compat, ofw_pcibus_get_compat), - DEVMETHOD(ofw_bus_get_model, ofw_pcibus_get_model), - DEVMETHOD(ofw_bus_get_name, ofw_pcibus_get_name), - DEVMETHOD(ofw_bus_get_node, ofw_pcibus_get_node), - DEVMETHOD(ofw_bus_get_type, ofw_pcibus_get_type), + DEVMETHOD(ofw_bus_get_devinfo, ofw_pcibus_get_devinfo), + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), { 0, 0 } }; struct ofw_pcibus_devinfo { struct pci_devinfo opd_dinfo; - char *opd_compat; - char *opd_model; - char *opd_name; - char *opd_type; - phandle_t opd_node; + struct ofw_bus_devinfo opd_obdinfo; }; struct ofw_pcibus_softc { @@ -209,7 +204,6 @@ ofw_pcibus_attach(device_t dev) struct ofw_pci_register pcir; struct ofw_pcibus_devinfo *dinfo; phandle_t node, child; - char *cname; u_int slot, busno, func; /* @@ -222,31 +216,21 @@ ofw_pcibus_attach(device_t dev) node = ofw_bus_get_node(dev); for (child = OF_child(node); child != 0; child = OF_peer(child)) { - if ((OF_getprop_alloc(child, "name", 1, (void **)&cname)) == -1) + if (OF_getprop(child, "reg", &pcir, sizeof(pcir)) == -1) continue; - - if (OF_getprop(child, "reg", &pcir, sizeof(pcir)) == -1) { - device_printf(dev, "<%s>: incomplete\n", cname); - free(cname, M_OFWPROP); - continue; - } slot = OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi); func = OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi); ofw_pcibus_setup_device(pcib, busno, slot, func); dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib, busno, slot, func, sizeof(*dinfo)); - if (dinfo != NULL) { - dinfo->opd_name = cname; - dinfo->opd_node = child; - OF_getprop_alloc(child, "compatible", 1, - (void **)&dinfo->opd_compat); - OF_getprop_alloc(child, "device_type", 1, - (void **)&dinfo->opd_type); - OF_getprop_alloc(child, "model", 1, - (void **)&dinfo->opd_model); - pci_add_child(dev, (struct pci_devinfo *)dinfo); - } else - free(cname, M_OFWPROP); + if (dinfo == NULL) + continue; + if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) != + 0) { + pci_freecfg((struct pci_devinfo *)dinfo); + continue; + } + pci_add_child(dev, (struct pci_devinfo *)dinfo); } return (bus_generic_attach(dev)); @@ -255,15 +239,14 @@ ofw_pcibus_attach(device_t dev) static int ofw_pcibus_assign_interrupt(device_t dev, device_t child) { - struct ofw_pcibus_devinfo *dinfo = device_get_ivars(child); - pcicfgregs *cfg = &dinfo->opd_dinfo.cfg; ofw_pci_intr_t intr; int isz; - isz = OF_getprop(dinfo->opd_node, "interrupts", &intr, sizeof(intr)); + isz = OF_getprop(ofw_bus_get_node(child), "interrupts", &intr, + sizeof(intr)); if (isz != sizeof(intr)) { /* No property; our best guess is the intpin. */ - intr = cfg->intpin; + intr = pci_get_intpin(child); } else if (intr >= 255) { /* * A fully specified interrupt (including IGN), as present on @@ -283,47 +266,11 @@ ofw_pcibus_assign_interrupt(device_t dev, device_t child) return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, intr)); } -static const char * -ofw_pcibus_get_compat(device_t bus, device_t dev) -{ - struct ofw_pcibus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->opd_compat); -} - -static const char * -ofw_pcibus_get_model(device_t bus, device_t dev) +static const struct ofw_bus_devinfo * +ofw_pcibus_get_devinfo(device_t bus, device_t dev) { struct ofw_pcibus_devinfo *dinfo; dinfo = device_get_ivars(dev); - return (dinfo->opd_model); -} - -static const char * -ofw_pcibus_get_name(device_t bus, device_t dev) -{ - struct ofw_pcibus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->opd_name); -} - -static phandle_t -ofw_pcibus_get_node(device_t bus, device_t dev) -{ - struct ofw_pcibus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->opd_node); -} - -static const char * -ofw_pcibus_get_type(device_t bus, device_t dev) -{ - struct ofw_pcibus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->opd_type); + return (&dinfo->opd_obdinfo); } diff --git a/sys/sparc64/sbus/dma_sbus.c b/sys/sparc64/sbus/dma_sbus.c index 9f34a8fc3b23..673dc3e5ab3f 100644 --- a/sys/sparc64/sbus/dma_sbus.c +++ b/sys/sparc64/sbus/dma_sbus.c @@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -87,12 +88,7 @@ __FBSDID("$FreeBSD$"); #include struct dma_devinfo { - char *ddi_compat; /* PROM compatible */ - char *ddi_model; /* PROM model */ - char *ddi_name; /* PROM name */ - phandle_t ddi_node; /* PROM node */ - char *ddi_type; /* PROM device_type */ - + struct ofw_bus_devinfo ddi_obdinfo; struct resource_list ddi_rl; }; @@ -112,14 +108,12 @@ static bus_get_resource_list_t dma_get_resource_list; #if 0 static bus_setup_intr_t dma_setup_intr; #endif -static ofw_bus_get_compat_t dma_get_compat; -static ofw_bus_get_model_t dma_get_model; -static ofw_bus_get_name_t dma_get_name; -static ofw_bus_get_node_t dma_get_node; -static ofw_bus_get_type_t dma_get_type; +static ofw_bus_get_devinfo_t dma_get_devinfo; -static struct dma_devinfo *dma_setup_dinfo(device_t, phandle_t, char *); +static struct dma_devinfo *dma_setup_dinfo(device_t, struct dma_softc *, + phandle_t); static void dma_destroy_dinfo(struct dma_devinfo *); +static int dma_print_res(struct dma_devinfo *); static device_method_t dma_methods[] = { /* Device interface */ @@ -143,11 +137,12 @@ static device_method_t dma_methods[] = { DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_compat, dma_get_compat), - DEVMETHOD(ofw_bus_get_model, dma_get_model), - DEVMETHOD(ofw_bus_get_name, dma_get_name), - DEVMETHOD(ofw_bus_get_node, dma_get_node), - DEVMETHOD(ofw_bus_get_type, dma_get_type), + DEVMETHOD(ofw_bus_get_devinfo, dma_get_devinfo), + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), { 0, 0 } }; @@ -182,13 +177,12 @@ dma_attach(device_t dev) struct dma_devinfo *ddi; device_t cdev; const char *name; - char *cabletype, *cname; + char *cabletype; uint32_t csr; phandle_t child, node; int error, burst, children; dsc = device_get_softc(dev); - bzero(dsc, sizeof(struct dma_softc)); lsc = &dsc->sc_lsi64854; name = ofw_bus_get_name(dev); @@ -268,40 +262,26 @@ dma_attach(device_t dev) /* Attach children. */ children = 0; for (child = OF_child(node); child != 0; child = OF_peer(child)) { - if ((OF_getprop_alloc(child, "name", 1, (void **)&cname)) == -1) + if ((ddi = dma_setup_dinfo(dev, dsc, child)) == NULL) continue; - if ((ddi = dma_setup_dinfo(dev, child, cname)) == NULL) { - device_printf(dev, "<%s>: incomplete\n", cname); - free(cname, M_OFWPROP); - continue; - } if (children != 0) { - device_printf(dev, "<%s>: only one child per DMA " - "channel supported\n", cname); + device_printf(dev, + "<%s>: only one child per DMA channel supported\n", + ddi->ddi_obdinfo.obd_name); dma_destroy_dinfo(ddi); - free(cname, M_OFWPROP); continue; } if ((cdev = device_add_child(dev, NULL, -1)) == NULL) { device_printf(dev, "<%s>: device_add_child failed\n", - cname); + ddi->ddi_obdinfo.obd_name); dma_destroy_dinfo(ddi); - free(cname, M_OFWPROP); continue; } device_set_ivars(cdev, ddi); children++; } - error = bus_generic_attach(dev); - if (error != 0) { - device_printf(dev, "bus_generic_attach failed\n"); - goto fail_lsi; - } + return (bus_generic_attach(dev)); - return (0); - - fail_lsi: - lsi64854_detach(lsc); fail_lpdma: bus_dma_tag_destroy(lsc->sc_parent_dmat); fail_lres: @@ -310,30 +290,25 @@ dma_attach(device_t dev) } static struct dma_devinfo * -dma_setup_dinfo(device_t dev, phandle_t node, char *name) +dma_setup_dinfo(device_t dev, struct dma_softc *dsc, phandle_t node) { - struct dma_softc *dsc; struct dma_devinfo *ddi; struct sbus_regs *reg; uint32_t base, iv, *intr; int i, nreg, nintr, slot, rslot; - dsc = device_get_softc(dev); - ddi = malloc(sizeof(*ddi), M_DEVBUF, M_WAITOK | M_ZERO); - if (ddi == NULL) + if (ofw_bus_gen_setup_devinfo(&ddi->ddi_obdinfo, node) != 0) { + free(ddi, M_DEVBUF); return (NULL); + } resource_list_init(&ddi->ddi_rl); - ddi->ddi_name = name; - ddi->ddi_node = node; - OF_getprop_alloc(node, "compatible", 1, (void **)&ddi->ddi_compat); - OF_getprop_alloc(node, "device_type", 1, (void **)&ddi->ddi_type); - OF_getprop_alloc(node, "model", 1, (void **)&ddi->ddi_model); slot = -1; nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)®); if (nreg == -1) { - dma_destroy_dinfo(ddi); - return (NULL); + device_printf(dev, "<%s>: incomplete\n", + ddi->ddi_obdinfo.obd_name); + goto fail; } for (i = 0; i < nreg; i++) { base = reg[i].sbr_offset; @@ -343,10 +318,10 @@ dma_setup_dinfo(device_t dev, phandle_t node, char *name) } else rslot = reg[i].sbr_slot; if (slot != -1 && slot != rslot) { - device_printf(dev, "<%s>: multiple slots\n", name); + device_printf(dev, "<%s>: multiple slots\n", + ddi->ddi_obdinfo.obd_name); free(reg, M_OFWPROP); - dma_destroy_dinfo(ddi); - return (NULL); + goto fail; } slot = rslot; @@ -356,9 +331,8 @@ dma_setup_dinfo(device_t dev, phandle_t node, char *name) free(reg, M_OFWPROP); if (slot != dsc->sc_slot) { device_printf(dev, "<%s>: parent and child slot do not match\n", - name); - dma_destroy_dinfo(ddi); - return (NULL); + ddi->ddi_obdinfo.obd_name); + goto fail; } /* @@ -383,6 +357,10 @@ dma_setup_dinfo(device_t dev, phandle_t node, char *name) free(intr, M_OFWPROP); } return (ddi); + + fail: + dma_destroy_dinfo(ddi); + return (NULL); } static void @@ -390,27 +368,17 @@ dma_destroy_dinfo(struct dma_devinfo *dinfo) { resource_list_free(&dinfo->ddi_rl); - if (dinfo->ddi_compat != NULL) - free(dinfo->ddi_compat, M_OFWPROP); - if (dinfo->ddi_model != NULL) - free(dinfo->ddi_model, M_OFWPROP); - if (dinfo->ddi_type != NULL) - free(dinfo->ddi_type, M_OFWPROP); + ofw_bus_gen_destroy_devinfo(&dinfo->ddi_obdinfo); free(dinfo, M_DEVBUF); } static int dma_print_child(device_t dev, device_t child) { - struct dma_devinfo *ddi; - struct resource_list *rl; int rv; - ddi = device_get_ivars(child); - rl = &ddi->ddi_rl; rv = bus_print_child_header(dev, child); - rv += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx"); - rv += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); + rv += dma_print_res(device_get_ivars(child)); rv += bus_print_child_footer(dev, child); return (rv); } @@ -418,16 +386,13 @@ dma_print_child(device_t dev, device_t child) static void dma_probe_nomatch(device_t dev, device_t child) { - struct dma_devinfo *ddi; - struct resource_list *rl; + const char *type; - ddi = device_get_ivars(child); - rl = &ddi->ddi_rl; - device_printf(dev, "<%s>", ddi->ddi_name); - resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx"); - resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); - printf(" type %s (no driver attached)\n", - ddi->ddi_type != NULL ? ddi->ddi_type : "unknown"); + device_printf(dev, "<%s>", ofw_bus_get_name(child)); + dma_print_res(device_get_ivars(child)); + type = ofw_bus_get_type(child); + printf(" type %s (no driver attached)\n", + type != NULL ? type : "unknown"); } static struct resource_list * @@ -460,47 +425,23 @@ dma_setup_intr(device_t dev, device_t child, struct resource *ires, int flags, } #endif -static const char * -dma_get_compat(device_t bus, device_t dev) +static const struct ofw_bus_devinfo * +dma_get_devinfo(device_t bus, device_t child) { - struct dma_devinfo *dinfo; + struct dma_devinfo *ddi; - dinfo = device_get_ivars(dev); - return (dinfo->ddi_compat); + ddi = device_get_ivars(child); + return (&ddi->ddi_obdinfo); } -static const char * -dma_get_model(device_t bus, device_t dev) +static int +dma_print_res(struct dma_devinfo *ddi) { - struct dma_devinfo *dinfo; + int rv; - dinfo = device_get_ivars(dev); - return (dinfo->ddi_model); -} - -static const char * -dma_get_name(device_t bus, device_t dev) -{ - struct dma_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->ddi_name); -} - -static phandle_t -dma_get_node(device_t bus, device_t dev) -{ - struct dma_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->ddi_node); -} - -static const char * -dma_get_type(device_t bus, device_t dev) -{ - struct dma_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->ddi_type); + rv = 0; + rv += resource_list_print_type(&ddi->ddi_rl, "mem", SYS_RES_MEMORY, + "%#lx"); + rv += resource_list_print_type(&ddi->ddi_rl, "irq", SYS_RES_IRQ, "%ld"); + return (rv); } diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c index 1c245d342786..472d76dd700b 100644 --- a/sys/sparc64/sbus/sbus.c +++ b/sys/sparc64/sbus/sbus.c @@ -114,6 +114,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -136,13 +137,9 @@ __FBSDID("$FreeBSD$"); struct sbus_devinfo { int sdi_burstsz; int sdi_clockfreq; - char *sdi_compat; /* PROM compatible */ - char *sdi_model; /* PROM model */ - char *sdi_name; /* PROM name */ - phandle_t sdi_node; /* PROM node */ int sdi_slot; - char *sdi_type; /* PROM device_type */ + struct ofw_bus_devinfo sdi_obdinfo; struct resource_list sdi_rl; }; @@ -206,20 +203,17 @@ static bus_alloc_resource_t sbus_alloc_resource; static bus_release_resource_t sbus_release_resource; static bus_activate_resource_t sbus_activate_resource; static bus_deactivate_resource_t sbus_deactivate_resource; -static ofw_bus_get_compat_t sbus_get_compat; -static ofw_bus_get_model_t sbus_get_model; -static ofw_bus_get_name_t sbus_get_name; -static ofw_bus_get_node_t sbus_get_node; -static ofw_bus_get_type_t sbus_get_type; +static ofw_bus_get_devinfo_t sbus_get_devinfo; static int sbus_inlist(const char *, const char **); -static struct sbus_devinfo * sbus_setup_dinfo(struct sbus_softc *sc, - phandle_t node, char *name); -static void sbus_destroy_dinfo(struct sbus_devinfo *dinfo); +static struct sbus_devinfo * sbus_setup_dinfo(device_t, struct sbus_softc *, + phandle_t); +static void sbus_destroy_dinfo(struct sbus_devinfo *); static void sbus_intr_stub(void *); static bus_space_tag_t sbus_alloc_bustag(struct sbus_softc *); static void sbus_overtemp(void *); static void sbus_pwrfail(void *); +static int sbus_print_res(struct sbus_devinfo *); static device_method_t sbus_methods[] = { /* Device interface */ @@ -240,11 +234,12 @@ static device_method_t sbus_methods[] = { DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_compat, sbus_get_compat), - DEVMETHOD(ofw_bus_get_model, sbus_get_model), - DEVMETHOD(ofw_bus_get_name, sbus_get_name), - DEVMETHOD(ofw_bus_get_node, sbus_get_node), - DEVMETHOD(ofw_bus_get_type, sbus_get_type), + DEVMETHOD(ofw_bus_get_devinfo, sbus_get_devinfo), + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), { 0, 0 } }; @@ -305,7 +300,7 @@ sbus_attach(device_t dev) device_t cdev; bus_addr_t phys; bus_size_t size; - char *name, *cname; + char *name; phandle_t child, node; u_int64_t mr; int intr, clock, rid, vec, i; @@ -456,14 +451,8 @@ sbus_attach(device_t dev) * and then configuring each device. */ for (child = OF_child(node); child != 0; child = OF_peer(child)) { - if ((OF_getprop_alloc(child, "name", 1, (void **)&cname)) == -1) + if ((sdi = sbus_setup_dinfo(dev, sc, child)) == NULL) continue; - - if ((sdi = sbus_setup_dinfo(sc, child, cname)) == NULL) { - device_printf(dev, "<%s>: incomplete\n", cname); - free(cname, M_OFWPROP); - continue; - } /* * For devices where there are variants that are actually * split into two SBus devices (as opposed to the first @@ -476,17 +465,22 @@ sbus_attach(device_t dev) * drivers which generally is more hackish. */ cdev = device_add_child_ordered(dev, (OF_child(child) == 0 && - sbus_inlist(cname, sbus_order_first)) ? SBUS_ORDER_FIRST : - SBUS_ORDER_NORMAL, NULL, -1); - if (cdev == NULL) - panic("%s: device_add_child_ordered failed", __func__); + sbus_inlist(sdi->sdi_obdinfo.obd_name, sbus_order_first)) ? + SBUS_ORDER_FIRST : SBUS_ORDER_NORMAL, NULL, -1); + if (cdev == NULL) { + device_printf(dev, + "<%s>: device_add_child_ordered failed\n", + sdi->sdi_obdinfo.obd_name); + sbus_destroy_dinfo(sdi); + continue; + } device_set_ivars(cdev, sdi); } return (bus_generic_attach(dev)); } static struct sbus_devinfo * -sbus_setup_dinfo(struct sbus_softc *sc, phandle_t node, char *name) +sbus_setup_dinfo(device_t dev, struct sbus_softc *sc, phandle_t node) { struct sbus_devinfo *sdi; struct sbus_regs *reg; @@ -494,21 +488,19 @@ sbus_setup_dinfo(struct sbus_softc *sc, phandle_t node, char *name) int i, nreg, nintr, slot, rslot; sdi = malloc(sizeof(*sdi), M_DEVBUF, M_ZERO | M_WAITOK); - if (sdi == NULL) + if (ofw_bus_gen_setup_devinfo(&sdi->sdi_obdinfo, node) != 0) { + free(sdi, M_DEVBUF); return (NULL); + } resource_list_init(&sdi->sdi_rl); - sdi->sdi_name = name; - sdi->sdi_node = node; - OF_getprop_alloc(node, "compatible", 1, (void **)&sdi->sdi_compat); - OF_getprop_alloc(node, "device_type", 1, (void **)&sdi->sdi_type); - OF_getprop_alloc(node, "model", 1, (void **)&sdi->sdi_model); slot = -1; nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)®); if (nreg == -1) { - if (sdi->sdi_type == NULL || - strcmp(sdi->sdi_type, "hierarchical") != 0) { - sbus_destroy_dinfo(sdi); - return (NULL); + if (sdi->sdi_obdinfo.obd_type == NULL || + strcmp(sdi->sdi_obdinfo.obd_type, "hierarchical") != 0) { + device_printf(dev, "<%s>: incomplete\n", + sdi->sdi_obdinfo.obd_name); + goto fail; } } else { for (i = 0; i < nreg; i++) { @@ -518,8 +510,12 @@ sbus_setup_dinfo(struct sbus_softc *sc, phandle_t node, char *name) base = SBUS_ABS_TO_OFFSET(base); } else rslot = reg[i].sbr_slot; - if (slot != -1 && slot != rslot) - panic("%s: multiple slots", __func__); + if (slot != -1 && slot != rslot) { + device_printf(dev, "<%s>: multiple slots\n", + sdi->sdi_obdinfo.obd_name); + free(reg, M_OFWPROP); + goto fail; + } slot = rslot; resource_list_add(&sdi->sdi_rl, SYS_RES_MEMORY, i, @@ -560,35 +556,28 @@ sbus_setup_dinfo(struct sbus_softc *sc, phandle_t node, char *name) sdi->sdi_clockfreq = sc->sc_clockfreq; return (sdi); + +fail: + sbus_destroy_dinfo(sdi); + return (NULL); } -/* Free everything except sdi_name, which is handled separately. */ static void sbus_destroy_dinfo(struct sbus_devinfo *dinfo) { resource_list_free(&dinfo->sdi_rl); - if (dinfo->sdi_compat != NULL) - free(dinfo->sdi_compat, M_OFWPROP); - if (dinfo->sdi_model != NULL) - free(dinfo->sdi_model, M_OFWPROP); - if (dinfo->sdi_type != NULL) - free(dinfo->sdi_type, M_OFWPROP); + ofw_bus_gen_destroy_devinfo(&dinfo->sdi_obdinfo); free(dinfo, M_DEVBUF); } static int sbus_print_child(device_t dev, device_t child) { - struct sbus_devinfo *dinfo; - struct resource_list *rl; int rv; - dinfo = device_get_ivars(child); - rl = &dinfo->sdi_rl; rv = bus_print_child_header(dev, child); - rv += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx"); - rv += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); + rv += sbus_print_res(device_get_ivars(child)); rv += bus_print_child_footer(dev, child); return (rv); } @@ -596,16 +585,13 @@ sbus_print_child(device_t dev, device_t child) static void sbus_probe_nomatch(device_t dev, device_t child) { - struct sbus_devinfo *dinfo; - struct resource_list *rl; + const char *type; - dinfo = device_get_ivars(child); - rl = &dinfo->sdi_rl; - device_printf(dev, "<%s>", dinfo->sdi_name); - resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx"); - resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); + device_printf(dev, "<%s>", ofw_bus_get_name(child)); + sbus_print_res(device_get_ivars(child)); + type = ofw_bus_get_type(child); printf(" type %s (no driver attached)\n", - dinfo->sdi_type != NULL ? dinfo->sdi_type : "unknown"); + type != NULL ? type : "unknown"); } static int @@ -732,8 +718,8 @@ sbus_setup_intr(device_t dev, device_t child, struct resource *ires, int flags, } static int -sbus_teardown_intr(device_t dev, device_t child, - struct resource *vec, void *cookie) +sbus_teardown_intr(device_t dev, device_t child, struct resource *vec, + void *cookie) { struct sbus_clr *scl; int error; @@ -885,6 +871,15 @@ sbus_release_resource(device_t bus, device_t child, int type, int rid, return (0); } +static const struct ofw_bus_devinfo * +sbus_get_devinfo(device_t bus, device_t child) +{ + struct sbus_devinfo *sdi; + + sdi = device_get_ivars(child); + return (&sdi->sdi_obdinfo); +} + /* * Handle an overtemp situation. * @@ -926,47 +921,15 @@ sbus_alloc_bustag(struct sbus_softc *sc) return (sbt); } -static const char * -sbus_get_compat(device_t bus, device_t dev) +static int +sbus_print_res(struct sbus_devinfo *sdi) { - struct sbus_devinfo *dinfo; + int rv; - dinfo = device_get_ivars(dev); - return (dinfo->sdi_compat); -} - -static const char * -sbus_get_model(device_t bus, device_t dev) -{ - struct sbus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->sdi_model); -} - -static const char * -sbus_get_name(device_t bus, device_t dev) -{ - struct sbus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->sdi_name); -} - -static phandle_t -sbus_get_node(device_t bus, device_t dev) -{ - struct sbus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->sdi_node); -} - -static const char * -sbus_get_type(device_t bus, device_t dev) -{ - struct sbus_devinfo *dinfo; - - dinfo = device_get_ivars(dev); - return (dinfo->sdi_type); + rv = 0; + rv += resource_list_print_type(&sdi->sdi_rl, "mem", SYS_RES_MEMORY, + "%#lx"); + rv += resource_list_print_type(&sdi->sdi_rl, "irq", SYS_RES_IRQ, + "%ld"); + return (rv); }