/* * A frame has been uploaded: pass the resulting mbuf up to * the higher level protocols. */ static void lgue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct lgue_softc *sc; struct mbuf *m; struct ifnet *ifp; int total_len; sc = priv; if (sc->lgue_dying) return; ifp = &sc->lgue_arpcom.ac_if; total_len = 0; if (!(ifp->if_flags & IFF_RUNNING)) return; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) return; if (usbd_ratecheck(&sc->lgue_rx_notice)) { if_printf(ifp, "usb error on rx:%s\n", usbd_errstr(status)); } if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->lgue_ep[LGUE_ENDPT_RX]); goto done; } usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); if (total_len < sizeof(struct ether_header)) { IFNET_STAT_INC(ifp, ierrors, 1); goto done; } if (lgue_newbuf(sc, total_len, &m) == ENOBUFS) { IFNET_STAT_INC(ifp, ierrors, 1); return; } IFNET_STAT_INC(ifp, ipackets, 1); m_copyback(m, 0, total_len, sc->lgue_rx_buf); m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = total_len; usb_ether_input(m); lgue_rxstart(ifp); return; done: usbd_setup_xfer(sc->lgue_rx_xfer, sc->lgue_ep[LGUE_ENDPT_RX], sc, sc->lgue_rx_buf, LGUE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, lgue_rxeof); usbd_transfer(sc->lgue_rx_xfer); }
Static void cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct ue_chain *c = priv; struct cdce_softc *sc = c->ue_sc; struct ifnet *ifp; struct mbuf *m; int total_len = 0; CDCE_LOCK(sc); ifp = GET_IFP(sc); if (sc->cdce_dying || !(ifp->if_flags & IFF_RUNNING)) { CDCE_UNLOCK(sc); return; } if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { CDCE_UNLOCK(sc); return; } if (sc->cdce_rxeof_errors == 0) printf("%s: usb error on rx: %s\n", USBDEVNAME(sc->cdce_dev), usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->cdce_bulkin_pipe); DELAY(sc->cdce_rxeof_errors * 10000); sc->cdce_rxeof_errors++; goto done; } sc->cdce_rxeof_errors = 0; usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); if (sc->cdce_flags & CDCE_ZAURUS) total_len -= 4; /* Strip off CRC added by Zaurus */ m = c->ue_mbuf; if (total_len < sizeof(struct ether_header)) { ifp->if_ierrors++; goto done; } ifp->if_ipackets++; m->m_pkthdr.rcvif = (struct ifnet *)&sc->q; m->m_pkthdr.len = m->m_len = total_len; /* Put the packet on the special USB input queue. */ usb_ether_input(m); CDCE_UNLOCK(sc); return; done: /* Setup new transfer. */ usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cdce_rxeof); usbd_transfer(c->ue_xfer); CDCE_UNLOCK(sc); return; }