9 Replies Latest reply on Jul 22, 2020 10:38 PM by YatheeshK_36

    Unexpected ERROR_ABORTED from CyFx3BootUsbDmaXferData in USB2 mode

    OlJo_4577026

      Hi

       

      I have a second stage bootloader that uses the FX3 boot firmware library; I'm testing using the FX3 superspeed explorer kit with a custom daughterboard attached.

       

      The bootloader works correctly when connected via USB3. However, I get unexpected USB control transfer failures when connected by USB2 in specific circumstances.

      When calling CyFx3BootUsbDmaXferData() to receive data for an OUT control transfer, sometimes it will return CY_FX3_BOOT_ERROR_ABORTED unexpectedly. Setup processing doesn't block (and there is no visible delay in debug output at the point of failure), and as far as I am aware there should be no second control transfer / setup packet being received; but the SUDAV interrupt bit is definitely set at the point of failure, which is why ERROR_ABORTED ends up being returned, and the transfer does fail on the host side.

       

      This shows up both during USB enumeration, and when using vendor control transfers. It happens when directly connected to a USB2 port, or when connected to a USB3 port with a USB2 cable, or when connected to a USB3 port but with USB3 functionality disabled in the call to CyFx3BootUsbConnect().

       

      It seems like it is a timing- or bus-state-related problem as:

      1) it only happens when the FX3 is connected directly to the host. If there is a USB hub in between, everything works fine.

      2) when USB enumeration fails due to the error, the host will do a USB reset and subsequent enumeration then works OK.

      3) the specific transfer which it fails on varies depending on how much debug output I have enabled (debug output is going to the UART only)

       

      I get this failure both when loading the second-stage bootloader from EEPROM, and when loading via USB using the ROM bootloader.

       

      I do _not_ get a failure when my separate main firmware that uses the full FX3 library is used (same USB descriptors, different code).

       

      Any ideas what is causing this / how to work around it?

       

      Here is an example of an enumeration failure, with the FX3 directly connected to the host. After the ERROR_ABORTED, the host does a USB reset and re-enumerates successfully:

       

      pv2boot: USB_RESET

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x100 wLength=64

      pv2boot:  -> EP0 write 18 bytes to host

      pv2boot:  -> done

      pv2boot: USB_RESET

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x100 wLength=18

      pv2boot:  -> EP0 write 18 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0xF00 wLength=5

      pv2boot:  -> EP0 write 5 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0xF00 wLength=22

      pv2boot:  -> EP0 write 22 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x200 wLength=9

      pv2boot:  -> EP0 write 9 bytes to host

      pv2boot: xferdata (write) failed: ERROR_ABORTED

      pv2boot:   SUDAV=64

      pv2boot:   SUTOK=0

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x100 wLength=64

      pv2boot:  -> EP0 write 18 bytes to host

      pv2boot:  -> done

      pv2boot: USB_RESET

      pv2boot: USB_RESET

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x100 wLength=18

      pv2boot:  -> EP0 write 18 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0xF00 wLength=5

      pv2boot:  -> EP0 write 5 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0xF00 wLength=22

      pv2boot:  -> EP0 write 22 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x200 wLength=9

      pv2boot:  -> EP0 write 9 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x200 wLength=41

      pv2boot:  -> EP0 write 41 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x300 wLength=255

      pv2boot:  -> EP0 write 4 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x409 wValue=0x302 wLength=255

      pv2boot:  -> EP0 write 24 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x409 wValue=0x301 wLength=255

      pv2boot:  -> EP0 write 24 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x409 wValue=0x303 wLength=255

      pv2boot:  -> EP0 write 18 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x0 request=0x9 wIndex=0x0 wValue=0x1 wLength=0

      pv2boot:  -> ACK

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0xF00 wLength=5

      pv2boot:  -> EP0 write 5 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0xF00 wLength=22

      pv2boot:  -> EP0 write 22 bytes to host

      pv2boot:  -> done

       

      (I suspect the first of two USB resets and the setup request immediately following the error may actually have occurred in the other order)

       

      The host reported this enumeration failure (and successful retry):

       

      [696630.259280] usb 1-6: new high-speed USB device number 29 using xhci_hcd

      [696630.463468] usb 1-6: unable to read config index 0 descriptor/start: -71

      [696630.463487] usb 1-6: can't read configurations, error -71

      [696630.799003] usb 1-6: new high-speed USB device number 30 using xhci_hcd

      [696631.106032] usb 1-6: New USB device found, idVendor=04b4, idProduct=fafb

       

      Also on the host side, a wireshark capture of USB activity shows the GetDescriptor control transfer failing with -EPROTO ("protocol error", which is unfortunately a catchall for a lot of different unexpected-device-behaviour errors)

       

      Here is an example of the same USB2 enumeration working correctly, with a hub between the FX3 and the host. The requests appear to be identical to the failing case:

       

      pv2boot: USB_RESET

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x100 wLength=64

      pv2boot:  -> EP0 write 18 bytes to host

      pv2boot:  -> done

      pv2boot: USB_RESET

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x100 wLength=18

      pv2boot:  -> EP0 write 18 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0xF00 wLength=5

      pv2boot:  -> EP0 write 5 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0xF00 wLength=22

      pv2boot:  -> EP0 write 22 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x200 wLength=9

      pv2boot:  -> EP0 write 9 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x200 wLength=41

      pv2boot:  -> EP0 write 41 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0x300 wLength=255

      pv2boot:  -> EP0 write 4 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x409 wValue=0x302 wLength=255

      pv2boot:  -> EP0 write 24 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x409 wValue=0x301 wLength=255

      pv2boot:  -> EP0 write 24 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x409 wValue=0x303 wLength=255

      pv2boot:  -> EP0 write 18 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x0 request=0x9 wIndex=0x0 wValue=0x1 wLength=0

      pv2boot:  -> ACK

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0xF00 wLength=5

      pv2boot:  -> EP0 write 5 bytes to host

      pv2boot:  -> done

      pv2boot: setup: type=0x80 request=0x6 wIndex=0x0 wValue=0xF00 wLength=22

      pv2boot:  -> EP0 write 22 bytes to host

      pv2boot:  -> done