diff mbox series

[6/8] usb: cdns3: gadget: need to handle sg case for WA2 case

Message ID 20200901084454.28649-7-peter.chen@nxp.com
State Superseded
Headers show
Series usb: cdns3: improve the sg use case | expand

Commit Message

Peter Chen Sept. 1, 2020, 8:44 a.m. UTC
Add sg support for WA2 case.

Signed-off-by: Peter Chen <peter.chen@nxp.com>
---
 drivers/usb/cdns3/gadget.c | 44 +++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 13 deletions(-)

Comments

Felipe Balbi Sept. 8, 2020, 6:29 a.m. UTC | #1
Hi,

Peter Chen <peter.chen@nxp.com> writes:
> Add sg support for WA2 case.

what's WA2? Care to spell it out?

> Signed-off-by: Peter Chen <peter.chen@nxp.com>
> ---
>  drivers/usb/cdns3/gadget.c | 44 +++++++++++++++++++++++++++-----------
>  1 file changed, 31 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
> index 6cb44c354f40..1fd36bc5c6db 100644
> --- a/drivers/usb/cdns3/gadget.c
> +++ b/drivers/usb/cdns3/gadget.c
> @@ -462,6 +462,36 @@ static int cdns3_start_all_request(struct cdns3_device *priv_dev,
>  		(reg) |= EP_STS_EN_DESCMISEN; \
>  	} } while (0)
>  
> +static void __cdns3_descmiss_copy_data(struct usb_request *request,
> +	struct usb_request *descmiss_req)
> +{
> +	int length = request->actual + descmiss_req->actual;
> +	struct scatterlist *s = request->sg;
> +
> +	if (!s) {
> +		if (length <= request->length) {
> +			memcpy(&((u8 *)request->buf)[request->actual],

			memcpy(request->buf + request->actual, ... ?

> +			       descmiss_req->buf,
> +			       descmiss_req->actual);
> +			request->actual = length;
> +		} else {
> +			/* It should never occures */
                                           ^^^^^^^
                                           occur

ps: famous last words :-)

> +			request->status = -ENOMEM;

this is not documented as a valid status for usb request
completion. Who's treating this -ENOMEM case? Which gadgets have you
tested with this change?
diff mbox series

Patch

diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
index 6cb44c354f40..1fd36bc5c6db 100644
--- a/drivers/usb/cdns3/gadget.c
+++ b/drivers/usb/cdns3/gadget.c
@@ -462,6 +462,36 @@  static int cdns3_start_all_request(struct cdns3_device *priv_dev,
 		(reg) |= EP_STS_EN_DESCMISEN; \
 	} } while (0)
 
+static void __cdns3_descmiss_copy_data(struct usb_request *request,
+	struct usb_request *descmiss_req)
+{
+	int length = request->actual + descmiss_req->actual;
+	struct scatterlist *s = request->sg;
+
+	if (!s) {
+		if (length <= request->length) {
+			memcpy(&((u8 *)request->buf)[request->actual],
+			       descmiss_req->buf,
+			       descmiss_req->actual);
+			request->actual = length;
+		} else {
+			/* It should never occures */
+			request->status = -ENOMEM;
+		}
+	} else {
+		if (length <= sg_dma_len(s)) {
+			void *p = phys_to_virt(sg_dma_address(s));
+
+			memcpy(&((u8 *)p)[request->actual],
+				descmiss_req->buf,
+				descmiss_req->actual);
+			request->actual = length;
+		} else {
+			request->status = -ENOMEM;
+		}
+	}
+}
+
 /**
  * cdns3_wa2_descmiss_copy_data copy data from internal requests to
  * request queued by class driver.
@@ -488,21 +518,9 @@  static void cdns3_wa2_descmiss_copy_data(struct cdns3_endpoint *priv_ep,
 
 		chunk_end = descmiss_priv_req->flags & REQUEST_INTERNAL_CH;
 		length = request->actual + descmiss_req->actual;
-
 		request->status = descmiss_req->status;
-
-		if (length <= request->length) {
-			memcpy(&((u8 *)request->buf)[request->actual],
-			       descmiss_req->buf,
-			       descmiss_req->actual);
-			request->actual = length;
-		} else {
-			/* It should never occures */
-			request->status = -ENOMEM;
-		}
-
+		__cdns3_descmiss_copy_data(request, descmiss_req);
 		list_del_init(&descmiss_priv_req->list);
-
 		kfree(descmiss_req->buf);
 		cdns3_gadget_ep_free_request(&priv_ep->endpoint, descmiss_req);
 		--priv_ep->wa2_counter;