aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2011-08-27 15:07:53 -0400
committerFelipe Balbi <balbi@ti.com>2011-09-09 06:02:04 -0400
commit5812b1c236774ea580b6af39411eb4f7297d7623 (patch)
treef25e68599057b95f7f0302922a17566b1e67e303 /drivers/usb/dwc3
parentdc137f01aca23ceb196945130a960e2a01b95890 (diff)
usb: dwc3: add a bounce buffer for control endpoints
This core cannot handle OUT transfers which aren't aligned to wMaxPacketSize, but that can happen at least on control endpoint with the USB Audio Class. This patch adds a bounce buffer to be used on the case of a non-aligned ep0out request is queued. Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/core.h6
-rw-r--r--drivers/usb/dwc3/gadget.c29
2 files changed, 28 insertions, 7 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 08d8ff6b943a..8688b5a809d2 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -505,11 +505,13 @@ static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat)
505 * struct dwc3 - representation of our controller 505 * struct dwc3 - representation of our controller
506 * @ctrl_req: usb control request which is used for ep0 506 * @ctrl_req: usb control request which is used for ep0
507 * @ep0_trb: trb which is used for the ctrl_req 507 * @ep0_trb: trb which is used for the ctrl_req
508 * @ep0_bounce: bounce buffer for ep0
508 * @setup_buf: used while precessing STD USB requests 509 * @setup_buf: used while precessing STD USB requests
509 * @ctrl_req_addr: dma address of ctrl_req 510 * @ctrl_req_addr: dma address of ctrl_req
510 * @ep0_trb: dma address of ep0_trb 511 * @ep0_trb: dma address of ep0_trb
511 * @ep0_usb_req: dummy req used while handling STD USB requests 512 * @ep0_usb_req: dummy req used while handling STD USB requests
512 * @setup_buf_addr: dma address of setup_buf 513 * @setup_buf_addr: dma address of setup_buf
514 * @ep0_bounce_addr: dma address of ep0_bounce
513 * @lock: for synchronizing 515 * @lock: for synchronizing
514 * @dev: pointer to our struct device 516 * @dev: pointer to our struct device
515 * @event_buffer_list: a list of event buffers 517 * @event_buffer_list: a list of event buffers
@@ -522,6 +524,7 @@ static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat)
522 * @is_selfpowered: true when we are selfpowered 524 * @is_selfpowered: true when we are selfpowered
523 * @three_stage_setup: set if we perform a three phase setup 525 * @three_stage_setup: set if we perform a three phase setup
524 * @ep0_status_pending: ep0 status response without a req is pending 526 * @ep0_status_pending: ep0 status response without a req is pending
527 * @ep0_bounced: true when we used bounce buffer
525 * @ep0state: state of endpoint zero 528 * @ep0state: state of endpoint zero
526 * @link_state: link state 529 * @link_state: link state
527 * @speed: device speed (super, high, full, low) 530 * @speed: device speed (super, high, full, low)
@@ -531,10 +534,12 @@ static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat)
531struct dwc3 { 534struct dwc3 {
532 struct usb_ctrlrequest *ctrl_req; 535 struct usb_ctrlrequest *ctrl_req;
533 struct dwc3_trb_hw *ep0_trb; 536 struct dwc3_trb_hw *ep0_trb;
537 void *ep0_bounce;
534 u8 *setup_buf; 538 u8 *setup_buf;
535 dma_addr_t ctrl_req_addr; 539 dma_addr_t ctrl_req_addr;
536 dma_addr_t ep0_trb_addr; 540 dma_addr_t ep0_trb_addr;
537 dma_addr_t setup_buf_addr; 541 dma_addr_t setup_buf_addr;
542 dma_addr_t ep0_bounce_addr;
538 struct usb_request ep0_usb_req; 543 struct usb_request ep0_usb_req;
539 /* device lock */ 544 /* device lock */
540 spinlock_t lock; 545 spinlock_t lock;
@@ -564,6 +569,7 @@ struct dwc3 {
564 unsigned is_selfpowered:1; 569 unsigned is_selfpowered:1;
565 unsigned three_stage_setup:1; 570 unsigned three_stage_setup:1;
566 unsigned ep0_status_pending:1; 571 unsigned ep0_status_pending:1;
572 unsigned ep0_bounced:1;
567 573
568 enum dwc3_ep0_state ep0state; 574 enum dwc3_ep0_state ep0state;
569 enum dwc3_link_state link_state; 575 enum dwc3_link_state link_state;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 56ccd97000a6..569473bcfb50 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1957,6 +1957,14 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
1957 goto err2; 1957 goto err2;
1958 } 1958 }
1959 1959
1960 dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
1961 512, &dwc->ep0_bounce_addr, GFP_KERNEL);
1962 if (!dwc->ep0_bounce) {
1963 dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n");
1964 ret = -ENOMEM;
1965 goto err3;
1966 }
1967
1960 dev_set_name(&dwc->gadget.dev, "gadget"); 1968 dev_set_name(&dwc->gadget.dev, "gadget");
1961 1969
1962 dwc->gadget.ops = &dwc3_gadget_ops; 1970 dwc->gadget.ops = &dwc3_gadget_ops;
@@ -1978,7 +1986,7 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
1978 1986
1979 ret = dwc3_gadget_init_endpoints(dwc); 1987 ret = dwc3_gadget_init_endpoints(dwc);
1980 if (ret) 1988 if (ret)
1981 goto err3; 1989 goto err4;
1982 1990
1983 irq = platform_get_irq(to_platform_device(dwc->dev), 0); 1991 irq = platform_get_irq(to_platform_device(dwc->dev), 0);
1984 1992
@@ -1987,7 +1995,7 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
1987 if (ret) { 1995 if (ret) {
1988 dev_err(dwc->dev, "failed to request irq #%d --> %d\n", 1996 dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
1989 irq, ret); 1997 irq, ret);
1990 goto err4; 1998 goto err5;
1991 } 1999 }
1992 2000
1993 /* Enable all but Start and End of Frame IRQs */ 2001 /* Enable all but Start and End of Frame IRQs */
@@ -2006,27 +2014,31 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
2006 if (ret) { 2014 if (ret) {
2007 dev_err(dwc->dev, "failed to register gadget device\n"); 2015 dev_err(dwc->dev, "failed to register gadget device\n");
2008 put_device(&dwc->gadget.dev); 2016 put_device(&dwc->gadget.dev);
2009 goto err5; 2017 goto err6;
2010 } 2018 }
2011 2019
2012 ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); 2020 ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);
2013 if (ret) { 2021 if (ret) {
2014 dev_err(dwc->dev, "failed to register udc\n"); 2022 dev_err(dwc->dev, "failed to register udc\n");
2015 goto err6; 2023 goto err7;
2016 } 2024 }
2017 2025
2018 return 0; 2026 return 0;
2019 2027
2020err6: 2028err7:
2021 device_unregister(&dwc->gadget.dev); 2029 device_unregister(&dwc->gadget.dev);
2022 2030
2023err5: 2031err6:
2024 dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); 2032 dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
2025 free_irq(irq, dwc); 2033 free_irq(irq, dwc);
2026 2034
2027err4: 2035err5:
2028 dwc3_gadget_free_endpoints(dwc); 2036 dwc3_gadget_free_endpoints(dwc);
2029 2037
2038err4:
2039 dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
2040 dwc->ep0_bounce_addr);
2041
2030err3: 2042err3:
2031 dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2, 2043 dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
2032 dwc->setup_buf, dwc->setup_buf_addr); 2044 dwc->setup_buf, dwc->setup_buf_addr);
@@ -2059,6 +2071,9 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
2059 2071
2060 dwc3_gadget_free_endpoints(dwc); 2072 dwc3_gadget_free_endpoints(dwc);
2061 2073
2074 dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
2075 dwc->ep0_bounce_addr);
2076
2062 dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2, 2077 dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
2063 dwc->setup_buf, dwc->setup_buf_addr); 2078 dwc->setup_buf, dwc->setup_buf_addr);
2064 2079