Print this page
10135 picl plugins need smatch fixes
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/picl/plugins/common/memcfg/piclmemcfg_comm.c
+++ new/usr/src/cmd/picl/plugins/common/memcfg/piclmemcfg_comm.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
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
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 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + *
25 + * Copyright (c) 2018, Joyent, Inc.
24 26 */
25 27
26 28 /*
27 29 * This plugin creates memory configuration nodes and properties in the
28 30 * PICL tree for Cheetah platforms.
29 31 *
30 32 * Subtree of memory-controller in the physical aspect.
31 33 * memory-controller --- memory-module-group --- memory-module
32 34 *
33 35 * Subtree of memory in the logical aspect.
34 36 * memory --- memory-segment --- memory-bank
35 37 * Add property _memory-module-group_ at memory-segment referring to the
36 38 * memory-module-group if InterleaveFactor is one, or at memory-bank
37 39 * if InterleaveFactor is greater than one.
38 40 *
39 41 * Undo strategy:
40 42 * Create all nodes and properties, or none if it fails in physical and
41 43 * logical memory tree respectively. It keeps on creating logic
42 44 * memory tree although it falis on physical logic tree, but no link to
43 45 * memory module group.
44 46 *
45 47 * NOTE:
46 48 * It depends on PICL devtree plugin and currently
47 49 * there is no refresh routine for DR.
48 50 */
49 51 #include <stdio.h>
50 52 #include <stdlib.h>
51 53 #include <string.h>
52 54 #include <unistd.h>
53 55 #include <alloca.h>
54 56 #include <syslog.h>
55 57 #include <string.h>
56 58 #include <libintl.h>
57 59 #include <picl.h>
58 60 #include <picltree.h>
59 61 #include <fcntl.h>
60 62 #include <errno.h>
61 63 #include <sys/types.h>
62 64 #include <dirent.h>
63 65 #include <sys/stat.h>
64 66 #include <mc.h>
65 67 #include <libnvpair.h>
66 68 #include <limits.h>
67 69 #include "piclmemcfg.h"
68 70
69 71 /*
70 72 * Plugin registration entry points
71 73 */
72 74 static void piclmemcfg_register(void);
73 75 static void piclmemcfg_init(void);
74 76 static void piclmemcfg_fini(void);
75 77
76 78 /*
77 79 * PICL event handler
78 80 */
79 81 static void piclmemcfg_evhandler(const char *ename, const void *earg,
80 82 size_t size, void *cookie);
81 83
82 84 #pragma init(piclmemcfg_register)
83 85
84 86 static picld_plugin_reg_t my_reg_info = {
85 87 PICLD_PLUGIN_VERSION_1,
86 88 PICLD_PLUGIN_NON_CRITICAL,
87 89 "SUNW_piclmemcfg",
88 90 piclmemcfg_init,
89 91 piclmemcfg_fini
90 92 };
91 93
92 94 /*
93 95 * Log message texts
94 96 */
95 97 #define EM_INIT_FAILED gettext("SUNW_piclmemcfg init failed!\n")
96 98 #define EM_PHYSIC_MEM_TREE_FAILED \
97 99 gettext("SUNW_piclmemcfg physical memory tree failed!\n")
98 100 #define EM_LOGIC_MEM_TREE_FAILED \
99 101 gettext("SUNW_piclmemcfg logical memory tree failed!\n")
100 102
101 103 #define EM_INIT_MC_FAILED \
102 104 gettext("SUNW_piclmemcfg init mc failed!\n")
103 105
104 106 /*
105 107 * Global variables for Memory Controllers
106 108 */
107 109 #define MC_DIR "/dev/mc/"
108 110
109 111 static int nsegments; /* The number of memory segments */
110 112 static int nbanks; /* The max. number of banks per segment */
111 113 static int ndevgrps; /* The max. number of device groups per mc */
112 114 static int ndevs; /* The max. number of devices per dev group */
113 115 static int transfersize;
114 116
115 117 static picl_nodehdl_t *msegh_info;
116 118
117 119 /*
118 120 * Memory-module-group node handle list, a singal linking list, where
119 121 * memory module group id is the key to match.
120 122 *
121 123 * It is allocated and added to the head of list, and freed as well.
122 124 * The mmgh field is cleared if failure is encountered in the physical
123 125 * memory tree.
124 126 *
125 127 * This list is accessed in the logical memory tree, and allocated memory
126 128 * is released at the end of plugin.
127 129 */
128 130 typedef struct memmodgrp_info {
129 131 int mmgid;
130 132 struct memmodgrp_info *next;
131 133 picl_nodehdl_t mmgh;
132 134 picl_nodehdl_t mch;
133 135 } mmodgrp_info_t;
134 136
135 137 static mmodgrp_info_t *head2mmodgrp;
136 138
137 139 /*
138 140 * Release the allocated memory of mmodgrp_info
139 141 */
140 142 static void
141 143 free_allocated_mem(void)
142 144 {
143 145 mmodgrp_info_t *mmghdl, *currmmghdl;
144 146
145 147 mmghdl = head2mmodgrp;
146 148
147 149 while (mmghdl) {
148 150 currmmghdl = mmghdl;
149 151 mmghdl = mmghdl->next;
150 152 free(currmmghdl);
151 153 }
152 154
153 155 head2mmodgrp = NULL;
154 156 }
155 157
156 158 /*
157 159 * Delete nodes whose MC is gone at mmodgrp_info
158 160 */
159 161 static void
160 162 del_plugout_mmodgrp(picl_nodehdl_t mch)
161 163 {
162 164 mmodgrp_info_t *mmghdl, *prevmmghdl, *nextmmghdl;
163 165
164 166 for (mmghdl = head2mmodgrp, prevmmghdl = NULL; mmghdl != NULL;
165 167 mmghdl = nextmmghdl) {
166 168 nextmmghdl = mmghdl->next;
167 169 if (mmghdl->mch == mch) {
168 170 if (prevmmghdl == NULL)
169 171 /* we are at the head */
170 172 head2mmodgrp = nextmmghdl;
171 173 else
172 174 prevmmghdl->next = nextmmghdl;
173 175 free(mmghdl);
174 176 } else
175 177 prevmmghdl = mmghdl;
176 178 }
177 179 }
178 180
179 181 /*
180 182 * Search the memory module group node in the mmodgrp_info by global id.
181 183 * The matched memory-module-group node handle will be assigned to
182 184 * the second parameter.
183 185 */
184 186 static int
185 187 find_mem_mod_grp_hdl(int id, picl_nodehdl_t *mmodgrph)
186 188 {
187 189 mmodgrp_info_t *mmghdl;
188 190 int err = PICL_FAILURE;
189 191
190 192 mmghdl = head2mmodgrp;
191 193
192 194 while (mmghdl) {
193 195 if ((mmghdl->mmgh) && (mmghdl->mmgid == id)) {
194 196 *mmodgrph = mmghdl->mmgh;
195 197 err = PICL_SUCCESS;
196 198 break;
197 199 }
198 200 mmghdl = mmghdl->next;
199 201 }
200 202
201 203 return (err);
202 204 }
203 205
204 206 /*
205 207 * Delete nodes and properties created in the physical memory tree.
206 208 */
207 209 static void
208 210 undo_phymem_tree(void)
209 211 {
210 212 mmodgrp_info_t *mmghdl;
211 213
212 214 mmghdl = head2mmodgrp;
213 215
214 216 while (mmghdl) {
215 217 /*
216 218 * Delete nodes and properties of memory-module-group(s)
217 219 */
218 220 if (mmghdl->mmgh == NULL)
219 221 continue;
220 222
221 223 (void) ptree_delete_node(mmghdl->mmgh);
222 224 (void) ptree_destroy_node(mmghdl->mmgh);
223 225
224 226 /*
225 227 * Clear out the saved node handle of memory module group
226 228 * so that logic memory tree won't link to it.
227 229 */
228 230 mmghdl->mch = mmghdl->mmgh = NULL;
229 231 mmghdl = mmghdl->next;
230 232 }
231 233 }
232 234
233 235 /*
234 236 * Create all memory-banks under the given memory-segment.
235 237 */
236 238 static int
237 239 add_mem_banks(picl_nodehdl_t msegh, int fd, struct mc_segment *mcseg)
238 240 {
239 241 int i;
240 242 int err = PICL_SUCCESS;
241 243 static picl_nodehdl_t mmodgrph;
242 244 picl_prophdl_t bankh;
243 245 ptree_propinfo_t propinfo;
244 246 struct mc_bank mcbank;
245 247 char propname[PICL_CLASSNAMELEN_MAX];
246 248
247 249 /*
248 250 * Get all bank information via ioctl
249 251 */
250 252 for (i = 0; i < mcseg->nbanks; i++) {
251 253 mcbank.id = mcseg->bankids[i].globalid;
252 254 if (ioctl(fd, MCIOC_BANK, &mcbank) == -1)
253 255 return (PICL_FAILURE);
254 256
255 257 /*
256 258 * Create memory-bank node under memory-segment node
257 259 */
258 260 err = ptree_create_and_add_node(msegh, PICL_NAME_MEMORY_BANK,
259 261 PICL_CLASS_MEMORY_BANK, &bankh);
260 262 if (err != PICL_SUCCESS)
261 263 break;
262 264
263 265 /*
264 266 * Add property, Size to memory-bank node
265 267 */
266 268 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
267 269 PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (mcbank.size),
268 270 PICL_PROP_SIZE, NULL, NULL);
269 271 if (err != PICL_SUCCESS)
270 272 break;
271 273
272 274 err = ptree_create_and_add_prop(bankh, &propinfo, &mcbank.size,
273 275 NULL);
274 276 if (err != PICL_SUCCESS)
275 277 break;
276 278
277 279 /*
278 280 * Add property, AddressMask to memory-bank node
279 281 */
280 282 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
281 283 PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (mcbank.mask),
282 284 PICL_PROP_ADDRESSMASK, NULL, NULL);
283 285 if (err != PICL_SUCCESS)
284 286 break;
285 287
286 288 err = ptree_create_and_add_prop(bankh, &propinfo, &mcbank.mask,
287 289 NULL);
288 290 if (err != PICL_SUCCESS)
289 291 break;
290 292
291 293 /*
292 294 * Add property, AddressMatch to memory-bank node
293 295 */
294 296 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
295 297 PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (mcbank.match),
296 298 PICL_PROP_ADDRESSMATCH, NULL, NULL);
297 299 if (err != PICL_SUCCESS)
298 300 break;
299 301
300 302 err = ptree_create_and_add_prop(bankh, &propinfo,
301 303 &mcbank.match, NULL);
302 304 if (err != PICL_SUCCESS)
303 305 break;
304 306
305 307 /*
306 308 * Add global id of bank to property, ID memory-bank node
307 309 */
308 310 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
309 311 PICL_PTYPE_INT, PICL_READ, sizeof (mcbank.id), PICL_PROP_ID,
310 312 NULL, NULL);
311 313 if (err != PICL_SUCCESS)
312 314 break;
313 315
314 316 err = ptree_create_and_add_prop(bankh, &propinfo, &mcbank.id,
315 317 NULL);
316 318 if (err != PICL_SUCCESS)
317 319 break;
318 320
319 321 /*
320 322 * Add property, _memory-module-group_ to memory-bank node
321 323 */
322 324 if ((find_mem_mod_grp_hdl(mcbank.devgrpid.globalid,
323 325 &mmodgrph)) != PICL_SUCCESS)
324 326 continue;
325 327
326 328 /*
327 329 * The number of memory modules > 1 means there needs
328 330 * memory module group, and then refers to it. Otherwise,
329 331 * it refers to memory module node handle instead.
330 332 */
331 333 (void) strlcpy(propname, (ndevs > 1 ?
332 334 PICL_REFPROP_MEMORY_MODULE_GROUP :
333 335 PICL_REFPROP_MEMORY_MODULE), PICL_CLASSNAMELEN_MAX);
334 336
335 337 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
336 338 PICL_PTYPE_REFERENCE, PICL_READ, sizeof (picl_nodehdl_t),
337 339 propname, NULL, NULL);
338 340 if (err != PICL_SUCCESS)
339 341 break;
340 342
341 343 err = ptree_create_and_add_prop(bankh, &propinfo, &mmodgrph,
342 344 NULL);
343 345 if (err != PICL_SUCCESS)
344 346 break;
345 347 }
346 348 return (PICL_SUCCESS);
347 349 }
348 350
349 351 static void
350 352 undo_logical_tree(int nsegments)
351 353 {
352 354 int i;
353 355 /*
354 356 * Undo in the logical memory tree
355 357 */
356 358 for (i = 0; i < nsegments; i++) {
357 359 (void) ptree_delete_node(msegh_info[i]);
358 360 (void) ptree_destroy_node(msegh_info[i]);
359 361 }
360 362 }
361 363
362 364 /*
363 365 * Create logical memory tree
364 366 * memory --- memory-segment --- memory-bank
365 367 * Get information via ioctl of memory control driver
366 368 */
367 369 static int
368 370 create_logical_tree(picl_nodehdl_t memh, int fd)
369 371 {
370 372 int i;
371 373 int err = PICL_SUCCESS;
372 374 picl_nodehdl_t msegh;
373 375 ptree_propinfo_t propinfo;
374 376 struct mc_memory *mcmem;
375 377 struct mc_segment *mcseg;
376 378 picl_prophdl_t proph;
377 379 uint64_t memsize = 0;
378 380
379 381 /*
380 382 * allocate memory for mc_memory where nsegmentids are various
381 383 */
382 384 if ((mcmem = alloca((nsegments - 1) * sizeof (mcmem->segmentids[0]) +
383 385 sizeof (*mcmem))) == NULL)
384 386 return (PICL_FAILURE);
385 387
386 388 mcmem->nsegments = nsegments;
387 389
388 390 /*
389 391 * Get logical memory information
390 392 */
391 393 if (ioctl(fd, MCIOC_MEM, mcmem) == -1)
392 394 return (PICL_FAILURE);
393 395
394 396 /*
395 397 * allocate memory for mc_segment where nbanks are various
396 398 */
397 399 if ((mcseg = alloca((nbanks - 1) * sizeof (mcseg->bankids[0]) +
398 400 sizeof (*mcseg))) == NULL)
399 401 return (PICL_FAILURE);
400 402
401 403 /*
402 404 * Get all segments to create memory-segment nodes and
403 405 * add properties.
404 406 */
405 407 for (i = 0; i < nsegments; i++) {
406 408 mcseg->id = mcmem->segmentids[i].globalid;
407 409 mcseg->nbanks = nbanks;
408 410
409 411 if (ioctl(fd, MCIOC_SEG, mcseg) == -1)
410 412 break;
411 413
412 414 /*
413 415 * Create memory-segment node under memory node
414 416 */
↓ open down ↓ |
381 lines elided |
↑ open up ↑ |
415 417 err = ptree_create_and_add_node(memh, PICL_NAME_MEMORY_SEGMENT,
416 418 PICL_CLASS_MEMORY_SEGMENT, &msegh);
417 419 if (err != PICL_SUCCESS)
418 420 break;
419 421
420 422 msegh_info[i] = msegh;
421 423
422 424 /*
423 425 * Add property, Size to memory-segment node
424 426 */
425 - if ((ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
427 + err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
426 428 PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (mcseg->size),
427 - PICL_PROP_SIZE, NULL, NULL)) != PICL_SUCCESS)
429 + PICL_PROP_SIZE, NULL, NULL);
428 430 if (err != PICL_SUCCESS)
429 431 break;
430 432
431 433 memsize += mcseg->size;
432 434 err = ptree_create_and_add_prop(msegh, &propinfo, &mcseg->size,
433 435 NULL);
434 436 if (err != PICL_SUCCESS)
435 437 break;
436 438
437 439 /*
438 440 * Add property, BaseAddress to memory-segment node
439 441 */
440 442 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
441 443 PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (mcseg->base),
442 444 PICL_PROP_BASEADDRESS, NULL, NULL);
443 445 if (err != PICL_SUCCESS)
444 446 break;
445 447
446 448 err = ptree_create_and_add_prop(msegh, &propinfo, &mcseg->base,
447 449 NULL);
448 450 if (err != PICL_SUCCESS)
449 451 break;
450 452
451 453 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
452 454 PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (mcseg->ifactor),
453 455 PICL_PROP_INTERLEAVE_FACTOR, NULL, NULL);
454 456 if (err != PICL_SUCCESS)
455 457 break;
456 458
457 459 err = ptree_create_and_add_prop(msegh, &propinfo,
458 460 &mcseg->ifactor, NULL);
459 461 if (err != PICL_SUCCESS)
460 462 break;
461 463
462 464 err = add_mem_banks(msegh, fd, mcseg);
463 465 if (err != PICL_SUCCESS)
464 466 break;
465 467 }
466 468
467 469 if (err != PICL_SUCCESS) {
468 470 undo_logical_tree(nsegments);
469 471 return (err);
470 472 }
471 473
472 474 err = ptree_get_prop_by_name(memh, PICL_PROP_SIZE, &proph);
473 475 if (err == PICL_SUCCESS) { /* update the value */
474 476 err = ptree_update_propval(proph, &memsize, sizeof (memsize));
475 477 return (err);
476 478 }
477 479
478 480 /*
479 481 * Add the size property
480 482 */
481 483 (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
482 484 PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (memsize),
483 485 PICL_PROP_SIZE, NULL, NULL);
484 486 err = ptree_create_and_add_prop(memh, &propinfo, &memsize, NULL);
485 487
486 488 return (err);
487 489 }
488 490
489 491 /*
490 492 * Add memory-module nodes and properties at each enabled memory-module-group.
491 493 * The formula of unique id is (id of the given memory module group *
492 494 * max number of memory modules per memory module group) + index
493 495 * of memory modules in this memory module group
494 496 */
495 497 static int
496 498 add_mem_modules(picl_nodehdl_t mmodgrph, struct mc_devgrp *mcdevgrp)
497 499 {
498 500 uint64_t size;
499 501 picl_nodehdl_t dimmh;
500 502 ptree_propinfo_t propinfo;
501 503 int i;
502 504 int err = PICL_SUCCESS;
503 505
504 506 size = mcdevgrp->size / mcdevgrp->ndevices;
505 507
506 508 /*
507 509 * Get all memory-modules of the given memory-module-group
508 510 */
509 511 for (i = 0; i < mcdevgrp->ndevices; i++) {
510 512 /*
511 513 * Create memory-module node under memory-module-group
512 514 */
513 515 err = ptree_create_and_add_node(mmodgrph,
514 516 PICL_NAME_MEMORY_MODULE, PICL_CLASS_MEMORY_MODULE, &dimmh);
515 517 if (err != PICL_SUCCESS)
516 518 break;
517 519
518 520 /*
519 521 * Add property, Size to memory-module-group node
520 522 */
521 523 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
522 524 PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (size),
523 525 PICL_PROP_SIZE, NULL, NULL);
524 526 if (err != PICL_SUCCESS)
525 527 break;
526 528
527 529 err = ptree_create_and_add_prop(dimmh, &propinfo, &size, NULL);
528 530 if (err != PICL_SUCCESS)
529 531 break;
530 532
531 533 /*
532 534 * Add property, ID to memory-module-group node
533 535 */
534 536 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
535 537 PICL_PTYPE_INT, PICL_READ, sizeof (i), PICL_PROP_ID,
536 538 NULL, NULL);
537 539 if (err != PICL_SUCCESS)
538 540 break;
539 541
540 542 err = ptree_create_and_add_prop(dimmh, &propinfo, &i,
541 543 NULL);
542 544 if (err != PICL_SUCCESS)
543 545 break;
544 546 }
545 547 return (err);
546 548 }
547 549
548 550 /*
549 551 * Create the subtree at every enabled Memory Controller where size of
550 552 * memory module group is greater than zero.
551 553 * Get information via ioctl of memory control driver
552 554 */
553 555 static int
554 556 create_physical_tree(picl_nodehdl_t mch, void *args)
555 557 {
556 558 int i, portid;
557 559 int err = PICL_SUCCESS;
558 560 mmodgrp_info_t *mmghdl;
559 561 picl_nodehdl_t mmodgrph;
560 562 ptree_propinfo_t propinfo;
561 563 struct mc_control *mccontrol;
562 564 struct mc_devgrp mcdevgrp;
563 565 int fd;
564 566
565 567 fd = (int)args;
566 568 /*
567 569 * Get portid of memory-controller as the key to get its
568 570 * configuration via ioctl.
569 571 */
570 572 err = ptree_get_propval_by_name(mch, OBP_PROP_PORTID, &portid,
571 573 sizeof (portid));
572 574 if (err != PICL_SUCCESS)
573 575 return (err);
574 576
575 577 if ((mccontrol = alloca((ndevgrps - 1) *
576 578 sizeof (mccontrol->devgrpids[0]) + sizeof (*mccontrol))) == NULL)
577 579 return (PICL_FAILURE);
578 580
579 581 mccontrol->id = portid;
580 582 mccontrol->ndevgrps = ndevgrps;
581 583
582 584 if (ioctl(fd, MCIOC_CONTROL, mccontrol) == -1) {
583 585 if (errno == EINVAL)
584 586 return (PICL_WALK_CONTINUE);
585 587 else
586 588 return (PICL_FAILURE);
587 589 }
588 590
589 591 /*
590 592 * If returned ndevgrps is zero, Memory Controller is disable, and
591 593 * skip it.
592 594 */
593 595 if (mccontrol->ndevgrps == 0)
594 596 return (PICL_WALK_CONTINUE);
595 597
596 598 /*
597 599 * Get all memory module groups of the given memory controller.
598 600 */
599 601 for (i = 0; i < mccontrol->ndevgrps; i++) {
600 602 int mmglocalid = mccontrol->devgrpids[i].localid;
601 603
602 604 mcdevgrp.id = mccontrol->devgrpids[i].globalid;
603 605
604 606 if (ioctl(fd, MCIOC_DEVGRP, &mcdevgrp) == -1)
605 607 return (PICL_FAILURE);
606 608
607 609 /*
608 610 * Node doesn't need to be created if size is 0, i.e.
609 611 * there is no memory dimm at slot.
610 612 */
611 613 if (mcdevgrp.size == 0)
612 614 continue;
613 615
614 616 /*
615 617 * Create memory-module-group node under memory-controller
616 618 */
617 619 err = ptree_create_and_add_node(mch, PICL_NAME_MEM_MOD_GROUP,
618 620 PICL_CLASS_MEMORY_MODULE_GROUP, &mmodgrph);
619 621 if (err != PICL_SUCCESS)
620 622 break;
621 623
622 624 /*
623 625 * Allocate space for mmodgrp_info to save the information
624 626 * so that it is easier to do the undo and setup of the
625 627 * reference property in logical memory tree.
626 628 */
627 629 if ((mmghdl = malloc(sizeof (*mmghdl))) == NULL)
628 630 return (PICL_FAILURE);
629 631
630 632 /*
631 633 * Save the information and add it to the beginnong of list.
632 634 */
633 635 mmghdl->mmgid = mcdevgrp.id;
634 636 mmghdl->mmgh = mmodgrph;
635 637 mmghdl->mch = mch;
636 638 mmghdl->next = head2mmodgrp;
637 639
638 640 head2mmodgrp = mmghdl;
639 641
640 642 /*
641 643 * Add property, Size to memory-module-group node
642 644 */
643 645 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
644 646 PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (mcdevgrp.size),
645 647 PICL_PROP_SIZE, NULL, NULL);
646 648 if (err != PICL_SUCCESS)
647 649 break;
648 650
649 651 err = ptree_create_and_add_prop(mmodgrph, &propinfo,
650 652 &mcdevgrp.size, NULL);
651 653 if (err != PICL_SUCCESS)
652 654 break;
653 655
654 656 /*
655 657 * Add property, ID to memory-module-group node
656 658 */
657 659 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
658 660 PICL_PTYPE_INT, PICL_READ, sizeof (mmglocalid),
659 661 PICL_PROP_ID, NULL, NULL);
660 662 if (err != PICL_SUCCESS)
661 663 break;
662 664
663 665 err = ptree_create_and_add_prop(mmodgrph, &propinfo,
664 666 &mmglocalid, NULL);
665 667 if (err != PICL_SUCCESS)
666 668 break;
667 669
668 670 /*
669 671 * Create all memory-module nodes and properties.
670 672 */
671 673 err = add_mem_modules(mmodgrph, &mcdevgrp);
672 674 if (err != PICL_SUCCESS)
673 675 break;
674 676 }
675 677
676 678 if (err == PICL_SUCCESS)
677 679 return (PICL_WALK_CONTINUE);
678 680 return (err);
679 681 }
680 682
681 683 /*
682 684 * Create physical memory tree
683 685 * memory-controller --- memory-module-group --- memory-module
684 686 *
685 687 * It searches all memory-controller nodes in the whole devtree.
686 688 * It returns failure if encountering error in physical tree.
687 689 */
688 690 static int
689 691 find_mc_create_tree(picl_nodehdl_t rooth, int fd)
690 692 {
691 693 int err;
692 694
693 695 err = ptree_walk_tree_by_class(rooth, PICL_CLASS_MEMORY_CONTROLLER,
694 696 (void *)fd, create_physical_tree);
695 697 return (err);
696 698 }
697 699
698 700 static int
699 701 init_mc(void)
700 702 {
701 703 struct mc_memconf mcmemconf;
702 704 int fd;
703 705 DIR *dirp;
704 706 struct dirent *retp;
705 707 char path[PATH_MAX];
706 708 int found = 0;
707 709 int valid_entry = 0;
708 710
709 711 /* open the directory */
710 712 if ((dirp = opendir(MC_DIR)) == NULL) {
711 713 /*
712 714 * As not all platforms have mc drivers that create the
713 715 * /dev/mc directory, print a message only if there is
714 716 * an entry found on which the open failed.
715 717 */
716 718 if (errno != ENOENT)
717 719 syslog(LOG_ERR, EM_INIT_MC_FAILED);
718 720 return (-1);
719 721 }
720 722
721 723 /* start searching this directory */
722 724 while ((retp = readdir(dirp)) != NULL) {
723 725 /* skip . .. etc... */
724 726 if (strcmp(retp->d_name, ".") == 0 ||
725 727 strcmp(retp->d_name, "..") == 0)
726 728 continue;
727 729
728 730 (void) strcpy(path, MC_DIR);
729 731 (void) strcat(path, retp->d_name);
730 732 /* open the memory controller driver */
731 733 if ((fd = open(path, O_RDONLY, 0)) != -1) {
732 734 found = 1;
733 735 break;
734 736 }
735 737 if (errno != ENOENT)
736 738 valid_entry = 1;
737 739 }
738 740 (void) closedir(dirp);
739 741
740 742 if (!found) {
741 743 if (valid_entry)
742 744 syslog(LOG_ERR, EM_INIT_MC_FAILED);
743 745 return (-1);
744 746 }
745 747
746 748 /*
747 749 * Initialize some global variables via ioctl
748 750 */
749 751 if (ioctl(fd, MCIOC_MEMCONF, &mcmemconf) == -1) {
750 752 (void) close(fd);
751 753 return (-1);
752 754 }
753 755
754 756 nsegments = mcmemconf.nsegments;
755 757 nbanks = mcmemconf.nbanks;
756 758 ndevgrps = mcmemconf.ndevgrps;
757 759 ndevs = mcmemconf.ndevs;
758 760 transfersize = mcmemconf.xfer_size;
759 761
760 762 return (fd);
761 763 }
762 764
763 765 /*
764 766 * executed as part of .init when the plugin is dlopen()ed
765 767 */
766 768 void
767 769 piclmemcfg_register(void)
768 770 {
769 771 (void) picld_plugin_register(&my_reg_info);
770 772 }
771 773
772 774 /*
773 775 * init entry point of the plugin
774 776 * Creates the PICL nodes and properties in the physical and logical aspects.
775 777 */
776 778 void
777 779 piclmemcfg_init(void)
778 780 {
779 781 picl_nodehdl_t plfh;
780 782 picl_nodehdl_t memh;
781 783 ptree_propinfo_t propinfo;
782 784 int fd, err;
783 785
784 786 /*
785 787 * Initialize the header pointer of mmodgrp_info list
786 788 */
787 789 head2mmodgrp = NULL;
788 790 msegh_info = NULL;
789 791
790 792 if ((fd = init_mc()) < 0)
791 793 return;
792 794
793 795 /*
794 796 * allocate memory to save memory-segment node handles. Thus,
795 797 * it is easier to delete them if it fails.
796 798 */
797 799 if ((msegh_info = malloc(nsegments * sizeof (picl_nodehdl_t))) ==
798 800 NULL) {
799 801 syslog(LOG_ERR, EM_INIT_FAILED);
800 802 (void) close(fd);
801 803 return;
802 804 }
803 805
804 806 /*
805 807 * find platform node
806 808 */
807 809 if ((ptree_get_node_by_path(PLATFORM_PATH, &plfh)) != PICL_SUCCESS) {
808 810 syslog(LOG_ERR, EM_INIT_FAILED);
809 811 (void) close(fd);
810 812 return;
811 813 }
812 814
813 815 /*
814 816 * Find the memory node
815 817 */
816 818 if ((ptree_get_node_by_path(MEMORY_PATH, &memh)) != PICL_SUCCESS) {
817 819 syslog(LOG_ERR, EM_INIT_FAILED);
818 820 (void) close(fd);
819 821 return;
820 822 }
821 823
822 824 /*
823 825 * Create subtree of memory-controller in the physical aspect.
824 826 * memory-controller --- memory-module-group --- memory-module
825 827 */
826 828 err = find_mc_create_tree(plfh, fd);
827 829
828 830 if (err != PICL_SUCCESS) {
829 831 undo_phymem_tree();
830 832 syslog(LOG_ERR, EM_PHYSIC_MEM_TREE_FAILED);
831 833 }
832 834
833 835 /*
834 836 * Add property, TransferSize to memory node
835 837 */
836 838 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
837 839 PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (transfersize),
838 840 PICL_PROP_TRANSFER_SIZE, NULL, NULL);
839 841 if (err != PICL_SUCCESS) {
840 842 (void) close(fd);
841 843 return;
842 844 }
843 845
844 846 err = ptree_create_and_add_prop(memh, &propinfo,
845 847 &transfersize, NULL);
846 848 if (err != PICL_SUCCESS) {
847 849 (void) close(fd);
848 850 return;
849 851 }
850 852
851 853 /*
852 854 * Create subtree of memory in the logical aspect.
853 855 * memory --- memory-segment --- memory-bank
854 856 */
855 857 if ((create_logical_tree(memh, fd)) != PICL_SUCCESS) {
856 858 syslog(LOG_ERR, EM_LOGIC_MEM_TREE_FAILED);
857 859 undo_logical_tree(nsegments);
858 860 }
859 861
860 862 (void) close(fd);
861 863 (void) ptree_register_handler(PICLEVENT_MC_ADDED,
862 864 piclmemcfg_evhandler, NULL);
863 865 (void) ptree_register_handler(PICLEVENT_MC_REMOVED,
864 866 piclmemcfg_evhandler, NULL);
865 867 }
866 868
867 869 /*
868 870 * fini entry point of the plugin
869 871 */
870 872 void
871 873 piclmemcfg_fini(void)
872 874 {
873 875 (void) ptree_unregister_handler(PICLEVENT_MC_ADDED,
874 876 piclmemcfg_evhandler, NULL);
875 877 (void) ptree_unregister_handler(PICLEVENT_MC_REMOVED,
876 878 piclmemcfg_evhandler, NULL);
877 879 /*
878 880 * Release all the allocated memory for global structures
879 881 */
880 882 free_allocated_mem();
881 883 if (msegh_info)
882 884 free(msegh_info);
883 885 }
884 886
885 887 /*
886 888 * Event handler of this plug-in
887 889 */
888 890 /*ARGSUSED*/
889 891 static void
890 892 piclmemcfg_evhandler(const char *ename, const void *earg, size_t size,
891 893 void *cookie)
892 894 {
893 895 int err;
894 896 int fd;
895 897 picl_nodehdl_t memh;
896 898 picl_nodehdl_t nodeh;
897 899 int old_nsegs;
898 900 nvlist_t *nvlp;
899 901
900 902 memh = NULL;
901 903 if (nvlist_unpack((char *)earg, size, &nvlp, NULL))
902 904 return;
903 905
904 906 if (nvlist_lookup_uint64(nvlp, PICLEVENTARG_NODEHANDLE, &nodeh)) {
905 907 nvlist_free(nvlp);
906 908 return;
907 909 }
908 910 nvlist_free(nvlp);
909 911
910 912 /*
911 913 * get the memory node
912 914 */
913 915 err = ptree_get_node_by_path(MEMORY_PATH, &memh);
914 916 if (err != PICL_SUCCESS)
915 917 return;
916 918
917 919 /*
918 920 * nsegments won't be overwritten until init_mc succeeds
919 921 */
920 922 old_nsegs = nsegments;
921 923 if ((fd = init_mc()) < 0)
922 924 return;
923 925
924 926 if (strcmp(ename, PICLEVENT_MC_ADDED) == 0)
925 927 (void) create_physical_tree(nodeh, (void *)fd);
926 928 else if (strcmp(ename, PICLEVENT_MC_REMOVED) == 0)
927 929 /*
928 930 * Delete the entry at the list only since class at PICL is
929 931 * deleted in devtree plugin.
930 932 */
931 933 (void) del_plugout_mmodgrp(nodeh);
932 934
933 935 (void) undo_logical_tree(old_nsegs);
934 936 free(msegh_info);
935 937
936 938 /*
937 939 * allocate memory to save memory-segment node handles. Thus,
938 940 * it is easier to delete them if it fails.
939 941 */
940 942 if ((msegh_info = malloc(nsegments * sizeof (picl_nodehdl_t))) ==
941 943 NULL) {
942 944 (void) close(fd);
943 945 return;
944 946 }
945 947
946 948 (void) create_logical_tree(memh, fd);
947 949
948 950 (void) close(fd);
949 951 }
↓ open down ↓ |
512 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX