diff options
Diffstat (limited to 'arch/ia64/sn/kernel/io_init.c')
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 233d55115d33..a4c78152b336 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/nodemask.h> | 10 | #include <linux/nodemask.h> |
11 | #include <asm/sn/types.h> | 11 | #include <asm/sn/types.h> |
12 | #include <asm/sn/addrs.h> | 12 | #include <asm/sn/addrs.h> |
13 | #include <asm/sn/sn_feature_sets.h> | ||
13 | #include <asm/sn/geo.h> | 14 | #include <asm/sn/geo.h> |
14 | #include <asm/sn/io.h> | 15 | #include <asm/sn/io.h> |
15 | #include <asm/sn/pcibr_provider.h> | 16 | #include <asm/sn/pcibr_provider.h> |
@@ -165,8 +166,46 @@ sn_pcidev_info_get(struct pci_dev *dev) | |||
165 | return NULL; | 166 | return NULL; |
166 | } | 167 | } |
167 | 168 | ||
169 | /* Older PROM flush WAR | ||
170 | * | ||
171 | * 01/16/06 -- This war will be in place until a new official PROM is released. | ||
172 | * Additionally note that the struct sn_flush_device_war also has to be | ||
173 | * removed from arch/ia64/sn/include/xtalk/hubdev.h | ||
174 | */ | ||
175 | static u8 war_implemented = 0; | ||
176 | |||
177 | static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, | ||
178 | struct sn_flush_device_common *common) | ||
179 | { | ||
180 | struct sn_flush_device_war *war_list; | ||
181 | struct sn_flush_device_war *dev_entry; | ||
182 | struct ia64_sal_retval isrv = {0,0,0,0}; | ||
183 | |||
184 | if (!war_implemented) { | ||
185 | printk(KERN_WARNING "PROM version < 4.50 -- implementing old " | ||
186 | "PROM flush WAR\n"); | ||
187 | war_implemented = 1; | ||
188 | } | ||
189 | |||
190 | war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); | ||
191 | if (!war_list) | ||
192 | BUG(); | ||
193 | |||
194 | SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, | ||
195 | nasid, widget, __pa(war_list), 0, 0, 0 ,0); | ||
196 | if (isrv.status) | ||
197 | panic("sn_device_fixup_war failed: %s\n", | ||
198 | ia64_sal_strerror(isrv.status)); | ||
199 | |||
200 | dev_entry = war_list + device; | ||
201 | memcpy(common,dev_entry, sizeof(*common)); | ||
202 | kfree(war_list); | ||
203 | |||
204 | return isrv.status; | ||
205 | } | ||
206 | |||
168 | /* | 207 | /* |
169 | * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for | 208 | * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for |
170 | * each node in the system. | 209 | * each node in the system. |
171 | */ | 210 | */ |
172 | static void sn_fixup_ionodes(void) | 211 | static void sn_fixup_ionodes(void) |
@@ -242,12 +281,21 @@ static void sn_fixup_ionodes(void) | |||
242 | memset(dev_entry->common, 0x0, sizeof(struct | 281 | memset(dev_entry->common, 0x0, sizeof(struct |
243 | sn_flush_device_common)); | 282 | sn_flush_device_common)); |
244 | 283 | ||
245 | status = sal_get_device_dmaflush_list(nasid, | 284 | if (sn_prom_feature_available( |
246 | widget, | 285 | PRF_DEVICE_FLUSH_LIST)) |
247 | device, | 286 | status = sal_get_device_dmaflush_list( |
287 | nasid, | ||
288 | widget, | ||
289 | device, | ||
248 | (u64)(dev_entry->common)); | 290 | (u64)(dev_entry->common)); |
249 | if (status) | 291 | else |
250 | BUG(); | 292 | status = sn_device_fixup_war(nasid, |
293 | widget, | ||
294 | device, | ||
295 | dev_entry->common); | ||
296 | if (status != SALRET_OK) | ||
297 | panic("SAL call failed: %s\n", | ||
298 | ia64_sal_strerror(status)); | ||
251 | 299 | ||
252 | spin_lock_init(&dev_entry->sfdl_flush_lock); | 300 | spin_lock_init(&dev_entry->sfdl_flush_lock); |
253 | } | 301 | } |