Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / drivers / usb / core / devio.c
index d8b0476..545da37 100644 (file)
@@ -47,7 +47,6 @@
 #include <linux/usbdevice_fs.h>
 #include <linux/cdev.h>
 #include <linux/notifier.h>
-#include <linux/security.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 #include <linux/moduleparam.h>
@@ -59,9 +58,6 @@
 #define USB_DEVICE_MAX                 USB_MAXBUS * 128
 static struct class *usb_device_class;
 
-/* Mutual exclusion for removal, open, and release */
-DEFINE_MUTEX(usbfs_mutex);
-
 struct async {
        struct list_head asynclist;
        struct dev_state *ps;
@@ -72,7 +68,6 @@ struct async {
        void __user *userbuffer;
        void __user *userurb;
        struct urb *urb;
-       u32 secid;
 };
 
 static int usbfs_snoop = 0;
@@ -317,7 +312,7 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
                sinfo.si_code = SI_ASYNCIO;
                sinfo.si_addr = as->userurb;
                kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, 
-                                     as->euid, as->secid);
+                                     as->euid);
        }
        snoop(&urb->dev->dev, "urb complete\n");
        snoop_urb(urb, as->userurb);
@@ -544,19 +539,21 @@ static int usbdev_open(struct inode *inode, struct file *file)
        struct dev_state *ps;
        int ret;
 
-       /* Protect against simultaneous removal or release */
-       mutex_lock(&usbfs_mutex);
-
+       /* 
+        * no locking necessary here, as chrdev_open has the kernel lock
+        * (still acquire the kernel lock for safety)
+        */
        ret = -ENOMEM;
        if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL)))
-               goto out;
+               goto out_nolock;
 
+       lock_kernel();
        ret = -ENOENT;
        /* check if we are called from a real node or usbfs */
        if (imajor(inode) == USB_DEVICE_MAJOR)
                dev = usbdev_lookup_minor(iminor(inode));
        if (!dev)
-               dev = inode->i_private;
+               dev = inode->u.generic_ip;
        if (!dev) {
                kfree(ps);
                goto out;
@@ -575,13 +572,13 @@ static int usbdev_open(struct inode *inode, struct file *file)
        ps->disc_euid = current->euid;
        ps->disccontext = NULL;
        ps->ifclaimed = 0;
-       security_task_getsecid(current, &ps->secid);
        wmb();
        list_add_tail(&ps->list, &dev->filelist);
        file->private_data = ps;
  out:
-       mutex_unlock(&usbfs_mutex);
-       return ret;
+       unlock_kernel();
+ out_nolock:
+        return ret;
 }
 
 static int usbdev_release(struct inode *inode, struct file *file)
@@ -591,12 +588,7 @@ static int usbdev_release(struct inode *inode, struct file *file)
        unsigned int ifnum;
 
        usb_lock_device(dev);
-
-       /* Protect against simultaneous open */
-       mutex_lock(&usbfs_mutex);
        list_del_init(&ps->list);
-       mutex_unlock(&usbfs_mutex);
-
        for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed);
                        ifnum++) {
                if (test_bit(ifnum, &ps->ifclaimed))
@@ -605,8 +597,9 @@ static int usbdev_release(struct inode *inode, struct file *file)
        destroy_all_async(ps);
        usb_unlock_device(dev);
        usb_put_dev(dev);
+       ps->dev = NULL;
        kfree(ps);
-       return 0;
+        return 0;
 }
 
 static int proc_control(struct dev_state *ps, void __user *arg)
@@ -830,7 +823,8 @@ static int proc_connectinfo(struct dev_state *ps, void __user *arg)
 
 static int proc_resetdevice(struct dev_state *ps)
 {
-       return usb_reset_composite_device(ps->dev, NULL);
+       return usb_reset_device(ps->dev);
+
 }
 
 static int proc_setintf(struct dev_state *ps, void __user *arg)
@@ -929,8 +923,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
                                != USB_ENDPOINT_XFER_CONTROL)
                        return -EINVAL;
-               /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */
-               if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE))
+               /* min 8 byte setup packet, max arbitrary */
+               if (uurb->buffer_length < 8 || uurb->buffer_length > PAGE_SIZE)
                        return -EINVAL;
                if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL)))
                        return -ENOMEM;
@@ -988,8 +982,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                        return -EFAULT;
                }
                for (totlen = u = 0; u < uurb->number_of_packets; u++) {
-                       /* arbitrary limit, sufficient for USB 2.0 high-bandwidth iso */
-                       if (isopkt[u].length > 8192) {
+                       if (isopkt[u].length > 1023) {
                                kfree(isopkt);
                                return -EINVAL;
                        }
@@ -1060,7 +1053,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
        as->pid = current->pid;
        as->uid = current->uid;
        as->euid = current->euid;
-       security_task_getsecid(current, &as->secid);
        if (!(uurb->endpoint & USB_DIR_IN)) {
                if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, as->urb->transfer_buffer_length)) {
                        free_async(as);