/*------------------------------------------------------------------------* * usb_detach *------------------------------------------------------------------------*/ static int usb_detach(device_t dev) { struct usb_bus *bus = device_get_softc(dev); DPRINTF("\n"); if (bus == NULL) { /* was never setup properly */ return (0); } /* Stop power watchdog */ usb_callout_drain(&bus->power_wdog); #if USB_HAVE_ROOT_MOUNT_HOLD /* Let the USB explore process detach all devices. */ usb_root_mount_rel(bus); #endif USB_BUS_LOCK(bus); /* Queue detach job */ usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus), &bus->detach_msg[0], &bus->detach_msg[1]); /* Wait for detach to complete */ usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus), &bus->detach_msg[0], &bus->detach_msg[1]); #if USB_HAVE_UGEN /* Wait for cleanup to complete */ usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus), &bus->cleanup_msg[0], &bus->cleanup_msg[1]); #endif USB_BUS_UNLOCK(bus); #if USB_HAVE_PER_BUS_PROCESS /* Get rid of USB callback processes */ usb_proc_free(USB_BUS_GIANT_PROC(bus)); usb_proc_free(USB_BUS_NON_GIANT_ISOC_PROC(bus)); usb_proc_free(USB_BUS_NON_GIANT_BULK_PROC(bus)); /* Get rid of USB explore process */ usb_proc_free(USB_BUS_EXPLORE_PROC(bus)); /* Get rid of control transfer process */ usb_proc_free(USB_BUS_CONTROL_XFER_PROC(bus)); #endif #if USB_HAVE_PF usbpf_detach(bus); #endif return (0); }
static int g_modem_detach(device_t dev) { struct g_modem_softc *sc = device_get_softc(dev); DPRINTF("\n"); lockmgr(&sc->sc_lock, LK_EXCLUSIVE); usb_callout_stop(&sc->sc_callout); usb_callout_stop(&sc->sc_watchdog); lockmgr(&sc->sc_lock, LK_RELEASE); usbd_transfer_unsetup(sc->sc_xfer, G_MODEM_N_TRANSFER); usb_callout_drain(&sc->sc_callout); usb_callout_drain(&sc->sc_watchdog); lockuninit(&sc->sc_lock); return (0); }
static int g_audio_detach(device_t dev) { struct g_audio_softc *sc = device_get_softc(dev); DPRINTF("\n"); mtx_lock(&sc->sc_mtx); usb_callout_stop(&sc->sc_callout); usb_callout_stop(&sc->sc_watchdog); mtx_unlock(&sc->sc_mtx); usbd_transfer_unsetup(sc->sc_xfer, G_AUDIO_N_TRANSFER); usb_callout_drain(&sc->sc_callout); usb_callout_drain(&sc->sc_watchdog); mtx_destroy(&sc->sc_mtx); return (0); }
/*------------------------------------------------------------------------* * usb_detach *------------------------------------------------------------------------*/ static int usb_detach(device_t dev) { struct usb_bus *bus = device_get_softc(dev); DPRINTF("\n"); if (bus == NULL) { /* was never setup properly */ return (0); } /* Stop power watchdog */ usb_callout_drain(&bus->power_wdog); /* Let the USB explore process detach all devices. */ usb_root_mount_rel(bus); USB_BUS_LOCK(bus); /* Queue detach job */ usb_proc_msignal(&bus->explore_proc, &bus->detach_msg[0], &bus->detach_msg[1]); /* Wait for detach to complete */ usb_proc_mwait(&bus->explore_proc, &bus->detach_msg[0], &bus->detach_msg[1]); #if USB_HAVE_UGEN /* Wait for cleanup to complete */ usb_proc_mwait(&bus->explore_proc, &bus->cleanup_msg[0], &bus->cleanup_msg[1]); #endif USB_BUS_UNLOCK(bus); /* Get rid of USB callback processes */ usb_proc_free(&bus->giant_callback_proc); usb_proc_free(&bus->non_giant_callback_proc); /* Get rid of USB explore process */ usb_proc_free(&bus->explore_proc); /* Get rid of control transfer process */ usb_proc_free(&bus->control_xfer_proc); #if USB_HAVE_PF usbpf_detach(bus); #endif return (0); }
void uether_ifdetach(struct usb_ether *ue) { struct ifnet *ifp; /* wait for any post attach or other command to complete */ usb_proc_drain(&ue->ue_tq); /* read "ifnet" pointer after taskqueue drain */ ifp = ue->ue_ifp; if (ifp != NULL) { /* we are not running any more */ UE_LOCK(ue); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; UE_UNLOCK(ue); /* drain any callouts */ usb_callout_drain(&ue->ue_watchdog); /* detach miibus */ if (ue->ue_miibus != NULL) { mtx_lock(&Giant); /* device_xxx() depends on this */ device_delete_child(ue->ue_dev, ue->ue_miibus); mtx_unlock(&Giant); } /* detach ethernet */ ether_ifdetach(ifp); /* free interface instance */ if_free(ifp); /* free sysctl */ sysctl_ctx_free(&ue->ue_sysctl_ctx); /* free unit */ free_unr(ueunit, ue->ue_unit); } /* free taskqueue, if any */ usb_proc_free(&ue->ue_tq); }
static void usie_if_stop(struct usie_softc *sc) { usb_callout_drain(&sc->sc_if_sync_ch); mtx_lock(&sc->sc_mtx); /* usie_cns_req() clears IFF_* flags */ usie_cns_req(sc, USIE_CNS_ID_STOP, USIE_CNS_OB_LINK_UPDATE); usbd_transfer_stop(sc->sc_if_xfer[USIE_IF_TX]); usbd_transfer_stop(sc->sc_if_xfer[USIE_IF_RX]); usbd_transfer_stop(sc->sc_if_xfer[USIE_IF_STATUS]); /* shutdown device */ usie_if_cmd(sc, USIE_HIP_DOWN); mtx_unlock(&sc->sc_mtx); }
static int xhci_pci_detach(device_t self) { struct xhci_softc *sc = device_get_softc(self); device_t bdev; if (sc->sc_bus.bdev != NULL) { 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_io_res) { usb_callout_drain(&sc->sc_callout); xhci_halt_controller(sc); } pci_disable_busmaster(self); if (sc->sc_irq_res && sc->sc_intr_hdl) { bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl); sc->sc_intr_hdl = NULL; } if (sc->sc_irq_res) { if (sc->sc_irq_rid == 1) pci_release_msi(self); bus_release_resource(self, SYS_RES_IRQ, sc->sc_irq_rid, sc->sc_irq_res); sc->sc_irq_res = NULL; } if (sc->sc_io_res) { bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM, sc->sc_io_res); sc->sc_io_res = NULL; } xhci_uninit(sc); return (0); }
static int tegra_xhci_detach(device_t dev) { struct tegra_xhci_softc *sc; struct xhci_softc *xsc; sc = device_get_softc(dev); xsc = &sc->xhci_softc; /* during module unload there are lots of children leftover */ device_delete_children(dev); if (sc->xhci_inited) { usb_callout_drain(&xsc->sc_callout); xhci_halt_controller(xsc); } if (xsc->sc_irq_res && xsc->sc_intr_hdl) { bus_teardown_intr(dev, xsc->sc_irq_res, xsc->sc_intr_hdl); xsc->sc_intr_hdl = NULL; } if (xsc->sc_irq_res) { bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(xsc->sc_irq_res), xsc->sc_irq_res); xsc->sc_irq_res = NULL; } if (xsc->sc_io_res != NULL) { bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(xsc->sc_io_res), xsc->sc_io_res); xsc->sc_io_res = NULL; } if (sc->xhci_inited) xhci_uninit(xsc); if (sc->irq_hdl_mbox != NULL) bus_teardown_intr(dev, sc->irq_res_mbox, sc->irq_hdl_mbox); if (sc->fw_vaddr != 0) kmem_free(kernel_arena, sc->fw_vaddr, sc->fw_size); LOCK_DESTROY(sc); return (0); }
void uether_ifdetach(struct usb_ether *ue) { struct ifnet *ifp; /* wait for any post attach or other command to complete */ usb_proc_drain(&ue->ue_tq); /* read "ifnet" pointer after taskqueue drain */ ifp = uether_getifp(ue); if (ifp != NULL) { /* we are not running any more */ UE_LOCK(ue); ifp->if_flags &= ~IFF_RUNNING; UE_UNLOCK(ue); /* drain any callouts */ usb_callout_drain(&ue->ue_watchdog); /* detach miibus */ if (ue->ue_miibus != NULL) { device_delete_child(ue->ue_dev, ue->ue_miibus); } /* detach ethernet */ ether_ifdetach(ifp); /* free sysctl */ sysctl_ctx_free(&ue->ue_sysctl_ctx); /* free unit */ devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(ue), ue->ue_unit); } /* free taskqueue, if any */ usb_proc_free(&ue->ue_tq); }