/*------------------ Private Device Attachment Functions --------------------*/ static void privcmd_identify(driver_t *driver, device_t parent) { KASSERT(xen_domain(), ("Trying to attach privcmd device on non Xen domain")); if (BUS_ADD_CHILD(parent, 0, "privcmd", 0) == NULL) panic("unable to attach privcmd user-space device"); }
static void vpo_identify(driver_t *driver, device_t parent) { device_t dev; dev = device_find_child(parent, "vpo", -1); if (!dev) BUS_ADD_CHILD(parent, 0, "vpo", -1); }
static void wiibus_identify(driver_t *driver, device_t parent) { if (strcmp(installed_platform(), "wii") != 0) return; if (device_find_child(parent, "wiibus", -1) == NULL) BUS_ADD_CHILD(parent, 0, "wiibus", 0); }
static void spibus_hinted_child(device_t bus, const char *dname, int dunit) { device_t child; struct spibus_ivar *devi; child = BUS_ADD_CHILD(bus, 0, dname, dunit); devi = SPIBUS_IVAR(child); resource_int_value(dname, dunit, "cs", &devi->cs); }
static void vmbus_identify(driver_t *driver, device_t parent) { if (!hv_vmbus_query_hypervisor_presence()) return; vm_guest = VM_GUEST_HV; BUS_ADD_CHILD(parent, 0, "vmbus", 0); }
static void iicbus_hinted_child(device_t bus, const char *dname, int dunit) { device_t child; struct iicbus_ivar *devi; child = BUS_ADD_CHILD(bus, 0, dname, dunit); devi = IICBUS_IVAR(child); resource_int_value(dname, dunit, "addr", &devi->addr); }
static void sc_identify(driver_t *driver, device_t parent) { /* * Add with a priority guaranteed to make it last on * the device list. */ BUS_ADD_CHILD(parent, INT_MAX, SC_DRIVER_NAME, 0); }
static void bcm2835_cpufreq_identify(driver_t *driver, device_t parent) { DPRINTF("driver=%p, parent=%p\n", driver, parent); if (device_find_child(parent, "bcm2835_cpufreq", -1) != NULL) return; if (BUS_ADD_CHILD(parent, 0, "bcm2835_cpufreq", -1) == NULL) device_printf(parent, "add child failed\n"); }
/* * Locate the ACPI timer using the FADT, set up and allocate the I/O resources * we will be using. */ static int acpi_hpet_identify(driver_t *driver, device_t parent) { ACPI_TABLE_HPET *hpet; ACPI_TABLE_HEADER *hdr; ACPI_STATUS status; device_t child; /* * Just try once, do nothing if the 'acpi' bus is rescanned. */ if (device_get_state(parent) == DS_ATTACHED) return 0; ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); /* Only one HPET device can be added. */ if (devclass_get_device(acpi_hpet_devclass, 0)) return ENXIO; /* Currently, ID and minimum clock tick info is unused. */ status = AcpiGetTable(ACPI_SIG_HPET, 1, &hdr); if (ACPI_FAILURE(status)) return ENXIO; /* * The unit number could be derived from hdr->Sequence but we only * support one HPET device. */ hpet = (ACPI_TABLE_HPET *)hdr; if (hpet->Sequence != 0) { kprintf("ACPI HPET table warning: Sequence is non-zero (%d)\n", hpet->Sequence); } child = BUS_ADD_CHILD(parent, parent, 0, "acpi_hpet", 0); if (child == NULL) { device_printf(parent, "%s: can't add acpi_hpet0\n", __func__); return ENXIO; } /* Record a magic value so we can detect this device later. */ acpi_set_magic(child, (uintptr_t)&acpi_hpet_devclass); acpi_hpet_res_start = hpet->Address.Address; if (bus_set_resource(child, SYS_RES_MEMORY, 0, hpet->Address.Address, HPET_MEM_WIDTH, -1)) { device_printf(child, "could not set iomem resources: " "0x%jx, %d\n", (uintmax_t)hpet->Address.Address, HPET_MEM_WIDTH); return ENOMEM; } return 0; }
static int legacy_attach(device_t dev) { device_t child; /* * Let our child drivers identify any child devices that they * can find. Once that is done attach any devices that we * found. */ bus_generic_probe(dev); bus_generic_attach(dev); #ifndef PC98 /* * If we didn't see EISA or ISA on a pci bridge, create some * connection points now so they show up "on motherboard". */ if (!devclass_get_device(devclass_find("eisa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "eisa", 0); if (child == NULL) panic("legacy_attach eisa"); device_probe_and_attach(child); } #endif #ifdef DEV_MCA if (MCA_system && !devclass_get_device(devclass_find("mca"), 0)) { child = BUS_ADD_CHILD(dev, 0, "mca", 0); if (child == 0) panic("legacy_probe mca"); device_probe_and_attach(child); } #endif if (!devclass_get_device(devclass_find("isa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "isa", 0); if (child == NULL) panic("legacy_attach isa"); device_probe_and_attach(child); } return 0; }
static int nexus_acpi_attach(device_t dev) { nexus_init_resources(); bus_generic_probe(dev); if (BUS_ADD_CHILD(dev, 10, "acpi", 0) == NULL) panic("failed to add acpi0 device"); return (bus_generic_attach(dev)); }
/* * Define the syscons nexus device attachment */ static void ofwfb_scidentify(driver_t *driver, device_t parent) { device_t child; /* * Add with a priority guaranteed to make it last on * the device list */ child = BUS_ADD_CHILD(parent, INT_MAX, SC_DRIVER_NAME, 0); }
static void ixp425_hinted_child(device_t bus, const char *dname, int dunit) { device_t child; struct ixp425_ivar *ivar; child = BUS_ADD_CHILD(bus, 0, dname, dunit); ivar = IXP425_IVAR(child); resource_int_value(dname, dunit, "addr", &ivar->addr); resource_int_value(dname, dunit, "irq", &ivar->irq); }
static void octm_identify(driver_t *drv, device_t parent) { unsigned i; if (!octeon_has_feature(OCTEON_FEATURE_MGMT_PORT)) return; for (i = 0; i < CVMX_MGMT_PORT_NUM_PORTS; i++) BUS_ADD_CHILD(parent, 0, "octm", i); }
static void ofwbus_identify(driver_t *driver, device_t parent) { /* Check if Open Firmware has been instantiated */ if (OF_peer(0) == 0) return; if (device_find_child(parent, "ofwbus", -1) == NULL) BUS_ADD_CHILD(parent, 0, "ofwbus", -1); }
static void xc_identify(driver_t *driver, device_t parent) { device_t child; if (!xen_pv_domain()) return; child = BUS_ADD_CHILD(parent, 0, driver_name, 0); device_set_driver(child, driver); device_set_desc(child, "Xen Console"); }
static void gic_v3_acpi_identify(driver_t *driver, device_t parent) { struct madt_table_data madt_data; ACPI_TABLE_MADT *madt; vm_paddr_t physaddr; device_t dev; physaddr = acpi_find_table(ACPI_SIG_MADT); if (physaddr == 0) return; madt = acpi_map_table(physaddr, ACPI_SIG_MADT); if (madt == NULL) { device_printf(parent, "gic: Unable to map the MADT\n"); return; } madt_data.parent = parent; madt_data.dist = NULL; madt_data.count = 0; acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, madt_handler, &madt_data); if (madt_data.dist == NULL) { device_printf(parent, "No gic interrupt or distributor table\n"); goto out; } /* This is for the wrong GIC version */ if (madt_data.dist->Version != ACPI_MADT_GIC_VERSION_V3) goto out; dev = BUS_ADD_CHILD(parent, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE, "gic", -1); if (dev == NULL) { device_printf(parent, "add gic child failed\n"); goto out; } /* Add the MADT data */ BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 0, madt_data.dist->BaseAddress, 128 * 1024); madt_data.dev = dev; acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, rdist_map, &madt_data); acpi_set_private(dev, (void *)(uintptr_t)madt_data.dist->Version); out: acpi_unmap_table(madt); }
static void efirtc_identify(driver_t *driver, device_t parent) { /* Don't add the driver unless we have working runtime services. */ if (efi_rt_ok() != 0) return; if (device_find_child(parent, "efirtc", -1) != NULL) return; if (BUS_ADD_CHILD(parent, 0, "efirtc", -1) == NULL) device_printf(parent, "add child failed\n"); }
static void nexus_hinted_child(device_t bus, const char *dname, int dunit) { device_t child; long maddr; int msize; int order; int result; int irq; int mem_hints_count; if ((resource_int_value(dname, dunit, "order", &order)) != 0) order = 1000; child = BUS_ADD_CHILD(bus, order, dname, dunit); if (child == NULL) return; /* * Set hard-wired resources for hinted child using * specific RIDs. */ mem_hints_count = 0; if (resource_long_value(dname, dunit, "maddr", &maddr) == 0) mem_hints_count++; if (resource_int_value(dname, dunit, "msize", &msize) == 0) mem_hints_count++; /* check if all info for mem resource has been provided */ if ((mem_hints_count > 0) && (mem_hints_count < 2)) { printf("Either maddr or msize hint is missing for %s%d\n", dname, dunit); } else if (mem_hints_count) { dprintf("%s: discovered hinted child %s at maddr %p(%d)\n", __func__, device_get_nameunit(child), (void *)(intptr_t)maddr, msize); result = bus_set_resource(child, SYS_RES_MEMORY, 0, maddr, msize); if (result != 0) { device_printf(bus, "warning: bus_set_resource() failed\n"); } } if (resource_int_value(dname, dunit, "irq", &irq) == 0) { result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); if (result != 0) device_printf(bus, "warning: bus_set_resource() failed\n"); } }
static void xendebug_identify(driver_t *driver, device_t parent) { KASSERT(xen_domain(), ("Trying to add Xen debug device to non-xen guest")); if (xen_hvm_domain() && !xen_vector_callback_enabled) return; if (BUS_ADD_CHILD(parent, 0, "debug", 0) == NULL) panic("Unable to add Xen debug device."); }
static void cferes_identify(driver_t* driver, device_t parent) { device_t child; int i; struct resource *res; int result; int rid; struct cferes_softc *sc; uint64_t addr, len, type; child = BUS_ADD_CHILD(parent, 100, "cferes", -1); device_set_driver(child, driver); sc = device_get_softc(child); sc->rnum = 0; for (i = 0; i < ~0U; i++) { result = cfe_enummem(i, CFE_FLG_FULL_ARENA, &addr, &len, &type); if (result < 0) break; if (type != CFE_MI_RESERVED) { if (bootverbose) printf("%s: skipping non reserved range 0x%0jx(%jd)\n", device_getnameunit(child), (uintmax_t)addr, (uintmax_t)len); continue; } bus_set_resource(child, SYS_RES_MEMORY, sc->rnum, addr, len); rid = sc->rnum; res = bus_alloc_resource_any(child, SYS_RES_MEMORY, &rid, 0); if (res == NULL) { bus_delete_resource(child, SYS_RES_MEMORY, sc->rnum); continue; } sc->rid[sc->rnum] = rid; sc->res[sc->rnum] = res; sc->rnum++; if (sc->rnum == MAX_CFE_RESERVATIONS) break; } if (sc->rnum == 0) { device_delete_child(parent, child); return; } device_set_desc(child, "CFE reserved memory"); }
static void isahint_add_device(device_t parent, const char *name, int unit) { device_t child; int sensitive, start, count, t; int order; /* device-specific flag overrides any wildcard */ sensitive = 0; if (resource_int_value(name, unit, "sensitive", &sensitive) != 0) resource_int_value(name, -1, "sensitive", &sensitive); if (sensitive) order = ISA_ORDER_SENSITIVE; else order = ISA_ORDER_SPECULATIVE; child = BUS_ADD_CHILD(parent, parent, order, name, unit); if (child == 0) return; start = 0; count = 0; resource_int_value(name, unit, "port", &start); resource_int_value(name, unit, "portsize", &count); if (start > 0 || count > 0) bus_set_resource(child, SYS_RES_IOPORT, 0, start, count, -1); start = 0; count = 0; resource_int_value(name, unit, "maddr", &start); resource_int_value(name, unit, "msize", &count); if (start > 0 || count > 0) bus_set_resource(child, SYS_RES_MEMORY, 0, start, count, -1); if (resource_int_value(name, unit, "irq", &start) == 0 && start > 0) { bus_set_resource(child, SYS_RES_IRQ, 0, start, 1, machintr_legacy_intr_cpuid(start)); } if (resource_int_value(name, unit, "drq", &start) == 0 && start >= 0) bus_set_resource(child, SYS_RES_DRQ, 0, start, 1, -1); if (resource_int_value(name, unit, "flags", &t) == 0) device_set_flags(child, t); if (resource_int_value(name, unit, "disabled", &t) == 0 && t != 0) device_disable(child); }
static void uart_chipc_identify(driver_t *driver, device_t parent) { struct chipc_capabilities *caps; caps = BHND_CHIPC_GET_CAPABILITIES(parent); if (caps->num_uarts == 0) return; /* * TODO: add more than one UART */ BUS_ADD_CHILD(parent, 0, "uart", -1); }
static void gpiobus_hinted_child(device_t bus, const char *dname, int dunit) { struct gpiobus_softc *sc = GPIOBUS_SOFTC(bus); struct gpiobus_ivar *devi; device_t child; int pins; child = BUS_ADD_CHILD(bus, 0, dname, dunit); devi = GPIOBUS_IVAR(child); resource_int_value(dname, dunit, "pins", &pins); if (gpiobus_parse_pins(sc, child, pins)) device_delete_child(bus, child); }
static void pmtimer_identify(driver_t *driver, device_t parent) { device_t child; /* * Only add a child if one doesn't exist already. */ child = devclass_get_device(pmtimer_devclass, 0); if (child == NULL) { child = BUS_ADD_CHILD(parent, 0, "pmtimer", 0); if (child == NULL) panic("pmtimer_identify"); } }
static int nandsim_start_ctrl(int num) { device_t nexus, ndev; devclass_t nexus_devclass; int ret = 0; nand_debug(NDBG_SIM,"start ctlr num:%d", num); if (num >= MAX_SIM_DEV) return (EINVAL); if (!ctrls[num].created) return (ENODEV); if (ctrls[num].running) return (EBUSY); /* We will add our device as a child of the nexus0 device */ if (!(nexus_devclass = devclass_find("nexus")) || !(nexus = devclass_get_device(nexus_devclass, 0))) return (EFAULT); /* * Create a newbus device representing this frontend instance * * XXX powerpc nexus doesn't implement bus_add_child, so child * must be added by device_add_child(). */ #if defined(__powerpc__) ndev = device_add_child(nexus, "nandsim", num); #else ndev = BUS_ADD_CHILD(nexus, 0, "nandsim", num); #endif if (!ndev) return (EFAULT); mtx_lock(&Giant); ret = device_probe_and_attach(ndev); mtx_unlock(&Giant); if (ret == 0) { ctrls[num].sim_ctrl_dev = ndev; ctrls[num].running = 1; } return (ret); }
static void iicbus_hinted_child(device_t bus, const char *dname, int dunit) { device_t child; int irq; struct iicbus_ivar *devi; child = BUS_ADD_CHILD(bus, 0, dname, dunit); devi = IICBUS_IVAR(child); resource_int_value(dname, dunit, "addr", &devi->addr); if (resource_int_value(dname, dunit, "irq", &irq) == 0) { if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0) device_printf(bus, "warning: bus_set_resource() failed\n"); } }
static void atpic_isa_identify(driver_t *drv, device_t parent) { device_t child; child = BUS_ADD_CHILD(parent, ISA_ORDER_SENSITIVE, drv->name, -1); device_set_driver(child, drv); isa_set_logicalid(child, atpic_ids[0].ip_id); isa_set_vendorid(child, atpic_ids[0].ip_id); bus_set_resource(child, SYS_RES_IOPORT, ATPIC_MASTER, IO_ICU1, 2); bus_set_resource(child, SYS_RES_IOPORT, ATPIC_SLAVE, IO_ICU2, 2); /* ISA interrupts are routed through external interrupt 0. */ bus_set_resource(child, SYS_RES_IRQ, 0, PIC_IRQ_EXT(0), 1); }
static int nexus_attach(device_t dev) { /* * Mask the legacy PICs - we will use the I/O SAPIC for interrupt. */ outb(IO_ICU1+1, 0xff); outb(IO_ICU2+1, 0xff); if (acpi_identify() == 0) BUS_ADD_CHILD(dev, 10, "acpi", 0); clock_register(dev, 1000); bus_generic_attach(dev); return 0; }
static void cpu_identify(driver_t *driver, device_t parent) { device_t child; int i; /* * Attach a cpuX device for each CPU. We use an order of 150 * so that these devices are attached after the Host-PCI * bridges (which are added at order 100). */ CPU_FOREACH(i) { child = BUS_ADD_CHILD(parent, 150, "cpu", i); if (child == NULL) panic("legacy_attach cpu"); } }