|
@@ -24,7 +24,6 @@
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
-#undef DEBUG
|
|
|
// #define VERBOSE DBG_VERBOSE
|
|
|
|
|
|
#include <linux/device.h>
|
|
@@ -75,9 +74,17 @@
|
|
|
* it constrains the sorts of USB configuration change events that work.
|
|
|
* The errata for these chips are misleading; some "fixed" bugs from
|
|
|
* pxa250 a0/a1 b0/b1/b2 sure act like they're still there.
|
|
|
+ *
|
|
|
+ * Note that the UDC hardware supports DMA (except on IXP) but that's
|
|
|
+ * not used here. IN-DMA (to host) is simple enough, when the data is
|
|
|
+ * suitably aligned (16 bytes) ... the network stack doesn't do that,
|
|
|
+ * other software can. OUT-DMA is buggy in most chip versions, as well
|
|
|
+ * as poorly designed (data toggle not automatic). So this driver won't
|
|
|
+ * bother using DMA. (Mostly-working IN-DMA support was available in
|
|
|
+ * kernels before 2.6.23, but was never enabled or well tested.)
|
|
|
*/
|
|
|
|
|
|
-#define DRIVER_VERSION "4-May-2005"
|
|
|
+#define DRIVER_VERSION "30-June-2007"
|
|
|
#define DRIVER_DESC "PXA 25x USB Device Controller driver"
|
|
|
|
|
|
|
|
@@ -86,12 +93,9 @@ static const char driver_name [] = "pxa2xx_udc";
|
|
|
static const char ep0name [] = "ep0";
|
|
|
|
|
|
|
|
|
-// #define USE_DMA
|
|
|
-// #define USE_OUT_DMA
|
|
|
// #define DISABLE_TEST_MODE
|
|
|
|
|
|
#ifdef CONFIG_ARCH_IXP4XX
|
|
|
-#undef USE_DMA
|
|
|
|
|
|
/* cpu-specific register addresses are compiled in to this code */
|
|
|
#ifdef CONFIG_ARCH_PXA
|
|
@@ -103,25 +107,6 @@ static const char ep0name [] = "ep0";
|
|
|
#include "pxa2xx_udc.h"
|
|
|
|
|
|
|
|
|
-#ifdef USE_DMA
|
|
|
-static int use_dma = 1;
|
|
|
-module_param(use_dma, bool, 0);
|
|
|
-MODULE_PARM_DESC (use_dma, "true to use dma");
|
|
|
-
|
|
|
-static void dma_nodesc_handler (int dmach, void *_ep);
|
|
|
-static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req);
|
|
|
-
|
|
|
-#ifdef USE_OUT_DMA
|
|
|
-#define DMASTR " (dma support)"
|
|
|
-#else
|
|
|
-#define DMASTR " (dma in)"
|
|
|
-#endif
|
|
|
-
|
|
|
-#else /* !USE_DMA */
|
|
|
-#define DMASTR " (pio only)"
|
|
|
-#undef USE_OUT_DMA
|
|
|
-#endif
|
|
|
-
|
|
|
#ifdef CONFIG_USB_PXA2XX_SMALL
|
|
|
#define SIZE_STR " (small)"
|
|
|
#else
|
|
@@ -280,9 +265,8 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep,
|
|
|
}
|
|
|
|
|
|
ep->desc = desc;
|
|
|
- ep->dma = -1;
|
|
|
ep->stopped = 0;
|
|
|
- ep->pio_irqs = ep->dma_irqs = 0;
|
|
|
+ ep->pio_irqs = 0;
|
|
|
ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize);
|
|
|
|
|
|
/* flush fifo (mostly for OUT buffers) */
|
|
@@ -290,30 +274,6 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep,
|
|
|
|
|
|
/* ... reset halt state too, if we could ... */
|
|
|
|
|
|
-#ifdef USE_DMA
|
|
|
- /* for (some) bulk and ISO endpoints, try to get a DMA channel and
|
|
|
- * bind it to the endpoint. otherwise use PIO.
|
|
|
- */
|
|
|
- switch (ep->bmAttributes) {
|
|
|
- case USB_ENDPOINT_XFER_ISOC:
|
|
|
- if (le16_to_cpu(desc->wMaxPacketSize) % 32)
|
|
|
- break;
|
|
|
- // fall through
|
|
|
- case USB_ENDPOINT_XFER_BULK:
|
|
|
- if (!use_dma || !ep->reg_drcmr)
|
|
|
- break;
|
|
|
- ep->dma = pxa_request_dma ((char *)_ep->name,
|
|
|
- (le16_to_cpu (desc->wMaxPacketSize) > 64)
|
|
|
- ? DMA_PRIO_MEDIUM /* some iso */
|
|
|
- : DMA_PRIO_LOW,
|
|
|
- dma_nodesc_handler, ep);
|
|
|
- if (ep->dma >= 0) {
|
|
|
- *ep->reg_drcmr = DRCMR_MAPVLD | ep->dma;
|
|
|
- DMSG("%s using dma%d\n", _ep->name, ep->dma);
|
|
|
- }
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
DBG(DBG_VERBOSE, "enabled %s\n", _ep->name);
|
|
|
return 0;
|
|
|
}
|
|
@@ -333,14 +293,6 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep)
|
|
|
|
|
|
nuke (ep, -ESHUTDOWN);
|
|
|
|
|
|
-#ifdef USE_DMA
|
|
|
- if (ep->dma >= 0) {
|
|
|
- *ep->reg_drcmr = 0;
|
|
|
- pxa_free_dma (ep->dma);
|
|
|
- ep->dma = -1;
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
/* flush fifo (mostly for IN buffers) */
|
|
|
pxa2xx_ep_fifo_flush (_ep);
|
|
|
|
|
@@ -390,11 +342,6 @@ pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req)
|
|
|
}
|
|
|
|
|
|
|
|
|
-/* PXA cache needs flushing with DMA I/O (it's dma-incoherent), but there's
|
|
|
- * no device-affinity and the heap works perfectly well for i/o buffers.
|
|
|
- * It wastes much less memory than dma_alloc_coherent() would, and even
|
|
|
- * prevents cacheline (32 bytes wide) sharing problems.
|
|
|
- */
|
|
|
static void *
|
|
|
pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
|
|
|
dma_addr_t *dma, gfp_t gfp_flags)
|
|
@@ -403,11 +350,7 @@ pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
|
|
|
|
|
|
retval = kmalloc (bytes, gfp_flags & ~(__GFP_DMA|__GFP_HIGHMEM));
|
|
|
if (retval)
|
|
|
-#ifdef USE_DMA
|
|
|
- *dma = virt_to_bus (retval);
|
|
|
-#else
|
|
|
*dma = (dma_addr_t)~0;
|
|
|
-#endif
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
@@ -517,18 +460,8 @@ write_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
|
|
|
/* requests complete when all IN data is in the FIFO */
|
|
|
if (is_last) {
|
|
|
done (ep, req, 0);
|
|
|
- if (list_empty(&ep->queue) || unlikely(ep->dma >= 0)) {
|
|
|
+ if (list_empty(&ep->queue))
|
|
|
pio_irq_disable (ep->bEndpointAddress);
|
|
|
-#ifdef USE_DMA
|
|
|
- /* unaligned data and zlps couldn't use dma */
|
|
|
- if (unlikely(!list_empty(&ep->queue))) {
|
|
|
- req = list_entry(ep->queue.next,
|
|
|
- struct pxa2xx_request, queue);
|
|
|
- kick_dma(ep,req);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-#endif
|
|
|
- }
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -727,182 +660,6 @@ read_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-#ifdef USE_DMA
|
|
|
-
|
|
|
-#define MAX_IN_DMA ((DCMD_LENGTH + 1) - BULK_FIFO_SIZE)
|
|
|
-
|
|
|
-static void
|
|
|
-start_dma_nodesc(struct pxa2xx_ep *ep, struct pxa2xx_request *req, int is_in)
|
|
|
-{
|
|
|
- u32 dcmd = req->req.length;
|
|
|
- u32 buf = req->req.dma;
|
|
|
- u32 fifo = io_v2p ((u32)ep->reg_uddr);
|
|
|
-
|
|
|
- /* caller guarantees there's a packet or more remaining
|
|
|
- * - IN may end with a short packet (TSP set separately),
|
|
|
- * - OUT is always full length
|
|
|
- */
|
|
|
- buf += req->req.actual;
|
|
|
- dcmd -= req->req.actual;
|
|
|
- ep->dma_fixup = 0;
|
|
|
-
|
|
|
- /* no-descriptor mode can be simple for bulk-in, iso-in, iso-out */
|
|
|
- DCSR(ep->dma) = DCSR_NODESC;
|
|
|
- if (is_in) {
|
|
|
- DSADR(ep->dma) = buf;
|
|
|
- DTADR(ep->dma) = fifo;
|
|
|
- if (dcmd > MAX_IN_DMA)
|
|
|
- dcmd = MAX_IN_DMA;
|
|
|
- else
|
|
|
- ep->dma_fixup = (dcmd % ep->ep.maxpacket) != 0;
|
|
|
- dcmd |= DCMD_BURST32 | DCMD_WIDTH1
|
|
|
- | DCMD_FLOWTRG | DCMD_INCSRCADDR;
|
|
|
- } else {
|
|
|
-#ifdef USE_OUT_DMA
|
|
|
- DSADR(ep->dma) = fifo;
|
|
|
- DTADR(ep->dma) = buf;
|
|
|
- if (ep->bmAttributes != USB_ENDPOINT_XFER_ISOC)
|
|
|
- dcmd = ep->ep.maxpacket;
|
|
|
- dcmd |= DCMD_BURST32 | DCMD_WIDTH1
|
|
|
- | DCMD_FLOWSRC | DCMD_INCTRGADDR;
|
|
|
-#endif
|
|
|
- }
|
|
|
- DCMD(ep->dma) = dcmd;
|
|
|
- DCSR(ep->dma) = DCSR_RUN | DCSR_NODESC
|
|
|
- | (unlikely(is_in)
|
|
|
- ? DCSR_STOPIRQEN /* use dma_nodesc_handler() */
|
|
|
- : 0); /* use handle_ep() */
|
|
|
-}
|
|
|
-
|
|
|
-static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req)
|
|
|
-{
|
|
|
- int is_in = ep->bEndpointAddress & USB_DIR_IN;
|
|
|
-
|
|
|
- if (is_in) {
|
|
|
- /* unaligned tx buffers and zlps only work with PIO */
|
|
|
- if ((req->req.dma & 0x0f) != 0
|
|
|
- || unlikely((req->req.length - req->req.actual)
|
|
|
- == 0)) {
|
|
|
- pio_irq_enable(ep->bEndpointAddress);
|
|
|
- if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0)
|
|
|
- (void) write_fifo(ep, req);
|
|
|
- } else {
|
|
|
- start_dma_nodesc(ep, req, USB_DIR_IN);
|
|
|
- }
|
|
|
- } else {
|
|
|
- if ((req->req.length - req->req.actual) < ep->ep.maxpacket) {
|
|
|
- DMSG("%s short dma read...\n", ep->ep.name);
|
|
|
- /* we're always set up for pio out */
|
|
|
- read_fifo (ep, req);
|
|
|
- } else {
|
|
|
- *ep->reg_udccs = UDCCS_BO_DME
|
|
|
- | (*ep->reg_udccs & UDCCS_BO_FST);
|
|
|
- start_dma_nodesc(ep, req, USB_DIR_OUT);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static void cancel_dma(struct pxa2xx_ep *ep)
|
|
|
-{
|
|
|
- struct pxa2xx_request *req;
|
|
|
- u32 tmp;
|
|
|
-
|
|
|
- if (DCSR(ep->dma) == 0 || list_empty(&ep->queue))
|
|
|
- return;
|
|
|
-
|
|
|
- DCSR(ep->dma) = 0;
|
|
|
- while ((DCSR(ep->dma) & DCSR_STOPSTATE) == 0)
|
|
|
- cpu_relax();
|
|
|
-
|
|
|
- req = list_entry(ep->queue.next, struct pxa2xx_request, queue);
|
|
|
- tmp = DCMD(ep->dma) & DCMD_LENGTH;
|
|
|
- req->req.actual = req->req.length - (tmp & DCMD_LENGTH);
|
|
|
-
|
|
|
- /* the last tx packet may be incomplete, so flush the fifo.
|
|
|
- * FIXME correct req.actual if we can
|
|
|
- */
|
|
|
- if (ep->bEndpointAddress & USB_DIR_IN)
|
|
|
- *ep->reg_udccs = UDCCS_BI_FTF;
|
|
|
-}
|
|
|
-
|
|
|
-/* dma channel stopped ... normal tx end (IN), or on error (IN/OUT) */
|
|
|
-static void dma_nodesc_handler(int dmach, void *_ep)
|
|
|
-{
|
|
|
- struct pxa2xx_ep *ep = _ep;
|
|
|
- struct pxa2xx_request *req;
|
|
|
- u32 tmp, completed;
|
|
|
-
|
|
|
- local_irq_disable();
|
|
|
-
|
|
|
- req = list_entry(ep->queue.next, struct pxa2xx_request, queue);
|
|
|
-
|
|
|
- ep->dma_irqs++;
|
|
|
- ep->dev->stats.irqs++;
|
|
|
- HEX_DISPLAY(ep->dev->stats.irqs);
|
|
|
-
|
|
|
- /* ack/clear */
|
|
|
- tmp = DCSR(ep->dma);
|
|
|
- DCSR(ep->dma) = tmp;
|
|
|
- if ((tmp & DCSR_STOPSTATE) == 0
|
|
|
- || (DDADR(ep->dma) & DDADR_STOP) != 0) {
|
|
|
- DBG(DBG_VERBOSE, "%s, dcsr %08x ddadr %08x\n",
|
|
|
- ep->ep.name, DCSR(ep->dma), DDADR(ep->dma));
|
|
|
- goto done;
|
|
|
- }
|
|
|
- DCSR(ep->dma) = 0; /* clear DCSR_STOPSTATE */
|
|
|
-
|
|
|
- /* update transfer status */
|
|
|
- completed = tmp & DCSR_BUSERR;
|
|
|
- if (ep->bEndpointAddress & USB_DIR_IN)
|
|
|
- tmp = DSADR(ep->dma);
|
|
|
- else
|
|
|
- tmp = DTADR(ep->dma);
|
|
|
- req->req.actual = tmp - req->req.dma;
|
|
|
-
|
|
|
- /* FIXME seems we sometimes see partial transfers... */
|
|
|
-
|
|
|
- if (unlikely(completed != 0))
|
|
|
- req->req.status = -EIO;
|
|
|
- else if (req->req.actual) {
|
|
|
- /* these registers have zeroes in low bits; they miscount
|
|
|
- * some (end-of-transfer) short packets: tx 14 as tx 12
|
|
|
- */
|
|
|
- if (ep->dma_fixup)
|
|
|
- req->req.actual = min(req->req.actual + 3,
|
|
|
- req->req.length);
|
|
|
-
|
|
|
- tmp = (req->req.length - req->req.actual);
|
|
|
- completed = (tmp == 0);
|
|
|
- if (completed && (ep->bEndpointAddress & USB_DIR_IN)) {
|
|
|
-
|
|
|
- /* maybe validate final short packet ... */
|
|
|
- if ((req->req.actual % ep->ep.maxpacket) != 0)
|
|
|
- *ep->reg_udccs = UDCCS_BI_TSP/*|UDCCS_BI_TPC*/;
|
|
|
-
|
|
|
- /* ... or zlp, using pio fallback */
|
|
|
- else if (ep->bmAttributes == USB_ENDPOINT_XFER_BULK
|
|
|
- && req->req.zero) {
|
|
|
- DMSG("%s zlp terminate ...\n", ep->ep.name);
|
|
|
- completed = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (likely(completed)) {
|
|
|
- done(ep, req, 0);
|
|
|
-
|
|
|
- /* maybe re-activate after completion */
|
|
|
- if (ep->stopped || list_empty(&ep->queue))
|
|
|
- goto done;
|
|
|
- req = list_entry(ep->queue.next, struct pxa2xx_request, queue);
|
|
|
- }
|
|
|
- kick_dma(ep, req);
|
|
|
-done:
|
|
|
- local_irq_enable();
|
|
|
-}
|
|
|
-
|
|
|
-#endif
|
|
|
-
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
static int
|
|
@@ -941,19 +698,8 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|
|
(ep->desc->wMaxPacketSize)))
|
|
|
return -EMSGSIZE;
|
|
|
|
|
|
-#ifdef USE_DMA
|
|
|
- // FIXME caller may already have done the dma mapping
|
|
|
- if (ep->dma >= 0) {
|
|
|
- _req->dma = dma_map_single(dev->dev,
|
|
|
- _req->buf, _req->length,
|
|
|
- ((ep->bEndpointAddress & USB_DIR_IN) != 0)
|
|
|
- ? DMA_TO_DEVICE
|
|
|
- : DMA_FROM_DEVICE);
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n",
|
|
|
- _ep->name, _req, _req->length, _req->buf);
|
|
|
+ _ep->name, _req, _req->length, _req->buf);
|
|
|
|
|
|
local_irq_save(flags);
|
|
|
|
|
@@ -1001,11 +747,6 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|
|
local_irq_restore (flags);
|
|
|
return -EL2HLT;
|
|
|
}
|
|
|
-#ifdef USE_DMA
|
|
|
- /* either start dma or prime pio pump */
|
|
|
- } else if (ep->dma >= 0) {
|
|
|
- kick_dma(ep, req);
|
|
|
-#endif
|
|
|
/* can the FIFO can satisfy the request immediately? */
|
|
|
} else if ((ep->bEndpointAddress & USB_DIR_IN) != 0) {
|
|
|
if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0
|
|
@@ -1016,7 +757,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|
|
req = NULL;
|
|
|
}
|
|
|
|
|
|
- if (likely (req && ep->desc) && ep->dma < 0)
|
|
|
+ if (likely (req && ep->desc))
|
|
|
pio_irq_enable(ep->bEndpointAddress);
|
|
|
}
|
|
|
|
|
@@ -1037,10 +778,6 @@ static void nuke(struct pxa2xx_ep *ep, int status)
|
|
|
struct pxa2xx_request *req;
|
|
|
|
|
|
/* called with irqs blocked */
|
|
|
-#ifdef USE_DMA
|
|
|
- if (ep->dma >= 0 && !ep->stopped)
|
|
|
- cancel_dma(ep);
|
|
|
-#endif
|
|
|
while (!list_empty(&ep->queue)) {
|
|
|
req = list_entry(ep->queue.next,
|
|
|
struct pxa2xx_request,
|
|
@@ -1075,19 +812,7 @@ static int pxa2xx_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
-#ifdef USE_DMA
|
|
|
- if (ep->dma >= 0 && ep->queue.next == &req->queue && !ep->stopped) {
|
|
|
- cancel_dma(ep);
|
|
|
- done(ep, req, -ECONNRESET);
|
|
|
- /* restart i/o */
|
|
|
- if (!list_empty(&ep->queue)) {
|
|
|
- req = list_entry(ep->queue.next,
|
|
|
- struct pxa2xx_request, queue);
|
|
|
- kick_dma(ep, req);
|
|
|
- }
|
|
|
- } else
|
|
|
-#endif
|
|
|
- done(ep, req, -ECONNRESET);
|
|
|
+ done(ep, req, -ECONNRESET);
|
|
|
|
|
|
local_irq_restore(flags);
|
|
|
return 0;
|
|
@@ -1324,7 +1049,7 @@ udc_proc_read(char *page, char **start, off_t off, int count,
|
|
|
/* basic device status */
|
|
|
t = scnprintf(next, size, DRIVER_DESC "\n"
|
|
|
"%s version: %s\nGadget driver: %s\nHost %s\n\n",
|
|
|
- driver_name, DRIVER_VERSION SIZE_STR DMASTR,
|
|
|
+ driver_name, DRIVER_VERSION SIZE_STR "(pio)",
|
|
|
dev->driver ? dev->driver->driver.name : "(none)",
|
|
|
is_vbus_present() ? "full speed" : "disconnected");
|
|
|
size -= t;
|
|
@@ -1389,7 +1114,6 @@ udc_proc_read(char *page, char **start, off_t off, int count,
|
|
|
for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) {
|
|
|
struct pxa2xx_ep *ep = &dev->ep [i];
|
|
|
struct pxa2xx_request *req;
|
|
|
- int t;
|
|
|
|
|
|
if (i != 0) {
|
|
|
const struct usb_endpoint_descriptor *d;
|
|
@@ -1399,10 +1123,9 @@ udc_proc_read(char *page, char **start, off_t off, int count,
|
|
|
continue;
|
|
|
tmp = *dev->ep [i].reg_udccs;
|
|
|
t = scnprintf(next, size,
|
|
|
- "%s max %d %s udccs %02x irqs %lu/%lu\n",
|
|
|
+ "%s max %d %s udccs %02x irqs %lu\n",
|
|
|
ep->ep.name, le16_to_cpu (d->wMaxPacketSize),
|
|
|
- (ep->dma >= 0) ? "dma" : "pio", tmp,
|
|
|
- ep->pio_irqs, ep->dma_irqs);
|
|
|
+ "pio", tmp, ep->pio_irqs);
|
|
|
/* TODO translate all five groups of udccs bits! */
|
|
|
|
|
|
} else /* ep0 should only have one transfer queued */
|
|
@@ -1422,19 +1145,7 @@ udc_proc_read(char *page, char **start, off_t off, int count,
|
|
|
continue;
|
|
|
}
|
|
|
list_for_each_entry(req, &ep->queue, queue) {
|
|
|
-#ifdef USE_DMA
|
|
|
- if (ep->dma >= 0 && req->queue.prev == &ep->queue)
|
|
|
- t = scnprintf(next, size,
|
|
|
- "\treq %p len %d/%d "
|
|
|
- "buf %p (dma%d dcmd %08x)\n",
|
|
|
- &req->req, req->req.actual,
|
|
|
- req->req.length, req->req.buf,
|
|
|
- ep->dma, DCMD(ep->dma)
|
|
|
- // low 13 bits == bytes-to-go
|
|
|
- );
|
|
|
- else
|
|
|
-#endif
|
|
|
- t = scnprintf(next, size,
|
|
|
+ t = scnprintf(next, size,
|
|
|
"\treq %p len %d/%d buf %p\n",
|
|
|
&req->req, req->req.actual,
|
|
|
req->req.length, req->req.buf);
|
|
@@ -1487,7 +1198,6 @@ static void udc_disable(struct pxa2xx_udc *dev)
|
|
|
|
|
|
ep0_idle (dev);
|
|
|
dev->gadget.speed = USB_SPEED_UNKNOWN;
|
|
|
- LED_CONNECTED_OFF;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1513,7 +1223,7 @@ static void udc_reinit(struct pxa2xx_udc *dev)
|
|
|
ep->desc = NULL;
|
|
|
ep->stopped = 0;
|
|
|
INIT_LIST_HEAD (&ep->queue);
|
|
|
- ep->pio_irqs = ep->dma_irqs = 0;
|
|
|
+ ep->pio_irqs = 0;
|
|
|
}
|
|
|
|
|
|
/* the rest was statically initialized, and is read-only */
|
|
@@ -1665,7 +1375,6 @@ stop_activity(struct pxa2xx_udc *dev, struct usb_gadget_driver *driver)
|
|
|
del_timer_sync(&dev->timer);
|
|
|
|
|
|
/* report disconnect; the driver is already quiesced */
|
|
|
- LED_CONNECTED_OFF;
|
|
|
if (driver)
|
|
|
driver->disconnect(&dev->gadget);
|
|
|
|
|
@@ -1714,16 +1423,13 @@ lubbock_vbus_irq(int irq, void *_dev)
|
|
|
int vbus;
|
|
|
|
|
|
dev->stats.irqs++;
|
|
|
- HEX_DISPLAY(dev->stats.irqs);
|
|
|
switch (irq) {
|
|
|
case LUBBOCK_USB_IRQ:
|
|
|
- LED_CONNECTED_ON;
|
|
|
vbus = 1;
|
|
|
disable_irq(LUBBOCK_USB_IRQ);
|
|
|
enable_irq(LUBBOCK_USB_DISC_IRQ);
|
|
|
break;
|
|
|
case LUBBOCK_USB_DISC_IRQ:
|
|
|
- LED_CONNECTED_OFF;
|
|
|
vbus = 0;
|
|
|
disable_irq(LUBBOCK_USB_DISC_IRQ);
|
|
|
enable_irq(LUBBOCK_USB_IRQ);
|
|
@@ -2039,18 +1745,6 @@ static void handle_ep(struct pxa2xx_ep *ep)
|
|
|
|
|
|
/* fifos can hold packets, ready for reading... */
|
|
|
if (likely(req)) {
|
|
|
-#ifdef USE_OUT_DMA
|
|
|
-// TODO didn't yet debug out-dma. this approach assumes
|
|
|
-// the worst about short packets and RPC; it might be better.
|
|
|
-
|
|
|
- if (likely(ep->dma >= 0)) {
|
|
|
- if (!(udccs & UDCCS_BO_RSP)) {
|
|
|
- *ep->reg_udccs = UDCCS_BO_RPC;
|
|
|
- ep->dma_irqs++;
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-#endif
|
|
|
completed = read_fifo(ep, req);
|
|
|
} else
|
|
|
pio_irq_disable (ep->bEndpointAddress);
|
|
@@ -2073,7 +1767,6 @@ pxa2xx_udc_irq(int irq, void *_dev)
|
|
|
int handled;
|
|
|
|
|
|
dev->stats.irqs++;
|
|
|
- HEX_DISPLAY(dev->stats.irqs);
|
|
|
do {
|
|
|
u32 udccr = UDCCR;
|
|
|
|
|
@@ -2124,7 +1817,6 @@ pxa2xx_udc_irq(int irq, void *_dev)
|
|
|
} else {
|
|
|
DBG(DBG_VERBOSE, "USB reset end\n");
|
|
|
dev->gadget.speed = USB_SPEED_FULL;
|
|
|
- LED_CONNECTED_ON;
|
|
|
memset(&dev->stats, 0, sizeof dev->stats);
|
|
|
/* driver and endpoints are still reset */
|
|
|
}
|
|
@@ -2216,7 +1908,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
|
|
.reg_udccs = &UDCCS1,
|
|
|
.reg_uddr = &UDDR1,
|
|
|
- drcmr (25)
|
|
|
},
|
|
|
.ep[2] = {
|
|
|
.ep = {
|
|
@@ -2231,7 +1922,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.reg_udccs = &UDCCS2,
|
|
|
.reg_ubcr = &UBCR2,
|
|
|
.reg_uddr = &UDDR2,
|
|
|
- drcmr (26)
|
|
|
},
|
|
|
#ifndef CONFIG_USB_PXA2XX_SMALL
|
|
|
.ep[3] = {
|
|
@@ -2246,7 +1936,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.bmAttributes = USB_ENDPOINT_XFER_ISOC,
|
|
|
.reg_udccs = &UDCCS3,
|
|
|
.reg_uddr = &UDDR3,
|
|
|
- drcmr (27)
|
|
|
},
|
|
|
.ep[4] = {
|
|
|
.ep = {
|
|
@@ -2261,7 +1950,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.reg_udccs = &UDCCS4,
|
|
|
.reg_ubcr = &UBCR4,
|
|
|
.reg_uddr = &UDDR4,
|
|
|
- drcmr (28)
|
|
|
},
|
|
|
.ep[5] = {
|
|
|
.ep = {
|
|
@@ -2290,7 +1978,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
|
|
.reg_udccs = &UDCCS6,
|
|
|
.reg_uddr = &UDDR6,
|
|
|
- drcmr (30)
|
|
|
},
|
|
|
.ep[7] = {
|
|
|
.ep = {
|
|
@@ -2305,7 +1992,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.reg_udccs = &UDCCS7,
|
|
|
.reg_ubcr = &UBCR7,
|
|
|
.reg_uddr = &UDDR7,
|
|
|
- drcmr (31)
|
|
|
},
|
|
|
.ep[8] = {
|
|
|
.ep = {
|
|
@@ -2319,7 +2005,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.bmAttributes = USB_ENDPOINT_XFER_ISOC,
|
|
|
.reg_udccs = &UDCCS8,
|
|
|
.reg_uddr = &UDDR8,
|
|
|
- drcmr (32)
|
|
|
},
|
|
|
.ep[9] = {
|
|
|
.ep = {
|
|
@@ -2334,7 +2019,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.reg_udccs = &UDCCS9,
|
|
|
.reg_ubcr = &UBCR9,
|
|
|
.reg_uddr = &UDDR9,
|
|
|
- drcmr (33)
|
|
|
},
|
|
|
.ep[10] = {
|
|
|
.ep = {
|
|
@@ -2363,7 +2047,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
|
|
.reg_udccs = &UDCCS11,
|
|
|
.reg_uddr = &UDDR11,
|
|
|
- drcmr (35)
|
|
|
},
|
|
|
.ep[12] = {
|
|
|
.ep = {
|
|
@@ -2378,7 +2061,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.reg_udccs = &UDCCS12,
|
|
|
.reg_ubcr = &UBCR12,
|
|
|
.reg_uddr = &UDDR12,
|
|
|
- drcmr (36)
|
|
|
},
|
|
|
.ep[13] = {
|
|
|
.ep = {
|
|
@@ -2392,7 +2074,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.bmAttributes = USB_ENDPOINT_XFER_ISOC,
|
|
|
.reg_udccs = &UDCCS13,
|
|
|
.reg_uddr = &UDDR13,
|
|
|
- drcmr (37)
|
|
|
},
|
|
|
.ep[14] = {
|
|
|
.ep = {
|
|
@@ -2407,7 +2088,6 @@ static struct pxa2xx_udc memory = {
|
|
|
.reg_udccs = &UDCCS14,
|
|
|
.reg_ubcr = &UBCR14,
|
|
|
.reg_uddr = &UDDR14,
|
|
|
- drcmr (38)
|
|
|
},
|
|
|
.ep[15] = {
|
|
|
.ep = {
|
|
@@ -2465,7 +2145,7 @@ static struct pxa2xx_udc memory = {
|
|
|
static int __init pxa2xx_udc_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
struct pxa2xx_udc *dev = &memory;
|
|
|
- int retval, out_dma = 1, vbus_irq, irq;
|
|
|
+ int retval, vbus_irq, irq;
|
|
|
u32 chiprev;
|
|
|
|
|
|
/* insist on Intel/ARM/XScale */
|
|
@@ -2488,7 +2168,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
|
|
|
case PXA250_B2: case PXA210_B2:
|
|
|
case PXA250_B1: case PXA210_B1:
|
|
|
case PXA250_B0: case PXA210_B0:
|
|
|
- out_dma = 0;
|
|
|
+ /* OUT-DMA is broken ... */
|
|
|
/* fall through */
|
|
|
case PXA250_C0: case PXA210_C0:
|
|
|
break;
|
|
@@ -2497,11 +2177,9 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
|
|
|
case IXP425_B0:
|
|
|
case IXP465_AD:
|
|
|
dev->has_cfr = 1;
|
|
|
- out_dma = 0;
|
|
|
break;
|
|
|
#endif
|
|
|
default:
|
|
|
- out_dma = 0;
|
|
|
printk(KERN_ERR "%s: unrecognized processor: %08x\n",
|
|
|
driver_name, chiprev);
|
|
|
/* iop3xx, ixp4xx, ... */
|
|
@@ -2512,25 +2190,11 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
|
|
|
if (irq < 0)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- pr_debug("%s: IRQ %d%s%s%s\n", driver_name, irq,
|
|
|
+ pr_debug("%s: IRQ %d%s%s\n", driver_name, irq,
|
|
|
dev->has_cfr ? "" : " (!cfr)",
|
|
|
- out_dma ? "" : " (broken dma-out)",
|
|
|
- SIZE_STR DMASTR
|
|
|
+ SIZE_STR "(pio)"
|
|
|
);
|
|
|
|
|
|
-#ifdef USE_DMA
|
|
|
-#ifndef USE_OUT_DMA
|
|
|
- out_dma = 0;
|
|
|
-#endif
|
|
|
- /* pxa 250 erratum 130 prevents using OUT dma (fixed C0) */
|
|
|
- if (!out_dma) {
|
|
|
- DMSG("disabled OUT dma\n");
|
|
|
- dev->ep[ 2].reg_drcmr = dev->ep[ 4].reg_drcmr = 0;
|
|
|
- dev->ep[ 7].reg_drcmr = dev->ep[ 9].reg_drcmr = 0;
|
|
|
- dev->ep[12].reg_drcmr = dev->ep[14].reg_drcmr = 0;
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
/* other non-static parts of init */
|
|
|
dev->dev = &pdev->dev;
|
|
|
dev->mach = pdev->dev.platform_data;
|
|
@@ -2619,11 +2283,6 @@ lubbock_fail0:
|
|
|
free_irq(LUBBOCK_USB_DISC_IRQ, dev);
|
|
|
goto lubbock_fail0;
|
|
|
}
|
|
|
-#ifdef DEBUG
|
|
|
- /* with U-Boot (but not BLOB), hex is off by default */
|
|
|
- HEX_DISPLAY(dev->stats.irqs);
|
|
|
- LUB_DISC_BLNK_LED &= 0xff;
|
|
|
-#endif
|
|
|
} else
|
|
|
#endif
|
|
|
if (vbus_irq) {
|