This fixes a race condition when multiple EPs perform transfers at the
same time.
Moreover, reorganize the USB packet memory taking into account only the
allocated endpoints. This allows to reduce the memory reserved for
buffer descriptor table (metadata), and enlarge the "useful" memory that
can be allocated for the real USB transfers (data).
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4384
38d2e660-2303-0410-9eaa-
f027e97ec537
/* Endpoint descriptors: used for handling requests to use with endpoints */
static stm32_UsbEp ep_cnfg[EP_MAX_NUM];
/* Endpoint descriptors: used for handling requests to use with endpoints */
static stm32_UsbEp ep_cnfg[EP_MAX_NUM];
+STATIC_ASSERT(EP_MAX_NUM <= EP_MAX_HW_NUM);
/* USB EP0 control descriptor */
static const UsbEndpointDesc USB_CtrlEpDescr0 =
/* USB EP0 control descriptor */
static const UsbEndpointDesc USB_CtrlEpDescr0 =
static stm32_UsbMemSlot *mem_use;
/* USB packet memory management: memory buffer metadata */
static stm32_UsbMemSlot *mem_use;
/* USB packet memory management: memory buffer metadata */
-static stm32_UsbMemSlot memory_buffer[EP_MAX_HW_NUM >> 1];
+static stm32_UsbMemSlot memory_buffer[EP_MAX_NUM];
/* Endpoint TX and RX buffers */
/// \cond
/* XXX: use the empty cond section to silent a buggy doxygen warning */
static bool rx_done, tx_done;
static size_t rx_size, tx_size;
/* Endpoint TX and RX buffers */
/// \cond
/* XXX: use the empty cond section to silent a buggy doxygen warning */
static bool rx_done, tx_done;
static size_t rx_size, tx_size;
-static uint8_t ep_buffer[_MIN(CONFIG_USB_BUFSIZE, USB_XFER_MAX_SIZE)] ALIGNED(4);
+
+#define EP_BUFFER_SIZE _MIN(CONFIG_USB_BUFSIZE, USB_XFER_MAX_SIZE)
+STATIC_ASSERT(!(EP_BUFFER_SIZE & 0x03));
+
+static uint8_t ep_buffer[EP_MAX_NUM][EP_BUFFER_SIZE] ALIGNED(4);
/// \endcond
/* Allocate a free block of the packet memory */
/// \endcond
/* Allocate a free block of the packet memory */
mem = mem->next;
}
/* Check for out-of-memory condition */
mem = mem->next;
}
/* Check for out-of-memory condition */
- if ((*pOffset + max_size) >= USB_BDT_OFFSET)
+ if (UNLIKELY((*pOffset + max_size) >= USB_BDT_OFFSET))
return false;
/*
* Allocate a new memory block, next to the last allocated block.
*/
mem_useNew = usb_malloc();
return false;
/*
* Allocate a new memory block, next to the last allocated block.
*/
mem_useNew = usb_malloc();
- if (mem_useNew == NULL)
+ if (UNLIKELY(mem_useNew == NULL))
return false;
/* Insert the block to the list of allocated blocks */
if (mem_use == NULL)
return false;
/* Insert the block to the list of allocated blocks */
if (mem_use == NULL)
ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size)
{
int ep_num = usb_ep_logical_to_hw(ep);
ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size)
{
int ep_num = usb_ep_logical_to_hw(ep);
- ssize_t max_size = sizeof(ep_buffer);
+ ssize_t max_size = sizeof(ep_buffer[ep_num]);
/* Non-blocking read for EP0 */
if (ep_num == CTRL_ENP_OUT)
/* Non-blocking read for EP0 */
if (ep_num == CTRL_ENP_OUT)
usb_status_handler(ep_num);
else
{
usb_status_handler(ep_num);
else
{
- __usb_ep_read(ep_num, ep_buffer, size,
+ __usb_ep_read(ep_num, ep_buffer[ep_num], size,
- memcpy(buffer, ep_buffer, size);
+ memcpy(buffer, ep_buffer[ep_num], size);
rx_size = 0;
/* Blocking read */
rx_size = 0;
/* Blocking read */
- __usb_ep_read(ep_num, ep_buffer, size, usb_endpointRead_complete);
+ __usb_ep_read(ep_num, ep_buffer[ep_num], size,
+ usb_endpointRead_complete);
while (!rx_done)
cpu_relax();
while (!rx_done)
cpu_relax();
- memcpy(buffer, ep_buffer, rx_size);
+ memcpy(buffer, ep_buffer[ep_num], rx_size);
ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size)
{
int ep_num = usb_ep_logical_to_hw(ep);
ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size)
{
int ep_num = usb_ep_logical_to_hw(ep);
- ssize_t max_size = sizeof(ep_buffer);
+ ssize_t max_size = sizeof(ep_buffer[ep_num]);
/* Non-blocking write for EP0 */
if (ep_num == CTRL_ENP_IN)
/* Non-blocking write for EP0 */
if (ep_num == CTRL_ENP_IN)
usb_status_handler(ep_num);
else
{
usb_status_handler(ep_num);
else
{
- memcpy(ep_buffer, buffer, size);
- __usb_ep_write(ep_num, ep_buffer, size,
+ memcpy(ep_buffer[ep_num], buffer, size);
+ __usb_ep_write(ep_num, ep_buffer[ep_num], size,
usb_status_handler);
}
return size;
usb_status_handler);
}
return size;
tx_size = 0;
/* Blocking write */
tx_size = 0;
/* Blocking write */
- memcpy(ep_buffer, buffer, size);
- __usb_ep_write(ep_num, ep_buffer, size, usb_endpointWrite_complete);
+ memcpy(ep_buffer[ep_num], buffer, size);
+ __usb_ep_write(ep_num, ep_buffer[ep_num], size,
+ usb_endpointWrite_complete);
while (!tx_done)
cpu_relax();
while (!tx_done)
cpu_relax();
/* Offset of the buffer descriptor table inside the packet memory */
#define USB_BDT_OFFSET \
/* Offset of the buffer descriptor table inside the packet memory */
#define USB_BDT_OFFSET \
- ((USB_PACKET_MEMORY_SIZE - (sizeof(stm32_UsbBd) * EP_MAX_HW_NUM)) & ~7)
+ ((USB_PACKET_MEMORY_SIZE - (sizeof(stm32_UsbBd) * EP_MAX_NUM)) & ~7)
#define USB_MEM_ADDR(offset) \
(USB_PACKET_MEMORY_BASE + ((offset << 1) & ~3) + (offset & 1))
#define USB_MEM_ADDR(offset) \
(USB_PACKET_MEMORY_BASE + ((offset << 1) & ~3) + (offset & 1))