diff options
Diffstat (limited to 'sys/dev/usb/usb_ethersubr.c')
-rw-r--r-- | sys/dev/usb/usb_ethersubr.c | 93 |
1 files changed, 88 insertions, 5 deletions
diff --git a/sys/dev/usb/usb_ethersubr.c b/sys/dev/usb/usb_ethersubr.c index bccc7ea5e1bb..90eff91e51d6 100644 --- a/sys/dev/usb/usb_ethersubr.c +++ b/sys/dev/usb/usb_ethersubr.c @@ -144,18 +144,101 @@ void usb_tx_done(m) } struct mbuf * -usb_ether_newbuf(const char *devname) +usb_ether_newbuf(void) { struct mbuf *m_new; m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (m_new == NULL) { - printf("%s: no memory for rx list " - "-- packet dropped!\n", devname); + if (m_new == NULL) return (NULL); - } m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; m_adj(m_new, ETHER_ALIGN); return (m_new); } + +int +usb_ether_rx_list_init(void *sc, struct ue_cdata *cd, + usbd_device_handle ue_udev) +{ + struct ue_chain *c; + int i; + + for (i = 0; i < UE_RX_LIST_CNT; i++) { + c = &cd->ue_rx_chain[i]; + c->ue_sc = sc; + c->ue_idx = i; + c->ue_mbuf = usb_ether_newbuf(); + if (c->ue_mbuf == NULL) + return (ENOBUFS); + if (c->ue_xfer == NULL) { + c->ue_xfer = usbd_alloc_xfer(ue_udev); + if (c->ue_xfer == NULL) + return (ENOBUFS); + c->ue_buf = usbd_alloc_buffer(c->ue_xfer, UE_BUFSZ); + if (c->ue_buf == NULL) + return (ENOBUFS); + } + } + + return (0); +} + +int +usb_ether_tx_list_init(void *sc, struct ue_cdata *cd, + usbd_device_handle ue_udev) +{ + struct ue_chain *c; + int i; + + for (i = 0; i < UE_TX_LIST_CNT; i++) { + c = &cd->ue_tx_chain[i]; + c->ue_sc = sc; + c->ue_idx = i; + c->ue_mbuf = NULL; + if (c->ue_xfer == NULL) { + c->ue_xfer = usbd_alloc_xfer(ue_udev); + if (c->ue_xfer == NULL) + return (ENOBUFS); + c->ue_buf = usbd_alloc_buffer(c->ue_xfer, UE_BUFSZ); + if (c->ue_buf == NULL) + return (ENOBUFS); + } + } + + return (0); +} + +void +usb_ether_rx_list_free(struct ue_cdata *cd) +{ + int i; + + for (i = 0; i < UE_RX_LIST_CNT; i++) { + if (cd->ue_rx_chain[i].ue_mbuf != NULL) { + m_freem(cd->ue_rx_chain[i].ue_mbuf); + cd->ue_rx_chain[i].ue_mbuf = NULL; + } + if (cd->ue_rx_chain[i].ue_xfer != NULL) { + usbd_free_xfer(cd->ue_rx_chain[i].ue_xfer); + cd->ue_rx_chain[i].ue_xfer = NULL; + } + } +} + +void +usb_ether_tx_list_free(struct ue_cdata *cd) +{ + int i; + + for (i = 0; i < UE_RX_LIST_CNT; i++) { + if (cd->ue_tx_chain[i].ue_mbuf != NULL) { + m_freem(cd->ue_tx_chain[i].ue_mbuf); + cd->ue_tx_chain[i].ue_mbuf = NULL; + } + if (cd->ue_tx_chain[i].ue_xfer != NULL) { + usbd_free_xfer(cd->ue_tx_chain[i].ue_xfer); + cd->ue_tx_chain[i].ue_xfer = NULL; + } + } +} |