aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/usb/error-codes.txt6
-rw-r--r--drivers/usb/core/devio.c22
-rw-r--r--drivers/usb/core/urb.c7
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 |