Skip to content
Snippets Groups Projects
  • Vitaly Kuzmichev's avatar
    98fae970
    USB-CDC: Prevent rx_req being enqueued twice · 98fae970
    Vitaly Kuzmichev authored
    
    After gadget reinitializaton (after tftp has been done once)
    packet_received may become equal to 1 due to nuking OUT_EP
    while disabling it in eth_reset_config.
    
    rx_submit called from usb_eth_init queues rx_req first time.
    But the first call of usb_eth_recv from NetLoop queues rx_req
    again due to packet_received = 1.
    
    The following flow shows the path of functions calls when
    this happens:
    
     net/net.c:NetLoop
     |
     +-net/eth.c:eth_init
     |   ether.c:usb_eth_init
     |   |
     |   +-udc_driver:usb_gadget_handle_interrupts
     |   |   udc_driver:...
     |   |     ether.c:eth_setup
     |   |       ether.c:eth_set_config
     |   |         ether.c:eth_reset_config
     |   |           udc_driver:usb_ep_disable
     |   |             udc_driver:nuke
     |   |               ether.c:rx_complete
     |   |                 ether.c: packet_received = 1;
     |   |
     |   +-ether.c:rx_submit
     |       udc_driver:usb_ep_queue --- The first time when rx_req is queued
     |
     +-net/eth.c:eth_rx
         ether.c:usb_eth_recv
         |
         +-udc_driver:usb_gadget_handle_interrupts
         |   udc_driver:... --- no interrupts, returning
         +-ether.c: if (packet_received) { ...
             ether.c:rx_submit
               udc_driver:usb_ep_queue --- The second time!
    
    Signed-off-by: default avatarVitaly Kuzmichev <vkuzmichev@mvista.com>
    98fae970
    History
    USB-CDC: Prevent rx_req being enqueued twice
    Vitaly Kuzmichev authored
    
    After gadget reinitializaton (after tftp has been done once)
    packet_received may become equal to 1 due to nuking OUT_EP
    while disabling it in eth_reset_config.
    
    rx_submit called from usb_eth_init queues rx_req first time.
    But the first call of usb_eth_recv from NetLoop queues rx_req
    again due to packet_received = 1.
    
    The following flow shows the path of functions calls when
    this happens:
    
     net/net.c:NetLoop
     |
     +-net/eth.c:eth_init
     |   ether.c:usb_eth_init
     |   |
     |   +-udc_driver:usb_gadget_handle_interrupts
     |   |   udc_driver:...
     |   |     ether.c:eth_setup
     |   |       ether.c:eth_set_config
     |   |         ether.c:eth_reset_config
     |   |           udc_driver:usb_ep_disable
     |   |             udc_driver:nuke
     |   |               ether.c:rx_complete
     |   |                 ether.c: packet_received = 1;
     |   |
     |   +-ether.c:rx_submit
     |       udc_driver:usb_ep_queue --- The first time when rx_req is queued
     |
     +-net/eth.c:eth_rx
         ether.c:usb_eth_recv
         |
         +-udc_driver:usb_gadget_handle_interrupts
         |   udc_driver:... --- no interrupts, returning
         +-ether.c: if (packet_received) { ...
             ether.c:rx_submit
               udc_driver:usb_ep_queue --- The second time!
    
    Signed-off-by: default avatarVitaly Kuzmichev <vkuzmichev@mvista.com>