any way to detect usb detached from a device driver ?
Hans Petter Selasky
hselasky at c2i.net
Wed Jan 10 23:35:29 UTC 2007
Hi Luigi,
On Wednesday 10 January 2007 13:46, Luigi Rizzo wrote:
> On Tue, Jan 09, 2007 at 09:37:21PM +0100, Hans Petter Selasky wrote:
> > On Tuesday 09 January 2007 17:34, Luigi Rizzo wrote:
[...]
>
> sorry but i cannot figure out how the above helps in the
> detach case e.g. when a process is waiting for an ioctl
> or read operation to complete - can you give more details ?
"usb_cdev" is an abstraction layer for pluggable devices that wants to create
a device under /dev, to read/write some data. It does not help unless you
port your PWC driver over to using the "usb_cdev" system, instead of devfs
directly.
>
> In my case, i did the following:
>
> USB_DETACH(pwc)
> {
> USB_DETACH_START(pwc, sc);
> again:
> if(sc->sc_videopipe != NULL) {
> usbd_abort_pipe(sc->sc_videopipe);
> usbd_close_pipe(sc->sc_videopipe);
> sc->sc_videopipe = NULL;
> }
> sc->error_status = EPIPE;
> if(sc->vopen) {
> if(sc->state & PWC_ASLEEP)
> wakeup(sc);
> if(sc->state & PWC_POLL) {
> sc->state &= ~PWC_POLL;
> selwakeuppri(&sc->rsel,PZERO);
> }
> device_printf(sc->sc_dev, "Disconnected while webcam is in
> use!\n"); usb_detach_wait(USBDEV(sc->sc_dev));
> goto again;
> }
>
> if(sc->sc_dev_t != NULL)
> destroy_dev(sc->sc_dev_t);
>
> mtx_destroy(&sc->ptrlock);
> pwc_free_buffers(sc,1);
>
> usbd_add_drv_event(USB_EVENT_DRIVER_DETACH,sc->udev,USBDEV(sc->sc_dev));
> return 0;
> }
>
> and at the end of the close routine
>
> ...
> sc->vopen = 0;
> usb_detach_wakeup(USBDEV(sc->sc_dev));
> }
>
> so the USB_DETACH() will wake up any process blocked,
> the sc->error_status = EPIPE; should force an error and
> cause the process to call close().
>
> The down side is that you are still in the hands
> of the process to let the detach complete. Ideally one
> would just flag the descriptor as 'detach_pending'
> and get rid of it at the end of the close(), while the
> DETACH() could terminate without doing the free()
What I do is to ensure that no thread is executing in any of the devfs
callbacks. This might imply some waiting. Then I simply destroy the device
using destroy_dev(). This way you don't have to wait for the userland process
to call close(), which might not happen right away.
See "usb_cdev_detach()" for more info.
--HPS
More information about the freebsd-usb
mailing list