PetteriAimonen opened a new pull request #3162:
URL: https://github.com/apache/incubator-nuttx/pull/3162


   ## Summary
   
   For example Windows RNDIS driver issues SETUP requests that are 76 bytes 
long. Previously NuttX would read them all, but only if they arrive at the same 
time. If host transfer scheduling causes a pause between the two DATA packets, 
`stm32_ep0out_receive()` would proceed with an incomplete transfer. The rest of 
the data could either be skipped by the error handler branch, or be left in NAK 
state forever, stopping any further communication on the endpoint.
   
   Example USB trace:
   
   <pre>
   13:44:49.290952 | usb_packet-1: SETUP ADDR 1 EP 0
   13:44:49.290955 | usb_packet-1: DATA0 [ 21 00 00 00 00 00 4C 00 ]            
<--- Request to transfer 76 bytes to device
   13:44:49.290963 | usb_packet-1: ACK
   13:44:49.290970 | usb_packet-1: IN ADDR 1 EP 1
   13:44:49.290974 | usb_packet-1: NAK
                   | Previous two lines repeated 150 times
   13:44:49.291909 | usb_packet-1: SOF 1251
   13:44:49.291942 | usb_packet-1: IN ADDR 1 EP 3
   13:44:49.291946 | usb_packet-1: NAK
   13:44:49.291960 | usb_packet-1: OUT ADDR 1 EP 0
   13:44:49.291963 | usb_packet-1: DATA1 [ 04 00 00 00 4C 00 00 00 FE 02 00 00 
01 01 02 00 30 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]
   13:44:49.292009 | usb_packet-1: NAK                           <--- Trying to 
transfer first 64 bytes, but NuttX is not yet ready
   13:44:49.292044 | usb_packet-1: IN ADDR 1 EP 1
                   | Previous two lines repeated 139 times
   13:44:49.292909 | usb_packet-1: SOF 1252
   13:44:49.292943 | usb_packet-1: IN ADDR 1 EP 3
   13:44:49.292946 | usb_packet-1: NAK
   13:44:49.292961 | usb_packet-1: OUT ADDR 1 EP 0
   13:44:49.292964 | usb_packet-1: DATA1 [ 04 00 00 00 4C 00 00 00 FE 02 00 00 
01 01 02 00 30 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]
   13:44:49.293010 | usb_packet-1: ACK                           <---- NuttX 
accepts the first 64 bytes
   13:44:49.293046 | usb_packet-1: IN ADDR 1 EP 1
   13:44:49.293049 | usb_packet-1: NAK
                   | Previous two lines repeated 138 times        <---- Host is 
slow to send second part of transfer, NuttX IRQ handler executes in meanwhile 
and setup handler is already executed.
   13:44:49.293909 | usb_packet-1: SOF 1253
   13:44:49.293943 | usb_packet-1: IN ADDR 1 EP 3
   13:44:49.293946 | usb_packet-1: NAK
   13:44:49.293961 | usb_packet-1: OUT ADDR 1 EP 0
   13:44:49.293964 | usb_packet-1: DATA0 [ 00 00 00 00 00 00 00 00 00 00 00 00 ]
   13:44:49.293975 | usb_packet-1: NAK                        <------ NuttX 
refuses last 12 bytes of transfer
   ...
   13:44:49.296962 | usb_packet-1: OUT ADDR 1 EP 0    <---- Host will keep 
retrying and communication no longer works
   13:44:49.296965 | usb_packet-1: DATA0 [ 00 00 00 00 00 00 00 00 00 00 00 00 ]
   13:44:49.296976 | usb_packet-1: NAK
   </pre>
   
   This commit changes it so that the whole transfer has to be received before 
SETUP handler is called. The variable `priv->ep0datlen` is used to track the 
total amount of received data until it matches the transfer length specified in 
SETUP packet.
   
   Depending on `CONFIG_USBDEV_SETUP_MAXDATASIZE` any excess bytes will be 
discarded, but doing this in a controlled way ensures deterministic behavior. 
In the specific case of RNDIS, the trailing bytes are unused padding bytes and 
can be safely discarded.
   
   ## Impact
   
   Fully backward compatible. The previous behavior was already to drop bytes 
that
   do not fit in buffer, but it only worked if all of the USB packets arrived 
before IRQ
   handler ran. With this patch the logic behaves the same even if the second
   USB packet is delayed due to other USB traffic.
   
   ## Testing
   
   Tested on custom STM32F4 board with USB RNDIS driver.
   
   The bug can be easiest reproduced by opening the Windows network adapter 
statistics
   window, which causes concurrent RNDIS requests. Note that there is also a 
separate
   RNDIS bug that happens in this situation, fix in separate pull request.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to