aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn/kernel/io_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/sn/kernel/io_init.c')
-rw-r--r--arch/ia64/sn/kernel/io_init.c60
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 */
175static u8 war_implemented = 0;
176
177static 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 */
172static void sn_fixup_ionodes(void) 211static 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 }