multiple interface test case

Roman Kagan rkagan at mail.ru
Sun Apr 10 12:59:48 EDT 2005


  Hi Duncan,

Here's the reduced version of your testatm_8, which doesn't touch usbatm
at all.  I can't get it to fail with my single-interface devices.  If it
breaks for you, we can send it to usb-devel list asking for help in
debugging it.

I'm interested in the outcome too as I'd like to put proper multiple
interface handling into xusbatm :)

Cheers,
  Roman.

=====================================================
#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;

	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", __func__);

	for (i=0; i < num_interfaces; i++) {
		cur_intf = usb_ifnum_to_if(usb_dev, i);

		if ((i != ifnum) && 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;
			}
		}
	}

	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;

	dbg("%s entered", __func__);

	release_interfaces(usb_dev, num_interfaces);
}

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");



More information about the Usbatm mailing list