OSDN Git Service

usb: dwc2: gadget: Increase descriptors count for ISOC's
authorMinas Harutyunyan <minas.harutyunyan@synopsys.com>
Mon, 18 Mar 2019 10:24:30 +0000 (14:24 +0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 31 May 2019 13:46:10 +0000 (06:46 -0700)
[ Upstream commit 54f37f56631747075f1f9a2f0edf6ba405e3e66c ]

Some function drivers queueing more than 128 ISOC requests at a time.
To avoid "descriptor chain full" cases, increasing descriptors count
from MAX_DMA_DESC_NUM_GENERIC to MAX_DMA_DESC_NUM_HS_ISOC for ISOC's
only.

Signed-off-by: Minas Harutyunyan <hminas@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/usb/dwc2/gadget.c

index 220c0f9..03614ef 100644 (file)
@@ -675,13 +675,11 @@ static unsigned int dwc2_gadget_get_chain_limit(struct dwc2_hsotg_ep *hs_ep)
        unsigned int maxsize;
 
        if (is_isoc)
-               maxsize = hs_ep->dir_in ? DEV_DMA_ISOC_TX_NBYTES_LIMIT :
-                                          DEV_DMA_ISOC_RX_NBYTES_LIMIT;
+               maxsize = (hs_ep->dir_in ? DEV_DMA_ISOC_TX_NBYTES_LIMIT :
+                                          DEV_DMA_ISOC_RX_NBYTES_LIMIT) *
+                                          MAX_DMA_DESC_NUM_HS_ISOC;
        else
-               maxsize = DEV_DMA_NBYTES_LIMIT;
-
-       /* Above size of one descriptor was chosen, multiple it */
-       maxsize *= MAX_DMA_DESC_NUM_GENERIC;
+               maxsize = DEV_DMA_NBYTES_LIMIT * MAX_DMA_DESC_NUM_GENERIC;
 
        return maxsize;
 }
@@ -864,7 +862,7 @@ static int dwc2_gadget_fill_isoc_desc(struct dwc2_hsotg_ep *hs_ep,
 
        /* Update index of last configured entry in the chain */
        hs_ep->next_desc++;
-       if (hs_ep->next_desc >= MAX_DMA_DESC_NUM_GENERIC)
+       if (hs_ep->next_desc >= MAX_DMA_DESC_NUM_HS_ISOC)
                hs_ep->next_desc = 0;
 
        return 0;
@@ -896,7 +894,7 @@ static void dwc2_gadget_start_isoc_ddma(struct dwc2_hsotg_ep *hs_ep)
        }
 
        /* Initialize descriptor chain by Host Busy status */
-       for (i = 0; i < MAX_DMA_DESC_NUM_GENERIC; i++) {
+       for (i = 0; i < MAX_DMA_DESC_NUM_HS_ISOC; i++) {
                desc = &hs_ep->desc_list[i];
                desc->status = 0;
                desc->status |= (DEV_DMA_BUFF_STS_HBUSY
@@ -2083,7 +2081,7 @@ static void dwc2_gadget_complete_isoc_request_ddma(struct dwc2_hsotg_ep *hs_ep)
                dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
 
                hs_ep->compl_desc++;
-               if (hs_ep->compl_desc > (MAX_DMA_DESC_NUM_GENERIC - 1))
+               if (hs_ep->compl_desc > (MAX_DMA_DESC_NUM_HS_ISOC - 1))
                        hs_ep->compl_desc = 0;
                desc_sts = hs_ep->desc_list[hs_ep->compl_desc].status;
        }
@@ -3779,6 +3777,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
        unsigned int i, val, size;
        int ret = 0;
        unsigned char ep_type;
+       int desc_num;
 
        dev_dbg(hsotg->dev,
                "%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n",
@@ -3825,11 +3824,15 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
        dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n",
                __func__, epctrl, epctrl_reg);
 
+       if (using_desc_dma(hsotg) && ep_type == USB_ENDPOINT_XFER_ISOC)
+               desc_num = MAX_DMA_DESC_NUM_HS_ISOC;
+       else
+               desc_num = MAX_DMA_DESC_NUM_GENERIC;
+
        /* Allocate DMA descriptor chain for non-ctrl endpoints */
        if (using_desc_dma(hsotg) && !hs_ep->desc_list) {
                hs_ep->desc_list = dmam_alloc_coherent(hsotg->dev,
-                       MAX_DMA_DESC_NUM_GENERIC *
-                       sizeof(struct dwc2_dma_desc),
+                       desc_num * sizeof(struct dwc2_dma_desc),
                        &hs_ep->desc_list_dma, GFP_ATOMIC);
                if (!hs_ep->desc_list) {
                        ret = -ENOMEM;
@@ -3971,7 +3974,7 @@ error1:
 
 error2:
        if (ret && using_desc_dma(hsotg) && hs_ep->desc_list) {
-               dmam_free_coherent(hsotg->dev, MAX_DMA_DESC_NUM_GENERIC *
+               dmam_free_coherent(hsotg->dev, desc_num *
                        sizeof(struct dwc2_dma_desc),
                        hs_ep->desc_list, hs_ep->desc_list_dma);
                hs_ep->desc_list = NULL;