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 2014 Garrett D'Amore <garrett@damore.org>
  23  *
  24  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  25  */
  26 
  27 #ifndef _SYS_INSTANCE_H
  28 #define _SYS_INSTANCE_H
  29 
  30 /*
  31  * Instance number assignment data structures
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <sys/param.h>
  36 #include <sys/dditypes.h>
  37 #include <sys/list.h>
  38 
  39 #ifdef  __cplusplus
  40 extern "C" {
  41 #endif
  42 
  43 #define INSTANCE_FILE   "/etc/path_to_inst"
  44 #define INSTANCE_FILE_SUFFIX    ".old"
  45 
  46 
  47 #if     defined(_KERNEL) || defined(_KMEMUSER)
  48 
  49 /*
  50  * The form of a node;  These form a tree that is parallel to the
  51  * dev_info tree, but always fully populated.  The tree is rooted in
  52  * the in_softstate struct (e_ddi_inst_state.ins_root).
  53  *
  54  * Each node has one or more in_drv entries hanging from it.
  55  * (It will have more than one if it has been driven by more than one driver
  56  * over its lifetime.  This can happen due to a generic name
  57  * or to a "compatible" name giving a more specific driver).
  58  */
  59 
  60 typedef struct in_node {
  61         char            *in_node_name;  /* devi_node_name of this node  */
  62         char            *in_unit_addr;  /* address part of name         */
  63         struct in_node  *in_child;      /* children of this node        */
  64         struct in_node  *in_sibling;    /* "peers" of this node         */
  65         struct in_drv   *in_drivers;    /* drivers bound to this node   */
  66         struct in_node  *in_parent;     /* parent of this node          */
  67         dev_info_t      *in_devi;       /* corresponding devinfo        */
  68 } in_node_t;
  69 
  70 typedef struct in_drv {
  71         char            *ind_driver_name; /* canonical name of driver   */
  72         int             ind_instance;     /* current instance number    */
  73         int             ind_state;        /* see below                  */
  74         /*
  75          * The following field is used to link instance numbers for the
  76          * same driver off of devnamesp or in_no_major or in_no_instance
  77          */
  78         struct in_drv   *ind_next;        /* next for this driver       */
  79         struct in_drv   *ind_next_drv;    /* next driver this node      */
  80         struct in_node  *ind_node;        /* node that these hang on    */
  81 } in_drv_t;
  82 
  83 /*
  84  * Values for in_state
  85  */
  86 #define IN_PROVISIONAL  0x1     /* provisional instance number assigned */
  87 #define IN_PERMANENT    0x2     /* instance number has been confirmed */
  88 #define IN_UNKNOWN      0x3     /* instance number not yet assigned */
  89 #define IN_BORROWED     0x4     /* instance number from alias */
  90 
  91 
  92 /*
  93  * Guard for path to instance file
  94  */
  95 #define PTI_GUARD "#\n#\tCaution! This file contains critical kernel state\n#\n"
  96 
  97 
  98 /*
  99  * special value for dn_instance
 100  */
 101 #define IN_SEARCHME (-1)
 102 
 103 #endif  /* defined(_KERNEL) || defined(_KMEMUSER) */
 104 
 105 #ifdef  _KERNEL
 106 void e_ddi_instance_init(void);
 107 uint_t e_ddi_assign_instance(dev_info_t *dip);
 108 void e_ddi_keep_instance(dev_info_t *dip);
 109 void e_ddi_free_instance(dev_info_t *dip, char *addr);
 110 int e_ddi_instance_majorinstance_to_path(major_t major,
 111         uint_t instance, char *path);
 112 void e_ddi_unorphan_instance_nos(void);
 113 void e_ddi_enter_instance(void);
 114 void e_ddi_exit_instance(void);
 115 in_node_t *e_ddi_instance_root(void);
 116 int e_ddi_instance_is_clean(void);
 117 void e_ddi_instance_set_clean(void);
 118 
 119 /* Platform instance override functions */
 120 uint_t impl_assign_instance(dev_info_t *dip);
 121 int impl_keep_instance(dev_info_t *dip);
 122 int impl_free_instance(dev_info_t *dip);
 123 
 124 /* walk the instance tree */
 125 int e_ddi_walk_instances(int (*)(const char *,
 126     in_node_t *, in_drv_t *, void *), void *);
 127 
 128 /* for DDI-MP */
 129 in_node_t *e_ddi_path_to_instance(char *path);
 130 void e_ddi_borrow_instance(dev_info_t *cdip, in_node_t *cnp);
 131 void e_ddi_return_instance(dev_info_t *cdip, char *addr, in_node_t *cnp);
 132 
 133 /* return values from e_ddi_walk_instances callback */
 134 #define INST_WALK_CONTINUE      0
 135 #define INST_WALK_TERMINATE     1
 136 
 137 
 138 #else   /* _KERNEL */
 139 extern int inst_sync(char *pathname, int flags);
 140 #endif  /* _KERNEL */
 141 
 142 #define INST_SYNC_IF_REQUIRED   0
 143 #define INST_SYNC_ALWAYS        1
 144 
 145 #ifdef  __cplusplus
 146 }
 147 #endif
 148 
 149 #endif  /* _SYS_INSTANCE_H */