• Bjørn Mork's avatar
    cdc-wdm: fix "out-of-sync" due to missing notifications · 833415a3
    Bjørn Mork authored
    The driver enforces a strict one-to-one relationship between the
    received RESPONSE_AVAILABLE notifications and messages read from
    the device. At the same time, it will cancel the interrupt URB
    when there is no client holding the character device open.
    
    Many devices do not cope well with this behaviour.  They maintain
    a FIFO queue of messages, and send notifications on a best effort
    basis.  Messages are queued regardless of whether the notification
    is successful or not. So if the driver loses a single notification,
    which can easily happen when the interrupt URB is cancelled, then
    the device and driver becomes out-of-sync. New messages end up
    at the end of the queue, while the associated notification makes
    the driver read only the first message from the queue.
    
    This state is permanent from a user point of view. There is no
    no way to flush the device queue without resetting the device or
    using another driver.
    
    The problem is easy to hit with current QMI and MBIM command line
    tools, which typically close the character device after seeing
    the reply they expect. Any pending unsolicited messages from the
    device will then trigger the driver bug.
    
    Fix by always reading all queued messages from the device when
    the notification URB is first submitted.  This is expected to
    end with an -EPIPE status when there are no more pending
    messages, so demote the printk associated with -EPIPE to debug
    level.
    
    The workaround has been tested on a large number of different MBIM
    and QMI devices, as well as the Ericsson F5521gw and H5321gw modems
    with real Device Management functions.
    Signed-off-by: default avatarBjørn Mork <bjorn@mork.no>
    Acked-by: default avatarOliver Neukum <oneukum@suse.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    833415a3
cdc-wdm.c 29.5 KB