On Wed, May 04, 2005 at 10:30:57AM +0400, Roman Kagan wrote: > On Fri, Apr 29, 2005 at 02:34:59PM -0400, Alan Stern wrote: > > Does the patch look good? If you like it, I'll submit it to Greg. > > Yes it looks reasonable. At the moment I can't test the problematic > multi-interface USB device case where that bug revealed itself, which > was observed by Duncan Sands; I'm attaching a simple test case we've > been using to trigger the problem, so you may want to try it out before > submitting. To do that, you need to load the test driver giving vendor and > product IDs of your multi-interface device as module parameters, and > then rmmod the driver while the device is still plugged in: it used to > spin forever
Sorry, forgot to attach the test case (it's very simple but can save you a bit of typing). Roman. =============================================================== #define DEBUG #include <linux/module.h> #include <linux/usb.h> unsigned short vendor; module_param(vendor, ushort, 0444); unsigned short product; module_param(product, ushort, 0444); static int test_usb_probe(struct usb_interface *intf, const struct usb_device_id *id); void test_usb_disconnect(struct usb_interface *intf); static struct usb_device_id test_usb_ids[2]; static struct usb_driver test_usb_driver = { .owner = THIS_MODULE, .name = "test", .probe = test_usb_probe, .disconnect = test_usb_disconnect, .id_table = test_usb_ids }; static void release_interfaces(struct usb_device *usb_dev, int num_interfaces) { struct usb_interface *cur_intf; int i; dbg("%s entered", __func__); for(i = 0; i < num_interfaces; i++) if ((cur_intf = usb_ifnum_to_if(usb_dev, i))) { usb_set_intfdata(cur_intf, NULL); usb_driver_release_interface(&test_usb_driver, cur_intf); } } static int test_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usb_dev = interface_to_usbdev(intf); struct usb_interface *cur_intf; int ifnum = intf->altsetting->desc.bInterfaceNumber; int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces; int i, ret; dbg("%s entered: intf 0x%p driver 0x%p", __func__, intf, intf->dev.driver); for (i=0; i < num_interfaces; i++) { cur_intf = usb_ifnum_to_if(usb_dev, i); if ((i != ifnum) && cur_intf) { dbg("%s: claiming intf 0x%p", __func__, cur_intf); ret = usb_driver_claim_interface(&test_usb_driver, cur_intf, usb_dev); if (ret < 0) { dbg("%s: failed to claim interface %d (%d)\n", __func__, i, ret); release_interfaces(usb_dev, i); return ret; } dbg("%s: claimed intf 0x%p driver 0x%p", __func__, cur_intf, cur_intf->dev.driver); } } return 0; } void test_usb_disconnect(struct usb_interface *intf) { struct usb_device *usb_dev = interface_to_usbdev(intf); int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces; int i = 0; struct list_head *l, *n; dbg("%s entered: intf 0x%p driver 0x%p", __func__, intf, intf->dev.driver); if (intf->dev.driver) list_for_each_safe(l, n, &intf->dev.driver->devices) i++; dbg("%s: driver 0x%p has %d devices", __func__, intf->dev.driver, i); if (usb_get_intfdata(intf)) release_interfaces(usb_dev, num_interfaces); else dbg("NULL instance"); } static int __init test_init(void) { dbg("%s entered", __func__); printk("vendor: %04x, product: %04x\n", vendor, product); test_usb_ids[0].match_flags = USB_DEVICE_ID_MATCH_DEVICE; test_usb_ids[0].idVendor = vendor; test_usb_ids[0].idProduct = product; return usb_register(&test_usb_driver); } module_init(test_init); static void __exit test_exit(void) { dbg("%s entered", __func__); usb_deregister(&test_usb_driver); } module_exit(test_exit); MODULE_LICENSE("GPL"); ------------------------------------------------------- This SF.Net email is sponsored by: NEC IT Guy Games. Get your fingers limbered up and give it your best shot. 4 great events, 4 opportunities to win big! Highest score wins.NEC IT Guy Games. Play to win an NEC 61 plasma display. Visit http://www.necitguy.com/?r=20 _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel