Changeset b63a7cc in mainline
- Timestamp:
- 2006-11-06T20:19:56Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2f8f480
- Parents:
- 1b43a04
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/genarch/ofw_tree.c
r1b43a04 rb63a7cc 70 70 * Transfer entire information from the OpenFirmware device tree 'current' node to 71 71 * its memory representation in 'current_node'. This function recursively processes 72 * all node's peers and children. 72 * all node's children. Node's peers are processed iteratively in order to prevent 73 * stack from overflowing. 73 74 * 74 75 * @param current_node Pointer to uninitialized ofw_tree_node structure that will … … 84 85 phandle peer; 85 86 phandle child; 86 unsigned properties = 0;87 87 size_t len; 88 88 int i; 89 89 90 /* 91 * Initialize node. 92 */ 93 current_node->parent = parent_node; 94 current_node->peer = NULL; 95 current_node->child = NULL; 96 current_node->node_handle = current; 97 current_node->properties = 0; 98 current_node->property = NULL; 99 current_node->device = NULL; 100 101 /* 102 * Get the disambigued name. 103 */ 104 len = ofw_package_to_path(current, path, MAX_PATH_LEN); 105 if (len == -1) 106 return; 107 108 path[len] = '\0'; 109 for (i = len - 1; i >= 0 && path[i] != '/'; i--) 110 ; 111 i++; /* do not include '/' */ 112 113 len -= i; 114 current_node->da_name = ofw_tree_space_alloc(len + 1); /* add space for trailing '\0' */ 115 if (!current_node->da_name) 116 return; 117 118 memcpy(current_node->da_name, &path[i], len); 119 current_node->da_name[len] = '\0'; 120 121 /* 122 * Recursively process the potential peer node. 123 */ 124 peer = ofw_get_peer_node(current); 125 if (peer != 0 && peer != -1) { 126 ofw_tree_node_t *peer_node; 127 128 peer_node = ofw_tree_node_alloc(); 129 if (peer_node) { 130 ofw_tree_node_process(peer_node, parent_node, peer); 131 current_node->peer = peer_node; 90 while (current_node) { 91 /* 92 * Initialize node. 93 */ 94 current_node->parent = parent_node; 95 current_node->peer = NULL; 96 current_node->child = NULL; 97 current_node->node_handle = current; 98 current_node->properties = 0; 99 current_node->property = NULL; 100 current_node->device = NULL; 101 102 /* 103 * Get the disambigued name. 104 */ 105 len = ofw_package_to_path(current, path, MAX_PATH_LEN); 106 if (len == -1) 107 return; 108 109 path[len] = '\0'; 110 for (i = len - 1; i >= 0 && path[i] != '/'; i--) 111 ; 112 i++; /* do not include '/' */ 113 114 len -= i; 115 116 /* add space for trailing '\0' */ 117 current_node->da_name = ofw_tree_space_alloc(len + 1); 118 if (!current_node->da_name) 119 return; 120 121 memcpy(current_node->da_name, &path[i], len); 122 current_node->da_name[len] = '\0'; 123 124 125 /* 126 * Recursively process the potential child node. 127 */ 128 child = ofw_get_child_node(current); 129 if (child != 0 && child != -1) { 130 ofw_tree_node_t *child_node; 131 132 child_node = ofw_tree_node_alloc(); 133 if (child_node) { 134 ofw_tree_node_process(child_node, current_node, child); 135 current_node->child = child_node; 136 } 132 137 } 138 139 /* 140 * Count properties. 141 */ 142 name[0] = '\0'; 143 while (ofw_next_property(current, name, name) == 1) 144 current_node->properties++; 145 146 if (!current_node->properties) 147 return; 148 149 /* 150 * Copy properties. 151 */ 152 current_node->property = ofw_tree_properties_alloc(current_node->properties); 153 if (!current_node->property) 154 return; 155 156 name[0] = '\0'; 157 for (i = 0; ofw_next_property(current, name, name) == 1; i++) { 158 size_t size; 159 160 if (i == current_node->properties) 161 break; 162 163 memcpy(current_node->property[i].name, name, 164 OFW_TREE_PROPERTY_MAX_NAMELEN); 165 current_node->property[i].name[OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0'; 166 167 size = ofw_get_proplen(current, name); 168 current_node->property[i].size = size; 169 if (size) { 170 void *buf; 171 172 buf = ofw_tree_space_alloc(size); 173 if (current_node->property[i].value = buf) { 174 /* 175 * Copy property value to memory node. 176 */ 177 (void) ofw_get_property(current, name, buf, size); 178 } 179 } else { 180 current_node->property[i].value = NULL; 181 } 182 } 183 184 current_node->properties = i; /* Just in case we ran out of memory. */ 185 186 /* 187 * Iteratively process the next peer node. 188 * Note that recursion is a bad idea here. 189 * Due to the topology of the OpenFirmware device tree, 190 * the nesting of peer nodes could be to wide and the 191 * risk of overflowing the stack is too real. 192 */ 193 peer = ofw_get_peer_node(current); 194 if (peer != 0 && peer != -1) { 195 ofw_tree_node_t *peer_node; 196 197 peer_node = ofw_tree_node_alloc(); 198 if (peer_node) { 199 current_node->peer = peer_node; 200 current_node = peer_node; 201 current = peer; 202 /* 203 * Process the peer in next iteration. 204 */ 205 continue; 206 } 207 } 208 /* 209 * No more peers on this level. 210 */ 211 break; 133 212 } 134 135 /*136 * Recursively process the potential child node.137 */138 child = ofw_get_child_node(current);139 if (child != 0 && child != -1) {140 ofw_tree_node_t *child_node;141 142 child_node = ofw_tree_node_alloc();143 if (child_node) {144 ofw_tree_node_process(child_node, current_node, child);145 current_node->child = child_node;146 }147 }148 149 /*150 * Count properties.151 */152 name[0] = '\0';153 while (ofw_next_property(current, name, name) == 1)154 current_node->properties++;155 156 if (!current_node->properties)157 return;158 159 /*160 * Copy properties.161 */162 current_node->property = ofw_tree_properties_alloc(current_node->properties);163 if (!current_node->property)164 return;165 166 name[0] = '\0';167 for (i = 0; ofw_next_property(current, name, name) == 1; i++) {168 size_t size;169 170 if (i == current_node->properties)171 break;172 173 memcpy(current_node->property[i].name, name, OFW_TREE_PROPERTY_MAX_NAMELEN);174 current_node->property[i].name[OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0';175 176 size = ofw_get_proplen(current, name);177 current_node->property[i].size = size;178 if (size) {179 void *buf;180 181 buf = ofw_tree_space_alloc(size);182 if (current_node->property[i].value = buf) {183 /*184 * Copy property value to memory node.185 */186 (void) ofw_get_property(current, name, buf, size);187 }188 } else {189 current_node->property[i].value = NULL;190 }191 }192 193 current_node->properties = i; /* Just in case we ran out of memory. */194 213 } 195 214
Note:
See TracChangeset
for help on using the changeset viewer.