Subject: Re: usb control endpoint exclusive access
To: None <wulf@ping.net.au, gdt@ir.bbn.com>
From: None <davef1624@aol.com>
List: tech-kern
Date: 05/18/2005 21:27:06
I'm using the UPL device driver for the Prolific PL2301/PL2302 
host-to-host bridge cable.

This driver doesn't employ the use of reference counts to protect 
against device detaches preempting
in-progress I/O or control requests to/from the device.

I've noticed that most other USB device driver make use of reference 
counts for this purpose.
For example, in ugen.c:


ugen_detach() {

           ... code to abort all pipes ...

            if (--sc->sc_refcnt >= 0) {
                /* Wake everyone */
                for (i = 0; i < USB_MAX_ENDPOINTS; i++)
                    wakeup(&sc->sc_endpoints[i][IN]);

                /* Wait for processes to go away */
                usb_detach_wait(USBDEV(sc->sc_dev)
            }

            ... continue & exit from ugen_detach()
 }

In all routines that initiate I/O, sc->sc_refcnt is incremented, I/O is 
performed, and then decremented.
For example, in ugenread() :


             sc->sc_refcnt++
             error = ugen_do_read(sc, endpt, uio, flag);
             if (--sc->sc_refcnt < 0)
                 usb_detach_wakeup(USBDEV(sc->sc_dev));


I've seen several crashes in the UPL driver which appear to be the 
result of it's detach routine
being called and preempting in progress I/O, and hence deallocating 
critical data-structures
that the I/O is dependent on.

For example, I see a crash in usbd_alloc_xfer(), on the following line:

usbd_alloc_xfer(usbd_device_handle dev)
             usbd_xfer_handle xfer;

              xfer = dev->bus->methods->allocx(dev->bus)       <-- NULL 
pointer dereference here


 From the crash(es), either the 'bus' pointer or the 'methods' pointer 
is invalid.
This is because the UPL detach routine has preempted the UPL init code,
deallocated the above data structures, and exited.

So I believe the correct fix for this is to utilize the reference count 
approach
which I see is used in several other USB device drivers.

Can anybody comment on this approach (reference count approach),
and/or better explain to me why the reference counts are used,
and whether or not I should also implement them in the UPL driver.

Thanks for your help,
Dave