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 /*
  23  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2012 Garrett D'Amore <garrett@damore.org>.  All rights reserved.
  25  * Copyright 2016 Joyent, Inc.
  26  * Copyright (c) 2016 by Delphix. All rights reserved.
  27  * Copyright 2018 Nexenta Systems, Inc.
  28  */
  29 
  30 #ifndef _SYS_DDI_IMPLDEFS_H
  31 #define _SYS_DDI_IMPLDEFS_H
  32 
  33 #include <sys/types.h>
  34 #include <sys/param.h>
  35 #include <sys/t_lock.h>
  36 #include <sys/ddipropdefs.h>
  37 #include <sys/devops.h>
  38 #include <sys/autoconf.h>
  39 #include <sys/mutex.h>
  40 #include <vm/page.h>
  41 #include <sys/dacf_impl.h>
  42 #include <sys/ndifm.h>
  43 #include <sys/epm.h>
  44 #include <sys/ddidmareq.h>
  45 #include <sys/ddi_intr.h>
  46 #include <sys/ddi_hp.h>
  47 #include <sys/ddi_hp_impl.h>
  48 #include <sys/ddi_isa.h>
  49 #include <sys/id_space.h>
  50 #include <sys/modhash.h>
  51 #include <sys/bitset.h>
  52 
  53 #ifdef  __cplusplus
  54 extern "C" {
  55 #endif
  56 
  57 /*
  58  * The device id implementation has been switched to be based on properties.
  59  * For compatibility with di_devid libdevinfo interface the following
  60  * must be defined:
  61  */
  62 #define DEVID_COMPATIBILITY     ((ddi_devid_t)-1)
  63 
  64 /*
  65  * Definitions for node class.
  66  * DDI_NC_PROM: a node with a nodeid that may be used in a promif call.
  67  * DDI_NC_PSEUDO: a software created node with a software assigned nodeid.
  68  */
  69 typedef enum {
  70         DDI_NC_PROM = 0,
  71         DDI_NC_PSEUDO
  72 } ddi_node_class_t;
  73 
  74 /*
  75  * Definitions for generic callback mechanism.
  76  */
  77 typedef enum {
  78         DDI_CB_INTR_ADD,                /* More available interrupts */
  79         DDI_CB_INTR_REMOVE              /* Fewer available interrupts */
  80 } ddi_cb_action_t;
  81 
  82 typedef enum {
  83         DDI_CB_FLAG_INTR = 0x1          /* Driver is IRM aware */
  84 } ddi_cb_flags_t;
  85 
  86 #define DDI_CB_FLAG_VALID(f)    ((f) & DDI_CB_FLAG_INTR)
  87 
  88 typedef int     (*ddi_cb_func_t)(dev_info_t *dip, ddi_cb_action_t action,
  89                     void *cbarg, void *arg1, void *arg2);
  90 
  91 typedef struct ddi_cb {
  92         uint64_t        cb_flags;
  93         dev_info_t      *cb_dip;
  94         ddi_cb_func_t   cb_func;
  95         void            *cb_arg1;
  96         void            *cb_arg2;
  97 } ddi_cb_t;
  98 
  99 /*
 100  * dev_info:    The main device information structure this is intended to be
 101  *              opaque to drivers and drivers should use ddi functions to
 102  *              access *all* driver accessible fields.
 103  *
 104  * devi_parent_data includes property lists (interrupts, registers, etc.)
 105  * devi_driver_data includes whatever the driver wants to place there.
 106  */
 107 struct devinfo_audit;
 108 
 109 typedef struct devi_port {
 110         union {
 111                 struct {
 112                         uint32_t type;
 113                         uint32_t pad;
 114                 } port;
 115                 uint64_t type64;
 116         } info;
 117         void    *priv_p;
 118 } devi_port_t;
 119 
 120 typedef struct devi_bus_priv {
 121         devi_port_t port_up;
 122         devi_port_t port_down;
 123 } devi_bus_priv_t;
 124 
 125 #if defined(__x86)
 126 struct iommulib_unit;
 127 typedef struct iommulib_unit *iommulib_handle_t;
 128 struct iommulib_nex;
 129 typedef struct iommulib_nex *iommulib_nexhandle_t;
 130 #endif
 131 
 132 typedef uint8_t ndi_flavor_t;
 133 struct ddi_hp_cn_handle;
 134 
 135 struct in_node;
 136 
 137 struct dev_info  {
 138 
 139         struct dev_info *devi_parent;   /* my parent node in tree       */
 140         struct dev_info *devi_child;    /* my child list head           */
 141         struct dev_info *devi_sibling;  /* next element on my level     */
 142 
 143         char    *devi_binding_name;     /* name used to bind driver:    */
 144                                         /* shared storage, points to    */
 145                                         /* devi_node_name, devi_compat_names */
 146                                         /* or devi_rebinding_name       */
 147 
 148         char    *devi_addr;             /* address part of name         */
 149 
 150         int     devi_nodeid;            /* device nodeid                */
 151         int     devi_instance;          /* device instance number       */
 152 
 153         struct dev_ops *devi_ops;       /* driver operations            */
 154 
 155         void    *devi_parent_data;      /* parent private data          */
 156         void    *devi_driver_data;      /* driver private data          */
 157 
 158         ddi_prop_t *devi_drv_prop_ptr;  /* head of driver prop list */
 159         ddi_prop_t *devi_sys_prop_ptr;  /* head of system prop list */
 160 
 161         struct ddi_minor_data *devi_minor;      /* head of minor list */
 162         struct dev_info *devi_next;     /* Next instance of this device */
 163         kmutex_t devi_lock;             /* Protects per-devinfo data */
 164 
 165         /* logical parents for busop primitives */
 166 
 167         struct dev_info *devi_bus_map_fault;    /* bus_map_fault parent  */
 168         void            *devi_obsolete;         /* obsolete placeholder */
 169         struct dev_info *devi_bus_dma_allochdl; /* bus_dma_newhdl parent */
 170         struct dev_info *devi_bus_dma_freehdl;  /* bus_dma_freehdl parent */
 171         struct dev_info *devi_bus_dma_bindhdl;  /* bus_dma_bindhdl parent */
 172         struct dev_info *devi_bus_dma_unbindhdl; /* bus_dma_unbindhdl parent */
 173         struct dev_info *devi_bus_dma_flush;    /* bus_dma_flush parent  */
 174         struct dev_info *devi_bus_dma_win;      /* bus_dma_win parent    */
 175         struct dev_info *devi_bus_dma_ctl;      /* bus_dma_ctl parent    */
 176         struct dev_info *devi_bus_ctl;          /* bus_ctl parent        */
 177 
 178         ddi_prop_t *devi_hw_prop_ptr;           /* head of hw prop list */
 179 
 180         char    *devi_node_name;                /* The 'name' of the node */
 181         char    *devi_compat_names;             /* A list of driver names */
 182         size_t  devi_compat_length;             /* Size of compat_names */
 183 
 184         int (*devi_bus_dma_bindfunc)(dev_info_t *, dev_info_t *,
 185             ddi_dma_handle_t, struct ddi_dma_req *, ddi_dma_cookie_t *,
 186             uint_t *);
 187         int (*devi_bus_dma_unbindfunc)(dev_info_t *, dev_info_t *,
 188             ddi_dma_handle_t);
 189 
 190         char            *devi_devid_str;        /* registered device id */
 191 
 192         /*
 193          * power management entries
 194          * components exist even if the device is not currently power managed
 195          */
 196         struct pm_info *devi_pm_info;           /* 0 => dev not power managed */
 197         uint_t          devi_pm_flags;          /* pm flags */
 198         int             devi_pm_num_components; /* number of components */
 199         size_t          devi_pm_comp_size;      /* size of devi_components */
 200         struct pm_component *devi_pm_components; /* array of pm components */
 201         struct dev_info *devi_pm_ppm;           /* ppm attached to this one */
 202         void            *devi_pm_ppm_private;   /* for use by ppm driver */
 203         int             devi_pm_dev_thresh;     /* "device" threshold */
 204         uint_t          devi_pm_kidsupcnt;      /* # of kids powered up */
 205         struct pm_scan  *devi_pm_scan;          /* pm scan info */
 206         uint_t          devi_pm_noinvolpm;      /* # of descendents no-invol */
 207         uint_t          devi_pm_volpmd;         /* # of voluntarily pm'ed */
 208         kmutex_t        devi_pm_lock;           /* pm lock for state */
 209         kmutex_t        devi_pm_busy_lock;      /* for component busy count */
 210 
 211         uint_t          devi_state;             /* device/bus state flags */
 212                                                 /* see below for definitions */
 213         kcondvar_t      devi_cv;                /* cv */
 214         int             devi_ref;               /* reference count */
 215 
 216         dacf_rsrvlist_t *devi_dacf_tasks;       /* dacf reservation queue */
 217 
 218         ddi_node_class_t devi_node_class;       /* Node class */
 219         int             devi_node_attributes;   /* Node attributes: See below */
 220 
 221         char            *devi_device_class;
 222 
 223         /*
 224          * New mpxio kernel hooks entries
 225          */
 226         int             devi_mdi_component;     /* mpxio component type */
 227         void            *devi_mdi_client;       /* mpxio client information */
 228         void            *devi_mdi_xhci;         /* vhci/phci info */
 229 
 230         ddi_prop_list_t *devi_global_prop_list; /* driver global properties */
 231         major_t         devi_major;             /* driver major number */
 232         ddi_node_state_t devi_node_state;       /* state of node */
 233         uint_t          devi_flags;             /* configuration flags */
 234         int             devi_circular;          /* for recursive operations */
 235         void            *devi_busy_thread;      /* thread operating on node */
 236         void            *devi_taskq;            /* hotplug taskq */
 237 
 238         /* device driver statistical and audit info */
 239         struct devinfo_audit *devi_audit;               /* last state change */
 240 
 241         /*
 242          * FMA support for resource caches and error handlers
 243          */
 244         struct i_ddi_fmhdl      *devi_fmhdl;
 245 
 246         uint_t          devi_cpr_flags;
 247 
 248         /* Owned by DDI interrupt framework */
 249         devinfo_intr_t  *devi_intr_p;
 250 
 251         void            *devi_nex_pm;           /* nexus PM private */
 252 
 253         char            *devi_addr_buf;         /* buffer for devi_addr */
 254 
 255         char            *devi_rebinding_name;   /* binding_name of rebind */
 256 
 257         /* For device contracts that have this dip's minor node as resource */
 258         kmutex_t        devi_ct_lock;           /* contract lock */
 259         kcondvar_t      devi_ct_cv;             /* contract cv */
 260         int             devi_ct_count;          /* # of outstanding responses */
 261         int             devi_ct_neg;            /* neg. occurred on dip */
 262         list_t          devi_ct;
 263 
 264         /* owned by bus framework */
 265         devi_bus_priv_t devi_bus;               /* bus private data */
 266 
 267         /* Declarations of the pure dynamic properties to snapshot */
 268         struct i_ddi_prop_dyn   *devi_prop_dyn_driver;  /* prop_op */
 269         struct i_ddi_prop_dyn   *devi_prop_dyn_parent;  /* bus_prop_op */
 270 
 271 #if defined(__x86)
 272         /* For x86 (Intel and AMD) IOMMU support */
 273         void            *devi_iommu;
 274         iommulib_handle_t       devi_iommulib_handle;
 275         iommulib_nexhandle_t    devi_iommulib_nex_handle;
 276 #endif
 277 
 278         /* Generic callback mechanism */
 279         ddi_cb_t        *devi_cb_p;
 280 
 281         /* ndi 'flavors' */
 282         ndi_flavor_t    devi_flavor;            /* flavor assigned by parent */
 283         ndi_flavor_t    devi_flavorv_n;         /* number of child-flavors */
 284         void            **devi_flavorv;         /* child-flavor specific data */
 285 
 286         /* Owned by hotplug framework */
 287         struct ddi_hp_cn_handle *devi_hp_hdlp;   /* hotplug handle list */
 288 
 289         struct in_node  *devi_in_node; /* pointer to devinfo node's in_node_t */
 290 };
 291 
 292 #define DEVI(dev_info_type)     ((struct dev_info *)(dev_info_type))
 293 
 294 /*
 295  * NB: The 'name' field, for compatibility with old code (both existing
 296  * device drivers and userland code), is now defined as the name used
 297  * to bind the node to a device driver, and not the device node name.
 298  * If the device node name does not define a binding to a device driver,
 299  * and the framework uses a different algorithm to create the binding to
 300  * the driver, the node name and binding name will be different.
 301  *
 302  * Note that this implies that the node name plus instance number does
 303  * NOT create a unique driver id; only the binding name plus instance
 304  * number creates a unique driver id.
 305  *
 306  * New code should not use 'devi_name'; use 'devi_binding_name' or
 307  * 'devi_node_name' and/or the routines that access those fields.
 308  */
 309 
 310 #define devi_name devi_binding_name
 311 
 312 /*
 313  * DDI_CF1, DDI_CF2 and DDI_DRV_UNLOADED are obsolete. They are kept
 314  * around to allow legacy drivers to to compile.
 315  */
 316 #define DDI_CF1(devi)           (DEVI(devi)->devi_addr != NULL)
 317 #define DDI_CF2(devi)           (DEVI(devi)->devi_ops != NULL)
 318 #define DDI_DRV_UNLOADED(devi)  (DEVI(devi)->devi_ops == &mod_nodev_ops)
 319 
 320 /*
 321  * The device state flags (devi_state) contains information regarding
 322  * the state of the device (Online/Offline/Down).  For bus nexus
 323  * devices, the device state also contains state information regarding
 324  * the state of the bus represented by this nexus node.
 325  *
 326  * Device state information is stored in bits [0-7], bus state in bits
 327  * [8-15].
 328  *
 329  * NOTE: all devi_state updates should be protected by devi_lock.
 330  */
 331 #define DEVI_DEVICE_OFFLINE     0x00000001
 332 #define DEVI_DEVICE_DOWN        0x00000002
 333 #define DEVI_DEVICE_DEGRADED    0x00000004
 334 #define DEVI_DEVICE_REMOVED     0x00000008 /* hardware removed */
 335 
 336 #define DEVI_BUS_QUIESCED       0x00000100
 337 #define DEVI_BUS_DOWN           0x00000200
 338 #define DEVI_NDI_CONFIG         0x00000400 /* perform config when attaching */
 339 
 340 #define DEVI_S_ATTACHING        0x00010000
 341 #define DEVI_S_DETACHING        0x00020000
 342 #define DEVI_S_ONLINING         0x00040000
 343 #define DEVI_S_OFFLINING        0x00080000
 344 
 345 #define DEVI_S_INVOKING_DACF    0x00100000 /* busy invoking a dacf task */
 346 
 347 #define DEVI_S_UNBOUND          0x00200000
 348 #define DEVI_S_REPORT           0x08000000 /* report status change */
 349 
 350 #define DEVI_S_EVADD            0x10000000 /* state of devfs event */
 351 #define DEVI_S_EVREMOVE         0x20000000 /* state of devfs event */
 352 #define DEVI_S_NEED_RESET       0x40000000 /* devo_reset should be called */
 353 
 354 /*
 355  * Device state macros.
 356  * o All SET/CLR/DONE users must protect context with devi_lock.
 357  * o DEVI_SET_DEVICE_ONLINE users must do their own DEVI_SET_REPORT.
 358  * o DEVI_SET_DEVICE_{DOWN|DEGRADED|UP} should only be used when !OFFLINE.
 359  * o DEVI_SET_DEVICE_UP clears DOWN and DEGRADED.
 360  */
 361 #define DEVI_IS_DEVICE_OFFLINE(dip)                                     \
 362         ((DEVI(dip)->devi_state & DEVI_DEVICE_OFFLINE) == DEVI_DEVICE_OFFLINE)
 363 
 364 #define DEVI_SET_DEVICE_ONLINE(dip)     {                               \
 365         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 366         if (DEVI(dip)->devi_state & DEVI_DEVICE_DEGRADED) {              \
 367                 mutex_exit(&DEVI(dip)->devi_lock);                       \
 368                 e_ddi_undegrade_finalize(dip);                          \
 369                 mutex_enter(&DEVI(dip)->devi_lock);                      \
 370         }                                                               \
 371         /* setting ONLINE clears DOWN, DEGRADED, OFFLINE */             \
 372         DEVI(dip)->devi_state &= ~(DEVI_DEVICE_DOWN |                    \
 373             DEVI_DEVICE_DEGRADED | DEVI_DEVICE_OFFLINE);                \
 374         }
 375 
 376 #define DEVI_SET_DEVICE_OFFLINE(dip)    {                               \
 377         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 378         DEVI(dip)->devi_state |= (DEVI_DEVICE_OFFLINE | DEVI_S_REPORT);      \
 379         }
 380 
 381 #define DEVI_IS_DEVICE_DOWN(dip)                                        \
 382         ((DEVI(dip)->devi_state & DEVI_DEVICE_DOWN) == DEVI_DEVICE_DOWN)
 383 
 384 #define DEVI_SET_DEVICE_DOWN(dip)       {                               \
 385         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 386         ASSERT(!DEVI_IS_DEVICE_OFFLINE(dip));                           \
 387         DEVI(dip)->devi_state |= (DEVI_DEVICE_DOWN | DEVI_S_REPORT); \
 388         }
 389 
 390 #define DEVI_IS_DEVICE_DEGRADED(dip)                                    \
 391         ((DEVI(dip)->devi_state &                                        \
 392             (DEVI_DEVICE_DEGRADED|DEVI_DEVICE_DOWN)) == DEVI_DEVICE_DEGRADED)
 393 
 394 #define DEVI_SET_DEVICE_DEGRADED(dip)   {                               \
 395         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 396         ASSERT(!DEVI_IS_DEVICE_OFFLINE(dip));                           \
 397         mutex_exit(&DEVI(dip)->devi_lock);                               \
 398         e_ddi_degrade_finalize(dip);                                    \
 399         mutex_enter(&DEVI(dip)->devi_lock);                              \
 400         DEVI(dip)->devi_state |= (DEVI_DEVICE_DEGRADED | DEVI_S_REPORT); \
 401         }
 402 
 403 #define DEVI_SET_DEVICE_UP(dip)         {                               \
 404         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 405         ASSERT(!DEVI_IS_DEVICE_OFFLINE(dip));                           \
 406         if (DEVI(dip)->devi_state & DEVI_DEVICE_DEGRADED) {              \
 407                 mutex_exit(&DEVI(dip)->devi_lock);                       \
 408                 e_ddi_undegrade_finalize(dip);                          \
 409                 mutex_enter(&DEVI(dip)->devi_lock);                      \
 410         }                                                               \
 411         DEVI(dip)->devi_state &= ~(DEVI_DEVICE_DEGRADED | DEVI_DEVICE_DOWN); \
 412         DEVI(dip)->devi_state |= DEVI_S_REPORT;                              \
 413         }
 414 
 415 /* Device removal and insertion */
 416 #define DEVI_IS_DEVICE_REMOVED(dip)                                     \
 417         ((DEVI(dip)->devi_state & DEVI_DEVICE_REMOVED) == DEVI_DEVICE_REMOVED)
 418 
 419 #define DEVI_SET_DEVICE_REMOVED(dip)    {                               \
 420         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 421         DEVI(dip)->devi_state |= DEVI_DEVICE_REMOVED | DEVI_S_REPORT;        \
 422         }
 423 
 424 #define DEVI_SET_DEVICE_REINSERTED(dip) {                               \
 425         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 426         DEVI(dip)->devi_state &= ~DEVI_DEVICE_REMOVED;                   \
 427         DEVI(dip)->devi_state |= DEVI_S_REPORT;                              \
 428         }
 429 
 430 /* Bus state change macros */
 431 #define DEVI_IS_BUS_QUIESCED(dip)                                       \
 432         ((DEVI(dip)->devi_state & DEVI_BUS_QUIESCED) == DEVI_BUS_QUIESCED)
 433 
 434 #define DEVI_SET_BUS_ACTIVE(dip)        {                               \
 435         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 436         DEVI(dip)->devi_state &= ~DEVI_BUS_QUIESCED;                     \
 437         DEVI(dip)->devi_state |= DEVI_S_REPORT;                              \
 438         }
 439 
 440 #define DEVI_SET_BUS_QUIESCE(dip)       {                               \
 441         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 442         DEVI(dip)->devi_state |= (DEVI_BUS_QUIESCED | DEVI_S_REPORT);        \
 443         }
 444 
 445 #define DEVI_IS_BUS_DOWN(dip)                                           \
 446         ((DEVI(dip)->devi_state & DEVI_BUS_DOWN) == DEVI_BUS_DOWN)
 447 
 448 #define DEVI_SET_BUS_UP(dip)            {                               \
 449         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 450         DEVI(dip)->devi_state &= ~DEVI_BUS_DOWN;                 \
 451         DEVI(dip)->devi_state |= DEVI_S_REPORT;                              \
 452         }
 453 
 454 #define DEVI_SET_BUS_DOWN(dip)          {                               \
 455         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 456         DEVI(dip)->devi_state |= (DEVI_BUS_DOWN | DEVI_S_REPORT);    \
 457         }
 458 
 459 /* Status change report needed */
 460 #define DEVI_NEED_REPORT(dip)                                           \
 461         ((DEVI(dip)->devi_state & DEVI_S_REPORT) == DEVI_S_REPORT)
 462 
 463 #define DEVI_SET_REPORT(dip)            {                               \
 464         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 465         DEVI(dip)->devi_state |= DEVI_S_REPORT;                              \
 466         }
 467 
 468 #define DEVI_REPORT_DONE(dip)           {                               \
 469         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 470         DEVI(dip)->devi_state &= ~DEVI_S_REPORT;                 \
 471         }
 472 
 473 /* Do an NDI_CONFIG for its children */
 474 #define DEVI_NEED_NDI_CONFIG(dip)                                       \
 475         ((DEVI(dip)->devi_state & DEVI_NDI_CONFIG) == DEVI_NDI_CONFIG)
 476 
 477 #define DEVI_SET_NDI_CONFIG(dip)        {                               \
 478         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 479         DEVI(dip)->devi_state |= DEVI_NDI_CONFIG;                    \
 480         }
 481 
 482 #define DEVI_CLR_NDI_CONFIG(dip)        {                               \
 483         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 484         DEVI(dip)->devi_state &= ~DEVI_NDI_CONFIG;                       \
 485         }
 486 
 487 /* Attaching or detaching state */
 488 #define DEVI_IS_ATTACHING(dip)                                          \
 489         ((DEVI(dip)->devi_state & DEVI_S_ATTACHING) == DEVI_S_ATTACHING)
 490 
 491 #define DEVI_SET_ATTACHING(dip)         {                               \
 492         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 493         DEVI(dip)->devi_state |= DEVI_S_ATTACHING;                   \
 494         }
 495 
 496 #define DEVI_CLR_ATTACHING(dip)         {                               \
 497         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 498         DEVI(dip)->devi_state &= ~DEVI_S_ATTACHING;                      \
 499         }
 500 
 501 #define DEVI_IS_DETACHING(dip)                                          \
 502         ((DEVI(dip)->devi_state & DEVI_S_DETACHING) == DEVI_S_DETACHING)
 503 
 504 #define DEVI_SET_DETACHING(dip)         {                               \
 505         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 506         DEVI(dip)->devi_state |= DEVI_S_DETACHING;                   \
 507         }
 508 
 509 #define DEVI_CLR_DETACHING(dip)         {                               \
 510         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 511         DEVI(dip)->devi_state &= ~DEVI_S_DETACHING;                      \
 512         }
 513 
 514 /* Onlining or offlining state */
 515 #define DEVI_IS_ONLINING(dip)                                           \
 516         ((DEVI(dip)->devi_state & DEVI_S_ONLINING) == DEVI_S_ONLINING)
 517 
 518 #define DEVI_SET_ONLINING(dip)          {                               \
 519         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 520         DEVI(dip)->devi_state |= DEVI_S_ONLINING;                    \
 521         }
 522 
 523 #define DEVI_CLR_ONLINING(dip)          {                               \
 524         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 525         DEVI(dip)->devi_state &= ~DEVI_S_ONLINING;                       \
 526         }
 527 
 528 #define DEVI_IS_OFFLINING(dip)                                          \
 529         ((DEVI(dip)->devi_state & DEVI_S_OFFLINING) == DEVI_S_OFFLINING)
 530 
 531 #define DEVI_SET_OFFLINING(dip)         {                               \
 532         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 533         DEVI(dip)->devi_state |= DEVI_S_OFFLINING;                   \
 534         }
 535 
 536 #define DEVI_CLR_OFFLINING(dip)         {                               \
 537         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 538         DEVI(dip)->devi_state &= ~DEVI_S_OFFLINING;                      \
 539         }
 540 
 541 #define DEVI_IS_IN_RECONFIG(dip)                                        \
 542         (DEVI(dip)->devi_state & (DEVI_S_OFFLINING | DEVI_S_ONLINING))
 543 
 544 /* Busy invoking a dacf task against this node */
 545 #define DEVI_IS_INVOKING_DACF(dip)                                      \
 546         ((DEVI(dip)->devi_state & DEVI_S_INVOKING_DACF) == DEVI_S_INVOKING_DACF)
 547 
 548 #define DEVI_SET_INVOKING_DACF(dip)     {                               \
 549         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 550         DEVI(dip)->devi_state |= DEVI_S_INVOKING_DACF;                       \
 551         }
 552 
 553 #define DEVI_CLR_INVOKING_DACF(dip)     {                               \
 554         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 555         DEVI(dip)->devi_state &= ~DEVI_S_INVOKING_DACF;                  \
 556         }
 557 
 558 /* Events for add/remove */
 559 #define DEVI_EVADD(dip)                                                 \
 560         ((DEVI(dip)->devi_state & DEVI_S_EVADD) == DEVI_S_EVADD)
 561 
 562 #define DEVI_SET_EVADD(dip)             {                               \
 563         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 564         DEVI(dip)->devi_state &= ~DEVI_S_EVREMOVE;                       \
 565         DEVI(dip)->devi_state |= DEVI_S_EVADD;                               \
 566         }
 567 
 568 #define DEVI_EVREMOVE(dip)                                              \
 569         ((DEVI(dip)->devi_state & DEVI_S_EVREMOVE) == DEVI_S_EVREMOVE)
 570 
 571 #define DEVI_SET_EVREMOVE(dip)          {                               \
 572         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 573         DEVI(dip)->devi_state &= ~DEVI_S_EVADD;                          \
 574         DEVI(dip)->devi_state |= DEVI_S_EVREMOVE;                    \
 575         }
 576 
 577 #define DEVI_SET_EVUNINIT(dip)          {                               \
 578         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 579         DEVI(dip)->devi_state &= ~(DEVI_S_EVADD | DEVI_S_EVREMOVE);      \
 580         }
 581 
 582 /* Need to call the devo_reset entry point for this device at shutdown */
 583 #define DEVI_NEED_RESET(dip)                                            \
 584         ((DEVI(dip)->devi_state & DEVI_S_NEED_RESET) == DEVI_S_NEED_RESET)
 585 
 586 #define DEVI_SET_NEED_RESET(dip)        {                               \
 587         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 588         DEVI(dip)->devi_state |= DEVI_S_NEED_RESET;                  \
 589         }
 590 
 591 #define DEVI_CLR_NEED_RESET(dip)        {                               \
 592         ASSERT(mutex_owned(&DEVI(dip)->devi_lock));                      \
 593         DEVI(dip)->devi_state &= ~DEVI_S_NEED_RESET;                     \
 594         }
 595 
 596 /*
 597  * devi_flags bits
 598  *
 599  * NOTE: all devi_state updates should be protected by devi_lock.
 600  */
 601 #define DEVI_BUSY               0x00000001 /* busy configuring children */
 602 #define DEVI_MADE_CHILDREN      0x00000002 /* children made from specs */
 603 #define DEVI_ATTACHED_CHILDREN  0x00000004 /* attached all existing children */
 604 #define DEVI_BRANCH_HELD        0x00000008 /* branch rooted at this dip held */
 605 #define DEVI_NO_BIND            0x00000010 /* prevent driver binding */
 606 #define DEVI_CACHED_DEVID       0x00000020 /* devid cached in devid cache */
 607 #define DEVI_PHCI_SIGNALS_VHCI  0x00000040 /* pHCI ndi_devi_exit signals vHCI */
 608 #define DEVI_REBIND             0x00000080 /* post initchild driver rebind */
 609 #define DEVI_RETIRED            0x00000100 /* device is retired */
 610 #define DEVI_RETIRING           0x00000200 /* being evaluated for retire */
 611 #define DEVI_R_CONSTRAINT       0x00000400 /* constraints have been applied  */
 612 #define DEVI_R_BLOCKED          0x00000800 /* constraints block retire  */
 613 #define DEVI_CT_NOP             0x00001000 /* NOP contract event occurred */
 614 #define DEVI_PCI_DEVICE         0x00002000 /* dip is PCI */
 615 #define DEVI_GONE               0x00004000 /* device is physically removed */
 616 
 617 #define DEVI_BUSY_CHANGING(dip) (DEVI(dip)->devi_flags & DEVI_BUSY)
 618 #define DEVI_BUSY_OWNED(dip)    (DEVI_BUSY_CHANGING(dip) &&     \
 619         ((DEVI(dip))->devi_busy_thread == curthread))
 620 
 621 #define DEVI_IS_PCI(dip)        (DEVI(dip)->devi_flags & DEVI_PCI_DEVICE)
 622 #define DEVI_SET_PCI(dip)       (DEVI(dip)->devi_flags |= (DEVI_PCI_DEVICE))
 623 
 624 #define DEVI_IS_GONE(dip)       (DEVI(dip)->devi_flags & DEVI_GONE)
 625 #define DEVI_SET_GONE(dip)      (DEVI(dip)->devi_flags |= DEVI_GONE)
 626 #define DEVI_UNSET_GONE(dip)    (DEVI(dip)->devi_flags &= ~DEVI_GONE)
 627 
 628 char    *i_ddi_devi_class(dev_info_t *);
 629 int     i_ddi_set_devi_class(dev_info_t *, char *, int);
 630 
 631 /*
 632  * This structure represents one piece of bus space occupied by a given
 633  * device. It is used in an array for devices with multiple address windows.
 634  */
 635 struct regspec {
 636         uint_t regspec_bustype;         /* cookie for bus type it's on */
 637         uint_t regspec_addr;            /* address of reg relative to bus */
 638         uint_t regspec_size;            /* size of this register set */
 639 };
 640 
 641 /*
 642  * This is a version of the above structure that works for 64-bit mappings and
 643  * doesn't rely on overloading of fields as is done on SPARC. Eventually the
 644  * struct regspec should be replaced with this.
 645  */
 646 struct regspec64 {
 647         uint64_t regspec_bustype;       /* cookie for bus type it's on */
 648         uint64_t regspec_addr;          /* address of reg relative to bus */
 649         uint64_t regspec_size;          /* size of this register set */
 650 };
 651 
 652 /*
 653  * This structure represents one piece of nexus bus space.
 654  * It is used in an array for nexi with multiple bus spaces
 655  * to define the childs offsets in the parents bus space.
 656  */
 657 struct rangespec {
 658         uint_t rng_cbustype;            /* Child's address, hi order */
 659         uint_t rng_coffset;             /* Child's address, lo order */
 660         uint_t rng_bustype;             /* Parent's address, hi order */
 661         uint_t rng_offset;              /* Parent's address, lo order */
 662         uint_t rng_size;                /* size of space for this entry */
 663 };
 664 
 665 #ifdef _KERNEL
 666 
 667 typedef enum {
 668         DDI_PRE = 0,
 669         DDI_POST = 1
 670 } ddi_pre_post_t;
 671 
 672 /*
 673  * This structure represents notification of a child attach event
 674  * These could both be the same if attach/detach commands were in the
 675  * same name space.
 676  * Note that the target dip is passed as an arg already.
 677  */
 678 struct attachspec {
 679         ddi_attach_cmd_t cmd;   /* type of event */
 680         ddi_pre_post_t  when;   /* one of DDI_PRE or DDI_POST */
 681         dev_info_t      *pdip;  /* parent of attaching node */
 682         int             result; /* result of attach op (post command only) */
 683 };
 684 
 685 /*
 686  * This structure represents notification of a child detach event
 687  * Note that the target dip is passed as an arg already.
 688  */
 689 struct detachspec {
 690         ddi_detach_cmd_t cmd;   /* type of event */
 691         ddi_pre_post_t  when;   /* one of DDI_PRE or DDI_POST */
 692         dev_info_t      *pdip;  /* parent of detaching node */
 693         int             result; /* result of detach op (post command only) */
 694 };
 695 
 696 #endif /* _KERNEL */
 697 
 698 typedef enum {
 699         DDM_MINOR = 0,
 700         DDM_ALIAS,
 701         DDM_DEFAULT,
 702         DDM_INTERNAL_PATH
 703 } ddi_minor_type;
 704 
 705 /* implementation flags for driver specified device access control */
 706 #define DM_NO_FSPERM    0x1
 707 
 708 struct devplcy;
 709 
 710 struct ddi_minor {
 711         char            *name;          /* name of node */
 712         dev_t           dev;            /* device number */
 713         int             spec_type;      /* block or char */
 714         int             flags;          /* access flags */
 715         char            *node_type;     /* block, byte, serial, network */
 716         struct devplcy  *node_priv;     /* privilege for this minor */
 717         mode_t          priv_mode;      /* default apparent privilege mode */
 718 };
 719 
 720 /*
 721  * devi_node_attributes contains node attributes private to the
 722  * ddi implementation. As a consumer, do not use these bit definitions
 723  * directly, use the ndi functions that check for the existence of the
 724  * specific node attributes.
 725  *
 726  * DDI_PERSISTENT indicates a 'persistent' node; one that is not
 727  * automatically freed by the framework if the driver is unloaded
 728  * or the driver fails to attach to this node.
 729  *
 730  * DDI_AUTO_ASSIGNED_NODEID indicates that the nodeid was auto-assigned
 731  * by the framework and should be auto-freed if the node is removed.
 732  *
 733  * DDI_VHCI_NODE indicates that the node type is VHCI. This flag
 734  * must be set by ndi_devi_config_vhci() routine only.
 735  *
 736  * DDI_HIDDEN_NODE indicates that the node should not show up in snapshots
 737  * or in /devices.
 738  *
 739  * DDI_HOTPLUG_NODE indicates that the node created by nexus hotplug.
 740  */
 741 #define DDI_PERSISTENT                  0x01
 742 #define DDI_AUTO_ASSIGNED_NODEID        0x02
 743 #define DDI_VHCI_NODE                   0x04
 744 #define DDI_HIDDEN_NODE                 0x08
 745 #define DDI_HOTPLUG_NODE                0x10
 746 
 747 #define DEVI_VHCI_NODE(dip)                                             \
 748         (DEVI(dip)->devi_node_attributes & DDI_VHCI_NODE)
 749 
 750 /*
 751  * The ddi_minor_data structure gets filled in by ddi_create_minor_node.
 752  * It then gets attached to the devinfo node as a property.
 753  */
 754 struct ddi_minor_data {
 755         struct ddi_minor_data *next;    /* next one in the chain */
 756         dev_info_t      *dip;           /* pointer to devinfo node */
 757         ddi_minor_type  type;           /* Following data type */
 758         struct ddi_minor d_minor;       /* Actual minor node data */
 759 };
 760 
 761 #define ddm_name        d_minor.name
 762 #define ddm_dev         d_minor.dev
 763 #define ddm_flags       d_minor.flags
 764 #define ddm_spec_type   d_minor.spec_type
 765 #define ddm_node_type   d_minor.node_type
 766 #define ddm_node_priv   d_minor.node_priv
 767 #define ddm_priv_mode   d_minor.priv_mode
 768 
 769 /*
 770  * parent private data structure contains register, interrupt, property
 771  * and range information.
 772  */
 773 struct ddi_parent_private_data {
 774         int par_nreg;                   /* number of regs */
 775         struct regspec *par_reg;        /* array of regs */
 776         int par_nintr;                  /* number of interrupts */
 777         struct intrspec *par_intr;      /* array of possible interrupts */
 778         int par_nrng;                   /* number of ranges */
 779         struct rangespec *par_rng;      /* array of ranges */
 780 };
 781 #define DEVI_PD(d)      \
 782         ((struct ddi_parent_private_data *)DEVI((d))->devi_parent_data)
 783 
 784 #define sparc_pd_getnreg(dev)           (DEVI_PD(dev)->par_nreg)
 785 #define sparc_pd_getnintr(dev)          (DEVI_PD(dev)->par_nintr)
 786 #define sparc_pd_getnrng(dev)           (DEVI_PD(dev)->par_nrng)
 787 #define sparc_pd_getreg(dev, n)         (&DEVI_PD(dev)->par_reg[(n)])
 788 #define sparc_pd_getintr(dev, n)        (&DEVI_PD(dev)->par_intr[(n)])
 789 #define sparc_pd_getrng(dev, n)         (&DEVI_PD(dev)->par_rng[(n)])
 790 
 791 #ifdef _KERNEL
 792 /*
 793  * This data structure is private to the indexed soft state allocator.
 794  */
 795 typedef struct i_ddi_soft_state {
 796         void            **array;        /* the array of pointers */
 797         kmutex_t        lock;           /* serialize access to this struct */
 798         size_t          size;           /* how many bytes per state struct */
 799         size_t          n_items;        /* how many structs herein */
 800         struct i_ddi_soft_state *next;  /* 'dirty' elements */
 801 } i_ddi_soft_state;
 802 
 803 /*
 804  * This data structure is private to the stringhashed soft state allocator.
 805  */
 806 typedef struct i_ddi_soft_state_bystr {
 807         size_t          ss_size;        /* how many bytes per state struct */
 808         mod_hash_t      *ss_mod_hash;   /* hash implementation */
 809 } i_ddi_soft_state_bystr;
 810 
 811 /*
 812  * This data structure is private to the ddi_strid_* implementation
 813  */
 814 typedef struct i_ddi_strid {
 815         size_t          strid_chunksz;
 816         size_t          strid_spacesz;
 817         id_space_t      *strid_space;
 818         mod_hash_t      *strid_byid;
 819         mod_hash_t      *strid_bystr;
 820 } i_ddi_strid;
 821 #endif /* _KERNEL */
 822 
 823 /*
 824  * Solaris DDI DMA implementation structure and function definitions.
 825  *
 826  * Note: no callers of DDI functions must depend upon data structures
 827  * declared below. They are not guaranteed to remain constant.
 828  */
 829 
 830 /*
 831  * Implementation DMA mapping structure.
 832  *
 833  * The publicly visible ddi_dma_req structure is filled
 834  * in by a caller that wishes to map a memory object
 835  * for DMA. Internal to this implementation of the public
 836  * DDI DMA functions this request structure is put together
 837  * with bus nexus specific functions that have additional
 838  * information and constraints as to how to go about doing
 839  * the requested mapping function
 840  *
 841  * In this implementation, some of the information from the
 842  * original requester is retained throughout the lifetime
 843  * of the I/O mapping being active.
 844  */
 845 
 846 /*
 847  * This is the implementation specific description
 848  * of how we've mapped an object for DMA.
 849  */
 850 #if defined(__sparc)
 851 typedef struct ddi_dma_impl {
 852         /*
 853          * DMA mapping information
 854          */
 855         ulong_t dmai_mapping;   /* mapping cookie */
 856 
 857         /*
 858          * Size of the current mapping, in bytes.
 859          *
 860          * Note that this is distinct from the size of the object being mapped
 861          * for DVMA. We might have only a portion of the object mapped at any
 862          * given point in time.
 863          */
 864         uint_t  dmai_size;
 865 
 866         /*
 867          * Offset, in bytes, into object that is currently mapped.
 868          */
 869         off_t   dmai_offset;
 870 
 871         /*
 872          * Information gathered from the original DMA mapping
 873          * request and saved for the lifetime of the mapping.
 874          */
 875         uint_t          dmai_minxfer;
 876         uint_t          dmai_burstsizes;
 877         uint_t          dmai_ndvmapages;
 878         uint_t          dmai_pool;      /* cached DVMA space */
 879         uint_t          dmai_rflags;    /* requester's flags + ours */
 880         uint_t          dmai_inuse;     /* active handle? */
 881         uint_t          dmai_nwin;
 882         uint_t          dmai_winsize;
 883         caddr_t         dmai_nexus_private;
 884         void            *dmai_iopte;
 885         uint_t          *dmai_sbi;
 886         void            *dmai_minfo;    /* random mapping information */
 887         dev_info_t      *dmai_rdip;     /* original requester's dev_info_t */
 888         ddi_dma_obj_t   dmai_object;    /* requester's object */
 889         ddi_dma_attr_t  dmai_attr;      /* DMA attributes */
 890         ddi_dma_cookie_t *dmai_cookie;  /* pointer to first DMA cookie */
 891 
 892         int             (*dmai_fault_check)(struct ddi_dma_impl *handle);
 893         void            (*dmai_fault_notify)(struct ddi_dma_impl *handle);
 894         int             dmai_fault;
 895         ndi_err_t       dmai_error;
 896 
 897 } ddi_dma_impl_t;
 898 
 899 #elif defined(__x86)
 900 
 901 /*
 902  * ddi_dma_impl portion that genunix (sunddi.c) depends on. x86 rootnex
 903  * implementation specific state is in dmai_private.
 904  */
 905 typedef struct ddi_dma_impl {
 906         ddi_dma_cookie_t *dmai_cookie; /* array of DMA cookies */
 907         void            *dmai_private;
 908 
 909         /*
 910          * Information gathered from the original dma mapping
 911          * request and saved for the lifetime of the mapping.
 912          */
 913         uint_t          dmai_minxfer;
 914         uint_t          dmai_burstsizes;
 915         uint_t          dmai_rflags;    /* requester's flags + ours */
 916         int             dmai_nwin;
 917         dev_info_t      *dmai_rdip;     /* original requester's dev_info_t */
 918 
 919         ddi_dma_attr_t  dmai_attr;      /* DMA attributes */
 920 
 921         int             (*dmai_fault_check)(struct ddi_dma_impl *handle);
 922         void            (*dmai_fault_notify)(struct ddi_dma_impl *handle);
 923         int             dmai_fault;
 924         ndi_err_t       dmai_error;
 925 } ddi_dma_impl_t;
 926 
 927 #else
 928 #error "struct ddi_dma_impl not defined for this architecture"
 929 #endif  /* defined(__sparc) */
 930 
 931 /*
 932  * For now DMA segments share state with the DMA handle
 933  */
 934 typedef ddi_dma_impl_t ddi_dma_seg_impl_t;
 935 
 936 /*
 937  * These flags use reserved bits from the dma request flags.
 938  *
 939  * A note about the DMP_NOSYNC flags: the root nexus will
 940  * set these as it sees best. If an intermediate nexus
 941  * actually needs these operations, then during the unwind
 942  * from the call to ddi_dma_bind, the nexus driver *must*
 943  * clear the appropriate flag(s). This is because, as an
 944  * optimization, ddi_dma_sync(9F) looks at these flags before
 945  * deciding to spend the time going back up the tree.
 946  */
 947 
 948 #define _DMCM1  DDI_DMA_RDWR|DDI_DMA_REDZONE|DDI_DMA_PARTIAL
 949 #define _DMCM2  DDI_DMA_CONSISTENT|DMP_VMEREQ
 950 #define DMP_DDIFLAGS    (_DMCM1|_DMCM2)
 951 #define DMP_SHADOW      0x20
 952 #define DMP_LKIOPB      0x40
 953 #define DMP_LKSYSV      0x80
 954 #define DMP_IOCACHE     0x100
 955 #define DMP_USEHAT      0x200
 956 #define DMP_PHYSADDR    0x400
 957 #define DMP_INVALID     0x800
 958 #define DMP_NOLIMIT     0x1000
 959 #define DMP_VMEREQ      0x10000000
 960 #define DMP_BYPASSNEXUS 0x20000000
 961 #define DMP_NODEVSYNC   0x40000000
 962 #define DMP_NOCPUSYNC   0x80000000
 963 #define DMP_NOSYNC      (DMP_NODEVSYNC|DMP_NOCPUSYNC)
 964 
 965 /*
 966  * In order to complete a device to device mapping that
 967  * has percolated as high as an IU nexus (gone that high
 968  * because the DMA request is a VADDR type), we define
 969  * structure to use with the DDI_CTLOPS_DMAPMAPC request
 970  * that re-traverses the request tree to finish the
 971  * DMA 'mapping' for a device.
 972  */
 973 struct dma_phys_mapc {
 974         struct ddi_dma_req *dma_req;    /* original request */
 975         ddi_dma_impl_t *mp;             /* current handle, or none */
 976         int nptes;                      /* number of ptes */
 977         void *ptes;                     /* ptes already read */
 978 };
 979 
 980 #define MAXCALLBACK             20
 981 
 982 /*
 983  * Callback definitions
 984  */
 985 struct ddi_callback {
 986         struct ddi_callback     *c_nfree;
 987         struct ddi_callback     *c_nlist;
 988         int                     (*c_call)();
 989         int                     c_count;
 990         caddr_t                 c_arg;
 991         size_t                  c_size;
 992 };
 993 
 994 /*
 995  * Pure dynamic property declaration. A pure dynamic property is a property
 996  * for which a driver's prop_op(9E) implementation will return a value on
 997  * demand, but the property name does not exist on a property list (global,
 998  * driver, system, or hardware) - the person asking for the value must know
 999  * the name and type information.
1000  *
1001  * For a pure dynamic property to show up in a di_init() devinfo shapshot, the
1002  * devinfo driver must know name and type. The i_ddi_prop_dyn_t mechanism
1003  * allows a driver to define an array of the name/type information of its
1004  * dynamic properties. When a driver declares its dynamic properties in a
1005  * i_ddi_prop_dyn_t array, and registers that array using
1006  * i_ddi_prop_dyn_driver_set() the devinfo driver has sufficient information
1007  * to represent the properties in a snapshot - calling the driver's
1008  * prop_op(9E) to obtain values.
1009  *
1010  * The last element of a i_ddi_prop_dyn_t is detected via a NULL dp_name value.
1011  *
1012  * A pure dynamic property name associated with a minor_node/dev_t should be
1013  * defined with a dp_spec_type of S_IFCHR or S_IFBLK, as appropriate.  The
1014  * driver's prop_op(9E) entry point will be called for all
1015  * ddi_create_minor_node(9F) nodes of the specified spec_type. For a driver
1016  * where not all minor_node/dev_t combinations support the same named
1017  * properties, it is the responsibility of the prop_op(9E) implementation to
1018  * sort out what combinations are appropriate.
1019  *
1020  * A pure dynamic property of a devinfo node should be defined with a
1021  * dp_spec_type of 0.
1022  *
1023  * NB: Public DDI property interfaces no longer support pure dynamic
1024  * properties, but they are still still used.  A prime example is the cmlb
1025  * implementation of size(9P) properties. Using pure dynamic properties
1026  * reduces the space required to maintain per-partition information. Since
1027  * there are no public interfaces to create pure dynamic properties,
1028  * the i_ddi_prop_dyn_t mechanism should remain private.
1029  */
1030 typedef struct i_ddi_prop_dyn {
1031         char    *dp_name;               /* name of dynamic property */
1032         int     dp_type;                /* DDI_PROP_TYPE_ of property */
1033         int     dp_spec_type;           /* 0, S_IFCHR, S_IFBLK */
1034 } i_ddi_prop_dyn_t;
1035 void                    i_ddi_prop_dyn_driver_set(dev_info_t *,
1036                             i_ddi_prop_dyn_t *);
1037 i_ddi_prop_dyn_t        *i_ddi_prop_dyn_driver_get(dev_info_t *);
1038 void                    i_ddi_prop_dyn_parent_set(dev_info_t *,
1039                             i_ddi_prop_dyn_t *);
1040 i_ddi_prop_dyn_t        *i_ddi_prop_dyn_parent_get(dev_info_t *);
1041 void                    i_ddi_prop_dyn_cache_invalidate(dev_info_t *,
1042                             i_ddi_prop_dyn_t *);
1043 
1044 /*
1045  * Device id - Internal definition.
1046  */
1047 #define DEVID_MAGIC_MSB         0x69
1048 #define DEVID_MAGIC_LSB         0x64
1049 #define DEVID_REV_MSB           0x00
1050 #define DEVID_REV_LSB           0x01
1051 #define DEVID_HINT_SIZE         4
1052 
1053 typedef struct impl_devid {
1054         uchar_t did_magic_hi;                   /* device id magic # (msb) */
1055         uchar_t did_magic_lo;                   /* device id magic # (lsb) */
1056         uchar_t did_rev_hi;                     /* device id revision # (msb) */
1057         uchar_t did_rev_lo;                     /* device id revision # (lsb) */
1058         uchar_t did_type_hi;                    /* device id type (msb) */
1059         uchar_t did_type_lo;                    /* device id type (lsb) */
1060         uchar_t did_len_hi;                     /* length of devid data (msb) */
1061         uchar_t did_len_lo;                     /* length of devid data (lsb) */
1062         char    did_driver[DEVID_HINT_SIZE];    /* driver name - HINT */
1063         char    did_id[1];                      /* start of device id data */
1064 } impl_devid_t;
1065 
1066 #define DEVID_GETTYPE(devid)            ((ushort_t) \
1067                                             (((devid)->did_type_hi << NBBY) + \
1068                                             (devid)->did_type_lo))
1069 
1070 #define DEVID_FORMTYPE(devid, type)     (devid)->did_type_hi = hibyte((type)); \
1071                                         (devid)->did_type_lo = lobyte((type));
1072 
1073 #define DEVID_GETLEN(devid)             ((ushort_t) \
1074                                             (((devid)->did_len_hi << NBBY) + \
1075                                             (devid)->did_len_lo))
1076 
1077 #define DEVID_FORMLEN(devid, len)       (devid)->did_len_hi = hibyte((len)); \
1078                                         (devid)->did_len_lo = lobyte((len));
1079 
1080 /*
1081  * Per PSARC/1995/352, a binary devid contains fields for <magic number>,
1082  * <revision>, <driver_hint>, <type>, <id_length>, and the <id> itself.
1083  * This proposal would encode the binary devid into a string consisting
1084  * of "<magic><revision>,<driver_hint>@<type><id>" as indicated below
1085  * (<id_length> is rederived from the length of the string
1086  * representation of the <id>):
1087  *
1088  *      <magic>           ->"id"
1089  *
1090  *      <rev>             ->"%d"       // "0" -> type of DEVID_NONE  "id0"
1091  *                              // NOTE: PSARC/1995/352 <revision> is "1".
1092  *                              // NOTE: support limited to 10 revisions
1093  *                              //      in current implementation
1094  *
1095  *      <driver_hint>     ->"%s"       // "sd"/"ssd"
1096  *                              // NOTE: driver names limited to 4
1097  *                              //      characters for <revision> "1"
1098  *
1099  *      <type>            ->'w' |      // DEVID_SCSI3_WWN      <hex_id>
1100  *                      'W' |   // DEVID_SCSI3_WWN      <ascii_id>
1101  *                      't' |   // DEVID_SCSI3_VPD_T10  <hex_id>
1102  *                      'T' |   // DEVID_SCSI3_VPD_T10  <ascii_id>
1103  *                      'x' |   // DEVID_SCSI3_VPD_EUI  <hex_id>
1104  *                      'X' |   // DEVID_SCSI3_VPD_EUI  <ascii_id>
1105  *                      'n' |   // DEVID_SCSI3_VPD_NAA  <hex_id>
1106  *                      'N' |   // DEVID_SCSI3_VPD_NAA  <ascii_id>
1107  *                      's' |   // DEVID_SCSI_SERIAL    <hex_id>
1108  *                      'S' |   // DEVID_SCSI_SERIAL    <ascii_id>
1109  *                      'f' |   // DEVID_FAB            <hex_id>
1110  *                      'F' |   // DEVID_FAB            <ascii_id>
1111  *                      'e' |   // DEVID_ENCAP          <hex_id>
1112  *                      'E' |   // DEVID_ENCAP          <ascii_id>
1113  *                      'a' |   // DEVID_ATA_SERIAL     <hex_id>
1114  *                      'A' |   // DEVID_ATA_SERIAL     <ascii_id>
1115  *                      'u' |   // unknown              <hex_id>
1116  *                      'U'     // unknown              <ascii_id>
1117  *                              // NOTE:lower case -> <hex_id>
1118  *                              //      upper case -> <ascii_id>
1119  *                              // NOTE:this covers all types currently
1120  *                              //      defined for <revision> 1.
1121  *                              // NOTE:a <type> can be added
1122  *                              //      without changing the <revision>.
1123  *
1124  *      <id>              -> <ascii_id> |        // <type> is upper case
1125  *                      <hex_id>  // <type> is lower case
1126  *
1127  *      <ascii_id>        // only if all bytes of binary <id> field
1128  *                      // are in the set:
1129  *                      //      [A-Z][a-z][0-9]+-.= and space and 0x00
1130  *                      // the encoded form is:
1131  *                      //      [A-Z][a-z][0-9]+-.= and _ and ~
1132  *                      //      NOTE: ' ' <=> '_', 0x00 <=> '~'
1133  *                      // these sets are chosen to avoid shell
1134  *                      // and conflicts with DDI node names.
1135  *
1136  *      <hex_id>  // if not <ascii_id>; each byte of binary
1137  *                      // <id> maps a to 2 digit ascii hex
1138  *                      // representation in the string.
1139  *
1140  * This encoding provides a meaningful correlation between the /devices
1141  * path and the devid string where possible.
1142  *
1143  *   Fibre:
1144  *      sbus@6,0/SUNW,socal@d,10000/sf@1,0/ssd@w21000020370bb488,0:c,raw
1145  *      id1,ssd@w20000020370bb488:c,raw
1146  *
1147  *   Copper:
1148  *      sbus@7,0/SUNW,fas@3,8800000/sd@a,0:c
1149  *      id1,sd@SIBM_____1XY210__________:c
1150  */
1151 /* determine if a byte of an id meets ASCII representation requirements */
1152 #define DEVID_IDBYTE_ISASCII(b)         (                               \
1153         (((b) >= 'a') && ((b) <= 'z')) ||                         \
1154         (((b) >= 'A') && ((b) <= 'Z')) ||                         \
1155         (((b) >= '0') && ((b) <= '9')) ||                         \
1156         (b == '+') || (b == '-') || (b == '.') || (b == '=') ||         \
1157         (b == ' ') || (b == 0x00))
1158 
1159 /* set type to lower case to indicate that the did_id field is ascii */
1160 #define DEVID_TYPE_SETASCII(c)  (c - 0x20)      /* 'a' -> 'A' */
1161 
1162 /* determine from type if did_id field is binary or ascii */
1163 #define DEVID_TYPE_ISASCII(c)   (((c) >= 'A') && ((c) <= 'Z'))
1164 
1165 /* convert type field from binary to ascii */
1166 #define DEVID_TYPE_BINTOASCII(b)        (                               \
1167         ((b) == DEVID_SCSI3_WWN)        ? 'w' :                         \
1168         ((b) == DEVID_SCSI3_VPD_T10)    ? 't' :                         \
1169         ((b) == DEVID_SCSI3_VPD_EUI)    ? 'x' :                         \
1170         ((b) == DEVID_SCSI3_VPD_NAA)    ? 'n' :                         \
1171         ((b) == DEVID_SCSI_SERIAL)      ? 's' :                         \
1172         ((b) == DEVID_FAB)              ? 'f' :                         \
1173         ((b) == DEVID_ENCAP)            ? 'e' :                         \
1174         ((b) == DEVID_ATA_SERIAL)       ? 'a' :                         \
1175         'u')                                            /* unknown */
1176 
1177 /* convert type field from ascii to binary */
1178 #define DEVID_TYPE_ASCIITOBIN(c)        (                               \
1179         (((c) == 'w') || ((c) == 'W'))  ? DEVID_SCSI3_WWN :             \
1180         (((c) == 't') || ((c) == 'T'))  ? DEVID_SCSI3_VPD_T10 :         \
1181         (((c) == 'x') || ((c) == 'X'))  ? DEVID_SCSI3_VPD_EUI :         \
1182         (((c) == 'n') || ((c) == 'N'))  ? DEVID_SCSI3_VPD_NAA :         \
1183         (((c) == 's') || ((c) == 'S'))  ? DEVID_SCSI_SERIAL :           \
1184         (((c) == 'f') || ((c) == 'F'))  ? DEVID_FAB :                   \
1185         (((c) == 'e') || ((c) == 'E'))  ? DEVID_ENCAP :                 \
1186         (((c) == 'a') || ((c) == 'A'))  ? DEVID_ATA_SERIAL :            \
1187         DEVID_MAXTYPE +1)                               /* unknown */
1188 
1189 /* determine if the type should be forced to hex encoding (non-ascii) */
1190 #define DEVID_TYPE_BIN_FORCEHEX(b) (    \
1191         ((b) == DEVID_SCSI3_WWN) ||     \
1192         ((b) == DEVID_SCSI3_VPD_EUI) || \
1193         ((b) == DEVID_SCSI3_VPD_NAA) || \
1194         ((b) == DEVID_FAB))
1195 
1196 /* determine if the type is from a scsi3 vpd */
1197 #define IS_DEVID_SCSI3_VPD_TYPE(b) (    \
1198         ((b) == DEVID_SCSI3_VPD_T10) || \
1199         ((b) == DEVID_SCSI3_VPD_EUI) || \
1200         ((b) == DEVID_SCSI3_VPD_NAA))
1201 
1202 /* convert rev field from binary to ascii (only supports 10 revs) */
1203 #define DEVID_REV_BINTOASCII(b) (b + '0')
1204 
1205 /* convert rev field from ascii to binary (only supports 10 revs) */
1206 #define DEVID_REV_ASCIITOBIN(c) (c - '0')
1207 
1208 /* name of devid property */
1209 #define DEVID_PROP_NAME "devid"
1210 
1211 /*
1212  * prop_name used by pci_{save,restore}_config_regs()
1213  */
1214 #define SAVED_CONFIG_REGS "pci-config-regs"
1215 #define SAVED_CONFIG_REGS_MASK "pcie-config-regs-mask"
1216 #define SAVED_CONFIG_REGS_CAPINFO "pci-cap-info"
1217 
1218 typedef struct pci_config_header_state {
1219         uint16_t        chs_command;
1220         uint8_t         chs_cache_line_size;
1221         uint8_t         chs_latency_timer;
1222         uint8_t         chs_header_type;
1223         uint8_t         chs_sec_latency_timer;
1224         uint8_t         chs_bridge_control;
1225         uint32_t        chs_base0;
1226         uint32_t        chs_base1;
1227         uint32_t        chs_base2;
1228         uint32_t        chs_base3;
1229         uint32_t        chs_base4;
1230         uint32_t        chs_base5;
1231 } pci_config_header_state_t;
1232 
1233 #ifdef _KERNEL
1234 
1235 typedef struct pci_cap_save_desc {
1236         uint16_t        cap_offset;
1237         uint16_t        cap_id;
1238         uint32_t        cap_nregs;
1239 } pci_cap_save_desc_t;
1240 
1241 typedef struct pci_cap_entry {
1242         uint16_t                cap_id;
1243         uint16_t                cap_reg;
1244         uint16_t                cap_mask;
1245         uint32_t                cap_ndwords;
1246         uint32_t (*cap_save_func)(ddi_acc_handle_t confhdl, uint16_t cap_ptr,
1247             uint32_t *regbuf, uint32_t ndwords);
1248 } pci_cap_entry_t;
1249 
1250 #endif /* _KERNEL */
1251 
1252 #ifdef  __cplusplus
1253 }
1254 #endif
1255 
1256 #endif  /* _SYS_DDI_IMPLDEFS_H */