Merge tag 'pci-v3.18-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaa...
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc2 / hcd_intr.c
index 47b9eb5389b468d4710263bdd9a8d052cbba635c..551ba878b003c99a469a4cfa2421c2a1151ad184 100644 (file)
@@ -465,12 +465,8 @@ static int dwc2_update_urb_state(struct dwc2_hsotg *hsotg,
        /* Non DWORD-aligned buffer case handling */
        if (chan->align_buf && xfer_length && chan->ep_is_in) {
                dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__);
-               dma_sync_single_for_cpu(hsotg->dev, urb->dma, urb->length,
-                                       DMA_FROM_DEVICE);
                memcpy(urb->buf + urb->actual_length, chan->qh->dw_align_buf,
                       xfer_length);
-               dma_sync_single_for_device(hsotg->dev, urb->dma, urb->length,
-                                          DMA_FROM_DEVICE);
        }
 
        dev_vdbg(hsotg->dev, "urb->actual_length=%d xfer_length=%d\n",
@@ -560,14 +556,9 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state(
                    chan->ep_is_in) {
                        dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n",
                                 __func__);
-                       dma_sync_single_for_cpu(hsotg->dev, urb->dma,
-                                               urb->length, DMA_FROM_DEVICE);
                        memcpy(urb->buf + frame_desc->offset +
                               qtd->isoc_split_offset, chan->qh->dw_align_buf,
                               frame_desc->actual_length);
-                       dma_sync_single_for_device(hsotg->dev, urb->dma,
-                                                  urb->length,
-                                                  DMA_FROM_DEVICE);
                }
                break;
        case DWC2_HC_XFER_FRAME_OVERRUN:
@@ -594,14 +585,9 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state(
                    chan->ep_is_in) {
                        dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n",
                                 __func__);
-                       dma_sync_single_for_cpu(hsotg->dev, urb->dma,
-                                               urb->length, DMA_FROM_DEVICE);
                        memcpy(urb->buf + frame_desc->offset +
                               qtd->isoc_split_offset, chan->qh->dw_align_buf,
                               frame_desc->actual_length);
-                       dma_sync_single_for_device(hsotg->dev, urb->dma,
-                                                  urb->length,
-                                                  DMA_FROM_DEVICE);
                }
 
                /* Skip whole frame */
@@ -937,12 +923,8 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg *hsotg,
 
        if (chan->align_buf) {
                dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__);
-               dma_sync_single_for_cpu(hsotg->dev, qtd->urb->dma,
-                                       qtd->urb->length, DMA_FROM_DEVICE);
                memcpy(qtd->urb->buf + frame_desc->offset +
                       qtd->isoc_split_offset, chan->qh->dw_align_buf, len);
-               dma_sync_single_for_device(hsotg->dev, qtd->urb->dma,
-                                          qtd->urb->length, DMA_FROM_DEVICE);
        }
 
        qtd->isoc_split_offset += len;
@@ -1170,12 +1152,8 @@ static void dwc2_update_urb_state_abn(struct dwc2_hsotg *hsotg,
        /* Non DWORD-aligned buffer case handling */
        if (chan->align_buf && xfer_length && chan->ep_is_in) {
                dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__);
-               dma_sync_single_for_cpu(hsotg->dev, urb->dma, urb->length,
-                                       DMA_FROM_DEVICE);
                memcpy(urb->buf + urb->actual_length, chan->qh->dw_align_buf,
                       xfer_length);
-               dma_sync_single_for_device(hsotg->dev, urb->dma, urb->length,
-                                          DMA_FROM_DEVICE);
        }
 
        urb->actual_length += xfer_length;
@@ -1890,12 +1868,20 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
                                        "hcint 0x%08x, intsts 0x%08x\n",
                                        chan->hcint,
                                        readl(hsotg->regs + GINTSTS));
+                               goto error;
                        }
                }
        } else {
                dev_info(hsotg->dev,
                         "NYET/NAK/ACK/other in non-error case, 0x%08x\n",
                         chan->hcint);
+error:
+               /* Failthrough: use 3-strikes rule */
+               qtd->error_count++;
+               dwc2_update_urb_state_abn(hsotg, chan, chnum, qtd->urb,
+                                         qtd, DWC2_HC_XFER_XACT_ERR);
+               dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd);
+               dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_XACT_ERR);
        }
 }