-----Original Message----- From: Peter Chen [mailto:peter.chen@xxxxxxxxxxxxx] Sent: Tuesday, January 10, 2012 12:37 PM To: Peter Bestler Cc: linux-usb@xxxxxxxxxxxxxxx; craig@xxxxxxxxx; david-b@xxxxxxxxxxx; leoli@xxxxxxxxxxxxx; tanya.jiang@xxxxxxxxxxxxx Subject: Re: [BUG] g_printer: Kernel freeze at disconnect/reconnect 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. Ok so my understanding is correct. Can u tell me more about the vbus failing irq. Does the Freescale udc-device-controller emit the vbus failling irq, in usual device mode (not otg) ? How can I enable it: 'GPIO based peripheral-only VBUS sensing' (in KConfig ?). I tried this already, but the ISR (fsl_udc_irq) in fsl_udc_core was called only once at disconnect. Reading the interrupt-src register returned 256 (for suspend). I only want to use usb in usual host/slave-operation-mode. >> For enable connect/disconnect interrupt, you can enable BSVIE at otgsc to >> trigger them, the use BSV at otgsc to judge connect and disconnect You mean the connect/disconnect interrupt at otg-operationmode ? What do you mean with BSV ? > > 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. That is right. Actual I do this at suspend (but if the disconnect-cb will be called correct I am going to move this cleanup-stuff to the disconnect routine). > 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. I cannot trace (via printk) the entrance of fsl_udc_irq after a reconnect. The last Kern.log entry is from the suspend from disconnecting. This only occures if I have queued some usb_requests before and do no cleanup at disconnect (unqueue and flush_fifos). Shouldn't the device-controller be as fault-tolerant to handle this ? Now I am doing this cleanup at suspend (see above), and it works pretty fine. > > 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 That is what I want to do, but the Interrupthandler (fsl_udc_irq) doesn't get called at physical disconnect (like mentioned above). > > 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 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