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