3b80e91135fa283a11329b0fc776585e8ce58c19
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / sn / io / sn2 / pci_bus_cvlink.c
1 /* $Id$
2  *
3  * This file is subject to the terms and conditions of the GNU General Public
4  * License.  See the file "COPYING" in the main directory of this archive
5  * for more details.
6  *
7  * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
8  */
9
10 #include <linux/config.h>
11 #include <linux/init.h>
12 #include <linux/types.h>
13 #include <linux/pci.h>
14 #include <linux/pci_ids.h>
15 #include <linux/sched.h>
16 #include <linux/ioport.h>
17 #include <asm/sn/types.h>
18 #include <asm/sn/hack.h>
19 #include <asm/sn/sgi.h>
20 #include <asm/sn/io.h>
21 #include <asm/sn/driver.h>
22 #include <asm/sn/iograph.h>
23 #include <asm/param.h>
24 #include <asm/sn/pio.h>
25 #include <asm/sn/xtalk/xwidget.h>
26 #include <asm/sn/sn_private.h>
27 #include <asm/sn/addrs.h>
28 #include <asm/sn/invent.h>
29 #include <asm/sn/hcl.h>
30 #include <asm/sn/hcl_util.h>
31 #include <asm/sn/intr.h>
32 #include <asm/sn/xtalk/xtalkaddrs.h>
33 #include <asm/sn/klconfig.h>
34 #include <asm/sn/nodepda.h>
35 #include <asm/sn/pci/pciio.h>
36 #include <asm/sn/pci/pcibr.h>
37 #include <asm/sn/pci/pcibr_private.h>
38 #include <asm/sn/pci/pci_bus_cvlink.h>
39 #include <asm/sn/simulator.h>
40 #include <asm/sn/sn_cpuid.h>
41
42 extern int bridge_rev_b_data_check_disable;
43
44 devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
45 nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
46 void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
47 unsigned char num_bridges;
48 static int done_probing = 0;
49
50 static int pci_bus_map_create(devfs_handle_t xtalk, char * io_moduleid);
51 devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
52
53 extern unsigned char Is_pic_on_this_nasid[512];
54
55 extern void sn_init_irq_desc(void);
56 extern void register_pcibr_intr(int irq, pcibr_intr_t intr);
57
58
59 /*
60  * For the given device, initialize whether it is a PIC device.
61  */
62 static void
63 set_isPIC(struct sn_device_sysdata *device_sysdata)
64 {
65         pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
66         pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
67
68         device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);;
69 }
70
71 /*
72  * pci_bus_cvlink_init() - To be called once during initialization before 
73  *      SGI IO Infrastructure init is called.
74  */
75 void
76 pci_bus_cvlink_init(void)
77 {
78
79         extern void ioconfig_bus_init(void);
80
81         memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
82         memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
83
84         memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
85
86         num_bridges = 0;
87
88         ioconfig_bus_init();
89 }
90
91 /*
92  * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
93  *      pci bus vertex from the SGI IO Infrastructure.
94  */
95 devfs_handle_t
96 pci_bus_to_vertex(unsigned char busnum)
97 {
98
99         devfs_handle_t  pci_bus = NULL;
100
101
102         /*
103          * First get the xwidget vertex.
104          */
105         pci_bus = busnum_to_pcibr_vhdl[busnum];
106         return(pci_bus);
107 }
108
109 /*
110  * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
111  *      and function numbers.
112  */
113 devfs_handle_t
114 devfn_to_vertex(unsigned char busnum, unsigned int devfn)
115 {
116
117         int slot = 0;
118         int func = 0;
119         char    name[16];
120         devfs_handle_t  pci_bus = NULL;
121         devfs_handle_t  device_vertex = (devfs_handle_t)NULL;
122
123         /*
124          * Go get the pci bus vertex.
125          */
126         pci_bus = pci_bus_to_vertex(busnum);
127         if (!pci_bus) {
128                 /*
129                  * During probing, the Linux pci code invents non existant
130                  * bus numbers and pci_dev structures and tries to access
131                  * them to determine existance. Don't crib during probing.
132                  */
133                 if (done_probing)
134                         printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
135                 return(NULL);
136         }
137
138
139         /*
140          * Go get the slot&function vertex.
141          * Should call pciio_slot_func_to_name() when ready.
142          */
143         slot = PCI_SLOT(devfn);
144         func = PCI_FUNC(devfn);
145
146         /*
147          * For a NON Multi-function card the name of the device looks like:
148          * ../pci/1, ../pci/2 ..
149          */
150         if (func == 0) {
151                 sprintf(name, "%d", slot);
152                 if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
153                         GRAPH_SUCCESS) {
154                         if (device_vertex) {
155                                 return(device_vertex);
156                         }
157                 }
158         }
159                         
160         /*
161          * This maybe a multifunction card.  It's names look like:
162          * ../pci/1a, ../pci/1b, etc.
163          */
164         sprintf(name, "%d%c", slot, 'a'+func);
165         if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
166                 if (!device_vertex) {
167                         return(NULL);
168                 }
169         }
170
171         return(device_vertex);
172 }
173
174 /*
175  * For the given device, initialize the addresses for both the Device(x) Flush 
176  * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
177  * is connected.
178  */
179 static void
180 set_flush_addresses(struct pci_dev *device_dev, 
181         struct sn_device_sysdata *device_sysdata)
182 {
183         pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
184         pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
185         pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
186         bridge_t               *bridge = pcibr_soft->bs_base;
187         nasid_t                 nasid;
188
189         /*
190          * Get the nasid from the bridge.
191          */
192         nasid = NASID_GET(device_sysdata->dma_buf_sync);
193         if (IS_PIC_DEVICE(device_dev)) {
194                 device_sysdata->dma_buf_sync = (volatile unsigned int *)
195                         &bridge->b_wr_req_buf[pciio_slot].reg;
196                 device_sysdata->xbow_buf_sync = (volatile unsigned int *)
197                         XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0),
198                         pcibr_soft->bs_xid);
199         } else {
200                 /*
201                  * Accessing Xbridge and Xbow register when SHUB swapoper is on!.
202                  */
203                 device_sysdata->dma_buf_sync = (volatile unsigned int *)
204                         ((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4);
205                 device_sysdata->xbow_buf_sync = (volatile unsigned int *)
206                         ((uint64_t)(XBOW_PRIO_LINKREGS_PTR(
207                         NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4);
208         }
209
210 #ifdef DEBUG
211         printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
212                 device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
213
214 printk("set_flush_addresses: dma_buf_sync\n");
215         while((volatile unsigned int )*device_sysdata->dma_buf_sync);
216 printk("set_flush_addresses: xbow_buf_sync\n");
217         while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
218 #endif
219
220 }
221
222 /*
223  * Most drivers currently do not properly tell the arch specific pci dma
224  * interfaces whether they can handle A64. Here is where we privately
225  * keep track of this.
226  */
227 static void __init
228 set_sn_pci64(struct pci_dev *dev)
229 {
230         unsigned short vendor = dev->vendor;
231         unsigned short device = dev->device;
232
233         if (vendor == PCI_VENDOR_ID_QLOGIC) {
234                 if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
235                                 (device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
236                         SET_PCIA64(dev);
237                         return;
238                 }
239         }
240
241         if (vendor == PCI_VENDOR_ID_SGI) {
242                 if (device == PCI_DEVICE_ID_SGI_IOC3) {
243                         SET_PCIA64(dev);
244                         return;
245                 }
246         }
247
248 }
249
250 /*
251  * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
252  *      invoked at the end of pcibios_init() to link the Linux pci 
253  *      infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
254  *
255  *      Other platform specific fixup can also be done here.
256  */
257 void
258 sn_pci_fixup(int arg)
259 {
260         struct list_head *ln;
261         struct pci_bus *pci_bus = NULL;
262         struct pci_dev *device_dev = NULL;
263         struct sn_widget_sysdata *widget_sysdata;
264         struct sn_device_sysdata *device_sysdata;
265         pciio_intr_t intr_handle;
266         int cpuid, bit;
267         devfs_handle_t device_vertex;
268         pciio_intr_line_t lines;
269         extern void sn_pci_find_bios(void);
270         extern int numnodes;
271         int cnode;
272         extern void io_sh_swapper(int, int);
273
274         for (cnode = 0; cnode < numnodes; cnode++) {
275                 if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
276                         io_sh_swapper((cnodeid_to_nasid(cnode)), 0);
277         }
278
279         if (arg == 0) {
280 #ifdef CONFIG_PROC_FS
281                 extern void register_sn_procfs(void);
282 #endif
283
284                 sn_init_irq_desc();
285                 sn_pci_find_bios();
286                 for (cnode = 0; cnode < numnodes; cnode++) {
287                         extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
288                         intr_init_vecblk(NODEPDA(cnode), cnode, 0);
289                 } 
290
291                 /*
292                  * When we return to generic Linux, Swapper is always on ..
293                  */
294                 for (cnode = 0; cnode < numnodes; cnode++) {
295                         if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
296                                 io_sh_swapper((cnodeid_to_nasid(cnode)), 1);
297                 }
298 #ifdef CONFIG_PROC_FS
299                 register_sn_procfs();
300 #endif
301                 return;
302         }
303
304
305         done_probing = 1;
306
307         /*
308          * Initialize the pci bus vertex in the pci_bus struct.
309          */
310         for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
311                 pci_bus = pci_bus_b(ln);
312                 widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
313                                         GFP_KERNEL);
314                 widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
315                 pci_bus->sysdata = (void *)widget_sysdata;
316         }
317
318         /*
319          * set the root start and end so that drivers calling check_region()
320          * won't see a conflict
321          */
322         ioport_resource.start  = 0xc000000000000000;
323         ioport_resource.end =    0xcfffffffffffffff;
324
325         /*
326          * Initialize the device vertex in the pci_dev struct.
327          */
328         while ((device_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device_dev)) != NULL) {
329                 unsigned int irq;
330                 int idx;
331                 u16 cmd;
332                 devfs_handle_t vhdl;
333                 unsigned long size;
334                 extern int bit_pos_to_irq(int);
335
336                 if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
337                                 device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
338                         extern void pci_fixup_ioc3(struct pci_dev *d);
339                         pci_fixup_ioc3(device_dev);
340                 }
341
342                 /* Set the device vertex */
343
344                 device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
345                                         GFP_KERNEL);
346                 device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
347                 device_sysdata->isa64 = 0;
348                 /*
349                  * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
350                  * register addresses.
351                  */
352                 (void) set_flush_addresses(device_dev, device_sysdata);
353
354                 device_dev->sysdata = (void *) device_sysdata;
355                 set_sn_pci64(device_dev);
356                 set_isPIC(device_sysdata);
357
358                 pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
359
360                 /*
361                  * Set the resources address correctly.  The assumption here 
362                  * is that the addresses in the resource structure has been
363                  * read from the card and it was set in the card by our
364                  * Infrastructure ..
365                  */
366                 vhdl = device_sysdata->vhdl;
367                 for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
368                         size = 0;
369                         size = device_dev->resource[idx].end -
370                                 device_dev->resource[idx].start;
371                         if (size) {
372                                 device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
373                                 device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
374                         }
375                         else
376                                 continue;
377
378                         device_dev->resource[idx].end = 
379                                 device_dev->resource[idx].start + size;
380
381                         if (device_dev->resource[idx].flags & IORESOURCE_IO)
382                                 cmd |= PCI_COMMAND_IO;
383
384                         if (device_dev->resource[idx].flags & IORESOURCE_MEM)
385                                 cmd |= PCI_COMMAND_MEMORY;
386                 }
387 #if 0
388         /*
389          * Software WAR for a Software BUG.
390          * This is only temporary.
391          * See PV 872791
392          */
393
394                 /*
395                  * Now handle the ROM resource ..
396                  */
397                 size = device_dev->resource[PCI_ROM_RESOURCE].end -
398                         device_dev->resource[PCI_ROM_RESOURCE].start;
399
400                 if (size) {
401                         device_dev->resource[PCI_ROM_RESOURCE].start =
402                         (unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
403                                 size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
404                         device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
405                         device_dev->resource[PCI_ROM_RESOURCE].end =
406                         device_dev->resource[PCI_ROM_RESOURCE].start + size;
407                 }
408 #endif
409
410                 /*
411                  * Update the Command Word on the Card.
412                  */
413                 cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
414                                            /* bit gets dropped .. no harm */
415                 pci_write_config_word(device_dev, PCI_COMMAND, cmd);
416
417                 pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
418                 if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
419                         device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
420                                 lines = 1;
421                 }
422  
423                 device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
424                 device_vertex = device_sysdata->vhdl;
425  
426                 intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
427
428                 bit = intr_handle->pi_irq;
429                 cpuid = intr_handle->pi_cpu;
430                 irq = bit;
431                 irq = irq + (cpuid << 8);
432                 pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0);
433                 device_dev->irq = irq;
434                 register_pcibr_intr(irq, (pcibr_intr_t)intr_handle);
435 #ifdef ajmtestintr
436                 {
437                         int slot = PCI_SLOT(device_dev->devfn);
438                         static int timer_set = 0;
439                         pcibr_intr_t    pcibr_intr = (pcibr_intr_t)intr_handle;
440                         pcibr_soft_t    pcibr_soft = pcibr_intr->bi_soft;
441                         extern void intr_test_handle_intr(int, void*, struct pt_regs *);
442
443                         if (!timer_set) {
444                                 intr_test_set_timer();
445                                 timer_set = 1;
446                         }
447                         intr_test_register_irq(irq, pcibr_soft, slot);
448                         request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
449                 }
450 #endif
451
452         }
453
454         for (cnode = 0; cnode < numnodes; cnode++) {
455                 if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
456                         io_sh_swapper((cnodeid_to_nasid(cnode)), 1);
457         }
458 }
459
460 /*
461  * linux_bus_cvlink() Creates a link between the Linux PCI Bus number 
462  *      to the actual hardware component that it represents:
463  *      /dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
464  *
465  *      The bus vertex, when called to devfs_generate_path() returns:
466  *              hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
467  *              hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/0
468  *              hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/1
469  */
470 void
471 linux_bus_cvlink(void)
472 {
473         char name[8];
474         int index;
475         
476         for (index=0; index < MAX_PCI_XWIDGET; index++) {
477                 if (!busnum_to_pcibr_vhdl[index])
478                         continue;
479
480                 sprintf(name, "%x", index);
481                 (void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], 
482                                 name);
483         }
484 }
485
486 /*
487  * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
488  *
489  *      Linux PCI Bus numbers are assigned from lowest module_id numbers
490  *      (rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
491  *      HUB_WIDGET_ID_MIN:
492  *              widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
493  *
494  *      Given 2 modules 001c01 and 001c02 we get the following mappings:
495  *              001c01, widgetnum 15 = Bus number 0
496  *              001c01, widgetnum 14 = Bus number 1
497  *              001c02, widgetnum 15 = Bus number 3
498  *              001c02, widgetnum 14 = Bus number 4
499  *              etc.
500  *
501  * The rational for starting Bus Number 0 with Widget number 15 is because 
502  * the system boot disks are always connected via Widget 15 Slot 0 of the 
503  * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
504  * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
505  * module id(Master Cnode) of the system.
506  *      
507  */
508 static int 
509 pci_bus_map_create(devfs_handle_t xtalk, char * io_moduleid)
510 {
511
512         devfs_handle_t master_node_vertex = NULL;
513         devfs_handle_t xwidget = NULL;
514         devfs_handle_t pci_bus = NULL;
515         hubinfo_t hubinfo = NULL;
516         xwidgetnum_t widgetnum;
517         char pathname[128];
518         graph_error_t rv;
519         int bus;
520         int basebus_num;
521         int bus_number;
522
523         /*
524          * Loop throught this vertex and get the Xwidgets ..
525          */
526
527
528         /* PCI devices */
529
530         for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
531                 sprintf(pathname, "%d", widgetnum);
532                 xwidget = NULL;
533                 
534                 /*
535                  * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
536                  *           /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
537                  */
538                 rv = hwgraph_traverse(xtalk, pathname, &xwidget);
539                 if ( (rv != GRAPH_SUCCESS) ) {
540                         if (!xwidget) {
541                                 continue;
542                         }
543                 }
544
545                 sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
546                 pci_bus = NULL;
547                 if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
548                         if (!pci_bus) {
549                                 continue;
550 }
551
552                 /*
553                  * Assign the correct bus number and also the nasid of this 
554                  * pci Xwidget.
555                  * 
556                  * Should not be any race here ...
557                  */
558                 num_bridges++;
559                 busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
560
561                 /*
562                  * Get the master node and from there get the NASID.
563                  */
564                 master_node_vertex = device_master_get(xwidget);
565                 if (!master_node_vertex) {
566                         printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
567                 }
568         
569                 hubinfo_get(master_node_vertex, &hubinfo);
570                 if (!hubinfo) {
571                         printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
572                         return(1);
573                 } else {
574                         busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
575                 }
576
577                 /*
578                  * Pre assign DMA maps needed for 32 Bits Page Map DMA.
579                  */
580                 busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
581                         sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
582                 if (!busnum_to_atedmamaps[num_bridges - 1])
583                         printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
584
585                 memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
586                         sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
587
588         }
589
590         /*
591          * PCIX devices
592          * We number busses differently for PCI-X devices.
593          * We start from Lowest Widget on up ..
594          */
595
596         (void) ioconfig_get_busnum((char *)io_moduleid, &basebus_num);
597
598         for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
599
600                 /* Do both buses */
601                 for ( bus = 0; bus < 2; bus++ ) {
602                         sprintf(pathname, "%d", widgetnum);
603                         xwidget = NULL;
604                         
605                         /*
606                          * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
607                          *           /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus
608                          *           /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device
609                          */
610                         rv = hwgraph_traverse(xtalk, pathname, &xwidget);
611                         if ( (rv != GRAPH_SUCCESS) ) {
612                                 if (!xwidget) {
613                                         continue;
614                                 }
615                         }
616         
617                         if ( bus == 0 )
618                                 sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
619                         else
620                                 sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
621                         pci_bus = NULL;
622                         if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
623                                 if (!pci_bus) {
624                                         continue;
625                                 }
626         
627                         /*
628                          * Assign the correct bus number and also the nasid of this 
629                          * pci Xwidget.
630                          * 
631                          * Should not be any race here ...
632                          */
633                         bus_number = basebus_num + bus + io_brick_map_widget(MODULE_PXBRICK, widgetnum);
634 #ifdef DEBUG
635                         printk("bus_number %d basebus_num %d bus %d io %d\n", 
636                                 bus_number, basebus_num, bus, 
637                                 io_brick_map_widget(MODULE_PXBRICK, widgetnum));
638 #endif
639                         busnum_to_pcibr_vhdl[bus_number] = pci_bus;
640         
641                         /*
642                          * Pre assign DMA maps needed for 32 Bits Page Map DMA.
643                          */
644                         busnum_to_atedmamaps[bus_number] = (void *) kmalloc(
645                                 sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
646                         if (!busnum_to_atedmamaps[bus_number])
647                                 printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
648         
649                         memset(busnum_to_atedmamaps[bus_number], 0x0, 
650                                 sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
651                 }
652         }
653
654         return(0);
655 }
656
657 /*
658  * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
659  *      initialization has completed to set up the mappings between Xbridge
660  *      and logical pci bus numbers.  We also set up the NASID for each of these
661  *      xbridges.
662  *
663  *      Must be called before pci_init() is invoked.
664  */
665 int
666 pci_bus_to_hcl_cvlink(void) 
667 {
668
669         devfs_handle_t devfs_hdl = NULL;
670         devfs_handle_t xtalk = NULL;
671         int rv = 0;
672         char name[256];
673         char tmp_name[256];
674         int i, ii;
675
676         /*
677          * Figure out which IO Brick is connected to the Compute Bricks.
678          */
679         for (i = 0; i < nummodules; i++) {
680                 extern int iomoduleid_get(nasid_t);
681                 moduleid_t iobrick_id;
682                 nasid_t nasid = -1;
683                 int nodecnt;
684                 int n = 0;
685
686                 nodecnt = modules[i]->nodecnt;
687                 for ( n = 0; n < nodecnt; n++ ) {
688                         nasid = cnodeid_to_nasid(modules[i]->nodes[n]);
689                         iobrick_id = iomoduleid_get(nasid);
690                         if ((int)iobrick_id > 0) { /* Valid module id */
691                                 char name[12];
692                                 memset(name, 0, 12);
693                                 format_module_id((char *)&(modules[i]->io[n].moduleid), iobrick_id, MODULE_FORMAT_BRIEF);
694                         }
695                 }
696         }
697                                 
698         devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
699         for (i = 0; i < nummodules ; i++) {
700                 for ( ii = 0; ii < 2 ; ii++ ) {
701                         memset(name, 0, 256);
702                         memset(tmp_name, 0, 256);
703                         format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
704                         sprintf(tmp_name, "/slab/%d/Pbrick/xtalk", geo_slab(modules[i]->geoid[ii]));
705                         strcat(name, tmp_name);
706                         xtalk = NULL;
707                         rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
708                         pci_bus_map_create(xtalk, (char *)&(modules[i]->io[ii].moduleid));
709                 }
710         }
711
712         /*
713          * Create the Linux PCI bus number vertex link.
714          */
715         (void)linux_bus_cvlink();
716         (void)ioconfig_bus_new_entries();
717
718         return(0);
719 }