|
@@ -165,8 +165,45 @@ sn_pcidev_info_get(struct pci_dev *dev)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+/* Older PROM flush WAR
|
|
|
+ *
|
|
|
+ * 01/16/06 -- This war will be in place until a new official PROM is released.
|
|
|
+ * Additionally note that the struct sn_flush_device_war also has to be
|
|
|
+ * removed from arch/ia64/sn/include/xtalk/hubdev.h
|
|
|
+ */
|
|
|
+static u8 war_implemented = 0;
|
|
|
+
|
|
|
+static void sn_device_fixup_war(u64 nasid, u64 widget, int device,
|
|
|
+ struct sn_flush_device_common *common)
|
|
|
+{
|
|
|
+ struct sn_flush_device_war *war_list;
|
|
|
+ struct sn_flush_device_war *dev_entry;
|
|
|
+ struct ia64_sal_retval isrv = {0,0,0,0};
|
|
|
+
|
|
|
+ if (!war_implemented) {
|
|
|
+ printk(KERN_WARNING "PROM version < 4.50 -- implementing old "
|
|
|
+ "PROM flush WAR\n");
|
|
|
+ war_implemented = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
|
|
|
+ if (!war_list)
|
|
|
+ BUG();
|
|
|
+
|
|
|
+ SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
|
|
|
+ nasid, widget, __pa(war_list), 0, 0, 0 ,0);
|
|
|
+ if (isrv.status)
|
|
|
+ panic("sn_device_fixup_war failed: %s\n",
|
|
|
+ ia64_sal_strerror(isrv.status));
|
|
|
+
|
|
|
+ dev_entry = war_list + device;
|
|
|
+ memcpy(common,dev_entry, sizeof(*common));
|
|
|
+
|
|
|
+ kfree(war_list);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
- * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
|
|
|
+ * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
|
|
|
* each node in the system.
|
|
|
*/
|
|
|
static void sn_fixup_ionodes(void)
|
|
@@ -246,8 +283,19 @@ static void sn_fixup_ionodes(void)
|
|
|
widget,
|
|
|
device,
|
|
|
(u64)(dev_entry->common));
|
|
|
- if (status)
|
|
|
- BUG();
|
|
|
+ if (status) {
|
|
|
+ if (sn_sal_rev() < 0x0450) {
|
|
|
+ /* shortlived WAR for older
|
|
|
+ * PROM images
|
|
|
+ */
|
|
|
+ sn_device_fixup_war(nasid,
|
|
|
+ widget,
|
|
|
+ device,
|
|
|
+ dev_entry->common);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ BUG();
|
|
|
+ }
|
|
|
|
|
|
spin_lock_init(&dev_entry->sfdl_flush_lock);
|
|
|
}
|