Small updates:

 - don't try chiprev 0100 erratum 0114 workaround on
   newer chips; and (mostly) revert it when clearing
   endpoint halt feature.  (bugfix)

 - add missing define for the "force crc error" bit;
   I guess those #defines were generated from old chip
   specs!  potentially useful with test software.

 - sysfs register dump includes chiprev and decodes some
   of the more interesting endpoint response bits.

 - makes a sysfs "gadget" node, representing the gadget
   itself.  (decided against the class_device or bus_type
   approaches, until their value outweighs their costs.)

Please merge.

- Dave
--- linux-2.6/drivers/usb/gadget/net2280.h      2003-08-08 16:35:17.000000000 -0700
+++ gadget-2.6/drivers/usb/gadget/net2280.h     2003-08-24 19:35:26.000000000 -0700
@@ -389,6 +389,7 @@
        u32             ep_rsp;
 #define     SET_NAK_OUT_PACKETS                                 15
 #define     SET_EP_HIDE_STATUS_PHASE                            14
+#define     SET_EP_FORCE_CRC_ERROR                              13
 #define     SET_INTERRUPT_MODE                                  12
 #define     SET_CONTROL_STATUS_PHASE_HANDSHAKE                  11
 #define     SET_NAK_OUT_PACKETS_MODE                            10
@@ -396,6 +397,7 @@
 #define     SET_ENDPOINT_HALT                                   8
 #define     CLEAR_NAK_OUT_PACKETS                               7
 #define     CLEAR_EP_HIDE_STATUS_PHASE                          6
+#define     CLEAR_EP_FORCE_CRC_ERROR                            5
 #define     CLEAR_INTERRUPT_MODE                                4
 #define     CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE                3
 #define     CLEAR_NAK_OUT_PACKETS_MODE                          2
@@ -476,6 +478,9 @@
 #define REG_CHIPREV            0x03    /* in bcd */
 #define        REG_HS_NAK_RATE         0x0a    /* NAK per N uframes */
 
+#define        CHIPREV_1       0x0100
+#define        CHIPREV_1A      0x0110
+
 #ifdef __KERNEL__
 
 /* ep a-f highspeed and fullspeed maxpacket, addresses
@@ -529,24 +534,6 @@
        ep->stopped = 1;
 }
 
-static inline void set_halt (struct net2280_ep *ep)
-{
-       /* ep0 and bulk/intr endpoints */
-       writel (  (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
-                   /* set NAK_OUT for erratum 0114 */
-               | (1 << SET_NAK_OUT_PACKETS)
-               | (1 << SET_ENDPOINT_HALT)
-               , &ep->regs->ep_rsp);
-}
-
-static inline void clear_halt (struct net2280_ep *ep)
-{
-       /* bulk/intr endpoints */
-       writel (  (1 << CLEAR_ENDPOINT_HALT)
-               | (1 << CLEAR_ENDPOINT_TOGGLE)
-               , &ep->regs->ep_rsp);
-}
-
 /* count (<= 4) bytes in the next fifo write will be valid */
 static inline void set_fifo_bytecount (struct net2280_ep *ep, unsigned count)
 {
@@ -589,6 +576,28 @@
        // statistics...
 };
 
+static inline void set_halt (struct net2280_ep *ep)
+{
+       /* ep0 and bulk/intr endpoints */
+       writel (  (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
+                   /* set NAK_OUT for erratum 0114 */
+               | ((ep->dev->chiprev == CHIPREV_1) << SET_NAK_OUT_PACKETS)
+               | (1 << SET_ENDPOINT_HALT)
+               , &ep->regs->ep_rsp);
+}
+
+static inline void clear_halt (struct net2280_ep *ep)
+{
+       /* ep0 and bulk/intr endpoints */
+       writel (  (1 << CLEAR_ENDPOINT_HALT)
+               | (1 << CLEAR_ENDPOINT_TOGGLE)
+                   /* unless the gadget driver left a short packet in the
+                    * fifo, this reverses the erratum 0114 workaround.
+                    */
+               | ((ep->dev->chiprev == CHIPREV_1) << CLEAR_NAK_OUT_PACKETS)
+               , &ep->regs->ep_rsp);
+}
+
 #ifdef USE_RDK_LEDS
 
 static inline void net2280_led_init (struct net2280 *dev)
--- linux-2.6/drivers/usb/gadget/net2280.c      2003-08-09 07:42:10.000000000 -0700
+++ gadget-2.6/drivers/usb/gadget/net2280.c     2003-08-24 19:35:26.000000000 -0700
@@ -30,6 +30,7 @@
 
 /*
  * Copyright (C) 2003 David Brownell
+ * Copyright (C) 2003 NetChip Technologies
  *
  * 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
@@ -76,7 +77,7 @@
 
 
 #define        DRIVER_DESC             "NetChip 2280 USB Peripheral Controller"
-#define        DRIVER_VERSION          "May Day 2003"
+#define        DRIVER_VERSION          "Bastille Day 2003"
 
 #define        DMA_ADDR_INVALID        (~(dma_addr_t)0)
 #define        EP_DONTUSE              13      /* nonzero */
@@ -1344,11 +1345,12 @@
                s = "(none)";
 
        /* Main Control Registers */
-       t = snprintf (next, size, "%s " DRIVER_VERSION "\n"
+       t = snprintf (next, size, "%s version " DRIVER_VERSION
+                       ", chiprev %04x\n"
                        "devinit %03x fifoctl %08x gadget '%s'\n"
                        "pci irqenb0 %02x irqenb1 %08x "
                        "irqstat0 %04x irqstat1 %08x\n",
-                       driver_name,
+                       driver_name, dev->chiprev,
                        readl (&dev->regs->devinit),
                        readl (&dev->regs->fifoctl),
                        s,
@@ -1393,16 +1395,33 @@
                        continue;
 
                t1 = readl (&ep->regs->ep_cfg);
+               t2 = readl (&ep->regs->ep_rsp) & 0xff;
                t = snprintf (next, size,
-                               "%s\tcfg %05x rsp %02x enb %02x ",
-                               ep->ep.name, t1,
-                               readl (&ep->regs->ep_rsp) & 0xff,
+                               "%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s"
+                                       "irqenb %02x\n",
+                               ep->ep.name, t1, t2,
+                               (t2 & (1 << CLEAR_NAK_OUT_PACKETS))
+                                       ? "NAK " : "",
+                               (t2 & (1 << CLEAR_EP_HIDE_STATUS_PHASE))
+                                       ? "hide " : "",
+                               (t2 & (1 << CLEAR_EP_FORCE_CRC_ERROR))
+                                       ? "CRC " : "",
+                               (t2 & (1 << CLEAR_INTERRUPT_MODE))
+                                       ? "interrupt " : "",
+                               (t2 & (1<<CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE))
+                                       ? "status " : "",
+                               (t2 & (1 << CLEAR_NAK_OUT_PACKETS_MODE))
+                                       ? "NAKmode " : "",
+                               (t2 & (1 << CLEAR_ENDPOINT_TOGGLE))
+                                       ? "DATA1 " : "DATA0 ",
+                               (t2 & (1 << CLEAR_ENDPOINT_HALT))
+                                       ? "HALT " : "",
                                readl (&ep->regs->ep_irqenb));
                size -= t;
                next += t;
 
                t = snprintf (next, size,
-                               "stat %08x avail %04x "
+                               "\tstat %08x avail %04x "
                                "(ep%d%s-%s)%s\n",
                                readl (&ep->regs->ep_stat),
                                readl (&ep->regs->ep_avail),
@@ -1796,6 +1815,7 @@
                dev->ep [i].irqs = 0;
 
        /* hook up the driver ... */
+       driver->driver.bus = 0;
        dev->driver = driver;
        dev->gadget.dev.driver = &driver->driver;
        retval = driver->bind (&dev->gadget);
@@ -1807,10 +1827,6 @@
                return retval;
        }
 
-       // FIXME
-       // driver_register (&driver->driver);
-       // device_register (&dev->gadget.dev);
-
        device_create_file (&dev->pdev->dev, &dev_attr_function);
        device_create_file (&dev->pdev->dev, &dev_attr_queues);
 
@@ -1877,10 +1893,6 @@
        device_remove_file (&dev->pdev->dev, &dev_attr_function);
        device_remove_file (&dev->pdev->dev, &dev_attr_queues);
 
-       // FIXME
-       // device_unregister()
-       // driver_unregister (&driver->driver);
-
        DEBUG (dev, "unregistered driver '%s'\n", driver->driver.name);
        return 0;
 }
@@ -2049,9 +2061,9 @@
 
                /* maybe advance queue to next request */
                if (ep->num == 0) {
-                       /* FIXME need mechanism (request flag?) so control OUT
-                        * can decide to stall ep0 after that done() returns,
-                        * from non-irq context
+                       /* NOTE:  net2280 could let gadget driver start the
+                        * status stage later. since not all controllers let
+                        * them control that, the api doesn't (yet) allow it.
                         */
                        if (!ep->stopped)
                                allow_status (ep);
@@ -2174,6 +2186,8 @@
 
                /* watch control traffic at the token level, and force
                 * synchronization before letting the status stage happen.
+                * FIXME ignore tokens we'll NAK, until driver responds.
+                * that'll mean a lot less irqs for some drivers.
                 */
                ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0;
                if (ep->is_in)
@@ -2458,6 +2472,13 @@
 
 /*-------------------------------------------------------------------------*/
 
+static void gadget_release (struct device *_dev)
+{
+       struct net2280  *dev = dev_get_drvdata (_dev);
+
+       kfree (dev);
+}
+
 /* tear down the binding between this driver and the pci device */
 
 static void net2280_remove (struct pci_dev *pdev)
@@ -2493,12 +2514,12 @@
                                pci_resource_len (pdev, 0));
        if (dev->enabled)
                pci_disable_device (pdev);
+       device_unregister (&dev->gadget.dev);
        device_remove_file (&pdev->dev, &dev_attr_registers);
        pci_set_drvdata (pdev, 0);
 
-       INFO (dev, "unbind from pci %s\n", pci_name(pdev));
+       INFO (dev, "unbind\n");
 
-       kfree (dev);
        the_controller = 0;
 }
 
@@ -2518,7 +2539,7 @@
         * usb_gadget_driver_{register,unregister}() must change.
         */
        if (the_controller) {
-               WARN (the_controller, "ignoring %s\n", pci_name(pdev));
+               dev_warn (&pdev->dev, "ignoring\n");
                return -EBUSY;
        }
 
@@ -2534,9 +2555,11 @@
        dev->pdev = pdev;
        dev->gadget.ops = &net2280_ops;
 
-       strcpy (dev->gadget.dev.bus_id, pci_name(pdev));
+       /* the "gadget" abstracts/virtualizes the controller */
+       strcpy (dev->gadget.dev.bus_id, "gadget");
        dev->gadget.dev.parent = &pdev->dev;
        dev->gadget.dev.dma_mask = pdev->dev.dma_mask;
+       dev->gadget.dev.release = gadget_release;
        dev->gadget.name = driver_name;
 
        /* now all the pci goodies ... */
@@ -2650,6 +2673,7 @@
        INFO (dev, "version: %s\n", bufp);
        the_controller = dev;
 
+       device_register (&dev->gadget.dev);
        device_create_file (&pdev->dev, &dev_attr_registers);
 
        return 0;

Reply via email to