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