On Mon, Jan 09, 2012 at 03:11:59PM +0100, Peter Bestler wrote: > I am using the g_printer driver in combination with kernel 3.2-rc7. > The hardware-platform is a Freescale p2020 (devicecontroller is the > fsl-usb2-core). For testing I use the printer.c-app in > /Documentation/usb/gadget_printer.c > > After setting a correct configuration and transmit/receive some bytes > via poll and read/write I pull the usb-cable. The Kernel freezes instantly > and only a reboot can bring up the board again. Thats because the fsl-udc > does not receive a reset_irq at physical disconnect, only suspend_irq. The disconnect process will only occur suspend irq and vbus failing irq(if enabled), no reset will be received as reset_irq is sent by host. > > The Kernel get stuck at poll_wait() in printer_poll. To solve this I > implemented the suspend-cb which simple wake up the waitqueues in > combination with an 'online-flag' in printer-dev struct . This flag is set by > suspend/resume and checked in poll function. At physical disconnect the > g_printer-driver will return correct from poll (POLLERR_HUP). > It is only a hack for further debugging. Usually these wakeup-stuff should > be done by the disconnect callback (g_printer) (IMO). you can add this at your gadget driver's disconnect, and disconnect should be called when vbus failing irq is received. ->suspend may be called some other situations, like just plug in the cable or the host suspend the bus. For enable connect/disconnect interrupt, you can enable BSVIE at otgsc to trigger them, the use BSV at otgsc to judge connect and disconnect > > After applying the hack above, the application can catch the HUP-signal > successful. But after that the Kernel freezes at reconnecting the cable. > > My understanding of this problem: In printer_poll() and read, some > usb-requests are setup and queued to the udc by the driver > (setup_rx_req). These requests are for receiving data from host. > At (physical) disconnect there is no cleanup of these requests. > The udc-driver (fsl_udc_core) receives only a suspend_irq, calls the > registered callback .suspend and set the state to suspend. > > It seems that the disconnect-callback of g_printer is not called by > fsl_udc_core at physical disconnect. Also the fsl_udc_core does no internal > cleanup, because it does not receive a reset_irq. At reconnecting The cleanup should be called from gadget driver's disconnect, it will do some flush ,dequeue the reqest, and call the usb request's complete callback. > the cable usually reset_irq (with bus_reset) is triggered. > If I have used the poll function before disconnecting the cable, the > Kernel freezes at reconnect before calling the function fsl_udc_irq > (traced via printk). Isn't this the entrypoint to fsl_udc_core at reconnecting ? You mean the system is hang without any usb irqs is triggered when re-connect the cable? It seems not reasonable as only udc driver knows there is connection. > > Please correct me if I am wrong. > > How can we fix this issue? Please add disconnect interrupt handler first, and at disconnect interrupt handler call your g_printer's disconnect. Then see what happening next > > best regards > > Peter Bestler > > > -- > 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 > -- Best Regards, Peter Chen -- 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