2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * Walk the LDOM PRI component nodes and create appropriate topology nodes 2N/A * Allow for custom topo node creation routines based on topo-hc-name. 2N/A * List of custom enumerators for PRI nodes that require them. The most 2N/A * common nodes are listed first. 2N/A/* List of methods that will be registered in the nodes. */ 2N/A * In order to create a topology node from a PRI MDE node we need to know the 2N/A * topology parent node that should be used. So, after creating a topology 2N/A * node from an MDE node, we associate children of the MDE node with the new 2N/A * topology node. Thus, when the children are visited we can know the 2N/A * appropriate parent topology node to use. 2N/A * We take advantage of the libtopo threading model here, which guarantees a 2N/A * single thread and a single invocation at a time for an enumerator. This 2N/A * makes using a file-global safe. 2N/A/* The routine called for each node in the PRI while walking the graph */ 2N/A * Create a sub-range for a given PRI node and associate the given topology 2N/A * node with the children. 2N/A/* Routines to handle the list of topology parents and mde_nodes */ 2N/A /* Add the builtin functions to the list */ 2N/A /* Add the builtin methods to the list */ 2N/A * Begin to walk the machine description array starting at the given PRI node. 2N/A * Create a list to store topology nodes and their associated machine 2N/A * description index. This allows the code to know the parent of a 2N/A * node when creating topology entries. 2N/A /* Create a walker node for the parent of the start node */ 2N/A * This is a top-level node. Make sure we call the top level 2N/A * enumerator if there is not already a custom enumerator registered. 2N/A * There is no enumerator function registered for this 2N/A * hc name. Automatically register the top level node 2N/A * enumerator function. 2N/A "walker could not register enumerator for type " 2N/A "walker registered pi_enum_top enumerator for type %s\n",
2N/A /* Walk the machine description list starting at the given node */ 2N/A /* Successful completion */ 2N/A * Store that we have a partial enumeration and return 2N/A * that we have encountered an error. 2N/A * This should not happen. We want to always produce 2N/A * as complete a topology as possible, even in the face 2N/A * of errors, however, so set an error and continue. 2N/A "walker encountered invalid result: %d. " 2N/A /* Destroy the walker list, which is no longer necessary */ 2N/A * Visited once for each node in the machine description. Creates a topo 2N/A * node for the machine description node and associates it with it's parent, 2N/A * by calling an appropriate creation routine for the node type. 2N/A * This routine returns MDE_WALK_NEXT, MDE_WALK_DONE or MDE_WALK_ERROR 2N/A /* Make sure we have our private data */ 2N/A "walker processing node_0x%llx parent node 0x%llx\n",
2N/A /* Should we skip this node ? */ 2N/A /* Skip this node and continue to the next node */ 2N/A * No ID available to place this mde node in the topology so 2N/A * we cannot create a topology node. 2N/A * Find the parent topo node for this machine description node. 2N/A * If found, the element will also be removed from the list and the 2N/A * memory used to keep track of it released. We will only visit an 2N/A * MDE node once and so the memory is no longer needed. 2N/A * No parent was found or a NULL parent encountered. We 2N/A * cannot create a new topology node without a parent ( 2N/A * even for top level nodes). We associate children of 2N/A * this MDE node with a NULL parent to silently skip the 2N/A * remainder of this MDE branch. 2N/A * We have the mde node instance and parent information. 2N/A * Attempt to create a topology node for this mde node. 2N/A * We have failed to create a new topology node based on 2N/A * the current MDE node. We set partial enumeration and 2N/A * return without associating the children of this MDE 2N/A * node with a topology parent. This will propgate the 2N/A * creation error down this MDE branch. 2N/A * Associate the new topology node with any children of this mde node. 2N/A * A parent topology node is required even for top-level 2N/A * Find the topo-hc-name for this node which is used to find 2N/A * the specific creation function 2N/A /* Cannot get the hc-name */ 2N/A /* Determine the topology node creation routine to use */ 2N/A * A function is registered for this node. Convert the 2N/A * address to a pointer to function 2N/A * Create a topology node for this mde node by calling the identified 2N/A * enumeration function 2N/A "failed to create topo entry for node_0x%llx type %s\n",
2N/A * Need to check if we need enumerate internal expander 2N/A * attached bays. Since there is no MDE(PRI record) for 2N/A * an internal expander we are invoking the ses enumerator 2N/A * here. It will check if there is any internal enclosure 2N/A * and enumerate expander attached disks. 2N/A * Note that those nodes will be enumerated as a child of 2N/A * min and max instance is handled by 2N/A * the ses enumerator. 2N/A "enumerate expander attached " 2N/A "internal bays. Continue on.");
2N/A * Scan the children of a given MDE node and find all the sets of topo-hc-name 2N/A * types and their instance ranges. From this information we create topology 2N/A * node ranges on the given parent so that when the children are visited and a 2N/A * topology node is created, the range exists and the creation will succeed. 2N/A "walker failed to create node range with a NULL parent\n");
2N/A /* Determine how many children the given node has */ 2N/A /* This node has no children */ 2N/A /* Get the indexes for all the child nodes and put them in an array */ 2N/A * The children of the given node may have multiple types. 2N/A * Potentially, each child may have a different type and we need to 2N/A * create a topo node range for each one. 2N/A * We loop through the children and collect the type information for 2N/A * each one and associate the child with the given parent topo node. 2N/A /* Should this node be skipped? */ 2N/A /* Skip this node */ 2N/A /* Get the type of this node */ 2N/A /* Increment the count of nodes with this type */ 2N/A * We have not visited this type yet. Create 2N/A * a new range based on this nodes instance 2N/A * This error can only if there was a 2N/A * memory failure of some kind. Stop 2N/A * the walk or it will just get worse. 2N/A * We know the list exists now or the above 2N/A * would have failed. Just look it up. 2N/A /* Re-calculate the range minimums and maximums */ 2N/A * Associate this node with the given topo parent even if it 2N/A * has no instance. We do this so that later an error with 2N/A * the PRI node will be reported instead of an internal 2N/A * error about not being able to find the parent of a node 2N/A "could not add node_0x%llx to walker list\n",
2N/A * We have associated all the child nodes with the given topo parent 2N/A * in the walker list. Now we need to create topo ranges for each 2N/A * set of child types under the parent. 2N/A /* Get the type name and count from the list element */ 2N/A * We have the number of children with this type. 2N/A * Create an appropriate range. 2N/A "creating instance range %d to %d of type %s\n",
2N/A "failed to created node range %d to %d for " 2N/A /* Check the next node */ 2N/A /* Create min and max elements in this list */ 2N/A /* Initialize the uutil list structure */ 2N/A /* Destroy our list of items */ 2N/A * First, we empty the list of elements and free each one. 2N/A * We do not free the data elements as they are libtopo nodes 2N/A * and will be freed by libtopo 2N/A * Find the parent topo node for this machine description node. 2N/A * Nodes are removed from the list as they are found. They are only 2N/A * visited once and this eliminates the need for a separate routine 2N/A * that walks the list to free elements later. 2N/A /* Remove this element from the list */