Re: [PATCH v2] usb: gadget: eem: fix echo command packet response issue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jun 15, 2021 at 07:41:33AM +0800, Linyu Yuan wrote:
> From: Linyu Yuan <linyyuan@xxxxxxxxxxxxxx>
> 
> when receive eem echo command, it will send a response,
> but queue this response to the usb request which allocate
> from gadget device endpoint zero,
> and transmit the request to IN endpoint of eem interface.
> 
> on dwc3 gadget, it will trigger following warning in function
> __dwc3_gadget_ep_queue(),
> 
> 	if (WARN(req->dep != dep, "request %pK belongs to '%s'\n",
> 				&req->request, req->dep->name))
> 		return -EINVAL;
> 
> fix it by allocating a usb request from IN endpoint of eem interface,
> and transmit the usb request to same IN endpoint of eem interface.
> 
> Signed-off-by: Linyu Yuan <linyyuan@xxxxxxxxxxxxxx>
> ---
> 
> v2: fix mail format and expand commit message
> 
>  drivers/usb/gadget/function/f_eem.c | 44 +++++++++++++++++++++++++----
>  1 file changed, 39 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c
> index 2cd9942707b4..7de355c63189 100644
> --- a/drivers/usb/gadget/function/f_eem.c
> +++ b/drivers/usb/gadget/function/f_eem.c
> @@ -30,6 +30,11 @@ struct f_eem {
>  	u8				ctrl_id;
>  };
>  
> +struct in_context {
> +	struct sk_buff	*skb;
> +	struct usb_ep	*ep;
> +};
> +
>  static inline struct f_eem *func_to_eem(struct usb_function *f)
>  {
>  	return container_of(f, struct f_eem, port.func);
> @@ -320,9 +325,12 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
>  
>  static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req)
>  {
> -	struct sk_buff *skb = (struct sk_buff *)req->context;
> +	struct in_context *ctx = req->context;
>  
> -	dev_kfree_skb_any(skb);
> +	dev_kfree_skb_any(ctx->skb);
> +	kfree(req->buf);
> +	usb_ep_free_request(ctx->ep, req);
> +	kfree(ctx);
>  }
>  
>  /*
> @@ -410,7 +418,9 @@ static int eem_unwrap(struct gether *port,
>  		 * b15:		bmType (0 == data, 1 == command)
>  		 */
>  		if (header & BIT(15)) {
> -			struct usb_request	*req = cdev->req;
> +			struct usb_request	*req;
> +			struct in_context	*ctx;
> +			struct usb_ep		*ep;
>  			u16			bmEEMCmd;
>  
>  			/* EEM command packet format:
> @@ -439,13 +449,37 @@ static int eem_unwrap(struct gether *port,
>  				skb_trim(skb2, len);
>  				put_unaligned_le16(BIT(15) | BIT(11) | len,
>  							skb_push(skb2, 2));
> +
> +				ep = port->in_ep;
> +				req = usb_ep_alloc_request(ep, GFP_ATOMIC);
> +				if (!req)
> +					goto freeskb;
> +
> +				ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
> +				if (!ctx)
> +					goto freereq;
> +				ctx->skb = skb2;
> +				ctx->ep = ep;
> +
> +				req->buf = kmalloc(skb2->len, GFP_KERNEL);
> +				if (!req->buf)
> +					goto freectx;
> +
>  				skb_copy_bits(skb2, 0, req->buf, skb2->len);
>  				req->length = skb2->len;
>  				req->complete = eem_cmd_complete;
>  				req->zero = 1;
> -				req->context = skb2;
> -				if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC))
> +				req->context = ctx;
> +				if (usb_ep_queue(ep, req, GFP_ATOMIC)) {
>  					DBG(cdev, "echo response queue fail\n");
> +					kfree(req->buf);
> +freectx:
> +					kfree(ctx);
> +freereq:
> +					usb_ep_free_request(ep, req);
> +freeskb:
> +					dev_kfree_skb_any(skb2);

As much fun as it is jumping to the middle of a case statement, are you
sure you want to maintain this?

And you do not return an error?  Why not?  What happens then?

thanks,

greg k-h



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux