diff options
-rw-r--r-- | Documentation/usb/error-codes.txt | 6 | ||||
-rw-r--r-- | drivers/usb/core/devio.c | 22 | ||||
-rw-r--r-- | drivers/usb/core/urb.c | 7 |
3 files changed, 24 insertions, 11 deletions
diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt index 9cf83e8c27b8..d83703ea74b2 100644 --- a/Documentation/usb/error-codes.txt +++ b/Documentation/usb/error-codes.txt | |||
@@ -41,8 +41,8 @@ USB-specific: | |||
41 | 41 | ||
42 | -EFBIG Host controller driver can't schedule that many ISO frames. | 42 | -EFBIG Host controller driver can't schedule that many ISO frames. |
43 | 43 | ||
44 | -EPIPE Specified endpoint is stalled. For non-control endpoints, | 44 | -EPIPE The pipe type specified in the URB doesn't match the |
45 | reset this status with usb_clear_halt(). | 45 | endpoint's actual type. |
46 | 46 | ||
47 | -EMSGSIZE (a) endpoint maxpacket size is zero; it is not usable | 47 | -EMSGSIZE (a) endpoint maxpacket size is zero; it is not usable |
48 | in the current interface altsetting. | 48 | in the current interface altsetting. |
@@ -60,6 +60,8 @@ USB-specific: | |||
60 | 60 | ||
61 | -EHOSTUNREACH URB was rejected because the device is suspended. | 61 | -EHOSTUNREACH URB was rejected because the device is suspended. |
62 | 62 | ||
63 | -ENOEXEC A control URB doesn't contain a Setup packet. | ||
64 | |||
63 | 65 | ||
64 | ************************************************************************** | 66 | ************************************************************************** |
65 | * Error codes returned by in urb->status * | 67 | * Error codes returned by in urb->status * |
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, | |||
1104 | case USB_ENDPOINT_XFER_CONTROL: | 1104 | case USB_ENDPOINT_XFER_CONTROL: |
1105 | case USB_ENDPOINT_XFER_ISOC: | 1105 | case USB_ENDPOINT_XFER_ISOC: |
1106 | return -EINVAL; | 1106 | return -EINVAL; |
1107 | /* allow single-shot interrupt transfers, at bogus rates */ | 1107 | case USB_ENDPOINT_XFER_INT: |
1108 | /* allow single-shot interrupt transfers */ | ||
1109 | uurb->type = USBDEVFS_URB_TYPE_INTERRUPT; | ||
1110 | goto interrupt_urb; | ||
1108 | } | 1111 | } |
1109 | uurb->number_of_packets = 0; | 1112 | uurb->number_of_packets = 0; |
1110 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1113 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
1111 | return -EINVAL; | 1114 | return -EINVAL; |
1112 | break; | 1115 | break; |
1113 | 1116 | ||
1117 | case USBDEVFS_URB_TYPE_INTERRUPT: | ||
1118 | if (!usb_endpoint_xfer_int(&ep->desc)) | ||
1119 | return -EINVAL; | ||
1120 | interrupt_urb: | ||
1121 | uurb->number_of_packets = 0; | ||
1122 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | ||
1123 | return -EINVAL; | ||
1124 | break; | ||
1125 | |||
1114 | case USBDEVFS_URB_TYPE_ISO: | 1126 | case USBDEVFS_URB_TYPE_ISO: |
1115 | /* arbitrary limit */ | 1127 | /* arbitrary limit */ |
1116 | if (uurb->number_of_packets < 1 || | 1128 | if (uurb->number_of_packets < 1 || |
@@ -1143,14 +1155,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1143 | uurb->buffer_length = totlen; | 1155 | uurb->buffer_length = totlen; |
1144 | break; | 1156 | break; |
1145 | 1157 | ||
1146 | case USBDEVFS_URB_TYPE_INTERRUPT: | ||
1147 | uurb->number_of_packets = 0; | ||
1148 | if (!usb_endpoint_xfer_int(&ep->desc)) | ||
1149 | return -EINVAL; | ||
1150 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | ||
1151 | return -EINVAL; | ||
1152 | break; | ||
1153 | |||
1154 | default: | 1158 | default: |
1155 | return -EINVAL; | 1159 | return -EINVAL; |
1156 | } | 1160 | } |
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) | |||
387 | { | 387 | { |
388 | unsigned int orig_flags = urb->transfer_flags; | 388 | unsigned int orig_flags = urb->transfer_flags; |
389 | unsigned int allowed; | 389 | unsigned int allowed; |
390 | static int pipetypes[4] = { | ||
391 | PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT | ||
392 | }; | ||
393 | |||
394 | /* Check that the pipe's type matches the endpoint's type */ | ||
395 | if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) | ||
396 | return -EPIPE; /* The most suitable error code :-) */ | ||
390 | 397 | ||
391 | /* enforce simple/standard policy */ | 398 | /* enforce simple/standard policy */ |
392 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | | 399 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | |