int ata_identify(device_t dev) { struct ata_channel *ch = device_get_softc(dev); struct ata_device *master = NULL, *slave = NULL; device_t master_child = NULL, slave_child = NULL; int master_unit = -1, slave_unit = -1; if (ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER)) { if (!(master = kmalloc(sizeof(struct ata_device), M_ATA, M_INTWAIT | M_ZERO))) { device_printf(dev, "out of memory\n"); return ENOMEM; } master->unit = ATA_MASTER; } if (ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE)) { if (!(slave = kmalloc(sizeof(struct ata_device), M_ATA, M_INTWAIT | M_ZERO))) { kfree(master, M_ATA); device_printf(dev, "out of memory\n"); return ENOMEM; } slave->unit = ATA_SLAVE; } #ifdef ATA_STATIC_ID if (ch->devices & ATA_ATA_MASTER) master_unit = (device_get_unit(dev) << 1); #endif if (master && !(master_child = ata_add_child(dev, master, master_unit))) { kfree(master, M_ATA); master = NULL; } #ifdef ATA_STATIC_ID if (ch->devices & ATA_ATA_SLAVE) slave_unit = (device_get_unit(dev) << 1) + 1; #endif if (slave && !(slave_child = ata_add_child(dev, slave, slave_unit))) { kfree(slave, M_ATA); slave = NULL; } if (slave && ata_getparam(slave, 1)) { device_delete_child(dev, slave_child); kfree(slave, M_ATA); } if (master && ata_getparam(master, 1)) { device_delete_child(dev, master_child); kfree(master, M_ATA); } bus_generic_probe(dev); bus_generic_attach(dev); return 0; }
static int sbc_detach(device_t dev) { struct sbc_softc *scp = device_get_softc(dev); sbc_lock(scp); device_delete_child(dev, scp->child_midi2); device_delete_child(dev, scp->child_midi1); device_delete_child(dev, scp->child_pcm); release_resource(scp); sbc_lockdestroy(scp); return bus_generic_detach(dev); }
static void card_detect_task(void *arg, int pending) { struct fsl_sdhc_softc *sc = (struct fsl_sdhc_softc *)arg; int err; int insert; insert = read4(sc, SDHC_PRSSTAT) & PRSSTAT_CINS; mtx_lock(&sc->mtx); if (insert) { if (sc->child != NULL) { mtx_unlock(&sc->mtx); return; } sc->child = device_add_child(sc->self, "mmc", -1); if (sc->child == NULL) { device_printf(sc->self, "Couldn't add MMC bus!\n"); mtx_unlock(&sc->mtx); return; } /* Initialize MMC bus host structure. */ init_mmc_host_struct(sc); device_set_ivars(sc->child, &sc->mmc_host); } else { if (sc->child == NULL) { mtx_unlock(&sc->mtx); return; } } mtx_unlock(&sc->mtx); if (insert) { if ((err = device_probe_and_attach(sc->child)) != 0) { device_printf(sc->self, "MMC bus failed on probe " "and attach! error %d\n", err); device_delete_child(sc->self, sc->child); sc->child = NULL; } } else { if (device_delete_child(sc->self, sc->child) != 0) device_printf(sc->self, "Could not delete MMC bus!\n"); sc->child = NULL; } }
static int coremctl_detach(device_t dev) { struct coremctl_softc *sc = device_get_softc(dev); if (sc->sc_ecc != NULL) device_delete_child(dev, sc->sc_ecc); if (sc->sc_temp != NULL) device_delete_child(dev, sc->sc_temp); bus_generic_detach(dev); if (sc->sc_mch != NULL) pmap_unmapdev((vm_offset_t)sc->sc_mch, MCH_CORE_SIZE); return 0; }
int ata_detach(device_t dev) { struct ata_channel *ch = device_get_softc(dev); device_t *children; int nchildren, i; /* check that we have a valid channel to detach */ if (!ch->r_irq) return ENXIO; /* grap the channel lock so no new requests gets launched */ mtx_lock(&ch->state_mtx); ch->state |= ATA_STALL_QUEUE; mtx_unlock(&ch->state_mtx); /* detach & delete all children */ if (!device_get_children(dev, &children, &nchildren)) { for (i = 0; i < nchildren; i++) if (children[i]) device_delete_child(dev, children[i]); free(children, M_TEMP); } /* release resources */ bus_teardown_intr(dev, ch->r_irq, ch->ih); bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); ch->r_irq = NULL; mtx_destroy(&ch->state_mtx); mtx_destroy(&ch->queue_mtx); return 0; }
static int mvs_detach(device_t dev) { struct mvs_controller *ctlr = device_get_softc(dev); device_t *children; int nchildren, i; /* Detach & delete all children */ if (!device_get_children(dev, &children, &nchildren)) { for (i = 0; i < nchildren; i++) device_delete_child(dev, children[i]); free(children, M_TEMP); } /* Free interrupt. */ if (ctlr->irq.r_irq) { bus_teardown_intr(dev, ctlr->irq.r_irq, ctlr->irq.handle); bus_release_resource(dev, SYS_RES_IRQ, ctlr->irq.r_irq_rid, ctlr->irq.r_irq); } /* Free memory. */ rman_fini(&ctlr->sc_iomem); if (ctlr->r_mem) bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); mtx_destroy(&ctlr->mtx); return (0); }
static int vtpci_detach(device_t dev) { struct vtpci_softc *sc; device_t child; int error; sc = device_get_softc(dev); if ((child = sc->vtpci_child_dev) != NULL) { error = device_delete_child(dev, child); if (error) return (error); sc->vtpci_child_dev = NULL; } vtpci_reset(sc); if (sc->vtpci_msix_res != NULL) { bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(1), sc->vtpci_msix_res); sc->vtpci_msix_res = NULL; } if (sc->vtpci_res != NULL) { bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->vtpci_res); sc->vtpci_res = NULL; } return (0); }
static int nandsim_stop_ctrl(int num) { device_t nexus; devclass_t nexus_devclass; int ret = 0; nand_debug(NDBG_SIM,"stop controller num:%d", num); if (num >= MAX_SIM_DEV) { return (EINVAL); } if (!ctrls[num].created || !ctrls[num].running) { return (ENODEV); } /* 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 (ENODEV); } mtx_lock(&Giant); if (ctrls[num].sim_ctrl_dev) { ret = device_delete_child(nexus, ctrls[num].sim_ctrl_dev); ctrls[num].sim_ctrl_dev = NULL; } mtx_unlock(&Giant); ctrls[num].running = 0; return (ret); }
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 int zy7_ehci_detach(device_t dev) { ehci_softc_t *sc = device_get_softc(dev); sc->sc_flags &= ~EHCI_SCFLG_DONEINIT; if (device_is_attached(dev)) bus_generic_detach(dev); if (sc->sc_irq_res && sc->sc_intr_hdl) /* call ehci_detach() after ehci_init() called after * successful bus_setup_intr(). */ ehci_detach(sc); if (sc->sc_bus.bdev) { device_detach(sc->sc_bus.bdev); device_delete_child(dev, sc->sc_bus.bdev); } if (sc->sc_irq_res) { if (sc->sc_intr_hdl != NULL) bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr_hdl); bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->sc_irq_res), sc->sc_irq_res); } if (sc->sc_io_res) bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_io_res), sc->sc_io_res); usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc); return (0); }
/* * Since this is not a self-enumerating bus, and since we always add * children in attach, we have to always delete children here. */ static int gpiobus_detach(device_t dev) { struct gpiobus_softc *sc; struct gpiobus_ivar *devi; device_t *devlist; int i, err, ndevs; sc = GPIOBUS_SOFTC(dev); KASSERT(mtx_initialized(&sc->sc_mtx), ("gpiobus mutex not initialized")); GPIOBUS_LOCK_DESTROY(sc); if ((err = bus_generic_detach(dev)) != 0) return (err); if ((err = device_get_children(dev, &devlist, &ndevs)) != 0) return (err); for (i = 0; i < ndevs; i++) { device_delete_child(dev, devlist[i]); devi = GPIOBUS_IVAR(devlist[i]); if (devi->pins) { free(devi->pins, M_DEVBUF); devi->pins = NULL; } } free(devlist, M_TEMP); if (sc->sc_pins_mapped) { free(sc->sc_pins_mapped, M_DEVBUF); sc->sc_pins_mapped = NULL; } return (0); }
int ig4iic_detach(ig4iic_softc_t *sc) { int error; if (device_is_attached(sc->dev)) { error = bus_generic_detach(sc->dev); if (error) return (error); } if (sc->smb) device_delete_child(sc->dev, sc->smb); if (sc->intr_handle) bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); sx_xlock(&sc->call_lock); mtx_lock(&sc->io_lock); sc->smb = NULL; sc->intr_handle = NULL; reg_write(sc, IG4_REG_INTR_MASK, 0); reg_read(sc, IG4_REG_CLR_INTR); set_controller(sc, 0); mtx_unlock(&sc->io_lock); sx_xunlock(&sc->call_lock); return (0); }
/* * Detach the driver from the hardware and other systems in the kernel. */ int ed_detach(device_t dev) { struct ed_softc *sc = device_get_softc(dev); struct ifnet *ifp = sc->ifp; if (mtx_initialized(ED_MUTEX(sc))) ED_ASSERT_UNLOCKED(sc); if (ifp) { ED_LOCK(sc); if (bus_child_present(dev)) ed_stop(sc); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; ED_UNLOCK(sc); ether_ifdetach(ifp); callout_drain(&sc->tick_ch); } if (sc->irq_res != NULL && sc->irq_handle) bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); ed_release_resources(dev); if (sc->miibus) device_delete_child(dev, sc->miibus); if (mtx_initialized(ED_MUTEX(sc))) ED_LOCK_DESTROY(sc); bus_generic_detach(dev); return (0); }
static int ohci_pci_detach(device_t self) { ohci_softc_t *sc = device_get_softc(self); if (sc->sc_flags & OHCI_SCFLG_DONEINIT) { ohci_detach(sc, 0); sc->sc_flags &= ~OHCI_SCFLG_DONEINIT; } if (sc->irq_res && sc->ih) { int err = bus_teardown_intr(self, sc->irq_res, sc->ih); if (err) /* XXX or should we panic? */ device_printf(self, "Could not tear down irq, %d\n", err); sc->ih = NULL; } if (sc->sc_bus.bdev) { device_delete_child(self, sc->sc_bus.bdev); sc->sc_bus.bdev = NULL; } if (sc->irq_res) { bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res); sc->irq_res = NULL; } if (sc->io_res) { bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->io_res); sc->io_res = NULL; sc->iot = 0; sc->ioh = 0; } return 0; }
static int exynos_xhci_detach(device_t dev) { struct exynos_xhci_softc *esc = device_get_softc(dev); device_t bdev; int err; if (esc->base.sc_bus.bdev != NULL) { bdev = esc->base.sc_bus.bdev; device_detach(bdev); device_delete_child(dev, bdev); } /* During module unload there are lots of children leftover */ device_delete_children(dev); xhci_halt_controller(&esc->base); if (esc->res[2] && esc->base.sc_intr_hdl) { err = bus_teardown_intr(dev, esc->res[2], esc->base.sc_intr_hdl); if (err) { device_printf(dev, "Could not tear down IRQ," " %d\n", err); return (err); } } bus_release_resources(dev, exynos_xhci_spec, esc->res); xhci_uninit(&esc->base); return (0); }
int ig4iic_detach(ig4iic_softc_t *sc) { int error; mtx_lock(&sc->mtx); reg_write(sc, IG4_REG_INTR_MASK, 0); reg_read(sc, IG4_REG_CLR_INTR); set_controller(sc, 0); if (sc->generic_attached) { error = bus_generic_detach(sc->dev); if (error) goto done; sc->generic_attached = 0; } if (sc->smb) { device_delete_child(sc->dev, sc->smb); sc->smb = NULL; } if (sc->intr_handle) { bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); sc->intr_handle = NULL; } error = 0; done: mtx_unlock(&sc->mtx); return error; }
static int imx_ehci_detach(device_t dev) { struct imx_ehci_softc *sc; ehci_softc_t *esc; sc = device_get_softc(dev); esc = &sc->ehci_softc; if (esc->sc_bus.bdev != NULL) device_delete_child(dev, esc->sc_bus.bdev); if (esc->sc_flags & EHCI_SCFLG_DONEINIT) ehci_detach(esc); if (esc->sc_intr_hdl != NULL) bus_teardown_intr(dev, esc->sc_irq_res, esc->sc_intr_hdl); if (sc->ehci_irq_res != NULL) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ehci_irq_res); if (sc->ehci_mem_res != NULL) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->ehci_mem_res); usb_bus_mem_free_all(&esc->sc_bus, &ehci_iterate_hw_softc); /* During module unload there are lots of children leftover */ device_delete_children(dev); return (0); }
static int fm801_pci_detach(device_t dev) { int r; struct fm801_info *fm801; DPRINT("Forte Media FM801 detach\n"); fm801 = pcm_getdevinfo(dev); r = bus_generic_detach(dev); if (r) return r; if (fm801->radio != NULL) { r = device_delete_child(dev, fm801->radio); if (r) return r; fm801->radio = NULL; } r = pcm_unregister(dev); if (r) return r; bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg); bus_teardown_intr(dev, fm801->irq, fm801->ih); bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq); bus_dma_tag_destroy(fm801->parent_dmat); kfree(fm801, M_DEVBUF); return 0; }
static int a10_ehci_detach(device_t self) { ehci_softc_t *sc = device_get_softc(self); device_t bdev; int err; uint32_t reg_value = 0; if (sc->sc_bus.bdev) { bdev = sc->sc_bus.bdev; device_detach(bdev); device_delete_child(self, bdev); } /* during module unload there are lots of children leftover */ device_delete_children(self); if (sc->sc_irq_res && sc->sc_intr_hdl) { /* * only call ehci_detach() after ehci_init() */ ehci_detach(sc); err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl); if (err) /* XXX or should we panic? */ device_printf(self, "Could not tear down irq, %d\n", err); sc->sc_intr_hdl = NULL; } if (sc->sc_irq_res) { bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res); sc->sc_irq_res = NULL; } if (sc->sc_io_res) { bus_release_resource(self, SYS_RES_MEMORY, 0, sc->sc_io_res); sc->sc_io_res = NULL; } usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc); /* Disable configure port */ reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2); reg_value &= ~SW_SDRAM_BP_HPCR_ACCESS; A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value); /* Disable passby */ reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE); reg_value &= ~SW_AHB_INCR8; /* AHB INCR8 disable */ reg_value &= ~SW_AHB_INCR4; /* AHB burst type INCR4 disable */ reg_value &= ~SW_AHB_INCRX_ALIGN; /* AHB INCRX align disable */ reg_value &= ~SW_ULPI_BYPASS; /* ULPI bypass disable */ A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value); /* Disable clock for USB */ a10_clk_usb_deactivate(); return (0); }
int mii_phy_probe(device_t dev, device_t *child, ifm_change_cb_t ifmedia_upd, ifm_stat_cb_t ifmedia_sts) { void **v; int i; v = kmalloc(sizeof(vm_offset_t) * 2, M_DEVBUF, M_INTWAIT); v[0] = ifmedia_upd; v[1] = ifmedia_sts; *child = device_add_child(dev, "miibus", -1); device_set_ivars(*child, v); for (i = 0; i < MII_NPHY; i++) { if (!miibus_no_phy(dev, i)) break; } if (i == MII_NPHY) { device_delete_child(dev, *child); *child = NULL; return(ENXIO); } bus_generic_attach(dev); return(0); }
static int pcf_ebus_detach(device_t dev) { struct pcf_softc *sc; int rv; sc = DEVTOSOFTC(dev); if ((rv = bus_generic_detach(dev)) != 0) return (rv); if ((rv = device_delete_child(dev, sc->iicbus)) != 0) return (rv); if (sc->res_irq != 0) { bus_teardown_intr(dev, sc->res_irq, sc->intr_cookie); bus_release_resource(dev, SYS_RES_IRQ, sc->rid_irq, sc->res_irq); } bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport, sc->res_ioport); return (0); }
/******************************************************************************** * Bring the controller down to a dormant state and detach all child devices. * * Note that we can assume that the bioq on the controller is empty, as we won't * allow shutdown if any device is open. */ static int twe_shutdown(device_t dev) { struct twe_softc *sc = device_get_softc(dev); int i, s, error; debug_called(4); s = splbio(); error = 0; /* * Delete all our child devices. */ for (i = 0; i < TWE_MAX_UNITS; i++) { if (sc->twe_drive[i].td_disk != 0) { if ((error = device_delete_child(sc->twe_dev, sc->twe_drive[i].td_disk)) != 0) goto out; sc->twe_drive[i].td_disk = 0; } } /* * Bring the controller down. */ twe_deinit(sc); out: splx(s); return(error); }
static int at91_udp_detach(device_t dev) { struct at91_udp_softc *sc = device_get_softc(dev); device_t bdev; int err; if (sc->sc_dci.sc_bus.bdev) { bdev = sc->sc_dci.sc_bus.bdev; device_detach(bdev); device_delete_child(dev, bdev); } /* during module unload there are lots of children leftover */ device_delete_children(dev); USB_BUS_LOCK(&sc->sc_dci.sc_bus); callout_stop(&sc->sc_vbus); USB_BUS_UNLOCK(&sc->sc_dci.sc_bus); callout_drain(&sc->sc_vbus); /* disable Transceiver */ AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_TXVC, AT91_UDP_TXVC_DIS); /* disable and clear all interrupts */ AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_IDR, 0xFFFFFFFF); AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_ICR, 0xFFFFFFFF); if (sc->sc_dci.sc_irq_res && sc->sc_dci.sc_intr_hdl) { /* * only call at91_udp_uninit() after at91_udp_init() */ at91dci_uninit(&sc->sc_dci); err = bus_teardown_intr(dev, sc->sc_dci.sc_irq_res, sc->sc_dci.sc_intr_hdl); sc->sc_dci.sc_intr_hdl = NULL; } if (sc->sc_dci.sc_irq_res) { bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_dci.sc_irq_res); sc->sc_dci.sc_irq_res = NULL; } if (sc->sc_dci.sc_io_res) { bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID, sc->sc_dci.sc_io_res); sc->sc_dci.sc_io_res = NULL; } usb_bus_mem_free_all(&sc->sc_dci.sc_bus, NULL); /* disable clocks */ at91_pmc_clock_disable(sc->sc_iclk); at91_pmc_clock_disable(sc->sc_fclk); at91_pmc_clock_disable(sc->sc_mclk); at91_pmc_clock_deref(sc->sc_fclk); at91_pmc_clock_deref(sc->sc_iclk); at91_pmc_clock_deref(sc->sc_mclk); return (0); }
/* * Called from process context when we discover that a port has * been disconnected. */ void usb_disconnect_port(struct usbd_port *up, device_t parent) { usbd_device_handle dev = up->device; const char *hubname = device_get_nameunit(parent); int i; DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n", up, dev, up->portno)); #ifdef DIAGNOSTIC if (dev == NULL) { kprintf("usb_disconnect_port: no device\n"); return; } #endif if (dev->subdevs != NULL) { DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n")); for (i = 0; dev->subdevs[i]; i++) { kprintf("%s: at %s", device_get_nameunit(dev->subdevs[i]), hubname); if (up->portno != 0) kprintf(" port %d", up->portno); kprintf(" (addr %d) disconnected\n", dev->address); device_delete_child(device_get_parent(dev->subdevs[i]), dev->subdevs[i]); dev->subdevs[i] = NULL; } } usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev); dev->bus->devices[dev->address] = NULL; up->device = NULL; usb_free_device(dev); }
int ata_pci_detach(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); device_t *children; int nchildren, i; /* detach & delete all children */ if (!device_get_children(dev, &children, &nchildren)) { for (i = 0; i < nchildren; i++) device_delete_child(dev, children[i]); kfree(children, M_TEMP); } if (ctlr->r_irq) { bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle); bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ctlr->r_irq); ctlr->r_irq = NULL; } if (ctlr->r_res2) { bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, ctlr->r_res2); ctlr->r_res2 = NULL; } if (ctlr->r_res1) { bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1, ctlr->r_res1); ctlr->r_res1 = NULL; } return 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); }
/******************************************************************************** * Bring the controller down to a dormant state and detach all child devices. * * This function is called before detach, system shutdown, or before performing * an operation which may add or delete system disks. (Call amr_startup to * resume normal operation.) * * Note that we can assume that the bioq on the controller is empty, as we won't * allow shutdown if any device is open. */ static int amr_pci_shutdown(device_t dev) { struct amr_softc *sc = device_get_softc(dev); int i,error; debug_called(1); /* mark ourselves as in-shutdown */ sc->amr_state |= AMR_STATE_SHUTDOWN; /* flush controller */ device_printf(sc->amr_dev, "flushing cache..."); printf("%s\n", amr_flush(sc) ? "failed" : "done"); error = 0; /* delete all our child devices */ for(i = 0 ; i < AMR_MAXLD; i++) { if( sc->amr_drive[i].al_disk != 0) { if((error = device_delete_child(sc->amr_dev,sc->amr_drive[i].al_disk)) != 0) goto shutdown_out; sc->amr_drive[i].al_disk = 0; } } /* XXX disable interrupts? */ shutdown_out: return(error); }
static int mv_ehci_detach(device_t self) { ehci_softc_t *sc = device_get_softc(self); device_t bdev; int err; if (sc->sc_bus.bdev) { bdev = sc->sc_bus.bdev; device_detach(bdev); device_delete_child(self, bdev); } /* during module unload there are lots of children leftover */ device_delete_children(self); /* * disable interrupts that might have been switched on in mv_ehci_attach */ if (sc->sc_io_res) { EWRITE4(sc, USB_BRIDGE_INTR_MASK, 0); } if (sc->sc_irq_res && sc->sc_intr_hdl) { /* * only call ehci_detach() after ehci_init() */ ehci_detach(sc); err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl); if (err) /* XXX or should we panic? */ device_printf(self, "Could not tear down irq, %d\n", err); sc->sc_intr_hdl = NULL; } if (irq_err && ih_err) { err = bus_teardown_intr(self, irq_err, ih_err); if (err) device_printf(self, "Could not tear down irq, %d\n", err); ih_err = NULL; } if (irq_err) { bus_release_resource(self, SYS_RES_IRQ, 0, irq_err); irq_err = NULL; } if (sc->sc_irq_res) { bus_release_resource(self, SYS_RES_IRQ, 1, sc->sc_irq_res); sc->sc_irq_res = NULL; } if (sc->sc_io_res) { bus_release_resource(self, SYS_RES_MEMORY, 0, sc->sc_io_res); sc->sc_io_res = NULL; } usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc); return (0); }
static int mfi_pci_detach(device_t dev) { struct mfi_softc *sc; int error, devcount, i; device_t *devlist; sc = device_get_softc(dev); sx_xlock(&sc->mfi_config_lock); mtx_lock(&sc->mfi_io_lock); if ((sc->mfi_flags & MFI_FLAGS_OPEN) != 0) { mtx_unlock(&sc->mfi_io_lock); sx_xunlock(&sc->mfi_config_lock); return (EBUSY); } sc->mfi_detaching = 1; mtx_unlock(&sc->mfi_io_lock); if ((error = device_get_children(sc->mfi_dev, &devlist, &devcount)) != 0) { sx_xunlock(&sc->mfi_config_lock); return error; } for (i = 0; i < devcount; i++) device_delete_child(sc->mfi_dev, devlist[i]); free(devlist, M_TEMP); sx_xunlock(&sc->mfi_config_lock); EVENTHANDLER_DEREGISTER(shutdown_final, sc->mfi_eh); mfi_shutdown(sc); mfi_free(sc); mfi_pci_free(sc); return (0); }
static int mfi_pci_detach(device_t dev) { struct mfi_softc *sc; struct mfi_disk *ld; int error; sc = device_get_softc(dev); sx_xlock(&sc->mfi_config_lock); mtx_lock(&sc->mfi_io_lock); if ((sc->mfi_flags & MFI_FLAGS_OPEN) != 0) { mtx_unlock(&sc->mfi_io_lock); sx_xunlock(&sc->mfi_config_lock); return (EBUSY); } sc->mfi_detaching = 1; mtx_unlock(&sc->mfi_io_lock); while ((ld = TAILQ_FIRST(&sc->mfi_ld_tqh)) != NULL) { if ((error = device_delete_child(dev, ld->ld_dev)) != 0) { sc->mfi_detaching = 0; sx_xunlock(&sc->mfi_config_lock); return (error); } } sx_xunlock(&sc->mfi_config_lock); EVENTHANDLER_DEREGISTER(shutdown_final, sc->mfi_eh); mfi_shutdown(sc); mfi_free(sc); mfi_pci_free(sc); return (0); }