Skip to content

Commit

Permalink
USB: fix scatterlist PIO case (IOMMU)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David Brownell authored and Greg Kroah-Hartman committed Jul 30, 2007
1 parent e31c188 commit a12b8db
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions drivers/usb/core/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,22 @@ int usb_sg_init (
* Some systems need to revert to PIO when DMA is temporarily
* unavailable. For their sakes, both transfer_buffer and
* transfer_dma are set when possible. However this can only
* work on systems without HIGHMEM, since DMA buffers located
* in high memory are not directly addressable by the CPU for
* PIO ... so when HIGHMEM is in use, transfer_buffer is NULL
* work on systems without:
*
* - HIGHMEM, since DMA buffers located in high memory are
* not directly addressable by the CPU for PIO;
*
* - IOMMU, since dma_map_sg() is allowed to use an IOMMU to
* make virtually discontiguous buffers be "dma-contiguous"
* so that PIO and DMA need diferent numbers of URBs.
*
* So when HIGHMEM or IOMMU are in use, transfer_buffer is NULL
* to prevent stale pointers and to help spot bugs.
*/
if (dma) {
io->urbs [i]->transfer_dma = sg_dma_address (sg + i);
len = sg_dma_len (sg + i);
#ifdef CONFIG_HIGHMEM
#if defined(CONFIG_HIGHMEM) || defined(CONFIG_IOMMU)
io->urbs[i]->transfer_buffer = NULL;
#else
io->urbs[i]->transfer_buffer =
Expand Down

0 comments on commit a12b8db

Please sign in to comment.