diff options
Diffstat (limited to 'arch/ia64')
| -rw-r--r-- | arch/ia64/sn/include/xtalk/hubdev.h | 9 | ||||
| -rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 54 |
2 files changed, 60 insertions, 3 deletions
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h index 7c88e9a58516..8182583c762c 100644 --- a/arch/ia64/sn/include/xtalk/hubdev.h +++ b/arch/ia64/sn/include/xtalk/hubdev.h | |||
| @@ -51,6 +51,15 @@ struct sn_flush_device_kernel { | |||
| 51 | struct sn_flush_device_common *common; | 51 | struct sn_flush_device_common *common; |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | /* 01/16/06 This struct is the old PROM/kernel struct and needs to be included | ||
| 55 | * for older official PROMs to function on the new kernel base. This struct | ||
| 56 | * will be removed when the next official PROM release occurs. */ | ||
| 57 | |||
| 58 | struct sn_flush_device_war { | ||
| 59 | struct sn_flush_device_common common; | ||
| 60 | u32 filler; /* older PROMs expect the default size of a spinlock_t */ | ||
| 61 | }; | ||
| 62 | |||
| 54 | /* | 63 | /* |
| 55 | * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel. | 64 | * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel. |
| 56 | */ | 65 | */ |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 233d55115d33..00700f7e6837 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
| @@ -165,8 +165,45 @@ sn_pcidev_info_get(struct pci_dev *dev) | |||
| 165 | return NULL; | 165 | return NULL; |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | /* Older PROM flush WAR | ||
| 169 | * | ||
| 170 | * 01/16/06 -- This war will be in place until a new official PROM is released. | ||
| 171 | * Additionally note that the struct sn_flush_device_war also has to be | ||
| 172 | * removed from arch/ia64/sn/include/xtalk/hubdev.h | ||
| 173 | */ | ||
| 174 | static u8 war_implemented = 0; | ||
| 175 | |||
| 176 | static void sn_device_fixup_war(u64 nasid, u64 widget, int device, | ||
| 177 | struct sn_flush_device_common *common) | ||
| 178 | { | ||
| 179 | struct sn_flush_device_war *war_list; | ||
| 180 | struct sn_flush_device_war *dev_entry; | ||
| 181 | struct ia64_sal_retval isrv = {0,0,0,0}; | ||
| 182 | |||
| 183 | if (!war_implemented) { | ||
| 184 | printk(KERN_WARNING "PROM version < 4.50 -- implementing old " | ||
| 185 | "PROM flush WAR\n"); | ||
| 186 | war_implemented = 1; | ||
| 187 | } | ||
| 188 | |||
| 189 | war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); | ||
| 190 | if (!war_list) | ||
| 191 | BUG(); | ||
| 192 | |||
| 193 | SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, | ||
| 194 | nasid, widget, __pa(war_list), 0, 0, 0 ,0); | ||
| 195 | if (isrv.status) | ||
| 196 | panic("sn_device_fixup_war failed: %s\n", | ||
| 197 | ia64_sal_strerror(isrv.status)); | ||
| 198 | |||
| 199 | dev_entry = war_list + device; | ||
| 200 | memcpy(common,dev_entry, sizeof(*common)); | ||
| 201 | |||
| 202 | kfree(war_list); | ||
| 203 | } | ||
| 204 | |||
| 168 | /* | 205 | /* |
| 169 | * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for | 206 | * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for |
| 170 | * each node in the system. | 207 | * each node in the system. |
| 171 | */ | 208 | */ |
| 172 | static void sn_fixup_ionodes(void) | 209 | static void sn_fixup_ionodes(void) |
| @@ -246,8 +283,19 @@ static void sn_fixup_ionodes(void) | |||
| 246 | widget, | 283 | widget, |
| 247 | device, | 284 | device, |
| 248 | (u64)(dev_entry->common)); | 285 | (u64)(dev_entry->common)); |
| 249 | if (status) | 286 | if (status) { |
| 250 | BUG(); | 287 | if (sn_sal_rev() < 0x0450) { |
| 288 | /* shortlived WAR for older | ||
| 289 | * PROM images | ||
| 290 | */ | ||
| 291 | sn_device_fixup_war(nasid, | ||
| 292 | widget, | ||
| 293 | device, | ||
| 294 | dev_entry->common); | ||
| 295 | } | ||
| 296 | else | ||
| 297 | BUG(); | ||
| 298 | } | ||
| 251 | 299 | ||
| 252 | spin_lock_init(&dev_entry->sfdl_flush_lock); | 300 | spin_lock_init(&dev_entry->sfdl_flush_lock); |
| 253 | } | 301 | } |
