static void at91_add_child(device_t dev, int prio, const char *name, int unit, bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2) { device_t kid; struct at91_ivar *ivar; kid = device_add_child_ordered(dev, prio, name, unit); if (kid == NULL) { printf("Can't add child %s%d ordered\n", name, unit); return; } ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO); if (ivar == NULL) { device_delete_child(dev, kid); printf("Can't add alloc ivar\n"); return; } device_set_ivars(kid, ivar); resource_list_init(&ivar->resources); if (irq0 != -1) bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1); if (irq1 != 0) bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1); if (irq2 != 0) bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1); if (addr != 0) bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size); }
static device_t ofw_iicbus_add_child(device_t dev, u_int order, const char *name, int unit) { device_t child; struct ofw_iicbus_devinfo *devi; child = device_add_child_ordered(dev, order, name, unit); if (child == NULL) return (child); devi = malloc(sizeof(struct ofw_iicbus_devinfo), M_DEVBUF, M_NOWAIT | M_ZERO); if (devi == NULL) { device_delete_child(dev, child); return (0); } /* * NULL all the OFW-related parts of the ivars for non-OFW * children. */ devi->opd_obdinfo.obd_node = -1; devi->opd_obdinfo.obd_name = NULL; devi->opd_obdinfo.obd_compat = NULL; devi->opd_obdinfo.obd_type = NULL; devi->opd_obdinfo.obd_model = NULL; device_set_ivars(child, devi); return (child); }
static device_t cpu_add_child(device_t bus, u_int order, const char *name, int unit) { struct cpu_device *cd; device_t child; #ifndef __rtems__ struct pcpu *pc; #endif /* __rtems__ */ if ((cd = malloc(sizeof(*cd), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) return (NULL); resource_list_init(&cd->cd_rl); #ifndef __rtems__ pc = pcpu_find(device_get_unit(bus)); cd->cd_pcpu = pc; #endif /* __rtems__ */ child = device_add_child_ordered(bus, order, name, unit); if (child != NULL) { #ifndef __rtems__ pc->pc_device = child; #endif /* __rtems__ */ device_set_ivars(child, cd); } else free(cd, M_DEVBUF); return (child); }
static device_t atkbdc_isa_add_child(device_t bus, u_int order, const char *name, int unit) { atkbdc_device_t *ivar; atkbdc_softc_t *sc; device_t child; int t; sc = *(atkbdc_softc_t **)device_get_softc(bus); ivar = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV, M_NOWAIT | M_ZERO); if (!ivar) return NULL; child = device_add_child_ordered(bus, order, name, unit); if (child == NULL) { free(ivar, M_ATKBDDEV); return child; } resource_list_init(&ivar->resources); ivar->rid = order; /* * If the device is not created by the PnP BIOS or ACPI, refer * to device hints for IRQ. We always populate the resource * list entry so we can use a standard bus_get_resource() * method. */ if (order == KBDC_RID_KBD) { if (sc->irq == NULL) { if (resource_int_value(name, unit, "irq", &t) != 0) t = -1; } else t = rman_get_start(sc->irq); if (t > 0) resource_list_add(&ivar->resources, SYS_RES_IRQ, ivar->rid, t, t, 1); } if (resource_disabled(name, unit)) device_disable(child); device_set_ivars(child, ivar); return child; }
static device_t vnex_add_child(device_t dev, int order, const char *name, int unit) { device_t cdev; struct vnex_devinfo *vndi; cdev = device_add_child_ordered(dev, order, name, unit); if (cdev == NULL) return (NULL); vndi = malloc(sizeof(*vndi), M_DEVBUF, M_WAITOK | M_ZERO); vndi->vndi_mbdinfo.mbd_name = strdup(name, M_OFWPROP); resource_list_init(&vndi->vndi_rl); device_set_ivars(cdev, vndi); return (cdev); }
static device_t simplebus_add_child(device_t dev, u_int order, const char *name, int unit) { device_t cdev; struct simplebus_devinfo *ndi; cdev = device_add_child_ordered(dev, order, name, unit); if (cdev == NULL) return (NULL); ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO); ndi->obdinfo.obd_node = -1; resource_list_init(&ndi->rl); device_set_ivars(cdev, ndi); return (cdev); }
static device_t smbus_add_child(device_t dev, u_int order, const char *name, int unit) { struct smbus_ivar *devi; device_t child; child = device_add_child_ordered(dev, order, name, unit); if (child == NULL) return (child); devi = malloc(sizeof(struct smbus_ivar), M_DEVBUF, M_NOWAIT | M_ZERO); if (devi == NULL) { device_delete_child(dev, child); return (NULL); } device_set_ivars(child, devi); return (child); }
static device_t mv_pcib_ctrl_add_child(device_t dev, u_int order, const char *name, int unit) { device_t cdev; struct mv_pcib_ctrl_devinfo *di; cdev = device_add_child_ordered(dev, order, name, unit); if (cdev == NULL) return (NULL); di = malloc(sizeof(*di), M_DEVBUF, M_WAITOK | M_ZERO); di->di_dinfo.obd_node = -1; resource_list_init(&di->di_rl); device_set_ivars(cdev, di); return (cdev); }
static device_t canbus_add_child(device_t bus, u_int order, const char *name, int unit) { device_t child; struct canbus_device *cbdev; child = device_add_child_ordered(bus, order, name, unit); cbdev = malloc( sizeof(struct canbus_device), M_CANBUSDEV, M_NOWAIT | M_ZERO); if (!cbdev) return (0); resource_list_init(&cbdev->cbdev_resources); device_set_ivars(child, cbdev); return (child); }
static device_t iicbus_add_child(device_t dev, u_int order, const char *name, int unit) { device_t child; struct iicbus_ivar *devi; child = device_add_child_ordered(dev, order, name, unit); if (child == NULL) return (child); devi = malloc(sizeof(struct iicbus_ivar), M_DEVBUF, M_NOWAIT | M_ZERO); if (devi == NULL) { device_delete_child(dev, child); return (0); } resource_list_init(&devi->rl); device_set_ivars(child, devi); return (child); }
static device_t nexus_add_child(device_t bus, int order, const char *name, int unit) { device_t child; struct nexus_device *ndev; ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO); if (!ndev) return(0); resource_list_init(&ndev->nx_resources); child = device_add_child_ordered(bus, order, name, unit); /* should we free this in nexus_child_detached? */ device_set_ivars(child, ndev); return(child); }
static device_t acpi_cpu_add_child(device_t dev, int order, const char *name, int unit) { struct acpi_cpu_device *ad; device_t child; if ((ad = malloc(sizeof(*ad), M_TEMP, M_NOWAIT | M_ZERO)) == NULL) return (NULL); resource_list_init(&ad->ad_rl); child = device_add_child_ordered(dev, order, name, unit); if (child != NULL) device_set_ivars(child, ad); else free(ad, M_TEMP); return (child); }
static device_t ixp425_add_child(device_t dev, int order, const char *name, int unit) { device_t child; struct ixp425_ivar *ivar; child = device_add_child_ordered(dev, order, name, unit); if (child == NULL) return NULL; ivar = malloc(sizeof(struct ixp425_ivar), M_DEVBUF, M_NOWAIT); if (ivar == NULL) { device_delete_child(dev, child); return NULL; } ivar->addr = 0; ivar->irq = -1; device_set_ivars(child, ivar); return child; }
static device_t apb_add_child(device_t bus, u_int order, const char *name, int unit) { device_t child; struct apb_ivar *ivar; ivar = malloc(sizeof(struct apb_ivar), M_DEVBUF, M_WAITOK | M_ZERO); resource_list_init(&ivar->resources); child = device_add_child_ordered(bus, order, name, unit); if (child == NULL) { printf("Can't add child %s%d ordered\n", name, unit); return (0); } device_set_ivars(child, ivar); return (child); }
static device_t atkbdc_isa_add_child(device_t bus, int order, char *name, int unit) { atkbdc_device_t *ivar; device_t child; int t; ivar = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV, M_NOWAIT | M_ZERO); if (!ivar) return NULL; child = device_add_child_ordered(bus, order, name, unit); if (child == NULL) { free(ivar, M_ATKBDDEV); return child; } resource_list_init(&ivar->resources); ivar->rid = order; /* * If the device is not created by the PnP BIOS or ACPI, * refer to device hints for IRQ. */ if (ISA_PNP_PROBE(device_get_parent(bus), bus, atkbdc_ids) != 0) { if (resource_int_value(name, unit, "irq", &t) != 0) t = -1; } else { t = bus_get_resource_start(bus, SYS_RES_IRQ, ivar->rid); } if (t > 0) resource_list_add(&ivar->resources, SYS_RES_IRQ, ivar->rid, t, t, 1); if (resource_disabled(name, unit)) device_disable(child); device_set_ivars(child, ivar); return child; }
static device_t nexus_add_child(device_t dev, u_int order, const char *name, int unit) { device_t child; struct nexus_devinfo *dinfo; child = device_add_child_ordered(dev, order, name, unit); if (child == NULL) return (NULL); dinfo = malloc(sizeof(struct nexus_devinfo), M_NEXUS, M_NOWAIT|M_ZERO); if (dinfo == NULL) return (NULL); dinfo->ndi_node = -1; dinfo->ndi_name = name; device_set_ivars(child, dinfo); return (child); }
static device_t s3c24x0_add_child(device_t bus, int prio, const char *name, int unit) { device_t child; struct s3c2xx0_ivar *ivar; child = device_add_child_ordered(bus, prio, name, unit); if (child == NULL) return (NULL); ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO); if (ivar == NULL) { device_delete_child(bus, child); printf("Can't add alloc ivar\n"); return (NULL); } device_set_ivars(child, ivar); resource_list_init(&ivar->resources); return (child); }
static device_t legacy_add_child(device_t bus, int order, const char *name, int unit) { device_t child; struct legacy_device *atdev; atdev = malloc(sizeof(struct legacy_device), M_LEGACYDEV, M_NOWAIT | M_ZERO); if (atdev == NULL) return(NULL); atdev->lg_pcibus = -1; child = device_add_child_ordered(bus, order, name, unit); if (child == NULL) free(atdev, M_LEGACYDEV); else /* should we free this in legacy_child_detached? */ device_set_ivars(child, atdev); return (child); }
void at91_add_child(device_t dev, int prio, const char *name, int unit, bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2) { device_t kid; struct at91_ivar *ivar; kid = device_add_child_ordered(dev, prio, name, unit); if (kid == NULL) { printf("Can't add child %s%d ordered\n", name, unit); return; } ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO); if (ivar == NULL) { device_delete_child(dev, kid); printf("Can't add alloc ivar\n"); return; } device_set_ivars(kid, ivar); resource_list_init(&ivar->resources); if (irq0 != -1) { bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1); if (irq0 != AT91_IRQ_SYSTEM) at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0); } if (irq1 != 0) bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1); if (irq2 != 0) bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1); /* * Special case for on-board devices. These have their address * defined relative to AT91_PA_BASE in all the register files we * have. We could change this, but that's a lot of effort which * will be obsoleted when FDT arrives. */ if (addr != 0 && addr < 0x10000000 && addr >= 0x0f000000) addr += AT91_PA_BASE; if (addr != 0) bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size); }
static device_t omap_add_child(device_t bus, u_int order, const char *name, int unit) { device_t child; struct omap_ivar *ivar; ivar = malloc(sizeof(struct omap_ivar), M_DEVBUF, M_NOWAIT|M_ZERO); if (!ivar) return (0); resource_list_init(&ivar->resources); child = device_add_child_ordered(bus, order, name, unit); if (child == NULL) { device_printf(bus, "failed to add child: %s%d\n", name, unit); return (0); } /* should we free this in nexus_child_detached? */ device_set_ivars(child, ivar); return (child); }
device_t simplebus_add_device(device_t dev, phandle_t node, u_int order, const char *name, int unit, struct simplebus_devinfo *di) { struct simplebus_devinfo *ndi; device_t cdev; if ((ndi = simplebus_setup_dinfo(dev, node, di)) == NULL) return (NULL); cdev = device_add_child_ordered(dev, order, name, unit); if (cdev == NULL) { device_printf(dev, "<%s>: device_add_child failed\n", ndi->obdinfo.obd_name); resource_list_free(&ndi->rl); ofw_bus_gen_destroy_devinfo(&ndi->obdinfo); if (di == NULL) free(ndi, M_DEVBUF); return (NULL); } device_set_ivars(cdev, ndi); return(cdev); }
static device_t chipc_add_child(device_t dev, u_int order, const char *name, int unit) { struct chipc_softc *sc; struct chipc_devinfo *dinfo; device_t child; sc = device_get_softc(dev); child = device_add_child_ordered(dev, order, name, unit); if (child == NULL) return (NULL); dinfo = malloc(sizeof(struct chipc_devinfo), M_BHND, M_NOWAIT); if (dinfo == NULL) { device_delete_child(dev, child); return (NULL); } resource_list_init(&dinfo->resources); device_set_ivars(child, dinfo); return (child); }
static device_t nexus_add_child(device_t bus, int order, const char *name, int unit) { return device_add_child_ordered(bus, order, name, unit); }
static int sbus_attach(device_t dev) { struct sbus_softc *sc; struct sbus_devinfo *sdi; struct sbus_icarg *sica; struct sbus_ranges *range; struct resource *res; struct resource_list *rl; device_t cdev; bus_addr_t intrclr, intrmap, phys; bus_size_t size; u_long vec; phandle_t child, node; uint32_t prop; int i, j; sc = device_get_softc(dev); sc->sc_dev = dev; node = ofw_bus_get_node(dev); i = 0; sc->sc_sysio_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i, RF_ACTIVE); if (sc->sc_sysio_res == NULL) panic("%s: cannot allocate device memory", __func__); if (OF_getprop(node, "interrupts", &prop, sizeof(prop)) == -1) panic("%s: cannot get IGN", __func__); sc->sc_ign = INTIGN(prop); /* * Record clock frequency for synchronous SCSI. * IS THIS THE CORRECT DEFAULT?? */ if (OF_getprop(node, "clock-frequency", &prop, sizeof(prop)) == -1) prop = 25000000; sc->sc_clockfreq = prop; prop /= 1000; device_printf(dev, "clock %d.%03d MHz\n", prop / 1000, prop % 1000); /* * Collect address translations from the OBP. */ if ((sc->sc_nrange = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range)) == -1) { panic("%s: error getting ranges property", __func__); } sc->sc_rd = malloc(sizeof(*sc->sc_rd) * sc->sc_nrange, M_DEVBUF, M_NOWAIT | M_ZERO); if (sc->sc_rd == NULL) panic("%s: cannot allocate rmans", __func__); /* * Preallocate all space that the SBus bridge decodes, so that nothing * else gets in the way; set up rmans etc. */ rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); for (i = 0; i < sc->sc_nrange; i++) { phys = range[i].poffset | ((bus_addr_t)range[i].pspace << 32); size = range[i].size; sc->sc_rd[i].rd_slot = range[i].cspace; sc->sc_rd[i].rd_coffset = range[i].coffset; sc->sc_rd[i].rd_cend = sc->sc_rd[i].rd_coffset + size; j = resource_list_add_next(rl, SYS_RES_MEMORY, phys, phys + size - 1, size); if ((res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &j, RF_ACTIVE)) == NULL) panic("%s: cannot allocate decoded range", __func__); sc->sc_rd[i].rd_bushandle = rman_get_bushandle(res); sc->sc_rd[i].rd_rman.rm_type = RMAN_ARRAY; sc->sc_rd[i].rd_rman.rm_descr = "SBus Device Memory"; if (rman_init(&sc->sc_rd[i].rd_rman) != 0 || rman_manage_region(&sc->sc_rd[i].rd_rman, 0, size) != 0) panic("%s: failed to set up memory rman", __func__); sc->sc_rd[i].rd_poffset = phys; sc->sc_rd[i].rd_pend = phys + size; sc->sc_rd[i].rd_res = res; } free(range, M_OFWPROP); /* * Get the SBus burst transfer size if burst transfers are supported. */ if (OF_getprop(node, "up-burst-sizes", &sc->sc_burst, sizeof(sc->sc_burst)) == -1 || sc->sc_burst == 0) sc->sc_burst = (SBUS_BURST64_DEF << SBUS_BURST64_SHIFT) | SBUS_BURST_DEF; /* initalise the IOMMU */ /* punch in our copies */ sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(SBUS_IOMMU_BITS); sc->sc_is.is_bustag = rman_get_bustag(sc->sc_sysio_res); sc->sc_is.is_bushandle = rman_get_bushandle(sc->sc_sysio_res); sc->sc_is.is_iommu = SBR_IOMMU; sc->sc_is.is_dtag = SBR_IOMMU_TLB_TAG_DIAG; sc->sc_is.is_ddram = SBR_IOMMU_TLB_DATA_DIAG; sc->sc_is.is_dqueue = SBR_IOMMU_QUEUE_DIAG; sc->sc_is.is_dva = SBR_IOMMU_SVADIAG; sc->sc_is.is_dtcmp = 0; sc->sc_is.is_sb[0] = SBR_STRBUF; sc->sc_is.is_sb[1] = 0; /* * Note: the SBus IOMMU ignores the high bits of an address, so a NULL * DMA pointer will be translated by the first page of the IOTSB. * To detect bugs we'll allocate and ignore the first entry. */ iommu_init(device_get_nameunit(dev), &sc->sc_is, 3, -1, 1); /* Create the DMA tag. */ if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0, sc->sc_is.is_pmaxaddr, ~0, NULL, NULL, sc->sc_is.is_pmaxaddr, 0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_cdmatag) != 0) panic("%s: bus_dma_tag_create failed", __func__); /* Customize the tag. */ sc->sc_cdmatag->dt_cookie = &sc->sc_is; sc->sc_cdmatag->dt_mt = &iommu_dma_methods; /* * Hunt through all the interrupt mapping regs and register our * interrupt controller for the corresponding interrupt vectors. * We do this early in order to be able to catch stray interrupts. */ for (i = 0; i <= SBUS_MAX_INO; i++) { if (sbus_find_intrmap(sc, i, &intrmap, &intrclr) == 0) continue; sica = malloc(sizeof(*sica), M_DEVBUF, M_NOWAIT); if (sica == NULL) panic("%s: could not allocate interrupt controller " "argument", __func__); sica->sica_sc = sc; sica->sica_map = intrmap; sica->sica_clr = intrclr; #ifdef SBUS_DEBUG device_printf(dev, "intr map (INO %d, %s) %#lx: %#lx, clr: %#lx\n", i, (i & INTMAP_OBIO_MASK) == 0 ? "SBus slot" : "OBIO", (u_long)intrmap, (u_long)SYSIO_READ8(sc, intrmap), (u_long)intrclr); #endif j = intr_controller_register(INTMAP_VEC(sc->sc_ign, i), &sbus_ic, sica); if (j != 0) device_printf(dev, "could not register interrupt " "controller for INO %d (%d)\n", i, j); } /* Enable the over-temperature and power-fail interrupts. */ i = 4; sc->sc_ot_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i, RF_ACTIVE); if (sc->sc_ot_ires == NULL || INTIGN(vec = rman_get_start(sc->sc_ot_ires)) != sc->sc_ign || INTVEC(SYSIO_READ8(sc, SBR_THERM_INT_MAP)) != vec || intr_vectors[vec].iv_ic != &sbus_ic || bus_setup_intr(dev, sc->sc_ot_ires, INTR_TYPE_MISC | INTR_BRIDGE, NULL, sbus_overtemp, sc, &sc->sc_ot_ihand) != 0) panic("%s: failed to set up temperature interrupt", __func__); i = 3; sc->sc_pf_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i, RF_ACTIVE); if (sc->sc_pf_ires == NULL || INTIGN(vec = rman_get_start(sc->sc_pf_ires)) != sc->sc_ign || INTVEC(SYSIO_READ8(sc, SBR_POWER_INT_MAP)) != vec || intr_vectors[vec].iv_ic != &sbus_ic || bus_setup_intr(dev, sc->sc_pf_ires, INTR_TYPE_MISC | INTR_BRIDGE, NULL, sbus_pwrfail, sc, &sc->sc_pf_ihand) != 0) panic("%s: failed to set up power fail interrupt", __func__); /* Initialize the counter-timer. */ sparc64_counter_init(device_get_nameunit(dev), rman_get_bustag(sc->sc_sysio_res), rman_get_bushandle(sc->sc_sysio_res), SBR_TC0); /* * Loop through ROM children, fixing any relative addresses * and then configuring each device. */ for (child = OF_child(node); child != 0; child = OF_peer(child)) { if ((sdi = sbus_setup_dinfo(dev, sc, child)) == NULL) continue; /* * For devices where there are variants that are actually * split into two SBus devices (as opposed to the first * half of the device being a SBus device and the second * half hanging off of the first one) like 'auxio' and * 'SUNW,fdtwo' or 'dma' and 'esp' probe the SBus device * which is a prerequisite to the driver attaching to the * second one with a lower order. Saves us from dealing * with different probe orders in the respective device * drivers which generally is more hackish. */ cdev = device_add_child_ordered(dev, (OF_child(child) == 0 && 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)); }