Changeset e731b0d in mainline for kernel/genarch/src/ofw/ofw_tree.c
- Timestamp:
- 2009-08-20T16:58:55Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b9c7425
- Parents:
- a11099f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/ofw/ofw_tree.c
ra11099f re731b0d 32 32 /** 33 33 * @file 34 * @brief 34 * @brief OpenFirmware device tree navigation. 35 35 * 36 36 */ … … 40 40 #include <mm/slab.h> 41 41 #include <string.h> 42 #include <panic.h> 42 43 #include <print.h> 43 #include <panic.h> 44 45 #define PATH_MAX_LEN 80 46 #define NAME_BUF_LEN 50 44 45 #define PATH_MAX_LEN 256 46 #define NAME_BUF_LEN 50 47 47 48 48 static ofw_tree_node_t *ofw_root; … … 55 55 /** Get OpenFirmware node property. 56 56 * 57 * @param node Node in which to lookup the property. 58 * @param name Name of the property. 59 * 60 * @return Pointer to the property structure or NULL if no such 61 * property. 62 */ 63 ofw_tree_property_t * 64 ofw_tree_getprop(const ofw_tree_node_t *node, const char *name) 57 * @param node Node in which to lookup the property. 58 * @param name Name of the property. 59 * 60 * @return Pointer to the property structure or NULL if no such 61 * property. 62 * 63 */ 64 ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, 65 const char *name) 65 66 { 66 67 unsigned int i; … … 70 71 return &node->property[i]; 71 72 } 72 73 73 74 return NULL; 74 75 } … … 76 77 /** Return value of the 'name' property. 77 78 * 78 * @param node Node of interest. 79 * 80 * @return Value of the 'name' property belonging to the node. 79 * @param node Node of interest. 80 * 81 * @return Value of the 'name' property belonging to the node 82 * or NULL if the property is invalid. 83 * 81 84 */ 82 85 const char *ofw_tree_node_name(const ofw_tree_node_t *node) 83 86 { 84 ofw_tree_property_t *prop; 85 86 prop = ofw_tree_getprop(node, "name"); 87 if (!prop) 88 panic("Node without name property."); 89 90 if (prop->size < 2) 91 panic("Invalid name property."); 87 ofw_tree_property_t *prop = ofw_tree_getprop(node, "name"); 88 if ((!prop) || (prop->size < 2)) 89 return NULL; 92 90 93 91 return prop->value; … … 96 94 /** Lookup child of given name. 97 95 * 98 * @param node Node whose child is being looked up. 99 * @param name Name of the child being looked up. 100 * 101 * @return NULL if there is no such child or pointer to the 102 * matching child node. 103 */ 104 ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name) 96 * @param node Node whose child is being looked up. 97 * @param name Name of the child being looked up. 98 * 99 * @return NULL if there is no such child or pointer to the 100 * matching child node. 101 * 102 */ 103 ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, 104 const char *name) 105 105 { 106 106 ofw_tree_node_t *cur; … … 125 125 return cur; 126 126 } 127 127 128 128 return NULL; 129 129 } … … 131 131 /** Lookup first child of given device type. 132 132 * 133 * @param node 134 * @param nameDevice type of the child being looked up.135 * 136 * @return 137 * 138 * /139 ofw_tree_node_t * 140 ofw_tree_ find_child_by_device_type(ofw_tree_node_t *node, const char *name)141 { 142 ofw_tree_node_t *cur; 143 ofw_tree_ property_t *prop;133 * @param node Node whose child is being looked up. 134 * @param dtype Device type of the child being looked up. 135 * 136 * @return NULL if there is no such child or pointer to the 137 * matching child node. 138 * 139 */ 140 ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, 141 const char *dtype) 142 { 143 ofw_tree_node_t *cur; 144 144 145 145 for (cur = node->child; cur; cur = cur->peer) { 146 prop = ofw_tree_getprop(cur, "device_type"); 147 if (!prop || !prop->value) 146 ofw_tree_property_t *prop = 147 ofw_tree_getprop(cur, "device_type"); 148 149 if ((!prop) || (!prop->value)) 148 150 continue; 149 if (str_cmp(prop->value, name) == 0) 150 return cur; 151 } 152 151 152 if (str_cmp(prop->value, dtype) == 0) 153 return cur; 154 } 155 153 156 return NULL; 154 157 } … … 159 162 * are looked up iteratively to avoid stack overflow. 160 163 * 161 * @param root Root of the searched subtree. 162 * @param handle OpenFirmware handle. 163 * 164 * @return NULL if there is no such node or pointer to the matching 165 * node. 166 */ 167 ofw_tree_node_t * 168 ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle) 169 { 170 ofw_tree_node_t *cur; 171 172 for (cur = root; cur; cur = cur->peer) { 164 * @param root Root of the searched subtree. 165 * @param handle OpenFirmware handle. 166 * 167 * @return NULL if there is no such node or pointer to the matching 168 * node. 169 * 170 */ 171 ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, 172 uint32_t handle) 173 { 174 ofw_tree_node_t *cur; 175 176 for (cur = root; cur; cur = cur->peer) { 173 177 if (cur->node_handle == handle) 174 178 return cur; 175 179 176 180 if (cur->child) { 177 ofw_tree_node_t *node; 178 179 node = ofw_tree_find_node_by_handle(cur->child, handle); 181 ofw_tree_node_t *node 182 = ofw_tree_find_node_by_handle(cur->child, handle); 180 183 if (node) 181 184 return node; … … 183 186 } 184 187 185 return NULL; 188 return NULL; 186 189 } 187 190 188 191 /** Lookup first peer of given device type. 189 192 * 190 * @param node 191 * @param nameDevice type of the child being looked up.192 * 193 * @return 194 * 195 * /196 ofw_tree_node_t * 197 ofw_tree_ find_peer_by_device_type(ofw_tree_node_t *node, const char *name)198 { 199 ofw_tree_node_t *cur; 200 ofw_tree_ property_t *prop;193 * @param node Node whose peer is being looked up. 194 * @param dtype Device type of the child being looked up. 195 * 196 * @return NULL if there is no such child or pointer to the 197 * matching child node. 198 * 199 */ 200 ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, 201 const char *dtype) 202 { 203 ofw_tree_node_t *cur; 201 204 202 205 for (cur = node->peer; cur; cur = cur->peer) { 203 prop = ofw_tree_getprop(cur, "device_type"); 204 if (!prop || !prop->value) 206 ofw_tree_property_t *prop = 207 ofw_tree_getprop(cur, "device_type"); 208 209 if ((!prop) || (!prop->value)) 205 210 continue; 211 212 if (str_cmp(prop->value, dtype) == 0) 213 return cur; 214 } 215 216 return NULL; 217 } 218 219 /** Lookup first peer of given name. 220 * 221 * @param node Node whose peer is being looked up. 222 * @param name Name of the child being looked up. 223 * 224 * @return NULL if there is no such peer or pointer to the matching 225 * peer node. 226 * 227 */ 228 ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node, 229 const char *name) 230 { 231 ofw_tree_node_t *cur; 232 233 for (cur = node->peer; cur; cur = cur->peer) { 234 ofw_tree_property_t *prop 235 = ofw_tree_getprop(cur, "name"); 236 237 if ((!prop) || (!prop->value)) 238 continue; 239 206 240 if (str_cmp(prop->value, name) == 0) 207 241 return cur; 208 242 } 209 210 return NULL; 211 } 212 213 214 /** Lookup first peer of given name. 215 * 216 * @param node Node whose peer is being looked up. 217 * @param name Name of the child being looked up. 218 * 219 * @return NULL if there is no such peer or pointer to the matching 220 * peer node. 221 */ 222 ofw_tree_node_t * 223 ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name) 224 { 225 ofw_tree_node_t *cur; 226 ofw_tree_property_t *prop; 227 228 for (cur = node->peer; cur; cur = cur->peer) { 229 prop = ofw_tree_getprop(cur, "name"); 230 if (!prop || !prop->value) 231 continue; 232 if (str_cmp(prop->value, name) == 0) 233 return cur; 234 } 235 243 236 244 return NULL; 237 245 } … … 239 247 /** Lookup OpenFirmware node by its path. 240 248 * 241 * @param path Path to the node. 242 * 243 * @return NULL if there is no such node or pointer to the leaf 244 * node. 249 * @param path Path to the node. 250 * 251 * @return NULL if there is no such node or pointer to the leaf 252 * node. 253 * 245 254 */ 246 255 ofw_tree_node_t *ofw_tree_lookup(const char *path) 247 256 { 248 char buf[NAME_BUF_LEN + 1]; 257 if (path[0] != '/') 258 return NULL; 259 249 260 ofw_tree_node_t *node = ofw_root; 250 261 size_t i; 251 262 size_t j; 252 263 253 if (path[0] != '/')254 return NULL;255 256 264 for (i = 1; (i < str_size(path)) && (node); i = j + 1) { 257 265 for (j = i; (j < str_size(path)) && (path[j] != '/'); j++); … … 261 269 continue; 262 270 271 char buf[NAME_BUF_LEN + 1]; 263 272 memcpy(buf, &path[i], j - i); 264 273 buf[j - i] = 0; … … 269 278 } 270 279 271 /** PrintOpenFirmware device subtree rooted in a node.280 /** Walk the OpenFirmware device subtree rooted in a node. 272 281 * 273 282 * Child nodes are processed recursively and peer nodes are processed 274 283 * iteratively in order to avoid stack overflow. 275 284 * 276 * @param node Root of the subtree. 277 * @param path Current path, NULL for the very root of the entire tree. 278 */ 279 static void ofw_tree_node_print(const ofw_tree_node_t *node, const char *path) 280 { 281 char *p; 282 const ofw_tree_node_t *cur; 283 284 p = (char *) malloc(PATH_MAX_LEN, 0); 285 285 * @param node Root of the subtree. 286 * @param dtype Device type to look for. 287 * @param walker Routine to be invoked on found device. 288 * @param arg User argument to the walker. 289 * 290 * @return True if the walk should continue. 291 * 292 */ 293 static bool ofw_tree_walk_by_device_type_internal(ofw_tree_node_t *node, 294 const char *dtype, ofw_tree_walker_t walker, void *arg) 295 { 296 ofw_tree_node_t *cur; 297 286 298 for (cur = node; cur; cur = cur->peer) { 287 if (cur->parent) { 288 snprintf(p, PATH_MAX_LEN, "%s/%s", path, cur->da_name); 289 printf("%s\n", p); 299 ofw_tree_property_t *prop = 300 ofw_tree_getprop(cur, "device_type"); 301 302 if ((prop) && (prop->value) && (str_cmp(prop->value, dtype) == 0)) { 303 bool ret = walker(cur, arg); 304 if (!ret) 305 return false; 306 } 307 308 if (cur->child) { 309 bool ret = 310 ofw_tree_walk_by_device_type_internal(cur->child, dtype, walker, arg); 311 if (!ret) 312 return false; 313 } 314 } 315 316 return true; 317 } 318 319 /** Walk the OpenFirmware device tree and find devices by type. 320 * 321 * Walk the whole OpenFirmware device tree and if any node has 322 * the property "device_type" equal to dtype, run a walker on it. 323 * If the walker returns false, the walk does not continue. 324 * 325 * @param dtype Device type to look for. 326 * @param walker Routine to be invoked on found device. 327 * @param arg User argument to the walker. 328 * 329 */ 330 void ofw_tree_walk_by_device_type(const char *dtype, ofw_tree_walker_t walker, 331 void *arg) 332 { 333 (void) ofw_tree_walk_by_device_type_internal(ofw_root, dtype, walker, arg); 334 } 335 336 /** Print OpenFirmware device subtree rooted in a node. 337 * 338 * Child nodes are processed recursively and peer nodes are processed 339 * iteratively in order to avoid stack overflow. 340 * 341 * @param node Root of the subtree. 342 * @param path Current path, NULL for the very root of the entire tree. 343 * 344 */ 345 static void ofw_tree_node_print(ofw_tree_node_t *node, const char *path) 346 { 347 char *cur_path = (char *) malloc(PATH_MAX_LEN, 0); 348 ofw_tree_node_t *cur; 349 350 for (cur = node; cur; cur = cur->peer) { 351 if ((cur->parent) && (path)) { 352 snprintf(cur_path, PATH_MAX_LEN, "%s/%s", path, cur->da_name); 353 printf("%s\n", cur_path); 290 354 } else { 291 snprintf( p, PATH_MAX_LEN, "%s", cur->da_name);355 snprintf(cur_path, PATH_MAX_LEN, "%s", cur->da_name); 292 356 printf("/\n"); 293 357 } 294 358 295 359 if (cur->child) 296 ofw_tree_node_print(cur->child, p);297 } 298 299 free( p);360 ofw_tree_node_print(cur->child, cur_path); 361 } 362 363 free(cur_path); 300 364 } 301 365
Note:
See TracChangeset
for help on using the changeset viewer.