summaryrefslogtreecommitdiff
path: root/sys/dev/usb/if_bwfm_usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/if_bwfm_usb.c')
-rw-r--r--sys/dev/usb/if_bwfm_usb.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/sys/dev/usb/if_bwfm_usb.c b/sys/dev/usb/if_bwfm_usb.c
index 6029a889274..1d759c3dedb 100644
--- a/sys/dev/usb/if_bwfm_usb.c
+++ b/sys/dev/usb/if_bwfm_usb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bwfm_usb.c,v 1.5 2017/10/21 20:19:37 patrick Exp $ */
+/* $OpenBSD: if_bwfm_usb.c,v 1.6 2018/01/03 21:01:16 patrick Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
* Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
@@ -200,6 +200,7 @@ int bwfm_usb_txdata(struct bwfm_softc *, struct mbuf *);
int bwfm_usb_txctl(struct bwfm_softc *, char *, size_t);
int bwfm_usb_rxctl(struct bwfm_softc *, char *, size_t *);
+struct mbuf * bwfm_usb_newbuf(void);
void bwfm_usb_rxeof(struct usbd_xfer *, void *, usbd_status);
void bwfm_usb_txeof(struct usbd_xfer *, void *, usbd_status);
@@ -404,6 +405,27 @@ bwfm_usb_attachhook(struct device *self)
bwfm_attach(&sc->sc_sc);
}
+struct mbuf *
+bwfm_usb_newbuf(void)
+{
+ struct mbuf *m;
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL)
+ return (NULL);
+
+ MCLGET(m, M_DONTWAIT);
+ if (!(m->m_flags & M_EXT)) {
+ m_freem(m);
+ return (NULL);
+ }
+
+ m->m_len = m->m_pkthdr.len = MCLBYTES;
+ m_adj(m, ETHER_ALIGN);
+
+ return (m);
+}
+
void
bwfm_usb_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
@@ -412,6 +434,7 @@ bwfm_usb_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
struct bwfm_proto_bcdc_hdr *hdr;
usbd_status error;
uint32_t len, off;
+ struct mbuf *m;
DPRINTFN(2, ("%s: %s status %s\n", DEVNAME(sc), __func__,
usbd_errstr(status)));
@@ -437,7 +460,13 @@ bwfm_usb_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
len -= hdr->data_offset << 2;
off += hdr->data_offset << 2;
- bwfm_rx(&sc->sc_sc, &data->buf[off], len);
+ m = bwfm_usb_newbuf();
+ if (m == NULL)
+ goto resubmit;
+
+ memcpy(mtod(m, char *), data->buf + off, len);
+ m->m_len = m->m_pkthdr.len = len;
+ bwfm_rx(&sc->sc_sc, m);
resubmit:
usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf,