From: Bryan Wu <cooloney@xxxxxxxxxx> Some USB stick does not answer PING correctly which will make USB enumeration fail. We enable the NAK limit value to detect this PING issue, then disable the PING option for such ill-behaviored usb sticks. Signed-off-by: Bryan Wu <cooloney@xxxxxxxxxx> Signed-off-by: Mike Frysinger <vapier@xxxxxxxxxx> --- drivers/usb/musb/musb_core.c | 1 + drivers/usb/musb/musb_core.h | 3 +++ drivers/usb/musb/musb_host.c | 12 ++++++++++++ 3 files changed, 16 insertions(+), 0 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 4000cf6..6f0b471 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -571,6 +571,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, handled = IRQ_HANDLED; musb->is_active = 1; set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); + musb->disable_ping = 0; musb->ep0_stage = MUSB_EP0_START; diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index efb39b5..db013dd 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -386,6 +386,9 @@ struct musb { unsigned is_multipoint:1; unsigned ignore_disconnect:1; /* during bus resets */ + /* Disable PING packet to cope with ill-behaved usb thumb drives. */ + unsigned disable_ping:1; + #ifdef C_MP_TX unsigned bulk_split:1; #define can_bulk_split(musb,type) \ diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index db1b574..a0b3423 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1026,6 +1026,11 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) } else if (csr & MUSB_CSR0_H_NAKTIMEOUT) { DBG(2, "control NAK timeout\n"); + /* For some ill-behaved USB stick, control transfer should + * disable PING packet + */ + musb->disable_ping = 1; + /* NOTE: this code path would be a good place to PAUSE a * control transfer, if another one is queued, so that * ep0 is more likely to stay busy. That's already done @@ -1085,6 +1090,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) else csr = MUSB_CSR0_H_STATUSPKT | MUSB_CSR0_TXPKTRDY; + if (musb->disable_ping) + csr |= MUSB_CSR0_H_DIS_PING; /* flag status stage */ musb->ep0_stage = MUSB_EP0_STATUS; @@ -1975,6 +1982,11 @@ static int musb_urb_enqueue( /* ISO always uses logarithmic encoding */ interval = min_t(u8, epd->bInterval, 16); break; + case USB_ENDPOINT_XFER_CONTROL: + if (!musb->disable_ping) { + interval = (USB_SPEED_HIGH == urb->dev->speed) ? 8 : 0; + break; + } default: /* REVISIT we actually want to use NAK limits, hinting to the * transfer scheduling logic to try some other qh, e.g. try -- 1.6.3.1 -- 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