multiple interface test case

Duncan Sands baldrick at free.fr
Wed Apr 13 06:44:11 EDT 2005


Hi Roman, first of all, I'm using 2.6.12-rc2-mm3 with the attached test
driver (modified from what you sent).

On Wed, 2005-04-13 at 14:32 +0400, Roman Kagan wrote:
> On Wed, Apr 13, 2005 at 12:13:22PM +0200, Duncan Sands wrote:
> > Hi Roman, in -mm things are completely different.  Here's what
> > happens: driver_detach correctly iterates over the devices.
> > 
> > First device (interface 0):
> > 	device_release_driver calls usb_unbind_interface which calls
> > test_usb_disconnect.  This calls usb_driver_release_interface on each
> > interface:
> > 	interface 0: instant exit at this line:
> >       	  if (!dev->driver || dev->driver != &driver->driver)
> >        	         return;
> 
> No, this test passes for all three interfaces.  dev->driver is set to
> NULL later, in this routine or in device_release_driver()

yes, you are correct: all interfaces pass this test, and fail the
next test (can't even read my own dumps...)

> > 	interfaces 1 and 2: device_release_driver is NOT called, because
> > of this test:
> >     	    if (!klist_node_attached(&dev->knode_driver) && !klist_node_attached(&dev->knode_bus)) {
> 
> On the opposite: this test fails for intf 0 (the one disconnect() was
> called with), because device_release_driver() has already detached this
> device from the driver, but passes for other interfaces (otherwise what
> would be the reason for this test :).

No, you are wrong.  I put this code in there:

        /* don't disconnect from disconnect(), or before dev_add() */
        if (!klist_node_attached(&dev->knode_driver) && !klist_node_attached(&dev->knode_bus)) {
                printk("usb_driver_release_interface: releasing\n");
                device_release_driver(dev);
        } else printk("usb_driver_release_interface: skipping\n");

and here's what I see

release_interfaces: interface 0
usb_driver_release_interface: skipping <= somehow I failed to see this!
release_interfaces: interface 1
usb_driver_release_interface: skipping
release_interfaces: interface 2
usb_driver_release_interface: skipping


> > Second and third devices (interfaces 1 and 2):
> > 	device_release_driver does an instant exit because of this test:
> > 	         if (dev->driver) {
> 
> No, because the device_release_driver() for these interfaces has already
> been called from device_release_driver() for intf 0, the device list is
> already empty and the iteration in driver_detach only reaches interface
> 1, does nothing because dev->driver is NULL, and then advances to itself
> over and over.

Not with the kernel I'm running.

> > Summary: the fault seems to be in usb_driver_release_interface, which
> > shouldn't be setting dev->driver to NULL.
> 
> Disagreed :)  This dev->driver = NULL is a noop: it is set to NULL
> either in device_release_driver() which called us (when operating on the
> disconnect()-ed interface), or in device_release_driver() which we call.

No, we never call device_release_driver from
usb_driver_release_interface.

I think these differences are because we are running different kernels.
Are we?

D.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: roman.c
Type: text/x-csrc
Size: 2586 bytes
Desc: not available
Url : http://lists.infradead.org/pipermail/usbatm/attachments/20050413/9380dd6d/roman.bin


More information about the Usbatm mailing list