/* * Compare the /platform tree to the /frutree to determine if a * device has been removed */ static int is_removed_device(char *plat, char *fru) { int err; picl_nodehdl_t plath, frusloth, frumodh; /* Check for node in /platform tree */ err = ptree_get_node_by_path(plat, &plath); if (err == PICL_SUCCESS) return (PICL_FAILURE); /* * The node is not in /platform, so find the corresponding slot in * the frutree */ err = ptree_get_node_by_path(fru, &frusloth); if (err != PICL_SUCCESS) return (err); /* * If the slot in the frutree does not have a child, then return * PICL_FAILURE. This means that the /platform tree and * the frutree are consistent and no action is necessary. * Otherwise return PICL_SUCCESS to indicate that the needs * to be removed from the frutree */ err = ptree_get_propval_by_name(frusloth, PICL_PROP_CHILD, &frumodh, sizeof (picl_nodehdl_t)); if (err != PICL_SUCCESS) return (err); return (PICL_SUCCESS); }
/* * Given the root node of the device tree. * compare it to the picl tree and add to it cpus * that are new. */ static void add_cpus(di_node_t di_node) { int err; di_node_t cnode; picl_nodehdl_t plath; cpu_lookup_t cpu_arg; char *nodename; err = ptree_get_node_by_path(PLATFORM_PATH, &plath); if (err != PICL_SUCCESS) return; for (cnode = di_child_node(di_node); cnode != DI_NODE_NIL; cnode = di_sibling_node(cnode)) { nodename = di_node_name(cnode); if (nodename == NULL) continue; if (strcmp(nodename, OBP_CPU) == 0) { cpu_arg.di_node = cnode; if (ptree_walk_tree_by_class(plath, PICL_CLASS_CPU, &cpu_arg, cpu_exists) != PICL_SUCCESS) return; if (cpu_arg.result == 0) /* * Didn't find a matching cpu, add it. */ (void) construct_cpu_node(plath, cnode); } } }
/* Initialize the FRU node for the system board */ static int do_sysboard_init(picl_nodehdl_t rooth, picl_nodehdl_t *childh) { picl_nodehdl_t tmph; int err; /* Create the node for the system board */ if (ptree_get_node_by_path(platform_frupath[SYSBRD], &tmph) == PICL_SUCCESS) { err = ptree_create_node("system-board", "fru", childh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(*childh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(*childh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(rooth, *childh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, *childh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); } return (PICL_SUCCESS); }
/* Initializes the FRU nodes for the FCAL backplane */ static int do_fcal_init(picl_nodehdl_t rooth) { picl_nodehdl_t fcalbrdh; picl_nodehdl_t tmph; int err; /* Create the node for the FCAL backplane (if it exists) */ if (ptree_get_node_by_path(platform_frupath[FCAL], &tmph) == PICL_SUCCESS) { err = ptree_create_node("fcal-backplane", "fru", &fcalbrdh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(fcalbrdh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(fcalbrdh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(rooth, fcalbrdh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, fcalbrdh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); } return (PICL_SUCCESS); }
/* Hotplug routine used to remove an existing power supply */ static int remove_power_supply(int slotnum) { picl_nodehdl_t powersloth; picl_nodehdl_t powermodh; int err; /* Find the node for the given power supply slot */ if (ptree_get_node_by_path(frutree_power_supply[slotnum], &powersloth) == PICL_SUCCESS) { /* Make sure it's got a child, then delete it */ err = ptree_get_propval_by_name(powersloth, PICL_PROP_CHILD, &powermodh, sizeof (picl_nodehdl_t)); if (err != PICL_SUCCESS) { return (err); } err = ptree_delete_node(powermodh); if (err != PICL_SUCCESS) { return (err); } else { (void) ptree_destroy_node(powermodh); } /* Post picl-fru-removed event */ post_frudr_event(PICL_FRU_REMOVED, NULL, powermodh); } return (PICL_SUCCESS); }
/* * Given the start node of the device tree. * find all cpus in the picl tree that don't have * device tree counterparts and remove them. */ static void remove_cpus(di_node_t di_start) { int err; picl_nodehdl_t plath; cpu_lookup_t cpu_arg; err = ptree_get_node_by_path(PLATFORM_PATH, &plath); if (err != PICL_SUCCESS) return; do { cpu_arg.di_node = di_start; cpu_arg.nodeh = 0; cpu_arg.result = 0; if (ptree_walk_tree_by_class(plath, PICL_CLASS_CPU, &cpu_arg, remove_cpu_candidate) != PICL_SUCCESS) return; if (cpu_arg.result == 1) { err = ptree_delete_node(cpu_arg.nodeh); if (err == PICL_SUCCESS) ptree_destroy_node(cpu_arg.nodeh); } } while (cpu_arg.result); }
/* Initializes the FRU node for the RSC card */ static int do_rscboard_init(picl_nodehdl_t rooth) { picl_nodehdl_t rscbrdh; picl_nodehdl_t tmph; int err; /* Create the node for the RSC board (if it exists) */ if (ptree_get_node_by_path(platform_frupath[RSC], &tmph) == PICL_SUCCESS) { err = ptree_create_node("rsc-board", "fru", &rscbrdh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(rscbrdh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(rscbrdh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(rooth, rscbrdh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, rscbrdh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); } return (PICL_SUCCESS); }
/* Creates the FRU nodes for the DIMMs on a particular CPU Module */ static int do_dimms_init(picl_nodehdl_t rooth, int slot, int module) { picl_nodehdl_t dimmsloth; picl_nodehdl_t dimmmodh; picl_nodehdl_t tmph; int i, c, l, err; for (i = 0; i < DIMMS_PER_MOD; i++) { /* Create the node for the memory slot */ err = ptree_create_node("dimm-slot", "location", &dimmsloth); if (err != PICL_SUCCESS) return (err); err = add_slot_prop(dimmsloth, i); if (err != PICL_SUCCESS) return (err); c = ((slot * DIMMS_PER_SLOT) + (module * DIMMS_PER_MOD) + i) + CPU0_DIMM0; l = c - (DIMMS_PER_SLOT * slot); err = add_label_prop(dimmsloth, location_label[l]); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(rooth, dimmsloth); if (err != PICL_SUCCESS) return (err); /* If the memory module exists, create a node for it */ if (ptree_get_node_by_path(platform_frupath[c], &tmph) == PICL_SUCCESS) { err = ptree_create_node("dimm-module", "fru", &dimmmodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(dimmmodh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(dimmmodh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(dimmsloth, dimmmodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, dimmmodh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); } } return (PICL_SUCCESS); }
void env_picl_setup(void) { int err; sensor_node_t *snodep; fan_node_t *fnodep; picl_nodehdl_t plath; char fullfilename[PATH_MAX]; picl_nodehdl_t rooth; /* * Initialize sensorp and other fields in the sensor_nodes[] array */ for (snodep = sensor_nodes; snodep->sensor_name != NULL; snodep++) { snodep->sensorp = sensor_lookup(snodep->sensor_name); snodep->nodeh = NULL; snodep->proph = NULL; snodep->sdev_proph = NULL; } /* * Initialize fanp and other fields in the fan_nodes[] array */ for (fnodep = fan_nodes; fnodep->fan_name != NULL; fnodep++) { fnodep->fanp = fan_lookup(fnodep->fan_name); fnodep->nodeh = NULL; fnodep->proph = NULL; } /* * Get platform handle and populate PICL tree with environmental * nodes and properties */ err = ptree_get_node_by_path("/platform", &plath); if (err == PICL_SUCCESS) { err = add_sensor_nodes_and_props(plath); if (err == PICL_SUCCESS) err = add_fan_nodes_and_props(plath); } if (err != PICL_SUCCESS) { envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); return; } /* * Parse the envmodel.conf file and populate the PICL tree */ if (get_envmodel_conf_file(fullfilename) < 0) envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); if (ptree_get_root(&rooth) != PICL_SUCCESS) envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); err = picld_pluginutil_parse_config_file(rooth, fullfilename); if (err != PICL_SUCCESS) envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); }
/* Hotplug routine used to add a new CPU Mem Module (with associated DIMMs) */ static int add_cpu_module(int slotnum) { picl_nodehdl_t cpumemsloth; picl_nodehdl_t cpumemmodh; picl_nodehdl_t tmph; int i, err; /* Find the node for the given CPU Memory module slot */ if (ptree_get_node_by_path(frutree_cpu_module[slotnum], &cpumemsloth) == PICL_SUCCESS) { i = slotnum + CPUMOD0; /* Make sure it's in /platform and create the frutree nodes */ if (ptree_get_node_by_path(platform_frupath[i], &tmph) == PICL_SUCCESS) { err = ptree_create_node("cpu-mem-module", "fru", &cpumemmodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(cpumemmodh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(cpumemmodh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(cpumemsloth, cpumemmodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, cpumemmodh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); } err = do_cpu_module_init(cpumemmodh, slotnum); if (err != PICL_SUCCESS) return (err); } return (PICL_SUCCESS); }
/* Hotplug routine used to add a new power supply */ static int add_power_supply(int slotnum) { picl_nodehdl_t powersloth; picl_nodehdl_t powermodh; picl_nodehdl_t tmph; int i, err; /* Find the node for the given power supply slot */ if (ptree_get_node_by_path(frutree_power_supply[slotnum], &powersloth) == PICL_SUCCESS) { i = slotnum + PS0; /* Make sure it's in /platform and create the frutree node */ if (ptree_get_node_by_path(platform_frupath[i], &tmph) == PICL_SUCCESS) { err = ptree_create_node("power-supply", "fru", &powermodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(powermodh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(powermodh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(powersloth, powermodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, powermodh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); /* Post picl-fru-added event */ post_frudr_event(PICL_FRU_ADDED, NULL, powermodh); } } return (PICL_SUCCESS); }
/* Initializes the FRU nodes for the memory modules */ static int do_mem_init(picl_nodehdl_t rooth) { picl_nodehdl_t memsloth; picl_nodehdl_t memmodh; picl_nodehdl_t tmph; int i, err, slotnum; for (i = DIMM0; i <= DIMM7; i++) { /* Create the node for the memory slot */ err = ptree_create_node("mem-slot", "location", &memsloth); if (err != PICL_SUCCESS) return (err); slotnum = i - DIMM0; err = add_slot_prop(memsloth, slotnum); if (err != PICL_SUCCESS) return (err); err = add_label_prop(memsloth, location_label[i]); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(rooth, memsloth); if (err != PICL_SUCCESS) return (err); /* If the memory exists, create a node for it */ if (ptree_get_node_by_path(platform_frupath[i], &tmph) == PICL_SUCCESS) { err = ptree_create_node("mem-module", "fru", &memmodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(memmodh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(memmodh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(memsloth, memmodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, memmodh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); } } return (PICL_SUCCESS); }
/* Initializes the FRU nodes for the CPU modules */ static int do_cpus_init(picl_nodehdl_t rooth) { picl_nodehdl_t cpusloth; picl_nodehdl_t cpumodh; picl_nodehdl_t tmph; int i, err; for (i = CPU0; i <= CPU1; i++) { /* Create the node for the CPU slot */ err = ptree_create_node("cpu-slot", "location", &cpusloth); if (err != PICL_SUCCESS) return (err); err = add_slot_prop(cpusloth, i); if (err != PICL_SUCCESS) return (err); err = add_label_prop(cpusloth, location_label[i]); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(rooth, cpusloth); if (err != PICL_SUCCESS) return (err); /* If the CPU module exists, create a node for it */ if (ptree_get_node_by_path(platform_frupath[i], &tmph) == PICL_SUCCESS) { err = ptree_create_node("cpu-module", "fru", &cpumodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(cpumodh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(cpumodh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(cpusloth, cpumodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, cpumodh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); } } return (PICL_SUCCESS); }
/* * This function finds the property/node that corresponds to the given path * and returns its handle */ static void picld_get_node_by_path(picl_service_t *in) { picl_retnodebypath_t ret; int err; ret.cnum = PICL_CNUM_NODEBYPATH; err = ptree_get_node_by_path(in->req_nodebypath.pathbuf, &ret.nodeh); if (err != PICL_SUCCESS) picld_return_error(in->in.cnum, err); cvt_ptree2picl(&ret.nodeh); (void) rw_unlock(&init_lk); (void) door_return((char *)&ret, sizeof (ret), NULL, 0); }
/* Hotplug routine used to remove an existing CPU Mem Module */ static int remove_cpu_module(int slotnum) { picl_nodehdl_t cpumemsloth; picl_nodehdl_t cpumemmodh; int err; /* Find the node for the given CPU Memory module slot */ if (ptree_get_node_by_path(frutree_cpu_module[slotnum], &cpumemsloth) == PICL_SUCCESS) { /* Make sure it's got a child, then delete it */ err = ptree_get_propval_by_name(cpumemsloth, PICL_PROP_CHILD, &cpumemmodh, sizeof (picl_nodehdl_t)); if (err != PICL_SUCCESS) { return (err); } err = remove_all_nodes(cpumemmodh); if (err != PICL_SUCCESS) { return (err); } } return (PICL_SUCCESS); }
static int add_sensor_nodes_and_props(picl_nodehdl_t plath) { int err; char *pname, *nodename, *refnode, *devfs_path; node_list_t *node_list, *listp; sensor_node_t *snodep; sensor_thresh_t *threshp; picl_nodehdl_t nodeh, refnodeh, cnodeh; picl_prophdl_t proph; char unitaddr[UNITADDR_LEN_MAX]; env_sensor_t *sensorp; node_list = get_node_list_by_class(plath, PICL_CLASS_TEMP_DEVICE, NULL); if (node_list == NULL) return (PICL_FAILURE); for (listp = node_list; listp != NULL; listp = listp->next) { /* * Get "reg" property. Skip if no "reg" property found. */ nodeh = listp->nodeh; err = get_unit_address_prop(nodeh, (void *)unitaddr, sizeof (unitaddr)); if (err != PICL_SUCCESS) continue; for (snodep = sensor_nodes; snodep->sensor_name != NULL; snodep++) { /* Match "UnitAddress" property */ if (strcasecmp(unitaddr, snodep->unitaddr) != 0) continue; /* * Skip if already initialized or no sensor info */ sensorp = snodep->sensorp; if (snodep->nodeh != NULL || sensorp == NULL) continue; /* * Create temperature-sensor node */ nodename = snodep->sensor_name; err = ptree_create_and_add_node(nodeh, nodename, PICL_CLASS_TEMP_SENSOR, &cnodeh); if (env_debug) envd_log(LOG_INFO, "Creating PICL sensor node '%s' err:%d\n", nodename, err); if (err != PICL_SUCCESS) break; /* save node handle */ snodep->nodeh = cnodeh; /* * Add "devfs_path" property in child node */ devfs_path = sensorp->devfs_path; pname = PICL_PROP_DEVFS_PATH; err = add_regular_prop(cnodeh, pname, PICL_PTYPE_CHARSTRING, PICL_READ, strlen(devfs_path)+1, (void *)devfs_path, &proph); if (err != PICL_SUCCESS) break; /* * Now add volatile "temperature" volatile property * in this "temperature-sensor" class node. */ pname = PROP_TEMPERATURE; err = add_volatile_prop(cnodeh, pname, PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t), get_current_temp, NULL, &proph); if (err != PICL_SUCCESS) break; /* Save prop handle */ snodep->proph = proph; /* * Add threshold related properties */ threshp = sensorp->temp_thresh; if (threshp != NULL) add_sensor_thresh_props(cnodeh, threshp); /* * Finally create property in the sensed device * (if one specified) */ refnode = snodep->sdev_node; pname = snodep->sdev_pname; if (refnode == NULL || pname == NULL) continue; err = ptree_get_node_by_path(refnode, &refnodeh); if (err == PICL_SUCCESS) { err = add_volatile_prop(refnodeh, pname, PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t), get_current_temp, NULL, &proph); } if (err != PICL_SUCCESS) break; /* Save prop handle */ snodep->sdev_proph = proph; } if (err != PICL_SUCCESS) { delete_sensor_nodes_and_props(); free_node_list(node_list); if (env_debug) envd_log(LOG_INFO, "Can't create prop/node for sensor '%s'\n", nodename); return (err); } } free_node_list(node_list); return (PICL_SUCCESS); }
/* Initializes the FRU nodes for the motherboard and CPU Memory modules */ static int do_motherboard_init(picl_nodehdl_t rooth) { picl_nodehdl_t sysboardh; picl_nodehdl_t cpumemsloth; picl_nodehdl_t cpumemmodh; picl_nodehdl_t tmph; int i, err, slotnum; /* Create the node for the system board (if it exists) */ if (ptree_get_node_by_path(platform_frupath[SYSBRD], &tmph) == PICL_SUCCESS) { err = ptree_create_node("system-board", "fru", &sysboardh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(sysboardh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(sysboardh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(rooth, sysboardh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, sysboardh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); for (i = CPUMOD0; i <= CPUMOD3; i++) { /* Create the node for the CPU Memory slot */ err = ptree_create_node("cpu-mem-slot", "location", &cpumemsloth); if (err != PICL_SUCCESS) return (err); slotnum = i - CPUMOD0; err = add_slot_prop(cpumemsloth, slotnum); if (err != PICL_SUCCESS) return (err); err = add_label_prop(cpumemsloth, location_label[i]); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(sysboardh, cpumemsloth); if (err != PICL_SUCCESS) return (err); /* If CPU Mem module exists, create a node for it */ if (ptree_get_node_by_path(platform_frupath[i], &tmph) == PICL_SUCCESS) { err = ptree_create_node("cpu-mem-module", "fru", &cpumemmodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(cpumemmodh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(cpumemmodh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(cpumemsloth, cpumemmodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, cpumemmodh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); err = do_cpu_module_init(cpumemmodh, slotnum); if (err != PICL_SUCCESS) return (err); } } } return (PICL_SUCCESS); }
/* Initializes the FRU nodes for the FCAL backplanes and GBIC card */ static int do_fcal_init(picl_nodehdl_t rooth) { picl_nodehdl_t fcalsloth; picl_nodehdl_t fcalmodh; picl_nodehdl_t fcalgbich; picl_nodehdl_t tmph; int i, err, slotnum; for (i = FCAL0; i <= FCAL1; i++) { /* Create the node for the FCAL backplane slot */ err = ptree_create_node("fcal-backplane-slot", "location", &fcalsloth); if (err != PICL_SUCCESS) return (err); slotnum = i - FCAL0; err = add_slot_prop(fcalsloth, slotnum); if (err != PICL_SUCCESS) return (err); err = add_label_prop(fcalsloth, location_label[i]); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(rooth, fcalsloth); if (err != PICL_SUCCESS) return (err); /* If the FCAL backplane exists, create a node for it */ if (ptree_get_node_by_path(platform_frupath[i], &tmph) == PICL_SUCCESS) { err = ptree_create_node("fcal-backplane", "fru", &fcalmodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(fcalmodh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(fcalmodh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(fcalsloth, fcalmodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, fcalmodh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); } } /* If the FCAL GBIC board exists, create a node for it */ if (ptree_get_node_by_path(platform_frupath[FCALGBIC], &tmph) == PICL_SUCCESS) { err = ptree_create_node("fcal-gbic-board", "fru", &fcalgbich); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(fcalgbich, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(fcalgbich); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(rooth, fcalgbich); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, fcalgbich, FRU_PARENT); if (err != PICL_SUCCESS) return (err); } return (PICL_SUCCESS); }
/* Initializes the FRU nodes for the PDB and the power supplies */ static int do_power_supplies_init(picl_nodehdl_t rooth) { picl_nodehdl_t powerbrdh; picl_nodehdl_t powersloth; picl_nodehdl_t powermodh; picl_nodehdl_t tmph; int i, err, slotnum; /* Create the node for the PDB (if it exists) */ if (ptree_get_node_by_path(platform_frupath[PDB], &tmph) == PICL_SUCCESS) { err = ptree_create_node("power-dist-board", "fru", &powerbrdh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(powerbrdh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(powerbrdh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(rooth, powerbrdh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, powerbrdh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); for (i = PS0; i <= PS2; i++) { /* Create the node for the power supply slot */ err = ptree_create_node("power-supply-slot", "location", &powersloth); if (err != PICL_SUCCESS) return (err); slotnum = i - PS0; err = add_slot_prop(powersloth, slotnum); if (err != PICL_SUCCESS) return (err); err = add_label_prop(powersloth, location_label[i]); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(powerbrdh, powersloth); if (err != PICL_SUCCESS) return (err); /* If the PS exists, create a node for it */ if (ptree_get_node_by_path(platform_frupath[i], &tmph) == PICL_SUCCESS) { err = ptree_create_node("power-supply", "fru", &powermodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(powermodh, tmph, SEEPROM_SOURCE); if (err != PICL_SUCCESS) return (err); err = add_void_fda_prop(powermodh); if (err != PICL_SUCCESS) return (err); err = ptree_add_node(powersloth, powermodh); if (err != PICL_SUCCESS) return (err); err = add_ref_prop(tmph, powermodh, FRU_PARENT); if (err != PICL_SUCCESS) return (err); } } } return (PICL_SUCCESS); }
/* * update_picl * Called when disk goes off-line or goes to ready status. * In the case of disk ready, locate platform tree node for the disk * and add a target property (if missing). * (The target address is fixed for a given disk slot and is used to * tie the frutree disk-unit to the correct ssd node). * Returns EAGAIN for a retriable failure, otherwise 0. */ static int update_picl(led_dtls_t *dtls, int disk) { static char trailer[] = ",0"; picl_nodehdl_t slotndh; picl_nodehdl_t diskndh; ptree_propinfo_t propinfo; int r; if (dtls->disk_detected[disk] != 0) { picl_nodehdl_t fpndh; picl_nodehdl_t ssdndh; picl_prophdl_t tbl_h; picl_prophdl_t tbl_prop_h; picl_prophdl_t row_props_h[FCAL_DEVTABLE_NCOLS]; char valbuf[80]; char addr[MAXPATHLEN]; char *ptrd; const uchar_t *ptrs; int len; int addr_len; for (;;) { r = ptree_get_node_by_path(dtls->fcal_disk_parent, &fpndh); if (r != PICL_SUCCESS) { return (0); } r = ptree_get_propval_by_name(fpndh, PICL_PROP_CLASSNAME, (void *)valbuf, sizeof (valbuf)); if (r != PICL_SUCCESS) { return (0); } else if (strcmp(valbuf, "fp") == 0) { /* * The node with class fp (if present) is a * holding node representing no actual hardware. * Its presence results in two nodes with the * same effective address. (The fp class node is * UnitAddress 0,0 and the other fp node [class * devctl] has bus-addr 0,0). Locating the * required fp node for dynamic reconfiguration * then goes wrong. So, just remove it. */ SYSLOG(LOG_WARNING, EM_SPURIOUS_FP); r = ptree_delete_node(fpndh); if (r == PICL_SUCCESS) { (void) ptree_destroy_node(fpndh); continue; } return (0); } else { break; } } /* * Got a good parent node. Look at its children for a node * with this new port name. * * generate expected bus-addr property from the port-wwn * Note: dtls->disk_port[disk] points to an array of uchar_t, * the first character contains the length of the residue. * The bus-addr property is formatted as follows: * wabcdef0123456789,0 * where the 16 hex-digits represent 8 bytes from disk_port[]; */ ptrs = dtls->disk_port[disk]; if (ptrs == NULL) return (0); len = *ptrs++; ptrd = addr; *ptrd++ = 'w'; for (r = 0; r < len; r++, ptrd += 2) { (void) snprintf(ptrd, MAXPATHLEN - (ptrd - addr), "%.2x", *ptrs++); } addr_len = 1 + strlcat(addr, trailer, MAXPATHLEN); if (addr_len > MAXPATHLEN) return (0); r = ptree_find_node(fpndh, FCAL_PICL_PROP_BUS_ADDR, PICL_PTYPE_CHARSTRING, addr, addr_len, &ssdndh); /* * If the disk node corresponding to the newly inserted disk * cannot be found in the platform tree, we have probably * got in too early - probably before it's up to speed. In * this case, the WWN gleaned from devinfo may also be wrong. * This case is worth retrying in later polls when it may * succeed, so return EAGAIN. All other failures are probably * terminal, so log a failure and quit. */ if (r == PICL_NODENOTFOUND) return (EAGAIN); if (r != PICL_SUCCESS) { SYSLOG(LOG_ERR, EM_NO_FP_NODE, disk); return (0); } /* * Found platform entry for disk, add target prop */ r = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_INT, PICL_READ, sizeof (int), FCAL_PICL_PROP_TARGET, NULL, NULL); if (r != PICL_SUCCESS) return (0); (void) ptree_create_and_add_prop(ssdndh, &propinfo, &disk, NULL); /* * Remove pre-existing disk-unit node and its * properties - maybe its reference property is * out-of-date. */ delete_disk_unit(dtls, disk); /* * Add a disk-unit node in frutree */ r = find_disk_slot(dtls, disk, &slotndh); if (r != PICL_SUCCESS) return (0); r = ptree_create_and_add_node(slotndh, fcal_disk_unit, PICL_CLASS_FRU, &diskndh); if (r != PICL_SUCCESS) return (0); r = create_Device_table(&tbl_h, &tbl_prop_h); if (r != PICL_SUCCESS) return (0); r = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_CHARSTRING, PICL_READ, sizeof (PICL_CLASS_BLOCK), PICL_PROP_CLASS, NULL, NULL); if (r != PICL_SUCCESS) return (0); r = ptree_create_prop(&propinfo, PICL_CLASS_BLOCK, &row_props_h[0]); if (r != PICL_SUCCESS) return (0); r = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_REFERENCE, PICL_READ, sizeof (picl_prophdl_t), FCAL_PICL_BLOCK_REF, NULL, NULL); if (r != PICL_SUCCESS) return (0); r = ptree_create_prop(&propinfo, &ssdndh, &row_props_h[1]); if (r != PICL_SUCCESS) return (0); r = ptree_add_row_to_table(tbl_h, FCAL_DEVTABLE_NCOLS, row_props_h); if (r != PICL_SUCCESS) return (0); (void) ptree_add_prop(diskndh, tbl_prop_h); } else { /* * disk gone, remove disk_unit fru from frutree */ delete_disk_unit(dtls, disk); } return (0); }
void psvc_psr_plugin_init(void) { char *funcname = "psvc_plugin_psr_init"; int32_t i; int err; boolean_t present; /* * So the volatile read/write routines can retrieve data from * psvc or picl */ err = psvc_init(&hdlp); if (err != 0) { init_err(PSVC_INIT_ERR, funcname, strerror(errno)); } /* * Remove nodes whose devices aren't present from the picl tree. */ for (i = 0; i < psvc_hdl.obj_count; ++i) { picl_psvc_t *objp; uint64_t features; objp = &psvc_hdl.objects[i]; err = psvc_get_attr(hdlp, objp->name, PSVC_PRESENCE_ATTR, &present); if (err != PSVC_SUCCESS) continue; err = psvc_get_attr(hdlp, objp->name, PSVC_FEATURES_ATTR, &features); if (err != PSVC_SUCCESS) continue; if ((features & (PSVC_DEV_HOTPLUG | PSVC_DEV_OPTION)) && (present == PSVC_ABSENT)) { err = ptree_delete_node(objp->node); if (err != 0) { init_err(PTREE_DELETE_NODE_ERR, funcname, picl_strerror(err)); return; } } } /* * Remove PICL device nodes if their /devices file isn't present or * if the device file is present but the open returns ENXIO * which indicates that the node file doesn't represent a device * tree node and is probably a relic from some previous boot config */ for (i = 0; i < DEV_PR_COUNT; ++i) { picl_nodehdl_t dev_pr_node; int fd; fd = open(dev_pr_info[i].file, O_RDONLY); if (fd != -1) { close(fd); continue; } if ((errno != ENOENT) && (errno != ENXIO)) continue; err = ptree_get_node_by_path(dev_pr_info[i].path, &dev_pr_node); if (err != 0) { syslog(LOG_ERR, "Bad path: %s", dev_pr_info[i].path); init_err(PTREE_GET_NODE_ERR, funcname, picl_strerror(err)); return; } err = ptree_delete_node(dev_pr_node); if (err != 0) { init_err(PTREE_DELETE_NODE_ERR, funcname, picl_strerror(err)); return; } } free(psvc_hdl.objects); }
/* * this routine does the following: * 1. initializes the CPU geo-addr * 2. gets the system name * 3. create the chassis type property * 4. creates the conf_file property */ static picl_errno_t env_set_cpu_info() { int rc = 0; sc_reqmsg_t req_pkt; sc_rspmsg_t rsp_pkt; uint8_t size = 0; char conf_name[PICL_PROPNAMELEN_MAX]; /* get the geo_addr */ /* initialize the request packet */ (void) smc_init_smc_msg(&req_pkt, SMC_GET_GEOGRAPHICAL_ADDRESS, DEFAULT_SEQN, size); /* make a call to smc library to send cmd */ if (smc_send_msg(DEFAULT_FD, &req_pkt, &rsp_pkt, POLL_TIMEOUT) != SMC_SUCCESS) { return (PICL_FAILURE); } cpu_geo_addr = rsp_pkt.data[0]; /* get the system name */ if (sysinfo(SI_PLATFORM, sys_name, sizeof (sys_name)) == -1) { return (PICL_FAILURE); } (void) strncpy(chassisconf_name, sys_name, sizeof (chassisconf_name)); /* initialize the node handles */ if ((rc = ptree_get_root(&rooth)) != PICL_SUCCESS) { return (rc); } if ((rc = ptree_get_node_by_path(FRUTREE_PATH, &frutreeh)) != PICL_SUCCESS) { return (rc); } if ((rc = ptree_get_node_by_path(PICL_FRUTREE_CHASSIS, &chassis_nodehdl)) != PICL_SUCCESS) { return (rc); } /* create the chassis type property */ if ((rc = env_create_property(PICL_PTYPE_CHARSTRING, PICL_READ, PICL_PROPNAMELEN_MAX, PICL_PROP_CHASSIS_TYPE, NULLREAD, NULLWRITE, chassis_nodehdl, (picl_prophdl_t *)NULL, chassisconf_name)) != PICL_SUCCESS) { return (rc); } /* * create dummy prop to inform frutree plugin abt conf file * (rtm based or w/o rtm) * frutree plugin removes this prop after reading the value */ if (is_rtm_present() == B_TRUE) { (void) snprintf(conf_name, sizeof (conf_name), "%s.RTM.conf", chassisconf_name); } else { (void) snprintf(conf_name, sizeof (conf_name), "%s.conf", chassisconf_name); } if ((rc = env_create_property(PICL_PTYPE_CHARSTRING, PICL_READ, PICL_PROPNAMELEN_MAX, PICL_PROP_CONF_FILE, NULLREAD, NULLWRITE, chassis_nodehdl, (picl_prophdl_t *)NULL, conf_name)) != PICL_SUCCESS) { return (rc); } return (PICL_SUCCESS); }