static device_t newbus_device_create(device_t dev_par, phandle_t node, char *name, char *type, char *compat) { device_t child; struct fdtbus_devinfo *di; child = device_add_child(dev_par, NULL, -1); if (child == NULL) { free(name, M_OFWPROP); free(type, M_OFWPROP); free(compat, M_OFWPROP); return (NULL); } di = malloc(sizeof(*di), M_FDTBUS, M_WAITOK); di->di_node = node; di->di_name = name; di->di_type = type; di->di_compat = compat; resource_list_init(&di->di_res); if (fdt_reg_to_rl(node, &di->di_res)) { device_printf(child, "could not process 'reg' property\n"); newbus_device_destroy(child); child = NULL; goto out; } if (fdt_intr_to_rl(node, &di->di_res, di->di_intr_sl)) { device_printf(child, "could not process 'interrupts' " "property\n"); newbus_device_destroy(child); child = NULL; goto out; } device_set_ivars(child, di); debugf("added child name='%s', node=%p\n", name, (void *)node); out: return (child); }
static int simplebus_attach(device_t dev) { device_t dev_child; struct simplebus_devinfo *di; struct simplebus_softc *sc; phandle_t dt_node, dt_child; sc = device_get_softc(dev); /* * Walk simple-bus and add direct subordinates as our children. */ dt_node = ofw_bus_get_node(dev); for (dt_child = OF_child(dt_node); dt_child != 0; dt_child = OF_peer(dt_child)) { /* Check and process 'status' property. */ if (!(fdt_is_enabled(dt_child))) continue; if (!(fdt_pm_is_enabled(dt_child))) continue; di = malloc(sizeof(*di), M_SIMPLEBUS, M_WAITOK | M_ZERO); if (ofw_bus_gen_setup_devinfo(&di->di_ofw, dt_child) != 0) { free(di, M_SIMPLEBUS); device_printf(dev, "could not set up devinfo\n"); continue; } resource_list_init(&di->di_res); if (fdt_reg_to_rl(dt_child, &di->di_res)) { device_printf(dev, "%s: could not process 'reg' " "property\n", di->di_ofw.obd_name); /* XXX should unmap */ ofw_bus_gen_destroy_devinfo(&di->di_ofw); free(di, M_SIMPLEBUS); continue; } if (fdt_intr_to_rl(dt_child, &di->di_res, di->di_intr_sl)) { device_printf(dev, "%s: could not process " "'interrupts' property\n", di->di_ofw.obd_name); resource_list_free(&di->di_res); /* XXX should unmap */ ofw_bus_gen_destroy_devinfo(&di->di_ofw); free(di, M_SIMPLEBUS); continue; } /* Add newbus device for this FDT node */ dev_child = device_add_child(dev, NULL, -1); if (dev_child == NULL) { device_printf(dev, "could not add child: %s\n", di->di_ofw.obd_name); resource_list_free(&di->di_res); /* XXX should unmap */ ofw_bus_gen_destroy_devinfo(&di->di_ofw); free(di, M_SIMPLEBUS); continue; } #ifdef DEBUG device_printf(dev, "added child: %s\n\n", di->di_ofw.obd_name); #endif device_set_ivars(dev_child, di); } return (bus_generic_attach(dev)); }