aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-12-22 17:05:01 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-12-22 17:05:19 -0500
commitee0db58ade2c60342a7d648f375d0a4107c39527 (patch)
treeb5e2fce1dcfa281fd15427d109d5f1226de9c8c7 /drivers/usb/dwc3
parenteea9fc7ddda80d3221fd79430b841a2cb315bb9f (diff)
parenteeb720fb21d61dfc3aac780e721150998ef603af (diff)
Merge branch 'for-gadget/next' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
* 'for-gadget/next' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb: (24 commits) usb: dwc3: gadget: add support for SG lists usb: dwc3: gadget: don't force 'LST' always usb: dwc3: gadget: don't return anything on prepare trbs usb: dwc3: gadget: re-factor dwc3_prepare_trbs() usb: gadget: introduce support for sg lists usb: renesas: pipe: convert a long if into a XOR operation usb: gadget: remove useless depends on Kconfig usb: gadget: s3c-hsudc: remove the_controller global usb: gadget: s3c-hsudc: use release_mem_region instead of release_resource usb: gadget: s3c-hsudc: Add regulator handling usb: gadget: s3c-hsudc: use udc_start and udc_stop functions usb: gadget: s3c-hsudc: move device registration to probe usb: gadget: s3c-hsudc: add missing otg_put_transceiver in probe usb: gadget: s3c-hsudc: add __devinit to probe function usb: gadget: s3c-hsudc: move platform_data struct to global header USB: EHCI: Add Marvell Host Controller driver USB: OTG: add Marvell usb OTG driver support usb: gadget: mv_udc: drop ARCH dependency usb: gadget: mv_udc: fix bug in ep_dequeue usb: gadget: enlarge maxburst bit width. ...
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/gadget.c239
1 files changed, 160 insertions, 79 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 7367e5cb9831..4c6bedad51fd 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -65,6 +65,22 @@ void dwc3_map_buffer_to_dma(struct dwc3_request *req)
65 return; 65 return;
66 } 66 }
67 67
68 if (req->request.num_sgs) {
69 int mapped;
70
71 mapped = dma_map_sg(dwc->dev, req->request.sg,
72 req->request.num_sgs,
73 req->direction ? DMA_TO_DEVICE
74 : DMA_FROM_DEVICE);
75 if (mapped < 0) {
76 dev_err(dwc->dev, "failed to map SGs\n");
77 return;
78 }
79
80 req->request.num_mapped_sgs = mapped;
81 return;
82 }
83
68 if (req->request.dma == DMA_ADDR_INVALID) { 84 if (req->request.dma == DMA_ADDR_INVALID) {
69 req->request.dma = dma_map_single(dwc->dev, req->request.buf, 85 req->request.dma = dma_map_single(dwc->dev, req->request.buf,
70 req->request.length, req->direction 86 req->request.length, req->direction
@@ -82,6 +98,17 @@ void dwc3_unmap_buffer_from_dma(struct dwc3_request *req)
82 return; 98 return;
83 } 99 }
84 100
101 if (req->request.num_mapped_sgs) {
102 req->request.dma = DMA_ADDR_INVALID;
103 dma_unmap_sg(dwc->dev, req->request.sg,
104 req->request.num_sgs,
105 req->direction ? DMA_TO_DEVICE
106 : DMA_FROM_DEVICE);
107
108 req->request.num_mapped_sgs = 0;
109 return;
110 }
111
85 if (req->mapped) { 112 if (req->mapped) {
86 dma_unmap_single(dwc->dev, req->request.dma, 113 dma_unmap_single(dwc->dev, req->request.dma,
87 req->request.length, req->direction 114 req->request.length, req->direction
@@ -97,7 +124,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
97 struct dwc3 *dwc = dep->dwc; 124 struct dwc3 *dwc = dep->dwc;
98 125
99 if (req->queued) { 126 if (req->queued) {
100 dep->busy_slot++; 127 if (req->request.num_mapped_sgs)
128 dep->busy_slot += req->request.num_mapped_sgs;
129 else
130 dep->busy_slot++;
131
101 /* 132 /*
102 * Skip LINK TRB. We can't use req->trb and check for 133 * Skip LINK TRB. We can't use req->trb and check for
103 * DWC3_TRBCTL_LINK_TRB because it points the TRB we just 134 * DWC3_TRBCTL_LINK_TRB because it points the TRB we just
@@ -108,6 +139,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
108 dep->busy_slot++; 139 dep->busy_slot++;
109 } 140 }
110 list_del(&req->list); 141 list_del(&req->list);
142 req->trb = NULL;
111 143
112 if (req->request.status == -EINPROGRESS) 144 if (req->request.status == -EINPROGRESS)
113 req->request.status = status; 145 req->request.status = status;
@@ -544,6 +576,85 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
544 kfree(req); 576 kfree(req);
545} 577}
546 578
579/**
580 * dwc3_prepare_one_trb - setup one TRB from one request
581 * @dep: endpoint for which this request is prepared
582 * @req: dwc3_request pointer
583 */
584static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
585 struct dwc3_request *req, dma_addr_t dma,
586 unsigned length, unsigned last, unsigned chain)
587{
588 struct dwc3 *dwc = dep->dwc;
589 struct dwc3_trb_hw *trb_hw;
590 struct dwc3_trb trb;
591
592 unsigned int cur_slot;
593
594 dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n",
595 dep->name, req, (unsigned long long) dma,
596 length, last ? " last" : "",
597 chain ? " chain" : "");
598
599 trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
600 cur_slot = dep->free_slot;
601 dep->free_slot++;
602
603 /* Skip the LINK-TRB on ISOC */
604 if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
605 usb_endpoint_xfer_isoc(dep->desc))
606 return;
607
608 memset(&trb, 0, sizeof(trb));
609 if (!req->trb) {
610 dwc3_gadget_move_request_queued(req);
611 req->trb = trb_hw;
612 req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw);
613 }
614
615 if (usb_endpoint_xfer_isoc(dep->desc)) {
616 trb.isp_imi = true;
617 trb.csp = true;
618 } else {
619 trb.chn = chain;
620 trb.lst = last;
621 }
622
623 if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
624 trb.sid_sofn = req->request.stream_id;
625
626 switch (usb_endpoint_type(dep->desc)) {
627 case USB_ENDPOINT_XFER_CONTROL:
628 trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
629 break;
630
631 case USB_ENDPOINT_XFER_ISOC:
632 trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
633
634 /* IOC every DWC3_TRB_NUM / 4 so we can refill */
635 if (!(cur_slot % (DWC3_TRB_NUM / 4)))
636 trb.ioc = last;
637 break;
638
639 case USB_ENDPOINT_XFER_BULK:
640 case USB_ENDPOINT_XFER_INT:
641 trb.trbctl = DWC3_TRBCTL_NORMAL;
642 break;
643 default:
644 /*
645 * This is only possible with faulty memory because we
646 * checked it already :)
647 */
648 BUG();
649 }
650
651 trb.length = length;
652 trb.bplh = dma;
653 trb.hwo = true;
654
655 dwc3_trb_to_hw(&trb, trb_hw);
656}
657
547/* 658/*
548 * dwc3_prepare_trbs - setup TRBs from requests 659 * dwc3_prepare_trbs - setup TRBs from requests
549 * @dep: endpoint for which requests are being prepared 660 * @dep: endpoint for which requests are being prepared
@@ -553,18 +664,17 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
553 * transfers. The functions returns once there are not more TRBs available or 664 * transfers. The functions returns once there are not more TRBs available or
554 * it run out of requests. 665 * it run out of requests.
555 */ 666 */
556static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep, 667static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
557 bool starting)
558{ 668{
559 struct dwc3_request *req, *n, *ret = NULL; 669 struct dwc3_request *req, *n;
560 struct dwc3_trb_hw *trb_hw;
561 struct dwc3_trb trb;
562 u32 trbs_left; 670 u32 trbs_left;
671 unsigned int last_one = 0;
563 672
564 BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM); 673 BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
565 674
566 /* the first request must not be queued */ 675 /* the first request must not be queued */
567 trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK; 676 trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;
677
568 /* 678 /*
569 * if busy & slot are equal than it is either full or empty. If we are 679 * if busy & slot are equal than it is either full or empty. If we are
570 * starting to proceed requests then we are empty. Otherwise we ar 680 * starting to proceed requests then we are empty. Otherwise we ar
@@ -572,7 +682,7 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
572 */ 682 */
573 if (!trbs_left) { 683 if (!trbs_left) {
574 if (!starting) 684 if (!starting)
575 return NULL; 685 return;
576 trbs_left = DWC3_TRB_NUM; 686 trbs_left = DWC3_TRB_NUM;
577 /* 687 /*
578 * In case we start from scratch, we queue the ISOC requests 688 * In case we start from scratch, we queue the ISOC requests
@@ -596,94 +706,62 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
596 706
597 /* The last TRB is a link TRB, not used for xfer */ 707 /* The last TRB is a link TRB, not used for xfer */
598 if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->desc)) 708 if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->desc))
599 return NULL; 709 return;
600 710
601 list_for_each_entry_safe(req, n, &dep->request_list, list) { 711 list_for_each_entry_safe(req, n, &dep->request_list, list) {
602 unsigned int last_one = 0; 712 unsigned length;
603 unsigned int cur_slot; 713 dma_addr_t dma;
604 714
605 trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; 715 if (req->request.num_mapped_sgs > 0) {
606 cur_slot = dep->free_slot; 716 struct usb_request *request = &req->request;
607 dep->free_slot++; 717 struct scatterlist *sg = request->sg;
718 struct scatterlist *s;
719 int i;
608 720
609 /* Skip the LINK-TRB on ISOC */ 721 for_each_sg(sg, s, request->num_mapped_sgs, i) {
610 if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && 722 unsigned chain = true;
611 usb_endpoint_xfer_isoc(dep->desc))
612 continue;
613 723
614 dwc3_gadget_move_request_queued(req); 724 length = sg_dma_len(s);
615 memset(&trb, 0, sizeof(trb)); 725 dma = sg_dma_address(s);
616 trbs_left--;
617 726
618 /* Is our TRB pool empty? */ 727 if (i == (request->num_mapped_sgs - 1)
619 if (!trbs_left) 728 || sg_is_last(s)) {
620 last_one = 1; 729 last_one = true;
621 /* Is this the last request? */ 730 chain = false;
622 if (list_empty(&dep->request_list)) 731 }
623 last_one = 1;
624 732
625 /* 733 trbs_left--;
626 * FIXME we shouldn't need to set LST bit always but we are 734 if (!trbs_left)
627 * facing some weird problem with the Hardware where it doesn't 735 last_one = true;
628 * complete even though it has been previously started.
629 *
630 * While we're debugging the problem, as a workaround to
631 * multiple TRBs handling, use only one TRB at a time.
632 */
633 last_one = 1;
634 736
635 req->trb = trb_hw; 737 if (last_one)
636 if (!ret) 738 chain = false;
637 ret = req;
638 739
639 trb.bplh = req->request.dma; 740 dwc3_prepare_one_trb(dep, req, dma, length,
741 last_one, chain);
640 742
641 if (usb_endpoint_xfer_isoc(dep->desc)) { 743 if (last_one)
642 trb.isp_imi = true; 744 break;
643 trb.csp = true; 745 }
644 } else { 746 } else {
645 trb.lst = last_one; 747 dma = req->request.dma;
646 } 748 length = req->request.length;
749 trbs_left--;
647 750
648 if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable) 751 if (!trbs_left)
649 trb.sid_sofn = req->request.stream_id; 752 last_one = 1;
650 753
651 switch (usb_endpoint_type(dep->desc)) { 754 /* Is this the last request? */
652 case USB_ENDPOINT_XFER_CONTROL: 755 if (list_is_last(&req->list, &dep->request_list))
653 trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP; 756 last_one = 1;
654 break;
655 757
656 case USB_ENDPOINT_XFER_ISOC: 758 dwc3_prepare_one_trb(dep, req, dma, length,
657 trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; 759 last_one, false);
658 760
659 /* IOC every DWC3_TRB_NUM / 4 so we can refill */ 761 if (last_one)
660 if (!(cur_slot % (DWC3_TRB_NUM / 4))) 762 break;
661 trb.ioc = last_one;
662 break;
663
664 case USB_ENDPOINT_XFER_BULK:
665 case USB_ENDPOINT_XFER_INT:
666 trb.trbctl = DWC3_TRBCTL_NORMAL;
667 break;
668 default:
669 /*
670 * This is only possible with faulty memory because we
671 * checked it already :)
672 */
673 BUG();
674 } 763 }
675
676 trb.length = req->request.length;
677 trb.hwo = true;
678
679 dwc3_trb_to_hw(&trb, trb_hw);
680 req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw);
681
682 if (last_one)
683 break;
684 } 764 }
685
686 return ret;
687} 765}
688 766
689static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, 767static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
@@ -712,11 +790,13 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
712 /* req points to the first request which will be sent */ 790 /* req points to the first request which will be sent */
713 req = next_request(&dep->req_queued); 791 req = next_request(&dep->req_queued);
714 } else { 792 } else {
793 dwc3_prepare_trbs(dep, start_new);
794
715 /* 795 /*
716 * req points to the first request where HWO changed 796 * req points to the first request where HWO changed
717 * from 0 to 1 797 * from 0 to 1
718 */ 798 */
719 req = dwc3_prepare_trbs(dep, start_new); 799 req = next_request(&dep->req_queued);
720 } 800 }
721 if (!req) { 801 if (!req) {
722 dep->flags |= DWC3_EP_PENDING_REQUEST; 802 dep->flags |= DWC3_EP_PENDING_REQUEST;
@@ -2093,6 +2173,7 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
2093 dwc->gadget.max_speed = USB_SPEED_SUPER; 2173 dwc->gadget.max_speed = USB_SPEED_SUPER;
2094 dwc->gadget.speed = USB_SPEED_UNKNOWN; 2174 dwc->gadget.speed = USB_SPEED_UNKNOWN;
2095 dwc->gadget.dev.parent = dwc->dev; 2175 dwc->gadget.dev.parent = dwc->dev;
2176 dwc->gadget.sg_supported = true;
2096 2177
2097 dma_set_coherent_mask(&dwc->gadget.dev, dwc->dev->coherent_dma_mask); 2178 dma_set_coherent_mask(&dwc->gadget.dev, dwc->dev->coherent_dma_mask);
2098 2179