debuggers.hg

view linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pci.h @ 6681:d647c3d381d2

The attached patch fixes two problems I ran into with the swiotlb code
in unstable (changeset aeaa3c83f6e5). Tested on a dual Opteron x86-64
machine with 4GB of memory and a tg3 modified to only DMA below 2GB.

- swiotlb_dma_supported() checked that the device DMA mask was equal
or bigger than 4GB, when in fact all that's needed is that the device
be able to DMA into the swiotlb aperture (1GB on my AMD x86-64
machine). Some device are actually only 31-bit DMA capable, so this
would've tripped them.

- On some platforms, PCI unmaps and syncs are nops, so there's no need to
keep track of the dma_addr they need after the initial mapping. The
DMA API supports this via the DECLARE_PCI_UNMAP_ADDR macros (see
Documentation/DMA-mapping.txt). Since the swiotlb code does make us of
the dma_addr for swiotlb_unmap_xxx and (more importantly)
swiotlb_dma_sync_xxx, we need to define them to something
meaningful.

Signed-Off-By: Muli Ben-Yehuda <mulix@mulix.org>
author kaf24@firebug.cl.cam.ac.uk
date Tue Sep 06 18:25:00 2005 +0000 (2005-09-06)
parents dd668f7527cb
children 8db9c5873b9b
line source
1 #ifndef __x8664_PCI_H
2 #define __x8664_PCI_H
4 #include <linux/config.h>
5 #include <asm/io.h>
7 #ifdef __KERNEL__
9 #include <linux/mm.h> /* for struct page */
11 /* Can be used to override the logic in pci_scan_bus for skipping
12 already-configured bus numbers - to be used for buggy BIOSes
13 or architectures with incomplete PCI setup by the loader */
15 #ifdef CONFIG_PCI
16 extern unsigned int pcibios_assign_all_busses(void);
17 #else
18 #define pcibios_assign_all_busses() 0
19 #endif
20 #define pcibios_scan_all_fns(a, b) 0
22 extern int no_iommu, force_iommu;
24 extern unsigned long pci_mem_start;
25 #define PCIBIOS_MIN_IO 0x1000
26 #define PCIBIOS_MIN_MEM (pci_mem_start)
28 #define PCIBIOS_MIN_CARDBUS_IO 0x4000
30 void pcibios_config_init(void);
31 struct pci_bus * pcibios_scan_root(int bus);
32 extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
33 extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
35 void pcibios_set_master(struct pci_dev *dev);
36 void pcibios_penalize_isa_irq(int irq);
37 struct irq_routing_table *pcibios_get_irq_routing_table(void);
38 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
40 #include <linux/types.h>
41 #include <linux/slab.h>
42 #include <asm/scatterlist.h>
43 #include <linux/string.h>
44 #include <asm/page.h>
46 extern int iommu_setup(char *opt);
48 #ifdef CONFIG_GART_IOMMU
49 /* The PCI address space does equal the physical memory
50 * address space. The networking and block device layers use
51 * this boolean for bounce buffer decisions
52 *
53 * On AMD64 it mostly equals, but we set it to zero to tell some subsystems
54 * that an IOMMU is available.
55 */
56 #define PCI_DMA_BUS_IS_PHYS (no_iommu ? 1 : 0)
58 /*
59 * x86-64 always supports DAC, but sometimes it is useful to force
60 * devices through the IOMMU to get automatic sg list merging.
61 * Optional right now.
62 */
63 extern int iommu_sac_force;
64 #define pci_dac_dma_supported(pci_dev, mask) (!iommu_sac_force)
66 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
67 dma_addr_t ADDR_NAME;
68 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
69 __u32 LEN_NAME;
70 #define pci_unmap_addr(PTR, ADDR_NAME) \
71 ((PTR)->ADDR_NAME)
72 #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
73 (((PTR)->ADDR_NAME) = (VAL))
74 #define pci_unmap_len(PTR, LEN_NAME) \
75 ((PTR)->LEN_NAME)
76 #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
77 (((PTR)->LEN_NAME) = (VAL))
79 #elif defined(CONFIG_SWIOTLB)
81 #define PCI_DMA_BUS_IS_PHYS 0
83 #define pci_dac_dma_supported(pci_dev, mask) 1
85 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
86 dma_addr_t ADDR_NAME;
87 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
88 __u32 LEN_NAME;
89 #define pci_unmap_addr(PTR, ADDR_NAME) \
90 ((PTR)->ADDR_NAME)
91 #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
92 (((PTR)->ADDR_NAME) = (VAL))
93 #define pci_unmap_len(PTR, LEN_NAME) \
94 ((PTR)->LEN_NAME)
95 #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
96 (((PTR)->LEN_NAME) = (VAL))
98 #else
99 /* No IOMMU */
101 #define PCI_DMA_BUS_IS_PHYS 1
102 #define pci_dac_dma_supported(pci_dev, mask) 1
104 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
105 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
106 #define pci_unmap_addr(PTR, ADDR_NAME) (0)
107 #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
108 #define pci_unmap_len(PTR, LEN_NAME) (0)
109 #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
111 #endif
113 #include <asm-generic/pci-dma-compat.h>
115 static inline dma64_addr_t
116 pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
117 {
118 return ((dma64_addr_t) page_to_phys(page) +
119 (dma64_addr_t) offset);
120 }
122 static inline struct page *
123 pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
124 {
125 return virt_to_page(__va(dma_addr));
126 }
128 static inline unsigned long
129 pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
130 {
131 return (dma_addr & ~PAGE_MASK);
132 }
134 static inline void
135 pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
136 {
137 }
139 static inline void
140 pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
141 {
142 flush_write_buffers();
143 }
145 #define HAVE_PCI_MMAP
146 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
147 enum pci_mmap_state mmap_state, int write_combine);
149 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
150 {
151 }
153 #endif /* __KERNEL__ */
155 /* generic pci stuff */
156 #ifdef CONFIG_PCI
157 #include <asm-generic/pci.h>
158 #endif
160 /* On Xen we have to scan all functions since Xen hides bridges from
161 * us. If a bridge is at fn=0 and that slot has a multifunction
162 * device, we won't find the additional devices without scanning all
163 * functions. */
164 #undef pcibios_scan_all_fns
165 #define pcibios_scan_all_fns(a, b) 1
167 #endif /* __x8664_PCI_H */