Pull my head out of my ass and actually make the tx netisr stuff work right.

Do not not not call m_freem() in the txeof routines. Let the netisr routine
do it. This also makes the tx netisr queuing much simpler (I can just use
another ifqueue instead of the mess I had before.)

Thanks to Bosko Milekic for making me actually think about what I was
doing for a minute.
This commit is contained in:
wpaul 2000-01-14 01:36:16 +00:00
parent 6c95e5aaf1
commit 23e5d4a086
4 changed files with 22 additions and 46 deletions

View File

@ -1036,7 +1036,8 @@ static void aue_txeof(xfer, priv, status)
ifp->if_flags &= ~IFF_OACTIVE;
usbd_get_xfer_status(c->aue_xfer, NULL, NULL, NULL, &err);
m_freem(c->aue_mbuf);
c->aue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->aue_mbuf);
c->aue_mbuf = NULL;
if (err)
@ -1044,8 +1045,6 @@ static void aue_txeof(xfer, priv, status)
else
ifp->if_opackets++;
usb_tx_done(ifp);
splx(s);
return;

View File

@ -770,7 +770,8 @@ static void kue_txeof(xfer, priv, status)
usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &err);
m_freem(c->kue_mbuf);
c->kue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->kue_mbuf);
c->kue_mbuf = NULL;
if (err)
@ -778,8 +779,6 @@ static void kue_txeof(xfer, priv, status)
else
ifp->if_opackets++;
usb_tx_done(ifp);
splx(s);
return;

View File

@ -73,13 +73,8 @@ static const char rcsid[] =
"$FreeBSD$";
#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 struct ifqueue usbq_rx;
static struct ifqueue usbq_tx;
static void usbintr __P((void));
@ -89,14 +84,13 @@ static void usbintr()
struct mbuf *m;
struct usb_qdat *q;
struct ifnet *ifp;
struct usb_ifent *e;
int s;
s = splimp();
/* Check the RX queue */
while(1) {
IF_DEQUEUE(&usbq, m);
IF_DEQUEUE(&usbq_rx, m);
if (m == NULL)
break;
eh = mtod(m, struct ether_header *);
@ -131,13 +125,14 @@ static void usbintr()
}
/* Check the TX queue */
while (usb_iflisthead.lh_first != NULL) {
e = usb_iflisthead.lh_first;
ifp = e->ifp;
while(1) {
IF_DEQUEUE(&usbq_tx, m);
if (m == NULL)
break;
ifp = m->m_pkthdr.rcvif;
m_freem(m);
if (ifp->if_snd.ifq_head != NULL)
(*ifp->if_start)(ifp);
LIST_REMOVE(e, list);
free(e, M_USBDEV);
}
splx(s);
@ -147,12 +142,7 @@ static void usbintr()
void usb_register_netisr()
{
if (usb_inited == 0) {
register_netisr(NETISR_USB, usbintr);
LIST_INIT(&usb_iflisthead);
usb_inited++;
}
register_netisr(NETISR_USB, usbintr);
return;
}
@ -165,31 +155,19 @@ void usb_ether_input(m)
{
int s;
s = splimp();
IF_ENQUEUE(&usbq, m);
IF_ENQUEUE(&usbq_rx, m);
schednetisr(NETISR_USB);
splx(s);
return;
}
void usb_tx_done(ifp)
struct ifnet *ifp;
void usb_tx_done(m)
struct mbuf *m;
{
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);
int s;
s = splimp();
IF_ENQUEUE(&usbq_tx, m);
schednetisr(NETISR_USB);
splx(s);
return;
}

View File

@ -46,6 +46,6 @@ struct usb_qdat {
void usb_register_netisr __P((void));
void usb_ether_input __P((struct mbuf *));
void usb_tx_done __P((struct ifnet *));
void usb_tx_done __P((struct mbuf *));
#endif