diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2010-05-05 15:26:17 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:42 -0400 |
commit | 0ba169aff9181389f30f225ad92e113eeb2290b9 (patch) | |
tree | 50dc210826805224c8b2941dfcfbf55ffb4e3c02 /drivers/usb/core | |
parent | a9914127e834acf648a96c72b4e271dc0c1c7c74 (diff) |
USB: simplify usb_sg_init()
This patch (as1377) simplifies the code in usb_sg_init(), without
changing its functionality. It also removes a couple of unused fields
from the usb_sg_request structure.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/message.c | 93 |
1 files changed, 38 insertions, 55 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 63919b8abee1..a73e08fdab36 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -371,79 +371,64 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
371 | spin_lock_init(&io->lock); | 371 | spin_lock_init(&io->lock); |
372 | io->dev = dev; | 372 | io->dev = dev; |
373 | io->pipe = pipe; | 373 | io->pipe = pipe; |
374 | io->sg = sg; | ||
375 | io->nents = nents; | ||
376 | io->entries = nents; | ||
377 | 374 | ||
378 | /* initialize all the urbs we'll use */ | ||
379 | if (dev->bus->sg_tablesize > 0) { | 375 | if (dev->bus->sg_tablesize > 0) { |
380 | io->urbs = kmalloc(sizeof *io->urbs, mem_flags); | ||
381 | use_sg = true; | 376 | use_sg = true; |
377 | io->entries = 1; | ||
382 | } else { | 378 | } else { |
383 | io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); | ||
384 | use_sg = false; | 379 | use_sg = false; |
380 | io->entries = nents; | ||
385 | } | 381 | } |
382 | |||
383 | /* initialize all the urbs we'll use */ | ||
384 | io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); | ||
386 | if (!io->urbs) | 385 | if (!io->urbs) |
387 | goto nomem; | 386 | goto nomem; |
388 | 387 | ||
389 | urb_flags = 0; | 388 | urb_flags = URB_NO_INTERRUPT; |
390 | if (usb_pipein(pipe)) | 389 | if (usb_pipein(pipe)) |
391 | urb_flags |= URB_SHORT_NOT_OK; | 390 | urb_flags |= URB_SHORT_NOT_OK; |
392 | 391 | ||
393 | if (use_sg) { | 392 | for_each_sg(sg, sg, io->entries, i) { |
394 | io->urbs[0] = usb_alloc_urb(0, mem_flags); | 393 | struct urb *urb; |
395 | if (!io->urbs[0]) { | 394 | unsigned len; |
396 | io->entries = 0; | ||
397 | goto nomem; | ||
398 | } | ||
399 | |||
400 | io->urbs[0]->dev = NULL; | ||
401 | io->urbs[0]->pipe = pipe; | ||
402 | io->urbs[0]->interval = period; | ||
403 | io->urbs[0]->transfer_flags = urb_flags; | ||
404 | 395 | ||
405 | io->urbs[0]->complete = sg_complete; | 396 | urb = usb_alloc_urb(0, mem_flags); |
406 | io->urbs[0]->context = io; | 397 | if (!urb) { |
407 | 398 | io->entries = i; | |
408 | /* A length of zero means transfer the whole sg list */ | 399 | goto nomem; |
409 | io->urbs[0]->transfer_buffer_length = length; | ||
410 | if (length == 0) { | ||
411 | for_each_sg(sg, sg, io->entries, i) { | ||
412 | io->urbs[0]->transfer_buffer_length += | ||
413 | sg->length; | ||
414 | } | ||
415 | } | 400 | } |
416 | io->urbs[0]->sg = sg; | 401 | io->urbs[i] = urb; |
417 | io->urbs[0]->num_sgs = io->entries; | 402 | |
418 | io->entries = 1; | 403 | urb->dev = NULL; |
419 | } else { | 404 | urb->pipe = pipe; |
420 | urb_flags |= URB_NO_INTERRUPT; | 405 | urb->interval = period; |
421 | for_each_sg(sg, sg, io->entries, i) { | 406 | urb->transfer_flags = urb_flags; |
422 | unsigned len; | 407 | urb->complete = sg_complete; |
423 | 408 | urb->context = io; | |
424 | io->urbs[i] = usb_alloc_urb(0, mem_flags); | 409 | urb->sg = sg; |
425 | if (!io->urbs[i]) { | 410 | |
426 | io->entries = i; | 411 | if (use_sg) { |
427 | goto nomem; | 412 | /* There is no single transfer buffer */ |
413 | urb->transfer_buffer = NULL; | ||
414 | urb->num_sgs = nents; | ||
415 | |||
416 | /* A length of zero means transfer the whole sg list */ | ||
417 | len = length; | ||
418 | if (len == 0) { | ||
419 | for_each_sg(sg, sg, nents, i) | ||
420 | len += sg->length; | ||
428 | } | 421 | } |
429 | 422 | } else { | |
430 | io->urbs[i]->dev = NULL; | ||
431 | io->urbs[i]->pipe = pipe; | ||
432 | io->urbs[i]->interval = period; | ||
433 | io->urbs[i]->transfer_flags = urb_flags; | ||
434 | |||
435 | io->urbs[i]->complete = sg_complete; | ||
436 | io->urbs[i]->context = io; | ||
437 | |||
438 | /* | 423 | /* |
439 | * Some systems can't use DMA; they use PIO instead. | 424 | * Some systems can't use DMA; they use PIO instead. |
440 | * For their sakes, transfer_buffer is set whenever | 425 | * For their sakes, transfer_buffer is set whenever |
441 | * possible. | 426 | * possible. |
442 | */ | 427 | */ |
443 | if (!PageHighMem(sg_page(sg))) | 428 | if (!PageHighMem(sg_page(sg))) |
444 | io->urbs[i]->transfer_buffer = sg_virt(sg); | 429 | urb->transfer_buffer = sg_virt(sg); |
445 | else | 430 | else |
446 | io->urbs[i]->transfer_buffer = NULL; | 431 | urb->transfer_buffer = NULL; |
447 | 432 | ||
448 | len = sg->length; | 433 | len = sg->length; |
449 | if (length) { | 434 | if (length) { |
@@ -452,12 +437,10 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
452 | if (length == 0) | 437 | if (length == 0) |
453 | io->entries = i + 1; | 438 | io->entries = i + 1; |
454 | } | 439 | } |
455 | io->urbs[i]->transfer_buffer_length = len; | ||
456 | |||
457 | io->urbs[i]->sg = sg; | ||
458 | } | 440 | } |
459 | io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; | 441 | urb->transfer_buffer_length = len; |
460 | } | 442 | } |
443 | io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; | ||
461 | 444 | ||
462 | /* transaction state */ | 445 | /* transaction state */ |
463 | io->count = io->entries; | 446 | io->count = io->entries; |