Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Jan 2007 15:39:35 -0800
From:      Luigi Rizzo <rizzo@icir.org>
To:        Hans Petter Selasky <hselasky@c2i.net>
Cc:        freebsd-usb@freebsd.org
Subject:   Re: any way to detect usb detached from a device driver ?
Message-ID:  <20070110153935.B96102@xorpc.icir.org>
In-Reply-To: <200701102334.55338.hselasky@c2i.net>; from hselasky@c2i.net on Wed, Jan 10, 2007 at 11:34:54PM %2B0100
References:  <20070109083450.A75138@xorpc.icir.org> <200701092137.22421.hselasky@c2i.net> <20070110044653.A87966@xorpc.icir.org> <200701102334.55338.hselasky@c2i.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Jan 10, 2007 at 11:34:54PM +0100, Hans Petter Selasky wrote:
> 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.

ok... so if i understand well, once all processes have exited
the callbacks you destroy, which means that afterwards they will
not be able to invoke the callbacks anymore (nor crash the machine)
even if they retain a handle ?

	cheers
	luigi



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