X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fnet%2Fusb%2Fcdc_ncm.c;h=74fab1a4015657b52bd5b4c690990120171dc509;hb=bbc8d9228ea8e37ce29fa96150d10b85a2c7be60;hp=4cd582a4f625d55d5edd8c2cd3952d5571074921;hpb=a54dfb1a845c38a97686268d8c4086a63d9493aa;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 4cd582a4f625..74fab1a40156 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -540,10 +540,12 @@ advance: (ctx->ether_desc == NULL) || (ctx->control != intf)) goto error; - /* claim interfaces, if any */ - temp = usb_driver_claim_interface(driver, ctx->data, dev); - if (temp) - goto error; + /* claim data interface, if different from control */ + if (ctx->data != ctx->control) { + temp = usb_driver_claim_interface(driver, ctx->data, dev); + if (temp) + goto error; + } iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; @@ -623,6 +625,10 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) tasklet_kill(&ctx->bh); + /* handle devices with combined control and data interface */ + if (ctx->control == ctx->data) + ctx->data = NULL; + /* disconnect master --> disconnect slave */ if (intf == ctx->control && ctx->data) { usb_set_intfdata(ctx->data, NULL); @@ -1245,6 +1251,14 @@ static const struct usb_device_id cdc_devs[] = { .driver_info = (unsigned long) &wwan_info, }, + /* Huawei NCM devices disguised as vendor specific */ + { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16), + .driver_info = (unsigned long)&wwan_info, + }, + { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), + .driver_info = (unsigned long)&wwan_info, + }, + /* Generic CDC-NCM devices */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),