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