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) 1990, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #ifndef _SYS_AUTOCONF_H 26 #define _SYS_AUTOCONF_H 27 28 /* Derived from autoconf.h, SunOS 4.1.1 1.15 */ 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 /* 35 * This defines a parallel structure to the devops list. 36 */ 37 38 #include <sys/dditypes.h> 39 #include <sys/devops.h> 40 #include <sys/mutex.h> 41 #include <sys/thread.h> 42 #include <sys/obpdefs.h> 43 #include <sys/systm.h> 44 #include <sys/hwconf.h> 45 46 struct devnames { 47 char *dn_name; /* Name of this driver */ 48 int dn_flags; /* per-driver flags, see below */ 49 struct par_list *dn_pl; /* parent list, for making devinfos */ 50 kmutex_t dn_lock; /* Per driver lock (see below) */ 51 dev_info_t *dn_head; /* Head of instance list */ 52 int dn_instance; /* Next instance no. to assign */ 53 void *dn_inlist; /* instance # nodes for this driver */ 54 ddi_prop_list_t *dn_global_prop_ptr; /* per-driver global properties */ 55 kcondvar_t dn_wait; /* for ddi_hold_installed_driver */ 56 kthread_id_t dn_busy_thread; /* for debugging only */ 57 struct mperm *dn_mperm; /* minor permissions */ 58 struct mperm *dn_mperm_wild; /* default minor permission */ 59 struct mperm *dn_mperm_clone; /* minor permission, clone use */ 60 int dn_pinstance; /* Preassign instance boundary */ 61 }; 62 63 /* 64 * dn_lock is used to protect the driver initialization/loading 65 * from fini/unloading. It also protects each drivers devops 66 * reference count, the dn_flags, and the dn_head linked list of 67 * driver instances. The busy_changing bit is used to avoid 68 * recursive calls to ddi_hold_installed_driver to hold the 69 * same driver. 70 */ 71 72 /* 73 * Defines for dn_flags. 74 */ 75 #define DN_CONF_PARSED 0x0001 76 #define DN_DRIVER_BUSY 0x0002 /* for ddi_hold_installed_driver */ 77 #define DN_DRIVER_INACTIVE 0x0004 /* driver not active */ 78 #define DN_DRIVER_HELD 0x0020 /* held via ddi_hold_installed_driver */ 79 #define DN_TAKEN_GETUDEV 0x0040 /* getudev() used this entry */ 80 #define DN_DRIVER_REMOVED 0x0080 /* driver entry removed */ 81 82 #define DN_FORCE_ATTACH 0x0100 /* DDI_FORCEATTACH prop */ 83 #define DN_LEAF_DRIVER 0x0200 /* this is a leaf driver */ 84 #define DN_NETWORK_DRIVER 0x0400 /* network interface driver */ 85 #define DN_NO_AUTODETACH 0x0800 /* no autodetach */ 86 #define DN_GLDV3_DRIVER 0x1000 /* gldv3 (Nemo) driver */ 87 #define DN_PHCI_DRIVER 0x2000 /* pHCI driver */ 88 #define DN_OPEN_RETURNS_EINTR 0x4000 /* DDI_OPEN_RETURNS_EINTR prop */ 89 #define DN_SCSI_SIZE_CLEAN 0x8000 /* driver is scsi_size_clean() */ 90 #define DN_NETWORK_PHYSDRIVER 0x10000 /* physical network driver */ 91 #define DN_DEVID_REGISTRANT 0x20000 /* ddi-devid-registrant prop */ 92 93 #ifdef _KERNEL 94 95 /* 96 * Debugging flags and macros 97 */ 98 #define DDI_AUDIT 0x0001 99 #define DDI_DEBUG 0x0002 100 #define DDI_MTCONFIG 0x0004 101 #define DDI_DEBUG_BOOTMOD 0x0008 /* module loading to mount root */ 102 #define DDI_DEBUG_COMPAT 0x0010 /* ddi_hold_install_driver */ 103 #define LDI_DBG_OPENCLOSE 0x0020 /* ldi open/close info */ 104 #define LDI_DBG_ALLOCFREE 0x0040 /* ldi ident alloc/free info */ 105 #define LDI_DBG_STREAMS 0x0080 /* ldi streams link/unlink */ 106 #define LDI_DBG_EVENTCB 0x0100 /* ldi event callback info */ 107 #define DDI_INTR_API 0x0200 /* interrupt interface messages */ 108 #define DDI_INTR_IMPL 0x0400 /* interrupt implementation msgs */ 109 #define DDI_INTR_NEXUS 0x0800 /* interrupt messages from nexuses */ 110 #define DDI_DBG_RETIRE 0x1000 /* Retire related messages */ 111 #define DDI_DBG_RTR_VRBOSE 0x2000 /* Verbose Retire messages */ 112 #define DDI_DBG_RTR_TRACE 0x4000 /* Trace Retire messages */ 113 #define LDI_EV_DEBUG 0x8000 /* LDI events debug messages */ 114 #define LDI_EV_TRACE 0x10000 /* LDI events trace messages */ 115 #define DDI_INTR_IRM 0x20000 /* interrupt resource management */ 116 #define DDI_HP_API 0x40000 /* Hotplug interface messages */ 117 #define DDI_HP_IMPL 0x80000 /* Hotplug implementation msgs */ 118 #define DDI_HP_NEXUS 0x100000 /* Hotplug messages from nexuses */ 119 #define DDI_MP_DEBUG 0x200000 /* ddi-mp translations */ 120 121 extern int ddidebug; 122 123 #ifdef DEBUG 124 #define NDI_CONFIG_DEBUG(args) if (ddidebug & DDI_DEBUG) cmn_err args 125 #define BMDPRINTF(args) if (ddidebug & DDI_DEBUG_BOOTMOD) printf args 126 #define DCOMPATPRINTF(args) if (ddidebug & DDI_DEBUG_COMPAT) cmn_err args 127 #define LDI_OPENCLOSE(args) if (ddidebug & LDI_DBG_OPENCLOSE) cmn_err args 128 #define LDI_ALLOCFREE(args) if (ddidebug & LDI_DBG_ALLOCFREE) cmn_err args 129 #define LDI_STREAMS_LNK(args) if (ddidebug & LDI_DBG_STREAMS) cmn_err args 130 #define LDI_EVENTCB(args) if (ddidebug & LDI_DBG_EVENTCB) cmn_err args 131 #define DDI_INTR_APIDBG(args) if (ddidebug & DDI_INTR_API) cmn_err args 132 #define DDI_INTR_IMPLDBG(args) if (ddidebug & DDI_INTR_IMPL) cmn_err args 133 #define DDI_INTR_NEXDBG(args) if (ddidebug & DDI_INTR_NEXUS) cmn_err args 134 #define RIO_DEBUG(args) if (ddidebug & DDI_DBG_RETIRE) cmn_err args 135 #define RIO_VERBOSE(args) if (ddidebug & DDI_DBG_RTR_VRBOSE) cmn_err args 136 #define RIO_TRACE(args) if (ddidebug & DDI_DBG_RTR_TRACE) cmn_err args 137 #define LDI_EVDBG(args) if (ddidebug & LDI_EV_DEBUG) cmn_err args 138 #define LDI_EVTRC(args) if (ddidebug & LDI_EV_TRACE) cmn_err args 139 #define DDI_INTR_IRMDBG(args) if (ddidebug & DDI_INTR_IRM) cmn_err args 140 #define DDI_HP_APIDBG(args) if (ddidebug & DDI_HP_API) cmn_err args 141 #define DDI_HP_IMPLDBG(args) if (ddidebug & DDI_HP_IMPL) cmn_err args 142 #define DDI_HP_NEXDBG(args) if (ddidebug & DDI_HP_NEXUS) cmn_err args 143 #else 144 #define NDI_CONFIG_DEBUG(args) 145 #define BMDPRINTF(args) 146 #define DCOMPATPRINTF(args) 147 #define LDI_OPENCLOSE(args) 148 #define LDI_ALLOCFREE(args) 149 #define LDI_STREAMS_LNK(args) 150 #define LDI_EVENTCB(args) 151 #define DDI_INTR_APIDBG(args) 152 #define DDI_INTR_IMPLDBG(args) 153 #define DDI_INTR_NEXDBG(args) 154 #define RIO_DEBUG(args) if (ddidebug & DDI_DBG_RETIRE) cmn_err args 155 #define RIO_VERBOSE(args) if (ddidebug & DDI_DBG_RTR_VRBOSE) cmn_err args 156 #define RIO_TRACE(args) if (ddidebug & DDI_DBG_RTR_TRACE) cmn_err args 157 #define LDI_EVDBG(args) if (ddidebug & LDI_EV_DEBUG) cmn_err args 158 #define LDI_EVTRC(args) if (ddidebug & LDI_EV_TRACE) cmn_err args 159 #define DDI_INTR_IRMDBG(args) 160 #define DDI_HP_APIDBG(args) 161 #define DDI_HP_IMPLDBG(args) 162 #define DDI_HP_NEXDBG(args) 163 #endif 164 #define DDI_MP_DBG(args) if (ddidebug & DDI_MP_DEBUG) cmn_err args 165 166 167 /* 168 * DDI configuration logs 169 */ 170 #define DDI_STACK_DEPTH 14 171 172 typedef struct devinfo_audit { 173 dev_info_t *da_devinfo; /* address of devinfo node */ 174 hrtime_t da_timestamp; /* audit time */ 175 kthread_id_t da_thread; /* thread of transaction */ 176 struct devinfo_audit *da_lastlog; /* last log of state change */ 177 ddi_node_state_t da_node_state; /* devinfo state at log time */ 178 int da_device_state; /* device state */ 179 int da_depth; 180 pc_t da_stack[DDI_STACK_DEPTH]; 181 } devinfo_audit_t; 182 183 typedef struct { 184 kmutex_t dh_lock; 185 int dh_max; 186 int dh_curr; 187 int dh_hits; 188 devinfo_audit_t dh_entry[1]; 189 } devinfo_log_header_t; 190 191 struct di_cache { 192 uint32_t cache_valid; /* no lock needed - field atomic updt */ 193 kmutex_t cache_lock; /* protects fields below */ 194 void *cache_data; 195 size_t cache_size; 196 }; 197 198 extern struct di_cache di_cache; 199 extern int di_cache_debug; 200 extern volatile ulong_t devtree_gen; 201 202 /* 203 * Special dev_info nodes 204 */ 205 #define PSEUDO_PATH "/"DEVI_PSEUDO_NEXNAME 206 #define CLONE_PATH PSEUDO_PATH"/clone@0" 207 208 #define DI_CACHE_FILE "/etc/devices/snapshot_cache" 209 #define DI_CACHE_TEMP DI_CACHE_FILE".tmp" 210 211 extern dev_info_t *options_dip; 212 extern dev_info_t *pseudo_dip; 213 extern dev_info_t *clone_dip; 214 extern major_t clone_major; 215 extern major_t mm_major; 216 extern major_t nulldriver_major; 217 218 extern struct devnames *devnamesp; 219 extern struct devnames orphanlist; 220 221 extern struct dev_ops nodev_ops, mod_nodev_ops; 222 223 /* 224 * Obsolete interface, no longer used, to be removed. 225 * Retained only for driver compatibility. 226 */ 227 extern krwlock_t devinfo_tree_lock; /* obsolete */ 228 229 /* 230 * Acquires dn_lock, as above. 231 */ 232 #define LOCK_DEV_OPS(lp) mutex_enter((lp)) 233 #define UNLOCK_DEV_OPS(lp) mutex_exit((lp)) 234 235 /* 236 * Not to be used without obtaining the per-driver lock. 237 */ 238 #define INCR_DEV_OPS_REF(opsp) (opsp)->devo_refcnt++ 239 #define DECR_DEV_OPS_REF(opsp) (opsp)->devo_refcnt-- 240 #define CB_DRV_INSTALLED(opsp) ((opsp) != &nodev_ops && \ 241 (opsp) != &mod_nodev_ops) 242 #define DRV_UNLOADABLE(opsp) ((opsp)->devo_refcnt == 0) 243 #define DEV_OPS_HELD(opsp) ((opsp)->devo_refcnt > 0) 244 #define NEXUS_DRV(opsp) ((opsp)->devo_bus_ops != NULL) 245 #define NETWORK_DRV(maj) (devnamesp[(maj)].dn_flags & DN_NETWORK_DRIVER) 246 #define GLDV3_DRV(maj) (devnamesp[(maj)].dn_flags & DN_GLDV3_DRIVER) 247 #define NETWORK_PHYSDRV(maj) \ 248 (devnamesp[(maj)].dn_flags & DN_NETWORK_PHYSDRIVER) 249 250 extern void impl_rem_dev_props(dev_info_t *); 251 extern void add_class(char *, char *); 252 253 extern int make_mbind(char *, int, char *, struct bind **); 254 extern void delete_mbind(char *, struct bind **); 255 extern void purge_mbind(int, struct bind **); 256 257 extern void configure(void); 258 #if defined(__sparc) 259 extern void setcputype(void); 260 #endif 261 extern void devtree_freeze(void); 262 extern void reset_leaves(void); 263 extern void quiesce_devices(dev_info_t *, void *); 264 265 extern void setup_ddi(void); 266 extern void setup_ddi_poststartup(void); 267 extern void impl_ddi_callback_init(void); 268 extern void impl_fix_props(dev_info_t *, dev_info_t *, char *, int, caddr_t); 269 extern int impl_check_cpu(dev_info_t *); 270 extern int check_status(int, char *, dev_info_t *); 271 272 extern int exclude_settrap(int); 273 extern int exclude_level(int); 274 275 extern major_t path_to_major(char *); 276 extern void i_ddi_node_cache_init(void); 277 extern dev_info_t *i_ddi_alloc_node(dev_info_t *, const char *, pnode_t, int, 278 ddi_prop_t *, int); 279 extern void i_ddi_forceattach_drivers(void); 280 extern int i_ddi_io_initialized(void); 281 extern dev_info_t *i_ddi_create_branch(dev_info_t *, int); 282 extern void i_ddi_add_devimap(dev_info_t *dip); 283 extern void i_ddi_di_cache_invalidate(void); 284 extern void i_ddi_di_cache_free(struct di_cache *cache); 285 286 /* devname_state - for /dev to denote reconfig and system available */ 287 #define DS_RECONFIG 0x01 /* reconfig boot */ 288 #define DS_SYSAVAIL 0x02 /* implicit reconfig enabled */ 289 290 extern int i_ddi_sysavail(void); 291 extern int i_ddi_reconfig(void); 292 extern void i_ddi_set_sysavail(void); 293 extern void i_ddi_set_reconfig(void); 294 295 /* I/O retire related */ 296 extern int e_ddi_retire_device(char *path, char **cons_array); 297 extern int e_ddi_unretire_device(char *path); 298 extern int e_ddi_mark_retiring(dev_info_t *dip, void *arg); 299 extern int e_ddi_retire_notify(dev_info_t *dip, void *arg); 300 extern int e_ddi_retire_finalize(dev_info_t *dip, void *arg); 301 extern void e_ddi_degrade_finalize(dev_info_t *dip); 302 extern void e_ddi_undegrade_finalize(dev_info_t *dip); 303 304 extern int check_driver_quiesce(dev_info_t *dip, void *arg); 305 306 #endif /* _KERNEL */ 307 308 #ifdef __cplusplus 309 } 310 #endif 311 312 #endif /* _SYS_AUTOCONF_H */ 313