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

Reply via email to