summaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/cdc_ether.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/cdc_ether.c')
-rw-r--r--drivers/net/usb/cdc_ether.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 04ee044dde51..03ad4dc293aa 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -215,6 +215,10 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
goto bad_desc;
}
+ /* some devices merge these - skip class check */
+ if (info->control == info->data)
+ goto next_desc;
+
/* a data interface altsetting does the real i/o */
d = &info->data->cur_altsetting->desc;
if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
@@ -304,19 +308,23 @@ next_desc:
/* claim data interface and set it up ... with side effects.
* network traffic can't flow until an altsetting is enabled.
*/
- status = usb_driver_claim_interface(driver, info->data, dev);
- if (status < 0)
- return status;
+ if (info->data != info->control) {
+ status = usb_driver_claim_interface(driver, info->data, dev);
+ if (status < 0)
+ return status;
+ }
status = usbnet_get_endpoints(dev, info->data);
if (status < 0) {
/* ensure immediate exit from usbnet_disconnect */
usb_set_intfdata(info->data, NULL);
- usb_driver_release_interface(driver, info->data);
+ if (info->data != info->control)
+ usb_driver_release_interface(driver, info->data);
return status;
}
/* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */
- dev->status = NULL;
+ if (info->data != info->control)
+ dev->status = NULL;
if (info->control->cur_altsetting->desc.bNumEndpoints == 1) {
struct usb_endpoint_descriptor *desc;
@@ -349,6 +357,10 @@ void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
struct cdc_state *info = (void *) &dev->data;
struct usb_driver *driver = driver_of(intf);
+ /* combined interface - nothing to do */
+ if (info->data == info->control)
+ return;
+
/* disconnect master --> disconnect slave */
if (intf == info->control && info->data) {
/* ensure immediate exit from usbnet_disconnect */
@@ -634,13 +646,18 @@ static const struct usb_device_id products [] = {
},
/* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */
-#if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE)
{
USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM,
USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
.driver_info = 0,
},
-#endif
+
+/* Realtek RTL8153 Based USB 3.0 Ethernet Adapters */
+{
+ USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+ .driver_info = 0,
+},
/*
* WHITELIST!!!