1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 #ifndef _SYS_INSTANCE_H
  26 #define _SYS_INSTANCE_H
  27 
  28 /*
  29  * Instance number assignment data structures
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/param.h>
  34 #include <sys/dditypes.h>
  35 #include <sys/list.h>
  36 
  37 #ifdef  __cplusplus
  38 extern "C" {
  39 #endif
  40 
  41 #define INSTANCE_FILE   "/etc/path_to_inst"
  42 #define INSTANCE_FILE_SUFFIX    ".old"
  43 
  44 
  45 #if     defined(_KERNEL) || defined(_KMEMUSER)
  46 
  47 /*
  48  * The form of a node;  These form a tree that is parallel to the
  49  * dev_info tree, but always fully populated.  The tree is rooted in
  50  * the in_softstate struct (e_ddi_inst_state.ins_root).
  51  *
  52  * Each node has one or more in_drv entries hanging from it.
  53  * (It will have more than one if it has been driven by more than one driver
  54  * over its lifetime.  This can happen due to a generic name
  55  * or to a "compatible" name giving a more specific driver).
  56  */
  57 
  58 typedef struct in_node {
  59         char            *in_node_name;  /* devi_node_name of this node  */
  60         char            *in_unit_addr;  /* address part of name         */
  61         struct in_node  *in_child;      /* children of this node        */
  62         struct in_node  *in_sibling;    /* "peers" of this node         */
  63         struct in_drv   *in_drivers;    /* drivers bound to this node   */
  64         struct in_node  *in_parent;     /* parent of this node          */
  65         dev_info_t      *in_devi;       /* corresponding devinfo        */
  66 } in_node_t;
  67 
  68 typedef struct in_drv {
  69         char            *ind_driver_name; /* canonical name of driver   */
  70         int             ind_instance;     /* current instance number    */
  71         int             ind_state;        /* see below                  */
  72         /*
  73          * The following field is used to link instance numbers for the
  74          * same driver off of devnamesp or in_no_major or in_no_instance
  75          */
  76         struct in_drv   *ind_next;        /* next for this driver       */
  77         struct in_drv   *ind_next_drv;    /* next driver this node      */
  78         struct in_node  *ind_node;        /* node that these hang on    */
  79 } in_drv_t;
  80 
  81 /*
  82  * Values for in_state
  83  */
  84 #define IN_PROVISIONAL  0x1     /* provisional instance number assigned */
  85 #define IN_PERMANENT    0x2     /* instance number has been confirmed */
  86 #define IN_UNKNOWN      0x3     /* instance number not yet assigned */
  87 #define IN_BORROWED     0x4     /* instance number from alias */
  88 
  89 
  90 /*
  91  * Guard for path to instance file
  92  */
  93 #define PTI_GUARD "#\n#\tCaution! This file contains critical kernel state\n#\n"
  94 
  95 
  96 /*
  97  * special value for dn_instance
  98  */
  99 #define IN_SEARCHME (-1)
 100 
 101 #endif  /* defined(_KERNEL) || defined(_KMEMUSER) */
 102 
 103 #ifdef  _KERNEL
 104 void e_ddi_instance_init(void);
 105 uint_t e_ddi_assign_instance(dev_info_t *dip);
 106 void e_ddi_keep_instance(dev_info_t *dip);
 107 void e_ddi_free_instance(dev_info_t *dip, char *addr);
 108 int e_ddi_instance_majorinstance_to_path(major_t major,
 109         uint_t instance, char *path);
 110 void e_ddi_unorphan_instance_nos(void);
 111 void e_ddi_enter_instance(void);
 112 void e_ddi_exit_instance(void);
 113 in_node_t *e_ddi_instance_root(void);
 114 int e_ddi_instance_is_clean(void);
 115 void e_ddi_instance_set_clean(void);
 116 
 117 /* Platform instance override functions */
 118 uint_t impl_assign_instance(dev_info_t *dip);
 119 int impl_keep_instance(dev_info_t *dip);
 120 int impl_free_instance(dev_info_t *dip);
 121 
 122 /* walk the instance tree */
 123 int e_ddi_walk_instances(int (*)(const char *,
 124     in_node_t *, in_drv_t *, void *), void *);
 125 
 126 /* for DDI-MP */
 127 in_node_t *e_ddi_path_to_instance(char *path);
 128 void e_ddi_borrow_instance(dev_info_t *cdip, in_node_t *cnp);
 129 void e_ddi_return_instance(dev_info_t *cdip, char *addr, in_node_t *cnp);
 130 
 131 /* return values from e_ddi_walk_instances callback */
 132 #define INST_WALK_CONTINUE      0
 133 #define INST_WALK_TERMINATE     1
 134 
 135 
 136 #else   /* _KERNEL */
 137 #ifdef __STDC__
 138 extern int inst_sync(char *pathname, int flags);
 139 #else
 140 extern int inst_sync();
 141 #endif  /* __STDC__ */
 142 #endif  /* _KERNEL */
 143 
 144 #define INST_SYNC_IF_REQUIRED   0
 145 #define INST_SYNC_ALWAYS        1
 146 
 147 #ifdef  __cplusplus
 148 }
 149 #endif
 150 
 151 #endif  /* _SYS_INSTANCE_H */