ChangeSet 1.1276.1.52, 2003/08/27 17:31:43-07:00, [EMAIL PROTECTED]

[PATCH] USB: net2280 fixes: ep halt, sysfs

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.)


 drivers/usb/gadget/net2280.c |   68 +++++++++++++++++++++++++++++--------------
 drivers/usb/gadget/net2280.h |   45 +++++++++++++++++-----------
 2 files changed, 73 insertions(+), 40 deletions(-)


diff -Nru a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
--- a/drivers/usb/gadget/net2280.c      Tue Sep  2 12:43:19 2003
+++ b/drivers/usb/gadget/net2280.c      Tue Sep  2 12:43:19 2003
@@ -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
@@ -77,7 +78,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 */
@@ -1345,11 +1346,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,
@@ -1394,16 +1396,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),
@@ -1797,6 +1816,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);
@@ -1808,10 +1828,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);
 
@@ -1878,10 +1894,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;
 }
@@ -2050,9 +2062,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);
@@ -2175,6 +2187,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)
@@ -2459,6 +2473,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)
@@ -2494,12 +2515,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;
 }
 
@@ -2519,7 +2540,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;
        }
 
@@ -2535,9 +2556,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 ... */
@@ -2651,6 +2674,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;
diff -Nru a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h
--- a/drivers/usb/gadget/net2280.h      Tue Sep  2 12:43:19 2003
+++ b/drivers/usb/gadget/net2280.h      Tue Sep  2 12:43:19 2003
@@ -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)
 {
@@ -588,6 +575,28 @@
        struct pci_pool                 *requests;
        // 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
 



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to