Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
Archivo: nexus.c Proyecto: MarginC/kame
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);
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
Archivo: apb.c Proyecto: 2asoft/freebsd
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;
}
Ejemplo n.º 16
0
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);
}
Ejemplo n.º 17
0
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);
}
Ejemplo n.º 18
0
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);
}
Ejemplo n.º 19
0
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);
}
Ejemplo n.º 20
0
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);
}
Ejemplo n.º 21
0
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);
}
Ejemplo n.º 22
0
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);
}
Ejemplo n.º 23
0
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);
}
Ejemplo n.º 24
0
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));
}