initial commit with v2.6.9
[linux-2.6.9-moxart.git] / arch / ia64 / sn / io / sn2 / klconflib.c
blobe4edb7ca08cad0944851e9449495e322e2604425
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
6 * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
7 */
10 #include <linux/types.h>
11 #include <linux/ctype.h>
12 #include <asm/sn/sgi.h>
13 #include <asm/sn/sn_sal.h>
14 #include <asm/sn/io.h>
15 #include <asm/sn/sn_cpuid.h>
16 #include <asm/sn/iograph.h>
17 #include <asm/sn/hcl.h>
18 #include <asm/sn/labelcl.h>
19 #include <asm/sn/klconfig.h>
20 #include <asm/sn/nodepda.h>
21 #include <asm/sn/module.h>
22 #include <asm/sn/router.h>
23 #include <asm/sn/xtalk/xbow.h>
24 #include <asm/sn/ksys/l1.h>
27 #undef DEBUG_KLGRAPH
28 #ifdef DEBUG_KLGRAPH
29 #define DBG(x...) printk(x)
30 #else
31 #define DBG(x...)
32 #endif /* DEBUG_KLGRAPH */
34 extern int numionodes;
36 lboard_t *root_lboard[MAX_COMPACT_NODES];
37 static int hasmetarouter;
40 char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#=vo^34567890123456789...";
42 lboard_t *
43 find_lboard_any(lboard_t *start, unsigned char brd_type)
45 /* Search all boards stored on this node. */
46 while (start) {
47 if (start->brd_type == brd_type)
48 return start;
49 start = KLCF_NEXT_ANY(start);
52 /* Didn't find it. */
53 return (lboard_t *)NULL;
56 lboard_t *
57 find_lboard_nasid(lboard_t *start, nasid_t nasid, unsigned char brd_type)
60 while (start) {
61 if ((start->brd_type == brd_type) &&
62 (start->brd_nasid == nasid))
63 return start;
65 if (numionodes == numnodes)
66 start = KLCF_NEXT_ANY(start);
67 else
68 start = KLCF_NEXT(start);
71 /* Didn't find it. */
72 return (lboard_t *)NULL;
75 lboard_t *
76 find_lboard_class_any(lboard_t *start, unsigned char brd_type)
78 /* Search all boards stored on this node. */
79 while (start) {
80 if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
81 return start;
82 start = KLCF_NEXT_ANY(start);
85 /* Didn't find it. */
86 return (lboard_t *)NULL;
89 lboard_t *
90 find_lboard_class_nasid(lboard_t *start, nasid_t nasid, unsigned char brd_type)
92 /* Search all boards stored on this node. */
93 while (start) {
94 if (KLCLASS(start->brd_type) == KLCLASS(brd_type) &&
95 (start->brd_nasid == nasid))
96 return start;
98 if (numionodes == numnodes)
99 start = KLCF_NEXT_ANY(start);
100 else
101 start = KLCF_NEXT(start);
104 /* Didn't find it. */
105 return (lboard_t *)NULL;
110 klinfo_t *
111 find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
113 int index, j;
115 if (kli == (klinfo_t *)NULL) {
116 index = 0;
117 } else {
118 for (j = 0; j < KLCF_NUM_COMPS(brd); j++) {
119 if (kli == KLCF_COMP(brd, j))
120 break;
122 index = j;
123 if (index == KLCF_NUM_COMPS(brd)) {
124 DBG("find_component: Bad pointer: 0x%p\n", kli);
125 return (klinfo_t *)NULL;
127 index++; /* next component */
130 for (; index < KLCF_NUM_COMPS(brd); index++) {
131 kli = KLCF_COMP(brd, index);
132 DBG("find_component: brd %p kli %p request type = 0x%x kli type 0x%x\n", brd, kli, kli->struct_type, KLCF_COMP_TYPE(kli));
133 if (KLCF_COMP_TYPE(kli) == struct_type)
134 return kli;
137 /* Didn't find it. */
138 return (klinfo_t *)NULL;
141 klinfo_t *
142 find_first_component(lboard_t *brd, unsigned char struct_type)
144 return find_component(brd, (klinfo_t *)NULL, struct_type);
147 lboard_t *
148 find_lboard_modslot(lboard_t *start, geoid_t geoid)
150 /* Search all boards stored on this node. */
151 while (start) {
152 if (geo_cmp(start->brd_geoid, geoid))
153 return start;
154 start = KLCF_NEXT(start);
157 /* Didn't find it. */
158 return (lboard_t *)NULL;
162 * Convert a NIC name to a name for use in the hardware graph.
164 void
165 nic_name_convert(char *old_name, char *new_name)
167 int i;
168 char c;
169 char *compare_ptr;
171 if ((old_name[0] == '\0') || (old_name[1] == '\0')) {
172 strcpy(new_name, EDGE_LBL_XWIDGET);
173 } else {
174 for (i = 0; i < strlen(old_name); i++) {
175 c = old_name[i];
177 if (isalpha(c))
178 new_name[i] = tolower(c);
179 else if (isdigit(c))
180 new_name[i] = c;
181 else
182 new_name[i] = '_';
184 new_name[i] = '\0';
187 /* XXX -
188 * Since a bunch of boards made it out with weird names like
189 * IO6-fibbbed and IO6P2, we need to look for IO6 in a name and
190 * replace it with "baseio" to avoid confusion in the field.
191 * We also have to make sure we don't report media_io instead of
192 * baseio.
195 /* Skip underscores at the beginning of the name */
196 for (compare_ptr = new_name; (*compare_ptr) == '_'; compare_ptr++)
200 * Check for some names we need to replace. Early boards
201 * had junk following the name so check only the first
202 * characters.
204 if (!strncmp(new_name, "io6", 3) ||
205 !strncmp(new_name, "mio", 3) ||
206 !strncmp(new_name, "media_io", 8))
207 strcpy(new_name, "baseio");
208 else if (!strncmp(new_name, "divo", 4))
209 strcpy(new_name, "divo") ;
214 * get_actual_nasid
216 * Completely disabled brds have their klconfig on
217 * some other nasid as they have no memory. But their
218 * actual nasid is hidden in the klconfig. Use this
219 * routine to get it. Works for normal boards too.
221 nasid_t
222 get_actual_nasid(lboard_t *brd)
224 klhub_t *hub ;
226 if (!brd)
227 return INVALID_NASID ;
229 /* find out if we are a completely disabled brd. */
231 hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
232 if (!hub)
233 return INVALID_NASID ;
234 if (!(hub->hub_info.flags & KLINFO_ENABLE)) /* disabled node brd */
235 return hub->hub_info.physid ;
236 else
237 return brd->brd_nasid ;
241 xbow_port_io_enabled(nasid_t nasid, int link)
243 lboard_t *brd;
244 klxbow_t *xbow_p;
247 * look for boards that might contain an xbow or xbridge
249 brd = find_lboard_nasid((lboard_t *)KL_CONFIG_INFO(nasid), nasid, KLTYPE_IOBRICK_XBOW);
250 if (brd == NULL) return 0;
252 if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
253 == NULL)
254 return 0;
256 if (!XBOW_PORT_TYPE_IO(xbow_p, link) || !XBOW_PORT_IS_ENABLED(xbow_p, link))
257 return 0;
259 return 1;
262 void
263 board_to_path(lboard_t *brd, char *path)
265 moduleid_t modnum;
266 char *board_name;
267 char buffer[16];
269 ASSERT(brd);
271 switch (KLCLASS(brd->brd_type)) {
273 case KLCLASS_NODE:
274 board_name = EDGE_LBL_NODE;
275 break;
276 case KLCLASS_ROUTER:
277 if (brd->brd_type == KLTYPE_META_ROUTER) {
278 board_name = EDGE_LBL_META_ROUTER;
279 hasmetarouter++;
280 } else if (brd->brd_type == KLTYPE_REPEATER_ROUTER) {
281 board_name = EDGE_LBL_REPEATER_ROUTER;
282 hasmetarouter++;
283 } else
284 board_name = EDGE_LBL_ROUTER;
285 break;
286 case KLCLASS_MIDPLANE:
287 board_name = EDGE_LBL_MIDPLANE;
288 break;
289 case KLCLASS_IO:
290 board_name = EDGE_LBL_IO;
291 break;
292 case KLCLASS_IOBRICK:
293 if (brd->brd_type == KLTYPE_PXBRICK)
294 board_name = EDGE_LBL_PXBRICK;
295 else if (brd->brd_type == KLTYPE_IXBRICK)
296 board_name = EDGE_LBL_IXBRICK;
297 else if (brd->brd_type == KLTYPE_OPUSBRICK)
298 board_name = EDGE_LBL_OPUSBRICK;
299 else if (brd->brd_type == KLTYPE_CGBRICK)
300 board_name = EDGE_LBL_CGBRICK;
301 else
302 board_name = EDGE_LBL_IOBRICK;
303 break;
304 default:
305 board_name = EDGE_LBL_UNKNOWN;
308 modnum = geo_module(brd->brd_geoid);
309 memset(buffer, 0, 16);
310 format_module_id(buffer, modnum, MODULE_FORMAT_BRIEF);
311 sprintf(path, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d/%s", buffer, geo_slab(brd->brd_geoid), board_name);
314 #define MHZ 1000000
317 * Get the serial number of the main component of a board
318 * Returns 0 if a valid serial number is found
319 * 1 otherwise.
320 * Assumptions: Nic manufacturing string has the following format
321 * *Serial:<serial_number>;*
323 static int
324 component_serial_number_get(lboard_t *board,
325 klconf_off_t mfg_nic_offset,
326 char *serial_number,
327 char *key_pattern)
330 char *mfg_nic_string;
331 char *serial_string,*str;
332 int i;
333 char *serial_pattern = "Serial:";
335 /* We have an error on a null mfg nic offset */
336 if (!mfg_nic_offset)
337 return(1);
338 /* Get the hub's manufacturing nic information
339 * which is in the form of a pre-formatted string
341 mfg_nic_string =
342 (char *)NODE_OFFSET_TO_K0(NASID_GET(board),
343 mfg_nic_offset);
344 /* There is no manufacturing nic info */
345 if (!mfg_nic_string)
346 return(1);
348 str = mfg_nic_string;
349 /* Look for the key pattern first (if it is specified)
350 * and then print the serial number corresponding to that.
352 if (strcmp(key_pattern,"") &&
353 !(str = strstr(mfg_nic_string,key_pattern)))
354 return(1);
356 /* There is no serial number info in the manufacturing
357 * nic info
359 if (!(serial_string = strstr(str,serial_pattern)))
360 return(1);
362 serial_string = serial_string + strlen(serial_pattern);
363 /* Copy the serial number information from the klconfig */
364 i = 0;
365 while (serial_string[i] != ';') {
366 serial_number[i] = serial_string[i];
367 i++;
369 serial_number[i] = 0;
371 return(0);
374 * Get the serial number of a board
375 * Returns 0 if a valid serial number is found
376 * 1 otherwise.
380 board_serial_number_get(lboard_t *board,char *serial_number)
382 ASSERT(board && serial_number);
383 if (!board || !serial_number)
384 return(1);
386 strcpy(serial_number,"");
387 switch(KLCLASS(board->brd_type)) {
388 case KLCLASS_CPU: { /* Node board */
389 klhub_t *hub;
391 /* Get the hub component information */
392 hub = (klhub_t *)find_first_component(board,
393 KLSTRUCT_HUB);
394 /* If we don't have a hub component on an IP27
395 * then we have a weird klconfig.
397 if (!hub)
398 return(1);
399 /* Get the serial number information from
400 * the hub's manufacturing nic info
402 if (component_serial_number_get(board,
403 hub->hub_mfg_nic,
404 serial_number,
405 "IP37"))
406 return(1);
407 break;
409 case KLCLASS_IO: { /* IO board */
410 klbri_t *bridge;
412 /* Get the bridge component information */
413 bridge = (klbri_t *)find_first_component(board,
414 KLSTRUCT_BRI);
415 /* If we don't have a bridge component on an IO board
416 * then we have a weird klconfig.
418 if (!bridge)
419 return(1);
420 /* Get the serial number information from
421 * the bridge's manufacturing nic info
423 if (component_serial_number_get(board,
424 bridge->bri_mfg_nic,
425 serial_number, ""))
426 return(1);
427 break;
429 case KLCLASS_ROUTER: { /* Router board */
430 klrou_t *router;
432 /* Get the router component information */
433 router = (klrou_t *)find_first_component(board,
434 KLSTRUCT_ROU);
435 /* If we don't have a router component on a router board
436 * then we have a weird klconfig.
438 if (!router)
439 return(1);
440 /* Get the serial number information from
441 * the router's manufacturing nic info
443 if (component_serial_number_get(board,
444 router->rou_mfg_nic,
445 serial_number,
446 ""))
447 return(1);
448 break;
450 case KLCLASS_GFX: { /* Gfx board */
451 klgfx_t *graphics;
453 /* Get the graphics component information */
454 graphics = (klgfx_t *)find_first_component(board, KLSTRUCT_GFX);
455 /* If we don't have a gfx component on a gfx board
456 * then we have a weird klconfig.
458 if (!graphics)
459 return(1);
460 /* Get the serial number information from
461 * the graphics's manufacturing nic info
463 if (component_serial_number_get(board,
464 graphics->gfx_mfg_nic,
465 serial_number,
466 ""))
467 return(1);
468 break;
470 default:
471 strcpy(serial_number,"");
472 break;
474 return(0);
478 * Format a module id for printing.
480 * There are three possible formats:
482 * MODULE_FORMAT_BRIEF is the brief 6-character format, including
483 * the actual brick-type as recorded in the
484 * moduleid_t, eg. 002c15 for a C-brick, or
485 * 101#17 for a PX-brick.
487 * MODULE_FORMAT_LONG is the hwgraph format, eg. rack/002/bay/15
488 * of rack/101/bay/17 (note that the brick
489 * type does not appear in this format).
491 * MODULE_FORMAT_LCD is like MODULE_FORMAT_BRIEF, except that it
492 * ensures that the module id provided appears
493 * exactly as it would on the LCD display of
494 * the corresponding brick, eg. still 002c15
495 * for a C-brick, but 101p17 for a PX-brick.
497 void
498 format_module_id(char *buffer, moduleid_t m, int fmt)
500 int rack, position;
501 unsigned char brickchar;
503 rack = MODULE_GET_RACK(m);
504 ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES);
505 brickchar = MODULE_GET_BTCHAR(m);
507 if (fmt == MODULE_FORMAT_LCD) {
508 /* Be sure we use the same brick type character as displayed
509 * on the brick's LCD
511 switch (brickchar)
513 case L1_BRICKTYPE_PX:
514 brickchar = L1_BRICKTYPE_P;
515 break;
517 case L1_BRICKTYPE_IX:
518 brickchar = L1_BRICKTYPE_I;
519 break;
523 position = MODULE_GET_BPOS(m);
525 if ((fmt == MODULE_FORMAT_BRIEF) || (fmt == MODULE_FORMAT_LCD)) {
526 /* Brief module number format, eg. 002c15 */
528 /* Decompress the rack number */
529 *buffer++ = '0' + RACK_GET_CLASS(rack);
530 *buffer++ = '0' + RACK_GET_GROUP(rack);
531 *buffer++ = '0' + RACK_GET_NUM(rack);
533 /* Add the brick type */
534 *buffer++ = brickchar;
536 else if (fmt == MODULE_FORMAT_LONG) {
537 /* Fuller hwgraph format, eg. rack/002/bay/15 */
539 strcpy(buffer, EDGE_LBL_RACK "/"); buffer += strlen(buffer);
541 *buffer++ = '0' + RACK_GET_CLASS(rack);
542 *buffer++ = '0' + RACK_GET_GROUP(rack);
543 *buffer++ = '0' + RACK_GET_NUM(rack);
545 strcpy(buffer, "/" EDGE_LBL_RPOS "/"); buffer += strlen(buffer);
548 /* Add the bay position, using at least two digits */
549 if (position < 10)
550 *buffer++ = '0';
551 sprintf(buffer, "%d", position);
556 cbrick_type_get_nasid(nasid_t nasid)
558 moduleid_t module;
559 int t;
561 module = iomoduleid_get(nasid);
562 if (module < 0 ) {
563 return MODULE_CBRICK;
565 t = MODULE_GET_BTYPE(module);
566 if ((char)t == 'o') {
567 return MODULE_OPUSBRICK;
568 } else {
569 return MODULE_CBRICK;
571 return -1;