linux/arch/sparc/prom/tree_64.c
<<
>>
Prefs
   1/*
   2 * tree.c: Basic device tree traversal/scanning for the Linux
   3 *         prom library.
   4 *
   5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
   6 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
   7 */
   8
   9#include <linux/string.h>
  10#include <linux/types.h>
  11#include <linux/kernel.h>
  12#include <linux/sched.h>
  13#include <linux/module.h>
  14
  15#include <asm/openprom.h>
  16#include <asm/oplib.h>
  17#include <asm/ldc.h>
  18
  19static phandle prom_node_to_node(const char *type, phandle node)
  20{
  21        unsigned long args[5];
  22
  23        args[0] = (unsigned long) type;
  24        args[1] = 1;
  25        args[2] = 1;
  26        args[3] = (unsigned int) node;
  27        args[4] = (unsigned long) -1;
  28
  29        p1275_cmd_direct(args);
  30
  31        return (phandle) args[4];
  32}
  33
  34/* Return the child of node 'node' or zero if no this node has no
  35 * direct descendent.
  36 */
  37inline phandle __prom_getchild(phandle node)
  38{
  39        return prom_node_to_node("child", node);
  40}
  41
  42phandle prom_getchild(phandle node)
  43{
  44        phandle cnode;
  45
  46        if ((s32)node == -1)
  47                return 0;
  48        cnode = __prom_getchild(node);
  49        if ((s32)cnode == -1)
  50                return 0;
  51        return cnode;
  52}
  53EXPORT_SYMBOL(prom_getchild);
  54
  55inline phandle prom_getparent(phandle node)
  56{
  57        phandle cnode;
  58
  59        if ((s32)node == -1)
  60                return 0;
  61        cnode = prom_node_to_node("parent", node);
  62        if ((s32)cnode == -1)
  63                return 0;
  64        return cnode;
  65}
  66
  67/* Return the next sibling of node 'node' or zero if no more siblings
  68 * at this level of depth in the tree.
  69 */
  70inline phandle __prom_getsibling(phandle node)
  71{
  72        return prom_node_to_node(prom_peer_name, node);
  73}
  74
  75phandle prom_getsibling(phandle node)
  76{
  77        phandle sibnode;
  78
  79        if ((s32)node == -1)
  80                return 0;
  81        sibnode = __prom_getsibling(node);
  82        if ((s32)sibnode == -1)
  83                return 0;
  84
  85        return sibnode;
  86}
  87EXPORT_SYMBOL(prom_getsibling);
  88
  89/* Return the length in bytes of property 'prop' at node 'node'.
  90 * Return -1 on error.
  91 */
  92int prom_getproplen(phandle node, const char *prop)
  93{
  94        unsigned long args[6];
  95
  96        if (!node || !prop)
  97                return -1;
  98
  99        args[0] = (unsigned long) "getproplen";
 100        args[1] = 2;
 101        args[2] = 1;
 102        args[3] = (unsigned int) node;
 103        args[4] = (unsigned long) prop;
 104        args[5] = (unsigned long) -1;
 105
 106        p1275_cmd_direct(args);
 107
 108        return (int) args[5];
 109}
 110EXPORT_SYMBOL(prom_getproplen);
 111
 112/* Acquire a property 'prop' at node 'node' and place it in
 113 * 'buffer' which has a size of 'bufsize'.  If the acquisition
 114 * was successful the length will be returned, else -1 is returned.
 115 */
 116int prom_getproperty(phandle node, const char *prop,
 117                     char *buffer, int bufsize)
 118{
 119        unsigned long args[8];
 120        int plen;
 121
 122        plen = prom_getproplen(node, prop);
 123        if ((plen > bufsize) || (plen == 0) || (plen == -1))
 124                return -1;
 125
 126        args[0] = (unsigned long) prom_getprop_name;
 127        args[1] = 4;
 128        args[2] = 1;
 129        args[3] = (unsigned int) node;
 130        args[4] = (unsigned long) prop;
 131        args[5] = (unsigned long) buffer;
 132        args[6] = bufsize;
 133        args[7] = (unsigned long) -1;
 134
 135        p1275_cmd_direct(args);
 136
 137        return (int) args[7];
 138}
 139EXPORT_SYMBOL(prom_getproperty);
 140
 141/* Acquire an integer property and return its value.  Returns -1
 142 * on failure.
 143 */
 144int prom_getint(phandle node, const char *prop)
 145{
 146        int intprop;
 147
 148        if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
 149                return intprop;
 150
 151        return -1;
 152}
 153EXPORT_SYMBOL(prom_getint);
 154
 155/* Acquire an integer property, upon error return the passed default
 156 * integer.
 157 */
 158
 159int prom_getintdefault(phandle node, const char *property, int deflt)
 160{
 161        int retval;
 162
 163        retval = prom_getint(node, property);
 164        if (retval == -1)
 165                return deflt;
 166
 167        return retval;
 168}
 169EXPORT_SYMBOL(prom_getintdefault);
 170
 171/* Acquire a boolean property, 1=TRUE 0=FALSE. */
 172int prom_getbool(phandle node, const char *prop)
 173{
 174        int retval;
 175
 176        retval = prom_getproplen(node, prop);
 177        if (retval == -1)
 178                return 0;
 179        return 1;
 180}
 181EXPORT_SYMBOL(prom_getbool);
 182
 183/* Acquire a property whose value is a string, returns a null
 184 * string on error.  The char pointer is the user supplied string
 185 * buffer.
 186 */
 187void prom_getstring(phandle node, const char *prop, char *user_buf,
 188                int ubuf_size)
 189{
 190        int len;
 191
 192        len = prom_getproperty(node, prop, user_buf, ubuf_size);
 193        if (len != -1)
 194                return;
 195        user_buf[0] = 0;
 196}
 197EXPORT_SYMBOL(prom_getstring);
 198
 199/* Does the device at node 'node' have name 'name'?
 200 * YES = 1   NO = 0
 201 */
 202int prom_nodematch(phandle node, const char *name)
 203{
 204        char namebuf[128];
 205        prom_getproperty(node, "name", namebuf, sizeof(namebuf));
 206        if (strcmp(namebuf, name) == 0)
 207                return 1;
 208        return 0;
 209}
 210
 211/* Search siblings at 'node_start' for a node with name
 212 * 'nodename'.  Return node if successful, zero if not.
 213 */
 214phandle prom_searchsiblings(phandle node_start, const char *nodename)
 215{
 216        phandle thisnode;
 217        int error;
 218        char promlib_buf[128];
 219
 220        for(thisnode = node_start; thisnode;
 221            thisnode=prom_getsibling(thisnode)) {
 222                error = prom_getproperty(thisnode, "name", promlib_buf,
 223                                         sizeof(promlib_buf));
 224                /* Should this ever happen? */
 225                if(error == -1) continue;
 226                if(strcmp(nodename, promlib_buf)==0) return thisnode;
 227        }
 228
 229        return 0;
 230}
 231EXPORT_SYMBOL(prom_searchsiblings);
 232
 233static const char *prom_nextprop_name = "nextprop";
 234
 235/* Return the first property type for node 'node'.
 236 * buffer should be at least 32B in length
 237 */
 238char *prom_firstprop(phandle node, char *buffer)
 239{
 240        unsigned long args[7];
 241
 242        *buffer = 0;
 243        if ((s32)node == -1)
 244                return buffer;
 245
 246        args[0] = (unsigned long) prom_nextprop_name;
 247        args[1] = 3;
 248        args[2] = 1;
 249        args[3] = (unsigned int) node;
 250        args[4] = 0;
 251        args[5] = (unsigned long) buffer;
 252        args[6] = (unsigned long) -1;
 253
 254        p1275_cmd_direct(args);
 255
 256        return buffer;
 257}
 258EXPORT_SYMBOL(prom_firstprop);
 259
 260/* Return the property type string after property type 'oprop'
 261 * at node 'node' .  Returns NULL string if no more
 262 * property types for this node.
 263 */
 264char *prom_nextprop(phandle node, const char *oprop, char *buffer)
 265{
 266        unsigned long args[7];
 267        char buf[32];
 268
 269        if ((s32)node == -1) {
 270                *buffer = 0;
 271                return buffer;
 272        }
 273        if (oprop == buffer) {
 274                strcpy (buf, oprop);
 275                oprop = buf;
 276        }
 277
 278        args[0] = (unsigned long) prom_nextprop_name;
 279        args[1] = 3;
 280        args[2] = 1;
 281        args[3] = (unsigned int) node;
 282        args[4] = (unsigned long) oprop;
 283        args[5] = (unsigned long) buffer;
 284        args[6] = (unsigned long) -1;
 285
 286        p1275_cmd_direct(args);
 287
 288        return buffer;
 289}
 290EXPORT_SYMBOL(prom_nextprop);
 291
 292phandle prom_finddevice(const char *name)
 293{
 294        unsigned long args[5];
 295
 296        if (!name)
 297                return 0;
 298        args[0] = (unsigned long) "finddevice";
 299        args[1] = 1;
 300        args[2] = 1;
 301        args[3] = (unsigned long) name;
 302        args[4] = (unsigned long) -1;
 303
 304        p1275_cmd_direct(args);
 305
 306        return (int) args[4];
 307}
 308EXPORT_SYMBOL(prom_finddevice);
 309
 310int prom_node_has_property(phandle node, const char *prop)
 311{
 312        char buf [32];
 313        
 314        *buf = 0;
 315        do {
 316                prom_nextprop(node, buf, buf);
 317                if (!strcmp(buf, prop))
 318                        return 1;
 319        } while (*buf);
 320        return 0;
 321}
 322EXPORT_SYMBOL(prom_node_has_property);
 323
 324/* Set property 'pname' at node 'node' to value 'value' which has a length
 325 * of 'size' bytes.  Return the number of bytes the prom accepted.
 326 */
 327int
 328prom_setprop(phandle node, const char *pname, char *value, int size)
 329{
 330        unsigned long args[8];
 331
 332        if (size == 0)
 333                return 0;
 334        if ((pname == 0) || (value == 0))
 335                return 0;
 336        
 337#ifdef CONFIG_SUN_LDOMS
 338        if (ldom_domaining_enabled) {
 339                ldom_set_var(pname, value);
 340                return 0;
 341        }
 342#endif
 343        args[0] = (unsigned long) "setprop";
 344        args[1] = 4;
 345        args[2] = 1;
 346        args[3] = (unsigned int) node;
 347        args[4] = (unsigned long) pname;
 348        args[5] = (unsigned long) value;
 349        args[6] = size;
 350        args[7] = (unsigned long) -1;
 351
 352        p1275_cmd_direct(args);
 353
 354        return (int) args[7];
 355}
 356EXPORT_SYMBOL(prom_setprop);
 357
 358inline phandle prom_inst2pkg(int inst)
 359{
 360        unsigned long args[5];
 361        phandle node;
 362        
 363        args[0] = (unsigned long) "instance-to-package";
 364        args[1] = 1;
 365        args[2] = 1;
 366        args[3] = (unsigned int) inst;
 367        args[4] = (unsigned long) -1;
 368
 369        p1275_cmd_direct(args);
 370
 371        node = (int) args[4];
 372        if ((s32)node == -1)
 373                return 0;
 374        return node;
 375}
 376
 377int prom_ihandle2path(int handle, char *buffer, int bufsize)
 378{
 379        unsigned long args[7];
 380
 381        args[0] = (unsigned long) "instance-to-path";
 382        args[1] = 3;
 383        args[2] = 1;
 384        args[3] = (unsigned int) handle;
 385        args[4] = (unsigned long) buffer;
 386        args[5] = bufsize;
 387        args[6] = (unsigned long) -1;
 388
 389        p1275_cmd_direct(args);
 390
 391        return (int) args[6];
 392}
 393