diff options
| author | Roland Dreier <rdreier@cisco.com> | 2006-12-06 18:15:38 -0500 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2006-12-08 01:10:18 -0500 |
| commit | 1d4454e7ce30239e67b154ae08f6d906b9737334 (patch) | |
| tree | 293946b4886a2b9cae9e70479cdd2ab678dd94c4 /include/asm-ppc | |
| parent | 885ed0fb484cc2d0a539558edf47a2a7c4fdd664 (diff) | |
[POWERPC] Define pci_unmap_addr() et al. when CONFIG_NOT_COHERENT_CACHE=y
The current PowerPC code makes pci_unmap_addr(), pci_unmap_addr_set(),
and friends trivial for all 32-bit kernels. This is reasonable, since
for those kernels it is true that pci_unmap_single() does not need the
DMA address from the original DMA mapping -- in fact, it is a NOP.
However, I recently tried the tg3 driver on a PowerPC 440SPe machine,
which runs a 32-bit kernel and has non-cache-coherent PCI DMA. I
found that the tg3 driver crashed in pci_dma_sync_single_for_cpu(),
since for non-coherent systems, that function must invalidate the
cache for the DMA address range requested, and therefore it does use
the address passed in. tg3 uses a DMA address it stashes away with
pci_unmap_addr_set() and retrieves with pci_unmap_addr(). Of course,
since pci_unmap_addr() is defined to (0) right now, this doesn't work.
It seems to me that the tg3 driver is using pci_unmap_addr() in a
legitimate way -- I wouldn't want to have to teach all drivers that
they should use pci_unmap_addr() if they only need the address for
unmapping functions, but if they want the pci_dma_sync functions, then
they have to store the DMA address without the helper macros.
The right fix therefore seems to be in the definition of the macros in
<asm/pci.h> -- we should use the trivial versions only for 32-bit
kernels for coherent systems, and the real versions for both 64-bit
kernels and non-coherent systems.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-ppc')
| -rw-r--r-- | include/asm-ppc/pci.h | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 11ffaaa5da16..9d162028dab9 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h | |||
| @@ -61,6 +61,27 @@ extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr); | |||
| 61 | */ | 61 | */ |
| 62 | #define PCI_DMA_BUS_IS_PHYS (1) | 62 | #define PCI_DMA_BUS_IS_PHYS (1) |
| 63 | 63 | ||
| 64 | #ifdef CONFIG_NOT_COHERENT_CACHE | ||
| 65 | /* | ||
| 66 | * pci_unmap_{page,single} are NOPs but pci_dma_sync_single_for_cpu() | ||
| 67 | * and so on are not, so... | ||
| 68 | */ | ||
| 69 | |||
| 70 | #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ | ||
| 71 | dma_addr_t ADDR_NAME; | ||
| 72 | #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ | ||
| 73 | __u32 LEN_NAME; | ||
| 74 | #define pci_unmap_addr(PTR, ADDR_NAME) \ | ||
| 75 | ((PTR)->ADDR_NAME) | ||
| 76 | #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \ | ||
| 77 | (((PTR)->ADDR_NAME) = (VAL)) | ||
| 78 | #define pci_unmap_len(PTR, LEN_NAME) \ | ||
| 79 | ((PTR)->LEN_NAME) | ||
| 80 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ | ||
| 81 | (((PTR)->LEN_NAME) = (VAL)) | ||
| 82 | |||
| 83 | #else /* coherent */ | ||
| 84 | |||
| 64 | /* pci_unmap_{page,single} is a nop so... */ | 85 | /* pci_unmap_{page,single} is a nop so... */ |
| 65 | #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) | 86 | #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) |
| 66 | #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) | 87 | #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) |
| @@ -69,6 +90,8 @@ extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr); | |||
| 69 | #define pci_unmap_len(PTR, LEN_NAME) (0) | 90 | #define pci_unmap_len(PTR, LEN_NAME) (0) |
| 70 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) | 91 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) |
| 71 | 92 | ||
| 93 | #endif /* CONFIG_NOT_COHERENT_CACHE */ | ||
| 94 | |||
| 72 | #ifdef CONFIG_PCI | 95 | #ifdef CONFIG_PCI |
| 73 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | 96 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, |
| 74 | enum pci_dma_burst_strategy *strat, | 97 | enum pci_dma_burst_strategy *strat, |
