| Submitter | Bjørn Mork |
|---|---|
| Date | April 26, 2012, 10:55 a.m. |
| Message ID | <1335437703-6800-1-git-send-email-bjorn@mork.no> |
| Download | mbox | patch |
| Permalink | /patch/155246/ |
| State | Superseded |
| Headers | show |
Comments
Am Donnerstag, 26. April 2012, 12:55:03 schrieb Bjørn Mork: > Some RNDIS devices include a bogus CDC Union descriptor pointing > to non-existing interfaces. The RNDIS code is already prepared > to handle devices without a CDC Union descriptor by hardwiring > the driver to use interfaces 0 and 1, which is correct for the > devices with the bogus descriptor as well. So we can reuse the > existing workaround. Very good, except that this is a bit risky, because we may use interface 0 without checking that it belongs to us. Could you add a sanity check that the interface for which probe() is called is really the control interface in case a workaround is used? Regards Oliver -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Patch
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 90a3002..4ed5a38 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -83,6 +83,7 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) struct cdc_state *info = (void *) &dev->data; int status; int rndis; + bool android_rndis_quirk = false; struct usb_driver *driver = driver_of(intf); struct usb_cdc_mdlm_desc *desc = NULL; struct usb_cdc_mdlm_detail_desc *detail = NULL; @@ -195,6 +196,11 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) info->control, info->u->bSlaveInterface0, info->data); + /* fall back to hard-wiring for RNDIS */ + if (rndis) { + android_rndis_quirk = true; + goto next_desc; + } goto bad_desc; } if (info->control != intf) { @@ -271,8 +277,12 @@ next_desc: /* Microsoft ActiveSync based and some regular RNDIS devices lack the * CDC descriptors, so we'll hard-wire the interfaces and not check * for descriptors. + * + * Some Android RNDIS devices have a CDC Union descriptor pointing + * to non-existing interfaces. Ignore that and attempt the same + * hard-wired 0 and 1 interfaces. */ - if (rndis && !info->u) { + if (rndis && (!info->u || android_rndis_quirk)) { info->control = usb_ifnum_to_if(dev->udev, 0); info->data = usb_ifnum_to_if(dev->udev, 1); if (!info->control || !info->data) {
Some RNDIS devices include a bogus CDC Union descriptor pointing to non-existing interfaces. The RNDIS code is already prepared to handle devices without a CDC Union descriptor by hardwiring the driver to use interfaces 0 and 1, which is correct for the devices with the bogus descriptor as well. So we can reuse the existing workaround. Cc: Markus Kolb <linux-201011@tower-net.de> Cc: Iker Salmón San Millán <shaola@esdebian.org> Cc: Jonathan Nieder <jrnieder@gmail.com> Cc: Oliver Neukum <oliver@neukum.org> Cc: 655387@bugs.debian.org Cc: stable@vger.kernel.org Signed-off-by: Bjørn Mork <bjorn@mork.no> --- Something like this, then? This has only been build tested by me as I don't have any of the affected devices. It would be great if any of the reporters could verify that it solves the problem. I can provide prebuilt modules for Debian 3.2 based kernels to simplify the testing (just rmmod and insmod - no need to build or boot). Send me an email if you want the module. Sorry for the long delay in following up this. I totally forgot about it. Bjørn drivers/net/usb/cdc_ether.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)