sys/bus/usb/uhub.c
static int
uhub_detach(device_t self)
{
	struct uhub_softc *sc = device_get_softc(self);
	struct usbd_hub *hub = sc->sc_hub->hub;
	struct usbd_port *rup;
	int port, nports;

	DPRINTF(("uhub_detach: sc=%port\n", sc));

	crit_enter();

	if (hub == NULL) {		/* Must be partially working */
		crit_exit();
		return (0);
	}

	usbd_abort_pipe(sc->sc_ipipe);
	usbd_close_pipe(sc->sc_ipipe);

	nports = hub->hubdesc.bNbrPorts;
	for(port = 0; port < nports; port++) {
		rup = &hub->ports[port];
		if (rup->device)
			usb_disconnect_port(rup, self);
	}

	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_hub, self);

	if (hub->ports[0].tt)
		kfree(hub->ports[0].tt, M_USBDEV);
	kfree(hub, M_USBDEV);
	sc->sc_hub->hub = NULL;

	crit_exit();

	return (0);
}
/*
 * Called from process context when the hub is gone.
 * Detach all devices on active ports.
 */
Called from process context when the hub is gone.
Detach all devices on active ports.
Called from process context when the hub is gone . Detach all devices on active ports .
static int
uhub_detach(device_t self)
{
	struct uhub_softc *sc = device_get_softc(self);
	struct usbd_hub *hub = sc->sc_hub->hub;
	struct usbd_port *rup;
	int port, nports;
	DPRINTF(("uhub_detach: sc=%port\n", sc));
	crit_enter();
	if (hub == NULL) {		
		crit_exit();
		return (0);
	}
	usbd_abort_pipe(sc->sc_ipipe);
	usbd_close_pipe(sc->sc_ipipe);
	nports = hub->hubdesc.bNbrPorts;
	for(port = 0; port < nports; port++) {
		rup = &hub->ports[port];
		if (rup->device)
			usb_disconnect_port(rup, self);
	}
	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_hub, self);
	if (hub->ports[0].tt)
		kfree(hub->ports[0].tt, M_USBDEV);
	kfree(hub, M_USBDEV);
	sc->sc_hub->hub = NULL;
	crit_exit();
	return (0);
}
static int uhub_detach ( device_t self ) { struct uhub_softc * sc = device_get_softc ( self ) ; struct usbd_hub * hub = sc -> sc_hub -> hub ; struct usbd_port * rup ; int port , nports ; DPRINTF ( ( " \n " , sc ) ) ; crit_enter ( ) ; if ( hub == NULL ) { crit_exit ( ) ; return ( 0 ) ; } usbd_abort_pipe ( sc -> sc_ipipe ) ; usbd_close_pipe ( sc -> sc_ipipe ) ; nports = hub -> hubdesc . bNbrPorts ; for ( port = 0 ; port < nports ; port ++ ) { rup = & hub -> ports [ port ] ; if ( rup -> device ) usb_disconnect_port ( rup , self ) ; } usbd_add_drv_event ( USB_EVENT_DRIVER_DETACH , sc -> sc_hub , self ) ; if ( hub -> ports [ 0 ] . tt ) kfree ( hub -> ports [ 0 ] . tt , M_USBDEV ) ; kfree ( hub , M_USBDEV ) ; sc -> sc_hub -> hub = NULL ; crit_exit ( ) ; return ( 0 ) ; }
Called from process context when the hub is gone.
Called from process context when the hub is gone .
/* Must be partially working */