Esempio n. 1
0
/*
 * 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);
}
Esempio n. 2
0
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;
}