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);
}
示例#3
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);
}