diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-07-30 17:04:37 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:55:00 -0400 |
commit | 5b653c79c04c6b152b8dc7d18f8c8a7f77f4b235 (patch) | |
tree | 4ab74a90333751269f277789c3f45f7c06d07e14 /drivers/usb/core/urb.c | |
parent | a96173af521a173f45d3a27fa24265081f12e978 (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.c | 65 |
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 | */ |
278 | int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | 278 | int 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); |