aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorAnton Tikhomirov <av.tikhomirov@samsung.com>2011-04-21 04:06:41 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-02 20:00:26 -0400
commit9c39ddc60ee9eb70569d1658e512cfa232b9dd16 (patch)
tree01ef19e58780ec7403f465cd5b3a3e5a7e7c5cb6 /drivers/usb/gadget
parent26ab3d0ce95c270b1ca491d6970aa14852d8e5a3 (diff)
USB: s3c-hsotg: Fix stall condition processing
The following should be done for requests after endpoint stall condition is cleared: 1) 'in progress' request (if any) should be completed since Tx FIFO was flushed; 2) next request from queue (if any) should be started. This commit does that. Additionally set/clear stall condition code is fixed. Signed-off-by: Anton Tikhomirov <av.tikhomirov@samsung.com> Reviewed-by: Kyoungil Kim<ki0351.kim@samsung.com> Cc: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c142
1 files changed, 111 insertions, 31 deletions
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index cbbc33677fd..6be424e2cc6 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -679,6 +679,14 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
679 __func__, readl(hsotg->regs + epctrl_reg), index, 679 __func__, readl(hsotg->regs + epctrl_reg), index,
680 hs_ep->dir_in ? "in" : "out"); 680 hs_ep->dir_in ? "in" : "out");
681 681
682 /* If endpoint is stalled, we will restart request later */
683 ctrl = readl(hsotg->regs + epctrl_reg);
684
685 if (ctrl & S3C_DxEPCTL_Stall) {
686 dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index);
687 return;
688 }
689
682 length = ureq->length - ureq->actual; 690 length = ureq->length - ureq->actual;
683 691
684 if (0) 692 if (0)
@@ -731,18 +739,6 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
731 /* write size / packets */ 739 /* write size / packets */
732 writel(epsize, hsotg->regs + epsize_reg); 740 writel(epsize, hsotg->regs + epsize_reg);
733 741
734 ctrl = readl(hsotg->regs + epctrl_reg);
735
736 if (ctrl & S3C_DxEPCTL_Stall) {
737 dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index);
738
739 /* not sure what we can do here, if it is EP0 then we should
740 * get this cleared once the endpoint has transmitted the
741 * STALL packet, otherwise it needs to be cleared by the
742 * host.
743 */
744 }
745
746 if (using_dma(hsotg)) { 742 if (using_dma(hsotg)) {
747 unsigned int dma_reg; 743 unsigned int dma_reg;
748 744
@@ -1048,6 +1044,20 @@ static int s3c_hsotg_process_req_status(struct s3c_hsotg *hsotg,
1048static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value); 1044static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value);
1049 1045
1050/** 1046/**
1047 * get_ep_head - return the first request on the endpoint
1048 * @hs_ep: The controller endpoint to get
1049 *
1050 * Get the first request on the endpoint.
1051 */
1052static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep)
1053{
1054 if (list_empty(&hs_ep->queue))
1055 return NULL;
1056
1057 return list_first_entry(&hs_ep->queue, struct s3c_hsotg_req, queue);
1058}
1059
1060/**
1051 * s3c_hsotg_process_req_featire - process request {SET,CLEAR}_FEATURE 1061 * s3c_hsotg_process_req_featire - process request {SET,CLEAR}_FEATURE
1052 * @hsotg: The device state 1062 * @hsotg: The device state
1053 * @ctrl: USB control request 1063 * @ctrl: USB control request
@@ -1056,6 +1066,8 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
1056 struct usb_ctrlrequest *ctrl) 1066 struct usb_ctrlrequest *ctrl)
1057{ 1067{
1058 struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; 1068 struct s3c_hsotg_ep *ep0 = &hsotg->eps[0];
1069 struct s3c_hsotg_req *hs_req;
1070 bool restart;
1059 bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); 1071 bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE);
1060 struct s3c_hsotg_ep *ep; 1072 struct s3c_hsotg_ep *ep;
1061 int ret; 1073 int ret;
@@ -1081,6 +1093,29 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
1081 "%s: failed to send reply\n", __func__); 1093 "%s: failed to send reply\n", __func__);
1082 return ret; 1094 return ret;
1083 } 1095 }
1096
1097 if (!set) {
1098 /*
1099 * If we have request in progress,
1100 * then complete it
1101 */
1102 if (ep->req) {
1103 hs_req = ep->req;
1104 ep->req = NULL;
1105 list_del_init(&hs_req->queue);
1106 hs_req->req.complete(&ep->ep,
1107 &hs_req->req);
1108 }
1109
1110 /* If we have pending request, then start it */
1111 restart = !list_empty(&ep->queue);
1112 if (restart) {
1113 hs_req = get_ep_head(ep);
1114 s3c_hsotg_start_req(hsotg, ep,
1115 hs_req, false);
1116 }
1117 }
1118
1084 break; 1119 break;
1085 1120
1086 default: 1121 default:
@@ -1248,20 +1283,6 @@ static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg)
1248} 1283}
1249 1284
1250/** 1285/**
1251 * get_ep_head - return the first request on the endpoint
1252 * @hs_ep: The controller endpoint to get
1253 *
1254 * Get the first request on the endpoint.
1255*/
1256static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep)
1257{
1258 if (list_empty(&hs_ep->queue))
1259 return NULL;
1260
1261 return list_first_entry(&hs_ep->queue, struct s3c_hsotg_req, queue);
1262}
1263
1264/**
1265 * s3c_hsotg_complete_request - complete a request given to us 1286 * s3c_hsotg_complete_request - complete a request given to us
1266 * @hsotg: The device state. 1287 * @hsotg: The device state.
1267 * @hs_ep: The endpoint the request was on. 1288 * @hs_ep: The endpoint the request was on.
@@ -1684,6 +1705,37 @@ bad_mps:
1684 dev_err(hsotg->dev, "ep%d: bad mps of %d\n", ep, mps); 1705 dev_err(hsotg->dev, "ep%d: bad mps of %d\n", ep, mps);
1685} 1706}
1686 1707
1708/**
1709 * s3c_hsotg_txfifo_flush - flush Tx FIFO
1710 * @hsotg: The driver state
1711 * @idx: The index for the endpoint (0..15)
1712 */
1713static void s3c_hsotg_txfifo_flush(struct s3c_hsotg *hsotg, unsigned int idx)
1714{
1715 int timeout;
1716 int val;
1717
1718 writel(S3C_GRSTCTL_TxFNum(idx) | S3C_GRSTCTL_TxFFlsh,
1719 hsotg->regs + S3C_GRSTCTL);
1720
1721 /* wait until the fifo is flushed */
1722 timeout = 100;
1723
1724 while (1) {
1725 val = readl(hsotg->regs + S3C_GRSTCTL);
1726
1727 if ((val & (S3C_GRSTCTL_TxFFlsh)) == 0)
1728 break;
1729
1730 if (--timeout == 0) {
1731 dev_err(hsotg->dev,
1732 "%s: timeout flushing fifo (GRSTCTL=%08x)\n",
1733 __func__, val);
1734 }
1735
1736 udelay(1);
1737 }
1738}
1687 1739
1688/** 1740/**
1689 * s3c_hsotg_trytx - check to see if anything needs transmitting 1741 * s3c_hsotg_trytx - check to see if anything needs transmitting
@@ -1806,9 +1858,24 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
1806 } 1858 }
1807 } 1859 }
1808 1860
1809 if (ints & S3C_DxEPINT_EPDisbld) 1861 if (ints & S3C_DxEPINT_EPDisbld) {
1810 dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__); 1862 dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__);
1811 1863
1864 if (dir_in) {
1865 int epctl = readl(hsotg->regs + epctl_reg);
1866
1867 s3c_hsotg_txfifo_flush(hsotg, idx);
1868
1869 if ((epctl & S3C_DxEPCTL_Stall) &&
1870 (epctl & S3C_DxEPCTL_EPType_Bulk)) {
1871 int dctl = readl(hsotg->regs + S3C_DCTL);
1872
1873 dctl |= S3C_DCTL_CGNPInNAK;
1874 writel(dctl, hsotg->regs + S3C_DCTL);
1875 }
1876 }
1877 }
1878
1812 if (ints & S3C_DxEPINT_AHBErr) 1879 if (ints & S3C_DxEPINT_AHBErr)
1813 dev_dbg(hsotg->dev, "%s: AHBErr\n", __func__); 1880 dev_dbg(hsotg->dev, "%s: AHBErr\n", __func__);
1814 1881
@@ -2406,6 +2473,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
2406 unsigned long irqflags; 2473 unsigned long irqflags;
2407 u32 epreg; 2474 u32 epreg;
2408 u32 epctl; 2475 u32 epctl;
2476 u32 xfertype;
2409 2477
2410 dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); 2478 dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value);
2411 2479
@@ -2416,10 +2484,17 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
2416 epreg = S3C_DIEPCTL(index); 2484 epreg = S3C_DIEPCTL(index);
2417 epctl = readl(hs->regs + epreg); 2485 epctl = readl(hs->regs + epreg);
2418 2486
2419 if (value) 2487 if (value) {
2420 epctl |= S3C_DxEPCTL_Stall; 2488 epctl |= S3C_DxEPCTL_Stall + S3C_DxEPCTL_SNAK;
2421 else 2489 if (epctl & S3C_DxEPCTL_EPEna)
2490 epctl |= S3C_DxEPCTL_EPDis;
2491 } else {
2422 epctl &= ~S3C_DxEPCTL_Stall; 2492 epctl &= ~S3C_DxEPCTL_Stall;
2493 xfertype = epctl & S3C_DxEPCTL_EPType_MASK;
2494 if (xfertype == S3C_DxEPCTL_EPType_Bulk ||
2495 xfertype == S3C_DxEPCTL_EPType_Intterupt)
2496 epctl |= S3C_DxEPCTL_SetD0PID;
2497 }
2423 2498
2424 writel(epctl, hs->regs + epreg); 2499 writel(epctl, hs->regs + epreg);
2425 2500
@@ -2428,8 +2503,13 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
2428 2503
2429 if (value) 2504 if (value)
2430 epctl |= S3C_DxEPCTL_Stall; 2505 epctl |= S3C_DxEPCTL_Stall;
2431 else 2506 else {
2432 epctl &= ~S3C_DxEPCTL_Stall; 2507 epctl &= ~S3C_DxEPCTL_Stall;
2508 xfertype = epctl & S3C_DxEPCTL_EPType_MASK;
2509 if (xfertype == S3C_DxEPCTL_EPType_Bulk ||
2510 xfertype == S3C_DxEPCTL_EPType_Intterupt)
2511 epctl |= S3C_DxEPCTL_SetD0PID;
2512 }
2433 2513
2434 writel(epctl, hs->regs + epreg); 2514 writel(epctl, hs->regs + epreg);
2435 2515