forked from len0rd/rockbox
usb: ensure RX buffers are a multiple of the packet size
When performing an OUT transfer which is not a multiple of the max packet size, the last packet of the OUT transfer should be a short packet. However, there's no guarantee the host sends the expected amount of data in the final packet. The DWC2 USB controller handles this case by accepting any size packet and copying it out to memory. So if the packet is bigger than expected, it'll overrun the caller's buffer and Bad Things will happen. The USB 2.0 spec seems to endorse this behavior. Section 8.5.1 says "an ACK handshake indicates the endpoint has space for a wMaxPacketSize data payload." So it is possible that other USB controllers share the DWC2's behavior. The simplest solution is to force all USB RX buffers to be big enough to hold the transfer size, rounded up to a multiple of the max packet size. For example, a transfer of 700 bytes would require a 1024-byte buffer if the MPS = 512 bytes. Change-Id: Ibb84d2b2d53aec8800a3a7c2449f7a17480acbcf
This commit is contained in:
parent
a665c1faad
commit
24294bda15
3 changed files with 25 additions and 12 deletions
|
|
@ -666,8 +666,7 @@ void usb_hid_transfer_complete(int ep, int dir, int status, int length)
|
|||
* to the DAP using the host's custom driver */
|
||||
static int usb_hid_set_report(struct usb_ctrlrequest *req, void *reqdata)
|
||||
{
|
||||
static unsigned char buf[SET_REPORT_BUF_LEN] USB_DEVBSS_ATTR
|
||||
__attribute__((aligned(32)));
|
||||
static unsigned char buf[64] USB_DEVBSS_ATTR __attribute__((aligned(32)));
|
||||
int length;
|
||||
|
||||
if ((req->wValue >> 8) != REPORT_TYPE_OUTPUT)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue