USB: usbfs: export the URB_NO_INTERRUPT flag to userspace

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>

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 039ba23..6c4cd82 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -948,8 +948,11 @@
 	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 @@
 	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;
diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
index 17cb108..3118ede 100644
--- a/include/linux/usbdevice_fs.h
+++ b/include/linux/usbdevice_fs.h
@@ -77,8 +77,11 @@
 	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