Revert "usb: core: Add "quirks" parameter for usbcore"
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Mar 2018 15:30:40 +0000 (16:30 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Mar 2018 15:30:40 +0000 (16:30 +0100)
This reverts commit b27560e4d9e5240b5544c9c5650c7442e482646e as it
breaks the build for some arches :(

Reported-by: kbuild test robot <fengguang.wu@intel.com>
Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: Greg 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,

Documentation/admin-guide/kernel-parameters.txt
drivers/usb/core/quirks.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h

index 70a7398c20e25b8fa5b44d691843ad95f09010ef..1d1d53f85ddd79ce2218b7274b3114f41493ac3a 100644 (file)
 
        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.
 
index 42faaeead81bffbc70e4089cd97ff09c7f9444e5..f4a548471f0fabb09ed78688cad39e0e085a3ca9 100644 (file)
 #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
@@ -457,8 +320,8 @@ static int usb_amd_resume_quirk(struct usb_device *udev)
        return 0;
 }
 
-static u32 usb_detect_static_quirks(struct usb_device *udev,
-                                   const struct usb_device_id *id)
+static u32 __usb_detect_quirks(struct usb_device *udev,
+                              const struct usb_device_id *id)
 {
        u32 quirks = 0;
 
@@ -476,43 +339,21 @@ static u32 usb_detect_static_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_static_quirks(udev, usb_quirk_list);
+       udev->quirks = __usb_detect_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_static_quirks(udev,
+               udev->quirks |= __usb_detect_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);
@@ -531,7 +372,7 @@ void usb_detect_interface_quirks(struct usb_device *udev)
 {
        u32 quirks;
 
-       quirks = usb_detect_static_quirks(udev, usb_interface_quirk_list);
+       quirks = __usb_detect_quirks(udev, usb_interface_quirk_list);
        if (quirks == 0)
                return;
 
@@ -539,11 +380,3 @@ 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);
-}
index 0adb6345ff2e49d9f8cc13193a1a482827b97fcc..2f5fbc56a9ddcb75c897627ff9c36f2fe75917dd 100644 (file)
@@ -1259,7 +1259,6 @@ 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);
index 546a2219454b2de9bbf7e72f07dc1ae3f3602b60..149cc74809712faef1d9f8b4c17e4e91126ebb28 100644 (file)
@@ -36,7 +36,6 @@ 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,