Print this page
5253 kmem_alloc/kmem_zalloc won't fail with KM_SLEEP
5254 getrbuf won't fail with KM_SLEEP
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/os/fmsmb.c
+++ new/usr/src/uts/intel/os/fmsmb.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <sys/types.h>
27 27 #include <sys/time.h>
28 28 #include <sys/nvpair.h>
29 29 #include <sys/cmn_err.h>
30 30 #include <sys/fm/util.h>
31 31 #include <sys/fm/protocol.h>
32 32 #include <sys/smbios.h>
33 33 #include <sys/smbios_impl.h>
34 34
35 35 /*
36 36 * Variable used to determine if the x86 generic topology enumerator will
37 37 * revert to legacy enumeration. I.E. Big Kill Switch... tunable via
38 38 * /etc/system
39 39 */
40 40 int x86gentopo_legacy = 0;
41 41
42 42 #define MC 0
43 43 #define PROC 1
44 44 #define MAX_PAIRS 20
45 45 #define MAX_CONT 40
46 46
47 47 typedef struct bbindex {
48 48 int count;
49 49 uint16_t index[MAX_PAIRS];
50 50 } bbindex_t;
51 51
52 52 /*
53 53 * the enum values come from DMTF
54 54 */
55 55 typedef enum baseb {
56 56 BB_BAD = 0, /* There is no bb value 0 */
57 57 BB_UNKNOWN, /* Unknown */
58 58 BB_OTHER, /* Other */
59 59 BB_BLADE, /* Server Blade */
60 60 BB_CONNSW, /* Connectivity Switch */
61 61 BB_SMM, /* System Management Module */
62 62 BB_PROCMOD, /* Processor Module */
63 63 BB_IOMOD, /* I/O Module */
64 64 BB_MEMMOD, /* Memory Module */
65 65 BB_DBOARD, /* Daughter Board */
66 66 BB_MBOARD, /* Motherboard */
67 67 BB_PROCMMOD, /* Processor/Memory Module */
68 68 BB_PROCIOMOD, /* Processor/IO Module */
69 69 BB_ICONNBD /* Interconnect Board */
70 70 } bbd_t;
71 71
72 72 static struct bboard_type {
73 73 bbd_t baseb;
74 74 const char *name;
75 75 } bbd_type[] = {
76 76 {BB_BAD, NULL},
77 77 {BB_UNKNOWN, "unknown"},
78 78 {BB_OTHER, "other"},
79 79 {BB_BLADE, "systemboard"},
80 80 {BB_CONNSW, "connswitch"},
81 81 {BB_SMM, "smmodule"},
82 82 {BB_PROCMOD, "cpuboard"},
83 83 {BB_IOMOD, "ioboard"},
84 84 {BB_MEMMOD, "memboard"},
85 85 {BB_DBOARD, "systemboard"},
86 86 {BB_MBOARD, "motherboard"},
87 87 {BB_PROCMMOD, "systemboard"},
88 88 {BB_PROCIOMOD, "systemboard"},
89 89 {BB_ICONNBD, "systemboard"}
90 90 };
91 91
92 92 typedef struct smbs_con_ids {
93 93 int id;
94 94 int inst;
95 95 int cont_count;
96 96 uint16_t **cont_ids;
97 97 int cont_by_id;
98 98 int visited;
99 99 } smbs_con_ids_t;
100 100
101 101 typedef struct smbs_cnt {
102 102 int type; /* SMBIOS stucture type */
103 103 int count; /* number of table entries */
104 104 smbs_con_ids_t **ids; /* SMBIOS table entry id(s) */
105 105 } smbs_cnt_t;
106 106
107 107 /*
108 108 * dynamically allocate the storage for the smbs_cnt_t
109 109 */
110 110 static smbs_cnt_t *
111 111 smb_create_strcnt(int count)
112 112 {
113 113 smbs_cnt_t *types = NULL;
114 114 int i, j;
115 115
116 116 types = kmem_zalloc(sizeof (smbs_cnt_t), KM_SLEEP);
117 117
118 118 types->ids = (smbs_con_ids_t **)kmem_zalloc(
119 119 count * sizeof (smbs_con_ids_t *), KM_SLEEP);
120 120
121 121 for (i = 0; i < count; i++) {
122 122 types->ids[i] = (smbs_con_ids_t *)kmem_zalloc(
123 123 sizeof (smbs_con_ids_t), KM_SLEEP);
124 124 }
125 125
126 126 for (i = 0; i < count; i++) {
127 127 types->ids[i]->cont_ids = (uint16_t **)kmem_zalloc(
128 128 MAX_CONT * sizeof (uint16_t *), KM_SLEEP);
129 129 }
130 130
131 131 for (i = 0; i < count; i++) {
132 132 for (j = 0; j < MAX_CONT; j++) {
133 133 types->ids[i]->cont_ids[j] = (uint16_t *)kmem_zalloc(
134 134 sizeof (uint16_t), KM_SLEEP);
135 135 }
136 136 }
137 137 return (types);
138 138 }
139 139
140 140 /*
141 141 * free the smbs_cnt_t memory
142 142 */
143 143 static void
144 144 smb_free_strcnt(smbs_cnt_t *types, int count)
145 145 {
146 146 int i, j;
147 147
148 148 if (types == NULL)
149 149 return;
150 150
151 151 for (i = 0; i < count; i++) {
152 152 for (j = 0; j < MAX_CONT; j++) {
153 153 if (types->ids[i]->cont_ids[j] != NULL)
154 154 kmem_free(types->ids[i]->cont_ids[j],
155 155 sizeof (uint16_t));
156 156 }
157 157 }
158 158
159 159 for (i = 0; i < count; i++) {
160 160 if (types->ids[i]->cont_ids != NULL)
161 161 kmem_free(types->ids[i]->cont_ids,
162 162 MAX_CONT * sizeof (uint16_t *));
163 163 }
164 164
165 165 for (i = 0; i < count; i++) {
166 166 if (types->ids[i] != NULL)
167 167 kmem_free(types->ids[i], sizeof (smbs_con_ids_t));
168 168 }
169 169
170 170 if (types->ids != NULL)
171 171 kmem_free(types->ids, count * sizeof (smbs_con_ids_t *));
172 172
173 173 if (types != NULL)
174 174 kmem_free(types, sizeof (smbs_cnt_t));
175 175
176 176 }
177 177
178 178 /*
179 179 * count number of the structure type in the ksmbios
180 180 */
181 181 static int
182 182 smb_cnttypes(smbios_hdl_t *shp, int type)
183 183 {
184 184 const smb_struct_t *sp = shp->sh_structs;
185 185 int nstructs = shp->sh_nstructs;
186 186 int i;
187 187 int cnt = 0;
188 188
189 189 for (i = 0, cnt = 0; i < nstructs; i++, sp++) {
190 190 if (sp->smbst_hdr->smbh_type == type)
191 191 cnt++;
192 192 }
193 193 return (cnt);
194 194 }
195 195
196 196 static void
197 197 smb_strcnt(smbios_hdl_t *shp, smbs_cnt_t *stype)
198 198 {
199 199 const smb_struct_t *sp = shp->sh_structs;
200 200 int nstructs = shp->sh_nstructs;
201 201 smbios_bboard_t bb;
202 202 int i, cnt;
203 203 int mb_cnt = 0;
204 204 int cpub_cnt = 0;
205 205 int sysb_cnt = 0;
206 206 int memb_cnt = 0;
207 207 int iob_cnt = 0;
208 208 int inst = 0;
209 209 int rc = 0;
210 210
211 211 for (i = 0, cnt = 0; i < nstructs; i++, sp++) {
212 212 if (sp->smbst_hdr->smbh_type == stype->type) {
213 213 stype->ids[cnt]->id = sp->smbst_hdr->smbh_hdl;
214 214 stype->ids[cnt]->inst = cnt;
215 215 stype->ids[cnt]->visited = 0;
216 216 stype->ids[cnt]->cont_by_id = -1;
217 217 if (stype->type == SMB_TYPE_BASEBOARD) {
218 218 rc = smbios_info_bboard(shp,
219 219 stype->ids[cnt]->id, &bb);
220 220 if (rc == 0) {
221 221 switch (bb.smbb_type) {
222 222 case SMB_BBT_PROC :
223 223 inst = cpub_cnt++;
224 224 break;
225 225 case SMB_BBT_IO :
226 226 inst = iob_cnt++;
227 227 break;
228 228 case SMB_BBT_MEM :
229 229 inst = memb_cnt++;
230 230 break;
231 231 case SMB_BBT_MOTHER :
232 232 inst = mb_cnt++;
233 233 break;
234 234 default:
235 235 /*
236 236 * SMB_BBT_UNKNOWN
237 237 * SMB_BBT_OTHER
238 238 * SMB_BBT_SBLADE
239 239 * SMB_BBT_CSWITCH
240 240 * SMB_BBT_SMM
241 241 * SMB_BBT_DAUGHTER
242 242 * SMB_BBT_PROCMEM
243 243 * SMB_BBT_PROCIO
244 244 * SMB_BBT_INTER
245 245 */
246 246 inst = sysb_cnt++;
247 247 break;
248 248 }
249 249 stype->ids[cnt]->inst = inst;
250 250 }
251 251 }
252 252 cnt++;
253 253 }
254 254 }
255 255 stype->count = cnt;
256 256 }
257 257
258 258 /*
259 259 * Go through the smbios structures looking for type 2. Fill in
260 260 * the cont_id and cont_by_id for each type 2
261 261 *
262 262 */
263 263 static void
264 264 smb_bb_contains(smbios_hdl_t *shp, smbs_cnt_t *stype)
265 265 {
266 266 int i, j, cnt, c;
267 267 uint_t cont_count;
268 268 const smb_struct_t *spt;
269 269 smbios_bboard_t smb_bb;
270 270 uint16_t bb_id, cont_id;
271 271 uint_t cont_len;
272 272 id_t *cont_hdl = NULL;
273 273 int rc;
274 274
275 275 for (cnt = 0; cnt < stype->count; cnt++) {
276 276 bb_id = stype->ids[cnt]->id;
277 277 (void) smbios_info_bboard(shp, stype->ids[cnt]->id, &smb_bb);
278 278 cont_count = (uint_t)smb_bb.smbb_contn;
279 279 if (cont_count == 0) {
280 280 continue;
281 281 }
282 282
283 283 cont_len = sizeof (id_t);
284 284 cont_hdl = kmem_zalloc(cont_count * cont_len, KM_SLEEP);
285 285 if (cont_hdl == NULL)
286 286 continue;
287 287
288 288 rc = smbios_info_contains(shp, stype->ids[cnt]->id,
289 289 cont_count, cont_hdl);
290 290 if (rc > SMB_CONT_MAX) {
291 291 kmem_free(cont_hdl, cont_count * cont_len);
292 292 continue;
293 293 }
294 294 cont_count = MIN(rc, cont_count);
295 295
296 296 /*
297 297 * fill in the type 2 and type 4 ids which are
298 298 * contained in this type 2
299 299 */
300 300 c = 0;
301 301 for (j = 0; j < cont_count; j++) {
302 302 cont_id = (uint16_t)cont_hdl[j];
303 303 spt = smb_lookup_id(shp, cont_id);
304 304 if (spt->smbst_hdr->smbh_type == SMB_TYPE_BASEBOARD ||
305 305 spt->smbst_hdr->smbh_type == SMB_TYPE_PROCESSOR) {
306 306 *stype->ids[cnt]->cont_ids[c] = cont_id;
307 307 c++;
308 308 }
309 309
310 310 if (spt->smbst_hdr->smbh_type == SMB_TYPE_BASEBOARD) {
311 311 for (i = 0; i < stype->count; i++) {
312 312 if (stype->ids[i]->id == cont_id) {
313 313 stype->ids[i]->cont_by_id =
314 314 bb_id;
315 315 }
316 316 }
317 317 }
318 318
319 319 }
320 320 stype->ids[cnt]->cont_count = c;
321 321 if (cont_hdl != NULL)
322 322 kmem_free(cont_hdl, cont_count * cont_len);
323 323 }
324 324 }
325 325
326 326 /*
327 327 * Verify SMBIOS structures for x86 generic topology.
328 328 *
329 329 * Return (0) on success.
330 330 */
331 331 static int
332 332 fm_smb_check(smbios_hdl_t *shp)
333 333 {
334 334 int i, j;
335 335 int bb_cnt = 0;
336 336 int pr_cnt = 0;
337 337 int expr_cnt = 0;
338 338 int ma_cnt = 0;
339 339 int exma_cnt = 0;
340 340 int mdev_cnt = 0;
341 341 int exmdev_cnt = 0;
342 342 uint16_t bb_id;
343 343 uint16_t pr_id, expr_id;
344 344 uint16_t ma_id, exma_id;
345 345 uint16_t mdev_id, exmdev_id;
346 346 uint16_t *sys_ma;
347 347 smbios_bboard_t bb;
348 348 smbios_processor_ext_t exproc;
349 349 smbios_memarray_t ma;
350 350 smbios_memarray_ext_t exma;
351 351 smbios_memdevice_t mdev;
352 352 smbios_memdevice_ext_t exmdev;
353 353 smbs_cnt_t *bb_stype;
354 354 smbs_cnt_t *pr_stype, *expr_stype;
355 355 smbs_cnt_t *ma_stype, *exma_stype;
356 356 smbs_cnt_t *mdev_stype, *exmdev_stype;
357 357
358 358 /*
359 359 * Verify the existance of the requuired extended OEM-Specific
360 360 * structures and they coincide with the structures they extend
361 361 * (e.g. the number of extended processor structures equal the
362 362 * number of processor structures).
363 363 */
364 364 pr_cnt = smb_cnttypes(shp, SMB_TYPE_PROCESSOR);
365 365 expr_cnt = smb_cnttypes(shp, SUN_OEM_EXT_PROCESSOR);
366 366 ma_cnt = smb_cnttypes(shp, SMB_TYPE_MEMARRAY);
367 367 exma_cnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMARRAY);
368 368 mdev_cnt = smb_cnttypes(shp, SMB_TYPE_MEMDEVICE);
369 369 exmdev_cnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMDEVICE);
370 370 if (expr_cnt == 0 || exma_cnt == 0 || exmdev_cnt == 0 ||
371 371 expr_cnt != pr_cnt || exma_cnt > ma_cnt ||
372 372 exmdev_cnt > mdev_cnt) {
373 373 #ifdef DEBUG
374 374 cmn_err(CE_NOTE, "!Structure mismatch: ext_proc (%d) "
375 375 "proc (%d) ext_ma (%d) ma (%d) ext_mdev (%d) mdev (%d)\n",
376 376 expr_cnt, pr_cnt, exma_cnt, ma_cnt, exmdev_cnt,
377 377 mdev_cnt);
378 378 #endif /* DEBUG */
379 379 return (-1);
380 380 }
381 381
382 382 /*
383 383 * Verify the OEM-Specific structrures are correctly
384 384 * linked to the SMBIOS structure types they extend.
385 385 */
386 386
387 387 /* allocate processor stypes */
388 388 pr_stype = smb_create_strcnt(pr_cnt);
389 389 expr_stype = smb_create_strcnt(expr_cnt);
390 390
391 391 /* fill in stypes */
392 392 pr_stype->type = SMB_TYPE_PROCESSOR;
393 393 smb_strcnt(shp, pr_stype);
394 394 expr_stype->type = SUN_OEM_EXT_PROCESSOR;
395 395 smb_strcnt(shp, expr_stype);
396 396
397 397 /* verify the ext proc struct belong to the proc struct */
398 398 for (i = 0; i < pr_cnt; i++) {
399 399 pr_id = pr_stype->ids[i]->id;
400 400 expr_id = expr_stype->ids[i]->id;
401 401 (void) smbios_info_extprocessor(shp, expr_id, &exproc);
402 402 if (exproc.smbpe_processor != pr_id) {
403 403 #ifdef DEBUG
404 404 cmn_err(CE_NOTE, "!Processor struct linkage (%d)", i);
405 405 #endif /* DEBUG */
406 406 smb_free_strcnt(pr_stype, pr_cnt);
407 407 smb_free_strcnt(expr_stype, expr_cnt);
408 408 return (-1);
409 409 }
410 410 }
411 411
412 412 /* free stypes */
413 413 smb_free_strcnt(pr_stype, pr_cnt);
414 414 smb_free_strcnt(expr_stype, expr_cnt);
415 415
416 416 /* allocate memory array stypes */
417 417 ma_stype = smb_create_strcnt(ma_cnt);
418 418 exma_stype = smb_create_strcnt(exma_cnt);
419 419 sys_ma = kmem_zalloc(sizeof (uint16_t) * ma_cnt, KM_SLEEP);
420 420
421 421 /* fill in stypes */
422 422 ma_stype->type = SMB_TYPE_MEMARRAY;
423 423 smb_strcnt(shp, ma_stype);
424 424 exma_stype->type = SUN_OEM_EXT_MEMARRAY;
425 425 smb_strcnt(shp, exma_stype);
426 426
427 427 /* verify linkage from ext memarray struct to memarray struct */
428 428 for (i = 0; i < ma_cnt; i++) {
429 429 sys_ma[i] = (uint16_t)-1;
430 430 ma_id = ma_stype->ids[i]->id;
431 431 (void) smbios_info_memarray(shp, ma_id, &ma);
432 432 if (ma.smbma_use != SMB_MAU_SYSTEM)
433 433 continue;
434 434 /* this memarray is system memory */
435 435 sys_ma[i] = ma_id;
436 436 exma_id = exma_stype->ids[i]->id;
437 437 (void) smbios_info_extmemarray(shp, exma_id, &exma);
438 438 if (exma.smbmae_ma != ma_id) {
439 439 #ifdef DEBUG
440 440 cmn_err(CE_NOTE,
441 441 "!Memory Array struct linkage (%d)", i);
442 442 #endif /* DEBUG */
443 443 smb_free_strcnt(ma_stype, ma_cnt);
444 444 smb_free_strcnt(exma_stype, exma_cnt);
445 445 kmem_free(sys_ma, sizeof (uint16_t) * ma_cnt);
446 446 return (-1);
447 447 }
448 448 }
449 449
450 450 /* free stypes */
451 451 smb_free_strcnt(ma_stype, ma_cnt);
452 452 smb_free_strcnt(exma_stype, exma_cnt);
453 453
454 454 /* allocate memory device stypes */
455 455 mdev_stype = smb_create_strcnt(mdev_cnt);
456 456 exmdev_stype = smb_create_strcnt(exmdev_cnt);
457 457
458 458 /* fill in stypes */
459 459 mdev_stype->type = SMB_TYPE_MEMDEVICE;
460 460 smb_strcnt(shp, mdev_stype);
461 461 exmdev_stype->type = SUN_OEM_EXT_MEMDEVICE;
462 462 smb_strcnt(shp, exmdev_stype);
463 463
464 464 /* verify linkage */
465 465 for (i = 0; i < mdev_cnt; i++) {
466 466 mdev_id = mdev_stype->ids[i]->id;
467 467 (void) smbios_info_memdevice(shp, mdev_id, &mdev);
468 468 /* only check system memory devices */
469 469 for (j = 0; j < ma_cnt; j++) {
470 470 if (sys_ma[j] == mdev.smbmd_array)
471 471 break;
472 472 }
473 473 if (j == ma_cnt)
474 474 continue;
475 475 exmdev_id = exmdev_stype->ids[i]->id;
476 476 (void) smbios_info_extmemdevice(shp, exmdev_id, &exmdev);
477 477 if (exmdev.smbmdeve_md != mdev_id) {
478 478 #ifdef DEBUG
479 479 cmn_err(CE_NOTE, "!Memory Device struct linkage (%d)",
480 480 i);
481 481 #endif /* DEBUG */
482 482 smb_free_strcnt(mdev_stype, mdev_cnt);
483 483 smb_free_strcnt(exmdev_stype, exmdev_cnt);
484 484 kmem_free(sys_ma, sizeof (uint16_t) * ma_cnt);
485 485 return (-1);
486 486 }
487 487 }
488 488
489 489 /* free stypes */
490 490 smb_free_strcnt(mdev_stype, mdev_cnt);
491 491 smb_free_strcnt(exmdev_stype, exmdev_cnt);
492 492 kmem_free(sys_ma, sizeof (uint16_t) * ma_cnt);
493 493
494 494 /*
495 495 * Verify the presece of contained handles if there are more
496 496 * than one Type-2 (Base Board) structures.
497 497 */
498 498 bb_cnt = smb_cnttypes(shp, SMB_TYPE_BASEBOARD);
499 499 if (bb_cnt > 1) {
500 500 /* allocate base board stypes */
501 501 bb_stype = smb_create_strcnt(bb_cnt);
502 502
503 503 /* fill in stypes */
504 504 bb_stype->type = SMB_TYPE_BASEBOARD;
505 505 smb_strcnt(shp, bb_stype);
506 506
507 507 /* verify contained handles */
508 508 for (i = 0; i < bb_cnt; i++) {
509 509 bb_id = bb_stype->ids[i]->id;
510 510 (void) smbios_info_bboard(shp, bb_id, &bb);
511 511 if (bb.smbb_contn == 0) {
512 512 #ifdef DEBUG
513 513 cmn_err(CE_NOTE, "!No contained hanldes (%d)",
514 514 i);
515 515 #endif /* DEBUG */
516 516 smb_free_strcnt(bb_stype, bb_cnt);
517 517 return (-1);
518 518 }
519 519 }
520 520
521 521 /* free stypes */
522 522 smb_free_strcnt(bb_stype, bb_cnt);
523 523 }
524 524
525 525 return (0);
526 526 }
527 527
528 528 void
529 529 fm_smb_fmacompat()
530 530 {
531 531 int i, j;
532 532 int id;
533 533 int cnt;
534 534 const char **oem_strings = NULL;
535 535 smbs_cnt_t *oemstypes;
536 536 smbios_hdl_t *shp;
537 537 int strcnt;
538 538 int compat = 0;
539 539
540 540 /* check for BKS */
541 541 if (x86gentopo_legacy == 1) {
542 542 return;
543 543 }
544 544
545 545 shp = ksmbios;
546 546 if (shp == NULL) {
547 547 goto bad;
548 548 }
549 549
550 550 /* OEM strings (Type 11) */
551 551 strcnt = smb_cnttypes(shp, SMB_TYPE_OEMSTR);
552 552 if (strcnt == 0)
553 553 goto bad;
554 554
555 555 oemstypes = smb_create_strcnt(strcnt);
556 556 if (oemstypes == NULL)
557 557 goto bad;
558 558
559 559 oemstypes->type = SMB_TYPE_OEMSTR;
560 560 smb_strcnt(shp, oemstypes);
561 561
562 562 for (i = 0; i < oemstypes->count && compat == 0; i++) {
563 563 id = oemstypes->ids[i]->id;
564 564 cnt = smbios_info_strtab(shp, id, 0, NULL);
565 565 if (cnt > 0) {
566 566 oem_strings = kmem_zalloc(sizeof (char *) * cnt,
567 567 KM_SLEEP);
568 568 (void) smbios_info_strtab(shp, id, cnt, oem_strings);
569 569
570 570 for (j = 0; j < cnt; j++) {
571 571 if (strncmp(oem_strings[j], SMB_PRMS1,
572 572 strlen(SMB_PRMS1) + 1) == 0) {
573 573 compat = 1;
574 574 break;
575 575 }
576 576 }
577 577 kmem_free(oem_strings, sizeof (char *) * cnt);
578 578 }
579 579 }
580 580 smb_free_strcnt(oemstypes, strcnt);
581 581
582 582 /* sanity check SMBIOS structures */
583 583 if ((compat != 0) && (fm_smb_check(shp) == 0))
584 584 return;
585 585
586 586 bad:
587 587 /* not compatible with x86gentopo; revert to legacy enumeration */
588 588 #ifdef DEBUG
589 589 cmn_err(CE_NOTE,
590 590 "!SMBIOS is not compatible with x86 generic topology.");
591 591 cmn_err(CE_NOTE, "!Invoking legacy x86 topology enumeration.");
592 592 #endif /* DEBUG */
593 593 x86gentopo_legacy = 1;
594 594 }
595 595
596 596 static int
597 597 find_matching_apic(smbios_hdl_t *shp, uint16_t proc_id, uint_t strand_apicid)
598 598 {
599 599 uint16_t ext_id;
600 600 int i, j;
601 601 smbios_processor_ext_t ep;
602 602 smbs_cnt_t *pstypes;
603 603 int strcnt;
604 604
605 605 strcnt = smb_cnttypes(shp, SUN_OEM_EXT_PROCESSOR);
606 606 if (strcnt == 0)
607 607 return (0);
608 608
609 609 pstypes = smb_create_strcnt(strcnt);
610 610 if (pstypes == NULL)
611 611 return (0);
612 612
613 613 pstypes->type = SUN_OEM_EXT_PROCESSOR;
614 614 smb_strcnt(shp, pstypes);
615 615 for (i = 0; i < pstypes->count; i++) {
616 616 ext_id = pstypes->ids[i]->id;
617 617 (void) smbios_info_extprocessor(shp, ext_id, &ep);
618 618 if (ep.smbpe_processor == proc_id) {
619 619 for (j = 0; j < ep.smbpe_n; j++) {
620 620 if (ep.smbpe_apicid[j] == strand_apicid) {
621 621 smb_free_strcnt(pstypes, strcnt);
622 622 return (1);
623 623 }
624 624 }
625 625 }
626 626 }
627 627 smb_free_strcnt(pstypes, strcnt);
628 628 return (0);
629 629 }
630 630
631 631 /*
632 632 * go throught the type 2 structure contained_ids looking for
633 633 * the type 4 which has strand_apicid == this strand_apicid
634 634 */
635 635 static int
636 636 find_matching_proc(smbios_hdl_t *shp, uint_t strand_apicid,
637 637 uint16_t bb_id, uint16_t proc_hdl, int is_proc)
638 638 {
639 639 int n;
640 640 const smb_struct_t *sp;
641 641 smbios_bboard_t bb;
642 642 uint_t cont_count, cont_len;
643 643 uint16_t cont_id;
644 644 id_t *cont_hdl = NULL;
↓ open down ↓ |
644 lines elided |
↑ open up ↑ |
645 645 int rc;
646 646
647 647
648 648 (void) smbios_info_bboard(shp, bb_id, &bb);
649 649 cont_count = (uint_t)bb.smbb_contn;
650 650 if (cont_count == 0)
651 651 return (0);
652 652
653 653 cont_len = sizeof (id_t);
654 654 cont_hdl = kmem_zalloc(cont_count * cont_len, KM_SLEEP);
655 - if (cont_hdl == NULL)
656 - return (0);
657 655
658 656 rc = smbios_info_contains(shp, bb_id, cont_count, cont_hdl);
659 657 if (rc > SMB_CONT_MAX) {
660 658 kmem_free(cont_hdl, cont_count * cont_len);
661 659 return (0);
662 660 }
663 661 cont_count = MIN(rc, cont_count);
664 662
665 663 for (n = 0; n < cont_count; n++) {
666 664 cont_id = (uint16_t)cont_hdl[n];
667 665 sp = smb_lookup_id(shp, cont_id);
668 666 if (sp->smbst_hdr->smbh_type == SMB_TYPE_PROCESSOR) {
669 667 if (is_proc) {
670 668 if (find_matching_apic(shp, cont_id,
671 669 strand_apicid)) {
672 670 kmem_free(cont_hdl,
673 671 cont_count * cont_len);
674 672 return (1);
675 673 }
676 674 } else {
677 675 if (cont_id == proc_hdl) {
678 676 kmem_free(cont_hdl,
679 677 cont_count * cont_len);
680 678 return (1);
681 679 }
682 680 }
683 681 }
684 682 }
685 683 if (cont_hdl != NULL)
686 684 kmem_free(cont_hdl, cont_count * cont_len);
687 685
688 686 return (0);
689 687 }
690 688
691 689 void
692 690 get_bboard_index(smbs_cnt_t *bbstypes, uint_t bb_id, bbindex_t *bb_idx)
693 691 {
694 692 int curr_id, tmp_id;
695 693 int i, j, nb;
696 694 bbindex_t tmp_idx;
697 695
698 696 for (i = 0; i < MAX_PAIRS; i++)
699 697 tmp_idx.index[i] = 0;
700 698
701 699 tmp_idx.count = 0;
702 700
703 701 curr_id = bb_id;
704 702 for (nb = bbstypes->count-1, i = 0; nb >= 0; nb--) {
705 703 tmp_id = bbstypes->ids[nb]->id;
706 704 if (tmp_id == curr_id) {
707 705 tmp_idx.index[i] = nb;
708 706 tmp_idx.count++;
709 707 curr_id = bbstypes->ids[nb]->cont_by_id;
710 708 if (curr_id == -1)
711 709 break;
712 710 i++;
713 711 }
714 712 }
715 713
716 714 for (i = tmp_idx.count - 1, j = 0; i >= 0; i--) {
717 715 bb_idx->index[j] = tmp_idx.index[i];
718 716 j++;
719 717 }
720 718
721 719 bb_idx->count = tmp_idx.count;
722 720 }
723 721
724 722 int
725 723 get_chassis_inst(smbios_hdl_t *shp, uint16_t *chassis_inst,
726 724 uint16_t bb_id, int *chcnt)
727 725 {
728 726 int ch_strcnt;
729 727 smbs_cnt_t *chstypes;
730 728 uint16_t chassis_id, tmp_id;
731 729 smbios_bboard_t bb;
732 730 int rc = 0;
733 731 int i;
734 732
735 733 rc = smbios_info_bboard(shp, bb_id, &bb);
736 734 if (rc != 0) {
737 735 return (-1);
738 736 }
739 737
740 738 chassis_id = bb.smbb_chassis;
741 739
742 740 ch_strcnt = smb_cnttypes(shp, SMB_TYPE_CHASSIS);
743 741
744 742 if (ch_strcnt == 0)
745 743 return (-1);
746 744
747 745 chstypes = smb_create_strcnt(ch_strcnt);
748 746 if (chstypes == NULL)
749 747 return (-1);
750 748
751 749 chstypes->type = SMB_TYPE_CHASSIS;
752 750 smb_strcnt(shp, chstypes);
753 751
754 752 for (i = 0; i < chstypes->count; i++) {
755 753 tmp_id = chstypes->ids[i]->id;
756 754 if (tmp_id == chassis_id) {
757 755 *chassis_inst = chstypes->ids[i]->inst;
758 756 if (chstypes->ids[i]->inst != 0)
759 757 *chcnt = 2;
760 758 else
761 759 *chcnt = 1;
762 760 smb_free_strcnt(chstypes, ch_strcnt);
763 761 return (0);
764 762 }
765 763 }
766 764
767 765 smb_free_strcnt(chstypes, ch_strcnt);
768 766 return (-1);
769 767 }
770 768
771 769 int
772 770 smb_get_bb_fmri(smbios_hdl_t *shp, nvlist_t *fmri, uint_t parent,
773 771 smbs_cnt_t *bbstypes)
774 772 {
775 773 int rc = 0;
776 774 int i, j, n, cnt;
777 775 int id, index;
778 776 nvlist_t *pairs[MAX_PAIRS];
779 777 smbios_bboard_t bb;
780 778 uint16_t chassis_inst, mch_inst;
781 779 char name[40];
782 780 char idstr[11];
783 781 bbindex_t bb_idx;
784 782 uint16_t bbid;
785 783 int chcnt = 0;
786 784
787 785 for (n = 0; n < MAX_PAIRS; n++) {
788 786 bb_idx.index[n] = 0;
789 787 pairs[n] = NULL;
790 788 }
791 789 bb_idx.count = 0;
792 790
793 791 get_bboard_index(bbstypes, parent, &bb_idx);
794 792
795 793 index = bb_idx.index[0];
796 794 bbid = bbstypes->ids[index]->id;
797 795
798 796 rc = get_chassis_inst(shp, &chassis_inst, bbid, &chcnt);
799 797
800 798 if (rc != 0) {
801 799 return (rc);
802 800 }
803 801
804 802 if ((bb_idx.count + chcnt) > MAX_PAIRS) {
805 803 return (-1);
806 804 }
807 805
808 806 i = 0;
809 807 if (chcnt > 1) {
810 808 /*
811 809 * create main chassis pair
812 810 */
813 811 pairs[i] = fm_nvlist_create(NULL);
814 812 if (pairs[i] == NULL) {
815 813 return (-1);
816 814 }
817 815 mch_inst = 0;
818 816 (void) snprintf(idstr, sizeof (idstr), "%u", mch_inst);
819 817 if ((nvlist_add_string(pairs[i], FM_FMRI_HC_NAME,
820 818 "chassis") != 0) ||
821 819 (nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr)) != 0) {
822 820 fm_nvlist_destroy(pairs[i], FM_NVA_FREE);
823 821 return (-1);
824 822 }
825 823 i++;
826 824 }
827 825
828 826 /*
829 827 * create chassis pair
830 828 */
831 829 pairs[i] = fm_nvlist_create(NULL);
832 830 if (pairs[i] == NULL) {
833 831 for (n = 0; n < MAX_PAIRS; n++) {
834 832 if (pairs[n] != NULL)
835 833 fm_nvlist_destroy(pairs[n], FM_NVA_FREE);
836 834 }
837 835 return (-1);
838 836 }
839 837 (void) snprintf(idstr, sizeof (idstr), "%u", chassis_inst);
840 838 if ((nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, "chassis") != 0) ||
841 839 (nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr) != 0)) {
842 840 for (n = 0; n < MAX_PAIRS; n++) {
843 841 if (pairs[n] != NULL)
844 842 fm_nvlist_destroy(pairs[n], FM_NVA_FREE);
845 843 }
846 844 return (-1);
847 845 }
848 846
849 847 for (j = 0, i = chcnt, cnt = chcnt; j < bb_idx.count; j++) {
850 848 index = bb_idx.index[j];
851 849 bbid = bbstypes->ids[index]->id;
852 850 rc = smbios_info_bboard(shp, bbid, &bb);
853 851 if (rc != 0) {
854 852 rc = -1;
855 853 break;
856 854 }
857 855
858 856 pairs[i] = fm_nvlist_create(NULL);
859 857 if (pairs[i] == NULL) {
860 858 rc = -1;
861 859 break;
862 860 }
863 861
864 862 id = bbstypes->ids[index]->inst;
865 863 (void) snprintf(idstr, sizeof (idstr), "%u", id);
866 864 (void) strncpy(name, bbd_type[bb.smbb_type].name,
867 865 sizeof (name));
868 866 cnt++;
869 867
870 868 if (nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, name) != 0 ||
871 869 nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr)
872 870 != 0) {
873 871 rc = -1;
874 872 break;
875 873 }
876 874 i++;
877 875 }
878 876
879 877 if (rc != -1) {
880 878 if (nvlist_add_nvlist_array(fmri, FM_FMRI_HC_LIST,
881 879 pairs, cnt) != 0) {
882 880 rc = -1;
883 881 }
884 882 }
885 883
886 884 for (n = 0; n < cnt; n++) {
887 885 if (pairs[n] != NULL)
888 886 fm_nvlist_destroy(pairs[n], FM_NVA_FREE);
889 887 }
890 888
891 889 return (rc);
892 890 }
893 891
894 892 /*
895 893 * pass in strand_apic id
896 894 * return chip's bboards list which has strand_apicid == passed
897 895 * in strand_apic id
898 896 */
899 897 static nvlist_t *
900 898 smb_bboard(uint_t strand_apicid, uint16_t proc_hdl, int is_proc)
901 899 {
902 900 smbios_hdl_t *shp;
903 901 smbs_cnt_t *bbstypes;
904 902 int nb;
905 903 int bb_smbid;
906 904 nvlist_t *fmri = NULL;
907 905 int rc = 0;
908 906 int bb_strcnt;
909 907
910 908 if (x86gentopo_legacy)
911 909 return (NULL);
912 910
913 911 shp = ksmbios;
914 912 if (shp == NULL) {
915 913 goto bad;
916 914 }
917 915
918 916 /*
919 917 * Type 2 structs : "base board"
920 918 */
921 919 bb_strcnt = smb_cnttypes(shp, SMB_TYPE_BASEBOARD);
922 920 if (bb_strcnt == 0) {
923 921 goto bad;
924 922 }
925 923
926 924 bbstypes = smb_create_strcnt(bb_strcnt);
927 925 if (bbstypes == NULL) {
928 926 goto bad;
929 927 }
930 928
931 929 bbstypes->type = SMB_TYPE_BASEBOARD;
932 930 smb_strcnt(shp, bbstypes);
933 931 smb_bb_contains(shp, bbstypes);
934 932
935 933 for (nb = 0; nb < bbstypes->count; nb++) {
936 934 if (bbstypes->ids[nb]->visited) {
937 935 continue;
938 936 }
939 937
940 938 bbstypes->ids[nb]->visited = 1;
941 939 bb_smbid = bbstypes->ids[nb]->id;
942 940
943 941 /*
944 942 * check if there is a matching processor under
945 943 * this board. If found, find base board(s) of this proc
946 944 * If proc is not in contained handle of a base board and
947 945 * there is only one base board in the system, treat that base
948 946 * board as the parent of the proc
949 947 */
950 948 if (find_matching_proc(shp, strand_apicid,
951 949 bb_smbid, proc_hdl, is_proc) || (bbstypes->count == 1)) {
952 950 fmri = fm_nvlist_create(NULL);
953 951 if (fmri == NULL) {
954 952 smb_free_strcnt(bbstypes, bb_strcnt);
955 953 goto bad;
956 954 }
957 955 /*
958 956 * find parent by walking the cont_by_id
959 957 */
960 958 rc = smb_get_bb_fmri(shp, fmri, bb_smbid, bbstypes);
961 959 smb_free_strcnt(bbstypes, bb_strcnt);
962 960 if (rc == 0) {
963 961 return (fmri);
964 962 } else
965 963 goto bad;
966 964 }
967 965
968 966 }
969 967
970 968 smb_free_strcnt(bbstypes, bb_strcnt);
971 969 bad:
972 970 /* revert to legacy enumeration */
973 971 x86gentopo_legacy = 1;
974 972
975 973 return (NULL);
976 974 }
977 975
978 976 nvlist_t *
979 977 fm_smb_bboard(uint_t strand_apicid)
980 978 {
981 979 return (smb_bboard(strand_apicid, 0, PROC));
982 980 }
983 981
984 982 int
985 983 fm_smb_chipinst(uint_t strand_apicid, uint_t *chip_inst, uint16_t *smbiosid)
986 984 {
987 985 int n;
988 986 smbios_hdl_t *shp;
989 987 uint16_t proc_id;
990 988 smbs_cnt_t *pstypes;
991 989 int strcnt;
992 990
993 991 if (x86gentopo_legacy)
994 992 return (-1);
995 993
996 994 shp = ksmbios;
997 995 if (shp == NULL) {
998 996 goto bad;
999 997 }
1000 998
1001 999 strcnt = smb_cnttypes(shp, SMB_TYPE_PROCESSOR);
1002 1000 if (strcnt == 0)
1003 1001 goto bad;
1004 1002
1005 1003 pstypes = smb_create_strcnt(strcnt);
1006 1004 if (pstypes == NULL)
1007 1005 goto bad;
1008 1006
1009 1007 pstypes->type = SMB_TYPE_PROCESSOR;
1010 1008 smb_strcnt(shp, pstypes);
1011 1009 for (n = 0; n < pstypes->count; n++) {
1012 1010 proc_id = pstypes->ids[n]->id;
1013 1011 if (find_matching_apic(shp, proc_id, strand_apicid)) {
1014 1012 *chip_inst = pstypes->ids[n]->inst;
1015 1013 *smbiosid = pstypes->ids[n]->id;
1016 1014 smb_free_strcnt(pstypes, strcnt);
1017 1015 return (0);
1018 1016 }
1019 1017 }
1020 1018 smb_free_strcnt(pstypes, strcnt);
1021 1019 bad:
1022 1020 /* revert to legacy enumerarion */
1023 1021 x86gentopo_legacy = 1;
1024 1022
1025 1023 return (-1);
1026 1024 }
1027 1025
1028 1026 nvlist_t *
1029 1027 fm_smb_mc_bboards(uint_t bdf)
1030 1028 {
1031 1029
1032 1030 int i;
1033 1031 smbios_hdl_t *shp;
1034 1032 uint16_t ext_id;
1035 1033 smbios_memarray_ext_t em;
1036 1034 nvlist_t *fmri = NULL;
1037 1035 smbs_cnt_t *mastypes;
1038 1036 int strcnt;
1039 1037
1040 1038 if (x86gentopo_legacy)
1041 1039 return (NULL);
1042 1040
1043 1041 shp = ksmbios;
1044 1042 if (shp == NULL) {
1045 1043 goto bad;
1046 1044 }
1047 1045
1048 1046 strcnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMARRAY);
1049 1047 if (strcnt == 0)
1050 1048 goto bad;
1051 1049
1052 1050 mastypes = smb_create_strcnt(strcnt);
1053 1051 if (mastypes == NULL)
1054 1052 goto bad;
1055 1053
1056 1054 mastypes->type = SUN_OEM_EXT_MEMARRAY;
1057 1055 smb_strcnt(shp, mastypes);
1058 1056 for (i = 0; i < mastypes->count; i++) {
1059 1057 ext_id = mastypes->ids[i]->id;
1060 1058 (void) smbios_info_extmemarray(shp, ext_id, &em);
1061 1059 if (em.smbmae_bdf == bdf) {
1062 1060 fmri = smb_bboard(0, em.smbmae_comp, MC);
1063 1061 smb_free_strcnt(mastypes, strcnt);
1064 1062 return (fmri);
1065 1063 }
1066 1064 }
1067 1065 smb_free_strcnt(mastypes, strcnt);
1068 1066 bad:
1069 1067 /* revert to legacy enumerarion */
1070 1068 x86gentopo_legacy = 1;
1071 1069
1072 1070 return (NULL);
1073 1071 }
1074 1072
1075 1073 int
1076 1074 fm_smb_mc_chipinst(uint_t bdf, uint_t *chip_inst) {
1077 1075
1078 1076 int i, j;
1079 1077 smbios_hdl_t *shp;
1080 1078 smbios_memarray_ext_t em;
1081 1079 uint16_t ext_id, proc_id;
1082 1080 smbs_cnt_t *mastypes;
1083 1081 smbs_cnt_t *pstypes;
1084 1082 int ma_strcnt, p_strcnt;
1085 1083
1086 1084 if (x86gentopo_legacy)
1087 1085 return (-1);
1088 1086
1089 1087 shp = ksmbios;
1090 1088 if (shp == NULL) {
1091 1089 goto bad;
1092 1090 }
1093 1091
1094 1092 ma_strcnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMARRAY);
1095 1093 if (ma_strcnt == 0)
1096 1094 goto bad;
1097 1095
1098 1096 mastypes = smb_create_strcnt(ma_strcnt);
1099 1097 if (mastypes == NULL)
1100 1098 goto bad;
1101 1099
1102 1100 mastypes->type = SUN_OEM_EXT_MEMARRAY;
1103 1101 smb_strcnt(shp, mastypes);
1104 1102 for (i = 0; i < mastypes->count; i++) {
1105 1103 ext_id = mastypes->ids[i]->id;
1106 1104 (void) smbios_info_extmemarray(shp, ext_id, &em);
1107 1105 if (em.smbmae_bdf == bdf) {
1108 1106 p_strcnt = smb_cnttypes(shp, SMB_TYPE_PROCESSOR);
1109 1107 if (p_strcnt == 0) {
1110 1108 smb_free_strcnt(mastypes, ma_strcnt);
1111 1109 goto bad;
1112 1110 }
1113 1111
1114 1112 pstypes = smb_create_strcnt(p_strcnt);
1115 1113 if (pstypes == NULL) {
1116 1114 smb_free_strcnt(mastypes, ma_strcnt);
1117 1115 goto bad;
1118 1116 }
1119 1117
1120 1118 pstypes->type = SMB_TYPE_PROCESSOR;
1121 1119 smb_strcnt(shp, pstypes);
1122 1120 for (j = 0; j < pstypes->count; j++) {
1123 1121 proc_id = pstypes->ids[j]->id;
1124 1122 if (proc_id == em.smbmae_comp) {
1125 1123 *chip_inst = pstypes->ids[j]->inst;
1126 1124 smb_free_strcnt(mastypes, ma_strcnt);
1127 1125 smb_free_strcnt(pstypes, p_strcnt);
1128 1126 return (0);
1129 1127 }
1130 1128 }
1131 1129 }
1132 1130 }
1133 1131 smb_free_strcnt(mastypes, ma_strcnt);
1134 1132 smb_free_strcnt(pstypes, p_strcnt);
1135 1133 bad:
1136 1134 /* revert to legacy enumeration */
1137 1135 x86gentopo_legacy = 1;
1138 1136
1139 1137 return (-1);
1140 1138 }
↓ open down ↓ |
474 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX