Duncan:
I went ahead and created a patch to change all the places where devio.c
uses an interface index. Now it always uses just the interface number.
Does this look all right to you? I don't have a convenient way to test
it.
Alan Stern
===== drivers/usb/core/devio.c 1.108 vs edited =====
--- 1.108/drivers/usb/core/devio.c Fri Apr 30 06:01:37 2004
+++ edited/drivers/usb/core/devio.c Mon May 10 10:52:49 2004
@@ -349,23 +349,22 @@
struct usb_interface *iface;
int err;
- if (intf >= 8*sizeof(ps->ifclaimed)
- || intf >= dev->actconfig->desc.bNumInterfaces)
+ if (intf >= 8*sizeof(ps->ifclaimed))
return -EINVAL;
/* already claimed */
if (test_bit(intf, &ps->ifclaimed))
return 0;
- iface = dev->actconfig->interface[intf];
- err = -EBUSY;
/* lock against other changes to driver bindings */
down_write(&usb_bus_type.subsys.rwsem);
- if (!usb_interface_claimed(iface)) {
- usb_driver_claim_interface(&usbdevfs_driver, iface, ps);
- set_bit(intf, &ps->ifclaimed);
- err = 0;
- }
+ iface = usb_ifnum_to_if(dev, intf);
+ if (!iface)
+ err = -ENOENT;
+ else
+ err = usb_driver_claim_interface(&usbdevfs_driver, iface, ps);
up_write(&usb_bus_type.subsys.rwsem);
+ if (err == 0)
+ set_bit(intf, &ps->ifclaimed);
return err;
}
@@ -375,14 +374,16 @@
struct usb_interface *iface;
int err;
- if (intf >= 8*sizeof(ps->ifclaimed))
- return -EINVAL;
err = -EINVAL;
+ if (intf >= 8*sizeof(ps->ifclaimed))
+ return err;
dev = ps->dev;
/* lock against other changes to driver bindings */
down_write(&usb_bus_type.subsys.rwsem);
- if (test_and_clear_bit(intf, &ps->ifclaimed)) {
- iface = dev->actconfig->interface[intf];
+ iface = usb_ifnum_to_if(dev, intf);
+ if (!iface)
+ err = -ENOENT;
+ else if (test_and_clear_bit(intf, &ps->ifclaimed)) {
usb_driver_release_interface(&usbdevfs_driver, iface);
err = 0;
}
@@ -420,52 +421,32 @@
for (e = 0; e < alts->desc.bNumEndpoints; e++) {
endpt = &alts->endpoint[e].desc;
if (endpt->bEndpointAddress == ep)
- return i;
+ return alts->desc.bInterfaceNumber;
}
}
}
return -ENOENT;
}
-static int findintfif(struct usb_device *dev, unsigned int ifn)
-{
- unsigned int i;
-
- if (ifn & ~0xff)
- return -EINVAL;
- if (!dev->actconfig)
- return -ESRCH;
- for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
- if (dev->actconfig->interface[i]->
- altsetting[0].desc.bInterfaceNumber == ifn)
- return i;
- }
- return -ENOENT;
-}
-
static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsigned
int index)
{
- int ret;
+ int ret = 0;
if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
return 0;
+ index &= 0xff;
switch (requesttype & USB_RECIP_MASK) {
case USB_RECIP_ENDPOINT:
- if ((ret = findintfep(ps->dev, index & 0xff)) < 0)
- return ret;
- if ((ret = checkintf(ps, ret)))
- return ret;
+ if ((ret = findintfep(ps->dev, index)) >= 0)
+ ret = checkintf(ps, ret);
break;
case USB_RECIP_INTERFACE:
- if ((ret = findintfif(ps->dev, index & 0xff)) < 0)
- return ret;
- if ((ret = checkintf(ps, ret)))
- return ret;
+ ret = checkintf(ps, index);
break;
}
- return 0;
+ return ret;
}
/*
@@ -478,8 +459,7 @@
int ret;
/*
- * no locking necessary here, as both sys_open (actually filp_open)
- * and the hub thread have the kernel lock
+ * no locking necessary here, as chrdev_open has the kernel lock
* (still acquire the kernel lock for safety)
*/
ret = -ENOMEM;
@@ -684,17 +664,17 @@
if (copy_from_user(&gd, arg, sizeof(gd)))
return -EFAULT;
- if ((ret = findintfif(ps->dev, gd.interface)) < 0)
- return ret;
down_read(&usb_bus_type.subsys.rwsem);
- interface = ps->dev->actconfig->interface[ret];
- if (!interface || !interface->dev.driver) {
- up_read(&usb_bus_type.subsys.rwsem);
- return -ENODATA;
+ interface = usb_ifnum_to_if(ps->dev, gd.interface);
+ if (!interface || !interface->dev.driver)
+ ret = -ENODATA;
+ else {
+ strncpy(gd.driver, interface->dev.driver->name,
+ sizeof(gd.driver));
+ ret = (copy_to_user(arg, &gd, sizeof(gd)) ? -EFAULT : 0);
}
- strncpy(gd.driver, interface->dev.driver->name, sizeof(gd.driver));
up_read(&usb_bus_type.subsys.rwsem);
- return copy_to_user(arg, &gd, sizeof(gd)) ? -EFAULT : 0;
+ return ret;
}
static int proc_connectinfo(struct dev_state *ps, void __user *arg)
@@ -717,19 +697,14 @@
static int proc_setintf(struct dev_state *ps, void __user *arg)
{
struct usbdevfs_setinterface setintf;
- struct usb_interface *interface;
int ret;
if (copy_from_user(&setintf, arg, sizeof(setintf)))
return -EFAULT;
- if ((ret = findintfif(ps->dev, setintf.interface)) < 0)
- return ret;
- interface = ps->dev->actconfig->interface[ret];
- if ((ret = checkintf(ps, ret)))
+ if ((ret = checkintf(ps, setintf.interface)))
return ret;
- if (usb_set_interface(ps->dev, setintf.interface, setintf.altsetting))
- return -EINVAL;
- return 0;
+ return usb_set_interface(ps->dev, setintf.interface,
+ setintf.altsetting);
}
static int proc_setconfig(struct dev_state *ps, void __user *arg)
@@ -1062,13 +1037,10 @@
static int proc_claiminterface(struct dev_state *ps, void __user *arg)
{
unsigned int intf;
- int ret;
if (get_user(intf, (unsigned int __user *)arg))
return -EFAULT;
- if ((ret = findintfif(ps->dev, intf)) < 0)
- return ret;
- return claimintf(ps, ret);
+ return claimintf(ps, intf);
}
static int proc_releaseinterface(struct dev_state *ps, void __user *arg)
@@ -1078,8 +1050,6 @@
if (get_user(intf, (unsigned int __user *)arg))
return -EFAULT;
- if ((ret = findintfif(ps->dev, intf)) < 0)
- return ret;
if ((ret = releaseintf(ps, intf)) < 0)
return ret;
destroy_async_on_interface (ps, intf);
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to
deliver higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel