[RESEND PATCH 08/16] usb: musb: Fix receiving of bigger buffers

Lukasz Majewski lukma at denx.de
Sat Feb 6 15:15:16 CET 2021


On Fri,  5 Feb 2021 20:12:04 +0100
Pali Rohár <pali at kernel.org> wrote:

> If musb_peri_rx_ep() was called to processed received HW buffer but
> U-Boot cannot read it yet (e.g. because U-Boot SW buffer is full)
> then interrupt was marked as processed but HW buffer stayed
> unprocessed.
> 
> U-Boot tried to process this buffer again when it receive interrupt
> again, but it can receive it only when sender (host) send a new data.
> As sender (host) is not going to send a new data until U-Boot process
> current data this issue caused a deadlock in case sender (host) is
> emitting data faster than U-Boot can process it.
> 
> Reading musb intrrx register automatically clears this register and
> mark interrupt as processed. So to prevent marking interrupt in
> U-Boot as processed and a new variable pending_intrrx which would
> contain unprocessed bits of intrrx register.
> 
> And as a second step, every time when musb_peri_rx_ep() is called and
> there are waiting data to be processed (signaled by
> MUSB_RXCSR_RXPKTRDY) either acknowledge sender (via
> musb_peri_rx_ack()) that whole HW buffer was processed or set
> corresponding bit in pending_intrrx that HW buffer was not fully
> processed yet and next iteration is required after U-Boot allocate
> space for reading HW buffer.
> 
> This patch fixes receiving large usb buffers, e.g. file transfer via
> Kermit protocol implemented by 'loadb' U-Boot command over usbtty
> serial console.

Reviewed-by: Lukasz Majewski <lukma at denx.de>

> 
> Signed-off-by: Pali Rohár <pali at kernel.org>
> ---
>  drivers/usb/musb/musb_udc.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c
> index 28719cc3f6..7c74422623 100644
> --- a/drivers/usb/musb/musb_udc.c
> +++ b/drivers/usb/musb/musb_udc.c
> @@ -104,6 +104,8 @@ struct usb_endpoint_instance *ep0_endpoint;
>  static struct usb_device_instance *udc_device;
>  static int enabled;
>  
> +u16 pending_intrrx;
> +
>  #ifdef MUSB_DEBUG
>  static void musb_db_regs(void)
>  {
> @@ -664,7 +666,10 @@ static void musb_peri_rx_ep(unsigned int ep)
>  				/* The common musb fifo reader */
>  				read_fifo(ep, length, data);
>  
> -				musb_peri_rx_ack(ep);
> +				if (length == peri_rxcount)
> +					musb_peri_rx_ack(ep);
> +				else
> +					pending_intrrx |= (1 << ep);
>  
>  				/*
>  				 * urb's actual_length is updated in
> @@ -677,18 +682,24 @@ static void musb_peri_rx_ep(unsigned int ep)
>  					serial_printf("ERROR : %s %d
> no space " "in rcv buffer\n",
>  						      __PRETTY_FUNCTION__,
> ep); +
> +				pending_intrrx |= (1 << ep);
>  			}
>  		} else {
>  			if (debug_level > 0)
>  				serial_printf("ERROR : %s %d problem
> with " "endpoint\n",
>  					      __PRETTY_FUNCTION__,
> ep); +
> +			pending_intrrx |= (1 << ep);
>  		}
>  
>  	} else {
>  		if (debug_level > 0)
>  			serial_printf("ERROR : %s %d with nothing to
> do\n", __PRETTY_FUNCTION__, ep);
> +
> +		musb_peri_rx_ack(ep);
>  	}
>  }
>  
> @@ -770,6 +781,9 @@ void udc_irq(void)
>  			intrrx = readw(&musbr->intrrx);
>  			intrtx = readw(&musbr->intrtx);
>  
> +			intrrx |= pending_intrrx;
> +			pending_intrrx = 0;
> +
>  			if (intrrx)
>  				musb_peri_rx(intrrx);
>  




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210206/21a623c9/attachment.sig>


More information about the U-Boot mailing list