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
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel