The old USB ethernet code utilized a netisr to hand packets over
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Wed, 16 Feb 2005 22:50:28 +0000 (22:50 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Wed, 16 Feb 2005 22:50:28 +0000 (22:50 +0000)
the ether_input and cleanup after txeof. This was broken some
time ago and is a workaround for the different IPL of USB and
the network stack.

Reduce the amount of hacks by removing usb_tx_done, it can be
done mostly in-place with a slight race-condition in the enqueue
code. usb_ether_input now directly calls ether_input, the caller
is responsible for rearming the receiver. That's doesn't open
a race since the receiver doesn't have to handle the interface
queues, for the driver state is the driver responsible.

The IPL protection of the USB ethernet drivers has to be reviewed,
it's mostly not existing.

sys/bus/usb/usb_ethersubr.c
sys/bus/usb/usb_ethersubr.h
sys/dev/netif/aue/if_aue.c
sys/dev/netif/axe/if_axe.c
sys/dev/netif/cue/if_cue.c
sys/dev/netif/kue/if_kue.c

index 198d178..2db40d7 100644 (file)
@@ -31,7 +31,7 @@
  *
  *
  * $FreeBSD: src/sys/dev/usb/usb_ethersubr.c,v 1.17 2003/11/14 11:09:45 johan Exp $
- * $DragonFly: src/sys/bus/usb/usb_ethersubr.c,v 1.11 2005/02/15 10:30:11 joerg Exp $
+ * $DragonFly: src/sys/bus/usb/usb_ethersubr.c,v 1.12 2005/02/16 22:50:28 joerg Exp $
  */
 
 /*
 #include "usb.h"
 #include "usb_ethersubr.h"
 
-Static struct ifqueue usbq_rx;
-Static struct ifqueue usbq_tx;
-Static int mtx_inited = 0;
+Static int netisr_inited = 0;
 
 Static int usbintr(struct netmsg *msg)
 {
        struct mbuf *m = ((struct netmsg_packet *)msg)->nm_packet;
-       struct usb_qdat         *q;
-       struct ifnet            *ifp;
-       int                     s;
+       struct ifnet *ifp;
+       int s;
 
        s = splimp();
 
-       /* Check the RX queue */
-       while(1) {
-               IF_DEQUEUE(&usbq_rx, m);
-               if (m == NULL)
-                       break;
-               q = (struct usb_qdat *)m->m_pkthdr.rcvif;
-               ifp = q->ifp;
-               (*ifp->if_input)(ifp, m);
-
-               /* Re-arm the receiver */
-               (*q->if_rxstart)(ifp);
-               if (!ifq_is_empty(&ifp->if_snd))
-                       (*ifp->if_start)(ifp);
-       }
-
-       /* Check the TX queue */
-       while(1) {
-               IF_DEQUEUE(&usbq_tx, m);
-               if (m == NULL)
-                       break;
-               ifp = m->m_pkthdr.rcvif;
-               m_freem(m);
-               if (!ifq_is_empty(&ifp->if_snd))
-                       (*ifp->if_start)(ifp);
-       }
+       ifp = m->m_pkthdr.rcvif;
+       (*ifp->if_input)(ifp, m);
 
        splx(s);
 
@@ -121,11 +95,10 @@ Static int usbintr(struct netmsg *msg)
 void
 usb_register_netisr(void)
 {
-       if (mtx_inited)
-               return;
-       mtx_inited = 1;
-       netisr_register(NETISR_USB, cpu0_portfn, usbintr);
-       return;
+       if (netisr_inited == 0) {
+               netisr_inited = 1;
+               netisr_register(NETISR_USB, cpu0_portfn, usbintr);
+       }
 }
 
 /*
@@ -137,9 +110,3 @@ usb_ether_input(struct mbuf *m)
 {
        netisr_queue(NETISR_USB, m);
 }
-
-void
-usb_tx_done(struct mbuf *m)
-{
-       netisr_queue(NETISR_USB, m);
-}
index dafe6a8..87667eb 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/usb/usb_ethersubr.h,v 1.6 2003/03/04 23:19:55 jlemon Exp $
- * $DragonFly: src/sys/bus/usb/usb_ethersubr.h,v 1.4 2003/12/30 01:01:44 dillon Exp $
+ * $DragonFly: src/sys/bus/usb/usb_ethersubr.h,v 1.5 2005/02/16 22:50:28 joerg Exp $
  */
 
 #ifndef _USB_ETHERSUBR_H_
@@ -43,6 +43,5 @@ struct usb_qdat {
 
 void usb_register_netisr       (void);
 void usb_ether_input           (struct mbuf *);
-void usb_tx_done               (struct mbuf *);
 
 #endif
index 1cfdb4b..b14eedd 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.78 2003/12/17 14:23:07 sanpei Exp $
- * $DragonFly: src/sys/dev/netif/aue/if_aue.c,v 1.16 2005/02/15 16:44:23 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/aue/if_aue.c,v 1.17 2005/02/16 22:50:28 joerg Exp $
  *
  * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.19.2.18 2003/06/14 15:56:48 trhodes Exp $
  */
@@ -173,8 +173,6 @@ Static const struct aue_type aue_devs[] = {
 };
 #define aue_lookup(v, p) ((const struct aue_type *)usb_lookup(aue_devs, v, p))
 
-Static struct usb_qdat aue_qdat;
-
 Static int aue_match(device_ptr_t);
 Static int aue_attach(device_ptr_t);
 Static int aue_detach(device_ptr_t);
@@ -767,9 +765,6 @@ USB_ATTACH(aue)
                USB_ATTACH_ERROR_RETURN;
        }
 
-       aue_qdat.ifp = ifp;
-       aue_qdat.if_rxstart = aue_rxstart;
-
        /*
         * Call MI attach routine.
         */
@@ -1025,11 +1020,12 @@ aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        total_len -= (4 + ETHER_CRC_LEN);
 
        ifp->if_ipackets++;
-       m->m_pkthdr.rcvif = (struct ifnet *)&aue_qdat;
+       m->m_pkthdr.rcvif = ifp;
        m->m_pkthdr.len = m->m_len = total_len;
 
        /* Put the packet on the special USB input queue. */
        usb_ether_input(m);
+       aue_start(ifp);
        AUE_UNLOCK(sc);
        return;
 done:
@@ -1078,8 +1074,7 @@ aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        usbd_get_xfer_status(c->aue_xfer, NULL, NULL, NULL, &err);
 
        if (c->aue_mbuf != NULL) {
-               c->aue_mbuf->m_pkthdr.rcvif = ifp;
-               usb_tx_done(c->aue_mbuf);
+               m_free(c->aue_mbuf);
                c->aue_mbuf = NULL;
        }
 
@@ -1088,6 +1083,9 @@ aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        else
                ifp->if_opackets++;
 
+       if (!ifq_is_empty(&ifp->if_snd))
+               (*ifp->if_start)(ifp);
+
        AUE_UNLOCK(sc);
 
        return;
index e247ff4..66c93db 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/usb/if_axe.c,v 1.10 2003/12/08 07:54:14 obrien Exp $
- * $DragonFly: src/sys/dev/netif/axe/if_axe.c,v 1.8 2005/02/15 19:19:11 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/axe/if_axe.c,v 1.9 2005/02/16 22:50:28 joerg Exp $
  */
 /*
  * ASIX Electronics AX88172 USB 2.0 ethernet driver. Used in the
@@ -112,8 +112,6 @@ Static struct axe_type axe_devs[] = {
        { 0, 0 }
 };
 
-Static struct usb_qdat axe_qdat;
-
 Static int axe_match(device_ptr_t);
 Static int axe_attach(device_ptr_t);
 Static int axe_detach(device_ptr_t);
@@ -504,9 +502,6 @@ USB_ATTACH(axe)
        ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
        ifq_set_ready(&ifp->if_snd);
 
-       axe_qdat.ifp = ifp;
-       axe_qdat.if_rxstart = axe_rxstart;
-
        if (mii_phy_probe(self, &sc->axe_miibus,
            axe_ifmedia_upd, axe_ifmedia_sts)) {
                printf("axe%d: MII without any PHY!\n", sc->axe_unit);
@@ -704,11 +699,12 @@ axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        }
 
        ifp->if_ipackets++;
-       m->m_pkthdr.rcvif = (struct ifnet *)&axe_qdat;
+       m->m_pkthdr.rcvif = ifp;
        m->m_pkthdr.len = m->m_len = total_len;
 
        /* Put the packet on the special USB input queue. */
        usb_ether_input(m);
+       axe_rxstart(ifp);
        splx(s);
 
        return;
@@ -761,8 +757,7 @@ axe_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &err);
 
        if (c->axe_mbuf != NULL) {
-               c->axe_mbuf->m_pkthdr.rcvif = ifp;
-               usb_tx_done(c->axe_mbuf);
+               m_freem(c->axe_mbuf);
                c->axe_mbuf = NULL;
        }
 
@@ -771,6 +766,9 @@ axe_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        else
                ifp->if_opackets++;
 
+       if (!ifq_is_empty(&ifp->if_snd))
+               (*ifp->if_start)(ifp);
+
        splx(s);
 }
 
index 59861c4..b50cd55 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/usb/if_cue.c,v 1.45 2003/12/08 07:54:14 obrien Exp $
- * $DragonFly: src/sys/dev/netif/cue/if_cue.c,v 1.16 2005/02/15 20:23:10 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/cue/if_cue.c,v 1.17 2005/02/16 22:50:28 joerg Exp $
  *
  */
 
@@ -93,8 +93,6 @@ Static struct cue_type cue_devs[] = {
        { 0, 0 }
 };
 
-Static struct usb_qdat cue_qdat;
-
 Static int cue_match(device_ptr_t);
 Static int cue_attach(device_ptr_t);
 Static int cue_detach(device_ptr_t);
@@ -522,9 +520,6 @@ USB_ATTACH(cue)
        ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
        ifq_set_ready(&ifp->if_snd);
 
-       cue_qdat.ifp = ifp;
-       cue_qdat.if_rxstart = cue_rxstart;
-
        /*
         * Call MI attach routine.
         */
@@ -727,11 +722,13 @@ cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 
        ifp->if_ipackets++;
        m_adj(m, sizeof(u_int16_t));
-       m->m_pkthdr.rcvif = (struct ifnet *)&cue_qdat;
+       m->m_pkthdr.rcvif = ifp;
        m->m_pkthdr.len = m->m_len = total_len;
 
        /* Put the packet on the special USB input queue. */
        usb_ether_input(m);
+       cue_rxstart(ifp);
+
        CUE_UNLOCK(sc);
 
        return;
@@ -782,8 +779,7 @@ cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &err);
 
        if (c->cue_mbuf != NULL) {
-               c->cue_mbuf->m_pkthdr.rcvif = ifp;
-               usb_tx_done(c->cue_mbuf);
+               m_freem(c->cue_mbuf);
                c->cue_mbuf = NULL;
        }
 
@@ -792,6 +788,9 @@ cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        else
                ifp->if_opackets++;
 
+       if (!ifq_is_empty(&ifp->if_snd))
+               (*ifp->if_start)(ifp);
+
        CUE_UNLOCK(sc);
 
        return;
index 88060eb..7d7d96c 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  *  $FreeBSD: src/sys/dev/usb/if_kue.c,v 1.17.2.9 2003/04/13 02:39:25 murray Exp $
- * $DragonFly: src/sys/dev/netif/kue/if_kue.c,v 1.13 2004/10/14 18:31:02 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/kue/if_kue.c,v 1.14 2005/02/16 22:50:28 joerg Exp $
  */
 
 /*
@@ -74,6 +74,7 @@
 #include <sys/socket.h>
 
 #include <net/if.h>
+#include <net/ifq_var.h>
 #include <net/if_arp.h>
 #include <net/ethernet.h>
 #include <net/if_dl.h>
@@ -124,8 +125,6 @@ Static struct kue_type kue_devs[] = {
        { 0, 0 }
 };
 
-Static struct usb_qdat kue_qdat;
-
 Static int kue_match(device_ptr_t);
 Static int kue_attach(device_ptr_t);
 Static int kue_detach(device_ptr_t);
@@ -485,10 +484,8 @@ USB_ATTACH(kue)
        ifp->if_watchdog = kue_watchdog;
        ifp->if_init = kue_init;
        ifp->if_baudrate = 10000000;
-       ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
-
-       kue_qdat.ifp = ifp;
-       kue_qdat.if_rxstart = kue_rxstart;
+       ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
+       ifq_set_ready(&ifp->if_snd);
 
        /*
         * Call MI attach routine.
@@ -700,11 +697,13 @@ Static void kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
        }
 
        ifp->if_ipackets++;
-       m->m_pkthdr.rcvif = (struct ifnet *)&kue_qdat;
+       m->m_pkthdr.rcvif = ifp;
        m->m_pkthdr.len = m->m_len = total_len;
 
        /* Put the packet on the special USB input queue. */
        usb_ether_input(m);
+       kue_rxstart(ifp);
+
        KUE_UNLOCK(sc);
 
        return;
@@ -757,8 +756,7 @@ kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &err);
 
        if (c->kue_mbuf != NULL) {
-               c->kue_mbuf->m_pkthdr.rcvif = ifp;
-               usb_tx_done(c->kue_mbuf);
+               m_freem(c->kue_mbuf);
                c->kue_mbuf = NULL;
        }
 
@@ -767,6 +765,9 @@ kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        else
                ifp->if_opackets++;
 
+       if (!ifq_is_empty(&ifp->if_snd))
+               (*ifp->if_start)(ifp);
+
        KUE_UNLOCK(sc);
 
        return;
@@ -824,18 +825,18 @@ kue_start(struct ifnet *ifp)
                return;
        }
 
-       IF_DEQUEUE(&ifp->if_snd, m_head);
+       m_head = ifq_poll(&ifp->if_snd);
        if (m_head == NULL) {
                KUE_UNLOCK(sc);
                return;
        }
 
        if (kue_encap(sc, m_head, 0)) {
-               IF_PREPEND(&ifp->if_snd, m_head);
                ifp->if_flags |= IFF_OACTIVE;
                KUE_UNLOCK(sc);
                return;
        }
+       m_head = ifq_dequeue(&ifp->if_snd);
 
        /*
         * If there's a BPF listener, bounce a copy of this frame
@@ -1008,7 +1009,7 @@ kue_watchdog(struct ifnet *ifp)
        usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &stat);
        kue_txeof(c->kue_xfer, c, stat);
 
-       if (ifp->if_snd.ifq_head != NULL)
+       if (ifq_is_empty(&ifp->if_snd))
                kue_start(ifp);
        KUE_UNLOCK(sc);