Skip to content
  • Hans de Goede's avatar
    usb: Halt ep queue en cancel pending packets on a packet error · 0132b4b6
    Hans de Goede authored
    
    
    For controllers which queue up more then 1 packet at a time, we must halt the
    ep queue, and inside the controller code cancel all pending packets on an
    error.
    
    There are multiple reasons for this:
    1) Guests expect the controllers to halt ep queues on error, so that they
    get the opportunity to cancel transfers which the scheduled after the failing
    one, before processing continues
    
    2) Not cancelling queued up packets after a failed transfer also messes up
    the controller state machine, in the case of EHCI causing the following
    assert to trigger: "assert(p->qtdaddr == q->qtdaddr)" at hcd-ehci.c:2075
    
    3) For bulk endpoints with pipelining enabled (redirection to a real USB
    device), we must cancel all the transfers after this a failed one so that:
    a) If they've completed already, they are not processed further causing more
       stalls to be reported, originating from the same failed transfer
    b) If still in flight, they are cancelled before the guest does
       a clear stall, otherwise the guest and device can loose sync!
    
    Note this patch only touches the ehci and uhci controller changes, since AFAIK
    no other controllers actually queue up multiple transfer. If I'm wrong on this
    other controllers need to be updated too!
    
    Also note that this patch was heavily tested with the ehci code, where I had
    a reproducer for a device causing a transfer to fail. The uhci code is not
    tested with actually failing transfers and could do with a thorough review!
    
    Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
    Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
    0132b4b6