Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Jan 2007 23:34:54 +0100
From:      Hans Petter Selasky <hselasky@c2i.net>
To:        Luigi Rizzo <rizzo@icir.org>
Cc:        freebsd-usb@freebsd.org
Subject:   Re: any way to detect usb detached from a device driver ?
Message-ID:  <200701102334.55338.hselasky@c2i.net>
In-Reply-To: <20070110044653.A87966@xorpc.icir.org>
References:  <20070109083450.A75138@xorpc.icir.org> <200701092137.22421.hselasky@c2i.net> <20070110044653.A87966@xorpc.icir.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701102334.55338.hselasky>