RE: [PATCH] usb: musb: gadget: fix enumeration on heavy-loadedsystems

From: B, Ravi
Date: Tue Apr 16 2013 - 12:58:03 EST


> -----Original Message-----
> From: linux-usb-owner@xxxxxxxxxxxxxxx [mailto:linux-usb-
> owner@xxxxxxxxxxxxxxx] On Behalf Of Bilovol, Ruslan
> Sent: Tuesday, April 16, 2013 9:12 PM
> To: Balbi, Felipe; gregkh@xxxxxxxxxxxxxxxxxxx; linux-usb@xxxxxxxxxxxxxxx;
> linux-kernel@xxxxxxxxxxxxxxx
> Subject: [PATCH] usb: musb: gadget: fix enumeration on heavy-loaded
> systems
>
> From musb point of view, the Address Assignment sequence during
> device enumeration is next:
> - first ep0 interrupt:
> * read the address from USB_REQ_SET_ADDRESS request
> * set up CSR0L.DataEnd bit (that is ACK
> signalization for the host)
> - second ep0 interrupt:
> * indicates that the request completed successfully
> * set up musb device address
> Now musb device should answer to this address
>
> From the host perspective, if peripheral device acquires
> SET_ADDRESS request, it now may be accessed only using that address.
> However, on heavy loaded systems, time between first and
> second musb ep0 interrupts may be too long and musb controller
> misses requests between.

What is meant by heavily loaded system? Is the device is heavily loaded during enumeration stage? Why second ep0 interrupt is too long? whether interrupt occurrence to interrupt service is taking too long?

As result, device enumeration may be
> unsuccessful. This can be checked on USB3.0 Host and
> using USB3.0 test suite (from usb.org) running ch9 tests
> for USB2.0 devices.

You mean the usb2.0 musb controller (in device mode) connected to USB3.0 host?

> Usually 'Addressed state/TD9.1: Device Descriptor Test' will fail
>
> The fix consists in checking CSR0L.DataEnd state and assigning
> the device address in the first ep0 interrupt handling, so
> delay is as minimal as possible
>
> Signed-off-by: Ruslan Bilovol <ruslan.bilovol@xxxxxx>
> ---
> drivers/usb/musb/musb_gadget_ep0.c | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
> diff --git a/drivers/usb/musb/musb_gadget_ep0.c
> b/drivers/usb/musb/musb_gadget_ep0.c
> index c9c1ac4..59bc5a5 100644
> --- a/drivers/usb/musb/musb_gadget_ep0.c
> +++ b/drivers/usb/musb/musb_gadget_ep0.c
> @@ -885,6 +885,37 @@ stall:
> finish:
> musb_writew(regs, MUSB_CSR0,
> musb->ackpend);
> +
> + /*
> + * If we are at end of SET_ADDRESS sequence,
> + * update the address immediately if possible,
> + * otherwise we may miss packets between
> + * sending ACK from musb side and musb's next
> + * interrupt handler firing (in which we update
> + * the address). At least this fixes next
> + * USB2.0 ch9 test of USB30CV utility:
> + * "Addressed state - Device Descriptor test"
> + */
> + if (musb->set_address && (musb->ackpend &
> + MUSB_CSR0_P_DATAEND) &&
> + (musb->ep0_state ==
> + MUSB_EP0_STAGE_STATUSIN)) {
> + u16 ack_delay = 500;
> +
> + while ((musb_readw(regs, MUSB_CSR0) &
> + MUSB_CSR0_P_DATAEND) &&
> + --ack_delay) {
> + cpu_relax();
> + udelay(1);
> + }
> +
> + if (ack_delay) {
> + musb->set_address = false;
> + musb_writeb(mbase, MUSB_FADDR,
> + musb->address);
> + }
> + }
> +
> musb->ackpend = 0;
> }
> }

--
Ravi B
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/