static int wi_pcmcia_detach(device_t self, int flags) { struct wi_pcmcia_softc *psc = device_private(self); struct wi_softc *sc = &psc->sc_wi; int error; if (psc->sc_state != WI_PCMCIA_ATTACHED) return 0; error = wi_detach(&psc->sc_wi); if (error != 0) return error; if (sc->sc_ih != NULL) pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih); pcmcia_function_unconfigure(psc->sc_pf); return 0; }
int wi_pcmcia_detach(struct device *dev, int flags) { struct wi_pcmcia_softc *psc = (struct wi_pcmcia_softc *)dev; struct wi_softc *sc = &psc->sc_wi; struct ifnet *ifp = &sc->sc_ic.ic_if; if (!(sc->wi_flags & WI_FLAGS_ATTACHED)) return (0); wi_detach(sc); sc->wi_flags = 0; pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window); pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh); ether_ifdetach(ifp); if_detach(ifp); return (0); }
int wi_usb_detach(struct device *self, int flags) { struct wi_usb_softc *sc = (struct wi_usb_softc *)self; struct ifnet *ifp = WI_GET_IFP(sc); struct wi_softc *wsc = &sc->sc_wi; int s; int err; /* Detached before attach finished, so just bail out. */ if (!sc->wi_usb_attached) return (0); if (sc->wi_thread_info != NULL) { sc->wi_thread_info->dying = 1; sc->wi_thread_info->status |= WI_DYING; if (sc->wi_thread_info->idle) wakeup(sc->wi_thread_info); } /* tasks? */ s = splusb(); /* detach wi */ if (!(wsc->wi_flags & WI_FLAGS_ATTACHED)) { printf("%s: already detached\n", sc->wi_usb_dev.dv_xname); splx(s); return (0); } wi_detach(&sc->sc_wi); wsc->wi_flags = 0; if (ifp->if_softc != NULL) { ether_ifdetach(ifp); if_detach(ifp); } sc->wi_usb_attached = 0; if (--sc->wi_usb_refcnt >= 0) { /* Wait for processes to go away. */ usb_detach_wait(&sc->wi_usb_dev); } while (sc->wi_usb_nummem) { sc->wi_usb_nummem--; if (sc->wi_usb_txmem[sc->wi_usb_nummem] != NULL) free(sc->wi_usb_txmem[sc->wi_usb_nummem], M_DEVBUF); sc->wi_usb_txmem[sc->wi_usb_nummem] = NULL; } if (sc->wi_usb_ep[WI_USB_ENDPT_INTR] != NULL) { usbd_abort_pipe(sc->wi_usb_ep[WI_USB_ENDPT_INTR]); err = usbd_close_pipe(sc->wi_usb_ep[WI_USB_ENDPT_INTR]); if (err) { printf("%s: close intr pipe failed: %s\n", sc->wi_usb_dev.dv_xname, usbd_errstr(err)); } sc->wi_usb_ep[WI_USB_ENDPT_INTR] = NULL; } if (sc->wi_usb_ep[WI_USB_ENDPT_TX] != NULL) { usbd_abort_pipe(sc->wi_usb_ep[WI_USB_ENDPT_TX]); err = usbd_close_pipe(sc->wi_usb_ep[WI_USB_ENDPT_TX]); if (err) { printf("%s: close tx pipe failed: %s\n", sc->wi_usb_dev.dv_xname, usbd_errstr(err)); } sc->wi_usb_ep[WI_USB_ENDPT_TX] = NULL; } if (sc->wi_usb_ep[WI_USB_ENDPT_RX] != NULL) { usbd_abort_pipe(sc->wi_usb_ep[WI_USB_ENDPT_RX]); err = usbd_close_pipe(sc->wi_usb_ep[WI_USB_ENDPT_RX]); if (err) { printf("%s: close rx pipe failed: %s\n", sc->wi_usb_dev.dv_xname, usbd_errstr(err)); } sc->wi_usb_ep[WI_USB_ENDPT_RX] = NULL; } splx(s); return (0); }