Changeset b50b5af2 in mainline for kernel/genarch/src/ofw/ofw_tree.c


Ignore:
Timestamp:
2009-08-22T10:48:00Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
04803bf
Parents:
1ea99cc (diff), a71c158 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/ofw/ofw_tree.c

    r1ea99cc rb50b5af2  
    3232/**
    3333 * @file
    34  * @brief       OpenFirmware device tree navigation.
     34 * @brief OpenFirmware device tree navigation.
    3535 *
    3636 */
     
    4040#include <mm/slab.h>
    4141#include <string.h>
     42#include <panic.h>
    4243#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
    4747
    4848static ofw_tree_node_t *ofw_root;
     
    5555/** Get OpenFirmware node property.
    5656 *
    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 */
     64ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node,
     65    const char *name)
    6566{
    6667        unsigned int i;
     
    7071                        return &node->property[i];
    7172        }
    72 
     73       
    7374        return NULL;
    7475}
     
    7677/** Return value of the 'name' property.
    7778 *
    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 *
    8184 */
    8285const char *ofw_tree_node_name(const ofw_tree_node_t *node)
    8386{
    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;
    9290       
    9391        return prop->value;
     
    9694/** Lookup child of given name.
    9795 *
    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 */
     103ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node,
     104    const char *name)
    105105{
    106106        ofw_tree_node_t *cur;
     
    125125                        return cur;
    126126        }
    127                
     127       
    128128        return NULL;
    129129}
     
    131131/** Lookup first child of given device type.
    132132 *
    133  * @param node          Node whose child is being looked up.
    134  * @param name          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 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 */
     140ofw_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;
    144144       
    145145        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))
    148150                        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       
    153156        return NULL;
    154157}
     
    159162 * are looked up iteratively to avoid stack overflow.
    160163 *
    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 */
     171ofw_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) {
    173177                if (cur->node_handle == handle)
    174178                        return cur;
    175 
     179               
    176180                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);
    180183                        if (node)
    181184                                return node;
     
    183186        }
    184187       
    185         return NULL;   
     188        return NULL;
    186189}
    187190
    188191/** Lookup first peer of given device type.
    189192 *
    190  * @param node          Node whose peer is being looked up.
    191  * @param name          Device type of the child being looked up.
    192  *
    193  * @return              NULL if there is no such child or pointer to the
    194  *                      matching child node.
    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 */
     200ofw_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;
    201204       
    202205        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))
    205210                        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 */
     228ofw_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               
    206240                if (str_cmp(prop->value, name) == 0)
    207241                        return cur;
    208242        }
    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       
    236244        return NULL;
    237245}
     
    239247/** Lookup OpenFirmware node by its path.
    240248 *
    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 *
    245254 */
    246255ofw_tree_node_t *ofw_tree_lookup(const char *path)
    247256{
    248         char buf[NAME_BUF_LEN + 1];
     257        if (path[0] != '/')
     258                return NULL;
     259       
    249260        ofw_tree_node_t *node = ofw_root;
    250261        size_t i;
    251262        size_t j;
    252263       
    253         if (path[0] != '/')
    254                 return NULL;
    255        
    256264        for (i = 1; (i < str_size(path)) && (node); i = j + 1) {
    257265                for (j = i; (j < str_size(path)) && (path[j] != '/'); j++);
     
    261269                        continue;
    262270               
     271                char buf[NAME_BUF_LEN + 1];
    263272                memcpy(buf, &path[i], j - i);
    264273                buf[j - i] = 0;
     
    269278}
    270279
    271 /** Print OpenFirmware device subtree rooted in a node.
     280/** Walk the OpenFirmware device subtree rooted in a node.
    272281 *
    273282 * Child nodes are processed recursively and peer nodes are processed
    274283 * iteratively in order to avoid stack overflow.
    275284 *
    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 */
     293static 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       
    286298        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 */
     330void 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 */
     345static 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);
    290354                } else {
    291                         snprintf(p, PATH_MAX_LEN, "%s", cur->da_name);
     355                        snprintf(cur_path, PATH_MAX_LEN, "%s", cur->da_name);
    292356                        printf("/\n");
    293357                }
    294 
     358               
    295359                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);
    300364}
    301365
Note: See TracChangeset for help on using the changeset viewer.