Print this page
    
OS-126 Creating a LUN for retired device results in sysevent loop
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/sys/mdi_impldefs.h
          +++ new/usr/src/uts/common/sys/mdi_impldefs.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
       25 +/*
       26 + * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
       27 + */
  25   28  
  26   29  #ifndef _SYS_MDI_IMPLDEFS_H
  27   30  #define _SYS_MDI_IMPLDEFS_H
  28   31  
  29   32  
  30   33  #include <sys/note.h>
  31   34  #include <sys/types.h>
  32   35  #include <sys/sunmdi.h>
  33   36  #include <sys/modhash.h>
  34   37  #include <sys/callb.h>
  35   38  #include <sys/devctl.h>
  36   39  
  37   40  #ifdef  __cplusplus
  38   41  extern "C" {
  39   42  #endif
  40   43  
  41   44  #ifdef _KERNEL
  42   45  
  43   46  /*
  44   47   * Multipath Driver Interfaces
  45   48   *
  46   49   * The multipathing framework is provided in two modules.  The 'mpxio' misc.
  47   50   * module provides the core multipath framework and the 'scsi_vhci' nexus
  48   51   * driver provides the SCSI-III command set driver functionality for
  49   52   * managing Fibre-Channel storage devices.
  50   53   *
  51   54   * As in any multipathing solution there are three major problems to solve:
  52   55   *
  53   56   * 1) Identification and enumeration of multipath client devices.
  54   57   * 2) Optimal path selection when routing I/O requests.
  55   58   * 3) Observability interfaces to snapshot the multipath configuration,
  56   59   *    and infrastructure to provide performance and error statistics.
  57   60   *
  58   61   * The mpxio framework consists of several major components:
  59   62   *
  60   63   * 1) The MDI is the Multiplexed Device Interface; this is the core glue which
  61   64   *    holds the following components together.
  62   65   * 2) vHCI (Virtual Host Controller Interconnect) drivers provide multipathing
  63   66   *    services for a given bus technology (example: 'scsi_vhci' provides
  64   67   *    multipathing support for SCSI-III fibre-channel devices).
  65   68   * 3) pHCI (Physical Host Controller Interconnect) drivers provide transport
  66   69   *    services for a given host controller (example: 'fcp' provides transport
  67   70   *    for fibre-channel devices).
  68   71   * 4) Client Devices are standard Solaris target (or leaf) drivers
  69   72   *    (example: 'ssd' is the standard disk driver for fibre-channel arrays).
  70   73   * 5) Multipath information nodes ('pathinfo' nodes) connect client device
  71   74   *    nodes and pHCI device nodes in the device tree.
  72   75   *
  73   76   * With the scsi_vhci, a QLC card, and mpxio enabled, the device tree might
  74   77   * look like this:
  75   78   *
  76   79   *              /\
  77   80   *             /  ............
  78   81   *     <vHCI>:/               \
  79   82   *      +-----------+   +-----------+
  80   83   *      | scsi_vhci |   |  pci@1f,0 |
  81   84   *      +-----------+   +-----------+
  82   85   *            /   \               \
  83   86   * <Client>: /     \ :<Client>     \ :parent(pHCI)
  84   87   *  +----------+ +-----------+    +-------------+
  85   88   *  | ssd 1    | | ssd 2     |    | qlc@0,0     |
  86   89   *  +----------+ +-----------+    +-------------+
  87   90   *   |            |                /        \
  88   91   *   |            |       <pHCI>: /          \ :<pHCI>
  89   92   *   |            |      +-------------+   +-------------+
  90   93   *   |            |      | pHCI 1 (fp) |   | pHCI 2 (fp) |
  91   94   *   |            |      +-------------+   +-------------+
  92   95   *   |            |          /        |      /          |
  93   96   *   |            |    +------+       |    +------+     |
  94   97   *   |            |    | ssd 3|       |    | ssd  |     |
  95   98   *   |            |    |!mpxio|       |    | (OBP)|     |
  96   99   *   |            |    +------+       |    +------+     |
  97  100   *   |            |                   |                 |
  98  101   *   |            |       <pathinfo>: |                 |
  99  102   *   |            |               +-------+         +--------+
 100  103   *   |            +-------------->| path  |-------->| path   |
 101  104   *   |                            | info  |         | info   |
 102  105   *   |                            | node 1|         | node 3 |
 103  106   *   |                            +-------+         +--------+
 104  107   *   |                                |               |
 105  108   *   |                                |            +~~~~~~~~+
 106  109   *   |                            +-------+        :+--------+
 107  110   *   +--------------------------->| path  |-------->| path   |
 108  111   *                                | info  |        :| info   |
 109  112   *                                | node 2|        +| node 4 |
 110  113   *                                +-------+         +--------+
 111  114   *
 112  115   * The multipath information nodes (mdi_pathinfo nodes) establish the
 113  116   * relationship between the pseudo client driver instance nodes (children
 114  117   * of the vHCI) and the physical host controller interconnect (pHCI
 115  118   * drivers) forming a matrix structure.
 116  119   *
 117  120   * The mpxio module implements locking at multiple granularity levels to
 118  121   * support the needs of various consumers.  The multipath matrix can be
 119  122   * column locked, or row locked depending on the consumer. The intention
 120  123   * is to balance simplicity and performance.
 121  124   *
 122  125   * Locking:
 123  126   *
 124  127   * The devinfo locking still applies:
 125  128   *
 126  129   *   1) An ndi_devi_enter of a parent protects linkage/state of children.
 127  130   *   2) state >= DS_INITIALIZED adds devi_ref of parent
 128  131   *   3) devi_ref at state >= DS_ATTACHED prevents detach(9E).
 129  132   *
 130  133   * The ordering of 1) is (vHCI, pHCI). For a DEBUG kernel this ordering
 131  134   * is asserted by the ndi_devi_enter() implementation.  There is also an
 132  135   * ndi_devi_enter(Client), which is atypical since the client is a leaf.
 133  136   * This is done to synchronize pathinfo nodes during devinfo snapshot (see
 134  137   * di_register_pip) by pretending that the pathinfo nodes are children
 135  138   * of the client.
 136  139   *
 137  140   * In addition to devinfo locking the current implementation utilizes
 138  141   * the following locks:
 139  142   *
 140  143   *   mdi_mutex: protects the global list of vHCIs.
 141  144   *
 142  145   *   vh_phci_mutex: per-vHCI (mutex) lock: protects list of pHCIs registered
 143  146   *   with vHCI.
 144  147   *
 145  148   *   vh_client_mutex: per-vHCI (mutex) lock: protects list/hash of Clients
 146  149   *   associated with vHCI.
 147  150   *
 148  151   *   ph_mutex: per-pHCI (mutex) lock: protects the column (pHCI-mdi_pathinfo
 149  152   *   node list) and per-pHCI structure fields.  mdi_pathinfo node creation,
 150  153   *   deletion and child mdi_pathinfo node state changes are serialized on per
 151  154   *   pHCI basis (Protection against DR).
 152  155   *
 153  156   *   ct_mutex: per-client (mutex) lock: protects the row (client-mdi_pathinfo
 154  157   *   node list) and per-client structure fields.  The client-mdi_pathinfo node
 155  158   *   list is typically walked to select an optimal path when routing I/O
 156  159   *   requests.
 157  160   *
 158  161   *   pi_mutex: per-mdi_pathinfo (mutex) lock: protects the mdi_pathinfo node
 159  162   *   structure fields.
 160  163   *
 161  164   * Note that per-Client structure and per-pHCI fields are freely readable when
 162  165   * corresponding mdi_pathinfo locks are held, since holding an mdi_pathinfo
 163  166   * node guarantees that its corresponding client and pHCI devices will not be
 164  167   * freed.
 165  168   */
 166  169  
 167  170  /*
 168  171   * MDI Client global unique identifier property name string definition
 169  172   */
 170  173  extern const char                       *mdi_client_guid_prop;
 171  174  #define MDI_CLIENT_GUID_PROP            (char *)mdi_client_guid_prop
 172  175  
 173  176  /*
 174  177   * MDI Client load balancing policy definitions
 175  178   *
 176  179   * Load balancing policies are determined on a per-vHCI basis and are
 177  180   * configurable via the vHCI's driver.conf file.
 178  181   */
 179  182  typedef enum {
 180  183          LOAD_BALANCE_NONE,              /* Alternate pathing            */
 181  184          LOAD_BALANCE_RR,                /* Round Robin                  */
 182  185          LOAD_BALANCE_LBA                /* Logical Block Addressing     */
 183  186  } client_lb_t;
 184  187  
 185  188  typedef struct {
 186  189          int region_size;
 187  190  }client_lb_args_t;
 188  191  
 189  192  /*
 190  193   * MDI client load balancing property name/value string definitions
 191  194   */
 192  195  extern const char                       *mdi_load_balance;
 193  196  extern const char                       *mdi_load_balance_none;
 194  197  extern const char                       *mdi_load_balance_ap;
 195  198  extern const char                       *mdi_load_balance_rr;
 196  199  extern const char                       *mdi_load_balance_lba;
 197  200  
 198  201  #define LOAD_BALANCE_PROP               (char *)mdi_load_balance
 199  202  #define LOAD_BALANCE_PROP_NONE          (char *)mdi_load_balance_none
 200  203  #define LOAD_BALANCE_PROP_AP            (char *)mdi_load_balance_ap
 201  204  #define LOAD_BALANCE_PROP_RR            (char *)mdi_load_balance_rr
 202  205  #define LOAD_BALANCE_PROP_LBA           (char *)mdi_load_balance_lba
 203  206  
 204  207  /* default for region size */
 205  208  #define LOAD_BALANCE_DEFAULT_REGION_SIZE        18
 206  209  
 207  210  /*
 208  211   * vHCI drivers:
 209  212   *
 210  213   * vHCI drivers are pseudo nexus drivers which implement multipath services
 211  214   * for a specific command set or bus architecture ('class').  There is a
 212  215   * single instance of the vHCI driver for each command set which supports
 213  216   * multipath devices.
 214  217   *
 215  218   * Each vHCI driver registers the following callbacks from attach(9e).
 216  219   */
 217  220  #define MDI_VHCI_OPS_REV_1              1
 218  221  #define MDI_VHCI_OPS_REV                MDI_VHCI_OPS_REV_1
 219  222  
 220  223  typedef struct mdi_vhci_ops {
 221  224          /* revision management */
 222  225          int     vo_revision;
 223  226  
 224  227          /* mdi_pathinfo node init callback */
 225  228          int     (*vo_pi_init)(dev_info_t *vdip, mdi_pathinfo_t *pip, int flags);
 226  229  
 227  230          /* mdi_pathinfo node uninit callback */
 228  231          int     (*vo_pi_uninit)(dev_info_t *vdip, mdi_pathinfo_t *pip,
 229  232                      int flags);
 230  233  
 231  234          /* mdi_pathinfo node state change callback */
 232  235          int     (*vo_pi_state_change)(dev_info_t *vdip, mdi_pathinfo_t *pip,
 233  236                      mdi_pathinfo_state_t state, uint32_t, int flags);
 234  237  
 235  238          /* Client path failover callback */
 236  239          int     (*vo_failover)(dev_info_t *vdip, dev_info_t *cdip, int flags);
 237  240  
 238  241          /* Client attached callback */
 239  242          void    (*vo_client_attached)(dev_info_t *cdip);
 240  243  
 241  244          /* Ask vHCI if 'cinfo' device is support as a client */
 242  245          int     (*vo_is_dev_supported)(dev_info_t *vdip, dev_info_t *pdip,
 243  246                      void *cinfo);
 244  247  } mdi_vhci_ops_t;
 245  248  
 246  249  /*
 247  250   * An mdi_vhci structure is created and bound to the devinfo node of every
 248  251   * registered vHCI class driver; this happens when a vHCI registers itself from
 249  252   * attach(9e).  This structure is unbound and freed when the vHCI unregisters
 250  253   * at detach(9e) time;
 251  254   *
 252  255   * Each vHCI driver is associated with a vHCI class name; this is the handle
 253  256   * used to register and unregister pHCI drivers for a given transport.
 254  257   *
 255  258   * Locking: Different parts of this structure are guarded by different
 256  259   * locks: global threading of multiple vHCIs and initialization is protected
 257  260   * by mdi_mutex, the list of pHCIs associated with a vHCI is protected by
 258  261   * vh_phci_mutex, and Clients are protected by vh_client_mutex.
 259  262   *
 260  263   * XXX Depending on the context, some of the fields can be freely read without
 261  264   * holding any locks (ex. holding vh_client_mutex lock also guarantees that
 262  265   * the vHCI (parent) cannot be unexpectedly freed).
 263  266   */
 264  267  typedef struct mdi_vhci {
 265  268          /* protected by mdi_mutex... */
 266  269          struct mdi_vhci         *vh_next;       /* next vHCI link       */
 267  270          struct mdi_vhci         *vh_prev;       /* prev vHCI link       */
 268  271          char                    *vh_class;      /* vHCI class name      */
 269  272          dev_info_t              *vh_dip;        /* vHCI devi handle     */
 270  273          int                     vh_refcnt;      /* vHCI reference count */
 271  274          struct mdi_vhci_config  *vh_config;     /* vHCI config          */
 272  275          client_lb_t             vh_lb;          /* vHCI load-balancing  */
 273  276          struct mdi_vhci_ops     *vh_ops;        /* vHCI callback vectors */
 274  277  
 275  278          /* protected by MDI_VHCI_PHCI_LOCK vh_phci_mutex... */
 276  279          kmutex_t                vh_phci_mutex;  /* pHCI mutex           */
 277  280          int                     vh_phci_count;  /* pHCI device count    */
 278  281          struct mdi_phci         *vh_phci_head;  /* pHCI list head       */
 279  282          struct mdi_phci         *vh_phci_tail;  /* pHCI list tail       */
 280  283  
 281  284          /* protected by MDI_VHCI_CLIENT_LOCK vh_client_mutex... */
 282  285          kmutex_t                vh_client_mutex; /* Client mutex        */
 283  286          int                     vh_client_count; /* Client count        */
 284  287          struct client_hash      *vh_client_table; /* Client hash        */
 285  288  } mdi_vhci_t;
 286  289  
 287  290  /*
 288  291   * per-vHCI lock macros
 289  292   */
 290  293  #define MDI_VHCI_PHCI_LOCK(vh)          mutex_enter(&(vh)->vh_phci_mutex)
 291  294  #define MDI_VHCI_PHCI_TRYLOCK(vh)       mutex_tryenter(&(vh)->vh_phci_mutex)
 292  295  #define MDI_VHCI_PHCI_UNLOCK(vh)        mutex_exit(&(vh)->vh_phci_mutex)
 293  296  #ifdef  DEBUG
 294  297  #define MDI_VHCI_PCHI_LOCKED(vh)        MUTEX_HELD(&(vh)->vh_phci_mutex)
 295  298  #endif  /* DEBUG */
 296  299  #define MDI_VHCI_CLIENT_LOCK(vh)        mutex_enter(&(vh)->vh_client_mutex)
 297  300  #define MDI_VHCI_CLIENT_TRYLOCK(vh)     mutex_tryenter(&(vh)->vh_client_mutex)
 298  301  #define MDI_VHCI_CLIENT_UNLOCK(vh)      mutex_exit(&(vh)->vh_client_mutex)
 299  302  #ifdef  DEBUG
 300  303  #define MDI_VHCI_CLIENT_LOCKED(vh)      MUTEX_HELD(&(vh)->vh_client_mutex)
 301  304  #endif  /* DEBUG */
 302  305  
 303  306  
 304  307  /*
 305  308   * GUID Hash definitions
 306  309   *
 307  310   * Since all the mpxio managed devices for a given class are enumerated under
 308  311   * the single vHCI instance for that class, sequentially walking through the
 309  312   * client device link to find a client would be prohibitively slow.
 310  313   */
 311  314  
 312  315  #define CLIENT_HASH_TABLE_SIZE  (32)    /* GUID hash */
 313  316  
 314  317  /*
 315  318   * Client hash table structure
 316  319   */
 317  320  struct client_hash {
 318  321          struct mdi_client       *ct_hash_head;  /* Client hash head     */
 319  322          int                     ct_hash_count;  /* Client hash count    */
 320  323  };
 321  324  
 322  325  
 323  326  /*
 324  327   * pHCI Drivers:
 325  328   *
 326  329   * Physical HBA drivers provide transport services for mpxio-managed devices.
 327  330   * As each pHCI instance is attached, it must register itself with the mpxio
 328  331   * framework using mdi_phci_register().  When the pHCI is detached it must
 329  332   * similarly call mdi_phci_unregister().
 330  333   *
 331  334   * The framework maintains a list of registered pHCI device instances for each
 332  335   * vHCI.  This list involves (vh_phci_count, vh_phci_head, vh_phci_tail) and
 333  336   * (ph_next, ph_prev, ph_vhci) and is protected by vh_phci_mutex.
 334  337   *
 335  338   * Locking order:
 336  339   *
 337  340   * _NOTE(LOCK_ORDER(mdi_mutex, mdi_phci::ph_mutex))             XXX
 338  341   * _NOTE(LOCK_ORDER(mdi_phci::ph_mutex devinfo_tree_lock))              XXX
 339  342   */
 340  343  typedef struct mdi_phci {
 341  344          /* protected by MDI_VHCI_PHCI_LOCK vh_phci_mutex... */
 342  345          struct mdi_phci         *ph_next;       /* next pHCI link       */
 343  346          struct mdi_phci         *ph_prev;       /* prev pHCI link       */
 344  347          dev_info_t              *ph_dip;        /* pHCI devi handle     */
 345  348          struct mdi_vhci         *ph_vhci;       /* pHCI back ref. to vHCI */
 346  349  
 347  350          /* protected by MDI_PHCI_LOCK ph_mutex... */
 348  351          kmutex_t                ph_mutex;       /* per-pHCI mutex       */
 349  352          int                     ph_path_count;  /* pi count             */
 350  353          mdi_pathinfo_t          *ph_path_head;  /* pi list head         */
 351  354          mdi_pathinfo_t          *ph_path_tail;  /* pi list tail         */
 352  355          int                     ph_flags;       /* pHCI operation flags */
 353  356          int                     ph_unstable;    /* Paths in transient state */
 354  357          kcondvar_t              ph_unstable_cv; /* Paths in transient state */
 355  358  
 356  359          /* protected by mdi_phci_[gs]et_vhci_private caller... */
 357  360          void                    *ph_vprivate;   /* vHCI driver private  */
 358  361  } mdi_phci_t;
 359  362  
 360  363  /*
 361  364   * A pHCI device is 'unstable' while one or more paths are in a transitional
 362  365   * state.  Hotplugging is prevented during this state.
 363  366   */
 364  367  #define MDI_PHCI_UNSTABLE(ph)           (ph)->ph_unstable++;
 365  368  #define MDI_PHCI_STABLE(ph) { \
 366  369          (ph)->ph_unstable--; \
 367  370          if ((ph)->ph_unstable == 0) { \
 368  371                  cv_broadcast(&(ph)->ph_unstable_cv); \
 369  372          } \
 370  373  }
 371  374  
 372  375  /*
 373  376   * per-pHCI lock macros
 374  377   */
 375  378  #define MDI_PHCI_LOCK(ph)               mutex_enter(&(ph)->ph_mutex)
 376  379  #define MDI_PHCI_TRYLOCK(ph)            mutex_tryenter(&(ph)->ph_mutex)
 377  380  #define MDI_PHCI_UNLOCK(ph)             mutex_exit(&(ph)->ph_mutex)
 378  381  #ifdef  DEBUG
 379  382  #define MDI_PHCI_LOCKED(vh)             MUTEX_HELD(&(ph)->ph_mutex)
 380  383  #endif  /* DEBUG */
 381  384  
 382  385  /*
 383  386   * pHCI state definitions and macros to track the pHCI driver instance state
 384  387   */
 385  388  #define MDI_PHCI_FLAGS_OFFLINE          0x1     /* pHCI is offline */
 386  389  #define MDI_PHCI_FLAGS_SUSPEND          0x2     /* pHCI is suspended */
 387  390  #define MDI_PHCI_FLAGS_POWER_DOWN       0x4     /* pHCI is power down */
 388  391  #define MDI_PHCI_FLAGS_DETACH           0x8     /* pHCI is detached */
 389  392  #define MDI_PHCI_FLAGS_USER_DISABLE     0x10    /* pHCI is disabled,user */
 390  393  #define MDI_PHCI_FLAGS_D_DISABLE        0x20    /* pHCI is disabled,driver */
 391  394  #define MDI_PHCI_FLAGS_D_DISABLE_TRANS  0x40    /* pHCI is disabled,transient */
 392  395  #define MDI_PHCI_FLAGS_POWER_TRANSITION 0x80    /* pHCI is power transition */
 393  396  
 394  397  #define MDI_PHCI_DISABLE_MASK                                           \
 395  398              (MDI_PHCI_FLAGS_USER_DISABLE | MDI_PHCI_FLAGS_D_DISABLE |   \
 396  399              MDI_PHCI_FLAGS_D_DISABLE_TRANS)
 397  400  
 398  401  #define MDI_PHCI_IS_READY(ph)                                           \
 399  402              (((ph)->ph_flags & MDI_PHCI_DISABLE_MASK) == 0)
 400  403  
 401  404  #define MDI_PHCI_SET_OFFLINE(ph)                                        {\
 402  405              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 403  406              (ph)->ph_flags |= MDI_PHCI_FLAGS_OFFLINE;                   }
 404  407  #define MDI_PHCI_SET_ONLINE(ph)                                         {\
 405  408              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 406  409              (ph)->ph_flags &= ~MDI_PHCI_FLAGS_OFFLINE;                  }
 407  410  #define MDI_PHCI_IS_OFFLINE(ph)                                         \
 408  411              ((ph)->ph_flags & MDI_PHCI_FLAGS_OFFLINE)
 409  412  
 410  413  #define MDI_PHCI_SET_SUSPEND(ph)                                        {\
 411  414              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 412  415              (ph)->ph_flags |= MDI_PHCI_FLAGS_SUSPEND;                   }
 413  416  #define MDI_PHCI_SET_RESUME(ph)                                         {\
 414  417              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 415  418              (ph)->ph_flags &= ~MDI_PHCI_FLAGS_SUSPEND;                  }
 416  419  #define MDI_PHCI_IS_SUSPENDED(ph)                                       \
 417  420              ((ph)->ph_flags & MDI_PHCI_FLAGS_SUSPEND)
 418  421  
 419  422  #define MDI_PHCI_SET_DETACH(ph)                                         {\
 420  423              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 421  424              (ph)->ph_flags |= MDI_PHCI_FLAGS_DETACH;                    }
 422  425  #define MDI_PHCI_SET_ATTACH(ph)                                         {\
 423  426              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 424  427              (ph)->ph_flags &= ~MDI_PHCI_FLAGS_DETACH;                   }
 425  428  
 426  429  #define MDI_PHCI_SET_POWER_DOWN(ph)                                     {\
 427  430              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 428  431              (ph)->ph_flags |= MDI_PHCI_FLAGS_POWER_DOWN;                }
 429  432  #define MDI_PHCI_SET_POWER_UP(ph)                                       {\
 430  433              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 431  434              (ph)->ph_flags &= ~MDI_PHCI_FLAGS_POWER_DOWN;               }
 432  435  #define MDI_PHCI_IS_POWERED_DOWN(ph)                                    \
 433  436              ((ph)->ph_flags & MDI_PHCI_FLAGS_POWER_DOWN)
 434  437  
 435  438  #define MDI_PHCI_SET_USER_ENABLE(ph)                                    {\
 436  439              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 437  440              (ph)->ph_flags &= ~MDI_PHCI_FLAGS_USER_DISABLE;             }
 438  441  #define MDI_PHCI_SET_USER_DISABLE(ph)                                   {\
 439  442              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 440  443              (ph)->ph_flags |= MDI_PHCI_FLAGS_USER_DISABLE;              }
 441  444  #define MDI_PHCI_IS_USER_DISABLED(ph)                                   \
 442  445              ((ph)->ph_flags & MDI_PHCI_FLAGS_USER_DISABLE)
 443  446  
 444  447  #define MDI_PHCI_SET_DRV_ENABLE(ph)                                     {\
 445  448              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 446  449              (ph)->ph_flags &= ~MDI_PHCI_FLAGS_D_DISABLE;                }
 447  450  #define MDI_PHCI_SET_DRV_DISABLE(ph)                                    {\
 448  451              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 449  452              (ph)->ph_flags |= MDI_PHCI_FLAGS_D_DISABLE;                 }
 450  453  #define MDI_PHCI_IS_DRV_DISABLED(ph)                                    \
 451  454              ((ph)->ph_flags & MDI_PHCI_FLAGS_D_DISABLE)
 452  455  
 453  456  #define MDI_PHCI_SET_DRV_ENABLE_TRANSIENT(ph)                           {\
 454  457              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 455  458              (ph)->ph_flags &= ~MDI_PHCI_FLAGS_D_DISABLE_TRANS;          }
 456  459  #define MDI_PHCI_SET_DRV_DISABLE_TRANSIENT(ph)                          {\
 457  460              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 458  461              (ph)->ph_flags |= MDI_PHCI_FLAGS_D_DISABLE_TRANS;           }
 459  462  #define MDI_PHCI_IS_DRV_DISABLED_TRANSIENT(ph)                          \
 460  463              ((ph)->ph_flags & MDI_PHCI_FLAGS_D_DISABLE_TRANS)
 461  464  
 462  465  #define MDI_PHCI_SET_POWER_TRANSITION(ph)                               {\
 463  466              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 464  467              (ph)->ph_flags |= MDI_PHCI_FLAGS_POWER_TRANSITION;          }
 465  468  #define MDI_PHCI_CLEAR_POWER_TRANSITION(ph)                             {\
 466  469              ASSERT(MDI_PHCI_LOCKED(ph));                                \
 467  470              (ph)->ph_flags &= ~MDI_PHCI_FLAGS_POWER_TRANSITION;         }
 468  471  #define MDI_PHCI_IS_POWER_TRANSITION(ph)                                \
 469  472              ((ph)->ph_flags & MDI_PHCI_FLAGS_POWER_TRANSITION)
 470  473  
 471  474  /*
 472  475   * mpxio Managed Clients:
 473  476   *
 474  477   * This framework creates a struct mdi_client for every client device created
 475  478   * by the framework as a result of self-enumeration of target devices by the
 476  479   * registered pHCI devices.  This structure is bound to client device dev_info
 477  480   * node at the time of client device allocation (ndi_devi_alloc(9e)). This
 478  481   * structure is unbound from the dev_info node when mpxio framework removes a
 479  482   * client device node from the system.
 480  483   *
 481  484   * This structure is created when a first path is enumerated and removed when
 482  485   * last path is de-enumerated from the system.
 483  486   *
 484  487   * Multipath client devices are instantiated as children of corresponding vHCI
 485  488   * driver instance. Each client device is uniquely identified by a GUID
 486  489   * provided by target device itself.  The parent vHCI device also maintains a
 487  490   * hashed list of client devices, protected by vh_client_mutex.
 488  491   *
 489  492   * Typically pHCI devices self-enumerate their child devices using taskq,
 490  493   * resulting in multiple paths to the same client device to be enumerated by
 491  494   * competing threads.
 492  495   *
 493  496   * Currently this framework supports two kinds of load-balancing policy
 494  497   * configurable through the vHCI driver configuration files.
 495  498   *
 496  499   * NONE         - Legacy AP mode
 497  500   * Round Robin  - Balance the pHCI load in a Round Robin fashion.
 498  501   *
 499  502   * This framework identifies the client device in three distinct states:
 500  503   *
 501  504   * OPTIMAL      - Client device has at least one redundant path.
 502  505   * DEGRADED     - No redundant paths (critical).  Failure in the current active
 503  506   *                path would result in data access failures.
 504  507   * FAILED       - No paths are available to access this device.
 505  508   *
 506  509   * Locking order:
 507  510   *
 508  511   * _NOTE(LOCK_ORDER(mdi_mutex, mdi_client::ct_mutex))                   XXX
 509  512   * _NOTE(LOCK_ORDER(mdi_client::ct_mutex devinfo_tree_lock))            XXX
 510  513   */
 511  514  typedef struct mdi_client {
 512  515          /* protected by MDI_VHCI_CLIENT_LOCK vh_client_mutex... */
 513  516          struct mdi_client       *ct_hnext;      /* next client          */
 514  517          struct mdi_client       *ct_hprev;      /* prev client          */
 515  518          dev_info_t              *ct_dip;        /* client devi handle   */
 516  519          struct mdi_vhci         *ct_vhci;       /* vHCI back ref        */
 517  520          char                    *ct_drvname;    /* client driver name   */
 518  521          char                    *ct_guid;       /* client guid          */
 519  522          client_lb_t             ct_lb;          /* load balancing scheme */
 520  523          client_lb_args_t        *ct_lb_args;    /* load balancing args */
 521  524  
 522  525  
 523  526          /* protected by MDI_CLIENT_LOCK ct_mutex... */
 524  527          kmutex_t                ct_mutex;       /* per-client mutex     */
 525  528          int                     ct_path_count;  /* multi path count     */
 526  529          mdi_pathinfo_t          *ct_path_head;  /* multi path list head */
 527  530          mdi_pathinfo_t          *ct_path_tail;  /* multi path list tail */
 528  531          mdi_pathinfo_t          *ct_path_last;  /* last path used for i/o */
 529  532          int                     ct_state;       /* state information    */
 530  533          int                     ct_flags;       /* Driver op. flags     */
 531  534          int                     ct_failover_flags;      /* Failover args */
 532  535          int                     ct_failover_status;     /* last fo status */
 533  536          kcondvar_t              ct_failover_cv; /* Failover status cv   */
 534  537          int                     ct_unstable;    /* Paths in transient state */
 535  538          kcondvar_t              ct_unstable_cv; /* Paths in transient state */
 536  539  
 537  540          int                     ct_power_cnt;   /* Hold count on parent power */
 538  541          kcondvar_t              ct_powerchange_cv;
 539  542                                          /* Paths in power transient state */
 540  543          short                   ct_powercnt_config;
 541  544                                          /* held in pre/post config */
 542  545          short                   ct_powercnt_unconfig;
 543  546                                          /* held in pre/post unconfig */
 544  547          int                     ct_powercnt_reset;
 545  548                                          /* ct_power_cnt was reset */
 546  549  
 547  550          void                    *ct_cprivate;   /* client driver private */
 548  551          void                    *ct_vprivate;   /* vHCI driver private  */
 549  552  } mdi_client_t;
 550  553  
 551  554  /*
 552  555   * per-Client device locking definitions
 553  556   */
 554  557  #define MDI_CLIENT_LOCK(ct)             mutex_enter(&(ct)->ct_mutex)
 555  558  #define MDI_CLIENT_TRYLOCK(ct)          mutex_tryenter(&(ct)->ct_mutex)
 556  559  #define MDI_CLIENT_UNLOCK(ct)           mutex_exit(&(ct)->ct_mutex)
 557  560  #ifdef  DEBUG
 558  561  #define MDI_CLIENT_LOCKED(ct)           MUTEX_HELD(&(ct)->ct_mutex)
 559  562  #endif  /* DEBUG */
 560  563  
 561  564  /*
 562  565   * A Client device is in unstable while one or more paths are in transitional
 563  566   * state.  We do not allow failover to take place while paths are in transient
 564  567   * state. Similarly we do not allow state transition while client device
 565  568   * failover is in progress.
 566  569   */
 567  570  #define MDI_CLIENT_UNSTABLE(ct)         (ct)->ct_unstable++;
 568  571  #define MDI_CLIENT_STABLE(ct) { \
 569  572          (ct)->ct_unstable--; \
 570  573          if ((ct)->ct_unstable == 0) { \
 571  574                  cv_broadcast(&(ct)->ct_unstable_cv); \
 572  575          } \
 573  576  }
 574  577  
 575  578  /*
 576  579   * Client driver instance state definitions:
 577  580   */
  
    | 
      ↓ open down ↓ | 
    543 lines elided | 
    
      ↑ open up ↑ | 
  
 578  581  #define MDI_CLIENT_FLAGS_OFFLINE                0x00000001
 579  582  #define MDI_CLIENT_FLAGS_SUSPEND                0x00000002
 580  583  #define MDI_CLIENT_FLAGS_POWER_DOWN             0x00000004
 581  584  #define MDI_CLIENT_FLAGS_DETACH                 0x00000008
 582  585  #define MDI_CLIENT_FLAGS_FAILOVER               0x00000010
 583  586  #define MDI_CLIENT_FLAGS_REPORT_DEV             0x00000020
 584  587  #define MDI_CLIENT_FLAGS_PATH_FREE_IN_PROGRESS  0x00000040
 585  588  #define MDI_CLIENT_FLAGS_ASYNC_FREE             0x00000080
 586  589  #define MDI_CLIENT_FLAGS_DEV_NOT_SUPPORTED      0x00000100
 587  590  #define MDI_CLIENT_FLAGS_POWER_TRANSITION       0x00000200
      591 +#define MDI_CLIENT_FLAGS_NO_EVENT               0x10000000
 588  592  
 589  593  #define MDI_CLIENT_SET_OFFLINE(ct)                                      {\
 590  594              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 591  595              (ct)->ct_flags |= MDI_CLIENT_FLAGS_OFFLINE;                 }
 592  596  #define MDI_CLIENT_SET_ONLINE(ct)                                       {\
 593  597              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 594  598              (ct)->ct_flags &= ~MDI_CLIENT_FLAGS_OFFLINE;                }
 595  599  #define MDI_CLIENT_IS_OFFLINE(ct) \
 596  600              ((ct)->ct_flags & MDI_CLIENT_FLAGS_OFFLINE)
 597  601  
 598  602  #define MDI_CLIENT_SET_SUSPEND(ct)                                      {\
 599  603              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 600  604              (ct)->ct_flags |= MDI_CLIENT_FLAGS_SUSPEND;                 }
 601  605  #define MDI_CLIENT_SET_RESUME(ct)                                       {\
 602  606              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 603  607              (ct)->ct_flags &= ~MDI_CLIENT_FLAGS_SUSPEND;                }
 604  608  #define MDI_CLIENT_IS_SUSPENDED(ct) \
 605  609              ((ct)->ct_flags & MDI_CLIENT_FLAGS_SUSPEND)
 606  610  
 607  611  #define MDI_CLIENT_SET_POWER_DOWN(ct)                                   {\
 608  612              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 609  613              (ct)->ct_flags |= MDI_CLIENT_FLAGS_POWER_DOWN;              }
 610  614  #define MDI_CLIENT_SET_POWER_UP(ct)                                     {\
 611  615              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 612  616              (ct)->ct_flags &= ~MDI_CLIENT_FLAGS_POWER_DOWN;             }
 613  617  #define MDI_CLIENT_IS_POWERED_DOWN(ct) \
 614  618              ((ct)->ct_flags & MDI_CLIENT_FLAGS_POWER_DOWN)
 615  619  
 616  620  #define MDI_CLIENT_SET_POWER_TRANSITION(ct)                             {\
 617  621              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 618  622              (ct)->ct_flags |= MDI_CLIENT_FLAGS_POWER_TRANSITION;        }
 619  623  #define MDI_CLIENT_CLEAR_POWER_TRANSITION(ct)                           {\
 620  624              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 621  625              (ct)->ct_flags &= ~MDI_CLIENT_FLAGS_POWER_TRANSITION;       }
 622  626  #define MDI_CLIENT_IS_POWER_TRANSITION(ct) \
 623  627              ((ct)->ct_flags & MDI_CLIENT_FLAGS_POWER_TRANSITION)
 624  628  
 625  629  #define MDI_CLIENT_SET_DETACH(ct)                                       {\
 626  630              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 627  631              (ct)->ct_flags |= MDI_CLIENT_FLAGS_DETACH;                  }
 628  632  #define MDI_CLIENT_SET_ATTACH(ct)                                       {\
 629  633              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 630  634              (ct)->ct_flags &= ~MDI_CLIENT_FLAGS_DETACH;                 }
 631  635  #define MDI_CLIENT_IS_DETACHED(ct) \
 632  636              ((ct)->ct_flags & MDI_CLIENT_FLAGS_DETACH)
 633  637  
 634  638  #define MDI_CLIENT_SET_FAILOVER_IN_PROGRESS(ct)                         {\
 635  639              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 636  640              (ct)->ct_flags |= MDI_CLIENT_FLAGS_FAILOVER;                }
 637  641  #define MDI_CLIENT_CLEAR_FAILOVER_IN_PROGRESS(ct)                       {\
 638  642              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 639  643              (ct)->ct_flags &= ~MDI_CLIENT_FLAGS_FAILOVER;               }
 640  644  #define MDI_CLIENT_IS_FAILOVER_IN_PROGRESS(ct) \
 641  645              ((ct)->ct_flags & MDI_CLIENT_FLAGS_FAILOVER)
 642  646  
 643  647  #define MDI_CLIENT_SET_REPORT_DEV_NEEDED(ct)                            {\
 644  648              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 645  649              (ct)->ct_flags |= MDI_CLIENT_FLAGS_REPORT_DEV;              }
 646  650  #define MDI_CLIENT_CLEAR_REPORT_DEV_NEEDED(ct)                          {\
 647  651              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 648  652              (ct)->ct_flags &= ~MDI_CLIENT_FLAGS_REPORT_DEV;             }
 649  653  #define MDI_CLIENT_IS_REPORT_DEV_NEEDED(ct) \
 650  654              ((ct)->ct_flags & MDI_CLIENT_FLAGS_REPORT_DEV)
 651  655  
 652  656  #define MDI_CLIENT_SET_PATH_FREE_IN_PROGRESS(ct)                        {\
 653  657              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 654  658              (ct)->ct_flags |= MDI_CLIENT_FLAGS_PATH_FREE_IN_PROGRESS;   }
 655  659  #define MDI_CLIENT_CLEAR_PATH_FREE_IN_PROGRESS(ct)                      {\
 656  660              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 657  661              (ct)->ct_flags &= ~MDI_CLIENT_FLAGS_PATH_FREE_IN_PROGRESS;  }
 658  662  #define MDI_CLIENT_IS_PATH_FREE_IN_PROGRESS(ct) \
 659  663              ((ct)->ct_flags & MDI_CLIENT_FLAGS_PATH_FREE_IN_PROGRESS)
 660  664  
 661  665  #define MDI_CLIENT_SET_DEV_NOT_SUPPORTED(ct)                            {\
 662  666              ASSERT(MDI_CLIENT_LOCKED(ct));                              \
 663  667              (ct)->ct_flags |= MDI_CLIENT_FLAGS_DEV_NOT_SUPPORTED;       }
 664  668  #define MDI_CLIENT_IS_DEV_NOT_SUPPORTED(ct) \
 665  669              ((ct)->ct_flags & MDI_CLIENT_FLAGS_DEV_NOT_SUPPORTED)
 666  670  
 667  671  /*
 668  672   * Client operating states.
 669  673   */
 670  674  #define MDI_CLIENT_STATE_OPTIMAL        1
 671  675  #define MDI_CLIENT_STATE_DEGRADED       2
 672  676  #define MDI_CLIENT_STATE_FAILED         3
 673  677  
 674  678  #define MDI_CLIENT_STATE(ct) ((ct)->ct_state)
 675  679  #define MDI_CLIENT_SET_STATE(ct, state) ((ct)->ct_state = state)
 676  680  
 677  681  #define MDI_CLIENT_IS_FAILED(ct) \
 678  682              ((ct)->ct_state == MDI_CLIENT_STATE_FAILED)
 679  683  
 680  684  /*
 681  685   * mdi_pathinfo nodes:
 682  686   *
 683  687   * From this framework's perspective, a 'path' is a tuple consisting of a
 684  688   * client or end device, a host controller which provides device
 685  689   * identification and transport services (pHCI), and bus specific unit
 686  690   * addressing information.  A path may be decorated with properties which
 687  691   * describe the capabilities of the path; such properties are analogous to
 688  692   * device node and minor node properties.
 689  693   *
 690  694   * The framework maintains link list of mdi_pathinfo nodes created by every
 691  695   * pHCI driver instance via the pi_phci_link linkage; this is used (for example)
 692  696   * to make sure that all relevant pathinfo nodes are freed before the pHCI
 693  697   * is unregistered.
 694  698   *
 695  699   * Locking order:
 696  700   *
 697  701   * _NOTE(LOCK_ORDER(mdi_phci::ph_mutex mdi_pathinfo::pi_mutex))         XXX
 698  702   * _NOTE(LOCK_ORDER(mdi_client::ct_mutex mdi_pathinfo::pi_mutex))       XXX
 699  703   * _NOTE(LOCK_ORDER(mdi_phci::ph_mutex mdi_client::ct_mutex))           XXX
 700  704   * _NOTE(LOCK_ORDER(devinfo_tree_lock mdi_pathinfo::pi_mutex))          XXX
 701  705   *
 702  706   * mdi_pathinfo node structure definition
 703  707   */
 704  708  struct mdi_pathinfo {
 705  709          /* protected by MDI_PHCI_LOCK ph_mutex... */
 706  710          struct mdi_pathinfo     *pi_phci_link;   /* next path in phci list */
 707  711          mdi_phci_t              *pi_phci;       /* pHCI dev_info node   */
 708  712  
 709  713          /* protected by MDI_CLIENT_LOCK ct_mutex... */
 710  714          struct mdi_pathinfo     *pi_client_link; /* next path in client list */
 711  715          mdi_client_t            *pi_client;     /* client               */
 712  716  
 713  717          /* protected by MDI_VHCI_CLIENT_LOCK vh_client_mutex... */
 714  718          char                    *pi_addr;       /* path unit address    */
 715  719          int                     pi_path_instance; /* path instance */
 716  720  
 717  721          /* protected by MDI_PI_LOCK pi_mutex... */
 718  722          kmutex_t                pi_mutex;       /* per path mutex       */
 719  723          mdi_pathinfo_state_t    pi_state;       /* path state           */
 720  724          mdi_pathinfo_state_t    pi_old_state;   /* path state           */
 721  725          kcondvar_t              pi_state_cv;    /* path state condvar   */
 722  726          nvlist_t                *pi_prop;       /* Properties           */
 723  727          void                    *pi_cprivate;   /* client private info  */
 724  728          void                    *pi_pprivate;   /* phci private info    */
 725  729          int                     pi_ref_cnt;     /* pi reference count   */
 726  730          kcondvar_t              pi_ref_cv;      /* condition variable   */
 727  731          struct mdi_pi_kstats    *pi_kstats;     /* aggregate kstats */
 728  732          int                     pi_pm_held;     /* phci's kidsup incremented */
 729  733          int                     pi_preferred;   /* Preferred path       */
 730  734          void                    *pi_vprivate;   /* vhci private info    */
 731  735          uint_t                  pi_flags;       /* path flags */
 732  736  };
 733  737  
 734  738  /*
 735  739   * pathinfo statistics:
 736  740   *
 737  741   * The mpxio architecture allows for multiple pathinfo nodes for each
 738  742   * client-pHCI combination.  For statistics purposes, these statistics are
 739  743   * aggregated into a single client-pHCI set of kstats.
 740  744   */
 741  745  struct mdi_pi_kstats {
 742  746          int     pi_kstat_ref;           /* # paths aggregated, also a ref cnt */
 743  747          kstat_t *pi_kstat_iostats;      /* mdi:iopath statistic set */
 744  748          kstat_t *pi_kstat_errstats;     /* error statistics */
 745  749  };
 746  750  
 747  751  /*
 748  752   * pathinfo error kstat
 749  753   */
 750  754  struct pi_errs {
 751  755          struct kstat_named pi_softerrs;         /* "Soft" Error */
 752  756          struct kstat_named pi_harderrs;         /* "Hard" Error */
 753  757          struct kstat_named pi_transerrs;        /* Transport Errors */
 754  758          struct kstat_named pi_icnt_busy;        /* Interconnect Busy */
 755  759          struct kstat_named pi_icnt_errors;      /* Interconnect Errors */
 756  760          struct kstat_named pi_phci_rsrc;        /* pHCI No Resources */
 757  761          struct kstat_named pi_phci_localerr;    /* pHCI Local Errors */
 758  762          struct kstat_named pi_phci_invstate;    /* pHCI Invalid State */
 759  763          struct kstat_named pi_failedfrom;       /* Failover: Failed From */
 760  764          struct kstat_named pi_failedto;         /* Failover: Failed To */
 761  765  };
 762  766  
 763  767  /*
 764  768   * increment an error counter
 765  769   */
 766  770  #define MDI_PI_ERRSTAT(pip, x) { \
 767  771          if (MDI_PI((pip))->pi_kstats != NULL) { \
 768  772                  struct pi_errs *pep; \
 769  773                  pep = MDI_PI(pip)->pi_kstats->pi_kstat_errstats->ks_data; \
 770  774                  pep->x.value.ui32++; \
 771  775          } \
 772  776  }
 773  777  
 774  778  /*
 775  779   * error codes which can be passed to MDI_PI_ERRSTAT
 776  780   */
 777  781  #define MDI_PI_SOFTERR  pi_softerrs
 778  782  #define MDI_PI_HARDERR  pi_harderrs
 779  783  #define MDI_PI_TRANSERR pi_transerrs
 780  784  #define MDI_PI_ICNTBUSY pi_icnt_busy
 781  785  #define MDI_PI_ICNTERR  pi_icnt_errors
 782  786  #define MDI_PI_PHCIRSRC pi_phci_rsrc
 783  787  #define MDI_PI_PHCILOCL pi_phci_localerr
 784  788  #define MDI_PI_PHCIINVS pi_phci_invstate
 785  789  #define MDI_PI_FAILFROM pi_failedfrom
 786  790  #define MDI_PI_FAILTO   pi_failedto
 787  791  
 788  792  #define MDI_PI(type)                    ((struct mdi_pathinfo *)(type))
 789  793  
 790  794  #define MDI_PI_LOCK(pip)                mutex_enter(&MDI_PI(pip)->pi_mutex)
 791  795  #define MDI_PI_TRYLOCK(pip)             mutex_tryenter(&MDI_PI(pip)->pi_mutex)
 792  796  #define MDI_PI_UNLOCK(pip)              mutex_exit(&MDI_PI(pip)->pi_mutex)
 793  797  #ifdef  DEBUG
 794  798  #define MDI_PI_LOCKED(pip)              MUTEX_HELD(&MDI_PI(pip)->pi_mutex)
 795  799  #endif  /* DEBUG */
 796  800  
 797  801  #define MDI_PI_HOLD(pip)                (++MDI_PI(pip)->pi_ref_cnt)
 798  802  #define MDI_PI_RELE(pip)                (--MDI_PI(pip)->pi_ref_cnt)
 799  803  
 800  804  #define MDI_EXT_STATE_CHANGE            0x10000000
 801  805  
 802  806  
 803  807  #define MDI_DISABLE_OP                  0x1
 804  808  #define MDI_ENABLE_OP                   0x2
 805  809  #define MDI_BEFORE_STATE_CHANGE         0x4
 806  810  #define MDI_AFTER_STATE_CHANGE          0x8
 807  811  #define MDI_SYNC_FLAG                   0x10
 808  812  
 809  813  #define MDI_PI_STATE(pip)                                               \
 810  814          (MDI_PI((pip))->pi_state & MDI_PATHINFO_STATE_MASK)
 811  815  #define MDI_PI_OLD_STATE(pip)                                           \
 812  816          (MDI_PI((pip))->pi_old_state & MDI_PATHINFO_STATE_MASK)
 813  817  
 814  818  #define MDI_PI_EXT_STATE(pip)                                           \
 815  819          (MDI_PI((pip))->pi_state & MDI_PATHINFO_EXT_STATE_MASK)
 816  820  #define MDI_PI_OLD_EXT_STATE(pip)                                       \
 817  821          (MDI_PI((pip))->pi_old_state & MDI_PATHINFO_EXT_STATE_MASK)
 818  822  
 819  823  #define MDI_PI_SET_TRANSIENT(pip)                                       {\
 820  824          ASSERT(MDI_PI_LOCKED(pip));                                     \
 821  825          MDI_PI(pip)->pi_state |= MDI_PATHINFO_STATE_TRANSIENT;          }
 822  826  #define MDI_PI_CLEAR_TRANSIENT(pip)                                     {\
 823  827          ASSERT(MDI_PI_LOCKED(pip));                                     \
 824  828          MDI_PI(pip)->pi_state &= ~MDI_PATHINFO_STATE_TRANSIENT;         }
 825  829  #define MDI_PI_IS_TRANSIENT(pip) \
 826  830          (MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_TRANSIENT)
 827  831  
 828  832  #define MDI_PI_SET_USER_DISABLE(pip)                                    {\
 829  833          ASSERT(MDI_PI_LOCKED(pip));                                     \
 830  834          MDI_PI(pip)->pi_state |= MDI_PATHINFO_STATE_USER_DISABLE;       }
 831  835  #define MDI_PI_SET_DRV_DISABLE(pip)                                     {\
 832  836          ASSERT(MDI_PI_LOCKED(pip));                                     \
 833  837          MDI_PI(pip)->pi_state |= MDI_PATHINFO_STATE_DRV_DISABLE;        }
 834  838  #define MDI_PI_SET_DRV_DISABLE_TRANS(pip)                               {\
 835  839          ASSERT(MDI_PI_LOCKED(pip));                                     \
 836  840          MDI_PI(pip)->pi_state |= MDI_PATHINFO_STATE_DRV_DISABLE_TRANSIENT; }
 837  841  
 838  842  #define MDI_PI_SET_USER_ENABLE(pip)                                     {\
 839  843          ASSERT(MDI_PI_LOCKED(pip));                                     \
 840  844          MDI_PI(pip)->pi_state &= ~MDI_PATHINFO_STATE_USER_DISABLE;      }
 841  845  #define MDI_PI_SET_DRV_ENABLE(pip)                                      {\
 842  846          ASSERT(MDI_PI_LOCKED(pip));                                     \
 843  847          MDI_PI(pip)->pi_state &= ~MDI_PATHINFO_STATE_DRV_DISABLE;       }
 844  848  #define MDI_PI_SET_DRV_ENABLE_TRANS(pip)                                {\
 845  849          ASSERT(MDI_PI_LOCKED(pip));                                     \
 846  850          MDI_PI(pip)->pi_state &= ~MDI_PATHINFO_STATE_DRV_DISABLE_TRANSIENT; }
 847  851  
 848  852  #define MDI_PI_IS_USER_DISABLE(pip)                                     \
 849  853          (MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_USER_DISABLE)
 850  854  #define MDI_PI_IS_DRV_DISABLE(pip)                                      \
 851  855          (MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_DRV_DISABLE)
 852  856  #define MDI_PI_IS_DRV_DISABLE_TRANSIENT(pip)                            \
 853  857          (MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_DRV_DISABLE_TRANSIENT)
 854  858  
 855  859  #define MDI_PI_IS_DISABLE(pip)                                          \
 856  860          (MDI_PI_IS_USER_DISABLE(pip) ||                                 \
 857  861          MDI_PI_IS_DRV_DISABLE(pip) ||                                   \
 858  862          MDI_PI_IS_DRV_DISABLE_TRANSIENT(pip))
 859  863  
 860  864  #define MDI_PI_IS_INIT(pip)                                             \
 861  865          ((MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_MASK) ==           \
 862  866                  MDI_PATHINFO_STATE_INIT)
 863  867  
 864  868  #define MDI_PI_IS_INITING(pip)                                          \
 865  869          ((MDI_PI(pip)->pi_state & ~MDI_PATHINFO_EXT_STATE_MASK) ==      \
 866  870                  (MDI_PATHINFO_STATE_INIT | MDI_PATHINFO_STATE_TRANSIENT))
 867  871  
 868  872  #define MDI_PI_SET_INIT(pip)                                            {\
 869  873          ASSERT(MDI_PI_LOCKED(pip));                                     \
 870  874          MDI_PI(pip)->pi_state = MDI_PATHINFO_STATE_INIT;                }
 871  875  
 872  876  #define MDI_PI_SET_ONLINING(pip)                                        {\
 873  877          uint32_t        ext_state;                                      \
 874  878          ASSERT(MDI_PI_LOCKED(pip));                                     \
 875  879          ext_state = MDI_PI(pip)->pi_state & MDI_PATHINFO_EXT_STATE_MASK; \
 876  880          MDI_PI(pip)->pi_old_state = MDI_PI_STATE(pip);                  \
 877  881          MDI_PI(pip)->pi_state =                                         \
 878  882          (MDI_PATHINFO_STATE_ONLINE | MDI_PATHINFO_STATE_TRANSIENT);     \
 879  883          MDI_PI(pip)->pi_state |= ext_state;                             }
 880  884  
 881  885  #define MDI_PI_IS_ONLINING(pip)                                         \
 882  886          ((MDI_PI(pip)->pi_state & ~MDI_PATHINFO_EXT_STATE_MASK) ==      \
 883  887          (MDI_PATHINFO_STATE_ONLINE | MDI_PATHINFO_STATE_TRANSIENT))
 884  888  
 885  889  #define MDI_PI_SET_ONLINE(pip)                                          {\
 886  890          uint32_t        ext_state;                                      \
 887  891          ASSERT(MDI_PI_LOCKED(pip));                                     \
 888  892          ext_state = MDI_PI(pip)->pi_state & MDI_PATHINFO_EXT_STATE_MASK; \
 889  893          MDI_PI(pip)->pi_state = MDI_PATHINFO_STATE_ONLINE;              \
 890  894          MDI_PI(pip)->pi_state |= ext_state;                             }
 891  895  
 892  896  #define MDI_PI_IS_ONLINE(pip)                                           \
 893  897          ((MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_MASK) ==           \
 894  898          MDI_PATHINFO_STATE_ONLINE)
 895  899  
 896  900  #define MDI_PI_SET_OFFLINING(pip)                                       {\
 897  901          uint32_t        ext_state;                                      \
 898  902          ASSERT(MDI_PI_LOCKED(pip));                                     \
 899  903          ext_state = MDI_PI(pip)->pi_state & MDI_PATHINFO_EXT_STATE_MASK; \
 900  904          MDI_PI(pip)->pi_old_state = MDI_PI_STATE(pip);                  \
 901  905          MDI_PI(pip)->pi_state =                                         \
 902  906          (MDI_PATHINFO_STATE_OFFLINE | MDI_PATHINFO_STATE_TRANSIENT);    \
 903  907          MDI_PI(pip)->pi_state |= ext_state;                             }
 904  908  
 905  909  #define MDI_PI_IS_OFFLINING(pip)                                        \
 906  910          ((MDI_PI(pip)->pi_state & ~MDI_PATHINFO_EXT_STATE_MASK) ==      \
 907  911          (MDI_PATHINFO_STATE_OFFLINE | MDI_PATHINFO_STATE_TRANSIENT))
 908  912  
 909  913  #define MDI_PI_SET_OFFLINE(pip)                                         {\
 910  914          uint32_t        ext_state;                                      \
 911  915          ASSERT(MDI_PI_LOCKED(pip));                                     \
 912  916          ext_state = MDI_PI(pip)->pi_state & MDI_PATHINFO_EXT_STATE_MASK; \
 913  917          MDI_PI(pip)->pi_state = MDI_PATHINFO_STATE_OFFLINE;             \
 914  918          MDI_PI(pip)->pi_state |= ext_state;                             }
 915  919  
 916  920  #define MDI_PI_IS_OFFLINE(pip)                                          \
 917  921          ((MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_MASK) ==           \
 918  922          MDI_PATHINFO_STATE_OFFLINE)
 919  923  
 920  924  #define MDI_PI_SET_STANDBYING(pip)                                      {\
 921  925          uint32_t        ext_state;                                      \
 922  926          ASSERT(MDI_PI_LOCKED(pip));                                     \
 923  927          ext_state = MDI_PI(pip)->pi_state & MDI_PATHINFO_EXT_STATE_MASK; \
 924  928          MDI_PI(pip)->pi_old_state = MDI_PI_STATE(pip);                  \
 925  929          MDI_PI(pip)->pi_state =                                         \
 926  930          (MDI_PATHINFO_STATE_STANDBY | MDI_PATHINFO_STATE_TRANSIENT);    \
 927  931          MDI_PI(pip)->pi_state |= ext_state;                             }
 928  932  
 929  933  #define MDI_PI_SET_STANDBY(pip)                                         {\
 930  934          uint32_t        ext_state;                                      \
 931  935          ASSERT(MDI_PI_LOCKED(pip));                                     \
 932  936          ext_state = MDI_PI(pip)->pi_state & MDI_PATHINFO_EXT_STATE_MASK; \
 933  937          MDI_PI(pip)->pi_state = MDI_PATHINFO_STATE_STANDBY;             \
 934  938          MDI_PI(pip)->pi_state |= ext_state;                             }
 935  939  
 936  940  #define MDI_PI_IS_STANDBY(pip)                                          \
 937  941          ((MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_MASK) ==           \
 938  942          MDI_PATHINFO_STATE_STANDBY)
 939  943  
 940  944  #define MDI_PI_SET_FAULTING(pip)                                        {\
 941  945          uint32_t        ext_state;                                      \
 942  946          ASSERT(MDI_PI_LOCKED(pip));                                     \
 943  947          ext_state = MDI_PI(pip)->pi_state & MDI_PATHINFO_EXT_STATE_MASK; \
 944  948          MDI_PI(pip)->pi_old_state = MDI_PI_STATE(pip);                  \
 945  949          MDI_PI(pip)->pi_state =                                         \
 946  950              (MDI_PATHINFO_STATE_FAULT | MDI_PATHINFO_STATE_TRANSIENT);  \
 947  951          MDI_PI(pip)->pi_state |= ext_state;                             }
 948  952  
 949  953  #define MDI_PI_SET_FAULT(pip)                                           {\
 950  954          uint32_t        ext_state;                                      \
 951  955          ASSERT(MDI_PI_LOCKED(pip));                                     \
 952  956          ext_state = MDI_PI(pip)->pi_state & MDI_PATHINFO_EXT_STATE_MASK; \
 953  957          MDI_PI(pip)->pi_state = MDI_PATHINFO_STATE_FAULT;               \
 954  958          MDI_PI(pip)->pi_state |= ext_state;                             }
 955  959  
 956  960  #define MDI_PI_IS_FAULT(pip)                                            \
 957  961          ((MDI_PI(pip)->pi_state & MDI_PATHINFO_STATE_MASK) ==           \
 958  962          MDI_PATHINFO_STATE_FAULT)
 959  963  
 960  964  #define MDI_PI_IS_SUSPENDED(pip)                                        \
 961  965          ((MDI_PI(pip))->pi_phci->ph_flags & MDI_PHCI_FLAGS_SUSPEND)
 962  966  
 963  967  #define MDI_PI_FLAGS_SET_HIDDEN(pip)                                    {\
 964  968          ASSERT(MDI_PI_LOCKED(pip));                                     \
 965  969          MDI_PI(pip)->pi_flags |= MDI_PATHINFO_FLAGS_HIDDEN;             }
 966  970  #define MDI_PI_FLAGS_CLR_HIDDEN(pip)                                    {\
 967  971          ASSERT(MDI_PI_LOCKED(pip));                                     \
 968  972          MDI_PI(pip)->pi_flags &= ~MDI_PATHINFO_FLAGS_HIDDEN;            }
 969  973  #define MDI_PI_FLAGS_IS_HIDDEN(pip)                                     \
 970  974          ((MDI_PI(pip)->pi_flags & MDI_PATHINFO_FLAGS_HIDDEN) ==         \
 971  975          MDI_PATHINFO_FLAGS_HIDDEN)
 972  976  
 973  977  #define MDI_PI_FLAGS_SET_DEVICE_REMOVED(pip)                            {\
 974  978          ASSERT(MDI_PI_LOCKED(pip));                                     \
 975  979          MDI_PI(pip)->pi_flags |= MDI_PATHINFO_FLAGS_DEVICE_REMOVED;     }
 976  980  #define MDI_PI_FLAGS_CLR_DEVICE_REMOVED(pip)                            {\
 977  981          ASSERT(MDI_PI_LOCKED(pip));                                     \
 978  982          MDI_PI(pip)->pi_flags &= ~MDI_PATHINFO_FLAGS_DEVICE_REMOVED;    }
 979  983  #define MDI_PI_FLAGS_IS_DEVICE_REMOVED(pip)                             \
 980  984          ((MDI_PI(pip)->pi_flags & MDI_PATHINFO_FLAGS_DEVICE_REMOVED) == \
 981  985          MDI_PATHINFO_FLAGS_DEVICE_REMOVED)
 982  986  
 983  987  /*
 984  988   * mdi_vhcache_client, mdi_vhcache_pathinfo, and mdi_vhcache_phci structures
 985  989   * hold the vhci to phci client mappings of the on-disk vhci busconfig cache.
 986  990   */
 987  991  
 988  992  /* phci structure of vhci cache */
 989  993  typedef struct mdi_vhcache_phci {
 990  994          char                    *cphci_path;    /* phci path name */
 991  995          uint32_t                cphci_id;       /* used when building nvlist */
 992  996          mdi_phci_t              *cphci_phci;    /* pointer to actual phci */
 993  997          struct mdi_vhcache_phci *cphci_next;    /* next in vhci phci list */
 994  998  } mdi_vhcache_phci_t;
 995  999  
 996 1000  /* pathinfo structure of vhci cache */
 997 1001  typedef struct mdi_vhcache_pathinfo {
 998 1002          char                    *cpi_addr;      /* path address */
 999 1003          mdi_vhcache_phci_t      *cpi_cphci;     /* phci the path belongs to */
1000 1004          struct mdi_pathinfo     *cpi_pip;       /* ptr to actual pathinfo */
1001 1005          uint32_t                cpi_flags;      /* see below */
1002 1006          struct mdi_vhcache_pathinfo *cpi_next;  /* next path for the client */
1003 1007  } mdi_vhcache_pathinfo_t;
1004 1008  
1005 1009  /*
1006 1010   * cpi_flags
1007 1011   *
1008 1012   * MDI_CPI_HINT_PATH_DOES_NOT_EXIST - set when configuration of the path has
1009 1013   * failed.
1010 1014   */
1011 1015  #define MDI_CPI_HINT_PATH_DOES_NOT_EXIST        0x0001
1012 1016  
1013 1017  /* client structure of vhci cache */
1014 1018  typedef struct mdi_vhcache_client {
1015 1019          char                    *cct_name_addr; /* client address */
1016 1020          mdi_vhcache_pathinfo_t  *cct_cpi_head;  /* client's path list head */
1017 1021          mdi_vhcache_pathinfo_t  *cct_cpi_tail;  /* client's path list tail */
1018 1022          struct mdi_vhcache_client *cct_next;    /* next in vhci client list */
1019 1023  } mdi_vhcache_client_t;
1020 1024  
1021 1025  /* vhci cache structure - one for vhci instance */
1022 1026  typedef struct mdi_vhci_cache {
1023 1027          mdi_vhcache_phci_t      *vhcache_phci_head;     /* phci list head */
1024 1028          mdi_vhcache_phci_t      *vhcache_phci_tail;     /* phci list tail */
1025 1029          mdi_vhcache_client_t    *vhcache_client_head;   /* client list head */
1026 1030          mdi_vhcache_client_t    *vhcache_client_tail;   /* client list tail */
1027 1031          mod_hash_t              *vhcache_client_hash;   /* client hash */
1028 1032          int                     vhcache_flags;          /* see below */
1029 1033          int64_t                 vhcache_clean_time;     /* last clean time */
1030 1034          krwlock_t               vhcache_lock;           /* cache lock */
1031 1035  } mdi_vhci_cache_t;
1032 1036  
1033 1037  /* vhcache_flags */
1034 1038  #define MDI_VHCI_CACHE_SETUP_DONE       0x0001  /* cache setup completed */
1035 1039  
1036 1040  /* vhci bus config structure - one for vhci instance */
1037 1041  typedef struct mdi_vhci_config {
1038 1042          char                    *vhc_vhcache_filename;  /* on-disk file name */
1039 1043          mdi_vhci_cache_t        vhc_vhcache;            /* vhci cache */
1040 1044          kmutex_t                vhc_lock;               /* vhci config lock */
1041 1045          kcondvar_t              vhc_cv;
1042 1046          int                     vhc_flags;              /* see below */
1043 1047  
1044 1048          /* flush vhci cache when lbolt reaches vhc_flush_at_ticks */
1045 1049          clock_t                 vhc_flush_at_ticks;
1046 1050  
1047 1051          /*
1048 1052           * Head and tail of the client list whose paths are being configured
1049 1053           * asynchronously. vhc_acc_count is the number of clients on this list.
1050 1054           * vhc_acc_thrcount is the number threads running to configure
1051 1055           * the paths for these clients.
1052 1056           */
1053 1057          struct mdi_async_client_config *vhc_acc_list_head;
1054 1058          struct mdi_async_client_config *vhc_acc_list_tail;
1055 1059          int                     vhc_acc_count;
1056 1060          int                     vhc_acc_thrcount;
1057 1061  
1058 1062          /* callback id - for flushing the cache during system shutdown */
1059 1063          callb_id_t              vhc_cbid;
1060 1064  
1061 1065          /*
1062 1066           * vhc_path_discovery_boot -    number of times path discovery will be
1063 1067           *                              attempted during early boot.
1064 1068           * vhc_path_discovery_postboot  number of times path discovery will be
1065 1069           *                              attempted during late boot.
1066 1070           * vhc_path_discovery_cutoff_time - time at which paths were last
1067 1071           *                              discovered  + some timeout
1068 1072           */
1069 1073          int                     vhc_path_discovery_boot;
1070 1074          int                     vhc_path_discovery_postboot;
1071 1075          int64_t                 vhc_path_discovery_cutoff_time;
1072 1076  } mdi_vhci_config_t;
1073 1077  
1074 1078  /* vhc_flags */
1075 1079  #define MDI_VHC_SINGLE_THREADED         0x0001  /* config single threaded */
1076 1080  #define MDI_VHC_EXIT                    0x0002  /* exit all config activity */
1077 1081  #define MDI_VHC_VHCACHE_DIRTY           0x0004  /* cache dirty */
1078 1082  #define MDI_VHC_VHCACHE_FLUSH_THREAD    0x0008  /* cache flush thead running */
1079 1083  #define MDI_VHC_VHCACHE_FLUSH_ERROR     0x0010  /* failed to flush cache */
1080 1084  #define MDI_VHC_READONLY_FS             0x0020  /* filesys is readonly */
1081 1085  
1082 1086  typedef struct mdi_phys_path {
1083 1087          char                    *phys_path;
1084 1088          struct mdi_phys_path    *phys_path_next;
1085 1089  } mdi_phys_path_t;
1086 1090  
1087 1091  /*
1088 1092   * Lookup tokens are used to cache the result of the vhci cache client lookup
1089 1093   * operations (to reduce the number of real lookup operations).
1090 1094   */
1091 1095  typedef struct mdi_vhcache_lookup_token {
1092 1096          mdi_vhcache_client_t    *lt_cct;                /* vhcache client */
1093 1097          int64_t                 lt_cct_lookup_time;     /* last lookup time */
1094 1098  } mdi_vhcache_lookup_token_t;
1095 1099  
1096 1100  /* asynchronous configuration of client paths */
1097 1101  typedef struct mdi_async_client_config {
1098 1102          char                    *acc_ct_name;   /* client name */
1099 1103          char                    *acc_ct_addr;   /* client address */
1100 1104          mdi_phys_path_t         *acc_phclient_path_list_head;   /* path head */
1101 1105          mdi_vhcache_lookup_token_t acc_token;   /* lookup token */
1102 1106          struct mdi_async_client_config *acc_next; /* next in vhci acc list */
1103 1107  } mdi_async_client_config_t;
1104 1108  
1105 1109  /*
1106 1110   * vHCI driver instance registration/unregistration
1107 1111   *
1108 1112   * mdi_vhci_register() is called by a vHCI driver to register itself as the
1109 1113   * manager of devices from a particular 'class'.  This should be called from
1110 1114   * attach(9e).
1111 1115   *
1112 1116   * mdi_vhci_unregister() is called from detach(9E) to unregister a vHCI
1113 1117   * instance from the framework.
1114 1118   */
1115 1119  int             mdi_vhci_register(char *, dev_info_t *, mdi_vhci_ops_t *, int);
1116 1120  int             mdi_vhci_unregister(dev_info_t *, int);
1117 1121  
1118 1122  /*
1119 1123   * Utility functions
1120 1124   */
1121 1125  int             mdi_phci_get_path_count(dev_info_t *);
1122 1126  dev_info_t      *mdi_phci_path2devinfo(dev_info_t *, caddr_t);
1123 1127  
1124 1128  
1125 1129  /*
1126 1130   * Path Selection Functions:
1127 1131   *
1128 1132   * mdi_select_path() is called by a vHCI driver to select to which path an
1129 1133   * I/O request should be routed.  The caller passes the 'buf' structure as
1130 1134   * one of the parameters.  The mpxio framework uses the buf's contents to
1131 1135   * maintain per path statistics (total I/O size / count pending).  If more
1132 1136   * than one online path is available, the framework automatically selects
1133 1137   * a suitable one.  If a failover operation is active for this client device
1134 1138   * the call fails, returning MDI_BUSY.
1135 1139   *
1136 1140   * By default this function returns a suitable path in the 'online' state,
1137 1141   * based on the current load balancing policy.  Currently we support
1138 1142   * LOAD_BALANCE_NONE (Previously selected online path will continue to be
1139 1143   * used as long as the path is usable) and LOAD_BALANCE_RR (Online paths
1140 1144   * will be selected in a round robin fashion).  The load balancing scheme
1141 1145   * can be configured in the vHCI driver's configuration file (driver.conf).
1142 1146   *
1143 1147   * vHCI drivers may override this default behavior by specifying appropriate
1144 1148   * flags.  If start_pip is specified (non NULL), it is used as the routine's
1145 1149   * starting point; it starts walking from there to find the next appropriate
1146 1150   * path.
1147 1151   *
1148 1152   * The following values for 'flags' are currently defined, the third argument
1149 1153   * to mdi_select_path depends on the flags used.
1150 1154   *
1151 1155   *   <none>:                            default, arg is pip
1152 1156   *   MDI_SELECT_ONLINE_PATH:            select an ONLINE path preferred-first,
1153 1157   *                                      arg is pip
1154 1158   *   MDI_SELECT_STANDBY_PATH:           select a STANDBY path, arg is pip
1155 1159   *   MDI_SELECT_USER_DISABLE_PATH:      select user disable for failover and
1156 1160   *                                      auto_failback
1157 1161   *   MDI_SELECT_PATH_INSTANCE:          select a specific path, arg is
1158 1162   *                                      path instance
1159 1163   *   MDI_SELECT_NO_PREFERRED:           select path without preferred-first
1160 1164   *
1161 1165   * The selected paths are returned in an mdi_hold_path() state (pi_ref_cnt),
1162 1166   * caller should release the hold by calling mdi_rele_path() at the end of
1163 1167   * operation.
1164 1168   */
1165 1169  int             mdi_select_path(dev_info_t *, struct buf *, int,
1166 1170                      void *, mdi_pathinfo_t **);
1167 1171  int             mdi_set_lb_policy(dev_info_t *, client_lb_t);
1168 1172  int             mdi_set_lb_region_size(dev_info_t *, int);
1169 1173  client_lb_t     mdi_get_lb_policy(dev_info_t *);
1170 1174  
1171 1175  /*
1172 1176   * flags for mdi_select_path() routine
1173 1177   */
1174 1178  #define MDI_SELECT_ONLINE_PATH          0x0001
1175 1179  #define MDI_SELECT_STANDBY_PATH         0x0002
1176 1180  #define MDI_SELECT_USER_DISABLE_PATH    0x0004
1177 1181  #define MDI_SELECT_PATH_INSTANCE        0x0008
1178 1182  #define MDI_SELECT_NO_PREFERRED         0x0010
1179 1183  
1180 1184  /*
1181 1185   * MDI client device utility functions
1182 1186   */
1183 1187  int             mdi_client_get_path_count(dev_info_t *);
1184 1188  dev_info_t      *mdi_client_path2devinfo(dev_info_t *, caddr_t);
1185 1189  
1186 1190  /*
1187 1191   * Failover:
1188 1192   *
1189 1193   * The vHCI driver calls mdi_failover() to initiate a failover operation.
1190 1194   * mdi_failover() calls back into the vHCI driver's vo_failover()
1191 1195   * entry point to perform the actual failover operation.  The reason
1192 1196   * for requiring the vHCI driver to initiate failover by calling
1193 1197   * mdi_failover(), instead of directly executing vo_failover() itself,
1194 1198   * is to ensure that the mdi framework can keep track of the client
1195 1199   * state properly.  Additionally, mdi_failover() provides as a
1196 1200   * convenience the option of performing the failover operation
1197 1201   * synchronously or asynchronously
1198 1202   *
1199 1203   * Upon successful completion of the failover operation, the paths that were
1200 1204   * previously ONLINE will be in the STANDBY state, and the newly activated
1201 1205   * paths will be in the ONLINE state.
1202 1206   *
1203 1207   * The flags modifier determines whether the activation is done synchronously
1204 1208   */
1205 1209  int mdi_failover(dev_info_t *, dev_info_t *, int);
1206 1210  
1207 1211  /*
1208 1212   * Client device failover mode of operation
1209 1213   */
1210 1214  #define MDI_FAILOVER_SYNC       1       /* Synchronous Failover         */
1211 1215  #define MDI_FAILOVER_ASYNC      2       /* Asynchronous Failover        */
1212 1216  
1213 1217  /*
1214 1218   * mdi_is_dev_supported: The pHCI driver bus_config implementation calls
1215 1219   * mdi_is_dev_supported to determine if a child device should is supported as
1216 1220   * a vHCI child (i.e. as a client). The method used to specify the child
1217 1221   * device, via the cinfo argument, is by agreement between the pHCI and the
1218 1222   * vHCI.  In the case of SCSA and scsi_vhci cinfo is a pointer to the pHCI
1219 1223   * probe dev_info node, which is decorated with the device idenity information
1220 1224   * necessary to determine scsi_vhci support.
1221 1225   */
1222 1226  int mdi_is_dev_supported(char *class, dev_info_t *pdip, void *cinfo);
1223 1227  
1224 1228  /*
1225 1229   * mdi_pathinfo node kstat functions.
1226 1230   */
1227 1231  int mdi_pi_kstat_exists(mdi_pathinfo_t *);
1228 1232  int mdi_pi_kstat_create(mdi_pathinfo_t *pip, char *ks_name);
1229 1233  void mdi_pi_kstat_iosupdate(mdi_pathinfo_t *, struct buf *);
1230 1234  
1231 1235  /*
1232 1236   * mdi_pathinfo node extended state change functions.
1233 1237   */
1234 1238  int mdi_pi_get_state2(mdi_pathinfo_t *, mdi_pathinfo_state_t *, uint32_t *);
1235 1239  int mdi_pi_get_preferred(mdi_pathinfo_t *);
1236 1240  
1237 1241  /*
1238 1242   * mdi_pathinfo node member functions
1239 1243   */
1240 1244  void *mdi_pi_get_client_private(mdi_pathinfo_t *);
1241 1245  void mdi_pi_set_client_private(mdi_pathinfo_t *, void *);
1242 1246  void mdi_pi_set_state(mdi_pathinfo_t *, mdi_pathinfo_state_t);
1243 1247  void mdi_pi_set_preferred(mdi_pathinfo_t *, int);
1244 1248  
1245 1249  /* get/set vhci private data */
1246 1250  void *mdi_client_get_vhci_private(dev_info_t *);
1247 1251  void mdi_client_set_vhci_private(dev_info_t *, void *);
1248 1252  void *mdi_phci_get_vhci_private(dev_info_t *);
1249 1253  void mdi_phci_set_vhci_private(dev_info_t *, void *);
1250 1254  void *mdi_pi_get_vhci_private(mdi_pathinfo_t *);
1251 1255  void mdi_pi_set_vhci_private(mdi_pathinfo_t *, void *);
1252 1256  int mdi_dc_return_dev_state(mdi_pathinfo_t *pip, struct devctl_iocdata *dcp);
1253 1257  
1254 1258  /*
1255 1259   * mdi_pathinfo Property utilities
1256 1260   */
1257 1261  int mdi_prop_size(mdi_pathinfo_t *, size_t *);
1258 1262  int mdi_prop_pack(mdi_pathinfo_t *, char **, uint_t);
1259 1263  
1260 1264  /* obsolete interface, to be removed */
1261 1265  void mdi_get_next_path(dev_info_t *, mdi_pathinfo_t *, mdi_pathinfo_t **);
1262 1266  int mdi_get_component_type(dev_info_t *);
1263 1267  
1264 1268  #endif  /* _KERNEL */
1265 1269  
1266 1270  #ifdef  __cplusplus
1267 1271  }
1268 1272  #endif
1269 1273  
1270 1274  #endif  /* _SYS_MDI_IMPLDEFS_H */
  
    | 
      ↓ open down ↓ | 
    673 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX