]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/usb/cdc_ether.c
Merge git://git.infradead.org/mtd-2.6
[linux-2.6-omap-h63xx.git] / drivers / net / usb / cdc_ether.c
index 5a21f06bf8a54fab20e2bb70dd0f599b4be910c2..a934428a5890ba26adf4df7e00588d57a08ef786 100644 (file)
@@ -31,8 +31,7 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
 
 
 #if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE)
@@ -91,6 +90,22 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
                                "CDC descriptors on config\n");
        }
 
+       /* Maybe CDC descriptors are after the endpoint?  This bug has
+        * been seen on some 2Wire Inc RNDIS-ish products.
+        */
+       if (len == 0) {
+               struct usb_host_endpoint        *hep;
+
+               hep = intf->cur_altsetting->endpoint;
+               if (hep) {
+                       buf = hep->extra;
+                       len = hep->extralen;
+               }
+               if (len)
+                       dev_dbg(&intf->dev,
+                               "CDC descriptors on endpoint\n");
+       }
+
        /* this assumes that if there's a non-RNDIS vendor variant
         * of cdc-acm, it'll fail RNDIS requests cleanly.
         */
@@ -128,14 +143,14 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
                         * modem interface from an RNDIS non-modem.
                         */
                        if (rndis) {
-                               struct usb_cdc_acm_descriptor *d;
+                               struct usb_cdc_acm_descriptor *acm;
 
-                               d = (void *) buf;
-                               if (d->bmCapabilities) {
+                               acm = (void *) buf;
+                               if (acm->bmCapabilities) {
                                        dev_dbg(&intf->dev,
                                                "ACM capabilities %02x, "
                                                "not really RNDIS?\n",
-                                               d->bmCapabilities);
+                                               acm->bmCapabilities);
                                        goto bad_desc;
                                }
                        }
@@ -212,15 +227,16 @@ next_desc:
                buf += buf [0];
        }
 
-       /* Microsoft ActiveSync based RNDIS devices lack the CDC descriptors,
-        * so we'll hard-wire the interfaces and not check for descriptors.
+       /* Microsoft ActiveSync based and some regular RNDIS devices lack the
+        * CDC descriptors, so we'll hard-wire the interfaces and not check
+        * for descriptors.
         */
-       if (is_activesync(&intf->cur_altsetting->desc) && !info->u) {
+       if (rndis && !info->u) {
                info->control = usb_ifnum_to_if(dev->udev, 0);
                info->data = usb_ifnum_to_if(dev->udev, 1);
                if (!info->control || !info->data) {
                        dev_dbg(&intf->dev,
-                               "activesync: master #0/%p slave #1/%p\n",
+                               "rndis: master #0/%p slave #1/%p\n",
                                info->control,
                                info->data);
                        goto bad_desc;
@@ -300,7 +316,6 @@ void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
 }
 EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
 
-\f
 /*-------------------------------------------------------------------------
  *
  * Communications Device Class, Ethernet Control model