Hi,

Here's the updated patch against 2.6.16.2, which hopefully solves the
issues that were pointed out.  Except one thing:
> You missed an update to drivers/usb/core/hub.c to the
> configuration selection code ... it needs to know about
> this new RNDIS variant, avoiding it if there's a standard
> option.

Not sure what to do about this as these devices only have one
configuration, so please forgive me if I've misunderstood horribly,
which is quite likely. :)

Regards,
Ole André


On 4/4/06, Ole André Vadla Ravnås <[EMAIL PROTECTED]> wrote:
> Hi,
>
> Sorry about the late reply, work's been killing off most of my
> spare-time lately.
>
> > Could you resend without line wraps etc?  quoted-printable is
> > evil for patches.  Also, for my convenience in review, please
> > pass the "p" flag to diff ("diff -Naurp") so I can see what
> > procedures are being patched.  Plus, the right place to post
> > USB patches is [EMAIL PROTECTED] :)
>
> Ok, thanks, will do. I'll subscribe to that list as well and post the
> revised patch there. :)
>
> > Do you have a URL for this specification?  I only have the
> > RNDIS 1.0 specification, you seem to have access to some
> > sort of modified version ... maybe it fixes some of the holes
> > in the 1.0 spec?  Ditto the WM5 subclass and protocol ... those
> > look like official USB-IF values, and last I checked there were
> > no assigned values.
>
> Sorry, I've only got the 1.0 spec as well, I've basically
> reverse-engineered my way to figuring out what the changes are. (Wrote
> a quick 'n dirty app to help me comprehend the protocol:
> http://projects.collabora.co.uk/~oleavr/usbhound.png).
>
> > You missed an update to drivers/usb/core/hub.c to the
> > configuration selection code ... it needs to know about
> > this new RNDIS variant, avoiding it if there's a standard
> > option.
>
> Ah, I see. I'll fix this.
>
> > For rndis_host.c, please highlight that adding the extra 48
> > bytes is a requirement MSFT added after the RNDIS 1.0 spec.
>
> Good point! Noted.
>
> > For cdc_ether.c please make
> >
> >         /* multiline comments end like
> >          * this
> >          */
> >
> > instead of
> >
> >         /* the wrong multiline comment
> >          * style */
>
> Noted.
>
> > I'm glad to see this patch.  That rndis_host driver has had
> > relatively minimal testing against MSFT code ... so it's good
> > to see that it's getting used!
>
> That's good to hear. Thanks for your most excellent work! I've only
> received positive feedback from other users with WM5 devices so far,
> so things are looking good.
>
> > Hmm, well http://www.usb.org/developers/defined_class
> > says that there is a "misc" protocol for RNDIS, but it
> > doesn't match the one you provided (that's for Bluetooth!)
> > and there's no spec I can find ...
>
> Hmm, really? I've used base class 0xEF, sub-class 0x01 and protocol
> 0x01, which is what is specified there (if I understood it correctly).
>
> I'll post a revised patch as soon as I get back to life (by the end of
> the weekend or early next week). :) Thanks a lot for your time, most
> appreciated.
>
> Regards,
> Ole André
>
diff -Naurp linux-2.6.16.2-orig/drivers/usb/net/cdc_ether.c linux-2.6.16.2/drivers/usb/net/cdc_ether.c
--- linux-2.6.16.2-orig/drivers/usb/net/cdc_ether.c	2006-04-07 19:56:47.000000000 +0300
+++ linux-2.6.16.2/drivers/usb/net/cdc_ether.c	2006-04-10 01:03:10.000000000 +0300
@@ -72,7 +72,8 @@ int usbnet_generic_cdc_bind(struct usbne
 	/* this assumes that if there's a non-RNDIS vendor variant
 	 * of cdc-acm, it'll fail RNDIS requests cleanly.
 	 */
-	rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff);
+	rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff ||
+		 intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_MISC);
 
 	memset(info, 0, sizeof *info);
 	info->control = intf;
@@ -172,6 +173,61 @@ next_desc:
 		buf += buf [0];
 	}
 
+	/* Windows Mobile 5 based RNDIS devices lack the CDC descriptors,
+	 * so to work around this without changing too much of the overall
+	 * logic we fake those headers here.
+	 */
+	if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_MISC) {
+		struct usb_cdc_header_desc *h = NULL;
+		struct usb_cdc_union_desc *u = NULL;
+
+		dev_dbg(&intf->dev, "taking WM5 workaround path\n");
+
+		/* allocate and fill the missing structures */
+		h = kmalloc(sizeof(struct usb_cdc_header_desc), GFP_KERNEL);
+		u = kmalloc(sizeof(struct usb_cdc_union_desc), GFP_KERNEL);
+		if (!h || !u) {
+			if (h)
+				kfree(h);
+			if (u)
+				kfree(u);
+
+			return -ENOMEM;
+		}
+		
+		info->header = h;
+
+		h->bLength = sizeof(struct usb_cdc_header_desc);
+		h->bDescriptorType = USB_DT_CS_INTERFACE;
+		h->bDescriptorSubType = USB_CDC_HEADER_TYPE;
+
+		h->bcdCDC = 0;
+		
+		info->u = u;
+
+		u->bLength = sizeof(struct usb_cdc_union_desc);
+		u->bDescriptorType = USB_DT_CS_INTERFACE;
+		u->bDescriptorSubType = USB_CDC_UNION_TYPE;
+		
+		u->bMasterInterface0 = 0;
+		u->bSlaveInterface0 = 1;
+
+		/* initialize */
+		info->control = usb_ifnum_to_if(dev->udev,
+					info->u->bMasterInterface0);
+		info->data = usb_ifnum_to_if(dev->udev,
+					info->u->bSlaveInterface0);
+		if (!info->control || !info->data) {
+			dev_dbg(&intf->dev,
+				"master #%u/%p slave #%u/%p\n",
+				info->u->bMasterInterface0,
+				info->control,
+				info->u->bSlaveInterface0,
+				info->data);
+			goto bad_desc;
+		}
+	}
+	
 	if (!info->header || !info->u || (!rndis && !info->ether)) {
 		dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n",
 			info->header ? "" : "header ",
@@ -229,6 +285,17 @@ void usbnet_cdc_unbind(struct usbnet *de
 	struct cdc_state		*info = (void *) &dev->data;
 	struct usb_driver		*driver = driver_of(intf);
 
+	/* clean up resources allocated by the Windows Mobile 5
+	 * RNDIS workaround ...
+	 */
+	if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_MISC) {
+		if (info->header)
+			kfree(info->header);
+
+		if (info->u)
+			kfree(info->u);
+	}
+
 	/* disconnect master --> disconnect slave */
 	if (intf == info->control && info->data) {
 		/* ensure immediate exit from usbnet_disconnect */
diff -Naurp linux-2.6.16.2-orig/drivers/usb/net/rndis_host.c linux-2.6.16.2/drivers/usb/net/rndis_host.c
--- linux-2.6.16.2-orig/drivers/usb/net/rndis_host.c	2006-04-07 19:56:47.000000000 +0300
+++ linux-2.6.16.2/drivers/usb/net/rndis_host.c	2006-04-10 00:55:29.000000000 +0300
@@ -377,6 +377,7 @@ static int rndis_bind(struct usbnet *dev
 		struct rndis_set_c	*set_c;
 	} u;
 	u32			tmp;
+	char			*p;
 
 	/* we can't rely on i/o from stack working, or stack allocation */
 	u.buf = kmalloc(1024, GFP_KERNEL);
@@ -409,11 +410,18 @@ fail:
 	dev_dbg(&intf->dev, "hard mtu %u, align %d\n", dev->hard_mtu,
 		1 << le32_to_cpu(u.init_c->packet_alignment));
 
-	/* get designated host ethernet address */
-	memset(u.get, 0, sizeof *u.get);
+	/* get designated host ethernet address
+	 *
+	 * adding a payload exactly the same size as the expected
+	 * response' payload is a requirement added by MSFT as of
+	 * post-RNDIS 1.0
+	 */
+	memset(u.get, 0, sizeof *u.get + 48);
 	u.get->msg_type = RNDIS_MSG_QUERY;
-	u.get->msg_len = ccpu2(sizeof *u.get);
+	u.get->msg_len = ccpu2(sizeof *u.get + 48);
 	u.get->oid = OID_802_3_PERMANENT_ADDRESS;
+	u.get->len = ccpu2(48);
+	u.get->offset = ccpu2(20);
 
 	retval = rndis_command(dev, u.header);
 	if (unlikely(retval < 0)) {
@@ -575,10 +583,14 @@ static const struct driver_info	rndis_in
 
 /*-------------------------------------------------------------------------*/
 
+#define WM5_SUB_CLASS 0x01
+#define WM5_PROTOCOL  0x01
+
 static const struct usb_device_id	products [] = {
 {
 	/* RNDIS is MSFT's un-official variant of CDC ACM */
 	USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
+        USB_INTERFACE_INFO(USB_CLASS_MISC, WM5_SUB_CLASS, WM5_PROTOCOL),
 	.driver_info = (unsigned long) &rndis_info,
 },
 	{ },		// END
diff -Naurp linux-2.6.16.2-orig/include/linux/usb_ch9.h linux-2.6.16.2/include/linux/usb_ch9.h
--- linux-2.6.16.2-orig/include/linux/usb_ch9.h	2006-04-07 19:56:47.000000000 +0300
+++ linux-2.6.16.2/include/linux/usb_ch9.h	2006-04-10 00:22:01.000000000 +0300
@@ -217,6 +217,7 @@ struct usb_device_descriptor {
 #define USB_CLASS_CONTENT_SEC		0x0d	/* content security */
 #define USB_CLASS_VIDEO			0x0e
 #define USB_CLASS_WIRELESS_CONTROLLER	0xe0
+#define USB_CLASS_MISC			0xef
 #define USB_CLASS_APP_SPEC		0xfe
 #define USB_CLASS_VENDOR_SPEC		0xff
 



Reply via email to