linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / usb / gadget / net2280.c
index 0924323..67b13ab 100644 (file)
@@ -26,8 +26,6 @@
  * Copyright (C) 2003 David Brownell
  * Copyright (C) 2003-2005 PLX Technology, Inc.
  *
- * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility with 2282 chip
- *
  * 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
@@ -46,6 +44,7 @@
 #undef DEBUG           /* messages on error and most fault paths */
 #undef VERBOSE         /* extra debug messages (success too) */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -72,8 +71,8 @@
 #include <asm/unaligned.h>
 
 
-#define        DRIVER_DESC             "PLX NET228x USB Peripheral Controller"
-#define        DRIVER_VERSION          "2005 Sept 27"
+#define        DRIVER_DESC             "PLX NET2280 USB Peripheral Controller"
+#define        DRIVER_VERSION          "2005 Feb 03"
 
 #define        DMA_ADDR_INVALID        (~(dma_addr_t)0)
 #define        EP_DONTUSE              13      /* nonzero */
@@ -119,7 +118,7 @@ module_param (fifo_mode, ushort, 0644);
 /* enable_suspend -- When enabled, the driver will respond to
  * USB suspend requests by powering down the NET2280.  Otherwise,
  * USB suspend requests will be ignored.  This is acceptible for
- * self-powered devices
+ * self-powered devices, and helps avoid some quirks.
  */
 static int enable_suspend = 0;
 
@@ -224,11 +223,6 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
        ep->is_in = (tmp & USB_DIR_IN) != 0;
        if (!ep->is_in)
                writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
-       else if (dev->pdev->device != 0x2280) {
-               /* Added for 2282, Don't use nak packets on an in endpoint, this was ignored on 2280 */
-               writel ((1 << CLEAR_NAK_OUT_PACKETS)
-                       | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp);
-       }
 
        writel (tmp, &ep->regs->ep_cfg);
 
@@ -238,9 +232,8 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
                writel (tmp, &dev->regs->pciirqenb0);
 
                tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE)
-                       | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE);
-               if (dev->pdev->device == 0x2280)
-                       tmp |= readl (&ep->regs->ep_irqenb);
+                       | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE)
+                       | readl (&ep->regs->ep_irqenb);
                writel (tmp, &ep->regs->ep_irqenb);
        } else {                                /* dma, per-request */
                tmp = (1 << (8 + ep->num));     /* completion */
@@ -321,18 +314,10 @@ static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep)
        /* init to our chosen defaults, notably so that we NAK OUT
         * packets until the driver queues a read (+note erratum 0112)
         */
-       if (!ep->is_in || ep->dev->pdev->device == 0x2280) {
-               tmp = (1 << SET_NAK_OUT_PACKETS_MODE)
+       tmp = (1 << SET_NAK_OUT_PACKETS_MODE)
                | (1 << SET_NAK_OUT_PACKETS)
                | (1 << CLEAR_EP_HIDE_STATUS_PHASE)
                | (1 << CLEAR_INTERRUPT_MODE);
-       } else {
-               /* added for 2282 */
-               tmp = (1 << CLEAR_NAK_OUT_PACKETS_MODE)
-               | (1 << CLEAR_NAK_OUT_PACKETS)
-               | (1 << CLEAR_EP_HIDE_STATUS_PHASE)
-               | (1 << CLEAR_INTERRUPT_MODE);
-       }
 
        if (ep->num != 0) {
                tmp |= (1 << CLEAR_ENDPOINT_TOGGLE)
@@ -341,18 +326,14 @@ static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep)
        writel (tmp, &ep->regs->ep_rsp);
 
        /* scrub most status bits, and flush any fifo state */
-       if (ep->dev->pdev->device == 0x2280)
-               tmp = (1 << FIFO_OVERFLOW)
-                       | (1 << FIFO_UNDERFLOW);
-       else
-               tmp = 0;
-
-       writel (tmp | (1 << TIMEOUT)
+       writel (  (1 << TIMEOUT)
                | (1 << USB_STALL_SENT)
                | (1 << USB_IN_NAK_SENT)
                | (1 << USB_IN_ACK_RCVD)
                | (1 << USB_OUT_PING_NAK_SENT)
                | (1 << USB_OUT_ACK_SENT)
+               | (1 << FIFO_OVERFLOW)
+               | (1 << FIFO_UNDERFLOW)
                | (1 << FIFO_FLUSH)
                | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT)
                | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)
@@ -405,10 +386,11 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
                return NULL;
        ep = container_of (_ep, struct net2280_ep, ep);
 
-       req = kzalloc(sizeof(*req), gfp_flags);
+       req = kmalloc (sizeof *req, gfp_flags);
        if (!req)
                return NULL;
 
+       memset (req, 0, sizeof *req);
        req->req.dma = DMA_ADDR_INVALID;
        INIT_LIST_HEAD (&req->queue);
 
@@ -737,7 +719,7 @@ fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid)
         */
        if (ep->is_in)
                dmacount |= (1 << DMA_DIRECTION);
-       if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) || ep->dev->pdev->device != 0x2280)
+       else if ((dmacount % ep->ep.maxpacket) != 0)
                dmacount |= (1 << END_OF_CHAIN);
 
        req->valid = valid;
@@ -779,12 +761,9 @@ static inline void stop_dma (struct net2280_dma_regs __iomem *dma)
 static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma)
 {
        struct net2280_dma_regs __iomem *dma = ep->dma;
-       unsigned int tmp = (1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION);
-
-       if (ep->dev->pdev->device != 0x2280)
-               tmp |= (1 << END_OF_CHAIN);
 
-       writel (tmp, &dma->dmacount);
+       writel ((1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION),
+                       &dma->dmacount);
        writel (readl (&dma->dmastat), &dma->dmastat);
 
        writel (td_dma, &dma->dmadesc);
@@ -2132,11 +2111,7 @@ static void handle_ep_small (struct net2280_ep *ep)
        VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n",
                        ep->ep.name, t, req ? &req->req : 0);
 #endif
-       if (!ep->is_in || ep->dev->pdev->device == 0x2280)
-               writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat);
-       else
-               /* Added for 2282 */
-               writel (t, &ep->regs->ep_stat);
+       writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat);
 
        /* for ep0, monitor token irqs to catch data stage length errors
         * and to synchronize on status.
@@ -2165,7 +2140,7 @@ static void handle_ep_small (struct net2280_ep *ep)
                                        ep->stopped = 1;
                                        set_halt (ep);
                                        mode = 2;
-                               } else if (!req && !ep->stopped)
+                               } else if (!req && ep->stopped)
                                        write_fifo (ep, NULL);
                        }
                } else {
@@ -2240,8 +2215,7 @@ static void handle_ep_small (struct net2280_ep *ep)
                        if (likely (req)) {
                                req->td->dmacount = 0;
                                t = readl (&ep->regs->ep_avail);
-                               dma_done (ep, req, count,
-                                       (ep->out_overflow || t) ? -EOVERFLOW : 0);
+                               dma_done (ep, req, count, t);
                        }
 
                        /* also flush to prevent erratum 0106 trouble */
@@ -2279,7 +2253,9 @@ static void handle_ep_small (struct net2280_ep *ep)
                /* if we wrote it all, we're usually done */
                if (req->req.actual == req->req.length) {
                        if (ep->num == 0) {
-                               /* send zlps until the status stage */
+                               /* wait for control status */
+                               if (mode != 2)
+                                       req = NULL;
                        } else if (!req->req.zero || len != ep->ep.maxpacket)
                                mode = 2;
                }
@@ -2362,7 +2338,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
                        u32                     raw [2];
                        struct usb_ctrlrequest  r;
                } u;
-               int                             tmp;
+               int                             tmp = 0;
                struct net2280_request          *req;
 
                if (dev->gadget.speed == USB_SPEED_UNKNOWN) {
@@ -2389,19 +2365,14 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
                }
                ep->stopped = 0;
                dev->protocol_stall = 0;
-
-               if (ep->dev->pdev->device == 0x2280)
-                       tmp = (1 << FIFO_OVERFLOW)
-                               | (1 << FIFO_UNDERFLOW);
-               else
-                       tmp = 0;
-
-               writel (tmp | (1 << TIMEOUT)
+               writel (  (1 << TIMEOUT)
                        | (1 << USB_STALL_SENT)
                        | (1 << USB_IN_NAK_SENT)
                        | (1 << USB_IN_ACK_RCVD)
                        | (1 << USB_OUT_PING_NAK_SENT)
                        | (1 << USB_OUT_ACK_SENT)
+                       | (1 << FIFO_OVERFLOW)
+                       | (1 << FIFO_UNDERFLOW)
                        | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT)
                        | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)
                        | (1 << DATA_PACKET_RECEIVED_INTERRUPT)
@@ -2415,8 +2386,6 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
                cpu_to_le32s (&u.raw [0]);
                cpu_to_le32s (&u.raw [1]);
 
-               tmp = 0;
-
 #define        w_value         le16_to_cpup (&u.r.wValue)
 #define        w_index         le16_to_cpup (&u.r.wIndex)
 #define        w_length        le16_to_cpup (&u.r.wLength)
@@ -2626,17 +2595,10 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
                writel (stat, &dev->regs->irqstat1);
 
        /* some status we can just ignore */
-       if (dev->pdev->device == 0x2280)
-               stat &= ~((1 << CONTROL_STATUS_INTERRUPT)
-                         | (1 << SUSPEND_REQUEST_INTERRUPT)
-                         | (1 << RESUME_INTERRUPT)
-                         | (1 << SOF_INTERRUPT));
-       else
-               stat &= ~((1 << CONTROL_STATUS_INTERRUPT)
-                         | (1 << RESUME_INTERRUPT)
-                         | (1 << SOF_DOWN_INTERRUPT)
-                         | (1 << SOF_INTERRUPT));
-
+       stat &= ~((1 << CONTROL_STATUS_INTERRUPT)
+                       | (1 << SUSPEND_REQUEST_INTERRUPT)
+                       | (1 << RESUME_INTERRUPT)
+                       | (1 << SOF_INTERRUPT));
        if (!stat)
                return;
        // DEBUG (dev, "irqstat1 %08x\n", stat);
@@ -2741,10 +2703,6 @@ static irqreturn_t net2280_irq (int irq, void *_dev, struct pt_regs * r)
 {
        struct net2280          *dev = _dev;
 
-       /* shared interrupt, not ours */
-       if (!(readl(&dev->regs->irqstat0) & (1 << INTA_ASSERTED)))
-               return IRQ_NONE;
-
        spin_lock (&dev->lock);
 
        /* handle disconnect, dma, and more */
@@ -2821,6 +2779,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
        unsigned long           resource, len;
        void                    __iomem *base = NULL;
        int                     retval, i;
+       char                    buf [8], *bufp;
 
        /* if you want to support more than one controller in a system,
         * usb_gadget_driver_{register,unregister}() must change.
@@ -2831,13 +2790,13 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
        }
 
        /* alloc, and start init */
-       dev = kzalloc (sizeof *dev, SLAB_KERNEL);
+       dev = kmalloc (sizeof *dev, SLAB_KERNEL);
        if (dev == NULL){
                retval = -ENOMEM;
                goto done;
        }
 
-       pci_set_drvdata (pdev, dev);
+       memset (dev, 0, sizeof *dev);
        spin_lock_init (&dev->lock);
        dev->pdev = pdev;
        dev->gadget.ops = &net2280_ops;
@@ -2894,10 +2853,15 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
                retval = -ENODEV;
                goto done;
        }
-
-       if (request_irq (pdev->irq, net2280_irq, IRQF_SHARED, driver_name, dev)
+#ifndef __sparc__
+       scnprintf (buf, sizeof buf, "%d", pdev->irq);
+       bufp = buf;
+#else
+       bufp = __irq_itoa(pdev->irq);
+#endif
+       if (request_irq (pdev->irq, net2280_irq, SA_SHIRQ, driver_name, dev)
                        != 0) {
-               ERROR (dev, "request interrupt %d failed\n", pdev->irq);
+               ERROR (dev, "request interrupt %s failed\n", bufp);
                retval = -EBUSY;
                goto done;
        }
@@ -2945,9 +2909,10 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
        dev->chiprev = get_idx_reg (dev->regs, REG_CHIPREV) & 0xffff;
 
        /* done */
+       pci_set_drvdata (pdev, dev);
        INFO (dev, "%s\n", driver_desc);
-       INFO (dev, "irq %d, pci mem %p, chip rev %04x\n",
-                       pdev->irq, base, dev->chiprev);
+       INFO (dev, "irq %s, pci mem %p, chip rev %04x\n",
+                       bufp, base, dev->chiprev);
        INFO (dev, "version: " DRIVER_VERSION "; dma %s\n",
                        use_dma
                                ? (use_dma_chaining ? "chaining" : "enabled")
@@ -2965,22 +2930,6 @@ done:
        return retval;
 }
 
-/* make sure the board is quiescent; otherwise it will continue
- * generating IRQs across the upcoming reboot.
- */
-
-static void net2280_shutdown (struct pci_dev *pdev)
-{
-       struct net2280          *dev = pci_get_drvdata (pdev);
-
-       /* disable IRQs */
-       writel (0, &dev->regs->pciirqenb0);
-       writel (0, &dev->regs->pciirqenb1);
-
-       /* disable the pullup so the host will think we're gone */
-       writel (0, &dev->usb->usbctl);
-}
-
 
 /*-------------------------------------------------------------------------*/
 
@@ -2991,13 +2940,6 @@ static struct pci_device_id pci_ids [] = { {
        .device =       0x2280,
        .subvendor =    PCI_ANY_ID,
        .subdevice =    PCI_ANY_ID,
-}, {
-       .class =        ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
-       .class_mask =   ~0,
-       .vendor =       0x17cc,
-       .device =       0x2282,
-       .subvendor =    PCI_ANY_ID,
-       .subdevice =    PCI_ANY_ID,
 
 }, { /* end: all zeroes */ }
 };
@@ -3010,7 +2952,6 @@ static struct pci_driver net2280_pci_driver = {
 
        .probe =        net2280_probe,
        .remove =       net2280_remove,
-       .shutdown =     net2280_shutdown,
 
        /* FIXME add power management support */
 };