4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * This plugin creates memory configuration nodes and properties in the
28 * PICL tree for Cheetah platforms.
30 * Subtree of memory-controller in the physical aspect.
31 * memory-controller --- memory-module-group --- memory-module
33 * Subtree of memory in the logical aspect.
34 * memory --- memory-segment --- memory-bank
35 * Add property _memory-module-group_ at memory-segment referring to the
36 * memory-module-group if InterleaveFactor is one, or at memory-bank
37 * if InterleaveFactor is greater than one.
40 * Create all nodes and properties, or none if it fails in physical and
41 * logical memory tree respectively. It keeps on creating logic
42 * memory tree although it falis on physical logic tree, but no link to
43 * memory module group.
46 * It depends on PICL devtree plugin and currently
47 * there is no refresh routine for DR.
61 #include <sys/types.h>
65 #include <libnvpair.h>
67 #include "piclmemcfg.h"
70 * Plugin registration entry points
72 static void piclmemcfg_register(void);
73 static void piclmemcfg_init(void);
74 static void piclmemcfg_fini(void);
79 static void piclmemcfg_evhandler(const char *ename
, const void *earg
,
80 size_t size
, void *cookie
);
82 #pragma init(piclmemcfg_register)
84 static picld_plugin_reg_t my_reg_info
= {
85 PICLD_PLUGIN_VERSION_1
,
86 PICLD_PLUGIN_NON_CRITICAL
,
95 #define EM_INIT_FAILED gettext("SUNW_piclmemcfg init failed!\n")
96 #define EM_PHYSIC_MEM_TREE_FAILED \
97 gettext("SUNW_piclmemcfg physical memory tree failed!\n")
98 #define EM_LOGIC_MEM_TREE_FAILED \
99 gettext("SUNW_piclmemcfg logical memory tree failed!\n")
101 #define EM_INIT_MC_FAILED \
102 gettext("SUNW_piclmemcfg init mc failed!\n")
105 * Global variables for Memory Controllers
107 #define MC_DIR "/dev/mc/"
109 static int nsegments
; /* The number of memory segments */
110 static int nbanks
; /* The max. number of banks per segment */
111 static int ndevgrps
; /* The max. number of device groups per mc */
112 static int ndevs
; /* The max. number of devices per dev group */
113 static int transfersize
;
115 static picl_nodehdl_t
*msegh_info
;
118 * Memory-module-group node handle list, a singal linking list, where
119 * memory module group id is the key to match.
121 * It is allocated and added to the head of list, and freed as well.
122 * The mmgh field is cleared if failure is encountered in the physical
125 * This list is accessed in the logical memory tree, and allocated memory
126 * is released at the end of plugin.
128 typedef struct memmodgrp_info
{
130 struct memmodgrp_info
*next
;
135 static mmodgrp_info_t
*head2mmodgrp
;
138 * Release the allocated memory of mmodgrp_info
141 free_allocated_mem(void)
143 mmodgrp_info_t
*mmghdl
, *currmmghdl
;
145 mmghdl
= head2mmodgrp
;
149 mmghdl
= mmghdl
->next
;
157 * Delete nodes whose MC is gone at mmodgrp_info
160 del_plugout_mmodgrp(picl_nodehdl_t mch
)
162 mmodgrp_info_t
*mmghdl
, *prevmmghdl
, *nextmmghdl
;
164 for (mmghdl
= head2mmodgrp
, prevmmghdl
= NULL
; mmghdl
!= NULL
;
165 mmghdl
= nextmmghdl
) {
166 nextmmghdl
= mmghdl
->next
;
167 if (mmghdl
->mch
== mch
) {
168 if (prevmmghdl
== NULL
)
169 /* we are at the head */
170 head2mmodgrp
= nextmmghdl
;
172 prevmmghdl
->next
= nextmmghdl
;
180 * Search the memory module group node in the mmodgrp_info by global id.
181 * The matched memory-module-group node handle will be assigned to
182 * the second parameter.
185 find_mem_mod_grp_hdl(int id
, picl_nodehdl_t
*mmodgrph
)
187 mmodgrp_info_t
*mmghdl
;
188 int err
= PICL_FAILURE
;
190 mmghdl
= head2mmodgrp
;
193 if ((mmghdl
->mmgh
) && (mmghdl
->mmgid
== id
)) {
194 *mmodgrph
= mmghdl
->mmgh
;
198 mmghdl
= mmghdl
->next
;
205 * Delete nodes and properties created in the physical memory tree.
208 undo_phymem_tree(void)
210 mmodgrp_info_t
*mmghdl
;
212 mmghdl
= head2mmodgrp
;
216 * Delete nodes and properties of memory-module-group(s)
218 if (mmghdl
->mmgh
== (uintptr_t)NULL
)
221 (void) ptree_delete_node(mmghdl
->mmgh
);
222 (void) ptree_destroy_node(mmghdl
->mmgh
);
225 * Clear out the saved node handle of memory module group
226 * so that logic memory tree won't link to it.
228 mmghdl
->mch
= mmghdl
->mmgh
= (uintptr_t)NULL
;
229 mmghdl
= mmghdl
->next
;
234 * Create all memory-banks under the given memory-segment.
237 add_mem_banks(picl_nodehdl_t msegh
, int fd
, struct mc_segment
*mcseg
)
240 int err
= PICL_SUCCESS
;
241 static picl_nodehdl_t mmodgrph
;
242 picl_prophdl_t bankh
;
243 ptree_propinfo_t propinfo
;
244 struct mc_bank mcbank
;
245 char propname
[PICL_CLASSNAMELEN_MAX
];
248 * Get all bank information via ioctl
250 for (i
= 0; i
< mcseg
->nbanks
; i
++) {
251 mcbank
.id
= mcseg
->bankids
[i
].globalid
;
252 if (ioctl(fd
, MCIOC_BANK
, &mcbank
) == -1)
253 return (PICL_FAILURE
);
256 * Create memory-bank node under memory-segment node
258 err
= ptree_create_and_add_node(msegh
, PICL_NAME_MEMORY_BANK
,
259 PICL_CLASS_MEMORY_BANK
, &bankh
);
260 if (err
!= PICL_SUCCESS
)
264 * Add property, Size to memory-bank node
266 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
267 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (mcbank
.size
),
268 PICL_PROP_SIZE
, NULL
, NULL
);
269 if (err
!= PICL_SUCCESS
)
272 err
= ptree_create_and_add_prop(bankh
, &propinfo
, &mcbank
.size
,
274 if (err
!= PICL_SUCCESS
)
278 * Add property, AddressMask to memory-bank node
280 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
281 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (mcbank
.mask
),
282 PICL_PROP_ADDRESSMASK
, NULL
, NULL
);
283 if (err
!= PICL_SUCCESS
)
286 err
= ptree_create_and_add_prop(bankh
, &propinfo
, &mcbank
.mask
,
288 if (err
!= PICL_SUCCESS
)
292 * Add property, AddressMatch to memory-bank node
294 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
295 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (mcbank
.match
),
296 PICL_PROP_ADDRESSMATCH
, NULL
, NULL
);
297 if (err
!= PICL_SUCCESS
)
300 err
= ptree_create_and_add_prop(bankh
, &propinfo
,
301 &mcbank
.match
, NULL
);
302 if (err
!= PICL_SUCCESS
)
306 * Add global id of bank to property, ID memory-bank node
308 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
309 PICL_PTYPE_INT
, PICL_READ
, sizeof (mcbank
.id
), PICL_PROP_ID
,
311 if (err
!= PICL_SUCCESS
)
314 err
= ptree_create_and_add_prop(bankh
, &propinfo
, &mcbank
.id
,
316 if (err
!= PICL_SUCCESS
)
320 * Add property, _memory-module-group_ to memory-bank node
322 if ((find_mem_mod_grp_hdl(mcbank
.devgrpid
.globalid
,
323 &mmodgrph
)) != PICL_SUCCESS
)
327 * The number of memory modules > 1 means there needs
328 * memory module group, and then refers to it. Otherwise,
329 * it refers to memory module node handle instead.
331 (void) strlcpy(propname
, (ndevs
> 1 ?
332 PICL_REFPROP_MEMORY_MODULE_GROUP
:
333 PICL_REFPROP_MEMORY_MODULE
), PICL_CLASSNAMELEN_MAX
);
335 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
336 PICL_PTYPE_REFERENCE
, PICL_READ
, sizeof (picl_nodehdl_t
),
337 propname
, NULL
, NULL
);
338 if (err
!= PICL_SUCCESS
)
341 err
= ptree_create_and_add_prop(bankh
, &propinfo
, &mmodgrph
,
343 if (err
!= PICL_SUCCESS
)
346 return (PICL_SUCCESS
);
350 undo_logical_tree(int nsegments
)
354 * Undo in the logical memory tree
356 for (i
= 0; i
< nsegments
; i
++) {
357 (void) ptree_delete_node(msegh_info
[i
]);
358 (void) ptree_destroy_node(msegh_info
[i
]);
363 * Create logical memory tree
364 * memory --- memory-segment --- memory-bank
365 * Get information via ioctl of memory control driver
368 create_logical_tree(picl_nodehdl_t memh
, int fd
)
371 int err
= PICL_SUCCESS
;
372 picl_nodehdl_t msegh
;
373 ptree_propinfo_t propinfo
;
374 struct mc_memory
*mcmem
;
375 struct mc_segment
*mcseg
;
376 picl_prophdl_t proph
;
377 uint64_t memsize
= 0;
380 * allocate memory for mc_memory where nsegmentids are various
382 if ((mcmem
= alloca((nsegments
- 1) * sizeof (mcmem
->segmentids
[0]) +
383 sizeof (*mcmem
))) == NULL
)
384 return (PICL_FAILURE
);
386 mcmem
->nsegments
= nsegments
;
389 * Get logical memory information
391 if (ioctl(fd
, MCIOC_MEM
, mcmem
) == -1)
392 return (PICL_FAILURE
);
395 * allocate memory for mc_segment where nbanks are various
397 if ((mcseg
= alloca((nbanks
- 1) * sizeof (mcseg
->bankids
[0]) +
398 sizeof (*mcseg
))) == NULL
)
399 return (PICL_FAILURE
);
402 * Get all segments to create memory-segment nodes and
405 for (i
= 0; i
< nsegments
; i
++) {
406 mcseg
->id
= mcmem
->segmentids
[i
].globalid
;
407 mcseg
->nbanks
= nbanks
;
409 if (ioctl(fd
, MCIOC_SEG
, mcseg
) == -1)
413 * Create memory-segment node under memory node
415 err
= ptree_create_and_add_node(memh
, PICL_NAME_MEMORY_SEGMENT
,
416 PICL_CLASS_MEMORY_SEGMENT
, &msegh
);
417 if (err
!= PICL_SUCCESS
)
420 msegh_info
[i
] = msegh
;
423 * Add property, Size to memory-segment node
425 if ((ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
426 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (mcseg
->size
),
427 PICL_PROP_SIZE
, NULL
, NULL
)) != PICL_SUCCESS
)
428 if (err
!= PICL_SUCCESS
)
431 memsize
+= mcseg
->size
;
432 err
= ptree_create_and_add_prop(msegh
, &propinfo
, &mcseg
->size
,
434 if (err
!= PICL_SUCCESS
)
438 * Add property, BaseAddress to memory-segment node
440 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
441 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (mcseg
->base
),
442 PICL_PROP_BASEADDRESS
, NULL
, NULL
);
443 if (err
!= PICL_SUCCESS
)
446 err
= ptree_create_and_add_prop(msegh
, &propinfo
, &mcseg
->base
,
448 if (err
!= PICL_SUCCESS
)
451 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
452 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (mcseg
->ifactor
),
453 PICL_PROP_INTERLEAVE_FACTOR
, NULL
, NULL
);
454 if (err
!= PICL_SUCCESS
)
457 err
= ptree_create_and_add_prop(msegh
, &propinfo
,
458 &mcseg
->ifactor
, NULL
);
459 if (err
!= PICL_SUCCESS
)
462 err
= add_mem_banks(msegh
, fd
, mcseg
);
463 if (err
!= PICL_SUCCESS
)
467 if (err
!= PICL_SUCCESS
) {
468 undo_logical_tree(nsegments
);
472 err
= ptree_get_prop_by_name(memh
, PICL_PROP_SIZE
, &proph
);
473 if (err
== PICL_SUCCESS
) { /* update the value */
474 err
= ptree_update_propval(proph
, &memsize
, sizeof (memsize
));
479 * Add the size property
481 (void) ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
482 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (memsize
),
483 PICL_PROP_SIZE
, NULL
, NULL
);
484 err
= ptree_create_and_add_prop(memh
, &propinfo
, &memsize
, NULL
);
490 * Add memory-module nodes and properties at each enabled memory-module-group.
491 * The formula of unique id is (id of the given memory module group *
492 * max number of memory modules per memory module group) + index
493 * of memory modules in this memory module group
496 add_mem_modules(picl_nodehdl_t mmodgrph
, struct mc_devgrp
*mcdevgrp
)
499 picl_nodehdl_t dimmh
;
500 ptree_propinfo_t propinfo
;
502 int err
= PICL_SUCCESS
;
504 size
= mcdevgrp
->size
/ mcdevgrp
->ndevices
;
507 * Get all memory-modules of the given memory-module-group
509 for (i
= 0; i
< mcdevgrp
->ndevices
; i
++) {
511 * Create memory-module node under memory-module-group
513 err
= ptree_create_and_add_node(mmodgrph
,
514 PICL_NAME_MEMORY_MODULE
, PICL_CLASS_MEMORY_MODULE
, &dimmh
);
515 if (err
!= PICL_SUCCESS
)
519 * Add property, Size to memory-module-group node
521 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
522 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (size
),
523 PICL_PROP_SIZE
, NULL
, NULL
);
524 if (err
!= PICL_SUCCESS
)
527 err
= ptree_create_and_add_prop(dimmh
, &propinfo
, &size
, NULL
);
528 if (err
!= PICL_SUCCESS
)
532 * Add property, ID to memory-module-group node
534 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
535 PICL_PTYPE_INT
, PICL_READ
, sizeof (i
), PICL_PROP_ID
,
537 if (err
!= PICL_SUCCESS
)
540 err
= ptree_create_and_add_prop(dimmh
, &propinfo
, &i
,
542 if (err
!= PICL_SUCCESS
)
549 * Create the subtree at every enabled Memory Controller where size of
550 * memory module group is greater than zero.
551 * Get information via ioctl of memory control driver
554 create_physical_tree(picl_nodehdl_t mch
, void *args
)
557 int err
= PICL_SUCCESS
;
558 mmodgrp_info_t
*mmghdl
;
559 picl_nodehdl_t mmodgrph
;
560 ptree_propinfo_t propinfo
;
561 struct mc_control
*mccontrol
;
562 struct mc_devgrp mcdevgrp
;
567 * Get portid of memory-controller as the key to get its
568 * configuration via ioctl.
570 err
= ptree_get_propval_by_name(mch
, OBP_PROP_PORTID
, &portid
,
572 if (err
!= PICL_SUCCESS
)
575 if ((mccontrol
= alloca((ndevgrps
- 1) *
576 sizeof (mccontrol
->devgrpids
[0]) + sizeof (*mccontrol
))) == NULL
)
577 return (PICL_FAILURE
);
579 mccontrol
->id
= portid
;
580 mccontrol
->ndevgrps
= ndevgrps
;
582 if (ioctl(fd
, MCIOC_CONTROL
, mccontrol
) == -1) {
584 return (PICL_WALK_CONTINUE
);
586 return (PICL_FAILURE
);
590 * If returned ndevgrps is zero, Memory Controller is disable, and
593 if (mccontrol
->ndevgrps
== 0)
594 return (PICL_WALK_CONTINUE
);
597 * Get all memory module groups of the given memory controller.
599 for (i
= 0; i
< mccontrol
->ndevgrps
; i
++) {
600 int mmglocalid
= mccontrol
->devgrpids
[i
].localid
;
602 mcdevgrp
.id
= mccontrol
->devgrpids
[i
].globalid
;
604 if (ioctl(fd
, MCIOC_DEVGRP
, &mcdevgrp
) == -1)
605 return (PICL_FAILURE
);
608 * Node doesn't need to be created if size is 0, i.e.
609 * there is no memory dimm at slot.
611 if (mcdevgrp
.size
== 0)
615 * Create memory-module-group node under memory-controller
617 err
= ptree_create_and_add_node(mch
, PICL_NAME_MEM_MOD_GROUP
,
618 PICL_CLASS_MEMORY_MODULE_GROUP
, &mmodgrph
);
619 if (err
!= PICL_SUCCESS
)
623 * Allocate space for mmodgrp_info to save the information
624 * so that it is easier to do the undo and setup of the
625 * reference property in logical memory tree.
627 if ((mmghdl
= malloc(sizeof (*mmghdl
))) == NULL
)
628 return (PICL_FAILURE
);
631 * Save the information and add it to the beginnong of list.
633 mmghdl
->mmgid
= mcdevgrp
.id
;
634 mmghdl
->mmgh
= mmodgrph
;
636 mmghdl
->next
= head2mmodgrp
;
638 head2mmodgrp
= mmghdl
;
641 * Add property, Size to memory-module-group node
643 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
644 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (mcdevgrp
.size
),
645 PICL_PROP_SIZE
, NULL
, NULL
);
646 if (err
!= PICL_SUCCESS
)
649 err
= ptree_create_and_add_prop(mmodgrph
, &propinfo
,
650 &mcdevgrp
.size
, NULL
);
651 if (err
!= PICL_SUCCESS
)
655 * Add property, ID to memory-module-group node
657 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
658 PICL_PTYPE_INT
, PICL_READ
, sizeof (mmglocalid
),
659 PICL_PROP_ID
, NULL
, NULL
);
660 if (err
!= PICL_SUCCESS
)
663 err
= ptree_create_and_add_prop(mmodgrph
, &propinfo
,
665 if (err
!= PICL_SUCCESS
)
669 * Create all memory-module nodes and properties.
671 err
= add_mem_modules(mmodgrph
, &mcdevgrp
);
672 if (err
!= PICL_SUCCESS
)
676 if (err
== PICL_SUCCESS
)
677 return (PICL_WALK_CONTINUE
);
682 * Create physical memory tree
683 * memory-controller --- memory-module-group --- memory-module
685 * It searches all memory-controller nodes in the whole devtree.
686 * It returns failure if encountering error in physical tree.
689 find_mc_create_tree(picl_nodehdl_t rooth
, int fd
)
693 err
= ptree_walk_tree_by_class(rooth
, PICL_CLASS_MEMORY_CONTROLLER
,
694 (void *)fd
, create_physical_tree
);
701 struct mc_memconf mcmemconf
;
709 /* open the directory */
710 if ((dirp
= opendir(MC_DIR
)) == NULL
) {
712 * As not all platforms have mc drivers that create the
713 * /dev/mc directory, print a message only if there is
714 * an entry found on which the open failed.
717 syslog(LOG_ERR
, EM_INIT_MC_FAILED
);
721 /* start searching this directory */
722 while ((retp
= readdir(dirp
)) != NULL
) {
723 /* skip . .. etc... */
724 if (strcmp(retp
->d_name
, ".") == 0 ||
725 strcmp(retp
->d_name
, "..") == 0)
728 (void) strcpy(path
, MC_DIR
);
729 (void) strcat(path
, retp
->d_name
);
730 /* open the memory controller driver */
731 if ((fd
= open(path
, O_RDONLY
, 0)) != -1) {
738 (void) closedir(dirp
);
742 syslog(LOG_ERR
, EM_INIT_MC_FAILED
);
747 * Initialize some global variables via ioctl
749 if (ioctl(fd
, MCIOC_MEMCONF
, &mcmemconf
) == -1) {
754 nsegments
= mcmemconf
.nsegments
;
755 nbanks
= mcmemconf
.nbanks
;
756 ndevgrps
= mcmemconf
.ndevgrps
;
757 ndevs
= mcmemconf
.ndevs
;
758 transfersize
= mcmemconf
.xfer_size
;
764 * executed as part of .init when the plugin is dlopen()ed
767 piclmemcfg_register(void)
769 (void) picld_plugin_register(&my_reg_info
);
773 * init entry point of the plugin
774 * Creates the PICL nodes and properties in the physical and logical aspects.
777 piclmemcfg_init(void)
781 ptree_propinfo_t propinfo
;
785 * Initialize the header pointer of mmodgrp_info list
790 if ((fd
= init_mc()) < 0)
794 * allocate memory to save memory-segment node handles. Thus,
795 * it is easier to delete them if it fails.
797 if ((msegh_info
= malloc(nsegments
* sizeof (picl_nodehdl_t
))) ==
799 syslog(LOG_ERR
, EM_INIT_FAILED
);
807 if ((ptree_get_node_by_path(PLATFORM_PATH
, &plfh
)) != PICL_SUCCESS
) {
808 syslog(LOG_ERR
, EM_INIT_FAILED
);
814 * Find the memory node
816 if ((ptree_get_node_by_path(MEMORY_PATH
, &memh
)) != PICL_SUCCESS
) {
817 syslog(LOG_ERR
, EM_INIT_FAILED
);
823 * Create subtree of memory-controller in the physical aspect.
824 * memory-controller --- memory-module-group --- memory-module
826 err
= find_mc_create_tree(plfh
, fd
);
828 if (err
!= PICL_SUCCESS
) {
830 syslog(LOG_ERR
, EM_PHYSIC_MEM_TREE_FAILED
);
834 * Add property, TransferSize to memory node
836 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
837 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (transfersize
),
838 PICL_PROP_TRANSFER_SIZE
, NULL
, NULL
);
839 if (err
!= PICL_SUCCESS
) {
844 err
= ptree_create_and_add_prop(memh
, &propinfo
,
845 &transfersize
, NULL
);
846 if (err
!= PICL_SUCCESS
) {
852 * Create subtree of memory in the logical aspect.
853 * memory --- memory-segment --- memory-bank
855 if ((create_logical_tree(memh
, fd
)) != PICL_SUCCESS
) {
856 syslog(LOG_ERR
, EM_LOGIC_MEM_TREE_FAILED
);
857 undo_logical_tree(nsegments
);
861 (void) ptree_register_handler(PICLEVENT_MC_ADDED
,
862 piclmemcfg_evhandler
, NULL
);
863 (void) ptree_register_handler(PICLEVENT_MC_REMOVED
,
864 piclmemcfg_evhandler
, NULL
);
868 * fini entry point of the plugin
871 piclmemcfg_fini(void)
873 (void) ptree_unregister_handler(PICLEVENT_MC_ADDED
,
874 piclmemcfg_evhandler
, NULL
);
875 (void) ptree_unregister_handler(PICLEVENT_MC_REMOVED
,
876 piclmemcfg_evhandler
, NULL
);
878 * Release all the allocated memory for global structures
880 free_allocated_mem();
885 * Event handler of this plug-in
889 piclmemcfg_evhandler(const char *ename
, const void *earg
, size_t size
,
895 picl_nodehdl_t nodeh
;
899 memh
= (uintptr_t)NULL
;
900 if (nvlist_unpack((char *)earg
, size
, &nvlp
, 0))
903 if (nvlist_lookup_uint64(nvlp
, PICLEVENTARG_NODEHANDLE
, &nodeh
)) {
910 * get the memory node
912 err
= ptree_get_node_by_path(MEMORY_PATH
, &memh
);
913 if (err
!= PICL_SUCCESS
)
917 * nsegments won't be overwritten until init_mc succeeds
919 old_nsegs
= nsegments
;
920 if ((fd
= init_mc()) < 0)
923 if (strcmp(ename
, PICLEVENT_MC_ADDED
) == 0)
924 (void) create_physical_tree(nodeh
, (void *)fd
);
925 else if (strcmp(ename
, PICLEVENT_MC_REMOVED
) == 0)
927 * Delete the entry at the list only since class at PICL is
928 * deleted in devtree plugin.
930 (void) del_plugout_mmodgrp(nodeh
);
932 (void) undo_logical_tree(old_nsegs
);
936 * allocate memory to save memory-segment node handles. Thus,
937 * it is easier to delete them if it fails.
939 if ((msegh_info
= malloc(nsegments
* sizeof (picl_nodehdl_t
))) ==
945 (void) create_logical_tree(memh
, fd
);