diff options
author | David Brownell <david-b@pacbell.net> | 2007-07-22 18:13:13 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-30 16:27:45 -0400 |
commit | a12b8db02035673153bbf19bb3641a08bed9e4b8 (patch) | |
tree | c168c7816fb9da3e3a1596f42c1def295addf77b /drivers/usb | |
parent | e31c18804f584dd838a752f6628e8c15bd7a3372 (diff) |
USB: fix scatterlist PIO case (IOMMU)
Update the scatterlist logic so that PIO options are also disabled
when an IOMMU may have coalesced pages during dma_map_sg() ... it's
not just HIGHMEM that can make trouble supporting both PIO and DMA
based host controller drivers.
There also seems to be a cross-arch issue here, with 64bit powerpc
not using an IOMMU define ... and its IOMMU_VMERGE config can always
be overridden on the kernel command line. So this is better, but
still imperfect.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/message.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 25f63f1096b4..ad4b956380d2 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -411,15 +411,22 @@ int usb_sg_init ( | |||
411 | * Some systems need to revert to PIO when DMA is temporarily | 411 | * Some systems need to revert to PIO when DMA is temporarily |
412 | * unavailable. For their sakes, both transfer_buffer and | 412 | * unavailable. For their sakes, both transfer_buffer and |
413 | * transfer_dma are set when possible. However this can only | 413 | * transfer_dma are set when possible. However this can only |
414 | * work on systems without HIGHMEM, since DMA buffers located | 414 | * work on systems without: |
415 | * in high memory are not directly addressable by the CPU for | 415 | * |
416 | * PIO ... so when HIGHMEM is in use, transfer_buffer is NULL | 416 | * - HIGHMEM, since DMA buffers located in high memory are |
417 | * not directly addressable by the CPU for PIO; | ||
418 | * | ||
419 | * - IOMMU, since dma_map_sg() is allowed to use an IOMMU to | ||
420 | * make virtually discontiguous buffers be "dma-contiguous" | ||
421 | * so that PIO and DMA need diferent numbers of URBs. | ||
422 | * | ||
423 | * So when HIGHMEM or IOMMU are in use, transfer_buffer is NULL | ||
417 | * to prevent stale pointers and to help spot bugs. | 424 | * to prevent stale pointers and to help spot bugs. |
418 | */ | 425 | */ |
419 | if (dma) { | 426 | if (dma) { |
420 | io->urbs [i]->transfer_dma = sg_dma_address (sg + i); | 427 | io->urbs [i]->transfer_dma = sg_dma_address (sg + i); |
421 | len = sg_dma_len (sg + i); | 428 | len = sg_dma_len (sg + i); |
422 | #ifdef CONFIG_HIGHMEM | 429 | #if defined(CONFIG_HIGHMEM) || defined(CONFIG_IOMMU) |
423 | io->urbs[i]->transfer_buffer = NULL; | 430 | io->urbs[i]->transfer_buffer = NULL; |
424 | #else | 431 | #else |
425 | io->urbs[i]->transfer_buffer = | 432 | io->urbs[i]->transfer_buffer = |