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