Ole, can you verify this version works for you? This version is slimmed down (no kmalloc!) and includes a few missing pieces like Kconfig and hub.c updates..
- Dave
From: Ole Andre Vadla Ravnas <[EMAIL PROTECTED]> Windows Mobile 5 based devices described as supporting "ActiveSync": - Speak RNDIS but lack the CDC and union descriptors. This patch updates the cdc ethernet code to fake ACM descriptors we need. - Require RNDIS_MSG_QUERY messages to include a buffer of the size the response should generate. This patch updates the rndis host code to pass this will-be-ignored data. The resulting RNDIS host code has been reported to work with several WM5 based devices. Signed-off-by: Ole Andre Vadla Ravnaas <[EMAIL PROTECTED]> Cleanup, streamlining, bugfixes, Kconfig, and matching hub driver update. Signed-off-by: David Brownell <[EMAIL PROTECTED]> Index: g26/drivers/usb/net/cdc_ether.c =================================================================== --- g26.orig/drivers/usb/net/cdc_ether.c 2006-06-28 22:02:21.000000000 -0700 +++ g26/drivers/usb/net/cdc_ether.c 2006-06-29 21:40:40.000000000 -0700 @@ -1,6 +1,7 @@ /* * CDC Ethernet based networking peripherals * Copyright (C) 2003-2005 by David Brownell + * Copyrignt (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,6 +37,29 @@ #include "usbnet.h" +#if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) + +static int is_rndis(struct usb_interface_descriptor *desc) +{ + return desc->bInterfaceClass == USB_CLASS_COMM + && desc->bInterfaceSubClass == 2 + && desc->bInterfaceProtocol == 0xff; +} + +static int is_activesync(struct usb_interface_descriptor *desc) +{ + return desc->bInterfaceClass == USB_CLASS_MISC + && desc->bInterfaceSubClass == 1 + && desc->bInterfaceProtocol == 1; +} + +#else + +#define is_rndis(desc) 0 +#define is_activesync(desc) 0 + +#endif + /* * probes control interface, claims data interface, collects the bulk * endpoints, activates data interface (if needed), maybe sets MTU. @@ -72,7 +96,7 @@ 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 = is_rndis(&intf->cur_altsetting->desc); memset(info, 0, sizeof *info); info->control = intf; @@ -172,7 +196,26 @@ next_desc: buf += buf [0]; } - if (!info->header || !info->u || (!rndis && !info->ether)) { + /* Microsoft ActiveSync based 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)) { + rndis = 1; + + /* initialize */ + 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 #%u/%p slave #%u/%p\n", + info->u->bMasterInterface0, + info->control, + info->u->bSlaveInterface0, + info->data); + goto bad_desc; + } + + } else if (!info->header || !info->u || (!rndis && !info->ether)) { dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n", info->header ? "" : "header ", info->u ? "" : "union ", Index: g26/drivers/usb/net/rndis_host.c =================================================================== --- g26.orig/drivers/usb/net/rndis_host.c 2006-06-28 22:02:21.000000000 -0700 +++ g26/drivers/usb/net/rndis_host.c 2006-06-29 21:32:29.000000000 -0700 @@ -50,6 +50,8 @@ * - In some cases, MS-Windows will emit undocumented requests; this * matters more to peripheral implementations than host ones. * + * Moreover there's a no-open-specs variant of RNDIS called "ActiveSync". + * * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and * currently rare) "Ethernet Emulation Model" (EEM). @@ -423,11 +425,19 @@ 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 an evident requirement MSFT added for ActiveSync. + * This undocumented (and nonsensical) issue was found by sniffing + * protocol requests from the ActiveSync 4.1 Windows driver. + */ + 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)) { @@ -594,6 +604,10 @@ static const struct usb_device_id produc /* RNDIS is MSFT's un-official variant of CDC ACM */ USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), .driver_info = (unsigned long) &rndis_info, +}, { + /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ + USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), + .driver_info = (unsigned long) &rndis_info, }, { }, // END }; Index: g26/include/linux/usb_ch9.h =================================================================== --- g26.orig/include/linux/usb_ch9.h 2006-06-29 10:13:25.000000000 -0700 +++ g26/include/linux/usb_ch9.h 2006-06-29 10:55:55.000000000 -0700 @@ -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 Index: g26/drivers/usb/net/Kconfig =================================================================== --- g26.orig/drivers/usb/net/Kconfig 2006-06-28 22:02:21.000000000 -0700 +++ g26/drivers/usb/net/Kconfig 2006-06-29 20:57:42.000000000 -0700 @@ -208,13 +208,15 @@ config USB_NET_PLUSB with one of these chips. config USB_NET_RNDIS_HOST - tristate "Host for RNDIS devices (EXPERIMENTAL)" + tristate "Host for RNDIS and ActiveSync devices (EXPERIMENTAL)" depends on USB_USBNET && EXPERIMENTAL select USB_NET_CDCETHER help This option enables hosting "Remote NDIS" USB networking links, as encouraged by Microsoft (instead of CDC Ethernet!) for use in - various devices that may only support this protocol. + various devices that may only support this protocol. A variant + of this protocol (with even less public documentation) seems to + be at the root of Microsoft's "Active Sync" too. Avoid using this protocol unless you have no better options. The protocol specification is incomplete, and is controlled by Index: g26/drivers/usb/core/hub.c =================================================================== --- g26.orig/drivers/usb/core/hub.c 2006-06-29 10:13:26.000000000 -0700 +++ g26/drivers/usb/core/hub.c 2006-06-29 21:43:39.000000000 -0700 @@ -1176,6 +1176,21 @@ static inline const char *plural(int n) return (n == 1 ? "" : "s"); } +static int is_rndis(struct usb_interface_descriptor *desc) +{ + return desc->bInterfaceClass == USB_CLASS_COMM + && desc->bInterfaceSubClass == 2 + && desc->bInterfaceProtocol == 0xff; +} + +static int is_activesync(struct usb_interface_descriptor *desc) +{ + return desc->bInterfaceClass == USB_CLASS_MISC + && desc->bInterfaceSubClass == 1 + && desc->bInterfaceProtocol == 1; +} + + static int choose_configuration(struct usb_device *udev) { int i; @@ -1238,19 +1253,16 @@ static int choose_configuration(struct u continue; } - /* If the first config's first interface is COMM/2/0xff - * (MSFT RNDIS), rule it out unless Linux has host-side - * RNDIS support. */ - if (i == 0 && desc - && desc->bInterfaceClass == USB_CLASS_COMM - && desc->bInterfaceSubClass == 2 - && desc->bInterfaceProtocol == 0xff) { -#ifndef CONFIG_USB_NET_RNDIS_HOST - continue; -#else + /* When the first config's first interface is one of Microsoft's + * pet nonstandard Ethernet-over-USB protocols, ignore it unless + * this kernel has enabled the necessary host side driver. + */ + if (i == 0 && desc && (is_rndis(desc) || is_activesync(desc))) +#if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) best = c; +#else + continue; #endif - } /* From the remaining configs, choose the first one whose * first interface is for a non-vendor-specific class.
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel