diff options
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/message.c | 32 |
1 files changed, 10 insertions, 22 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 9720e699f47..da718e84d58 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -459,35 +459,23 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
459 | io->urbs[i]->context = io; | 459 | io->urbs[i]->context = io; |
460 | 460 | ||
461 | /* | 461 | /* |
462 | * Some systems need to revert to PIO when DMA is | 462 | * Some systems need to revert to PIO when DMA is temporarily |
463 | * temporarily unavailable. For their sakes, both | 463 | * unavailable. For their sakes, both transfer_buffer and |
464 | * transfer_buffer and transfer_dma are set when | 464 | * transfer_dma are set when possible. |
465 | * possible. However this can only work on systems | ||
466 | * without: | ||
467 | * | 465 | * |
468 | * - HIGHMEM, since DMA buffers located in high memory | 466 | * Note that if IOMMU coalescing occurred, we cannot |
469 | * are not directly addressable by the CPU for PIO; | 467 | * trust sg_page anymore, so check if S/G list shrunk. |
470 | * | ||
471 | * - IOMMU, since dma_map_sg() is allowed to use an | ||
472 | * IOMMU to make virtually discontiguous buffers be | ||
473 | * "dma-contiguous" so that PIO and DMA need diferent | ||
474 | * numbers of URBs. | ||
475 | * | ||
476 | * So when HIGHMEM or IOMMU are in use, transfer_buffer | ||
477 | * is NULL to prevent stale pointers and to help spot | ||
478 | * bugs. | ||
479 | */ | 468 | */ |
469 | if (io->nents == io->entries && !PageHighMem(sg_page(sg))) | ||
470 | io->urbs[i]->transfer_buffer = sg_virt(sg); | ||
471 | else | ||
472 | io->urbs[i]->transfer_buffer = NULL; | ||
473 | |||
480 | if (dma) { | 474 | if (dma) { |
481 | io->urbs[i]->transfer_dma = sg_dma_address(sg); | 475 | io->urbs[i]->transfer_dma = sg_dma_address(sg); |
482 | len = sg_dma_len(sg); | 476 | len = sg_dma_len(sg); |
483 | #if defined(CONFIG_HIGHMEM) || defined(CONFIG_GART_IOMMU) | ||
484 | io->urbs[i]->transfer_buffer = NULL; | ||
485 | #else | ||
486 | io->urbs[i]->transfer_buffer = sg_virt(sg); | ||
487 | #endif | ||
488 | } else { | 477 | } else { |
489 | /* hc may use _only_ transfer_buffer */ | 478 | /* hc may use _only_ transfer_buffer */ |
490 | io->urbs[i]->transfer_buffer = sg_virt(sg); | ||
491 | len = sg->length; | 479 | len = sg->length; |
492 | } | 480 | } |
493 | 481 | ||