1. 13 6月, 2018 2 次提交
    • K
      treewide: kzalloc() -> kcalloc() · 6396bb22
      Kees Cook 提交于
      The kzalloc() function has a 2-factor argument form, kcalloc(). This
      patch replaces cases of:
      
              kzalloc(a * b, gfp)
      
      with:
              kcalloc(a * b, gfp)
      
      as well as handling cases of:
      
              kzalloc(a * b * c, gfp)
      
      with:
      
              kzalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kzalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kzalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kzalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kzalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kzalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kzalloc
      + kcalloc
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kzalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(sizeof(THING) * C2, ...)
      |
        kzalloc(sizeof(TYPE) * C2, ...)
      |
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(C1 * C2, ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      6396bb22
    • K
      treewide: kmalloc() -> kmalloc_array() · 6da2ec56
      Kees Cook 提交于
      The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
      patch replaces cases of:
      
              kmalloc(a * b, gfp)
      
      with:
              kmalloc_array(a * b, gfp)
      
      as well as handling cases of:
      
              kmalloc(a * b * c, gfp)
      
      with:
      
              kmalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kmalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kmalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The tools/ directory was manually excluded, since it has its own
      implementation of kmalloc().
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kmalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kmalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kmalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kmalloc
      + kmalloc_array
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kmalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kmalloc(sizeof(THING) * C2, ...)
      |
        kmalloc(sizeof(TYPE) * C2, ...)
      |
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(C1 * C2, ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      6da2ec56
  2. 31 5月, 2018 5 次提交
    • G
      USB: core: no need to check return value of debugfs_create functions · b708692d
      Greg Kroah-Hartman 提交于
      When calling debugfs functions, there is no need to ever check the
      return value.  The function can work or not, but the code logic should
      never do something different based on this.
      
      Cc: Johan Hovold <johan@kernel.org>
      Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
      Cc: Peter Chen <peter.chen@nxp.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      b708692d
    • N
      usb: hub: Per-port setting to reduce TRSTRCY to 10 ms · aa071a92
      Nicolas Boichat 提交于
      Currently, the USB hub core waits for 50 ms after enumerating the
      device. This was added to help "some high speed devices" to
      enumerate (b789696a "[PATCH] USB: relax usbcore reset timings").
      
      On some devices, the time-to-active is important, so we provide
      a per-port option to reduce the time to what the USB specification
      requires: 10 ms.
      Signed-off-by: NNicolas Boichat <drinkcat@chromium.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      aa071a92
    • N
      usb: hub: Per-port setting to use old enumeration scheme · 25244227
      Nicolas Boichat 提交于
      The "old" enumeration scheme is considerably faster (it takes
      ~244ms instead of ~356ms to get the descriptor).
      
      It is currently only possible to use the old scheme globally
      (/sys/module/usbcore/parameters/old_scheme_first), which is not
      desirable as the new scheme was introduced to increase compatibility
      with more devices.
      
      However, in our case, we care about time-to-active for a specific
      USB device (which we make the firmware for), on a specific port
      (that is pogo-pin based: not a standard USB port). This new
      sysfs option makes it possible to use the old scheme on a single
      port only.
      Signed-off-by: NNicolas Boichat <drinkcat@chromium.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      25244227
    • R
      usb: core: message: remove extra endianness conversion in usb_set_isoch_delay · 48b73d0f
      Ruslan Bilovol 提交于
      No need to do extra endianness conversion in
      usb_set_isoch_delay because it is already done
      in usb_control_msg()
      
      Fixes: 886ee36e ("usb: core: add support for USB_REQ_SET_ISOCH_DELAY")
      Cc: Dmytro Panchenko <dmytro.panchenko@globallogic.com>
      Cc: Felipe Balbi <felipe.balbi@linux.intel.com>
      Cc: stable <stable@vger.kernel.org> # v4.16+
      Signed-off-by: NRuslan Bilovol <ruslan.bilovol@gmail.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      48b73d0f
    • M
      driver core: hold dev's parent lock when needed · 8c97a46a
      Martin Liu 提交于
      SoC have internal I/O buses that can't be proved for devices. The
      devices on the buses can be accessed directly without additinal
      configuration required. This type of bus is represented as
      "simple-bus". In some platforms, we name "soc" with "simple-bus"
      attribute and many devices are hooked under it described in DT
      (device tree).
      
      In commit bf74ad5b ("Hold the device's parent's lock during
      probe and remove") to solve USB subsystem lock sequence since
      USB device's characteristic. Thus "soc" needs to be locked
      whenever a device and driver's probing happen under "soc" bus.
      During this period, an async driver tries to probe a device which
      is under the "soc" bus would be blocked until previous driver
      finish the probing and release "soc" lock. And the next probing
      under the "soc" bus need to wait for async finish. Because of
      that, driver's async probe for init time improvement will be
      shadowed.
      
      Since many devices don't have USB devices' characteristic, they
      actually don't need parent's lock. Thus, we introduce a lock flag
      in bus_type struct and driver core would lock the parent lock base
      on the flag. For USB, we set this flag in usb_bus_type to keep
      original lock behavior in driver core.
      
      Async probe could have more benefit after this patch.
      Signed-off-by: NMartin Liu <liumartin@google.com>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      8c97a46a
  3. 04 5月, 2018 1 次提交
    • A
      USB: Accept bulk endpoints with 1024-byte maxpacket · fb5ee84e
      Alan Stern 提交于
      Some non-compliant high-speed USB devices have bulk endpoints with a
      1024-byte maxpacket size.  Although such endpoints don't work with
      xHCI host controllers, they do work with EHCI controllers.  We used to
      accept these invalid sizes (with a warning), but we no longer do
      because of an unintentional change introduced by commit aed9d65a
      ("USB: validate wMaxPacketValue entries in endpoint descriptors").
      
      This patch restores the old behavior, so that people with these
      peculiar devices can use them without patching their kernels by hand.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      Suggested-by: NElvinas <elvinas@veikia.lt>
      Fixes: aed9d65a ("USB: validate wMaxPacketValue entries in endpoint descriptors")
      CC: <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      fb5ee84e
  4. 25 4月, 2018 1 次提交
  5. 23 4月, 2018 2 次提交
  6. 22 4月, 2018 14 次提交
  7. 25 3月, 2018 3 次提交
  8. 23 3月, 2018 2 次提交
    • Z
      USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw · 64627388
      Zhengjun Xing 提交于
      USB3 hubs don't support global suspend.
      
      USB3 specification 10.10, Enhanced SuperSpeed hubs only support selective
      suspend and resume, they do not support global suspend/resume where the
      hub downstream facing ports states are not affected.
      
      When system enters hibernation it first enters freeze process where only
      the root hub enters suspend, usb_port_suspend() is not called for other
      devices, and suspend status flags are not set for them. Other devices are
      expected to suspend globally. Some external USB3 hubs will suspend the
      downstream facing port at global suspend. These devices won't be resumed
      at thaw as the suspend status flag is not set.
      
      A USB3 removable hard disk connected through a USB3 hub that won't resume
      at thaw will fail to synchronize SCSI cache, return “cmd cmplt err -71”
      error, and needs a 60 seconds timeout which causing system hang for 60s
      before the USB host reset the port for the USB3 removable hard disk to
      recover.
      
      Fix this by always calling usb_port_suspend() during freeze for USB3
      devices.
      Signed-off-by: NZhengjun Xing <zhengjun.xing@linux.intel.com>
      Cc: stable <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      64627388
    • T
      usb: hub: Reduce warning to notice on power loss · 0442d7b0
      Tomeu Vizoso 提交于
      Currently we warn the user when the root hub lost power after resume,
      but the user cannot do anything about it so it should probably be a
      notice.
      
      This will reduce the noise in the console during suspend and resume,
      which is already quite significant in many systems.
      Signed-off-by: NTomeu Vizoso <tomeu.vizoso@collabora.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      0442d7b0
  9. 22 3月, 2018 2 次提交
  10. 20 3月, 2018 2 次提交
  11. 12 3月, 2018 1 次提交
    • G
      Revert "usb: core: Add "quirks" parameter for usbcore" · 95713fb8
      Greg Kroah-Hartman 提交于
      This reverts commit b27560e4 as it
      breaks the build for some arches :(
      Reported-by: Nkbuild test robot <fengguang.wu@intel.com>
      Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      
      diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
      index 1d1d53f85ddd..70a7398c20e2 100644
      --- a/Documentation/admin-guide/kernel-parameters.txt
      +++ b/Documentation/admin-guide/kernel-parameters.txt
      @@ -4368,6 +4368,61 @@
      
       	usbcore.nousb	[USB] Disable the USB subsystem
      
      +	usbcore.quirks=
      +			[USB] A list of quirks entries to supplement or
      +			override the built-in usb core quirk list.  List
      +			entries are separated by commas.  Each entry has
      +			the form VID:PID:Flags where VID and PID are Vendor
      +			and Product ID values (4-digit hex numbers) and
      +			Flags is a set of characters, each corresponding
      +			to a common usb core quirk flag as follows:
      +				a = USB_QUIRK_STRING_FETCH_255 (string
      +					descriptors must not be fetched using
      +					a 255-byte read);
      +				b = USB_QUIRK_RESET_RESUME (device can't resume
      +					correctly so reset it instead);
      +				c = USB_QUIRK_NO_SET_INTF (device can't handle
      +					Set-Interface requests);
      +				d = USB_QUIRK_CONFIG_INTF_STRINGS (device can't
      +					handle its Configuration or Interface
      +					strings);
      +				e = USB_QUIRK_RESET (device can't be reset
      +					(e.g morph devices), don't use reset);
      +				f = USB_QUIRK_HONOR_BNUMINTERFACES (device has
      +					more interface descriptions than the
      +					bNumInterfaces count, and can't handle
      +					talking to these interfaces);
      +				g = USB_QUIRK_DELAY_INIT (device needs a pause
      +					during initialization, after we read
      +					the device descriptor);
      +				h = USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL (For
      +					high speed and super speed interrupt
      +					endpoints, the USB 2.0 and USB 3.0 spec
      +					require the interval in microframes (1
      +					microframe = 125 microseconds) to be
      +					calculated as interval = 2 ^
      +					(bInterval-1).
      +					Devices with this quirk report their
      +					bInterval as the result of this
      +					calculation instead of the exponent
      +					variable used in the calculation);
      +				i = USB_QUIRK_DEVICE_QUALIFIER (device can't
      +					handle device_qualifier descriptor
      +					requests);
      +				j = USB_QUIRK_IGNORE_REMOTE_WAKEUP (device
      +					generates spurious wakeup, ignore
      +					remote wakeup capability);
      +				k = USB_QUIRK_NO_LPM (device can't handle Link
      +					Power Management);
      +				l = USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL
      +					(Device reports its bInterval as linear
      +					frames instead of the USB 2.0
      +					calculation);
      +				m = USB_QUIRK_DISCONNECT_SUSPEND (Device needs
      +					to be disconnected before suspend to
      +					prevent spurious wakeup)
      +			Example: quirks=0781:5580:bk,0a5c:5834:gij
      +
       	usbhid.mousepoll=
       			[USBHID] The interval which mice are to be polled at.
      
      diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
      index f4a548471f0f..42faaeead81b 100644
      --- a/drivers/usb/core/quirks.c
      +++ b/drivers/usb/core/quirks.c
      @@ -11,6 +11,143 @@
       #include <linux/usb/hcd.h>
       #include "usb.h"
      
      +struct quirk_entry {
      +	u16 vid;
      +	u16 pid;
      +	u32 flags;
      +};
      +
      +static DEFINE_MUTEX(quirk_mutex);
      +
      +static struct quirk_entry *quirk_list;
      +static unsigned int quirk_count;
      +
      +static char quirks_param[128];
      +
      +static int quirks_param_set(const char *val, const struct kernel_param *kp)
      +{
      +	char *p, *field;
      +	u16 vid, pid;
      +	u32 flags;
      +	size_t i;
      +
      +	mutex_lock(&quirk_mutex);
      +
      +	if (!val || !*val) {
      +		quirk_count = 0;
      +		kfree(quirk_list);
      +		quirk_list = NULL;
      +		goto unlock;
      +	}
      +
      +	for (quirk_count = 1, i = 0; val[i]; i++)
      +		if (val[i] == ',')
      +			quirk_count++;
      +
      +	if (quirk_list) {
      +		kfree(quirk_list);
      +		quirk_list = NULL;
      +	}
      +
      +	quirk_list = kcalloc(quirk_count, sizeof(struct quirk_entry),
      +			     GFP_KERNEL);
      +	if (!quirk_list) {
      +		mutex_unlock(&quirk_mutex);
      +		return -ENOMEM;
      +	}
      +
      +	for (i = 0, p = (char *)val; p && *p;) {
      +		/* Each entry consists of VID:PID:flags */
      +		field = strsep(&p, ":");
      +		if (!field)
      +			break;
      +
      +		if (kstrtou16(field, 16, &vid))
      +			break;
      +
      +		field = strsep(&p, ":");
      +		if (!field)
      +			break;
      +
      +		if (kstrtou16(field, 16, &pid))
      +			break;
      +
      +		field = strsep(&p, ",");
      +		if (!field || !*field)
      +			break;
      +
      +		/* Collect the flags */
      +		for (flags = 0; *field; field++) {
      +			switch (*field) {
      +			case 'a':
      +				flags |= USB_QUIRK_STRING_FETCH_255;
      +				break;
      +			case 'b':
      +				flags |= USB_QUIRK_RESET_RESUME;
      +				break;
      +			case 'c':
      +				flags |= USB_QUIRK_NO_SET_INTF;
      +				break;
      +			case 'd':
      +				flags |= USB_QUIRK_CONFIG_INTF_STRINGS;
      +				break;
      +			case 'e':
      +				flags |= USB_QUIRK_RESET;
      +				break;
      +			case 'f':
      +				flags |= USB_QUIRK_HONOR_BNUMINTERFACES;
      +				break;
      +			case 'g':
      +				flags |= USB_QUIRK_DELAY_INIT;
      +				break;
      +			case 'h':
      +				flags |= USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL;
      +				break;
      +			case 'i':
      +				flags |= USB_QUIRK_DEVICE_QUALIFIER;
      +				break;
      +			case 'j':
      +				flags |= USB_QUIRK_IGNORE_REMOTE_WAKEUP;
      +				break;
      +			case 'k':
      +				flags |= USB_QUIRK_NO_LPM;
      +				break;
      +			case 'l':
      +				flags |= USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL;
      +				break;
      +			case 'm':
      +				flags |= USB_QUIRK_DISCONNECT_SUSPEND;
      +				break;
      +			/* Ignore unrecognized flag characters */
      +			}
      +		}
      +
      +		quirk_list[i++] = (struct quirk_entry)
      +			{ .vid = vid, .pid = pid, .flags = flags };
      +	}
      +
      +	if (i < quirk_count)
      +		quirk_count = i;
      +
      +unlock:
      +	mutex_unlock(&quirk_mutex);
      +
      +	return param_set_copystring(val, kp);
      +}
      +
      +static const struct kernel_param_ops quirks_param_ops = {
      +	.set = quirks_param_set,
      +	.get = param_get_string,
      +};
      +
      +static struct kparam_string quirks_param_string = {
      +	.maxlen = sizeof(quirks_param),
      +	.string = quirks_param,
      +};
      +
      +module_param_cb(quirks, &quirks_param_ops, &quirks_param_string, 0644);
      +MODULE_PARM_DESC(quirks, "Add/modify USB quirks by specifying quirks=vendorID:productID:quirks");
      +
       /* Lists of quirky USB devices, split in device quirks and interface quirks.
        * Device quirks are applied at the very beginning of the enumeration process,
        * right after reading the device descriptor. They can thus only match on device
      @@ -320,8 +457,8 @@ static int usb_amd_resume_quirk(struct usb_device *udev)
       	return 0;
       }
      
      -static u32 __usb_detect_quirks(struct usb_device *udev,
      -			       const struct usb_device_id *id)
      +static u32 usb_detect_static_quirks(struct usb_device *udev,
      +				    const struct usb_device_id *id)
       {
       	u32 quirks = 0;
      
      @@ -339,21 +476,43 @@ static u32 __usb_detect_quirks(struct usb_device *udev,
       	return quirks;
       }
      
      +static u32 usb_detect_dynamic_quirks(struct usb_device *udev)
      +{
      +	u16 vid = le16_to_cpu(udev->descriptor.idVendor);
      +	u16 pid = le16_to_cpu(udev->descriptor.idProduct);
      +	int i, flags = 0;
      +
      +	mutex_lock(&quirk_mutex);
      +
      +	for (i = 0; i < quirk_count; i++) {
      +		if (vid == quirk_list[i].vid && pid == quirk_list[i].pid) {
      +			flags = quirk_list[i].flags;
      +			break;
      +		}
      +	}
      +
      +	mutex_unlock(&quirk_mutex);
      +
      +	return flags;
      +}
      +
       /*
        * Detect any quirks the device has, and do any housekeeping for it if needed.
        */
       void usb_detect_quirks(struct usb_device *udev)
       {
      -	udev->quirks = __usb_detect_quirks(udev, usb_quirk_list);
      +	udev->quirks = usb_detect_static_quirks(udev, usb_quirk_list);
      
       	/*
       	 * Pixart-based mice would trigger remote wakeup issue on AMD
       	 * Yangtze chipset, so set them as RESET_RESUME flag.
       	 */
       	if (usb_amd_resume_quirk(udev))
      -		udev->quirks |= __usb_detect_quirks(udev,
      +		udev->quirks |= usb_detect_static_quirks(udev,
       				usb_amd_resume_quirk_list);
      
      +	udev->quirks ^= usb_detect_dynamic_quirks(udev);
      +
       	if (udev->quirks)
       		dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
       			udev->quirks);
      @@ -372,7 +531,7 @@ void usb_detect_interface_quirks(struct usb_device *udev)
       {
       	u32 quirks;
      
      -	quirks = __usb_detect_quirks(udev, usb_interface_quirk_list);
      +	quirks = usb_detect_static_quirks(udev, usb_interface_quirk_list);
       	if (quirks == 0)
       		return;
      
      @@ -380,3 +539,11 @@ void usb_detect_interface_quirks(struct usb_device *udev)
       		quirks);
       	udev->quirks |= quirks;
       }
      +
      +void usb_release_quirk_list(void)
      +{
      +	mutex_lock(&quirk_mutex);
      +	kfree(quirk_list);
      +	quirk_list = NULL;
      +	mutex_unlock(&quirk_mutex);
      +}
      diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
      index 2f5fbc56a9dd..0adb6345ff2e 100644
      --- a/drivers/usb/core/usb.c
      +++ b/drivers/usb/core/usb.c
      @@ -1259,6 +1259,7 @@ static void __exit usb_exit(void)
       	if (usb_disabled())
       		return;
      
      +	usb_release_quirk_list();
       	usb_deregister_device_driver(&usb_generic_driver);
       	usb_major_cleanup();
       	usb_deregister(&usbfs_driver);
      diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
      index 149cc7480971..546a2219454b 100644
      --- a/drivers/usb/core/usb.h
      +++ b/drivers/usb/core/usb.h
      @@ -36,6 +36,7 @@ extern void usb_deauthorize_interface(struct usb_interface *);
       extern void usb_authorize_interface(struct usb_interface *);
       extern void usb_detect_quirks(struct usb_device *udev);
       extern void usb_detect_interface_quirks(struct usb_device *udev);
      +extern void usb_release_quirk_list(void);
       extern int usb_remove_device(struct usb_device *udev);
      
       extern int usb_get_device_descriptor(struct usb_device *dev,
      95713fb8
  12. 10 3月, 2018 5 次提交