summaryrefslogtreecommitdiff
path: root/sys/dev/usb/if_atu.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2004-11-10 21:45:24 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2004-11-10 21:45:24 +0000
commite7c8cf8e36b5cafa39c9ae10f85f783815bb48fb (patch)
treebbea865bce16a709e846356a7b2b9eb40990d20a /sys/dev/usb/if_atu.c
parent82ad4c586d8e11d48b9dfb5b1bac1cc7b40132ed (diff)
allocate a single buffer for the rx xfer to use rather than let it try
allocating one every time we're restarting it in an interrupt handler. ok deraadt@
Diffstat (limited to 'sys/dev/usb/if_atu.c')
-rw-r--r--sys/dev/usb/if_atu.c66
1 files changed, 49 insertions, 17 deletions
diff --git a/sys/dev/usb/if_atu.c b/sys/dev/usb/if_atu.c
index 4bcde726cd8..5e8fbfbce53 100644
--- a/sys/dev/usb/if_atu.c
+++ b/sys/dev/usb/if_atu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_atu.c,v 1.4 2004/11/09 21:08:49 dlg Exp $ */
+/* $OpenBSD: if_atu.c,v 1.5 2004/11/10 21:45:23 dlg Exp $ */
/*
* Copyright (c) 2003, 2004
* Daan Vreeken <Danovitsch@Vitsch.net>. All rights reserved.
@@ -194,6 +194,7 @@ int atu_media_change(struct ifnet *ifp);
void atu_media_status(struct ifnet *ifp, struct ifmediareq *req);
int atu_xfer_list_init(struct atu_softc *sc, struct atu_chain *ch,
int listlen, int need_mbuf, int bufsize, struct atu_list_head *list);
+int atu_rx_list_init(struct atu_softc *);
void atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch,
int listlen);
void atu_print_beacon(struct atu_softc *sc, struct atu_rxpkt *pkt);
@@ -1767,7 +1768,6 @@ USB_ATTACH(atu)
sc->atu_encrypt = ATU_WEP_OFF;
/* Initialise transfer lists */
- SLIST_INIT(&sc->atu_cdata.atu_rx_free);
SLIST_INIT(&sc->atu_cdata.atu_tx_free);
SLIST_INIT(&sc->atu_cdata.atu_mgmt_free);
@@ -1879,14 +1879,14 @@ atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m)
if (m == NULL) {
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
if (m_new == NULL) {
- DPRINTF(("%s: no memory for rx list -- packet dropped!\n",
+ DPRINTF(("%s: no memory for rx list\n",
USBDEVNAME(sc->atu_dev)));
return(ENOBUFS);
}
MCLGET(m_new, M_DONTWAIT);
if (!(m_new->m_flags & M_EXT)) {
- DPRINTF(("%s: no memory for rx list -- packet dropped!\n",
+ DPRINTF(("%s: no memory for rx list\n",
USBDEVNAME(sc->atu_dev)));
m_freem(m_new);
return(ENOBUFS);
@@ -1902,6 +1902,39 @@ atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m)
}
int
+atu_rx_list_init(struct atu_softc *sc)
+{
+ struct atu_cdata *cd = &sc->atu_cdata;
+ struct atu_chain *c;
+ int i;
+
+ DPRINTFN(10, ("%s: atu_rx_list_init: enter\n",
+ USBDEVNAME(sc->atu_dev)));
+
+ for (i = 0; i < ATU_RX_LIST_CNT; i++) {
+ c = &cd->atu_rx_chain[i];
+ c->atu_sc = sc;
+ c->atu_idx = i;
+ if (c->atu_xfer != NULL) {
+ printf("UGH RX\n");
+ }
+ if (c->atu_xfer == NULL) {
+ c->atu_xfer = usbd_alloc_xfer(sc->atu_udev);
+ if (c->atu_xfer == NULL)
+ return (ENOBUFS);
+ c->atu_buf = usbd_alloc_buffer(c->atu_xfer,
+ ATU_RX_BUFSZ);
+ if (c->atu_buf == NULL) /* XXX free xfer */
+ return (ENOBUFS);
+ if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */
+ return(ENOBUFS);
+ }
+ }
+
+ return (0);
+}
+
+int
atu_xfer_list_init(struct atu_softc *sc, struct atu_chain *ch,
int listlen, int need_mbuf, int bufsize, struct atu_list_head *list)
{
@@ -2341,14 +2374,15 @@ atu_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
- m = c->atu_mbuf;
-
if (total_len <= 1) {
- DPRINTF(("%s: atuw_rxeof: too short\n",
+ DPRINTF(("%s: atu_rxeof: too short\n",
USBDEVNAME(sc->atu_dev)));
goto done;
}
+ m = c->atu_mbuf;
+ memcpy(mtod(m, char *), c->atu_buf, total_len);
+
pkt = mtod(m, struct atu_rxpkt *);
DPRINTFN(10, ("%s: -- RX (rate=%d enc=%d) mac=%s",
@@ -2470,13 +2504,11 @@ atu_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
done1:
splx(s);
done:
- /* Put transfer back into rx-chain */
- SLIST_INSERT_HEAD(&sc->atu_cdata.atu_rx_free, c, atu_list);
-
/* Setup new transfer. */
usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX],
- c, mtod(c->atu_mbuf, char *), ATU_RX_BUFSZ,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof);
+ c, c->atu_buf, ATU_RX_BUFSZ,
+ USBD_SHORT_XFER_OK | USBD_NO_COPY,
+ USBD_NO_TIMEOUT, atu_rxeof);
usbd_transfer(c->atu_xfer);
}
@@ -2761,9 +2793,8 @@ atu_init(void *xsc)
}
/* Init RX ring */
- if (atu_xfer_list_init(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT, 1,
- 0, &cd->atu_rx_free)) {
- DPRINTF(("%s: rx list init failed\n", USBDEVNAME(sc->atu_dev)));
+ if (atu_rx_list_init(sc)) {
+ printf("%s: rx list init failed\n", USBDEVNAME(sc->atu_dev));
}
/* Init mgmt ring */
@@ -2799,8 +2830,9 @@ atu_init(void *xsc)
c = &sc->atu_cdata.atu_rx_chain[i];
usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX],
- c, mtod(c->atu_mbuf, char *), ATU_RX_BUFSZ,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof);
+ c, c->atu_buf, ATU_RX_BUFSZ,
+ USBD_SHORT_XFER_OK | USBD_NO_COPY,
+ USBD_NO_TIMEOUT, atu_rxeof);
usbd_transfer(c->atu_xfer);
}