USB: usbfs: export the URB_NO_INTERRUPT flag to userspace
authorAlan Stern <stern@rowland.harvard.edu>
Thu, 17 Apr 2008 14:18:11 +0000 (10:18 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 25 Apr 2008 04:16:54 +0000 (21:16 -0700)
This patch (as1079) cleans up the way URB_* flags are exported in
usbfs.

The URB_NO_INTERRUPT flag is now exported (this is the
only behavioral change).

USBDEVFS_URB_* macros are added for URB_NO_FSBR,
URB_ZERO_PACKET, and URB_NO_INTERRUPT, making explicit the
fact that the kernel accepts them.

The flag matching takes into account that the URB_* values
may change as the kernel evolves, whereas the USBDEVFS_URB_*
values must remain fixed since they are a user API.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/core/devio.c
include/linux/usbdevice_fs.h

index 039ba23..6c4cd82 100644 (file)
@@ -948,8 +948,11 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
        int ret, ifnum = -1;
        int is_in;
 
-       if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK|
-                          URB_NO_FSBR|URB_ZERO_PACKET))
+       if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP |
+                               USBDEVFS_URB_SHORT_NOT_OK |
+                               USBDEVFS_URB_NO_FSBR |
+                               USBDEVFS_URB_ZERO_PACKET |
+                               USBDEVFS_URB_NO_INTERRUPT))
                return -EINVAL;
        if (!uurb->buffer)
                return -EINVAL;
@@ -1104,8 +1107,24 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
        as->urb->pipe = (uurb->type << 30) |
                        __create_pipe(ps->dev, uurb->endpoint & 0xf) |
                        (uurb->endpoint & USB_DIR_IN);
-       as->urb->transfer_flags = uurb->flags |
-                       (is_in ? URB_DIR_IN : URB_DIR_OUT);
+
+       /* This tedious sequence is necessary because the URB_* flags
+        * are internal to the kernel and subject to change, whereas
+        * the USBDEVFS_URB_* flags are a user API and must not be changed.
+        */
+       u = (is_in ? URB_DIR_IN : URB_DIR_OUT);
+       if (uurb->flags & USBDEVFS_URB_ISO_ASAP)
+               u |= URB_ISO_ASAP;
+       if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK)
+               u |= URB_SHORT_NOT_OK;
+       if (uurb->flags & USBDEVFS_URB_NO_FSBR)
+               u |= URB_NO_FSBR;
+       if (uurb->flags & USBDEVFS_URB_ZERO_PACKET)
+               u |= URB_ZERO_PACKET;
+       if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT)
+               u |= URB_NO_INTERRUPT;
+       as->urb->transfer_flags = u;
+
        as->urb->transfer_buffer_length = uurb->buffer_length;
        as->urb->setup_packet = (unsigned char *)dr;
        as->urb->start_frame = uurb->start_frame;
index 17cb108..3118ede 100644 (file)
@@ -77,8 +77,11 @@ struct usbdevfs_connectinfo {
        unsigned char slow;
 };
 
-#define USBDEVFS_URB_SHORT_NOT_OK          1
-#define USBDEVFS_URB_ISO_ASAP              2
+#define USBDEVFS_URB_SHORT_NOT_OK      0x01
+#define USBDEVFS_URB_ISO_ASAP          0x02
+#define USBDEVFS_URB_NO_FSBR           0x20
+#define USBDEVFS_URB_ZERO_PACKET       0x40
+#define USBDEVFS_URB_NO_INTERRUPT      0x80
 
 #define USBDEVFS_URB_TYPE_ISO             0
 #define USBDEVFS_URB_TYPE_INTERRUPT       1