* [ANNOUNCE] RNDIS Gadget Driver
@ 2004-03-25 22:11 Robert Schwebel
2004-03-25 22:52 ` David Brownell
2004-03-26 11:59 ` bert hubert
0 siblings, 2 replies; 20+ messages in thread
From: Robert Schwebel @ 2004-03-25 22:11 UTC (permalink / raw)
To: David Brownell; +Cc: linux-usb-devel, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 957 bytes --]
David,
finally, here is our RNDIS USB Gadget Driver - see the attached patch
against the gadget-2.4 BK tree as of now. It shouldn't be too difficult
to port this to 2.6.
The patch adds support for Microsoft's RNDIS protocol to the standard
g_ether driver. This makes it possible to connect a Linux USB gadget to
any standard Windows machine and <*PALIM!*> there is a new USB network
interface on the Windows side on which you can speak TCP/IP :-)
Unfortunately, although it works with the original Microsoft driver, you
need an inf file on the windows side; you can download the template for
that directly from M$.
Thanks to Auerswald GmbH for sponsoring this work!
Robert
--
Dipl.-Ing. Robert Schwebel | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
Handelsregister: Amtsgericht Hildesheim, HRA 2686
Hornemannstraße 12, 31137 Hildesheim, Germany
Phone: +49-5121-28619-0 | Fax: +49-5121-28619-4
[-- Attachment #2: gadget-rndis-20040325-1.diff --]
[-- Type: text/plain, Size: 81680 bytes --]
diff -urN gadget-2.4/drivers/usb/gadget/config.c linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/config.c
--- gadget-2.4/drivers/usb/gadget/config.c 2004-03-19 11:47:16.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/config.c 2004-03-25 22:50:17.000000000 +0100
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/string.h>
+#include <asm/byteorder.h>
#include <linux/usb_ch9.h>
@@ -50,13 +51,14 @@
/* fill buffer from src[] until null descriptor ptr */
for (; 0 != *src; src++) {
unsigned len = (*src)->bLength;
-
- if (len > buflen);
+
+ if (len > buflen)
return -EINVAL;
memcpy(dest, *src, len);
buflen -= len;
dest += len;
}
+
return dest - (u8 *)buf;
}
diff -urN gadget-2.4/drivers/usb/gadget/Config.in linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/Config.in
--- gadget-2.4/drivers/usb/gadget/Config.in 2004-03-19 11:47:16.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/Config.in 2004-03-19 16:16:48.000000000 +0100
@@ -68,6 +68,7 @@
dep_tristate ' Gadget Zero (DEVELOPMENT)' CONFIG_USB_ZERO $CONFIG_USB_GADGET_CONTROLLER
dep_tristate ' Ethernet Gadget (EXPERIMENTAL)' CONFIG_USB_ETH $CONFIG_USB_GADGET_CONTROLLER $CONFIG_NET
+ dep_tristate ' RNDIS support (EXPERIMENTAL)' CONFIG_USB_ETH_RNDIS $CONFIG_USB_ETH
dep_tristate ' Gadget Filesystem API (EXPERIMENTAL)' CONFIG_USB_GADGETFS $CONFIG_USB_GADGET_CONTROLLER
dep_tristate ' File-backed Storage Gadget (DEVELOPMENT)' CONFIG_USB_FILE_STORAGE $CONFIG_USB_GADGET_CONTROLLER
dep_mbool ' File-backed Storage Gadget test mode' CONFIG_USB_FILE_STORAGE_TEST $CONFIG_USB_FILE_STORAGE
diff -urN gadget-2.4/drivers/usb/gadget/epautoconf.c linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/epautoconf.c
--- gadget-2.4/drivers/usb/gadget/epautoconf.c 2004-03-19 11:47:16.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/epautoconf.c 2004-03-22 14:13:33.000000000 +0100
@@ -27,6 +27,7 @@
#include <linux/ctype.h>
#include <linux/string.h>
+#include <asm/byteorder.h>
#include <linux/usb_ch9.h>
#include <linux/usb_gadget.h>
diff -urN gadget-2.4/drivers/usb/gadget/ether.c linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/ether.c
--- gadget-2.4/drivers/usb/gadget/ether.c 2004-03-19 11:47:16.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/ether.c 2004-03-25 22:35:41.000000000 +0100
@@ -3,6 +3,15 @@
*
* Copyright (C) 2003 David Brownell
*
+ * 2003/2004 Robert Schwebel, Benedikt Spranger
+ * Added RNDIS support
+ *
+ * 2004-03-12 Kai-Uwe Bloem <linux-development@auerswald.de>
+ * Fixed header length bug in rx_complete
+ *
+ * 2004-03-25 Kai-Uwe Bloem <linux-development@auerswald.de>
+ * Fixed RX_EXTRA
+ *
* 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
* the Free Software Foundation; either version 2 of the License, or
@@ -19,8 +28,8 @@
*/
-// #define DEBUG 1
-// #define VERBOSE
+#define DEBUG 1
+#define VERBOSE
#include <linux/config.h>
#include <linux/kernel.h>
@@ -53,6 +62,12 @@
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
+#if defined(CONFIG_USB_ETH_RNDIS) | defined(CONFIG_USB_ETH_RNDIS_MODULE)
+#define GADGET_RNDIS
+#include "rndis.h"
+#define CS_INTERFACE 0x24
+#endif
+
/*-------------------------------------------------------------------------*/
/*
@@ -74,9 +89,15 @@
static const char shortname [] = "ether";
static const char driver_desc [] = DRIVER_DESC;
+#ifdef GADGET_RNDIS
+#define RNDIS_DRIVER_DESC "RNDIS Gadget"
+static const char rndis_shortname [] = "rndisether";
+static const char rndis_driver_desc [] = RNDIS_DRIVER_DESC;
+#endif
+
#define MIN_PACKET sizeof(struct ethhdr)
#define MAX_PACKET ETH_DATA_LEN /* biggest packet we'll rx/tx */
-#define RX_EXTRA 20 /* guard against rx overflows */
+#define RX_EXTRA 22 /* guard against rx overflows */
/* FIXME allow high speed jumbograms */
@@ -102,7 +123,7 @@
struct usb_request *req; /* for control responses */
u8 config;
- struct usb_ep *in_ep, *out_ep, *status_ep;
+ struct usb_ep *in_ep, *out_ep, *status_ep;
const struct usb_endpoint_descriptor
*in, *out, *status;
struct list_head tx_reqs, rx_reqs;
@@ -113,6 +134,15 @@
struct work_struct work;
unsigned long todo;
+#ifdef GADGET_RNDIS
+ struct usb_ep *rndis_status_ep;
+ const struct usb_endpoint_descriptor
+ *rndis_status;
+
+ /* some other RNDIS stuff */
+ int rndis;
+ int rndis_config;
+#endif
#define WORK_RX_MEMORY 0
};
@@ -146,6 +176,8 @@
* for some reason doesn't handle full speed bulk maxpacket of 64.
*/
+#define DEV_RNDIS_CONFIG_VALUE 1 /* RNDIS */
+#define DEV_CDC_CONFIG_VALUE 2 /* CDC or Linux special */
#define DEV_CONFIG_VALUE 3 /* some hardware cares */
/* #undef on hardware that can't implement CDC */
@@ -201,6 +233,12 @@
#define EP_OUT_NUM 2
static const char EP_IN_NAME [] = "ep1in-bulk";
#define EP_IN_NUM 1
+#ifdef GADGET_RNDIS
+static const char EP_RNDIS_STATUS_NAME [] = "ep5in-int";
+#define EP_RNDIS_STATUS_NUM 5
+#define EP_RNDIS_STATUS_LEN 8
+#endif
+
/* supports remote wakeup, but this driver doesn't */
/* no hw optimizations to apply */
@@ -291,8 +329,13 @@
#undef EP_STATUS_NUM
#undef DRIVER_VENDOR_NUM
#undef DRIVER_PRODUCT_NUM
+#ifdef CONFIG_ARCH_INNOKOM
+#define DRIVER_VENDOR_NUM 0x09BF
+#define DRIVER_PRODUCT_NUM 0x00E0
+#else
#define DRIVER_VENDOR_NUM 0x049f
#define DRIVER_PRODUCT_NUM 0x505a
+#endif /* CONFIG_ARCH_INNOKOM */
#endif /* CONFIG_CDC_ETHER */
/* power usage is config specific.
@@ -386,10 +429,16 @@
#define STRING_DATA 4
#define STRING_CONTROL 5
+#ifdef GADGET_RNDIS
+#define STRING_RNDIS_CONTROL 6
+#define STRING_RNDIS_DATA 7
+#define STRING_SERIAL_NUMBER 8
+#endif
+
#define USB_BUFSIZ 256 /* holds our biggest descriptor */
/*
- * This device advertises one configuration.
+ * This device advertises one or two configurations.
*/
static struct usb_device_descriptor
device_desc = {
@@ -397,8 +446,7 @@
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = __constant_cpu_to_le16 (0x0200),
-
- .bDeviceClass = DEV_CONFIG_CLASS,
+ .bDeviceClass = 0x02,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
@@ -407,7 +455,11 @@
.bcdDevice = __constant_cpu_to_le16 (DRIVER_VERSION_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
+#ifdef GADGET_RNDIS
+ .bNumConfigurations = 2,
+#else
.bNumConfigurations = 1,
+#endif
};
static struct usb_config_descriptor
@@ -427,6 +479,122 @@
.bMaxPower = (MAX_USB_POWER + 1) / 2,
};
+#ifdef GADGET_RNDIS
+static struct usb_config_descriptor
+rndis_config = {
+ .bLength = sizeof rndis_config,
+ .bDescriptorType = USB_DT_CONFIG,
+ .bNumInterfaces = 2,
+ .bConfigurationValue = DEV_RNDIS_CONFIG_VALUE,
+ .iConfiguration = STRING_PRODUCT,
+ .bmAttributes = USB_CONFIG_ATT_SELFPOWER | USB_CONFIG_ATT_ONE,
+ .bMaxPower = 0x00,
+};
+
+static struct usb_interface_descriptor
+rndis_control_intf = {
+ .bLength = sizeof rndis_control_intf,
+ .bDescriptorType = USB_DT_INTERFACE,
+
+ .bInterfaceNumber = 0,
+
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = 0x02, /* abstract control model */
+ .bInterfaceProtocol = 0xFF, /* vendor spec. */
+ .iInterface = STRING_RNDIS_CONTROL,
+};
+
+struct rndis_func_mgmt_descriptor
+{
+ u8 bLength;
+ u8 bDescriptorType;
+ u8 bDescriptorSubType;
+ u8 bmCapabilities;
+ u8 bDataInterface;
+} __attribute__ ((packed));
+
+struct rndis_func_abstract_descriptor
+{
+ u8 bLength;
+ u8 bDescriptorType;
+ u8 bDescriptorSubType;
+ u8 bmCapabilities;
+} __attribute__ ((packed));
+
+struct rndis_func_union_descriptor
+{
+ u8 bLength;
+ u8 bDescriptorType;
+ u8 bDescriptorSubType;
+ u8 bMasterInterface;
+ u8 bSlaveInterface;
+} __attribute__ ((packed));
+
+static const struct rndis_func_mgmt_descriptor
+rndis_mgmt_descriptor = {
+ .bLength = sizeof rndis_mgmt_descriptor,
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubType = 0x01,
+ .bmCapabilities = 0X00,
+ .bDataInterface = 0X01,
+};
+
+static struct rndis_func_abstract_descriptor
+rndis_abstract_descriptor = {
+ .bLength = sizeof rndis_abstract_descriptor,
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubType = 0x02,
+ .bmCapabilities = 0X00,
+};
+
+static struct rndis_func_union_descriptor
+rndis_union_descriptor = {
+ .bLength = sizeof rndis_union_descriptor,
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubType = 0x06,
+ .bMasterInterface = 0X00,
+ .bSlaveInterface = 0X01,
+};
+
+static const struct usb_interface_descriptor
+rndis_data_intf = {
+ .bLength = sizeof rndis_data_intf,
+ .bDescriptorType = USB_DT_INTERFACE,
+
+ .bInterfaceNumber = 1,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = 0x0a, /* DATA class */
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = STRING_RNDIS_DATA,
+};
+
+static const struct usb_endpoint_descriptor
+fs_rndis_control_ep = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = EP_RNDIS_STATUS_NUM | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize = __constant_cpu_to_le16 (EP_RNDIS_STATUS_LEN),
+ .bInterval = 1,
+};
+
+/* FIXME: highspeed */
+static const struct usb_endpoint_descriptor
+hs_rndis_control_ep = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = EP_RNDIS_STATUS_NUM | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize = __constant_cpu_to_le16 (EP_RNDIS_STATUS_LEN),
+ .bInterval = 1,
+};
+#endif
+
#ifdef DEV_CONFIG_CDC
/*
@@ -719,6 +886,34 @@
#endif /* !CONFIG_USB_GADGET_DUALSPEED */
+#ifdef GADGET_RNDIS
+static const struct usb_descriptor_header *fs_rndis_function [] = {
+ (struct usb_descriptor_header *) &rndis_control_intf,
+ (struct usb_descriptor_header *) &rndis_mgmt_descriptor,
+ (struct usb_descriptor_header *) &rndis_abstract_descriptor,
+ (struct usb_descriptor_header *) &rndis_union_descriptor,
+ (struct usb_descriptor_header *) &fs_rndis_control_ep,
+ (struct usb_descriptor_header *) &rndis_data_intf,
+ (struct usb_descriptor_header *) &fs_source_desc,
+ (struct usb_descriptor_header *) &fs_sink_desc,
+ 0,
+};
+
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+static const struct usb_descriptor_header *hs_rndis_function [] = {
+ (struct usb_descriptor_header *) &rndis_control_intf,
+ (struct usb_descriptor_header *) &rndis_mgmt_descriptor,
+ (struct usb_descriptor_header *) &rndis_abstract_descriptor,
+ (struct usb_descriptor_header *) &rndis_union_descriptor,
+ (struct usb_descriptor_header *) &fs_rndis_control_ep,
+ (struct usb_descriptor_header *) &rndis_data_intf,
+ (struct usb_descriptor_header *) &hs_source_desc,
+ (struct usb_descriptor_header *) &hs_sink_desc,
+ 0,
+};
+#endif
+#endif
+
/*-------------------------------------------------------------------------*/
/* descriptors that are built on-demand */
@@ -737,6 +932,12 @@
{ STRING_CONTROL, "CDC Communications Control", },
#endif
{ STRING_DATA, "Ethernet Data", },
+#ifdef GADGET_RNDIS
+ { STRING_RNDIS_CONTROL, "Remote NDIS Control", },
+ { STRING_RNDIS_DATA, "Remote NDIS Data", },
+ /* need some good idea here :-) */
+ { STRING_SERIAL_NUMBER, "2143658709", },
+#endif
{ } /* end of list */
};
@@ -746,7 +947,7 @@
};
/*
- * one config, two interfaces: control, data.
+ * one or two configs, both two interfaces: control, data.
* complications: class descriptors, and an altsetting.
*/
static int
@@ -754,22 +955,48 @@
{
int len;
const struct usb_descriptor_header **function = fs_function;
+#ifdef GADGET_RNDIS
+ const struct usb_descriptor_header **rndis_function = fs_rndis_function;
+#endif
#ifdef CONFIG_USB_GADGET_DUALSPEED
int hs = (speed == USB_SPEED_HIGH);
if (type == USB_DT_OTHER_SPEED_CONFIG)
hs = !hs;
if (hs)
+ {
function = hs_function;
+#ifdef GADGET_RNDIS
+ rndis_function = hs_rndis_function;
+#endif
+ }
#endif
/* a single configuration must always be index 0 */
- if (index > 0)
+ switch (index)
+ {
+#ifdef GADGET_RNDIS
+ case 0:
+ len = usb_gadget_config_buf (&rndis_config, buf, USB_BUFSIZ,
+ rndis_function);
+ break;
+ case 1:
+#else
+ case 0:
+#endif
+ len = usb_gadget_config_buf (ð_config, buf, USB_BUFSIZ,
+ function);
+ break;
+ default:
+ printk (KERN_WARNING "%s: invalid configuration #%d\n",
+ __FUNCTION__, index);
return -EINVAL;
- len = usb_gadget_config_buf (ð_config, buf, USB_BUFSIZ, function);
+ }
+
if (len < 0)
return len;
((struct usb_config_descriptor *) buf)->bDescriptorType = type;
+
return len;
}
@@ -854,7 +1081,22 @@
}
#endif /* !CONFIG_CDC_ETHER */
-
+#ifdef GADGET_RNDIS
+ /* RNDIS Status EP */
+ else if (strcmp (ep->name, EP_RNDIS_STATUS_NAME) == 0)
+ {
+ d = ep_desc (gadget, &hs_rndis_control_ep ,
+ &fs_rndis_control_ep);
+ result = usb_ep_enable (ep, d);
+ if (result == 0)
+ {
+ ep->driver_data = dev;
+ dev->rndis_status_ep = ep;
+ dev->rndis_status = d;
+ continue;
+ }
+ }
+#endif
/* ignore any other endpoints */
else
continue;
@@ -936,6 +1178,13 @@
dev->status_ep = 0;
}
#endif
+#ifdef GADGET_RNDIS
+ if (dev->rndis_status_ep)
+ {
+ usb_ep_disable (dev->rndis_status_ep);
+ dev->rndis_status_ep = 0;
+ }
+#endif
dev->config = 0;
}
@@ -960,11 +1209,18 @@
#endif
eth_reset_config (dev);
hw_optimize (gadget);
-
+
+#ifdef GADGET_RNDIS
+ dev->rndis = 0;
+#endif
switch (number) {
case DEV_CONFIG_VALUE:
result = set_ether_config (dev, gfp_flags);
break;
+ case DEV_RNDIS_CONFIG_VALUE:
+ dev->rndis = 1;
+ result = set_ether_config (dev, gfp_flags);
+ break;
default:
result = -EINVAL;
/* FALL THROUGH */
@@ -994,6 +1250,29 @@
/*-------------------------------------------------------------------------*/
+#ifdef GADGET_RNDIS
+static void rndis_response_complete (struct usb_ep *ep, struct usb_request *req)
+{
+ struct eth_dev *dev = ep->driver_data;
+
+ if (req->status || req->actual != req->length)
+ DEBUG (dev, "rndis response complete --> %d, %d/%d\n",
+ req->status, req->actual, req->length);
+ rndis_free_response (dev->rndis_config, req->buf);
+}
+
+static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
+{
+ struct eth_dev *dev = ep->driver_data;
+
+ /* parse Remote NDIS Message */
+ if (rndis_msg_parser (dev->rndis_config, (u8 *) req->buf))
+ printk (KERN_ERR "%s: rndis parse error\n", __FUNCTION__ );
+
+ return;
+}
+#endif
+
#ifdef EP_STATUS_NUM
/* section 3.8.2 table 11 of the CDC spec lists Ethernet notifications */
@@ -1120,6 +1399,12 @@
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 /* optional */
#define CDC_SET_ETHERNET_PACKET_FILTER 0x43 /* required */
+#ifdef GADGET_RNDIS
+/* RNDIS special control request types */
+#define RNDIS_SEND_ENCAPSULATED_COMMAND 0x21
+#define RNDIS_GET_ENCAPSULATED_RESPONSE 0xA1
+#endif
+
/*
* The setup() callback implements all the ep0 functionality that's not
* handled lower down. CDC has a number of less-common features:
@@ -1161,7 +1446,7 @@
case USB_DT_OTHER_SPEED_CONFIG:
if (!gadget->is_dualspeed)
break;
- // FALLTHROUGH
+ /* FALLTHROUGH */
#endif /* CONFIG_USB_GADGET_DUALSPEED */
case USB_DT_CONFIG:
value = config_buf (gadget->speed, req->buf,
@@ -1183,6 +1468,7 @@
case USB_REQ_SET_CONFIGURATION:
if (ctrl->bRequestType != 0)
break;
+ DEBUG (dev,"set configuration #%d\n", ctrl->wValue);
spin_lock (&dev->lock);
value = eth_set_config (dev, ctrl->wValue, GFP_ATOMIC);
spin_unlock (&dev->lock);
@@ -1285,7 +1572,34 @@
value = 0;
break;
#endif /* DEV_CONFIG_CDC */
-
+#ifdef GADGET_RNDIS
+ /* The winner is... */
+ /* RNDIS! */
+
+ case USB_REQ_GET_STATUS:
+ if (ctrl->bRequestType == RNDIS_SEND_ENCAPSULATED_COMMAND)
+ {
+ if (ctrl->wLength > USB_BUFSIZ) return -EDOM;
+ value = ctrl->wLength;
+ req->complete = rndis_command_complete;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ if (ctrl->bRequestType == RNDIS_GET_ENCAPSULATED_RESPONSE)
+ {
+ u8 *buf;
+
+ buf = rndis_get_next_response (dev->rndis_config,
+ &value);
+ if (buf)
+ {
+ memcpy (req->buf, buf, value);
+ req->complete = rndis_response_complete;
+ }
+ }
+ break;
+#endif
default:
VDEBUG (dev,
"unknown control req%02x.%02x v%04x i%04x l%d\n",
@@ -1407,6 +1721,65 @@
static void rx_complete (struct usb_ep *ep, struct usb_request *req);
+#ifdef GADGET_RNDIS
+static void rndis_send_media_state (struct eth_dev *dev, int connect)
+{
+ if (!dev) return;
+
+ if (connect)
+ {
+ if (rndis_signal_connect (dev->rndis_config))
+ return;
+ }
+ else
+ {
+ if (rndis_signal_disconnect (dev->rndis_config))
+ return;
+ }
+}
+
+int rndis_control_ack (struct net_device *net)
+{
+ struct eth_dev *dev = (struct eth_dev *) net->priv;
+ u32 length;
+ struct usb_request *resp;
+
+ /* RNDIS completion function */
+ /* Allocate response request ie. ACK */
+ resp = usb_ep_alloc_request (dev->rndis_status_ep, GFP_ATOMIC);
+ if (!resp)
+ {
+ DEBUG (dev, "status ENOMEM\n");
+ return -ENOMEM;
+ }
+
+ resp->buf = usb_ep_alloc_buffer (dev->rndis_status_ep, 8,
+ &resp->dma, GFP_ATOMIC);
+ if (!resp->buf)
+ {
+ DEBUG (dev, "status buf ENOMEM\n");
+ usb_ep_free_request (dev->rndis_status_ep, resp);
+ return -ENOMEM;
+ }
+
+ /* Send ACK */
+ resp->length = 8;
+ resp->complete = rndis_response_complete;
+
+ *((u32 *) resp->buf) = __constant_cpu_to_le32 (1);
+ *((u32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
+
+ length = usb_ep_queue (dev->rndis_status_ep, resp, GFP_ATOMIC);
+ if (length < 0)
+ {
+ resp->status = 0;
+ rndis_response_complete (dev->rndis_status_ep, resp);
+ }
+
+ return 0;
+}
+#endif
+
static int
rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags)
{
@@ -1415,7 +1788,9 @@
size_t size;
size = (sizeof (struct ethhdr) + dev->net->mtu + RX_EXTRA);
-
+#ifdef GADGET_RNDIS
+ if (dev->rndis) size += sizeof (struct rndis_packet_msg_type);
+#endif
if ((skb = alloc_skb (size, gfp_flags)) == 0) {
DEBUG (dev, "no rx skb\n");
goto enomem;
@@ -1451,6 +1826,9 @@
/* normal completion */
case 0:
skb_put (skb, req->actual);
+#ifdef GADGET_RNDIS
+ if (dev->rndis) rndis_rm_hdr (req->buf, &(skb->len));
+#endif
if (MIN_PACKET > skb->len
|| skb->len > (MAX_PACKET + ETH_HLEN)) {
dev->stats.rx_errors++;
@@ -1650,6 +2028,23 @@
/* no buffer copies needed, unless the network stack did it
* or the hardware can't use skb buffers.
*/
+#ifdef GADGET_RNDIS
+ {
+ struct sk_buff *skb_rndis;
+
+ if (dev->rndis)
+ {
+ skb_rndis = skb_realloc_headroom (skb, sizeof (struct rndis_packet_msg_type));
+
+ if (!skb_rndis) goto drop;
+ dev_kfree_skb_any (skb);
+ skb = skb_rndis;
+ rndis_add_hdr (skb);
+ length = skb->len;
+ }
+ }
+#endif
+
req->buf = skb->data;
req->context = skb;
req->complete = tx_complete;
@@ -1684,6 +2079,9 @@
}
if (retval) {
+#ifdef GADGET_RNDIS
+drop:
+#endif
dev->stats.tx_dropped++;
dev_kfree_skb_any (skb);
spin_lock_irqsave (&dev->lock, flags);
@@ -1704,7 +2102,15 @@
/* and open the tx floodgates */
atomic_set (&dev->tx_qlen, 0);
- netif_wake_queue (dev->net);
+ netif_wake_queue (dev->net);
+#ifdef GADGET_RNDIS
+ if (dev->rndis)
+ {
+ rndis_set_param_medium (dev->rndis_config, NDIS_MEDIUM_802_3,
+ 120000);
+ rndis_send_media_state (dev, 1);
+ }
+#endif
}
static int eth_open (struct net_device *net)
@@ -1743,8 +2149,17 @@
usb_ep_disable (dev->status_ep);
usb_ep_enable (dev->status_ep, dev->status);
#endif
+#ifdef GADGET_RNDIS
+ usb_ep_disable (dev->rndis_status_ep);
+ usb_ep_enable (dev->rndis_status_ep, dev->rndis_status);
+ }
+
+ if (dev->rndis)
+ {
+ rndis_set_param_medium (dev->rndis_config, NDIS_MEDIUM_802_3, 0);
+ rndis_send_media_state (dev, 0);
+#endif
}
-
return 0;
}
@@ -1756,7 +2171,9 @@
struct eth_dev *dev = get_gadget_data (gadget);
DEBUG (dev, "unbind\n");
-
+#ifdef GADGET_RNDIS
+ rndis_deregister (dev->rndis_config);
+#endif
/* we've already been disconnected ... no i/o is active */
if (dev->req) {
usb_ep_free_buffer (gadget->ep0,
@@ -1867,16 +2284,37 @@
// SET_NETDEV_DEV (dev->net, &gadget->dev);
status = register_netdev (dev->net);
- if (status == 0) {
-
- INFO (dev, "%s, " CHIP ", version: " DRIVER_VERSION "\n",
- driver_desc);
+ if (status)
+ {
+ pr_debug("%s: register_netdev failed, %d\n", shortname, status);
+ goto fail;
+ }
+ INFO (dev, "%s, " CHIP ", version: " DRIVER_VERSION "\n",
+ driver_desc);
+#ifdef GADGET_RNDIS
+ {
+ u32 *vendorID;
+
+ dev->rndis_config = rndis_register (rndis_control_ack);
+
+ if (dev->rndis_config >= 0)
+ {
+ if (rndis_set_param_dev (dev->rndis_config, dev->net,
+ &dev->stats)) goto fail;
+ if (rndis_set_param_vendor (dev->rndis_config, vendorID,
+ rndis_vendor_string)) goto fail;
+ if (rndis_set_param_medium (dev->rndis_config,
+ NDIS_MEDIUM_802_3,
+ 0)) goto fail;
+ }
+ INFO (dev, "RNDIS activated\n");
+ }
+#endif
#ifdef DEV_CONFIG_CDC
- INFO (dev, "CDC host enet %s\n", ethaddr);
+ INFO (dev, "CDC host enet %s\n", ethaddr);
#endif
- return status;
- }
- pr_debug("%s: register_netdev failed, %d\n", shortname, status);
+
+ return status;
fail:
eth_unbind (gadget);
return status;
@@ -1906,7 +2344,7 @@
};
MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_AUTHOR ("David Brownell");
+MODULE_AUTHOR ("David Brownell, Benedikt Spranger");
MODULE_LICENSE ("GPL");
diff -urN gadget-2.4/drivers/usb/gadget/Makefile linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/Makefile
--- gadget-2.4/drivers/usb/gadget/Makefile 2004-03-19 11:47:16.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/Makefile 2004-03-22 12:06:30.000000000 +0100
@@ -25,6 +25,7 @@
g_ether-objs := ether.o usbstring.o config.o
obj-$(CONFIG_USB_ETH) += g_ether.o
+obj-$(CONFIG_USB_ETH_RNDIS) += rndis.o
gadgetfs-objs := inode.o usbstring.o
obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o
@@ -35,7 +36,7 @@
g_serial-objs := gserial.o usbstring.o
obj-$(CONFIG_USB_G_SERIAL) += g_serial.o
-export-objs := $(controller-y) $(controller-m)
+export-objs := $(controller-y) $(controller-m) rndis.o
include $(TOPDIR)/Rules.make
diff -urN gadget-2.4/drivers/usb/gadget/ndis.h linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/ndis.h
--- gadget-2.4/drivers/usb/gadget/ndis.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/ndis.h 2004-03-25 22:35:41.000000000 +0100
@@ -0,0 +1,187 @@
+/*
+ * ndis.h
+ *
+ * ntddndis.h modified by Benedikt Spranger <b.spranger@pengutronix.de>
+ *
+ * Thanks to the cygwin development team,
+ * espacially to Casper S. Hornstrup <chorns@users.sourceforge.net>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef _LINUX_NDIS_H
+#define _LINUX_NDIS_H
+
+
+#define NDIS_STATUS_MULTICAST_FULL 0xC0010009
+#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A
+#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B
+
+/* NDIS_PNP_CAPABILITIES.Flags constants */
+#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001
+#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002
+#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004
+
+/* Required Object IDs (OIDs) */
+#define OID_GEN_SUPPORTED_LIST 0x00010101
+#define OID_GEN_HARDWARE_STATUS 0x00010102
+#define OID_GEN_MEDIA_SUPPORTED 0x00010103
+#define OID_GEN_MEDIA_IN_USE 0x00010104
+#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105
+#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106
+#define OID_GEN_LINK_SPEED 0x00010107
+#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108
+#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109
+#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A
+#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B
+#define OID_GEN_VENDOR_ID 0x0001010C
+#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D
+#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E
+#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F
+#define OID_GEN_DRIVER_VERSION 0x00010110
+#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111
+#define OID_GEN_PROTOCOL_OPTIONS 0x00010112
+#define OID_GEN_MAC_OPTIONS 0x00010113
+#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
+#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115
+#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116
+#define OID_GEN_SUPPORTED_GUIDS 0x00010117
+#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118
+#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119
+#define OID_GEN_MACHINE_NAME 0x0001021A
+#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B
+#define OID_GEN_VLAN_ID 0x0001021C
+
+/* Optional OIDs */
+#define OID_GEN_MEDIA_CAPABILITIES 0x00010201
+#define OID_GEN_PHYSICAL_MEDIUM 0x00010202
+
+/* Required statistics OIDs */
+#define OID_GEN_XMIT_OK 0x00020101
+#define OID_GEN_RCV_OK 0x00020102
+#define OID_GEN_XMIT_ERROR 0x00020103
+#define OID_GEN_RCV_ERROR 0x00020104
+#define OID_GEN_RCV_NO_BUFFER 0x00020105
+
+/* Optional statistics OIDs */
+#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201
+#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
+#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203
+#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
+#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205
+#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
+#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207
+#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
+#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209
+#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
+#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B
+#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
+#define OID_GEN_RCV_CRC_ERROR 0x0002020D
+#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
+#define OID_GEN_GET_TIME_CAPS 0x0002020F
+#define OID_GEN_GET_NETCARD_TIME 0x00020210
+#define OID_GEN_NETCARD_LOAD 0x00020211
+#define OID_GEN_DEVICE_PROFILE 0x00020212
+#define OID_GEN_INIT_TIME_MS 0x00020213
+#define OID_GEN_RESET_COUNTS 0x00020214
+#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215
+#define OID_GEN_FRIENDLY_NAME 0x00020216
+#define OID_GEN_MINIPORT_INFO 0x00020217
+#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218
+
+/* IEEE 802.3 (Ethernet) OIDs */
+#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001
+
+#define OID_802_3_PERMANENT_ADDRESS 0x01010101
+#define OID_802_3_CURRENT_ADDRESS 0x01010102
+#define OID_802_3_MULTICAST_LIST 0x01010103
+#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104
+#define OID_802_3_MAC_OPTIONS 0x01010105
+#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
+#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
+#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
+#define OID_802_3_XMIT_DEFERRED 0x01020201
+#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
+#define OID_802_3_RCV_OVERRUN 0x01020203
+#define OID_802_3_XMIT_UNDERRUN 0x01020204
+#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205
+#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
+#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
+
+/* OID_GEN_MINIPORT_INFO constants */
+#define NDIS_MINIPORT_BUS_MASTER 0x00000001
+#define NDIS_MINIPORT_WDM_DRIVER 0x00000002
+#define NDIS_MINIPORT_SG_LIST 0x00000004
+#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008
+#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010
+#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020
+#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040
+#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080
+#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100
+#define NDIS_MINIPORT_IS_NDIS_5 0x00000200
+#define NDIS_MINIPORT_IS_CO 0x00000400
+#define NDIS_MINIPORT_DESERIALIZE 0x00000800
+#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000
+#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000
+#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000
+#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000
+#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000
+#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000
+#define NDIS_MINIPORT_HIDDEN 0x00040000
+#define NDIS_MINIPORT_SWENUM 0x00080000
+#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000
+#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000
+#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000
+#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000
+#define NDIS_MINIPORT_64BITS_DMA 0x01000000
+
+#define NDIS_MEDIUM_802_3 0x00000000
+#define NDIS_MEDIUM_802_5 0x00000001
+#define NDIS_MEDIUM_FDDI 0x00000002
+#define NDIS_MEDIUM_WAN 0x00000003
+#define NDIS_MEDIUM_LOCAL_TALK 0x00000004
+#define NDIS_MEDIUM_DIX 0x00000005
+#define NDIS_MEDIUM_ARCENT_RAW 0x00000006
+#define NDIS_MEDIUM_ARCENT_878_2 0x00000007
+#define NDIS_MEDIUM_ATM 0x00000008
+#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009
+#define NDIS_MEDIUM_IRDA 0x0000000A
+#define NDIS_MEDIUM_BPC 0x0000000B
+#define NDIS_MEDIUM_CO_WAN 0x0000000C
+#define NDIS_MEDIUM_1394 0x0000000D
+
+#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
+#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
+#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
+#define NDIS_PACKET_TYPE_BROADCAST 0x00000008
+#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
+#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
+#define NDIS_PACKET_TYPE_SMT 0x00000040
+#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
+#define NDIS_PACKET_TYPE_GROUP 0x00000100
+#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200
+#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400
+#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800
+
+#define NDIS_MEDIA_STATE_CONNECTED 0x00000000
+#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001
+
+#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001
+#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002
+#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004
+#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008
+#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010
+#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020
+#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040
+#define NDIS_MAC_OPTION_RESERVED 0x80000000
+
+#endif /* _LINUX_NDIS_H */
diff -urN gadget-2.4/drivers/usb/gadget/pxa2xx_udc.c linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/pxa2xx_udc.c
--- gadget-2.4/drivers/usb/gadget/pxa2xx_udc.c 2004-02-04 09:47:51.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/pxa2xx_udc.c 2004-03-25 22:35:41.000000000 +0100
@@ -23,8 +23,10 @@
*
*/
+#if 0
#define DEBUG 1
-// #define VERBOSE DBG_VERBOSE
+#define VERBOSE DBG_VERBOSE
+#endif
#include <linux/config.h>
#include <linux/module.h>
@@ -1728,6 +1730,7 @@
switch (u.r.bRequest) {
/* hardware restricts gadget drivers here! */
case USB_REQ_SET_CONFIGURATION:
+ printk ("USB_REQ_SET_CONFIGURATION\n");
if (u.r.bRequestType == USB_RECIP_DEVICE) {
/* reflect hardware's automagic
* up to the gadget driver.
@@ -2099,7 +2102,8 @@
},
/* control endpoint */
- .ep[0] = {
+ .ep = {
+ [0] = {
.ep = {
.name = ep0name,
.ops = &pxa2xx_ep_ops,
@@ -2111,7 +2115,7 @@
},
/* first group of endpoints */
- .ep[1] = {
+ [1] = {
.ep = {
.name = "ep1in-bulk",
.ops = &pxa2xx_ep_ops,
@@ -2125,7 +2129,7 @@
.reg_uddr = &UDDR1,
drcmr (25)
},
- .ep[2] = {
+ [2] = {
.ep = {
.name = "ep2out-bulk",
.ops = &pxa2xx_ep_ops,
@@ -2141,7 +2145,7 @@
drcmr (26)
},
#ifndef CONFIG_USB_PXA2XX_SMALL
- .ep[3] = {
+ [3] = {
.ep = {
.name = "ep3in-iso",
.ops = &pxa2xx_ep_ops,
@@ -2155,7 +2159,7 @@
.reg_uddr = &UDDR3,
drcmr (27)
},
- .ep[4] = {
+ [4] = {
.ep = {
.name = "ep4out-iso",
.ops = &pxa2xx_ep_ops,
@@ -2170,7 +2174,7 @@
.reg_uddr = &UDDR4,
drcmr (28)
},
- .ep[5] = {
+ [5] = {
.ep = {
.name = "ep5in-int",
.ops = &pxa2xx_ep_ops,
@@ -2185,7 +2189,7 @@
},
/* second group of endpoints */
- .ep[6] = {
+ [6] = {
.ep = {
.name = "ep6in-bulk",
.ops = &pxa2xx_ep_ops,
@@ -2199,7 +2203,7 @@
.reg_uddr = &UDDR6,
drcmr (30)
},
- .ep[7] = {
+ [7] = {
.ep = {
.name = "ep7out-bulk",
.ops = &pxa2xx_ep_ops,
@@ -2214,7 +2218,7 @@
.reg_uddr = &UDDR7,
drcmr (31)
},
- .ep[8] = {
+ [8] = {
.ep = {
.name = "ep8in-iso",
.ops = &pxa2xx_ep_ops,
@@ -2228,7 +2232,7 @@
.reg_uddr = &UDDR8,
drcmr (32)
},
- .ep[9] = {
+ [9] = {
.ep = {
.name = "ep9out-iso",
.ops = &pxa2xx_ep_ops,
@@ -2243,7 +2247,7 @@
.reg_uddr = &UDDR9,
drcmr (33)
},
- .ep[10] = {
+ [10] = {
.ep = {
.name = "ep10in-int",
.ops = &pxa2xx_ep_ops,
@@ -2258,7 +2262,7 @@
},
/* third group of endpoints */
- .ep[11] = {
+ [11] = {
.ep = {
.name = "ep11in-bulk",
.ops = &pxa2xx_ep_ops,
@@ -2272,7 +2276,7 @@
.reg_uddr = &UDDR11,
drcmr (35)
},
- .ep[12] = {
+ [12] = {
.ep = {
.name = "ep12out-bulk",
.ops = &pxa2xx_ep_ops,
@@ -2287,7 +2291,7 @@
.reg_uddr = &UDDR12,
drcmr (36)
},
- .ep[13] = {
+ [13] = {
.ep = {
.name = "ep13in-iso",
.ops = &pxa2xx_ep_ops,
@@ -2301,7 +2305,7 @@
.reg_uddr = &UDDR13,
drcmr (37)
},
- .ep[14] = {
+ [14] = {
.ep = {
.name = "ep14out-iso",
.ops = &pxa2xx_ep_ops,
@@ -2316,7 +2320,7 @@
.reg_uddr = &UDDR14,
drcmr (38)
},
- .ep[15] = {
+ [15] = {
.ep = {
.name = "ep15in-int",
.ops = &pxa2xx_ep_ops,
@@ -2330,6 +2334,7 @@
.reg_uddr = &UDDR15,
},
#endif /* !CONFIG_USB_PXA2XX_SMALL */
+ }
};
#define CP15R0_VENDOR_MASK 0xffffe000
diff -urN gadget-2.4/drivers/usb/gadget/pxa2xx_udc.h linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/pxa2xx_udc.h
--- gadget-2.4/drivers/usb/gadget/pxa2xx_udc.h 2004-02-04 09:47:51.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/pxa2xx_udc.h 2004-03-25 22:35:41.000000000 +0100
@@ -297,7 +297,15 @@
#ifdef CONFIG_ARCH_INNOKOM
if (machine_is_innokom()) {
GPSR(GPIO_INNOKOM_USB_ONOFF) = GPIO_bit(GPIO_INNOKOM_USB_ONOFF);
- printk("RS: disappear\n");
+ printk("innokom: disappear\n");
+ udelay(5);
+ return;
+ }
+#endif
+#ifdef CONFIG_ARCH_CSB226
+ if (machine_is_csb226()) {
+ GPCR0 |= 0x00000080;
+ printk("csb226: disappear\n");
udelay(5);
return;
}
@@ -349,7 +357,16 @@
#ifdef CONFIG_ARCH_INNOKOM
if (machine_is_innokom()) {
GPCR(GPIO_INNOKOM_USB_ONOFF) = GPIO_bit(GPIO_INNOKOM_USB_ONOFF);
- printk("RS: appear\n");
+ printk("innokom: appear\n");
+ udelay(5);
+ return;
+ }
+#endif
+#ifdef CONFIG_ARCH_CSB226
+ if (machine_is_csb226()) {
+ GPDR0 |= 0x00000080;
+ GPSR0 |= 0x00000080;
+ printk("csb226: appear\n");
udelay(5);
return;
}
diff -urN gadget-2.4/drivers/usb/gadget/rndis.c linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/rndis.c
--- gadget-2.4/drivers/usb/gadget/rndis.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/rndis.c 2004-03-25 22:35:41.000000000 +0100
@@ -0,0 +1,1412 @@
+/*
+ * RNDIS MSG parser
+ *
+ * Version: $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $
+ *
+ * Authors: Benedikt Spranger, Pengutronix
+ * Robert Schwebel, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, as published by the Free Software Foundation.
+ *
+ * Due to the Remote NDIS Specification License Agreement this
+ * program may only be used to interact with a Microsoft Windows
+ * operating system or a bus/network-connected communication
+ * device.
+ *
+ * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
+ * Fixed message length bug in init_response
+ *
+ * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
+ * Fixed rndis_rm_hdr length bug.
+ */
+
+#define DRIVER_DESC "Remote NDIS Function"
+
+#define RNDIS_MAX_CONFIGS 47
+
+static const char shortname [] = "RNDIS";
+static const char driver_desc [] = DRIVER_DESC;
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/system.h>
+
+#include "rndis.h"
+
+#define DEBUG if (rndis_debug) printk
+
+static struct proc_dir_entry *rndis_connect_dir;
+static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
+
+static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS];
+static int rndis_debug = 0;
+
+MODULE_PARM (rndis_debug, "i");
+MODULE_PARM_DESC (rndis_debug, "enable debugging");
+
+/* Driver Version */
+static const u32 rndis_driver_version = __constant_cpu_to_le32 (1);
+
+/* Function Prototypes */
+static int rndis_init_response (int configNr, rndis_init_msg_type *buf);
+static int rndis_query_response (int configNr, rndis_query_msg_type *buf);
+static int rndis_set_response (int configNr, rndis_set_msg_type *buf);
+static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf);
+static int rndis_keepalive_response (int configNr,
+ rndis_keepalive_msg_type *buf);
+
+static rndis_resp_t *rndis_add_response (int configNr, u32 length);
+
+/* helper functions */
+static u32 devFlags2currentFilter (struct net_device *dev)
+{
+ u32 filter = 0;
+
+ if (!dev) return 0;
+
+ if (dev->flags & IFF_MULTICAST)
+ filter |= NDIS_PACKET_TYPE_MULTICAST;
+ if (dev->flags & IFF_BROADCAST)
+ filter |= NDIS_PACKET_TYPE_BROADCAST;
+ if (dev->flags & IFF_ALLMULTI)
+ filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
+ if (dev->flags & IFF_PROMISC)
+ filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
+
+ return filter;
+}
+
+static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev)
+{
+ if (!dev) return;
+
+ if (currentFilter & NDIS_PACKET_TYPE_MULTICAST)
+ dev->flags |= IFF_MULTICAST;
+ if (currentFilter & NDIS_PACKET_TYPE_BROADCAST)
+ dev->flags |= IFF_BROADCAST;
+ if (currentFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
+ dev->flags |= IFF_ALLMULTI;
+ if (currentFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
+ dev->flags |= IFF_PROMISC;
+}
+
+
+/* NDIS Functions */
+static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
+{
+ int retval = -ENOTSUPP;
+ u32 length = 0;
+ rndis_query_cmplt_type *resp;
+
+ if (!r) return -ENOMEM;
+ resp = (rndis_query_cmplt_type *) r->buf;
+
+ if (!resp) return -ENOMEM;
+
+ if (!resp) return -ENOMEM;
+
+ switch (OID)
+ {
+ /* mandatory */
+ case OID_GEN_SUPPORTED_LIST:
+ DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
+ length = sizeof (oid_supported_list);
+ memcpy ((u8 *) resp + 24, oid_supported_list, length);
+ retval = 0;
+ break;
+
+ /* mandatory */
+ case OID_GEN_HARDWARE_STATUS:
+ DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
+ length = 4;
+ /* Bogus question!
+ * Hardware must be ready to recieve high level protocols.
+ * BTW:
+ * reddite ergo quae sunt Caesaris Caesari
+ * et quae sunt Dei Deo!
+ */
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ break;
+
+ /* mandatory */
+ case OID_GEN_MEDIA_SUPPORTED:
+ DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].medium;
+ retval = 0;
+ break;
+
+ /* mandatory */
+ case OID_GEN_MEDIA_IN_USE:
+ DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
+ length = 4;
+ /* one medium, one transport... (maybe you do it better) */
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].medium;
+ retval = 0;
+ break;
+
+ case OID_GEN_MAXIMUM_LOOKAHEAD:
+ DEBUG("%s: OID_GEN_MAXIMUM_LOOKAHEAD\n", __FUNCTION__);
+ break;
+
+ /* mandatory */
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+ DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].dev)
+ {
+ length = 4;
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].dev->mtu;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ /* mandatory */
+ case OID_GEN_LINK_SPEED:
+ DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
+ length = 4;
+ if (rndis_per_dev_params [configNr].media_state)
+ *((u32 *) resp + 6) = 0;
+ else
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].speed;
+ retval = 0;
+ break;
+
+ case OID_GEN_TRANSMIT_BUFFER_SPACE:
+ DEBUG("%s: OID_GEN_TRANSMIT_BUFFER_SPACE\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ break;
+
+ case OID_GEN_RECEIVE_BUFFER_SPACE:
+ DEBUG("%s: OID_GEN_RECEIVE_BUFFER_SPACE\n", __FUNCTION__);
+ break;
+
+ /* mandatory */
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+ DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].dev)
+ {
+ length = 4;
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].dev->mtu;
+ retval = 0;
+ }
+ break;
+
+ /* mandatory */
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+ DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].dev)
+ {
+ length = 4;
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].dev->mtu;
+ retval = 0;
+ }
+ break;
+
+ /* mandatory */
+ case OID_GEN_VENDOR_ID:
+ DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].vendorID;
+ retval = 0;
+ break;
+
+ /* mandatory */
+ case OID_GEN_VENDOR_DESCRIPTION:
+ DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
+ length = strlen (rndis_per_dev_params [configNr].vendorDescr);
+ memcpy ((u8 *) resp + 24,
+ rndis_per_dev_params [configNr].vendorDescr, length);
+ retval = 0;
+ break;
+
+ /* mandatory */
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = devFlags2currentFilter (rndis_per_dev_params [configNr].dev);
+ retval = 0;
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+ DEBUG("%s: OID_GEN_CURRENT_LOOKAHEAD\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_DRIVER_VERSION:
+ DEBUG("%s: OID_GEN_DRIVER_VERSION\n", __FUNCTION__);
+ break;
+
+ /* mandatory */
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+ DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = RNDIS_MAX_TOTAL_SIZE;
+ retval = 0;
+ break;
+
+ case OID_GEN_PROTOCOL_OPTIONS:
+ DEBUG("%s: OID_GEN_PROTOCOL_OPTIONS\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_MAC_OPTIONS:
+ DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
+ NDIS_MAC_OPTION_FULL_DUPLEX;
+ retval = 0;
+ break;
+
+ /* mandatory */
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+ DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].media_state;
+ retval = 0;
+ break;
+
+ case OID_GEN_MAXIMUM_SEND_PACKETS:
+ DEBUG("%s: OID_GEN_MAXIMUM_SEND_PACKETS\n", __FUNCTION__);
+ break;
+
+ /* mandatory */
+ case OID_GEN_VENDOR_DRIVER_VERSION:
+ DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = rndis_driver_version;
+ retval = 0;
+ break;
+
+ case OID_GEN_SUPPORTED_GUIDS:
+ DEBUG("%s: OID_GEN_SUPPORTED_GUIDS\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_NETWORK_LAYER_ADDRESSES:
+ DEBUG("%s: OID_GEN_NETWORK_LAYER_ADDRESSES\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_TRANSPORT_HEADER_OFFSET:
+ DEBUG("%s: OID_GEN_TRANSPORT_HEADER_OFFSET\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_MACHINE_NAME:
+ DEBUG("%s: OID_GEN_MACHINE_NAME\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_RNDIS_CONFIG_PARAMETER:
+ DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ break;
+
+ case OID_GEN_VLAN_ID:
+ DEBUG("%s: OID_GEN_VLAN_ID\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_MEDIA_CAPABILITIES:
+ DEBUG("%s: OID_GEN_MEDIA_CAPABILITIES\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_PHYSICAL_MEDIUM:
+ DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ break;
+
+ /* mandatory */
+ case OID_GEN_XMIT_OK:
+ DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ length = 4;
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->tx_packets -
+ rndis_per_dev_params [configNr].stats->tx_errors -
+ rndis_per_dev_params [configNr].stats->tx_dropped;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ /* mandatory */
+ case OID_GEN_RCV_OK:
+ DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ length = 4;
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->rx_packets -
+ rndis_per_dev_params [configNr].stats->rx_errors -
+ rndis_per_dev_params [configNr].stats->rx_dropped;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ /* mandatory */
+ case OID_GEN_XMIT_ERROR:
+ DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ length = 4;
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->tx_errors;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ /* mandatory */
+ case OID_GEN_RCV_ERROR:
+ DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->rx_errors;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ /* mandatory */
+ case OID_GEN_RCV_NO_BUFFER:
+ DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->rx_dropped;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_DIRECTED_BYTES_XMIT:
+ DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
+ /*
+ * Aunt Tilly's size of shoes
+ * minus antarctica count of penguins
+ * divided by weight of Alpha Centauri
+ */
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ length = 4;
+ *((u32 *) resp + 6) = (rndis_per_dev_params [configNr].stats->tx_packets -
+ rndis_per_dev_params [configNr].stats->tx_errors -
+ rndis_per_dev_params [configNr].stats->tx_dropped)*123;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_DIRECTED_FRAMES_XMIT:
+ DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
+ /* dito */
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ length = 4;
+ *((u32 *) resp + 6) = (rndis_per_dev_params [configNr].stats->tx_packets -
+ rndis_per_dev_params [configNr].stats->tx_errors -
+ rndis_per_dev_params [configNr].stats->tx_dropped)/123;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_MULTICAST_BYTES_XMIT:
+ DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->multicast*1234;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_MULTICAST_FRAMES_XMIT:
+ DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->multicast;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_BROADCAST_BYTES_XMIT:
+ DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->tx_packets/42*255;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_BROADCAST_FRAMES_XMIT:
+ DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->tx_packets/42;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_DIRECTED_BYTES_RCV:
+ DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ break;
+
+ case OID_GEN_DIRECTED_FRAMES_RCV:
+ DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ break;
+
+ case OID_GEN_MULTICAST_BYTES_RCV:
+ DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->multicast*1111;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_MULTICAST_FRAMES_RCV:
+ DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->multicast;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_BROADCAST_BYTES_RCV:
+ DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->rx_packets/42*255;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_BROADCAST_FRAMES_RCV:
+ DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->rx_packets/42;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_RCV_CRC_ERROR:
+ DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->rx_crc_errors;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ case OID_GEN_TRANSMIT_QUEUE_LENGTH:
+ DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ break;
+
+ case OID_GEN_GET_TIME_CAPS:
+ DEBUG("%s: OID_GEN_GET_TIME_CAPS\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_GET_NETCARD_TIME:
+ DEBUG("%s: OID_GEN_GET_NETCARD_TIME\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_NETCARD_LOAD:
+ DEBUG("%s: OID_GEN_NETCARD_LOAD\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_DEVICE_PROFILE:
+ DEBUG("%s: OID_GEN_DEVICE_PROFILE\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_INIT_TIME_MS:
+ DEBUG("%s: OID_GEN_INIT_TIME_MS\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_RESET_COUNTS:
+ DEBUG("%s: OID_GEN_RESET_COUNTS\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_MEDIA_SENSE_COUNTS:
+ DEBUG("%s: OID_GEN_MEDIA_SENSE_COUNTS\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_FRIENDLY_NAME:
+ DEBUG("%s: OID_GEN_FRIENDLY_NAME\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_MINIPORT_INFO:
+ DEBUG("%s: OID_GEN_MINIPORT_INFO\n", __FUNCTION__);
+ break;
+
+ case OID_GEN_RESET_VERIFY_PARAMETERS:
+ DEBUG("%s: OID_GEN_RESET_VERIFY_PARAMETERS\n", __FUNCTION__);
+ break;
+
+ /* mandatory */
+ case OID_802_3_PERMANENT_ADDRESS:
+ DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].dev)
+ {
+ length = 6;
+ memcpy ((u8 *) resp + 24, rndis_per_dev_params [configNr].dev->dev_addr, length);
+ /*
+ * we need a MAC address and hope that
+ * (our MAC + 1) is not in use
+ */
+ *((u8 *) resp + 29) += 1;
+ retval = 0;
+ }
+ else
+ {
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ }
+ break;
+
+ /* mandatory */
+ case OID_802_3_CURRENT_ADDRESS:
+ DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].dev)
+ {
+ length = 6;
+ memcpy ((u8 *) resp + 24, rndis_per_dev_params [configNr].dev->dev_addr, length);
+ /*
+ * we need a MAC address and hope that
+ * (our MAC + 1) is not in use
+ */
+ *((u8 *) resp + 29) += 1;
+ retval = 0;
+ }
+ break;
+
+ /* mandatory */
+ case OID_802_3_MULTICAST_LIST:
+ DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
+ length = 4;
+ /* Multicast base address only */
+ *((u32 *) resp + 6) = 0xE0000000;
+ retval = 0;
+ break;
+
+ /* mandatory */
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+ DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
+ length = 4;
+ /* Multicast base address only */
+ *((u32 *) resp + 6) = 1;
+ retval = 0;
+ break;
+
+ case OID_802_3_MAC_OPTIONS:
+ DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
+ break;
+
+ /* mandatory */
+ case OID_802_3_RCV_ERROR_ALIGNMENT:
+ DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
+ if (rndis_per_dev_params [configNr].stats)
+ {
+ length = 4;
+ *((u32 *) resp + 6) = rndis_per_dev_params [configNr].stats->rx_frame_errors;
+ retval = 0;
+ }
+ break;
+
+ /* mandatory */
+ case OID_802_3_XMIT_ONE_COLLISION:
+ DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ break;
+
+ /* mandatory */
+ case OID_802_3_XMIT_MORE_COLLISIONS:
+ DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
+ length = 4;
+ *((u32 *) resp + 6) = 0;
+ retval = 0;
+ break;
+
+ case OID_802_3_XMIT_DEFERRED:
+ DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
+ /* TODO */
+ break;
+
+ case OID_802_3_XMIT_MAX_COLLISIONS:
+ DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__);
+ /* TODO */
+ break;
+
+ case OID_802_3_RCV_OVERRUN:
+ DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__);
+ /* TODO */
+ break;
+
+ case OID_802_3_XMIT_UNDERRUN:
+ DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__);
+ /* TODO */
+ break;
+
+ case OID_802_3_XMIT_HEARTBEAT_FAILURE:
+ DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__);
+ /* TODO */
+ break;
+
+ case OID_802_3_XMIT_TIMES_CRS_LOST:
+ DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__);
+ /* TODO */
+ break;
+
+ case OID_802_3_XMIT_LATE_COLLISIONS:
+ DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
+ /* TODO */
+ break;
+
+ default: printk (KERN_ERR "%s: unknown OID 0x%08X\n",
+ __FUNCTION__, OID);
+ }
+
+ resp->InformationBufferOffset = 16;
+ resp->InformationBufferLength = length;
+ resp->MessageLength = 24 + length;
+ r->length = 24 + length;
+ return retval;
+}
+
+static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
+ rndis_resp_t *r)
+{
+ rndis_set_cmplt_type *resp;
+ int i, retval = -ENOTSUPP;
+ struct rndis_config_parameter *param;
+
+ if (!r) return -ENOMEM;
+ resp = (rndis_set_cmplt_type *) r->buf;
+
+ if (!resp) return -ENOMEM;
+
+ switch (OID)
+ {
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
+ currentFilter2devFlags ((u32) ((u8 *) resp + 28),
+ rndis_per_dev_params [configNr].dev);
+ retval = 0;
+ if ((u32) ((u8 *) resp + 28))
+ rndis_per_dev_params [configNr].state = RNDIS_INITIALIZED;
+ else
+ rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED;
+ break;
+
+ case OID_802_3_MULTICAST_LIST:
+ /* I think we can ignore this */
+ DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
+ retval = 0;
+ break;
+
+ case OID_GEN_RNDIS_CONFIG_PARAMETER:
+ DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__);
+ param = (struct rndis_config_parameter *) buf;
+ if (param)
+ {
+ for (i = 0; i < param->ParameterNameLength; i++)
+ {
+ DEBUG ("%c",
+ *(buf + param->ParameterNameOffset + i));
+ }
+ DEBUG ("\n");
+ }
+
+ retval = 0;
+ break;
+
+ default: printk (KERN_ERR "%s: unknown OID 0x%08X\n",
+ __FUNCTION__, OID);
+ }
+
+ return retval;
+}
+
+/*
+ * Response Functions
+ */
+
+static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
+{
+ rndis_init_cmplt_type *resp;
+ rndis_resp_t *r;
+
+ if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
+
+ r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
+
+ if (!r) return -ENOMEM;
+
+ resp = (rndis_init_cmplt_type *) r->buf;
+
+ if (!resp) return -ENOMEM;
+
+ resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
+ resp->MessageLength = 52;
+ resp->RequestID = buf->RequestID;
+ resp->Status = RNDIS_STATUS_SUCCESS;
+ resp->MajorVersion = RNDIS_MAJOR_VERSION;
+ resp->MinorVersion = RNDIS_MINOR_VERSION;
+ resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
+ resp->Medium = RNDIS_MEDIUM_802_3;
+ resp->MaxPacketsPerTransfer = 1;
+ resp->MaxTransferSize = rndis_per_dev_params [configNr].dev->mtu +
+ sizeof (struct ethhdr) + sizeof (struct rndis_packet_msg_type) + 22;
+ resp->PacketAlignmentFactor = 0;
+ resp->AFListOffset = 0;
+ resp->AFListSize = 0;
+
+ if (rndis_per_dev_params [configNr].ack)
+ rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev);
+
+ return 0;
+}
+
+static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
+{
+ rndis_query_cmplt_type *resp;
+ rndis_resp_t *r;
+
+ DEBUG("%s: OID = %08X\n", __FUNCTION__, buf->OID);
+ if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
+
+ /*
+ * we need more memory:
+ * oid_supported_list is the largest answer
+ */
+ r = rndis_add_response (configNr, sizeof (oid_supported_list));
+
+ if (!r) return -ENOMEM;
+ resp = (rndis_query_cmplt_type *) r->buf;
+
+ if (!resp) return -ENOMEM;
+
+ resp->MessageType = REMOTE_NDIS_QUERY_CMPLT;
+ resp->MessageLength = 24;
+ resp->RequestID = buf->RequestID;
+
+ if (gen_ndis_query_resp (configNr, buf->OID, r))
+ {
+ /* OID not supported */
+ resp->Status = RNDIS_STATUS_NOT_SUPPORTED;
+ resp->InformationBufferLength = 0;
+ resp->InformationBufferOffset = 0;
+ }
+ else resp->Status = RNDIS_STATUS_SUCCESS;
+
+ if (rndis_per_dev_params [configNr].ack)
+ rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev);
+ return 0;
+}
+
+static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
+{
+ rndis_set_cmplt_type *resp;
+ rndis_resp_t *r;
+ int i;
+
+ r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
+
+ if (!r) return -ENOMEM;
+ resp = (rndis_set_cmplt_type *) r->buf;
+ if (!resp) return -ENOMEM;
+
+ DEBUG("%s: Length: %d\n", __FUNCTION__, buf->InformationBufferLength);
+ DEBUG("%s: Offset: %d\n", __FUNCTION__, buf->InformationBufferOffset);
+ DEBUG("%s: InfoBuffer: ", __FUNCTION__);
+
+ for (i = 0; i < buf->InformationBufferLength; i++)
+ {
+ DEBUG ("%02x ", *(((u8 *) buf) + i + 12 +
+ buf->InformationBufferOffset));
+ }
+
+ DEBUG ("\n");
+
+ resp->MessageType = REMOTE_NDIS_SET_CMPLT;
+ resp->MessageLength = 16;
+ resp->RequestID = buf->RequestID;
+ if (gen_ndis_set_resp (configNr, buf->OID,
+ ((u8 *) buf) + 28,
+ buf->InformationBufferLength, r))
+ resp->Status = RNDIS_STATUS_NOT_SUPPORTED;
+ else resp->Status = RNDIS_STATUS_SUCCESS;
+
+ if (rndis_per_dev_params [configNr].ack)
+ rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev);
+
+ return 0;
+}
+
+static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
+{
+ rndis_reset_cmplt_type *resp;
+ rndis_resp_t *r;
+
+ r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
+
+ if (!r) return -ENOMEM;
+ resp = (rndis_reset_cmplt_type *) r->buf;
+ if (!resp) return -ENOMEM;
+
+ resp->MessageType = REMOTE_NDIS_RESET_CMPLT;
+ resp->MessageLength = 16;
+ resp->Status = RNDIS_STATUS_SUCCESS;
+ resp->AddressingReset = 1; /* resent information */
+
+ if (rndis_per_dev_params [configNr].ack)
+ rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev);
+
+ return 0;
+}
+
+static int rndis_keepalive_response (int configNr,
+ rndis_keepalive_msg_type *buf)
+{
+ rndis_keepalive_cmplt_type *resp;
+ rndis_resp_t *r;
+
+ /* respond only in RNDIS_INITIALIZED state */
+ if (rndis_per_dev_params [configNr].state != RNDIS_INITIALIZED)
+ return 0;
+ r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));
+ resp = (rndis_keepalive_cmplt_type *) r->buf;
+ if (!resp) return -ENOMEM;
+
+ resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
+ resp->MessageLength = 16;
+ resp->RequestID = buf->RequestID;
+ resp->Status = RNDIS_STATUS_SUCCESS;
+
+ if (rndis_per_dev_params [configNr].ack)
+ rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev);
+
+ return 0;
+}
+
+
+/*
+ * Device to Host Comunication
+ */
+static int rndis_indicate_status_msg (int configNr, u32 status)
+{
+ rndis_indicate_status_msg_type *resp;
+ rndis_resp_t *r;
+
+ if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED)
+ return -ENOTSUPP;
+
+ r = rndis_add_response (configNr,
+ sizeof (rndis_indicate_status_msg_type));
+ if (!r) return -ENOMEM;
+
+ resp = (rndis_indicate_status_msg_type *) r->buf;
+ if (!resp) return -ENOMEM;
+
+ resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
+ resp->MessageLength = 20;
+ resp->Status = status;
+ resp->StatusBufferLength = 0;
+ resp->StatusBufferOffset = 0;
+
+ if (rndis_per_dev_params [configNr].ack)
+ rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev);
+ return 0;
+}
+
+int rndis_signal_connect (int configNr)
+{
+ rndis_per_dev_params [configNr].media_state = NDIS_MEDIA_STATE_CONNECTED;
+ return rndis_indicate_status_msg (configNr,
+ RNDIS_STATUS_MEDIA_CONNECT);
+}
+
+int rndis_signal_disconnect (int configNr)
+{
+ rndis_per_dev_params [configNr].media_state = NDIS_MEDIA_STATE_DISCONNECTED;
+ return rndis_indicate_status_msg (configNr,
+ RNDIS_STATUS_MEDIA_DISCONNECT);
+}
+
+/*
+ * Message Parser
+ */
+int rndis_msg_parser (u8 configNr, u8 *buf)
+{
+ u32 MsgType, MsgLength, *tmp;
+
+ if (!buf) return -ENOMEM;
+
+ tmp = (u32 *) buf;
+ MsgType = *tmp;
+ MsgLength = *(tmp + 1);
+
+ if (configNr >= RNDIS_MAX_CONFIGS) return -ENOTSUPP;
+
+ switch (MsgType)
+ {
+ case REMOTE_NDIS_INIZIALIZE_MSG:
+ DEBUG(KERN_INFO "%s: REMOTE_NDIS_INIZIALIZE_MSG\n",
+ __FUNCTION__ );
+ rndis_per_dev_params [configNr].state = RNDIS_INITIALIZED;
+ return rndis_init_response (configNr,
+ (rndis_init_msg_type *) buf);
+ break;
+
+ case REMOTE_NDIS_HALT_MSG:
+ DEBUG(KERN_INFO "%s: REMOTE_NDIS_HALT_MSG\n",
+ __FUNCTION__ );
+ rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED;
+ return 0;
+
+ case REMOTE_NDIS_QUERY_MSG:
+ DEBUG(KERN_INFO "%s: REMOTE_NDIS_QUERY_MSG\n",
+ __FUNCTION__ );
+ return rndis_query_response (configNr,
+ (rndis_query_msg_type *) buf);
+ break;
+
+ case REMOTE_NDIS_SET_MSG:
+ DEBUG(KERN_INFO "%s: REMOTE_NDIS_SET_MSG\n",
+ __FUNCTION__ );
+ return rndis_set_response (configNr,
+ (rndis_set_msg_type *) buf);
+ break;
+
+ case REMOTE_NDIS_RESET_MSG:
+ DEBUG(KERN_INFO "%s: REMOTE_NDIS_RESET_MSG\n",
+ __FUNCTION__ );
+ return rndis_reset_response (configNr,
+ (rndis_reset_msg_type *) buf);
+ break;
+
+ case REMOTE_NDIS_KEEPALIVE_MSG:
+ DEBUG(KERN_INFO "%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
+ __FUNCTION__ );
+ return rndis_keepalive_response (configNr,
+ (rndis_keepalive_msg_type *)
+ buf);
+ break;
+
+ default:
+ printk (KERN_ERR "%s: unknown RNDIS Message Type 0x%08X\n",
+ __FUNCTION__ , MsgType);
+ break;
+ }
+
+ return -ENOTSUPP;
+}
+
+int rndis_register (int (* rndis_control_ack) (struct net_device *))
+{
+ u8 i;
+ DEBUG("%s: ", __FUNCTION__ );
+
+ for (i = 0; i < RNDIS_MAX_CONFIGS; i++)
+ {
+ if (!rndis_per_dev_params [i].used)
+ {
+ rndis_per_dev_params [i].used = 1;
+ rndis_per_dev_params [i].ack = rndis_control_ack;
+ DEBUG("configNr = %d\n", i);
+ return i;
+ }
+ }
+ DEBUG("failed\n");
+
+ return -1;
+}
+
+void rndis_deregister (int configNr)
+{
+ DEBUG("%s: ", __FUNCTION__ );
+
+ if (configNr >= RNDIS_MAX_CONFIGS) return;
+ rndis_per_dev_params [configNr].used = 0;
+
+ return;
+}
+
+int rndis_set_param_dev (u8 configNr, struct net_device *dev,
+ struct net_device_stats *stats)
+{
+ DEBUG("%s: ", __FUNCTION__ );
+ if (!dev || !stats) return -1;
+ if (configNr >= RNDIS_MAX_CONFIGS) return -1;
+
+ rndis_per_dev_params [configNr].dev = dev;
+ rndis_per_dev_params [configNr].stats = stats;
+
+ return 0;
+}
+
+int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
+{
+ DEBUG("%s: ", __FUNCTION__ );
+ if (!vendorDescr) return -1;
+ if (configNr >= RNDIS_MAX_CONFIGS) return -1;
+
+ rndis_per_dev_params [configNr].vendorID = vendorID;
+ rndis_per_dev_params [configNr].vendorDescr = vendorDescr;
+
+ return 0;
+}
+
+int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
+{
+ DEBUG("%s: ", __FUNCTION__ );
+ if (configNr >= RNDIS_MAX_CONFIGS) return -1;
+
+ rndis_per_dev_params [configNr].medium = medium;
+ rndis_per_dev_params [configNr].speed = speed;
+
+ return 0;
+}
+
+void rndis_add_hdr (struct sk_buff *skb)
+{
+ if (!skb) return;
+ skb_push (skb, sizeof (struct rndis_packet_msg_type));
+ memset (skb->data, 0, sizeof (struct rndis_packet_msg_type));
+ *((u32 *) skb->data) = 1;
+ *((u32 *) skb->data + 1) = skb->len;
+ *((u32 *) skb->data + 2) = 36;
+ *((u32 *) skb->data + 3) = skb->len - 44;
+
+ return;
+}
+
+void rndis_free_response (int configNr, u8 *buf)
+{
+ rndis_resp_t *r;
+ struct list_head *act, *tmp;
+
+ list_for_each_safe (act, tmp,
+ &(rndis_per_dev_params [configNr].resp_queue))
+ {
+ r = list_entry (act, rndis_resp_t, list);
+ if (r && r->buf == buf)
+ {
+ list_del (&r->list);
+ kfree (r);
+ }
+ }
+}
+
+u8 *rndis_get_next_response (int configNr, u32 *length)
+{
+ rndis_resp_t *r;
+ struct list_head *act, *tmp;
+
+ if (!length) return NULL;
+
+ list_for_each_safe (act, tmp,
+ &(rndis_per_dev_params [configNr].resp_queue))
+ {
+ r = list_entry (act, rndis_resp_t, list);
+ if (!r->send)
+ {
+ r->send = 1;
+ *length = r->length;
+ return r->buf;
+ }
+ }
+
+ return NULL;
+}
+
+static rndis_resp_t *rndis_add_response (int configNr, u32 length)
+{
+ rndis_resp_t *r;
+
+ r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC);
+ if (!r) return NULL;
+
+ r->buf = (u8 *) (r + 1);
+ r->length = length;
+ r->send = 0;
+
+ list_add_tail (&r->list,
+ &(rndis_per_dev_params [configNr].resp_queue));
+ return r;
+}
+
+int rndis_rm_hdr (u8 *buf, u32 *length)
+{
+ u32 i, messageLen, dataOffset;
+
+ if (!buf || !length) return -1;
+ if (*((u32 *) buf) != 1) return -1;
+
+ messageLen = *((u32 *) buf + 1);
+
+ dataOffset = *((u32 *) buf + 2) + 8;
+ if (messageLen < dataOffset || messageLen > *length) return -1;
+
+ for (i = dataOffset; i < messageLen; i++)
+ buf [i - dataOffset] = buf [i];
+
+ *length = messageLen - dataOffset;
+
+ return 0;
+}
+
+int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
+ void *data)
+{
+ char *out = page;
+ int len;
+ rndis_params *param = (rndis_params *) data;
+
+ out += snprintf (out, count,
+ "Config Nr. %d\n"
+ "used : %s\n"
+ "state : %s\n"
+ "medium : 0x%08X\n"
+ "speed : %d\n"
+ "cable : %s\n"
+ "vendor ID : 0x%08X\n"
+ "vendor : %s\n",
+ param->confignr, (param->used) ? "y" : "n",
+ (param->state) ? "RNDIS_INITIALIZED" : "RNDIS_UNINITIALIZED",
+ param->medium,
+ (param->media_state) ? 0 : param->speed*100,
+ (param->media_state) ? "disconnected" : "connected",
+ param->vendorID, param->vendorDescr);
+
+ len = out - page;
+ len -= off;
+
+ if (len < count)
+ {
+ *eof = 1;
+ if (len <= 0) return 0;
+ }
+ else len = count;
+
+ *start = page + off;
+ return len;
+}
+
+int rndis_proc_write (struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ u32 speed = 0;
+ int i, fl_speed = 0;
+
+ for (i = 0; i < count; i++)
+ {
+ switch (*buffer)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ fl_speed = 1;
+ speed = speed*10 + *buffer - '0';
+ break;
+ case 'C':
+ case 'c':
+ rndis_signal_connect (((rndis_params *) data)->confignr);
+ break;
+ case 'D':
+ case 'd':
+ rndis_signal_disconnect (((rndis_params *) data)->confignr);
+ break;
+ default:
+ if (fl_speed) ((rndis_params *) data)->speed = speed;
+ else DEBUG ("%c is not valid\n", *buffer);
+ break;
+ }
+
+ buffer++;
+ }
+
+ return count;
+}
+
+static int __init init (void)
+{
+ u8 i;
+ char name [4];
+
+ if (!(rndis_connect_dir = proc_mkdir ("rndis", NULL)))
+ {
+ printk (KERN_ERR "%s: couldn't create /proc/rndis entry",
+ __FUNCTION__);
+ return -EIO;
+ }
+
+ for (i = 0; i < RNDIS_MAX_CONFIGS; i++)
+ {
+ sprintf (name, "%03d", i);
+ if (!(rndis_connect_state [i] = create_proc_entry (name, 0660,
+ rndis_connect_dir)))
+ {
+ DEBUG ("%s :remove entries", __FUNCTION__);
+ for (i--; i > 0; i--)
+ {
+ sprintf (name, "%03d", i);
+ remove_proc_entry (name, rndis_connect_dir);
+ }
+
+ remove_proc_entry ("000", rndis_connect_dir);
+ remove_proc_entry ("rndis", NULL);
+ return -EIO;
+ }
+ rndis_connect_state [i]->nlink = 1;
+ rndis_connect_state [i]->write_proc = rndis_proc_write;
+ rndis_connect_state [i]->read_proc = rndis_proc_read;
+ rndis_connect_state [i]->data = (void *) (rndis_per_dev_params + i);
+ rndis_per_dev_params [i].confignr = i;
+ rndis_per_dev_params [i].used = 0;
+ rndis_per_dev_params [i].state = RNDIS_UNINITIALIZED;
+ rndis_per_dev_params [i].media_state = NDIS_MEDIA_STATE_DISCONNECTED;
+ INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue));
+ }
+
+ return 0;
+}
+
+module_init (init);
+
+static void __exit cleanup (void)
+{
+ u8 i;
+ char name [4];
+
+ for (i = 0; i < RNDIS_MAX_CONFIGS; i++)
+ {
+ sprintf (name, "%03d", i);
+ remove_proc_entry (name, rndis_connect_dir);
+ }
+ remove_proc_entry ("rndis", NULL);
+ return;
+}
+
+module_exit (cleanup);
+
+EXPORT_SYMBOL(rndis_msg_parser);
+EXPORT_SYMBOL(rndis_register);
+EXPORT_SYMBOL(rndis_deregister);
+EXPORT_SYMBOL(rndis_set_param_dev);
+EXPORT_SYMBOL(rndis_set_param_medium);
+EXPORT_SYMBOL(rndis_set_param_vendor);
+EXPORT_SYMBOL(rndis_add_hdr);
+EXPORT_SYMBOL(rndis_rm_hdr);
+EXPORT_SYMBOL(rndis_signal_connect);
+EXPORT_SYMBOL(rndis_signal_disconnect);
+EXPORT_SYMBOL(rndis_get_next_response);
+EXPORT_SYMBOL(rndis_free_response);
+MODULE_DESCRIPTION (DRIVER_DESC);
+MODULE_AUTHOR ("Robert Schwebel <r.schwebel@pengutronix.de>, "\
+ "Benedikt Spranger <b.spranger@pengutronix.de>");
+MODULE_LICENSE ("GPL");
+
diff -urN gadget-2.4/drivers/usb/gadget/rndis.h linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/rndis.h
--- gadget-2.4/drivers/usb/gadget/rndis.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/rndis.h 2004-03-25 22:35:41.000000000 +0100
@@ -0,0 +1,314 @@
+/*
+ * RNDIS Definitions for Remote NDIS
+ *
+ * Version: $Id: rndis.h,v 1.15 2004/03/25 21:33:46 robert Exp $
+ *
+ * Authors: Benedikt Spranger, Pengutronix
+ * Robert Schwebel, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, as published by the Free Software Foundation.
+ *
+ * Due to the Remote NDIS Specification License Agreement this
+ * program may only be used to interact with a Microsoft Windows
+ * operating system or a bus/network-connected communication
+ * device.
+ */
+
+#include <asm/byteorder.h>
+#include <linux/netdevice.h>
+#include "ndis.h"
+
+#ifndef _LINUX_RNDIS_H
+#define _LINUX_RNDIS_H
+
+const char rndis_vendor_string [] = "GNU Linux";
+
+#define RNDIS_MAXIMUM_FRAME_SIZE 1518
+#define RNDIS_MAX_TOTAL_SIZE 1558
+
+/* Remote NDIS Versions */
+#define RNDIS_MAJOR_VERSION 1
+#define RNDIS_MINOR_VERSION 0
+
+/* Status Values */
+#define RNDIS_STATUS_SUCCESS 0x00000000U /* Success */
+#define RNDIS_STATUS_FAILURE 0xC0000001U /* Unspecified error */
+#define RNDIS_STATUS_INVALID_DATA 0xC0010015U /* Invalid data */
+#define RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBU /* Unsupported request */
+#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */
+#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */
+/* For all not specified status messages:
+ * RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx
+ */
+
+/* Message Set for Connectionless (802.3) Devices */
+#define REMOTE_NDIS_INIZIALIZE_MSG 0x00000002U /* Inizialize the device */
+#define REMOTE_NDIS_HALT_MSG 0x00000003U
+#define REMOTE_NDIS_QUERY_MSG 0x00000004U
+#define REMOTE_NDIS_SET_MSG 0x00000005U
+#define REMOTE_NDIS_RESET_MSG 0x00000006U
+#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007U
+#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008U
+
+/* Message completion */
+#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002U
+#define REMOTE_NDIS_QUERY_CMPLT 0x80000004U
+#define REMOTE_NDIS_SET_CMPLT 0x80000005U
+#define REMOTE_NDIS_RESET_CMPLT 0x80000006U
+#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008U
+
+/* Device Flags */
+#define RNDIS_DF_CONNECTIONLESS 0x00000001U
+#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002U
+
+#define RNDIS_MEDIUM_802_3 0x00000000U
+
+/* supported OIDs */
+static const u32 oid_supported_list [] =
+{
+ /* mandatory general */
+ /* the general stuff */
+ OID_GEN_SUPPORTED_LIST,
+ OID_GEN_HARDWARE_STATUS,
+ OID_GEN_MEDIA_SUPPORTED,
+ OID_GEN_MEDIA_IN_USE,
+ OID_GEN_MAXIMUM_FRAME_SIZE,
+ OID_GEN_LINK_SPEED,
+ OID_GEN_TRANSMIT_BUFFER_SPACE,
+ OID_GEN_TRANSMIT_BLOCK_SIZE,
+ OID_GEN_RECEIVE_BLOCK_SIZE,
+ OID_GEN_VENDOR_ID,
+ OID_GEN_VENDOR_DESCRIPTION,
+ OID_GEN_VENDOR_DRIVER_VERSION,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_MAC_OPTIONS,
+ OID_GEN_MEDIA_CONNECT_STATUS,
+ OID_GEN_PHYSICAL_MEDIUM,
+ OID_GEN_RNDIS_CONFIG_PARAMETER,
+
+ /* the statistical stuff */
+ OID_GEN_XMIT_OK,
+ OID_GEN_RCV_OK,
+ OID_GEN_XMIT_ERROR,
+ OID_GEN_RCV_ERROR,
+ OID_GEN_RCV_NO_BUFFER,
+ OID_GEN_DIRECTED_BYTES_XMIT,
+ OID_GEN_DIRECTED_FRAMES_XMIT,
+ OID_GEN_MULTICAST_BYTES_XMIT,
+ OID_GEN_MULTICAST_FRAMES_XMIT,
+ OID_GEN_BROADCAST_BYTES_XMIT,
+ OID_GEN_BROADCAST_FRAMES_XMIT,
+ OID_GEN_DIRECTED_BYTES_RCV,
+ OID_GEN_DIRECTED_FRAMES_RCV,
+ OID_GEN_MULTICAST_BYTES_RCV,
+ OID_GEN_MULTICAST_FRAMES_RCV,
+ OID_GEN_BROADCAST_BYTES_RCV,
+ OID_GEN_BROADCAST_FRAMES_RCV,
+ OID_GEN_RCV_CRC_ERROR,
+ OID_GEN_TRANSMIT_QUEUE_LENGTH,
+
+ /* mandatory 802.3 */
+ /* the general stuff */
+ OID_802_3_PERMANENT_ADDRESS,
+ OID_802_3_CURRENT_ADDRESS,
+ OID_802_3_MULTICAST_LIST,
+ OID_802_3_MAC_OPTIONS,
+ OID_802_3_MAXIMUM_LIST_SIZE,
+
+ /* the statistical stuff */
+ OID_802_3_RCV_ERROR_ALIGNMENT,
+ OID_802_3_XMIT_ONE_COLLISION,
+ OID_802_3_XMIT_MORE_COLLISIONS
+};
+
+
+typedef struct rndis_init_msg_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 RequestID;
+ u32 MajorVersion;
+ u32 MinorVersion;
+ u32 MaxTransferSize;
+} rndis_init_msg_type;
+
+typedef struct rndis_init_cmplt_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 RequestID;
+ u32 Status;
+ u32 MajorVersion;
+ u32 MinorVersion;
+ u32 DeviceFlags;
+ u32 Medium;
+ u32 MaxPacketsPerTransfer;
+ u32 MaxTransferSize;
+ u32 PacketAlignmentFactor;
+ u32 AFListOffset;
+ u32 AFListSize;
+} rndis_init_cmplt_type;
+
+typedef struct rndis_halt_msg_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 RequestID;
+} rndis_halt_msg_type;
+
+typedef struct rndis_query_msg_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 RequestID;
+ u32 OID;
+ u32 InformationBufferLength;
+ u32 InformationBufferOffset;
+ u32 DeviceVcHandle;
+} rndis_query_msg_type;
+
+typedef struct rndis_query_cmplt_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 RequestID;
+ u32 Status;
+ u32 InformationBufferLength;
+ u32 InformationBufferOffset;
+} rndis_query_cmplt_type;
+
+typedef struct rndis_set_msg_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 RequestID;
+ u32 OID;
+ u32 InformationBufferLength;
+ u32 InformationBufferOffset;
+ u32 DeviceVcHandle;
+} rndis_set_msg_type;
+
+typedef struct rndis_set_cmplt_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 RequestID;
+ u32 Status;
+} rndis_set_cmplt_type;
+
+typedef struct rndis_reset_msg_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 Reserved;
+} rndis_reset_msg_type;
+
+typedef struct rndis_reset_cmplt_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 Status;
+ u32 AddressingReset;
+} rndis_reset_cmplt_type;
+
+typedef struct rndis_indicate_status_msg_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 Status;
+ u32 StatusBufferLength;
+ u32 StatusBufferOffset;
+} rndis_indicate_status_msg_type;
+
+typedef struct rndis_keepalive_msg_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 RequestID;
+} rndis_keepalive_msg_type;
+
+typedef struct rndis_keepalive_cmplt_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 RequestID;
+ u32 Status;
+} rndis_keepalive_cmplt_type;
+
+struct rndis_packet_msg_type
+{
+ u32 MessageType;
+ u32 MessageLength;
+ u32 DataOffset;
+ u32 DataLength;
+ u32 OOBDataOffset;
+ u32 OOBDataLength;
+ u32 NumOOBDataElements;
+ u32 PerPacketInfoOffset;
+ u32 PerPacketInfoLength;
+ u32 VcHandle;
+ u32 Reserved;
+};
+
+struct rndis_config_parameter
+{
+ u32 ParameterNameOffset;
+ u32 ParameterNameLength;
+ u32 ParameterType;
+ u32 ParameterValueOffset;
+ u32 ParameterValueLength;
+};
+
+/* implementation specific */
+enum rndis_state
+{
+ RNDIS_UNINITIALIZED,
+ RNDIS_INITIALIZED,
+ RNDIS_DATA_INITIALIZED,
+};
+
+typedef struct rndis_resp_t
+{
+ struct list_head list;
+ u8 *buf;
+ u32 length;
+ int send;
+} rndis_resp_t;
+
+typedef struct rndis_params
+{
+ u8 confignr;
+ int used;
+ enum rndis_state state;
+ u32 medium;
+ u32 speed;
+ u32 media_state;
+ struct net_device *dev;
+ struct net_device_stats *stats;
+ u32 vendorID;
+ const char *vendorDescr;
+ int (*ack) (struct net_device *);
+ struct list_head resp_queue;
+} rndis_params;
+
+/* RNDIS Message parser and other useless functions */
+int rndis_msg_parser (u8 configNr, u8 *buf);
+int rndis_register (int (*rndis_control_ack) (struct net_device *));
+void rndis_deregister (int configNr);
+int rndis_set_param_dev (u8 configNr, struct net_device *dev,
+ struct net_device_stats *stats);
+int rndis_set_param_vendor (u8 configNr, u32 vendorID,
+ const char *vendorDescr);
+int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed);
+void rndis_add_hdr (struct sk_buff *skb);
+int rndis_rm_hdr (u8 *buf, u32 *length);
+u8 *rndis_get_next_response (int configNr, u32 *length);
+void rndis_free_response (int configNr, u8 *buf);
+int rndis_signal_connect (int configNr);
+int rndis_signal_disconnect (int configNr);
+int rndis_state (int configNr);
+
+#endif /* _LINUX_RNDIS_H */
diff -urN gadget-2.4/drivers/usb/gadget/usbstring.c linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/usbstring.c
--- gadget-2.4/drivers/usb/gadget/usbstring.c 2004-03-19 11:47:16.000000000 +0100
+++ linux-2.4.19-rmk7-pxa2-mtd20030728-ptx16pre/drivers/usb/gadget/usbstring.c 2004-03-25 22:35:41.000000000 +0100
@@ -12,6 +12,7 @@
#include <linux/list.h>
#include <linux/string.h>
#include <linux/init.h>
+#include <asm/byteorder.h>
#include <linux/usb_ch9.h>
#include <linux/usb_gadget.h>
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-25 22:11 [ANNOUNCE] RNDIS Gadget Driver Robert Schwebel
@ 2004-03-25 22:52 ` David Brownell
2004-03-26 10:37 ` David Woodhouse
2004-03-26 11:59 ` bert hubert
1 sibling, 1 reply; 20+ messages in thread
From: David Brownell @ 2004-03-25 22:52 UTC (permalink / raw)
To: Robert Schwebel; +Cc: linux-usb-devel, linux-kernel
Robert Schwebel wrote:
> David,
>
> finally, here is our RNDIS USB Gadget Driver - see the attached patch
> against the gadget-2.4 BK tree as of now. It shouldn't be too difficult
> to port this to 2.6.
Yowsza! I've been looking forward to this ... :)
I'll look it over and see how the 2.6 merge goes, and probably run
some revisions by you. The autoconfiguration updates will make this
more complicated, since g_ether is starting to support a more dynamic
configuration model; the HH.org crew need that, so PDA Linux distros
don't need to hard-wire as much knowledge about hardware targets
into their kernels.
> The patch adds support for Microsoft's RNDIS protocol to the standard
> g_ether driver. This makes it possible to connect a Linux USB gadget to
> any standard Windows machine and <*PALIM!*> there is a new USB network
> interface on the Windows side on which you can speak TCP/IP :-)
Which is exactly what a lot of Linux solution providers need to see;
I'm sure this will get a lot of use. Applause!
(Although I personally would prefer that Microsoft adopt vendor-neutral
protocols, instead of pushing the rest of the industry to adopt things
that are MSFT-biased ... for some reason, they haven't listened to almost
anyone on such topics. Oh well. ;)
> Unfortunately, although it works with the original Microsoft driver, you
> need an inf file on the windows side; you can download the template for
> that directly from M$.
>
> Thanks to Auerswald GmbH for sponsoring this work!
I'll add them to the official "thank you" list on the
http://www.linux-usb.org/gadget webpage.
- Dave
> Robert
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-25 22:52 ` David Brownell
@ 2004-03-26 10:37 ` David Woodhouse
2004-03-26 15:44 ` David Brownell
0 siblings, 1 reply; 20+ messages in thread
From: David Woodhouse @ 2004-03-26 10:37 UTC (permalink / raw)
To: David Brownell; +Cc: Robert Schwebel, linux-usb-devel, linux-kernel
On Thu, 2004-03-25 at 14:52 -0800, David Brownell wrote:
> (Although I personally would prefer that Microsoft adopt vendor-neutral
> protocols, instead of pushing the rest of the industry to adopt things
> that are MSFT-biased ... for some reason, they haven't listened to almost
> anyone on such topics. Oh well. ;)
Out of interest -- have they (or has anyone else) invented a 'file
system' USB device yet? For exporting some file systems, pretending to
be a block device really isn't very useful.
--
dwmw2
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 10:37 ` David Woodhouse
@ 2004-03-26 15:44 ` David Brownell
2004-03-26 23:23 ` [linux-usb-devel] " don
0 siblings, 1 reply; 20+ messages in thread
From: David Brownell @ 2004-03-26 15:44 UTC (permalink / raw)
To: David Woodhouse; +Cc: Robert Schwebel, linux-usb-devel, linux-kernel
David Woodhouse wrote:
>
> Out of interest -- have they (or has anyone else) invented a 'file
> system' USB device yet? For exporting some file systems, pretending to
> be a block device really isn't very useful.
There's a file system protocol used by many digital still cameras,
which isn't actually camera-specific. Not MSFT-specific either.
Originally called "Picture Transfer Protocol" (PTP) it's actually
more of a remote hierarchical filesystem protocol ... with an event
channel (handy for "new picture" or "inserted new flash memory")
and some built-in search capabilities ("what JPGs do you have").
The strangest capability was a file type tag, which isn't actually
that bizarre.
As with RNDIS, and USB Mass Storage, I understand that support for
PTP is part of MS-Windows since about Win2K. So a PTP gadget
driver would probably be a useful contribution to Linux.
- Dave
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [linux-usb-devel] Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 15:44 ` David Brownell
@ 2004-03-26 23:23 ` don
2004-03-27 17:02 ` David Brownell
0 siblings, 1 reply; 20+ messages in thread
From: don @ 2004-03-26 23:23 UTC (permalink / raw)
To: David Brownell
Cc: David Woodhouse, Robert Schwebel, linux-usb-devel, linux-kernel
On Fri, Mar 26, 2004 at 07:44:10AM -0800, David Brownell wrote:
> There's a file system protocol used by many digital still cameras,
> which isn't actually camera-specific. Not MSFT-specific either.
>
> Originally called "Picture Transfer Protocol" (PTP) it's actually
> more of a remote hierarchical filesystem protocol ... with an event
> channel (handy for "new picture" or "inserted new flash memory")
> and some built-in search capabilities ("what JPGs do you have").
> The strangest capability was a file type tag, which isn't actually
> that bizarre.
>
> As with RNDIS, and USB Mass Storage, I understand that support for
> PTP is part of MS-Windows since about Win2K. So a PTP gadget
> driver would probably be a useful contribution to Linux.
A host driver "USB PTP Storage" would be really nice too. First
as a generic camera interface, second to access a gadget with the
PTP interface.
(Please embarrass me by saying there already is one, I'll be so happy
I won't care :-) ).
I have a PTP camera and would certainly be happy to test such a driver.
Time to write it is a different matter.
Don Reid
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [linux-usb-devel] Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 23:23 ` [linux-usb-devel] " don
@ 2004-03-27 17:02 ` David Brownell
2004-03-28 2:47 ` don
0 siblings, 1 reply; 20+ messages in thread
From: David Brownell @ 2004-03-27 17:02 UTC (permalink / raw)
To: don; +Cc: David Woodhouse, Robert Schwebel, linux-usb-devel, linux-kernel
>>There's a file system protocol used by many digital still cameras,
>>which isn't actually camera-specific. Not MSFT-specific either.
>>...
>
> A host driver "USB PTP Storage" would be really nice too. First
> as a generic camera interface, second to access a gadget with the
> PTP interface.
>
> (Please embarrass me by saying there already is one, I'll be so happy
> I won't care :-) ).
There isn't one. There are two. No need to be embarrassed ... ;)
They're both user-mode drivers. "gPhoto2", and "jPhoto". The
author of jPhoto (moi) hasn't had time to update that code in
ages.
- Dave
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [linux-usb-devel] Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-27 17:02 ` David Brownell
@ 2004-03-28 2:47 ` don
2004-03-28 9:47 ` David Woodhouse
2004-03-28 15:34 ` David Brownell
0 siblings, 2 replies; 20+ messages in thread
From: don @ 2004-03-28 2:47 UTC (permalink / raw)
To: David Brownell
Cc: David Woodhouse, Robert Schwebel, linux-usb-devel, linux-kernel
On Sat, Mar 27, 2004 at 09:02:18AM -0800, David Brownell wrote:
> >>There's a file system protocol used by many digital still cameras,
> >>which isn't actually camera-specific. Not MSFT-specific either.
> >>...
> >
> >A host driver "USB PTP Storage" would be really nice too. First
> >as a generic camera interface, second to access a gadget with the
> >PTP interface.
> >
> >(Please embarrass me by saying there already is one, I'll be so happy
> >I won't care :-) ).
>
> There isn't one. There are two. No need to be embarrassed ... ;)
>
> They're both user-mode drivers. "gPhoto2", and "jPhoto". The
> author of jPhoto (moi) hasn't had time to update that code in
> ages.
These are applications, not file system interfaces like USB Mass Storage.
I want to mount the camera or gadget file system and access it from any
program, not run a separate app to fetch files like Mass Stor. mounts
a memory device.
Why create a dedicated app like a camera interface instead of using your
favorite image browser on some files?
--
Don Reid
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [linux-usb-devel] Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-28 2:47 ` don
@ 2004-03-28 9:47 ` David Woodhouse
2004-03-28 15:34 ` David Brownell
1 sibling, 0 replies; 20+ messages in thread
From: David Woodhouse @ 2004-03-28 9:47 UTC (permalink / raw)
To: don; +Cc: David Brownell, Robert Schwebel, linux-usb-devel, linux-kernel
On Sat, 2004-03-27 at 18:47 -0800, don wrote:
> These are applications, not file system interfaces like USB Mass Storage.
> I want to mount the camera or gadget file system and access it from any
> program, not run a separate app to fetch files like Mass Stor. mounts
> a memory device.
>
> Why create a dedicated app like a camera interface instead of using your
> favorite image browser on some files?
Bear in mind also that the reason I asked is because I want to export
_real_ file systems this way, so you can plug your iPAQ in and access
its file system without having to do it over NFS.
--
dwmw2
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [linux-usb-devel] Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-28 2:47 ` don
2004-03-28 9:47 ` David Woodhouse
@ 2004-03-28 15:34 ` David Brownell
1 sibling, 0 replies; 20+ messages in thread
From: David Brownell @ 2004-03-28 15:34 UTC (permalink / raw)
To: don; +Cc: David Woodhouse, Robert Schwebel, linux-usb-devel, linux-kernel
don wrote:
>>>A host driver "USB PTP Storage" would be really nice too. First
>>>as a generic camera interface, second to access a gadget with the
>>>PTP interface.
>>
>>There isn't one. There are two. No need to be embarrassed ... ;)
>>
>>They're both user-mode drivers. "gPhoto2", and "jPhoto". The
>>author of jPhoto (moi) hasn't had time to update that code in
>>ages.
>
>
> These are applications, not file system interfaces like USB Mass Storage.
> I want to mount the camera or gadget file system and access it from any
> program, not run a separate app to fetch files like Mass Stor. mounts
> a memory device.
As Andrew Zabolotny commented, NFS _does_ work today from those
devices. Except that it doesn't work to MS-Windows hosts, unless
they've been taught other parts of the protocol stack.
Presumably Samba over RNDIS would work from Windows, but that
would need extra work from many Linux hosts. Tradeoffs...
> Why create a dedicated app like a camera interface instead of using your
> favorite image browser on some files?
Well, PTP should take less memory inside the device/gadget than
a network stack, though it'd be less flexible. And there's
also something to be said for less code in the kernel, and a
simpler device setup model ... especially for the kinds of
products that'd be considering something like PTP.
But I think the basic answer to your question is probably just
that nobody's yet written, or at least submitted, PTP client
or server kernel code for Linux.
- Dave
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-25 22:11 [ANNOUNCE] RNDIS Gadget Driver Robert Schwebel
2004-03-25 22:52 ` David Brownell
@ 2004-03-26 11:59 ` bert hubert
2004-03-26 12:19 ` Robert Schwebel
1 sibling, 1 reply; 20+ messages in thread
From: bert hubert @ 2004-03-26 11:59 UTC (permalink / raw)
To: Robert Schwebel; +Cc: David Brownell, linux-usb-devel, linux-kernel
On Thu, Mar 25, 2004 at 11:11:45PM +0100, Robert Schwebel wrote:
> Unfortunately, although it works with the original Microsoft driver, you
> need an inf file on the windows side; you can download the template for
> that directly from M$.
I don't understand this comment, it would probably be very wise to add
something to Documentation/ about this.
> - .bDeviceClass = DEV_CONFIG_CLASS,
> + .bDeviceClass = 0x02,
Is this wise?
Thanks for this work, looks cool!
--
http://www.PowerDNS.com Open source, database driven DNS Software
http://lartc.org Linux Advanced Routing & Traffic Control HOWTO
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 11:59 ` bert hubert
@ 2004-03-26 12:19 ` Robert Schwebel
2004-03-26 12:26 ` bert hubert
2004-03-26 15:58 ` David Brownell
0 siblings, 2 replies; 20+ messages in thread
From: Robert Schwebel @ 2004-03-26 12:19 UTC (permalink / raw)
To: bert hubert, David Brownell, linux-usb-devel, linux-kernel
On Fri, Mar 26, 2004 at 12:59:47PM +0100, bert hubert wrote:
> > Unfortunately, although it works with the original Microsoft driver, you
> > need an inf file on the windows side; you can download the template for
> > that directly from M$.
>
> I don't understand this comment, it would probably be very wise to add
> something to Documentation/ about this.
You need such an .inf file on the windows side; M$ has a template where
you simply need to insert your vendor/device ID and other stuff. I'm not
sure about the license for these files, so I don't know if it is allowed
to distribute them.
> > - .bDeviceClass = DEV_CONFIG_CLASS,
> > + .bDeviceClass = 0x02,
>
> Is this wise?
Until now DEV_CONFIG_CLASS was 0xFF, which results in Windows getting
hickup. If you directly set this to 0x02 (Network Device) Win is happy.
Might be a good idea anyway.
Robert
--
Dipl.-Ing. Robert Schwebel | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
Handelsregister: Amtsgericht Hildesheim, HRA 2686
Hornemannstraße 12, 31137 Hildesheim, Germany
Phone: +49-5121-28619-0 | Fax: +49-5121-28619-4
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 12:19 ` Robert Schwebel
@ 2004-03-26 12:26 ` bert hubert
2004-03-26 15:58 ` David Brownell
1 sibling, 0 replies; 20+ messages in thread
From: bert hubert @ 2004-03-26 12:26 UTC (permalink / raw)
To: Robert Schwebel; +Cc: David Brownell, linux-usb-devel, linux-kernel
On Fri, Mar 26, 2004 at 01:19:28PM +0100, Robert Schwebel wrote:
> You need such an .inf file on the windows side; M$ has a template where
> you simply need to insert your vendor/device ID and other stuff. I'm not
> sure about the license for these files, so I don't know if it is allowed
> to distribute them.
And that .inf describes 'Linux'? No matter what the license is, you can link
to it and instruct people on how to change it. You could even show pieces of
the .inf with the linux data filled in ('fair use').
I ask about this because I know that to get adequate testing coverage,
experimenting with this code should be as easy as possible. Something like
'visit this URL and paste in the following: (...) and now do such and such
in windows and you should be set'.
I'll happily write this for you if you provide the pointers.
Good luck!
--
http://www.PowerDNS.com Open source, database driven DNS Software
http://lartc.org Linux Advanced Routing & Traffic Control HOWTO
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 12:19 ` Robert Schwebel
2004-03-26 12:26 ` bert hubert
@ 2004-03-26 15:58 ` David Brownell
2004-03-26 16:35 ` Robert Schwebel
1 sibling, 1 reply; 20+ messages in thread
From: David Brownell @ 2004-03-26 15:58 UTC (permalink / raw)
To: Robert Schwebel; +Cc: bert hubert, linux-usb-devel, linux-kernel
Robert Schwebel wrote:
> On Fri, Mar 26, 2004 at 12:59:47PM +0100, bert hubert wrote:
>
>>>- .bDeviceClass = DEV_CONFIG_CLASS,
>>>+ .bDeviceClass = 0x02,
>>
>>Is this wise?
>
>
> Until now DEV_CONFIG_CLASS was 0xFF, which results in Windows getting
> hickup. If you directly set this to 0x02 (Network Device) Win is happy.
Actually I suspect setting it to USB_CLASS_COMM would be preferred, in
RNDIS-specific config descriptors....
- Dave
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 15:58 ` David Brownell
@ 2004-03-26 16:35 ` Robert Schwebel
2004-03-26 17:45 ` David Brownell
0 siblings, 1 reply; 20+ messages in thread
From: Robert Schwebel @ 2004-03-26 16:35 UTC (permalink / raw)
To: David Brownell; +Cc: linux-usb-devel, linux-kernel
On Fri, Mar 26, 2004 at 07:58:04AM -0800, David Brownell wrote:
> >>>- .bDeviceClass = DEV_CONFIG_CLASS,
> >>>+ .bDeviceClass = 0x02,
> >>
> >>Is this wise?
> >
> >
> >Until now DEV_CONFIG_CLASS was 0xFF, which results in Windows getting
> >hickup. If you directly set this to 0x02 (Network Device) Win is happy.
>
> Actually I suspect setting it to USB_CLASS_COMM would be preferred, in
> RNDIS-specific config descriptors....
We have tried that, Windows does not like it. The only constellation
where it worked was setting the device descriptor's bConfigClass=0x02.
RNDIS is a sensitive beast. Do one bit different results in that uggly
"Error 10" message on the Windows side. We saw it when we started with
the driver, we saw it when the driver was half way finished and we will
see it again if somebody tweaks the driver without exactly knowing what
the guys at Microsoft smoked when they designed that protocol :-)
Robert
--
Dipl.-Ing. Robert Schwebel | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
Handelsregister: Amtsgericht Hildesheim, HRA 2686
Hornemannstraße 12, 31137 Hildesheim, Germany
Phone: +49-5121-28619-0 | Fax: +49-5121-28619-4
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 16:35 ` Robert Schwebel
@ 2004-03-26 17:45 ` David Brownell
2004-03-26 18:41 ` Robert Schwebel
0 siblings, 1 reply; 20+ messages in thread
From: David Brownell @ 2004-03-26 17:45 UTC (permalink / raw)
To: Robert Schwebel; +Cc: linux-usb-devel, linux-kernel
Robert Schwebel wrote:
> On Fri, Mar 26, 2004 at 07:58:04AM -0800, David Brownell wrote:
>
>>>>>- .bDeviceClass = DEV_CONFIG_CLASS,
>>>>>+ .bDeviceClass = 0x02,
>>>>
>>>>Is this wise?
>>>
>>>
>>>Until now DEV_CONFIG_CLASS was 0xFF, which results in Windows getting
>>>hickup. If you directly set this to 0x02 (Network Device) Win is happy.
>>
>>Actually I suspect setting it to USB_CLASS_COMM would be preferred, in
>>RNDIS-specific config descriptors....
(since: #define USB_CLASS_COMM 2)
> We have tried that, Windows does not like it. The only constellation
> where it worked was setting the device descriptor's bConfigClass=0x02.
Sorry, I meant "device" descriptors. Yes, I noticed their "spec"
had strange things to say. Is there some reason you're not including
the CDC header and union descriptors? That spec does talk about those,
and the erratum I found also talks about better CDC ACM conformance.
> RNDIS is a sensitive beast. Do one bit different results in that uggly
> "Error 10" message on the Windows side. We saw it when we started with
> the driver, we saw it when the driver was half way finished and we will
> see it again if somebody tweaks the driver without exactly knowing what
> the guys at Microsoft smoked when they designed that protocol :-)
I thought it was "just say no to vendor-neutral protocols" crack ...
although that close to BC they would have much better options! ;)
The purist in me is annoyed that rather than just defining a purely
vendor-specific protocol, they re-used bits and pieces of the USB-IF
CDC-ACM spec. It's not like they needed _any_ of it. (Unless maybe
subtle sabotoge of CDC was a goal?)
Different topic: I noticed that on PXA you were using "ep5-int".
That's documented as always using DATA0 -- data toggle not working.
Was that making any trouble for you? I've never actually tried
using those endpoints, because of that functional limitation.
Also it looks like you've only tested this on PXA hardware.
Most of the patch is the (R)NDIS support code, which is easy
to merge, but the "g_ether" updates will take longer.
- Dave
> Robert
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 17:45 ` David Brownell
@ 2004-03-26 18:41 ` Robert Schwebel
2004-03-26 19:45 ` David Brownell
2004-03-30 16:25 ` David Brownell
0 siblings, 2 replies; 20+ messages in thread
From: Robert Schwebel @ 2004-03-26 18:41 UTC (permalink / raw)
To: David Brownell; +Cc: linux-usb-devel, linux-kernel
On Fri, Mar 26, 2004 at 09:45:15AM -0800, David Brownell wrote:
> >We have tried that, Windows does not like it. The only constellation
> >where it worked was setting the device descriptor's bConfigClass=0x02.
>
> Sorry, I meant "device" descriptors. Yes, I noticed their "spec"
> had strange things to say. Is there some reason you're not including
> the CDC header and union descriptors? That spec does talk about those,
> and the erratum I found also talks about better CDC ACM conformance.
USB_CLASS_COM is surely ok. The descriptors may be a relict from the
time where the CDC equivalents where not in the driver...
The problem is that, as it is now, it works. The whole RNDIS stuff is
extremely time intensive to debug: when you have one odd value in some
place, Windows just says "Error 10" and you have to guess what you did
wrong. No further information available. So the best way to be
successful may be to check it in as it is, maybe add some FIXMEs, and
let the masses test the code. Then cleanup the remaining issues step by
step and wait until nobody crys any more :-)
> Different topic: I noticed that on PXA you were using "ep5-int".
> That's documented as always using DATA0 -- data toggle not working.
> Was that making any trouble for you? I've never actually tried
> using those endpoints, because of that functional limitation.
Well, there is no other interrupt endpoint on the PXA, and it somehow
works :-)
> Also it looks like you've only tested this on PXA hardware.
It was hard enough :-)
> Most of the patch is the (R)NDIS support code, which is easy
> to merge, but the "g_ether" updates will take longer.
Ok. We have tried to make the design as minimal-invasive as possible...
Robert
--
Dipl.-Ing. Robert Schwebel | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
Handelsregister: Amtsgericht Hildesheim, HRA 2686
Hornemannstraße 12, 31137 Hildesheim, Germany
Phone: +49-5121-28619-0 | Fax: +49-5121-28619-4
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 18:41 ` Robert Schwebel
@ 2004-03-26 19:45 ` David Brownell
2004-03-26 20:57 ` Robert Schwebel
2004-03-30 16:25 ` David Brownell
1 sibling, 1 reply; 20+ messages in thread
From: David Brownell @ 2004-03-26 19:45 UTC (permalink / raw)
To: Robert Schwebel; +Cc: linux-usb-devel, linux-kernel
Robert Schwebel wrote:
> ...
>
> The problem is that, as it is now, it works. The whole RNDIS stuff is
> extremely time intensive to debug: when you have one odd value in some
> place, Windows just says "Error 10" and you have to guess what you did
> wrong. No further information available. So the best way to be
> successful may be to check it in as it is, maybe add some FIXMEs, and
> let the masses test the code. Then cleanup the remaining issues step by
> step and wait until nobody crys any more :-)
Well, what I merge is necessarily going to work on more
hardware than just PXA ... it'll work over net2280 (at high
speed), goku, and surely other hardware. In most cases
that'll just require sanity testing. Maybe I can get Julian
to test on SH3, and it sounds like Andrew is getting close
on the MediaQ.
Once I can see it work, then it'll be ready for that more
widespread testing. (Do penguins actually cry?)
>>Different topic: I noticed that on PXA you were using "ep5-int".
>>That's documented as always using DATA0 -- data toggle not working.
>>Was that making any trouble for you? I've never actually tried
>>using those endpoints, because of that functional limitation.
>
>
> Well, there is no other interrupt endpoint on the PXA, and it somehow
> works :-)
It's not as if the protocol actually _needs_ an interrupt endpoint,
though the MSFT spec says it does. It's actually simpler for the
host to poll for completion on the control endpoint; none of the
requests should take very long to finish anyway. An RNDIS host
might not even notice those "toggle broken" issues.
Did you have any evidence that the MSFT host was actually using
that interrupt endpoint? Like CATC snooping showing it never
tried to collect responses until the interrupt packet arrived?
Also, which versions of MS-Windows did you test against? Some of
the MSFT docs suggest version-specific protocol quirks. That's
where I expect most of the end-user problem reports to appear!
Which is why I'd like to have all the documented protocol quirks
(including the other CDC descriptors) resolved before this starts
to get really broad testing.
- Dave
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 19:45 ` David Brownell
@ 2004-03-26 20:57 ` Robert Schwebel
2004-03-26 21:09 ` David Brownell
0 siblings, 1 reply; 20+ messages in thread
From: Robert Schwebel @ 2004-03-26 20:57 UTC (permalink / raw)
To: David Brownell; +Cc: linux-usb-devel, linux-kernel
On Fri, Mar 26, 2004 at 11:45:58AM -0800, David Brownell wrote:
> Well, what I merge is necessarily going to work on more hardware than
> just PXA ... it'll work over net2280 (at high speed), goku, and surely
> other hardware. In most cases that'll just require sanity testing.
> Maybe I can get Julian to test on SH3, and it sounds like Andrew is
> getting close on the MediaQ.
A broader variety of controllers would indeed be helpful. When you have
the stuff integrated the way you think it's right, just tell me and I'll
test if it still works on our testbed.
> Once I can see it work, then it'll be ready for that more widespread
> testing. (Do penguins actually cry?)
Only if they have to read Microsoft specifications :-)
> It's not as if the protocol actually _needs_ an interrupt endpoint,
> though the MSFT spec says it does. It's actually simpler for the host
> to poll for completion on the control endpoint; none of the requests
> should take very long to finish anyway. An RNDIS host might not even
> notice those "toggle broken" issues.
You probably underestimate the mental sensibility of Windows machines.
We have seen cases where the Windows host just floods you with
interrupts when it is not happy with things like these...
> Did you have any evidence that the MSFT host was actually using that
> interrupt endpoint? Like CATC snooping showing it never tried to
> collect responses until the interrupt packet arrived?
We have seen the packets with the protocol analyzer. I think we agree
that using an interrupt endpoint just to announce that the gadget has a
message for the host available, but that's how M$ designed it...
> Also, which versions of MS-Windows did you test against? Some of the
> MSFT docs suggest version-specific protocol quirks.
Win 98, XP, 2000. Auerswald currently tests all available other
variants, and the tests they invented are _really_ crazy ;)
Robert
--
Dipl.-Ing. Robert Schwebel | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
Handelsregister: Amtsgericht Hildesheim, HRA 2686
Hornemannstraße 12, 31137 Hildesheim, Germany
Phone: +49-5121-28619-0 | Fax: +49-5121-28619-4
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 20:57 ` Robert Schwebel
@ 2004-03-26 21:09 ` David Brownell
0 siblings, 0 replies; 20+ messages in thread
From: David Brownell @ 2004-03-26 21:09 UTC (permalink / raw)
To: Robert Schwebel; +Cc: linux-usb-devel, linux-kernel
Robert Schwebel wrote:
> A broader variety of controllers would indeed be helpful. When you have
> the stuff integrated the way you think it's right, just tell me and I'll
> test if it still works on our testbed.
OK, that'll work fine. Probably next week sometime.
>>It's not as if the protocol actually _needs_ an interrupt endpoint,
>>though the MSFT spec says it does. It's actually simpler for the host
>>to poll for completion on the control endpoint; none of the requests
>>should take very long to finish anyway. An RNDIS host might not even
>>notice those "toggle broken" issues.
>
>
> You probably underestimate the mental sensibility of Windows machines.
> We have seen cases where the Windows host just floods you with
> interrupts when it is not happy with things like these...
Any system where BSOD is anything other than a screensaver is
lacking many kinds of sensibility ... :)
That question was mostly for curiousity. The issue with interrupt
endpoints and data toggle is trivially resolved by using ep6in-bulk
instead of ep5in-int. Which is what the autoconfig version will
likely end up doing, since default quality-of-service model for
interrupt endpoints includes having working data toggle. PXA is
wierd in that way, but it's got endpoints to burn.
>>Did you have any evidence that the MSFT host was actually using that
>>interrupt endpoint? Like CATC snooping showing it never tried to
>>collect responses until the interrupt packet arrived?
>
>
> We have seen the packets with the protocol analyzer. I think we agree
> that using an interrupt endpoint just to announce that the gadget has a
> message for the host available, but that's how M$ designed it...
Sure it gets sent, but does it get used? If it does,
does the data toggle matter, or is MSFT by default
ignoring the toggle (and hence letting that needless
data stream be undetectably corrupted)?
>>Also, which versions of MS-Windows did you test against? Some of the
>>MSFT docs suggest version-specific protocol quirks.
>
>
> Win 98, XP, 2000. Auerswald currently tests all available other
> variants, and the tests they invented are _really_ crazy ;)
OK, so good basic coverage. Modulo bugs introduced by
various service packs or national releases ... ;)
- Dave
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [ANNOUNCE] RNDIS Gadget Driver
2004-03-26 18:41 ` Robert Schwebel
2004-03-26 19:45 ` David Brownell
@ 2004-03-30 16:25 ` David Brownell
1 sibling, 0 replies; 20+ messages in thread
From: David Brownell @ 2004-03-30 16:25 UTC (permalink / raw)
To: Robert Schwebel; +Cc: linux-usb-devel, linux-kernel
Robert Schwebel wrote:
>>Most of the patch is the (R)NDIS support code, which is easy
>>to merge, but the "g_ether" updates will take longer.
>
>
> Ok. We have tried to make the design as minimal-invasive as possible...
And that pretty much worked ... I've sent Greg a 2.6
version, tested with net2280 and goku_udc, so I hope
that'll appear in some "-mm" patch soonish (and then
presumably in 2.6.6-early).
It does need testing on PXA though.
- Dave
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2004-03-30 16:27 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-25 22:11 [ANNOUNCE] RNDIS Gadget Driver Robert Schwebel
2004-03-25 22:52 ` David Brownell
2004-03-26 10:37 ` David Woodhouse
2004-03-26 15:44 ` David Brownell
2004-03-26 23:23 ` [linux-usb-devel] " don
2004-03-27 17:02 ` David Brownell
2004-03-28 2:47 ` don
2004-03-28 9:47 ` David Woodhouse
2004-03-28 15:34 ` David Brownell
2004-03-26 11:59 ` bert hubert
2004-03-26 12:19 ` Robert Schwebel
2004-03-26 12:26 ` bert hubert
2004-03-26 15:58 ` David Brownell
2004-03-26 16:35 ` Robert Schwebel
2004-03-26 17:45 ` David Brownell
2004-03-26 18:41 ` Robert Schwebel
2004-03-26 19:45 ` David Brownell
2004-03-26 20:57 ` Robert Schwebel
2004-03-26 21:09 ` David Brownell
2004-03-30 16:25 ` David Brownell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox