openprom - PROM monitor configuration interface


     #include <sys/fcntl.h>

     #include <sys/types.h>

     #include <sys/openpromio.h>

     open("/dev/openprom", mode);


     The  internal  encoding  of  the  configuration  information
     stored in EEPROM or NVRAM varies from model to model, and on
     some systems the encoding is "hidden" by the  firmware.  The
     openprom  driver provides a consistent interface that allows
     a user or program to inspect and modify that  configuration,
     using  ioctl(2)  requests.   These  requests  are defined in

     struct openpromio {
         uint_t  oprom_size;       /* real size of following data */
         union {
              char  b[1];          /* NB: Adjacent, Null terminated */
              int   i;
                         } opio_u;
     #define oprom_array opio_u.b  /* property name/value array */
     #define oprom_node opio_u.i   /* nodeid from navigation config-ops */
     #define oprom_len opio_u.i    /* property len from OPROMGETPROPLEN */
     #define OPROMMAXPARAM 32768   /* max size of array (advisory) */

     For all ioctl(2) requests, the third parameter is a  pointer
     to  a  struct  openpromio. All property names and values are
     null-terminated strings; the value of a  numeric  option  is
     its ASCII representation.

     For the raw ioctl(2) operations shown below that  explicitly
     or  implicitly  specify  a nodeid, an error may be returned.
     This is due to the removal of the  node  from  the  firmware
     device tree by a Dynamic Reconfiguration operation. Programs
     should decide if the appropriate response is to restart  the
     scanning  operation from the beginning or terminate, inform-
     ing the user that the tree has changed.


           This ioctl takes the null-terminated name  of  a  pro-
           perty   in  the  oprom_array  and  returns  its  null-
           terminated value  (overlaying  its  name).  oprom_size
           should be set to the size of oprom_array; on return it
           will contain the size of the returned  value.  If  the
           named  property  does  not  exist,  or if there is not
           enough space to hold its value, then  oprom_size  will
           be set to zero. See BUGS below.

           This ioctl takes two adjacent strings in  oprom_array;
           the  null-terminated  property  name  followed  by the
           null-terminated value.

           This ioctl is similar to  OPROMSETOPT, except that  it
           uses the difference between the actual user array size
           and the length of the property name plus its null ter-

           This ioctl is  used  to  retrieve  properties  sequen-
           tially.  The  null-terminated  name  of  a property is
           placed into oprom_array and on return it  is  replaced
           with  the null-terminated name of the next property in
           the sequence, with oprom_size set  to  its  length.  A
           null  string  on  input  means  return the name of the
           first property; an oprom_size of zero on output  means
           there are no more properties.




           These  ioctls  provide  an  interface   to   the   raw
           config_ops  operations  in  the PROM monitor.  One can
           use them to  traverse  the  system  device  tree;  see

           This ioctl  provides  an  interface  to  the  property
           length  raw config op. It takes the name of a property
           in the buffer, and returns an integer in  the  buffer.
           It  returns  the  integer  -1 if the property does not
           exist; 0 if the property exists, but has no  value  (a
           boolean  property); or a positive integer which is the
           length of the property as reported by the  PROM  moni-
           tor. See BUGS below.

           This ioctl returns an arbitrary and platform-dependent
           NULL-terminated  string  in  oprom_array, representing
           the underlying version of the firmware.


           There are too many opens of the /dev/openprom device.

           A bad address has been passed to an ioctl(2) routine.

           The size value was invalid, or (for OPROMSETOPT) the
                property does not exist, or an invalid  ioctl  is
           being  issued,  or  the  ioctl is not supported by the
           firmware, or the nodeid specified does  not  exist  in
           the firmware device tree.

           The kernel could not allocate space to copy the user's

     EPERM Attempts have  been  made  to  write  to  a  read-only
           entity, or read from a write only entity.

     ENXIO Attempting to open a non-existent device.


     Example 1: oprom_array Data Allocation and Reuse

     The following example shows how the oprom_array is allocated
     and reused for data returned by the driver.

      * This program opens the openprom device and prints the platform
      * name (root node name property) and the prom version.
      * NOTE: /dev/openprom is readable only by user 'root' or group 'sys'.
     #include <stdio.h>
     #include <string.h>
     #include <fcntl.h>
     #include <errno.h>
     #include <unistd.h>
     #include <stdlib.h>
     #include <sys/openpromio.h>
     #define    min(a, b)    (a < b ? a : b)
     #define    max(a, b)    (a > b ? a : b)
     #define MAXNAMESZ 32          /* Maximum property *name* size */
     #define BUFSZ 1024            /* A Handly default buffer size */
     #define MAXVALSZ    (BUFSZ - sizeof (int))
     static char *promdev = "/dev/openprom";
      * Allocate an openpromio structure big enough to contain
      * a bufsize'd oprom_array. Zero out the structure and
      * set the oprom_size field to bufsize.
     static struct openpromio *
     opp_zalloc(size_t bufsize)
         struct openpromio *opp;
         opp = malloc(sizeof (struct openpromio) + bufsize);
         (void) memset(opp, 0, sizeof (struct openpromio) + bufsize);
         opp->oprom_size = bufsize;
         return (opp);
      * Free a 'struct openpromio' allocated by opp_zalloc
     static void
     opp_free(struct openpromio *opp)
      * Get the peer node of the given node.  The root node is the peer of zero.
      * After changing nodes, property lookups apply to that node.  The driver
      * 'remembers' what node you are in.
     static int
     peer(int nodeid, int fd)
         struct openpromio *opp;
         int i;
         opp = opp_zalloc(sizeof (int));
         opp->oprom_node = nodeid;
         if (ioctl(fd, OPROMNEXT, opp) < 0) {
         i = opp->oprom_node;
         struct openpromio *opp;
         int fd, proplen;
         size_t buflen;
         if ((fd = open(promdev, O_RDONLY)) < 0)  {
             fprintf(stderr, "Cannot open openprom device0);
          * Get and print the length and value of the
          * root node 'name' property

         (void) peer(0, fd);        /* Navigate to the root node */
          * Allocate an openpromio structure sized big enough to
          * take the string "name" as input and return the int-sized
          * length of the 'name' property.
          * Then, get the length of the 'name' property.
         buflen = max(sizeof (int), strlen("name") + 1);
         opp = opp_zalloc(buflen);
         (void) strcpy(opp->oprom_array, "name");
         if (ioctl(fd, OPROMGETPROPLEN, opp) < 0) {
             /* exit(1); */
             proplen = 0;    /* down-rev driver? */
         } else
             proplen = opp->oprom_len;
         if (proplen == -1) {
             printf("'name' property does not exist!0);
             exit (1);
          * Allocate an openpromio structure sized big enough
          * to take the string 'name' as input and to return
          * 'proplen + 1' bytes.  Then, get the value of the
          * 'name' property. Note how we make sure to size the
          * array at least one byte more than the returned length
          * to guarantee NULL termination.
         buflen = (proplen ? proplen + 1 : MAXVALSZ);
         buflen = max(buflen, strlen("name") + 1);
         opp = opp_zalloc(buflen);
         (void) strcpy(opp->oprom_array, "name");
         if (ioctl(fd, OPROMGETPROP, opp) < 0) {
         if (opp->oprom_size != 0)
             printf("Platform name <%s> property len <%d>0,
                 opp->oprom_array, proplen);
          * Allocate an openpromio structure assumed to be
          * big enough to get the 'prom version string'.
          * Get and print the prom version.
         opp->oprom_size = MAXVALSZ;
         if (ioctl(fd, OPROMGETVERSION, opp) < 0) {
         printf("Prom version <%s>0, opp->oprom_array);
         (void) close(fd);
         return (0);


           PROM monitor configuration interface


     eeprom(1M), monitor(1M), prtconf(1M), ioctl(2), mem(7D)


     There should be separate return values for non-existent pro-
     perties as opposed to not enough space for the value.

     An attempt to set a property to an illegal value results  in
     the PROM setting it to some legal value, with no error being
     returned. An OPROMGETOPT should be performed after an OPROM-
     SETOPT to verify that the set worked.

     Some PROMS lie about the property length of some string pro-
     perties,  omitting  the   NULL  terminator from the property
     length.  The  openprom driver attempts to transparently com-
     pensate  for  these  bugs  when returning property values by
     NULL terminating an extra character in the  user  buffer  if
     space  is available in the user buffer. This extra character
     is  excluded  from  the  oprom_size  field   returned   from
     OPROMGETPROP  and  OPROMGETOPT and excluded in the oprom_len
     field returned from OPROMGETPROPLEN but is returned  in  the
     user  buffer  from  the  calls that return data, if the user
     buffer is allocated at least one byte larger than  the  pro-
     perty length.

Man(1) output converted with man2html