summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/s3c_udc_otg_xfer_dma.c')
-rw-r--r--drivers/usb/gadget/s3c_udc_otg_xfer_dma.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c b/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c
index 7c7176b..06dfeed 100644
--- a/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c
+++ b/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c
@@ -110,8 +110,7 @@ static int setdma_rx(struct s3c_ep *ep, struct s3c_request *req)
ctrl = readl(&reg->out_endp[ep_num].doepctl);
- writel(the_controller->dma_addr[ep_index(ep)+1],
- &reg->out_endp[ep_num].doepdma);
+ writel((unsigned int) ep->dma_buf, &reg->out_endp[ep_num].doepdma);
writel(DOEPT_SIZ_PKT_CNT(pktcnt) | DOEPT_SIZ_XFER_SIZE(length),
&reg->out_endp[ep_num].doeptsiz);
writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, &reg->out_endp[ep_num].doepctl);
@@ -134,7 +133,6 @@ int setdma_tx(struct s3c_ep *ep, struct s3c_request *req)
u32 *buf, ctrl = 0;
u32 length, pktcnt;
u32 ep_num = ep_index(ep);
- u32 *p = the_controller->dma_buf[ep_index(ep)+1];
buf = req->req.buf + req->req.actual;
length = req->req.length - req->req.actual;
@@ -144,10 +142,10 @@ int setdma_tx(struct s3c_ep *ep, struct s3c_request *req)
ep->len = length;
ep->dma_buf = buf;
- memcpy(p, ep->dma_buf, length);
- flush_dcache_range((unsigned long) p ,
- (unsigned long) p + DMA_BUFFER_SIZE);
+ flush_dcache_range((unsigned long) ep->dma_buf,
+ (unsigned long) ep->dma_buf +
+ ROUND(ep->len, CONFIG_SYS_CACHELINE_SIZE));
if (length == 0)
pktcnt = 1;
@@ -160,8 +158,7 @@ int setdma_tx(struct s3c_ep *ep, struct s3c_request *req)
while (readl(&reg->grstctl) & TX_FIFO_FLUSH)
;
- writel(the_controller->dma_addr[ep_index(ep)+1],
- &reg->in_endp[ep_num].diepdma);
+ writel((unsigned long) ep->dma_buf, &reg->in_endp[ep_num].diepdma);
writel(DIEPT_SIZ_PKT_CNT(pktcnt) | DIEPT_SIZ_XFER_SIZE(length),
&reg->in_endp[ep_num].dieptsiz);
@@ -194,7 +191,6 @@ static void complete_rx(struct s3c_udc *dev, u8 ep_num)
struct s3c_ep *ep = &dev->ep[ep_num];
struct s3c_request *req = NULL;
u32 ep_tsr = 0, xfer_size = 0, is_short = 0;
- u32 *p = the_controller->dma_buf[ep_index(ep)+1];
if (list_empty(&ep->queue)) {
debug_cond(DEBUG_OUT_EP != 0,
@@ -214,10 +210,23 @@ static void complete_rx(struct s3c_udc *dev, u8 ep_num)
xfer_size = ep->len - xfer_size;
- invalidate_dcache_range((unsigned long) p,
- (unsigned long) p + DMA_BUFFER_SIZE);
-
- memcpy(ep->dma_buf, p, ep->len);
+ /*
+ * NOTE:
+ *
+ * Please be careful with proper buffer allocation for USB request,
+ * which needs to be aligned to CONFIG_SYS_CACHELINE_SIZE, not only
+ * with starting address, but also its size shall be a cache line
+ * multiplication.
+ *
+ * This will prevent from corruption of data allocated immediatelly
+ * before or after the buffer.
+ *
+ * For armv7, the cache_v7.c provides proper code to emit "ERROR"
+ * message to warn users.
+ */
+ invalidate_dcache_range((unsigned long) ep->dma_buf,
+ (unsigned long) ep->dma_buf +
+ ROUND(xfer_size, CONFIG_SYS_CACHELINE_SIZE));
req->req.actual += min(xfer_size, req->req.length - req->req.actual);
is_short = (xfer_size < ep->ep.maxpacket);
@@ -711,19 +720,14 @@ static int write_fifo_ep0(struct s3c_ep *ep, struct s3c_request *req)
int s3c_fifo_read(struct s3c_ep *ep, u32 *cp, int max)
{
- u32 bytes;
-
- bytes = sizeof(struct usb_ctrlrequest);
-
- invalidate_dcache_range((unsigned long) ep->dev->dma_buf[ep_index(ep)],
- (unsigned long) ep->dev->dma_buf[ep_index(ep)]
- + DMA_BUFFER_SIZE);
+ invalidate_dcache_range((unsigned long)cp, (unsigned long)cp +
+ ROUND(max, CONFIG_SYS_CACHELINE_SIZE));
debug_cond(DEBUG_EP0 != 0,
- "%s: bytes=%d, ep_index=%d %p\n", __func__,
- bytes, ep_index(ep), ep->dev->dma_buf[ep_index(ep)]);
+ "%s: bytes=%d, ep_index=%d 0x%p\n", __func__,
+ max, ep_index(ep), cp);
- return bytes;
+ return max;
}
/**
@@ -855,14 +859,12 @@ static int s3c_ep0_write(struct s3c_udc *dev)
return 1;
}
-u16 g_status;
-
int s3c_udc_get_status(struct s3c_udc *dev,
struct usb_ctrlrequest *crq)
{
u8 ep_num = crq->wIndex & 0x7F;
+ u16 g_status = 0;
u32 ep_ctrl;
- u32 *p = the_controller->dma_buf[1];
debug_cond(DEBUG_SETUP != 0,
"%s: *** USB_REQ_GET_STATUS\n", __func__);
@@ -900,12 +902,13 @@ int s3c_udc_get_status(struct s3c_udc *dev,
return 1;
}
- memcpy(p, &g_status, sizeof(g_status));
+ memcpy(usb_ctrl, &g_status, sizeof(g_status));
- flush_dcache_range((unsigned long) p,
- (unsigned long) p + DMA_BUFFER_SIZE);
+ flush_dcache_range((unsigned long) usb_ctrl,
+ (unsigned long) usb_ctrl +
+ ROUND(sizeof(g_status), CONFIG_SYS_CACHELINE_SIZE));
- writel(the_controller->dma_addr[1], &reg->in_endp[EP0_CON].diepdma);
+ writel(usb_ctrl_dma_addr, &reg->in_endp[EP0_CON].diepdma);
writel(DIEPT_SIZ_PKT_CNT(1) | DIEPT_SIZ_XFER_SIZE(2),
&reg->in_endp[EP0_CON].dieptsiz);