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>
