• Jack Pham's avatar
    usb: gadget: composite: Support more than 500mA MaxPower · a2035411
    Jack Pham authored
    USB 3.x SuperSpeed peripherals can draw up to 900mA of VBUS power
    when in configured state. However, if a configuration wanting to
    take advantage of this is added with MaxPower greater than 500
    (currently possible if using a ConfigFS gadget) the composite
    driver fails to accommodate this for a couple reasons:
    
     - usb_gadget_vbus_draw() when called from set_config() and
       composite_resume() will be passed the MaxPower value without
       regard for the current connection speed, resulting in a
       violation for USB 2.0 since the max is 500mA.
    
     - the bMaxPower of the configuration descriptor would be
       incorrectly encoded, again if the connection speed is only
       at USB 2.0 or below, likely wrapping around U8_MAX since
       the 2mA multiplier corresponds to a maximum of 510mA.
    
    Fix these by adding checks against the current gadget->speed
    when the c->MaxPower value is used (set_config() and
    composite_resume()) and appropriately limit based on whether
    it is currently at a low-/full-/high- or super-speed connection.
    
    Because 900 is not divisible by 8, with the round-up division
    currently used in encode_bMaxPower() a MaxPower of 900mA will
    result in an encoded value of 0x71. When a host stack (including
    Linux and Windows) enumerates this on a single port root hub, it
    reads this value back and decodes (multiplies by 8) to get 904mA
    which is strictly greater than 900mA that is typically budgeted
    for that port, causing it to reject the configuration. Instead,
    we should be using the round-down behavior of normal integral
    division so that 900 / 8 -> 0x70 or 896mA to stay within range.
    And we might as well change it for the high/full/low case as well
    for consistency.
    
    N.B. USB 3.2 Gen N x 2 allows for up to 1500mA but there doesn't
    seem to be any any peripheral controller supported by Linux that
    does two lane operation, so for now keeping the clamp at 900
    should be fine.
    Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
    Signed-off-by: default avatarFelipe Balbi <balbi@kernel.org>
    a2035411
composite.c 64.7 KB