RE: [PATCH] Workaround for hardware problem in host mode for the MUSB chipset. Add missed TXPKTRDY check.

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

 



Hi Sergei,

> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index 84c1897..83f1f50 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -1511,12 +1511,14 @@ static void choose_address(struct usb_device *udev)
>  		 * bus->devnum_next. */
>  		devnum = find_next_zero_bit(bus->devmap.devicemap, 128,
>  					    bus->devnum_next);
> -		if (devnum >= 128)
> +		/* Due to Hardware bugs we need to reserve a device address
> +		 * for flushing of endpoints. */
> +		if (devnum >= 127)
>  			devnum = find_next_zero_bit(bus->devmap.devicemap,
>  						    128, 1);
> -		bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
> +		bus->devnum_next = devnum >= 126 ? 1 : devnum + 1;
>  	}
> -	if (devnum < 128) {
> +	if (devnum < 127) {

    Oh, horror...

Should be technically Ok.

> diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
> index 877d20b..b14a5ff 100644
> --- a/drivers/usb/musb/musb_host.c
> +++ b/drivers/usb/musb/musb_host.c
> @@ -106,24 +106,41 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
>  static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
>  {
>  	void __iomem	*epio = ep->regs;
> +	void __iomem	*regs = ep->musb->mregs;
>  	u16		csr;
> -	u16		lastcsr = 0;
> -	int		retries = 1000;
> +	u8		addr;
> +	int		retries = 3000; /* 3ms */
>  
> +	/*
> +	 * NOTE: We are using a hack here because the FIFO-FLUSH
> +	 * bit is broken in hardware! The hack consists of changing

    Broken on which version of MUSB core?

All, I guess.

> +	 * the TXFUNCADDR to an unused device address and waiting
> +	 * for any pending USB packets to hit the 3-strikes and your

    s/your/you're/

Ok.

> +	 * gone rule.
> +	 */
> +	addr = musb_readb(regs, MUSB_BUSCTL_OFFSET(ep->epnum, MUSB_TXFUNCADDR));
>  	csr = musb_readw(epio, MUSB_TXCSR);
>  	while (csr & MUSB_TXCSR_FIFONOTEMPTY) {

    Besides, flushing is only documented to work when there's a full packet in 
FIFO, so this condition should probably change...

If you read on, you will see that on errors the TX FIFO will get flushed too.

> -		if (csr != lastcsr)
> -			DBG(3, "Host TX FIFONOTEMPTY csr: %02x\n", csr);
> -		lastcsr = csr;
> -		csr |= MUSB_TXCSR_FLUSHFIFO;
> -		musb_writew(epio, MUSB_TXCSR, csr);
> +		musb_writeb(regs, MUSB_BUSCTL_OFFSET(ep->epnum,
> +			MUSB_TXFUNCADDR), 127);

    There's special macro for that write, musb_write_txfunaddr().

Ok.

>  		csr = musb_readw(epio, MUSB_TXCSR);
> -		if (WARN(retries-- < 1,
> -				"Could not flush host TX%d fifo: csr: %04x\n",
> -				ep->epnum, csr))
> -			return;
> -		mdelay(1);
> +		retries--;
> +		if (retries == 0) {
> +			/* can happen if the USB clocks are OFF */

    So what? Why you changed WARN() to DBG()?

We can get a timeout in this loop during USB cable unplug, because then then the chip's clock is no longer running, and there is no response to any FIFO commands. This is not a serious problem so the WARN() was changed into DBG().

> +			DBG(3, "Could not flush host TX%d "
> +				"fifo: csr=0x%04x\n", ep->epnum, csr);
> +			break;
> +		}
> +		udelay(1);
>  	}
> +	/* clear any errors */
> +	csr &= ~(MUSB_TXCSR_H_ERROR
> +		| MUSB_TXCSR_H_RXSTALL
> +		| MUSB_TXCSR_H_NAKTIMEOUT);
> +	musb_writew(epio, MUSB_TXCSR, csr);

    Why?

Because when the 3-strikes and you're gone activates it will cause some error bits to be set which we should not report in the next TX transfer on the given FIFO.

> @@ -1141,7 +1158,9 @@ void musb_host_tx(struct musb *musb, u8 epnum)
>  		DBG(3, "TX 3strikes on ep=%d\n", epnum);
>  
>  		status = -ETIMEDOUT;
> -
> +	} else if (tx_csr & MUSB_TXCSR_TXPKTRDY) {
> +		/* BUSY - can happen during USB transfer cancel */
> +		return;

    Is this change somehow releated to yor proposed workaround?

No. This is a different issue, which actually causes data loss during stress tests.

--HPS @ STE
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

  Powered by Linux