--- local_tree.orig/drivers/usb/core/devio.c    2004-07-26 12:17:18.000000000 +0200
+++ local_tree/drivers/usb/core/devio.c 2004-07-29 18:38:16.817733447 +0200
@@ -71,6 +71,7 @@
                        dev_info( dev , format , ## arg);       \
        } while (0)
 
+#define MAX_BUFFER_LENGTH      16384
 
 static inline int connected (struct usb_device *dev)
 {
@@ -680,57 +681,79 @@
 
 static int proc_bulk(struct dev_state *ps, void __user *arg)
 {
-       struct usb_device *dev = ps->dev;
        struct usbdevfs_bulktransfer bulk;
-       unsigned int tmo, len1, pipe;
-       int len2;
-       unsigned char *tbuf;
-       int i, ret;
+       struct usb_device *dev = ps->dev;
+       unsigned char *tbuf = NULL;
+       struct urb *urb = NULL;
+       int dir_in, length, ret;
+       unsigned int pipe, timeout;
 
        if (copy_from_user(&bulk, arg, sizeof(bulk)))
                return -EFAULT;
-       if ((ret = findintfep(ps->dev, bulk.ep)) < 0)
-               return ret;
-       if ((ret = checkintf(ps, ret)))
-               return ret;
-       if (bulk.ep & USB_DIR_IN)
-               pipe = usb_rcvbulkpipe(dev, bulk.ep & 0x7f);
-       else
-               pipe = usb_sndbulkpipe(dev, bulk.ep & 0x7f);
-       if (!usb_maxpacket(dev, pipe, !(bulk.ep & USB_DIR_IN)))
+       length = bulk.len;
+       if (length < 0 || length > MAX_BUFFER_LENGTH)
                return -EINVAL;
-       len1 = bulk.len;
-       if (!(tbuf = kmalloc(len1, GFP_KERNEL)))
+       if (!(tbuf = kmalloc(length, GFP_KERNEL)))
                return -ENOMEM;
-       tmo = (bulk.timeout * HZ + 999) / 1000;
-       if (bulk.ep & 0x80) {
-               if (len1 && !access_ok(VERIFY_WRITE, bulk.data, len1)) {
-                       kfree(tbuf);
-                       return -EINVAL;
-               }
-               i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
-               if (!i && len2) {
-                       if (copy_to_user(bulk.data, tbuf, len2)) {
-                               kfree(tbuf);
-                               return -EFAULT;
-                       }
+       dir_in = bulk.ep & USB_DIR_IN;
+       if (dir_in) {
+               if (length && !access_ok(VERIFY_WRITE, bulk.data, length)) {
+                       ret = -EINVAL;
+                       goto out_free;
                }
        } else {
-               if (len1) {
-                       if (copy_from_user(tbuf, bulk.data, len1)) {
-                               kfree(tbuf);
-                               return -EFAULT;
+               if (length) {
+                       if (copy_from_user(tbuf, bulk.data, length)) {
+                               ret = -EFAULT;
+                               goto out_free;
                        }
                }
-               i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
        }
-       kfree(tbuf);
-       if (i < 0) {
+       if (!(urb = usb_alloc_urb(0, GFP_KERNEL))) {
+               ret = -ENOMEM;
+               goto out_free;
+       }
+       down(&dev->serialize);
+       if (!connected(dev)) {
+               ret = -ENODEV;
+               goto out_release;
+       }
+       if ((ret = findintfep(ps->dev, bulk.ep)) < 0)
+               goto out_release;
+       if ((ret = checkintf(ps, ret)))
+               goto out_release;
+       if (dir_in)
+               pipe = usb_rcvbulkpipe(dev, bulk.ep & 0x7f);
+       else
+               pipe = usb_sndbulkpipe(dev, bulk.ep & 0x7f);
+       if (!usb_maxpacket(dev, pipe, !dir_in)) {
+               ret = -EINVAL;
+               goto out_release;
+       }
+       timeout = (bulk.timeout * HZ + 999) / 1000;
+       usb_fill_bulk_urb(urb, dev, pipe, tbuf, length, NULL, NULL);
+       ret = start_wait_urb(dev, urb, timeout, &length);
+       up(&dev->serialize);
+       if (ret < 0) {
                dev_warn(&dev->dev, "usbfs: USBDEVFS_BULK failed "
-                        "ep 0x%x len %u ret %d\n", bulk.ep, bulk.len, i);
-               return i;
+                       "ep 0x%x len %u ret %d\n", bulk.ep, bulk.len, ret);
+               goto out_free;
+       }
+       if (dir_in && length) {
+               if (copy_to_user(bulk.data, tbuf, length)) {
+                       ret = -EFAULT;
+                       goto out_free;
+               }
        }
-       return len2;
+       usb_free_urb(urb);
+       kfree(tbuf);
+       return length;
+out_release:
+       up(&dev->serialize);
+out_free:
+       usb_free_urb(urb);
+       kfree(tbuf);
+       return ret;
 }
 
 static int proc_resetep(struct dev_state *ps, void __user *arg)
@@ -1375,16 +1398,10 @@
                break;
 
        case USBDEVFS_BULK:
-               down(&dev->serialize);
-               if (!connected(dev)) {
-                       up(&dev->serialize);
-                       return -ENODEV;
-               }
                snoop(&dev->dev, "%s: BULK\n", __FUNCTION__);
                ret = proc_bulk(ps, p);
                if (ret >= 0)
                        inode->i_mtime = CURRENT_TIME;
-               up(&dev->serialize);
                break;
 
        case USBDEVFS_RESETEP:


-------------------------------------------------------
This SF.Net email is sponsored by OSTG. Have you noticed the changes on
Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now,
one more big change to announce. We are now OSTG- Open Source Technology
Group. Come see the changes on the new OSTG site. www.ostg.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to