diff options
-rw-r--r-- | drivers/net/usb/qmi_wwan.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index e14479dd2438..aac68f5195c0 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -214,6 +214,20 @@ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) | |||
214 | struct usb_driver *subdriver = NULL; | 214 | struct usb_driver *subdriver = NULL; |
215 | atomic_t *pmcount = (void *)&dev->data[1]; | 215 | atomic_t *pmcount = (void *)&dev->data[1]; |
216 | 216 | ||
217 | /* ZTE makes devices where the interface descriptors and endpoint | ||
218 | * configurations of two or more interfaces are identical, even | ||
219 | * though the functions are completely different. If set, then | ||
220 | * driver_info->data is a bitmap of acceptable interface numbers | ||
221 | * allowing us to bind to one such interface without binding to | ||
222 | * all of them | ||
223 | */ | ||
224 | if (dev->driver_info->data && | ||
225 | !test_bit(intf->cur_altsetting->desc.bInterfaceNumber, &dev->driver_info->data)) { | ||
226 | dev_info(&intf->dev, "not on our whitelist - ignored"); | ||
227 | rv = -ENODEV; | ||
228 | goto err; | ||
229 | } | ||
230 | |||
217 | atomic_set(pmcount, 0); | 231 | atomic_set(pmcount, 0); |
218 | 232 | ||
219 | /* collect all three endpoints */ | 233 | /* collect all three endpoints */ |
@@ -341,6 +355,17 @@ static const struct driver_info qmi_wwan_gobi = { | |||
341 | .manage_power = qmi_wwan_manage_power, | 355 | .manage_power = qmi_wwan_manage_power, |
342 | }; | 356 | }; |
343 | 357 | ||
358 | /* ZTE suck at making USB descriptors */ | ||
359 | static const struct driver_info qmi_wwan_force_int4 = { | ||
360 | .description = "Qualcomm Gobi wwan/QMI device", | ||
361 | .flags = FLAG_WWAN, | ||
362 | .bind = qmi_wwan_bind_gobi, | ||
363 | .unbind = qmi_wwan_unbind_shared, | ||
364 | .manage_power = qmi_wwan_manage_power, | ||
365 | .data = BIT(4), /* interface whitelist bitmap */ | ||
366 | }; | ||
367 | |||
368 | |||
344 | #define HUAWEI_VENDOR_ID 0x12D1 | 369 | #define HUAWEI_VENDOR_ID 0x12D1 |
345 | #define QMI_GOBI_DEVICE(vend, prod) \ | 370 | #define QMI_GOBI_DEVICE(vend, prod) \ |
346 | USB_DEVICE(vend, prod), \ | 371 | USB_DEVICE(vend, prod), \ |
@@ -375,6 +400,15 @@ static const struct usb_device_id products[] = { | |||
375 | .bInterfaceProtocol = 0xff, | 400 | .bInterfaceProtocol = 0xff, |
376 | .driver_info = (unsigned long)&qmi_wwan_shared, | 401 | .driver_info = (unsigned long)&qmi_wwan_shared, |
377 | }, | 402 | }, |
403 | { /* ZTE MF820D */ | ||
404 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
405 | .idVendor = 0x19d2, | ||
406 | .idProduct = 0x0167, | ||
407 | .bInterfaceClass = 0xff, | ||
408 | .bInterfaceSubClass = 0xff, | ||
409 | .bInterfaceProtocol = 0xff, | ||
410 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
411 | }, | ||
378 | {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 412 | {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
379 | {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 413 | {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
380 | {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | 414 | {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ |