本文整理汇总了C++中device_add_child函数的典型用法代码示例。如果您正苦于以下问题:C++ device_add_child函数的具体用法?C++ device_add_child怎么用?C++ device_add_child使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了device_add_child函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ohci_ec_attach
static int
ohci_ec_attach(device_t dev)
{
struct ec_ohci_softc *sc = device_get_softc(dev);
bus_space_handle_t bsh;
int err;
int rid;
/* initialise some bus fields */
sc->sc_ohci.sc_bus.parent = dev;
sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;
/* get all DMA memory */
if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
return (ENOMEM);
}
sc->sc_ohci.sc_dev = dev;
rid = MEM_RID;
sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&rid, RF_ACTIVE);
if (!(sc->sc_ohci.sc_io_res)) {
err = ENOMEM;
goto error;
}
sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
bsh = rman_get_bushandle(sc->sc_ohci.sc_io_res);
/* Undocumented magic initialization */
bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x04, 0x146);
bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x44, 0x0200);
DELAY(1000);
sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);
if (bus_space_subregion(sc->sc_ohci.sc_io_tag, bsh, 0x4000000,
sc->sc_ohci.sc_io_size, &sc->sc_ohci.sc_io_hdl) != 0)
panic("%s: unable to subregion USB host registers",
device_get_name(dev));
rid = 0;
sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (!(sc->sc_ohci.sc_irq_res)) {
goto error;
}
sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
if (!(sc->sc_ohci.sc_bus.bdev)) {
goto error;
}
device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);
strlcpy(sc->sc_ohci.sc_vendor, "Cavium",
sizeof(sc->sc_ohci.sc_vendor));
#if (__FreeBSD_version >= 700031)
err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res,
INTR_TYPE_BIO | INTR_MPSAFE, NULL,
(driver_intr_t *)ohci_interrupt, sc,
&sc->sc_ohci.sc_intr_hdl);
#else
err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res,
INTR_TYPE_BIO | INTR_MPSAFE,
(driver_intr_t *)ohci_interrupt, sc,
&sc->sc_ohci.sc_intr_hdl);
#endif
if (err) {
sc->sc_ohci.sc_intr_hdl = NULL;
goto error;
}
bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
OHCI_CONTROL, 0);
err = ohci_init(&sc->sc_ohci);
if (!err) {
err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);
}
if (err) {
goto error;
}
return (0);
error:
ohci_ec_detach(dev);
return (ENXIO);
}
示例2: sata_attach
static int
sata_attach(device_t dev)
{
struct sata_softc *sc;
int mem_id, irq_id, error, i;
device_t ata_chan;
uint32_t reg;
sc = device_get_softc(dev);
sc->sc_dev = dev;
mem_id = 0;
irq_id = 0;
/* Allocate resources */
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&mem_id, RF_ACTIVE);
if (sc->sc_mem_res == NULL) {
device_printf(dev, "could not allocate memory.\n");
return (ENOMEM);
}
sc->sc_mem_res_bustag = rman_get_bustag(sc->sc_mem_res);
sc->sc_mem_res_bushdl = rman_get_bushandle(sc->sc_mem_res);
KASSERT(sc->sc_mem_res_bustag && sc->sc_mem_res_bushdl,
("cannot get bus handle or tag."));
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irq_id,
RF_ACTIVE);
if (sc->sc_irq_res == NULL) {
device_printf(dev, "could not allocate IRQ.\n");
error = ENOMEM;
goto err;
}
error = bus_setup_intr(dev, sc->sc_irq_res,
INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY,
NULL, sata_intr, sc, &sc->sc_irq_cookiep);
if (error != 0) {
device_printf(dev, "could not setup interrupt.\n");
goto err;
}
/* Attach channels */
for (i = 0; i < SATA_CHAN_NUM; i++) {
ata_chan = device_add_child(dev, "ata",
devclass_find_free_unit(ata_devclass, 0));
if (!ata_chan) {
device_printf(dev, "cannot add channel %d.\n", i);
error = ENOMEM;
goto err;
}
}
/* Disable interrupt coalescing */
reg = SATA_INL(sc, SATA_CR);
for (i = 0; i < SATA_CHAN_NUM; i++)
reg |= SATA_CR_COALDIS(i);
/* Disable DMA byte swapping */
if (sc->sc_version == 2)
reg |= SATA_CR_NODMABS | SATA_CR_NOEDMABS |
SATA_CR_NOPRDPBS;
SATA_OUTL(sc, SATA_CR, reg);
/* Clear and mask all interrupts */
SATA_OUTL(sc, SATA_ICR, 0);
SATA_OUTL(sc, SATA_MIMR, 0);
return(bus_generic_attach(dev));
err:
sata_detach(dev);
return (error);
}
示例3: at91_mci_attach
//.........这里部分代码省略.........
if (at91_mci_is_mci1rev2xx())
sc->sc_cap |= CAP_MCI1_REV2XX;
err = at91_mci_activate(dev);
if (err)
goto out;
AT91_MCI_LOCK_INIT(sc);
at91_mci_fini(dev);
at91_mci_init(dev);
/*
* Allocate DMA tags and maps and bounce buffers.
*
* The parms in the tag_create call cause the dmamem_alloc call to
* create each bounce buffer as a single contiguous buffer of BBSIZE
* bytes aligned to a 4096 byte boundary.
*
* Do not use DMA_COHERENT for these buffers because that maps the
* memory as non-cachable, which prevents cache line burst fills/writes,
* which is something we need since we're trying to overlap the
* byte-swapping with the DMA operations.
*/
err = bus_dma_tag_create(bus_get_dma_tag(dev), 4096, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
BBSIZE, 1, BBSIZE, 0, NULL, NULL, &sc->dmatag);
if (err != 0)
goto out;
for (i = 0; i < BBCOUNT; ++i) {
err = bus_dmamem_alloc(sc->dmatag, (void **)&sc->bbuf_vaddr[i],
BUS_DMA_NOWAIT, &sc->bbuf_map[i]);
if (err != 0)
goto out;
}
/*
* Activate the interrupt
*/
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
NULL, at91_mci_intr, sc, &sc->intrhand);
if (err) {
AT91_MCI_LOCK_DESTROY(sc);
goto out;
}
/*
* Allow 4-wire to be initially set via #define.
* Allow a device hint to override that.
* Allow a sysctl to override that.
*/
#if defined(AT91_MCI_HAS_4WIRE) && AT91_MCI_HAS_4WIRE != 0
sc->has_4wire = 1;
#endif
resource_int_value(device_get_name(dev), device_get_unit(dev),
"4wire", &sc->has_4wire);
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "4wire",
CTLFLAG_RW, &sc->has_4wire, 0, "has 4 wire SD Card bus");
if (sc->has_4wire)
sc->sc_cap |= CAP_HAS_4WIRE;
sc->allow_overclock = AT91_MCI_ALLOW_OVERCLOCK;
resource_int_value(device_get_name(dev), device_get_unit(dev),
"allow_overclock", &sc->allow_overclock);
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "allow_overclock",
CTLFLAG_RW, &sc->allow_overclock, 0,
"Allow up to 30MHz clock for 25MHz request when next highest speed 15MHz or less.");
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "debug",
CTLFLAG_RWTUN, &mci_debug, 0, "enable debug output");
/*
* Our real min freq is master_clock/512, but upper driver layers are
* going to set the min speed during card discovery, and the right speed
* for that is 400kHz, so advertise a safe value just under that.
*
* For max speed, while the rm9200 manual says the max is 50mhz, it also
* says it supports only the SD v1.0 spec, which means the real limit is
* 25mhz. On the other hand, historical use has been to slightly violate
* the standard by running the bus at 30MHz. For more information on
* that, see the comments at the top of this file.
*/
sc->host.f_min = 375000;
sc->host.f_max = at91_master_clock / 2;
if (sc->host.f_max > 25000000)
sc->host.f_max = 25000000;
sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
sc->host.caps = 0;
if (sc->sc_cap & CAP_HAS_4WIRE)
sc->host.caps |= MMC_CAP_4_BIT_DATA;
child = device_add_child(dev, "mmc", 0);
device_set_ivars(dev, &sc->host);
err = bus_generic_attach(dev);
out:
if (err)
at91_mci_deactivate(dev);
return (err);
}
示例4: nandbus_attach
static int
nandbus_attach(device_t dev)
{
device_t child, nfc;
struct nand_id chip_id;
struct nandbus_softc *sc;
struct nandbus_ivar *ivar;
struct nand_softc *nfc_sc;
struct nand_params *chip_params;
uint8_t cs, onfi;
sc = device_get_softc(dev);
sc->dev = dev;
nfc = device_get_parent(dev);
nfc_sc = device_get_softc(nfc);
mtx_init(&sc->nandbus_mtx, "nandbus lock", NULL, MTX_DEF);
cv_init(&sc->nandbus_cv, "nandbus cv");
/* Check each possible CS for existing nand devices */
for (cs = 0; cs < NAND_NCS; cs++) {
nand_debug(NDBG_BUS,"probe chip select %x", cs);
/* Select & reset chip */
if (nandbus_select_cs(dev, cs))
break;
if (nand_reset(dev))
continue;
/* Read manufacturer and device id */
if (nand_readid(dev, &chip_id.man_id, &chip_id.dev_id))
continue;
if (chip_id.man_id == 0xff)
continue;
/*
* First try to get info from the table. If that fails, see if
* the chip can provide ONFI info. We check the table first to
* allow table entries to override info from chips that are
* known to provide bad ONFI data.
*/
onfi = 0;
chip_params = nand_get_params(&chip_id);
if (chip_params == NULL) {
nand_probe_onfi(dev, &onfi);
}
/*
* At this point it appears there is a chip at this chipselect,
* so if we can't work with it, whine about it.
*/
if (chip_params == NULL && onfi == 0) {
if (bootverbose || (nand_debug_flag & NDBG_BUS))
printf("Chip params not found, chipsel: %d "
"(manuf: 0x%0x, chipid: 0x%0x, onfi: %d)\n",
cs, chip_id.man_id, chip_id.dev_id, onfi);
continue;
}
ivar = malloc(sizeof(struct nandbus_ivar),
M_NAND, M_WAITOK);
if (onfi == 1) {
ivar->cs = cs;
ivar->cols = 0;
ivar->rows = 0;
ivar->params = NULL;
ivar->man_id = chip_id.man_id;
ivar->dev_id = chip_id.dev_id;
ivar->is_onfi = onfi;
ivar->chip_cdev_name = nfc_sc->chip_cdev_name;
child = device_add_child(dev, NULL, -1);
device_set_ivars(child, ivar);
continue;
}
ivar->cs = cs;
ivar->cols = 1;
ivar->rows = 2;
ivar->params = chip_params;
ivar->man_id = chip_id.man_id;
ivar->dev_id = chip_id.dev_id;
ivar->is_onfi = onfi;
ivar->chip_cdev_name = nfc_sc->chip_cdev_name;
/*
* Check what type of device we have.
* devices bigger than 32MiB have on more row (3)
*/
if (chip_params->chip_size > 32)
ivar->rows++;
/* Large page devices have one more col (2) */
if (chip_params->chip_size >= 128 &&
chip_params->page_size > 512)
ivar->cols++;
//.........这里部分代码省略.........
示例5: rk30_gpio_attach
static int
rk30_gpio_attach(device_t dev)
{
struct rk30_gpio_softc *sc = device_get_softc(dev);
uint32_t func;
int i, rid;
phandle_t gpio;
if (rk30_gpio_sc)
return (ENXIO);
sc->sc_dev = dev;
mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF);
rid = 0;
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->sc_mem_res) {
device_printf(dev, "cannot allocate memory window\n");
return (ENXIO);
}
sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (!sc->sc_irq_res) {
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
device_printf(dev, "cannot allocate interrupt\n");
return (ENXIO);
}
/* Find our node. */
gpio = ofw_bus_get_node(sc->sc_dev);
if (!OF_hasprop(gpio, "gpio-controller"))
/* Node is not a GPIO controller. */
goto fail;
/* Initialize the software controlled pins. */
for (i = 0; i < RK30_GPIO_PINS; i++) {
snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
"pin %d", i);
func = rk30_gpio_get_function(sc, i);
sc->sc_gpio_pins[i].gp_pin = i;
sc->sc_gpio_pins[i].gp_caps = RK30_GPIO_DEFAULT_CAPS;
sc->sc_gpio_pins[i].gp_flags = rk30_gpio_func_flag(func);
}
sc->sc_gpio_npins = i;
device_add_child(dev, "gpioc", -1);
device_add_child(dev, "gpiobus", -1);
rk30_gpio_sc = sc;
rk30_gpio_init();
return (bus_generic_attach(dev));
fail:
if (sc->sc_irq_res)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
return (ENXIO);
}
示例6: xhci_pci_attach
static int
xhci_pci_attach(device_t self)
{
struct xhci_softc *sc = device_get_softc(self);
int err;
int rid;
/* XXX check for 64-bit capability */
if (xhci_init(sc, self)) {
device_printf(self, "Could not initialize softc\n");
goto error;
}
pci_enable_busmaster(self);
rid = PCI_XHCI_CBMEM;
sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->sc_io_res) {
device_printf(self, "Could not map memory\n");
goto error;
}
sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
sc->sc_io_size = rman_get_size(sc->sc_io_res);
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->sc_irq_res == NULL) {
device_printf(self, "Could not allocate IRQ\n");
goto error;
}
sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
if (sc->sc_bus.bdev == NULL) {
device_printf(self, "Could not add USB device\n");
goto error;
}
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
sprintf(sc->sc_vendor, "0x%04x", pci_get_vendor(self));
#if (__FreeBSD_version >= 700031)
err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl);
#else
err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
(driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl);
#endif
if (err) {
device_printf(self, "Could not setup IRQ, err=%d\n", err);
sc->sc_intr_hdl = NULL;
goto error;
}
xhci_pci_take_controller(self);
err = xhci_halt_controller(sc);
if (err == 0)
err = xhci_start_controller(sc);
if (err == 0)
err = device_probe_and_attach(sc->sc_bus.bdev);
if (err) {
device_printf(self, "XHCI halt/start/probe failed err=%d\n", err);
goto error;
}
return (0);
error:
xhci_pci_detach(self);
return (ENXIO);
}
示例7: cbb_pci_attach
static int
cbb_pci_attach(device_t brdev)
{
static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */
struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(brdev);
struct sysctl_ctx_list *sctx;
struct sysctl_oid *soid;
int rid;
device_t parent;
uint32_t pribus;
parent = device_get_parent(brdev);
mtx_init(&sc->mtx, device_get_nameunit(brdev), "cbb", MTX_DEF);
sc->chipset = cbb_chipset(pci_get_devid(brdev), NULL);
sc->dev = brdev;
sc->cbdev = NULL;
sc->exca[0].pccarddev = NULL;
sc->domain = pci_get_domain(brdev);
sc->secbus = pci_read_config(brdev, PCIR_SECBUS_2, 1);
sc->subbus = pci_read_config(brdev, PCIR_SUBBUS_2, 1);
sc->pribus = pcib_get_bus(parent);
SLIST_INIT(&sc->rl);
cbb_powerstate_d0(brdev);
rid = CBBR_SOCKBASE;
sc->base_res = bus_alloc_resource_any(brdev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->base_res) {
device_printf(brdev, "Could not map register memory\n");
mtx_destroy(&sc->mtx);
return (ENOMEM);
} else {
DEVPRINTF((brdev, "Found memory at %08lx\n",
rman_get_start(sc->base_res)));
}
sc->bst = rman_get_bustag(sc->base_res);
sc->bsh = rman_get_bushandle(sc->base_res);
exca_init(&sc->exca[0], brdev, sc->bst, sc->bsh, CBB_EXCA_OFFSET);
sc->exca[0].flags |= EXCA_HAS_MEMREG_WIN;
sc->exca[0].chipset = EXCA_CARDBUS;
sc->chipinit = cbb_chipinit;
sc->chipinit(sc);
/*Sysctls*/
sctx = device_get_sysctl_ctx(brdev);
soid = device_get_sysctl_tree(brdev);
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "domain",
CTLFLAG_RD, &sc->domain, 0, "Domain number");
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "pribus",
CTLFLAG_RD, &sc->pribus, 0, "Primary bus number");
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "secbus",
CTLFLAG_RD, &sc->secbus, 0, "Secondary bus number");
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "subbus",
CTLFLAG_RD, &sc->subbus, 0, "Subordinate bus number");
#if 0
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "memory",
CTLFLAG_RD, &sc->subbus, 0, "Memory window open");
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "premem",
CTLFLAG_RD, &sc->subbus, 0, "Prefetch memroy window open");
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "io1",
CTLFLAG_RD, &sc->subbus, 0, "io range 1 open");
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "io2",
CTLFLAG_RD, &sc->subbus, 0, "io range 2 open");
#endif
/*
* This is a gross hack. We should be scanning the entire pci
* tree, assigning bus numbers in a way such that we (1) can
* reserve 1 extra bus just in case and (2) all sub busses
* are in an appropriate range.
*/
DEVPRINTF((brdev, "Secondary bus is %d\n", sc->secbus));
pribus = pci_read_config(brdev, PCIR_PRIBUS_2, 1);
if (sc->secbus == 0 || sc->pribus != pribus) {
if (curr_bus_number <= sc->pribus)
curr_bus_number = sc->pribus + 1;
if (pribus != sc->pribus) {
DEVPRINTF((brdev, "Setting primary bus to %d\n",
sc->pribus));
pci_write_config(brdev, PCIR_PRIBUS_2, sc->pribus, 1);
}
sc->secbus = curr_bus_number++;
sc->subbus = curr_bus_number++;
DEVPRINTF((brdev, "Secondary bus set to %d subbus %d\n",
sc->secbus, sc->subbus));
pci_write_config(brdev, PCIR_SECBUS_2, sc->secbus, 1);
pci_write_config(brdev, PCIR_SUBBUS_2, sc->subbus, 1);
}
/* attach children */
sc->cbdev = device_add_child(brdev, "cardbus", -1);
if (sc->cbdev == NULL)
DEVPRINTF((brdev, "WARNING: cannot add cardbus bus.\n"));
else if (device_probe_and_attach(sc->cbdev) != 0)
DEVPRINTF((brdev, "WARNING: cannot attach cardbus bus!\n"));
sc->exca[0].pccarddev = device_add_child(brdev, "pccard", -1);
if (sc->exca[0].pccarddev == NULL)
DEVPRINTF((brdev, "WARNING: cannot add pccard bus.\n"));
//.........这里部分代码省略.........
示例8: dma_attach
static int
dma_attach(device_t dev)
{
struct dma_softc *dsc;
struct lsi64854_softc *lsc;
struct dma_devinfo *ddi;
device_t cdev;
const char *name;
char *cabletype;
uint32_t csr;
phandle_t child, node;
int error, i;
dsc = device_get_softc(dev);
lsc = &dsc->sc_lsi64854;
name = ofw_bus_get_name(dev);
node = ofw_bus_get_node(dev);
dsc->sc_ign = sbus_get_ign(dev);
dsc->sc_slot = sbus_get_slot(dev);
i = 0;
lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
RF_ACTIVE);
if (lsc->sc_res == NULL) {
device_printf(dev, "cannot allocate resources\n");
return (ENXIO);
}
if (strcmp(name, "espdma") == 0 || strcmp(name, "dma") == 0)
lsc->sc_channel = L64854_CHANNEL_SCSI;
else if (strcmp(name, "ledma") == 0) {
/*
* Check to see which cable type is currently active and
* set the appropriate bit in the ledma csr so that it
* gets used. If we didn't netboot, the PROM won't have
* the "cable-selection" property; default to TP and then
* the user can change it via a "media" option to ifconfig.
*/
csr = L64854_GCSR(lsc);
if ((OF_getprop_alloc(node, "cable-selection", 1,
(void **)&cabletype)) == -1) {
/* assume TP if nothing there */
csr |= E_TP_AUI;
} else {
if (strcmp(cabletype, "aui") == 0)
csr &= ~E_TP_AUI;
else
csr |= E_TP_AUI;
free(cabletype, M_OFWPROP);
}
L64854_SCSR(lsc, csr);
DELAY(20000); /* manual says we need a 20ms delay */
lsc->sc_channel = L64854_CHANNEL_ENET;
} else {
device_printf(dev, "unsupported DMA channel\n");
error = ENXIO;
goto fail_lres;
}
error = bus_dma_tag_create(
bus_get_dma_tag(dev), /* parent */
1, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
BUS_SPACE_MAXSIZE, /* maxsize */
BUS_SPACE_UNRESTRICTED, /* nsegments */
BUS_SPACE_MAXSIZE, /* maxsegsize */
0, /* flags */
NULL, NULL, /* no locking */
&lsc->sc_parent_dmat);
if (error != 0) {
device_printf(dev, "cannot allocate parent DMA tag\n");
goto fail_lres;
}
i = sbus_get_burstsz(dev);
lsc->sc_burst = (i & SBUS_BURST_32) ? 32 :
(i & SBUS_BURST_16) ? 16 : 0;
lsc->sc_dev = dev;
/* Attach children. */
i = 0;
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
if ((ddi = dma_setup_dinfo(dev, dsc, child)) == NULL)
continue;
if (i != 0) {
device_printf(dev,
"<%s>: only one child per DMA channel supported\n",
ddi->ddi_obdinfo.obd_name);
dma_destroy_dinfo(ddi);
continue;
}
if ((cdev = device_add_child(dev, NULL, -1)) == NULL) {
device_printf(dev, "<%s>: device_add_child failed\n",
ddi->ddi_obdinfo.obd_name);
dma_destroy_dinfo(ddi);
continue;
}
//.........这里部分代码省略.........
示例9: cuda_attach
//.........这里部分代码省略.........
if (sc->sc_memr == NULL) {
device_printf(dev, "Could not alloc mem resource!\n");
return (ENXIO);
}
sc->sc_irqrid = 0;
sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irqrid,
RF_ACTIVE);
if (sc->sc_irq == NULL) {
device_printf(dev, "could not allocate interrupt\n");
return (ENXIO);
}
if (bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC | INTR_MPSAFE
| INTR_ENTROPY, NULL, cuda_intr, dev, &sc->sc_ih) != 0) {
device_printf(dev, "could not setup interrupt\n");
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqrid,
sc->sc_irq);
return (ENXIO);
}
mtx_init(&sc->sc_mutex,"cuda",NULL,MTX_DEF | MTX_RECURSE);
sc->sc_sent = 0;
sc->sc_received = 0;
sc->sc_waiting = 0;
sc->sc_polling = 0;
sc->sc_state = CUDA_NOTREADY;
sc->sc_autopoll = 0;
sc->sc_rtc = -1;
STAILQ_INIT(&sc->sc_inq);
STAILQ_INIT(&sc->sc_outq);
STAILQ_INIT(&sc->sc_freeq);
for (i = 0; i < CUDA_MAXPACKETS; i++)
STAILQ_INSERT_TAIL(&sc->sc_freeq, &sc->sc_pkts[i], pkt_q);
/* Init CUDA */
reg = cuda_read_reg(sc, vDirB);
reg |= 0x30; /* register B bits 4 and 5: outputs */
cuda_write_reg(sc, vDirB, reg);
reg = cuda_read_reg(sc, vDirB);
reg &= 0xf7; /* register B bit 3: input */
cuda_write_reg(sc, vDirB, reg);
reg = cuda_read_reg(sc, vACR);
reg &= ~vSR_OUT; /* make sure SR is set to IN */
cuda_write_reg(sc, vACR, reg);
cuda_write_reg(sc, vACR, (cuda_read_reg(sc, vACR) | 0x0c) & ~0x10);
sc->sc_state = CUDA_IDLE; /* used by all types of hardware */
cuda_write_reg(sc, vIER, 0x84); /* make sure VIA interrupts are on */
cuda_idle(sc); /* reset ADB */
/* Reset CUDA */
i = cuda_read_reg(sc, vSR); /* clear interrupt */
cuda_write_reg(sc, vIER, 0x04); /* no interrupts while clearing */
cuda_idle(sc); /* reset state to idle */
DELAY(150);
cuda_tip(sc); /* signal start of frame */
DELAY(150);
cuda_toggle_ack(sc);
DELAY(150);
cuda_clear_tip(sc);
DELAY(150);
cuda_idle(sc); /* back to idle state */
i = cuda_read_reg(sc, vSR); /* clear interrupt */
cuda_write_reg(sc, vIER, 0x84); /* ints ok now */
/* Initialize child buses (ADB) */
node = ofw_bus_get_node(dev);
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
char name[32];
memset(name, 0, sizeof(name));
OF_getprop(child, "name", name, sizeof(name));
if (bootverbose)
device_printf(dev, "CUDA child <%s>\n",name);
if (strncmp(name, "adb", 4) == 0) {
sc->adb_bus = device_add_child(dev,"adb",-1);
}
}
clock_register(dev, 1000);
EVENTHANDLER_REGISTER(shutdown_final, cuda_shutdown, sc,
SHUTDOWN_PRI_LAST);
return (bus_generic_attach(dev));
}
示例10: vybrid_ehci_attach
static int
vybrid_ehci_attach(device_t dev)
{
struct vybrid_ehci_softc *esc;
ehci_softc_t *sc;
bus_space_handle_t bsh;
int err;
int reg;
esc = device_get_softc(dev);
esc->dev = dev;
sc = &esc->base;
sc->sc_bus.parent = dev;
sc->sc_bus.devices = sc->sc_devices;
sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
if (bus_alloc_resources(dev, vybrid_ehci_spec, esc->res)) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
}
/* EHCI registers */
sc->sc_io_tag = rman_get_bustag(esc->res[0]);
bsh = rman_get_bushandle(esc->res[0]);
sc->sc_io_size = rman_get_size(esc->res[0]);
esc->bst_usbc = rman_get_bustag(esc->res[1]);
esc->bsh_usbc = rman_get_bushandle(esc->res[1]);
esc->bst_phy = rman_get_bustag(esc->res[2]);
esc->bsh_phy = rman_get_bushandle(esc->res[2]);
/* get all DMA memory */
if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
&ehci_iterate_hw_softc))
return (ENXIO);
#if 0
printf("USBx_HCSPARAMS is 0x%08x\n",
bus_space_read_4(sc->sc_io_tag, bsh, USB_HCSPARAMS));
printf("USB_ID == 0x%08x\n",
bus_space_read_4(sc->sc_io_tag, bsh, USB_ID));
printf("USB_HWGENERAL == 0x%08x\n",
bus_space_read_4(sc->sc_io_tag, bsh, USB_HWGENERAL));
printf("USB_HWHOST == 0x%08x\n",
bus_space_read_4(sc->sc_io_tag, bsh, USB_HWHOST));
printf("USB_HWDEVICE == 0x%08x\n",
bus_space_read_4(sc->sc_io_tag, bsh, USB_HWDEVICE));
printf("USB_HWTXBUF == 0x%08x\n",
bus_space_read_4(sc->sc_io_tag, bsh, USB_HWTXBUF));
printf("USB_HWRXBUF == 0x%08x\n",
bus_space_read_4(sc->sc_io_tag, bsh, USB_HWRXBUF));
#endif
if (phy_init(esc)) {
device_printf(dev, "Could not setup PHY\n");
return (1);
}
/*
* Set handle to USB related registers subregion used by
* generic EHCI driver.
*/
err = bus_space_subregion(sc->sc_io_tag, bsh, 0x100,
sc->sc_io_size, &sc->sc_io_hdl);
if (err != 0)
return (ENXIO);
/* Setup interrupt handler */
err = bus_setup_intr(dev, esc->res[3], INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)ehci_interrupt, sc,
&sc->sc_intr_hdl);
if (err) {
device_printf(dev, "Could not setup irq, "
"%d\n", err);
return (1);
}
/* Add USB device */
sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
if (!sc->sc_bus.bdev) {
device_printf(dev, "Could not add USB device\n");
err = bus_teardown_intr(dev, esc->res[5],
sc->sc_intr_hdl);
if (err)
device_printf(dev, "Could not tear down irq,"
" %d\n", err);
return (1);
}
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
strlcpy(sc->sc_vendor, "Freescale", sizeof(sc->sc_vendor));
/* Set host mode */
reg = bus_space_read_4(sc->sc_io_tag, sc->sc_io_hdl, 0xA8);
reg |= 0x3;
bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, 0xA8, reg);
/* Set flags */
//.........这里部分代码省略.........
示例11: fsl_ehci_attach
static int
fsl_ehci_attach(device_t self)
{
ehci_softc_t *sc;
int rid;
int err;
bus_space_handle_t ioh;
bus_space_tag_t iot;
sc = device_get_softc(self);
rid = 0;
sc->sc_bus.parent = self;
sc->sc_bus.devices = sc->sc_devices;
sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
sc->sc_bus.dma_bits = 32;
if (usb_bus_mem_alloc_all(&sc->sc_bus,
USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc))
return (ENOMEM);
/* Allocate io resource for EHCI */
sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->sc_io_res == NULL) {
err = fsl_ehci_detach(self);
if (err) {
device_printf(self,
"Detach of the driver failed with error %d\n",
err);
}
return (ENXIO);
}
iot = rman_get_bustag(sc->sc_io_res);
/*
* Set handle to USB related registers subregion used by generic
* EHCI driver
*/
ioh = rman_get_bushandle(sc->sc_io_res);
err = bus_space_subregion(iot, ioh, FSL_EHCI_REG_OFF, FSL_EHCI_REG_SIZE,
&sc->sc_io_hdl);
if (err != 0) {
err = fsl_ehci_detach(self);
if (err) {
device_printf(self,
"Detach of the driver failed with error %d\n",
err);
}
return (ENXIO);
}
/* Set little-endian tag for use by the generic EHCI driver */
sc->sc_io_tag = &bs_le_tag;
/* Allocate irq */
sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (sc->sc_irq_res == NULL) {
err = fsl_ehci_detach(self);
if (err) {
device_printf(self,
"Detach of the driver failed with error %d\n",
err);
}
return (ENXIO);
}
/* Setup interrupt handler */
err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
if (err) {
device_printf(self, "Could not setup irq, %d\n", err);
sc->sc_intr_hdl = NULL;
err = fsl_ehci_detach(self);
if (err) {
device_printf(self,
"Detach of the driver failed with error %d\n",
err);
}
return (ENXIO);
}
/* Add USB device */
sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
if (!sc->sc_bus.bdev) {
device_printf(self, "Could not add USB device\n");
err = fsl_ehci_detach(self);
if (err) {
device_printf(self,
"Detach of the driver failed with error %d\n",
err);
}
return (ENOMEM);
}
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
sc->sc_id_vendor = 0x1234;
strlcpy(sc->sc_vendor, "Freescale", sizeof(sc->sc_vendor));
//.........这里部分代码省略.........
示例12: dotg_fdt_attach
static int
dotg_fdt_attach(device_t dev)
{
struct dwc_otg_softc *sc = device_get_softc(dev);
int err, rid;
/* setup controller interface softc */
/* initialise some bus fields */
sc->sc_mode = DWC_MODE_HOST;
sc->sc_bus.parent = dev;
sc->sc_bus.devices = sc->sc_devices;
sc->sc_bus.devices_max = DWC_OTG_MAX_DEVICES;
sc->sc_bus.dma_bits = 32;
/* get all DMA memory */
if (usb_bus_mem_alloc_all(&sc->sc_bus,
USB_GET_DMA_TAG(dev), NULL)) {
printf("No mem\n");
return (ENOMEM);
}
rid = 0;
sc->sc_io_res =
bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (!(sc->sc_io_res)) {
printf("Can`t alloc MEM\n");
goto error;
}
sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
sc->sc_io_size = rman_get_size(sc->sc_io_res);
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&rid, RF_ACTIVE);
if (!(sc->sc_irq_res)) {
printf("Can`t alloc IRQ\n");
goto error;
}
sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
if (!(sc->sc_bus.bdev)) {
printf("Can`t add usbus\n");
goto error;
}
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
err = bus_setup_intr(dev, sc->sc_irq_res,
INTR_TYPE_TTY | INTR_MPSAFE, dwc_otg_filter_interrupt,
dwc_otg_interrupt, sc, &sc->sc_intr_hdl);
if (err) {
sc->sc_intr_hdl = NULL;
printf("Can`t set IRQ handle\n");
goto error;
}
err = dwc_otg_init(sc);
if (err) printf("dotg_init fail\n");
if (!err) {
err = device_probe_and_attach(sc->sc_bus.bdev);
if (err) printf("device_probe_and_attach fail %d\n", err);
}
if (err) {
goto error;
}
return (0);
error:
dotg_fdt_detach(dev);
return (ENXIO);
}
示例13: gusisa_probe
static int
gusisa_probe(device_t dev)
{
device_t child;
struct resource *res, *res2;
int base, rid, rid2, flags;
unsigned char val;
base = isa_get_port(dev);
flags = device_get_flags(dev);
rid = 1;
res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, base + 0x100,
base + 0x107, 8, RF_ACTIVE);
if (res == NULL)
return ENXIO;
res2 = NULL;
/*
* Check for the presence of some GUS card. Reset the card,
* then see if we can access the memory on it.
*/
port_wr(res, 3, 0x4c);
port_wr(res, 5, 0);
DELAY(30 * 1000);
port_wr(res, 3, 0x4c);
port_wr(res, 5, 1);
DELAY(30 * 1000);
crit_enter();
/* Write to DRAM. */
port_wr(res, 3, 0x43); /* Register select */
port_wr(res, 4, 0); /* Low addr */
port_wr(res, 5, 0); /* Med addr */
port_wr(res, 3, 0x44); /* Register select */
port_wr(res, 4, 0); /* High addr */
port_wr(res, 7, 0x55); /* DRAM */
/* Read from DRAM. */
port_wr(res, 3, 0x43); /* Register select */
port_wr(res, 4, 0); /* Low addr */
port_wr(res, 5, 0); /* Med addr */
port_wr(res, 3, 0x44); /* Register select */
port_wr(res, 4, 0); /* High addr */
val = port_rd(res, 7); /* DRAM */
crit_exit();
if (val != 0x55)
goto fail;
rid2 = 0;
res2 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid2, base, base, 1,
RF_ACTIVE);
if (res2 == NULL)
goto fail;
crit_enter();
port_wr(res2, 0x0f, 0x20);
val = port_rd(res2, 0x0f);
crit_exit();
if (val == 0xff || (val & 0x06) == 0)
val = 0;
else {
val = port_rd(res2, 0x506); /* XXX Out of range. */
if (val == 0xff)
val = 0;
}
bus_release_resource(dev, SYS_RES_IOPORT, rid2, res2);
bus_release_resource(dev, SYS_RES_IOPORT, rid, res);
if (val >= 10) {
struct sndcard_func *func;
/* Looks like a GUS MAX. Set the rest of the resources. */
bus_set_resource(dev, SYS_RES_IOPORT, 2, base + 0x10c, 8, -1);
if (flags & DV_F_DUAL_DMA)
bus_set_resource(dev, SYS_RES_DRQ, 1,
flags & DV_F_DRQ_MASK, 1, -1);
/* We can support the CS4231 and MIDI devices. */
func = kmalloc(sizeof(struct sndcard_func), M_DEVBUF,
M_WAITOK | M_ZERO);
func->func = SCF_MIDI;
child = device_add_child(dev, "midi", -1);
device_set_ivars(child, func);
//.........这里部分代码省略.........
示例14: saf1761_otg_fdt_attach
static int
saf1761_otg_fdt_attach(device_t dev)
{
struct saf1761_otg_softc *sc = device_get_softc(dev);
char param[24];
int err;
int rid;
/* get configuration from FDT */
/* get bus-width, if any */
if (OF_getprop(ofw_bus_get_node(dev), "bus-width",
¶m, sizeof(param)) > 0) {
param[sizeof(param) - 1] = 0;
if (strcmp(param, "32") == 0)
sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_DATA_BUS_WIDTH;
} else {
/* assume 32-bit data bus */
sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_DATA_BUS_WIDTH;
}
/* get analog over-current setting */
if (OF_getprop(ofw_bus_get_node(dev), "analog-oc",
¶m, sizeof(param)) > 0) {
sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_ANA_DIGI_OC;
}
/* get DACK polarity */
if (OF_getprop(ofw_bus_get_node(dev), "dack-polarity",
¶m, sizeof(param)) > 0) {
sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_DACK_POL;
}
/* get DREQ polarity */
if (OF_getprop(ofw_bus_get_node(dev), "dreq-polarity",
¶m, sizeof(param)) > 0) {
sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_DREQ_POL;
}
/* get IRQ polarity */
if (OF_getprop(ofw_bus_get_node(dev), "int-polarity",
¶m, sizeof(param)) > 0) {
sc->sc_interrupt_cfg |= SOTG_INTERRUPT_CFG_INTPOL;
sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_INTR_POL;
}
/* get IRQ level triggering */
if (OF_getprop(ofw_bus_get_node(dev), "int-level",
¶m, sizeof(param)) > 0) {
sc->sc_interrupt_cfg |= SOTG_INTERRUPT_CFG_INTLVL;
sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_INTR_LEVEL;
}
/* initialise some bus fields */
sc->sc_bus.parent = dev;
sc->sc_bus.devices = sc->sc_devices;
sc->sc_bus.devices_max = SOTG_MAX_DEVICES;
/* get all DMA memory */
if (usb_bus_mem_alloc_all(&sc->sc_bus,
USB_GET_DMA_TAG(dev), NULL)) {
return (ENOMEM);
}
rid = 0;
sc->sc_io_res =
bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (sc->sc_io_res == NULL)
goto error;
sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
sc->sc_io_size = rman_get_size(sc->sc_io_res);
/* try to allocate the HC interrupt first */
rid = 1;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->sc_irq_res == NULL) {
/* try to allocate a common IRQ second */
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->sc_irq_res == NULL)
goto error;
}
sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
if (sc->sc_bus.bdev == NULL)
goto error;
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE,
&saf1761_otg_filter_interrupt, &saf1761_otg_interrupt, sc, &sc->sc_intr_hdl);
if (err) {
sc->sc_intr_hdl = NULL;
goto error;
}
err = saf1761_otg_init(sc);
//.........这里部分代码省略.........
示例15: at91_spi_attach
static int
at91_spi_attach(device_t dev)
{
struct at91_spi_softc *sc;
int err;
uint32_t csr;
sc = device_get_softc(dev);
sc->dev = dev;
sx_init(&sc->xfer_mtx, device_get_nameunit(dev));
/*
* Allocate resources.
*/
err = at91_spi_activate(dev);
if (err)
goto out;
/*
* Set up the hardware.
*/
WR4(sc, SPI_CR, SPI_CR_SWRST);
/* "Software Reset must be Written Twice" erratum */
WR4(sc, SPI_CR, SPI_CR_SWRST);
WR4(sc, SPI_IDR, 0xffffffff);
WR4(sc, SPI_MR, (0xf << 24) | SPI_MR_MSTR | SPI_MR_MODFDIS |
CS_TO_MR(0));
/*
* For now, run the bus at the slowest speed possible as otherwise we
* may encounter data corruption on transmit as seen with ETHERNUT5
* and AT45DB321D even though both board and slave device can take
* more.
* This also serves as a work-around for the "NPCSx rises if no data
* data is to be transmitted" erratum. The ideal workaround for the
* latter is to take the chip select control away from the peripheral
* and manage it directly as a GPIO line. The easy solution is to
* slow down the bus so dramatically that it just never gets starved
* as may be seen when the OCHI controller is running and consuming
* memory and APB bandwidth.
* Also, currently we lack a way for lettting both the board and the
* slave devices take their maximum supported SPI clocks into account.
*/
csr = SPI_CSR_CPOL | (4 << 16) | (0xff << 8);
WR4(sc, SPI_CSR0, csr);
WR4(sc, SPI_CSR1, csr);
WR4(sc, SPI_CSR2, csr);
WR4(sc, SPI_CSR3, csr);
WR4(sc, SPI_CR, SPI_CR_SPIEN);
WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS);
WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS);
WR4(sc, PDC_RNPR, 0);
WR4(sc, PDC_RNCR, 0);
WR4(sc, PDC_TNPR, 0);
WR4(sc, PDC_TNCR, 0);
WR4(sc, PDC_RPR, 0);
WR4(sc, PDC_RCR, 0);
WR4(sc, PDC_TPR, 0);
WR4(sc, PDC_TCR, 0);
RD4(sc, SPI_RDR);
RD4(sc, SPI_SR);
device_add_child(dev, "spibus", -1);
bus_generic_attach(dev);
out:
if (err)
at91_spi_deactivate(dev);
return (err);
}