2.5.70 update
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / sn / io / klgraph.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-2002 Silicon Graphics, Inc. All rights reserved.
8  */
9
10 /*
11  * klgraph.c-
12  *      This file specifies the interface between the kernel and the PROM's
13  *      configuration data structures.
14  */
15
16 #include <linux/types.h>
17 #include <linux/config.h>
18 #include <linux/slab.h>
19 #include <asm/sn/sgi.h>
20 #include <asm/sn/sn_sal.h>
21 #include <asm/sn/io.h>
22 #include <asm/sn/iograph.h>
23 #include <asm/sn/invent.h>
24 #include <asm/sn/hcl.h>
25 #include <asm/sn/labelcl.h>
26 #include <asm/sn/kldir.h>
27 #include <asm/sn/gda.h> 
28 #include <asm/sn/klconfig.h>
29 #include <asm/sn/router.h>
30 #include <asm/sn/xtalk/xbow.h>
31 #include <asm/sn/hcl_util.h>
32
33 /* #define KLGRAPH_DEBUG 1 */
34 #ifdef KLGRAPH_DEBUG
35 #define GRPRINTF(x)     printk x
36 #define CE_GRPANIC      CE_PANIC
37 #else
38 #define GRPRINTF(x)
39 #define CE_GRPANIC      CE_PANIC
40 #endif
41
42 #include <asm/sn/sn_private.h>
43
44 extern char arg_maxnodes[];
45 extern u64 klgraph_addr[];
46
47 /*
48  * Support for verbose inventory via hardware graph. 
49  * klhwg_invent_alloc allocates the necessary size of inventory information
50  * and fills in the generic information.
51  */
52 invent_generic_t *
53 klhwg_invent_alloc(cnodeid_t cnode, int class, int size)
54 {
55         invent_generic_t *invent;
56
57         invent = kern_malloc(size);
58         if (!invent) return NULL;
59         
60         invent->ig_module = NODE_MODULEID(cnode);
61         invent->ig_slot = SLOTNUM_GETSLOT(NODE_SLOTID(cnode));
62         invent->ig_invclass = class;
63
64         return invent;
65 }
66
67 /* 
68  * Add information about the baseio prom version number
69  * as a part of detailed inventory info in the hwgraph.
70  */
71 void
72 klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode)
73 {
74         invent_miscinfo_t       *baseio_inventory;
75         unsigned char           version = 0,revision = 0;
76
77         /* Allocate memory for the "detailed inventory" info
78          * for the baseio
79          */
80         baseio_inventory = (invent_miscinfo_t *) 
81                 klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t));
82         baseio_inventory->im_type = INV_IO6PROM;
83         /* Read the io6prom revision from the nvram */
84 #ifdef LATER
85         nvram_prom_version_get(&version,&revision);
86 #endif
87         /* Store the revision info  in the inventory */
88         baseio_inventory->im_version = version;
89         baseio_inventory->im_rev = revision;
90         /* Put the inventory info in the hardware graph */
91         hwgraph_info_add_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, 
92                              (arbitrary_info_t) baseio_inventory);
93         /* Make the information available to the user programs
94          * thru hwgfs.
95          */
96         hwgraph_info_export_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT,
97                                 sizeof(invent_miscinfo_t));
98 }
99
100 char    *hub_rev[] = {
101         "0.0",
102         "1.0",
103         "2.0",
104         "2.1",
105         "2.2",
106         "2.3"
107 };
108
109 /*
110  * Add detailed cpu inventory info to the hardware graph.
111  */
112 void
113 klhwg_hub_invent_info(devfs_handle_t hubv,
114                       cnodeid_t cnode, 
115                       klhub_t *hub)
116 {
117         invent_miscinfo_t *hub_invent;
118
119         hub_invent = (invent_miscinfo_t *) 
120             klhwg_invent_alloc(cnode, INV_MISC, sizeof(invent_miscinfo_t));
121         if (!hub_invent)
122             return;
123
124         if (KLCONFIG_INFO_ENABLED((klinfo_t *)hub))
125             hub_invent->im_gen.ig_flag = INVENT_ENABLED;
126
127         hub_invent->im_type = INV_HUB;
128         hub_invent->im_rev = hub->hub_info.revision;
129         hub_invent->im_speed = hub->hub_speed;
130         hwgraph_info_add_LBL(hubv, INFO_LBL_DETAIL_INVENT, 
131                              (arbitrary_info_t) hub_invent);
132         hwgraph_info_export_LBL(hubv, INFO_LBL_DETAIL_INVENT,
133                                 sizeof(invent_miscinfo_t));
134 }
135
136 /* ARGSUSED */
137 void
138 klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode)
139 {
140 #if defined(CONFIG_IA64_SGI_SN1)
141         devfs_handle_t myhubv;
142         devfs_handle_t hub_mon;
143         devfs_handle_t synergy;
144         devfs_handle_t fsb0;
145         devfs_handle_t fsb1;
146         int rc;
147         extern struct file_operations hub_mon_fops;
148
149         GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB));
150
151         (void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
152         rc = device_master_set(myhubv, node_vertex);
153
154         /*
155          * hub perf stats.
156          */
157         rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO,
158                         (arbitrary_info_t)(&NODEPDA(cnode)->hubstats));
159
160         if (rc != GRAPH_SUCCESS) {
161                 printk(KERN_WARNING  "klhwg_add_hub: Can't add hub info label 0x%p, code %d",
162                         (void *)myhubv, rc);
163         }
164
165         klhwg_hub_invent_info(myhubv, cnode, hub);
166
167         hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
168             0, DEVFS_FL_AUTO_DEVNUM,
169             0, 0,
170             S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
171             &hub_mon_fops,
172             (void *)(long)cnode);
173
174         init_hub_stats(cnode, NODEPDA(cnode));
175
176         /*
177          * synergy perf
178          */
179         (void) hwgraph_path_add(myhubv, EDGE_LBL_SYNERGY, &synergy);
180         (void) hwgraph_path_add(synergy, "0", &fsb0);
181         (void) hwgraph_path_add(synergy, "1", &fsb1);
182
183         fsb0 = hwgraph_register(fsb0, EDGE_LBL_PERFMON,
184             0, DEVFS_FL_AUTO_DEVNUM,
185             0, 0,
186             S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
187             &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 0));
188
189         fsb1 = hwgraph_register(fsb1, EDGE_LBL_PERFMON,
190             0, DEVFS_FL_AUTO_DEVNUM,
191             0, 0,
192             S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
193             &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 1));
194 #endif /* CONFIG_IA64_SGI_SN1 */
195 }
196
197 void
198 klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid)
199 {
200         lboard_t *brd;
201         klxbow_t *xbow_p;
202         nasid_t hub_nasid;
203         cnodeid_t hub_cnode;
204         int widgetnum;
205         devfs_handle_t xbow_v, hubv;
206         /*REFERENCED*/
207         graph_error_t err;
208
209         if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW)) == NULL)
210                         return;
211
212         if (KL_CONFIG_DUPLICATE_BOARD(brd))
213             return;
214
215         GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n",
216                         cnode, nasid));
217
218         if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
219             == NULL)
220             return;
221
222 #ifdef  LATER
223         /*
224          * We cannot support this function in devfs .. see below where 
225          * we use hwgraph_path_add() to create this vertex with a known 
226          * name.
227          */
228         err = hwgraph_vertex_create(&xbow_v);
229         ASSERT(err == GRAPH_SUCCESS);
230
231         xswitch_vertex_init(xbow_v);
232 #endif /* LATER */
233
234         for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
235                 if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) 
236                     continue;
237
238                 hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum);
239                 if (hub_nasid == INVALID_NASID) {
240                         printk(KERN_WARNING  "hub widget %d, skipping xbow graph\n", widgetnum);
241                         continue;
242                 }
243
244                 hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid);
245
246                 if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) {
247                         continue;
248                 }
249                         
250                 hubv = cnodeid_to_vertex(hub_cnode);
251
252                 err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v);
253                 if (err != GRAPH_SUCCESS) {
254                         if (err == GRAPH_DUP)
255                                 printk(KERN_WARNING  "klhwg_add_xbow: Check for "
256                                         "working routers and router links!");
257
258                         PRINT_PANIC("klhwg_add_xbow: Failed to add "
259                                 "edge: vertex 0x%p to vertex 0x%p,"
260                                 "error %d\n",
261                                 (void *)hubv, (void *)xbow_v, err);
262                 }
263                 xswitch_vertex_init(xbow_v); 
264
265                 NODEPDA(hub_cnode)->xbow_vhdl = xbow_v;
266
267                 /*
268                  * XXX - This won't work is we ever hook up two hubs
269                  * by crosstown through a crossbow.
270                  */
271                 if (hub_nasid != nasid) {
272                         NODEPDA(hub_cnode)->xbow_peer = nasid;
273                         NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer =
274                                 hub_nasid;
275                 }
276
277                 GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n",
278                         hub_nasid, EDGE_LBL_XTALK, hubv));
279
280 #ifdef  LATER
281                 err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK);
282                 if (err != GRAPH_SUCCESS) {
283                         if (err == GRAPH_DUP)
284                                 printk(KERN_WARNING  "klhwg_add_xbow: Check for "
285                                         "working routers and router links!");
286
287                         PRINT_PANIC("klhwg_add_xbow: Failed to add "
288                                 "edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p), "
289                                 "error %d\n",
290                                 hubv, hubv, xbow_v, xbow_v, err);
291                 }
292 #endif
293         }
294 }
295
296
297 /* ARGSUSED */
298 void
299 klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap)
300 {
301         nasid_t nasid;
302         lboard_t *brd;
303         klhub_t *hub;
304         devfs_handle_t node_vertex = NULL;
305         char path_buffer[100];
306         int rv;
307         char *s;
308         int board_disabled = 0;
309
310         nasid = COMPACT_TO_NASID_NODEID(cnode);
311         brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
312         GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n",
313                 cnode, nasid, brd));
314         ASSERT(brd);
315
316         do {
317
318                 /* Generate a hardware graph path for this board. */
319                 board_to_path(brd, path_buffer);
320
321                 GRPRINTF(("klhwg_add_node: adding %s to vertex 0x%p\n",
322                         path_buffer, hwgraph_root));
323                 rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
324
325                 if (rv != GRAPH_SUCCESS)
326                         PRINT_PANIC("Node vertex creation failed.  "
327                                           "Path == %s",
328                                 path_buffer);
329
330                 hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
331                 ASSERT(hub);
332                 if(hub->hub_info.flags & KLINFO_ENABLE)
333                         board_disabled = 0;
334                 else
335                         board_disabled = 1;
336                 
337                 if(!board_disabled) {
338                         mark_nodevertex_as_node(node_vertex,
339                                             cnode + board_disabled * numnodes);
340
341                         s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer));
342                         NODEPDA(cnode)->hwg_node_name =
343                                                 kmalloc(strlen(s) + 1,
344                                                 GFP_KERNEL);
345                         ASSERT_ALWAYS(NODEPDA(cnode)->hwg_node_name != NULL);
346                         strcpy(NODEPDA(cnode)->hwg_node_name, s);
347
348                         hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo);
349
350                         /* Set up node board's slot */
351                         NODEPDA(cnode)->slotdesc = brd->brd_slot;
352
353                         /* Set up the module we're in */
354                         NODEPDA(cnode)->module_id = brd->brd_module;
355                         NODEPDA(cnode)->module = module_lookup(brd->brd_module);
356                 }
357
358                 if(!board_disabled)
359                 klhwg_add_hub(node_vertex, hub, cnode);
360                 
361                 brd = KLCF_NEXT(brd);
362                 if (brd)
363                         brd = find_lboard(brd, KLTYPE_SNIA);
364                 else
365                         break;
366         } while(brd);
367 }
368
369
370 /* ARGSUSED */
371 void
372 klhwg_add_all_routers(devfs_handle_t hwgraph_root)
373 {
374         nasid_t nasid;
375         cnodeid_t cnode;
376         lboard_t *brd;
377         devfs_handle_t node_vertex;
378         char path_buffer[100];
379         int rv;
380
381         for (cnode = 0; cnode < numnodes; cnode++) {
382                 nasid = COMPACT_TO_NASID_NODEID(cnode);
383
384                 GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n",
385                         cnode));
386
387                 brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
388                                 KLTYPE_ROUTER);
389
390                 if (!brd)
391                         /* No routers stored in this node's memory */
392                         continue;
393
394                 do {
395                         ASSERT(brd);
396                         GRPRINTF(("Router board struct is %p\n", brd));
397
398                         /* Don't add duplicate boards. */
399                         if (brd->brd_flags & DUPLICATE_BOARD)
400                                 continue;
401
402                         GRPRINTF(("Router 0x%p module number is %d\n", brd, brd->brd_module));
403                         /* Generate a hardware graph path for this board. */
404                         board_to_path(brd, path_buffer);
405
406                         GRPRINTF(("Router path is %s\n", path_buffer));
407
408                         /* Add the router */
409                         GRPRINTF(("klhwg_add_all_routers: adding %s to vertex 0x%p\n",
410                                 path_buffer, hwgraph_root));
411                         rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
412
413                         if (rv != GRAPH_SUCCESS)
414                                 PRINT_PANIC("Router vertex creation "
415                                                   "failed.  Path == %s",
416                                         path_buffer);
417
418                         GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n",
419                                         brd));
420                 /* Find the rest of the routers stored on this node. */
421                 } while ( (brd = find_lboard_class(KLCF_NEXT(brd),
422                          KLTYPE_ROUTER)) );
423
424                 GRPRINTF(("klhwg_add_all_routers: Done.\n"));
425         }
426
427 }
428
429 /* ARGSUSED */
430 void
431 klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd,
432                          cnodeid_t cnode, nasid_t nasid)
433 {
434         klrou_t *router;
435         char path_buffer[50];
436         char dest_path[50];
437         devfs_handle_t router_hndl;
438         devfs_handle_t dest_hndl;
439         int rc;
440         int port;
441         lboard_t *dest_brd;
442
443         GRPRINTF(("klhwg_connect_one_router: Connecting router on cnode %d\n",
444                         cnode));
445
446         /* Don't add duplicate boards. */
447         if (brd->brd_flags & DUPLICATE_BOARD) {
448                 GRPRINTF(("klhwg_connect_one_router: Duplicate router 0x%p on cnode %d\n",
449                         brd, cnode));
450                 return;
451         }
452
453         /* Generate a hardware graph path for this board. */
454         board_to_path(brd, path_buffer);
455
456         rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl);
457
458         if (rc != GRAPH_SUCCESS && is_specified(arg_maxnodes))
459                         return;
460
461         if (rc != GRAPH_SUCCESS)
462                 printk(KERN_WARNING  "Can't find router: %s", path_buffer);
463
464         /* We don't know what to do with multiple router components */
465         if (brd->brd_numcompts != 1) {
466                 PRINT_PANIC("klhwg_connect_one_router: %d cmpts on router\n",
467                         brd->brd_numcompts);
468                 return;
469         }
470
471
472         /* Convert component 0 to klrou_t ptr */
473         router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd),
474                                               brd->brd_compts[0]);
475
476         for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
477                 /* See if the port's active */
478                 if (router->rou_port[port].port_nasid == INVALID_NASID) {
479                         GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n",
480                                  port));
481                         continue;
482                 }
483                 if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(router->rou_port[port].port_nasid) 
484                     == INVALID_CNODEID) {
485                         continue;
486                 }
487
488                 dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
489                                 router->rou_port[port].port_nasid,
490                                 router->rou_port[port].port_offset);
491
492                 /* Generate a hardware graph path for this board. */
493                 board_to_path(dest_brd, dest_path);
494
495                 rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
496
497                 if (rc != GRAPH_SUCCESS) {
498                         if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
499                                 continue;
500                         PRINT_PANIC("Can't find router: %s", dest_path);
501                 }
502                 GRPRINTF(("klhwg_connect_one_router: Link from %s/%d to %s\n",
503                           path_buffer, port, dest_path));
504
505                 sprintf(dest_path, "%d", port);
506
507                 rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path);
508
509                 if (rc == GRAPH_DUP) {
510                         GRPRINTF(("Skipping port %d. nasid %d %s/%s\n",
511                                   port, router->rou_port[port].port_nasid,
512                                   path_buffer, dest_path));
513                         continue;
514                 }
515
516                 if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes))
517                         PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
518                                 path_buffer, dest_path, (void *)dest_hndl, rc);
519                 
520         }
521 }
522
523
524 void
525 klhwg_connect_routers(devfs_handle_t hwgraph_root)
526 {
527         nasid_t nasid;
528         cnodeid_t cnode;
529         lboard_t *brd;
530
531         for (cnode = 0; cnode < numnodes; cnode++) {
532                 nasid = COMPACT_TO_NASID_NODEID(cnode);
533
534                 GRPRINTF(("klhwg_connect_routers: Connecting routers on cnode %d\n",
535                         cnode));
536
537                 brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
538                                 KLTYPE_ROUTER);
539
540                 if (!brd)
541                         continue;
542
543                 do {
544
545                         nasid = COMPACT_TO_NASID_NODEID(cnode);
546
547                         klhwg_connect_one_router(hwgraph_root, brd,
548                                                  cnode, nasid);
549
550                 /* Find the rest of the routers stored on this node. */
551                 } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
552         }
553 }
554
555
556
557 void
558 klhwg_connect_hubs(devfs_handle_t hwgraph_root)
559 {
560         nasid_t nasid;
561         cnodeid_t cnode;
562         lboard_t *brd;
563         klhub_t *hub;
564         lboard_t *dest_brd;
565         devfs_handle_t hub_hndl;
566         devfs_handle_t dest_hndl;
567         char path_buffer[50];
568         char dest_path[50];
569         graph_error_t rc;
570
571         for (cnode = 0; cnode < numnodes; cnode++) {
572                 nasid = COMPACT_TO_NASID_NODEID(cnode);
573
574                 GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n",
575                         cnode));
576
577                 brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
578                 ASSERT(brd);
579
580                 hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
581                 ASSERT(hub);
582
583                 /* See if the port's active */
584                 if (hub->hub_port.port_nasid == INVALID_NASID) {
585                         GRPRINTF(("klhwg_connect_hubs: port inactive.\n"));
586                         continue;
587                 }
588
589                 if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(hub->hub_port.port_nasid) == INVALID_CNODEID)
590                         continue;
591
592                 /* Generate a hardware graph path for this board. */
593                 board_to_path(brd, path_buffer);
594
595                 GRPRINTF(("klhwg_connect_hubs: Hub path is %s.\n", path_buffer));
596                 rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl);
597
598                 if (rc != GRAPH_SUCCESS)
599                         printk(KERN_WARNING  "Can't find hub: %s", path_buffer);
600
601                 dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
602                                 hub->hub_port.port_nasid,
603                                 hub->hub_port.port_offset);
604
605                 /* Generate a hardware graph path for this board. */
606                 board_to_path(dest_brd, dest_path);
607
608                 rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
609
610                 if (rc != GRAPH_SUCCESS) {
611                         if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
612                                 continue;
613                         PRINT_PANIC("Can't find board: %s", dest_path);
614                 } else {
615                 
616
617                         GRPRINTF(("klhwg_connect_hubs: Link from %s to %s.\n",
618                           path_buffer, dest_path));
619
620                         rc = hwgraph_edge_add(hub_hndl, dest_hndl, EDGE_LBL_INTERCONNECT);
621
622                         if (rc != GRAPH_SUCCESS)
623                                 PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
624                                 path_buffer, dest_path, (void *)dest_hndl, rc);
625
626                 }
627         }
628 }
629
630 /* Store the pci/vme disabled board information as extended administrative
631  * hints which can later be used by the drivers using the device/driver
632  * admin interface. 
633  */
634 void
635 klhwg_device_disable_hints_add(void)
636 {
637         cnodeid_t       cnode;          /* node we are looking at */
638         nasid_t         nasid;          /* nasid of the node */
639         lboard_t        *board;         /* board we are looking at */
640         int             comp_index;     /* component index */
641         klinfo_t        *component;     /* component in the board we are
642                                          * looking at 
643                                          */
644         char            device_name[MAXDEVNAME];
645         
646 #ifdef  LATER
647         device_admin_table_init();
648 #endif
649         for(cnode = 0; cnode < numnodes; cnode++) {
650                 nasid = COMPACT_TO_NASID_NODEID(cnode);
651                 board = (lboard_t *)KL_CONFIG_INFO(nasid);
652                 /* Check out all the board info stored  on a node */
653                 while(board) {
654                         /* No need to look at duplicate boards or non-io 
655                          * boards
656                          */
657                         if (KL_CONFIG_DUPLICATE_BOARD(board) ||
658                             KLCLASS(board->brd_type) != KLCLASS_IO) {
659                                 board = KLCF_NEXT(board);
660                                 continue;
661                         }
662                         /* Check out all the components of a board */
663                         for (comp_index = 0; 
664                              comp_index < KLCF_NUM_COMPS(board);
665                              comp_index++) {
666                                 component = KLCF_COMP(board,comp_index);
667                                 /* If the component is enabled move on to
668                                  * the next component
669                                  */
670                                 if (KLCONFIG_INFO_ENABLED(component))
671                                         continue;
672                                 /* NOTE : Since the prom only supports
673                                  * the disabling of pci devices the following
674                                  * piece of code makes sense. 
675                                  * Make sure that this assumption is valid
676                                  */
677                                 /* This component is disabled. Store this
678                                  * hint in the extended device admin table
679                                  */
680                                 /* Get the canonical name of the pci device */
681                                 device_component_canonical_name_get(board,
682                                                             component,
683                                                             device_name);
684 #ifdef  LATER
685                                 device_admin_table_update(device_name,
686                                                           ADMIN_LBL_DISABLED,
687                                                           "yes");
688 #endif
689 #ifdef DEBUG
690                                 printf("%s DISABLED\n",device_name);
691 #endif                          
692                         }
693                         /* go to the next board info stored on this 
694                          * node 
695                          */
696                         board = KLCF_NEXT(board);
697                 }
698         }
699 }
700
701 void
702 klhwg_add_all_modules(devfs_handle_t hwgraph_root)
703 {
704         cmoduleid_t     cm;
705         char            name[128];
706         devfs_handle_t  vhdl;
707         int             rc;
708         char            buffer[16];
709
710         /* Add devices under each module */
711
712         for (cm = 0; cm < nummodules; cm++) {
713                 /* Use module as module vertex fastinfo */
714
715 #ifdef __ia64
716                 memset(buffer, 0, 16);
717                 format_module_id(buffer, modules[cm]->id, MODULE_FORMAT_BRIEF);
718                 sprintf(name, EDGE_LBL_MODULE "/%s", buffer);
719 #else
720                 sprintf(name, EDGE_LBL_MODULE "/%x", modules[cm]->id);
721 #endif
722
723                 rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
724                 ASSERT(rc == GRAPH_SUCCESS);
725                 rc = rc;
726
727                 hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) modules[cm]);
728
729                 /* Add system controller */
730
731 #ifdef __ia64
732                 sprintf(name,
733                         EDGE_LBL_MODULE "/%s/" EDGE_LBL_L1,
734                         buffer);
735 #else
736                 sprintf(name,
737                         EDGE_LBL_MODULE "/%x/" EDGE_LBL_L1,
738                         modules[cm]->id);
739 #endif
740
741                 rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
742                 ASSERT_ALWAYS(rc == GRAPH_SUCCESS); 
743                 rc = rc;
744
745                 hwgraph_info_add_LBL(vhdl,
746                                      INFO_LBL_ELSC,
747                                      (arbitrary_info_t) (__psint_t) 1);
748
749 #ifdef  LATER
750                 sndrv_attach(vhdl);
751 #else
752                 /*
753                  * We need to call the drivers attach routine ..
754                  */
755                 FIXME("klhwg_add_all_modules: Need code to call driver attach.\n");
756 #endif
757         }
758 }
759
760 void
761 klhwg_add_all_nodes(devfs_handle_t hwgraph_root)
762 {
763         //gda_t         *gdap = GDA;
764         gda_t           *gdap;
765         cnodeid_t       cnode;
766
767         gdap = (gda_t *)0xe000000000002400;
768
769         FIXME("klhwg_add_all_nodes: FIX GDA\n");
770
771         for (cnode = 0; cnode < numnodes; cnode++) {
772                 ASSERT(gdap->g_nasidtable[cnode] != INVALID_NASID);
773                 klhwg_add_node(hwgraph_root, cnode, gdap);
774         }
775
776         for (cnode = 0; cnode < numnodes; cnode++) {
777                 ASSERT(gdap->g_nasidtable[cnode] != INVALID_NASID);
778
779                 klhwg_add_xbow(cnode, gdap->g_nasidtable[cnode]);
780         }
781
782         /*
783          * As for router hardware inventory information, we set this
784          * up in router.c. 
785          */
786         
787         klhwg_add_all_routers(hwgraph_root);
788         klhwg_connect_routers(hwgraph_root);
789         klhwg_connect_hubs(hwgraph_root);
790
791         /* Assign guardian nodes to each of the
792          * routers in the system.
793          */
794
795 #ifdef  LATER
796         router_guardians_set(hwgraph_root);
797 #endif
798
799         /* Go through the entire system's klconfig
800          * to figure out which pci components have been disabled
801          */
802         klhwg_device_disable_hints_add();
803
804 }