Files
simtrace2/firmware/libcommon/source/usb_buf.c
Harald Welte f4a625be53 usb_buf: count number of elements in queue
This is in preparation for limiting the maximum queue length

Change-Id: I7cb184d7a1ccb519010a2f3e3295cc3a5fbf8052
Related: OS#4251
2019-12-14 21:50:59 +01:00

94 lines
2.4 KiB
C

/* USB buffer library
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*/
#include "board.h"
#include "trace.h"
#include "usb_buf.h"
#include "simtrace_usb.h"
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/msgb.h>
#include <errno.h>
#define USB_ALLOC_SIZE 280
static struct usb_buffered_ep usb_buffered_ep[BOARD_USB_NUMENDPOINTS];
struct usb_buffered_ep *usb_get_buf_ep(uint8_t ep)
{
if (ep >= ARRAY_SIZE(usb_buffered_ep))
return NULL;
return &usb_buffered_ep[ep];
}
/***********************************************************************
* User API
***********************************************************************/
struct llist_head *usb_get_queue(uint8_t ep)
{
struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
if (!bep)
return NULL;
return &bep->queue;
}
/* allocate a USB buffer for use with given end-point */
struct msgb *usb_buf_alloc(uint8_t ep)
{
struct msgb *msg;
msg = msgb_alloc(USB_ALLOC_SIZE, "USB");
if (!msg)
return NULL;
msg->dst = usb_get_buf_ep(ep);
return msg;
}
/* release/return the USB buffer to the pool */
void usb_buf_free(struct msgb *msg)
{
msgb_free(msg);
}
/* submit a USB buffer for transmission to host */
int usb_buf_submit(struct msgb *msg)
{
struct usb_buffered_ep *ep = msg->dst;
if (!msg->dst) {
TRACE_ERROR("%s: msg without dst\r\n", __func__);
usb_buf_free(msg);
return -EINVAL;
}
/* no need for irqsafe operation, as the usb_tx_queue is
* processed only by the main loop context */
msgb_enqueue_count(&ep->queue, msg, &ep->queue_len);
return 0;
}
void usb_buf_init(void)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(usb_buffered_ep); i++) {
struct usb_buffered_ep *ep = &usb_buffered_ep[i];
INIT_LLIST_HEAD(&ep->queue);
}
}