From 14722ef4acedc643f0b78b7165ceff2d300dae4d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 17 Apr 2008 10:18:11 -0400 Subject: 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 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 27 +++++++++++++++++++++++---- include/linux/usbdevice_fs.h | 7 +++++-- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 039ba23cc8b..6c4cd82d7d1 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -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; diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h index 17cb108b7db..3118ede2c67 100644 --- a/include/linux/usbdevice_fs.h +++ b/include/linux/usbdevice_fs.h @@ -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 -- cgit v1.2.3