]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/core/devio.c
[PATCH] USB: fix check_ctrlrecip to allow control transfers in state ADDRESS
[linux-2.6-omap-h63xx.git] / drivers / usb / core / devio.c
index 942cd437dc489d48876ef8da3534de94e677042d..545da37afca7bdec6f464d547d575f02570d10cc 100644 (file)
@@ -134,26 +134,21 @@ static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, l
        }
 
        if (pos < sizeof(struct usb_device_descriptor)) {
-               struct usb_device_descriptor *desc = kmalloc(sizeof(*desc), GFP_KERNEL);
-               if (!desc) {
-                       ret = -ENOMEM;
-                       goto err;
-               }
-               memcpy(desc, &dev->descriptor, sizeof(dev->descriptor));
-               le16_to_cpus(&desc->bcdUSB);
-               le16_to_cpus(&desc->idVendor);
-               le16_to_cpus(&desc->idProduct);
-               le16_to_cpus(&desc->bcdDevice);
+               struct usb_device_descriptor temp_desc ; /* 18 bytes - fits on the stack */
+
+               memcpy(&temp_desc, &dev->descriptor, sizeof(dev->descriptor));
+               le16_to_cpus(&temp_desc.bcdUSB);
+               le16_to_cpus(&temp_desc.idVendor);
+               le16_to_cpus(&temp_desc.idProduct);
+               le16_to_cpus(&temp_desc.bcdDevice);
 
                len = sizeof(struct usb_device_descriptor) - pos;
                if (len > nbytes)
                        len = nbytes;
-               if (copy_to_user(buf, ((char *)desc) + pos, len)) {
-                       kfree(desc);
+               if (copy_to_user(buf, ((char *)&temp_desc) + pos, len)) {
                        ret = -EFAULT;
                        goto err;
                }
-               kfree(desc);
 
                *ppos += len;
                buf += len;
@@ -402,7 +397,6 @@ static void driver_disconnect(struct usb_interface *intf)
 }
 
 struct usb_driver usbfs_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usbfs",
        .probe =        driver_probe,
        .disconnect =   driver_disconnect,
@@ -499,7 +493,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
 {
        int ret = 0;
 
-       if (ps->dev->state != USB_STATE_CONFIGURED)
+       if (ps->dev->state != USB_STATE_ADDRESS
+        && ps->dev->state != USB_STATE_CONFIGURED)
                return -EHOSTUNREACH;
        if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
                return 0;
@@ -1350,9 +1345,7 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
        /* let kernel drivers try to (re)bind to the interface */
        case USBDEVFS_CONNECT:
                usb_unlock_device(ps->dev);
-               usb_lock_all_devices();
                bus_rescan_devices(intf->dev.bus);
-               usb_unlock_all_devices();
                usb_lock_device(ps->dev);
                break;
 
@@ -1392,13 +1385,13 @@ static int proc_ioctl_default(struct dev_state *ps, void __user *arg)
 }
 
 #ifdef CONFIG_COMPAT
-static int proc_ioctl_compat(struct dev_state *ps, void __user *arg)
+static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg)
 {
        struct usbdevfs_ioctl32 __user *uioc;
        struct usbdevfs_ioctl ctrl;
        u32 udata;
 
-       uioc = compat_ptr(arg);
+       uioc = compat_ptr((long)arg);
        if (get_user(ctrl.ifno, &uioc->ifno) ||
            get_user(ctrl.ioctl_code, &uioc->ioctl_code) ||
            __get_user(udata, &uioc->data))
@@ -1511,7 +1504,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 
        case USBDEVFS_IOCTL32:
                snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
-               ret = proc_ioctl_compat(ps, p);
+               ret = proc_ioctl_compat(ps, (compat_uptr_t)(long)p);
                break;
 #endif