On Monday 30 August 2010 17:34:22 Vasily Khoruzhick wrote: > From: Fabian Godehardt <fg@xxxxxxxxx> > > This is a patch that seems to make the USB hangs on the S3C244X go away. > At least a good amount of ping torture didn't make them come back so far. > > The issue is that, if there are several back-to-back packets, sometimes no > interrupt is generated for one of them. This seems to be caused by the > mysterious dual packet mode, which the USB hardware enters automatically > if the endpoint size is half that of the FIFO. (On the 244X, this is the > normal situation for bulk data endpoints.) > > There is also a timing factor in this. It seems that what happens is that > the USB hardware automatically sends an acknowledgement if there is only > one packet in the FIFO (the FIFO has space for two). If another packet > arrives before the host has retrieved and acknowledged the previous one, > no interrupt is generated for that second one. > > However, there may be an indication. There is one undocumented bit (none > of the 244x manuals document it), OUT_CRS1_REG[1], that seems to be set > suspiciously often when this condition occurs. There is also > CLR_DATA_TOGGLE, OUT_CRS1_REG[7], which may have a function related to > this. (The Samsung manual is rather terse on that, as usual.) > > This needs to be examined further. For now, the patch seems to do the > trick. > > Signed-off-by: Vasily Khoruzhick <anarsoul@xxxxxxxxx> > --- > drivers/usb/gadget/s3c2410_udc.c | 16 +++++++++++++++- > 1 files changed, 15 insertions(+), 1 deletions(-) > > diff --git a/drivers/usb/gadget/s3c2410_udc.c > b/drivers/usb/gadget/s3c2410_udc.c index ea2b3c7..fed323c 100644 > --- a/drivers/usb/gadget/s3c2410_udc.c > +++ b/drivers/usb/gadget/s3c2410_udc.c > @@ -902,7 +902,7 @@ static irqreturn_t s3c2410_udc_irq(int dummy, void > *_dev) int pwr_reg; > int ep0csr; > int i; > - u32 idx; > + u32 idx, idx2; > unsigned long flags; > > spin_lock_irqsave(&dev->lock, flags); > @@ -1017,6 +1017,20 @@ static irqreturn_t s3c2410_udc_irq(int dummy, void > *_dev) } > } > > + /* what else causes this interrupt? a receive! who is it? */ > + if (!usb_status && !usbd_status && !pwr_reg && !ep0csr) { > + for (i = 1; i < S3C2410_ENDPOINTS; i++) { > + idx2 = udc_read(S3C2410_UDC_INDEX_REG); > + udc_write(i, S3C2410_UDC_INDEX_REG); > + > + if (udc_read(S3C2410_UDC_OUT_CSR1_REG) & 0x1) > + s3c2410_udc_handle_ep(&dev->ep[i]); > + > + /* restore index */ > + udc_write(idx2, S3C2410_UDC_INDEX_REG); > + } > + } > + > dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", IRQ_USBD); > > /* Restore old index */ Ping? s3c2410_udc is broken for s3c244x for ages, fix is available, why not to apply it? Regards Vasily -- 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