summaryrefslogtreecommitdiff
path: root/drivers/usb/cdns3/gadget.h
diff options
context:
space:
mode:
authorPawel Laszczak <pawell@cadence.com>2019-07-02 14:38:02 +0100
committerFelipe Balbi <felipe.balbi@linux.intel.com>2019-07-03 10:46:07 +0300
commit573aff747ee350a0541c3a24cacd92a286fb9522 (patch)
treeb7168480b4b7254e7ca20650c39d4c373803c70e /drivers/usb/cdns3/gadget.h
parent8bc1901ca7b07d864fca11461b3875b31f949765 (diff)
downloadlinux-573aff747ee350a0541c3a24cacd92a286fb9522.tar.gz
linux-573aff747ee350a0541c3a24cacd92a286fb9522.tar.bz2
linux-573aff747ee350a0541c3a24cacd92a286fb9522.zip
usb:cdns3 Fix for stuck packets in on-chip OUT buffer.
Controller for OUT endpoints has shared on-chip buffers for all incoming packets, including ep0out. It's FIFO buffer, so packets must be handled by DMA in correct order. If the first packet in the buffer will not be handled, then the following packets directed for other endpoints and functions will be blocked. Additionally the packets directed to one endpoint can block entire on-chip buffers. In this case transfer to other endpoints also will blocked. To resolve this issue after raising the descriptor missing interrupt driver prepares internal usb_request object and use it to arm DMA transfer. The problematic situation was observed in case when endpoint has been enabled but no usb_request were queued. Driver try detects such endpoints and will use this workaround only for these endpoint. Driver use limited number of buffer. This number can be set by macro CDNS_WA2_NUM_BUFFERS. Such blocking situation was observed on ACM gadget. For this function host send OUT data packet but ACM function is not prepared for this packet. It's cause that buffer placed in on chip memory block transfer to other endpoints. Issue has been fixed for DEV_VER_V2 version of controller. Signed-off-by: Pawel Laszczak <pawell@cadence.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/cdns3/gadget.h')
-rw-r--r--drivers/usb/cdns3/gadget.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/usb/cdns3/gadget.h b/drivers/usb/cdns3/gadget.h
index 64cead1aee32..42f58048975f 100644
--- a/drivers/usb/cdns3/gadget.h
+++ b/drivers/usb/cdns3/gadget.h
@@ -1079,6 +1079,7 @@ struct cdns3_trb {
#define CDNS3_EP_ISO_SS_BURST 3
#define CDNS3_MAX_NUM_DESCMISS_BUF 32
#define CDNS3_DESCMIS_BUF_SIZE 2048 /* Bytes */
+#define CDNS3_WA2_NUM_BUFFERS 128
/*-------------------------------------------------------------------------*/
/* Used structs */
@@ -1089,11 +1090,15 @@ struct cdns3_device;
* @endpoint: usb endpoint
* @pending_req_list: list of requests queuing on transfer ring.
* @deferred_req_list: list of requests waiting for queuing on transfer ring.
+ * @wa2_descmiss_req_list: list of requests internally allocated by driver.
* @trb_pool: transfer ring - array of transaction buffers
* @trb_pool_dma: dma address of transfer ring
* @cdns3_dev: device associated with this endpoint
* @name: a human readable name e.g. ep1out
* @flags: specify the current state of endpoint
+ * @descmis_req: internal transfer object used for getting data from on-chip
+ * buffer. It can happen only if function driver doesn't send usb_request
+ * object on time.
* @dir: endpoint direction
* @num: endpoint number (1 - 15)
* @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK
@@ -1110,6 +1115,8 @@ struct cdns3_endpoint {
struct usb_ep endpoint;
struct list_head pending_req_list;
struct list_head deferred_req_list;
+ struct list_head wa2_descmiss_req_list;
+ int wa2_counter;
struct cdns3_trb *trb_pool;
dma_addr_t trb_pool_dma;
@@ -1127,8 +1134,13 @@ struct cdns3_endpoint {
#define EP_CLAIMED BIT(7)
#define EP_DEFERRED_DRDY BIT(8)
#define EP_QUIRK_ISO_OUT_EN BIT(9)
+#define EP_QUIRK_EXTRA_BUF_DET BIT(10)
+#define EP_QUIRK_EXTRA_BUF_EN BIT(11)
+#define EP_QUIRK_END_TRANSFER BIT(12)
u32 flags;
+ struct cdns3_request *descmis_req;
+
u8 dir;
u8 num;
u8 type;
@@ -1176,6 +1188,7 @@ struct cdns3_aligned_buf {
* @aligned_buf: object holds information about aligned buffer associated whit
* this endpoint
* @flags: flag specifying special usage of request
+ * @list: used by internally allocated request to add to wa2_descmiss_req_list.
*/
struct cdns3_request {
struct usb_request request;