aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn/kernel
diff options
context:
space:
mode:
authorMark Maule <maule@sgi.com>2005-04-25 14:26:03 -0400
committerTony Luck <tony.luck@intel.com>2005-04-25 14:26:03 -0400
commite955d82543fea76b02aa243b182e782f71bda82c (patch)
tree58dc9df5161f47bca69c8dc9c819495f15694352 /arch/ia64/sn/kernel
parent25ee7e3832951cf5896b194f6cd929a44863f419 (diff)
[IA64-SGI] sn2-pci-dma-abstraction.patch
Provide an abstraction of the altix pci dma runtime layer so that multiple pci-based bridges can be supported. Signed-off-by: Mark Maule <maule@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/sn/kernel')
-rw-r--r--arch/ia64/sn/kernel/io_init.c72
1 files changed, 64 insertions, 8 deletions
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 001880812b7c..3e5e4a901302 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -34,6 +34,37 @@ struct brick {
34 34
35int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */ 35int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */
36 36
37struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */
38
39/*
40 * Hooks and struct for unsupported pci providers
41 */
42
43static dma_addr_t
44sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size)
45{
46 return 0;
47}
48
49static void
50sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction)
51{
52 return;
53}
54
55static void *
56sn_default_pci_bus_fixup(struct pcibus_bussoft *soft)
57{
58 return NULL;
59}
60
61static struct sn_pcibus_provider sn_pci_default_provider = {
62 .dma_map = sn_default_pci_map,
63 .dma_map_consistent = sn_default_pci_map,
64 .dma_unmap = sn_default_pci_unmap,
65 .bus_fixup = sn_default_pci_bus_fixup,
66};
67
37/* 68/*
38 * Retrieve the DMA Flush List given nasid. This list is needed 69 * Retrieve the DMA Flush List given nasid. This list is needed
39 * to implement the WAR - Flush DMA data on PIO Reads. 70 * to implement the WAR - Flush DMA data on PIO Reads.
@@ -201,6 +232,7 @@ static void sn_pci_fixup_slot(struct pci_dev *dev)
201 struct sn_irq_info *sn_irq_info; 232 struct sn_irq_info *sn_irq_info;
202 struct pci_dev *host_pci_dev; 233 struct pci_dev *host_pci_dev;
203 int status = 0; 234 int status = 0;
235 struct pcibus_bussoft *bs;
204 236
205 dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL); 237 dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL);
206 if (SN_PCIDEV_INFO(dev) <= 0) 238 if (SN_PCIDEV_INFO(dev) <= 0)
@@ -241,6 +273,7 @@ static void sn_pci_fixup_slot(struct pci_dev *dev)
241 } 273 }
242 274
243 /* set up host bus linkages */ 275 /* set up host bus linkages */
276 bs = SN_PCIBUS_BUSSOFT(dev->bus);
244 host_pci_dev = 277 host_pci_dev =
245 pci_find_slot(SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32, 278 pci_find_slot(SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32,
246 SN_PCIDEV_INFO(dev)-> 279 SN_PCIDEV_INFO(dev)->
@@ -248,10 +281,16 @@ static void sn_pci_fixup_slot(struct pci_dev *dev)
248 SN_PCIDEV_INFO(dev)->pdi_host_pcidev_info = 281 SN_PCIDEV_INFO(dev)->pdi_host_pcidev_info =
249 SN_PCIDEV_INFO(host_pci_dev); 282 SN_PCIDEV_INFO(host_pci_dev);
250 SN_PCIDEV_INFO(dev)->pdi_linux_pcidev = dev; 283 SN_PCIDEV_INFO(dev)->pdi_linux_pcidev = dev;
251 SN_PCIDEV_INFO(dev)->pdi_pcibus_info = SN_PCIBUS_BUSSOFT(dev->bus); 284 SN_PCIDEV_INFO(dev)->pdi_pcibus_info = bs;
285
286 if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) {
287 SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type];
288 } else {
289 SN_PCIDEV_BUSPROVIDER(dev) = &sn_pci_default_provider;
290 }
252 291
253 /* Only set up IRQ stuff if this device has a host bus context */ 292 /* Only set up IRQ stuff if this device has a host bus context */
254 if (SN_PCIDEV_BUSSOFT(dev) && sn_irq_info->irq_irq) { 293 if (bs && sn_irq_info->irq_irq) {
255 SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = sn_irq_info; 294 SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = sn_irq_info;
256 dev->irq = SN_PCIDEV_INFO(dev)->pdi_sn_irq_info->irq_irq; 295 dev->irq = SN_PCIDEV_INFO(dev)->pdi_sn_irq_info->irq_irq;
257 sn_irq_fixup(dev, sn_irq_info); 296 sn_irq_fixup(dev, sn_irq_info);
@@ -271,6 +310,7 @@ static void sn_pci_controller_fixup(int segment, int busnum)
271 struct pcibus_bussoft *prom_bussoft_ptr; 310 struct pcibus_bussoft *prom_bussoft_ptr;
272 struct hubdev_info *hubdev_info; 311 struct hubdev_info *hubdev_info;
273 void *provider_soft; 312 void *provider_soft;
313 struct sn_pcibus_provider *provider;
274 314
275 status = 315 status =
276 sal_get_pcibus_info((u64) segment, (u64) busnum, 316 sal_get_pcibus_info((u64) segment, (u64) busnum,
@@ -291,16 +331,22 @@ static void sn_pci_controller_fixup(int segment, int busnum)
291 /* 331 /*
292 * Per-provider fixup. Copies the contents from prom to local 332 * Per-provider fixup. Copies the contents from prom to local
293 * area and links SN_PCIBUS_BUSSOFT(). 333 * 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 */ 334 */
298 335
299 if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) { 336 if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) {
300 return; /* no further fixup necessary */ 337 return; /* unsupported asic type */
338 }
339
340 provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type];
341 if (provider == NULL) {
342 return; /* no provider registerd for this asic */
343 }
344
345 provider_soft = NULL;
346 if (provider->bus_fixup) {
347 provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr);
301 } 348 }
302 349
303 provider_soft = pcibr_bus_fixup(prom_bussoft_ptr);
304 if (provider_soft == NULL) { 350 if (provider_soft == NULL) {
305 return; /* fixup failed or not applicable */ 351 return; /* fixup failed or not applicable */
306 } 352 }
@@ -339,6 +385,16 @@ static int __init sn_pci_init(void)
339 return 0; 385 return 0;
340 386
341 /* 387 /*
388 * prime sn_pci_provider[]. Individial provider init routines will
389 * override their respective default entries.
390 */
391
392 for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++)
393 sn_pci_provider[i] = &sn_pci_default_provider;
394
395 pcibr_init_provider();
396
397 /*
342 * This is needed to avoid bounce limit checks in the blk layer 398 * This is needed to avoid bounce limit checks in the blk layer
343 */ 399 */
344 ia64_max_iommu_merge_mask = ~PAGE_MASK; 400 ia64_max_iommu_merge_mask = ~PAGE_MASK;