ChangeSet 1.1148.6.10, 2003/10/14 16:48:25-07:00, [EMAIL PROTECTED]

[PATCH] USB: usb ethernet gadget

Please update the ethernet "gadget" driver with this patch:

    - fixes an newish oops in some cdc shutdown paths
    - works on more 2.4 kernel variants
    - synchronizes with more recent 2.6 code
    - supports another controller (tc86c001 "goku_udc")

The oops basically came from recent changes that seemed
to behave on PXA hardware, but not the more functional
CDC-capable stuff (like net2280).


 drivers/usb/gadget/ether.c |  130 +++++++++++++++++++++++++++------------------
 1 files changed, 80 insertions(+), 50 deletions(-)


diff -Nru a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
--- a/drivers/usb/gadget/ether.c        Fri Oct 24 17:01:03 2003
+++ b/drivers/usb/gadget/ether.c        Fri Oct 24 17:01:03 2003
@@ -23,8 +23,8 @@
 // #define VERBOSE
 
 #include <linux/config.h>
-#include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
@@ -87,11 +87,12 @@
 #endif
 
 /* 2.5 modified and renamed these */
-
+#ifndef        INIT_WORK
 #define work_struct            tq_struct
 #define INIT_WORK              INIT_TQUEUE
 #define schedule_work          schedule_task
 #define        flush_scheduled_work    flush_scheduled_tasks
+#endif
 
 /*-------------------------------------------------------------------------*/
 
@@ -117,28 +118,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* This driver keeps a variable number of requests queued, more at
- * high speeds.  (Numbers are just educated guesses, untuned.)
- * Shrink the queue if memory is tight, or make it bigger to
- * handle bigger traffic bursts between IRQs (assuming hw dma queues)
- */
-
-static unsigned qmult = 4;
-
-#define HS_FACTOR      5
-
-#define qlen(gadget) \
-       (qmult*((gadget->speed == USB_SPEED_HIGH) ? HS_FACTOR : 1))
-
-/* defer IRQs on highspeed TX */
-#define TX_DELAY       8
-
-
-MODULE_PARM (qmult, "i");
-MODULE_PARM_DESC (qmult, "rx/tx buffering factor");
-
-/*-------------------------------------------------------------------------*/
-
 /* Thanks to NetChip Technologies for donating this product ID.
  *
  * DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
@@ -187,6 +166,7 @@
  */
 #ifdef CONFIG_USB_ETH_NET2280
 #define CHIP                   "net2280"
+#define DEFAULT_QLEN           4               /* has dma chaining */
 #define DRIVER_VERSION_NUM     0x0111
 #define EP0_MAXPACKET          64
 static const char EP_OUT_NAME [] = "ep-a";
@@ -232,7 +212,7 @@
 /* supports remote wakeup, but this driver doesn't */
 
 /* no hw optimizations to apply */
-#define hw_optimize(g) do {} while (0);
+#define hw_optimize(g) do {} while (0)
 #endif
 
 /*
@@ -255,7 +235,28 @@
 /* doesn't support remote wakeup? */
 
 /* no hw optimizations to apply */
-#define hw_optimize(g) do {} while (0);
+#define hw_optimize(g) do {} while (0)
+#endif
+
+/*
+ * Toshiba TC86C001 ("Goku-S") UDC
+ *
+ * This has three semi-configurable full speed bulk/interrupt endpoints.
+ */
+#ifdef CONFIG_USB_ETH_GOKU
+#define CHIP                   "goku"
+#define DRIVER_VERSION_NUM     0x0116
+#define EP0_MAXPACKET          8
+static const char EP_OUT_NAME [] = "ep1-bulk";
+#define EP_OUT_NUM     1
+static const char EP_IN_NAME [] = "ep2-bulk";
+#define EP_IN_NUM      2
+static const char EP_STATUS_NAME [] = "ep3-bulk";
+#define EP_STATUS_NUM  3
+#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
+/* doesn't support remote wakeup */
+
+#define hw_optimize(g) do {} while (0)
 #endif
 
 /*-------------------------------------------------------------------------*/
@@ -313,9 +314,32 @@
 
 /*-------------------------------------------------------------------------*/
 
+#ifndef DEFAULT_QLEN
+#define DEFAULT_QLEN   2       /* double buffering by default */
+#endif
+
+#ifdef HIGHSPEED
+
+static unsigned qmult = 5;
+MODULE_PARM (qmult, "i");
+
+
+/* for dual-speed hardware, use deeper queues at highspeed */
+#define qlen(gadget) \
+       (DEFAULT_QLEN*((gadget->speed == USB_SPEED_HIGH) ? qmult : 1))
+
+/* also defer IRQs on highspeed TX */
+#define TX_DELAY       DEFAULT_QLEN
+
+#else  /* !HIGHSPEED ... full speed: */
+#define qlen(gadget) DEFAULT_QLEN
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
 #define xprintk(d,level,fmt,args...) \
-       printk(level "%s %s: " fmt , shortname , (d)->gadget->dev.bus_id , \
-               ## args)
+       printk(level "%s: " fmt , (d)->net->name , ## args)
 
 #ifdef DEBUG
 #undef DEBUG
@@ -892,6 +916,8 @@
 
 static void eth_reset_config (struct eth_dev *dev)
 {
+       struct usb_request      *req;
+
        if (dev->config == 0)
                return;
 
@@ -900,17 +926,30 @@
        netif_stop_queue (dev->net);
        netif_carrier_off (dev->net);
 
-       /* just disable endpoints, forcing completion of pending i/o.
-        * all our completion handlers free their requests in this case.
+       /* disable endpoints, forcing (synchronous) completion of
+        * pending i/o.  then free the requests.
         */
        if (dev->in_ep) {
                usb_ep_disable (dev->in_ep);
+               while (likely (!list_empty (&dev->tx_reqs))) {
+                       req = container_of (dev->tx_reqs.next,
+                                               struct usb_request, list);
+                       list_del (&req->list);
+                       usb_ep_free_request (dev->in_ep, req);
+               }
                dev->in_ep = 0;
        }
        if (dev->out_ep) {
                usb_ep_disable (dev->out_ep);
+               while (likely (!list_empty (&dev->rx_reqs))) {
+                       req = container_of (dev->rx_reqs.next,
+                                               struct usb_request, list);
+                       list_del (&req->list);
+                       usb_ep_free_request (dev->out_ep, req);
+               }
                dev->out_ep = 0;
        }
+
 #ifdef EP_STATUS_NUM
        if (dev->status_ep) {
                usb_ep_disable (dev->status_ep);
@@ -1676,7 +1715,7 @@
 {
        struct eth_dev          *dev = (struct eth_dev *) net->priv;
 
-       DEBUG (dev, "%s\n", __FUNCTION__);
+       VDEBUG (dev, "%s\n", __FUNCTION__);
        netif_stop_queue (net);
 
        DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
@@ -1690,6 +1729,7 @@
                usb_ep_disable (dev->out_ep);
                if (netif_carrier_ok (dev->net)) {
                        DEBUG (dev, "host still using in/out endpoints\n");
+                       // FIXME idiom may leave toggle wrong here
                        usb_ep_enable (dev->in_ep, dev->in);
                        usb_ep_enable (dev->out_ep, dev->out);
                }
@@ -1708,7 +1748,6 @@
 eth_unbind (struct usb_gadget *gadget)
 {
        struct eth_dev          *dev = get_gadget_data (gadget);
-       struct usb_request      *req;
 
        DEBUG (dev, "unbind\n");
 
@@ -1721,19 +1760,6 @@
                dev->req = 0;
        }
 
-       while (!list_empty (&dev->tx_reqs)) {
-               req = container_of (dev->tx_reqs.next,
-                                       struct usb_request, list);
-               list_del (&req->list);
-               usb_ep_free_request (dev->in_ep, req);
-       }
-       while (!list_empty (&dev->rx_reqs)) {
-               req = container_of (dev->rx_reqs.next,
-                                       struct usb_request, list);
-               list_del (&req->list);
-               usb_ep_free_request (dev->out_ep, req);
-       }
-
        unregister_netdev (dev->net);
        dev_put (dev->net);
 
@@ -1816,10 +1842,6 @@
        dev->gadget = gadget;
        set_gadget_data (gadget, dev);
        gadget->ep0->driver_data = dev;
-       INFO (dev, "%s, " CHIP ", version: " DRIVER_VERSION "\n", driver_desc);
-#ifdef DEV_CONFIG_CDC
-       INFO (dev, "CDC host enet %s\n", ethaddr);
-#endif
        
        /* two kinds of host-initiated state changes:
         *  - iff DATA transfer is active, carrier is "on"
@@ -1830,8 +1852,16 @@
 
        // SET_NETDEV_DEV (dev->net, &gadget->dev);
        status = register_netdev (dev->net);
-       if (status == 0)
+       if (status == 0) {
+
+               INFO (dev, "%s, " CHIP ", version: " DRIVER_VERSION "\n",
+                               driver_desc);
+#ifdef DEV_CONFIG_CDC
+               INFO (dev, "CDC host enet %s\n", ethaddr);
+#endif
                return status;
+       }
+       pr_debug("%s: register_netdev failed, %d\n", shortname, status);
 fail:
        eth_unbind (gadget);
        return status;



-------------------------------------------------------
This SF.net email is sponsored by: The SF.net Donation Program.
Do you like what SourceForge.net is doing for the Open
Source Community?  Make a contribution, and help us add new
features and functionality. Click here: http://sourceforge.net/donate/
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to