File: /usr/src/linux/arch/ia64/sn/io/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 Silicon Graphics, Inc.
8      * Copyright (C) 2000 by Colin Ngam
9      */
10     
11     #include <linux/init.h>
12     #include <linux/types.h>
13     #include <linux/pci.h>
14     #include <linux/sched.h>
15     #include <linux/ioport.h>
16     #include <asm/sn/types.h>
17     #include <asm/sn/hack.h>
18     #include <asm/sn/sgi.h>
19     #include <asm/sn/iobus.h>
20     #include <asm/sn/iograph.h>
21     #include <asm/param.h>
22     #include <asm/sn/pio.h>
23     #include <asm/sn/xtalk/xwidget.h>
24     #include <asm/sn/sn_private.h>
25     #include <asm/sn/addrs.h>
26     #include <asm/sn/invent.h>
27     #include <asm/sn/hcl.h>
28     #include <asm/sn/hcl_util.h>
29     #include <asm/sn/agent.h>
30     #include <asm/sn/intr.h>
31     #include <asm/sn/xtalk/xtalkaddrs.h>
32     #include <asm/sn/klconfig.h>
33     #include <asm/sn/io.h>
34     
35     #include <asm/sn/pci/pciio.h>
36     // #include <sys/ql.h>
37     #include <asm/sn/pci/pcibr.h>
38     #include <asm/sn/pci/pcibr_private.h>
39     extern int bridge_rev_b_data_check_disable;
40     #include <asm/sn/pci/pci_bus_cvlink.h>
41     
42     #define MAX_PCI_XWIDGET 256
43     devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
44     nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
45     void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
46     unsigned char num_bridges;
47     static int done_probing = 0;
48     
49     static int pci_bus_map_create(devfs_handle_t xtalk);
50     devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
51     
52     #define SN1_IOPORTS_UNIT 256
53     #define MAX_IOPORTS 0xffff
54     #define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN1_IOPORTS_UNIT)
55     struct ioports_to_tlbs_s ioports_to_tlbs[MAX_IOPORTS_CHUNKS];
56     unsigned long sn1_allocate_ioports(unsigned long pci_address);
57     
58     
59     
60     /*
61      * pci_bus_cvlink_init() - To be called once during initialization before 
62      *	SGI IO Infrastructure init is called.
63      */
64     void
65     pci_bus_cvlink_init(void)
66     {
67     	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
68     	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
69     
70     	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
71     
72     	memset(ioports_to_tlbs, 0x0, sizeof(ioports_to_tlbs));
73     
74     	num_bridges = 0;
75     }
76     
77     /*
78      * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
79      *	pci bus vertex from the SGI IO Infrastructure.
80      */
81     devfs_handle_t
82     pci_bus_to_vertex(unsigned char busnum)
83     {
84     
85     	devfs_handle_t	pci_bus = NULL;
86     
87     
88     	/*
89     	 * First get the xwidget vertex.
90     	 */
91     	pci_bus = busnum_to_pcibr_vhdl[busnum];
92     	return(pci_bus);
93     }
94     
95     /*
96      * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
97      *	and function numbers.
98      */
99     devfs_handle_t
100     devfn_to_vertex(unsigned char busnum, unsigned int devfn)
101     {
102     
103     	int slot = 0;
104     	int func = 0;
105     	char	name[16];
106     	devfs_handle_t  pci_bus = NULL;
107     	devfs_handle_t	device_vertex = NULL;
108     
109     	/*
110     	 * Go get the pci bus vertex.
111     	 */
112     	pci_bus = pci_bus_to_vertex(busnum);
113     	if (!pci_bus) {
114     		/*
115     		 * During probing, the Linux pci code invents non existant
116     		 * bus numbers and pci_dev structures and tries to access
117     		 * them to determine existance. Don't crib during probing.
118     		 */
119     		if (done_probing)
120     			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
121     		return(NULL);
122     	}
123     
124     
125     	/*
126     	 * Go get the slot&function vertex.
127     	 * Should call pciio_slot_func_to_name() when ready.
128     	 */
129     	slot = PCI_SLOT(devfn);
130     	func = PCI_FUNC(devfn);
131     
132     	if (func == 0)
133             	sprintf(name, "%d", slot);
134     	else
135     		sprintf(name, "%d%c", slot, 'a'+func);
136     
137     	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
138     		if (!device_vertex) {
139     			return(NULL);
140     		}
141     	}
142     
143     	return(device_vertex);
144     }
145     
146     /*
147      * Most drivers currently do not properly tell the arch specific pci dma
148      * interfaces whether they can handle A64. Here is where we privately
149      * keep track of this.
150      */
151     static void __init
152     set_sn1_pci64(struct pci_dev *dev)
153     {
154     	unsigned short vendor = dev->vendor;
155     	unsigned short device = dev->device;
156     
157     	if (vendor == PCI_VENDOR_ID_QLOGIC) {
158     		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
159     				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
160     			SET_PCIA64(dev);
161     			return;
162     		}
163     	}
164     
165     	if (vendor == PCI_VENDOR_ID_SGI) {
166     		if (device == PCI_DEVICE_ID_SGI_IOC3) {
167     			SET_PCIA64(dev);
168     			return;
169     		}
170     	}
171     
172     }
173     
174     /*
175      * sn1_allocate_ioports() - This routine provides the allocation and 
176      *	mappings between Linux style IOPORTs management.
177      *
178      *	For simplicity sake, SN1 will allocate IOPORTs in chunks of 
179      *	256bytes .. irrespective of what the card desires.  This may 
180      *	have to change when we understand how to deal with legacy ioports 
181      *	which are hardcoded in some drivers e.g. SVGA.
182      *
183      *	Ofcourse, the SN1 IO Infrastructure has no concept of IOPORT numbers.
184      *	It will remain so.  The IO Infrastructure will continue to map 
185      *	IO Resource just like IRIX.  When this is done, we map IOPORT 
186      *	chunks to these resources.  The Linux drivers will see and use real 
187      *	IOPORT numbers.  The various IOPORT access macros e.g. inb/outb etc. 
188      *	does the munging of these IOPORT numbers to make a Uncache Virtual 
189      *	Address.  This address via the tlb entries generates the PCI Address 
190      *	allocated by the SN1 IO Infrastructure Layer.
191      */
192     static unsigned long sn1_ioport_num = 0x100; /* Reserve room for Legacy stuff */
193     unsigned long
194     sn1_allocate_ioports(unsigned long pci_address)
195     {
196     	
197     	unsigned long ioport_index;
198     
199     	/*
200     	 * Just some idiot checking ..
201     	 */
202     	if ( sn1_ioport_num > 0xffff ) {
203     		printk("sn1_allocate_ioports: No more IO PORTS available\n");
204     		return(-1);
205     	}
206     
207     	/*
208     	 * See Section 4.1.1.5 of Intel IA-64 Acrchitecture Software Developer's
209     	 * Manual for details.
210     	 */
211     	ioport_index = sn1_ioport_num / SN1_IOPORTS_UNIT;
212     	ioports_to_tlbs[ioport_index].ppn = pci_address;
213     	ioports_to_tlbs[ioport_index].p = 1; /* Present Bit */
214     	ioports_to_tlbs[ioport_index].ma = 5; /* Memory Attributes */
215     	ioports_to_tlbs[ioport_index].a = 0; /* Set Data Access Bit Fault */
216     	ioports_to_tlbs[ioport_index].d = 0; /* Dirty Bit */
217     	ioports_to_tlbs[ioport_index].pl = 3;/* Privilege Level - All levels can R/W*/
218     	ioports_to_tlbs[ioport_index].ar = 2; /* Access Rights - R/W only*/
219     	ioports_to_tlbs[ioport_index].ed = 0; /* Exception Deferral Bit */
220     	ioports_to_tlbs[ioport_index].ig = 0; /* Ignored */
221     
222     	printk("sn1_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index].ppn);
223     	
224     	sn1_ioport_num += SN1_IOPORTS_UNIT;
225     
226     	return(sn1_ioport_num - SN1_IOPORTS_UNIT);
227     }
228     
229     /*
230      * sn1_pci_fixup() - This routine is called when platform_pci_fixup() is 
231      *	invoked at the end of pcibios_init() to link the Linux pci 
232      *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
233      *
234      *	Other platform specific fixup can also be done here.
235      */
236     void
237     sn1_pci_fixup(int arg)
238     {
239     	struct list_head *ln;
240     	struct pci_bus *pci_bus = NULL;
241     	struct pci_dev *device_dev = NULL;
242     	struct sn1_widget_sysdata *widget_sysdata;
243     	struct sn1_device_sysdata *device_sysdata;
244     	unsigned long ioport;
245     	pciio_intr_t intr_handle;
246     	int cpuid, bit;
247     	devfs_handle_t *device_vertex;
248     	pciio_intr_line_t lines;
249     	extern void sn1_pci_find_bios(void);
250     
251     
252     unsigned long   res;
253     
254     	if (arg == 0) {
255     		sn1_pci_find_bios();
256     		return;
257     	}
258     
259     #if 0
260     {
261             devfs_handle_t  bridge_vhdl = pci_bus_to_vertex(0);
262             pcibr_soft_t    pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl);
263     	bridge_t        *bridge = pcibr_soft->bs_base;
264             printk("pci_fixup_ioc3: Before devreg fixup\n");
265             printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg);
266             printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg);
267             printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg);
268             printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg);
269             printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg);
270             printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg);
271             printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg);
272             printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg);
273     }
274     #endif
275     	done_probing = 1;
276     
277     	if ( IS_RUNNING_ON_SIMULATOR() ) {
278     		printk("sn1_pci_fixup not supported on simulator.\n");
279     		return;
280     	}
281     
282     #ifdef REAL_HARDWARE
283     
284     	/*
285     	 * Initialize the pci bus vertex in the pci_bus struct.
286     	 */
287     	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
288     		pci_bus = pci_bus_b(ln);
289     		widget_sysdata = kmalloc(sizeof(struct sn1_widget_sysdata), 
290     					GFP_KERNEL);
291     		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
292     		pci_bus->sysdata = (void *)widget_sysdata;
293     	}
294     
295     	/*
296      	 * set the root start and end so that drivers calling check_region()
297     	 * won't see a conflict
298     	 */
299     	ioport_resource.start |= IO_SWIZ_BASE;
300     	ioport_resource.end |= (HSPEC_SWIZ_BASE-1);
301     	/*
302     	 * Initialize the device vertex in the pci_dev struct.
303     	 */
304     	pci_for_each_dev(device_dev) {
305     		unsigned int irq;
306     		int idx;
307     		u16 cmd;
308     		devfs_handle_t vhdl;
309     		unsigned long size;
310     
311     		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
312     				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
313     			extern void pci_fixup_ioc3(struct pci_dev *d);
314     			pci_fixup_ioc3(device_dev);
315     		}
316     
317     		/* Set the device vertex */
318     
319     		device_sysdata = kmalloc(sizeof(struct sn1_device_sysdata),
320     					GFP_KERNEL);
321     		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
322     		device_sysdata->isa64 = 0;
323     		device_dev->sysdata = (void *) device_sysdata;
324     		set_sn1_pci64(device_dev);
325     		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
326     
327     		/*
328     		 * Set the resources address correctly.  The assumption here 
329     		 * is that the addresses in the resource structure has been
330     		 * read from the card and it was set in the card by our
331     		 * Infrastructure ..
332     		 */
333     		vhdl = device_sysdata->vhdl;
334     		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
335     			size = 0;
336     			size = device_dev->resource[idx].end -
337     				device_dev->resource[idx].start;
338     			if (size) {
339     				res = 0;
340     				res = pciio_config_get(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + idx, 4);
341     				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, PCIIO_BYTE_STREAM);
342     
343     /* printk("sn1_pci_fixup: Mapped Address = 0x%p size = 0x%x\n", device_dev->resource[idx].start, size); */
344     			}
345     			else
346     				continue;
347     
348     			device_dev->resource[idx].end = 
349     				device_dev->resource[idx].start + size;
350     
351     			/*
352     			 * Adjust the addresses to go to the SWIZZLE ..
353     			 */
354     			device_dev->resource[idx].start = 
355     				device_dev->resource[idx].start & 0xfffff7ffffffffff;
356     			device_dev->resource[idx].end = 
357     				device_dev->resource[idx].end & 0xfffff7ffffffffff;
358     			res = 0;
359     			res = pciio_config_get(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + idx, 4);
360     			if (device_dev->resource[idx].flags & IORESOURCE_IO) {
361     				cmd |= PCI_COMMAND_IO;
362     				ioport = sn1_allocate_ioports(device_dev->resource[idx].start);
363     				/* device_dev->resource[idx].start = ioport; */
364     				/* device_dev->resource[idx].end = ioport + SN1_IOPORTS_UNIT */
365     			}
366     			else if (device_dev->resource[idx].flags & IORESOURCE_MEM)
367     				cmd |= PCI_COMMAND_MEMORY;
368     		}
369     		/*
370     		 * Now handle the ROM resource ..
371     		 */
372     		size = device_dev->resource[PCI_ROM_RESOURCE].end -
373     			device_dev->resource[PCI_ROM_RESOURCE].start;
374     		device_dev->resource[PCI_ROM_RESOURCE].start =
375     			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
376     				size, 0, PCIIO_BYTE_STREAM);
377     		device_dev->resource[PCI_ROM_RESOURCE].end =
378     			device_dev->resource[PCI_ROM_RESOURCE].start + size;
379     
380                     /*
381                      * go through synergy swizzled space
382                      */
383     		device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL;
384     		device_dev->resource[PCI_ROM_RESOURCE].end   &= 0xfffff7ffffffffffUL;
385     
386     		/*
387     		 * Update the Command Word on the Card.
388     		 */
389     		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
390     					   /* bit gets dropped .. no harm */
391     		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
392     
393     		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, &lines);
394     #ifdef BRINGUP
395     		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
396     			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
397     				lines = 1;
398     		}
399     
400     #endif
401      
402     		device_sysdata = (struct sn1_device_sysdata *)device_dev->sysdata;
403     		device_vertex = device_sysdata->vhdl;
404      
405     		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
406     
407     		bit = intr_handle->pi_irq;
408     		cpuid = intr_handle->pi_cpu;
409     		irq = bit_pos_to_irq(bit);
410     		irq = irq + (cpuid << 8);
411     		pciio_intr_connect(intr_handle, NULL, NULL, NULL);
412     		device_dev->irq = irq;
413     
414     	}
415     #endif	/* REAL_HARDWARE */
416     #if 0
417     
418     {
419             devfs_handle_t  bridge_vhdl = pci_bus_to_vertex(0);
420             pcibr_soft_t    pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl);
421             bridge_t        *bridge = pcibr_soft->bs_base;
422     
423             printk("pci_fixup_ioc3: Before devreg fixup\n");
424             printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg);
425             printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg);
426             printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg);
427             printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg);
428             printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg);
429             printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg);
430             printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg);
431             printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg);
432     }
433     #endif
434     
435     }
436     
437     /*
438      * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
439      *
440      *	Linux PCI Bus numbers are assigned from lowest module_id numbers
441      *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
442      *	HUB_WIDGET_ID_MIN:
443      *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
444      *
445      *	Given 2 modules 001c01 and 001c02 we get the following mappings:
446      *		001c01, widgetnum 15 = Bus number 0
447      *		001c01, widgetnum 14 = Bus number 1
448      *		001c02, widgetnum 15 = Bus number 3
449      *		001c02, widgetnum 14 = Bus number 4
450      *		etc.
451      *
452      * The rational for starting Bus Number 0 with Widget number 15 is because 
453      * the system boot disks are always connected via Widget 15 Slot 0 of the 
454      * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
455      * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
456      * module id(Master Cnode) of the system.
457      *	
458      */
459     static int 
460     pci_bus_map_create(devfs_handle_t xtalk)
461     {
462     
463     	devfs_handle_t master_node_vertex = NULL;
464     	devfs_handle_t xwidget = NULL;
465     	devfs_handle_t pci_bus = NULL;
466     	hubinfo_t hubinfo = NULL;
467     	xwidgetnum_t widgetnum;
468     	char pathname[128];
469     	graph_error_t rv;
470     
471     	/*
472     	 * Loop throught this vertex and get the Xwidgets ..
473     	 */
474     	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
475             {
476                     int pos;
477                     char dname[256];
478                     pos = devfs_generate_path(xtalk, dname, 256);
479                     printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
480             }
481     
482     		sprintf(pathname, "%d", widgetnum);
483     		xwidget = NULL;
484     		
485     		/*
486     		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
487     		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
488     		 */
489     		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
490     		if ( (rv != GRAPH_SUCCESS) ) {
491     			if (!xwidget)
492     				continue;
493     		}
494     
495     		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
496     		pci_bus = NULL;
497     		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
498     			if (!pci_bus)
499     				continue;
500     
501     		/*
502     		 * Assign the correct bus number and also the nasid of this 
503     		 * pci Xwidget.
504     		 * 
505     		 * Should not be any race here ...
506     		 */
507     		num_bridges++;
508     		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
509     
510     		/*
511     		 * Get the master node and from there get the NASID.
512     		 */
513     		master_node_vertex = device_master_get(xwidget);
514     		if (!master_node_vertex) {
515     			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", xwidget);
516     		}
517     	
518     		hubinfo_get(master_node_vertex, &hubinfo);
519     		if (!hubinfo) {
520     			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", master_node_vertex);
521     			return(1);
522     		} else {
523     			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
524     		}
525     
526     		/*
527     		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
528     		 */
529     		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
530     			sizeof(struct sn1_dma_maps_s) * 512, GFP_KERNEL);
531     		if (!busnum_to_atedmamaps[num_bridges - 1])
532     			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, xwidget);
533     
534     		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
535     			sizeof(struct sn1_dma_maps_s) * 512);
536     
537     	}
538     
539             return(0);
540     }
541     
542     /*
543      * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
544      *      initialization has completed to set up the mappings between Xbridge
545      *      and logical pci bus numbers.  We also set up the NASID for each of these
546      *      xbridges.
547      *
548      *      Must be called before pci_init() is invoked.
549      */
550     int
551     pci_bus_to_hcl_cvlink(void) 
552     {
553     
554     	devfs_handle_t devfs_hdl = NULL;
555     	devfs_handle_t module_comp = NULL;
556     	devfs_handle_t node = NULL;
557     	devfs_handle_t xtalk = NULL;
558     	graph_vertex_place_t placeptr = EDGE_PLACE_WANT_REAL_EDGES;
559     	int rv = 0;
560     	char name[256];
561     	int master_iobrick;
562     	moduleid_t iobrick_id;
563     	int i;
564     
565     	/*
566     	 * Iterate throught each xtalk links in the system ..
567     	 * /hw/module/001c01/node/xtalk/ 8|9|10|11|12|13|14|15 
568     	 *
569     	 * /hw/module/001c01/node/xtalk/15 -> /hw/module/001c01/Ibrick/xtalk/15
570     	 *
571     	 * What if it is not pci?
572     	 */
573     	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
574     
575     	/*
576     	 * To provide consistent(not persistent) device naming, we need to start 
577     	 * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 
578     	 * with an attached I-Brick.  Find the master_iobrick.
579     	 */
580     	master_iobrick = -1;
581     	for (i = 0; i < nummodules; i++) {
582     		moduleid_t iobrick_id; 
583     		iobrick_id = iobrick_module_get(&modules[i]->elsc);
584     		if (iobrick_id > 0) { /* Valid module id */
585     			if (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) {
586     				master_iobrick = i;
587     				break;
588     			}
589     		}
590     	}
591     
592     	/*
593     	 * The master_iobrick gets bus 0 and 1.
594     	 */
595     	if (master_iobrick >= 0) {
596     		memset(name, 0, 256);
597     		format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF);
598     		strcat(name, "/node/xtalk");
599     		xtalk = NULL;
600     		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
601     		pci_bus_map_create(xtalk);
602     	}
603     		
604     	/*
605     	 * Now go do the rest of the modules, starting from the C-Brick with the lowest 
606     	 * module id, remembering to skip the master_iobrick, which was done above.
607     	 */
608     	for (i = 0; i < nummodules; i++) {
609     		if (i == master_iobrick) {
610     			continue; /* Did the master_iobrick already. */
611     		}
612     
613     		memset(name, 0, 256);
614     		format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
615     		strcat(name, "/node/xtalk");
616     		xtalk = NULL;
617     		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
618     		pci_bus_map_create(xtalk);
619     	}
620     
621     	return(0);
622     }
623     
624     /*
625      * sgi_pci_intr_support -
626      */
627     int
628     sgi_pci_intr_support (unsigned int requested_irq, device_desc_t *dev_desc,
629     	devfs_handle_t *bus_vertex, pciio_intr_line_t *lines,
630     	devfs_handle_t *device_vertex)
631     
632     {
633     
634     	unsigned int bus;
635     	unsigned int devfn;
636     	struct pci_dev *pci_dev;
637     	unsigned char intr_pin = 0;
638     	struct sn1_widget_sysdata *widget_sysdata;
639     	struct sn1_device_sysdata *device_sysdata;
640     
641     	if (!dev_desc || !bus_vertex || !device_vertex) {
642     		printk("WARNING: sgi_pci_intr_support: Invalid parameter dev_desc 0x%p, bus_vertex 0x%p, device_vertex 0x%p\n", dev_desc, bus_vertex, device_vertex);
643     		return(-1);
644     	}
645     
646     	devfn = (requested_irq >> 8) & 0xff;
647     	bus = (requested_irq >> 16) & 0xffff;
648     	pci_dev = pci_find_slot(bus, devfn);
649     	widget_sysdata = (struct sn1_widget_sysdata *)pci_dev->bus->sysdata;
650     	*bus_vertex = widget_sysdata->vhdl;
651     	device_sysdata = (struct sn1_device_sysdata *)pci_dev->sysdata;
652     	*device_vertex = device_sysdata->vhdl;
653     #if 0
654     	{
655     		int pos;
656     		char dname[256];
657     		pos = devfs_generate_path(*device_vertex, dname, 256);
658     		printk("%s : path= %s pos %d\n", __FUNCTION__, &dname[pos], pos);
659     	}
660     #endif /* BRINGUP */
661     
662     
663     	/*
664     	 * Get the Interrupt PIN.
665     	 */
666     	pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intr_pin);
667     	*lines = (pciio_intr_line_t)intr_pin;
668     
669     #ifdef BRINGUP
670     	/*
671     	 * ioc3 can't decode the PCI_INTERRUPT_PIN field of its config
672     	 * space so we have to set it here
673     	 */
674     	if (pci_dev->vendor == PCI_VENDOR_ID_SGI &&
675     	    pci_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
676     		*lines = 1;
677     	}
678     #endif /* BRINGUP */
679     
680     	/* Not supported currently */
681     	*dev_desc = NULL;
682     	return(0);
683     
684     }
685