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.c78
1 files changed, 68 insertions, 10 deletions
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 001880812b7c..18160a06a8c9 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -11,14 +11,15 @@
11#include <asm/sn/types.h> 11#include <asm/sn/types.h>
12#include <asm/sn/sn_sal.h> 12#include <asm/sn/sn_sal.h>
13#include <asm/sn/addrs.h> 13#include <asm/sn/addrs.h>
14#include "pci/pcibus_provider_defs.h" 14#include <asm/sn/pcibus_provider_defs.h>
15#include "pci/pcidev.h" 15#include <asm/sn/pcidev.h>
16#include "pci/pcibr_provider.h" 16#include "pci/pcibr_provider.h"
17#include "xtalk/xwidgetdev.h" 17#include "xtalk/xwidgetdev.h"
18#include <asm/sn/geo.h> 18#include <asm/sn/geo.h>
19#include "xtalk/hubdev.h" 19#include "xtalk/hubdev.h"
20#include <asm/sn/io.h> 20#include <asm/sn/io.h>
21#include <asm/sn/simulator.h> 21#include <asm/sn/simulator.h>
22#include <asm/sn/tioca_provider.h>
22 23
23char master_baseio_wid; 24char master_baseio_wid;
24nasid_t master_nasid = INVALID_NASID; /* Partition Master */ 25nasid_t master_nasid = INVALID_NASID; /* Partition Master */
@@ -34,6 +35,37 @@ struct brick {
34 35
35int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */ 36int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */
36 37
38struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */
39
40/*
41 * Hooks and struct for unsupported pci providers
42 */
43
44static dma_addr_t
45sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size)
46{
47 return 0;
48}
49
50static void
51sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction)
52{
53 return;
54}
55
56static void *
57sn_default_pci_bus_fixup(struct pcibus_bussoft *soft)
58{
59 return NULL;
60}
61
62static struct sn_pcibus_provider sn_pci_default_provider = {
63 .dma_map = sn_default_pci_map,
64 .dma_map_consistent = sn_default_pci_map,
65 .dma_unmap = sn_default_pci_unmap,
66 .bus_fixup = sn_default_pci_bus_fixup,
67};
68
37/* 69/*
38 * Retrieve the DMA Flush List given nasid. This list is needed 70 * Retrieve the DMA Flush List given nasid. This list is needed
39 * to implement the WAR - Flush DMA data on PIO Reads. 71 * to implement the WAR - Flush DMA data on PIO Reads.
@@ -201,6 +233,7 @@ static void sn_pci_fixup_slot(struct pci_dev *dev)
201 struct sn_irq_info *sn_irq_info; 233 struct sn_irq_info *sn_irq_info;
202 struct pci_dev *host_pci_dev; 234 struct pci_dev *host_pci_dev;
203 int status = 0; 235 int status = 0;
236 struct pcibus_bussoft *bs;
204 237
205 dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL); 238 dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL);
206 if (SN_PCIDEV_INFO(dev) <= 0) 239 if (SN_PCIDEV_INFO(dev) <= 0)
@@ -241,6 +274,7 @@ static void sn_pci_fixup_slot(struct pci_dev *dev)
241 } 274 }
242 275
243 /* set up host bus linkages */ 276 /* set up host bus linkages */
277 bs = SN_PCIBUS_BUSSOFT(dev->bus);
244 host_pci_dev = 278 host_pci_dev =
245 pci_find_slot(SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32, 279 pci_find_slot(SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32,
246 SN_PCIDEV_INFO(dev)-> 280 SN_PCIDEV_INFO(dev)->
@@ -248,10 +282,16 @@ static void sn_pci_fixup_slot(struct pci_dev *dev)
248 SN_PCIDEV_INFO(dev)->pdi_host_pcidev_info = 282 SN_PCIDEV_INFO(dev)->pdi_host_pcidev_info =
249 SN_PCIDEV_INFO(host_pci_dev); 283 SN_PCIDEV_INFO(host_pci_dev);
250 SN_PCIDEV_INFO(dev)->pdi_linux_pcidev = dev; 284 SN_PCIDEV_INFO(dev)->pdi_linux_pcidev = dev;
251 SN_PCIDEV_INFO(dev)->pdi_pcibus_info = SN_PCIBUS_BUSSOFT(dev->bus); 285 SN_PCIDEV_INFO(dev)->pdi_pcibus_info = bs;
286
287 if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) {
288 SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type];
289 } else {
290 SN_PCIDEV_BUSPROVIDER(dev) = &sn_pci_default_provider;
291 }
252 292
253 /* Only set up IRQ stuff if this device has a host bus context */ 293 /* Only set up IRQ stuff if this device has a host bus context */
254 if (SN_PCIDEV_BUSSOFT(dev) && sn_irq_info->irq_irq) { 294 if (bs && sn_irq_info->irq_irq) {
255 SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = sn_irq_info; 295 SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = sn_irq_info;
256 dev->irq = SN_PCIDEV_INFO(dev)->pdi_sn_irq_info->irq_irq; 296 dev->irq = SN_PCIDEV_INFO(dev)->pdi_sn_irq_info->irq_irq;
257 sn_irq_fixup(dev, sn_irq_info); 297 sn_irq_fixup(dev, sn_irq_info);
@@ -271,6 +311,7 @@ static void sn_pci_controller_fixup(int segment, int busnum)
271 struct pcibus_bussoft *prom_bussoft_ptr; 311 struct pcibus_bussoft *prom_bussoft_ptr;
272 struct hubdev_info *hubdev_info; 312 struct hubdev_info *hubdev_info;
273 void *provider_soft; 313 void *provider_soft;
314 struct sn_pcibus_provider *provider;
274 315
275 status = 316 status =
276 sal_get_pcibus_info((u64) segment, (u64) busnum, 317 sal_get_pcibus_info((u64) segment, (u64) busnum,
@@ -291,16 +332,22 @@ static void sn_pci_controller_fixup(int segment, int busnum)
291 /* 332 /*
292 * Per-provider fixup. Copies the contents from prom to local 333 * Per-provider fixup. Copies the contents from prom to local
293 * area and links SN_PCIBUS_BUSSOFT(). 334 * area and links SN_PCIBUS_BUSSOFT().
294 *
295 * Note: Provider is responsible for ensuring that prom_bussoft_ptr
296 * represents an asic-type that it can handle.
297 */ 335 */
298 336
299 if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) { 337 if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) {
300 return; /* no further fixup necessary */ 338 return; /* unsupported asic type */
339 }
340
341 provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type];
342 if (provider == NULL) {
343 return; /* no provider registerd for this asic */
344 }
345
346 provider_soft = NULL;
347 if (provider->bus_fixup) {
348 provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr);
301 } 349 }
302 350
303 provider_soft = pcibr_bus_fixup(prom_bussoft_ptr);
304 if (provider_soft == NULL) { 351 if (provider_soft == NULL) {
305 return; /* fixup failed or not applicable */ 352 return; /* fixup failed or not applicable */
306 } 353 }
@@ -339,6 +386,17 @@ static int __init sn_pci_init(void)
339 return 0; 386 return 0;
340 387
341 /* 388 /*
389 * prime sn_pci_provider[]. Individial provider init routines will
390 * override their respective default entries.
391 */
392
393 for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++)
394 sn_pci_provider[i] = &sn_pci_default_provider;
395
396 pcibr_init_provider();
397 tioca_init_provider();
398
399 /*
342 * This is needed to avoid bounce limit checks in the blk layer 400 * This is needed to avoid bounce limit checks in the blk layer
343 */ 401 */
344 ia64_max_iommu_merge_mask = ~PAGE_MASK; 402 ia64_max_iommu_merge_mask = ~PAGE_MASK;