Commit b9f90eb2740203ff2592efe640409ad48335d1c2

Authored by Bjørn Mork
Committed by David S. Miller
1 parent 4e42200caf

net: qmi_wwan: fix Gobi device probing

Ignoring interfaces with additional descriptors is not a reliable
method for locating the correct interface on Gobi devices.  There
is at least one device where this method fails:
https://bbs.archlinux.org/viewtopic.php?id=143506

The result is that the AT command port (interface #2) is hidden
from qcserial, preventing traditional serial modem usage:

[   15.562552] qmi_wwan 4-1.6:1.0: cdc-wdm0: USB WDM device
[   15.562691] qmi_wwan 4-1.6:1.0: wwan0: register 'qmi_wwan' at usb-0000:00:1d.0-1.6, Qualcomm Gobi wwan/QMI device, 1e:df:3c:3a:4e:3b
[   15.563383] qmi_wwan: probe of 4-1.6:1.1 failed with error -22
[   15.564189] qmi_wwan 4-1.6:1.2: cdc-wdm1: USB WDM device
[   15.564302] qmi_wwan 4-1.6:1.2: wwan1: register 'qmi_wwan' at usb-0000:00:1d.0-1.6, Qualcomm Gobi wwan/QMI device, 1e:df:3c:3a:4e:3b
[   15.564328] qmi_wwan: probe of 4-1.6:1.3 failed with error -22
[   15.569376] qcserial 4-1.6:1.1: Qualcomm USB modem converter detected
[   15.569440] usb 4-1.6: Qualcomm USB modem converter now attached to ttyUSB0
[   15.570372] qcserial 4-1.6:1.3: Qualcomm USB modem converter detected
[   15.570430] usb 4-1.6: Qualcomm USB modem converter now attached to ttyUSB1

Use static interface numbers taken from the interface map in
qcserial for all Gobi devices instead:

	Gobi 1K USB layout:
	0: serial port (doesn't respond)
	1: serial port (doesn't respond)
	2: AT-capable modem port
	3: QMI/net

	Gobi 2K+ USB layout:
	0: QMI/net
	1: DM/DIAG (use libqcdm from ModemManager for communication)
	2: AT-capable modem port
	3: NMEA

This should be more reliable over all, and will also prevent the
noisy "probe failed" messages.  The whitelisting logic is expected
to be replaced by direct interface number matching in 3.6.

Reported-by: Heinrich Siebmanns (Harvey) <H.Siebmanns@t-online.de>
Cc: <stable@vger.kernel.org> # v3.4: 0000188 USB: qmi_wwan: Make forced int 4 whitelist generic
Cc: <stable@vger.kernel.org> # v3.4: f7142e6 USB: qmi_wwan: Add ZTE (Vodafone) K3520-Z
Cc: <stable@vger.kernel.org> # v3.4
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 40 additions and 43 deletions Side-by-side Diff

drivers/net/usb/qmi_wwan.c
... ... @@ -257,29 +257,6 @@
257 257 return rv;
258 258 }
259 259  
260   -/* Gobi devices uses identical class/protocol codes for all interfaces regardless
261   - * of function. Some of these are CDC ACM like and have the exact same endpoints
262   - * we are looking for. This leaves two possible strategies for identifying the
263   - * correct interface:
264   - * a) hardcoding interface number, or
265   - * b) use the fact that the wwan interface is the only one lacking additional
266   - * (CDC functional) descriptors
267   - *
268   - * Let's see if we can get away with the generic b) solution.
269   - */
270   -static int qmi_wwan_bind_gobi(struct usbnet *dev, struct usb_interface *intf)
271   -{
272   - int rv = -EINVAL;
273   -
274   - /* ignore any interface with additional descriptors */
275   - if (intf->cur_altsetting->extralen)
276   - goto err;
277   -
278   - rv = qmi_wwan_bind_shared(dev, intf);
279   -err:
280   - return rv;
281   -}
282   -
283 260 static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf)
284 261 {
285 262 struct usb_driver *subdriver = (void *)dev->data[0];
286 263  
287 264  
288 265  
... ... @@ -347,15 +324,15 @@
347 324 .manage_power = qmi_wwan_manage_power,
348 325 };
349 326  
350   -static const struct driver_info qmi_wwan_gobi = {
351   - .description = "Qualcomm Gobi wwan/QMI device",
  327 +static const struct driver_info qmi_wwan_force_int0 = {
  328 + .description = "Qualcomm WWAN/QMI device",
352 329 .flags = FLAG_WWAN,
353   - .bind = qmi_wwan_bind_gobi,
  330 + .bind = qmi_wwan_bind_shared,
354 331 .unbind = qmi_wwan_unbind_shared,
355 332 .manage_power = qmi_wwan_manage_power,
  333 + .data = BIT(0), /* interface whitelist bitmap */
356 334 };
357 335  
358   -/* ZTE suck at making USB descriptors */
359 336 static const struct driver_info qmi_wwan_force_int1 = {
360 337 .description = "Qualcomm WWAN/QMI device",
361 338 .flags = FLAG_WWAN,
... ... @@ -365,6 +342,15 @@
365 342 .data = BIT(1), /* interface whitelist bitmap */
366 343 };
367 344  
  345 +static const struct driver_info qmi_wwan_force_int3 = {
  346 + .description = "Qualcomm WWAN/QMI device",
  347 + .flags = FLAG_WWAN,
  348 + .bind = qmi_wwan_bind_shared,
  349 + .unbind = qmi_wwan_unbind_shared,
  350 + .manage_power = qmi_wwan_manage_power,
  351 + .data = BIT(3), /* interface whitelist bitmap */
  352 +};
  353 +
368 354 static const struct driver_info qmi_wwan_force_int4 = {
369 355 .description = "Qualcomm WWAN/QMI device",
370 356 .flags = FLAG_WWAN,
371 357  
372 358  
... ... @@ -390,16 +376,23 @@
390 376 static const struct driver_info qmi_wwan_sierra = {
391 377 .description = "Sierra Wireless wwan/QMI device",
392 378 .flags = FLAG_WWAN,
393   - .bind = qmi_wwan_bind_gobi,
  379 + .bind = qmi_wwan_bind_shared,
394 380 .unbind = qmi_wwan_unbind_shared,
395 381 .manage_power = qmi_wwan_manage_power,
396 382 .data = BIT(8) | BIT(19), /* interface whitelist bitmap */
397 383 };
398 384  
399 385 #define HUAWEI_VENDOR_ID 0x12D1
  386 +
  387 +/* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */
  388 +#define QMI_GOBI1K_DEVICE(vend, prod) \
  389 + USB_DEVICE(vend, prod), \
  390 + .driver_info = (unsigned long)&qmi_wwan_force_int3
  391 +
  392 +/* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */
400 393 #define QMI_GOBI_DEVICE(vend, prod) \
401 394 USB_DEVICE(vend, prod), \
402   - .driver_info = (unsigned long)&qmi_wwan_gobi
  395 + .driver_info = (unsigned long)&qmi_wwan_force_int0
403 396  
404 397 static const struct usb_device_id products[] = {
405 398 { /* Huawei E392, E398 and possibly others sharing both device id and more... */
... ... @@ -510,20 +503,24 @@
510 503 .bInterfaceProtocol = 0xff,
511 504 .driver_info = (unsigned long)&qmi_wwan_sierra,
512 505 },
513   - {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
514   - {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
515   - {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */
516   - {QMI_GOBI_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */
517   - {QMI_GOBI_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */
518   - {QMI_GOBI_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */
519   - {QMI_GOBI_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */
520   - {QMI_GOBI_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */
521   - {QMI_GOBI_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */
522   - {QMI_GOBI_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */
523   - {QMI_GOBI_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */
524   - {QMI_GOBI_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */
525   - {QMI_GOBI_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */
526   - {QMI_GOBI_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */
  506 +
  507 + /* Gobi 1000 devices */
  508 + {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
  509 + {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
  510 + {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */
  511 + {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */
  512 + {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */
  513 + {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */
  514 + {QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */
  515 + {QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */
  516 + {QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */
  517 + {QMI_GOBI1K_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */
  518 + {QMI_GOBI1K_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */
  519 + {QMI_GOBI1K_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */
  520 + {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */
  521 + {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */
  522 +
  523 + /* Gobi 2000 and 3000 devices */
527 524 {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */
528 525 {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */
529 526 {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */