فهرست منبع

Revert "usb: core: Add "quirks" parameter for usbcore"

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,
Greg Kroah-Hartman 7 سال پیش
والد
کامیت
95713fb8aa
4فایلهای تغییر یافته به همراه5 افزوده شده و 229 حذف شده
  1. 0 55
      Documentation/admin-guide/kernel-parameters.txt
  2. 5 172
      drivers/usb/core/quirks.c
  3. 0 1
      drivers/usb/core/usb.c
  4. 0 1
      drivers/usb/core/usb.h

+ 0 - 55
Documentation/admin-guide/kernel-parameters.txt

@@ -4368,61 +4368,6 @@
 
 	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.
 

+ 5 - 172
drivers/usb/core/quirks.c

@@ -11,143 +11,6 @@
 #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);
-}

+ 0 - 1
drivers/usb/core/usb.c

@@ -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);

+ 0 - 1
drivers/usb/core/usb.h

@@ -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,