diff options
Diffstat (limited to 'drivers/net/usb/cdc_ncm.c')
| -rw-r--r-- | drivers/net/usb/cdc_ncm.c | 22 | 
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 4cd582a4f62..74fab1a4015 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),  |