aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorHayes Wang2021-04-16 16:04:37 +0800
committerDavid S. Miller2021-04-16 15:28:31 -0700
commitc2198943e33b100ed21dfb636c8fa6baef841e9d (patch)
tree2b9606d884cda82119aa36be187b5507217dd158 /drivers/net/usb
parent4a51b0e8a0143b0e83d51d9c58c6416c3818a9f2 (diff)
r8152: search the configuration of vendor mode
The vendor mode is not always at config #1, so it is necessary to set the correct configuration number. Signed-off-by: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r--drivers/net/usb/r8152.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 34c1ee61af01..9119a860e9bd 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -29,7 +29,7 @@
#include <linux/usb/r8152.h>
/* Information for net-next */
-#define NETNEXT_VERSION "11"
+#define NETNEXT_VERSION "12"
/* Information for net */
#define NET_VERSION "11"
@@ -8107,6 +8107,39 @@ static void r8156b_init(struct r8152 *tp)
tp->coalesce = 15000; /* 15 us */
}
+static bool rtl_vendor_mode(struct usb_interface *intf)
+{
+ struct usb_host_interface *alt = intf->cur_altsetting;
+ struct usb_device *udev;
+ struct usb_host_config *c;
+ int i, num_configs;
+
+ if (alt->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC)
+ return true;
+
+ /* The vendor mode is not always config #1, so to find it out. */
+ udev = interface_to_usbdev(intf);
+ c = udev->config;
+ num_configs = udev->descriptor.bNumConfigurations;
+ for (i = 0; i < num_configs; (i++, c++)) {
+ struct usb_interface_descriptor *desc = NULL;
+
+ if (c->desc.bNumInterfaces > 0)
+ desc = &c->intf_cache[0]->altsetting->desc;
+ else
+ continue;
+
+ if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
+ usb_driver_set_configuration(udev, c->desc.bConfigurationValue);
+ break;
+ }
+ }
+
+ WARN_ON_ONCE(i == num_configs);
+
+ return false;
+}
+
static int rtl8152_pre_reset(struct usb_interface *intf)
{
struct r8152 *tp = usb_get_intfdata(intf);
@@ -9345,10 +9378,8 @@ static int rtl8152_probe(struct usb_interface *intf,
if (version == RTL_VER_UNKNOWN)
return -ENODEV;
- if (udev->actconfig->desc.bConfigurationValue != 1) {
- usb_driver_set_configuration(udev, 1);
+ if (!rtl_vendor_mode(intf))
return -ENODEV;
- }
if (intf->cur_altsetting->desc.bNumEndpoints < 3)
return -ENODEV;