aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/urb.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-07-30 17:04:37 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-12 17:55:00 -0400
commit5b653c79c04c6b152b8dc7d18f8c8a7f77f4b235 (patch)
tree4ab74a90333751269f277789c3f45f7c06d07e14 /drivers/usb/core/urb.c
parenta96173af521a173f45d3a27fa24265081f12e978 (diff)
USB: add urb->ep
This patch (as943) prepares the way for eliminating urb->pipe by introducing an endpoint pointer into struct urb. For now urb->ep is set by usb_submit_urb() from the pipe value; eventually drivers will set it themselves and we will remove urb->pipe completely. The patch also adds new inline routines to retrieve an endpoint descriptor's number and transfer type, essentially as replacements for usb_pipeendpoint and usb_pipetype. usb_submit_urb(), usb_hcd_submit_urb(), and usb_hcd_unlink_urb() are converted to use the new field and new routines. Other parts of usbcore will be converted in later patches. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/urb.c')
-rw-r--r--drivers/usb/core/urb.c65
1 files changed, 35 insertions, 30 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index be630228461..ff53acb4fab 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -277,9 +277,10 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
277 */ 277 */
278int usb_submit_urb(struct urb *urb, gfp_t mem_flags) 278int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
279{ 279{
280 int pipe, temp, max; 280 int xfertype, max;
281 struct usb_device *dev; 281 struct usb_device *dev;
282 int is_out; 282 struct usb_host_endpoint *ep;
283 int is_out;
283 284
284 if (!urb || urb->hcpriv || !urb->complete) 285 if (!urb || urb->hcpriv || !urb->complete)
285 return -EINVAL; 286 return -EINVAL;
@@ -291,30 +292,34 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
291 || dev->state == USB_STATE_SUSPENDED) 292 || dev->state == USB_STATE_SUSPENDED)
292 return -EHOSTUNREACH; 293 return -EHOSTUNREACH;
293 294
295 /* For now, get the endpoint from the pipe. Eventually drivers
296 * will be required to set urb->ep directly and we will eliminate
297 * urb->pipe.
298 */
299 ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out)
300 [usb_pipeendpoint(urb->pipe)];
301 if (!ep)
302 return -ENOENT;
303
304 urb->ep = ep;
294 urb->status = -EINPROGRESS; 305 urb->status = -EINPROGRESS;
295 urb->actual_length = 0; 306 urb->actual_length = 0;
296 307
297 /* Lots of sanity checks, so HCDs can rely on clean data 308 /* Lots of sanity checks, so HCDs can rely on clean data
298 * and don't need to duplicate tests 309 * and don't need to duplicate tests
299 */ 310 */
300 pipe = urb->pipe; 311 xfertype = usb_endpoint_type(&ep->desc);
301 temp = usb_pipetype(pipe); 312 is_out = usb_pipeout(urb->pipe);
302 is_out = usb_pipeout(pipe);
303 313
304 if (!usb_pipecontrol(pipe) && dev->state < USB_STATE_CONFIGURED) 314 if (xfertype != USB_ENDPOINT_XFER_CONTROL &&
315 dev->state < USB_STATE_CONFIGURED)
305 return -ENODEV; 316 return -ENODEV;
306 317
307 /* FIXME there should be a sharable lock protecting us against 318 max = le16_to_cpu(ep->desc.wMaxPacketSize);
308 * config/altsetting changes and disconnects, kicking in here.
309 * (here == before maxpacket, and eventually endpoint type,
310 * checks get made.)
311 */
312
313 max = usb_maxpacket(dev, pipe, is_out);
314 if (max <= 0) { 319 if (max <= 0) {
315 dev_dbg(&dev->dev, 320 dev_dbg(&dev->dev,
316 "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", 321 "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",
317 usb_pipeendpoint(pipe), is_out ? "out" : "in", 322 usb_endpoint_num(&ep->desc), is_out ? "out" : "in",
318 __FUNCTION__, max); 323 __FUNCTION__, max);
319 return -EMSGSIZE; 324 return -EMSGSIZE;
320 } 325 }
@@ -323,7 +328,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
323 * but drivers only control those sizes for ISO. 328 * but drivers only control those sizes for ISO.
324 * while we're checking, initialize return status. 329 * while we're checking, initialize return status.
325 */ 330 */
326 if (temp == PIPE_ISOCHRONOUS) { 331 if (xfertype == USB_ENDPOINT_XFER_ISOC) {
327 int n, len; 332 int n, len;
328 333
329 /* "high bandwidth" mode, 1-3 packets/uframe? */ 334 /* "high bandwidth" mode, 1-3 packets/uframe? */
@@ -359,19 +364,19 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
359 /* enforce simple/standard policy */ 364 /* enforce simple/standard policy */
360 allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | 365 allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
361 URB_NO_INTERRUPT); 366 URB_NO_INTERRUPT);
362 switch (temp) { 367 switch (xfertype) {
363 case PIPE_BULK: 368 case USB_ENDPOINT_XFER_BULK:
364 if (is_out) 369 if (is_out)
365 allowed |= URB_ZERO_PACKET; 370 allowed |= URB_ZERO_PACKET;
366 /* FALLTHROUGH */ 371 /* FALLTHROUGH */
367 case PIPE_CONTROL: 372 case USB_ENDPOINT_XFER_CONTROL:
368 allowed |= URB_NO_FSBR; /* only affects UHCI */ 373 allowed |= URB_NO_FSBR; /* only affects UHCI */
369 /* FALLTHROUGH */ 374 /* FALLTHROUGH */
370 default: /* all non-iso endpoints */ 375 default: /* all non-iso endpoints */
371 if (!is_out) 376 if (!is_out)
372 allowed |= URB_SHORT_NOT_OK; 377 allowed |= URB_SHORT_NOT_OK;
373 break; 378 break;
374 case PIPE_ISOCHRONOUS: 379 case USB_ENDPOINT_XFER_ISOC:
375 allowed |= URB_ISO_ASAP; 380 allowed |= URB_ISO_ASAP;
376 break; 381 break;
377 } 382 }
@@ -393,9 +398,9 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
393 * supports different values... this uses EHCI/UHCI defaults (and 398 * supports different values... this uses EHCI/UHCI defaults (and
394 * EHCI can use smaller non-default values). 399 * EHCI can use smaller non-default values).
395 */ 400 */
396 switch (temp) { 401 switch (xfertype) {
397 case PIPE_ISOCHRONOUS: 402 case USB_ENDPOINT_XFER_ISOC:
398 case PIPE_INTERRUPT: 403 case USB_ENDPOINT_XFER_INT:
399 /* too small? */ 404 /* too small? */
400 if (urb->interval <= 0) 405 if (urb->interval <= 0)
401 return -EINVAL; 406 return -EINVAL;
@@ -405,29 +410,29 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
405 // NOTE usb handles 2^15 410 // NOTE usb handles 2^15
406 if (urb->interval > (1024 * 8)) 411 if (urb->interval > (1024 * 8))
407 urb->interval = 1024 * 8; 412 urb->interval = 1024 * 8;
408 temp = 1024 * 8; 413 max = 1024 * 8;
409 break; 414 break;
410 case USB_SPEED_FULL: /* units are frames/msec */ 415 case USB_SPEED_FULL: /* units are frames/msec */
411 case USB_SPEED_LOW: 416 case USB_SPEED_LOW:
412 if (temp == PIPE_INTERRUPT) { 417 if (xfertype == USB_ENDPOINT_XFER_INT) {
413 if (urb->interval > 255) 418 if (urb->interval > 255)
414 return -EINVAL; 419 return -EINVAL;
415 // NOTE ohci only handles up to 32 420 // NOTE ohci only handles up to 32
416 temp = 128; 421 max = 128;
417 } else { 422 } else {
418 if (urb->interval > 1024) 423 if (urb->interval > 1024)
419 urb->interval = 1024; 424 urb->interval = 1024;
420 // NOTE usb and ohci handle up to 2^15 425 // NOTE usb and ohci handle up to 2^15
421 temp = 1024; 426 max = 1024;
422 } 427 }
423 break; 428 break;
424 default: 429 default:
425 return -EINVAL; 430 return -EINVAL;
426 } 431 }
427 /* power of two? */ 432 /* power of two? */
428 while (temp > urb->interval) 433 while (max > urb->interval)
429 temp >>= 1; 434 max >>= 1;
430 urb->interval = temp; 435 urb->interval = max;
431 } 436 }
432 437
433 return usb_hcd_submit_urb(urb, mem_flags); 438 return usb_hcd_submit_urb(urb, mem_flags);