diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-22 18:07:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-22 18:07:59 -0400 |
commit | 6c763eb9ead86c612492b59287b36c0dcf7d09b1 (patch) | |
tree | 46497ff44bcf909517bffac70f0d6c7ad45ae1f0 /arch | |
parent | dcc1a66a09420ccc5a22671bddc5a842f92d67e5 (diff) | |
parent | cf34a8e07f02c76f3f1232eecb681301a3d7b10b (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6: (27 commits)
[PATCH] PCI: nVidia quirk to make AER PCI-E extended capability visible
[PATCH] PCI: fix issues with extended conf space when MMCONFIG disabled because of e820
[PATCH] PCI: Bus Parity Status sysfs interface
[PATCH] PCI: fix memory leak in MMCONFIG error path
[PATCH] PCI: fix error with pci_get_device() call in the mpc85xx driver
[PATCH] PCI: MSI-K8T-Neo2-Fir: run only where needed
[PATCH] PCI: fix race with pci_walk_bus and pci_destroy_dev
[PATCH] PCI: clean up pci documentation to be more specific
[PATCH] PCI: remove unneeded msi code
[PATCH] PCI: don't move ioapics below PCI bridge
[PATCH] PCI: cleanup unused variable about msi driver
[PATCH] PCI: disable msi mode in pci_disable_device
[PATCH] PCI: Allow MSI to work on kexec kernel
[PATCH] PCI: AMD 8131 MSI quirk called too late, bus_flags not inherited ?
[PATCH] PCI: Move various PCI IDs to header file
[PATCH] PCI Bus Parity Status-broken hardware attribute, EDAC foundation
[PATCH] PCI: i386/x86_84: disable PCI resource decode on device disable
[PATCH] PCI ACPI: Rename the functions to avoid multiple instances.
[PATCH] PCI: don't enable device if already enabled
[PATCH] PCI: Add a "enable" sysfs attribute to the pci devices to allow userspace (Xorg) to enable devices without doing foul direct access
...
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/common.c | 1 | ||||
-rw-r--r-- | arch/i386/pci/i386.c | 9 | ||||
-rw-r--r-- | arch/i386/pci/mmconfig.c | 9 | ||||
-rw-r--r-- | arch/i386/pci/pci.h | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/irq_ia64.c | 19 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 9 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/irq.c | 142 | ||||
-rw-r--r-- | arch/ia64/sn/pci/pci_dma.c | 10 | ||||
-rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_dma.c | 62 | ||||
-rw-r--r-- | arch/ia64/sn/pci/tioca_provider.c | 8 | ||||
-rw-r--r-- | arch/ia64/sn/pci/tioce_provider.c | 65 | ||||
-rw-r--r-- | arch/ppc/platforms/85xx/mpc85xx_cds_common.c | 9 | ||||
-rw-r--r-- | arch/x86_64/pci/mmconfig.c | 13 |
14 files changed, 235 insertions, 124 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 40e5aba3ad3d..fbe93084244c 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -202,6 +202,8 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | |||
202 | if (mcfg->config[i].base_reserved) { | 202 | if (mcfg->config[i].base_reserved) { |
203 | printk(KERN_ERR PREFIX | 203 | printk(KERN_ERR PREFIX |
204 | "MMCONFIG not in low 4GB of memory\n"); | 204 | "MMCONFIG not in low 4GB of memory\n"); |
205 | kfree(pci_mmcfg_config); | ||
206 | pci_mmcfg_config_num = 0; | ||
205 | return -ENODEV; | 207 | return -ENODEV; |
206 | } | 208 | } |
207 | } | 209 | } |
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index dbece776c5b2..c624b61e1104 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -288,6 +288,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
288 | 288 | ||
289 | void pcibios_disable_device (struct pci_dev *dev) | 289 | void pcibios_disable_device (struct pci_dev *dev) |
290 | { | 290 | { |
291 | pcibios_disable_resources(dev); | ||
291 | if (pcibios_disable_irq) | 292 | if (pcibios_disable_irq) |
292 | pcibios_disable_irq(dev); | 293 | pcibios_disable_irq(dev); |
293 | } | 294 | } |
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index ed2c8c899bd3..7852827a599b 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c | |||
@@ -242,6 +242,15 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) | |||
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
244 | 244 | ||
245 | void pcibios_disable_resources(struct pci_dev *dev) | ||
246 | { | ||
247 | u16 cmd; | ||
248 | |||
249 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
250 | cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); | ||
251 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
252 | } | ||
253 | |||
245 | /* | 254 | /* |
246 | * If we set up a device for bus mastering, we need to check the latency | 255 | * If we set up a device for bus mastering, we need to check the latency |
247 | * timer as certain crappy BIOSes forget to set it properly. | 256 | * timer as certain crappy BIOSes forget to set it properly. |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 6b1ea0c9a570..e545b0992c48 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -15,7 +15,9 @@ | |||
15 | #include <asm/e820.h> | 15 | #include <asm/e820.h> |
16 | #include "pci.h" | 16 | #include "pci.h" |
17 | 17 | ||
18 | #define MMCONFIG_APER_SIZE (256*1024*1024) | 18 | /* aperture is up to 256MB but BIOS may reserve less */ |
19 | #define MMCONFIG_APER_MIN (2 * 1024*1024) | ||
20 | #define MMCONFIG_APER_MAX (256 * 1024*1024) | ||
19 | 21 | ||
20 | /* Assume systems with more busses have correct MCFG */ | 22 | /* Assume systems with more busses have correct MCFG */ |
21 | #define MAX_CHECK_BUS 16 | 23 | #define MAX_CHECK_BUS 16 |
@@ -197,9 +199,10 @@ void __init pci_mmcfg_init(void) | |||
197 | return; | 199 | return; |
198 | 200 | ||
199 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | 201 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, |
200 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | 202 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, |
201 | E820_RESERVED)) { | 203 | E820_RESERVED)) { |
202 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | 204 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", |
205 | pci_mmcfg_config[0].base_address); | ||
203 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | 206 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); |
204 | return; | 207 | return; |
205 | } | 208 | } |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index 12035e29108b..12bf3d8dda29 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -35,6 +35,7 @@ extern unsigned int pcibios_max_latency; | |||
35 | 35 | ||
36 | void pcibios_resource_survey(void); | 36 | void pcibios_resource_survey(void); |
37 | int pcibios_enable_resources(struct pci_dev *, int); | 37 | int pcibios_enable_resources(struct pci_dev *, int); |
38 | void pcibios_disable_resources(struct pci_dev *); | ||
38 | 39 | ||
39 | /* pci-pc.c */ | 40 | /* pci-pc.c */ |
40 | 41 | ||
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 6c4d59fd0364..ef9a2b49307a 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
@@ -46,6 +46,10 @@ | |||
46 | 46 | ||
47 | #define IRQ_DEBUG 0 | 47 | #define IRQ_DEBUG 0 |
48 | 48 | ||
49 | /* These can be overridden in platform_irq_init */ | ||
50 | int ia64_first_device_vector = IA64_DEF_FIRST_DEVICE_VECTOR; | ||
51 | int ia64_last_device_vector = IA64_DEF_LAST_DEVICE_VECTOR; | ||
52 | |||
49 | /* default base addr of IPI table */ | 53 | /* default base addr of IPI table */ |
50 | void __iomem *ipi_base_addr = ((void __iomem *) | 54 | void __iomem *ipi_base_addr = ((void __iomem *) |
51 | (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR)); | 55 | (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR)); |
@@ -60,7 +64,7 @@ __u8 isa_irq_to_vector_map[16] = { | |||
60 | }; | 64 | }; |
61 | EXPORT_SYMBOL(isa_irq_to_vector_map); | 65 | EXPORT_SYMBOL(isa_irq_to_vector_map); |
62 | 66 | ||
63 | static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)]; | 67 | static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_MAX_DEVICE_VECTORS)]; |
64 | 68 | ||
65 | int | 69 | int |
66 | assign_irq_vector (int irq) | 70 | assign_irq_vector (int irq) |
@@ -89,6 +93,19 @@ free_irq_vector (int vector) | |||
89 | printk(KERN_WARNING "%s: double free!\n", __FUNCTION__); | 93 | printk(KERN_WARNING "%s: double free!\n", __FUNCTION__); |
90 | } | 94 | } |
91 | 95 | ||
96 | int | ||
97 | reserve_irq_vector (int vector) | ||
98 | { | ||
99 | int pos; | ||
100 | |||
101 | if (vector < IA64_FIRST_DEVICE_VECTOR || | ||
102 | vector > IA64_LAST_DEVICE_VECTOR) | ||
103 | return -EINVAL; | ||
104 | |||
105 | pos = vector - IA64_FIRST_DEVICE_VECTOR; | ||
106 | return test_and_set_bit(pos, ia64_vector_mask); | ||
107 | } | ||
108 | |||
92 | #ifdef CONFIG_SMP | 109 | #ifdef CONFIG_SMP |
93 | # define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) | 110 | # define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) |
94 | #else | 111 | #else |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 5101ac462643..dc09a6a28a37 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -58,7 +58,7 @@ static int max_pcibus_number = 255; /* Default highest pci bus number */ | |||
58 | */ | 58 | */ |
59 | 59 | ||
60 | static dma_addr_t | 60 | static dma_addr_t |
61 | sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size) | 61 | sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type) |
62 | { | 62 | { |
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
@@ -457,13 +457,6 @@ void sn_pci_fixup_slot(struct pci_dev *dev) | |||
457 | pcidev_info->pdi_sn_irq_info = NULL; | 457 | pcidev_info->pdi_sn_irq_info = NULL; |
458 | kfree(sn_irq_info); | 458 | kfree(sn_irq_info); |
459 | } | 459 | } |
460 | |||
461 | /* | ||
462 | * MSI currently not supported on altix. Remove this when | ||
463 | * the MSI abstraction patches are integrated into the kernel | ||
464 | * (sometime after 2.6.16 releases) | ||
465 | */ | ||
466 | dev->no_msi = 1; | ||
467 | } | 460 | } |
468 | 461 | ||
469 | /* | 462 | /* |
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index c265e02f5036..dc8e2b696713 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c | |||
@@ -26,11 +26,11 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info); | |||
26 | 26 | ||
27 | int sn_force_interrupt_flag = 1; | 27 | int sn_force_interrupt_flag = 1; |
28 | extern int sn_ioif_inited; | 28 | extern int sn_ioif_inited; |
29 | static struct list_head **sn_irq_lh; | 29 | struct list_head **sn_irq_lh; |
30 | static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ | 30 | static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ |
31 | 31 | ||
32 | static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, | 32 | u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, |
33 | u64 sn_irq_info, | 33 | struct sn_irq_info *sn_irq_info, |
34 | int req_irq, nasid_t req_nasid, | 34 | int req_irq, nasid_t req_nasid, |
35 | int req_slice) | 35 | int req_slice) |
36 | { | 36 | { |
@@ -40,12 +40,13 @@ static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, | |||
40 | 40 | ||
41 | SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT, | 41 | SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT, |
42 | (u64) SAL_INTR_ALLOC, (u64) local_nasid, | 42 | (u64) SAL_INTR_ALLOC, (u64) local_nasid, |
43 | (u64) local_widget, (u64) sn_irq_info, (u64) req_irq, | 43 | (u64) local_widget, __pa(sn_irq_info), (u64) req_irq, |
44 | (u64) req_nasid, (u64) req_slice); | 44 | (u64) req_nasid, (u64) req_slice); |
45 | |||
45 | return ret_stuff.status; | 46 | return ret_stuff.status; |
46 | } | 47 | } |
47 | 48 | ||
48 | static inline void sn_intr_free(nasid_t local_nasid, int local_widget, | 49 | void sn_intr_free(nasid_t local_nasid, int local_widget, |
49 | struct sn_irq_info *sn_irq_info) | 50 | struct sn_irq_info *sn_irq_info) |
50 | { | 51 | { |
51 | struct ia64_sal_retval ret_stuff; | 52 | struct ia64_sal_retval ret_stuff; |
@@ -112,73 +113,91 @@ static void sn_end_irq(unsigned int irq) | |||
112 | 113 | ||
113 | static void sn_irq_info_free(struct rcu_head *head); | 114 | static void sn_irq_info_free(struct rcu_head *head); |
114 | 115 | ||
115 | static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) | 116 | struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, |
117 | nasid_t nasid, int slice) | ||
116 | { | 118 | { |
117 | struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; | 119 | int vector; |
118 | int cpuid, cpuphys; | 120 | int cpuphys; |
121 | int64_t bridge; | ||
122 | int local_widget, status; | ||
123 | nasid_t local_nasid; | ||
124 | struct sn_irq_info *new_irq_info; | ||
125 | struct sn_pcibus_provider *pci_provider; | ||
119 | 126 | ||
120 | cpuid = first_cpu(mask); | 127 | new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); |
121 | cpuphys = cpu_physical_id(cpuid); | 128 | if (new_irq_info == NULL) |
129 | return NULL; | ||
122 | 130 | ||
123 | list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, | 131 | memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); |
124 | sn_irq_lh[irq], list) { | 132 | |
125 | u64 bridge; | 133 | bridge = (u64) new_irq_info->irq_bridge; |
126 | int local_widget, status; | 134 | if (!bridge) { |
127 | nasid_t local_nasid; | 135 | kfree(new_irq_info); |
128 | struct sn_irq_info *new_irq_info; | 136 | return NULL; /* irq is not a device interrupt */ |
129 | struct sn_pcibus_provider *pci_provider; | 137 | } |
130 | |||
131 | new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); | ||
132 | if (new_irq_info == NULL) | ||
133 | break; | ||
134 | memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); | ||
135 | |||
136 | bridge = (u64) new_irq_info->irq_bridge; | ||
137 | if (!bridge) { | ||
138 | kfree(new_irq_info); | ||
139 | break; /* irq is not a device interrupt */ | ||
140 | } | ||
141 | 138 | ||
142 | local_nasid = NASID_GET(bridge); | 139 | local_nasid = NASID_GET(bridge); |
143 | 140 | ||
144 | if (local_nasid & 1) | 141 | if (local_nasid & 1) |
145 | local_widget = TIO_SWIN_WIDGETNUM(bridge); | 142 | local_widget = TIO_SWIN_WIDGETNUM(bridge); |
146 | else | 143 | else |
147 | local_widget = SWIN_WIDGETNUM(bridge); | 144 | local_widget = SWIN_WIDGETNUM(bridge); |
148 | 145 | ||
149 | /* Free the old PROM new_irq_info structure */ | 146 | vector = sn_irq_info->irq_irq; |
150 | sn_intr_free(local_nasid, local_widget, new_irq_info); | 147 | /* Free the old PROM new_irq_info structure */ |
151 | /* Update kernels new_irq_info with new target info */ | 148 | sn_intr_free(local_nasid, local_widget, new_irq_info); |
152 | unregister_intr_pda(new_irq_info); | 149 | /* Update kernels new_irq_info with new target info */ |
150 | unregister_intr_pda(new_irq_info); | ||
153 | 151 | ||
154 | /* allocate a new PROM new_irq_info struct */ | 152 | /* allocate a new PROM new_irq_info struct */ |
155 | status = sn_intr_alloc(local_nasid, local_widget, | 153 | status = sn_intr_alloc(local_nasid, local_widget, |
156 | __pa(new_irq_info), irq, | 154 | new_irq_info, vector, |
157 | cpuid_to_nasid(cpuid), | 155 | nasid, slice); |
158 | cpuid_to_slice(cpuid)); | ||
159 | 156 | ||
160 | /* SAL call failed */ | 157 | /* SAL call failed */ |
161 | if (status) { | 158 | if (status) { |
162 | kfree(new_irq_info); | 159 | kfree(new_irq_info); |
163 | break; | 160 | return NULL; |
164 | } | 161 | } |
165 | 162 | ||
166 | new_irq_info->irq_cpuid = cpuid; | 163 | cpuphys = nasid_slice_to_cpuid(nasid, slice); |
167 | register_intr_pda(new_irq_info); | 164 | new_irq_info->irq_cpuid = cpuphys; |
165 | register_intr_pda(new_irq_info); | ||
168 | 166 | ||
169 | pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; | 167 | pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; |
170 | if (pci_provider && pci_provider->target_interrupt) | ||
171 | (pci_provider->target_interrupt)(new_irq_info); | ||
172 | 168 | ||
173 | spin_lock(&sn_irq_info_lock); | 169 | /* |
174 | list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); | 170 | * If this represents a line interrupt, target it. If it's |
175 | spin_unlock(&sn_irq_info_lock); | 171 | * an msi (irq_int_bit < 0), it's already targeted. |
176 | call_rcu(&sn_irq_info->rcu, sn_irq_info_free); | 172 | */ |
173 | if (new_irq_info->irq_int_bit >= 0 && | ||
174 | pci_provider && pci_provider->target_interrupt) | ||
175 | (pci_provider->target_interrupt)(new_irq_info); | ||
176 | |||
177 | spin_lock(&sn_irq_info_lock); | ||
178 | list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); | ||
179 | spin_unlock(&sn_irq_info_lock); | ||
180 | call_rcu(&sn_irq_info->rcu, sn_irq_info_free); | ||
177 | 181 | ||
178 | #ifdef CONFIG_SMP | 182 | #ifdef CONFIG_SMP |
179 | set_irq_affinity_info((irq & 0xff), cpuphys, 0); | 183 | set_irq_affinity_info((vector & 0xff), cpuphys, 0); |
180 | #endif | 184 | #endif |
181 | } | 185 | |
186 | return new_irq_info; | ||
187 | } | ||
188 | |||
189 | static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) | ||
190 | { | ||
191 | struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; | ||
192 | nasid_t nasid; | ||
193 | int slice; | ||
194 | |||
195 | nasid = cpuid_to_nasid(first_cpu(mask)); | ||
196 | slice = cpuid_to_slice(first_cpu(mask)); | ||
197 | |||
198 | list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, | ||
199 | sn_irq_lh[irq], list) | ||
200 | (void)sn_retarget_vector(sn_irq_info, nasid, slice); | ||
182 | } | 201 | } |
183 | 202 | ||
184 | struct hw_interrupt_type irq_type_sn = { | 203 | struct hw_interrupt_type irq_type_sn = { |
@@ -202,6 +221,9 @@ void sn_irq_init(void) | |||
202 | int i; | 221 | int i; |
203 | irq_desc_t *base_desc = irq_desc; | 222 | irq_desc_t *base_desc = irq_desc; |
204 | 223 | ||
224 | ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR; | ||
225 | ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; | ||
226 | |||
205 | for (i = 0; i < NR_IRQS; i++) { | 227 | for (i = 0; i < NR_IRQS; i++) { |
206 | if (base_desc[i].handler == &no_irq_type) { | 228 | if (base_desc[i].handler == &no_irq_type) { |
207 | base_desc[i].handler = &irq_type_sn; | 229 | base_desc[i].handler = &irq_type_sn; |
@@ -285,6 +307,7 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) | |||
285 | /* link it into the sn_irq[irq] list */ | 307 | /* link it into the sn_irq[irq] list */ |
286 | spin_lock(&sn_irq_info_lock); | 308 | spin_lock(&sn_irq_info_lock); |
287 | list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); | 309 | list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); |
310 | reserve_irq_vector(sn_irq_info->irq_irq); | ||
288 | spin_unlock(&sn_irq_info_lock); | 311 | spin_unlock(&sn_irq_info_lock); |
289 | 312 | ||
290 | register_intr_pda(sn_irq_info); | 313 | register_intr_pda(sn_irq_info); |
@@ -310,8 +333,11 @@ void sn_irq_unfixup(struct pci_dev *pci_dev) | |||
310 | spin_lock(&sn_irq_info_lock); | 333 | spin_lock(&sn_irq_info_lock); |
311 | list_del_rcu(&sn_irq_info->list); | 334 | list_del_rcu(&sn_irq_info->list); |
312 | spin_unlock(&sn_irq_info_lock); | 335 | spin_unlock(&sn_irq_info_lock); |
336 | if (list_empty(sn_irq_lh[sn_irq_info->irq_irq])) | ||
337 | free_irq_vector(sn_irq_info->irq_irq); | ||
313 | call_rcu(&sn_irq_info->rcu, sn_irq_info_free); | 338 | call_rcu(&sn_irq_info->rcu, sn_irq_info_free); |
314 | pci_dev_put(pci_dev); | 339 | pci_dev_put(pci_dev); |
340 | |||
315 | } | 341 | } |
316 | 342 | ||
317 | static inline void | 343 | static inline void |
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index b4b84c269210..7a291a271511 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <asm/dma.h> | 13 | #include <asm/dma.h> |
14 | #include <asm/sn/pcibr_provider.h> | 14 | #include <asm/sn/intr.h> |
15 | #include <asm/sn/pcibus_provider_defs.h> | 15 | #include <asm/sn/pcibus_provider_defs.h> |
16 | #include <asm/sn/pcidev.h> | 16 | #include <asm/sn/pcidev.h> |
17 | #include <asm/sn/sn_sal.h> | 17 | #include <asm/sn/sn_sal.h> |
@@ -113,7 +113,8 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size, | |||
113 | * resources. | 113 | * resources. |
114 | */ | 114 | */ |
115 | 115 | ||
116 | *dma_handle = provider->dma_map_consistent(pdev, phys_addr, size); | 116 | *dma_handle = provider->dma_map_consistent(pdev, phys_addr, size, |
117 | SN_DMA_ADDR_PHYS); | ||
117 | if (!*dma_handle) { | 118 | if (!*dma_handle) { |
118 | printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); | 119 | printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); |
119 | free_pages((unsigned long)cpuaddr, get_order(size)); | 120 | free_pages((unsigned long)cpuaddr, get_order(size)); |
@@ -176,7 +177,7 @@ dma_addr_t sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size, | |||
176 | BUG_ON(dev->bus != &pci_bus_type); | 177 | BUG_ON(dev->bus != &pci_bus_type); |
177 | 178 | ||
178 | phys_addr = __pa(cpu_addr); | 179 | phys_addr = __pa(cpu_addr); |
179 | dma_addr = provider->dma_map(pdev, phys_addr, size); | 180 | dma_addr = provider->dma_map(pdev, phys_addr, size, SN_DMA_ADDR_PHYS); |
180 | if (!dma_addr) { | 181 | if (!dma_addr) { |
181 | printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); | 182 | printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); |
182 | return 0; | 183 | return 0; |
@@ -260,7 +261,8 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | |||
260 | for (i = 0; i < nhwentries; i++, sg++) { | 261 | for (i = 0; i < nhwentries; i++, sg++) { |
261 | phys_addr = SG_ENT_PHYS_ADDRESS(sg); | 262 | phys_addr = SG_ENT_PHYS_ADDRESS(sg); |
262 | sg->dma_address = provider->dma_map(pdev, | 263 | sg->dma_address = provider->dma_map(pdev, |
263 | phys_addr, sg->length); | 264 | phys_addr, sg->length, |
265 | SN_DMA_ADDR_PHYS); | ||
264 | 266 | ||
265 | if (!sg->dma_address) { | 267 | if (!sg->dma_address) { |
266 | printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); | 268 | printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c index 9f86bb6519aa..a86c7b945962 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c | |||
@@ -41,7 +41,7 @@ extern int sn_ioif_inited; | |||
41 | 41 | ||
42 | static dma_addr_t | 42 | static dma_addr_t |
43 | pcibr_dmamap_ate32(struct pcidev_info *info, | 43 | pcibr_dmamap_ate32(struct pcidev_info *info, |
44 | u64 paddr, size_t req_size, u64 flags) | 44 | u64 paddr, size_t req_size, u64 flags, int dma_flags) |
45 | { | 45 | { |
46 | 46 | ||
47 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; | 47 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; |
@@ -81,9 +81,12 @@ pcibr_dmamap_ate32(struct pcidev_info *info, | |||
81 | if (IS_PCIX(pcibus_info)) | 81 | if (IS_PCIX(pcibus_info)) |
82 | ate_flags &= ~(PCI32_ATE_PREF); | 82 | ate_flags &= ~(PCI32_ATE_PREF); |
83 | 83 | ||
84 | xio_addr = | 84 | if (SN_DMA_ADDRTYPE(dma_flags == SN_DMA_ADDR_PHYS)) |
85 | IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : | 85 | xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : |
86 | PHYS_TO_TIODMA(paddr); | 86 | PHYS_TO_TIODMA(paddr); |
87 | else | ||
88 | xio_addr = paddr; | ||
89 | |||
87 | offset = IOPGOFF(xio_addr); | 90 | offset = IOPGOFF(xio_addr); |
88 | ate = ate_flags | (xio_addr - offset); | 91 | ate = ate_flags | (xio_addr - offset); |
89 | 92 | ||
@@ -91,6 +94,13 @@ pcibr_dmamap_ate32(struct pcidev_info *info, | |||
91 | if (IS_PIC_SOFT(pcibus_info)) { | 94 | if (IS_PIC_SOFT(pcibus_info)) { |
92 | ate |= (pcibus_info->pbi_hub_xid << PIC_ATE_TARGETID_SHFT); | 95 | ate |= (pcibus_info->pbi_hub_xid << PIC_ATE_TARGETID_SHFT); |
93 | } | 96 | } |
97 | |||
98 | /* | ||
99 | * If we're mapping for MSI, set the MSI bit in the ATE | ||
100 | */ | ||
101 | if (dma_flags & SN_DMA_MSI) | ||
102 | ate |= PCI32_ATE_MSI; | ||
103 | |||
94 | ate_write(pcibus_info, ate_index, ate_count, ate); | 104 | ate_write(pcibus_info, ate_index, ate_count, ate); |
95 | 105 | ||
96 | /* | 106 | /* |
@@ -105,20 +115,27 @@ pcibr_dmamap_ate32(struct pcidev_info *info, | |||
105 | if (pcibus_info->pbi_devreg[internal_device] & PCIBR_DEV_SWAP_DIR) | 115 | if (pcibus_info->pbi_devreg[internal_device] & PCIBR_DEV_SWAP_DIR) |
106 | ATE_SWAP_ON(pci_addr); | 116 | ATE_SWAP_ON(pci_addr); |
107 | 117 | ||
118 | |||
108 | return pci_addr; | 119 | return pci_addr; |
109 | } | 120 | } |
110 | 121 | ||
111 | static dma_addr_t | 122 | static dma_addr_t |
112 | pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, | 123 | pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, |
113 | u64 dma_attributes) | 124 | u64 dma_attributes, int dma_flags) |
114 | { | 125 | { |
115 | struct pcibus_info *pcibus_info = (struct pcibus_info *) | 126 | struct pcibus_info *pcibus_info = (struct pcibus_info *) |
116 | ((info->pdi_host_pcidev_info)->pdi_pcibus_info); | 127 | ((info->pdi_host_pcidev_info)->pdi_pcibus_info); |
117 | u64 pci_addr; | 128 | u64 pci_addr; |
118 | 129 | ||
119 | /* Translate to Crosstalk View of Physical Address */ | 130 | /* Translate to Crosstalk View of Physical Address */ |
120 | pci_addr = (IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : | 131 | if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS) |
121 | PHYS_TO_TIODMA(paddr)) | dma_attributes; | 132 | pci_addr = IS_PIC_SOFT(pcibus_info) ? |
133 | PHYS_TO_DMA(paddr) : | ||
134 | PHYS_TO_TIODMA(paddr) | dma_attributes; | ||
135 | else | ||
136 | pci_addr = IS_PIC_SOFT(pcibus_info) ? | ||
137 | paddr : | ||
138 | paddr | dma_attributes; | ||
122 | 139 | ||
123 | /* Handle Bus mode */ | 140 | /* Handle Bus mode */ |
124 | if (IS_PCIX(pcibus_info)) | 141 | if (IS_PCIX(pcibus_info)) |
@@ -130,7 +147,9 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, | |||
130 | ((u64) pcibus_info-> | 147 | ((u64) pcibus_info-> |
131 | pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT); | 148 | pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT); |
132 | } else | 149 | } else |
133 | pci_addr |= TIOCP_PCI64_CMDTYPE_MEM; | 150 | pci_addr |= (dma_flags & SN_DMA_MSI) ? |
151 | TIOCP_PCI64_CMDTYPE_MSI : | ||
152 | TIOCP_PCI64_CMDTYPE_MEM; | ||
134 | 153 | ||
135 | /* If PCI mode, func zero uses VCHAN0, every other func uses VCHAN1 */ | 154 | /* If PCI mode, func zero uses VCHAN0, every other func uses VCHAN1 */ |
136 | if (!IS_PCIX(pcibus_info) && PCI_FUNC(info->pdi_linux_pcidev->devfn)) | 155 | if (!IS_PCIX(pcibus_info) && PCI_FUNC(info->pdi_linux_pcidev->devfn)) |
@@ -141,7 +160,7 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, | |||
141 | 160 | ||
142 | static dma_addr_t | 161 | static dma_addr_t |
143 | pcibr_dmatrans_direct32(struct pcidev_info * info, | 162 | pcibr_dmatrans_direct32(struct pcidev_info * info, |
144 | u64 paddr, size_t req_size, u64 flags) | 163 | u64 paddr, size_t req_size, u64 flags, int dma_flags) |
145 | { | 164 | { |
146 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; | 165 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; |
147 | struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> | 166 | struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> |
@@ -156,8 +175,14 @@ pcibr_dmatrans_direct32(struct pcidev_info * info, | |||
156 | return 0; | 175 | return 0; |
157 | } | 176 | } |
158 | 177 | ||
159 | xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : | 178 | if (dma_flags & SN_DMA_MSI) |
160 | PHYS_TO_TIODMA(paddr); | 179 | return 0; |
180 | |||
181 | if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS) | ||
182 | xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : | ||
183 | PHYS_TO_TIODMA(paddr); | ||
184 | else | ||
185 | xio_addr = paddr; | ||
161 | 186 | ||
162 | xio_base = pcibus_info->pbi_dir_xbase; | 187 | xio_base = pcibus_info->pbi_dir_xbase; |
163 | offset = xio_addr - xio_base; | 188 | offset = xio_addr - xio_base; |
@@ -327,7 +352,7 @@ void sn_dma_flush(u64 addr) | |||
327 | */ | 352 | */ |
328 | 353 | ||
329 | dma_addr_t | 354 | dma_addr_t |
330 | pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size) | 355 | pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size, int dma_flags) |
331 | { | 356 | { |
332 | dma_addr_t dma_handle; | 357 | dma_addr_t dma_handle; |
333 | struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev); | 358 | struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev); |
@@ -344,11 +369,11 @@ pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size) | |||
344 | */ | 369 | */ |
345 | 370 | ||
346 | dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr, | 371 | dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr, |
347 | PCI64_ATTR_PREF); | 372 | PCI64_ATTR_PREF, dma_flags); |
348 | } else { | 373 | } else { |
349 | /* Handle 32-63 bit cards via direct mapping */ | 374 | /* Handle 32-63 bit cards via direct mapping */ |
350 | dma_handle = pcibr_dmatrans_direct32(pcidev_info, phys_addr, | 375 | dma_handle = pcibr_dmatrans_direct32(pcidev_info, phys_addr, |
351 | size, 0); | 376 | size, 0, dma_flags); |
352 | if (!dma_handle) { | 377 | if (!dma_handle) { |
353 | /* | 378 | /* |
354 | * It is a 32 bit card and we cannot do direct mapping, | 379 | * It is a 32 bit card and we cannot do direct mapping, |
@@ -356,7 +381,8 @@ pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size) | |||
356 | */ | 381 | */ |
357 | 382 | ||
358 | dma_handle = pcibr_dmamap_ate32(pcidev_info, phys_addr, | 383 | dma_handle = pcibr_dmamap_ate32(pcidev_info, phys_addr, |
359 | size, PCI32_ATE_PREF); | 384 | size, PCI32_ATE_PREF, |
385 | dma_flags); | ||
360 | } | 386 | } |
361 | } | 387 | } |
362 | 388 | ||
@@ -365,18 +391,18 @@ pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size) | |||
365 | 391 | ||
366 | dma_addr_t | 392 | dma_addr_t |
367 | pcibr_dma_map_consistent(struct pci_dev * hwdev, unsigned long phys_addr, | 393 | pcibr_dma_map_consistent(struct pci_dev * hwdev, unsigned long phys_addr, |
368 | size_t size) | 394 | size_t size, int dma_flags) |
369 | { | 395 | { |
370 | dma_addr_t dma_handle; | 396 | dma_addr_t dma_handle; |
371 | struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev); | 397 | struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev); |
372 | 398 | ||
373 | if (hwdev->dev.coherent_dma_mask == ~0UL) { | 399 | if (hwdev->dev.coherent_dma_mask == ~0UL) { |
374 | dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr, | 400 | dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr, |
375 | PCI64_ATTR_BAR); | 401 | PCI64_ATTR_BAR, dma_flags); |
376 | } else { | 402 | } else { |
377 | dma_handle = (dma_addr_t) pcibr_dmamap_ate32(pcidev_info, | 403 | dma_handle = (dma_addr_t) pcibr_dmamap_ate32(pcidev_info, |
378 | phys_addr, size, | 404 | phys_addr, size, |
379 | PCI32_ATE_BAR); | 405 | PCI32_ATE_BAR, dma_flags); |
380 | } | 406 | } |
381 | 407 | ||
382 | return dma_handle; | 408 | return dma_handle; |
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index be0176912968..20de72791b97 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c | |||
@@ -515,11 +515,17 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) | |||
515 | * use the GART mapped mode. | 515 | * use the GART mapped mode. |
516 | */ | 516 | */ |
517 | static u64 | 517 | static u64 |
518 | tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count) | 518 | tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) |
519 | { | 519 | { |
520 | u64 mapaddr; | 520 | u64 mapaddr; |
521 | 521 | ||
522 | /* | 522 | /* |
523 | * Not supported for now ... | ||
524 | */ | ||
525 | if (dma_flags & SN_DMA_MSI) | ||
526 | return 0; | ||
527 | |||
528 | /* | ||
523 | * If card is 64 or 48 bit addresable, use a direct mapping. 32 | 529 | * If card is 64 or 48 bit addresable, use a direct mapping. 32 |
524 | * bit direct is so restrictive w.r.t. where the memory resides that | 530 | * bit direct is so restrictive w.r.t. where the memory resides that |
525 | * we don't use it even though CA has some support. | 531 | * we don't use it even though CA has some support. |
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index 833295624e5d..4cac7bdc7c7f 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c | |||
@@ -170,7 +170,8 @@ tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr) | |||
170 | (ATE_PAGE((start)+(len)-1, pagesize) - ATE_PAGE(start, pagesize) + 1) | 170 | (ATE_PAGE((start)+(len)-1, pagesize) - ATE_PAGE(start, pagesize) + 1) |
171 | 171 | ||
172 | #define ATE_VALID(ate) ((ate) & (1UL << 63)) | 172 | #define ATE_VALID(ate) ((ate) & (1UL << 63)) |
173 | #define ATE_MAKE(addr, ps) (((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63)) | 173 | #define ATE_MAKE(addr, ps, msi) \ |
174 | (((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63) | ((msi)?(1UL << 62):0)) | ||
174 | 175 | ||
175 | /* | 176 | /* |
176 | * Flavors of ate-based mapping supported by tioce_alloc_map() | 177 | * Flavors of ate-based mapping supported by tioce_alloc_map() |
@@ -196,15 +197,17 @@ tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr) | |||
196 | * | 197 | * |
197 | * 63 - must be 1 to indicate d64 mode to CE hardware | 198 | * 63 - must be 1 to indicate d64 mode to CE hardware |
198 | * 62 - barrier bit ... controlled with tioce_dma_barrier() | 199 | * 62 - barrier bit ... controlled with tioce_dma_barrier() |
199 | * 61 - 0 since this is not an MSI transaction | 200 | * 61 - msi bit ... specified through dma_flags |
200 | * 60:54 - reserved, MBZ | 201 | * 60:54 - reserved, MBZ |
201 | */ | 202 | */ |
202 | static u64 | 203 | static u64 |
203 | tioce_dma_d64(unsigned long ct_addr) | 204 | tioce_dma_d64(unsigned long ct_addr, int dma_flags) |
204 | { | 205 | { |
205 | u64 bus_addr; | 206 | u64 bus_addr; |
206 | 207 | ||
207 | bus_addr = ct_addr | (1UL << 63); | 208 | bus_addr = ct_addr | (1UL << 63); |
209 | if (dma_flags & SN_DMA_MSI) | ||
210 | bus_addr |= (1UL << 61); | ||
208 | 211 | ||
209 | return bus_addr; | 212 | return bus_addr; |
210 | } | 213 | } |
@@ -261,7 +264,7 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base, | |||
261 | */ | 264 | */ |
262 | static u64 | 265 | static u64 |
263 | tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | 266 | tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, |
264 | u64 ct_addr, int len) | 267 | u64 ct_addr, int len, int dma_flags) |
265 | { | 268 | { |
266 | int i; | 269 | int i; |
267 | int j; | 270 | int j; |
@@ -270,6 +273,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
270 | int entries; | 273 | int entries; |
271 | int nates; | 274 | int nates; |
272 | u64 pagesize; | 275 | u64 pagesize; |
276 | int msi_capable, msi_wanted; | ||
273 | u64 *ate_shadow; | 277 | u64 *ate_shadow; |
274 | u64 *ate_reg; | 278 | u64 *ate_reg; |
275 | u64 addr; | 279 | u64 addr; |
@@ -291,6 +295,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
291 | ate_reg = ce_mmr->ce_ure_ate3240; | 295 | ate_reg = ce_mmr->ce_ure_ate3240; |
292 | pagesize = ce_kern->ce_ate3240_pagesize; | 296 | pagesize = ce_kern->ce_ate3240_pagesize; |
293 | bus_base = TIOCE_M32_MIN; | 297 | bus_base = TIOCE_M32_MIN; |
298 | msi_capable = 1; | ||
294 | break; | 299 | break; |
295 | case TIOCE_ATE_M40: | 300 | case TIOCE_ATE_M40: |
296 | first = 0; | 301 | first = 0; |
@@ -299,6 +304,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
299 | ate_reg = ce_mmr->ce_ure_ate40; | 304 | ate_reg = ce_mmr->ce_ure_ate40; |
300 | pagesize = MB(64); | 305 | pagesize = MB(64); |
301 | bus_base = TIOCE_M40_MIN; | 306 | bus_base = TIOCE_M40_MIN; |
307 | msi_capable = 0; | ||
302 | break; | 308 | break; |
303 | case TIOCE_ATE_M40S: | 309 | case TIOCE_ATE_M40S: |
304 | /* | 310 | /* |
@@ -311,11 +317,16 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
311 | ate_reg = ce_mmr->ce_ure_ate3240; | 317 | ate_reg = ce_mmr->ce_ure_ate3240; |
312 | pagesize = GB(16); | 318 | pagesize = GB(16); |
313 | bus_base = TIOCE_M40S_MIN; | 319 | bus_base = TIOCE_M40S_MIN; |
320 | msi_capable = 0; | ||
314 | break; | 321 | break; |
315 | default: | 322 | default: |
316 | return 0; | 323 | return 0; |
317 | } | 324 | } |
318 | 325 | ||
326 | msi_wanted = dma_flags & SN_DMA_MSI; | ||
327 | if (msi_wanted && !msi_capable) | ||
328 | return 0; | ||
329 | |||
319 | nates = ATE_NPAGES(ct_addr, len, pagesize); | 330 | nates = ATE_NPAGES(ct_addr, len, pagesize); |
320 | if (nates > entries) | 331 | if (nates > entries) |
321 | return 0; | 332 | return 0; |
@@ -344,7 +355,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
344 | for (j = 0; j < nates; j++) { | 355 | for (j = 0; j < nates; j++) { |
345 | u64 ate; | 356 | u64 ate; |
346 | 357 | ||
347 | ate = ATE_MAKE(addr, pagesize); | 358 | ate = ATE_MAKE(addr, pagesize, msi_wanted); |
348 | ate_shadow[i + j] = ate; | 359 | ate_shadow[i + j] = ate; |
349 | tioce_mmr_storei(ce_kern, &ate_reg[i + j], ate); | 360 | tioce_mmr_storei(ce_kern, &ate_reg[i + j], ate); |
350 | addr += pagesize; | 361 | addr += pagesize; |
@@ -371,7 +382,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
371 | * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info. | 382 | * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info. |
372 | */ | 383 | */ |
373 | static u64 | 384 | static u64 |
374 | tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr) | 385 | tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr, int dma_flags) |
375 | { | 386 | { |
376 | int dma_ok; | 387 | int dma_ok; |
377 | int port; | 388 | int port; |
@@ -381,6 +392,9 @@ tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr) | |||
381 | u64 ct_lower; | 392 | u64 ct_lower; |
382 | dma_addr_t bus_addr; | 393 | dma_addr_t bus_addr; |
383 | 394 | ||
395 | if (dma_flags & SN_DMA_MSI) | ||
396 | return 0; | ||
397 | |||
384 | ct_upper = ct_addr & ~0x3fffffffUL; | 398 | ct_upper = ct_addr & ~0x3fffffffUL; |
385 | ct_lower = ct_addr & 0x3fffffffUL; | 399 | ct_lower = ct_addr & 0x3fffffffUL; |
386 | 400 | ||
@@ -507,7 +521,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) | |||
507 | */ | 521 | */ |
508 | static u64 | 522 | static u64 |
509 | tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, | 523 | tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, |
510 | int barrier) | 524 | int barrier, int dma_flags) |
511 | { | 525 | { |
512 | unsigned long flags; | 526 | unsigned long flags; |
513 | u64 ct_addr; | 527 | u64 ct_addr; |
@@ -523,15 +537,18 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, | |||
523 | if (dma_mask < 0x7fffffffUL) | 537 | if (dma_mask < 0x7fffffffUL) |
524 | return 0; | 538 | return 0; |
525 | 539 | ||
526 | ct_addr = PHYS_TO_TIODMA(paddr); | 540 | if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS) |
541 | ct_addr = PHYS_TO_TIODMA(paddr); | ||
542 | else | ||
543 | ct_addr = paddr; | ||
527 | 544 | ||
528 | /* | 545 | /* |
529 | * If the device can generate 64 bit addresses, create a D64 map. | 546 | * If the device can generate 64 bit addresses, create a D64 map. |
530 | * Since this should never fail, bypass the rest of the checks. | ||
531 | */ | 547 | */ |
532 | if (dma_mask == ~0UL) { | 548 | if (dma_mask == ~0UL) { |
533 | mapaddr = tioce_dma_d64(ct_addr); | 549 | mapaddr = tioce_dma_d64(ct_addr, dma_flags); |
534 | goto dma_map_done; | 550 | if (mapaddr) |
551 | goto dma_map_done; | ||
535 | } | 552 | } |
536 | 553 | ||
537 | pcidev_to_tioce(pdev, NULL, &ce_kern, &port); | 554 | pcidev_to_tioce(pdev, NULL, &ce_kern, &port); |
@@ -574,18 +591,22 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, | |||
574 | 591 | ||
575 | if (byte_count > MB(64)) { | 592 | if (byte_count > MB(64)) { |
576 | mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40S, | 593 | mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40S, |
577 | port, ct_addr, byte_count); | 594 | port, ct_addr, byte_count, |
595 | dma_flags); | ||
578 | if (!mapaddr) | 596 | if (!mapaddr) |
579 | mapaddr = | 597 | mapaddr = |
580 | tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1, | 598 | tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1, |
581 | ct_addr, byte_count); | 599 | ct_addr, byte_count, |
600 | dma_flags); | ||
582 | } else { | 601 | } else { |
583 | mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1, | 602 | mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1, |
584 | ct_addr, byte_count); | 603 | ct_addr, byte_count, |
604 | dma_flags); | ||
585 | if (!mapaddr) | 605 | if (!mapaddr) |
586 | mapaddr = | 606 | mapaddr = |
587 | tioce_alloc_map(ce_kern, TIOCE_ATE_M40S, | 607 | tioce_alloc_map(ce_kern, TIOCE_ATE_M40S, |
588 | port, ct_addr, byte_count); | 608 | port, ct_addr, byte_count, |
609 | dma_flags); | ||
589 | } | 610 | } |
590 | } | 611 | } |
591 | 612 | ||
@@ -593,7 +614,7 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, | |||
593 | * 32-bit direct is the next mode to try | 614 | * 32-bit direct is the next mode to try |
594 | */ | 615 | */ |
595 | if (!mapaddr && dma_mask >= 0xffffffffUL) | 616 | if (!mapaddr && dma_mask >= 0xffffffffUL) |
596 | mapaddr = tioce_dma_d32(pdev, ct_addr); | 617 | mapaddr = tioce_dma_d32(pdev, ct_addr, dma_flags); |
597 | 618 | ||
598 | /* | 619 | /* |
599 | * Last resort, try 32-bit ATE-based map. | 620 | * Last resort, try 32-bit ATE-based map. |
@@ -601,7 +622,7 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, | |||
601 | if (!mapaddr) | 622 | if (!mapaddr) |
602 | mapaddr = | 623 | mapaddr = |
603 | tioce_alloc_map(ce_kern, TIOCE_ATE_M32, -1, ct_addr, | 624 | tioce_alloc_map(ce_kern, TIOCE_ATE_M32, -1, ct_addr, |
604 | byte_count); | 625 | byte_count, dma_flags); |
605 | 626 | ||
606 | spin_unlock_irqrestore(&ce_kern->ce_lock, flags); | 627 | spin_unlock_irqrestore(&ce_kern->ce_lock, flags); |
607 | 628 | ||
@@ -622,9 +643,9 @@ dma_map_done: | |||
622 | * in the address. | 643 | * in the address. |
623 | */ | 644 | */ |
624 | static u64 | 645 | static u64 |
625 | tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count) | 646 | tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) |
626 | { | 647 | { |
627 | return tioce_do_dma_map(pdev, paddr, byte_count, 0); | 648 | return tioce_do_dma_map(pdev, paddr, byte_count, 0, dma_flags); |
628 | } | 649 | } |
629 | 650 | ||
630 | /** | 651 | /** |
@@ -636,9 +657,9 @@ tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count) | |||
636 | * Simply call tioce_do_dma_map() to create a map with the barrier bit set | 657 | * Simply call tioce_do_dma_map() to create a map with the barrier bit set |
637 | * in the address. | 658 | * in the address. |
638 | */ static u64 | 659 | */ static u64 |
639 | tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count) | 660 | tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) |
640 | { | 661 | { |
641 | return tioce_do_dma_map(pdev, paddr, byte_count, 1); | 662 | return tioce_do_dma_map(pdev, paddr, byte_count, 1, dma_flags); |
642 | } | 663 | } |
643 | 664 | ||
644 | /** | 665 | /** |
@@ -696,7 +717,7 @@ tioce_reserve_m32(struct tioce_kernel *ce_kern, u64 base, u64 limit) | |||
696 | while (ate_index <= last_ate) { | 717 | while (ate_index <= last_ate) { |
697 | u64 ate; | 718 | u64 ate; |
698 | 719 | ||
699 | ate = ATE_MAKE(0xdeadbeef, ps); | 720 | ate = ATE_MAKE(0xdeadbeef, ps, 0); |
700 | ce_kern->ce_ate3240_shadow[ate_index] = ate; | 721 | ce_kern->ce_ate3240_shadow[ate_index] = ate; |
701 | tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_ate3240[ate_index], | 722 | tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_ate3240[ate_index], |
702 | ate); | 723 | ate); |
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index c9e0aeeca3d8..4368dc3f3c30 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c | |||
@@ -379,13 +379,12 @@ mpc85xx_cds_pcibios_fixup(void) | |||
379 | PCI_DEVICE_ID_VIA_82C586_2, NULL))) { | 379 | PCI_DEVICE_ID_VIA_82C586_2, NULL))) { |
380 | dev->irq = 10; | 380 | dev->irq = 10; |
381 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); | 381 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); |
382 | pci_dev_put(dev); | ||
383 | } | ||
384 | 382 | ||
385 | if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, | 383 | if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, |
386 | PCI_DEVICE_ID_VIA_82C586_2, dev))) { | 384 | PCI_DEVICE_ID_VIA_82C586_2, dev))) { |
387 | dev->irq = 11; | 385 | dev->irq = 11; |
388 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); | 386 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); |
387 | } | ||
389 | pci_dev_put(dev); | 388 | pci_dev_put(dev); |
390 | } | 389 | } |
391 | } | 390 | } |
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index a2060e4d5de6..3c55c76c6fd5 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c | |||
@@ -13,7 +13,10 @@ | |||
13 | 13 | ||
14 | #include "pci.h" | 14 | #include "pci.h" |
15 | 15 | ||
16 | #define MMCONFIG_APER_SIZE (256*1024*1024) | 16 | /* aperture is up to 256MB but BIOS may reserve less */ |
17 | #define MMCONFIG_APER_MIN (2 * 1024*1024) | ||
18 | #define MMCONFIG_APER_MAX (256 * 1024*1024) | ||
19 | |||
17 | /* Verify the first 16 busses. We assume that systems with more busses | 20 | /* Verify the first 16 busses. We assume that systems with more busses |
18 | get MCFG right. */ | 21 | get MCFG right. */ |
19 | #define MAX_CHECK_BUS 16 | 22 | #define MAX_CHECK_BUS 16 |
@@ -175,9 +178,10 @@ void __init pci_mmcfg_init(void) | |||
175 | return; | 178 | return; |
176 | 179 | ||
177 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | 180 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, |
178 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | 181 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, |
179 | E820_RESERVED)) { | 182 | E820_RESERVED)) { |
180 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | 183 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", |
184 | pci_mmcfg_config[0].base_address); | ||
181 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | 185 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); |
182 | return; | 186 | return; |
183 | } | 187 | } |
@@ -190,7 +194,8 @@ void __init pci_mmcfg_init(void) | |||
190 | } | 194 | } |
191 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | 195 | for (i = 0; i < pci_mmcfg_config_num; ++i) { |
192 | pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; | 196 | pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; |
193 | pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); | 197 | pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, |
198 | MMCONFIG_APER_MAX); | ||
194 | if (!pci_mmcfg_virt[i].virt) { | 199 | if (!pci_mmcfg_virt[i].virt) { |
195 | printk("PCI: Cannot map mmconfig aperture for segment %d\n", | 200 | printk("PCI: Cannot map mmconfig aperture for segment %d\n", |
196 | pci_mmcfg_config[i].pci_segment_group_number); | 201 | pci_mmcfg_config[i].pci_segment_group_number); |