diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/devio.c | 22 | ||||
-rw-r--r-- | drivers/usb/core/urb.c | 7 |
2 files changed, 20 insertions, 9 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index a678186f218f..431d17287a86 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1104,13 +1104,25 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, case USB_ENDPOINT_XFER_CONTROL: case USB_ENDPOINT_XFER_ISOC: return -EINVAL; - /* allow single-shot interrupt transfers, at bogus rates */ + case USB_ENDPOINT_XFER_INT: + /* allow single-shot interrupt transfers */ + uurb->type = USBDEVFS_URB_TYPE_INTERRUPT; + goto interrupt_urb; } uurb->number_of_packets = 0; if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) return -EINVAL; break; + case USBDEVFS_URB_TYPE_INTERRUPT: + if (!usb_endpoint_xfer_int(&ep->desc)) + return -EINVAL; + interrupt_urb: + uurb->number_of_packets = 0; + if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) + return -EINVAL; + break; + case USBDEVFS_URB_TYPE_ISO: /* arbitrary limit */ if (uurb->number_of_packets < 1 || @@ -1143,14 +1155,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, uurb->buffer_length = totlen; break; - case USBDEVFS_URB_TYPE_INTERRUPT: - uurb->number_of_packets = 0; - if (!usb_endpoint_xfer_int(&ep->desc)) - return -EINVAL; - if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) - return -EINVAL; - break; - default: return -EINVAL; } diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index e7cae1334693..e2bd153cbd89 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -387,6 +387,13 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) { unsigned int orig_flags = urb->transfer_flags; unsigned int allowed; + static int pipetypes[4] = { + PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT + }; + + /* Check that the pipe's type matches the endpoint's type */ + if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) + return -EPIPE; /* The most suitable error code :-) */ /* enforce simple/standard policy */ allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | |