// SPDX-License-Identifier: GPL-2.0+
/*
 * Driver for the PLX NET2280 USB device controller.
 * Specs and errata are available from <http://www.plxtech.com>.
 *
 * PLX Technology Inc. (formerly NetChip Technology) supported the
 * development of this driver.
 *
 *
 * CODE STATUS HIGHLIGHTS
 *
 * This driver should work well with most "gadget" drivers, including
 * the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers
 * as well as Gadget Zero and Gadgetfs.
 *
 * DMA is enabled by default.
 *
 * MSI is enabled by default.  The legacy IRQ is used if MSI couldn't
 * be enabled.
 *
 * Note that almost all the errata workarounds here are only needed for
 * rev1 chips.  Rev1a silicon (0110) fixes almost all of them.
 */

/*
 * Copyright (C) 2003 David Brownell
 * Copyright (C) 2003-2005 PLX Technology, Inc.
 * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS
 *
 * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility
 *	with 2282 chip
 *
 * Modified Ricardo Ribalda Qtechnology AS  to provide compatibility
 *	with usb 338x chip. Based on PLX driver
 */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/prefetch.h>
#include <linux/io.h>
#include <linux/iopoll.h>

#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/unaligned.h>

#define	DRIVER_DESC		"PLX NET228x/USB338x USB Peripheral Controller"
#define	DRIVER_VERSION		"2005 Sept 27/v3.0"

#define	EP_DONTUSE		13	/* nonzero */

#define USE_RDK_LEDS		/* GPIO pins control three LEDs */


static const char driver_name[] = "net2280";
static const char driver_desc[] = DRIVER_DESC;

static const u32 ep_bit[9] = { 0, 17, 2, 19, 4, 1, 18, 3, 20 };
static const char ep0name[] = "ep0";

#define EP_INFO(_name, _caps) \
	{ \
		.name = _name, \
		.caps = _caps, \
	}

static const struct {
	const char *name;
	const struct usb_ep_caps caps;
} ep_info_dft[] = { /* Default endpoint configuration */
	EP_INFO(ep0name,
		USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL, USB_EP_CAPS_DIR_ALL)),
	EP_INFO("ep-a",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_ALL)),
	EP_INFO("ep-b",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_ALL)),
	EP_INFO("ep-c",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_ALL)),
	EP_INFO("ep-d",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_ALL)),
	EP_INFO("ep-e",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_ALL)),
	EP_INFO("ep-f",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_ALL)),
	EP_INFO("ep-g",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_ALL)),
	EP_INFO("ep-h",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_ALL)),
}, ep_info_adv[] = { /* Endpoints for usb3380 advance mode */
	EP_INFO(ep0name,
		USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL, USB_EP_CAPS_DIR_ALL)),
	EP_INFO("ep1in",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)),
	EP_INFO("ep2out",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
	EP_INFO("ep3in",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)),
	EP_INFO("ep4out",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
	EP_INFO("ep1out",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
	EP_INFO("ep2in",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)),
	EP_INFO("ep3out",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
	EP_INFO("ep4in",
		USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)),
};

#undef EP_INFO

/* mode 0 == ep-{a,b,c,d} 1K fifo each
 * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable
 * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable
 */
static ushort fifo_mode;

/* "modprobe net2280 fifo_mode=1" etc */
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 acceptable for
 * self-powered devices
 */
static bool enable_suspend;

/* "modprobe net2280 enable_suspend=1" etc */
module_param(enable_suspend, bool, 0444);

#define	DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out")

static char *type_string(u8 bmAttributes)
{
	switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) {
	case USB_ENDPOINT_XFER_BULK:	return "bulk";
	case USB_ENDPOINT_XFER_ISOC:	return "iso";
	case USB_ENDPOINT_XFER_INT:	return "intr";
	}
	return "control";
}

#include "net2280.h"

#define valid_bit	cpu_to_le32(BIT(VALID_BIT))
#define dma_done_ie	cpu_to_le32(BIT(DMA_DONE_INTERRUPT_ENABLE))

static void ep_clear_seqnum(struct net2280_ep *ep);
static void stop_activity(struct net2280 *dev,
					struct usb_gadget_driver *driver);
static void ep0_start(struct net2280 *dev);

/*-------------------------------------------------------------------------*/
static inline void enable_pciirqenb(struct net2280_ep *ep)
{
	u32 tmp = readl(&ep->dev->regs->pciirqenb0);

	if (ep->dev->quirks & PLX_LEGACY)
		tmp |= BIT(ep->num);
	else
		tmp |= BIT(ep_bit[ep->num]);
	writel(tmp, &ep->dev->regs->pciirqenb0);

	return;
}

static int
net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
{
	struct net2280		*dev;
	struct net2280_ep	*ep;
	u32			max;
	u32 tmp = 0;
	u32 type;
	unsigned long		flags;
	static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 };
	int ret = 0;

	ep = container_of(_ep, struct net2280_ep, ep);
	if (!_ep || !desc || ep->desc || _ep->name == ep0name ||
			desc->bDescriptorType != USB_DT_ENDPOINT) {
		pr_err("%s: failed at line=%d\n", __func__, __LINE__);
		return -EINVAL;
	}
	dev = ep->dev;
	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
		ret = -ESHUTDOWN;
		goto print_err;
	}

	/* erratum 0119 workaround ties up an endpoint number */
	if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) {
		ret = -EDOM;
		goto print_err;
	}

	if (dev->quirks & PLX_PCIE) {
		if ((desc->bEndpointAddress & 0x0f) >= 0x0c) {
			ret = -EDOM;
			goto print_err;
		}
		ep->is_in = !!usb_endpoint_dir_in(desc);
		if (dev->enhanced_mode && ep->is_in && ep_key[ep->num]) {
			ret = -EINVAL;
			goto print_err;
		}
	}

	/* sanity check ep-e/ep-f since their fifos are small */
	max = usb_endpoint_maxp(desc);
	if (ep->num > 4 && max > 64 && (dev->quirks & PLX_LEGACY)) {
		ret = -ERANGE;
		goto print_err;
	}

	spin_lock_irqsave(&dev->lock, flags);
	_ep->maxpacket = max;
	ep->desc = desc;

	/* ep_reset() has already been called */
	ep->stopped = 0;
	ep->wedged = 0;
	ep->out_overflow = 0;

	/* set speed-dependent max packet; may kick in high bandwidth */
	set_max_speed(ep, max);

	/* set type, direction, address; reset fifo counters */
	writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat);

	if ((dev->quirks & PLX_PCIE) && dev->enhanced_mode) {
		tmp = readl(&ep->cfg->ep_cfg);
		/* If USB ep number doesn't match hardware ep number */
		if ((tmp & 0xf) != usb_endpoint_num(desc)) {
			ret = -EINVAL;
			spin_unlock_irqrestore(&dev->lock, flags);
			goto print_err;
		}
		if (ep->is_in)
			tmp &= ~USB3380_EP_CFG_MASK_IN;
		else
			tmp &= ~USB3380_EP_CFG_MASK_OUT;
	}
	type = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
	if (type == USB_ENDPOINT_XFER_INT) {
		/* erratum 0105 workaround prevents hs NYET */
		if (dev->chiprev == 0100 &&
				dev->gadget.speed == USB_SPEED_HIGH &&
				!(desc->bEndpointAddress & USB_DIR_IN))
			writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE),
				&ep->regs->ep_rsp);
	} else if (type == USB_ENDPOINT_XFER_BULK) {
		/* catch some particularly blatant driver bugs */
		if ((dev->gadget.speed == USB_SPEED_SUPER && max != 1024) ||
		    (dev->gadget.speed == USB_SPEED_HIGH && max != 512) ||
		    (dev->gadget.speed == USB_SPEED_FULL && max > 64)) {
			spin_unlock_irqrestore(&dev->lock, flags);
			ret = -ERANGE;
			goto print_err;
		}
	}
	ep->is_iso = (type == USB_ENDPOINT_XFER_ISOC);
	/* Enable this endpoint */
	if (dev->quirks & PLX_LEGACY) {
		tmp |= type << ENDPOINT_TYPE;
		tmp |= desc->bEndpointAddress;
		/* default full fifo lines */
		tmp |= (4 << ENDPOINT_BYTE_COUNT);
		tmp |= BIT(ENDPOINT_ENABLE);
		ep->is_in = (tmp & USB_DIR_IN) != 0;
	} else {
		/* In Legacy mode, only OUT endpoints are used */
		if (dev->enhanced_mode && ep->is_in) {
			tmp |= type << IN_ENDPOINT_TYPE;
			tmp |= BIT(IN_ENDPOINT_ENABLE);
		} else {
			tmp |= type << OUT_ENDPOINT_TYPE;
			tmp |= BIT(OUT_ENDPOINT_ENABLE);
			tmp |= (ep->is_in << ENDPOINT_DIRECTION);
		}

		tmp |= (4 << ENDPOINT_BYTE_COUNT);
		if (!dev->enhanced_mode)
			tmp |= usb_endpoint_num(desc);
		tmp |= (ep->ep.maxburst << MAX_BURST_SIZE);
	}

	/* Make sure all the registers are written before ep_rsp*/
	wmb();

	/* for OUT transfers, block the rx fifo until a read is posted */
	if (!ep->is_in)
		writel(BIT(SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
	else if (!(dev->quirks & PLX_2280)) {
		/* Added for 2282, Don't use nak packets on an in endpoint,
		 * this was ignored on 2280
		 */
		writel(BIT(CLEAR_NAK_OUT_PACKETS) |
			BIT(CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp);
	}

	if (dev->quirks & PLX_PCIE)
		ep_clear_seqnum(ep);
	writel(tmp, &ep->cfg->ep_cfg);

	/* enable irqs */
	if (!ep->dma) {				/* pio, per-packet */
		enable_pciirqenb(ep);

		tmp = BIT(DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) |
			BIT(DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE);
		if (dev->quirks & PLX_2280)
			tmp |= readl(&ep->regs->ep_irqenb);
		writel(tmp, &ep->regs->ep_irqenb);
	} else {				/* dma, per-request */
		tmp = BIT((8 + ep->num));	/* completion */
		tmp |= readl(&dev->regs->pciirqenb1);
		writel(tmp, &dev->regs->pciirqenb1);

		/* for short OUT transfers, dma completions can't
		 * advance the queue; do it pio-style, by hand.
		 * NOTE erratum 0112 workaround #2
		 */
		if ((desc->bEndpointAddress & USB_DIR_IN) == 0) {
			tmp = BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE);
			writel(tmp, &ep->regs->ep_irqenb);

			enable_pciirqenb(ep);
		}
	}

	tmp = desc->bEndpointAddress;
	ep_dbg(dev, "enabled %s (ep%d%s-%s) %s max %04x\n",
		_ep->name, tmp & 0x0f, DIR_STRING(tmp),
		type_string(desc->bmAttributes),
		ep->dma ? "dma" : "pio", max);

	/* pci writes may still be posted */
	spin_unlock_irqrestore(&dev->lock, flags);
	return ret;

print_err:
	dev_err(&ep->dev->pdev->dev, "%s: error=%d\n", __func__, ret);
	return ret;
}

static int handshake(u32 __iomem *ptr, u32 mask, u32 done, int usec)
{
	u32	result;
	int	ret;

	ret = readl_poll_timeout_atomic(ptr, result,
					((result & mask) == done ||
					 result == U32_MAX),
					1, usec);
	if (result == U32_MAX)		/* device unplugged */
		return -ENODEV;

	return ret;
}

static const struct usb_ep_ops net2280_ep_ops;

static void ep_reset_228x(struct net2280_regs __iomem *regs,
			  struct net2280_ep *ep)
{
	u32		tmp;

	ep->desc = NULL;
	INIT_LIST_HEAD(&ep->queue);

	usb_ep_set_maxpacket_limit(&ep->ep, ~0);
	ep->ep.ops = &net2280_ep_ops;

	/* disable the dma, irqs, endpoint... */
	if (ep->dma) {
		writel(0, &ep->dma->dmactl);
		writel(BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) |
			BIT(DMA_TRANSACTION_DONE_INTERRUPT) |
			BIT(DMA_ABORT),
			&ep->dma->dmastat);

		tmp = readl(&regs->pciirqenb0);
		tmp &= ~BIT(ep->num);
		writel(tmp, &regs->pciirqenb0);
	} else {
		tmp = readl(&regs->pciirqenb1);
		tmp &= ~BIT((8 + ep->num));	/* completion */
		writel(tmp, &regs->pciirqenb1);
	}
	writel(0, &ep->regs->ep_irqenb);

	/* 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->quirks & PLX_2280)) {
		tmp = BIT(SET_NAK_OUT_PACKETS_MODE) |
		BIT(SET_NAK_OUT_PACKETS) |
		BIT(CLEAR_EP_HIDE_STATUS_PHASE) |
		BIT(CLEAR_INTERRUPT_MODE);
	} else {
		/* added for 2282 */
		tmp = BIT(CLEAR_NAK_OUT_PACKETS_MODE) |
		BIT(CLEAR_NAK_OUT_PACKETS) |
		BIT(CLEAR_EP_HIDE_STATUS_PHASE) |
		BIT(CLEAR_INTERRUPT_MODE);
	}

	if (ep->num != 0) {
		tmp |= BIT(CLEAR_ENDPOINT_TOGGLE) |
			BIT(CLEAR_ENDPOINT_HALT);
	}
	writel(tmp, &ep->regs->ep_rsp);

	/* scrub most status bits, and flush any fifo state */
	if (ep->dev->quirks & PLX_2280)
		tmp = BIT(FIFO_OVERFLOW) |
			BIT(FIFO_UNDERFLOW);
	else
		tmp = 0;

	writel(tmp | BIT(TIMEOUT) |
		BIT(USB_STALL_SENT) |
		BIT(USB_IN_NAK_SENT) |
		BIT(USB_IN_ACK_RCVD) |
		BIT(USB_OUT_PING_NAK_SENT) |
		BIT(USB_OUT_ACK_SENT) |
		BIT(FIFO_FLUSH) |
		BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) |
		BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) |
		BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
		BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
		BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
		BIT(DATA_IN_TOKEN_INTERRUPT),
		&ep->regs->ep_stat);

	/* fifo size is handled separately */
}

static void ep_reset_338x(struct net2280_regs __iomem *regs,
					struct net2280_ep *ep)
{
	u32 tmp, dmastat;

	ep->desc = NULL;
	INIT_LIST_HEAD(&ep->queue);

	usb_ep_set_maxpacket_limit(&ep->ep, ~0);
	ep->ep.ops = &net2280_ep_ops;

	/* disable the dma, irqs, endpoint... */
	if (ep->dma) {
		writel(0, &ep->dma->dmactl);
		writel(BIT(DMA_ABORT_DONE_INTERRUPT) |
		       BIT(DMA_PAUSE_DONE_INTERRUPT) |
		       BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) |
		       BIT(DMA_TRANSACTION_DONE_INTERRUPT),
		       /* | BIT(DMA_ABORT), */
		       &ep->dma->dmastat);

		dmastat = readl(&ep->dma->dmastat);
		if (dmastat == 0x5002) {
			ep_warn(ep->dev, "The dmastat return = %x!!\n",
			       dmastat);
			writel(0x5a, &ep->dma->dmastat);
		}

		tmp = readl(&regs->pciirqenb0);
		tmp &= ~BIT(ep_bit[ep->num]);
		writel(tmp, &regs->pciirqenb0);
	} else {
		if (ep->num < 5) {
			tmp = readl(&regs->pciirqenb1);
			tmp &= ~BIT((8 + ep->num));	/* completion */
			writel(tmp, &regs->pciirqenb1);
		}
	}
	writel(0, &ep->regs->ep_irqenb);

	writel(BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) |
	       BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) |
	       BIT(FIFO_OVERFLOW) |
	       BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
	       BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
	       BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
	       BIT(DATA_IN_TOKEN_INTERRUPT), &ep->regs->ep_stat);

	tmp = readl(&ep->cfg->ep_cfg);
	if (ep->is_in)
		tmp &= ~USB3380_EP_CFG_MASK_IN;
	else
		tmp &= ~USB3380_EP_CFG_MASK_OUT;
	writel(tmp, &ep->cfg->ep_cfg);
}

static void nuke(struct net2280_ep *);

static int net2280_disable(struct usb_ep *_ep)
{
	struct net2280_ep	*ep;
	unsigned long		flags;

	ep = container_of(_ep, struct net2280_ep, ep);
	if (!_ep || _ep->name == ep0name) {
		pr_err("%s: Invalid ep=%p\n", __func__, _ep);
		return -EINVAL;
	}
	spin_lock_irqsave(&ep->dev->lock, flags);
	nuke(ep);

	if (ep->dev->quirks & PLX_PCIE)
		ep_reset_338x(ep->dev->regs, ep);
	else
		ep_reset_228x(ep->dev->regs, ep);

	ep_vdbg(ep->dev, "disabled %s %s\n",
			ep->dma ? "dma" : "pio", _ep->name);

	/* synch memory views with the device */
	(void)readl(&ep->cfg->ep_cfg);

	if (!ep->dma && ep->num >= 1 && ep->num <= 4)
		ep->dma = &ep->dev->dma[ep->num - 1];

	spin_unlock_irqrestore(&ep->dev->lock, flags);
	return 0;
}

/*-------------------------------------------------------------------------*/

static struct usb_request
*net2280_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
{
	struct net2280_ep	*ep;
	struct net2280_request	*req;

	if (!_ep) {
		pr_err("%s: Invalid ep\n", __func__);
		return NULL;
	}
	ep = container_of(_ep, struct net2280_ep, ep);

	req = kzalloc(sizeof(*req), gfp_flags);
	if (!req)
		return NULL;

	INIT_LIST_HEAD(&req->queue);

	/* this dma descriptor may be swapped with the previous dummy */
	if (ep->dma) {
		struct net2280_dma	*td;

		td = dma_pool_alloc(ep->dev->requests, gfp_flags,
				&req->td_dma);
		if (!td) {
			kfree(req);
			return NULL;
		}
		td->dmacount = 0;	/* not VALID */
		td->dmadesc = td->dmaaddr;
		req->td = td;
	}
	return &req->req;
}

static void net2280_free_request(struct usb_ep *_ep, struct usb_request *_req)
{
	struct net2280_ep	*ep;
	struct net2280_request	*req;

	ep = container_of(_ep, struct net2280_ep, ep);
	if (!_ep || !_req) {
		dev_err(&ep->dev->pdev->dev, "%s: Invalid ep=%p or req=%p\n",
							__func__, _ep, _req);
		return;
	}

	req = container_of(_req, struct net2280_request, req);
	WARN_ON(!list_empty(&req->queue));
	if (req->td)
		dma_pool_free(ep->dev->requests, req->td, req->td_dma);
	kfree(req);
}

/*-------------------------------------------------------------------------*/

/* load a packet into the fifo we use for usb IN transfers.
 * works for all endpoints.
 *
 * NOTE: pio with ep-a..ep-d could stuff multiple packets into the fifo
 * at a time, but this code is simpler because it knows it only writes
 * one packet.  ep-a..ep-d should use dma instead.
 */
static void write_fifo(struct net2280_ep *ep, struct usb_request *req)
{
	struct net2280_ep_regs	__iomem *regs = ep->regs;
	u8			*buf;
	u32			tmp;
	unsigned		count, total;

	/* INVARIANT:  fifo is currently empty. (testable) */

	if (req) {
		buf = req->buf + req->actual;
		prefetch(buf);
		total = req->length - req->actual;
	} else {
		total = 0;
		buf = NULL;
	}

	/* write just one packet at a time */
	count = ep->ep.maxpacket;
	if (count > total)	/* min() cannot be used on a bitfield */
		count = total;

	ep_vdbg(ep->dev, "write %s fifo (IN) %d bytes%s req %p\n",
			ep->ep.name, count,
			(count != ep->ep.maxpacket) ? " (short)" : "",
			req);
	while (count >= 4) {
		/* NOTE be careful if you try to align these. fifo lines
		 * should normally be full (4 bytes) and successive partial
		 * lines are ok only in certain cases.
		 */
		tmp = get_unaligned((u32 *)buf);
		cpu_to_le32s(&tmp);
		writel(tmp, &regs->ep_data);
		buf += 4;
		count -= 4;
	}

	/* last fifo entry is "short" unless we wrote a full packet.
	 * also explicitly validate last word in (periodic) transfers
	 * when maxpacket is not a multiple of 4 bytes.
	 */
	if (count || total < ep->ep.maxpacket) {
		tmp = count ? get_unaligned((u32 *)buf) : count;
		cpu_to_le32s(&tmp);
		set_fifo_bytecount(ep, count & 0x03);
		writel(tmp, &regs->ep_data);
	}

	/* pci writes may still be posted */
}

/* work around erratum 0106: PCI and USB race over the OUT fifo.
 * caller guarantees chiprev 0100, out endpoint is NAKing, and
 * there's no real data in the fifo.
 *
 * NOTE:  also used in cases where that erratum doesn't apply:
 * where the host wrote "too much" data to us.
 */
static void out_flush(struct net2280_ep *ep)
{
	u32	__iomem *statp;
	u32	tmp;

	statp = &ep->regs->ep_stat;

	tmp = readl(statp);
	if (tmp & BIT(NAK_OUT_PACKETS)) {
		ep_dbg(ep->dev, "%s %s %08x !NAK\n",
			ep->ep.name, __func__, tmp);
		writel(BIT(SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
	}

	writel(BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
		BIT(DATA_PACKET_RECEIVED_INTERRUPT),
		statp);
	writel(BIT(FIFO_FLUSH), statp);
	/* Make sure that stap is written */
	mb();
	tmp = readl(statp);
	if (tmp & BIT(DATA_OUT_PING_TOKEN_INTERRUPT) &&
			/* high speed did bulk NYET; fifo isn't filling */
			ep->dev->gadget.speed == USB_SPEED_FULL) {
		unsigned	usec;

		usec = 50;		/* 64 byte bulk/interrupt */
		handshake(statp, BIT(USB_OUT_PING_NAK_SENT),
				BIT(USB_OUT_PING_NAK_SENT), usec);
		/* NAK done; now CLEAR_NAK_OUT_PACKETS is safe */
	}
}

/* unload packet(s) from the fifo we use for usb OUT transfers.
 * returns true iff the request completed, because of short packet
 * or the request buffer having filled with full packets.
 *
 * for ep-a..ep-d this will read multiple packets out when they
 * have been accepted.
 */
static int read_fifo(struct net2280_ep *ep, struct net2280_request *req)
{
	struct net2280_ep_regs	__iomem *regs = ep->regs;
	u8			*buf = req->req.buf + req->req.actual;
	unsigned		count, tmp, is_short;
	unsigned		cleanup = 0, prevent = 0;

	/* erratum 0106 ... packets coming in during fifo reads might
	 * be incompletely rejected.  not all cases have workarounds.
	 */
	if (ep->dev->chiprev == 0x0100 &&
			ep->dev->gadget.speed == USB_SPEED_FULL) {
		udelay(1);
		tmp = readl(&ep->regs->ep_stat);
		if ((tmp & BIT(NAK_OUT_PACKETS)))
			cleanup = 1;
		else if ((tmp & BIT(FIFO_FULL))) {
			start_out_naking(ep);
			prevent = 1;
		}
		/* else: hope we don't see the problem */
	}

	/* never overflow the rx buffer. the fifo reads packets until
	 * it sees a short one; we might not be ready for them all.
	 */
	prefetchw(buf);
	count = readl(&regs->ep_avail);
	if (unlikely(count == 0)) {
		udelay(1);
		tmp = readl(&ep->regs->ep_stat);
		count = readl(&regs->ep_avail);
		/* handled that data already? */
		if (count == 0 && (tmp & BIT(NAK_OUT_PACKETS)) == 0)
			return 0;
	}

	tmp = req->req.length - req->req.actual;
	if (count > tmp) {
		/* as with DMA, data overflow gets flushed */
		if ((tmp % ep->ep.maxpacket) != 0) {
			ep_err(ep->dev,
				"%s out fifo %d bytes, expected %d\n",
				ep->ep.name, count, tmp);
			req->req.status = -EOVERFLOW;
			cleanup = 1;
			/* NAK_OUT_PACKETS will be set, so flushing is safe;
			 * the next read will start with the next packet
			 */
		} /* else it's a ZLP, no worries */
		count = tmp;
	}
	req->req.actual += count;

	is_short = (count == 0) || ((count % ep->ep.maxpacket) != 0);

	ep_vdbg(ep->dev, "read %s fifo (OUT) %d bytes%s%s%s req %p %d/%d\n",
			ep->ep.name, count, is_short ? " (short)" : "",
			cleanup ? " flush" : "", prevent ? " nak" : "",
			req, req->req.actual, req->req.length);

	while (count >= 4) {
		tmp = readl(&regs->ep_data);
		cpu_to_le32s(&tmp);
		put_unaligned(tmp, (u32 *)buf);
		buf += 4;
		count -= 4;
	}
	if (count) {
		tmp = readl(&regs->ep_data);
		/* LE conversion is implicit here: */
		do {
			*buf++ = (u8) tmp;
			tmp >>= 8;
		} while (--count);
	}
	if (cleanup)
		out_flush(ep);
	if (prevent) {
		writel(BIT(CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
		(void) readl(&ep->regs->ep_rsp);
	}

	return is_short || req->req.actual == req->req.length;
}

/* fill out dma descriptor to match a given request */
static void fill_dma_desc(struct net2280_ep *ep,
					struct net2280_request *req, int valid)
{
	struct net2280_dma	*td = req->td;
	u32			dmacount = req->req.length;

	/* don't let DMA continue after a short OUT packet,
	 * so overruns can't affect the next transfer.
	 * in case of overruns on max-size packets, we can't
	 * stop the fifo from filling but we can flush it.
	 */
	if (ep->is_in)
		dmacount |= BIT(DMA_DIRECTION);
	if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) ||
					!(ep->dev->quirks & PLX_2280))
		dmacount |= BIT(END_OF_CHAIN);

	req->valid = valid;
	if (valid)
		dmacount |= BIT(VALID_BIT);
	dmacount |= BIT(DMA_DONE_INTERRUPT_ENABLE);

	/* td->dmadesc = previously set by caller */
	td->dmaaddr = cpu_to_le32 (req->req.dma);

	/* 2280 may be polling VALID_BIT through ep->dma->dmadesc */
	wmb();
	td->dmacount = cpu_to_le32(dmacount);
}

static const u32 dmactl_default =
		BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) |
		BIT(DMA_CLEAR_COUNT_ENABLE) |
		/* erratum 0116 workaround part 1 (use POLLING) */
		(POLL_100_USEC << DESCRIPTOR_POLLING_RATE) |
		BIT(DMA_VALID_BIT_POLLING_ENABLE) |
		BIT(DMA_VALID_BIT_ENABLE) |
		BIT(DMA_SCATTER_GATHER_ENABLE) |
		/* erratum 0116 workaround part 2 (no AUTOSTART) */
		BIT(DMA_ENABLE);

static inline void spin_stop_dma(struct net2280_dma_regs __iomem *dma)
{
	handshake(&dma->dmactl, BIT(DMA_ENABLE), 0, 50);
}

static inline void stop_dma(struct net2280_dma_regs __iomem *dma)
{
	writel(readl(&dma->dmactl) & ~BIT(DMA_ENABLE), &dma->dmactl);
	spin_stop_dma(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 = BIT(VALID_BIT) | (ep->is_in << DMA_DIRECTION);

	if (!(ep->dev->quirks & PLX_2280))
		tmp |= BIT(END_OF_CHAIN);

	writel(tmp, &dma->dmacount);
	writel(readl(&dma->dmastat), &dma->dmastat);

	writel(td_dma, &dma->dmadesc);
	if (ep->dev->quirks & PLX_PCIE)
		dmactl |= BIT(DMA_REQUEST_OUTSTANDING);
	writel(dmactl, &dma->dmactl);

	/* erratum 0116 workaround part 3:  pci arbiter away from net2280 */
	(void) readl(&ep->dev->pci->pcimstctl);

	writel(BIT(DMA_START), &dma->dmastat);
}

static void start_dma(struct net2280_ep *ep, struct net2280_request *req)
{
	u32			tmp;
	struct net2280_dma_regs	__iomem *dma = ep->dma;

	/* FIXME can't use DMA for ZLPs */

	/* on this path we "know" there's no dma active (yet) */
	WARN_ON(readl(&dma->dmactl) & BIT(DMA_ENABLE));
	writel(0, &ep->dma->dmactl);

	/* previous OUT packet might have been short */
	if (!ep->is_in && (readl(&ep->regs->ep_stat) &
				BIT(NAK_OUT_PACKETS))) {
		writel(BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT),
			&ep->regs->ep_stat);

		tmp = readl(&ep->regs->ep_avail);
		if (tmp) {
			writel(readl(&dma->dmastat), &dma->dmastat);

			/* transfer all/some fifo data */
			writel(req->req.dma, &dma->dmaaddr);
			tmp = min(tmp, req->req.length);

			/* dma irq, faking scatterlist status */
			req->td->dmacount = cpu_to_le32(req->req.length - tmp);
			writel(BIT(DMA_DONE_INTERRUPT_ENABLE) | tmp,
					&dma->dmacount);
			req->td->dmadesc = 0;
			req->valid = 1;

			writel(BIT(DMA_ENABLE), &dma->dmactl);
			writel(BIT(DMA_START), &dma->dmastat);
			return;
		}
		stop_out_naking(ep);
	}

	tmp = dmactl_default;

	/* force packet boundaries between dma requests, but prevent the
	 * controller from automagically writing a last "short" packet
	 * (zero length) unless the driver explicitly said to do that.
	 */
	if (ep->is_in) {
		if (likely((req->req.length % ep->ep.maxpacket) ||
							req->req.zero)){
			tmp |= BIT(DMA_FIFO_VALIDATE);
			ep->in_fifo_validate = 1;
		} else
			ep->in_fifo_validate = 0;
	}

	/* init req->td, pointing to the current dummy */
	req->td->dmadesc = cpu_to_le32 (ep->td_dma);
	fill_dma_desc(ep, req, 1);

	req->td->dmacount |= cpu_to_le32(BIT(END_OF_CHAIN));

	start_queue(ep, tmp, req->td_dma);
}

static inline void
queue_dma(struct net2280_ep *ep, struct net2280_request *req, int valid)
{
	/* swap new dummy for old, link; fill and maybe activate */
	swap(ep->dummy, req->td);
	swap(ep->td_dma, req->td_dma);

	req->td->dmadesc = cpu_to_le32 (ep->td_dma);

	fill_dma_desc(ep, req, valid);
}

static void
done(struct net2280_ep *ep, struct net2280_request *req, int status)
{
	struct net2280		*dev;
	unsigned		stopped = ep->stopped;

	list_del_init(&req->queue);

	if (req->req.status == -EINPROGRESS)
		req->req.status = status;
	else
		status = req->req.status;

	dev = ep->dev;
	if (ep->dma)
		usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in);

	if (status && status != -ESHUTDOWN)
		ep_vdbg(dev, "complete %s req %p stat %d len %u/%u\n",
			ep->ep.name, &req->req, status,
			req->req.actual, req->req.length);

	/* don't modify queue heads during completion callback */
	ep->stopped = 1;
	spin_unlock(&dev->lock);
	usb_gadget_giveback_request(&ep->ep, &req->req);
	spin_lock(&dev->lock);
	ep->stopped = stopped;
}

/*-------------------------------------------------------------------------*/

static int
net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{
	struct net2280_request	*req;
	struct net2280_ep	*ep;
	struct net2280		*dev;
	unsigned long		flags;
	int ret = 0;

	/* we always require a cpu-view buffer, so that we can
	 * always use pio (as fallback or whatever).
	 */
	ep = container_of(_ep, struct net2280_ep, ep);
	if (!_ep || (!ep->desc && ep->num != 0)) {
		pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep);
		return -EINVAL;
	}
	req = container_of(_req, struct net2280_request, req);
	if (!_req || !_req->complete || !_req->buf ||
				!list_empty(&req->queue)) {
		ret = -EINVAL;
		goto print_err;
	}
	if (_req->length > (~0 & DMA_BYTE_COUNT_MASK)) {
		ret = -EDOM;
		goto print_err;
	}
	dev = ep->dev;
	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
		ret = -ESHUTDOWN;
		goto print_err;
	}

	/* FIXME implement PIO fallback for ZLPs with DMA */
	if (ep->dma && _req->length == 0) {
		ret = -EOPNOTSUPP;
		goto print_err;
	}

	/* set up dma mapping in case the caller didn't */
	if (ep->dma) {
		ret = usb_gadget_map_request(&dev->gadget, _req,
				ep->is_in);
		if (ret)
			goto print_err;
	}

	ep_vdbg(dev, "%s queue req %p, len %d buf %p\n",
			_ep->name, _req, _req->length, _req->buf);

	spin_lock_irqsave(&dev->lock, flags);

	_req->status = -EINPROGRESS;
	_req->actual = 0;

	/* kickstart this i/o queue? */
	if  (list_empty(&ep->queue) && !ep->stopped &&
		!((dev->quirks & PLX_PCIE) && ep->dma &&
		  (readl(&ep->regs->ep_rsp) & BIT(CLEAR_ENDPOINT_HALT)))) {

		/* use DMA if the endpoint supports it, else pio */
		if (ep->dma)
			start_dma(ep, req);
		else {
			/* maybe there's no control data, just status ack */
			if (ep->num == 0 && _req->length == 0) {
				allow_status(ep);
				done(ep, req, 0);
				ep_vdbg(dev, "%s status ack\n", ep->ep.name);
				goto done;
			}

			/* PIO ... stuff the fifo, or unblock it.  */
			if (ep->is_in)
				write_fifo(ep, _req);
			else {
				u32	s;

				/* OUT FIFO might have packet(s) buffered */
				s = readl(&ep->regs->ep_stat);
				if ((s & BIT(FIFO_EMPTY)) == 0) {
					/* note:  _req->short_not_ok is
					 * ignored here since PIO _always_
					 * stops queue advance here, and
					 * _req->status doesn't change for
					 * short reads (only _req->actual)
					 */
					if (read_fifo(ep, req) &&
							ep->num == 0) {
						done(ep, req, 0);
						allow_status(ep);
						/* don't queue it */
						req = NULL;
					} else if (read_fifo(ep, req) &&
							ep->num != 0) {
						done(ep, req, 0);
						req = NULL;
					} else
						s = readl(&ep->regs->ep_stat);
				}

				/* don't NAK, let the fifo fill */
				if (req && (s & BIT(NAK_OUT_PACKETS)))
					writel(BIT(CLEAR_NAK_OUT_PACKETS),
							&ep->regs->ep_rsp);
			}
		}

	} else if (ep->dma) {
		int	valid = 1;

		if (ep->is_in) {
			int	expect;

			/* preventing magic zlps is per-engine state, not
			 * per-transfer; irq logic must recover hiccups.
			 */
			expect = likely(req->req.zero ||
				(req->req.length % ep->ep.maxpacket));
			if (expect != ep->in_fifo_validate)
				valid = 0;
		}
		queue_dma(ep, req, valid);

	} /* else the irq handler advances the queue. */

	ep->responded = 1;
	if (req)
		list_add_tail(&req->queue, &ep->queue);
done:
	spin_unlock_irqrestore(&dev->lock, flags);

	/* pci writes may still be posted */
	return ret;

print_err:
	dev_err(&ep->dev->pdev->dev, "%s: error=%d\n", __func__, ret);
	return ret;
}

static inline void
dma_done(struct net2280_ep *ep,	struct net2280_request *req, u32 dmacount,
		int status)
{
	req->req.actual = req->req.length - (DMA_BYTE_COUNT_MASK & dmacount);
	done(ep, req, status);
}

static int scan_dma_completions(struct net2280_ep *ep)
{
	int num_completed = 0;

	/* only look at descriptors that were "naturally" retired,
	 * so fifo and list head state won't matter
	 */
	while (!list_empty(&ep->queue)) {
		struct net2280_request	*req;
		u32 req_dma_count;

		req = list_entry(ep->queue.next,
				struct net2280_request, queue);
		if (!req->valid)
			break;
		rmb();
		req_dma_count = le32_to_cpup(&req->td->dmacount);
		if ((req_dma_count & BIT(VALID_BIT)) != 0)
			break;

		/* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short"
		 * cases where DMA must be aborted; this code handles
		 * all non-abort DMA completions.
		 */
		if (unlikely(req->td->dmadesc == 0)) {
			/* paranoia */
			u32 const ep_dmacount = readl(&ep->dma->dmacount);

			if (ep_dmacount & DMA_BYTE_COUNT_MASK)
				break;
			/* single transfer mode */
			dma_done(ep, req, req_dma_count, 0);
			num_completed++;
			break;
		} else if (!ep->is_in &&
			   (req->req.length % ep->ep.maxpacket) &&
			   !(ep->dev->quirks & PLX_PCIE)) {

			u32 const ep_stat = readl(&ep->regs->ep_stat);
			/* AVOID TROUBLE HERE by not issuing short reads from
			 * your gadget driver.  That helps avoids errata 0121,
			 * 0122, and 0124; not all cases trigger the warning.
			 */
			if ((ep_stat & BIT(NAK_OUT_PACKETS)) == 0) {
				ep_warn(ep->dev, "%s lost packet sync!\n",
						ep->ep.name);
				req->req.status = -EOVERFLOW;
			} else {
				u32 const ep_avail = readl(&ep->regs->ep_avail);
				if (ep_avail) {
					/* fifo gets flushed later */
					ep->out_overflow = 1;
					ep_dbg(ep->dev,
						"%s dma, discard %d len %d\n",
						ep->ep.name, ep_avail,
						req->req.length);
					req->req.status = -EOVERFLOW;
				}
			}
		}
		dma_done(ep, req, req_dma_count, 0);
		num_completed++;
	}

	return num_completed;
}

static void restart_dma(struct net2280_ep *ep)
{
	struct net2280_request	*req;

	if (ep->stopped)
		return;
	req = list_entry(ep->queue.next, struct net2280_request, queue);

	start_dma(ep, req);
}

static void abort_dma(struct net2280_ep *ep)
{
	/* abort the current transfer */
	if (likely(!list_empty(&ep->queue))) {
		/* FIXME work around errata 0121, 0122, 0124 */
		writel(BIT(DMA_ABORT), &ep->dma->dmastat);
		spin_stop_dma(ep->dma);
	} else
		stop_dma(ep->dma);
	scan_dma_completions(ep);
}

/* dequeue ALL requests */
static void nuke(struct net2280_ep *ep)
{
	struct net2280_request	*req;

	/* called with spinlock held */
	ep->stopped = 1;
	if (ep->dma)
		abort_dma(ep);
	while (!list_empty(&ep->queue)) {
		req = list_entry(ep->queue.next,
				struct net2280_request,
				queue);
		done(ep, req, -ESHUTDOWN);
	}
}

/* dequeue JUST ONE request */
static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req)
{
	struct net2280_ep	*ep;
	struct net2280_request	*req = NULL;
	struct net2280_request	*iter;
	unsigned long		flags;
	u32			dmactl;
	int			stopped;

	ep = container_of(_ep, struct net2280_ep, ep);
	if (!_ep || (!ep->desc && ep->num != 0) || !_req) {
		pr_err("%s: Invalid ep=%p or ep->desc or req=%p\n",
						__func__, _ep, _req);
		return -EINVAL;
	}

	spin_lock_irqsave(&ep->dev->lock, flags);
	stopped = ep->stopped;

	/* quiesce dma while we patch the queue */
	dmactl = 0;
	ep->stopped = 1;
	if (ep->dma) {
		dmactl = readl(&ep->dma->dmactl);
		/* WARNING erratum 0127 may kick in ... */
		stop_dma(ep->dma);
		scan_dma_completions(ep);
	}

	/* make sure it's still queued on this endpoint */
	list_for_each_entry(iter, &ep->queue, queue) {
		if (&iter->req != _req)
			continue;
		req = iter;
		break;
	}
	if (!req) {
		ep->stopped = stopped;
		spin_unlock_irqrestore(&ep->dev->lock, flags);
		ep_dbg(ep->dev, "%s: Request mismatch\n", __func__);
		return -EINVAL;
	}

	/* queue head may be partially complete. */
	if (ep->queue.next == &req->queue) {
		if (ep->dma) {
			ep_dbg(ep->dev, "unlink (%s) dma\n", _ep->name);
			_req->status = -ECONNRESET;
			abort_dma(ep);
			if (likely(ep->queue.next == &req->queue)) {
				/* NOTE: misreports single-transfer mode*/
				req->td->dmacount = 0;	/* invalidate */
				dma_done(ep, req,
					readl(&ep->dma->dmacount),
					-ECONNRESET);
			}
		} else {
			ep_dbg(ep->dev, "unlink (%s) pio\n", _ep->name);
			done(ep, req, -ECONNRESET);
		}
		req = NULL;
	}

	if (req)
		done(ep, req, -ECONNRESET);
	ep->stopped = stopped;

	if (ep->dma) {
		/* turn off dma on inactive queues */
		if (list_empty(&ep->queue))
			stop_dma(ep->dma);
		else if (!ep->stopped) {
			/* resume current request, or start new one */
			if (req)
				writel(dmactl, &ep->dma->dmactl);
			else
				start_dma(ep, list_entry(ep->queue.next,
					struct net2280_request, queue));
		}
	}

	spin_unlock_irqrestore(&ep->dev->lock, flags);
	return 0;
}

/*-------------------------------------------------------------------------*/

static int net2280_fifo_status(struct usb_ep *_ep);

static int
net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
{
	struct net2280_ep	*ep;
	unsigned long		flags;
	int			retval = 0;

	ep = container_of(_ep, struct net2280_ep, ep);
	if (!_ep || (!ep->desc && ep->num != 0)) {
		pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep);
		return -EINVAL;
	}
	if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) {
		retval = -ESHUTDOWN;
		goto print_err;
	}
	if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03)
						== USB_ENDPOINT_XFER_ISOC) {
		retval = -EINVAL;
		goto print_err;
	}

	spin_lock_irqsave(&ep->dev->lock, flags);
	if (!list_empty(&ep->queue)) {
		retval = -EAGAIN;
		goto print_unlock;
	} else if (ep->is_in && value && net2280_fifo_status(_ep) != 0) {
		retval = -EAGAIN;
		goto print_unlock;
	} else {
		ep_vdbg(ep->dev, "%s %s %s\n", _ep->name,
				value ? "set" : "clear",
				wedged ? "wedge" : "halt");
		/* set/clear, then synch memory views with the device */
		if (value) {
			if (ep->num == 0)
				ep->dev->protocol_stall = 1;
			else
				set_halt(ep);
			if (wedged)
				ep->wedged = 1;
		} else {
			clear_halt(ep);
			if (ep->dev->quirks & PLX_PCIE &&
				!list_empty(&ep->queue) && ep->td_dma)
					restart_dma(ep);
			ep->wedged = 0;
		}
		(void) readl(&ep->regs->ep_rsp);
	}
	spin_unlock_irqrestore(&ep->dev->lock, flags);

	return retval;

print_unlock:
	spin_unlock_irqrestore(&ep->dev->lock, flags);
print_err:
	dev_err(&ep->dev->pdev->dev, "%s: error=%d\n", __func__, retval);
	return retval;
}

static int net2280_set_halt(struct usb_ep *_ep, int value)
{
	return net2280_set_halt_and_wedge(_ep, value, 0);
}

static int net2280_set_wedge(struct usb_ep *_ep)
{
	if (!_ep || _ep->name == ep0name) {
		pr_err("%s: Invalid ep=%p or ep0\n", __func__, _ep);
		return -EINVAL;
	}
	return net2280_set_halt_and_wedge(_ep, 1, 1);
}

static int net2280_fifo_status(struct usb_ep *_ep)
{
	struct net2280_ep	*ep;
	u32			avail;

	ep = container_of(_ep, struct net2280_ep, ep);
	if (!_ep || (!ep->desc && ep->num != 0)) {
		pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep);
		return -ENODEV;
	}
	if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) {
		dev_err(&ep->dev->pdev->dev,
			"%s: Invalid driver=%p or speed=%d\n",
			__func__, ep->dev->driver, ep->dev->gadget.speed);
		return -ESHUTDOWN;
	}

	avail = readl(&ep->regs->ep_avail) & (BIT(12) - 1);
	if (avail > ep->fifo_size) {
		dev_err(&ep->dev->pdev->dev, "%s: Fifo overflow\n", __func__);
		return -EOVERFLOW;
	}
	if (ep->is_in)
		avail = ep->fifo_size - avail;
	return avail;
}

static void net2280_fifo_flush(struct usb_ep *_ep)
{
	struct net2280_ep	*ep;

	ep = container_of(_ep, struct net2280_ep, ep);
	if (!_ep || (!ep->desc && ep->num != 0)) {
		pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep);
		return;
	}
	if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) {
		dev_err(&ep->dev->pdev->dev,
			"%s: Invalid driver=%p or speed=%d\n",
			__func__, ep->dev->driver, ep->dev->gadget.speed);
		return;
	}

	writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat);
	(void) readl(&ep->regs->ep_rsp);
}

static const struct usb_ep_ops net2280_ep_ops = {
	.enable		= net2280_enable,
	.disable	= net2280_disable,

	.alloc_request	= net2280_alloc_request,
	.free_request	= net2280_free_request,

	.queue		= net2280_queue,
	.dequeue	= net2280_dequeue,

	.set_halt	= net2280_set_halt,
	.set_wedge	= net2280_set_wedge,
	.fifo_status	= net2280_fifo_status,
	.fifo_flush	= net2280_fifo_flush,
};

/*-------------------------------------------------------------------------*/

static int net2280_get_frame(struct usb_gadget *_gadget)
{
	struct net2280		*dev;
	unsigned long		flags;
	u16			retval;

	if (!_gadget)
		return -ENODEV;
	dev = container_of(_gadget, struct net2280, gadget);
	spin_lock_irqsave(&dev->lock, flags);
	retval = get_idx_reg(dev->regs, REG_FRAME) & 0x03ff;
	spin_unlock_irqrestore(&dev->lock, flags);
	return retval;
}

static int net2280_wakeup(struct usb_gadget *_gadget)
{
	struct net2280		*dev;
	u32			tmp;
	unsigned long		flags;

	if (!_gadget)
		return 0;
	dev = container_of(_gadget, struct net2280, gadget);

	spin_lock_irqsave(&dev->lock, flags);
	tmp = readl(&dev->usb->usbctl);
	if (tmp & BIT(DEVICE_REMOTE_WAKEUP_ENABLE))
		writel(BIT(GENERATE_RESUME), &dev->usb->usbstat);
	spin_unlock_irqrestore(&dev->lock, flags);

	/* pci writes may still be posted */
	return 0;
}

static int net2280_set_selfpowered(struct usb_gadget *_gadget, int value)
{
	struct net2280		*dev;
	u32			tmp;
	unsigned long		flags;

	if (!_gadget)
		return 0;
	dev = container_of(_gadget, struct net2280, gadget);

	spin_lock_irqsave(&dev->lock, flags);
	tmp = readl(&dev->usb->usbctl);
	if (value) {
		tmp |= BIT(SELF_POWERED_STATUS);
		_gadget->is_selfpowered = 1;
	} else {
		tmp &= ~BIT(SELF_POWERED_STATUS);
		_gadget->is_selfpowered = 0;
	}
	writel(tmp, &dev->usb->usbctl);
	spin_unlock_irqrestore(&dev->lock, flags);

	return 0;
}

static int net2280_pullup(struct usb_gadget *_gadget, int is_on)
{
	struct net2280  *dev;
	u32             tmp;
	unsigned long   flags;

	if (!_gadget)
		return -ENODEV;
	dev = container_of(_gadget, struct net2280, gadget);

	spin_lock_irqsave(&dev->lock, flags);
	tmp = readl(&dev->usb->usbctl);
	dev->softconnect = (is_on != 0);
	if (is_on) {
		ep0_start(dev);
		writel(tmp | BIT(USB_DETECT_ENABLE), &dev->usb->usbctl);
	} else {
		writel(tmp & ~BIT(USB_DETECT_ENABLE), &dev->usb->usbctl);
		stop_activity(dev, NULL);
	}

	spin_unlock_irqrestore(&dev->lock, flags);

	return 0;
}

static struct usb_ep *net2280_match_ep(struct usb_gadget *_gadget,
		struct usb_endpoint_descriptor *desc,
		struct usb_ss_ep_comp_descriptor *ep_comp)
{
	char name[8];
	struct usb_ep *ep;

	if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT) {
		/* ep-e, ep-f are PIO with only 64 byte fifos */
		ep = gadget_find_ep_by_name(_gadget, "ep-e");
		if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
			return ep;
		ep = gadget_find_ep_by_name(_gadget, "ep-f");
		if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
			return ep;
	}

	/* USB3380: Only first four endpoints have DMA channels. Allocate
	 * slower interrupt endpoints from PIO hw endpoints, to allow bulk/isoc
	 * endpoints use DMA hw endpoints.
	 */
	if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT &&
	    usb_endpoint_dir_in(desc)) {
		ep = gadget_find_ep_by_name(_gadget, "ep2in");
		if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
			return ep;
		ep = gadget_find_ep_by_name(_gadget, "ep4in");
		if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
			return ep;
	} else if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT &&
		   !usb_endpoint_dir_in(desc)) {
		ep = gadget_find_ep_by_name(_gadget, "ep1out");
		if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
			return ep;
		ep = gadget_find_ep_by_name(_gadget, "ep3out");
		if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
			return ep;
	} else if (usb_endpoint_type(desc) != USB_ENDPOINT_XFER_BULK &&
		   usb_endpoint_dir_in(desc)) {
		ep = gadget_find_ep_by_name(_gadget, "ep1in");
		if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
			return ep;
		ep = gadget_find_ep_by_name(_gadget, "ep3in");
		if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
			return ep;
	} else if (usb_endpoint_type(desc) != USB_ENDPOINT_XFER_BULK &&
		   !usb_endpoint_dir_in(desc)) {
		ep = gadget_find_ep_by_name(_gadget, "ep2out");
		if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
			return ep;
		ep = gadget_find_ep_by_name(_gadget, "ep4out");
		if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
			return ep;
	}

	/* USB3380: use same address for usb and hardware endpoints */
	snprintf(name, sizeof(name), "ep%d%s", usb_endpoint_num(desc),
			usb_endpoint_dir_in(desc) ? "in" : "out");
	ep = gadget_find_ep_by_name(_gadget, name);
	if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
		return ep;

	return NULL;
}

static int net2280_start(struct usb_gadget *_gadget,
		struct usb_gadget_driver *driver);
static int net2280_stop(struct usb_gadget *_gadget);
static void net2280_async_callbacks(struct usb_gadget *_gadget, bool enable);

static const struct usb_gadget_ops net2280_ops = {
	.get_frame	= net2280_get_frame,
	.wakeup		= net2280_wakeup,
	.set_selfpowered = net2280_set_selfpowered,
	.pullup		= net2280_pullup,
	.udc_start	= net2280_start,
	.udc_stop	= net2280_stop,
	.udc_async_callbacks = net2280_async_callbacks,
	.match_ep	= net2280_match_ep,
};

/*-------------------------------------------------------------------------*/

#ifdef	CONFIG_USB_GADGET_DEBUG_FILES

/* FIXME move these into procfs, and use seq_file.
 * Sysfs _still_ doesn't behave for arbitrarily sized files,
 * and also doesn't help products using this with 2.4 kernels.
 */

/* "function" sysfs attribute */
static ssize_t function_show(struct device *_dev, struct device_attribute *attr,
			     char *buf)
{
	struct net2280	*dev = dev_get_drvdata(_dev);

	if (!dev->driver || !dev->driver->function ||
			strlen(dev->driver->function) > PAGE_SIZE)
		return 0;
	return scnprintf(buf, PAGE_SIZE, "%s\n", dev->driver->function);
}
static DEVICE_ATTR_RO(function);

static ssize_t registers_show(struct device *_dev,
			      struct device_attribute *attr, char *buf)
{
	struct net2280		*dev;
	char			*next;
	unsigned		size, t;
	unsigned long		flags;
	int			i;
	u32			t1, t2;
	const char		*s;

	dev = dev_get_drvdata(_dev);
	next = buf;
	size = PAGE_SIZE;
	spin_lock_irqsave(&dev->lock, flags);

	if (dev->driver)
		s = dev->driver->driver.name;
	else
		s = "(none)";

	/* Main Control Registers */
	t = scnprintf(next, size, "%s version " DRIVER_VERSION
			", chiprev %04x\n\n"
			"devinit %03x fifoctl %08x gadget '%s'\n"
			"pci irqenb0 %02x irqenb1 %08x "
			"irqstat0 %04x irqstat1 %08x\n",
			driver_name, dev->chiprev,
			readl(&dev->regs->devinit),
			readl(&dev->regs->fifoctl),
			s,
			readl(&dev->regs->pciirqenb0),
			readl(&dev->regs->pciirqenb1),
			readl(&dev->regs->irqstat0),
			readl(&dev->regs->irqstat1));
	size -= t;
	next += t;

	/* USB Control Registers */
	t1 = readl(&dev->usb->usbctl);
	t2 = readl(&dev->usb->usbstat);
	if (t1 & BIT(VBUS_PIN)) {
		if (t2 & BIT(HIGH_SPEED))
			s = "high speed";
		else if (dev->gadget.speed == USB_SPEED_UNKNOWN)
			s = "powered";
		else
			s = "full speed";
		/* full speed bit (6) not working?? */
	} else
			s = "not attached";
	t = scnprintf(next, size,
			"stdrsp %08x usbctl %08x usbstat %08x "
				"addr 0x%02x (%s)\n",
			readl(&dev->usb->stdrsp), t1, t2,
			readl(&dev->usb->ouraddr), s);
	size -= t;
	next += t;

	/* PCI Master Control Registers */

	/* DMA Control Registers */

	/* Configurable EP Control Registers */
	for (i = 0; i < dev->n_ep; i++) {
		struct net2280_ep	*ep;

		ep = &dev->ep[i];
		if (i && !ep->desc)
			continue;

		t1 = readl(&ep->cfg->ep_cfg);
		t2 = readl(&ep->regs->ep_rsp) & 0xff;
		t = scnprintf(next, size,
				"\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s"
					"irqenb %02x\n",
				ep->ep.name, t1, t2,
				(t2 & BIT(CLEAR_NAK_OUT_PACKETS))
					? "NAK " : "",
				(t2 & BIT(CLEAR_EP_HIDE_STATUS_PHASE))
					? "hide " : "",
				(t2 & BIT(CLEAR_EP_FORCE_CRC_ERROR))
					? "CRC " : "",
				(t2 & BIT(CLEAR_INTERRUPT_MODE))
					? "interrupt " : "",
				(t2 & BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE))
					? "status " : "",
				(t2 & BIT(CLEAR_NAK_OUT_PACKETS_MODE))
					? "NAKmode " : "",
				(t2 & BIT(CLEAR_ENDPOINT_TOGGLE))
					? "DATA1 " : "DATA0 ",
				(t2 & BIT(CLEAR_ENDPOINT_HALT))
					? "HALT " : "",
				readl(&ep->regs->ep_irqenb));
		size -= t;
		next += t;

		t = scnprintf(next, size,
				"\tstat %08x avail %04x "
				"(ep%d%s-%s)%s\n",
				readl(&ep->regs->ep_stat),
				readl(&ep->regs->ep_avail),
				t1 & 0x0f, DIR_STRING(t1),
				type_string(t1 >> 8),
				ep->stopped ? "*" : "");
		size -= t;
		next += t;

		if (!ep->dma)
			continue;

		t = scnprintf(next, size,
				"  dma\tctl %08x stat %08x count %08x\n"
				"\taddr %08x desc %08x\n",
				readl(&ep->dma->dmactl),
				readl(&ep->dma->dmastat),
				readl(&ep->dma->dmacount),
				readl(&ep->dma->dmaaddr),
				readl(&ep->dma->dmadesc));
		size -= t;
		next += t;

	}

	/* Indexed Registers (none yet) */

	/* Statistics */
	t = scnprintf(next, size, "\nirqs:  ");
	size -= t;
	next += t;
	for (i = 0; i < dev->n_ep; i++) {
		struct net2280_ep	*ep;

		ep = &dev->ep[i];
		if (i && !ep->irqs)
			continue;
		t = scnprintf(next, size, " %s/%lu", ep->ep.name, ep->irqs);
		size -= t;
		next += t;

	}
	t = scnprintf(next, size, "\n");
	size -= t;
	next += t;

	spin_unlock_irqrestore(&dev->lock, flags);

	return PAGE_SIZE - size;
}
static DEVICE_ATTR_RO(registers);

static ssize_t queues_show(struct device *_dev, struct device_attribute *attr,
			   char *buf)
{
	struct net2280		*dev;
	char			*next;
	unsigned		size;
	unsigned long		flags;
	int			i;

	dev = dev_get_drvdata(_dev);
	next = buf;
	size = PAGE_SIZE;
	spin_lock_irqsave(&dev->lock, flags);

	for (i = 0; i < dev->n_ep; i++) {
		struct net2280_ep		*ep = &dev->ep[i];
		struct net2280_request		*req;
		int				t;

		if (i != 0) {
			const struct usb_endpoint_descriptor	*d;

			d = ep->desc;
			if (!d)
				continue;
			t = d->bEndpointAddress;
			t = scnprintf(next, size,
				"\n%s (ep%d%s-%s) max %04x %s fifo %d\n",
				ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK,
				(t & USB_DIR_IN) ? "in" : "out",
				type_string(d->bmAttributes),
				usb_endpoint_maxp(d),
				ep->dma ? "dma" : "pio", ep->fifo_size
				);
		} else /* ep0 should only have one transfer queued */
			t = scnprintf(next, size, "ep0 max 64 pio %s\n",
					ep->is_in ? "in" : "out");
		if (t <= 0 || t > size)
			goto done;
		size -= t;
		next += t;

		if (list_empty(&ep->queue)) {
			t = scnprintf(next, size, "\t(nothing queued)\n");
			if (t <= 0 || t > size)
				goto done;
			size -= t;
			next += t;
			continue;
		}
		list_for_each_entry(req, &ep->queue, queue) {
			if (ep->dma && req->td_dma == readl(&ep->dma->dmadesc))
				t = scnprintf(next, size,
					"\treq %p len %d/%d "
					"buf %p (dmacount %08x)\n",
					&req->req, req->req.actual,
					req->req.length, req->req.buf,
					readl(&ep->dma->dmacount));
			else
				t = scnprintf(next, size,
					"\treq %p len %d/%d buf %p\n",
					&req->req, req->req.actual,
					req->req.length, req->req.buf);
			if (t <= 0 || t > size)
				goto done;
			size -= t;
			next += t;

			if (ep->dma) {
				struct net2280_dma	*td;

				td = req->td;
				t = scnprintf(next, size, "\t    td %08x "
					" count %08x buf %08x desc %08x\n",
					(u32) req->td_dma,
					le32_to_cpu(td->dmacount),
					le32_to_cpu(td->dmaaddr),
					le32_to_cpu(td->dmadesc));
				if (t <= 0 || t > size)
					goto done;
				size -= t;
				next += t;
			}
		}
	}

done:
	spin_unlock_irqrestore(&dev->lock, flags);
	return PAGE_SIZE - size;
}
static DEVICE_ATTR_RO(queues);


#else

#define device_create_file(a, b)	(0)
#define device_remove_file(a, b)	do { } while (0)

#endif

/*-------------------------------------------------------------------------*/

/* another driver-specific mode might be a request type doing dma
 * to/from another device fifo instead of to/from memory.
 */

static void set_fifo_mode(struct net2280 *dev, int mode)
{
	/* keeping high bits preserves BAR2 */
	writel((0xffff << PCI_BASE2_RANGE) | mode, &dev->regs->fifoctl);

	/* always ep-{a,b,e,f} ... maybe not ep-c or ep-d */
	INIT_LIST_HEAD(&dev->gadget.ep_list);
	list_add_tail(&dev->ep[1].ep.ep_list, &dev->gadget.ep_list);
	list_add_tail(&dev->ep[2].ep.ep_list, &dev->gadget.ep_list);
	switch (mode) {
	case 0:
		list_add_tail(&dev->ep[3].ep.ep_list, &dev->gadget.ep_list);
		list_add_tail(&dev->ep[4].ep.ep_list, &dev->gadget.ep_list);
		dev->ep[1].fifo_size = dev->ep[2].fifo_size = 1024;
		break;
	case 1:
		dev->ep[1].fifo_size = dev->ep[2].fifo_size = 2048;
		break;
	case 2:
		list_add_tail(&dev->ep[3].ep.ep_list, &dev->gadget.ep_list);
		dev->ep[1].fifo_size = 2048;
		dev->ep[2].fifo_size = 1024;
		break;
	}
	/* fifo sizes for ep0, ep-c, ep-d, ep-e, and ep-f never change */
	list_add_tail(&dev->ep[5].ep.ep_list, &dev->gadget.ep_list);
	list_add_tail(&dev->ep[6].ep.ep_list, &dev->gadget.ep_list);
}

static void defect7374_disable_data_eps(struct net2280 *dev)
{
	/*
	 * For Defect 7374, disable data EPs (and more):
	 *  - This phase undoes the earlier phase of the Defect 7374 workaround,
	 *    returing ep regs back to normal.
	 */
	struct net2280_ep *ep;
	int i;
	unsigned char ep_sel;
	u32 tmp_reg;

	for (i = 1; i < 5; i++) {
		ep = &dev->ep[i];
		writel(i, &ep->cfg->ep_cfg);
	}

	/* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */
	for (i = 0; i < 6; i++)
		writel(0, &dev->dep[i].dep_cfg);

	for (ep_sel = 0; ep_sel <= 21; ep_sel++) {
		/* Select an endpoint for subsequent operations: */
		tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
		writel(((tmp_reg & ~0x1f) | ep_sel), &dev->plregs->pl_ep_ctrl);

		if (ep_sel < 2 || (ep_sel > 9 && ep_sel < 14) ||
					ep_sel == 18 || ep_sel == 20)
			continue;

		/* Change settings on some selected endpoints */
		tmp_reg = readl(&dev->plregs->pl_ep_cfg_4);
		tmp_reg &= ~BIT(NON_CTRL_IN_TOLERATE_BAD_DIR);
		writel(tmp_reg, &dev->plregs->pl_ep_cfg_4);
		tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
		tmp_reg |= BIT(EP_INITIALIZED);
		writel(tmp_reg, &dev->plregs->pl_ep_ctrl);
	}
}

static void defect7374_enable_data_eps_zero(struct net2280 *dev)
{
	u32 tmp = 0, tmp_reg;
	u32 scratch;
	int i;
	unsigned char ep_sel;

	scratch = get_idx_reg(dev->regs, SCRATCH);

	WARN_ON((scratch & (0xf << DEFECT7374_FSM_FIELD))
		== DEFECT7374_FSM_SS_CONTROL_READ);

	scratch &= ~(0xf << DEFECT7374_FSM_FIELD);

	ep_warn(dev, "Operate Defect 7374 workaround soft this time");
	ep_warn(dev, "It will operate on cold-reboot and SS connect");

	/*GPEPs:*/
	tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) |
			(2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) |
			((dev->enhanced_mode) ?
			 BIT(OUT_ENDPOINT_ENABLE) | BIT(IN_ENDPOINT_ENABLE) :
			 BIT(ENDPOINT_ENABLE)));

	for (i = 1; i < 5; i++)
		writel(tmp, &dev->ep[i].cfg->ep_cfg);

	/* CSRIN, PCIIN, STATIN, RCIN*/
	tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE));
	writel(tmp, &dev->dep[1].dep_cfg);
	writel(tmp, &dev->dep[3].dep_cfg);
	writel(tmp, &dev->dep[4].dep_cfg);
	writel(tmp, &dev->dep[5].dep_cfg);

	/*Implemented for development and debug.
	 * Can be refined/tuned later.*/
	for (ep_sel = 0; ep_sel <= 21; ep_sel++) {
		/* Select an endpoint for subsequent operations: */
		tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
		writel(((tmp_reg & ~0x1f) | ep_sel),
				&dev->plregs->pl_ep_ctrl);

		if (ep_sel == 1) {
			tmp =
				(readl(&dev->plregs->pl_ep_ctrl) |
				 BIT(CLEAR_ACK_ERROR_CODE) | 0);
			writel(tmp, &dev->plregs->pl_ep_ctrl);
			continue;
		}

		if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) ||
				ep_sel == 18  || ep_sel == 20)
			continue;

		tmp = (readl(&dev->plregs->pl_ep_cfg_4) |
				BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0);
		writel(tmp, &dev->plregs->pl_ep_cfg_4);

		tmp = readl(&dev->plregs->pl_ep_ctrl) &
			~BIT(EP_INITIALIZED);
		writel(tmp, &dev->plregs->pl_ep_ctrl);

	}

	/* Set FSM to focus on the first Control Read:
	 * - Tip: Connection speed is known upon the first
	 * setup request.*/
	scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ;
	set_idx_reg(dev->regs, SCRATCH, scratch);

}

/* keeping it simple:
 * - one bus driver, initted first;
 * - one function driver, initted second
 *
 * most of the work to support multiple net2280 controllers would
 * be to associate this gadget driver (yes?) with all of them, or
 * perhaps to bind specific drivers to specific devices.
 */

static void usb_reset_228x(struct net2280 *dev)
{
	u32	tmp;

	dev->gadget.speed = USB_SPEED_UNKNOWN;
	(void) readl(&dev->usb->usbctl);

	net2280_led_init(dev);

	/* disable automatic responses, and irqs */
	writel(0, &dev->usb->stdrsp);
	writel(0, &dev->regs->pciirqenb0);
	writel(0, &dev->regs->pciirqenb1);

	/* clear old dma and irq state */
	for (tmp = 0; tmp < 4; tmp++) {
		struct net2280_ep       *ep = &dev->ep[tmp + 1];
		if (ep->dma)
			abort_dma(ep);
	}

	writel(~0, &dev->regs->irqstat0),
	writel(~(u32)BIT(SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1),

	/* reset, and enable pci */
	tmp = readl(&dev->regs->devinit) |
		BIT(PCI_ENABLE) |
		BIT(FIFO_SOFT_RESET) |
		BIT(USB_SOFT_RESET) |
		BIT(M8051_RESET);
	writel(tmp, &dev->regs->devinit);

	/* standard fifo and endpoint allocations */
	set_fifo_mode(dev, (fifo_mode <= 2) ? fifo_mode : 0);
}

static void usb_reset_338x(struct net2280 *dev)
{
	u32 tmp;

	dev->gadget.speed = USB_SPEED_UNKNOWN;
	(void)readl(&dev->usb->usbctl);

	net2280_led_init(dev);

	if (dev->bug7734_patched) {
		/* disable automatic responses, and irqs */
		writel(0, &dev->usb->stdrsp);
		writel(0, &dev->regs->pciirqenb0);
		writel(0, &dev->regs->pciirqenb1);
	}

	/* clear old dma and irq state */
	for (tmp = 0; tmp < 4; tmp++) {
		struct net2280_ep *ep = &dev->ep[tmp + 1];
		struct net2280_dma_regs __iomem *dma;

		if (ep->dma) {
			abort_dma(ep);
		} else {
			dma = &dev->dma[tmp];
			writel(BIT(DMA_ABORT), &dma->dmastat);
			writel(0, &dma->dmactl);
		}
	}

	writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1);

	if (dev->bug7734_patched) {
		/* reset, and enable pci */
		tmp = readl(&dev->regs->devinit) |
		    BIT(PCI_ENABLE) |
		    BIT(FIFO_SOFT_RESET) |
		    BIT(USB_SOFT_RESET) |
		    BIT(M8051_RESET);

		writel(tmp, &dev->regs->devinit);
	}

	/* always ep-{1,2,3,4} ... maybe not ep-3 or ep-4 */
	INIT_LIST_HEAD(&dev->gadget.ep_list);

	for (tmp = 1; tmp < dev->n_ep; tmp++)
		list_add_tail(&dev->ep[tmp].ep.ep_list, &dev->gadget.ep_list);

}

static void usb_reset(struct net2280 *dev)
{
	if (dev->quirks & PLX_LEGACY)
		return usb_reset_228x(dev);
	return usb_reset_338x(dev);
}

static void usb_reinit_228x(struct net2280 *dev)
{
	u32	tmp;

	/* basic endpoint init */
	for (tmp = 0; tmp < 7; tmp++) {
		struct net2280_ep	*ep = &dev->ep[tmp];

		ep->ep.name = ep_info_dft[tmp].name;
		ep->ep.caps = ep_info_dft[tmp].caps;
		ep->dev = dev;
		ep->num = tmp;

		if (tmp > 0 && tmp <= 4) {
			ep->fifo_size = 1024;
			ep->dma = &dev->dma[tmp - 1];
		} else
			ep->fifo_size = 64;
		ep->regs = &dev->epregs[tmp];
		ep->cfg = &dev->epregs[tmp];
		ep_reset_228x(dev->regs, ep);
	}
	usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 64);
	usb_ep_set_maxpacket_limit(&dev->ep[5].ep, 64);
	usb_ep_set_maxpacket_limit(&dev->ep[6].ep, 64);

	dev->gadget.ep0 = &dev->ep[0].ep;
	dev->ep[0].stopped = 0;
	INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);

	/* we want to prevent lowlevel/insecure access from the USB host,
	 * but erratum 0119 means this enable bit is ignored
	 */
	for (tmp = 0; tmp < 5; tmp++)
		writel(EP_DONTUSE, &dev->dep[tmp].dep_cfg);
}

static void usb_reinit_338x(struct net2280 *dev)
{
	int i;
	u32 tmp, val;
	static const u32 ne[9] = { 0, 1, 2, 3, 4, 1, 2, 3, 4 };
	static const u32 ep_reg_addr[9] = { 0x00, 0xC0, 0x00, 0xC0, 0x00,
						0x00, 0xC0, 0x00, 0xC0 };

	/* basic endpoint init */
	for (i = 0; i < dev->n_ep; i++) {
		struct net2280_ep *ep = &dev->ep[i];

		ep->ep.name = dev->enhanced_mode ? ep_info_adv[i].name :
						   ep_info_dft[i].name;
		ep->ep.caps = dev->enhanced_mode ? ep_info_adv[i].caps :
						   ep_info_dft[i].caps;
		ep->dev = dev;
		ep->num = i;

		if (i > 0 && i <= 4)
			ep->dma = &dev->dma[i - 1];

		if (dev->enhanced_mode) {
			ep->cfg = &dev->epregs[ne[i]];
			/*
			 * Set USB endpoint number, hardware allows same number
			 * in both directions.
			 */
			 if (i > 0 && i < 5)
				writel(ne[i], &ep->cfg->ep_cfg);
			ep->regs = (struct net2280_ep_regs __iomem *)
				(((void __iomem *)&dev->epregs[ne[i]]) +
				ep_reg_addr[i]);
		} else {
			ep->cfg = &dev->epregs[i];
			ep->regs = &dev->epregs[i];
		}

		ep->fifo_size = (i != 0) ? 2048 : 512;

		ep_reset_338x(dev->regs, ep);
	}
	usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 512);

	dev->gadget.ep0 = &dev->ep[0].ep;
	dev->ep[0].stopped = 0;

	/* Link layer set up */
	if (dev->bug7734_patched) {
		tmp = readl(&dev->usb_ext->usbctl2) &
		    ~(BIT(U1_ENABLE) | BIT(U2_ENABLE) | BIT(LTM_ENABLE));
		writel(tmp, &dev->usb_ext->usbctl2);
	}

	/* Hardware Defect and Workaround */
	val = readl(&dev->llregs->ll_lfps_5);
	val &= ~(0xf << TIMER_LFPS_6US);
	val |= 0x5 << TIMER_LFPS_6US;
	writel(val, &dev->llregs->ll_lfps_5);

	val = readl(&dev->llregs->ll_lfps_6);
	val &= ~(0xffff << TIMER_LFPS_80US);
	val |= 0x0100 << TIMER_LFPS_80US;
	writel(val, &dev->llregs->ll_lfps_6);

	/*
	 * AA_AB Errata. Issue 4. Workaround for SuperSpeed USB
	 * Hot Reset Exit Handshake may Fail in Specific Case using
	 * Default Register Settings. Workaround for Enumeration test.
	 */
	val = readl(&dev->llregs->ll_tsn_counters_2);
	val &= ~(0x1f << HOT_TX_NORESET_TS2);
	val |= 0x10 << HOT_TX_NORESET_TS2;
	writel(val, &dev->llregs->ll_tsn_counters_2);

	val = readl(&dev->llregs->ll_tsn_counters_3);
	val &= ~(0x1f << HOT_RX_RESET_TS2);
	val |= 0x3 << HOT_RX_RESET_TS2;
	writel(val, &dev->llregs->ll_tsn_counters_3);

	/*
	 * AB errata. Errata 11. Workaround for Default Duration of LFPS
	 * Handshake Signaling for Device-Initiated U1 Exit is too short.
	 * Without this, various enumeration failures observed with
	 * modern superspeed hosts.
	 */
	val = readl(&dev->llregs->ll_lfps_timers_2);
	writel((val & 0xffff0000) | LFPS_TIMERS_2_WORKAROUND_VALUE,
	       &dev->llregs->ll_lfps_timers_2);

	/*
	 * Set Recovery Idle to Recover bit:
	 * - On SS connections, setting Recovery Idle to Recover Fmw improves
	 *   link robustness with various hosts and hubs.
	 * - It is safe to set for all connection speeds; all chip revisions.
	 * - R-M-W to leave other bits undisturbed.
	 * - Reference PLX TT-7372
	*/
	val = readl(&dev->llregs->ll_tsn_chicken_bit);
	val |= BIT(RECOVERY_IDLE_TO_RECOVER_FMW);
	writel(val, &dev->llregs->ll_tsn_chicken_bit);

	INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);

	/* disable dedicated endpoints */
	writel(0x0D, &dev->dep[0].dep_cfg);
	writel(0x0D, &dev->dep[1].dep_cfg);
	writel(0x0E, &dev->dep[2].dep_cfg);
	writel(0x0E, &dev->dep[3].dep_cfg);
	writel(0x0F, &dev->dep[4].dep_cfg);
	writel(0x0C, &dev->dep[5].dep_cfg);
}

static void usb_reinit(struct net2280 *dev)
{
	if (dev->quirks & PLX_LEGACY)
		return usb_reinit_228x(dev);
	return usb_reinit_338x(dev);
}

static void ep0_start_228x(struct net2280 *dev)
{
	writel(BIT(CLEAR_EP_HIDE_STATUS_PHASE) |
		BIT(CLEAR_NAK_OUT_PACKETS) |
		BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE),
		&dev->epregs[0].ep_rsp);

	/*
	 * hardware optionally handles a bunch of standard requests
	 * that the API hides from drivers anyway.  have it do so.
	 * endpoint status/features are handled in software, to
	 * help pass tests for some dubious behavior.
	 */
	writel(BIT(SET_TEST_MODE) |
		BIT(SET_ADDRESS) |
		BIT(DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP) |
		BIT(GET_DEVICE_STATUS) |
		BIT(GET_INTERFACE_STATUS),
		&dev->usb->stdrsp);
	writel(BIT(USB_ROOT_PORT_WAKEUP_ENABLE) |
		BIT(SELF_POWERED_USB_DEVICE) |
		BIT(REMOTE_WAKEUP_SUPPORT) |
		(dev->softconnect << USB_DETECT_ENABLE) |
		BIT(SELF_POWERED_STATUS),
		&dev->usb->usbctl);

	/* enable irqs so we can see ep0 and general operation  */
	writel(BIT(SETUP_PACKET_INTERRUPT_ENABLE) |
		BIT(ENDPOINT_0_INTERRUPT_ENABLE),
		&dev->regs->pciirqenb0);
	writel(BIT(PCI_INTERRUPT_ENABLE) |
		BIT(PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE) |
		BIT(PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE) |
		BIT(PCI_RETRY_ABORT_INTERRUPT_ENABLE) |
		BIT(VBUS_INTERRUPT_ENABLE) |
		BIT(ROOT_PORT_RESET_INTERRUPT_ENABLE) |
		BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE),
		&dev->regs->pciirqenb1);

	/* don't leave any writes posted */
	(void) readl(&dev->usb->usbctl);
}

static void ep0_start_338x(struct net2280 *dev)
{

	if (dev->bug7734_patched)
		writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE) |
		       BIT(SET_EP_HIDE_STATUS_PHASE),
		       &dev->epregs[0].ep_rsp);

	/*
	 * hardware optionally handles a bunch of standard requests
	 * that the API hides from drivers anyway.  have it do so.
	 * endpoint status/features are handled in software, to
	 * help pass tests for some dubious behavior.
	 */
	writel(BIT(SET_ISOCHRONOUS_DELAY) |
	       BIT(SET_SEL) |
	       BIT(SET_TEST_MODE) |
	       BIT(SET_ADDRESS) |
	       BIT(GET_INTERFACE_STATUS) |
	       BIT(GET_DEVICE_STATUS),
		&dev->usb->stdrsp);
	dev->wakeup_enable = 1;
	writel(BIT(USB_ROOT_PORT_WAKEUP_ENABLE) |
	       (dev->softconnect << USB_DETECT_ENABLE) |
	       BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
	       &dev->usb->usbctl);

	/* enable irqs so we can see ep0 and general operation  */
	writel(BIT(SETUP_PACKET_INTERRUPT_ENABLE) |
	       BIT(ENDPOINT_0_INTERRUPT_ENABLE),
	       &dev->regs->pciirqenb0);
	writel(BIT(PCI_INTERRUPT_ENABLE) |
	       BIT(ROOT_PORT_RESET_INTERRUPT_ENABLE) |
	       BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE) |
	       BIT(VBUS_INTERRUPT_ENABLE),
	       &dev->regs->pciirqenb1);

	/* don't leave any writes posted */
	(void)readl(&dev->usb->usbctl);
}

static void ep0_start(struct net2280 *dev)
{
	if (dev->quirks & PLX_LEGACY)
		return ep0_start_228x(dev);
	return ep0_start_338x(dev);
}

/* when a driver is successfully registered, it will receive
 * control requests including set_configuration(), which enables
 * non-control requests.  then usb traffic follows until a
 * disconnect is reported.  then a host may connect again, or
 * the driver might get unbound.
 */
static int net2280_start(struct usb_gadget *_gadget,
		struct usb_gadget_driver *driver)
{
	struct net2280		*dev;
	int			retval;
	unsigned		i;

	/* insist on high speed support from the driver, since
	 * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE)
	 * "must not be used in normal operation"
	 */
	if (!driver || driver->max_speed < USB_SPEED_HIGH ||
			!driver->setup)
		return -EINVAL;

	dev = container_of(_gadget, struct net2280, gadget);

	for (i = 0; i < dev->n_ep; i++)
		dev->ep[i].irqs = 0;

	/* hook up the driver ... */
	dev->driver = driver;

	retval = device_create_file(&dev->pdev->dev, &dev_attr_function);
	if (retval)
		goto err_unbind;
	retval = device_create_file(&dev->pdev->dev, &dev_attr_queues);
	if (retval)
		goto err_func;

	/* enable host detection and ep0; and we're ready
	 * for set_configuration as well as eventual disconnect.
	 */
	net2280_led_active(dev, 1);

	if ((dev->quirks & PLX_PCIE) && !dev->bug7734_patched)
		defect7374_enable_data_eps_zero(dev);

	ep0_start(dev);

	/* pci writes may still be posted */
	return 0;

err_func:
	device_remove_file(&dev->pdev->dev, &dev_attr_function);
err_unbind:
	dev->driver = NULL;
	return retval;
}

static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver)
{
	int			i;

	/* don't disconnect if it's not connected */
	if (dev->gadget.speed == USB_SPEED_UNKNOWN)
		driver = NULL;

	/* stop hardware; prevent new request submissions;
	 * and kill any outstanding requests.
	 */
	usb_reset(dev);
	for (i = 0; i < dev->n_ep; i++)
		nuke(&dev->ep[i]);

	/* report disconnect; the driver is already quiesced */
	if (dev->async_callbacks && driver) {
		spin_unlock(&dev->lock);
		driver->disconnect(&dev->gadget);
		spin_lock(&dev->lock);
	}

	usb_reinit(dev);
}

static int net2280_stop(struct usb_gadget *_gadget)
{
	struct net2280	*dev;
	unsigned long	flags;

	dev = container_of(_gadget, struct net2280, gadget);

	spin_lock_irqsave(&dev->lock, flags);
	stop_activity(dev, NULL);
	spin_unlock_irqrestore(&dev->lock, flags);

	net2280_led_active(dev, 0);

	device_remove_file(&dev->pdev->dev, &dev_attr_function);
	device_remove_file(&dev->pdev->dev, &dev_attr_queues);

	dev->driver = NULL;

	return 0;
}

static void net2280_async_callbacks(struct usb_gadget *_gadget, bool enable)
{
	struct net2280	*dev = container_of(_gadget, struct net2280, gadget);

	spin_lock_irq(&dev->lock);
	dev->async_callbacks = enable;
	spin_unlock_irq(&dev->lock);
}

/*-------------------------------------------------------------------------*/

/* handle ep0, ep-e, ep-f with 64 byte packets: packet per irq.
 * also works for dma-capable endpoints, in pio mode or just
 * to manually advance the queue after short OUT transfers.
 */
static void handle_ep_small(struct net2280_ep *ep)
{
	struct net2280_request	*req;
	u32			t;
	/* 0 error, 1 mid-data, 2 done */
	int			mode = 1;

	if (!list_empty(&ep->queue))
		req = list_entry(ep->queue.next,
			struct net2280_request, queue);
	else
		req = NULL;

	/* ack all, and handle what we care about */
	t = readl(&ep->regs->ep_stat);
	ep->irqs++;

	ep_vdbg(ep->dev, "%s ack ep_stat %08x, req %p\n",
			ep->ep.name, t, req ? &req->req : NULL);

	if (!ep->is_in || (ep->dev->quirks & PLX_2280))
		writel(t & ~BIT(NAK_OUT_PACKETS), &ep->regs->ep_stat);
	else
		/* Added for 2282 */
		writel(t, &ep->regs->ep_stat);

	/* for ep0, monitor token irqs to catch data stage length errors
	 * and to synchronize on status.
	 *
	 * also, to defer reporting of protocol stalls ... here's where
	 * data or status first appears, handling stalls here should never
	 * cause trouble on the host side..
	 *
	 * control requests could be slightly faster without token synch for
	 * status, but status can jam up that way.
	 */
	if (unlikely(ep->num == 0)) {
		if (ep->is_in) {
			/* status; stop NAKing */
			if (t & BIT(DATA_OUT_PING_TOKEN_INTERRUPT)) {
				if (ep->dev->protocol_stall) {
					ep->stopped = 1;
					set_halt(ep);
				}
				if (!req)
					allow_status(ep);
				mode = 2;
			/* reply to extra IN data tokens with a zlp */
			} else if (t & BIT(DATA_IN_TOKEN_INTERRUPT)) {
				if (ep->dev->protocol_stall) {
					ep->stopped = 1;
					set_halt(ep);
					mode = 2;
				} else if (ep->responded &&
						!req && !ep->stopped)
					write_fifo(ep, NULL);
			}
		} else {
			/* status; stop NAKing */
			if (t & BIT(DATA_IN_TOKEN_INTERRUPT)) {
				if (ep->dev->protocol_stall) {
					ep->stopped = 1;
					set_halt(ep);
				}
				mode = 2;
			/* an extra OUT token is an error */
			} else if (((t & BIT(DATA_OUT_PING_TOKEN_INTERRUPT)) &&
					req &&
					req->req.actual == req->req.length) ||
					(ep->responded && !req)) {
				ep->dev->protocol_stall = 1;
				set_halt(ep);
				ep->stopped = 1;
				if (req)
					done(ep, req, -EOVERFLOW);
				req = NULL;
			}
		}
	}

	if (unlikely(!req))
		return;

	/* manual DMA queue advance after short OUT */
	if (likely(ep->dma)) {
		if (t & BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT)) {
			struct net2280_request *stuck_req = NULL;
			int	stopped = ep->stopped;
			int	num_completed;
			int	stuck = 0;
			u32	count;

			/* TRANSFERRED works around OUT_DONE erratum 0112.
			 * we expect (N <= maxpacket) bytes; host wrote M.
			 * iff (M < N) we won't ever see a DMA interrupt.
			 */
			ep->stopped = 1;
			for (count = 0; ; t = readl(&ep->regs->ep_stat)) {

				/* any preceding dma transfers must finish.
				 * dma handles (M >= N), may empty the queue
				 */
				num_completed = scan_dma_completions(ep);
				if (unlikely(list_empty(&ep->queue) ||
						ep->out_overflow)) {
					req = NULL;
					break;
				}
				req = list_entry(ep->queue.next,
					struct net2280_request, queue);

				/* here either (M < N), a "real" short rx;
				 * or (M == N) and the queue didn't empty
				 */
				if (likely(t & BIT(FIFO_EMPTY))) {
					count = readl(&ep->dma->dmacount);
					count &= DMA_BYTE_COUNT_MASK;
					if (readl(&ep->dma->dmadesc)
							!= req->td_dma)
						req = NULL;
					break;
				}

				/* Escape loop if no dma transfers completed
				 * after few retries.
				 */
				if (num_completed == 0) {
					if (stuck_req == req &&
					    readl(&ep->dma->dmadesc) !=
						  req->td_dma && stuck++ > 5) {
						count = readl(
							&ep->dma->dmacount);
						count &= DMA_BYTE_COUNT_MASK;
						req = NULL;
						ep_dbg(ep->dev, "%s escape stuck %d, count %u\n",
							ep->ep.name, stuck,
							count);
						break;
					} else if (stuck_req != req) {
						stuck_req = req;
						stuck = 0;
					}
				} else {
					stuck_req = NULL;
					stuck = 0;
				}

				udelay(1);
			}

			/* stop DMA, leave ep NAKing */
			writel(BIT(DMA_ABORT), &ep->dma->dmastat);
			spin_stop_dma(ep->dma);

			if (likely(req)) {
				req->td->dmacount = 0;
				t = readl(&ep->regs->ep_avail);
				dma_done(ep, req, count,
					(ep->out_overflow || t)
						? -EOVERFLOW : 0);
			}

			/* also flush to prevent erratum 0106 trouble */
			if (unlikely(ep->out_overflow ||
					(ep->dev->chiprev == 0x0100 &&
					ep->dev->gadget.speed
					== USB_SPEED_FULL))) {
				out_flush(ep);
				ep->out_overflow = 0;
			}

			/* (re)start dma if needed, stop NAKing */
			ep->stopped = stopped;
			if (!list_empty(&ep->queue))
				restart_dma(ep);
		} else
			ep_dbg(ep->dev, "%s dma ep_stat %08x ??\n",
					ep->ep.name, t);
		return;

	/* data packet(s) received (in the fifo, OUT) */
	} else if (t & BIT(DATA_PACKET_RECEIVED_INTERRUPT)) {
		if (read_fifo(ep, req) && ep->num != 0)
			mode = 2;

	/* data packet(s) transmitted (IN) */
	} else if (t & BIT(DATA_PACKET_TRANSMITTED_INTERRUPT)) {
		unsigned	len;

		len = req->req.length - req->req.actual;
		if (len > ep->ep.maxpacket)
			len = ep->ep.maxpacket;
		req->req.actual += len;

		/* if we wrote it all, we're usually done */
		/* send zlps until the status stage */
		if ((req->req.actual == req->req.length) &&
			(!req->req.zero || len != ep->ep.maxpacket) && ep->num)
				mode = 2;

	/* there was nothing to do ...  */
	} else if (mode == 1)
		return;

	/* done */
	if (mode == 2) {
		/* stream endpoints often resubmit/unlink in completion */
		done(ep, req, 0);

		/* maybe advance queue to next request */
		if (ep->num == 0) {
			/* 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);
			req = NULL;
		} else {
			if (!list_empty(&ep->queue) && !ep->stopped)
				req = list_entry(ep->queue.next,
					struct net2280_request, queue);
			else
				req = NULL;
			if (req && !ep->is_in)
				stop_out_naking(ep);
		}
	}

	/* is there a buffer for the next packet?
	 * for best streaming performance, make sure there is one.
	 */
	if (req && !ep->stopped) {

		/* load IN fifo with next packet (may be zlp) */
		if (t & BIT(DATA_PACKET_TRANSMITTED_INTERRUPT))
			write_fifo(ep, &req->req);
	}
}

static struct net2280_ep *get_ep_by_addr(struct net2280 *dev, u16 wIndex)
{
	struct net2280_ep	*ep;

	if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
		return &dev->ep[0];
	list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) {
		u8	bEndpointAddress;

		if (!ep->desc)
			continue;
		bEndpointAddress = ep->desc->bEndpointAddress;
		if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
			continue;
		if ((wIndex & 0x0f) == (bEndpointAddress & 0x0f))
			return ep;
	}
	return NULL;
}

static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r)
{
	u32 scratch, fsmvalue;
	u32 ack_wait_timeout, state;

	/* Workaround for Defect 7374 (U1/U2 erroneously rejected): */
	scratch = get_idx_reg(dev->regs, SCRATCH);
	fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD);
	scratch &= ~(0xf << DEFECT7374_FSM_FIELD);

	if (!((fsmvalue == DEFECT7374_FSM_WAITING_FOR_CONTROL_READ) &&
				(r.bRequestType & USB_DIR_IN)))
		return;

	/* This is the first Control Read for this connection: */
	if (!(readl(&dev->usb->usbstat) & BIT(SUPER_SPEED_MODE))) {
		/*
		 * Connection is NOT SS:
		 * - Connection must be FS or HS.
		 * - This FSM state should allow workaround software to
		 * run after the next USB connection.
		 */
		scratch |= DEFECT7374_FSM_NON_SS_CONTROL_READ;
		dev->bug7734_patched = 1;
		goto restore_data_eps;
	}

	/* Connection is SS: */
	for (ack_wait_timeout = 0;
			ack_wait_timeout < DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS;
			ack_wait_timeout++) {

		state =	readl(&dev->plregs->pl_ep_status_1)
			& (0xff << STATE);
		if ((state >= (ACK_GOOD_NORMAL << STATE)) &&
			(state <= (ACK_GOOD_MORE_ACKS_TO_COME << STATE))) {
			scratch |= DEFECT7374_FSM_SS_CONTROL_READ;
			dev->bug7734_patched = 1;
			break;
		}

		/*
		 * We have not yet received host's Data Phase ACK
		 * - Wait and try again.
		 */
		udelay(DEFECT_7374_PROCESSOR_WAIT_TIME);
	}


	if (ack_wait_timeout >= DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS) {
		ep_err(dev, "FAIL: Defect 7374 workaround waited but failed "
		"to detect SS host's data phase ACK.");
		ep_err(dev, "PL_EP_STATUS_1(23:16):.Expected from 0x11 to 0x16"
		"got 0x%2.2x.\n", state >> STATE);
	} else {
		ep_warn(dev, "INFO: Defect 7374 workaround waited about\n"
		"%duSec for Control Read Data Phase ACK\n",
			DEFECT_7374_PROCESSOR_WAIT_TIME * ack_wait_timeout);
	}

restore_data_eps:
	/*
	 * Restore data EPs to their pre-workaround settings (disabled,
	 * initialized, and other details).
	 */
	defect7374_disable_data_eps(dev);

	set_idx_reg(dev->regs, SCRATCH, scratch);

	return;
}

static void ep_clear_seqnum(struct net2280_ep *ep)
{
	struct net2280 *dev = ep->dev;
	u32 val;
	static const u32 ep_pl[9] = { 0, 3, 4, 7, 8, 2, 5, 6, 9 };

	val = readl(&dev->plregs->pl_ep_ctrl) & ~0x1f;
	val |= ep_pl[ep->num];
	writel(val, &dev->plregs->pl_ep_ctrl);
	val |= BIT(SEQUENCE_NUMBER_RESET);
	writel(val, &dev->plregs->pl_ep_ctrl);

	return;
}

static void handle_stat0_irqs_superspeed(struct net2280 *dev,
		struct net2280_ep *ep, struct usb_ctrlrequest r)
{
	struct net2280_ep *e;
	u16 status;
	int tmp = 0;

#define	w_value		le16_to_cpu(r.wValue)
#define	w_index		le16_to_cpu(r.wIndex)
#define	w_length	le16_to_cpu(r.wLength)

	switch (r.bRequest) {
	case USB_REQ_SET_CONFIGURATION:
		dev->addressed_state = !w_value;
		goto usb3_delegate;

	case USB_REQ_GET_STATUS:
		switch (r.bRequestType) {
		case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
			status = dev->wakeup_enable ? 0x02 : 0x00;
			if (dev->gadget.is_selfpowered)
				status |= BIT(0);
			status |= (dev->u1_enable << 2 | dev->u2_enable << 3 |
							dev->ltm_enable << 4);
			writel(0, &dev->epregs[0].ep_irqenb);
			set_fifo_bytecount(ep, sizeof(status));
			writel((__force u32) status, &dev->epregs[0].ep_data);
			allow_status_338x(ep);
			break;

		case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
			e = get_ep_by_addr(dev, w_index);
			if (!e)
				goto do_stall3;
			status = readl(&e->regs->ep_rsp) &
						BIT(CLEAR_ENDPOINT_HALT);
			writel(0, &dev->epregs[0].ep_irqenb);
			set_fifo_bytecount(ep, sizeof(status));
			writel((__force u32) status, &dev->epregs[0].ep_data);
			allow_status_338x(ep);
			break;

		default:
			goto usb3_delegate;
		}
		break;

	case USB_REQ_CLEAR_FEATURE:
		switch (r.bRequestType) {
		case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
			if (!dev->addressed_state) {
				switch (w_value) {
				case USB_DEVICE_U1_ENABLE:
					dev->u1_enable = 0;
					writel(readl(&dev->usb_ext->usbctl2) &
						~BIT(U1_ENABLE),
						&dev->usb_ext->usbctl2);
					allow_status_338x(ep);
					goto next_endpoints3;

				case USB_DEVICE_U2_ENABLE:
					dev->u2_enable = 0;
					writel(readl(&dev->usb_ext->usbctl2) &
						~BIT(U2_ENABLE),
						&dev->usb_ext->usbctl2);
					allow_status_338x(ep);
					goto next_endpoints3;

				case USB_DEVICE_LTM_ENABLE:
					dev->ltm_enable = 0;
					writel(readl(&dev->usb_ext->usbctl2) &
						~BIT(LTM_ENABLE),
						&dev->usb_ext->usbctl2);
					allow_status_338x(ep);
					goto next_endpoints3;

				default:
					break;
				}
			}
			if (w_value == USB_DEVICE_REMOTE_WAKEUP) {
				dev->wakeup_enable = 0;
				writel(readl(&dev->usb->usbctl) &
					~BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
					&dev->usb->usbctl);
				allow_status_338x(ep);
				break;
			}
			goto usb3_delegate;

		case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
			e = get_ep_by_addr(dev,	w_index);
			if (!e)
				goto do_stall3;
			if (w_value != USB_ENDPOINT_HALT)
				goto do_stall3;
			ep_vdbg(dev, "%s clear halt\n", e->ep.name);
			/*
			 * Workaround for SS SeqNum not cleared via
			 * Endpoint Halt (Clear) bit. select endpoint
			 */
			ep_clear_seqnum(e);
			clear_halt(e);
			if (!list_empty(&e->queue) && e->td_dma)
				restart_dma(e);
			allow_status(ep);
			ep->stopped = 1;
			break;

		default:
			goto usb3_delegate;
		}
		break;
	case USB_REQ_SET_FEATURE:
		switch (r.bRequestType) {
		case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
			if (!dev->addressed_state) {
				switch (w_value) {
				case USB_DEVICE_U1_ENABLE:
					dev->u1_enable = 1;
					writel(readl(&dev->usb_ext->usbctl2) |
						BIT(U1_ENABLE),
						&dev->usb_ext->usbctl2);
					allow_status_338x(ep);
					goto next_endpoints3;

				case USB_DEVICE_U2_ENABLE:
					dev->u2_enable = 1;
					writel(readl(&dev->usb_ext->usbctl2) |
						BIT(U2_ENABLE),
						&dev->usb_ext->usbctl2);
					allow_status_338x(ep);
					goto next_endpoints3;

				case USB_DEVICE_LTM_ENABLE:
					dev->ltm_enable = 1;
					writel(readl(&dev->usb_ext->usbctl2) |
						BIT(LTM_ENABLE),
						&dev->usb_ext->usbctl2);
					allow_status_338x(ep);
					goto next_endpoints3;
				default:
					break;
				}
			}

			if (w_value == USB_DEVICE_REMOTE_WAKEUP) {
				dev->wakeup_enable = 1;
				writel(readl(&dev->usb->usbctl) |
					BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
					&dev->usb->usbctl);
				allow_status_338x(ep);
				break;
			}
			goto usb3_delegate;

		case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
			e = get_ep_by_addr(dev,	w_index);
			if (!e || (w_value != USB_ENDPOINT_HALT))
				goto do_stall3;
			ep->stopped = 1;
			if (ep->num == 0)
				ep->dev->protocol_stall = 1;
			else {
				if (ep->dma)
					abort_dma(ep);
				set_halt(ep);
			}
			allow_status_338x(ep);
			break;

		default:
			goto usb3_delegate;
		}

		break;
	default:

usb3_delegate:
		ep_vdbg(dev, "setup %02x.%02x v%04x i%04x l%04x ep_cfg %08x\n",
				r.bRequestType, r.bRequest,
				w_value, w_index, w_length,
				readl(&ep->cfg->ep_cfg));

		ep->responded = 0;
		if (dev->async_callbacks) {
			spin_unlock(&dev->lock);
			tmp = dev->driver->setup(&dev->gadget, &r);
			spin_lock(&dev->lock);
		}
	}
do_stall3:
	if (tmp < 0) {
		ep_vdbg(dev, "req %02x.%02x protocol STALL; stat %d\n",
				r.bRequestType, r.bRequest, tmp);
		dev->protocol_stall = 1;
		/* TD 9.9 Halt Endpoint test. TD 9.22 Set feature test */
		set_halt(ep);
	}

next_endpoints3:

#undef	w_value
#undef	w_index
#undef	w_length

	return;
}

static void usb338x_handle_ep_intr(struct net2280 *dev, u32 stat0)
{
	u32 index;
	u32 bit;

	for (index = 0; index < ARRAY_SIZE(ep_bit); index++) {
		bit = BIT(ep_bit[index]);

		if (!stat0)
			break;

		if (!(stat0 & bit))
			continue;

		stat0 &= ~bit;

		handle_ep_small(&dev->ep[index]);
	}
}

static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
{
	struct net2280_ep	*ep;
	u32			num, scratch;

	/* most of these don't need individual acks */
	stat &= ~BIT(INTA_ASSERTED);
	if (!stat)
		return;
	/* ep_dbg(dev, "irqstat0 %04x\n", stat); */

	/* starting a control request? */
	if (unlikely(stat & BIT(SETUP_PACKET_INTERRUPT))) {
		union {
			u32			raw[2];
			struct usb_ctrlrequest	r;
		} u;
		int				tmp;
		struct net2280_request		*req;

		if (dev->gadget.speed == USB_SPEED_UNKNOWN) {
			u32 val = readl(&dev->usb->usbstat);
			if (val & BIT(SUPER_SPEED)) {
				dev->gadget.speed = USB_SPEED_SUPER;
				usb_ep_set_maxpacket_limit(&dev->ep[0].ep,
						EP0_SS_MAX_PACKET_SIZE);
			} else if (val & BIT(HIGH_SPEED)) {
				dev->gadget.speed = USB_SPEED_HIGH;
				usb_ep_set_maxpacket_limit(&dev->ep[0].ep,
						EP0_HS_MAX_PACKET_SIZE);
			} else {
				dev->gadget.speed = USB_SPEED_FULL;
				usb_ep_set_maxpacket_limit(&dev->ep[0].ep,
						EP0_HS_MAX_PACKET_SIZE);
			}
			net2280_led_speed(dev, dev->gadget.speed);
			ep_dbg(dev, "%s\n",
					usb_speed_string(dev->gadget.speed));
		}

		ep = &dev->ep[0];
		ep->irqs++;

		/* make sure any leftover request state is cleared */
		stat &= ~BIT(ENDPOINT_0_INTERRUPT);
		while (!list_empty(&ep->queue)) {
			req = list_entry(ep->queue.next,
					struct net2280_request, queue);
			done(ep, req, (req->req.actual == req->req.length)
						? 0 : -EPROTO);
		}
		ep->stopped = 0;
		dev->protocol_stall = 0;
		if (!(dev->quirks & PLX_PCIE)) {
			if (ep->dev->quirks & PLX_2280)
				tmp = BIT(FIFO_OVERFLOW) |
				    BIT(FIFO_UNDERFLOW);
			else
				tmp = 0;

			writel(tmp | BIT(TIMEOUT) |
				   BIT(USB_STALL_SENT) |
				   BIT(USB_IN_NAK_SENT) |
				   BIT(USB_IN_ACK_RCVD) |
				   BIT(USB_OUT_PING_NAK_SENT) |
				   BIT(USB_OUT_ACK_SENT) |
				   BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) |
				   BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) |
				   BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
				   BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
				   BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
				   BIT(DATA_IN_TOKEN_INTERRUPT),
				   &ep->regs->ep_stat);
		}
		u.raw[0] = readl(&dev->usb->setup0123);
		u.raw[1] = readl(&dev->usb->setup4567);

		cpu_to_le32s(&u.raw[0]);
		cpu_to_le32s(&u.raw[1]);

		if ((dev->quirks & PLX_PCIE) && !dev->bug7734_patched)
			defect7374_workaround(dev, u.r);

		tmp = 0;

#define	w_value		le16_to_cpu(u.r.wValue)
#define	w_index		le16_to_cpu(u.r.wIndex)
#define	w_length	le16_to_cpu(u.r.wLength)

		/* ack the irq */
		writel(BIT(SETUP_PACKET_INTERRUPT), &dev->regs->irqstat0);
		stat ^= BIT(SETUP_PACKET_INTERRUPT);

		/* 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) {
			scratch = BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
				BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
				BIT(DATA_IN_TOKEN_INTERRUPT);
			stop_out_naking(ep);
		} else
			scratch = BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
				BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
				BIT(DATA_IN_TOKEN_INTERRUPT);
		writel(scratch, &dev->epregs[0].ep_irqenb);

		/* we made the hardware handle most lowlevel requests;
		 * everything else goes uplevel to the gadget code.
		 */
		ep->responded = 1;

		if (dev->gadget.speed == USB_SPEED_SUPER) {
			handle_stat0_irqs_superspeed(dev, ep, u.r);
			goto next_endpoints;
		}

		switch (u.r.bRequest) {
		case USB_REQ_GET_STATUS: {
			struct net2280_ep	*e;
			__le32			status;

			/* hw handles device and interface status */
			if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT))
				goto delegate;
			e = get_ep_by_addr(dev, w_index);
			if (!e || w_length > 2)
				goto do_stall;

			if (readl(&e->regs->ep_rsp) & BIT(SET_ENDPOINT_HALT))
				status = cpu_to_le32(1);
			else
				status = cpu_to_le32(0);

			/* don't bother with a request object! */
			writel(0, &dev->epregs[0].ep_irqenb);
			set_fifo_bytecount(ep, w_length);
			writel((__force u32)status, &dev->epregs[0].ep_data);
			allow_status(ep);
			ep_vdbg(dev, "%s stat %02x\n", ep->ep.name, status);
			goto next_endpoints;
			}
			break;
		case USB_REQ_CLEAR_FEATURE: {
			struct net2280_ep	*e;

			/* hw handles device features */
			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
				goto delegate;
			if (w_value != USB_ENDPOINT_HALT || w_length != 0)
				goto do_stall;
			e = get_ep_by_addr(dev, w_index);
			if (!e)
				goto do_stall;
			if (e->wedged) {
				ep_vdbg(dev, "%s wedged, halt not cleared\n",
						ep->ep.name);
			} else {
				ep_vdbg(dev, "%s clear halt\n", e->ep.name);
				clear_halt(e);
				if ((ep->dev->quirks & PLX_PCIE) &&
					!list_empty(&e->queue) && e->td_dma)
						restart_dma(e);
			}
			allow_status(ep);
			goto next_endpoints;
			}
			break;
		case USB_REQ_SET_FEATURE: {
			struct net2280_ep	*e;

			/* hw handles device features */
			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
				goto delegate;
			if (w_value != USB_ENDPOINT_HALT || w_length != 0)
				goto do_stall;
			e = get_ep_by_addr(dev, w_index);
			if (!e)
				goto do_stall;
			if (e->ep.name == ep0name)
				goto do_stall;
			set_halt(e);
			if ((dev->quirks & PLX_PCIE) && e->dma)
				abort_dma(e);
			allow_status(ep);
			ep_vdbg(dev, "%s set halt\n", ep->ep.name);
			goto next_endpoints;
			}
			break;
		default:
delegate:
			ep_vdbg(dev, "setup %02x.%02x v%04x i%04x l%04x "
				"ep_cfg %08x\n",
				u.r.bRequestType, u.r.bRequest,
				w_value, w_index, w_length,
				readl(&ep->cfg->ep_cfg));
			ep->responded = 0;
			if (dev->async_callbacks) {
				spin_unlock(&dev->lock);
				tmp = dev->driver->setup(&dev->gadget, &u.r);
				spin_lock(&dev->lock);
			}
		}

		/* stall ep0 on error */
		if (tmp < 0) {
do_stall:
			ep_vdbg(dev, "req %02x.%02x protocol STALL; stat %d\n",
					u.r.bRequestType, u.r.bRequest, tmp);
			dev->protocol_stall = 1;
		}

		/* some in/out token irq should follow; maybe stall then.
		 * driver must queue a request (even zlp) or halt ep0
		 * before the host times out.
		 */
	}

#undef	w_value
#undef	w_index
#undef	w_length

next_endpoints:
	if ((dev->quirks & PLX_PCIE) && dev->enhanced_mode) {
		u32 mask = (BIT(ENDPOINT_0_INTERRUPT) |
			USB3380_IRQSTAT0_EP_INTR_MASK_IN |
			USB3380_IRQSTAT0_EP_INTR_MASK_OUT);

		if (stat & mask) {
			usb338x_handle_ep_intr(dev, stat & mask);
			stat &= ~mask;
		}
	} else {
		/* endpoint data irq ? */
		scratch = stat & 0x7f;
		stat &= ~0x7f;
		for (num = 0; scratch; num++) {
			u32		t;

			/* do this endpoint's FIFO and queue need tending? */
			t = BIT(num);
			if ((scratch & t) == 0)
				continue;
			scratch ^= t;

			ep = &dev->ep[num];
			handle_ep_small(ep);
		}
	}

	if (stat)
		ep_dbg(dev, "unhandled irqstat0 %08x\n", stat);
}

#define DMA_INTERRUPTS (BIT(DMA_D_INTERRUPT) | \
		BIT(DMA_C_INTERRUPT) | \
		BIT(DMA_B_INTERRUPT) | \
		BIT(DMA_A_INTERRUPT))
#define	PCI_ERROR_INTERRUPTS ( \
		BIT(PCI_MASTER_ABORT_RECEIVED_INTERRUPT) | \
		BIT(PCI_TARGET_ABORT_RECEIVED_INTERRUPT) | \
		BIT(PCI_RETRY_ABORT_INTERRUPT))

static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
__releases(dev->lock)
__acquires(dev->lock)
{
	struct net2280_ep	*ep;
	u32			tmp, num, mask, scratch;

	/* after disconnect there's nothing else to do! */
	tmp = BIT(VBUS_INTERRUPT) | BIT(ROOT_PORT_RESET_INTERRUPT);
	mask = BIT(SUPER_SPEED) | BIT(HIGH_SPEED) | BIT(FULL_SPEED);

	/* VBUS disconnect is indicated by VBUS_PIN and VBUS_INTERRUPT set.
	 * Root Port Reset is indicated by ROOT_PORT_RESET_INTERRUPT set and
	 * both HIGH_SPEED and FULL_SPEED clear (as ROOT_PORT_RESET_INTERRUPT
	 * only indicates a change in the reset state).
	 */
	if (stat & tmp) {
		bool	reset = false;
		bool	disconnect = false;

		/*
		 * Ignore disconnects and resets if the speed hasn't been set.
		 * VBUS can bounce and there's always an initial reset.
		 */
		writel(tmp, &dev->regs->irqstat1);
		if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
			if ((stat & BIT(VBUS_INTERRUPT)) &&
					(readl(&dev->usb->usbctl) &
						BIT(VBUS_PIN)) == 0) {
				disconnect = true;
				ep_dbg(dev, "disconnect %s\n",
						dev->driver->driver.name);
			} else if ((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) &&
					(readl(&dev->usb->usbstat) & mask)
						== 0) {
				reset = true;
				ep_dbg(dev, "reset %s\n",
						dev->driver->driver.name);
			}

			if (disconnect || reset) {
				stop_activity(dev, dev->driver);
				ep0_start(dev);
				if (dev->async_callbacks) {
					spin_unlock(&dev->lock);
					if (reset)
						usb_gadget_udc_reset(&dev->gadget, dev->driver);
					else
						(dev->driver->disconnect)(&dev->gadget);
					spin_lock(&dev->lock);
				}
				return;
			}
		}
		stat &= ~tmp;

		/* vBUS can bounce ... one of many reasons to ignore the
		 * notion of hotplug events on bus connect/disconnect!
		 */
		if (!stat)
			return;
	}

	/* NOTE: chip stays in PCI D0 state for now, but it could
	 * enter D1 to save more power
	 */
	tmp = BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT);
	if (stat & tmp) {
		writel(tmp, &dev->regs->irqstat1);
		spin_unlock(&dev->lock);
		if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) {
			if (dev->async_callbacks && dev->driver->suspend)
				dev->driver->suspend(&dev->gadget);
			if (!enable_suspend)
				stat &= ~BIT(SUSPEND_REQUEST_INTERRUPT);
		} else {
			if (dev->async_callbacks && dev->driver->resume)
				dev->driver->resume(&dev->gadget);
			/* at high speed, note erratum 0133 */
		}
		spin_lock(&dev->lock);
		stat &= ~tmp;
	}

	/* clear any other status/irqs */
	if (stat)
		writel(stat, &dev->regs->irqstat1);

	/* some status we can just ignore */
	if (dev->quirks & PLX_2280)
		stat &= ~(BIT(CONTROL_STATUS_INTERRUPT) |
			  BIT(SUSPEND_REQUEST_INTERRUPT) |
			  BIT(RESUME_INTERRUPT) |
			  BIT(SOF_INTERRUPT));
	else
		stat &= ~(BIT(CONTROL_STATUS_INTERRUPT) |
			  BIT(RESUME_INTERRUPT) |
			  BIT(SOF_DOWN_INTERRUPT) |
			  BIT(SOF_INTERRUPT));

	if (!stat)
		return;
	/* ep_dbg(dev, "irqstat1 %08x\n", stat);*/

	/* DMA status, for ep-{a,b,c,d} */
	scratch = stat & DMA_INTERRUPTS;
	stat &= ~DMA_INTERRUPTS;
	scratch >>= 9;
	for (num = 0; scratch; num++) {
		struct net2280_dma_regs	__iomem *dma;

		tmp = BIT(num);
		if ((tmp & scratch) == 0)
			continue;
		scratch ^= tmp;

		ep = &dev->ep[num + 1];
		dma = ep->dma;

		if (!dma)
			continue;

		/* clear ep's dma status */
		tmp = readl(&dma->dmastat);
		writel(tmp, &dma->dmastat);

		/* dma sync*/
		if (dev->quirks & PLX_PCIE) {
			u32 r_dmacount = readl(&dma->dmacount);
			if (!ep->is_in &&  (r_dmacount & 0x00FFFFFF) &&
			    (tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT)))
				continue;
		}

		if (!(tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) {
			ep_dbg(ep->dev, "%s no xact done? %08x\n",
				ep->ep.name, tmp);
			continue;
		}
		stop_dma(ep->dma);

		/* OUT transfers terminate when the data from the
		 * host is in our memory.  Process whatever's done.
		 * On this path, we know transfer's last packet wasn't
		 * less than req->length. NAK_OUT_PACKETS may be set,
		 * or the FIFO may already be holding new packets.
		 *
		 * IN transfers can linger in the FIFO for a very
		 * long time ... we ignore that for now, accounting
		 * precisely (like PIO does) needs per-packet irqs
		 */
		scan_dma_completions(ep);

		/* disable dma on inactive queues; else maybe restart */
		if (!list_empty(&ep->queue)) {
			tmp = readl(&dma->dmactl);
			restart_dma(ep);
		}
		ep->irqs++;
	}

	/* NOTE:  there are other PCI errors we might usefully notice.
	 * if they appear very often, here's where to try recovering.
	 */
	if (stat & PCI_ERROR_INTERRUPTS) {
		ep_err(dev, "pci dma error; stat %08x\n", stat);
		stat &= ~PCI_ERROR_INTERRUPTS;
		/* these are fatal errors, but "maybe" they won't
		 * happen again ...
		 */
		stop_activity(dev, dev->driver);
		ep0_start(dev);
		stat = 0;
	}

	if (stat)
		ep_dbg(dev, "unhandled irqstat1 %08x\n", stat);
}

static irqreturn_t net2280_irq(int irq, void *_dev)
{
	struct net2280		*dev = _dev;

	/* shared interrupt, not ours */
	if ((dev->quirks & PLX_LEGACY) &&
		(!(readl(&dev->regs->irqstat0) & BIT(INTA_ASSERTED))))
		return IRQ_NONE;

	spin_lock(&dev->lock);

	/* handle disconnect, dma, and more */
	handle_stat1_irqs(dev, readl(&dev->regs->irqstat1));

	/* control requests and PIO */
	handle_stat0_irqs(dev, readl(&dev->regs->irqstat0));

	if (dev->quirks & PLX_PCIE) {
		/* re-enable interrupt to trigger any possible new interrupt */
		u32 pciirqenb1 = readl(&dev->regs->pciirqenb1);
		writel(pciirqenb1 & 0x7FFFFFFF, &dev->regs->pciirqenb1);
		writel(pciirqenb1, &dev->regs->pciirqenb1);
	}

	spin_unlock(&dev->lock);

	return IRQ_HANDLED;
}

/*-------------------------------------------------------------------------*/

static void gadget_release(struct device *_dev)
{
	struct net2280	*dev = container_of(_dev, struct net2280, gadget.dev);

	kfree(dev);
}

/* tear down the binding between this driver and the pci device */

static void net2280_remove(struct pci_dev *pdev)
{
	struct net2280		*dev = pci_get_drvdata(pdev);

	if (dev->added)
		usb_del_gadget(&dev->gadget);

	BUG_ON(dev->driver);

	/* then clean up the resources we allocated during probe() */
	if (dev->requests) {
		int		i;
		for (i = 1; i < 5; i++) {
			if (!dev->ep[i].dummy)
				continue;
			dma_pool_free(dev->requests, dev->ep[i].dummy,
					dev->ep[i].td_dma);
		}
		dma_pool_destroy(dev->requests);
	}
	if (dev->got_irq)
		free_irq(pdev->irq, dev);
	if (dev->quirks & PLX_PCIE)
		pci_disable_msi(pdev);
	if (dev->regs) {
		net2280_led_shutdown(dev);
		iounmap(dev->regs);
	}
	if (dev->region)
		release_mem_region(pci_resource_start(pdev, 0),
				pci_resource_len(pdev, 0));
	if (dev->enabled)
		pci_disable_device(pdev);
	device_remove_file(&pdev->dev, &dev_attr_registers);

	ep_info(dev, "unbind\n");
	usb_put_gadget(&dev->gadget);
}

/* wrap this driver around the specified device, but
 * don't respond over USB until a gadget driver binds to us.
 */

static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct net2280		*dev;
	unsigned long		resource, len;
	void			__iomem *base = NULL;
	int			retval, i;

	/* alloc, and start init */
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (dev == NULL) {
		retval = -ENOMEM;
		goto done;
	}

	pci_set_drvdata(pdev, dev);
	usb_initialize_gadget(&pdev->dev, &dev->gadget, gadget_release);
	spin_lock_init(&dev->lock);
	dev->quirks = id->driver_data;
	dev->pdev = pdev;
	dev->gadget.ops = &net2280_ops;
	dev->gadget.max_speed = (dev->quirks & PLX_SUPERSPEED) ?
				USB_SPEED_SUPER : USB_SPEED_HIGH;

	/* the "gadget" abstracts/virtualizes the controller */
	dev->gadget.name = driver_name;

	/* now all the pci goodies ... */
	if (pci_enable_device(pdev) < 0) {
		retval = -ENODEV;
		goto done;
	}
	dev->enabled = 1;

	/* BAR 0 holds all the registers
	 * BAR 1 is 8051 memory; unused here (note erratum 0103)
	 * BAR 2 is fifo memory; unused here
	 */
	resource = pci_resource_start(pdev, 0);
	len = pci_resource_len(pdev, 0);
	if (!request_mem_region(resource, len, driver_name)) {
		ep_dbg(dev, "controller already in use\n");
		retval = -EBUSY;
		goto done;
	}
	dev->region = 1;

	/* FIXME provide firmware download interface to put
	 * 8051 code into the chip, e.g. to turn on PCI PM.
	 */

	base = ioremap(resource, len);
	if (base == NULL) {
		ep_dbg(dev, "can't map memory\n");
		retval = -EFAULT;
		goto done;
	}
	dev->regs = (struct net2280_regs __iomem *) base;
	dev->usb = (struct net2280_usb_regs __iomem *) (base + 0x0080);
	dev->pci = (struct net2280_pci_regs __iomem *) (base + 0x0100);
	dev->dma = (struct net2280_dma_regs __iomem *) (base + 0x0180);
	dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200);
	dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300);

	if (dev->quirks & PLX_PCIE) {
		u32 fsmvalue;
		u32 usbstat;
		dev->usb_ext = (struct usb338x_usb_ext_regs __iomem *)
							(base + 0x00b4);
		dev->llregs = (struct usb338x_ll_regs __iomem *)
							(base + 0x0700);
		dev->plregs = (struct usb338x_pl_regs __iomem *)
							(base + 0x0800);
		usbstat = readl(&dev->usb->usbstat);
		dev->enhanced_mode = !!(usbstat & BIT(11));
		dev->n_ep = (dev->enhanced_mode) ? 9 : 5;
		/* put into initial config, link up all endpoints */
		fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
					(0xf << DEFECT7374_FSM_FIELD);
		/* See if firmware needs to set up for workaround: */
		if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) {
			dev->bug7734_patched = 1;
			writel(0, &dev->usb->usbctl);
		} else
			dev->bug7734_patched = 0;
	} else {
		dev->enhanced_mode = 0;
		dev->n_ep = 7;
		/* put into initial config, link up all endpoints */
		writel(0, &dev->usb->usbctl);
	}

	usb_reset(dev);
	usb_reinit(dev);

	/* irq setup after old hardware is cleaned up */
	if (!pdev->irq) {
		ep_err(dev, "No IRQ.  Check PCI setup!\n");
		retval = -ENODEV;
		goto done;
	}

	if (dev->quirks & PLX_PCIE)
		if (pci_enable_msi(pdev))
			ep_err(dev, "Failed to enable MSI mode\n");

	if (request_irq(pdev->irq, net2280_irq, IRQF_SHARED,
							driver_name, dev)) {
		ep_err(dev, "request interrupt %d failed\n", pdev->irq);
		retval = -EBUSY;
		goto done;
	}
	dev->got_irq = 1;

	/* DMA setup */
	/* NOTE:  we know only the 32 LSBs of dma addresses may be nonzero */
	dev->requests = dma_pool_create("requests", &pdev->dev,
		sizeof(struct net2280_dma),
		0 /* no alignment requirements */,
		0 /* or page-crossing issues */);
	if (!dev->requests) {
		ep_dbg(dev, "can't get request pool\n");
		retval = -ENOMEM;
		goto done;
	}
	for (i = 1; i < 5; i++) {
		struct net2280_dma	*td;

		td = dma_pool_alloc(dev->requests, GFP_KERNEL,
				&dev->ep[i].td_dma);
		if (!td) {
			ep_dbg(dev, "can't get dummy %d\n", i);
			retval = -ENOMEM;
			goto done;
		}
		td->dmacount = 0;	/* not VALID */
		td->dmadesc = td->dmaaddr;
		dev->ep[i].dummy = td;
	}

	/* enable lower-overhead pci memory bursts during DMA */
	if (dev->quirks & PLX_LEGACY)
		writel(BIT(DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) |
			/*
			 * 256 write retries may not be enough...
			   BIT(PCI_RETRY_ABORT_ENABLE) |
			*/
			BIT(DMA_READ_MULTIPLE_ENABLE) |
			BIT(DMA_READ_LINE_ENABLE),
			&dev->pci->pcimstctl);
	/* erratum 0115 shouldn't appear: Linux inits PCI_LATENCY_TIMER */
	pci_set_master(pdev);
	pci_try_set_mwi(pdev);

	/* ... also flushes any posted pci writes */
	dev->chiprev = get_idx_reg(dev->regs, REG_CHIPREV) & 0xffff;

	/* done */
	ep_info(dev, "%s\n", driver_desc);
	ep_info(dev, "irq %d, pci mem %p, chip rev %04x\n",
			pdev->irq, base, dev->chiprev);
	ep_info(dev, "version: " DRIVER_VERSION "; %s\n",
		dev->enhanced_mode ? "enhanced mode" : "legacy mode");
	retval = device_create_file(&pdev->dev, &dev_attr_registers);
	if (retval)
		goto done;

	retval = usb_add_gadget(&dev->gadget);
	if (retval)
		goto done;
	dev->added = 1;
	return 0;

done:
	if (dev) {
		net2280_remove(pdev);
		kfree(dev);
	}
	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);

}


/*-------------------------------------------------------------------------*/

static const struct pci_device_id pci_ids[] = { {
	.class =	PCI_CLASS_SERIAL_USB_DEVICE,
	.class_mask =	~0,
	.vendor =	PCI_VENDOR_ID_PLX_LEGACY,
	.device =	0x2280,
	.subvendor =	PCI_ANY_ID,
	.subdevice =	PCI_ANY_ID,
	.driver_data =	PLX_LEGACY | PLX_2280,
	}, {
	.class =	PCI_CLASS_SERIAL_USB_DEVICE,
	.class_mask =	~0,
	.vendor =	PCI_VENDOR_ID_PLX_LEGACY,
	.device =	0x2282,
	.subvendor =	PCI_ANY_ID,
	.subdevice =	PCI_ANY_ID,
	.driver_data =	PLX_LEGACY,
	},
	{
	.class =	PCI_CLASS_SERIAL_USB_DEVICE,
	.class_mask =	~0,
	.vendor =	PCI_VENDOR_ID_PLX,
	.device =	0x2380,
	.subvendor =	PCI_ANY_ID,
	.subdevice =	PCI_ANY_ID,
	.driver_data =	PLX_PCIE,
	 },
	{
	.class =	((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
	.class_mask =	~0,
	.vendor =	PCI_VENDOR_ID_PLX,
	.device =	0x3380,
	.subvendor =	PCI_ANY_ID,
	.subdevice =	PCI_ANY_ID,
	.driver_data =	PLX_PCIE | PLX_SUPERSPEED,
	 },
	{
	.class =	PCI_CLASS_SERIAL_USB_DEVICE,
	.class_mask =	~0,
	.vendor =	PCI_VENDOR_ID_PLX,
	.device =	0x3382,
	.subvendor =	PCI_ANY_ID,
	.subdevice =	PCI_ANY_ID,
	.driver_data =	PLX_PCIE | PLX_SUPERSPEED,
	 },
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(pci, pci_ids);

/* pci driver glue; this is a "new style" PCI driver module */
static struct pci_driver net2280_pci_driver = {
	.name =		driver_name,
	.id_table =	pci_ids,

	.probe =	net2280_probe,
	.remove =	net2280_remove,
	.shutdown =	net2280_shutdown,

	/* FIXME add power management support */
};

module_pci_driver(net2280_pci_driver);

MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR("David Brownell");
MODULE_LICENSE("GPL");
