blob: ddeb43bdd971e213e324d2e4c319ae56e1a52d52 [file] [log] [blame]
Harald Welte8e7fca32017-05-07 16:14:33 +02001#include "board.h"
2#include "trace.h"
3#include "usb_buf.h"
4
5#include "osmocom/core/linuxlist.h"
6#include "osmocom/core/msgb.h"
7#include <errno.h>
8
9#define USB_ALLOC_SIZE 280
10
11static struct usb_buffered_ep usb_buffered_ep[BOARD_USB_NUMENDPOINTS];
12
13struct usb_buffered_ep *usb_get_buf_ep(uint8_t ep)
14{
15 if (ep >= ARRAY_SIZE(usb_buffered_ep))
16 return NULL;
17 return &usb_buffered_ep[ep];
18}
19
20
21/***********************************************************************
22 * User API
23 ***********************************************************************/
24
25struct llist_head *usb_get_queue(uint8_t ep)
26{
27 struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
28 if (!bep)
29 return NULL;
30 return &bep->queue;
31}
32
33/* allocate a USB buffer for use with given end-point */
34struct msgb *usb_buf_alloc(uint8_t ep)
35{
36 struct msgb *msg;
37
38 msg = msgb_alloc(USB_ALLOC_SIZE, "USB");
39 if (!msg)
40 return NULL;
41 msg->dst = usb_get_buf_ep(ep);
42 return msg;
43}
44
45/* release/return the USB buffer to the pool */
46void usb_buf_free(struct msgb *msg)
47{
48 msgb_free(msg);
49}
50
51/* submit a USB buffer for transmission to host */
52int usb_buf_submit(struct msgb *msg)
53{
54 struct usb_buffered_ep *ep = msg->dst;
55
56 if (!msg->dst) {
57 TRACE_ERROR("%s: msg without dst\r\n", __func__);
58 usb_buf_free(msg);
59 return -EINVAL;
60 }
61
62 /* no need for irqsafe operation, as the usb_tx_queue is
63 * processed only by the main loop context */
64 msgb_enqueue(&ep->queue, msg);
65 return 0;
66}
67
68void usb_buf_init(void)
69{
70 unsigned int i;
71
72 for (i = 0; i < ARRAY_SIZE(usb_buffered_ep); i++) {
73 struct usb_buffered_ep *ep = &usb_buffered_ep[i];
74 INIT_LLIST_HEAD(&ep->queue);
75 }
76}