diff options
author | Hayes Wang <hayeswang@realtek.com> | 2021-04-16 11:04:37 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-04-17 01:28:31 +0300 |
commit | c2198943e33b100ed21dfb636c8fa6baef841e9d (patch) | |
tree | 2b9606d884cda82119aa36be187b5507217dd158 /drivers/net/usb/r8152.c | |
parent | 4a51b0e8a0143b0e83d51d9c58c6416c3818a9f2 (diff) | |
download | linux-c2198943e33b100ed21dfb636c8fa6baef841e9d.tar.xz |
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/r8152.c')
-rw-r--r-- | drivers/net/usb/r8152.c | 39 |
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; |