From 23fa18eaa71266feff7ba8d83022d9e1cc83c65a Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:42:03 +0000
Subject: [PATCH] disable pwm7
---
kernel/drivers/usb/core/generic.c | 113 +++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 75 insertions(+), 38 deletions(-)
diff --git a/kernel/drivers/usb/core/generic.c b/kernel/drivers/usb/core/generic.c
index 761073d..26f9fb9 100644
--- a/kernel/drivers/usb/core/generic.c
+++ b/kernel/drivers/usb/core/generic.c
@@ -21,6 +21,7 @@
#include <linux/usb.h>
#include <linux/usb/hcd.h>
+#include <uapi/linux/usb/audio.h>
#include "usb.h"
static inline const char *plural(int n)
@@ -42,34 +43,14 @@
&& desc->bInterfaceProtocol == 1;
}
-static int get_usb_audio_config(struct usb_host_bos *bos)
+static bool is_audio(struct usb_interface_descriptor *desc)
{
- unsigned int desc_cnt, num_cfg_desc, len = 0;
- unsigned char *buffer;
- struct usb_config_summary_descriptor *conf_summary;
+ return desc->bInterfaceClass == USB_CLASS_AUDIO;
+}
- if (!bos || !bos->config_summary)
- goto done;
-
- num_cfg_desc = bos->num_config_summary_desc;
- conf_summary = bos->config_summary;
- buffer = (unsigned char *)conf_summary;
- for (desc_cnt = 0; desc_cnt < num_cfg_desc; desc_cnt++) {
- conf_summary =
- (struct usb_config_summary_descriptor *)(buffer + len);
-
- len += conf_summary->bLength;
-
- if (conf_summary->bcdVersion != USB_CONFIG_SUMMARY_DESC_REV ||
- conf_summary->bClass != USB_CLASS_AUDIO)
- continue;
-
- /* return 1st config as per device preference */
- return conf_summary->bConfigurationIndex[0];
- }
-
-done:
- return -EINVAL;
+static bool is_uac3_config(struct usb_interface_descriptor *desc)
+{
+ return desc->bInterfaceProtocol == UAC_VERSION_3;
}
int usb_choose_configuration(struct usb_device *udev)
@@ -137,6 +118,31 @@
continue;
}
+ /*
+ * Select first configuration as default for audio so that
+ * devices that don't comply with UAC3 protocol are supported.
+ * But, still iterate through other configurations and
+ * select UAC3 compliant config if present.
+ */
+ if (desc && is_audio(desc)) {
+ /* Always prefer the first found UAC3 config */
+ if (is_uac3_config(desc)) {
+ best = c;
+ break;
+ }
+
+ /* If there is no UAC3 config, prefer the first config */
+ else if (i == 0)
+ best = c;
+
+ /* Unconditional continue, because the rest of the code
+ * in the loop is irrelevant for audio devices, and
+ * because it can reassign best, which for audio devices
+ * we don't want.
+ */
+ continue;
+ }
+
/* When the first config's first interface is one of Microsoft's
* pet nonstandard Ethernet-over-USB protocols, ignore it unless
* this kernel has enabled the necessary host side driver.
@@ -175,10 +181,7 @@
insufficient_power, plural(insufficient_power));
if (best) {
- /* choose device preferred config */
- i = get_usb_audio_config(udev->bos);
- if (i < 0)
- i = best->desc.bConfigurationValue;
+ i = best->desc.bConfigurationValue;
dev_dbg(&udev->dev,
"configuration #%d chosen from %d choice%s\n",
i, num_configs, plural(num_configs));
@@ -192,7 +195,35 @@
}
EXPORT_SYMBOL_GPL(usb_choose_configuration);
-static int generic_probe(struct usb_device *udev)
+static int __check_for_non_generic_match(struct device_driver *drv, void *data)
+{
+ struct usb_device *udev = data;
+ struct usb_device_driver *udrv;
+
+ if (!is_usb_device_driver(drv))
+ return 0;
+ udrv = to_usb_device_driver(drv);
+ if (udrv == &usb_generic_driver)
+ return 0;
+ return usb_driver_applicable(udev, udrv);
+}
+
+static bool usb_generic_driver_match(struct usb_device *udev)
+{
+ if (udev->use_generic_driver)
+ return true;
+
+ /*
+ * If any other driver wants the device, leave the device to this other
+ * driver.
+ */
+ if (bus_for_each_drv(&usb_bus_type, NULL, udev, __check_for_non_generic_match))
+ return false;
+
+ return true;
+}
+
+int usb_generic_driver_probe(struct usb_device *udev)
{
int err, c;
@@ -219,7 +250,7 @@
return 0;
}
-static void generic_disconnect(struct usb_device *udev)
+void usb_generic_driver_disconnect(struct usb_device *udev)
{
usb_notify_remove_device(udev);
@@ -231,7 +262,7 @@
#ifdef CONFIG_PM
-static int generic_suspend(struct usb_device *udev, pm_message_t msg)
+int usb_generic_driver_suspend(struct usb_device *udev, pm_message_t msg)
{
int rc;
@@ -254,10 +285,12 @@
else
rc = usb_port_suspend(udev, msg);
+ if (rc == 0)
+ usbfs_notify_suspend(udev);
return rc;
}
-static int generic_resume(struct usb_device *udev, pm_message_t msg)
+int usb_generic_driver_resume(struct usb_device *udev, pm_message_t msg)
{
int rc;
@@ -270,6 +303,9 @@
rc = hcd_bus_resume(udev, msg);
else
rc = usb_port_resume(udev, msg);
+
+ if (rc == 0)
+ usbfs_notify_resume(udev);
return rc;
}
@@ -277,11 +313,12 @@
struct usb_device_driver usb_generic_driver = {
.name = "usb",
- .probe = generic_probe,
- .disconnect = generic_disconnect,
+ .match = usb_generic_driver_match,
+ .probe = usb_generic_driver_probe,
+ .disconnect = usb_generic_driver_disconnect,
#ifdef CONFIG_PM
- .suspend = generic_suspend,
- .resume = generic_resume,
+ .suspend = usb_generic_driver_suspend,
+ .resume = usb_generic_driver_resume,
#endif
.supports_autosuspend = 1,
};
--
Gitblit v1.6.2