Date: Sun, 13 May 2007 20:58:57 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 119795 for review Message-ID: <200705132058.l4DKwvpk072662@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=119795 Change 119795 by hselasky@hselasky_mini_itx on 2007/05/13 20:58:10 Teardown the USB transfers a little bit earlier in the USB network drivers. Some fixes to if_zyd regarding unlocked forwarding of data to the ieee80211 layer. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/if_aue.c#25 edit .. //depot/projects/usb/src/sys/dev/usb/if_axe.c#24 edit .. //depot/projects/usb/src/sys/dev/usb/if_cdce.c#17 edit .. //depot/projects/usb/src/sys/dev/usb/if_cue.c#20 edit .. //depot/projects/usb/src/sys/dev/usb/if_kue.c#22 edit .. //depot/projects/usb/src/sys/dev/usb/if_rue.c#21 edit .. //depot/projects/usb/src/sys/dev/usb/if_rum.c#4 edit .. //depot/projects/usb/src/sys/dev/usb/if_udav.c#21 edit .. //depot/projects/usb/src/sys/dev/usb/if_ural.c#27 edit .. //depot/projects/usb/src/sys/dev/usb/if_zyd.c#11 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/if_aue.c#25 (text+ko) ==== @@ -960,6 +960,9 @@ mtx_unlock(&(sc->sc_mtx)); + /* stop all USB transfers first */ + usbd_transfer_unsetup(sc->sc_xfer, AUE_ENDPT_MAX); + /* get rid of any late children */ bus_generic_detach(dev); @@ -968,8 +971,6 @@ if_free(ifp); } - usbd_transfer_unsetup(sc->sc_xfer, AUE_ENDPT_MAX); - usbd_config_td_unsetup(&(sc->sc_config_td)); __callout_drain(&(sc->sc_watchdog)); ==== //depot/projects/usb/src/sys/dev/usb/if_axe.c#24 (text+ko) ==== @@ -947,6 +947,9 @@ mtx_unlock(&(sc->sc_mtx)); + /* stop all USB transfers first */ + usbd_transfer_unsetup(sc->sc_xfer, AXE_ENDPT_MAX); + /* get rid of any late children */ bus_generic_detach(dev); @@ -955,8 +958,6 @@ if_free(ifp); } - usbd_transfer_unsetup(sc->sc_xfer, AXE_ENDPT_MAX); - usbd_config_td_unsetup(&(sc->sc_config_td)); __callout_drain(&(sc->sc_watchdog)); ==== //depot/projects/usb/src/sys/dev/usb/if_cdce.c#17 (text+ko) ==== @@ -414,6 +414,9 @@ mtx_unlock(&(sc->sc_mtx)); + /* stop all USB transfers first */ + usbd_transfer_unsetup(sc->sc_xfer, CDCE_ENDPT_MAX); + /* get rid of any late children */ bus_generic_detach(dev); @@ -423,8 +426,6 @@ ifmedia_removeall(&(sc->sc_ifmedia)); } - usbd_transfer_unsetup(sc->sc_xfer, CDCE_ENDPT_MAX); - mtx_destroy(&(sc->sc_mtx)); return (0); ==== //depot/projects/usb/src/sys/dev/usb/if_cue.c#20 (text+ko) ==== @@ -599,6 +599,9 @@ mtx_unlock(&(sc->sc_mtx)); + /* stop all USB transfers first */ + usbd_transfer_unsetup(sc->sc_xfer, CUE_ENDPT_MAX); + /* get rid of any late children */ bus_generic_detach(dev); @@ -607,8 +610,6 @@ if_free(ifp); } - usbd_transfer_unsetup(sc->sc_xfer, CUE_ENDPT_MAX); - usbd_config_td_unsetup(&(sc->sc_config_td)); __callout_drain(&(sc->sc_watchdog)); ==== //depot/projects/usb/src/sys/dev/usb/if_kue.c#22 (text+ko) ==== @@ -635,6 +635,9 @@ mtx_unlock(&(sc->sc_mtx)); + /* stop all USB transfers first */ + usbd_transfer_unsetup(sc->sc_xfer, KUE_ENDPT_MAX); + /* get rid of any late children */ bus_generic_detach(dev); @@ -643,8 +646,6 @@ if_free(ifp); } - usbd_transfer_unsetup(sc->sc_xfer, KUE_ENDPT_MAX); - usbd_config_td_unsetup(&(sc->sc_config_td)); __callout_drain(&(sc->sc_watchdog)); ==== //depot/projects/usb/src/sys/dev/usb/if_rue.c#21 (text+ko) ==== @@ -853,6 +853,9 @@ mtx_unlock(&(sc->sc_mtx)); + /* stop all USB transfers first */ + usbd_transfer_unsetup(sc->sc_xfer, RUE_ENDPT_MAX); + /* get rid of any late children */ bus_generic_detach(dev); @@ -861,8 +864,6 @@ if_free(ifp); } - usbd_transfer_unsetup(sc->sc_xfer, RUE_ENDPT_MAX); - usbd_config_td_unsetup(&(sc->sc_config_td)); __callout_drain(&(sc->sc_watchdog)); ==== //depot/projects/usb/src/sys/dev/usb/if_rum.c#4 (text+ko) ==== @@ -518,9 +518,7 @@ mtx_unlock(&(sc->sc_mtx)); - /* XXX make sure that all USB callbacks have exited - * before tearing down the network stack: - */ + /* stop all USB transfers first */ usbd_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER); /* get rid of any late children */ ==== //depot/projects/usb/src/sys/dev/usb/if_udav.c#21 (text+ko) ==== @@ -465,6 +465,9 @@ mtx_unlock(&(sc->sc_mtx)); + /* stop all USB transfers first */ + usbd_transfer_unsetup(sc->sc_xfer, UDAV_ENDPT_MAX); + /* get rid of any late children */ bus_generic_detach(dev); @@ -473,8 +476,6 @@ if_free(ifp); } - usbd_transfer_unsetup(sc->sc_xfer, UDAV_ENDPT_MAX); - usbd_config_td_unsetup(&(sc->sc_config_td)); __callout_drain(&(sc->sc_watchdog)); ==== //depot/projects/usb/src/sys/dev/usb/if_ural.c#27 (text+ko) ==== @@ -573,9 +573,7 @@ mtx_unlock(&(sc->sc_mtx)); - /* XXX make sure that all USB callbacks have exited - * before tearing down the network stack: - */ + /* stop all USB transfers first */ usbd_transfer_unsetup(sc->sc_xfer, URAL_N_TRANSFER); /* get rid of any late children */ ==== //depot/projects/usb/src/sys/dev/usb/if_zyd.c#11 (text+ko) ==== @@ -78,6 +78,12 @@ #define DPRINTF(...) #endif +struct mq { /* mini-queue */ + struct mbuf *ifq_head; + struct mbuf *ifq_tail; + uint16_t ifq_len; +}; + static device_probe_t zyd_probe; static device_attach_t zyd_attach; static device_detach_t zyd_detach; @@ -120,7 +126,7 @@ static void zyd_cfg_write32_batch(struct zyd_softc *sc, const struct zyd_adpairs32 *data, uint32_t count); static void zyd_cfg_rfwrite(struct zyd_softc *sc, uint32_t value, uint8_t bits); static void zyd_cfg_stateoutput(struct zyd_softc *sc) __used; -static void zyd_rxframeproc(struct usbd_xfer *xfer, uint16_t offset, uint16_t len); +static void zyd_rxframeproc(struct usbd_xfer *xfer, struct mq *mq, uint16_t offset, uint16_t len); static uint8_t zyd_cfg_uploadfirmware(struct zyd_softc *sc); static void zyd_cfg_lock_phy(struct zyd_softc *sc); static void zyd_cfg_unlock_phy(struct zyd_softc *sc); @@ -954,7 +960,8 @@ * inside a single USB transfer. */ static void -zyd_rxframeproc(struct usbd_xfer *xfer, uint16_t offset, uint16_t len) +zyd_rxframeproc(struct usbd_xfer *xfer, struct mq *mq, + uint16_t offset, uint16_t len) { struct zyd_softc *sc = xfer->priv_sc; struct ieee80211com *ic = &(sc->sc_ic); @@ -1029,11 +1036,11 @@ ni = ieee80211_find_rxnode(ic, (void *)(m->m_data)); - /* send the frame to the 802.11 layer */ - ieee80211_input(ic, m, ni, desc.signalstrength, 0); + /* XXX our small hacks XXX */ + ni->ni_rssi = desc.signalstrength; + m->m_pkthdr.rcvif = (void *)ni; - /* node is no longer needed */ - ieee80211_free_node(ni); + _IF_ENQUEUE(mq, m); DPRINTF(sc, 14, "rx done\n"); @@ -1078,7 +1085,10 @@ struct zyd_softc *sc = xfer->priv_sc; struct ieee80211com *ic = &(sc->sc_ic); struct ifnet *ifp = ic->ic_ifp; + struct ieee80211_node *ni; struct zyd_rxleninfoapp info; + struct mq mq = { NULL, NULL, 0 }; + struct mbuf *m; USBD_CHECK_STATUS(xfer); @@ -1133,17 +1143,45 @@ goto tr_setup; } - zyd_rxframeproc(xfer, ZYD_PLCP_HDR_SIZE, + zyd_rxframeproc(xfer, &mq, ZYD_PLCP_HDR_SIZE, xfer->actlen - ZYD_PLCP_HDR_SIZE); } tr_setup: if (sc->sc_flags & ZYD_FLAG_BULK_READ_STALL) { usbd_transfer_start(sc->sc_xfer[ZYD_TR_BULK_CS_RD]); - return; + } else { + usbd_start_hardware(xfer); } - usbd_start_hardware(xfer); + /* At the end of a USB callback it is always safe + * to unlock the private mutex of a device! That + * is why we do the "ieee80211_input" here, and not + * some lines up! + */ + if (mq.ifq_head) { + + mtx_unlock(&(sc->sc_mtx)); + + while (1) { + + _IF_DEQUEUE(&(mq), m); + + if (m == NULL) break; + + /* XXX undo our small hacks XXX */ + ni = (void *)(m->m_pkthdr.rcvif); + m->m_pkthdr.rcvif = ifp; + + /* send the frame to the 802.11 layer */ + ieee80211_input(ic, m, ni, ni->ni_rssi, 0); + + /* node is no longer needed */ + ieee80211_free_node(ni); + } + + mtx_lock(&(sc->sc_mtx)); + } return; } @@ -2157,6 +2195,9 @@ mtx_unlock(&(sc->sc_mtx)); + /* stop all USB transfers first */ + usbd_transfer_unsetup(sc->sc_xfer, ZYD_TR_MAX); + /* get rid of any late children */ bus_generic_detach(dev); @@ -2166,8 +2207,6 @@ if_free(ifp); } - usbd_transfer_unsetup(sc->sc_xfer, ZYD_TR_MAX); - usbd_config_td_unsetup(&(sc->sc_config_td)); __callout_drain(&(sc->sc_watchdog));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200705132058.l4DKwvpk072662>