• David Brownell's avatar
    [PATCH] rm "automagic resubmit" for usb interrupt transfers · e9c72b55
    David Brownell authored
    Here's that promised patch to remove the problematic "automagic
    resubmit" mode from the API for interrupt transfers.  It covers
    the core (including main HCDs) and a few essential drivers.
    
    All urbs now obey a simple rule:  submit them once, then wait for
    some completion callback.  Or unlink the urb if you're impatient,
    canceling the i/o request (which may have been partially completed).
    Bulk and interrupt transfers now behave the same at the API level,
    except that only interrupt transfers have bandwidth failure modes.
    
    
    Previously, interrupt transfers were different from bulk transfers
    in several ways that made limited sense.  The only thing that's
    supposed to be special is achieving service latency guarantees by
    using the reserved periodic bandwidth.
    
    But there were a lot of other restrictions, plus HCD-dependent
    behaviors/bugs.  Doing something like sending a 97 byte message
    to a device portably was a thing of pain, since the low-level
    "one packet per interval" rule was pushed up to drivers instead
    of being handled inside HCDs like it is for bulk, and sending a
    final "short" packet meant an urb unlink/relink.  (Fixing this
    required UHCI to use a queue of TDs, like EHCI and OHCI; fixed
    by 2.5.44, and a small change in this patch.  I'm not sure the
    unlink/relink issues have ever been really addressed.)  Neither
    1-msec transfer intervals nor USB 2.0 "high bandwidth" mode can
    reliably be serviced without a multi-buffered queue of interrupt
    transfers.  (Comes almost for free with TD queueing; as of 2.5.44
    all HCDs should do this.)
    
    And then there's "automagic resubmission", which made HCDs
    keep urbs during their complete() callbacks in a rather curious
    state ... half-owned by HCD, half-owned by device driver, not
    exactly linked but maybe not unlinked either.  Bug-prone, and
    hard to test.
    
    
    So that's all gone now!  This particular patch
    
      - updates the main hcds to use normal urb-completion logic
        for interrupt transfers, nothing special. (*)
    
      - makes usbcore (hub and root hub drivers) expect that, and
        removes an old kernel 2.3 "urb state confusion" workaround.
        (urb->dev is no longer nulled to distinguish unlinked urbs,
        since there's no longer a "half-in/half-out" state.)  also
        the relevent kerneldoc is updated.
    
      - enables the 'usbtest' support for interrupt transfers, in
        both queued and non-queued modes.  (but I haven't made time
        to test this ... the hcds "should" be fine since they use the
        same code now for bulk and interrupt, and bulk checked out.)
    
      - teaches hid-core, usbkbd, and usbmouse how to resubmit
        interrupt transfers explicitly. usb keyboards/mice work,
        but some less-common HID devices won't.
    
      - updated usb/net drivers (catc, kaweth, pegasus, rtl8150)
    
    But it doesn't update all device drivers that use interrupt
    transfers.  The failure mode for un-converted drivers will
    be that interrupts after the first one get lost, and the
    fix for those drivers will be simple (see what the drivers
    here do).
    
    
    (*) It doesn't touch non-{E,O,U}HCI HCDs, like the SL-811HS,
         since those changes will require hardware as well as
         some quality time with 'usbtest'.
    e9c72b55
pegasus.c 28.8 KB