summaryrefslogtreecommitdiff
path: root/sys/dev/usb/usb_ethersubr.c
diff options
context:
space:
mode:
authorBill Paul <wpaul@FreeBSD.org>2000-01-12 17:46:40 +0000
committerBill Paul <wpaul@FreeBSD.org>2000-01-12 17:46:40 +0000
commit502c509ce0d7260d2f01ede9bb564623c4f67ef7 (patch)
treed4f6a193e399533d1b7b240229250b9ee0a06b8c /sys/dev/usb/usb_ethersubr.c
parent49503b44fd1e3ffc1d21955f67f93b20810dd424 (diff)
Notes
Diffstat (limited to 'sys/dev/usb/usb_ethersubr.c')
-rw-r--r--sys/dev/usb/usb_ethersubr.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/sys/dev/usb/usb_ethersubr.c b/sys/dev/usb/usb_ethersubr.c
index ded747e61edb..ffe8a7dbbe6c 100644
--- a/sys/dev/usb/usb_ethersubr.c
+++ b/sys/dev/usb/usb_ethersubr.c
@@ -55,6 +55,7 @@
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
+#include <sys/malloc.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -63,6 +64,7 @@
#include <net/ethernet.h>
#include <net/netisr.h>
+#include <dev/usb/usb.h>
#include <dev/usb/usb_ethersubr.h>
#ifndef lint
@@ -71,6 +73,12 @@ static const char rcsid[] =
#endif
static struct ifqueue usbq;
+struct usb_ifent {
+ struct ifnet *ifp;
+ LIST_ENTRY(usb_ifent) list;
+};
+static LIST_HEAD(, usb_ifent) usb_iflisthead;
+static int usb_inited = 0;
static void usbintr __P((void));
@@ -78,17 +86,33 @@ static void usbintr()
{
struct ether_header *eh;
struct mbuf *m;
+ struct ifnet *ifp;
+ struct usb_ifent *e;
int s;
s = splimp();
+ /* Check the RX queue */
while(1) {
IF_DEQUEUE(&usbq, m);
if (m == NULL)
break;
eh = mtod(m, struct ether_header *);
m_adj(m, sizeof(struct ether_header));
- ether_input(m->m_pkthdr.rcvif, eh, m);
+ ifp = m->m_pkthdr.rcvif;
+ ether_input(ifp, eh, m);
+ if (ifp->if_snd.ifq_head != NULL)
+ (*ifp->if_start)(ifp);
+ }
+
+ /* Check the TX queue */
+ while (usb_iflisthead.lh_first != NULL) {
+ e = usb_iflisthead.lh_first;
+ ifp = e->ifp;
+ if (ifp->if_snd.ifq_head != NULL)
+ (*ifp->if_start)(ifp);
+ LIST_REMOVE(e, list);
+ free(e, M_USBDEV);
}
splx(s);
@@ -98,7 +122,12 @@ static void usbintr()
void usb_register_netisr()
{
- register_netisr(NETISR_USB, usbintr);
+ if (usb_inited == 0) {
+ register_netisr(NETISR_USB, usbintr);
+ LIST_INIT(&usb_iflisthead);
+ usb_inited++;
+ }
+
return;
}
@@ -116,3 +145,26 @@ void usb_ether_input(m)
splx(s);
return;
}
+
+void usb_tx_done(ifp)
+ struct ifnet *ifp;
+{
+ struct usb_ifent *e;
+
+ /* See if this if is already scheduled. */
+ for (e = usb_iflisthead.lh_first; e != NULL; e = e->list.le_next) {
+ if (ifp == e->ifp)
+ return;
+ }
+
+ e = malloc(sizeof(struct usb_ifent), M_USB, M_NOWAIT);
+ if (e == NULL)
+ return;
+
+ e->ifp = ifp;
+
+ LIST_INSERT_HEAD(&usb_iflisthead, e, list);
+ schednetisr(NETISR_USB);
+
+ return;
+}