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) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
  26  * Copyright (c) 2016 by Delphix. All rights reserved.
  27  */
  28 
  29 #include <sys/note.h>
  30 
  31 /*
  32  * Generic SCSI Host Bus Adapter interface implementation
  33  */
  34 #include <sys/scsi/scsi.h>
  35 #include <sys/scsi/generic/sas.h>
  36 #include <sys/file.h>
  37 #include <sys/disp.h>                     /* for minclsyspri */
  38 #include <sys/ddi_impldefs.h>
  39 #include <sys/ndi_impldefs.h>
  40 #include <sys/sunndi.h>
  41 #include <sys/ddi.h>
  42 #include <sys/sunmdi.h>
  43 #include <sys/mdi_impldefs.h>
  44 #include <sys/callb.h>
  45 #include <sys/epm.h>
  46 #include <sys/damap.h>
  47 #include <sys/time.h>
  48 #include <sys/sunldi.h>
  49 #include <sys/fm/protocol.h>
  50 
  51 extern struct scsi_pkt *scsi_init_cache_pkt(struct scsi_address *,
  52                     struct scsi_pkt *, struct buf *, int, int, int, int,
  53                     int (*)(caddr_t), caddr_t);
  54 extern void     scsi_free_cache_pkt(struct scsi_address *, struct scsi_pkt *);
  55 extern void     scsi_cache_dmafree(struct scsi_address *, struct scsi_pkt *);
  56 extern void     scsi_sync_cache_pkt(struct scsi_address *, struct scsi_pkt *);
  57 extern int      modrootloaded;
  58 
  59 /*
  60  * Round up all allocations so that we can guarantee
  61  * long-long alignment.  This is the same alignment
  62  * provided by kmem_alloc().
  63  */
  64 #define ROUNDUP(x)      (((x) + 0x07) & ~0x07)
  65 
  66 /* Magic number to track correct allocations in wrappers */
  67 #define PKT_WRAPPER_MAGIC       0xa110ced       /* alloced correctly */
  68 
  69 kmutex_t        scsi_flag_nointr_mutex;
  70 kcondvar_t      scsi_flag_nointr_cv;
  71 kmutex_t        scsi_log_mutex;
  72 
  73 /* asynchronous probe barrier deletion data structures */
  74 static kmutex_t scsi_hba_barrier_mutex;
  75 static kcondvar_t       scsi_hba_barrier_cv;
  76 static struct scsi_hba_barrier {
  77         struct scsi_hba_barrier *barrier_next;
  78         clock_t                 barrier_endtime;
  79         dev_info_t              *barrier_probe;
  80 }               *scsi_hba_barrier_list;
  81 static int      scsi_hba_devi_is_barrier(dev_info_t *probe);
  82 static void     scsi_hba_barrier_tran_tgt_free(dev_info_t *probe);
  83 static void     scsi_hba_barrier_add(dev_info_t *probe, int seconds);
  84 static int      scsi_hba_remove_node(dev_info_t *child);
  85 static void     scsi_hba_barrier_daemon(void *arg);
  86 
  87 /* LUN-change ASC/ASCQ processing data structures (stage1 and stage2) */
  88 static kmutex_t         scsi_lunchg1_mutex;
  89 static kcondvar_t       scsi_lunchg1_cv;
  90 static struct scsi_pkt  *scsi_lunchg1_list;
  91 static void             scsi_lunchg1_daemon(void *arg);
  92 static kmutex_t         scsi_lunchg2_mutex;
  93 static kcondvar_t       scsi_lunchg2_cv;
  94 static struct scsi_lunchg2 {
  95         struct scsi_lunchg2     *lunchg2_next;
  96         char                    *lunchg2_path;
  97 }                       *scsi_lunchg2_list;
  98 static void             scsi_lunchg2_daemon(void *arg);
  99 
 100 static int      scsi_findchild(dev_info_t *self, char *name, char *addr,
 101     int init, dev_info_t **dchildp, mdi_pathinfo_t **pchildp, int *ppi);
 102 
 103 /* return value defines for scsi_findchild */
 104 #define CHILD_TYPE_NONE         0
 105 #define CHILD_TYPE_DEVINFO      1
 106 #define CHILD_TYPE_PATHINFO     2
 107 
 108 /*
 109  * Enumeration code path currently being followed. SE_BUSCONFIG results in
 110  * DEVI_SID_NODEID, and SE_HP (hotplug) results in DEVI_SID_HP_NODEID.
 111  *
 112  * Since hotplug enumeration is based on information obtained from hardware
 113  * (tgtmap/report_lun) the type/severity of enumeration error messages is
 114  * sometimes based SE_HP (indirectly via ndi_dev_is_hotplug_node()). By
 115  * convention, these messages are all produced by scsi_enumeration_failed().
 116  */
 117 typedef enum { SE_BUSCONFIG = 0, SE_HP = 1 } scsi_enum_t;
 118 
 119 /* compatible properties of driver to use during probe/enumeration operations */
 120 static char     *compatible_probe = "scsa,probe";
 121 static char     *compatible_nodev = "scsa,nodev";
 122 static char     *scsi_probe_ascii[] = SCSIPROBE_ASCII;
 123 
 124 /* number of LUNs we attempt to get on the first SCMD_REPORT_LUNS command */
 125 int     scsi_lunrpt_default_max = 256;
 126 int     scsi_lunrpt_timeout = 3;        /* seconds */
 127 
 128 /*
 129  * Only enumerate one lun if reportluns fails on a SCSI_VERSION_3 device
 130  * (tunable based on calling context).
 131  */
 132 int     scsi_lunrpt_failed_do1lun = (1 << SE_HP);
 133 
 134 /* 'scsi-binding-set' value for legacy enumerated 'spi' transports */
 135 char    *scsi_binding_set_spi = "spi";
 136 
 137 /* enable NDI_DEVI_DEBUG for bus_[un]config operations */
 138 int     scsi_hba_bus_config_debug = 0;
 139 
 140 /* DEBUG: enable NDI_DEVI_REMOVE for bus_unconfig of dynamic node */
 141 int     scsi_hba_bus_unconfig_remove = 0;
 142 
 143 /* number of probe serilization messages */
 144 int     scsi_hba_wait_msg = 5;
 145 
 146 /*
 147  * Establish the timeout used to cache (in the probe node) the fact that the
 148  * device does not exist. This replaces the target specific probe cache.
 149  */
 150 int     scsi_hba_barrier_timeout = (60);                /* seconds */
 151 
 152 #ifdef  DEBUG
 153 int     scsi_hba_bus_config_failure_msg = 0;
 154 int     scsi_hba_bus_config_failure_dbg = 0;
 155 int     scsi_hba_bus_config_success_msg = 0;
 156 int     scsi_hba_bus_config_success_dbg = 0;
 157 #endif  /* DEBUG */
 158 
 159 /*
 160  * Structure for scsi_hba_iportmap_* implementation/wrap.
 161  */
 162 typedef struct impl_scsi_iportmap {
 163         dev_info_t      *iportmap_hba_dip;
 164         damap_t         *iportmap_dam;
 165         int             iportmap_create_window;
 166         uint64_t        iportmap_create_time;           /* clock64_t */
 167         int             iportmap_create_csync_usec;
 168         int             iportmap_settle_usec;
 169         int             iportmap_sync_cnt;
 170 } impl_scsi_iportmap_t;
 171 
 172 /*
 173  * Structure for scsi_hba_tgtmap_* implementation/wrap.
 174  *
 175  * Every call to scsi_hba_tgtmap_set_begin will increment tgtmap_reports,
 176  * and a call to scsi_hba_tgtmap_set_end will reset tgtmap_reports to zero.
 177  * If, in scsi_hba_tgtmap_set_begin, we detect a tgtmap_reports value of
 178  * scsi_hba_tgtmap_reports_max we produce a message to indicate that
 179  * the caller is never completing an observation (i.e. we are not making
 180  * any forward progress). If this message occurs, it indicates that the
 181  * solaris hotplug ramifications at the target and lun level are no longer
 182  * tracking.
 183  *
 184  * NOTE: LUNMAPSIZE OK for now, but should be dynamic in reportlun code.
 185  */
 186 typedef struct impl_scsi_tgtmap {
 187         scsi_hba_tran_t *tgtmap_tran;
 188         int             tgtmap_reports;                 /* _begin, no _end */
 189         int             tgtmap_noisy;
 190         scsi_tgt_activate_cb_t          tgtmap_activate_cb;
 191         scsi_tgt_deactivate_cb_t        tgtmap_deactivate_cb;
 192         void            *tgtmap_mappriv;
 193         damap_t         *tgtmap_dam[SCSI_TGT_NTYPES];
 194         int             tgtmap_create_window;
 195         uint64_t        tgtmap_create_time;             /* clock64_t */
 196         int             tgtmap_create_csync_usec;
 197         int             tgtmap_settle_usec;
 198         int             tgtmap_sync_cnt;
 199 } impl_scsi_tgtmap_t;
 200 #define LUNMAPSIZE 256          /* 256 LUNs/target */
 201 
 202 /* Produce warning if number of begins without an end exceed this value */
 203 int     scsi_hba_tgtmap_reports_max = 256;
 204 
 205 static int      scsi_tgtmap_sync(scsi_hba_tgtmap_t *, int);
 206 
 207 /* Default settle_usec damap_sync factor */
 208 int     scsi_hba_map_settle_f = 10;
 209 
 210 
 211 /* Prototype for static dev_ops devo_*() functions */
 212 static int      scsi_hba_info(
 213                         dev_info_t              *self,
 214                         ddi_info_cmd_t          infocmd,
 215                         void                    *arg,
 216                         void                    **result);
 217 
 218 /* Prototypes for static bus_ops bus_*() functions */
 219 static int      scsi_hba_bus_ctl(
 220                         dev_info_t              *self,
 221                         dev_info_t              *child,
 222                         ddi_ctl_enum_t          op,
 223                         void                    *arg,
 224                         void                    *result);
 225 
 226 static int      scsi_hba_map_fault(
 227                         dev_info_t              *self,
 228                         dev_info_t              *child,
 229                         struct hat              *hat,
 230                         struct seg              *seg,
 231                         caddr_t                 addr,
 232                         struct devpage          *dp,
 233                         pfn_t                   pfn,
 234                         uint_t                  prot,
 235                         uint_t                  lock);
 236 
 237 static int      scsi_hba_get_eventcookie(
 238                         dev_info_t              *self,
 239                         dev_info_t              *child,
 240                         char                    *name,
 241                         ddi_eventcookie_t       *eventp);
 242 
 243 static int      scsi_hba_add_eventcall(
 244                         dev_info_t              *self,
 245                         dev_info_t              *child,
 246                         ddi_eventcookie_t       event,
 247                         void                    (*callback)(
 248                                 dev_info_t              *dip,
 249                                 ddi_eventcookie_t       event,
 250                                 void                    *arg,
 251                                 void                    *bus_impldata),
 252                         void                    *arg,
 253                         ddi_callback_id_t       *cb_id);
 254 
 255 static int      scsi_hba_remove_eventcall(
 256                         dev_info_t              *self,
 257                         ddi_callback_id_t       id);
 258 
 259 static int      scsi_hba_post_event(
 260                         dev_info_t              *self,
 261                         dev_info_t              *child,
 262                         ddi_eventcookie_t       event,
 263                         void                    *bus_impldata);
 264 
 265 static int      scsi_hba_bus_config(
 266                         dev_info_t              *self,
 267                         uint_t                  flags,
 268                         ddi_bus_config_op_t     op,
 269                         void                    *arg,
 270                         dev_info_t              **childp);
 271 
 272 static int      scsi_hba_bus_unconfig(
 273                         dev_info_t              *self,
 274                         uint_t                  flags,
 275                         ddi_bus_config_op_t     op,
 276                         void                    *arg);
 277 
 278 static int      scsi_hba_fm_init_child(
 279                         dev_info_t              *self,
 280                         dev_info_t              *child,
 281                         int                     cap,
 282                         ddi_iblock_cookie_t     *ibc);
 283 
 284 static int      scsi_hba_bus_power(
 285                         dev_info_t              *self,
 286                         void                    *impl_arg,
 287                         pm_bus_power_op_t       op,
 288                         void                    *arg,
 289                         void                    *result);
 290 
 291 /* bus_ops vector for SCSI HBA's. */
 292 static struct bus_ops scsi_hba_busops = {
 293         BUSO_REV,
 294         nullbusmap,                     /* bus_map */
 295         NULL,                           /* bus_get_intrspec */
 296         NULL,                           /* bus_add_intrspec */
 297         NULL,                           /* bus_remove_intrspec */
 298         scsi_hba_map_fault,             /* bus_map_fault */
 299         NULL,                           /* bus_dma_map */
 300         ddi_dma_allochdl,               /* bus_dma_allochdl */
 301         ddi_dma_freehdl,                /* bus_dma_freehdl */
 302         ddi_dma_bindhdl,                /* bus_dma_bindhdl */
 303         ddi_dma_unbindhdl,              /* bus_unbindhdl */
 304         ddi_dma_flush,                  /* bus_dma_flush */
 305         ddi_dma_win,                    /* bus_dma_win */
 306         ddi_dma_mctl,                   /* bus_dma_ctl */
 307         scsi_hba_bus_ctl,               /* bus_ctl */
 308         ddi_bus_prop_op,                /* bus_prop_op */
 309         scsi_hba_get_eventcookie,       /* bus_get_eventcookie */
 310         scsi_hba_add_eventcall,         /* bus_add_eventcall */
 311         scsi_hba_remove_eventcall,      /* bus_remove_eventcall */
 312         scsi_hba_post_event,            /* bus_post_event */
 313         NULL,                           /* bus_intr_ctl */
 314         scsi_hba_bus_config,            /* bus_config */
 315         scsi_hba_bus_unconfig,          /* bus_unconfig */
 316         scsi_hba_fm_init_child,         /* bus_fm_init */
 317         NULL,                           /* bus_fm_fini */
 318         NULL,                           /* bus_fm_access_enter */
 319         NULL,                           /* bus_fm_access_exit */
 320         scsi_hba_bus_power              /* bus_power */
 321 };
 322 
 323 /* cb_ops for hotplug :devctl and :scsi support */
 324 static struct cb_ops scsi_hba_cbops = {
 325         scsi_hba_open,
 326         scsi_hba_close,
 327         nodev,                  /* strategy */
 328         nodev,                  /* print */
 329         nodev,                  /* dump */
 330         nodev,                  /* read */
 331         nodev,                  /* write */
 332         scsi_hba_ioctl,         /* ioctl */
 333         nodev,                  /* devmap */
 334         nodev,                  /* mmap */
 335         nodev,                  /* segmap */
 336         nochpoll,               /* poll */
 337         ddi_prop_op,            /* prop_op */
 338         NULL,                   /* stream */
 339         D_NEW|D_MP|D_HOTPLUG,   /* cb_flag */
 340         CB_REV,                 /* rev */
 341         nodev,                  /* int (*cb_aread)() */
 342         nodev                   /* int (*cb_awrite)() */
 343 };
 344 
 345 /* Prototypes for static scsi_hba.c/SCSA private lunmap interfaces */
 346 static int      scsi_lunmap_create(
 347                         dev_info_t              *self,
 348                         impl_scsi_tgtmap_t      *tgtmap,
 349                         char                    *tgt_addr);
 350 static void     scsi_lunmap_destroy(
 351                         dev_info_t              *self,
 352                         impl_scsi_tgtmap_t      *tgtmap,
 353                         char                    *tgt_addr);
 354 static void     scsi_lunmap_set_begin(
 355                         dev_info_t              *self,
 356                         damap_t                 *lundam);
 357 static int      scsi_lunmap_set_add(
 358                         dev_info_t              *self,
 359                         damap_t                 *lundam,
 360                         char                    *taddr,
 361                         scsi_lun64_t            lun_num,
 362                         int                     lun_sfunc);
 363 static void     scsi_lunmap_set_end(
 364                         dev_info_t              *self,
 365                         damap_t                 *lundam);
 366 
 367 /* Prototypes for static misc. scsi_hba.c private bus_config interfaces */
 368 static int scsi_hba_bus_config_iports(dev_info_t *self, uint_t flags,
 369     ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
 370 static int scsi_hba_bus_config_spi(dev_info_t *self, uint_t flags,
 371     ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
 372 static dev_info_t *scsi_hba_bus_config_port(dev_info_t *self,
 373     char *nameaddr, scsi_enum_t se);
 374 
 375 #ifdef  sparc
 376 static int scsi_hba_bus_config_prom_node(dev_info_t *self, uint_t flags,
 377     void *arg, dev_info_t **childp);
 378 #endif  /* sparc */
 379 
 380 
 381 /*
 382  * SCSI_HBA_LOG is used for all messages. A logging level is specified when
 383  * generating a message. Some levels correspond directly to cmn_err levels,
 384  * some are associated with increasing levels diagnostic/debug output (LOG1-4),
 385  * and others are associated with specific levels of interface (LOGMAP).
 386  * For _LOG() messages, a __func__ prefix will identify the function origin
 387  * of the message. For _LOG_NF messages, there is no function prefix or
 388  * self/child context. Filtering of messages is provided based on logging
 389  * level, but messages with cmn_err logging level and messages generated
 390  * generated with _LOG_NF() are never filtered.
 391  *
 392  * For debugging, more complete information can be displayed with each message
 393  * (full device path and pointer values) by adjusting scsi_hba_log_info.
 394  */
 395 /* logging levels */
 396 #define SCSI_HBA_LOGCONT        CE_CONT
 397 #define SCSI_HBA_LOGNOTE        CE_NOTE
 398 #define SCSI_HBA_LOGWARN        CE_WARN
 399 #define SCSI_HBA_LOGPANIC       CE_PANIC
 400 #define SCSI_HBA_LOGIGNORE      CE_IGNORE
 401 #define SCSI_HBA_LOG_CE_MASK    0x0000000F      /* no filter for these levels */
 402 #define SCSI_HBA_LOG1           0x00000010      /* DIAG1 level enable */
 403 #define SCSI_HBA_LOG2           0x00000020      /* DIAG2 level enable */
 404 #define SCSI_HBA_LOG3           0x00000040      /* DIAG3 level enable */
 405 #define SCSI_HBA_LOG4           0x00000080      /* DIAG4 level enable */
 406 #define SCSI_HBA_LOGMAPPHY      0x00000100      /* MAPPHY level enable */
 407 #define SCSI_HBA_LOGMAPIPT      0x00000200      /* MAPIPT level enable */
 408 #define SCSI_HBA_LOGMAPTGT      0x00000400      /* MAPTGT level enable */
 409 #define SCSI_HBA_LOGMAPLUN      0x00000800      /* MAPLUN level enable */
 410 #define SCSI_HBA_LOGMAPCFG      0x00001000      /* MAPCFG level enable */
 411 #define SCSI_HBA_LOGMAPUNCFG    0x00002000      /* MAPUNCFG level enable */
 412 #define SCSI_HBA_LOGTRACE       0x00010000      /* TRACE enable */
 413 #if (CE_CONT | CE_NOTE | CE_WARN | CE_PANIC | CE_IGNORE) > SCSI_HBA_LOG_CE_MASK
 414 Error, problem with CE_ definitions
 415 #endif
 416 
 417 /*
 418  * Tunable log message augmentation and filters: filters do not apply to
 419  * SCSI_HBA_LOG_CE_MASK level messages or LOG_NF() messages.
 420  *
 421  * An example set of /etc/system tunings to simplify debug a SCSA pHCI HBA
 422  * driver called "pmcs", including "scsi_vhci" operation, by capturing
 423  * log information in the system log might be:
 424  *
 425  * echo "set scsi:scsi_hba_log_filter_level=0x3ff0"             >> /etc/system
 426  * echo "set scsi:scsi_hba_log_filter_phci=\"pmcs\""            >> /etc/system
 427  * echo "set scsi:scsi_hba_log_filter_vhci=\"scsi_vhci\""       >> /etc/system
 428  *
 429  * To capture information on just HBA-SCSAv3 *map operation, use
 430  * echo "set scsi:scsi_hba_log_filter_level=0x3f10"             >> /etc/system
 431  *
 432  * For debugging an HBA driver, you may also want to set:
 433  *
 434  * echo "set scsi:scsi_hba_log_align=1"                         >> /etc/system
 435  * echo "set scsi:scsi_hba_log_mt_disable=0x6"                  >> /etc/system
 436  * echo "set mtc_off=1"                                         >> /etc/system
 437  * echo "set mdi_mtc_off=1"                                     >> /etc/system
 438  * echo "set scsi:scsi_hba_log_fcif=0"                          >> /etc/system
 439  */
 440 int             scsi_hba_log_filter_level =
 441                         SCSI_HBA_LOG1 |
 442                         0;
 443 char            *scsi_hba_log_filter_phci = "\0\0\0\0\0\0\0\0\0\0\0\0";
 444 char            *scsi_hba_log_filter_vhci = "\0\0\0\0\0\0\0\0\0\0\0\0";
 445 int             scsi_hba_log_align = 0; /* NOTE: will not cause truncation */
 446 int             scsi_hba_log_fcif = '!'; /* "^!?" first char in format */
 447                                         /* NOTE: iff level > SCSI_HBA_LOG1 */
 448                                         /* '\0'0x00 -> console and system log */
 449                                         /* '^' 0x5e -> console_only */
 450                                         /* '!' 0x21 -> system log only */
 451                                         /* '?' 0x2F -> See cmn_err(9F) */
 452 int             scsi_hba_log_info =     /* augmentation: extra info output */
 453                         (0 << 0) |        /* 0x0001: process information */
 454                         (0 << 1) |        /* 0x0002: full /devices path */
 455                         (0 << 2); /* 0x0004: devinfo pointer */
 456 
 457 int             scsi_hba_log_mt_disable =
 458                         /* SCSI_ENUMERATION_MT_LUN_DISABLE |    (ie 0x02) */
 459                         /* SCSI_ENUMERATION_MT_TARGET_DISABLE | (ie 0x04) */
 460                         0;
 461 
 462 /* static data for HBA logging subsystem */
 463 static kmutex_t scsi_hba_log_mutex;
 464 static char     scsi_hba_log_i[512];
 465 static char     scsi_hba_log_buf[512];
 466 static char     scsi_hba_fmt[512];
 467 
 468 /* Macros to use in scsi_hba.c source code below */
 469 #define SCSI_HBA_LOG(x) scsi_hba_log x
 470 #define _LOG(level)     SCSI_HBA_LOG##level, __func__
 471 #define _MAP(map)       SCSI_HBA_LOGMAP##map, __func__
 472 #define _LOG_NF(level)  SCSI_HBA_LOG##level, NULL, NULL, NULL
 473 #define _LOG_TRACE      _LOG(TRACE)
 474 #define _LOGLUN         _MAP(LUN)
 475 #define _LOGTGT         _MAP(TGT)
 476 #define _LOGIPT         _MAP(IPT)
 477 #define _LOGPHY         _MAP(PHY)
 478 #define _LOGCFG         _MAP(CFG)
 479 #define _LOGUNCFG       _MAP(UNCFG)
 480 
 481 /*PRINTFLIKE5*/
 482 static void
 483 scsi_hba_log(int level, const char *func, dev_info_t *self, dev_info_t *child,
 484     const char *fmt, ...)
 485 {
 486         va_list         ap;
 487         int             clevel;
 488         int             align;
 489         char            *info;
 490         char            *f;
 491         char            *ua;
 492 
 493         /* derive self from child's parent */
 494         if ((self == NULL) && child)
 495                 self = ddi_get_parent(child);
 496 
 497         /* no filtering of SCSI_HBA_LOG_CE_MASK or LOG_NF messages */
 498         if (((level & SCSI_HBA_LOG_CE_MASK) != level) && (func != NULL)) {
 499                 /* scsi_hba_log_filter_level: filter on level as bitmask */
 500                 if ((level & scsi_hba_log_filter_level) == 0)
 501                         return;
 502 
 503                 /* scsi_hba_log_filter_phci/vhci: on name of driver */
 504                 if (*scsi_hba_log_filter_phci &&
 505                     ((self == NULL) ||
 506                     (ddi_driver_name(self) == NULL) ||
 507                     strcmp(ddi_driver_name(self), scsi_hba_log_filter_phci))) {
 508                         /* does not match pHCI, check vHCI */
 509                         if (*scsi_hba_log_filter_vhci &&
 510                             ((self == NULL) ||
 511                             (ddi_driver_name(self) == NULL) ||
 512                             strcmp(ddi_driver_name(self),
 513                             scsi_hba_log_filter_vhci))) {
 514                                 /* does not match vHCI */
 515                                 return;
 516                         }
 517                 }
 518 
 519 
 520                 /* passed filters, determine align */
 521                 align = scsi_hba_log_align;
 522 
 523                 /* shorten func for filtered output */
 524                 if (strncmp(func, "scsi_hba_", 9) == 0)
 525                         func += 9;
 526                 if (strncmp(func, "scsi_", 5) == 0)
 527                         func += 5;
 528         } else {
 529                 /* don't align output that is never filtered */
 530                 align = 0;
 531         }
 532 
 533         /* determine the cmn_err form from the level */
 534         clevel = ((level & SCSI_HBA_LOG_CE_MASK) == level) ? level : CE_CONT;
 535 
 536         /* protect common buffers used to format output */
 537         mutex_enter(&scsi_hba_log_mutex);
 538 
 539         /* skip special first characters, we add them back below */
 540         f = (char *)fmt;
 541         if (*f && strchr("^!?", *f))
 542                 f++;
 543         va_start(ap, fmt);
 544         (void) vsprintf(scsi_hba_log_buf, f, ap);
 545         va_end(ap);
 546 
 547         /* augment message with 'information' */
 548         info = scsi_hba_log_i;
 549         *info = '\0';
 550         if ((scsi_hba_log_info & 0x0001) && curproc && PTOU(curproc)->u_comm) {
 551                 (void) sprintf(info, "%s[%d]%p ",
 552                     PTOU(curproc)->u_comm, curproc->p_pid, (void *)curthread);
 553                 info += strlen(info);
 554         }
 555         if (self) {
 556                 if ((scsi_hba_log_info & 0x0004) && (child || self)) {
 557                         (void) sprintf(info, "%p ",
 558                             (void *)(child ? child : self));
 559                         info += strlen(info);
 560                 }
 561                 if (scsi_hba_log_info & 0x0002)     {
 562                         (void) ddi_pathname(child ? child : self, info);
 563                         (void) strcat(info, " ");
 564                         info += strlen(info);
 565                 }
 566 
 567                 /* always provide 'default' information about self &child */
 568                 (void) sprintf(info, "%s%d ", ddi_driver_name(self),
 569                     ddi_get_instance(self));
 570                 info += strlen(info);
 571                 if (child) {
 572                         ua = ddi_get_name_addr(child);
 573                         (void) sprintf(info, "%s@%s ",
 574                             ddi_node_name(child), (ua && *ua) ? ua : "");
 575                         info += strlen(info);
 576                 }
 577         }
 578 
 579         /* turn off alignment if truncation would occur */
 580         if (align && ((strlen(func) > 18) || (strlen(scsi_hba_log_i) > 36)))
 581                 align = 0;
 582 
 583         /* adjust for aligned output */
 584         if (align) {
 585                 if (func == NULL)
 586                         func = "";
 587                 /* remove trailing blank with align output */
 588                 if ((info != scsi_hba_log_i) && (*(info -1) == '\b'))
 589                         *(info - 1) = '\0';
 590         }
 591 
 592         /* special "first character in format" must be in format itself */
 593         f = scsi_hba_fmt;
 594         if (fmt[0] && strchr("^!?", fmt[0]))
 595                 *f++ = fmt[0];
 596         else if (scsi_hba_log_fcif && (level > SCSI_HBA_LOG1))
 597                 *f++ = (char)scsi_hba_log_fcif;         /* add global fcif */
 598         if (align)
 599                 (void) sprintf(f, "%s", "%-18.18s: %36.36s: %s%s");
 600         else
 601                 (void) sprintf(f, "%s", func ? "%s: %s%s%s" : "%s%s%s");
 602 
 603         if (func)
 604                 cmn_err(clevel, scsi_hba_fmt, func, scsi_hba_log_i,
 605                     scsi_hba_log_buf, clevel == CE_CONT ? "\n" : "");
 606         else
 607                 cmn_err(clevel, scsi_hba_fmt, scsi_hba_log_i,
 608                     scsi_hba_log_buf, clevel == CE_CONT ? "\n" : "");
 609         mutex_exit(&scsi_hba_log_mutex);
 610 }
 611 
 612 int     scsi_enumeration_failed_panic = 0;
 613 int     scsi_enumeration_failed_hotplug = 1;
 614 
 615 static void
 616 scsi_enumeration_failed(dev_info_t *child, scsi_enum_t se,
 617     char *arg, char *when)
 618 {
 619         /* If 'se' is -1 the 'se' value comes from child. */
 620         if (se == -1) {
 621                 ASSERT(child);
 622                 se = ndi_dev_is_hotplug_node(child) ? SE_HP : SE_BUSCONFIG;
 623         }
 624 
 625         if (scsi_enumeration_failed_panic) {
 626                 /* set scsi_enumeration_failed_panic to debug */
 627                 SCSI_HBA_LOG((_LOG(PANIC), NULL, child,
 628                     "%s%senumeration failed during %s",
 629                     arg ? arg : "", arg ? " " : "", when));
 630         } else if (scsi_enumeration_failed_hotplug && (se == SE_HP)) {
 631                 /* set scsi_enumeration_failed_hotplug for console messages */
 632                 SCSI_HBA_LOG((_LOG(WARN), NULL, child,
 633                     "%s%senumeration failed during %s",
 634                     arg ? arg : "", arg ? " " : "", when));
 635         } else {
 636                 /* default */
 637                 SCSI_HBA_LOG((_LOG(2), NULL, child,
 638                     "%s%senumeration failed during %s",
 639                     arg ? arg : "", arg ? " " : "", when));
 640         }
 641 }
 642 
 643 /*
 644  * scsi_hba version of [nm]di_devi_enter/[nm]di_devi_exit that detects if HBA
 645  * is a PHCI, and chooses mdi/ndi locking implementation.
 646  */
 647 static void
 648 scsi_hba_devi_enter(dev_info_t *self, int *circp)
 649 {
 650         if (MDI_PHCI(self))
 651                 mdi_devi_enter(self, circp);
 652         else
 653                 ndi_devi_enter(self, circp);
 654 }
 655 
 656 static int
 657 scsi_hba_devi_tryenter(dev_info_t *self, int *circp)
 658 {
 659         if (MDI_PHCI(self))
 660                 return (mdi_devi_tryenter(self, circp));
 661         else
 662                 return (ndi_devi_tryenter(self, circp));
 663 }
 664 
 665 static void
 666 scsi_hba_devi_exit(dev_info_t *self, int circ)
 667 {
 668         if (MDI_PHCI(self))
 669                 mdi_devi_exit(self, circ);
 670         else
 671                 ndi_devi_exit(self, circ);
 672 }
 673 
 674 static void
 675 scsi_hba_devi_enter_phci(dev_info_t *self, int *circp)
 676 {
 677         if (MDI_PHCI(self))
 678                 mdi_devi_enter_phci(self, circp);
 679 }
 680 
 681 static void
 682 scsi_hba_devi_exit_phci(dev_info_t *self, int circ)
 683 {
 684         if (MDI_PHCI(self))
 685                 mdi_devi_exit_phci(self, circ);
 686 }
 687 
 688 static int
 689 scsi_hba_dev_is_sid(dev_info_t *child)
 690 {
 691         /*
 692          * Use ndi_dev_is_persistent_node instead of ddi_dev_is_sid to avoid
 693          * any possible locking issues in mixed nexus devctl code (like usb).
 694          */
 695         return (ndi_dev_is_persistent_node(child));
 696 }
 697 
 698 /*
 699  * Called from _init() when loading "scsi" module
 700  */
 701 void
 702 scsi_initialize_hba_interface()
 703 {
 704         SCSI_HBA_LOG((_LOG_TRACE, NULL, NULL, __func__));
 705 
 706         /* We need "scsiprobe" and "scsinodev" as an alias or a driver. */
 707         if (ddi_name_to_major(compatible_probe) == DDI_MAJOR_T_NONE) {
 708                 SCSI_HBA_LOG((_LOG_NF(WARN), "failed to resolve '%s' "
 709                     "driver alias, defaulting to 'nulldriver'",
 710                     compatible_probe));
 711 
 712                 /* If no "nulldriver" driver nothing will work... */
 713                 compatible_probe = "nulldriver";
 714                 if (ddi_name_to_major(compatible_probe) == DDI_MAJOR_T_NONE)
 715                         SCSI_HBA_LOG((_LOG_NF(WARN), "no probe '%s' driver, "
 716                             "system misconfigured", compatible_probe));
 717         }
 718         if (ddi_name_to_major(compatible_nodev) == DDI_MAJOR_T_NONE) {
 719                 SCSI_HBA_LOG((_LOG_NF(WARN), "failed to resolve '%s' "
 720                     "driver alias, defaulting to 'nulldriver'",
 721                     compatible_nodev));
 722 
 723                 /* If no "nulldriver" driver nothing will work... */
 724                 compatible_nodev = "nulldriver";
 725                 if (ddi_name_to_major(compatible_nodev) == DDI_MAJOR_T_NONE)
 726                         SCSI_HBA_LOG((_LOG_NF(WARN), "no nodev '%s' driver, "
 727                             "system misconfigured", compatible_nodev));
 728         }
 729 
 730         /*
 731          * Verify our special node name "probe" will not be used in other ways.
 732          * Don't expect things to work if they are.
 733          */
 734         if (ddi_major_to_name(ddi_name_to_major("probe")))
 735                 SCSI_HBA_LOG((_LOG_NF(WARN),
 736                     "driver already using special node name 'probe'"));
 737 
 738         mutex_init(&scsi_log_mutex, NULL, MUTEX_DRIVER, NULL);
 739         mutex_init(&scsi_flag_nointr_mutex, NULL, MUTEX_DRIVER, NULL);
 740         cv_init(&scsi_flag_nointr_cv, NULL, CV_DRIVER, NULL);
 741         mutex_init(&scsi_hba_log_mutex, NULL, MUTEX_DRIVER, NULL);
 742 
 743         /* initialize the asynchronous barrier deletion daemon */
 744         mutex_init(&scsi_hba_barrier_mutex, NULL, MUTEX_DRIVER, NULL);
 745         cv_init(&scsi_hba_barrier_cv, NULL, CV_DRIVER, NULL);
 746         (void) thread_create(NULL, 0,
 747             (void (*)())scsi_hba_barrier_daemon, NULL,
 748             0, &p0, TS_RUN, minclsyspri);
 749 
 750         /* initialize lun change ASC/ASCQ processing daemon (stage1 & stage2) */
 751         mutex_init(&scsi_lunchg1_mutex, NULL, MUTEX_DRIVER, NULL);
 752         cv_init(&scsi_lunchg1_cv, NULL, CV_DRIVER, NULL);
 753         (void) thread_create(NULL, 0,
 754             (void (*)())scsi_lunchg1_daemon, NULL,
 755             0, &p0, TS_RUN, minclsyspri);
 756         mutex_init(&scsi_lunchg2_mutex, NULL, MUTEX_DRIVER, NULL);
 757         cv_init(&scsi_lunchg2_cv, NULL, CV_DRIVER, NULL);
 758         (void) thread_create(NULL, 0,
 759             (void (*)())scsi_lunchg2_daemon, NULL,
 760             0, &p0, TS_RUN, minclsyspri);
 761 }
 762 
 763 int
 764 scsi_hba_pkt_constructor(void *buf, void *arg, int kmflag)
 765 {
 766         struct scsi_pkt_cache_wrapper *pktw;
 767         struct scsi_pkt         *pkt;
 768         scsi_hba_tran_t         *tran = (scsi_hba_tran_t *)arg;
 769         int                     pkt_len;
 770         char                    *ptr;
 771 
 772         /*
 773          * allocate a chunk of memory for the following:
 774          * scsi_pkt
 775          * pcw_* fields
 776          * pkt_ha_private
 777          * pkt_cdbp, if needed
 778          * (pkt_private always null)
 779          * pkt_scbp, if needed
 780          */
 781         pkt_len = tran->tran_hba_len + sizeof (struct scsi_pkt_cache_wrapper);
 782         if (tran->tran_hba_flags & SCSI_HBA_TRAN_CDB)
 783                 pkt_len += DEFAULT_CDBLEN;
 784         if (tran->tran_hba_flags & SCSI_HBA_TRAN_SCB)
 785                 pkt_len += DEFAULT_SCBLEN;
 786         bzero(buf, pkt_len);
 787 
 788         ptr = buf;
 789         pktw = buf;
 790         ptr += sizeof (struct scsi_pkt_cache_wrapper);
 791         pkt = &(pktw->pcw_pkt);
 792         pkt->pkt_ha_private = (opaque_t)ptr;
 793 
 794         pktw->pcw_magic = PKT_WRAPPER_MAGIC; /* alloced correctly */
 795         /*
 796          * keep track of the granularity at the time this handle was
 797          * allocated
 798          */
 799         pktw->pcw_granular = tran->tran_dma_attr.dma_attr_granular;
 800 
 801         if (ddi_dma_alloc_handle(tran->tran_hba_dip, &tran->tran_dma_attr,
 802             kmflag == KM_SLEEP ? SLEEP_FUNC: NULL_FUNC, NULL,
 803             &pkt->pkt_handle) != DDI_SUCCESS) {
 804 
 805                 return (-1);
 806         }
 807         ptr += tran->tran_hba_len;
 808         if (tran->tran_hba_flags & SCSI_HBA_TRAN_CDB) {
 809                 pkt->pkt_cdbp = (opaque_t)ptr;
 810                 ptr += DEFAULT_CDBLEN;
 811         }
 812         pkt->pkt_private = NULL;
 813         if (tran->tran_hba_flags & SCSI_HBA_TRAN_SCB)
 814                 pkt->pkt_scbp = (opaque_t)ptr;
 815         if (tran->tran_pkt_constructor)
 816                 return ((*tran->tran_pkt_constructor)(pkt, arg, kmflag));
 817         else
 818                 return (0);
 819 }
 820 
 821 #define P_TO_TRAN(pkt)  ((pkt)->pkt_address.a_hba_tran)
 822 
 823 void
 824 scsi_hba_pkt_destructor(void *buf, void *arg)
 825 {
 826         struct scsi_pkt_cache_wrapper *pktw = buf;
 827         struct scsi_pkt         *pkt = &(pktw->pcw_pkt);
 828         scsi_hba_tran_t         *tran = (scsi_hba_tran_t *)arg;
 829 
 830         ASSERT(pktw->pcw_magic == PKT_WRAPPER_MAGIC);
 831         ASSERT((pktw->pcw_flags & PCW_BOUND) == 0);
 832         if (tran->tran_pkt_destructor)
 833                 (*tran->tran_pkt_destructor)(pkt, arg);
 834 
 835         /* make sure nobody messed with our pointers */
 836         ASSERT(pkt->pkt_ha_private == (opaque_t)((char *)pkt +
 837             sizeof (struct scsi_pkt_cache_wrapper)));
 838         ASSERT(((tran->tran_hba_flags & SCSI_HBA_TRAN_SCB) == 0) ||
 839             (pkt->pkt_scbp == (opaque_t)((char *)pkt +
 840             tran->tran_hba_len +
 841             (((tran->tran_hba_flags & SCSI_HBA_TRAN_CDB) == 0) ?
 842             0 : DEFAULT_CDBLEN) +
 843             DEFAULT_PRIVLEN + sizeof (struct scsi_pkt_cache_wrapper))));
 844         ASSERT(((tran->tran_hba_flags & SCSI_HBA_TRAN_CDB) == 0) ||
 845             (pkt->pkt_cdbp == (opaque_t)((char *)pkt +
 846             tran->tran_hba_len +
 847             sizeof (struct scsi_pkt_cache_wrapper))));
 848         ASSERT(pkt->pkt_handle);
 849         ddi_dma_free_handle(&pkt->pkt_handle);
 850         pkt->pkt_handle = NULL;
 851         pkt->pkt_numcookies = 0;
 852         pktw->pcw_total_xfer = 0;
 853         pktw->pcw_totalwin = 0;
 854         pktw->pcw_curwin = 0;
 855 }
 856 
 857 /*
 858  * Called by an HBA from _init() to plumb in common SCSA bus_ops and
 859  * cb_ops for the HBA's :devctl and :scsi minor nodes.
 860  */
 861 int
 862 scsi_hba_init(struct modlinkage *modlp)
 863 {
 864         struct dev_ops *hba_dev_ops;
 865 
 866         SCSI_HBA_LOG((_LOG_TRACE, NULL, NULL, __func__));
 867 
 868         /*
 869          * Get a pointer to the dev_ops structure of the HBA and plumb our
 870          * bus_ops vector into the HBA's dev_ops structure.
 871          */
 872         hba_dev_ops = ((struct modldrv *)(modlp->ml_linkage[0]))->drv_dev_ops;
 873         ASSERT(hba_dev_ops->devo_bus_ops == NULL);
 874         hba_dev_ops->devo_bus_ops = &scsi_hba_busops;
 875 
 876         /*
 877          * Plumb our cb_ops vector into the HBA's dev_ops structure to
 878          * provide getinfo and hotplugging ioctl support if the HBA driver
 879          * does not already provide this support.
 880          */
 881         if (hba_dev_ops->devo_cb_ops == NULL) {
 882                 hba_dev_ops->devo_cb_ops = &scsi_hba_cbops;
 883         }
 884         if (hba_dev_ops->devo_cb_ops->cb_open == scsi_hba_open) {
 885                 ASSERT(hba_dev_ops->devo_cb_ops->cb_close == scsi_hba_close);
 886                 hba_dev_ops->devo_getinfo = scsi_hba_info;
 887         }
 888         return (0);
 889 }
 890 
 891 /*
 892  * Called by an HBA attach(9E) to allocate a scsi_hba_tran(9S) structure. An
 893  * HBA driver will then initialize the structure and then call
 894  * scsi_hba_attach_setup(9F).
 895  */
 896 /*ARGSUSED*/
 897 scsi_hba_tran_t *
 898 scsi_hba_tran_alloc(
 899         dev_info_t              *self,
 900         int                     flags)
 901 {
 902         scsi_hba_tran_t         *tran;
 903 
 904         SCSI_HBA_LOG((_LOG_TRACE, self, NULL, __func__));
 905 
 906         /* allocate SCSA flavors for self */
 907         ndi_flavorv_alloc(self, SCSA_NFLAVORS);
 908 
 909         tran = kmem_zalloc(sizeof (scsi_hba_tran_t),
 910             (flags & SCSI_HBA_CANSLEEP) ? KM_SLEEP : KM_NOSLEEP);
 911 
 912         if (tran) {
 913                 tran->tran_interconnect_type = INTERCONNECT_PARALLEL;
 914 
 915                 /*
 916                  * HBA driver called scsi_hba_tran_alloc(), so tran structure
 917                  * is proper size and unused/newer fields are zero.
 918                  *
 919                  * NOTE: We use SCSA_HBA_SCSA_TA as an obtuse form of
 920                  * versioning to detect old HBA drivers that do not use
 921                  * scsi_hba_tran_alloc, and would present garbage data
 922                  * (instead of valid/zero data) for newer tran fields.
 923                  */
 924                 tran->tran_hba_flags |= SCSI_HBA_SCSA_TA;
 925         }
 926 
 927         return (tran);
 928 }
 929 
 930 /*
 931  * Called by an HBA to free a scsi_hba_tran structure
 932  */
 933 void
 934 scsi_hba_tran_free(
 935         scsi_hba_tran_t         *tran)
 936 {
 937         SCSI_HBA_LOG((_LOG_TRACE, tran->tran_hba_dip, NULL, __func__));
 938 
 939         kmem_free(tran, sizeof (scsi_hba_tran_t));
 940 }
 941 
 942 int
 943 scsi_tran_ext_alloc(
 944         scsi_hba_tran_t         *tran,
 945         size_t                  length,
 946         int                     flags)
 947 {
 948         void    *tran_ext;
 949         int     ret = DDI_FAILURE;
 950 
 951         tran_ext = kmem_zalloc(length,
 952             (flags & SCSI_HBA_CANSLEEP) ? KM_SLEEP : KM_NOSLEEP);
 953         if (tran_ext != NULL) {
 954                 tran->tran_extension = tran_ext;
 955                 ret = DDI_SUCCESS;
 956         }
 957         return (ret);
 958 }
 959 
 960 void
 961 scsi_tran_ext_free(
 962         scsi_hba_tran_t         *tran,
 963         size_t                  length)
 964 {
 965         if (tran->tran_extension != NULL) {
 966                 kmem_free(tran->tran_extension, length);
 967                 tran->tran_extension = NULL;
 968         }
 969 }
 970 
 971 /*
 972  * Common nexus teardown code: used by both scsi_hba_detach() on SCSA HBA node
 973  * and iport_postdetach_tran_scsi_device() on a SCSA HBA iport node (and for
 974  * failure cleanup). Undo scsa_nexus_setup in reverse order.
 975  *
 976  * NOTE: Since we are in the Solaris IO framework, we can depend on
 977  * undocumented cleanup operations performed by other parts of the framework:
 978  * like detach_node() calling ddi_prop_remove_all() and
 979  * ddi_remove_minor_node(,NULL).
 980  */
 981 static void
 982 scsa_nexus_teardown(dev_info_t *self, scsi_hba_tran_t   *tran)
 983 {
 984         /* Teardown FMA. */
 985         if (tran->tran_hba_flags & SCSI_HBA_SCSA_FM) {
 986                 ddi_fm_fini(self);
 987                 tran->tran_hba_flags &= ~SCSI_HBA_SCSA_FM;
 988         }
 989 }
 990 
 991 /*
 992  * Common nexus setup code: used by both scsi_hba_attach_setup() on SCSA HBA
 993  * node and iport_preattach_tran_scsi_device() on a SCSA HBA iport node.
 994  *
 995  * This code makes no assumptions about tran use by scsi_device children.
 996  */
 997 static int
 998 scsa_nexus_setup(dev_info_t *self, scsi_hba_tran_t *tran)
 999 {
1000         int             capable;
1001         int             scsa_minor;
1002 
1003         /*
1004          * NOTE: SCSA maintains an 'fm-capable' domain, in tran_fm_capable,
1005          * that is not dependent (limited by) the capabilities of its parents.
1006          * For example a devinfo node in a branch that is not
1007          * DDI_FM_EREPORT_CAPABLE may report as capable, via tran_fm_capable,
1008          * to its scsi_device children.
1009          *
1010          * Get 'fm-capable' property from driver.conf, if present. If not
1011          * present, default to the scsi_fm_capable global (which has
1012          * DDI_FM_EREPORT_CAPABLE set by default).
1013          */
1014         if (tran->tran_fm_capable == DDI_FM_NOT_CAPABLE)
1015                 tran->tran_fm_capable = ddi_prop_get_int(DDI_DEV_T_ANY, self,
1016                     DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1017                     "fm-capable", scsi_fm_capable);
1018 
1019         /*
1020          * If an HBA is *not* doing its own fma support by calling
1021          * ddi_fm_init() prior to scsi_hba_attach_setup(), we provide a minimal
1022          * common SCSA implementation so that scsi_device children can generate
1023          * ereports via scsi_fm_ereport_post().  We use ddi_fm_capable() to
1024          * detect an HBA calling ddi_fm_init() prior to scsi_hba_attach_setup().
1025          */
1026         if (tran->tran_fm_capable &&
1027             (ddi_fm_capable(self) == DDI_FM_NOT_CAPABLE)) {
1028                 /*
1029                  * We are capable of something, pass our capabilities up the
1030                  * tree, but use a local variable so our parent can't limit
1031                  * our capabilities (we don't want our parent to clear
1032                  * DDI_FM_EREPORT_CAPABLE).
1033                  *
1034                  * NOTE: iblock cookies are not important because scsi HBAs
1035                  * always interrupt below LOCK_LEVEL.
1036                  */
1037                 capable = tran->tran_fm_capable;
1038                 ddi_fm_init(self, &capable, NULL);
1039 
1040                 /*
1041                  * Set SCSI_HBA_SCSA_FM bit to mark us as using the common
1042                  * minimal SCSA fm implementation -  we called ddi_fm_init(),
1043                  * so we are responsible for calling ddi_fm_fini() in
1044                  * scsi_hba_detach().
1045                  *
1046                  * NOTE: if ddi_fm_init fails to establish handle, SKIP cleanup.
1047                  */
1048                 if (DEVI(self)->devi_fmhdl)
1049                         tran->tran_hba_flags |= SCSI_HBA_SCSA_FM;
1050         }
1051 
1052         /* If SCSA responsible for for minor nodes, create :devctl minor. */
1053         scsa_minor = (ddi_get_driver(self)->devo_cb_ops->cb_open ==
1054             scsi_hba_open) ? 1 : 0;
1055         if (scsa_minor && ((ddi_create_minor_node(self, "devctl", S_IFCHR,
1056             INST2DEVCTL(ddi_get_instance(self)), DDI_NT_SCSI_NEXUS, 0) !=
1057             DDI_SUCCESS))) {
1058                 SCSI_HBA_LOG((_LOG(WARN), self, NULL,
1059                     "can't create :devctl minor node"));
1060                 goto fail;
1061         }
1062 
1063         return (DDI_SUCCESS);
1064 
1065 fail:   scsa_nexus_teardown(self, tran);
1066         return (DDI_FAILURE);
1067 }
1068 
1069 /*
1070  * Common tran teardown code: used by iport_postdetach_tran_scsi_device() on a
1071  * SCSA HBA iport node and (possibly) by scsi_hba_detach() on SCSA HBA node
1072  * (and for failure cleanup). Undo scsa_tran_setup in reverse order.
1073  *
1074  * NOTE: Since we are in the Solaris IO framework, we can depend on
1075  * undocumented cleanup operations performed by other parts of the framework:
1076  * like detach_node() calling ddi_prop_remove_all() and
1077  * ddi_remove_minor_node(,NULL).
1078  */
1079 static void
1080 scsa_tran_teardown(dev_info_t *self, scsi_hba_tran_t *tran)
1081 {
1082         tran->tran_iport_dip = NULL;
1083 
1084         /* Teardown pHCI registration */
1085         if (tran->tran_hba_flags & SCSI_HBA_SCSA_PHCI) {
1086                 (void) mdi_phci_unregister(self, 0);
1087                 tran->tran_hba_flags &= ~SCSI_HBA_SCSA_PHCI;
1088         }
1089 }
1090 
1091 /*
1092  * Common tran setup code: used by iport_preattach_tran_scsi_device() on a
1093  * SCSA HBA iport node and (possibly) by scsi_hba_attach_setup() on SCSA HBA
1094  * node.
1095  */
1096 static int
1097 scsa_tran_setup(dev_info_t *self, scsi_hba_tran_t *tran)
1098 {
1099         int                     scsa_minor;
1100         int                     id;
1101         char                    *scsi_binding_set;
1102         static const char       *interconnect[] = INTERCONNECT_TYPE_ASCII;
1103 
1104         SCSI_HBA_LOG((_LOG_TRACE, self, NULL, __func__));
1105 
1106         /* If SCSA responsible for for minor nodes, create ":scsi" */
1107         scsa_minor = (ddi_get_driver(self)->devo_cb_ops->cb_open ==
1108             scsi_hba_open) ? 1 : 0;
1109         if (scsa_minor && (ddi_create_minor_node(self, "scsi", S_IFCHR,
1110             INST2SCSI(ddi_get_instance(self)),
1111             DDI_NT_SCSI_ATTACHMENT_POINT, 0) != DDI_SUCCESS)) {
1112                 SCSI_HBA_LOG((_LOG(WARN), self, NULL,
1113                     "can't create :scsi minor node"));
1114                 goto fail;
1115         }
1116 
1117         /*
1118          * If the property does not already exist on self then see if we can
1119          * pull it from further up the tree and define it on self. If the
1120          * property does not exist above (including options.conf) then use the
1121          * default value specified (global variable). We pull things down from
1122          * above for faster "DDI_PROP_NOTPROM | DDI_PROP_DONTPASS" runtime
1123          * access.
1124          *
1125          * Future: Should we avoid creating properties when value == global?
1126          */
1127 #define CONFIG_INT_PROP(s, p, dv)       {                       \
1128         if ((ddi_prop_exists(DDI_DEV_T_ANY, s,                  \
1129             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, p) == 0) &&   \
1130             (ndi_prop_update_int(DDI_DEV_T_NONE, s, p,          \
1131             ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(s),  \
1132             DDI_PROP_NOTPROM, p, dv)) != DDI_PROP_SUCCESS))     \
1133                 SCSI_HBA_LOG((_LOG(WARN), NULL, s,              \
1134                     "can't create property '%s'", p));          \
1135         }
1136 
1137         /* Decorate with scsi configuration properties */
1138         CONFIG_INT_PROP(self, "scsi-enumeration", scsi_enumeration);
1139         CONFIG_INT_PROP(self, "scsi-options", scsi_options);
1140         CONFIG_INT_PROP(self, "scsi-reset-delay", scsi_reset_delay);
1141         CONFIG_INT_PROP(self, "scsi-watchdog-tick", scsi_watchdog_tick);
1142         CONFIG_INT_PROP(self, "scsi-selection-timeout", scsi_selection_timeout);
1143         CONFIG_INT_PROP(self, "scsi-tag-age-limit", scsi_tag_age_limit);
1144 
1145         /*
1146          * Pull down the scsi-initiator-id from further up the tree, or as
1147          * defined by OBP. Place on node for faster access. NOTE: there is
1148          * some confusion about what the name of the property should be.
1149          */
1150         id = ddi_prop_get_int(DDI_DEV_T_ANY, self, 0, "initiator-id", -1);
1151         if (id == -1)
1152                 id = ddi_prop_get_int(DDI_DEV_T_ANY, self, 0,
1153                     "scsi-initiator-id", -1);
1154         if (id != -1)
1155                 CONFIG_INT_PROP(self, "scsi-initiator-id", id);
1156 
1157         /*
1158          * If we are responsible for tran allocation, establish
1159          * 'initiator-interconnect-type'.
1160          */
1161         if ((tran->tran_hba_flags & SCSI_HBA_SCSA_TA) &&
1162             (tran->tran_interconnect_type > 0) &&
1163             (tran->tran_interconnect_type < INTERCONNECT_MAX)) {
1164                 if (ndi_prop_update_string(DDI_DEV_T_NONE, self,
1165                     "initiator-interconnect-type",
1166                     (char *)interconnect[tran->tran_interconnect_type])
1167                     != DDI_PROP_SUCCESS) {
1168                         SCSI_HBA_LOG((_LOG(WARN), self, NULL,
1169                             "failed to establish "
1170                             "'initiator-interconnect-type'"));
1171                         goto fail;
1172                 }
1173         }
1174 
1175         /*
1176          * The 'scsi-binding-set' property can be defined in driver.conf
1177          * files of legacy drivers on an as-needed basis. If 'scsi-binding-set'
1178          * is not driver.conf defined, and the HBA is not implementing its own
1179          * private bus_config, we define scsi-binding-set to the default
1180          * 'spi' legacy value.
1181          *
1182          * NOTE: This default 'spi' value will be deleted if an HBA driver
1183          * ends up using the scsi_hba_tgtmap_create() enumeration services.
1184          *
1185          * NOTE: If we were ever to decide to derive 'scsi-binding-set' from
1186          * the IEEE-1275 'device_type' property then this is where that code
1187          * should go - there is not enough consistency in 'device_type' to do
1188          * this correctly at this point in time.
1189          */
1190         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, self,
1191             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-binding-set",
1192             &scsi_binding_set) == DDI_PROP_SUCCESS) {
1193                 SCSI_HBA_LOG((_LOG(2), NULL, self,
1194                     "external 'scsi-binding-set' \"%s\"", scsi_binding_set));
1195                 ddi_prop_free(scsi_binding_set);
1196         } else if (scsi_binding_set_spi &&
1197             ((tran->tran_bus_config == NULL) ||
1198             (tran->tran_bus_config == scsi_hba_bus_config_spi))) {
1199                 if (ndi_prop_update_string(DDI_DEV_T_NONE, self,
1200                     "scsi-binding-set", scsi_binding_set_spi) !=
1201                     DDI_PROP_SUCCESS) {
1202                         SCSI_HBA_LOG((_LOG(WARN), self, NULL,
1203                             "failed to establish 'scsi_binding_set' default"));
1204                         goto fail;
1205                 }
1206                 SCSI_HBA_LOG((_LOG(2), NULL, self,
1207                     "default 'scsi-binding-set' \"%s\"", scsi_binding_set_spi));
1208         } else
1209                 SCSI_HBA_LOG((_LOG(2), NULL, self,
1210                     "no 'scsi-binding-set'"));
1211 
1212         /*
1213          * If SCSI_HBA_TRAN_PHCI is set, take care of pHCI registration of the
1214          * initiator.
1215          */
1216         if ((tran->tran_hba_flags & SCSI_HBA_TRAN_PHCI) &&
1217             (mdi_phci_register(MDI_HCI_CLASS_SCSI, self, 0) == MDI_SUCCESS))
1218                 tran->tran_hba_flags |= SCSI_HBA_SCSA_PHCI;
1219 
1220         /* NOTE: tran_hba_dip is for DMA operation at the HBA node level */
1221         tran->tran_iport_dip = self;         /* for iport association */
1222         return (DDI_SUCCESS);
1223 
1224 fail:   scsa_tran_teardown(self, tran);
1225         return (DDI_FAILURE);
1226 }
1227 
1228 /*
1229  * Called by a SCSA HBA driver to attach an instance of the driver to
1230  * SCSA HBA node  enumerated by PCI.
1231  */
1232 int
1233 scsi_hba_attach_setup(
1234         dev_info_t              *self,
1235         ddi_dma_attr_t          *hba_dma_attr,
1236         scsi_hba_tran_t         *tran,
1237         int                     flags)
1238 {
1239         int                     len;
1240         char                    cache_name[96];
1241 
1242         SCSI_HBA_LOG((_LOG_TRACE, self, NULL, __func__));
1243 
1244         /*
1245          * Verify that we are a driver so other code does not need to
1246          * check for NULL ddi_get_driver() result.
1247          */
1248         if (ddi_get_driver(self) == NULL)
1249                 return (DDI_FAILURE);
1250 
1251         /*
1252          * Verify that we are called on a SCSA HBA node (function enumerated
1253          * by PCI), not on an iport node.
1254          */
1255         ASSERT(scsi_hba_iport_unit_address(self) == NULL);
1256         if (scsi_hba_iport_unit_address(self))
1257                 return (DDI_FAILURE);           /* self can't be an iport */
1258 
1259         /* Caller must provide the tran. */
1260         ASSERT(tran);
1261         if (tran == NULL)
1262                 return (DDI_FAILURE);
1263 
1264         /*
1265          * Verify correct scsi_hba_tran_t form:
1266          *
1267          * o Both or none of tran_get_name/tran_get_addr.
1268          *   NOTE: Older  SCSA HBA drivers for SCSI transports with addressing
1269          *   that did not fit the SPI "struct scsi_address" model were required
1270          *   to implement tran_get_name and tran_get_addr. This is no longer
1271          *   true - modern transport drivers should now use common SCSA
1272          *   enumeration services.  The SCSA enumeration code will represent
1273          *   the unit-address using well-known address properties
1274          *   (SCSI_ADDR_PROP_TARGET_PORT, SCSI_ADDR_PROP_LUN64) during
1275          *   devinfo/pathinfo node creation. The HBA driver can obtain values
1276          *   using scsi_device_prop_lookup_*() from its tran_tgt_init(9E).
1277          *
1278          */
1279         if ((tran->tran_get_name == NULL) ^ (tran->tran_get_bus_addr == NULL)) {
1280                 SCSI_HBA_LOG((_LOG(WARN), self, NULL,
1281                     "should support both or neither: "
1282                     "tran_get_name, tran_get_bus_addr"));
1283                 return (DDI_FAILURE);
1284         }
1285 
1286         /*
1287          * Establish the devinfo context of this tran structure, preserving
1288          * knowledge of how the tran was allocated.
1289          */
1290         tran->tran_hba_dip = self;           /* for DMA */
1291         tran->tran_hba_flags = (flags & ~SCSI_HBA_SCSA_TA) |
1292             (tran->tran_hba_flags & SCSI_HBA_SCSA_TA);
1293 
1294         /* Establish flavor of transport (and ddi_get_driver_private()) */
1295         ndi_flavorv_set(self, SCSA_FLAVOR_SCSI_DEVICE, tran);
1296 
1297         /*
1298          * Note: We only need dma_attr_minxfer and dma_attr_burstsizes
1299          * from the DMA attributes. scsi_hba_attach(9f) only guarantees
1300          * that these two fields are initialized properly. If this
1301          * changes, be sure to revisit the implementation of
1302          * scsi_hba_attach(9F).
1303          */
1304         (void) memcpy(&tran->tran_dma_attr, hba_dma_attr,
1305             sizeof (ddi_dma_attr_t));
1306 
1307         /* Create tran_setup_pkt(9E) kmem_cache. */
1308         if (tran->tran_setup_pkt) {
1309                 ASSERT(tran->tran_init_pkt == NULL);
1310                 ASSERT(tran->tran_destroy_pkt == NULL);
1311                 if (tran->tran_init_pkt || tran->tran_destroy_pkt)
1312                         goto fail;
1313 
1314                 tran->tran_init_pkt = scsi_init_cache_pkt;
1315                 tran->tran_destroy_pkt = scsi_free_cache_pkt;
1316                 tran->tran_sync_pkt = scsi_sync_cache_pkt;
1317                 tran->tran_dmafree = scsi_cache_dmafree;
1318 
1319                 len = sizeof (struct scsi_pkt_cache_wrapper);
1320                 len += ROUNDUP(tran->tran_hba_len);
1321                 if (tran->tran_hba_flags & SCSI_HBA_TRAN_CDB)
1322                         len += ROUNDUP(DEFAULT_CDBLEN);
1323                 if (tran->tran_hba_flags & SCSI_HBA_TRAN_SCB)
1324                         len += ROUNDUP(DEFAULT_SCBLEN);
1325 
1326                 (void) snprintf(cache_name, sizeof (cache_name),
1327                     "pkt_cache_%s_%d", ddi_driver_name(self),
1328                     ddi_get_instance(self));
1329 
1330                 tran->tran_pkt_cache_ptr = kmem_cache_create(
1331                     cache_name, len, 8, scsi_hba_pkt_constructor,
1332                     scsi_hba_pkt_destructor, NULL, tran, NULL, 0);
1333         }
1334 
1335         /* Perform node setup independent of initiator role */
1336         if (scsa_nexus_setup(self, tran) != DDI_SUCCESS)
1337                 goto fail;
1338 
1339         /*
1340          * The SCSI_HBA_HBA flag is passed to scsi_hba_attach_setup when the
1341          * HBA driver knows that *all* children of the SCSA HBA node will be
1342          * 'iports'. If the SCSA HBA node can have iport children and also
1343          * function as an initiator for xxx_device children then it should
1344          * not specify SCSI_HBA_HBA in its scsi_hba_attach_setup call. An
1345          * HBA driver that does not manage iports should not set SCSA_HBA_HBA.
1346          */
1347         if (tran->tran_hba_flags & SCSI_HBA_HBA) {
1348                 /*
1349                  * Set the 'ddi-config-driver-node' property on the nexus
1350                  * node that notify attach_driver_nodes() to configure all
1351                  * immediate children so that nodes which bind to the
1352                  * same driver as parent are able to be added into per-driver
1353                  * list.
1354                  */
1355                 if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
1356                     self, "ddi-config-driver-node") != DDI_PROP_SUCCESS)
1357                         goto fail;
1358         } else {
1359                 if (scsa_tran_setup(self, tran) != DDI_SUCCESS)
1360                         goto fail;
1361         }
1362 
1363         return (DDI_SUCCESS);
1364 
1365 fail:   (void) scsi_hba_detach(self);
1366         return (DDI_FAILURE);
1367 }
1368 
1369 /*
1370  * Called by an HBA to detach an instance of the driver. This may be called
1371  * for SCSA HBA nodes and for SCSA iport nodes.
1372  */
1373 int
1374 scsi_hba_detach(dev_info_t *self)
1375 {
1376         scsi_hba_tran_t         *tran;
1377 
1378         ASSERT(scsi_hba_iport_unit_address(self) == NULL);
1379         if (scsi_hba_iport_unit_address(self))
1380                 return (DDI_FAILURE);           /* self can't be an iport */
1381 
1382         /* Check all error return conditions upfront */
1383         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE);
1384         ASSERT(tran);
1385         if (tran == NULL)
1386                 return (DDI_FAILURE);
1387 
1388         ASSERT(tran->tran_open_flag == 0);
1389         if (tran->tran_open_flag)
1390                 return (DDI_FAILURE);
1391 
1392         if (!(tran->tran_hba_flags & SCSI_HBA_HBA))
1393                 scsa_tran_teardown(self, tran);
1394         scsa_nexus_teardown(self, tran);
1395 
1396         /* Teardown tran_setup_pkt(9E) kmem_cache. */
1397         if (tran->tran_pkt_cache_ptr) {
1398                 kmem_cache_destroy(tran->tran_pkt_cache_ptr);
1399                 tran->tran_pkt_cache_ptr = NULL;
1400         }
1401 
1402         (void) memset(&tran->tran_dma_attr, 0, sizeof (ddi_dma_attr_t));
1403 
1404         /* Teardown flavor of transport (and ddi_get_driver_private()) */
1405         ndi_flavorv_set(self, SCSA_FLAVOR_SCSI_DEVICE, NULL);
1406 
1407         tran->tran_hba_dip = NULL;
1408 
1409         return (DDI_SUCCESS);
1410 }
1411 
1412 
1413 /*
1414  * Called by an HBA from _fini()
1415  */
1416 void
1417 scsi_hba_fini(struct modlinkage *modlp)
1418 {
1419         struct dev_ops *hba_dev_ops;
1420 
1421         SCSI_HBA_LOG((_LOG_TRACE, NULL, NULL, __func__));
1422 
1423         /* Get the devops structure of this module and clear bus_ops vector. */
1424         hba_dev_ops = ((struct modldrv *)(modlp->ml_linkage[0]))->drv_dev_ops;
1425 
1426         if (hba_dev_ops->devo_cb_ops == &scsi_hba_cbops)
1427                 hba_dev_ops->devo_cb_ops = NULL;
1428 
1429         if (hba_dev_ops->devo_getinfo == scsi_hba_info)
1430                 hba_dev_ops->devo_getinfo = NULL;
1431 
1432         hba_dev_ops->devo_bus_ops = (struct bus_ops *)NULL;
1433 }
1434 
1435 /*
1436  * SAS specific functions
1437  */
1438 smp_hba_tran_t *
1439 smp_hba_tran_alloc(dev_info_t *self)
1440 {
1441         /* allocate SCSA flavors for self */
1442         ndi_flavorv_alloc(self, SCSA_NFLAVORS);
1443         return (kmem_zalloc(sizeof (smp_hba_tran_t), KM_SLEEP));
1444 }
1445 
1446 void
1447 smp_hba_tran_free(smp_hba_tran_t *tran)
1448 {
1449         kmem_free(tran, sizeof (smp_hba_tran_t));
1450 }
1451 
1452 int
1453 smp_hba_attach_setup(
1454         dev_info_t              *self,
1455         smp_hba_tran_t          *tran)
1456 {
1457         ASSERT(scsi_hba_iport_unit_address(self) == NULL);
1458         if (scsi_hba_iport_unit_address(self))
1459                 return (DDI_FAILURE);           /* self can't be an iport */
1460 
1461         /*
1462          * The owner of the this devinfo_t was responsible
1463          * for informing the framework already about
1464          * additional flavors.
1465          */
1466         ndi_flavorv_set(self, SCSA_FLAVOR_SMP, tran);
1467         return (DDI_SUCCESS);
1468 }
1469 
1470 int
1471 smp_hba_detach(dev_info_t *self)
1472 {
1473         ASSERT(scsi_hba_iport_unit_address(self) == NULL);
1474         if (scsi_hba_iport_unit_address(self))
1475                 return (DDI_FAILURE);           /* self can't be an iport */
1476 
1477         ndi_flavorv_set(self, SCSA_FLAVOR_SMP, NULL);
1478         return (DDI_SUCCESS);
1479 }
1480 
1481 /*
1482  * SMP child flavored functions
1483  */
1484 static int
1485 smp_busctl_ua(dev_info_t *child, char *addr, int maxlen)
1486 {
1487         char            *tport;
1488         char            *wwn;
1489 
1490         /* limit ndi_devi_findchild_by_callback to expected flavor */
1491         if (ndi_flavor_get(child) != SCSA_FLAVOR_SMP)
1492                 return (DDI_FAILURE);
1493 
1494         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
1495             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1496             SCSI_ADDR_PROP_TARGET_PORT, &tport) == DDI_SUCCESS) {
1497                 (void) snprintf(addr, maxlen, "%s", tport);
1498                 ddi_prop_free(tport);
1499                 return (DDI_SUCCESS);
1500         }
1501 
1502         /*
1503          * NOTE: the following code should be deleted when mpt is changed to
1504          * use SCSI_ADDR_PROP_TARGET_PORT instead of SMP_WWN.
1505          */
1506         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
1507             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1508             SMP_WWN, &wwn) == DDI_SUCCESS) {
1509                 (void) snprintf(addr, maxlen, "w%s", wwn);
1510                 ddi_prop_free(wwn);
1511                 return (DDI_SUCCESS);
1512         }
1513         return (DDI_FAILURE);
1514 }
1515 
1516 static int
1517 smp_busctl_reportdev(dev_info_t *child)
1518 {
1519         dev_info_t      *self = ddi_get_parent(child);
1520         char            *tport;
1521         char            *wwn;
1522 
1523         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
1524             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1525             SCSI_ADDR_PROP_TARGET_PORT, &tport) == DDI_SUCCESS) {
1526                 SCSI_HBA_LOG((_LOG_NF(CONT), "?%s%d at %s%d: target-port %s",
1527                     ddi_driver_name(child), ddi_get_instance(child),
1528                     ddi_driver_name(self), ddi_get_instance(self), tport));
1529                 ddi_prop_free(tport);
1530                 return (DDI_SUCCESS);
1531         }
1532 
1533         /*
1534          * NOTE: the following code should be deleted when mpt is changed to
1535          * use SCSI_ADDR_PROP_TARGET_PORT instead of SMP_WWN.
1536          */
1537         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
1538             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1539             SMP_WWN, &wwn) == DDI_SUCCESS) {
1540                 SCSI_HBA_LOG((_LOG_NF(CONT), "?%s%d at %s%d: wwn %s",
1541                     ddi_driver_name(child), ddi_get_instance(child),
1542                     ddi_driver_name(self), ddi_get_instance(self), wwn));
1543                 ddi_prop_free(wwn);
1544                 return (DDI_SUCCESS);
1545         }
1546         return (DDI_FAILURE);
1547 }
1548 
1549 static int
1550 smp_busctl_initchild(dev_info_t *child)
1551 {
1552         dev_info_t              *self = ddi_get_parent(child);
1553         smp_hba_tran_t          *tran;
1554         dev_info_t              *dup;
1555         char                    addr[SCSI_MAXNAMELEN];
1556         struct smp_device       *smp_sd;
1557         uint64_t                wwn;
1558 
1559         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SMP);
1560         ASSERT(tran);
1561         if (tran == NULL)
1562                 return (DDI_FAILURE);
1563 
1564         if (smp_busctl_ua(child, addr, sizeof (addr)) != DDI_SUCCESS)
1565                 return (DDI_NOT_WELL_FORMED);
1566         if (scsi_wwnstr_to_wwn(addr, &wwn))
1567                 return (DDI_NOT_WELL_FORMED);
1568 
1569         /* Prevent duplicate nodes.  */
1570         dup = ndi_devi_findchild_by_callback(self, ddi_node_name(child), addr,
1571             smp_busctl_ua);
1572         if (dup) {
1573                 ASSERT(ndi_flavor_get(dup) == SCSA_FLAVOR_SMP);
1574                 if (ndi_flavor_get(dup) != SCSA_FLAVOR_SMP) {
1575                         SCSI_HBA_LOG((_LOG(1), NULL, child,
1576                             "init failed: %s@%s: not SMP flavored",
1577                             ddi_node_name(child), addr));
1578                         return (DDI_FAILURE);
1579                 }
1580                 if (dup != child) {
1581                         SCSI_HBA_LOG((_LOG(4), NULL, child,
1582                             "init failed: %s@%s: detected duplicate %p",
1583                             ddi_node_name(child), addr, (void *)dup));
1584                         return (DDI_FAILURE);
1585                 }
1586         }
1587 
1588 
1589         /* set the node @addr string */
1590         ddi_set_name_addr(child, addr);
1591 
1592         /* Allocate and initialize smp_device. */
1593         smp_sd = kmem_zalloc(sizeof (struct smp_device), KM_SLEEP);
1594         smp_sd->smp_sd_dev = child;
1595         smp_sd->smp_sd_address.smp_a_hba_tran = tran;
1596         bcopy(&wwn, smp_sd->smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE);
1597 
1598         ddi_set_driver_private(child, smp_sd);
1599 
1600         if (tran->smp_tran_init && ((*tran->smp_tran_init)(self, child,
1601             tran, smp_sd) != DDI_SUCCESS)) {
1602                 kmem_free(smp_sd, sizeof (struct smp_device));
1603                 scsi_enumeration_failed(child, -1, NULL, "smp_tran_init");
1604                 ddi_set_driver_private(child, NULL);
1605                 ddi_set_name_addr(child, NULL);
1606                 return (DDI_FAILURE);
1607         }
1608 
1609         return (DDI_SUCCESS);
1610 }
1611 
1612 /*ARGSUSED*/
1613 static int
1614 smp_busctl_uninitchild(dev_info_t *child)
1615 {
1616         dev_info_t              *self = ddi_get_parent(child);
1617         struct smp_device       *smp_sd = ddi_get_driver_private(child);
1618         smp_hba_tran_t          *tran;
1619 
1620         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SMP);
1621         ASSERT(smp_sd && tran);
1622         if ((smp_sd == NULL) || (tran == NULL))
1623                 return (DDI_FAILURE);
1624 
1625         if (tran->smp_tran_free)
1626                 (*tran->smp_tran_free) (self, child, tran, smp_sd);
1627 
1628         kmem_free(smp_sd, sizeof (*smp_sd));
1629         ddi_set_driver_private(child, NULL);
1630         ddi_set_name_addr(child, NULL);
1631         return (DDI_SUCCESS);
1632 }
1633 
1634 /* Find an "smp" child at the specified address. */
1635 static dev_info_t *
1636 smp_findchild(dev_info_t *self, char *addr)
1637 {
1638         dev_info_t      *child;
1639 
1640         /* Search "smp" devinfo child at specified address. */
1641         ASSERT(self && DEVI_BUSY_OWNED(self) && addr);
1642         for (child = ddi_get_child(self); child;
1643             child = ddi_get_next_sibling(child)) {
1644                 /* skip non-"smp" nodes */
1645                 if (ndi_flavor_get(child) != SCSA_FLAVOR_SMP)
1646                         continue;
1647 
1648                 /* Attempt initchild to establish unit-address */
1649                 if (i_ddi_node_state(child) < DS_INITIALIZED)
1650                         (void) ddi_initchild(self, child);
1651 
1652                 /* Verify state and non-NULL unit-address. */
1653                 if ((i_ddi_node_state(child) < DS_INITIALIZED) ||
1654                     (ddi_get_name_addr(child) == NULL))
1655                         continue;
1656 
1657                 /* Return "smp" child if unit-address matches. */
1658                 if (strcmp(ddi_get_name_addr(child), addr) == 0)
1659                         return (child);
1660         }
1661         return (NULL);
1662 }
1663 
1664 /*
1665  * Search for "smp" child of self at the specified address. If found, online
1666  * and return with a hold.  Unlike general SCSI configuration, we can assume
1667  * the the device is actually there when we are called (i.e., device is
1668  * created by hotplug, not by bus_config).
1669  */
1670 int
1671 smp_hba_bus_config(dev_info_t *self, char *addr, dev_info_t **childp)
1672 {
1673         dev_info_t      *child;
1674         int             circ;
1675 
1676         ASSERT(self && addr && childp);
1677         *childp = NULL;
1678 
1679         /* Search for "smp" child. */
1680         scsi_hba_devi_enter(self, &circ);
1681         if ((child = smp_findchild(self, addr)) == NULL) {
1682                 scsi_hba_devi_exit(self, circ);
1683                 return (NDI_FAILURE);
1684         }
1685 
1686         /* Attempt online. */
1687         if (ndi_devi_online(child, 0) != NDI_SUCCESS) {
1688                 scsi_hba_devi_exit(self, circ);
1689                 return (NDI_FAILURE);
1690         }
1691 
1692         /* On success, return with active hold. */
1693         ndi_hold_devi(child);
1694         scsi_hba_devi_exit(self, circ);
1695         *childp = child;
1696         return (NDI_SUCCESS);
1697 }
1698 
1699 
1700 
1701 /* Create "smp" child devinfo node at specified unit-address. */
1702 int
1703 smp_hba_bus_config_taddr(dev_info_t *self, char *addr)
1704 {
1705         dev_info_t              *child;
1706         int                     circ;
1707 
1708         /*
1709          * NOTE: If we ever uses a generic node name (.vs. a driver name)
1710          * or define a 'compatible' property, this code will need to use
1711          * a 'probe' node (ala scsi_device support) to obtain identity
1712          * information from the device.
1713          */
1714 
1715         /* Search for "smp" child. */
1716         scsi_hba_devi_enter(self, &circ);
1717         child = smp_findchild(self, addr);
1718         if (child) {
1719                 /* Child exists, note if this was a new reinsert. */
1720                 if (ndi_devi_device_insert(child))
1721                         SCSI_HBA_LOG((_LOGCFG, self, NULL,
1722                             "devinfo smp@%s device_reinsert", addr));
1723 
1724                 scsi_hba_devi_exit(self, circ);
1725                 return (NDI_SUCCESS);
1726         }
1727 
1728         /* Allocate "smp" child devinfo node and establish flavor of child. */
1729         ndi_devi_alloc_sleep(self, "smp", DEVI_SID_HP_NODEID, &child);
1730         ASSERT(child);
1731         ndi_flavor_set(child, SCSA_FLAVOR_SMP);
1732 
1733         /* Add unit-address property to child. */
1734         if (ndi_prop_update_string(DDI_DEV_T_NONE, child,
1735             SCSI_ADDR_PROP_TARGET_PORT, addr) != DDI_PROP_SUCCESS) {
1736                 (void) ndi_devi_free(child);
1737                 scsi_hba_devi_exit(self, circ);
1738                 return (NDI_FAILURE);
1739         }
1740 
1741         /* Attempt to online the new "smp" node. */
1742         (void) ndi_devi_online(child, 0);
1743 
1744         scsi_hba_devi_exit(self, circ);
1745         return (NDI_SUCCESS);
1746 }
1747 
1748 /*
1749  * Wrapper to scsi_ua_get which takes a devinfo argument instead of a
1750  * scsi_device structure.
1751  */
1752 static int
1753 scsi_busctl_ua(dev_info_t *child, char *addr, int maxlen)
1754 {
1755         struct scsi_device      *sd;
1756 
1757         /* limit ndi_devi_findchild_by_callback to expected flavor */
1758         if (ndi_flavor_get(child) != SCSA_FLAVOR_SCSI_DEVICE)
1759                 return (DDI_FAILURE);
1760 
1761         /* nodes are named by tran_get_name or default "tgt,lun" */
1762         sd = ddi_get_driver_private(child);
1763         if (sd && (scsi_ua_get(sd, addr, maxlen) == 1))
1764                 return (DDI_SUCCESS);
1765 
1766         return (DDI_FAILURE);
1767 }
1768 
1769 static int
1770 scsi_busctl_reportdev(dev_info_t *child)
1771 {
1772         dev_info_t              *self = ddi_get_parent(child);
1773         struct scsi_device      *sd = ddi_get_driver_private(child);
1774         scsi_hba_tran_t         *tran;
1775         char                    ua[SCSI_MAXNAMELEN];
1776         char                    ra[SCSI_MAXNAMELEN];
1777 
1778         SCSI_HBA_LOG((_LOG_TRACE, NULL, child, __func__));
1779 
1780         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE);
1781         ASSERT(tran && sd);
1782         if ((tran == NULL) || (sd == NULL))
1783                 return (DDI_FAILURE);
1784 
1785         /* get the unit_address and bus_addr information */
1786         if ((scsi_ua_get(sd, ua, sizeof (ua)) == 0) ||
1787             (scsi_ua_get_reportdev(sd, ra, sizeof (ra)) == 0)) {
1788                 SCSI_HBA_LOG((_LOG(WARN), NULL, child, "REPORTDEV failure"));
1789                 return (DDI_FAILURE);
1790         }
1791 
1792         if (tran->tran_get_name == NULL)
1793                 SCSI_HBA_LOG((_LOG_NF(CONT), "?%s%d at %s%d: %s",
1794                     ddi_driver_name(child), ddi_get_instance(child),
1795                     ddi_driver_name(self), ddi_get_instance(self), ra));
1796         else if (*ra)
1797                 SCSI_HBA_LOG((_LOG_NF(CONT),
1798                     "?%s%d at %s%d: unit-address %s: %s",
1799                     ddi_driver_name(child), ddi_get_instance(child),
1800                     ddi_driver_name(self), ddi_get_instance(self), ua, ra));
1801         else
1802                 SCSI_HBA_LOG((_LOG_NF(CONT),
1803                     "?%s%d at %s%d: unit-address %s",
1804                     ddi_driver_name(child), ddi_get_instance(child),
1805                     ddi_driver_name(self), ddi_get_instance(self), ua));
1806 
1807         return (DDI_SUCCESS);
1808 }
1809 
1810 
1811 /*
1812  * scsi_busctl_initchild is called to initialize the SCSA transport for
1813  * communication with a particular child scsi target device. Successful
1814  * initialization requires properties on the node which describe the address
1815  * of the target device. If the address of the target device can't be
1816  * determined from properties then DDI_NOT_WELL_FORMED is returned. Nodes that
1817  * are DDI_NOT_WELL_FORMED are considered an implementation artifact and
1818  * are hidden from devinfo snapshots by calling ndi_devi_set_hidden().
1819  * The child may be one of the following types of devinfo nodes:
1820  *
1821  * OBP node:
1822  *      OBP does not enumerate target devices attached a SCSI bus. These
1823  *      template/stub/wild-card nodes are a legacy artifact for support of old
1824  *      driver loading methods. Since they have no properties,
1825  *      DDI_NOT_WELL_FORMED will be returned.
1826  *
1827  * SID node:
1828  *      The node may be either a:
1829  *          o   probe/barrier SID node
1830  *          o   a dynamic SID target node
1831  *
1832  * driver.conf node: The situation for this nexus is different than most.
1833  *      Typically a driver.conf node definition is used to either define a
1834  *      new child devinfo node or to further decorate (via merge) a SID
1835  *      child with properties. In our case we use the nodes for *both*
1836  *      purposes.
1837  *
1838  * In both the SID node and driver.conf node cases we must form the nodes
1839  * "@addr" from the well-known scsi(9P) device unit-address properties on
1840  * the node.
1841  *
1842  * For HBA drivers that implement the deprecated tran_get_name interface,
1843  * "@addr" construction involves having that driver interpret properties via
1844  * scsi_busctl_ua -> scsi_ua_get -> tran_get_name: there is no
1845  * requirement for the property names to be well-known.
1846  *
1847  * NOTE: We don't currently support "merge".  When this support is added a
1848  * specific property, like "unit-address", should *always* identify a
1849  * driver.conf node that needs to be merged into a specific SID node. When
1850  * enumeration is enabled, a .conf node without the "unit-address" property
1851  * should be ignored.  The best way to establish the "unit-address" property
1852  * would be to have the system assign parent= and unit-address= from an
1853  * instance=# driver.conf entry (by using the instance tree).
1854  */
1855 static int
1856 scsi_busctl_initchild(dev_info_t *child)
1857 {
1858         dev_info_t              *self = ddi_get_parent(child);
1859         dev_info_t              *dup;
1860         scsi_hba_tran_t         *tran;
1861         struct scsi_device      *sd;
1862         scsi_hba_tran_t         *tran_clone;
1863         char                    *class;
1864         int                     tgt;
1865         int                     lun;
1866         int                     sfunc;
1867         int                     err = DDI_FAILURE;
1868         char                    addr[SCSI_MAXNAMELEN];
1869 
1870         ASSERT(DEVI_BUSY_OWNED(self));
1871         SCSI_HBA_LOG((_LOG(4), NULL, child, "init begin"));
1872 
1873         /*
1874          * For a driver like fp with multiple upper-layer-protocols
1875          * it is possible for scsi_hba_init in _init to plumb SCSA
1876          * and have the load of fcp (which does scsi_hba_attach_setup)
1877          * to fail.  In this case we may get here with a NULL hba.
1878          */
1879         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE);
1880         if (tran == NULL)
1881                 return (DDI_NOT_WELL_FORMED);
1882 
1883         /*
1884          * OBP may create template/stub/wild-card nodes for legacy driver
1885          * loading methods. These nodes have no properties, so we lack the
1886          * addressing properties to initchild them. Hide the node and return
1887          * DDI_NOT_WELL_FORMED.
1888          *
1889          * Future: define/use a ndi_devi_has_properties(dip) type interface.
1890          *
1891          * NOTE: It would be nice if we could delete these ill formed nodes by
1892          * implementing a DDI_NOT_WELL_FORMED_DELETE return code. This can't
1893          * be done until leadville debug code removes its dependencies
1894          * on the devinfo still being present after a failed ndi_devi_online.
1895          */
1896         if ((DEVI(child)->devi_hw_prop_ptr == NULL) &&
1897             (DEVI(child)->devi_drv_prop_ptr == NULL) &&
1898             (DEVI(child)->devi_sys_prop_ptr == NULL)) {
1899                 SCSI_HBA_LOG((_LOG(4), NULL, child,
1900                     "init failed: no properties"));
1901                 ndi_devi_set_hidden(child);
1902                 return (DDI_NOT_WELL_FORMED);
1903         }
1904 
1905         /* get legacy SPI addressing properties */
1906         if ((tgt = ddi_prop_get_int(DDI_DEV_T_ANY, child,
1907             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1908             SCSI_ADDR_PROP_TARGET, -1)) == -1) {
1909                 tgt = 0;
1910                 /*
1911                  * A driver.conf node for merging always has a target= property,
1912                  * even if it is just a dummy that does not contain the real
1913                  * target address. However drivers that register devids may
1914                  * create stub driver.conf nodes without a target= property so
1915                  * that pathological devid resolution works. Hide the stub
1916                  * node and return DDI_NOT_WELL_FORMED.
1917                  */
1918                 if (!scsi_hba_dev_is_sid(child)) {
1919                         SCSI_HBA_LOG((_LOG(4), NULL, child,
1920                             "init failed: stub .conf node"));
1921                         ndi_devi_set_hidden(child);
1922                         return (DDI_NOT_WELL_FORMED);
1923                 }
1924         }
1925         lun = ddi_prop_get_int(DDI_DEV_T_ANY, child,
1926             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, SCSI_ADDR_PROP_LUN, 0);
1927         sfunc = ddi_prop_get_int(DDI_DEV_T_ANY, child,
1928             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, SCSI_ADDR_PROP_SFUNC, -1);
1929 
1930         /*
1931          * The scsi_address structure may not specify all the addressing
1932          * information. For an old HBA that doesn't support tran_get_name
1933          * (most pre-SCSI-3 HBAs) the scsi_address structure is still used,
1934          * so the target property must exist and the LUN must be < 256.
1935          */
1936         if ((tran->tran_get_name == NULL) &&
1937             ((tgt >= USHRT_MAX) || (lun >= 256))) {
1938                 SCSI_HBA_LOG((_LOG(1), NULL, child,
1939                     "init failed: illegal/missing properties"));
1940                 ndi_devi_set_hidden(child);
1941                 return (DDI_NOT_WELL_FORMED);
1942         }
1943 
1944         /*
1945          * We need to initialize a fair amount of our environment to invoke
1946          * tran_get_name (via scsi_busctl_ua and scsi_ua_get) to
1947          * produce the "@addr" name from addressing properties. Allocate and
1948          * initialize scsi device structure.
1949          */
1950         sd = kmem_zalloc(sizeof (struct scsi_device), KM_SLEEP);
1951         mutex_init(&sd->sd_mutex, NULL, MUTEX_DRIVER, NULL);
1952         sd->sd_dev = child;
1953         sd->sd_pathinfo = NULL;
1954         sd->sd_uninit_prevent = 0;
1955         ddi_set_driver_private(child, sd);
1956 
1957         if (tran->tran_hba_flags & SCSI_HBA_ADDR_COMPLEX) {
1958                 /*
1959                  * For a SCSI_HBA_ADDR_COMPLEX transport we store a pointer to
1960                  * scsi_device in the scsi_address structure.  This allows an
1961                  * HBA driver to find its per-scsi_device private data
1962                  * (accessible to the HBA given just the scsi_address by using
1963                  *  scsi_address_device(9F)/scsi_device_hba_private_get(9F)).
1964                  */
1965                 sd->sd_address.a.a_sd = sd;
1966                 tran_clone = NULL;
1967         } else {
1968                 /*
1969                  * Initialize the scsi_address so that a SCSI-2 target driver
1970                  * talking to a SCSI-2 device on a SCSI-3 bus (spi) continues
1971                  * to work. We skew the secondary function value so that we
1972                  * can tell from the address structure if we are processing
1973                  * a secondary function request.
1974                  */
1975                 sd->sd_address.a_target = (ushort_t)tgt;
1976                 sd->sd_address.a_lun = (uchar_t)lun;
1977                 if (sfunc == -1)
1978                         sd->sd_address.a_sublun = (uchar_t)0;
1979                 else
1980                         sd->sd_address.a_sublun = (uchar_t)sfunc + 1;
1981 
1982                 /*
1983                  * NOTE: Don't limit LUNs to scsi_options value because a
1984                  * scsi_device discovered via SPI dynamic enumeration might
1985                  * still support SCMD_REPORT_LUNS.
1986                  */
1987 
1988                 /*
1989                  * Deprecated: Use SCSI_HBA_ADDR_COMPLEX:
1990                  *   Clone transport structure if requested. Cloning allows
1991                  *   an HBA to maintain target-specific information if
1992                  *   necessary, such as target addressing information that
1993                  *   does not adhere to the scsi_address structure format.
1994                  */
1995                 if (tran->tran_hba_flags & SCSI_HBA_TRAN_CLONE) {
1996                         tran_clone = kmem_alloc(
1997                             sizeof (scsi_hba_tran_t), KM_SLEEP);
1998                         bcopy((caddr_t)tran,
1999                             (caddr_t)tran_clone, sizeof (scsi_hba_tran_t));
2000                         tran = tran_clone;
2001                         tran->tran_sd = sd;
2002                 } else {
2003                         tran_clone = NULL;
2004                         ASSERT(tran->tran_sd == NULL);
2005                 }
2006         }
2007 
2008         /* establish scsi_address pointer to the HBA's tran structure */
2009         sd->sd_address.a_hba_tran = tran;
2010 
2011         /*
2012          * This is a grotty hack that allows direct-access (non-scsa) drivers
2013          * (like chs, ata, and mlx which all make cmdk children) to put its
2014          * own vector in the 'a_hba_tran' field. When all the drivers that do
2015          * this are fixed, please remove this hack.
2016          *
2017          * NOTE: This hack is also shows up in the DEVP_TO_TRAN implementation
2018          * in scsi_confsubr.c.
2019          */
2020         sd->sd_tran_safe = tran;
2021 
2022         /*
2023          * If the class property is not already established, set it to "scsi".
2024          * This is done so that parent= driver.conf nodes have class.
2025          */
2026         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
2027             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "class",
2028             &class) == DDI_PROP_SUCCESS) {
2029                 ddi_prop_free(class);
2030         } else if (ndi_prop_update_string(DDI_DEV_T_NONE, child,
2031             "class", "scsi") != DDI_PROP_SUCCESS) {
2032                 SCSI_HBA_LOG((_LOG(2), NULL, child, "init failed: class"));
2033                 ndi_devi_set_hidden(child);
2034                 err = DDI_NOT_WELL_FORMED;
2035                 goto failure;
2036         }
2037 
2038         /* Establish the @addr name of the child. */
2039         *addr = '\0';
2040         if (scsi_busctl_ua(child, addr, sizeof (addr)) != DDI_SUCCESS) {
2041                 /*
2042                  * Some driver.conf files add bogus target properties (relative
2043                  * to their nexus representation of target) to their stub
2044                  * nodes, causing the check above to not filter them.
2045                  */
2046                 SCSI_HBA_LOG((_LOG(3), NULL, child,
2047                     "init failed: scsi_busctl_ua call"));
2048                 ndi_devi_set_hidden(child);
2049                 err = DDI_NOT_WELL_FORMED;
2050                 goto failure;
2051         }
2052         if (*addr == '\0') {
2053                 SCSI_HBA_LOG((_LOG(2), NULL, child, "init failed: ua"));
2054                 ndi_devi_set_hidden(child);
2055                 err = DDI_NOT_WELL_FORMED;
2056                 goto failure;
2057         }
2058 
2059         /* Prevent duplicate nodes.  */
2060         dup = ndi_devi_findchild_by_callback(self, ddi_node_name(child), addr,
2061             scsi_busctl_ua);
2062         if (dup) {
2063                 ASSERT(ndi_flavor_get(dup) == SCSA_FLAVOR_SCSI_DEVICE);
2064                 if (ndi_flavor_get(dup) != SCSA_FLAVOR_SCSI_DEVICE) {
2065                         SCSI_HBA_LOG((_LOG(1), NULL, child,
2066                             "init failed: %s@%s: not SCSI_DEVICE flavored",
2067                             ddi_node_name(child), addr));
2068                         goto failure;
2069                 }
2070                 if (dup != child) {
2071                         SCSI_HBA_LOG((_LOG(4), NULL, child,
2072                             "init failed: %s@%s: detected duplicate %p",
2073                             ddi_node_name(child), addr, (void *)dup));
2074                         goto failure;
2075                 }
2076         }
2077 
2078         /* set the node @addr string */
2079         ddi_set_name_addr(child, addr);
2080 
2081         /* call HBA's target init entry point if it exists */
2082         if (tran->tran_tgt_init != NULL) {
2083                 SCSI_HBA_LOG((_LOG(4), NULL, child, "init tran_tgt_init"));
2084                 sd->sd_tran_tgt_free_done = 0;
2085                 if ((*tran->tran_tgt_init)
2086                     (self, child, tran, sd) != DDI_SUCCESS) {
2087                         scsi_enumeration_failed(child, -1, NULL,
2088                             "tran_tgt_init");
2089                         goto failure;
2090                 }
2091         }
2092 
2093         SCSI_HBA_LOG((_LOG(3), NULL, child, "init successful"));
2094         return (DDI_SUCCESS);
2095 
2096 failure:
2097         if (tran_clone)
2098                 kmem_free(tran_clone, sizeof (scsi_hba_tran_t));
2099         mutex_destroy(&sd->sd_mutex);
2100         kmem_free(sd, sizeof (*sd));
2101         ddi_set_driver_private(child, NULL);
2102         ddi_set_name_addr(child, NULL);
2103 
2104         return (err);           /* remove the node */
2105 }
2106 
2107 static int
2108 scsi_busctl_uninitchild(dev_info_t *child)
2109 {
2110         dev_info_t              *self = ddi_get_parent(child);
2111         struct scsi_device      *sd = ddi_get_driver_private(child);
2112         scsi_hba_tran_t         *tran;
2113         scsi_hba_tran_t         *tran_clone;
2114 
2115         ASSERT(DEVI_BUSY_OWNED(self));
2116 
2117         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE);
2118         ASSERT(tran && sd);
2119         if ((tran == NULL) || (sd == NULL))
2120                 return (DDI_FAILURE);
2121 
2122         /*
2123          * We use sd_uninit_prevent to avoid uninitializing barrier/probe
2124          * nodes that are still in use. Since barrier/probe nodes are not
2125          * attached we can't prevent their state demotion via ndi_hold_devi.
2126          */
2127         if (sd->sd_uninit_prevent) {
2128                 SCSI_HBA_LOG((_LOG(2), NULL, child, "uninit prevented"));
2129                 return (DDI_FAILURE);
2130         }
2131 
2132         /*
2133          * Don't uninitialize a client node if it still has paths.
2134          */
2135         if (MDI_CLIENT(child) && mdi_client_get_path_count(child)) {
2136                 SCSI_HBA_LOG((_LOG(2), NULL, child,
2137                     "uninit prevented, client has paths"));
2138                 return (DDI_FAILURE);
2139         }
2140 
2141         SCSI_HBA_LOG((_LOG(3), NULL, child, "uninit begin"));
2142 
2143         if (tran->tran_hba_flags & SCSI_HBA_TRAN_CLONE) {
2144                 tran_clone = sd->sd_address.a_hba_tran;
2145 
2146                 /* ... grotty hack, involving sd_tran_safe, continued. */
2147                 if (tran_clone != sd->sd_tran_safe) {
2148                         tran_clone = sd->sd_tran_safe;
2149 #ifdef  DEBUG
2150                         /*
2151                          * Complain so things get fixed and hack can, at
2152                          * some point in time, be removed.
2153                          */
2154                         SCSI_HBA_LOG((_LOG(WARN), self, NULL,
2155                             "'%s' is corrupting a_hba_tran", sd->sd_dev ?
2156                             ddi_driver_name(sd->sd_dev) : "unknown_driver"));
2157 #endif  /* DEBUG */
2158                 }
2159 
2160                 ASSERT(tran_clone->tran_hba_flags & SCSI_HBA_TRAN_CLONE);
2161                 ASSERT(tran_clone->tran_sd == sd);
2162                 tran = tran_clone;
2163         } else {
2164                 tran_clone = NULL;
2165                 ASSERT(tran->tran_sd == NULL);
2166         }
2167 
2168         /*
2169          * To simplify host adapter drivers we guarantee that multiple
2170          * tran_tgt_init(9E) calls of the same unit address are never
2171          * active at the same time.  This requires that we always call
2172          * tran_tgt_free on probe/barrier nodes directly prior to
2173          * uninitchild.
2174          *
2175          * NOTE: To correctly support SCSI_HBA_TRAN_CLONE, we must use
2176          * the (possibly cloned) hba_tran pointer from the scsi_device
2177          * instead of hba_tran.
2178          */
2179         if (tran->tran_tgt_free) {
2180                 if (!sd->sd_tran_tgt_free_done) {
2181                         SCSI_HBA_LOG((_LOG(4), NULL, child,
2182                             "uninit tran_tgt_free"));
2183                         (*tran->tran_tgt_free) (self, child, tran, sd);
2184                         sd->sd_tran_tgt_free_done = 1;
2185                 } else {
2186                         SCSI_HBA_LOG((_LOG(4), NULL, child,
2187                             "uninit tran_tgt_free already done"));
2188                 }
2189         }
2190 
2191         /*
2192          * If a inquiry data is still allocated (by scsi_probe()) we
2193          * free the allocation here. This keeps scsi_inq valid for the
2194          * same duration as the corresponding inquiry properties. It
2195          * also allows a tran_tgt_init() implementation that establishes
2196          * sd_inq to deal with deallocation in its tran_tgt_free
2197          * (setting sd_inq back to NULL) without upsetting the
2198          * framework. Moving the inquiry free here also allows setting
2199          * of sd_uninit_prevent to preserve the data for lun0 based
2200          * scsi_get_device_type_scsi_options() calls.
2201          */
2202         if (sd->sd_inq) {
2203                 kmem_free(sd->sd_inq, SUN_INQSIZE);
2204                 sd->sd_inq = (struct scsi_inquiry *)NULL;
2205         }
2206 
2207         mutex_destroy(&sd->sd_mutex);
2208         if (tran_clone)
2209                 kmem_free(tran_clone, sizeof (scsi_hba_tran_t));
2210         kmem_free(sd, sizeof (*sd));
2211 
2212         ddi_set_driver_private(child, NULL);
2213         SCSI_HBA_LOG((_LOG(3), NULL, child, "uninit complete"));
2214         ddi_set_name_addr(child, NULL);
2215         return (DDI_SUCCESS);
2216 }
2217 
2218 static int
2219 iport_busctl_ua(dev_info_t *child, char *addr, int maxlen)
2220 {
2221         char    *iport_ua;
2222 
2223         /* limit ndi_devi_findchild_by_callback to expected flavor */
2224         if (ndi_flavor_get(child) != SCSA_FLAVOR_IPORT)
2225                 return (DDI_FAILURE);
2226 
2227         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
2228             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
2229             SCSI_ADDR_PROP_IPORTUA, &iport_ua) != DDI_SUCCESS) {
2230                 return (DDI_FAILURE);
2231         }
2232 
2233         (void) snprintf(addr, maxlen, "%s", iport_ua);
2234         ddi_prop_free(iport_ua);
2235         return (DDI_SUCCESS);
2236 }
2237 
2238 static int
2239 iport_busctl_reportdev(dev_info_t *child)
2240 {
2241         dev_info_t      *self = ddi_get_parent(child);
2242         char            *iport_ua;
2243         char            *initiator_port = NULL;
2244 
2245         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
2246             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
2247             SCSI_ADDR_PROP_IPORTUA, &iport_ua) != DDI_SUCCESS)
2248                 return (DDI_FAILURE);
2249 
2250         (void) ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
2251             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
2252             SCSI_ADDR_PROP_INITIATOR_PORT, &initiator_port);
2253 
2254         if (initiator_port) {
2255                 SCSI_HBA_LOG((_LOG_NF(CONT),
2256                     "?%s%d at %s%d: %s %s %s %s",
2257                     ddi_driver_name(child), ddi_get_instance(child),
2258                     ddi_driver_name(self), ddi_get_instance(self),
2259                     SCSI_ADDR_PROP_INITIATOR_PORT, initiator_port,
2260                     SCSI_ADDR_PROP_IPORTUA, iport_ua));
2261                 ddi_prop_free(initiator_port);
2262         } else {
2263                 SCSI_HBA_LOG((_LOG_NF(CONT), "?%s%d at %s%d: %s %s",
2264                     ddi_driver_name(child), ddi_get_instance(child),
2265                     ddi_driver_name(self), ddi_get_instance(self),
2266                     SCSI_ADDR_PROP_IPORTUA, iport_ua));
2267         }
2268         ddi_prop_free(iport_ua);
2269         return (DDI_SUCCESS);
2270 }
2271 
2272 /* initchild SCSA iport 'child' node */
2273 static int
2274 iport_busctl_initchild(dev_info_t *child)
2275 {
2276         dev_info_t      *self = ddi_get_parent(child);
2277         dev_info_t      *dup = NULL;
2278         char            addr[SCSI_MAXNAMELEN];
2279 
2280         if (iport_busctl_ua(child, addr, sizeof (addr)) != DDI_SUCCESS)
2281                 return (DDI_NOT_WELL_FORMED);
2282 
2283         /* Prevent duplicate nodes.  */
2284         dup = ndi_devi_findchild_by_callback(self, ddi_node_name(child), addr,
2285             iport_busctl_ua);
2286         if (dup) {
2287                 ASSERT(ndi_flavor_get(dup) == SCSA_FLAVOR_IPORT);
2288                 if (ndi_flavor_get(dup) != SCSA_FLAVOR_IPORT) {
2289                         SCSI_HBA_LOG((_LOG(1), NULL, child,
2290                             "init failed: %s@%s: not IPORT flavored",
2291                             ddi_node_name(child), addr));
2292                         return (DDI_FAILURE);
2293                 }
2294                 if (dup != child) {
2295                         SCSI_HBA_LOG((_LOG(4), NULL, child,
2296                             "init failed: %s@%s: detected duplicate %p",
2297                             ddi_node_name(child), addr, (void *)dup));
2298                         return (DDI_FAILURE);
2299                 }
2300         }
2301 
2302         /* set the node @addr string */
2303         ddi_set_name_addr(child, addr);
2304 
2305         return (DDI_SUCCESS);
2306 }
2307 
2308 /* uninitchild SCSA iport 'child' node */
2309 static int
2310 iport_busctl_uninitchild(dev_info_t *child)
2311 {
2312         ddi_set_name_addr(child, NULL);
2313         return (DDI_SUCCESS);
2314 }
2315 
2316 /* Uninitialize scsi_device flavor of transport on SCSA iport 'child' node. */
2317 static void
2318 iport_postdetach_tran_scsi_device(dev_info_t *child)
2319 {
2320         scsi_hba_tran_t         *tran;
2321 
2322         tran = ndi_flavorv_get(child, SCSA_FLAVOR_SCSI_DEVICE);
2323         if (tran == NULL)
2324                 return;
2325 
2326         scsa_tran_teardown(child, tran);
2327         scsa_nexus_teardown(child, tran);
2328 
2329         ndi_flavorv_set(child, SCSA_FLAVOR_SCSI_DEVICE, NULL);
2330         scsi_hba_tran_free(tran);
2331 }
2332 
2333 /* Initialize scsi_device flavor of transport on SCSA iport 'child' node. */
2334 static void
2335 iport_preattach_tran_scsi_device(dev_info_t *child)
2336 {
2337         dev_info_t      *hba = ddi_get_parent(child);
2338         scsi_hba_tran_t *htran;
2339         scsi_hba_tran_t *tran;
2340 
2341         /* parent HBA node scsi_device tran is required */
2342         htran = ndi_flavorv_get(hba, SCSA_FLAVOR_SCSI_DEVICE);
2343         ASSERT(htran);
2344 
2345         /* Allocate iport child's scsi_device transport vector */
2346         tran = scsi_hba_tran_alloc(child, SCSI_HBA_CANSLEEP);
2347         ASSERT(tran);
2348 
2349         /* Structure-copy scsi_device transport of HBA to iport. */
2350         *tran = *htran;
2351 
2352         /*
2353          * Reset scsi_device transport fields not shared with the
2354          * parent, and not established below.
2355          */
2356         tran->tran_open_flag = 0;
2357         tran->tran_hba_private = NULL;
2358 
2359         /* Establish the devinfo context of this tran structure. */
2360         tran->tran_iport_dip = child;
2361 
2362         /* Clear SCSI_HBA_SCSA flags (except TA) */
2363         tran->tran_hba_flags &=
2364             ~(SCSI_HBA_SCSA_FM | SCSI_HBA_SCSA_PHCI);   /* clear parent state */
2365         tran->tran_hba_flags |= SCSI_HBA_SCSA_TA;    /* always TA */
2366         tran->tran_hba_flags &= ~SCSI_HBA_HBA;           /* never HBA */
2367 
2368         /* Establish flavor of transport (and ddi_get_driver_private()) */
2369         ndi_flavorv_set(child, SCSA_FLAVOR_SCSI_DEVICE, tran);
2370 
2371         /* Setup iport node */
2372         if ((scsa_nexus_setup(child, tran) != DDI_SUCCESS) ||
2373             (scsa_tran_setup(child, tran) != DDI_SUCCESS))
2374                 iport_postdetach_tran_scsi_device(child);
2375 }
2376 
2377 /* Uninitialize smp_device flavor of transport on SCSA iport 'child' node. */
2378 static void
2379 iport_postdetach_tran_smp_device(dev_info_t *child)
2380 {
2381         smp_hba_tran_t  *tran;
2382 
2383         tran = ndi_flavorv_get(child, SCSA_FLAVOR_SMP);
2384         if (tran == NULL)
2385                 return;
2386 
2387         ndi_flavorv_set(child, SCSA_FLAVOR_SMP, NULL);
2388         smp_hba_tran_free(tran);
2389 }
2390 
2391 /* Initialize smp_device flavor of transport on SCSA iport 'child' node. */
2392 static void
2393 iport_preattach_tran_smp_device(dev_info_t *child)
2394 {
2395         dev_info_t      *hba = ddi_get_parent(child);
2396         smp_hba_tran_t  *htran;
2397         smp_hba_tran_t  *tran;
2398 
2399         /* parent HBA node smp_device tran is optional */
2400         htran = ndi_flavorv_get(hba, SCSA_FLAVOR_SMP);
2401         if (htran == NULL) {
2402                 ndi_flavorv_set(child, SCSA_FLAVOR_SMP, NULL);
2403                 return;
2404         }
2405 
2406         /* Allocate iport child's smp_device transport vector */
2407         tran = smp_hba_tran_alloc(child);
2408 
2409         /* Structure-copy smp_device transport of HBA to iport. */
2410         *tran = *htran;
2411 
2412         /* Establish flavor of transport */
2413         ndi_flavorv_set(child, SCSA_FLAVOR_SMP, tran);
2414 }
2415 
2416 /*
2417  * Generic bus_ctl operations for SCSI HBA's,
2418  * hiding the busctl interface from the HBA.
2419  */
2420 /*ARGSUSED*/
2421 static int
2422 scsi_hba_bus_ctl(
2423         dev_info_t              *self,
2424         dev_info_t              *child,
2425         ddi_ctl_enum_t          op,
2426         void                    *arg,
2427         void                    *result)
2428 {
2429         int                     child_flavor = 0;
2430         int                     val;
2431         ddi_dma_attr_t          *attr;
2432         scsi_hba_tran_t         *tran;
2433         struct attachspec       *as;
2434         struct detachspec       *ds;
2435 
2436         /* For some ops, child is 'arg'. */
2437         if ((op == DDI_CTLOPS_INITCHILD) || (op == DDI_CTLOPS_UNINITCHILD))
2438                 child = (dev_info_t *)arg;
2439 
2440         /* Determine the flavor of the child: scsi, smp, iport */
2441         child_flavor = ndi_flavor_get(child);
2442 
2443         switch (op) {
2444         case DDI_CTLOPS_INITCHILD:
2445                 switch (child_flavor) {
2446                 case SCSA_FLAVOR_SCSI_DEVICE:
2447                         return (scsi_busctl_initchild(child));
2448                 case SCSA_FLAVOR_SMP:
2449                         return (smp_busctl_initchild(child));
2450                 case SCSA_FLAVOR_IPORT:
2451                         return (iport_busctl_initchild(child));
2452                 default:
2453                         return (DDI_FAILURE);
2454                 }
2455                 /* NOTREACHED */
2456 
2457         case DDI_CTLOPS_UNINITCHILD:
2458                 switch (child_flavor) {
2459                 case SCSA_FLAVOR_SCSI_DEVICE:
2460                         return (scsi_busctl_uninitchild(child));
2461                 case SCSA_FLAVOR_SMP:
2462                         return (smp_busctl_uninitchild(child));
2463                 case SCSA_FLAVOR_IPORT:
2464                         return (iport_busctl_uninitchild(child));
2465                 default:
2466                         return (DDI_FAILURE);
2467                 }
2468                 /* NOTREACHED */
2469 
2470         case DDI_CTLOPS_REPORTDEV:
2471                 switch (child_flavor) {
2472                 case SCSA_FLAVOR_SCSI_DEVICE:
2473                         return (scsi_busctl_reportdev(child));
2474                 case SCSA_FLAVOR_SMP:
2475                         return (smp_busctl_reportdev(child));
2476                 case SCSA_FLAVOR_IPORT:
2477                         return (iport_busctl_reportdev(child));
2478                 default:
2479                         return (DDI_FAILURE);
2480                 }
2481                 /* NOTREACHED */
2482 
2483         case DDI_CTLOPS_ATTACH:
2484                 as = (struct attachspec *)arg;
2485 
2486                 if (child_flavor != SCSA_FLAVOR_IPORT)
2487                         return (DDI_SUCCESS);
2488 
2489                 /* iport processing */
2490                 if (as->when == DDI_PRE) {
2491                         /* setup pre attach(9E) */
2492                         iport_preattach_tran_scsi_device(child);
2493                         iport_preattach_tran_smp_device(child);
2494                 } else if ((as->when == DDI_POST) &&
2495                     (as->result != DDI_SUCCESS)) {
2496                         /* cleanup if attach(9E) failed */
2497                         iport_postdetach_tran_scsi_device(child);
2498                         iport_postdetach_tran_smp_device(child);
2499                 }
2500                 return (DDI_SUCCESS);
2501 
2502         case DDI_CTLOPS_DETACH:
2503                 ds = (struct detachspec *)arg;
2504 
2505                 if (child_flavor != SCSA_FLAVOR_IPORT)
2506                         return (DDI_SUCCESS);
2507 
2508                 /* iport processing */
2509                 if ((ds->when == DDI_POST) &&
2510                     (ds->result == DDI_SUCCESS)) {
2511                         /* cleanup if detach(9E) was successful */
2512                         iport_postdetach_tran_scsi_device(child);
2513                         iport_postdetach_tran_smp_device(child);
2514                 }
2515                 return (DDI_SUCCESS);
2516 
2517         case DDI_CTLOPS_IOMIN:
2518                 tran = ddi_get_driver_private(self);
2519                 ASSERT(tran);
2520                 if (tran == NULL)
2521                         return (DDI_FAILURE);
2522 
2523                 /*
2524                  * The 'arg' value of nonzero indicates 'streaming'
2525                  * mode. If in streaming mode, pick the largest
2526                  * of our burstsizes available and say that that
2527                  * is our minimum value (modulo what minxfer is).
2528                  */
2529                 attr = &tran->tran_dma_attr;
2530                 val = *((int *)result);
2531                 val = maxbit(val, attr->dma_attr_minxfer);
2532                 *((int *)result) = maxbit(val, ((intptr_t)arg ?
2533                     (1<<ddi_ffs(attr->dma_attr_burstsizes)-1) :
2534                     (1<<(ddi_fls(attr->dma_attr_burstsizes)-1))));
2535 
2536                 return (ddi_ctlops(self, child, op, arg, result));
2537 
2538         case DDI_CTLOPS_SIDDEV:
2539                 return (ndi_dev_is_persistent_node(child) ?
2540                     DDI_SUCCESS : DDI_FAILURE);
2541 
2542         case DDI_CTLOPS_POWER:
2543                 return (DDI_SUCCESS);
2544 
2545         /*
2546          * These ops correspond to functions that "shouldn't" be called
2547          * by a SCSI target driver. So we whine when we're called.
2548          */
2549         case DDI_CTLOPS_DMAPMAPC:
2550         case DDI_CTLOPS_REPORTINT:
2551         case DDI_CTLOPS_REGSIZE:
2552         case DDI_CTLOPS_NREGS:
2553         case DDI_CTLOPS_SLAVEONLY:
2554         case DDI_CTLOPS_AFFINITY:
2555         case DDI_CTLOPS_POKE:
2556         case DDI_CTLOPS_PEEK:
2557                 SCSI_HBA_LOG((_LOG(WARN), self, NULL, "invalid op (%d)", op));
2558                 return (DDI_FAILURE);
2559 
2560         /* Everything else we pass up */
2561         case DDI_CTLOPS_PTOB:
2562         case DDI_CTLOPS_BTOP:
2563         case DDI_CTLOPS_BTOPR:
2564         case DDI_CTLOPS_DVMAPAGESIZE:
2565         default:
2566                 return (ddi_ctlops(self, child, op, arg, result));
2567         }
2568         /* NOTREACHED */
2569 }
2570 
2571 /*
2572  * Private wrapper for scsi_pkt's allocated via scsi_hba_pkt_alloc()
2573  */
2574 struct scsi_pkt_wrapper {
2575         struct scsi_pkt         scsi_pkt;
2576         int                     pkt_wrapper_magic;
2577         int                     pkt_wrapper_len;
2578 };
2579 
2580 #if !defined(lint)
2581 _NOTE(SCHEME_PROTECTS_DATA("unique per thread", scsi_pkt_wrapper))
2582 _NOTE(SCHEME_PROTECTS_DATA("Unshared Data", dev_ops))
2583 #endif
2584 
2585 /*
2586  * Called by an HBA to allocate a scsi_pkt
2587  */
2588 /*ARGSUSED*/
2589 struct scsi_pkt *
2590 scsi_hba_pkt_alloc(
2591         dev_info_t              *self,
2592         struct scsi_address     *ap,
2593         int                     cmdlen,
2594         int                     statuslen,
2595         int                     tgtlen,
2596         int                     hbalen,
2597         int                     (*callback)(caddr_t arg),
2598         caddr_t                 arg)
2599 {
2600         struct scsi_pkt         *pkt;
2601         struct scsi_pkt_wrapper *hba_pkt;
2602         caddr_t                 p;
2603         int                     acmdlen, astatuslen, atgtlen, ahbalen;
2604         int                     pktlen;
2605 
2606         /* Sanity check */
2607         if (callback != SLEEP_FUNC && callback != NULL_FUNC)
2608                 SCSI_HBA_LOG((_LOG(WARN), self, NULL,
2609                     "callback must be SLEEP_FUNC or NULL_FUNC"));
2610 
2611         /*
2612          * Round up so everything gets allocated on long-word boundaries
2613          */
2614         acmdlen = ROUNDUP(cmdlen);
2615         astatuslen = ROUNDUP(statuslen);
2616         atgtlen = ROUNDUP(tgtlen);
2617         ahbalen = ROUNDUP(hbalen);
2618         pktlen = sizeof (struct scsi_pkt_wrapper) +
2619             acmdlen + astatuslen + atgtlen + ahbalen;
2620 
2621         hba_pkt = kmem_zalloc(pktlen,
2622             (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP);
2623         if (hba_pkt == NULL) {
2624                 ASSERT(callback == NULL_FUNC);
2625                 return (NULL);
2626         }
2627 
2628         /*
2629          * Set up our private info on this pkt
2630          */
2631         hba_pkt->pkt_wrapper_len = pktlen;
2632         hba_pkt->pkt_wrapper_magic = PKT_WRAPPER_MAGIC;      /* alloced correctly */
2633         pkt = &hba_pkt->scsi_pkt;
2634 
2635         /*
2636          * Set up pointers to private data areas, cdb, and status.
2637          */
2638         p = (caddr_t)(hba_pkt + 1);
2639         if (hbalen > 0) {
2640                 pkt->pkt_ha_private = (opaque_t)p;
2641                 p += ahbalen;
2642         }
2643         if (tgtlen > 0) {
2644                 pkt->pkt_private = (opaque_t)p;
2645                 p += atgtlen;
2646         }
2647         if (statuslen > 0) {
2648                 pkt->pkt_scbp = (uchar_t *)p;
2649                 p += astatuslen;
2650         }
2651         if (cmdlen > 0) {
2652                 pkt->pkt_cdbp = (uchar_t *)p;
2653         }
2654 
2655         /*
2656          * Initialize the pkt's scsi_address
2657          */
2658         pkt->pkt_address = *ap;
2659 
2660         /*
2661          * NB: It may not be safe for drivers, esp target drivers, to depend
2662          * on the following fields being set until all the scsi_pkt
2663          * allocation violations discussed in scsi_pkt.h are all resolved.
2664          */
2665         pkt->pkt_cdblen = cmdlen;
2666         pkt->pkt_tgtlen = tgtlen;
2667         pkt->pkt_scblen = statuslen;
2668 
2669         return (pkt);
2670 }
2671 
2672 /*
2673  * Called by an HBA to free a scsi_pkt
2674  */
2675 /*ARGSUSED*/
2676 void
2677 scsi_hba_pkt_free(
2678         struct scsi_address     *ap,
2679         struct scsi_pkt         *pkt)
2680 {
2681         kmem_free(pkt, ((struct scsi_pkt_wrapper *)pkt)->pkt_wrapper_len);
2682 }
2683 
2684 /*
2685  * Return 1 if the scsi_pkt used a proper allocator.
2686  *
2687  * The DDI does not allow a driver to allocate it's own scsi_pkt(9S), a
2688  * driver should not have *any* compiled in dependencies on "sizeof (struct
2689  * scsi_pkt)". While this has been the case for many years, a number of
2690  * drivers have still not been fixed. This function can be used to detect
2691  * improperly allocated scsi_pkt structures, and produce messages identifying
2692  * drivers that need to be fixed.
2693  *
2694  * While drivers in violation are being fixed, this function can also
2695  * be used by the framework to detect packets that violated allocation
2696  * rules.
2697  *
2698  * NB: It is possible, but very unlikely, for this code to return a false
2699  * positive (finding correct magic, but for wrong reasons).  Careful
2700  * consideration is needed for callers using this interface to condition
2701  * access to newer scsi_pkt fields (those after pkt_reason).
2702  *
2703  * NB: As an aid to minimizing the amount of work involved in 'fixing' legacy
2704  * drivers that violate scsi_*(9S) allocation rules, private
2705  * scsi_pkt_size()/scsi_size_clean() functions are available (see their
2706  * implementation for details).
2707  *
2708  * *** Non-legacy use of scsi_pkt_size() is discouraged. ***
2709  *
2710  * NB: When supporting broken HBA drivers is not longer a concern, this
2711  * code should be removed.
2712  */
2713 int
2714 scsi_pkt_allocated_correctly(struct scsi_pkt *pkt)
2715 {
2716         struct scsi_pkt_wrapper *hba_pkt = (struct scsi_pkt_wrapper *)pkt;
2717         int     magic;
2718         major_t major;
2719 #ifdef  DEBUG
2720         int     *pspwm, *pspcwm;
2721 
2722         /*
2723          * We are getting scsi packets from two 'correct' wrapper schemes,
2724          * make sure we are looking at the same place in both to detect
2725          * proper allocation.
2726          */
2727         pspwm = &((struct scsi_pkt_wrapper *)0)->pkt_wrapper_magic;
2728         pspcwm = &((struct scsi_pkt_cache_wrapper *)0)->pcw_magic;
2729         ASSERT(pspwm == pspcwm);
2730 #endif  /* DEBUG */
2731 
2732 
2733         /*
2734          * Check to see if driver is scsi_size_clean(), assume it
2735          * is using the scsi_pkt_size() interface everywhere it needs to
2736          * if the driver indicates it is scsi_size_clean().
2737          */
2738         major = ddi_driver_major(P_TO_TRAN(pkt)->tran_hba_dip);
2739         if (devnamesp[major].dn_flags & DN_SCSI_SIZE_CLEAN)
2740                 return (1);             /* ok */
2741 
2742         /*
2743          * Special case crossing a page boundary. If the scsi_pkt was not
2744          * allocated correctly, then across a page boundary we have a
2745          * fault hazard.
2746          */
2747         if ((((uintptr_t)(&hba_pkt->scsi_pkt)) & MMU_PAGEMASK) ==
2748             (((uintptr_t)(&hba_pkt->pkt_wrapper_magic)) & MMU_PAGEMASK)) {
2749                 /* fastpath, no cross-page hazard */
2750                 magic = hba_pkt->pkt_wrapper_magic;
2751         } else {
2752                 /* add protection for cross-page hazard */
2753                 if (ddi_peek32((dev_info_t *)NULL,
2754                     &hba_pkt->pkt_wrapper_magic, &magic) == DDI_FAILURE) {
2755                         return (0);     /* violation */
2756                 }
2757         }
2758 
2759         /* properly allocated packet always has correct magic */
2760         return ((magic == PKT_WRAPPER_MAGIC) ? 1 : 0);
2761 }
2762 
2763 /*
2764  * Private interfaces to simplify conversion of legacy drivers so they don't
2765  * depend on scsi_*(9S) size. Instead of using these private interface, HBA
2766  * drivers should use DDI sanctioned allocation methods:
2767  *
2768  *      scsi_pkt        Use scsi_hba_pkt_alloc(9F), or implement
2769  *                      tran_setup_pkt(9E).
2770  *
2771  *      scsi_device     You are doing something strange/special, a scsi_device
2772  *                      structure should only be allocated by scsi_hba.c
2773  *                      initchild code or scsi_vhci.c code.
2774  *
2775  *      scsi_hba_tran   Use scsi_hba_tran_alloc(9F).
2776  */
2777 size_t
2778 scsi_pkt_size()
2779 {
2780         return (sizeof (struct scsi_pkt));
2781 }
2782 
2783 size_t
2784 scsi_hba_tran_size()
2785 {
2786         return (sizeof (scsi_hba_tran_t));
2787 }
2788 
2789 size_t
2790 scsi_device_size()
2791 {
2792         return (sizeof (struct scsi_device));
2793 }
2794 
2795 /*
2796  * Legacy compliance to scsi_pkt(9S) allocation rules through use of
2797  * scsi_pkt_size() is detected by the 'scsi-size-clean' driver.conf property
2798  * or an HBA driver calling to scsi_size_clean() from attach(9E).  A driver
2799  * developer should only indicate that a legacy driver is clean after using
2800  * SCSI_SIZE_CLEAN_VERIFY to ensure compliance (see scsi_pkt.h).
2801  */
2802 void
2803 scsi_size_clean(dev_info_t *self)
2804 {
2805         major_t         major;
2806         struct devnames *dnp;
2807 
2808         ASSERT(self);
2809         major = ddi_driver_major(self);
2810         ASSERT(major < devcnt);
2811         if (major >= devcnt) {
2812                 SCSI_HBA_LOG((_LOG(WARN), self, NULL,
2813                     "scsi_pkt_size: bogus major: %d", major));
2814                 return;
2815         }
2816 
2817         /* Set DN_SCSI_SIZE_CLEAN flag in dn_flags. */
2818         dnp = &devnamesp[major];
2819         if ((dnp->dn_flags & DN_SCSI_SIZE_CLEAN) == 0) {
2820                 LOCK_DEV_OPS(&dnp->dn_lock);
2821                 dnp->dn_flags |= DN_SCSI_SIZE_CLEAN;
2822                 UNLOCK_DEV_OPS(&dnp->dn_lock);
2823         }
2824 }
2825 
2826 
2827 /*
2828  * Called by an HBA to map strings to capability indices
2829  */
2830 int
2831 scsi_hba_lookup_capstr(
2832         char                    *capstr)
2833 {
2834         /*
2835          * Capability strings: only add entries to mask the legacy
2836          * '_' vs. '-' misery.  All new capabilities should use '-',
2837          * and be captured be added to SCSI_CAP_ASCII.
2838          */
2839         static struct cap_strings {
2840                 char    *cap_string;
2841                 int     cap_index;
2842         } cap_strings[] = {
2843                 { "dma_max",            SCSI_CAP_DMA_MAX                },
2844                 { "msg_out",            SCSI_CAP_MSG_OUT                },
2845                 { "wide_xfer",          SCSI_CAP_WIDE_XFER              },
2846                 { NULL,                 0                               }
2847         };
2848         static char             *cap_ascii[] = SCSI_CAP_ASCII;
2849         char                    **cap;
2850         int                     i;
2851         struct cap_strings      *cp;
2852 
2853         for (cap = cap_ascii, i = 0; *cap != NULL; cap++, i++)
2854                 if (strcmp(*cap, capstr) == 0)
2855                         return (i);
2856 
2857         for (cp = cap_strings; cp->cap_string != NULL; cp++)
2858                 if (strcmp(cp->cap_string, capstr) == 0)
2859                         return (cp->cap_index);
2860 
2861         return (-1);
2862 }
2863 
2864 /*
2865  * Called by an HBA to determine if the system is in 'panic' state.
2866  */
2867 int
2868 scsi_hba_in_panic()
2869 {
2870         return (panicstr != NULL);
2871 }
2872 
2873 /*
2874  * If a SCSI target driver attempts to mmap memory,
2875  * the buck stops here.
2876  */
2877 /*ARGSUSED*/
2878 static int
2879 scsi_hba_map_fault(
2880         dev_info_t              *self,
2881         dev_info_t              *child,
2882         struct hat              *hat,
2883         struct seg              *seg,
2884         caddr_t                 addr,
2885         struct devpage          *dp,
2886         pfn_t                   pfn,
2887         uint_t                  prot,
2888         uint_t                  lock)
2889 {
2890         return (DDI_FAILURE);
2891 }
2892 
2893 static int
2894 scsi_hba_get_eventcookie(
2895         dev_info_t              *self,
2896         dev_info_t              *child,
2897         char                    *name,
2898         ddi_eventcookie_t       *eventp)
2899 {
2900         scsi_hba_tran_t         *tran;
2901 
2902         tran = ddi_get_driver_private(self);
2903         if (tran->tran_get_eventcookie &&
2904             ((*tran->tran_get_eventcookie)(self,
2905             child, name, eventp) == DDI_SUCCESS)) {
2906                 return (DDI_SUCCESS);
2907         }
2908 
2909         return (ndi_busop_get_eventcookie(self, child, name, eventp));
2910 }
2911 
2912 static int
2913 scsi_hba_add_eventcall(
2914         dev_info_t              *self,
2915         dev_info_t              *child,
2916         ddi_eventcookie_t       event,
2917         void                    (*callback)(
2918                                         dev_info_t *self,
2919                                         ddi_eventcookie_t event,
2920                                         void *arg,
2921                                         void *bus_impldata),
2922         void                    *arg,
2923         ddi_callback_id_t       *cb_id)
2924 {
2925         scsi_hba_tran_t         *tran;
2926 
2927         tran = ddi_get_driver_private(self);
2928         if (tran->tran_add_eventcall &&
2929             ((*tran->tran_add_eventcall)(self, child,
2930             event, callback, arg, cb_id) == DDI_SUCCESS)) {
2931                 return (DDI_SUCCESS);
2932         }
2933 
2934         return (DDI_FAILURE);
2935 }
2936 
2937 static int
2938 scsi_hba_remove_eventcall(dev_info_t *self, ddi_callback_id_t cb_id)
2939 {
2940         scsi_hba_tran_t         *tran;
2941         ASSERT(cb_id);
2942 
2943         tran = ddi_get_driver_private(self);
2944         if (tran->tran_remove_eventcall &&
2945             ((*tran->tran_remove_eventcall)(
2946             self, cb_id) == DDI_SUCCESS)) {
2947                 return (DDI_SUCCESS);
2948         }
2949 
2950         return (DDI_FAILURE);
2951 }
2952 
2953 static int
2954 scsi_hba_post_event(
2955         dev_info_t              *self,
2956         dev_info_t              *child,
2957         ddi_eventcookie_t       event,
2958         void                    *bus_impldata)
2959 {
2960         scsi_hba_tran_t         *tran;
2961 
2962         tran = ddi_get_driver_private(self);
2963         if (tran->tran_post_event &&
2964             ((*tran->tran_post_event)(self,
2965             child, event, bus_impldata) == DDI_SUCCESS)) {
2966                 return (DDI_SUCCESS);
2967         }
2968 
2969         return (DDI_FAILURE);
2970 }
2971 
2972 /*
2973  * Default getinfo(9e) for scsi_hba
2974  */
2975 /* ARGSUSED */
2976 static int
2977 scsi_hba_info(dev_info_t *self, ddi_info_cmd_t infocmd, void *arg,
2978     void **result)
2979 {
2980         int error = DDI_SUCCESS;
2981 
2982         switch (infocmd) {
2983         case DDI_INFO_DEVT2INSTANCE:
2984                 *result = (void *)(intptr_t)(MINOR2INST(getminor((dev_t)arg)));
2985                 break;
2986         default:
2987                 error = DDI_FAILURE;
2988         }
2989         return (error);
2990 }
2991 
2992 /*
2993  * Default open and close routine for scsi_hba
2994  */
2995 /* ARGSUSED */
2996 int
2997 scsi_hba_open(dev_t *devp, int flags, int otyp, cred_t *credp)
2998 {
2999         dev_info_t      *self;
3000         scsi_hba_tran_t *tran;
3001         int             rv = 0;
3002 
3003         if (otyp != OTYP_CHR)
3004                 return (EINVAL);
3005 
3006         if ((self = e_ddi_hold_devi_by_dev(*devp, 0)) == NULL)
3007                 return (ENXIO);
3008 
3009         tran = ddi_get_driver_private(self);
3010         if (tran == NULL) {
3011                 ddi_release_devi(self);
3012                 return (ENXIO);
3013         }
3014 
3015         /*
3016          * tran_open_flag bit field:
3017          *      0:      closed
3018          *      1:      shared open by minor at bit position
3019          *      1 at 31st bit:  exclusive open
3020          */
3021         mutex_enter(&(tran->tran_open_lock));
3022         if (flags & FEXCL) {
3023                 if (tran->tran_open_flag != 0) {
3024                         rv = EBUSY;             /* already open */
3025                 } else {
3026                         tran->tran_open_flag = TRAN_OPEN_EXCL;
3027                 }
3028         } else {
3029                 if (tran->tran_open_flag == TRAN_OPEN_EXCL) {
3030                         rv = EBUSY;             /* already excl. open */
3031                 } else {
3032                         int minor = getminor(*devp) & TRAN_MINOR_MASK;
3033                         tran->tran_open_flag |= (1 << minor);
3034                         /*
3035                          * Ensure that the last framework reserved minor
3036                          * is unused. Otherwise, the exclusive open
3037                          * mechanism may break.
3038                          */
3039                         ASSERT(minor != 31);
3040                 }
3041         }
3042         mutex_exit(&(tran->tran_open_lock));
3043 
3044         ddi_release_devi(self);
3045         return (rv);
3046 }
3047 
3048 /* ARGSUSED */
3049 int
3050 scsi_hba_close(dev_t dev, int flag, int otyp, cred_t *credp)
3051 {
3052         dev_info_t      *self;
3053         scsi_hba_tran_t *tran;
3054 
3055         if (otyp != OTYP_CHR)
3056                 return (EINVAL);
3057 
3058         if ((self = e_ddi_hold_devi_by_dev(dev, 0)) == NULL)
3059                 return (ENXIO);
3060 
3061         tran = ddi_get_driver_private(self);
3062         if (tran == NULL) {
3063                 ddi_release_devi(self);
3064                 return (ENXIO);
3065         }
3066 
3067         mutex_enter(&(tran->tran_open_lock));
3068         if (tran->tran_open_flag == TRAN_OPEN_EXCL) {
3069                 tran->tran_open_flag = 0;
3070         } else {
3071                 int minor = getminor(dev) & TRAN_MINOR_MASK;
3072                 tran->tran_open_flag &= ~(1 << minor);
3073         }
3074         mutex_exit(&(tran->tran_open_lock));
3075 
3076         ddi_release_devi(self);
3077         return (0);
3078 }
3079 
3080 /*
3081  * standard ioctl commands for SCSI hotplugging
3082  */
3083 /* ARGSUSED */
3084 int
3085 scsi_hba_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
3086     int *rvalp)
3087 {
3088         dev_info_t              *self;
3089         struct devctl_iocdata   *dcp = NULL;
3090         dev_info_t              *child = NULL;
3091         mdi_pathinfo_t          *path = NULL;
3092         struct scsi_device      *sd;
3093         scsi_hba_tran_t         *tran;
3094         uint_t                  bus_state;
3095         int                     rv = 0;
3096         int                     circ;
3097         char                    *name;
3098         char                    *addr;
3099 
3100         self = e_ddi_hold_devi_by_dev(dev, 0);
3101         if (self == NULL) {
3102                 rv = ENXIO;
3103                 goto out;
3104         }
3105 
3106         if (DEVI(self)->devi_flags & (DEVI_RETIRED | DEVI_RETIRING)) {
3107                 rv = ENXIO;
3108                 goto out;
3109         }
3110 
3111         tran = ddi_get_driver_private(self);
3112         if (tran == NULL) {
3113                 rv = ENXIO;
3114                 goto out;
3115         }
3116 
3117         /* Ioctls for which the generic implementation suffices. */
3118         switch (cmd) {
3119         case DEVCTL_BUS_GETSTATE:
3120                 rv = ndi_devctl_ioctl(self, cmd, arg, mode, 0);
3121                 goto out;
3122         }
3123 
3124         /* read devctl ioctl data */
3125         if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS) {
3126                 rv = EFAULT;
3127                 goto out;
3128         }
3129 
3130         /* Ioctls that require child identification */
3131         switch (cmd) {
3132         case DEVCTL_DEVICE_GETSTATE:
3133         case DEVCTL_DEVICE_ONLINE:
3134         case DEVCTL_DEVICE_OFFLINE:
3135         case DEVCTL_DEVICE_REMOVE:
3136         case DEVCTL_DEVICE_RESET:
3137                 name = ndi_dc_getname(dcp);
3138                 addr = ndi_dc_getaddr(dcp);
3139                 if ((name == NULL) || (addr == NULL)) {
3140                         rv = EINVAL;
3141                         goto out;
3142                 }
3143 
3144                 /*
3145                  * Find child with name@addr - might find a devinfo
3146                  * child (child), a pathinfo child (path), or nothing.
3147                  */
3148                 scsi_hba_devi_enter(self, &circ);
3149 
3150                 (void) scsi_findchild(self, name, addr, 1, &child, &path, NULL);
3151                 if (path) {
3152                         /* Found a pathinfo */
3153                         ASSERT(path && (child == NULL));
3154                         mdi_hold_path(path);
3155                         scsi_hba_devi_exit_phci(self, circ);
3156                         sd = NULL;
3157                 } else if (child) {
3158                         /* Found a devinfo */
3159                         ASSERT(child && (path == NULL));
3160 
3161                         /* verify scsi_device of child */
3162                         if (ndi_flavor_get(child) == SCSA_FLAVOR_SCSI_DEVICE)
3163                                 sd = ddi_get_driver_private(child);
3164                         else
3165                                 sd = NULL;
3166                 } else {
3167                         ASSERT((path == NULL) && (child == NULL));
3168                         scsi_hba_devi_exit(self, circ);
3169                         rv = ENXIO;                     /* found nothing */
3170                         goto out;
3171                 }
3172                 break;
3173 
3174         case DEVCTL_BUS_RESETALL:       /* ioctl that operate on any child */
3175                 /*
3176                  * Find a child's scsi_address so we can invoke tran_reset.
3177                  *
3178                  * Future: If no child exists, we could fake a child. This will
3179                  * be a enhancement for the future - for now, we fall back to
3180                  * BUS_RESET.
3181                  */
3182                 scsi_hba_devi_enter(self, &circ);
3183                 child = ddi_get_child(self);
3184                 sd = NULL;
3185                 while (child) {
3186                         /* verify scsi_device of child */
3187                         if (ndi_flavor_get(child) == SCSA_FLAVOR_SCSI_DEVICE)
3188                                 sd = ddi_get_driver_private(child);
3189                         if (sd != NULL) {
3190                                 /*
3191                                  * NOTE: node has a scsi_device structure, so
3192                                  * it must be initialized.
3193                                  */
3194                                 ndi_hold_devi(child);
3195                                 break;
3196                         }
3197                         child = ddi_get_next_sibling(child);
3198                 }
3199                 scsi_hba_devi_exit(self, circ);
3200                 break;
3201         }
3202 
3203         switch (cmd) {
3204         case DEVCTL_DEVICE_GETSTATE:
3205                 if (path) {
3206                         if (mdi_dc_return_dev_state(path, dcp) != MDI_SUCCESS)
3207                                 rv = EFAULT;
3208                 } else if (child) {
3209                         if (ndi_dc_return_dev_state(child, dcp) != NDI_SUCCESS)
3210                                 rv = EFAULT;
3211                 } else {
3212                         rv = ENXIO;
3213                 }
3214                 break;
3215 
3216         case DEVCTL_DEVICE_RESET:
3217                 if (sd == NULL) {
3218                         rv = ENOTTY;
3219                         break;
3220                 }
3221                 if (tran->tran_reset == NULL) {
3222                         rv = ENOTSUP;
3223                         break;
3224                 }
3225 
3226                 /* Start with the small stick */
3227                 if (scsi_reset(&sd->sd_address, RESET_LUN) == 1)
3228                         break;          /* LUN reset worked */
3229                 if (scsi_reset(&sd->sd_address, RESET_TARGET) != 1)
3230                         rv = EIO;       /* Target reset failed */
3231                 break;
3232 
3233         case DEVCTL_BUS_QUIESCE:
3234                 if ((ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) &&
3235                     (bus_state == BUS_QUIESCED))
3236                         rv = EALREADY;
3237                 else if (tran->tran_quiesce == NULL)
3238                         rv = ENOTSUP; /* man ioctl(7I) says ENOTTY */
3239                 else if (tran->tran_quiesce(self) != 0)
3240                         rv = EIO;
3241                 else if (ndi_set_bus_state(self, BUS_QUIESCED) != NDI_SUCCESS)
3242                         rv = EIO;
3243                 break;
3244 
3245         case DEVCTL_BUS_UNQUIESCE:
3246                 if ((ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) &&
3247                     (bus_state == BUS_ACTIVE))
3248                         rv = EALREADY;
3249                 else if (tran->tran_unquiesce == NULL)
3250                         rv = ENOTSUP; /* man ioctl(7I) says ENOTTY */
3251                 else if (tran->tran_unquiesce(self) != 0)
3252                         rv = EIO;
3253                 else if (ndi_set_bus_state(self, BUS_ACTIVE) != NDI_SUCCESS)
3254                         rv = EIO;
3255                 break;
3256 
3257         case DEVCTL_BUS_RESET:
3258                 if (tran->tran_bus_reset == NULL)
3259                         rv = ENOTSUP; /* man ioctl(7I) says ENOTTY */
3260                 else if (tran->tran_bus_reset(self, RESET_BUS) != 1)
3261                         rv = EIO;
3262                 break;
3263 
3264         case DEVCTL_BUS_RESETALL:
3265                 if ((sd != NULL) &&
3266                     (scsi_reset(&sd->sd_address, RESET_ALL) == 1)) {
3267                         break;          /* reset all worked */
3268                 }
3269                 if (tran->tran_bus_reset == NULL) {
3270                         rv = ENOTSUP; /* man ioctl(7I) says ENOTTY */
3271                         break;
3272                 }
3273                 if (tran->tran_bus_reset(self, RESET_BUS) != 1)
3274                         rv = EIO;       /* bus reset failed */
3275                 break;
3276 
3277         case DEVCTL_BUS_CONFIGURE:
3278                 if (ndi_devi_config(self, NDI_DEVFS_CLEAN | NDI_DEVI_PERSIST |
3279                     NDI_CONFIG_REPROBE) != NDI_SUCCESS) {
3280                         rv = EIO;
3281                 }
3282                 break;
3283 
3284         case DEVCTL_BUS_UNCONFIGURE:
3285                 if (ndi_devi_unconfig(self,
3286                     NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE) != NDI_SUCCESS) {
3287                         rv = EBUSY;
3288                 }
3289                 break;
3290 
3291         case DEVCTL_DEVICE_ONLINE:
3292                 ASSERT(child || path);
3293                 if (path) {
3294                         if (mdi_pi_online(path, NDI_USER_REQ) != MDI_SUCCESS)
3295                                 rv = EIO;
3296                 } else {
3297                         if (ndi_devi_online(child, 0) != NDI_SUCCESS)
3298                                 rv = EIO;
3299                 }
3300                 break;
3301 
3302         case DEVCTL_DEVICE_OFFLINE:
3303                 ASSERT(child || path);
3304                 if (sd != NULL)
3305                         (void) scsi_clear_task_set(&sd->sd_address);
3306                 if (path) {
3307                         if (mdi_pi_offline(path, NDI_USER_REQ) != MDI_SUCCESS)
3308                                 rv = EIO;
3309                 } else {
3310                         if (ndi_devi_offline(child,
3311                             NDI_DEVFS_CLEAN) != NDI_SUCCESS)
3312                                 rv = EIO;
3313                 }
3314                 break;
3315 
3316         case DEVCTL_DEVICE_REMOVE:
3317                 ASSERT(child || path);
3318                 if (sd != NULL)
3319                         (void) scsi_clear_task_set(&sd->sd_address);
3320                 if (path) {
3321                         /* NOTE: don't pass NDI_DEVI_REMOVE to mdi_pi_offline */
3322                         if (mdi_pi_offline(path, NDI_USER_REQ) == MDI_SUCCESS) {
3323                                 scsi_hba_devi_enter_phci(self, &circ);
3324                                 mdi_rele_path(path);
3325 
3326                                 /* ... here is the DEVICE_REMOVE part. */
3327                                 (void) mdi_pi_free(path, 0);
3328                                 path = NULL;
3329                         } else {
3330                                 rv = EIO;
3331                         }
3332                 } else {
3333                         if (ndi_devi_offline(child,
3334                             NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE) != NDI_SUCCESS)
3335                                 rv = EIO;
3336                 }
3337                 break;
3338 
3339         default:
3340                 ASSERT(dcp != NULL);
3341                 rv = ENOTTY;
3342                 break;
3343         }
3344 
3345         /* all done -- clean up and return */
3346 out:
3347         /* release hold on what we found */
3348         if (path) {
3349                 scsi_hba_devi_enter_phci(self, &circ);
3350                 mdi_rele_path(path);
3351         }
3352         if (path || child)
3353                 scsi_hba_devi_exit(self, circ);
3354 
3355         if (dcp)
3356                 ndi_dc_freehdl(dcp);
3357 
3358         if (self)
3359                 ddi_release_devi(self);
3360 
3361         *rvalp = rv;
3362 
3363         return (rv);
3364 }
3365 
3366 /*ARGSUSED*/
3367 static int
3368 scsi_hba_fm_init_child(dev_info_t *self, dev_info_t *child, int cap,
3369     ddi_iblock_cookie_t *ibc)
3370 {
3371         scsi_hba_tran_t *tran = ddi_get_driver_private(self);
3372 
3373         return (tran ? tran->tran_fm_capable : scsi_fm_capable);
3374 }
3375 
3376 static int
3377 scsi_hba_bus_power(dev_info_t *self, void *impl_arg, pm_bus_power_op_t op,
3378     void *arg, void *result)
3379 {
3380         scsi_hba_tran_t *tran;
3381 
3382         tran = ddi_get_driver_private(self);
3383         if (tran && tran->tran_bus_power) {
3384                 return (tran->tran_bus_power(self, impl_arg,
3385                     op, arg, result));
3386         }
3387 
3388         return (pm_busop_bus_power(self, impl_arg, op, arg, result));
3389 }
3390 
3391 /*
3392  * Return the lun64 value from a address string: "addr,lun[,sfunc]". Either
3393  * the lun is after the first ',' or the entire address string is the lun.
3394  * Return SCSI_LUN64_ILLEGAL if the format is incorrect. A lun64 is at most
3395  * 16 hex digits long.
3396  *
3397  * If the address string specified has incorrect syntax (busconfig one of
3398  * bogus /devices path) then scsi_addr_to_lun64 can return SCSI_LUN64_ILLEGAL.
3399  */
3400 static scsi_lun64_t
3401 scsi_addr_to_lun64(char *addr)
3402 {
3403         scsi_lun64_t    lun64;
3404         char            *s;
3405         int             i;
3406 
3407         if (addr) {
3408                 s = strchr(addr, ',');                  /* "addr,lun" */
3409                 if (s)
3410                         s++;                            /* skip ',', at lun */
3411                 else
3412                         s = addr;                       /* "lun" */
3413 
3414                 for (lun64 = 0, i = 0; *s && (i < 16); s++, i++) {
3415                         if (*s >= '0' && *s <= '9')
3416                                 lun64 = (lun64 << 4) + (*s - '0');
3417                         else if (*s >= 'A' && *s <= 'F')
3418                                 lun64 = (lun64 << 4) + 10 + (*s - 'A');
3419                         else if (*s >= 'a' && *s <= 'f')
3420                                 lun64 = (lun64 << 4) + 10 + (*s - 'a');
3421                         else
3422                                 break;
3423                 }
3424                 if (*s && (*s != ','))          /* [,sfunc] is OK */
3425                         lun64 = SCSI_LUN64_ILLEGAL;
3426         } else
3427                 lun64 = SCSI_LUN64_ILLEGAL;
3428 
3429         if (lun64 == SCSI_LUN64_ILLEGAL)
3430                 SCSI_HBA_LOG((_LOG(2), NULL, NULL,
3431                     "addr_to_lun64 %s lun %" PRIlun64,
3432                     addr ? addr : "NULL", lun64));
3433         return (lun64);
3434 }
3435 
3436 /*
3437  * Return the sfunc value from a address string: "addr,lun[,sfunc]". Either the
3438  * sfunc is after the second ',' or the entire address string is the sfunc.
3439  * Return -1 if there is only one ',' in the address string or the string is
3440  * invalid. An sfunc is at most two hex digits long.
3441  */
3442 static int
3443 scsi_addr_to_sfunc(char *addr)
3444 {
3445         int             sfunc;
3446         char            *s;
3447         int             i;
3448 
3449         if (addr) {
3450                 s = strchr(addr, ',');                  /* "addr,lun" */
3451                 if (s) {
3452                         s++;                            /* skip ',', at lun */
3453                         s = strchr(s, ',');             /* "lun,sfunc" */
3454                         if (s == NULL)
3455                                 return (-1);            /* no ",sfunc" */
3456                         s++;                            /* skip ',', at sfunc */
3457                 } else
3458                         s = addr;                       /* "sfunc" */
3459 
3460                 for (sfunc = 0, i = 0; *s && (i < 2); s++, i++) {
3461                         if (*s >= '0' && *s <= '9')
3462                                 sfunc = (sfunc << 4) + (*s - '0');
3463                         else if (*s >= 'A' && *s <= 'F')
3464                                 sfunc = (sfunc << 4) + 10 + (*s - 'A');
3465                         else if (*s >= 'a' && *s <= 'f')
3466                                 sfunc = (sfunc << 4) + 10 + (*s - 'a');
3467                         else
3468                                 break;
3469                 }
3470                 if (*s)
3471                         sfunc = -1;                     /* illegal */
3472         } else
3473                 sfunc = -1;
3474         return (sfunc);
3475 }
3476 
3477 /*
3478  * Convert scsi ascii string data to NULL terminated (semi) legal IEEE 1275
3479  * "compatible" (name) property form.
3480  *
3481  * For ASCII INQUIRY data, a one-way conversion algorithm is needed to take
3482  * SCSI_ASCII (20h - 7Eh) to a 1275-like compatible form. The 1275 spec allows
3483  * letters, digits, one ",", and ". _ + -", all limited by a maximum 31
3484  * character length. Since ", ." are used as separators in the compatible
3485  * string itself, they are converted to "_". All SCSI_ASCII characters that
3486  * are illegal in 1275, as well as any illegal SCSI_ASCII characters
3487  * encountered, are converted to "_". To reduce length, trailing blanks are
3488  * trimmed from SCSI_ASCII fields prior to conversion.
3489  *
3490  * Example: SCSI_ASCII "ST32550W SUN2.1G" -> "ST32550W_SUN2_1G"
3491  *
3492  * NOTE: the 1275 string form is always less than or equal to the scsi form.
3493  */
3494 static char *
3495 string_scsi_to_1275(char *s_1275, char *s_scsi, int len)
3496 {
3497         (void) strncpy(s_1275, s_scsi, len);
3498         s_1275[len--] = '\0';
3499 
3500         while (len >= 0) {
3501                 if (s_1275[len] == ' ')
3502                         s_1275[len--] = '\0';   /* trim trailing " " */
3503                 else
3504                         break;
3505         }
3506 
3507         while (len >= 0) {
3508                 if (((s_1275[len] >= 'a') && (s_1275[len] <= 'z')) ||
3509                     ((s_1275[len] >= 'A') && (s_1275[len] <= 'Z')) ||
3510                     ((s_1275[len] >= '0') && (s_1275[len] <= '9')) ||
3511                     (s_1275[len] == '_') ||
3512                     (s_1275[len] == '+') ||
3513                     (s_1275[len] == '-'))
3514                         len--;                  /* legal 1275  */
3515                 else
3516                         s_1275[len--] = '_';    /* illegal SCSI_ASCII | 1275 */
3517         }
3518 
3519         return (s_1275);
3520 }
3521 
3522 /*
3523  * Given the inquiry data, binding_set, and dtype_node for a scsi device,
3524  * return the nodename and compatible property for the device. The "compatible"
3525  * concept comes from IEEE-1275. The compatible information is returned is in
3526  * the correct form for direct use defining the "compatible" string array
3527  * property. Internally, "compatible" is also used to determine the nodename
3528  * to return.
3529  *
3530  * This function is provided as a separate entry point for use by drivers that
3531  * currently issue their own non-SCSA inquiry command and perform their own
3532  * node creation based their own private compiled in tables. Converting these
3533  * drivers to use this interface provides a quick easy way of obtaining
3534  * consistency as well as the flexibility associated with the 1275 techniques.
3535  *
3536  * The dtype_node is passed as a separate argument (instead of having the
3537  * implementation use inq_dtype). It indicates that information about
3538  * a secondary function embedded service should be produced.
3539  *
3540  * Callers must always use scsi_hba_nodename_compatible_free, even if
3541  * *nodenamep is null, to free the nodename and compatible information
3542  * when done.
3543  *
3544  * If a nodename can't be determined then **compatiblep will point to a
3545  * diagnostic string containing all the compatible forms.
3546  *
3547  * NOTE: some compatible strings may violate the 31 character restriction
3548  * imposed by IEEE-1275. This is not a problem because Solaris does not care
3549  * about this 31 character limit.
3550  *
3551  * Each compatible form belongs to a form-group.  The form-groups currently
3552  * defined are generic ("scsiclass"), binding-set ("scsa.b"), and failover
3553  * ("scsa.f").
3554  *
3555  * The following compatible forms, in high to low precedence
3556  * order, are defined for SCSI target device nodes.
3557  *
3558  *  scsiclass,DDEEFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR (1 *1&2)
3559  *  scsiclass,DDEE.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR    (2 *1)
3560  *  scsiclass,DDFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR   (3 *2)
3561  *  scsiclass,DD.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR      (4)
3562  *  scsiclass,DDEEFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP       (5 *1&2)
3563  *  scsiclass,DDEE.vVVVVVVVV.pPPPPPPPPPPPPPPPP          (6 *1)
3564  *  scsiclass,DDFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP         (7 *2)
3565  *  scsiclass,DD.vVVVVVVVV.pPPPPPPPPPPPPPPPP            (8)
3566  *  scsa,DD.bBBBBBBBB                                   (8.5 *3)
3567  *  scsiclass,DDEEFFF                                   (9 *1&2)
3568  *  scsiclass,DDEE                                      (10 *1)
3569  *  scsiclass,DDFFF                                     (11 *2)
3570  *  scsiclass,DD                                        (12)
3571  *  scsa.fFFF                                           (12.5 *4)
3572  *  scsiclass                                           (13)
3573  *
3574  *        *1 only produced on a secondary function node
3575  *        *2 only produced when generic form-group flags exist.
3576  *        *3 only produced when binding-set form-group legacy support is needed
3577  *        *4 only produced when failover form-group flags exist.
3578  *
3579  *      where:
3580  *
3581  *      v                       is the letter 'v'. Denotest the
3582  *                              beginning of VVVVVVVV.
3583  *
3584  *      VVVVVVVV                Translated scsi_vendor.
3585  *
3586  *      p                       is the letter 'p'. Denotes the
3587  *                              beginning of PPPPPPPPPPPPPPPP.
3588  *
3589  *      PPPPPPPPPPPPPPPP        Translated scsi_product.
3590  *
3591  *      r                       is the letter 'r'. Denotes the
3592  *                              beginning of RRRR.
3593  *
3594  *      RRRR                    Translated scsi_revision.
3595  *
3596  *      DD                      is a two digit ASCII hexadecimal
3597  *                              number. The value of the two digits is
3598  *                              based one the SCSI "Peripheral device
3599  *                              type" command set associated with the
3600  *                              node. On a primary node this is the
3601  *                              scsi_dtype of the primary command set,
3602  *                              on a secondary node this is the
3603  *                              scsi_dtype associated with the secondary
3604  *                              function embedded command set.
3605  *
3606  *      EE                      Same encoding used for DD. This form is
3607  *                              only generated on secondary function
3608  *                              nodes. The DD secondary function is embedded
3609  *                              in an EE device.
3610  *
3611  *      FFF                     Concatenation, in alphabetical order,
3612  *                              of the flag characters within a form-group.
3613  *                              For a given form-group, the following
3614  *                              flags are defined.
3615  *
3616  *                              scsiclass: (generic form-group):
3617  *                                R     Removable_Media: Used when
3618  *                                      inq_rmb is set.
3619  *                                S     SAF-TE device: Used when
3620  *                                      inquiry information indicates
3621  *                                      SAF-TE devices.
3622  *
3623  *                              scsa.f: (failover form-group):
3624  *                                E     Explicit Target_Port_Group: Used
3625  *                                      when inq_tpgse is set and 'G' is
3626  *                                      alse present.
3627  *                                G     GUID: Used when a GUID can be
3628  *                                      generated for the device.
3629  *                                I     Implicit Target_Port_Group: Used
3630  *                                      when inq_tpgs is set and 'G' is
3631  *                                      also present.
3632  *
3633  *                              Forms using FFF are only be generated
3634  *                              if there are applicable flag
3635  *                              characters.
3636  *
3637  *      b                       is the letter 'b'. Denotes the
3638  *                              beginning of BBBBBBBB.
3639  *
3640  *      BBBBBBBB                Binding-set. Operating System Specific:
3641  *                              scsi-binding-set property of HBA.
3642  */
3643 #define NCOMPAT         (1 + (13 + 2) + 1)
3644 #define COMPAT_LONGEST  (strlen( \
3645         "scsiclass,DDEEFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR" + 1))
3646 
3647 /*
3648  * Private version with extra device 'identity' arguments to allow code
3649  * to determine GUID FFF support.
3650  */
3651 static void
3652 scsi_hba_ident_nodename_compatible_get(struct scsi_inquiry *inq,
3653     uchar_t *inq80, size_t inq80len, uchar_t *inq83, size_t inq83len,
3654     char *binding_set, int dtype_node, char *compat0,
3655     char **nodenamep, char **drivernamep,
3656     char ***compatiblep, int *ncompatiblep)
3657 {
3658         char            vid[sizeof (inq->inq_vid) + 1 ];
3659         char            pid[sizeof (inq->inq_pid) + 1];
3660         char            rev[sizeof (inq->inq_revision) + 1];
3661         char            gf[sizeof ("RS\0")];
3662         char            ff[sizeof ("EGI\0")];
3663         int             dtype_device;
3664         int             ncompat;                /* number of compatible */
3665         char            **compatp;              /* compatible ptrs */
3666         int             i;
3667         char            *nname;                 /* nodename */
3668         char            *dname;                 /* driver name */
3669         char            **csp;
3670         char            *p;
3671         int             tlen;
3672         int             len;
3673         major_t         major;
3674         ddi_devid_t     devid;
3675         char            *guid;
3676         uchar_t         *iqd = (uchar_t *)inq;
3677 
3678         /*
3679          * Nodename_aliases: This table was originally designed to be
3680          * implemented via a new nodename_aliases file - a peer to the
3681          * driver_aliases that selects a nodename based on compatible
3682          * forms in much the same say driver_aliases is used to select
3683          * driver bindings from compatible forms. Each compatible form
3684          * is an 'alias'. Until a more general need for a
3685          * nodename_aliases file exists, which may never occur, the
3686          * scsi mappings are described here via a compiled in table.
3687          *
3688          * This table contains nodename mappings for self-identifying
3689          * scsi devices enumerated by the Solaris kernel. For a given
3690          * device, the highest precedence "compatible" form with a
3691          * mapping is used to select the nodename for the device. This
3692          * will typically be a generic nodename, however in some legacy
3693          * compatibility cases a driver nodename mapping may be selected.
3694          *
3695          * Because of possible breakage associated with switching SCSI
3696          * target devices from driver nodenames to generic nodenames,
3697          * we are currently unable to support generic nodenames for all
3698          * SCSI devices (binding-sets). Although /devices paths are
3699          * defined as unstable, avoiding possible breakage is
3700          * important. Some of the newer SCSI transports (USB) already
3701          * use generic nodenames. All new SCSI transports and target
3702          * devices should use generic nodenames. At times this decision
3703          * may be architecture dependent (sparc .vs. intel) based on when
3704          * a transport was supported on a particular architecture.
3705          *
3706          * We provide a base set of generic nodename mappings based on
3707          * scsiclass dtype and higher-precedence driver nodename
3708          * mappings based on scsa "binding-set" to cover legacy
3709          * issues. The binding-set is typically associated with
3710          * "scsi-binding-set" property value of the HBA. The legacy
3711          * mappings are provided independent of whether the driver they
3712          * refer to is installed. This allows a correctly named node
3713          * be created at discovery time, and binding to occur when/if
3714          * an add_drv of the legacy driver occurs.
3715          *
3716          * We also have mappings for legacy SUN hardware that
3717          * misidentifies itself (enclosure services which identify
3718          * themselves as processors). All future hardware should use
3719          * the correct dtype.
3720          *
3721          * As SCSI HBAs are modified to use the SCSA interfaces for
3722          * self-identifying SCSI target devices (PSARC/2004/116) the
3723          * nodename_aliases table (PSARC/2004/420) should be augmented
3724          * with legacy mappings in order to maintain compatibility with
3725          * existing /devices paths, especially for devices that house
3726          * an OS. Failure to do this may cause upgrade problems.
3727          * Additions for new target devices or transports should not
3728          * add scsa binding-set compatible mappings.
3729          */
3730         static struct nodename_aliases {
3731                 char    *na_nodename;           /* nodename */
3732                 char    *na_alias;              /* compatible form match */
3733         } na[] = {
3734         /* # mapping to generic nodenames based on scsi dtype */
3735                 {"disk",                "scsiclass,00"},
3736                 {"tape",                "scsiclass,01"},
3737                 {"printer",             "scsiclass,02"},
3738                 {"processor",           "scsiclass,03"},
3739                 {"worm",                "scsiclass,04"},
3740                 {"cdrom",               "scsiclass,05"},
3741                 {"scanner",             "scsiclass,06"},
3742                 {"optical-disk",        "scsiclass,07"},
3743                 {"medium-changer",      "scsiclass,08"},
3744                 {"obsolete",            "scsiclass,09"},
3745                 {"prepress-a",          "scsiclass,0a"},
3746                 {"prepress-b",          "scsiclass,0b"},
3747                 {"array-controller",    "scsiclass,0c"},
3748                 {"enclosure",           "scsiclass,0d"},
3749                 {"disk",                "scsiclass,0e"},
3750                 {"card-reader",         "scsiclass,0f"},
3751                 {"bridge",              "scsiclass,10"},
3752                 {"object-store",        "scsiclass,11"},
3753                 {"reserved",            "scsiclass,12"},
3754                 {"reserved",            "scsiclass,13"},
3755                 {"reserved",            "scsiclass,14"},
3756                 {"reserved",            "scsiclass,15"},
3757                 {"reserved",            "scsiclass,16"},
3758                 {"reserved",            "scsiclass,17"},
3759                 {"reserved",            "scsiclass,18"},
3760                 {"reserved",            "scsiclass,19"},
3761                 {"reserved",            "scsiclass,1a"},
3762                 {"reserved",            "scsiclass,1b"},
3763                 {"reserved",            "scsiclass,1c"},
3764                 {"reserved",            "scsiclass,1d"},
3765                 {"well-known-lun",      "scsiclass,1e"},
3766                 {"unknown",             "scsiclass,1f"},
3767 
3768 #ifdef  sparc
3769         /* # legacy mapping to driver nodenames for fcp binding-set */
3770                 {"ssd",                 "scsa,00.bfcp"},
3771                 {"st",                  "scsa,01.bfcp"},
3772                 {"sgen",                "scsa,08.bfcp"},
3773                 {"ses",                 "scsa,0d.bfcp"},
3774 
3775         /* # legacy mapping to driver nodenames for vhci binding-set */
3776                 {"ssd",                 "scsa,00.bvhci"},
3777                 {"st",                  "scsa,01.bvhci"},
3778                 {"sgen",                "scsa,08.bvhci"},
3779                 {"ses",                 "scsa,0d.bvhci"},
3780 #else   /* sparc */
3781         /* # for x86 fcp and vhci use generic nodenames */
3782 #endif  /* sparc */
3783 
3784         /* # legacy mapping to driver nodenames for spi binding-set */
3785                 {"sd",                  "scsa,00.bspi"},
3786                 {"sd",                  "scsa,05.bspi"},
3787                 {"sd",                  "scsa,07.bspi"},
3788                 {"st",                  "scsa,01.bspi"},
3789                 {"ses",                 "scsa,0d.bspi"},
3790 
3791         /* #                            SUN misidentified spi hardware */
3792                 {"ses",                 "scsiclass,03.vSUN.pD2"},
3793                 {"ses",                 "scsiclass,03.vSYMBIOS.pD1000"},
3794 
3795         /* # legacy mapping to driver nodenames for atapi binding-set */
3796                 {"sd",                  "scsa,00.batapi"},
3797                 {"sd",                  "scsa,05.batapi"},
3798                 {"sd",                  "scsa,07.batapi"},
3799                 {"st",                  "scsa,01.batapi"},
3800                 {"unknown",             "scsa,0d.batapi"},
3801 
3802         /* # legacy mapping to generic nodenames for usb binding-set */
3803                 {"disk",                "scsa,05.busb"},
3804                 {"disk",                "scsa,07.busb"},
3805                 {"changer",             "scsa,08.busb"},
3806                 {"comm",                "scsa,09.busb"},
3807                 {"array_ctlr",          "scsa,0c.busb"},
3808                 {"esi",                 "scsa,0d.busb"},
3809 
3810         /*
3811          * mapping nodenames for mpt based on scsi dtype
3812          * for being compatible with the original node names
3813          * under mpt controller
3814          */
3815                 {"sd",                  "scsa,00.bmpt"},
3816                 {"sd",                  "scsa,05.bmpt"},
3817                 {"sd",                  "scsa,07.bmpt"},
3818                 {"st",                  "scsa,01.bmpt"},
3819                 {"ses",                 "scsa,0d.bmpt"},
3820                 {"sgen",                "scsa,08.bmpt"},
3821                 {NULL,          NULL}
3822         };
3823         struct nodename_aliases *nap;
3824 
3825         /* NOTE: drivernamep can be NULL */
3826         ASSERT(nodenamep && compatiblep && ncompatiblep &&
3827             (binding_set == NULL || (strlen(binding_set) <= 8)));
3828         if ((nodenamep == NULL) || (compatiblep == NULL) ||
3829             (ncompatiblep == NULL))
3830                 return;
3831 
3832         /*
3833          * In order to reduce runtime we allocate one block of memory that
3834          * contains both the NULL terminated array of pointers to compatible
3835          * forms and the individual compatible strings. This block is
3836          * somewhat larger than needed, but is short lived - it only exists
3837          * until the caller can transfer the information into the "compatible"
3838          * string array property and call scsi_hba_nodename_compatible_free.
3839          */
3840         tlen = NCOMPAT * COMPAT_LONGEST;
3841         compatp = kmem_alloc((NCOMPAT * sizeof (char *)) + tlen, KM_SLEEP);
3842 
3843         /* convert inquiry data from SCSI ASCII to 1275 string */
3844         (void) string_scsi_to_1275(vid, inq->inq_vid,
3845             sizeof (inq->inq_vid));
3846         (void) string_scsi_to_1275(pid, inq->inq_pid,
3847             sizeof (inq->inq_pid));
3848         (void) string_scsi_to_1275(rev, inq->inq_revision,
3849             sizeof (inq->inq_revision));
3850         ASSERT((strlen(vid) <= sizeof (inq->inq_vid)) &&
3851             (strlen(pid) <= sizeof (inq->inq_pid)) &&
3852             (strlen(rev) <= sizeof (inq->inq_revision)));
3853 
3854         /*
3855          * Form flags in ***ALPHABETICAL*** order within form-group:
3856          *
3857          * NOTE: When adding a new flag to an existing form-group, careful
3858          * consideration must be given to not breaking existing bindings
3859          * based on that form-group.
3860          */
3861 
3862         /*
3863          * generic form-group flags
3864          *   R  removable:
3865          *      Set when inq_rmb is set and for well known scsi dtypes. For a
3866          *      bus where the entire device is removable (like USB), we expect
3867          *      the HBA to intercept the inquiry data and set inq_rmb.
3868          *      Since OBP does not distinguish removable media in its generic
3869          *      name selection we avoid setting the 'R' flag if the root is not
3870          *      yet mounted.
3871          *   S  SAF-TE device
3872          *      Set when the device type is SAT-TE.
3873          */
3874         i = 0;
3875         dtype_device = inq->inq_dtype & DTYPE_MASK;
3876         if (modrootloaded && (inq->inq_rmb ||
3877             (dtype_device == DTYPE_WORM) ||
3878             (dtype_device == DTYPE_RODIRECT) ||
3879             (dtype_device == DTYPE_OPTICAL)))
3880                 gf[i++] = 'R';                  /* removable */
3881         gf[i] = '\0';
3882 
3883         if (modrootloaded &&
3884             (dtype_device == DTYPE_PROCESSOR) &&
3885             (strncmp((char *)&iqd[44], "SAF-TE", 4) == 0))
3886                 gf[i++] = 'S';
3887         gf[i] = '\0';
3888 
3889         /*
3890          * failover form-group flags
3891          *   E  Explicit Target_Port_Group_Supported:
3892          *      Set for a device that has a GUID if inq_tpgse also set.
3893          *   G  GUID:
3894          *      Set when we have identity information, can determine a devid
3895          *      from the identity information, and can generate a guid from
3896          *      that devid.
3897          *   I  Implicit Target_Port_Group_Supported:
3898          *      Set for a device that has a GUID if inq_tpgs also set.
3899          */
3900         i = 0;
3901         if ((inq80 || inq83) &&
3902             (ddi_devid_scsi_encode(DEVID_SCSI_ENCODE_VERSION_LATEST, NULL,
3903             (uchar_t *)inq, sizeof (*inq), inq80, inq80len, inq83, inq83len,
3904             &devid) == DDI_SUCCESS)) {
3905                 guid = ddi_devid_to_guid(devid);
3906                 ddi_devid_free(devid);
3907         } else
3908                 guid = NULL;
3909         if (guid && (inq->inq_tpgs & TPGS_FAILOVER_EXPLICIT))
3910                 ff[i++] = 'E';                  /* EXPLICIT TPGS */
3911         if (guid)
3912                 ff[i++] = 'G';                  /* GUID */
3913         if (guid && (inq->inq_tpgs & TPGS_FAILOVER_IMPLICIT))
3914                 ff[i++] = 'I';                  /* IMPLICIT TPGS */
3915         ff[i] = '\0';
3916         if (guid)
3917                 ddi_devid_free_guid(guid);
3918 
3919         /*
3920          * Construct all applicable compatible forms. See comment at the
3921          * head of the function for a description of the compatible forms.
3922          */
3923         csp = compatp;
3924         p = (char *)(compatp + NCOMPAT);
3925 
3926         /* ( 0) driver (optional, not documented in scsi(4)) */
3927         if (compat0) {
3928                 *csp++ = p;
3929                 (void) snprintf(p, tlen, "%s", compat0);
3930                 len = strlen(p) + 1;
3931                 p += len;
3932                 tlen -= len;
3933         }
3934 
3935         /* ( 1) scsiclass,DDEEFFF.vV.pP.rR */
3936         if ((dtype_device != dtype_node) && *gf && *vid && *pid && *rev) {
3937                 *csp++ = p;
3938                 (void) snprintf(p, tlen, "scsiclass,%02x%02x%s.v%s.p%s.r%s",
3939                     dtype_node, dtype_device, gf, vid, pid, rev);
3940                 len = strlen(p) + 1;
3941                 p += len;
3942                 tlen -= len;
3943         }
3944 
3945         /* ( 2) scsiclass,DDEE.vV.pP.rR */
3946         if ((dtype_device != dtype_node) && *vid && *pid && *rev) {
3947                 *csp++ = p;
3948                 (void) snprintf(p, tlen, "scsiclass,%02x%02x.v%s.p%s.r%s",
3949                     dtype_node, dtype_device, vid, pid, rev);
3950                 len = strlen(p) + 1;
3951                 p += len;
3952                 tlen -= len;
3953         }
3954 
3955         /* ( 3) scsiclass,DDFFF.vV.pP.rR */
3956         if (*gf && *vid && *pid && *rev) {
3957                 *csp++ = p;
3958                 (void) snprintf(p, tlen, "scsiclass,%02x%s.v%s.p%s.r%s",
3959                     dtype_node, gf, vid, pid, rev);
3960                 len = strlen(p) + 1;
3961                 p += len;
3962                 tlen -= len;
3963         }
3964 
3965         /* ( 4) scsiclass,DD.vV.pP.rR */
3966         if (*vid && *pid && *rev) {
3967                 *csp++ = p;
3968                 (void) snprintf(p, tlen, "scsiclass,%02x.v%s.p%s.r%s",
3969                     dtype_node, vid, pid, rev);
3970                 len = strlen(p) + 1;
3971                 p += len;
3972                 tlen -= len;
3973         }
3974 
3975         /* ( 5) scsiclass,DDEEFFF.vV.pP */
3976         if ((dtype_device != dtype_node) && *gf && *vid && *pid) {
3977                 *csp++ = p;
3978                 (void) snprintf(p, tlen, "scsiclass,%02x%02x%s.v%s.p%s",
3979                     dtype_node, dtype_device, gf, vid, pid);
3980                 len = strlen(p) + 1;
3981                 p += len;
3982                 tlen -= len;
3983         }
3984 
3985         /* ( 6) scsiclass,DDEE.vV.pP */
3986         if ((dtype_device != dtype_node) && *vid && *pid) {
3987                 *csp++ = p;
3988                 (void) snprintf(p, tlen, "scsiclass,%02x%02x.v%s.p%s",
3989                     dtype_node, dtype_device, vid, pid);
3990                 len = strlen(p) + 1;
3991                 p += len;
3992                 tlen -= len;
3993         }
3994 
3995         /* ( 7) scsiclass,DDFFF.vV.pP */
3996         if (*gf && *vid && *pid) {
3997                 *csp++ = p;
3998                 (void) snprintf(p, tlen, "scsiclass,%02x%s.v%s.p%s",
3999                     dtype_node, gf, vid, pid);
4000                 len = strlen(p) + 1;
4001                 p += len;
4002                 tlen -= len;
4003         }
4004 
4005         /* ( 8) scsiclass,DD.vV.pP */
4006         if (*vid && *pid) {
4007                 *csp++ = p;
4008                 (void) snprintf(p, tlen, "scsiclass,%02x.v%s.p%s",
4009                     dtype_node, vid, pid);
4010                 len = strlen(p) + 1;
4011                 p += len;
4012                 tlen -= len;
4013         }
4014 
4015         /* (8.5) scsa,DD.bB (not documented in scsi(4)) */
4016         if (binding_set) {
4017                 *csp++ = p;
4018                 (void) snprintf(p, tlen, "scsa,%02x.b%s",
4019                     dtype_node, binding_set);
4020                 len = strlen(p) + 1;
4021                 p += len;
4022                 tlen -= len;
4023         }
4024 
4025         /* ( 9) scsiclass,DDEEFFF */
4026         if ((dtype_device != dtype_node) && *gf) {
4027                 *csp++ = p;
4028                 (void) snprintf(p, tlen, "scsiclass,%02x%02x%s",
4029                     dtype_node, dtype_device, gf);
4030                 len = strlen(p) + 1;
4031                 p += len;
4032                 tlen -= len;
4033         }
4034 
4035         /* (10) scsiclass,DDEE */
4036         if (dtype_device != dtype_node) {
4037                 *csp++ = p;
4038                 (void) snprintf(p, tlen, "scsiclass,%02x%02x",
4039                     dtype_node, dtype_device);
4040                 len = strlen(p) + 1;
4041                 p += len;
4042                 tlen -= len;
4043         }
4044 
4045         /* (11) scsiclass,DDFFF */
4046         if (*gf) {
4047                 *csp++ = p;
4048                 (void) snprintf(p, tlen, "scsiclass,%02x%s",
4049                     dtype_node, gf);
4050                 len = strlen(p) + 1;
4051                 p += len;
4052                 tlen -= len;
4053         }
4054 
4055         /* (12) scsiclass,DD */
4056         *csp++ = p;
4057         (void) snprintf(p, tlen, "scsiclass,%02x", dtype_node);
4058         len = strlen(p) + 1;
4059         p += len;
4060         tlen -= len;
4061 
4062         /* (12.5) scsa.fFFF */
4063         if (*ff) {
4064                 *csp++ = p;
4065                 (void) snprintf(p, tlen, "scsa.f%s", ff);
4066                 len = strlen(p) + 1;
4067                 p += len;
4068                 tlen -= len;
4069         }
4070 
4071         /* (13) scsiclass */
4072         *csp++ = p;
4073         (void) snprintf(p, tlen, "scsiclass");
4074         len = strlen(p) + 1;
4075         p += len;
4076         tlen -= len;
4077         ASSERT(tlen >= 0);
4078 
4079         *csp = NULL;                    /* NULL terminate array of pointers */
4080         ncompat = csp - compatp;
4081 
4082         /*
4083          * When determining a nodename, a nodename_aliases specified
4084          * mapping has precedence over using a driver_aliases specified
4085          * driver binding as a nodename.
4086          *
4087          * See if any of the compatible forms have a nodename_aliases
4088          * specified nodename. These mappings are described by
4089          * nodename_aliases entries like:
4090          *
4091          *      disk            "scsiclass,00"
4092          *      enclosure       "scsiclass,03.vSYMBIOS.pD1000"
4093          *      ssd             "scsa,00.bfcp"
4094          *
4095          * All nodename_aliases mappings should idealy be to generic
4096          * names, however a higher precedence legacy mapping to a
4097          * driver name may exist. The highest precedence mapping
4098          * provides the nodename, so legacy driver nodename mappings
4099          * (if they exist) take precedence over generic nodename
4100          * mappings.
4101          */
4102         for (nname = NULL, csp = compatp; (nname == NULL) && *csp; csp++) {
4103                 for (nap = na; nap->na_nodename; nap++) {
4104                         if (strcmp(*csp, nap->na_alias) == 0) {
4105                                 nname = nap->na_nodename;
4106                                 break;
4107                         }
4108                 }
4109         }
4110 
4111         /*
4112          * Determine the driver name based on compatible (which may
4113          * have the passed in compat0 as the first item). The driver_aliases
4114          * file has entries like
4115          *
4116          *      sd      "scsiclass,00"
4117          *
4118          * that map compatible forms to specific drivers. These entries are
4119          * established by add_drv/update_drv. We use the most specific
4120          * driver binding as the nodename. This matches the eventual
4121          * ddi_driver_compatible_major() binding that will be
4122          * established by bind_node()
4123          */
4124         for (dname = NULL, csp = compatp; *csp; csp++) {
4125                 major = ddi_name_to_major(*csp);
4126                 if ((major == DDI_MAJOR_T_NONE) ||
4127                     (devnamesp[major].dn_flags & DN_DRIVER_REMOVED))
4128                         continue;
4129                 if (dname = ddi_major_to_name(major))
4130                         break;
4131         }
4132 
4133         /*
4134          * If no nodename_aliases mapping exists then use the
4135          * driver_aliases specified driver binding as a nodename.
4136          */
4137         if (nname == NULL)
4138                 nname = dname;
4139 
4140         /* return results */
4141         if (nname) {
4142                 *nodenamep = kmem_alloc(strlen(nname) + 1, KM_SLEEP);
4143                 (void) strcpy(*nodenamep, nname);
4144         } else {
4145                 *nodenamep = NULL;
4146 
4147                 /*
4148                  * If no nodename could be determined return a special
4149                  * 'compatible' to be used for a diagnostic message. This
4150                  * compatible contains all compatible forms concatenated
4151                  * into a single string pointed to by the first element.
4152                  */
4153                 for (csp = compatp; *(csp + 1); csp++)
4154                         *((*csp) + strlen(*csp)) = ' ';
4155                 *(compatp + 1) = NULL;
4156                 ncompat = 1;
4157 
4158         }
4159         if (drivernamep) {
4160                 if (dname) {
4161                         *drivernamep = kmem_alloc(strlen(dname) + 1, KM_SLEEP);
4162                         (void) strcpy(*drivernamep, dname);
4163                 } else
4164                         *drivernamep = NULL;
4165         }
4166         *compatiblep = compatp;
4167         *ncompatiblep = ncompat;
4168 }
4169 
4170 /*
4171  * Free allocations associated with scsi_hba_ident_nodename_compatible_get.
4172  */
4173 static void
4174 scsi_hba_ident_nodename_compatible_free(char *nodename, char *drivername,
4175     char **compatible)
4176 {
4177         if (nodename)
4178                 kmem_free(nodename, strlen(nodename) + 1);
4179         if (drivername)
4180                 kmem_free(drivername, strlen(drivername) + 1);
4181         if (compatible)
4182                 kmem_free(compatible, (NCOMPAT * sizeof (char *)) +
4183                     (NCOMPAT * COMPAT_LONGEST));
4184 }
4185 
4186 void
4187 scsi_hba_nodename_compatible_get(struct scsi_inquiry *inq,
4188     char *binding_set, int dtype_node, char *compat0,
4189     char **nodenamep, char ***compatiblep, int *ncompatiblep)
4190 {
4191         scsi_hba_ident_nodename_compatible_get(inq,
4192             NULL, 0, NULL, 0, binding_set, dtype_node, compat0, nodenamep,
4193             NULL, compatiblep, ncompatiblep);
4194 }
4195 
4196 void
4197 scsi_hba_nodename_compatible_free(char *nodename, char **compatible)
4198 {
4199         scsi_hba_ident_nodename_compatible_free(nodename, NULL, compatible);
4200 }
4201 
4202 /* return the unit_address associated with a scsi_device */
4203 char *
4204 scsi_device_unit_address(struct scsi_device *sd)
4205 {
4206         mdi_pathinfo_t  *pip;
4207 
4208         ASSERT(sd && sd->sd_dev);
4209         if ((sd == NULL) || (sd->sd_dev == NULL))
4210                 return (NULL);
4211 
4212         pip = (mdi_pathinfo_t *)sd->sd_pathinfo;
4213         if (pip)
4214                 return (mdi_pi_get_addr(pip));
4215         else
4216                 return (ddi_get_name_addr(sd->sd_dev));
4217 }
4218 
4219 /* scsi_device property interfaces */
4220 #define _TYPE_DEFINED(flags)                                            \
4221         (((flags & SCSI_DEVICE_PROP_TYPE_MSK) == SCSI_DEVICE_PROP_PATH) || \
4222         ((flags & SCSI_DEVICE_PROP_TYPE_MSK) == SCSI_DEVICE_PROP_DEVICE))
4223 
4224 #define _DEVICE_PIP(sd, flags)                                          \
4225         ((((flags & SCSI_DEVICE_PROP_TYPE_MSK) == SCSI_DEVICE_PROP_PATH) && \
4226         sd->sd_pathinfo) ? (mdi_pathinfo_t *)sd->sd_pathinfo : NULL)
4227 
4228 int
4229 scsi_device_prop_get_int(struct scsi_device *sd, uint_t flags,
4230     char *name, int defval)
4231 {
4232         mdi_pathinfo_t  *pip;
4233         int             v = defval;
4234         int             data;
4235         int             rv;
4236 
4237         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4238         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4239             !_TYPE_DEFINED(flags))
4240                 return (v);
4241 
4242         pip = _DEVICE_PIP(sd, flags);
4243         if (pip) {
4244                 rv = mdi_prop_lookup_int(pip, name, &data);
4245                 if (rv == DDI_PROP_SUCCESS)
4246                         v = data;
4247         } else
4248                 v = ddi_prop_get_int(DDI_DEV_T_ANY, sd->sd_dev,
4249                     DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, name, v);
4250         return (v);
4251 }
4252 
4253 
4254 int64_t
4255 scsi_device_prop_get_int64(struct scsi_device *sd, uint_t flags,
4256     char *name, int64_t defval)
4257 {
4258         mdi_pathinfo_t  *pip;
4259         int64_t         v = defval;
4260         int64_t         data;
4261         int             rv;
4262 
4263         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4264         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4265             !_TYPE_DEFINED(flags))
4266                 return (v);
4267 
4268         pip = _DEVICE_PIP(sd, flags);
4269         if (pip) {
4270                 rv = mdi_prop_lookup_int64(pip, name, &data);
4271                 if (rv == DDI_PROP_SUCCESS)
4272                         v = data;
4273         } else
4274                 v = ddi_prop_get_int64(DDI_DEV_T_ANY, sd->sd_dev,
4275                     DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, name, v);
4276         return (v);
4277 }
4278 
4279 int
4280 scsi_device_prop_lookup_byte_array(struct scsi_device *sd, uint_t flags,
4281     char *name, uchar_t **data, uint_t *nelements)
4282 {
4283         mdi_pathinfo_t  *pip;
4284         int             rv;
4285 
4286         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4287         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4288             !_TYPE_DEFINED(flags))
4289                 return (DDI_PROP_INVAL_ARG);
4290 
4291         pip = _DEVICE_PIP(sd, flags);
4292         if (pip)
4293                 rv = mdi_prop_lookup_byte_array(pip, name, data, nelements);
4294         else
4295                 rv = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, sd->sd_dev,
4296                     DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4297                     name, data, nelements);
4298         return (rv);
4299 }
4300 
4301 int
4302 scsi_device_prop_lookup_int_array(struct scsi_device *sd, uint_t flags,
4303     char *name, int **data, uint_t *nelements)
4304 {
4305         mdi_pathinfo_t  *pip;
4306         int             rv;
4307 
4308         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4309         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4310             !_TYPE_DEFINED(flags))
4311                 return (DDI_PROP_INVAL_ARG);
4312 
4313         pip = _DEVICE_PIP(sd, flags);
4314         if (pip)
4315                 rv = mdi_prop_lookup_int_array(pip, name, data, nelements);
4316         else
4317                 rv = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, sd->sd_dev,
4318                     DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4319                     name, data, nelements);
4320         return (rv);
4321 }
4322 
4323 
4324 int
4325 scsi_device_prop_lookup_string(struct scsi_device *sd, uint_t flags,
4326     char *name, char **data)
4327 {
4328         mdi_pathinfo_t  *pip;
4329         int             rv;
4330 
4331         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4332         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4333             !_TYPE_DEFINED(flags))
4334                 return (DDI_PROP_INVAL_ARG);
4335 
4336         pip = _DEVICE_PIP(sd, flags);
4337         if (pip)
4338                 rv = mdi_prop_lookup_string(pip, name, data);
4339         else
4340                 rv = ddi_prop_lookup_string(DDI_DEV_T_ANY, sd->sd_dev,
4341                     DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4342                     name, data);
4343         return (rv);
4344 }
4345 
4346 int
4347 scsi_device_prop_lookup_string_array(struct scsi_device *sd, uint_t flags,
4348     char *name, char ***data, uint_t *nelements)
4349 {
4350         mdi_pathinfo_t  *pip;
4351         int             rv;
4352 
4353         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4354         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4355             !_TYPE_DEFINED(flags))
4356                 return (DDI_PROP_INVAL_ARG);
4357 
4358         pip = _DEVICE_PIP(sd, flags);
4359         if (pip)
4360                 rv = mdi_prop_lookup_string_array(pip, name, data, nelements);
4361         else
4362                 rv = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, sd->sd_dev,
4363                     DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4364                     name, data, nelements);
4365         return (rv);
4366 }
4367 
4368 int
4369 scsi_device_prop_update_byte_array(struct scsi_device *sd, uint_t flags,
4370     char *name, uchar_t *data, uint_t nelements)
4371 {
4372         mdi_pathinfo_t  *pip;
4373         int             rv;
4374 
4375         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4376         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4377             !_TYPE_DEFINED(flags))
4378                 return (DDI_PROP_INVAL_ARG);
4379 
4380         pip = _DEVICE_PIP(sd, flags);
4381         if (pip)
4382                 rv = mdi_prop_update_byte_array(pip, name, data, nelements);
4383         else
4384                 rv = ndi_prop_update_byte_array(DDI_DEV_T_NONE, sd->sd_dev,
4385                     name, data, nelements);
4386         return (rv);
4387 }
4388 
4389 int
4390 scsi_device_prop_update_int(struct scsi_device *sd, uint_t flags,
4391     char *name, int data)
4392 {
4393         mdi_pathinfo_t  *pip;
4394         int             rv;
4395 
4396         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4397         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4398             !_TYPE_DEFINED(flags))
4399                 return (DDI_PROP_INVAL_ARG);
4400 
4401         pip = _DEVICE_PIP(sd, flags);
4402         if (pip)
4403                 rv = mdi_prop_update_int(pip, name, data);
4404         else
4405                 rv = ndi_prop_update_int(DDI_DEV_T_NONE, sd->sd_dev,
4406                     name, data);
4407         return (rv);
4408 }
4409 
4410 int
4411 scsi_device_prop_update_int64(struct scsi_device *sd, uint_t flags,
4412     char *name, int64_t data)
4413 {
4414         mdi_pathinfo_t  *pip;
4415         int             rv;
4416 
4417         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4418         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4419             !_TYPE_DEFINED(flags))
4420                 return (DDI_PROP_INVAL_ARG);
4421 
4422         pip = _DEVICE_PIP(sd, flags);
4423         if (pip)
4424                 rv = mdi_prop_update_int64(pip, name, data);
4425         else
4426                 rv = ndi_prop_update_int64(DDI_DEV_T_NONE, sd->sd_dev,
4427                     name, data);
4428         return (rv);
4429 }
4430 
4431 int
4432 scsi_device_prop_update_int_array(struct scsi_device *sd, uint_t flags,
4433     char *name, int *data, uint_t nelements)
4434 {
4435         mdi_pathinfo_t  *pip;
4436         int             rv;
4437 
4438         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4439         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4440             !_TYPE_DEFINED(flags))
4441                 return (DDI_PROP_INVAL_ARG);
4442 
4443         pip = _DEVICE_PIP(sd, flags);
4444         if (pip)
4445                 rv = mdi_prop_update_int_array(pip, name, data, nelements);
4446         else
4447                 rv = ndi_prop_update_int_array(DDI_DEV_T_NONE, sd->sd_dev,
4448                     name, data, nelements);
4449         return (rv);
4450 }
4451 
4452 int
4453 scsi_device_prop_update_string(struct scsi_device *sd, uint_t flags,
4454     char *name, char *data)
4455 {
4456         mdi_pathinfo_t  *pip;
4457         int             rv;
4458 
4459         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4460         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4461             !_TYPE_DEFINED(flags))
4462                 return (DDI_PROP_INVAL_ARG);
4463 
4464         pip = _DEVICE_PIP(sd, flags);
4465         if (pip)
4466                 rv = mdi_prop_update_string(pip, name, data);
4467         else
4468                 rv = ndi_prop_update_string(DDI_DEV_T_NONE, sd->sd_dev,
4469                     name, data);
4470         return (rv);
4471 }
4472 
4473 int
4474 scsi_device_prop_update_string_array(struct scsi_device *sd, uint_t flags,
4475     char *name, char **data, uint_t nelements)
4476 {
4477         mdi_pathinfo_t  *pip;
4478         int             rv;
4479 
4480         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4481         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4482             !_TYPE_DEFINED(flags))
4483                 return (DDI_PROP_INVAL_ARG);
4484 
4485         pip = _DEVICE_PIP(sd, flags);
4486         if (pip)
4487                 rv = mdi_prop_update_string_array(pip, name, data, nelements);
4488         else
4489                 rv = ndi_prop_update_string_array(DDI_DEV_T_NONE, sd->sd_dev,
4490                     name, data, nelements);
4491         return (rv);
4492 }
4493 
4494 int
4495 scsi_device_prop_remove(struct scsi_device *sd, uint_t flags, char *name)
4496 {
4497         mdi_pathinfo_t  *pip;
4498         int             rv;
4499 
4500         ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
4501         if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
4502             !_TYPE_DEFINED(flags))
4503                 return (DDI_PROP_INVAL_ARG);
4504 
4505         pip = _DEVICE_PIP(sd, flags);
4506         if (pip)
4507                 rv = mdi_prop_remove(pip, name);
4508         else
4509                 rv = ndi_prop_remove(DDI_DEV_T_NONE, sd->sd_dev, name);
4510         return (rv);
4511 }
4512 
4513 void
4514 scsi_device_prop_free(struct scsi_device *sd, uint_t flags, void *data)
4515 {
4516         mdi_pathinfo_t  *pip;
4517 
4518         ASSERT(sd && data && sd->sd_dev && _TYPE_DEFINED(flags));
4519         if ((sd == NULL) || (data == NULL) || (sd->sd_dev == NULL) ||
4520             !_TYPE_DEFINED(flags))
4521                 return;
4522 
4523         pip = _DEVICE_PIP(sd, flags);
4524         if (pip)
4525                 (void) mdi_prop_free(data);
4526         else
4527                 ddi_prop_free(data);
4528 }
4529 
4530 /* SMP device property interfaces */
4531 int
4532 smp_device_prop_get_int(struct smp_device *smp_sd, char *name, int defval)
4533 {
4534         int             v = defval;
4535 
4536         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4537         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4538                 return (v);
4539 
4540         v = ddi_prop_get_int(DDI_DEV_T_ANY, smp_sd->smp_sd_dev,
4541             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, name, v);
4542         return (v);
4543 }
4544 
4545 
4546 int64_t
4547 smp_device_prop_get_int64(struct smp_device *smp_sd, char *name, int64_t defval)
4548 {
4549         int64_t         v = defval;
4550 
4551         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4552         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4553                 return (v);
4554 
4555         v = ddi_prop_get_int64(DDI_DEV_T_ANY, smp_sd->smp_sd_dev,
4556             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, name, v);
4557         return (v);
4558 }
4559 
4560 int
4561 smp_device_prop_lookup_byte_array(struct smp_device *smp_sd, char *name,
4562     uchar_t **data, uint_t *nelements)
4563 {
4564         int             rv;
4565 
4566         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4567         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4568                 return (DDI_PROP_INVAL_ARG);
4569 
4570         rv = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, smp_sd->smp_sd_dev,
4571             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4572             name, data, nelements);
4573         return (rv);
4574 }
4575 
4576 int
4577 smp_device_prop_lookup_int_array(struct smp_device *smp_sd, char *name,
4578     int **data, uint_t *nelements)
4579 {
4580         int             rv;
4581 
4582         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4583         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4584                 return (DDI_PROP_INVAL_ARG);
4585 
4586         rv = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, smp_sd->smp_sd_dev,
4587             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4588             name, data, nelements);
4589         return (rv);
4590 }
4591 
4592 
4593 int
4594 smp_device_prop_lookup_string(struct smp_device *smp_sd, char *name,
4595     char **data)
4596 {
4597         int             rv;
4598 
4599         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4600         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4601                 return (DDI_PROP_INVAL_ARG);
4602 
4603         rv = ddi_prop_lookup_string(DDI_DEV_T_ANY, smp_sd->smp_sd_dev,
4604             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4605             name, data);
4606         return (rv);
4607 }
4608 
4609 int
4610 smp_device_prop_lookup_string_array(struct smp_device *smp_sd, char *name,
4611     char ***data, uint_t *nelements)
4612 {
4613         int             rv;
4614 
4615         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4616         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4617                 return (DDI_PROP_INVAL_ARG);
4618 
4619         rv = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, smp_sd->smp_sd_dev,
4620             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
4621             name, data, nelements);
4622         return (rv);
4623 }
4624 
4625 int
4626 smp_device_prop_update_byte_array(struct smp_device *smp_sd, char *name,
4627     uchar_t *data, uint_t nelements)
4628 {
4629         int             rv;
4630 
4631         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4632         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4633                 return (DDI_PROP_INVAL_ARG);
4634 
4635         rv = ndi_prop_update_byte_array(DDI_DEV_T_NONE, smp_sd->smp_sd_dev,
4636             name, data, nelements);
4637         return (rv);
4638 }
4639 
4640 int
4641 smp_device_prop_update_int(struct smp_device *smp_sd, char *name, int data)
4642 {
4643         int             rv;
4644 
4645         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4646         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4647                 return (DDI_PROP_INVAL_ARG);
4648 
4649         rv = ndi_prop_update_int(DDI_DEV_T_NONE, smp_sd->smp_sd_dev,
4650             name, data);
4651         return (rv);
4652 }
4653 
4654 int
4655 smp_device_prop_update_int64(struct smp_device *smp_sd, char *name,
4656     int64_t data)
4657 {
4658         int             rv;
4659 
4660         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4661         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4662                 return (DDI_PROP_INVAL_ARG);
4663 
4664         rv = ndi_prop_update_int64(DDI_DEV_T_NONE, smp_sd->smp_sd_dev,
4665             name, data);
4666         return (rv);
4667 }
4668 
4669 int
4670 smp_device_prop_update_int_array(struct smp_device *smp_sd, char *name,
4671     int *data, uint_t nelements)
4672 {
4673         int             rv;
4674 
4675         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4676         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4677                 return (DDI_PROP_INVAL_ARG);
4678 
4679         rv = ndi_prop_update_int_array(DDI_DEV_T_NONE, smp_sd->smp_sd_dev,
4680             name, data, nelements);
4681         return (rv);
4682 }
4683 
4684 int
4685 smp_device_prop_update_string(struct smp_device *smp_sd, char *name, char *data)
4686 {
4687         int             rv;
4688 
4689         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4690         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4691                 return (DDI_PROP_INVAL_ARG);
4692 
4693         rv = ndi_prop_update_string(DDI_DEV_T_NONE, smp_sd->smp_sd_dev,
4694             name, data);
4695         return (rv);
4696 }
4697 
4698 int
4699 smp_device_prop_update_string_array(struct smp_device *smp_sd, char *name,
4700     char **data, uint_t nelements)
4701 {
4702         int             rv;
4703 
4704         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4705         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4706                 return (DDI_PROP_INVAL_ARG);
4707 
4708         rv = ndi_prop_update_string_array(DDI_DEV_T_NONE, smp_sd->smp_sd_dev,
4709             name, data, nelements);
4710         return (rv);
4711 }
4712 
4713 int
4714 smp_device_prop_remove(struct smp_device *smp_sd, char *name)
4715 {
4716         int             rv;
4717 
4718         ASSERT(smp_sd && name && smp_sd->smp_sd_dev);
4719         if ((smp_sd == NULL) || (name == NULL) || (smp_sd->smp_sd_dev == NULL))
4720                 return (DDI_PROP_INVAL_ARG);
4721 
4722         rv = ndi_prop_remove(DDI_DEV_T_NONE, smp_sd->smp_sd_dev, name);
4723         return (rv);
4724 }
4725 
4726 void
4727 smp_device_prop_free(struct smp_device *smp_sd, void *data)
4728 {
4729         ASSERT(smp_sd && data && smp_sd->smp_sd_dev);
4730         if ((smp_sd == NULL) || (data == NULL) || (smp_sd->smp_sd_dev == NULL))
4731                 return;
4732 
4733         ddi_prop_free(data);
4734 }
4735 
4736 /*
4737  * scsi_hba_ua_set: given "unit-address" string, set properties.
4738  *
4739  * Function to set the properties on a devinfo or pathinfo node from
4740  * the "unit-address" part of a "name@unit-address" /devices path 'name'
4741  * string.
4742  *
4743  * This function works in conjunction with scsi_ua_get()/scsi_hba_ua_get()
4744  * (and possibly with an HBA driver's tran_tgt_init() implementation).
4745  */
4746 static int
4747 scsi_hba_ua_set(char *ua, dev_info_t *dchild, mdi_pathinfo_t *pchild)
4748 {
4749         char            *p;
4750         int             tgt;
4751         char            *tgt_port_end;
4752         char            *tgt_port;
4753         int             tgt_port_len;
4754         int             sfunc;
4755         scsi_lun64_t    lun64;
4756 
4757         /* Caller must choose to decorate devinfo *or* pathinfo */
4758         ASSERT((dchild != NULL) ^ (pchild != NULL));
4759         if (dchild && pchild)
4760                 return (0);
4761 
4762         /*
4763          * generic implementation based on "tgt,lun[,sfunc]" address form.
4764          * parse hex "tgt" part of "tgt,lun[,sfunc]"
4765          */
4766         p = ua;
4767         tgt_port_end = NULL;
4768         for (tgt = 0; *p && *p != ','; p++) {
4769                 if (*p >= '0' && *p <= '9')
4770                         tgt = (tgt << 4) + (*p - '0');
4771                 else if (*p >= 'a' && *p <= 'f')
4772                         tgt = (tgt << 4) + 10 + (*p - 'a');
4773                 else
4774                         tgt = -1;               /* non-numeric */
4775 
4776                 /*
4777                  * if non-numeric or our of range set tgt to -1 and
4778                  * skip forward
4779                  */
4780                 if (tgt < 0) {
4781                         tgt = -1;
4782                         for (; *p && *p != ','; p++)
4783                                 ;
4784                         break;
4785                 }
4786         }
4787         tgt_port_end = p;
4788 
4789         /* parse hex ",lun" part of "tgt,lun[,sfunc]" */
4790         if (*p)
4791                 p++;
4792         for (lun64 = 0; *p && *p != ','; p++) {
4793                 if (*p >= '0' && *p <= '9')
4794                         lun64 = (lun64 << 4) + (*p - '0');
4795                 else if (*p >= 'a' && *p <= 'f')
4796                         lun64 = (lun64 << 4) + 10 + (*p - 'a');
4797                 else
4798                         return (0);
4799         }
4800 
4801         /* parse hex ",sfunc" part of "tgt,lun[,sfunc]" */
4802         if (*p) {
4803                 p++;
4804                 for (sfunc = 0; *p; p++) {
4805                         if (*p >= '0' && *p <= '9')
4806                                 sfunc = (sfunc << 4) + (*p - '0');
4807                         else if (*p >= 'a' && *p <= 'f')
4808                                 sfunc = (sfunc << 4) + 10 + (*p - 'a');
4809                         else
4810                                 return (0);
4811                 }
4812         } else
4813                 sfunc = -1;
4814 
4815         if (dchild) {
4816                 /*
4817                  * Decorate a devinfo node with unit address properties.
4818                  * This adds the the addressing properties needed to
4819                  * DDI_CTLOPS_UNINITCHILD the devinfo node (i.e. perform
4820                  * the reverse operation - form unit address from properties).
4821                  */
4822                 if ((tgt != -1) && (ndi_prop_update_int(DDI_DEV_T_NONE, dchild,
4823                     SCSI_ADDR_PROP_TARGET, tgt) != DDI_PROP_SUCCESS))
4824                         return (0);
4825 
4826                 if (tgt_port_end) {
4827                         tgt_port_len = tgt_port_end - ua + 1;
4828                         tgt_port = kmem_alloc(tgt_port_len, KM_SLEEP);
4829                         (void) strlcpy(tgt_port, ua, tgt_port_len);
4830                         if (ndi_prop_update_string(DDI_DEV_T_NONE, dchild,
4831                             SCSI_ADDR_PROP_TARGET_PORT, tgt_port) !=
4832                             DDI_PROP_SUCCESS) {
4833                                 kmem_free(tgt_port, tgt_port_len);
4834                                 return (0);
4835                         }
4836                         kmem_free(tgt_port, tgt_port_len);
4837                 }
4838 
4839                 /* Set the appropriate lun properties. */
4840                 if (lun64 < SCSI_32LUNS_PER_TARGET) {
4841                         if (ndi_prop_update_int(DDI_DEV_T_NONE, dchild,
4842                             SCSI_ADDR_PROP_LUN, (int)lun64) != DDI_PROP_SUCCESS)
4843                                 return (0);
4844                 }
4845                 if (ndi_prop_update_int64(DDI_DEV_T_NONE, dchild,
4846                     SCSI_ADDR_PROP_LUN64, lun64) != DDI_PROP_SUCCESS)
4847                         return (0);
4848 
4849                 /* Set the sfunc property */
4850                 if ((sfunc != -1) &&
4851                     (ndi_prop_update_int(DDI_DEV_T_NONE, dchild,
4852                     SCSI_ADDR_PROP_SFUNC, (int)sfunc) != DDI_PROP_SUCCESS))
4853                         return (0);
4854         } else if (pchild) {
4855                 /*
4856                  * Decorate a pathinfo node with unit address properties.
4857                  */
4858                 if ((tgt != -1) && (mdi_prop_update_int(pchild,
4859                     SCSI_ADDR_PROP_TARGET, tgt) != DDI_PROP_SUCCESS))
4860                         return (0);
4861 
4862                 if (tgt_port_end) {
4863                         tgt_port_len = tgt_port_end - ua + 1;
4864                         tgt_port = kmem_alloc(tgt_port_len, KM_SLEEP);
4865                         (void) strlcpy(tgt_port, ua, tgt_port_len);
4866                         if (mdi_prop_update_string(pchild,
4867                             SCSI_ADDR_PROP_TARGET_PORT, tgt_port) !=
4868                             DDI_PROP_SUCCESS) {
4869                                 kmem_free(tgt_port, tgt_port_len);
4870                                 return (0);
4871                         }
4872                         kmem_free(tgt_port, tgt_port_len);
4873                 }
4874 
4875                 /* Set the appropriate lun properties */
4876                 if (lun64 < SCSI_32LUNS_PER_TARGET) {
4877                         if (mdi_prop_update_int(pchild, SCSI_ADDR_PROP_LUN,
4878                             (int)lun64) != DDI_PROP_SUCCESS)
4879                                 return (0);
4880                 }
4881 
4882                 if (mdi_prop_update_int64(pchild, SCSI_ADDR_PROP_LUN64,
4883                     lun64) != DDI_PROP_SUCCESS)
4884                         return (0);
4885 
4886                 /* Set the sfunc property */
4887                 if ((sfunc != -1) &&
4888                     (mdi_prop_update_int(pchild,
4889                     SCSI_ADDR_PROP_SFUNC, (int)sfunc) != DDI_PROP_SUCCESS))
4890                         return (0);
4891         }
4892         return (1);
4893 }
4894 
4895 /*
4896  * Private ndi_devi_find/mdi_pi_find implementation - find the child
4897  * dev_info/path_info of self whose phci name matches "name@caddr".
4898  * We have our own implementation because we need to search with both
4899  * forms of sibling lists (dev_info and path_info) and we need to be able
4900  * to search with a NULL name in order to find siblings already associated
4901  * with a given unit-address (same @addr). NOTE: NULL name search will never
4902  * return probe node.
4903  *
4904  * If pchildp is NULL and we find a pathinfo child, we return the client
4905  * devinfo node in *dchildp.
4906  *
4907  * The init flag argument should be clear when called from places where
4908  * recursion could occur (like scsi_busctl_initchild) and when the caller
4909  * has already performed a search for name@addr with init set (performance).
4910  *
4911  * Future: Integrate ndi_devi_findchild_by_callback into scsi_findchild.
4912  */
4913 static int
4914 scsi_findchild(dev_info_t *self, char *name, char *addr, int init,
4915     dev_info_t **dchildp, mdi_pathinfo_t **pchildp, int *ppi)
4916 {
4917         dev_info_t      *dchild;        /* devinfo child */
4918         mdi_pathinfo_t  *pchild;        /* pathinfo child */
4919         int             found = CHILD_TYPE_NONE;
4920         char            *daddr;
4921 
4922         ASSERT(self && DEVI_BUSY_OWNED(self));
4923         ASSERT(addr && dchildp);
4924         if ((self == NULL) || (addr == NULL) || (dchildp == NULL))
4925                 return (CHILD_TYPE_NONE);
4926 
4927         *dchildp = NULL;
4928         if (pchildp)
4929                 *pchildp = NULL;
4930         if (ppi)
4931                 *ppi = 0;
4932 
4933         /* Walk devinfo child list to find a match */
4934         for (dchild = ddi_get_child(self); dchild;
4935             dchild = ddi_get_next_sibling(dchild)) {
4936                 if (i_ddi_node_state(dchild) < DS_INITIALIZED)
4937                         continue;
4938 
4939                 daddr = ddi_get_name_addr(dchild);
4940                 if (daddr && (strcmp(addr, daddr) == 0) &&
4941                     ((name == NULL) ||
4942                     (strcmp(name, DEVI(dchild)->devi_node_name) == 0))) {
4943                         /*
4944                          * If we are asked to find "anything" at a given
4945                          * unit-address (name == NULL), we don't realy want
4946                          * to find the 'probe' node. The existance of
4947                          * a probe node on a 'name == NULL' search should
4948                          * fail.  This will trigger slow-path code where
4949                          * we explicity look for, and synchronize against,
4950                          * a node named "probe" at the unit-address.
4951                          */
4952                         if ((name == NULL) &&
4953                             scsi_hba_devi_is_barrier(dchild)) {
4954                                 SCSI_HBA_LOG((_LOG(4), NULL, dchild,
4955                                     "%s@%s 'probe' devinfo found, skip",
4956                                     name ? name : "", addr));
4957                                 continue;
4958                         }
4959 
4960                         /* We have found a match. */
4961                         found |= CHILD_TYPE_DEVINFO;
4962                         SCSI_HBA_LOG((_LOG(4), NULL, dchild,
4963                             "%s@%s devinfo found", name ? name : "", addr));
4964                         *dchildp = dchild;              /* devinfo found */
4965                         break;
4966                 }
4967         }
4968 
4969         /*
4970          * Walk pathinfo child list to find a match.
4971          *
4972          * NOTE: Unlike devinfo nodes, pathinfo nodes have a string searchable
4973          * unit-address from creation - so there is no need for an 'init'
4974          * search block of code for pathinfo nodes below.
4975          */
4976         pchild = mdi_pi_find(self, NULL, addr);
4977         if (pchild) {
4978                 /*
4979                  * NOTE: If name specified and we match a pathinfo unit
4980                  * address, we don't check the client node name.
4981                  */
4982                 if (ppi)
4983                         *ppi = mdi_pi_get_path_instance(pchild);
4984                 found |= CHILD_TYPE_PATHINFO;
4985 
4986                 if (pchildp) {
4987                         SCSI_HBA_LOG((_LOG(4), self, NULL,
4988                             "%s pathinfo found", mdi_pi_spathname(pchild)));
4989                         *pchildp = pchild;              /* pathinfo found */
4990                 } else if (*dchildp == NULL) {
4991                         /*
4992                          * Did not find a devinfo node, found a pathinfo node,
4993                          * but caller did not ask us to return a pathinfo node:
4994                          * we return the 'client' devinfo node instead (but
4995                          * with CHILD_TYPE_PATHINFO 'found' return value).
4996                          */
4997                         dchild = mdi_pi_get_client(pchild);
4998                         SCSI_HBA_LOG((_LOG(4), NULL, dchild,
4999                             "%s pathinfo found, client switch",
5000                             mdi_pi_spathname(pchild)));
5001 
5002                         /*
5003                          * A pathinfo node always has a 'client' devinfo node,
5004                          * but we need to ensure that the 'client' is
5005                          * initialized and has a scsi_device structure too.
5006                          */
5007                         ASSERT(dchild);
5008                         if (i_ddi_node_state(dchild) < DS_INITIALIZED) {
5009                                 SCSI_HBA_LOG((_LOG(4), NULL, dchild,
5010                                     "%s found client, initchild",
5011                                     mdi_pi_spathname(pchild)));
5012                                 (void) ddi_initchild(ddi_get_parent(dchild),
5013                                     dchild);
5014                         }
5015                         if (i_ddi_node_state(dchild) >= DS_INITIALIZED) {
5016                                 /* client found and initialized */
5017                                 *dchildp = dchild;
5018                         } else {
5019                                 SCSI_HBA_LOG((_LOG(4), NULL, dchild,
5020                                     "%s found client, but failed initchild",
5021                                     mdi_pi_spathname(pchild)));
5022                         }
5023                 }
5024         }
5025 
5026         /* Try devinfo again with initchild of uninitialized nodes */
5027         if ((found == CHILD_TYPE_NONE) && init) {
5028                 for (dchild = ddi_get_child(self); dchild;
5029                     dchild = ddi_get_next_sibling(dchild)) {
5030                         /* skip if checked above */
5031                         if (i_ddi_node_state(dchild) >= DS_INITIALIZED)
5032                                 continue;
5033                         /* attempt initchild to establish unit-address */
5034                         (void) ddi_initchild(self, dchild);
5035                         if (i_ddi_node_state(dchild) < DS_INITIALIZED)
5036                                 continue;
5037                         daddr = ddi_get_name_addr(dchild);
5038                         if (daddr &&
5039                             ((name == NULL) || (strcmp(name,
5040                             DEVI(dchild)->devi_node_name) == 0)) &&
5041                             (strcmp(addr, daddr) == 0)) {
5042                                 found |= CHILD_TYPE_DEVINFO;
5043                                 SCSI_HBA_LOG((_LOG(4), NULL, dchild,
5044                                     "%s@%s devinfo found post initchild",
5045                                     name ? name : "", addr));
5046                                 *dchildp = dchild;      /* devinfo found */
5047                                 break;  /* node found */
5048                         }
5049                 }
5050         }
5051 
5052         /*
5053          * We should never find devinfo and pathinfo at the same
5054          * unit-address.
5055          */
5056         ASSERT(found != (CHILD_TYPE_DEVINFO | CHILD_TYPE_PATHINFO));
5057         if (found == (CHILD_TYPE_DEVINFO | CHILD_TYPE_PATHINFO)) {
5058                 found = CHILD_TYPE_NONE;
5059                 *dchildp = NULL;
5060                 *pchildp = NULL;
5061         }
5062         return (found);
5063 }
5064 
5065 /*
5066  * Given information about a child device (contained on probe node) construct
5067  * and return a pointer to the dynamic SID devinfo node associated with the
5068  * device. In the creation of this SID node a compatible property for the
5069  * device is formed and used to establish a nodename (via
5070  * /etc/nodename_aliases) and to bind a driver (via /etc/driver_aliases).
5071  *
5072  * If this routine is called then we got a response from a device and
5073  * obtained the inquiry data from the device. Some inquiry results indicate
5074  * that the specific LUN we addressed does not exist, and we don't want to
5075  * bind a standard target driver to the node we create. Even though the
5076  * specific LUN is not usable, the framework may still want to bind a
5077  * target driver to the device for internal communication with the device -
5078  * an example would be issuing a report_lun to enumerate other LUNs under a
5079  * DPQ_NEVER LUN0. Another example would be wanting to known that the
5080  * DPQ_NEVER LUN0 device exists in BUS_CONFIG_ONE for non-existent LUN
5081  * caching optimizations. To support this we let the caller specify a
5082  * compatible property (or driver). If LUN0 inquiry data indicates that the
5083  * LUN does not exist then we establish compat0 as the highest precedence(0)
5084  * compatible form. If used, this compat0 driver will never be called on to
5085  * issue external commands to the device.
5086  *
5087  * If no driver binds to the device using driver_alias we establish the driver
5088  * passed in as the node name.
5089  */
5090 
5091 extern int e_devid_cache_pathinfo(mdi_pathinfo_t *, ddi_devid_t);
5092 
5093 static int
5094 scsi_device_createchild(dev_info_t *self, char *addr, scsi_enum_t se,
5095     struct scsi_device *sdprobe, dev_info_t **dchildp, mdi_pathinfo_t **pchildp)
5096 {
5097         scsi_lun64_t            lun64;
5098         int                     dtype;
5099         int                     dpq;
5100         int                     dpq_vu;
5101         int                     dtype_node;
5102         int                     lunexists;
5103         char                    *compat0;
5104         char                    *nname;
5105         char                    **compat = NULL;
5106         int                     ncompat;
5107         dev_info_t              *dchild = NULL;
5108         mdi_pathinfo_t          *pchild = NULL;
5109         dev_info_t              *probe = sdprobe->sd_dev;
5110         struct scsi_inquiry     *inq = sdprobe->sd_inq;
5111         uchar_t                 *inq80 = NULL;
5112         uchar_t                 *inq83 = NULL;
5113         uint_t                  inq80len, inq83len;
5114         char                    *binding_set = NULL;
5115         char                    *dname = NULL;
5116         ddi_devid_t             devid;
5117         int                     have_devid = 0;
5118         ddi_devid_t             cdevid;
5119         int                     have_cdevid = 0;
5120         char                    *devid_str;
5121         char                    *guid = NULL;
5122 
5123         ASSERT(self && addr && *addr && DEVI_BUSY_OWNED(self));
5124         ASSERT(dchildp && pchildp);
5125 
5126         /*
5127          * Determine the lun and whether the lun exists. We may need to create
5128          * a node for LUN0 (with compat0 driver binding) even if the lun does
5129          * not exist - so we can run report_lun to find additional LUNs.
5130          */
5131         lun64 = scsi_addr_to_lun64(addr);
5132         dtype = inq->inq_dtype & DTYPE_MASK;             /* device */
5133         dpq = inq->inq_dtype & DPQ_MASK;
5134         dpq_vu = inq->inq_dtype & DPQ_VUNIQ ? 1 : 0;
5135 
5136         dtype_node = scsi_addr_to_sfunc(addr);          /* secondary function */
5137         if (dtype_node == -1)
5138                 dtype_node = dtype;                     /* node for device */
5139 
5140         lunexists = (dtype != dtype_node) ||            /* override */
5141             ((dpq_vu == 0) && (dpq == DPQ_POSSIBLE)) || /* ANSII */
5142             (dpq_vu && (lun64 == 0));                   /* VU LUN0 */
5143         if (dtype == DTYPE_UNKNOWN)
5144                 lunexists = 0;
5145 
5146         SCSI_HBA_LOG((_LOG(4), self, NULL,
5147             "@%s dtype %x %x dpq_vu %d dpq %x: %d",
5148             addr, dtype, dtype_node, dpq_vu, dpq, lunexists));
5149 
5150         /* A non-existent LUN0 uses compatible_nodev. */
5151         if (lunexists) {
5152                 compat0 = NULL;                         /* compat0 not needed */
5153         } else if (lun64 == 0) {
5154                 compat0 = compatible_nodev;
5155                 SCSI_HBA_LOG((_LOG(2), self, NULL,
5156                     "@%s lun 0 with compat0 %s", addr, compat0));
5157         } else
5158                 goto out;                               /* no node created */
5159 
5160         /* Obtain identity information from probe node. */
5161         if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, probe,
5162             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "inquiry-page-80",
5163             &inq80, &inq80len) != DDI_PROP_SUCCESS)
5164                 inq80 = NULL;
5165         if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, probe,
5166             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "inquiry-page-83",
5167             &inq83, &inq83len) != DDI_PROP_SUCCESS)
5168                 inq83 = NULL;
5169 
5170         /* Get "scsi-binding-set" property (if there is one). */
5171         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, self,
5172             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
5173             "scsi-binding-set", &binding_set) == DDI_PROP_SUCCESS)
5174                 SCSI_HBA_LOG((_LOG(2), NULL, probe,
5175                     "binding_set '%s'", binding_set));
5176 
5177         /* determine the node name and compatible information */
5178         scsi_hba_ident_nodename_compatible_get(inq,
5179             inq80, inq80len, inq83, inq83len, binding_set, dtype_node,
5180             compat0, &nname, &dname, &compat, &ncompat);
5181 
5182         if (nname == NULL) {
5183                 /*
5184                  * We will not be able to create a node because we could not
5185                  * determine a node name. Print out a NODRIVER level warning
5186                  * message with the compatible forms for the device. Note that
5187                  * there may be a driver.conf node that attaches to the device,
5188                  * which is why we only produce this warning message for debug
5189                  * kernels.
5190                  */
5191                 SCSI_HBA_LOG((_LOG(1), NULL, self,
5192                     "no node_name for device @%s:\n      compatible: %s",
5193                     addr, *compat));
5194                 goto out;
5195         }
5196 
5197         /*
5198          * FUTURE: some day we may want an accurate "compatible" on the probe
5199          * node so that vhci_is_dev_supported() in scsi_vhci could, at
5200          * least in part, determine/configure based on "compatible".
5201          *
5202          *      if (ndi_prop_update_string_array(DDI_DEV_T_NONE, probe,
5203          *          "compatible", compat, ncompat) != DDI_PROP_SUCCESS) {
5204          *              SCSI_HBA_LOG((_LOG(3), self, NULL,
5205          *                  "%s@%s failed probe compatible decoration",
5206          *                  nname, addr));
5207          *              goto out;
5208          *      }
5209          */
5210 
5211         /* Encode devid from identity information. */
5212         if (ddi_devid_scsi_encode(DEVID_SCSI_ENCODE_VERSION_LATEST, dname,
5213             (uchar_t *)inq, sizeof (*inq), inq80, inq80len, inq83, inq83len,
5214             &devid) == DDI_SUCCESS) {
5215                 have_devid = 1;
5216 
5217                 /* Attempt to form guid from devid. */
5218                 guid = ddi_devid_to_guid(devid);
5219 
5220                 /* Produce string devid for debug. */
5221                 devid_str = ddi_devid_str_encode(devid, NULL);
5222                 SCSI_HBA_LOG((_LOG(3), self, probe, "devid '%s' guid '%s'",
5223                     devid_str ? devid_str : "NULL", guid ? guid : "NULL"));
5224                 ddi_devid_str_free(devid_str);
5225         }
5226 
5227 
5228         /*
5229          * Determine if the device should be enumerated as under the vHCI
5230          * (client node) or under the pHCI. By convention scsi_vhci expects
5231          * the "cinfo" argument identity information to be represented as a
5232          * devinfo node with the needed information (i.e. the pHCI probe node).
5233          */
5234         if ((guid == NULL) ||
5235             (mdi_is_dev_supported(MDI_HCI_CLASS_SCSI, self, sdprobe) !=
5236             MDI_SUCCESS)) {
5237                 SCSI_HBA_LOG((_LOG(3), self, probe, "==> devinfo"));
5238 
5239                 /*
5240                  * Enumerate under pHCI:
5241                  *
5242                  * Create dynamic SID dchild node. No attempt is made to
5243                  * transfer information (except the addressing and identity
5244                  * information) from the probe node to the dynamic node since
5245                  * there may be HBA specific side effects that the framework
5246                  * does not known how to transfer.
5247                  */
5248                 ndi_devi_alloc_sleep(self, nname,
5249                     (se == SE_HP) ? DEVI_SID_HP_NODEID : DEVI_SID_NODEID,
5250                     &dchild);
5251                 ASSERT(dchild);
5252                 ndi_flavor_set(dchild, SCSA_FLAVOR_SCSI_DEVICE);
5253 
5254                 /*
5255                  * Decorate new node with addressing properties (via
5256                  * scsi_hba_ua_set()), compatible, identity information, and
5257                  * class.
5258                  */
5259                 if ((scsi_hba_ua_set(addr, dchild, NULL) == 0) ||
5260                     (ndi_prop_update_string_array(DDI_DEV_T_NONE, dchild,
5261                     "compatible", compat, ncompat) != DDI_PROP_SUCCESS) ||
5262                     (inq80 && (ndi_prop_update_byte_array(DDI_DEV_T_NONE,
5263                     dchild, "inquiry-page-80", inq80, inq80len) !=
5264                     DDI_PROP_SUCCESS)) ||
5265                     (inq83 && (ndi_prop_update_byte_array(DDI_DEV_T_NONE,
5266                     dchild, "inquiry-page-83", inq83, inq83len) !=
5267                     DDI_PROP_SUCCESS)) ||
5268                     (ndi_prop_update_string(DDI_DEV_T_NONE, dchild,
5269                     "class", "scsi") != DDI_PROP_SUCCESS)) {
5270                         SCSI_HBA_LOG((_LOG(2), self, NULL,
5271                             "devinfo @%s failed decoration", addr));
5272                         (void) scsi_hba_remove_node(dchild);
5273                         dchild = NULL;
5274                         goto out;
5275                 }
5276 
5277                 /* Bind the driver */
5278                 if (ndi_devi_bind_driver(dchild, 0) != NDI_SUCCESS) {
5279                         /* need to bind in order to register a devid */
5280                         SCSI_HBA_LOG((_LOGCFG, NULL, dchild,
5281                             "devinfo @%s created, no driver-> "
5282                             "no devid_register", addr));
5283                         goto out;
5284                 }
5285 
5286                 /* Register devid */
5287                 if (have_devid) {
5288                         if (ddi_devid_register(dchild, devid) == DDI_FAILURE)
5289                                 SCSI_HBA_LOG((_LOG(1), NULL, dchild,
5290                                     "devinfo @%s created, "
5291                                     "devid register failed", addr));
5292                         else
5293                                 SCSI_HBA_LOG((_LOG(2), NULL, dchild,
5294                                     "devinfo @%s created with devid", addr));
5295                 } else
5296                         SCSI_HBA_LOG((_LOG(2), NULL, dchild,
5297                             "devinfo @%s created, no devid", addr));
5298         } else {
5299                 /*
5300                  * Enumerate under vHCI:
5301                  *
5302                  * Create a pathinfo pchild node.
5303                  */
5304                 SCSI_HBA_LOG((_LOG(3), self, probe, "==>pathinfo"));
5305 
5306                 if (mdi_pi_alloc_compatible(self, nname, guid, addr, compat,
5307                     ncompat, 0, &pchild) != MDI_SUCCESS) {
5308                         SCSI_HBA_LOG((_LOG(2), self, probe,
5309                             "pathinfo alloc failed"));
5310                         goto out;
5311                 }
5312 
5313                 ASSERT(pchild);
5314                 dchild = mdi_pi_get_client(pchild);
5315                 ASSERT(dchild);
5316                 ndi_flavor_set(dchild, SCSA_FLAVOR_SCSI_DEVICE);
5317 
5318                 /*
5319                  * Decorate new node with addressing properties via
5320                  * scsi_hba_ua_set().
5321                  */
5322                 if (scsi_hba_ua_set(addr, NULL, pchild) == 0) {
5323                         SCSI_HBA_LOG((_LOG(1), self, NULL,
5324                             "pathinfo %s decoration failed",
5325                             mdi_pi_spathname(pchild)));
5326                         (void) mdi_pi_free(pchild, 0);
5327                         pchild = NULL;
5328                         goto out;
5329                 }
5330 
5331                 /* Bind the driver */
5332                 if (ndi_devi_bind_driver(dchild, 0) != NDI_SUCCESS) {
5333                         /* need to bind in order to register a devid */
5334                         SCSI_HBA_LOG((_LOGCFG, self, NULL,
5335                             "pathinfo %s created, no client driver-> "
5336                             "no devid_register", mdi_pi_spathname(pchild)));
5337                         goto out;
5338                 }
5339 
5340                 /* Watch out for inconsistancies in devids. */
5341                 if (ddi_devid_get(dchild, &cdevid) == DDI_SUCCESS)
5342                         have_cdevid = 1;
5343 
5344                 if (have_devid && !have_cdevid) {
5345                         /* Client does not yet have devid, register ours. */
5346                         if (ddi_devid_register(dchild, devid) == DDI_FAILURE)
5347                                 SCSI_HBA_LOG((_LOG(1), self, NULL,
5348                                     "pathinfo %s created, "
5349                                     "devid register failed",
5350                                     mdi_pi_spathname(pchild)));
5351                         else
5352                                 SCSI_HBA_LOG((_LOG(2), self, NULL,
5353                                     "pathinfo %s created with devid",
5354                                     mdi_pi_spathname(pchild)));
5355                 } else if (have_devid && have_cdevid) {
5356                         /*
5357                          * We have devid and client already has devid:
5358                          * they must be the same.
5359                          */
5360                         if (ddi_devid_compare(cdevid, devid) != 0) {
5361                                 SCSI_HBA_LOG((_LOG(WARN), NULL, dchild,
5362                                     "mismatched devid on path %s",
5363                                     mdi_pi_spathname(pchild)));
5364                         }
5365                 } else if (!have_devid && have_cdevid) {
5366                         /*
5367                          * Client already has a devid, but we don't:
5368                          * we should not have missing devids.
5369                          */
5370                         SCSI_HBA_LOG((_LOG(WARN), NULL, dchild,
5371                             "missing devid on path %s",
5372                             mdi_pi_spathname(pchild)));
5373                 } else if (!have_cdevid && !have_devid) {
5374                         /* devid not supported */
5375                         SCSI_HBA_LOG((_LOG(2), self, NULL,
5376                             "pathinfo %s created, no devid",
5377                             mdi_pi_spathname(pchild)));
5378                 }
5379 
5380                 /*
5381                  * The above has registered devid for the device under
5382                  * the client node.  Now register it under the full pHCI
5383                  * path to the device.  We'll get an entry equivalent to
5384                  * booting with mpxio disabled.  This is needed for
5385                  * telemetry during enumeration.
5386                  */
5387                 if (e_devid_cache_pathinfo(pchild, devid) == DDI_SUCCESS) {
5388                         SCSI_HBA_LOG((_LOG(2), NULL, dchild,
5389                             "pathinfo @%s created with devid", addr));
5390                 } else {
5391                         SCSI_HBA_LOG((_LOG(1), NULL, dchild,
5392                             "pathinfo @%s devid cache failed", addr));
5393                 }
5394         }
5395 
5396         /* free the node name and compatible information */
5397 out:    if (have_devid)
5398                 ddi_devid_free(devid);
5399         if (have_cdevid)
5400                 ddi_devid_free(cdevid);
5401         if (guid)
5402                 ddi_devid_free_guid(guid);
5403         if (compat)
5404                 scsi_hba_ident_nodename_compatible_free(nname, dname, compat);
5405         if (inq80)
5406                 ddi_prop_free(inq80);
5407         if (inq83)
5408                 ddi_prop_free(inq83);
5409         if (binding_set)
5410                 ddi_prop_free(binding_set);
5411 
5412         /* return child_type results */
5413         if (pchild) {
5414                 *dchildp = NULL;
5415                 *pchildp = pchild;
5416                 return (CHILD_TYPE_PATHINFO);
5417         } else if (dchild) {
5418                 *dchildp = dchild;
5419                 *pchildp = NULL;
5420                 return (CHILD_TYPE_DEVINFO);
5421         }
5422 
5423         return (CHILD_TYPE_NONE);
5424 }
5425 
5426 /*
5427  * Call scsi_device_createchild and then initchild the new node.
5428  */
5429 static dev_info_t *
5430 scsi_device_configchild(dev_info_t *self, char *addr, scsi_enum_t se,
5431     struct scsi_device *sdprobe, int *circp, int *ppi)
5432 {
5433         int             child_type;
5434         dev_info_t      *dchild;
5435         mdi_pathinfo_t  *pchild;
5436         dev_info_t      *child;
5437         int             rval;
5438 
5439         ASSERT(self && addr && *addr && DEVI_BUSY_OWNED(self));
5440         if (ppi)
5441                 *ppi = 0;
5442 
5443         child_type = scsi_device_createchild(self, addr, se, sdprobe,
5444             &dchild, &pchild);
5445 
5446         /*
5447          * Prevent multiple initialized (tran_tgt_init) nodes associated with
5448          * the same @addr at the same time by calling tran_tgt_free() on the
5449          * probe node prior to promotion of the 'real' node.  After the call
5450          * to scsi_hba_barrier_tran_tgt_free(), the HBA no longer has any
5451          * probe node context.
5452          */
5453         scsi_hba_barrier_tran_tgt_free(sdprobe->sd_dev);
5454 
5455         switch (child_type) {
5456         case CHILD_TYPE_NONE:
5457                 child = NULL;
5458                 break;
5459 
5460         case CHILD_TYPE_PATHINFO:
5461                 /*
5462                  * Online pathinfo: Hold the path and exit the pHCI while
5463                  * calling mdi_pi_online() to avoid deadlock with power
5464                  * management of pHCI.
5465                  */
5466                 ASSERT(MDI_PHCI(self));
5467                 mdi_hold_path(pchild);
5468                 scsi_hba_devi_exit_phci(self, *circp);
5469 
5470                 rval = mdi_pi_online(pchild, 0);
5471 
5472                 scsi_hba_devi_enter_phci(self, circp);
5473                 mdi_rele_path(pchild);
5474 
5475                 if (rval != MDI_SUCCESS) {
5476                         /* pathinfo form of "failed during tran_tgt_init" */
5477                         scsi_enumeration_failed(NULL, se,
5478                             mdi_pi_spathname(pchild), "path online");
5479                         (void) mdi_pi_free(pchild, 0);
5480                         return (NULL);
5481                 }
5482 
5483                 /*
5484                  * Return the path_instance of the pathinfo node.
5485                  *
5486                  * NOTE: We assume that sd_inq is not path-specific.
5487                  */
5488                 if (ppi)
5489                         *ppi = mdi_pi_get_path_instance(pchild);
5490 
5491 
5492                 /*
5493                  * Fallthrough into CHILD_TYPE_DEVINFO code to promote
5494                  * the 'client' devinfo node as a dchild.
5495                  */
5496                 dchild = mdi_pi_get_client(pchild);
5497                 SCSI_HBA_LOG((_LOG(4), NULL, dchild,
5498                     "pathinfo online successful"));
5499                 /* FALLTHROUGH */
5500 
5501         case CHILD_TYPE_DEVINFO:
5502                 /*
5503                  * For now, we ndi_devi_online() the child because some other
5504                  * parts of the IO framework, like degenerate devid code,
5505                  * depend on bus_config driving nodes to DS_ATTACHED. At some
5506                  * point in the future, to keep things light-weight, we would
5507                  * like to change the ndi_devi_online call below to be
5508                  *
5509                  *      if (ddi_initchild(self, dchild) != DDI_SUCCESS)
5510                  *
5511                  * This would promote the node so that framework code could
5512                  * find the child with an @addr search, but does not incur
5513                  * attach(9E) overhead for BUS_CONFIG_ALL cases where the
5514                  * framework is not interested in attach of the node.
5515                  *
5516                  * NOTE: If the addr specified has incorrect syntax (busconfig
5517                  * one of bogus /devices path) then call below can fail.
5518                  */
5519                 if (ndi_devi_online(dchild, 0) != NDI_SUCCESS) {
5520                         SCSI_HBA_LOG((_LOG(2), NULL, dchild,
5521                             "devinfo online failed"));
5522 
5523                         /* failed online does not remove the node */
5524                         (void) scsi_hba_remove_node(dchild);
5525                         return (NULL);
5526                 }
5527                 SCSI_HBA_LOG((_LOG(4), NULL, dchild,
5528                     "devinfo initchild successful"));
5529                 child = dchild;
5530                 break;
5531         }
5532         return (child);
5533 }
5534 
5535 void
5536 scsi_hba_pkt_comp(struct scsi_pkt *pkt)
5537 {
5538         scsi_hba_tran_t *tran;
5539         uint8_t         *sensep;
5540 
5541         ASSERT(pkt);
5542 
5543         /*
5544          * Catch second call on the same packet before doing anything else.
5545          */
5546         if (pkt->pkt_flags & FLAG_PKT_COMP_CALLED) {
5547                 cmn_err(
5548 #ifdef DEBUG
5549                     CE_PANIC,
5550 #else
5551                     CE_WARN,
5552 #endif
5553                     "%s duplicate scsi_hba_pkt_comp(9F) on same scsi_pkt(9S)",
5554                     mod_containing_pc(caller()));
5555         }
5556 
5557         pkt->pkt_flags |= FLAG_PKT_COMP_CALLED;
5558 
5559         if (pkt->pkt_comp == NULL)
5560                 return;
5561 
5562         /*
5563          * For HBA drivers that implement tran_setup_pkt(9E), if we are
5564          * completing a 'consistent' mode DMA operation then we must
5565          * perform dma_sync prior to calling pkt_comp to ensure that
5566          * the target driver sees the correct data in memory.
5567          */
5568         ASSERT((pkt->pkt_flags & FLAG_NOINTR) == 0);
5569         if (((pkt->pkt_dma_flags & DDI_DMA_CONSISTENT) &&
5570             (pkt->pkt_dma_flags & DDI_DMA_READ)) &&
5571             ((P_TO_TRAN(pkt)->tran_setup_pkt) != NULL)) {
5572                 scsi_sync_pkt(pkt);
5573         }
5574 
5575         /*
5576          * If the HBA driver is using SCSAv3 scsi_hba_tgtmap_create enumeration
5577          * then we detect the special ASC/ASCQ completion codes that indicate
5578          * that the lun configuration of a target has changed. Since we need to
5579          * be determine scsi_device given scsi_address enbedded in
5580          * scsi_pkt (via scsi_address_device(9F)), we also require use of
5581          * SCSI_HBA_ADDR_COMPLEX.
5582          */
5583         tran = pkt->pkt_address.a_hba_tran;
5584         ASSERT(tran);
5585         if ((tran->tran_tgtmap == NULL) ||
5586             !(tran->tran_hba_flags & SCSI_HBA_ADDR_COMPLEX))
5587                 goto comp;              /* not using tgtmap */
5588 
5589         /*
5590          * Check for lun-change notification and queue the scsi_pkt for
5591          * lunchg1 processing. The 'pkt_comp' call to the target driver
5592          * is part of lunchg1 processing.
5593          */
5594         if ((pkt->pkt_reason == CMD_CMPLT) &&
5595             (((*pkt->pkt_scbp) & STATUS_MASK) == STATUS_CHECK) &&
5596             (pkt->pkt_state & STATE_ARQ_DONE)) {
5597                 sensep = (uint8_t *)&(((struct scsi_arq_status *)(uintptr_t)
5598                     (pkt->pkt_scbp))->sts_sensedata);
5599                 if (((scsi_sense_key(sensep) == KEY_UNIT_ATTENTION) &&
5600                     (scsi_sense_asc(sensep) == 0x3f) &&
5601                     (scsi_sense_ascq(sensep) == 0x0e)) ||
5602 
5603                     ((scsi_sense_key(sensep) == KEY_UNIT_ATTENTION) &&
5604                     (scsi_sense_asc(sensep) == 0x25) &&
5605                     (scsi_sense_ascq(sensep) == 0x00))) {
5606                         /*
5607                          * The host adaptor is done with the packet, we use
5608                          * pkt_stmp stage-temporary to link the packet for
5609                          * lunchg1 processing.
5610                          *
5611                          * NOTE: pkt_ha_private is not available since its use
5612                          * extends to tran_teardown_pkt.
5613                          */
5614                         mutex_enter(&scsi_lunchg1_mutex);
5615                         pkt->pkt_stmp = scsi_lunchg1_list;
5616                         scsi_lunchg1_list = pkt;
5617                         if (pkt->pkt_stmp == NULL)
5618                                 (void) cv_signal(&scsi_lunchg1_cv);
5619                         mutex_exit(&scsi_lunchg1_mutex);
5620                         return;
5621                 }
5622         }
5623 
5624 comp:   (*pkt->pkt_comp)(pkt);
5625 }
5626 
5627 /*
5628  * return 1 if the specified node is a barrier/probe node
5629  */
5630 static int
5631 scsi_hba_devi_is_barrier(dev_info_t *probe)
5632 {
5633         if (probe && (strcmp(ddi_node_name(probe), "probe") == 0))
5634                 return (1);
5635         return (0);
5636 }
5637 
5638 /*
5639  * A host adapter driver is easier to write if we prevent multiple initialized
5640  * (tran_tgt_init) scsi_device structures to the same unit-address at the same
5641  * time.  We prevent this from occurring all the time during the barrier/probe
5642  * node to real child hand-off by calling scsi_hba_barrier_tran_tgt_free
5643  * on the probe node prior to ddi_inichild of the 'real' node.  As part of
5644  * this early tran_tgt_free implementation, we must also call this function
5645  * as we put a probe node on the scsi_hba_barrier_list.
5646  */
5647 static void
5648 scsi_hba_barrier_tran_tgt_free(dev_info_t *probe)
5649 {
5650         struct scsi_device      *sdprobe;
5651         dev_info_t              *self;
5652         scsi_hba_tran_t         *tran;
5653 
5654         ASSERT(probe && scsi_hba_devi_is_barrier(probe));
5655 
5656         /* Return if we never called tran_tgt_init(9E). */
5657         if (i_ddi_node_state(probe) < DS_INITIALIZED)
5658                 return;
5659 
5660         sdprobe = ddi_get_driver_private(probe);
5661         self = ddi_get_parent(probe);
5662         ASSERT(sdprobe && self);
5663         tran = ddi_get_driver_private(self);
5664         ASSERT(tran);
5665 
5666         if (tran->tran_tgt_free) {
5667                 /*
5668                  * To correctly support TRAN_CLONE, we need to use the same
5669                  * cloned scsi_hba_tran(9S) structure for both tran_tgt_init(9E)
5670                  * and tran_tgt_free(9E).
5671                  */
5672                 if (tran->tran_hba_flags & SCSI_HBA_TRAN_CLONE)
5673                         tran = sdprobe->sd_address.a_hba_tran;
5674 
5675                 if (!sdprobe->sd_tran_tgt_free_done) {
5676                         SCSI_HBA_LOG((_LOG(4), NULL, probe,
5677                             "tran_tgt_free EARLY"));
5678                         (*tran->tran_tgt_free) (self, probe, tran, sdprobe);
5679                         sdprobe->sd_tran_tgt_free_done = 1;
5680                 } else {
5681                         SCSI_HBA_LOG((_LOG(4), NULL, probe,
5682                             "tran_tgt_free EARLY already done"));
5683                 }
5684         }
5685 }
5686 
5687 /*
5688  * Add an entry to the list of barrier nodes to be asynchronously deleted by
5689  * the scsi_hba_barrier_daemon after the specified timeout. Nodes on
5690  * the barrier list are used to implement the bus_config probe cache
5691  * of non-existent devices. The nodes are at DS_INITIALIZED, so their
5692  * @addr is established for searching. Since devi_ref of a DS_INITIALIZED
5693  * node will *not* prevent demotion, demotion is prevented by setting
5694  * sd_uninit_prevent. Devinfo snapshots attempt to attach probe cache
5695  * nodes, and on failure attempt to demote the node (without the participation
5696  * of bus_unconfig) to DS_BOUND - this demotion is prevented via
5697  * sd_uninit_prevent causing any attempted DDI_CTLOPS_UNINITCHILD to fail.
5698  * Probe nodes are bound to nulldriver. The list is sorted by
5699  * expiration time.
5700  *
5701  * NOTE: If we drove a probe node to DS_ATTACHED, we could use ndi_hold_devi()
5702  * to prevent demotion (instead of sd_uninit_prevent).
5703  */
5704 static void
5705 scsi_hba_barrier_add(dev_info_t *probe, int seconds)
5706 {
5707         struct scsi_hba_barrier *nb;
5708         struct scsi_hba_barrier *b;
5709         struct scsi_hba_barrier **bp;
5710         clock_t                 endtime;
5711 
5712         ASSERT(scsi_hba_devi_is_barrier(probe));
5713 
5714         /* HBA is no longer responsible for nodes on the barrier list. */
5715         scsi_hba_barrier_tran_tgt_free(probe);
5716         nb = kmem_alloc(sizeof (struct scsi_hba_barrier), KM_SLEEP);
5717         mutex_enter(&scsi_hba_barrier_mutex);
5718         endtime = ddi_get_lbolt() + drv_usectohz(seconds * MICROSEC);
5719         for (bp = &scsi_hba_barrier_list; (b = *bp) != NULL;
5720             bp = &b->barrier_next)
5721                 if (b->barrier_endtime > endtime)
5722                         break;
5723         nb->barrier_next = *bp;
5724         nb->barrier_endtime = endtime;
5725         nb->barrier_probe = probe;
5726         *bp = nb;
5727         if (bp == &scsi_hba_barrier_list)
5728                 (void) cv_signal(&scsi_hba_barrier_cv);
5729         mutex_exit(&scsi_hba_barrier_mutex);
5730 }
5731 
5732 /*
5733  * Attempt to remove devinfo node node, return 1 if removed. We
5734  * don't try to remove barrier nodes that have sd_uninit_prevent set
5735  * (even though they should fail device_uninitchild).
5736  */
5737 static int
5738 scsi_hba_remove_node(dev_info_t *child)
5739 {
5740         dev_info_t              *self = ddi_get_parent(child);
5741         struct scsi_device      *sd;
5742         int                     circ;
5743         int                     remove = 1;
5744         int                     ret = 0;
5745         char                    na[SCSI_MAXNAMELEN];
5746 
5747         scsi_hba_devi_enter(self, &circ);
5748 
5749         /* Honor sd_uninit_prevent on barrier nodes */
5750         if (scsi_hba_devi_is_barrier(child)) {
5751                 sd = ddi_get_driver_private(child);
5752                 if (sd && sd->sd_uninit_prevent)
5753                         remove = 0;
5754         }
5755 
5756         if (remove) {
5757                 (void) ddi_deviname(child, na);
5758                 if (ddi_remove_child(child, 0) != DDI_SUCCESS) {
5759                         SCSI_HBA_LOG((_LOG(2), NULL, child,
5760                             "remove_node failed"));
5761                 } else {
5762                         child = NULL;           /* child is gone */
5763                         SCSI_HBA_LOG((_LOG(4), self, NULL,
5764                             "remove_node removed %s", *na ? &na[1] : na));
5765                         ret = 1;
5766                 }
5767         } else {
5768                 SCSI_HBA_LOG((_LOG(4), NULL, child, "remove_node prevented"));
5769         }
5770         scsi_hba_devi_exit(self, circ);
5771         return (ret);
5772 }
5773 
5774 /*
5775  * The asynchronous barrier deletion daemon. Waits for a barrier timeout
5776  * to expire, then deletes the barrier (removes it as a child).
5777  */
5778 /*ARGSUSED*/
5779 static void
5780 scsi_hba_barrier_daemon(void *arg)
5781 {
5782         struct scsi_hba_barrier *b;
5783         dev_info_t              *probe;
5784         callb_cpr_t             cprinfo;
5785         int                     circ;
5786         dev_info_t              *self;
5787 
5788         CALLB_CPR_INIT(&cprinfo, &scsi_hba_barrier_mutex,
5789             callb_generic_cpr, "scsi_hba_barrier_daemon");
5790 again:  mutex_enter(&scsi_hba_barrier_mutex);
5791         for (;;) {
5792                 b = scsi_hba_barrier_list;
5793                 if (b == NULL) {
5794                         /* all barriers expired, wait for barrier_add */
5795                         CALLB_CPR_SAFE_BEGIN(&cprinfo);
5796                         (void) cv_wait(&scsi_hba_barrier_cv,
5797                             &scsi_hba_barrier_mutex);
5798                         CALLB_CPR_SAFE_END(&cprinfo, &scsi_hba_barrier_mutex);
5799                 } else {
5800                         if (ddi_get_lbolt() >= b->barrier_endtime) {
5801                                 /*
5802                                  * Drop and retry if ordering issue. Do this
5803                                  * before calling scsi_hba_remove_node() and
5804                                  * deadlocking.
5805                                  */
5806                                 probe = b->barrier_probe;
5807                                 self = ddi_get_parent(probe);
5808                                 if (scsi_hba_devi_tryenter(self, &circ) == 0) {
5809 delay:                                  mutex_exit(&scsi_hba_barrier_mutex);
5810                                         delay_random(5);
5811                                         goto again;
5812                                 }
5813 
5814                                 /* process expired barrier */
5815                                 if (!scsi_hba_remove_node(probe)) {
5816                                         /* remove failed, delay and retry */
5817                                         SCSI_HBA_LOG((_LOG(4), NULL, probe,
5818                                             "delay expire"));
5819                                         scsi_hba_devi_exit(self, circ);
5820                                         goto delay;
5821                                 }
5822                                 scsi_hba_barrier_list = b->barrier_next;
5823                                 kmem_free(b, sizeof (struct scsi_hba_barrier));
5824                                 scsi_hba_devi_exit(self, circ);
5825                         } else {
5826                                 /* establish timeout for next barrier expire */
5827                                 (void) cv_timedwait(&scsi_hba_barrier_cv,
5828                                     &scsi_hba_barrier_mutex,
5829                                     b->barrier_endtime);
5830                         }
5831                 }
5832         }
5833 }
5834 
5835 /*
5836  * Remove all barriers associated with the specified HBA. This is called
5837  * from from the bus_unconfig implementation to remove probe nodes associated
5838  * with the specified HBA (self) so that probe nodes that have not expired
5839  * will not prevent DR of the HBA.
5840  */
5841 static void
5842 scsi_hba_barrier_purge(dev_info_t *self)
5843 {
5844         struct scsi_hba_barrier **bp;
5845         struct scsi_hba_barrier *b;
5846 
5847         mutex_enter(&scsi_hba_barrier_mutex);
5848         for (bp = &scsi_hba_barrier_list; (b = *bp) != NULL; ) {
5849                 if (ddi_get_parent(b->barrier_probe) == self) {
5850                         if (scsi_hba_remove_node(b->barrier_probe)) {
5851                                 *bp = b->barrier_next;
5852                                 kmem_free(b, sizeof (struct scsi_hba_barrier));
5853                         } else {
5854                                 SCSI_HBA_LOG((_LOG(4), NULL, b->barrier_probe,
5855                                     "skip purge"));
5856                         }
5857                 } else
5858                         bp = &b->barrier_next;
5859         }
5860 
5861         mutex_exit(&scsi_hba_barrier_mutex);
5862 }
5863 
5864 /*
5865  * LUN-change processing daemons: processing occurs in two stages:
5866  *
5867  * Stage 1:     Daemon waits for a lunchg1 queued scsi_pkt, dequeues the pkt,
5868  *              forms the path, completes the scsi_pkt (pkt_comp), and
5869  *              queues the path for stage 2 processing. The use of stage 1
5870  *              avoids issues related to memory allocation in interrupt context
5871  *              (scsi_hba_pkt_comp()). We delay the pkt_comp completion until
5872  *              after lunchg1 processing forms the path for stage 2 - this is
5873  *              done to prevent the target driver from detaching until the
5874  *              path formation is complete (driver with outstanding commands
5875  *              should not detach).
5876  *
5877  * Stage 2:     Daemon waits for a lunchg2 queued request, dequeues the
5878  *              request, and opens the path using ldi_open_by_name(). The
5879  *              path opened uses a special "@taddr,*" unit address that will
5880  *              trigger lun enumeration in scsi_hba_bus_configone(). We
5881  *              trigger lun enumeration in stage 2 to avoid problems when
5882  *              initial ASC/ASCQ trigger occurs during discovery.
5883  */
5884 /*ARGSUSED*/
5885 static void
5886 scsi_lunchg1_daemon(void *arg)
5887 {
5888         callb_cpr_t             cprinfo;
5889         struct scsi_pkt         *pkt;
5890         scsi_hba_tran_t         *tran;
5891         dev_info_t              *self;
5892         struct scsi_device      *sd;
5893         char                    *ua, *p;
5894         char                    taddr[SCSI_MAXNAMELEN];
5895         char                    path[MAXPATHLEN];
5896         struct scsi_lunchg2     *lunchg2;
5897 
5898         CALLB_CPR_INIT(&cprinfo, &scsi_lunchg1_mutex,
5899             callb_generic_cpr, "scsi_lunchg1_daemon");
5900         mutex_enter(&scsi_lunchg1_mutex);
5901         for (;;) {
5902                 pkt = scsi_lunchg1_list;
5903                 if (pkt == NULL) {
5904                         /* All lunchg1 processing requests serviced, wait. */
5905                         CALLB_CPR_SAFE_BEGIN(&cprinfo);
5906                         (void) cv_wait(&scsi_lunchg1_cv,
5907                             &scsi_lunchg1_mutex);
5908                         CALLB_CPR_SAFE_END(&cprinfo, &scsi_lunchg1_mutex);
5909                         continue;
5910                 }
5911 
5912                 /* Unlink and perform lunchg1 processing on pkt. */
5913                 scsi_lunchg1_list = pkt->pkt_stmp;
5914 
5915                 /* Determine initiator port (self) from the pkt_address. */
5916                 tran = pkt->pkt_address.a_hba_tran;
5917                 ASSERT(tran && tran->tran_tgtmap && tran->tran_iport_dip);
5918                 self = tran->tran_iport_dip;
5919 
5920                 /*
5921                  * Determine scsi_devie from pkt_address (depends on
5922                  * SCSI_HBA_ADDR_COMPLEX).
5923                  */
5924                 sd = scsi_address_device(&(pkt->pkt_address));
5925                 ASSERT(sd);
5926                 if (sd == NULL) {
5927                         (*pkt->pkt_comp)(pkt);
5928                         continue;
5929                 }
5930 
5931                 /* Determine unit-address from scsi_device. */
5932                 ua = scsi_device_unit_address(sd);
5933 
5934                 /* Extract taddr from the unit-address. */
5935                 for (p = taddr; (*ua != ',') && (*ua != '\0'); )
5936                         *p++ = *ua++;
5937                 *p = '\0';                      /* NULL terminate taddr */
5938 
5939                 /*
5940                  * Form path using special "@taddr,*" notation to trigger
5941                  * lun enumeration.
5942                  */
5943                 (void) ddi_pathname(self, path);
5944                 (void) strcat(path, "/luns@");
5945                 (void) strcat(path, taddr);
5946                 (void) strcat(path, ",*");
5947 
5948                 /*
5949                  * Now that we have the path, complete the pkt that
5950                  * triggered lunchg1 processing.
5951                  */
5952                 (*pkt->pkt_comp)(pkt);
5953 
5954                 /* Allocate element for stage2 processing queue. */
5955                 lunchg2 = kmem_alloc(sizeof (*lunchg2), KM_SLEEP);
5956                 lunchg2->lunchg2_path = strdup(path);
5957 
5958                 /* Queue and dispatch to stage 2. */
5959                 SCSI_HBA_LOG((_LOG(2), self, NULL,
5960                     "lunchg stage1: queue %s", lunchg2->lunchg2_path));
5961                 mutex_enter(&scsi_lunchg2_mutex);
5962                 lunchg2->lunchg2_next = scsi_lunchg2_list;
5963                 scsi_lunchg2_list = lunchg2;
5964                 if (lunchg2->lunchg2_next == NULL)
5965                         (void) cv_signal(&scsi_lunchg2_cv);
5966                 mutex_exit(&scsi_lunchg2_mutex);
5967         }
5968 }
5969 
5970 /*ARGSUSED*/
5971 static void
5972 scsi_lunchg2_daemon(void *arg)
5973 {
5974         callb_cpr_t             cprinfo;
5975         struct scsi_lunchg2     *lunchg2;
5976         ldi_ident_t             li;
5977         ldi_handle_t            lh;
5978 
5979         CALLB_CPR_INIT(&cprinfo, &scsi_lunchg2_mutex,
5980             callb_generic_cpr, "scsi_lunchg2_daemon");
5981 
5982         li = ldi_ident_from_anon();
5983         mutex_enter(&scsi_lunchg2_mutex);
5984         for (;;) {
5985                 lunchg2 = scsi_lunchg2_list;
5986                 if (lunchg2 == NULL) {
5987                         /* All lunchg2 processing requests serviced, wait. */
5988                         CALLB_CPR_SAFE_BEGIN(&cprinfo);
5989                         (void) cv_wait(&scsi_lunchg2_cv,
5990                             &scsi_lunchg2_mutex);
5991                         CALLB_CPR_SAFE_END(&cprinfo, &scsi_lunchg2_mutex);
5992                         continue;
5993                 }
5994 
5995                 /* Unlink and perform lunchg2 processing on pkt. */
5996                 scsi_lunchg2_list = lunchg2->lunchg2_next;
5997 
5998                 /*
5999                  * Open and close the path to trigger lun enumeration.  We
6000                  * don't expect the open to succeed, but we do expect code in
6001                  * scsi_hba_bus_configone() to trigger lun enumeration.
6002                  */
6003                 SCSI_HBA_LOG((_LOG(2), NULL, NULL,
6004                     "lunchg stage2: open %s", lunchg2->lunchg2_path));
6005                 if (ldi_open_by_name(lunchg2->lunchg2_path,
6006                     FREAD, kcred, &lh, li) == 0)
6007                         (void) ldi_close(lh, FREAD, kcred);
6008 
6009                 /* Free path and linked element. */
6010                 strfree(lunchg2->lunchg2_path);
6011                 kmem_free(lunchg2, sizeof (*lunchg2));
6012         }
6013 }
6014 
6015 /*
6016  * Enumerate a child at the specified @addr. If a device exists @addr then
6017  * ensure that we have the appropriately named devinfo node for it. Name is
6018  * NULL in the bus_config_all case. This routine has no knowledge of the
6019  * format of an @addr string or associated addressing properties.
6020  *
6021  * The caller must guarantee that there is an open scsi_hba_devi_enter on the
6022  * parent. We return the scsi_device structure for the child device. This
6023  * scsi_device structure is valid until the caller scsi_hba_devi_exit the
6024  * parent. The caller can add do ndi_hold_devi of the child prior to the
6025  * scsi_hba_devi_exit to extend the validity of the child.
6026  *
6027  * In some cases the returned scsi_device structure may be used to drive
6028  * additional SCMD_REPORT_LUNS operations by bus_config_all callers.
6029  *
6030  * The first operation performed is to see if there is a dynamic SID nodes
6031  * already attached at the specified "name@addr". This is the fastpath
6032  * case for resolving a reference to a node that has already been created.
6033  * All other references are serialized for a given @addr prior to probing
6034  * to determine the type of device, if any, at the specified @addr.
6035  * If no device is present then NDI_FAILURE is returned. The fact that a
6036  * device does not exist may be determined via the barrier/probe cache,
6037  * minimizing the probes of non-existent devices.
6038  *
6039  * When there is a device present the dynamic SID node is created based on
6040  * the device found. If a driver.conf node exists for the same @addr it
6041  * will either merge into the dynamic SID node (if the SID node bound to
6042  * that driver), or exist independently. To prevent the actions of one driver
6043  * causing side effects in another, code prevents multiple SID nodes from
6044  * binding to the same "@addr" at the same time. There is autodetach code
6045  * to allow one device to be replaced with another at the same @addr for
6046  * slot addressed SCSI bus implementations (SPI). For compatibility with
6047  * legacy driver.conf behavior, the code does not prevent multiple driver.conf
6048  * nodes from attaching to the same @addr at the same time.
6049  *
6050  * This routine may have the side effect of creating nodes for devices other
6051  * than the one being sought. It is possible that there is a different type of
6052  * target device at that target/lun address than we were asking for. In that
6053  * It is the caller's responsibility to determine whether the device we found,
6054  * if any, at the specified address, is the one it really wanted.
6055  */
6056 static struct scsi_device *
6057 scsi_device_config(dev_info_t *self, char *name, char *addr, scsi_enum_t se,
6058     int *circp, int *ppi)
6059 {
6060         dev_info_t              *child = NULL;
6061         dev_info_t              *probe = NULL;
6062         struct scsi_device      *sdchild;
6063         struct scsi_device      *sdprobe;
6064         dev_info_t              *dsearch;
6065         mdi_pathinfo_t          *psearch;
6066         major_t                 major;
6067         int                     sp;
6068         int                     pi = 0;
6069         int                     wait_msg = scsi_hba_wait_msg;
6070         int                     chg;
6071 
6072         ASSERT(self && addr && DEVI_BUSY_OWNED(self));
6073 
6074         SCSI_HBA_LOG((_LOG(4), self, NULL, "%s@%s wanted",
6075             name ? name : "", addr));
6076 
6077         /* playing with "probe" node name is dangerous */
6078         if (name && (strcmp(name, "probe") == 0))
6079                 return (NULL);
6080 
6081         /*
6082          * NOTE: use 'goto done;' or 'goto fail;'. There should only be one
6083          * 'return' statement from here to the end of the function - the one
6084          * on the last line of the function.
6085          */
6086 
6087         /*
6088          * Fastpath: search to see if we are requesting a named SID node that
6089          * already exists (we already created) - probe node does not count.
6090          * scsi_findchild() does not hold the returned devinfo node, but
6091          * this is OK since the caller has a scsi_hba_devi_enter on the
6092          * attached parent HBA (self). The caller is responsible for attaching
6093          * and placing a hold on the child (directly via ndi_hold_devi or
6094          * indirectly via ndi_busop_bus_config) before doing an
6095          * scsi_hba_devi_exit on the parent.
6096          *
6097          * NOTE: This fastpath prevents detecting a driver binding change
6098          * (autodetach) if the same nodename is used for old and new binding.
6099          */
6100         /* first call is with init set */
6101         (void) scsi_findchild(self, name, addr, 1, &dsearch, NULL, &pi);
6102         if (dsearch && scsi_hba_dev_is_sid(dsearch) &&
6103             !scsi_hba_devi_is_barrier(dsearch)) {
6104                 SCSI_HBA_LOG((_LOG(4), NULL, dsearch,
6105                     "%s@%s devinfo fastpath", name ? name : "", addr));
6106                 child = dsearch;
6107                 goto done;
6108         }
6109 
6110         /*
6111          * Create a barrier devinfo node used to "probe" the device with. We
6112          * need to drive this node to DS_INITIALIZED so that the
6113          * DDI_CTLOPS_INITCHILD has occurred, bringing the SCSA transport to
6114          * a state useable state for issuing our "probe" commands. We establish
6115          * this barrier node with a node name of "probe" and compatible
6116          * property of "scsiprobe". The compatible property must be associated
6117          * in /etc/driver_aliases with a scsi target driver available in the
6118          * root file system (sd).
6119          *
6120          * The "probe" that we perform on the barrier node, after it is
6121          * DS_INITIALIZED, is used to find the information needed to create a
6122          * dynamic devinfo (SID) node. This "probe" is separate from the
6123          * probe(9E) call associated with the transition of a node from
6124          * DS_INITIALIZED to DS_PROBED. The probe(9E) call that eventually
6125          * occurs against the created SID node should find ddi_dev_is_sid and
6126          * just return DDI_PROBE_DONTCARE.
6127          *
6128          * Trying to avoid the use of a barrier node is not a good idea
6129          * because we may have an HBA driver that uses generic bus_config
6130          * (this code) but implements its own DDI_CTLOPS_INITCHILD with side
6131          * effects that we can't duplicate (such as the ATA nexus driver).
6132          *
6133          * The probe/barrier node plays an integral part of the locking scheme.
6134          * The objective is to single thread probes of the same device (same
6135          * @addr) while allowing parallelism for probes of different devices
6136          * with the same parent. At this point we are serialized on our self.
6137          * For parallelism we will need to release our self. Prior to release
6138          * we construct a barrier for probes of the same device to serialize
6139          * against. The "probe@addr" node acts as this barrier. An entering
6140          * thread must wait until the probe node does not exist - it can then
6141          * create and link the probe node - dropping the HBA (self) lock after
6142          * the node is linked and visible (after ddi_initchild). A side effect
6143          * of this is that transports should not "go over the wire" (i.e. do
6144          * things that incur significant delays) until after tran_target_init.
6145          * This means that the first "over the wire" operation should occur
6146          * at tran_target_probe time - when things are running in parallel
6147          * again.
6148          *
6149          * If the probe node exists then another probe with the same @addr is
6150          * in progress, we must wait until there is no probe in progress
6151          * before proceeding, and when we proceed we must continue to hold the
6152          * HBA (self) until we have linked a new probe node as a barrier.
6153          *
6154          * When a device is found to *not* exist, its probe/barrier node may be
6155          * marked with DEVICE_REMOVED with node deletion scheduled for some
6156          * future time (seconds). This asynchronous deletion allows the
6157          * framework to detect repeated requests to the same non-existent
6158          * device and avoid overhead associated with contacting a non-existent
6159          * device again and again.
6160          */
6161         for (;;) {
6162                 /*
6163                  * Search for probe node - they should only exist as devinfo
6164                  * nodes.
6165                  */
6166                 (void) scsi_findchild(self, "probe", addr,
6167                     0, &probe, &psearch, NULL);
6168                 if (probe == NULL) {
6169                         if (psearch)
6170                                 SCSI_HBA_LOG((_LOG(2), self,
6171                                     mdi_pi_get_client(psearch),
6172                                     "???? @%s 'probe' search found "
6173                                     "pathinfo: %p", addr, (void *)psearch));
6174                         break;
6175                 }
6176 
6177                 /*
6178                  * The barrier node may cache the non-existence of a device
6179                  * by leaving the barrier node in place (with
6180                  * DEVI_DEVICE_REMOVED flag set ) for some amount of time after
6181                  * the failure of a probe. This flag is used to fail
6182                  * additional probes until the barrier probe node is deleted,
6183                  * which will occur from a timeout some time after a failed
6184                  * probe. The failed probe will use DEVI_SET_DEVICE_REMOVED
6185                  * and schedule probe node deletion from a timeout. The callers
6186                  * scsi_hba_devi_exit on the way out of the first failure will
6187                  * do the cv_broadcast associated with the cv_wait below - this
6188                  * handles threads that wait prior to DEVI_DEVICE_REMOVED being
6189                  * set.
6190                  */
6191                 if (DEVI_IS_DEVICE_REMOVED(probe)) {
6192                         SCSI_HBA_LOG((_LOG(3), NULL, probe,
6193                             "detected probe DEVICE_REMOVED"));
6194                         probe = NULL;   /* deletion already scheduled */
6195                         goto fail;
6196                 }
6197 
6198                 /*
6199                  * Drop the lock on the HBA (self) and wait until the probe in
6200                  * progress has completed. A changes in the sibling list from
6201                  * removing the probe node will cause cv_wait to return
6202                  * (scsi_hba_devi_exit does the cv_broadcast).
6203                  */
6204                 if (wait_msg) {
6205                         wait_msg--;
6206                         SCSI_HBA_LOG((_LOG(2), NULL, probe,
6207                             "exists, probe already in progress: %s", wait_msg ?
6208                             "waiting..." : "last msg, but still waiting..."));
6209                 }
6210 
6211                 /*
6212                  * NOTE: we could avoid rare case of one second delay by
6213                  * implementing scsi_hba_devi_exit_and_wait based on
6214                  * ndi/mdi_devi_exit_and_wait (and consider switching devcfg.c
6215                  * code to use these ndi/mdi interfaces too).
6216                  */
6217                 scsi_hba_devi_exit(self, *circp);
6218                 mutex_enter(&DEVI(self)->devi_lock);
6219                 (void) cv_timedwait(&DEVI(self)->devi_cv,
6220                     &DEVI(self)->devi_lock,
6221                     ddi_get_lbolt() + drv_usectohz(MICROSEC));
6222                 mutex_exit(&DEVI(self)->devi_lock);
6223                 scsi_hba_devi_enter(self, circp);
6224         }
6225         ASSERT(probe == NULL);
6226 
6227         /*
6228          * Search to see if we are requesting a SID node that already exists.
6229          * We hold the HBA (self) and there is not another probe in progress at
6230          * the same @addr. scsi_findchild() does not hold the returned
6231          * devinfo node but this is OK since we hold the HBA (self).
6232          */
6233         if (name) {
6234                 (void) scsi_findchild(self, name, addr, 1, &dsearch, NULL, &pi);
6235                 if (dsearch && scsi_hba_dev_is_sid(dsearch)) {
6236                         SCSI_HBA_LOG((_LOG(4), NULL, dsearch,
6237                             "%s@%s probe devinfo fastpath",
6238                             name ? name : "", addr));
6239                         child = dsearch;
6240                         goto done;
6241                 }
6242         }
6243 
6244         /*
6245          * We are looking for a SID node that does not exist or a driver.conf
6246          * node.
6247          *
6248          * To avoid probe side effects, before we probe the device at the
6249          * specified address we need to check to see if there is already an
6250          * initialized child "@addr".
6251          *
6252          * o If we find an initialized SID child and name is NULL or matches
6253          *   the name or the name of the attached driver then we return the
6254          *   existing node.
6255          *
6256          * o If we find a non-matching SID node, we will attempt to autodetach
6257          *   and remove the node in preference to our new node.
6258          *
6259          * o If SID node found does not match and can't be autodetached, we
6260          *   fail: we only allow one SID node at an address.
6261          *
6262          * NOTE: This code depends on SID nodes showing up prior to
6263          * driver.conf nodes in the sibling list.
6264          */
6265         for (;;) {
6266                 /* first NULL name call is with init set */
6267                 (void) scsi_findchild(self, NULL, addr, 1, &dsearch, NULL, &pi);
6268                 if (dsearch == NULL)
6269                         break;
6270                 ASSERT(!scsi_hba_devi_is_barrier(dsearch));
6271 
6272                 /*
6273                  * To detect changes in driver binding that should attempt
6274                  * autodetach we determine the major number of the driver
6275                  * that should currently be associated with the device based
6276                  * on the compatible property.
6277                  */
6278                 major = DDI_MAJOR_T_NONE;
6279                 if (scsi_hba_dev_is_sid(dsearch))
6280                         major = ddi_compatible_driver_major(dsearch, NULL);
6281                 if ((major == DDI_MAJOR_T_NONE) && (name == NULL))
6282                         major = ddi_driver_major(dsearch);
6283 
6284                 if ((scsi_hba_dev_is_sid(dsearch) ||
6285                     (i_ddi_node_state(dsearch) >= DS_INITIALIZED)) &&
6286                     ((name == NULL) ||
6287                     (strcmp(ddi_node_name(dsearch), name) == 0) ||
6288                     (strcmp(ddi_driver_name(dsearch), name) == 0)) &&
6289                     (major == ddi_driver_major(dsearch))) {
6290                         SCSI_HBA_LOG((_LOG(3), NULL, dsearch,
6291                             "already attached @addr"));
6292                         child = dsearch;
6293                         goto done;
6294                 }
6295 
6296                 if (!scsi_hba_dev_is_sid(dsearch))
6297                         break;                  /* driver.conf node */
6298 
6299                 /*
6300                  * Implement autodetach of SID node for situations like a
6301                  * previously "scsinodev" LUN0 coming into existence (or a
6302                  * disk/tape on an SPI transport at same addr but never both
6303                  * powered on at the same time). Try to autodetach the existing
6304                  * SID node @addr. If that works, search again - otherwise fail.
6305                  */
6306                 SCSI_HBA_LOG((_LOG(2), NULL, dsearch,
6307                     "looking for %s@%s: SID @addr exists, autodetach",
6308                     name ? name : "", addr));
6309                 if (!scsi_hba_remove_node(dsearch)) {
6310                         SCSI_HBA_LOG((_LOG(2), NULL, dsearch,
6311                             "autodetach @%s failed: fail %s@%s",
6312                             addr, name ? name : "", addr));
6313                         goto fail;
6314                 }
6315                 SCSI_HBA_LOG((_LOG(2), self, NULL, "autodetach @%s OK", addr));
6316         }
6317 
6318         /*
6319          * We will be creating a new SID node, allocate probe node
6320          * used to find out information about the device located @addr.
6321          * The probe node also acts as a barrier against additional
6322          * configuration at the same address, and in the case of non-existent
6323          * devices it will (for some amount of time) avoid re-learning that
6324          * the device does not exist on every reference. Once the probe
6325          * node is DS_LINKED we can drop the HBA (self).
6326          *
6327          * The probe node is allocated as a hidden node so that it does not
6328          * show up in devinfo snapshots.
6329          */
6330         ndi_devi_alloc_sleep(self, "probe",
6331             (se == SE_HP) ? DEVI_SID_HP_HIDDEN_NODEID : DEVI_SID_HIDDEN_NODEID,
6332             &probe);
6333         ASSERT(probe);
6334         ndi_flavor_set(probe, SCSA_FLAVOR_SCSI_DEVICE);
6335 
6336         /*
6337          * Decorate the probe node with the property representation of @addr
6338          * unit-address string prior to initchild so that initchild can
6339          * construct the name of the node from properties and tran_tgt_init
6340          * implementation can determine what LUN is being referenced.
6341          *
6342          * If the addr specified has incorrect syntax (busconfig one of bogus
6343          * /devices path) then scsi_hba_ua_set can fail.  If the address
6344          * is not understood by the SCSA HBA driver then this operation will
6345          * work, but tran_tgt_init may still fail (for example the HBA
6346          * driver may not support secondary functions).
6347          */
6348         if (scsi_hba_ua_set(addr, probe, NULL) == 0) {
6349                 SCSI_HBA_LOG((_LOG(2), NULL, probe,
6350                     "@%s failed scsi_hba_ua_set", addr));
6351                 goto fail;
6352         }
6353 
6354         /*
6355          * Set the class property to "scsi". This is sufficient to distinguish
6356          * the node for HBAs that have multiple classes of children (like uata
6357          * - which has "dada" class for ATA children and "scsi" class for
6358          * ATAPI children) and may not use our scsi_busctl_initchild()
6359          * implementation. We also add a "compatible" property of "scsiprobe"
6360          * to select the probe driver.
6361          */
6362         if ((ndi_prop_update_string(DDI_DEV_T_NONE, probe,
6363             "class", "scsi") != DDI_PROP_SUCCESS) ||
6364             (ndi_prop_update_string_array(DDI_DEV_T_NONE, probe,
6365             "compatible", &compatible_probe, 1) != DDI_PROP_SUCCESS)) {
6366                 SCSI_HBA_LOG((_LOG(1), NULL, probe,
6367                     "@%s failed node decoration", addr));
6368                 goto fail;
6369         }
6370 
6371         /*
6372          * Promote probe node to DS_INITIALIZED so that transport can be used
6373          * for scsi_probe. After this the node is linked and visible as a
6374          * barrier for serialization of other @addr operations.
6375          *
6376          * NOTE: If we attached the probe node, we could get rid of
6377          * uninit_prevent.
6378          */
6379         if (ddi_initchild(self, probe) != DDI_SUCCESS) {
6380                 SCSI_HBA_LOG((_LOG(2), NULL, probe,
6381                     "@%s failed initchild", addr));
6382 
6383                 /* probe node will be removed in fail exit path */
6384                 goto fail;
6385         }
6386 
6387         /* get the scsi_device structure of the probe node */
6388         sdprobe = ddi_get_driver_private(probe);
6389         ASSERT(sdprobe);
6390 
6391         /*
6392          * Do scsi_probe. The probe node is linked and visible as a barrier.
6393          * We prevent uninitialization of the probe node and drop our HBA (self)
6394          * while we run scsi_probe() of this "@addr". This allows the framework
6395          * to support multiple scsi_probes for different devices attached to
6396          * the same HBA (self) in parallel. We prevent node demotion of the
6397          * probe node from DS_INITIALIZED by setting sd_uninit_prevent. The
6398          * probe node can not be successfully demoted below DS_INITIALIZED
6399          * (scsi_busctl_uninitchild will fail) until we zero sd_uninit_prevent
6400          * as we are freeing the node via scsi_hba_remove_node(probe).
6401          */
6402         sdprobe->sd_uninit_prevent++;
6403         scsi_hba_devi_exit(self, *circp);
6404         sp = scsi_probe(sdprobe, SLEEP_FUNC);
6405 
6406         /* Introduce a small delay here to increase parallelism. */
6407         delay_random(5);
6408 
6409         if (sp == SCSIPROBE_EXISTS) {
6410                 /*
6411                  * For a device that exists, while still running in parallel,
6412                  * also get identity information from device. This is done
6413                  * separate from scsi_probe/tran_tgt_probe/scsi_hba_probe
6414                  * since the probe code path may still be used for HBAs
6415                  * that don't use common bus_config services (we don't want
6416                  * to expose that code path to a behavior change). This
6417                  * operation is called 'identity' to avoid confusion with
6418                  * deprecated identify(9E).
6419                  *
6420                  * Future: We may eventually want to allow HBA customization via
6421                  * scsi_identity/tran_tgt_identity/scsi_device_identity, but for
6422                  * now we just scsi_device_identity.
6423                  *
6424                  * The identity operation will establish additional properties
6425                  * on the probe node related to device identity:
6426                  *
6427                  *      "inquiry-page-80"       byte array of SCSI page 80
6428                  *      "inquiry-page-83"       byte array of SCSI page 83
6429                  *
6430                  * These properties will be used to generate a devid
6431                  * (ddi_devid_scsi_encode) and guid - and to register
6432                  * (ddi_devid_register) a devid for the device.
6433                  *
6434                  * If identify fails (non-zero return), the we had allocation
6435                  * problems or the device returned inconsistent results then
6436                  * we pretend that device does not exist.
6437                  */
6438                 if (scsi_device_identity(sdprobe, SLEEP_FUNC)) {
6439                         scsi_enumeration_failed(probe, -1, NULL, "identify");
6440                         sp = SCSIPROBE_FAILURE;
6441                 }
6442 
6443                 /*
6444                  * Future: Is there anything more we can do here to help avoid
6445                  * serialization on iport parent during scsi_device attach(9E)?
6446                  */
6447         }
6448         scsi_hba_devi_enter(self, circp);
6449         sdprobe->sd_uninit_prevent--;
6450 
6451         if (sp != SCSIPROBE_EXISTS) {
6452                 scsi_enumeration_failed(probe, -1, NULL, "probe");
6453 
6454                 if ((se != SE_HP) && scsi_hba_barrier_timeout) {
6455                         /*
6456                          * Target does not exist. Mark the barrier probe node
6457                          * as DEVICE_REMOVED and schedule an asynchronous
6458                          * deletion of the node in scsi_hba_barrier_timeout
6459                          * seconds. We keep our hold on the probe node
6460                          * until we are ready perform the asynchronous node
6461                          * deletion.
6462                          */
6463                         SCSI_HBA_LOG((_LOG(3), NULL, probe,
6464                             "set probe DEVICE_REMOVED"));
6465                         mutex_enter(&DEVI(probe)->devi_lock);
6466                         DEVI_SET_DEVICE_REMOVED(probe);
6467                         mutex_exit(&DEVI(probe)->devi_lock);
6468 
6469                         scsi_hba_barrier_add(probe, scsi_hba_barrier_timeout);
6470                         probe = NULL;
6471                 }
6472                 goto fail;
6473         }
6474 
6475         /* Create the child node from the inquiry data in the probe node. */
6476         if ((child = scsi_device_configchild(self, addr, se, sdprobe,
6477             circp, &pi)) == NULL) {
6478                 /*
6479                  * This may fail because there was no driver binding identified
6480                  * via driver_alias. We may still have a conf node.
6481                  */
6482                 if (name) {
6483                         (void) scsi_findchild(self, name, addr,
6484                             0, &child, NULL, &pi);
6485                         if (child)
6486                                 SCSI_HBA_LOG((_LOG(2), NULL, child,
6487                                     "using driver.conf driver binding"));
6488                 }
6489                 if (child == NULL) {
6490                         SCSI_HBA_LOG((_LOG(2), NULL, probe,
6491                             "device not configured"));
6492                         goto fail;
6493                 }
6494         }
6495 
6496         /*
6497          * Transfer the inquiry data from the probe node to the child
6498          * SID node to avoid an extra scsi_probe. Callers depend on
6499          * established inquiry data for the returned scsi_device.
6500          */
6501         sdchild = ddi_get_driver_private(child);
6502         if (sdchild && (sdchild->sd_inq == NULL)) {
6503                 sdchild->sd_inq = sdprobe->sd_inq;
6504                 sdprobe->sd_inq = NULL;
6505         }
6506 
6507         /*
6508          * If we are doing a bus_configone and the node we created has the
6509          * wrong node and driver name then switch the return result to a
6510          * driver.conf node with the correct name - if such a node exists.
6511          */
6512         if (name && (strcmp(ddi_node_name(child), name) != 0) &&
6513             (strcmp(ddi_driver_name(child), name) != 0)) {
6514                 (void) scsi_findchild(self, name, addr,
6515                     0, &dsearch, NULL, &pi);
6516                 if (dsearch == NULL) {
6517                         SCSI_HBA_LOG((_LOG(2), NULL, child,
6518                             "wrong device configured %s@%s", name, addr));
6519                         /*
6520                          * We can't remove when modrootloaded == 0 in case
6521                          * boot-device a uses generic name and
6522                          * scsi_hba_nodename_compatible_get() returned a
6523                          * legacy binding-set driver oriented name.
6524                          */
6525                         if (modrootloaded) {
6526                                 (void) scsi_hba_remove_node(child);
6527                                 child = NULL;
6528                                 goto fail;
6529                         }
6530                 } else {
6531                         SCSI_HBA_LOG((_LOG(2), NULL, dsearch,
6532                             "device configured, but switching to driver.conf"));
6533                         child = dsearch;
6534                 }
6535         }
6536 
6537         /* get the scsi_device structure from the node */
6538         SCSI_HBA_LOG((_LOG(3), NULL, child, "device configured"));
6539 
6540         if (child) {
6541 done:           ASSERT(child);
6542                 sdchild = ddi_get_driver_private(child);
6543                 ASSERT(sdchild);
6544 
6545                 /*
6546                  * We may have ended up here after promotion of a previously
6547                  * demoted node, where demotion deleted sd_inq data in
6548                  * scsi_busctl_uninitchild.  We redo the scsi_probe() to
6549                  * reestablish sd_inq.  We also want to redo the scsi_probe
6550                  * for devices are currently device_isremove in order to
6551                  * detect new device_insert.
6552                  */
6553                 if ((sdchild->sd_inq == NULL) ||
6554                     ((pi == NULL) && ndi_devi_device_isremoved(child))) {
6555 
6556                         /* hotplug_node can only be revived via hotplug. */
6557                         if ((se == SE_HP) || !ndi_dev_is_hotplug_node(child)) {
6558                                 SCSI_HBA_LOG((_LOG(3), NULL, child,
6559                                     "scsi_probe() demoted devinfo"));
6560 
6561                                 sp = scsi_probe(sdchild, SLEEP_FUNC);
6562 
6563                                 if (sp == SCSIPROBE_EXISTS) {
6564                                         ASSERT(sdchild->sd_inq);
6565 
6566                                         /*
6567                                          * Devinfo child exists and we are
6568                                          * talking to the device, report
6569                                          * reinsert and note if this was a
6570                                          * new reinsert.
6571                                          */
6572                                         chg = ndi_devi_device_insert(child);
6573                                         SCSI_HBA_LOG((_LOGCFG, NULL, child,
6574                                             "devinfo %s@%s device_reinsert%s",
6575                                             name ? name : "", addr,
6576                                             chg ? "" : "ed already"));
6577                                 } else {
6578                                         scsi_enumeration_failed(child, se,
6579                                             NULL, "reprobe");
6580 
6581                                         chg = ndi_devi_device_remove(child);
6582                                         SCSI_HBA_LOG((_LOG(2), NULL, child,
6583                                             "%s device_remove%s",
6584                                             (sp > (sizeof (scsi_probe_ascii) /
6585                                             sizeof (scsi_probe_ascii[0]))) ?
6586                                             "UNKNOWN" : scsi_probe_ascii[sp],
6587                                             chg ? "" : "ed already"));
6588 
6589                                         child = NULL;
6590                                         sdchild = NULL;
6591                                 }
6592                         } else {
6593                                 SCSI_HBA_LOG((_LOG(2), NULL, child,
6594                                     "no reprobe"));
6595 
6596                                 child = NULL;
6597                                 sdchild = NULL;
6598                         }
6599                 }
6600         } else {
6601 fail:           ASSERT(child == NULL);
6602                 sdchild = NULL;
6603         }
6604         if (probe) {
6605                 /*
6606                  * Clean up probe node, destroying node if uninit_prevent
6607                  * it is going to zero. Destroying the probe node (deleting
6608                  * from the sibling list) will wake up any people waiting on
6609                  * the probe node barrier.
6610                  */
6611                 SCSI_HBA_LOG((_LOG(4), NULL, probe, "remove probe"));
6612                 if (!scsi_hba_remove_node(probe)) {
6613                         /*
6614                          * Probe node removal should not fail, but if it
6615                          * does we hand that responsibility over to the
6616                          * async barrier deletion thread - other references
6617                          * to the same unit-address can hang until the
6618                          * probe node delete completes.
6619                          */
6620                         SCSI_HBA_LOG((_LOG(4), NULL, probe,
6621                             "remove probe failed, go async"));
6622                         scsi_hba_barrier_add(probe, 1);
6623                 }
6624                 probe = NULL;
6625         }
6626 
6627         /*
6628          * If we successfully resolved via a pathinfo node, we need to find
6629          * the pathinfo node and ensure that it is online (if possible). This
6630          * is done for the case where the device was open when
6631          * scsi_device_unconfig occurred, so mdi_pi_free did not occur. If the
6632          * device has now been reinserted, we want the path back online.
6633          * NOTE: This needs to occur after destruction of the probe node to
6634          * avoid ASSERT related to two nodes at the same unit-address.
6635          */
6636         if (sdchild && pi && (probe == NULL)) {
6637                 ASSERT(MDI_PHCI(self));
6638 
6639                 (void) scsi_findchild(self, NULL, addr,
6640                     0, &dsearch, &psearch, NULL);
6641                 ASSERT((psearch == NULL) ||
6642                     (mdi_pi_get_client(psearch) == child));
6643 
6644                 if (psearch && mdi_pi_device_isremoved(psearch)) {
6645                         /*
6646                          * Verify that we can talk to the device, and if
6647                          * so note if this is a new device_insert.
6648                          *
6649                          * NOTE: We depend on mdi_path_select(), when given
6650                          * a specific path_instance, to select that path
6651                          * even if the path is offline.
6652                          *
6653                          * NOTE: A Client node is not ndi_dev_is_hotplug_node().
6654                          */
6655                         if (se == SE_HP) {
6656                                 SCSI_HBA_LOG((_LOG(3), NULL, child,
6657                                     "%s scsi_probe() demoted pathinfo",
6658                                     mdi_pi_spathname(psearch)));
6659 
6660                                 sp = scsi_hba_probe_pi(sdchild, SLEEP_FUNC, pi);
6661 
6662                                 if (sp == SCSIPROBE_EXISTS) {
6663                                         /*
6664                                          * Pathinfo child exists and we are
6665                                          * talking to the device, report
6666                                          * reinsert and note if this
6667                                          * was a new reinsert.
6668                                          */
6669                                         chg = mdi_pi_device_insert(psearch);
6670                                         SCSI_HBA_LOG((_LOGCFG, self, NULL,
6671                                             "pathinfo %s device_reinsert%s",
6672                                             mdi_pi_spathname(psearch),
6673                                             chg ? "" : "ed already"));
6674 
6675                                         if (chg)
6676                                                 (void) mdi_pi_online(psearch,
6677                                                     0);
6678 
6679                                         /*
6680                                          * Report client reinsert and note if
6681                                          * this was a new reinsert.
6682                                          */
6683                                         chg = ndi_devi_device_insert(child);
6684                                         SCSI_HBA_LOG((_LOGCFG, NULL, child,
6685                                             "client devinfo %s@%s "
6686                                             "device_reinsert%s",
6687                                             name ? name : "", addr,
6688                                             chg ? "" : "ed already"));
6689                                 } else {
6690                                         scsi_enumeration_failed(child, se,
6691                                             mdi_pi_spathname(psearch),
6692                                             "reprobe");
6693                                         child = NULL;
6694                                         sdchild = NULL;
6695                                 }
6696 
6697                         } else {
6698                                 SCSI_HBA_LOG((_LOG(2), NULL, child,
6699                                     "%s no reprobe",
6700                                     mdi_pi_spathname(psearch)));
6701 
6702                                 child = NULL;
6703                                 sdchild = NULL;
6704                         }
6705                 }
6706         }
6707 
6708         /* If asked for path_instance, return it. */
6709         if (ppi)
6710                 *ppi = pi;
6711 
6712         return (sdchild);
6713 }
6714 
6715 static void
6716 scsi_device_unconfig(dev_info_t *self, char *name, char *addr, int *circp)
6717 {
6718         dev_info_t              *child = NULL;
6719         mdi_pathinfo_t          *path = NULL;
6720         char                    *spathname;
6721         int                     rval;
6722 
6723         ASSERT(self && addr && DEVI_BUSY_OWNED(self));
6724 
6725         /*
6726          * We have a catch-22. We may have a demoted node that we need to find
6727          * and offline/remove. To find the node if it isn't demoted, we
6728          * use scsi_findchild. If it's demoted, we then use
6729          * ndi_devi_findchild_by_callback.
6730          */
6731         (void) scsi_findchild(self, name, addr, 0, &child, &path, NULL);
6732 
6733         if ((child == NULL) && (path == NULL)) {
6734                 child = ndi_devi_findchild_by_callback(self, name, addr,
6735                     scsi_busctl_ua);
6736                 if (child) {
6737                         SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
6738                             "devinfo %s@%s found by callback",
6739                             name ? name : "", addr));
6740                         ASSERT(ndi_flavor_get(child) ==
6741                             SCSA_FLAVOR_SCSI_DEVICE);
6742                         if (ndi_flavor_get(child) != SCSA_FLAVOR_SCSI_DEVICE) {
6743                                 SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
6744                                     "devinfo %s@%s not SCSI_DEVICE flavored",
6745                                     name ? name : "", addr));
6746                                 child = NULL;
6747                         }
6748                 }
6749         }
6750 
6751         if (child) {
6752                 ASSERT(child && (path == NULL));
6753 
6754                 /* Don't unconfig probe nodes. */
6755                 if (scsi_hba_devi_is_barrier(child)) {
6756                         SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
6757                             "devinfo %s@%s is_barrier, skip",
6758                             name ? name : "", addr));
6759                         return;
6760                 }
6761 
6762                 /* Attempt to offline/remove the devinfo node */
6763                 if (ndi_devi_offline(child,
6764                     NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE) == DDI_SUCCESS) {
6765                         SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
6766                             "devinfo %s@%s offlined and removed",
6767                             name ? name : "", addr));
6768                 } else if (ndi_devi_device_remove(child)) {
6769                         /* Offline/remove failed, note new device_remove */
6770                         SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
6771                             "devinfo %s@%s offline failed, device_remove",
6772                             name ? name : "", addr));
6773                 }
6774         } else if (path) {
6775                 ASSERT(path && (child == NULL));
6776 
6777                 /*
6778                  * Attempt to offline/remove the pathinfo node.
6779                  *
6780                  * NOTE: mdi_pi_offline of last path will fail if the
6781                  * device is open (i.e. the client can't be offlined).
6782                  *
6783                  * NOTE: For mdi there is no REMOVE flag for mdi_pi_offline().
6784                  * When mdi_pi_offline returns MDI_SUCCESS, we are responsible
6785                  * for remove via mdi_pi_free().
6786                  */
6787                 mdi_hold_path(path);
6788                 spathname = mdi_pi_spathname(path);     /* valid after free */
6789                 scsi_hba_devi_exit_phci(self, *circp);
6790                 rval = mdi_pi_offline(path, 0);
6791                 scsi_hba_devi_enter_phci(self, circp);
6792 
6793                 /* Note new device_remove */
6794                 if (mdi_pi_device_remove(path))
6795                         SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
6796                             "pathinfo %s note device_remove", spathname));
6797 
6798                 mdi_rele_path(path);
6799                 if (rval == MDI_SUCCESS) {
6800                         (void) mdi_pi_free(path, 0);
6801                         SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
6802                             "pathinfo %s offlined, then freed", spathname));
6803                 }
6804         } else {
6805                 ASSERT((path == NULL) && (child == NULL));
6806 
6807                 SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
6808                     "%s@%s not found", name ? name : "", addr));
6809         }
6810 }
6811 
6812 /*
6813  * configure the device at the specified "@addr" address.
6814  */
6815 static struct scsi_device *
6816 scsi_hba_bus_configone_addr(dev_info_t *self, char *addr, scsi_enum_t se)
6817 {
6818         int                     circ;
6819         struct scsi_device      *sd;
6820 
6821         scsi_hba_devi_enter(self, &circ);
6822         sd = scsi_device_config(self, NULL, addr, se, &circ, NULL);
6823         scsi_hba_devi_exit(self, circ);
6824         return (sd);
6825 }
6826 
6827 /*
6828  * unconfigure the device at the specified "@addr" address.
6829  */
6830 static void
6831 scsi_hba_bus_unconfigone_addr(dev_info_t *self, char *addr)
6832 {
6833         int                     circ;
6834 
6835         scsi_hba_devi_enter(self, &circ);
6836         (void) scsi_device_unconfig(self, NULL, addr, &circ);
6837         scsi_hba_devi_exit(self, circ);
6838 }
6839 
6840 /*
6841  * The bus_config_all operations are multi-threaded for performance. A
6842  * separate thread per target and per LUN is used. The config handle is used
6843  * to coordinate all the threads at a given level and the config thread data
6844  * contains the required information for a specific thread to identify what it
6845  * is processing and the handle under which this is being processed.
6846  */
6847 
6848 /* multi-threaded config handle */
6849 struct  scsi_hba_mte_h {
6850         dev_info_t              *h_self;        /* initiator port */
6851         int                     h_thr_count;
6852         kmutex_t                h_lock;
6853         kcondvar_t              h_cv;
6854 };
6855 
6856 /* target of 'self' config thread data */
6857 struct scsi_hba_mte_td {
6858         struct scsi_hba_mte_h   *td_h;
6859         char                    *td_taddr;      /* target port */
6860         int                     td_mt;
6861         scsi_enum_t             td_se;
6862 };
6863 
6864 /* Invoke callback on a vector of taddrs from multiple threads */
6865 static void
6866 scsi_hba_thread_taddrs(dev_info_t *self, char **taddrs, int mt,
6867     scsi_enum_t se, void (*callback)(void *arg))
6868 {
6869         struct scsi_hba_mte_h   *h;     /* HBA header */
6870         struct scsi_hba_mte_td  *td;    /* target data */
6871         char                    **taddr;
6872 
6873         /* allocate and initialize the handle */
6874         h = kmem_zalloc(sizeof (*h), KM_SLEEP);
6875         mutex_init(&h->h_lock, NULL, MUTEX_DEFAULT, NULL);
6876         cv_init(&h->h_cv, NULL, CV_DEFAULT, NULL);
6877         h->h_self = self;
6878 
6879         /* loop over all the targets */
6880         for (taddr = taddrs; *taddr; taddr++) {
6881                 /* allocate a thread data structure for target */
6882                 td = kmem_alloc(sizeof (*td), KM_SLEEP);
6883                 td->td_h = h;
6884                 td->td_taddr = *taddr;
6885                 td->td_mt = mt;
6886                 td->td_se = se;
6887 
6888                 /* process the target */
6889                 mutex_enter(&h->h_lock);
6890                 h->h_thr_count++;
6891                 mutex_exit(&h->h_lock);
6892 
6893                 if (mt & SCSI_ENUMERATION_MT_TARGET_DISABLE)
6894                         callback((void *)td);
6895                 else
6896                         (void) thread_create(NULL, 0, callback, (void *)td,
6897                             0, &p0, TS_RUN, minclsyspri);
6898         }
6899 
6900         /* wait for all the target threads to complete */
6901         mutex_enter(&h->h_lock);
6902         while (h->h_thr_count > 0)
6903                 cv_wait(&h->h_cv, &h->h_lock);
6904         mutex_exit(&h->h_lock);
6905 
6906         /* free the handle */
6907         cv_destroy(&h->h_cv);
6908         mutex_destroy(&h->h_lock);
6909         kmem_free(h, sizeof (*h));
6910 }
6911 
6912 
6913 /* lun/secondary function of lun0 config thread data */
6914 struct scsi_hba_mte_ld {
6915         struct scsi_hba_mte_h   *ld_h;
6916         char                    *ld_taddr;      /* target port */
6917         scsi_lun64_t            ld_lun64;       /* lun */
6918         int                     ld_sfunc;       /* secondary function */
6919         scsi_enum_t             ld_se;
6920 };
6921 
6922 /*
6923  * Enumerate the LUNs and secondary functions of the specified target. The
6924  * target portion of the "@addr" is already represented as a string in the
6925  * thread data, we add a ",lun" representation to this and perform a
6926  * bus_configone byte of enumeration on that "@addr".
6927  */
6928 static void
6929 scsi_hba_enum_lsf_of_tgt_thr(void *arg)
6930 {
6931         struct scsi_hba_mte_ld  *ld = (struct scsi_hba_mte_ld *)arg;
6932         struct scsi_hba_mte_h   *h = ld->ld_h;
6933         dev_info_t              *self = h->h_self;
6934         char                    addr[SCSI_MAXNAMELEN];
6935 
6936         /* make string form of "@taddr,lun[,sfunc]" and see if it exists */
6937         if (ld->ld_sfunc == -1)
6938                 (void) snprintf(addr, sizeof (addr),
6939                     "%s,%" PRIx64, ld->ld_taddr, ld->ld_lun64);
6940         else
6941                 (void) snprintf(addr, sizeof (addr),
6942                     "%s,%" PRIx64 ",%x",
6943                     ld->ld_taddr, ld->ld_lun64, ld->ld_sfunc);
6944 
6945         /* configure device at that unit-address address */
6946         (void) scsi_hba_bus_configone_addr(self, addr, ld->ld_se);
6947 
6948         /* signal completion of this LUN thread to the target */
6949         mutex_enter(&h->h_lock);
6950         if (--h->h_thr_count == 0)
6951                 cv_broadcast(&h->h_cv);
6952         mutex_exit(&h->h_lock);
6953 
6954         /* free config thread data */
6955         kmem_free(ld, sizeof (*ld));
6956 }
6957 
6958 /* Format of SCSI REPORT_LUNS report */
6959 typedef struct scsi_lunrpt {
6960         uchar_t         lunrpt_len_msb;         /* # LUNs being reported */
6961         uchar_t         lunrpt_len_mmsb;
6962         uchar_t         lunrpt_len_mlsb;
6963         uchar_t         lunrpt_len_lsb;
6964         uchar_t         lunrpt_reserved[4];
6965         scsi_lun_t      lunrpt_luns[1];         /* LUNs, variable size */
6966 } scsi_lunrpt_t;
6967 
6968 /*
6969  * scsi_device_reportluns()
6970  *
6971  * Callers of this routine should ensure that the 'sd0' scsi_device structure
6972  * and 'pi' path_instance specified are associated with a responding LUN0.
6973  * This should not be called for SCSI-1 devices.
6974  *
6975  * To get a LUN report, we must allocate a buffer. To know how big to make the
6976  * buffer, we must know the number of LUNs. To know the number of LUNs, we must
6977  * get a LUN report. We first issue a SCMD_REPORT_LUNS command using a
6978  * reasonably sized buffer that's big enough to report all LUNs for most
6979  * typical devices. If it turns out that we needed a bigger buffer, we attempt
6980  * to allocate a buffer of sufficient size, and reissue the command. If the
6981  * first command succeeds, but the second fails, we return whatever we were
6982  * able to get the first time. We return enough information for the caller to
6983  * tell whether they got all the LUNs or only a subset.
6984  *
6985  * If successful, we allocate an array of scsi_lun_t to hold the results. The
6986  * caller must kmem_free(*lunarrayp, *sizep) when finished with it. Upon
6987  * successful return return value is NDI_SUCCESS and:
6988  *
6989  *      *lunarrayp points to the allocated array,
6990  *      *nlunsp is the number of valid LUN entries in the array,
6991  *      *tlunsp is the total number of LUNs in the target,
6992  *      *sizep is the size of the lunarrayp array, which must be freed.
6993  *
6994  * If the *nlunsp is less than *tlunsp, then we were only able to retrieve a
6995  * subset of the total set of LUNs in the target.
6996  */
6997 static int
6998 scsi_device_reportluns(struct scsi_device *sd0, char *taddr, int pi,
6999     scsi_lun_t **lunarrayp, uint32_t *nlunsp, uint32_t *tlunsp, size_t *sizep)
7000 {
7001         struct buf      *lunrpt_bp;
7002         struct scsi_pkt *lunrpt_pkt;
7003         scsi_lunrpt_t   *lunrpt;
7004         uint32_t        bsize;
7005         uint32_t        tluns, nluns;
7006         int             default_maxluns = scsi_lunrpt_default_max;
7007         dev_info_t      *child;
7008 
7009         ASSERT(sd0 && lunarrayp && nlunsp && tlunsp && sizep);
7010 
7011         /*
7012          * NOTE: child should only be used in SCSI_HBA_LOG context since with
7013          * vHCI enumeration it may be the vHCI 'client' devinfo child instead
7014          * of a child of the 'self' pHCI we are enumerating.
7015          */
7016         child = sd0->sd_dev;
7017 
7018         /* first try, look for up to scsi_lunrpt_default_max LUNs */
7019         nluns = default_maxluns;
7020 
7021 again:  bsize = sizeof (struct scsi_lunrpt) +
7022             ((nluns - 1) * sizeof (struct scsi_lun));
7023 
7024         lunrpt_bp = scsi_alloc_consistent_buf(&sd0->sd_address,
7025             (struct buf *)NULL, bsize, B_READ, SLEEP_FUNC, NULL);
7026         if (lunrpt_bp == NULL) {
7027                 SCSI_HBA_LOG((_LOG(1), NULL, child, "failed alloc"));
7028                 return (NDI_NOMEM);
7029         }
7030 
7031         lunrpt_pkt = scsi_init_pkt(&sd0->sd_address,
7032             (struct scsi_pkt *)NULL, lunrpt_bp, CDB_GROUP5,
7033             sizeof (struct scsi_arq_status), 0, PKT_CONSISTENT,
7034             SLEEP_FUNC, NULL);
7035         if (lunrpt_pkt == NULL) {
7036                 SCSI_HBA_LOG((_LOG(1), NULL, child, "failed init"));
7037                 scsi_free_consistent_buf(lunrpt_bp);
7038                 return (NDI_NOMEM);
7039         }
7040 
7041         (void) scsi_setup_cdb((union scsi_cdb *)lunrpt_pkt->pkt_cdbp,
7042             SCMD_REPORT_LUNS, 0, bsize, 0);
7043 
7044         lunrpt_pkt->pkt_time = scsi_lunrpt_timeout;
7045 
7046         /*
7047          * When sd0 is a vHCI scsi device, we need reportlun to be issued
7048          * against a specific LUN0 path_instance that we are enumerating.
7049          */
7050         lunrpt_pkt->pkt_path_instance = pi;
7051         lunrpt_pkt->pkt_flags |= FLAG_PKT_PATH_INSTANCE;
7052 
7053         /*
7054          * NOTE: scsi_poll may not allow HBA specific recovery from TRAN_BUSY.
7055          */
7056         if (scsi_poll(lunrpt_pkt) < 0) {
7057                 SCSI_HBA_LOG((_LOG(2), NULL, child, "reportlun not supported"));
7058                 scsi_destroy_pkt(lunrpt_pkt);
7059                 scsi_free_consistent_buf(lunrpt_bp);
7060                 return (NDI_FAILURE);
7061         }
7062 
7063         scsi_destroy_pkt(lunrpt_pkt);
7064 
7065         lunrpt = (scsi_lunrpt_t *)lunrpt_bp->b_un.b_addr;
7066 
7067         /* Compute the total number of LUNs in the target */
7068         tluns = (((uint_t)lunrpt->lunrpt_len_msb << 24) |
7069             ((uint_t)lunrpt->lunrpt_len_mmsb << 16) |
7070             ((uint_t)lunrpt->lunrpt_len_mlsb << 8) |
7071             ((uint_t)lunrpt->lunrpt_len_lsb)) >> 3;
7072 
7073         if (tluns == 0) {
7074                 /* Illegal response -- this target is broken */
7075                 SCSI_HBA_LOG((_LOG(1), NULL, child, "illegal tluns of zero"));
7076                 scsi_free_consistent_buf(lunrpt_bp);
7077                 return (DDI_NOT_WELL_FORMED);
7078         }
7079 
7080         if (tluns > nluns) {
7081                 /* have more than we allocated space for */
7082                 if (nluns == default_maxluns) {
7083                         /* first time around, reallocate larger */
7084                         scsi_free_consistent_buf(lunrpt_bp);
7085                         nluns = tluns;
7086                         goto again;
7087                 }
7088 
7089                 /* uh oh, we got a different tluns the second time! */
7090                 SCSI_HBA_LOG((_LOG(1), NULL, child,
7091                     "tluns changed from %d to %d", nluns, tluns));
7092         } else
7093                 nluns = tluns;
7094 
7095         /*
7096          * Now we have:
7097          *      lunrpt_bp is the buffer we're using;
7098          *      tluns is the total number of LUNs the target says it has;
7099          *      nluns is the number of LUNs we were able to get into the buffer.
7100          *
7101          * Copy the data out of scarce iopb memory into regular kmem.
7102          * The caller must kmem_free(*lunarrayp, *sizep) when finished with it.
7103          */
7104         *lunarrayp = (scsi_lun_t *)kmem_alloc(
7105             nluns * sizeof (scsi_lun_t), KM_SLEEP);
7106         if (*lunarrayp == NULL) {
7107                 SCSI_HBA_LOG((_LOG(1), NULL, child, "NULL lunarray"));
7108                 scsi_free_consistent_buf(lunrpt_bp);
7109                 return (NDI_NOMEM);
7110         }
7111 
7112         *sizep = nluns * sizeof (scsi_lun_t);
7113         *nlunsp = nluns;
7114         *tlunsp = tluns;
7115         bcopy((void *)&lunrpt->lunrpt_luns, (void *)*lunarrayp, *sizep);
7116         scsi_free_consistent_buf(lunrpt_bp);
7117         SCSI_HBA_LOG((_LOG(3), NULL, child,
7118             "@%s,0 path %d: %d/%d luns", taddr, pi, nluns, tluns));
7119         return (NDI_SUCCESS);
7120 }
7121 
7122 /*
7123  * Enumerate all the LUNs and secondary functions of the specified 'taddr'
7124  * target port as accessed via 'self' pHCI.  Note that sd0 may be associated
7125  * with a child of the vHCI instead of 'self' - in this case the 'pi'
7126  * path_instance is used to ensure that the SCMD_REPORT_LUNS command is issued
7127  * through the 'self' pHCI path.
7128  *
7129  * We multi-thread across all the LUNs and secondary functions and enumerate
7130  * them. Which LUNs exist is based on SCMD_REPORT_LUNS data.
7131  *
7132  * The scsi_device we are called with should be for LUN0 and has been probed.
7133  *
7134  * This function is structured so that an HBA that has a different target
7135  * addressing structure can still use this function to enumerate the its
7136  * LUNs if it uses "taddr,lun" for its LUN space.
7137  *
7138  * We make assumptions about other LUNs associated with the target:
7139  *
7140  *      For SCSI-2 and SCSI-3 target we will issue the SCSI report_luns
7141  *      command. If this fails or we have a SCSI-1 then the number of
7142  *      LUNs is determined based on SCSI_OPTIONS_NLUNS. For a SCSI-1
7143  *      target we never probe above LUN 8, even if SCSI_OPTIONS_NLUNS
7144  *      indicates we should.
7145  *
7146  * HBA drivers wanting a different set of assumptions should implement their
7147  * own LUN enumeration code.
7148  */
7149 static int
7150 scsi_hba_enum_lsf_of_t(struct scsi_device *sd0,
7151     dev_info_t *self, char *taddr, int pi, int mt, scsi_enum_t se)
7152 {
7153         dev_info_t              *child;
7154         scsi_hba_tran_t         *tran;
7155         impl_scsi_tgtmap_t      *tgtmap;
7156         damap_id_t              tgtid;
7157         damap_t                 *tgtdam;
7158         damap_t                 *lundam = NULL;
7159         struct scsi_hba_mte_h   *h;
7160         struct scsi_hba_mte_ld  *ld;
7161         int                     aver;
7162         scsi_lun_t              *lunp = NULL;
7163         int                     lun;
7164         uint32_t                nluns;
7165         uint32_t                tluns;
7166         size_t                  size;
7167         scsi_lun64_t            lun64;
7168         int                     maxluns;
7169 
7170         /*
7171          * If LUN0 failed then we have no other LUNs.
7172          *
7173          * NOTE: We need sd_inq to be valid to check ansi version. Since
7174          * scsi_unprobe is now a noop (sd_inq freeded in
7175          * scsi_busctl_uninitchild) sd_inq remains valid even if a target
7176          * driver detach(9E) occurs, resulting in a scsi_unprobe call
7177          * (sd_uninit_prevent keeps sd_inq valid by failing any
7178          * device_uninitchild attempts).
7179          */
7180         ASSERT(sd0 && sd0->sd_uninit_prevent && sd0->sd_dev && sd0->sd_inq);
7181         if ((sd0 == NULL) || (sd0->sd_dev == NULL) || (sd0->sd_inq == NULL)) {
7182                 SCSI_HBA_LOG((_LOG(1), NULL, sd0 ? sd0->sd_dev : NULL,
7183                     "not setup correctly:%s%s%s",
7184                     (sd0 == NULL) ? " device" : "",
7185                     (sd0 && (sd0->sd_dev == NULL)) ? " dip" : "",
7186                     (sd0 && (sd0->sd_inq == NULL)) ? " inq" : ""));
7187                 return (DDI_FAILURE);
7188         }
7189 
7190         /*
7191          * NOTE: child should only be used in SCSI_HBA_LOG context since with
7192          * vHCI enumeration it may be the vHCI 'client' devinfo child instead
7193          * of a child of the 'self' pHCI we are enumerating.
7194          */
7195         child = sd0->sd_dev;
7196 
7197         /* Determine if we are reporting lun observations into lunmap. */
7198         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE);
7199         tgtmap = (impl_scsi_tgtmap_t *)tran->tran_tgtmap;
7200         if (tgtmap) {
7201                 tgtdam = tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE];
7202                 tgtid = damap_lookup(tgtdam, taddr);
7203                 if (tgtid != NODAM) {
7204                         lundam = damap_id_priv_get(tgtdam, tgtid);
7205                         damap_id_rele(tgtdam, tgtid);
7206                         ASSERT(lundam);
7207                 }
7208         }
7209 
7210         if (lundam) {
7211                 /* If using lunmap, start the observation */
7212                 scsi_lunmap_set_begin(self, lundam);
7213         } else {
7214                 /* allocate and initialize the LUN handle */
7215                 h = kmem_zalloc(sizeof (*h), KM_SLEEP);
7216                 mutex_init(&h->h_lock, NULL, MUTEX_DEFAULT, NULL);
7217                 cv_init(&h->h_cv, NULL, CV_DEFAULT, NULL);
7218                 h->h_self = self;
7219         }
7220 
7221         /* See if SCMD_REPORT_LUNS works for SCSI-2 and beyond */
7222         aver = sd0->sd_inq->inq_ansi;
7223         if ((aver >= SCSI_VERSION_2) && (scsi_device_reportluns(sd0,
7224             taddr, pi, &lunp, &nluns, &tluns, &size) == NDI_SUCCESS)) {
7225 
7226                 ASSERT(lunp && (size > 0) && (nluns > 0) && (tluns > 0));
7227 
7228                 /* loop over the reported LUNs */
7229                 SCSI_HBA_LOG((_LOG(2), NULL, child,
7230                     "@%s,0 path %d: enumerating %d reported lun%s", taddr, pi,
7231                     nluns, nluns > 1 ? "s" : ""));
7232 
7233                 for (lun = 0; lun < nluns; lun++) {
7234                         lun64 = scsi_lun_to_lun64(lunp[lun]);
7235 
7236                         if (lundam) {
7237                                 if (scsi_lunmap_set_add(self, lundam,
7238                                     taddr, lun64, -1) != DDI_SUCCESS) {
7239                                         SCSI_HBA_LOG((_LOG_NF(WARN),
7240                                             "@%s,%" PRIx64 " failed to create",
7241                                             taddr, lun64));
7242                                 }
7243                         } else {
7244                                 if (lun64 == 0)
7245                                         continue;
7246 
7247                                 /* allocate a thread data structure for LUN */
7248                                 ld = kmem_alloc(sizeof (*ld), KM_SLEEP);
7249                                 ld->ld_h = h;
7250                                 ld->ld_taddr = taddr;
7251                                 ld->ld_lun64 = lun64;
7252                                 ld->ld_sfunc = -1;
7253                                 ld->ld_se = se;
7254 
7255                                 /* process the LUN */
7256                                 mutex_enter(&h->h_lock);
7257                                 h->h_thr_count++;
7258                                 mutex_exit(&h->h_lock);
7259 
7260                                 if (mt & SCSI_ENUMERATION_MT_LUN_DISABLE)
7261                                         scsi_hba_enum_lsf_of_tgt_thr(
7262                                             (void *)ld);
7263                                 else
7264                                         (void) thread_create(NULL, 0,
7265                                             scsi_hba_enum_lsf_of_tgt_thr,
7266                                             (void *)ld, 0, &p0, TS_RUN,
7267                                             minclsyspri);
7268                         }
7269                 }
7270 
7271                 /* free the LUN array allocated by scsi_device_reportluns */
7272                 kmem_free(lunp, size);
7273         } else {
7274                 /* Determine the number of LUNs to enumerate. */
7275                 maxluns = scsi_get_scsi_maxluns(sd0);
7276 
7277                 /* Couldn't get SCMD_REPORT_LUNS data */
7278                 if (aver >= SCSI_VERSION_3) {
7279                         scsi_enumeration_failed(child, se, taddr, "report_lun");
7280 
7281                         /*
7282                          * Based on calling context tunable, only enumerate one
7283                          * lun (lun0) if scsi_device_reportluns() fails on a
7284                          * SCSI_VERSION_3 or greater device.
7285                          */
7286                         if (scsi_lunrpt_failed_do1lun & (1 << se))
7287                                 maxluns = 1;
7288                 }
7289 
7290                 /* loop over possible LUNs, skipping LUN0 */
7291                 if (maxluns > 1)
7292                         SCSI_HBA_LOG((_LOG(2), NULL, child,
7293                             "@%s,0 path %d: enumerating luns 1-%d", taddr, pi,
7294                             maxluns - 1));
7295                 else
7296                         SCSI_HBA_LOG((_LOG(2), NULL, child,
7297                             "@%s,0 path %d: enumerating just lun0", taddr, pi));
7298 
7299                 for (lun64 = 0; lun64 < maxluns; lun64++) {
7300                         if (lundam) {
7301                                 if (scsi_lunmap_set_add(self, lundam,
7302                                     taddr, lun64, -1) != DDI_SUCCESS) {
7303                                         SCSI_HBA_LOG((_LOG_NF(WARN),
7304                                             "@%s,%" PRIx64 " failed to create",
7305                                             taddr, lun64));
7306                                 }
7307                         } else {
7308                                 if (lun64 == 0)
7309                                         continue;
7310 
7311                                 /* allocate a thread data structure for LUN */
7312                                 ld = kmem_alloc(sizeof (*ld), KM_SLEEP);
7313                                 ld->ld_h = h;
7314                                 ld->ld_taddr = taddr;
7315                                 ld->ld_lun64 = lun64;
7316                                 ld->ld_sfunc = -1;
7317                                 ld->ld_se = se;
7318 
7319                                 /* process the LUN */
7320                                 mutex_enter(&h->h_lock);
7321                                 h->h_thr_count++;
7322                                 mutex_exit(&h->h_lock);
7323                                 if (mt & SCSI_ENUMERATION_MT_LUN_DISABLE)
7324                                         scsi_hba_enum_lsf_of_tgt_thr(
7325                                             (void *)ld);
7326                                 else
7327                                         (void) thread_create(NULL, 0,
7328                                             scsi_hba_enum_lsf_of_tgt_thr,
7329                                             (void *)ld, 0, &p0, TS_RUN,
7330                                             minclsyspri);
7331                         }
7332                 }
7333         }
7334 
7335         /*
7336          * If we have an embedded service as a secondary function on LUN0 and
7337          * the primary LUN0 function is different than the secondary function
7338          * then enumerate the secondary function. The sfunc value is the dtype
7339          * associated with the embedded service.
7340          *
7341          * inq_encserv: enclosure service and our dtype is not DTYPE_ESI
7342          * or DTYPE_UNKNOWN then create a separate DTYPE_ESI node for
7343          * enclosure service access.
7344          */
7345         ASSERT(sd0->sd_inq);
7346         if (sd0->sd_inq->inq_encserv &&
7347             ((sd0->sd_inq->inq_dtype & DTYPE_MASK) != DTYPE_UNKNOWN) &&
7348             ((sd0->sd_inq->inq_dtype & DTYPE_MASK) != DTYPE_ESI) &&
7349             ((sd0->sd_inq->inq_ansi >= SCSI_VERSION_3))) {
7350                 if (lundam) {
7351                         if (scsi_lunmap_set_add(self, lundam,
7352                             taddr, 0, DTYPE_ESI) != DDI_SUCCESS) {
7353                                 SCSI_HBA_LOG((_LOG_NF(WARN),
7354                                     "@%s,0,%x failed to create",
7355                                     taddr, DTYPE_ESI));
7356                         }
7357                 } else {
7358                         /* allocate a thread data structure for sfunc */
7359                         ld = kmem_alloc(sizeof (*ld), KM_SLEEP);
7360                         ld->ld_h = h;
7361                         ld->ld_taddr = taddr;
7362                         ld->ld_lun64 = 0;
7363                         ld->ld_sfunc = DTYPE_ESI;
7364                         ld->ld_se = se;
7365 
7366                         /* process the LUN */
7367                         mutex_enter(&h->h_lock);
7368                         h->h_thr_count++;
7369                         mutex_exit(&h->h_lock);
7370                         if (mt & SCSI_ENUMERATION_MT_LUN_DISABLE)
7371                                 scsi_hba_enum_lsf_of_tgt_thr((void *)ld);
7372                         else
7373                                 (void) thread_create(NULL, 0,
7374                                     scsi_hba_enum_lsf_of_tgt_thr, (void *)ld,
7375                                     0, &p0, TS_RUN, minclsyspri);
7376                 }
7377         }
7378 
7379         /*
7380          * Future: Add secondary function support for:
7381          *      inq_mchngr (DTYPE_CHANGER)
7382          *      inq_sccs (DTYPE_ARRAY_CTRL)
7383          */
7384 
7385         if (lundam) {
7386                 /* If using lunmap, end the observation */
7387                 scsi_lunmap_set_end(self, lundam);
7388         } else {
7389                 /* wait for all the LUN threads of this target to complete */
7390                 mutex_enter(&h->h_lock);
7391                 while (h->h_thr_count > 0)
7392                         cv_wait(&h->h_cv, &h->h_lock);
7393                 mutex_exit(&h->h_lock);
7394 
7395                 /* free the target handle */
7396                 cv_destroy(&h->h_cv);
7397                 mutex_destroy(&h->h_lock);
7398                 kmem_free(h, sizeof (*h));
7399         }
7400 
7401         return (DDI_SUCCESS);
7402 }
7403 
7404 /*
7405  * Enumerate LUN0 and all other LUNs and secondary functions associated with
7406  * the specified target address.
7407  *
7408  * Return NDI_SUCCESS if we might have created a new node.
7409  * Return NDI_FAILURE if we definitely did not create a new node.
7410  */
7411 static int
7412 scsi_hba_bus_config_taddr(dev_info_t *self, char *taddr, int mt, scsi_enum_t se)
7413 {
7414         char                    addr[SCSI_MAXNAMELEN];
7415         struct scsi_device      *sd;
7416         int                     circ;
7417         int                     ret;
7418         int                     pi;
7419 
7420         /* See if LUN0 of the specified target exists. */
7421         (void) snprintf(addr, sizeof (addr), "%s,0", taddr);
7422 
7423         scsi_hba_devi_enter(self, &circ);
7424         sd = scsi_device_config(self, NULL, addr, se, &circ, &pi);
7425 
7426         if (sd) {
7427                 /*
7428                  * LUN0 exists, enumerate all the other LUNs.
7429                  *
7430                  * With vHCI enumeration, when 'self' is a pHCI the sd
7431                  * scsi_device may be associated with the vHCI 'client'.
7432                  * In this case 'pi' is the path_instance needed to
7433                  * continue enumeration communication LUN0 via 'self'
7434                  * pHCI and specific 'taddr' target address.
7435                  *
7436                  * We prevent the removal of LUN0 until we are done with
7437                  * prevent/allow because we must exit the parent for
7438                  * multi-threaded scsi_hba_enum_lsf_of_t().
7439                  *
7440                  * NOTE: scsi_unprobe is a noop, sd->sd_inq is valid until
7441                  * device_uninitchild - so sd_uninit_prevent keeps sd_inq valid
7442                  * by failing any device_uninitchild attempts.
7443                  */
7444                 ret = NDI_SUCCESS;
7445                 sd->sd_uninit_prevent++;
7446                 scsi_hba_devi_exit(self, circ);
7447 
7448                 (void) scsi_hba_enum_lsf_of_t(sd, self, taddr, pi, mt, se);
7449 
7450                 scsi_hba_devi_enter(self, &circ);
7451                 sd->sd_uninit_prevent--;
7452         } else
7453                 ret = NDI_FAILURE;
7454         scsi_hba_devi_exit(self, circ);
7455         return (ret);
7456 }
7457 
7458 /* Config callout from scsi_hba_thread_taddrs */
7459 static void
7460 scsi_hba_taddr_config_thr(void *arg)
7461 {
7462         struct scsi_hba_mte_td  *td = (struct scsi_hba_mte_td *)arg;
7463         struct scsi_hba_mte_h   *h = td->td_h;
7464 
7465         (void) scsi_hba_bus_config_taddr(h->h_self, td->td_taddr,
7466             td->td_mt, td->td_se);
7467 
7468         /* signal completion of this target thread to the HBA */
7469         mutex_enter(&h->h_lock);
7470         if (--h->h_thr_count == 0)
7471                 cv_broadcast(&h->h_cv);
7472         mutex_exit(&h->h_lock);
7473 
7474         /* free config thread data */
7475         kmem_free(td, sizeof (*td));
7476 }
7477 
7478 /*
7479  * Enumerate all the children of the specified SCSI parallel interface (spi).
7480  * An HBA associated with a non-parallel scsi bus should be using another bus
7481  * level enumeration implementation (possibly their own) and calling
7482  * scsi_hba_bus_config_taddr to do enumeration of devices associated with a
7483  * particular target address.
7484  *
7485  * On an spi bus the targets are sequentially enumerated based on the
7486  * width of the bus. We also take care to try to skip the HBAs own initiator
7487  * id. See scsi_hba_enum_lsf_of_t() for LUN and secondary function enumeration.
7488  *
7489  * Return NDI_SUCCESS if we might have created a new node.
7490  * Return NDI_FAILURE if we definitely did not create a new node.
7491  *
7492  * Note: At some point we may want to expose this interface in transport.h
7493  * if we find an hba that implements bus_config but still uses spi-like target
7494  * addresses.
7495  */
7496 static int
7497 scsi_hba_bus_configall_spi(dev_info_t *self, int mt)
7498 {
7499         int     options;
7500         int     ntargets;
7501         int     id;
7502         int     tgt;
7503         char    **taddrs;
7504         char    **taddr;
7505         char    *tbuf;
7506 
7507         /*
7508          * Find the number of targets supported on the bus. Look at the per
7509          * bus scsi-options property on the HBA node and check its
7510          * SCSI_OPTIONS_WIDE setting.
7511          */
7512         options = ddi_prop_get_int(DDI_DEV_T_ANY, self,
7513             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-options", -1);
7514         if ((options != -1) && ((options & SCSI_OPTIONS_WIDE) == 0))
7515                 ntargets = NTARGETS;                    /* 8 */
7516         else
7517                 ntargets = NTARGETS_WIDE;               /* 16 */
7518 
7519         /*
7520          * Find the initiator-id for the HBA so we can skip that. We get the
7521          * cached value on the HBA node, established in scsi_hba_attach_setup.
7522          * If we were unable to determine the id then we rely on the HBA to
7523          * fail gracefully when asked to enumerate itself.
7524          */
7525         id = ddi_prop_get_int(DDI_DEV_T_ANY, self,
7526             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-initiator-id", -1);
7527         if (id > ntargets) {
7528                 SCSI_HBA_LOG((_LOG(1), self, NULL,
7529                     "'scsi-initiator-id' bogus for %d target bus: %d",
7530                     ntargets, id));
7531                 id = -1;
7532         }
7533         SCSI_HBA_LOG((_LOG(2), self, NULL,
7534             "enumerating targets 0-%d skip %d", ntargets, id));
7535 
7536         /* form vector of target addresses */
7537         taddrs = kmem_zalloc(sizeof (char *) * (ntargets + 1), KM_SLEEP);
7538         for (tgt = 0, taddr = taddrs; tgt < ntargets; tgt++) {
7539                 /* skip initiator */
7540                 if (tgt == id)
7541                         continue;
7542 
7543                 /* convert to string and enumerate the target address */
7544                 tbuf = kmem_alloc(((tgt/16) + 1) + 1, KM_SLEEP);
7545                 (void) sprintf(tbuf, "%x", tgt);
7546                 ASSERT(strlen(tbuf) == ((tgt/16) + 1));
7547                 *taddr++ = tbuf;
7548         }
7549 
7550         /* null terminate vector of target addresses */
7551         *taddr = NULL;
7552 
7553         /* configure vector of target addresses */
7554         scsi_hba_thread_taddrs(self, taddrs, mt, SE_BUSCONFIG,
7555             scsi_hba_taddr_config_thr);
7556 
7557         /* free vector of target addresses */
7558         for (taddr = taddrs; *taddr; taddr++)
7559                 kmem_free(*taddr, strlen(*taddr) + 1);
7560         kmem_free(taddrs, sizeof (char *) * (ntargets + 1));
7561         return (NDI_SUCCESS);
7562 }
7563 
7564 /*
7565  * Transport independent bus_configone BUS_CONFIG_ONE implementation.  Takes
7566  * same arguments, minus op, as scsi_hba_bus_config(), tran_bus_config(),
7567  * and scsi_hba_bus_config_spi().
7568  */
7569 int
7570 scsi_hba_bus_configone(dev_info_t *self, uint_t flags, char *arg,
7571     dev_info_t **childp)
7572 {
7573         int                     ret;
7574         int                     circ;
7575         char                    *name, *addr;
7576         char                    *lcp;
7577         char                    sc1, sc2;
7578         char                    nameaddr[SCSI_MAXNAMELEN];
7579         extern int              i_ndi_make_spec_children(dev_info_t *, uint_t);
7580         struct scsi_device      *sd0, *sd;
7581         scsi_lun64_t            lun64;
7582         int                     mt;
7583 
7584         /* parse_name modifies arg1, we must duplicate "name@addr" */
7585         (void) strcpy(nameaddr, arg);
7586         i_ddi_parse_name(nameaddr, &name, &addr, NULL);
7587 
7588         /* verify the form of the node - we need an @addr */
7589         if ((name == NULL) || (addr == NULL) ||
7590             (*name == '\0') || (*addr == '\0')) {
7591                 /*
7592                  * OBP may create ill formed template/stub/wild-card
7593                  * nodes (no @addr) for legacy driver loading methods -
7594                  * ignore them.
7595                  */
7596                 SCSI_HBA_LOG((_LOG(2), self, NULL, "%s ill formed", arg));
7597                 return (NDI_FAILURE);
7598         }
7599 
7600         /*
7601          * Check to see if this is a non-scsi flavor configuration operation.
7602          */
7603         if (strcmp(name, "smp") == 0) {
7604                 /*
7605                  * Configure the child, and if we're successful return with
7606                  * active hold.
7607                  */
7608                 return (smp_hba_bus_config(self, addr, childp));
7609         }
7610 
7611         /*
7612          * The framework does not ensure the creation of driver.conf
7613          * nodes prior to calling a nexus bus_config. For legacy
7614          * support of driver.conf file nodes we want to create our
7615          * driver.conf file children now so that we can detect if we
7616          * are being asked to bus_configone one of these nodes.
7617          *
7618          * Needing driver.conf file nodes prior to bus config is unique
7619          * to scsi_enumeration mixed mode (legacy driver.conf and
7620          * dynamic SID node) support. There is no general need for the
7621          * framework to make driver.conf children prior to bus_config.
7622          *
7623          * We enter our HBA (self) prior to scsi_device_config, and
7624          * pass it our circ. The scsi_device_config may exit the
7625          * HBA around scsi_probe() operations to allow for parallelism.
7626          * This is done after the probe node "@addr" is available as a
7627          * barrier to prevent parallel probes of the same device. The
7628          * probe node is also configured in a way that it can't be
7629          * removed by the framework until we are done with it.
7630          *
7631          * NOTE: The framework is currently preventing many parallel
7632          * sibling operations (such as attaches), so the parallelism
7633          * we are providing is of marginal use until that is improved.
7634          * The most logical way to solve this would be to have separate
7635          * target and lun nodes. This would be a large change in the
7636          * format of /devices paths and is not being pursued at this
7637          * time. The need for parallelism will become more of an issue
7638          * with top-down attach for mpxio/vhci and for iSCSI support.
7639          * We may want to eventually want a dual mode implementation,
7640          * where the HBA determines if we should construct separate
7641          * target and lun devinfo nodes.
7642          */
7643         scsi_hba_devi_enter(self, &circ);
7644         SCSI_HBA_LOG((_LOG(4), self, NULL, "%s@%s config_one", name, addr));
7645         (void) i_ndi_make_spec_children(self, flags);
7646 
7647         /*
7648          * For bus_configone, we make sure that we can find LUN0
7649          * first. This allows the delayed probe/barrier deletion for a
7650          * non-existent LUN0 (if enabled in scsi_device_config) to
7651          * cover all LUNs on the target. This is done to minimize the
7652          * number of independent target selection timeouts that occur
7653          * when a target with many LUNs is no longer accessible
7654          * (powered off). This removes the need for target driver
7655          * probe cache implementations.
7656          *
7657          * This optimization may not be desirable in a pure bridge
7658          * environment where targets on the other side of the bridge
7659          * show up as LUNs to the host. If we ever need to support
7660          * such a configuration then we should consider implementing a
7661          * SCSI_OPTIONS_ILUN0 bit.
7662          *
7663          * NOTE: we are *not* applying any target limitation filtering
7664          * to bus_configone, which means that we are relying on the
7665          * HBA tran_tgt_init entry point invoked by scsi_busctl_initchild
7666          * to fail.
7667          */
7668         sd0 = (struct scsi_device *)-1;
7669         lcp = strchr(addr, ',');                /* "addr,lun[,sfunc]" */
7670         if (lcp) {
7671                 /*
7672                  * With "tgt,lun[,sfunc]" addressing, multiple addressing levels
7673                  * have been compressed into single devinfo node unit-address.
7674                  * This presents a mismatch - there is no bus_config to discover
7675                  * LUNs below a specific target, the only choice is to
7676                  * BUS_CONFIG_ALL the HBA. To support BUS_CONFIG_ALL_LUNS below
7677                  * a specific target, a bus_configone with lun address of "*"
7678                  * triggers lun discovery below a target.
7679                  */
7680                 if (*(lcp + 1) == '*') {
7681                         mt = ddi_prop_get_int(DDI_DEV_T_ANY, self,
7682                             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
7683                             "scsi-enumeration", scsi_enumeration);
7684                         mt |= scsi_hba_log_mt_disable;
7685 
7686                         SCSI_HBA_LOG((_LOG(2), self, NULL,
7687                             "%s@%s lun enumeration triggered", name, addr));
7688                         *lcp = '\0';            /* turn ',' into '\0' */
7689                         scsi_hba_devi_exit(self, circ);
7690                         (void) scsi_hba_bus_config_taddr(self, addr,
7691                             mt, SE_BUSCONFIG);
7692                         return (NDI_FAILURE);
7693                 }
7694 
7695                 /* convert hex lun number from ascii */
7696                 lun64 = scsi_addr_to_lun64(lcp + 1);
7697 
7698                 if ((lun64 != 0) && (lun64 != SCSI_LUN64_ILLEGAL)) {
7699                         /*
7700                          * configure ",0" lun first, saving off
7701                          * original lun characters.
7702                          */
7703                         sc1 = *(lcp + 1);
7704                         sc2 = *(lcp + 2);
7705                         *(lcp + 1) = '0';
7706                         *(lcp + 2) = '\0';
7707                         sd0 = scsi_device_config(self,
7708                             NULL, addr, SE_BUSCONFIG, &circ, NULL);
7709 
7710                         /* restore original lun */
7711                         *(lcp + 1) = sc1;
7712                         *(lcp + 2) = sc2;
7713 
7714                         /*
7715                          * Apply maxlun filtering.
7716                          *
7717                          * Future: We still have the kludged
7718                          * scsi_check_ss2_LUN_limit() filtering off
7719                          * scsi_probe() to catch bogus driver.conf
7720                          * entries.
7721                          */
7722                         if (sd0 && (lun64 < SCSI_32LUNS_PER_TARGET) &&
7723                             (lun64 >= scsi_get_scsi_maxluns(sd0))) {
7724                                 sd0 = NULL;
7725                                 SCSI_HBA_LOG((_LOG(4), self, NULL,
7726                                     "%s@%s filtered", name, addr));
7727                         } else
7728                                 SCSI_HBA_LOG((_LOG(4), self, NULL,
7729                                     "%s@%s lun 0 %s", name, addr,
7730                                     sd0 ? "worked" : "failed"));
7731                 }
7732         }
7733 
7734         /*
7735          * configure the requested device if LUN0 exists or we were
7736          * unable to determine the lun format to determine if LUN0
7737          * exists.
7738          */
7739         if (sd0) {
7740                 sd = scsi_device_config(self,
7741                     name, addr, SE_BUSCONFIG, &circ, NULL);
7742         } else {
7743                 sd = NULL;
7744                 SCSI_HBA_LOG((_LOG(2), self, NULL,
7745                     "%s@%s no lun 0 or filtered lun", name, addr));
7746         }
7747 
7748         /*
7749          * We know what we found, to reduce overhead we finish BUS_CONFIG_ONE
7750          * processing without calling back to the frameworks
7751          * ndi_busop_bus_config (unless we goto framework below).
7752          *
7753          * If the reference is to a driver name and we created a generic name
7754          * (bound to that driver) we will still succeed.  This is important
7755          * for correctly resolving old drivername references to device that now
7756          * uses a generic names across the transition to generic naming. This
7757          * is effectively an internal implementation of the NDI_DRIVERNAME flag.
7758          *
7759          * We also need to special case the resolve_pathname OBP boot-device
7760          * case (modrootloaded == 0) where reference is to a generic name but
7761          * we created a legacy driver name node by returning just returning
7762          * the node created.
7763          */
7764         if (sd && sd->sd_dev &&
7765             ((strcmp(ddi_node_name(sd->sd_dev), name) == 0) ||
7766             (strcmp(ddi_driver_name(sd->sd_dev), name) == 0) ||
7767             (modrootloaded == 0)) &&
7768             (ndi_devi_online(sd->sd_dev,
7769             flags & NDI_NO_EVENT) == NDI_SUCCESS)) {
7770 
7771                 /* device attached, return devinfo node with hold */
7772                 ret = NDI_SUCCESS;
7773                 *childp = sd->sd_dev;
7774                 ndi_hold_devi(sd->sd_dev);
7775         } else {
7776                 /*
7777                  * In the process of failing we may have added nodes to the HBA
7778                  * (self), clearing DEVI_MADE_CHILDREN. To reduce the overhead
7779                  * associated with the frameworks reaction to this we clear the
7780                  * flag here.
7781                  */
7782                 mutex_enter(&DEVI(self)->devi_lock);
7783                 DEVI(self)->devi_flags &= ~DEVI_MADE_CHILDREN;
7784                 mutex_exit(&DEVI(self)->devi_lock);
7785                 ret = NDI_FAILURE;
7786 
7787                 /*
7788                  * The framework may still be able to succeed with
7789                  * with its GENERIC_PROP code.
7790                  */
7791                 scsi_hba_devi_exit(self, circ);
7792                 if (flags & NDI_DRV_CONF_REPROBE)
7793                         flags |= NDI_CONFIG_REPROBE;
7794                 flags |= NDI_MDI_FALLBACK;      /* devinfo&pathinfo children */
7795                 return (ndi_busop_bus_config(self, flags, BUS_CONFIG_ONE,
7796                     (void *)arg, childp, 0));
7797         }
7798 
7799         scsi_hba_devi_exit(self, circ);
7800         return (ret);
7801 }
7802 
7803 /*
7804  * Perform SCSI Parallel Interconnect bus_config
7805  */
7806 static int
7807 scsi_hba_bus_config_spi(dev_info_t *self, uint_t flags,
7808     ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
7809 {
7810         int                     ret;
7811         int                     mt;
7812 
7813         /*
7814          * Enumerate scsi target devices: See if we are doing generic dynamic
7815          * enumeration: if driver.conf has not specified the 'scsi-enumeration'
7816          * knob then use the global scsi_enumeration knob.
7817          */
7818         mt = ddi_prop_get_int(DDI_DEV_T_ANY, self,
7819             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
7820             "scsi-enumeration", scsi_enumeration);
7821         mt |= scsi_hba_log_mt_disable;
7822 
7823         if ((mt & SCSI_ENUMERATION_ENABLE) == 0) {
7824                 /*
7825                  * Static driver.conf file enumeration:
7826                  *
7827                  * Force reprobe for BUS_CONFIG_ONE or when manually
7828                  * reconfiguring via devfsadm(1m) to emulate deferred attach.
7829                  * Reprobe only discovers driver.conf enumerated nodes, more
7830                  * dynamic implementations probably require their own
7831                  * bus_config.
7832                  */
7833                 if ((op == BUS_CONFIG_ONE) || (flags & NDI_DRV_CONF_REPROBE))
7834                         flags |= NDI_CONFIG_REPROBE;
7835                 flags |= NDI_MDI_FALLBACK;      /* devinfo&pathinfo children */
7836                 return (ndi_busop_bus_config(self, flags, op, arg, childp, 0));
7837         }
7838 
7839         if (scsi_hba_bus_config_debug)
7840                 flags |= NDI_DEVI_DEBUG;
7841 
7842         /*
7843          * Generic spi dynamic bus config enumeration to discover and enumerate
7844          * the target device nodes we are looking for.
7845          */
7846         switch (op) {
7847         case BUS_CONFIG_ONE:    /* enumerate the named child */
7848                 ret = scsi_hba_bus_configone(self, flags, (char *)arg, childp);
7849                 break;
7850 
7851         case BUS_CONFIG_ALL:    /* enumerate all children on the bus */
7852         case BUS_CONFIG_DRIVER: /* enumerate all children that bind to driver */
7853                 SCSI_HBA_LOG((_LOG(3), self, NULL,
7854                     "BUS_CONFIG_%s mt %x",
7855                     (op == BUS_CONFIG_ALL) ? "ALL" : "DRIVER", mt));
7856 
7857                 /*
7858                  * Enumerate targets on SCSI parallel interconnect and let the
7859                  * framework finish the operation (attach the nodes).
7860                  */
7861                 if ((ret = scsi_hba_bus_configall_spi(self, mt)) == NDI_SUCCESS)
7862                         ret = ndi_busop_bus_config(self, flags, op,
7863                             arg, childp, 0);
7864                 break;
7865 
7866         default:
7867                 ret = NDI_FAILURE;
7868                 break;
7869         }
7870         return (ret);
7871 }
7872 
7873 /*
7874  * Perform SCSI Parallel Interconnect bus_unconfig
7875  */
7876 static int
7877 scsi_hba_bus_unconfig_spi(dev_info_t *self, uint_t flags,
7878     ddi_bus_config_op_t op, void *arg)
7879 {
7880         int     mt;
7881         int     circ;
7882         int     ret;
7883 
7884         /*
7885          * See if we are doing generic dynamic enumeration: if driver.conf has
7886          * not specified the 'scsi-enumeration' knob then use the global
7887          * scsi_enumeration knob.
7888          */
7889         mt = ddi_prop_get_int(DDI_DEV_T_ANY, self,
7890             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
7891             "scsi-enumeration", scsi_enumeration);
7892         mt |= scsi_hba_log_mt_disable;
7893 
7894         if ((mt & SCSI_ENUMERATION_ENABLE) == 0)
7895                 return (ndi_busop_bus_unconfig(self, flags, op, arg));
7896 
7897         if (scsi_hba_bus_config_debug)
7898                 flags |= NDI_DEVI_DEBUG;
7899 
7900         scsi_hba_devi_enter(self, &circ);
7901         switch (op) {
7902         case BUS_UNCONFIG_ONE:
7903                 SCSI_HBA_LOG((_LOG(3), self, NULL,
7904                     "unconfig one: %s", (char *)arg));
7905                 ret = NDI_SUCCESS;
7906                 break;
7907 
7908         case BUS_UNCONFIG_ALL:
7909         case BUS_UNCONFIG_DRIVER:
7910                 ret = NDI_SUCCESS;
7911                 break;
7912 
7913         default:
7914                 ret = NDI_FAILURE;
7915                 break;
7916         }
7917 
7918         /* Perform the generic default bus unconfig */
7919         if (ret == NDI_SUCCESS)
7920                 ret = ndi_busop_bus_unconfig(self, flags, op, arg);
7921 
7922         scsi_hba_devi_exit(self, circ);
7923 
7924         return (ret);
7925 }
7926 
7927 static int
7928 scsi_hba_bus_config_tgtmap(dev_info_t *self, uint_t flags,
7929     ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
7930 {
7931         scsi_hba_tran_t         *tran;
7932         impl_scsi_tgtmap_t      *tgtmap;
7933         uint64_t                tsa = 0;        /* clock64_t */
7934         int                     maxdev;
7935         int                     sync_usec;
7936         int                     synced;
7937         int                     ret = NDI_FAILURE;
7938 
7939         if ((op != BUS_CONFIG_ONE) && (op != BUS_CONFIG_ALL) &&
7940             (op != BUS_CONFIG_DRIVER))
7941                 goto out;
7942 
7943         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE);
7944         tgtmap = (impl_scsi_tgtmap_t *)tran->tran_tgtmap;
7945         ASSERT(tgtmap);
7946 
7947         /*
7948          * MPXIO is never a sure thing (and we have mixed children), so
7949          * set NDI_NDI_FALLBACK so that ndi_busop_bus_config will
7950          * search for both devinfo and pathinfo children.
7951          *
7952          * Future: Remove NDI_MDI_FALLBACK since devcfg.c now looks for
7953          * devinfo/pathinfo children in parallel (instead of old way of
7954          * looking for one form of child and then doing "fallback" to
7955          * look for other form of child).
7956          */
7957         flags |= NDI_MDI_FALLBACK;      /* devinfo&pathinfo children */
7958 
7959         /*
7960          * If bus_config occurred within the map create-to-hotplug_sync window,
7961          * we need the framework to wait for children that are physicaly
7962          * present at map create time to show up (via tgtmap hotplug config).
7963          *
7964          * The duration of this window is specified by the HBA driver at
7965          * scsi_hba_tgtmap_create(9F) time (during attach(9E)). Its
7966          * 'csync_usec' value is selected based on how long it takes the HBA
7967          * driver to get from map creation to initial observation for something
7968          * already plugged in. Estimate high, a low estimate can result in
7969          * devices not showing up correctly on first reference. The call to
7970          * ndi_busop_bus_config needs a timeout value large enough so that
7971          * the map sync call further down is not a noop (i.e. done against
7972          * an empty map when something is infact plugged in). With
7973          * BUS_CONFIG_ONE, the call to ndi_busop_bus_config will return as
7974          * soon as the desired device is enumerated via hotplug - so we are
7975          * not committed to waiting the entire time.
7976          *
7977          * We are typically outside the window, so timeout is 0.
7978          */
7979         sync_usec = tgtmap->tgtmap_create_csync_usec;
7980         if (tgtmap->tgtmap_create_window) {
7981                 tsa = ddi_get_lbolt64() - tgtmap->tgtmap_create_time;
7982                 if (tsa < drv_usectohz(sync_usec)) {
7983                         tsa = drv_usectohz(sync_usec) - tsa;
7984                         ret = ndi_busop_bus_config(self,
7985                             flags, op, arg, childp, (clock_t)tsa);
7986                 } else
7987                         tsa = 0;        /* passed window */
7988 
7989                 /* First one out closes the window. */
7990                 tgtmap->tgtmap_create_window = 0;
7991         } else if (op == BUS_CONFIG_ONE)
7992                 ret = ndi_busop_bus_config(self, flags, op, arg, childp, 0);
7993 
7994         /* Return if doing a BUS_CONFIG_ONE and we found what we want. */
7995         if ((op == BUS_CONFIG_ONE) && (ret == NDI_SUCCESS))
7996                 goto out;               /* performance path */
7997 
7998         /*
7999          * We sync if we were in the window, on the first bus_config_one, and
8000          * every bus_config_all (or bus_config_driver).
8001          */
8002         if (tsa || (tgtmap->tgtmap_sync_cnt == 0) ||
8003             (op != BUS_CONFIG_ONE)) {
8004                 /*
8005                  * Sync current observations in the map and look again.  We
8006                  * place an upper bound on the amount of time we will wait for
8007                  * sync to complete to avoid a bad device causing this
8008                  * busconfig operation to hang.
8009                  *
8010                  * We are typically stable, so damap_sync returns immediately.
8011                  *
8012                  * Max time to wait for sync is settle_usec per possible device.
8013                  */
8014                 tgtmap->tgtmap_sync_cnt++;
8015                 maxdev = damap_size(tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]);
8016                 maxdev = (maxdev > scsi_hba_map_settle_f) ? maxdev :
8017                     scsi_hba_map_settle_f;
8018                 sync_usec = maxdev * tgtmap->tgtmap_settle_usec;
8019                 synced = scsi_tgtmap_sync((scsi_hba_tgtmap_t *)tgtmap,
8020                     sync_usec);
8021                 if (!synced)
8022                         SCSI_HBA_LOG((_LOGCFG, self, NULL,
8023                             "tgtmap_sync timeout"));
8024         } else
8025                 synced = -1;
8026 
8027         if (op == BUS_CONFIG_ONE)
8028                 ret = scsi_hba_bus_configone(self, flags, arg, childp);
8029         else
8030                 ret = ndi_busop_bus_config(self, flags, op, arg, childp, 0);
8031 
8032 out:
8033 #ifdef  DEBUG
8034         if (ret != NDI_SUCCESS) {
8035                 if (scsi_hba_bus_config_failure_msg ||
8036                     scsi_hba_bus_config_failure_dbg) {
8037                         scsi_hba_bus_config_failure_msg--;
8038                         printf("%s%d: bus_config_tgtmap %p failure on %s: "
8039                             "%d %d\n",
8040                             ddi_driver_name(self), ddi_get_instance(self),
8041                             (void *)tgtmap,
8042                             (op == BUS_CONFIG_ONE) ? (char *)arg : "ALL",
8043                             (int)tsa, synced);
8044                 }
8045                 if (scsi_hba_bus_config_failure_dbg) {
8046                         scsi_hba_bus_config_failure_dbg--;
8047                         debug_enter("config_tgtmap failure");
8048                 }
8049         } else if (scsi_hba_bus_config_success_msg ||
8050             scsi_hba_bus_config_success_dbg) {
8051                 scsi_hba_bus_config_success_msg--;
8052                 printf("%s%d: bus_config_tgtmap %p success on %s: %d %d\n",
8053                     ddi_driver_name(self), ddi_get_instance(self),
8054                     (void *)tgtmap,
8055                     (op == BUS_CONFIG_ONE) ? (char *)arg : "ALL",
8056                     (int)tsa, synced);
8057                 if (scsi_hba_bus_config_success_dbg) {
8058                         scsi_hba_bus_config_success_dbg--;
8059                         debug_enter("config_tgtmap success");
8060                 }
8061         }
8062 #endif  /* DEBUG */
8063         return (ret);
8064 }
8065 
8066 static int
8067 scsi_hba_bus_unconfig_tgtmap(dev_info_t *self, uint_t flags,
8068     ddi_bus_config_op_t op, void *arg)
8069 {
8070         int ret = NDI_FAILURE;
8071 
8072         switch (op) {
8073         case BUS_UNCONFIG_ONE:
8074         case BUS_UNCONFIG_DRIVER:
8075         case BUS_UNCONFIG_ALL:
8076                 ret = NDI_SUCCESS;
8077                 break;
8078         default:
8079                 break;
8080         }
8081 
8082         if (ret == NDI_SUCCESS) {
8083                 flags &= ~NDI_DEVI_REMOVE;
8084                 ret = ndi_busop_bus_unconfig(self, flags, op, arg);
8085         }
8086         return (ret);
8087 }
8088 
8089 static int
8090 scsi_hba_bus_config_iportmap(dev_info_t *self, uint_t flags,
8091     ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
8092 {
8093         scsi_hba_tran_t         *tran;
8094         impl_scsi_iportmap_t    *iportmap;
8095         dev_info_t              *child;
8096         int                     circ;
8097         uint64_t                tsa = 0;        /* clock64_t */
8098         int                     sync_usec;
8099         int                     synced;
8100         int                     ret = NDI_FAILURE;
8101 
8102         if ((op != BUS_CONFIG_ONE) && (op != BUS_CONFIG_ALL) &&
8103             (op != BUS_CONFIG_DRIVER))
8104                 goto out;
8105 
8106         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE);
8107         iportmap = (impl_scsi_iportmap_t *)tran->tran_iportmap;
8108         ASSERT(iportmap);
8109 
8110         /*
8111          * MPXIO is never a sure thing (and we have mixed children), so
8112          * set NDI_NDI_FALLBACK so that ndi_busop_bus_config will
8113          * search for both devinfo and pathinfo children.
8114          *
8115          * Future: Remove NDI_MDI_FALLBACK since devcfg.c now looks for
8116          * devinfo/pathinfo children in parallel (instead of old way of
8117          * looking for one form of child and then doing "fallback" to
8118          * look for other form of child).
8119          */
8120         flags |= NDI_MDI_FALLBACK;      /* devinfo&pathinfo children */
8121 
8122         /*
8123          * If bus_config occurred within the map create-to-hotplug_sync window,
8124          * we need the framework to wait for children that are physicaly
8125          * present at map create time to show up (via iportmap hotplug config).
8126          *
8127          * The duration of this window is specified by the HBA driver at
8128          * scsi_hba_iportmap_create(9F) time (during attach(9E)). Its
8129          * 'csync_usec' value is selected based on how long it takes the HBA
8130          * driver to get from map creation to initial observation for something
8131          * already plugged in. Estimate high, a low estimate can result in
8132          * devices not showing up correctly on first reference. The call to
8133          * ndi_busop_bus_config needs a timeout value large enough so that
8134          * the map sync call further down is not a noop (i.e. done against
8135          * an empty map when something is infact plugged in). With
8136          * BUS_CONFIG_ONE, the call to ndi_busop_bus_config will return as
8137          * soon as the desired device is enumerated via hotplug - so we are
8138          * not committed to waiting the entire time.
8139          *
8140          * We are typically outside the window, so timeout is 0.
8141          */
8142         sync_usec = iportmap->iportmap_create_csync_usec;
8143         if (iportmap->iportmap_create_window) {
8144                 tsa = ddi_get_lbolt64() - iportmap->iportmap_create_time;
8145                 if (tsa < drv_usectohz(sync_usec)) {
8146                         tsa = drv_usectohz(sync_usec) - tsa;
8147                         ret = ndi_busop_bus_config(self,
8148                             flags, op, arg, childp, (clock_t)tsa);
8149                 } else
8150                         tsa = 0;        /* passed window */
8151 
8152                 /* First one out closes the window. */
8153                 iportmap->iportmap_create_window = 0;
8154         } else if (op == BUS_CONFIG_ONE)
8155                 ret = ndi_busop_bus_config(self, flags, op, arg, childp, 0);
8156 
8157         /* Return if doing a BUS_CONFIG_ONE and we found what we want. */
8158         if ((op == BUS_CONFIG_ONE) && (ret == NDI_SUCCESS))
8159                 goto out;               /* performance path */
8160 
8161         /*
8162          * We sync if we were in the window, on the first bus_config_one, and
8163          * every bus_config_all (or bus_config_driver).
8164          */
8165         if (tsa || (iportmap->iportmap_sync_cnt == 0) ||
8166             (op != BUS_CONFIG_ONE)) {
8167                 /*
8168                  * Sync current observations in the map and look again.  We
8169                  * place an upper bound on the amount of time we will wait for
8170                  * sync to complete to avoid a bad device causing this
8171                  * busconfig operation to hang.
8172                  *
8173                  * We are typically stable, so damap_sync returns immediately.
8174                  *
8175                  * Max time to wait for sync is settle_usec times settle factor.
8176                  */
8177                 iportmap->iportmap_sync_cnt++;
8178                 synced = damap_sync(iportmap->iportmap_dam, sync_usec);
8179                 if (!synced)
8180                         SCSI_HBA_LOG((_LOGCFG, self, NULL,
8181                             "iportmap_sync timeout"));
8182         } else
8183                 synced = -1;
8184 
8185         if (op == BUS_CONFIG_ONE) {
8186                 /* create the iport node child */
8187                 scsi_hba_devi_enter(self, &circ);
8188                 if ((child = scsi_hba_bus_config_port(self, (char *)arg,
8189                     SE_BUSCONFIG)) != NULL) {
8190                         if (childp) {
8191                                 ndi_hold_devi(child);
8192                                 *childp = child;
8193                         }
8194                         ret = NDI_SUCCESS;
8195                 }
8196                 scsi_hba_devi_exit(self, circ);
8197         } else
8198                 ret = ndi_busop_bus_config(self, flags, op, arg, childp, 0);
8199 
8200 out:
8201 #ifdef  DEBUG
8202         if (ret != NDI_SUCCESS) {
8203                 if (scsi_hba_bus_config_failure_msg ||
8204                     scsi_hba_bus_config_failure_dbg) {
8205                         scsi_hba_bus_config_failure_msg--;
8206                         printf("%s%d: bus_config_iportmap %p failure on %s: "
8207                             "%d %d\n",
8208                             ddi_driver_name(self), ddi_get_instance(self),
8209                             (void *)iportmap,
8210                             (op == BUS_CONFIG_ONE) ? (char *)arg : "ALL",
8211                             (int)tsa, synced);
8212                 }
8213                 if (scsi_hba_bus_config_failure_dbg) {
8214                         scsi_hba_bus_config_failure_dbg--;
8215                         debug_enter("config_iportmap failure");
8216                 }
8217         } else if (scsi_hba_bus_config_success_msg ||
8218             scsi_hba_bus_config_success_dbg) {
8219                 scsi_hba_bus_config_success_msg--;
8220                 printf("%s%d: bus_config_iportmap %p success on %s: %d %d\n",
8221                     ddi_driver_name(self), ddi_get_instance(self),
8222                     (void *)iportmap,
8223                     (op == BUS_CONFIG_ONE) ? (char *)arg : "ALL",
8224                     (int)tsa, synced);
8225                 if (scsi_hba_bus_config_success_dbg) {
8226                         scsi_hba_bus_config_success_dbg--;
8227                         debug_enter("config_iportmap success");
8228                 }
8229         }
8230 #endif  /* DEBUG */
8231         return (ret);
8232 }
8233 
8234 static int
8235 scsi_hba_bus_unconfig_iportmap(dev_info_t *self, uint_t flags,
8236     ddi_bus_config_op_t op, void *arg)
8237 {
8238         flags &= ~NDI_DEVI_REMOVE;
8239         return (ndi_busop_bus_unconfig(self, flags, op, arg));
8240 }
8241 
8242 /*
8243  * SCSI HBA bus config enumeration entry point. Called via the bus_ops
8244  * bus_config entry point for all SCSA HBA drivers.
8245  *
8246  *  o   If an HBA implements its own bus_config via tran_bus_config then we
8247  *      invoke it. An HBA that implements its own tran_bus_config entry point
8248  *      may still call back into common SCSA code bus_config code for:
8249  *
8250  *      o SPI bus_config (scsi_hba_bus_spi)
8251  *      o LUN and secondary function enumeration (scsi_hba_enum_lsf_of_t()).
8252  *      o configuration of a specific device (scsi_device_config).
8253  *      o determining 1275 SCSI nodename and compatible property
8254  *        (scsi_hba_nodename_compatible_get/_free).
8255  *
8256  *   o  Otherwise we implement a SCSI parallel interface (spi) bus config.
8257  *
8258  * Return NDI_SUCCESS if we might have created a new node.
8259  * Return NDI_FAILURE if we definitely did not create a new node.
8260  */
8261 static int
8262 scsi_hba_bus_config(dev_info_t *self, uint_t flags,
8263     ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
8264 {
8265         scsi_hba_tran_t *tran;
8266         int             ret;
8267 
8268         /* make sure that we will not disappear */
8269         ASSERT(DEVI(self)->devi_ref);
8270 
8271         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE);
8272         if (tran == NULL) {
8273                 /* NULL tran driver.conf config (used by cmdk). */
8274                 if ((op == BUS_CONFIG_ONE) || (flags & NDI_DRV_CONF_REPROBE))
8275                         flags |= NDI_CONFIG_REPROBE;
8276                 return (ndi_busop_bus_config(self, flags, op, arg, childp, 0));
8277         }
8278 
8279         /* Check if self is HBA-only node. */
8280         if (tran->tran_hba_flags & SCSI_HBA_HBA) {
8281                 /* The bus_config request is to configure iports below HBA. */
8282 
8283 #ifdef  sparc
8284                 /*
8285                  * Sparc's 'boot-device' OBP property value lacks an /iport@X/
8286                  * component. Prior to the mount of root, we drive a disk@
8287                  * BUS_CONFIG_ONE operatino down a level to resolve an
8288                  * OBP 'boot-device' path.
8289                  *
8290                  * Future: Add (modrootloaded == 0) below, and insure that
8291                  * all attempts bus_conf of 'bo_name' (in OBP form) occur
8292                  * prior to 'modrootloaded = 1;' assignment in vfs_mountroot.
8293                  */
8294                 if ((op == BUS_CONFIG_ONE) &&
8295                     (strncmp((char *)arg, "disk@", strlen("disk@")) == 0)) {
8296                         return (scsi_hba_bus_config_prom_node(self,
8297                             flags, arg, childp));
8298                 }
8299 #endif  /* sparc */
8300 
8301                 if (tran->tran_iportmap) {
8302                         /* config based on scsi_hba_iportmap API */
8303                         ret = scsi_hba_bus_config_iportmap(self,
8304                             flags, op, arg, childp);
8305                 } else {
8306                         /* config based on 'iport_register' API */
8307                         ret = scsi_hba_bus_config_iports(self,
8308                             flags, op, arg, childp);
8309                 }
8310                 return (ret);
8311         }
8312 
8313         /* Check to see how the iport/HBA does target/lun bus config. */
8314         if (tran->tran_bus_config) {
8315                 /* HBA config based on Sun-private/legacy tran_bus_config */
8316                 ret = tran->tran_bus_config(self, flags, op, arg, childp);
8317         } else if (tran->tran_tgtmap) {
8318                 /* SCSAv3 config based on scsi_hba_tgtmap_*() API */
8319                 ret =  scsi_hba_bus_config_tgtmap(self, flags, op, arg, childp);
8320         } else {
8321                 /* SCSA config based on SCSI Parallel Interconnect */
8322                 ret = scsi_hba_bus_config_spi(self, flags, op, arg, childp);
8323         }
8324         return (ret);
8325 }
8326 
8327 /*
8328  * Called via the bus_ops bus_unconfig entry point for SCSI HBA drivers.
8329  */
8330 static int
8331 scsi_hba_bus_unconfig(dev_info_t *self, uint_t flags,
8332     ddi_bus_config_op_t op, void *arg)
8333 {
8334         int             circ;
8335         scsi_hba_tran_t *tran;
8336         int             ret;
8337 
8338         tran = ddi_get_driver_private(self);
8339         if (tran == NULL) {
8340                 /* NULL tran driver.conf unconfig (used by cmdk). */
8341                 return (ndi_busop_bus_unconfig(self, flags, op, arg));
8342         }
8343 
8344         /*
8345          * Purge barrier/probe node children. We do this prior to
8346          * tran_bus_unconfig in case the unconfig implementation calls back
8347          * into the common code at a different enumeration level, such a
8348          * scsi_device_config, which still creates barrier/probe nodes.
8349          */
8350         scsi_hba_devi_enter(self, &circ);
8351         scsi_hba_barrier_purge(self);
8352         scsi_hba_devi_exit(self, circ);
8353 
8354         /* DEBUG: for testing, allow bus_unconfig do drive removal. */
8355         if (scsi_hba_bus_unconfig_remove)
8356                 flags |= NDI_DEVI_REMOVE;
8357 
8358         /* Check if self is HBA-only node. */
8359         if (tran->tran_hba_flags & SCSI_HBA_HBA) {
8360                 /* The bus_config request is to unconfigure iports below HBA. */
8361                 if (tran->tran_iportmap) {
8362                         /* SCSAv3 unconfig based on scsi_hba_iportmap API */
8363                         ret = scsi_hba_bus_unconfig_iportmap(self,
8364                             flags, op, arg);
8365                 } else if (tran->tran_bus_unconfig) {
8366                         /* HBA unconfig based on Sun-private/legacy API */
8367                         ret = tran->tran_bus_unconfig(self, flags, op, arg);
8368                 } else {
8369                         /* Standard framework unconfig. */
8370                         ret = ndi_busop_bus_unconfig(self, flags, op, arg);
8371                 }
8372                 return (ret);
8373         }
8374 
8375         /* Check to see how the iport/HBA does target/lun bus unconfig. */
8376         if (tran->tran_bus_unconfig) {
8377                 /* HBA unconfig based on Sun-private/legacy tran_bus_unconfig */
8378                 ret = tran->tran_bus_unconfig(self, flags, op, arg);
8379         } else if (tran->tran_tgtmap) {
8380                 /* SCSAv3 unconfig based on scsi_hba_tgtmap_*() API */
8381                 ret = scsi_hba_bus_unconfig_tgtmap(self, flags, op, arg);
8382         } else {
8383                 /* SCSA unconfig based on SCSI Parallel Interconnect */
8384                 ret = scsi_hba_bus_unconfig_spi(self, flags, op, arg);
8385         }
8386         return (ret);
8387 }
8388 
8389 static int
8390 scsi_tgtmap_scsi_config(void *arg, damap_t *mapp, damap_id_t tgtid)
8391 {
8392         scsi_hba_tran_t         *tran = (scsi_hba_tran_t *)arg;
8393         dev_info_t              *self = tran->tran_iport_dip;
8394         impl_scsi_tgtmap_t      *tgtmap;
8395         char                    *tgtaddr;
8396         int                     cfg_status, mt;
8397 
8398         tgtmap = (impl_scsi_tgtmap_t *)tran->tran_tgtmap;
8399         tgtaddr = damap_id2addr(mapp, tgtid);
8400 
8401         if (scsi_lunmap_create(self, tgtmap, tgtaddr) != DDI_SUCCESS) {
8402                 SCSI_HBA_LOG((_LOG_NF(WARN),
8403                     "failed to create lunmap for %s", tgtaddr));
8404         }
8405 
8406         mt = ddi_prop_get_int(DDI_DEV_T_ANY, self,
8407             DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, "scsi-enumeration",
8408             scsi_enumeration);
8409         mt |= scsi_hba_log_mt_disable;
8410 
8411         cfg_status = scsi_hba_bus_config_taddr(self, tgtaddr, mt, SE_HP);
8412         if (cfg_status != NDI_SUCCESS) {
8413                 SCSI_HBA_LOG((_LOGCFG, self, NULL, "%s @%s config status %d",
8414                     damap_name(mapp), tgtaddr, cfg_status));
8415                 scsi_lunmap_destroy(self, tgtmap, tgtaddr);
8416                 return (DAM_FAILURE);
8417         }
8418 
8419         return (DAM_SUCCESS);
8420 }
8421 
8422 
8423 static int
8424 scsi_tgtmap_scsi_unconfig(void *arg, damap_t *mapp, damap_id_t tgtid)
8425 {
8426         scsi_hba_tran_t         *tran = (scsi_hba_tran_t *)arg;
8427         dev_info_t              *self = tran->tran_iport_dip;
8428         impl_scsi_tgtmap_t      *tgtmap;
8429         char                    *tgt_addr;
8430 
8431         tgtmap = (impl_scsi_tgtmap_t *)tran->tran_tgtmap;
8432         tgt_addr = damap_id2addr(mapp, tgtid);
8433 
8434         SCSI_HBA_LOG((_LOGUNCFG, self, NULL, "%s @%s", damap_name(mapp),
8435             tgt_addr));
8436         scsi_lunmap_destroy(self, tgtmap, tgt_addr);
8437         return (DAM_SUCCESS);
8438 }
8439 
8440 static int
8441 scsi_tgtmap_smp_config(void *arg, damap_t *mapp, damap_id_t tgtid)
8442 {
8443         scsi_hba_tran_t *tran = (scsi_hba_tran_t *)arg;
8444         dev_info_t      *self = tran->tran_iport_dip;
8445         char            *addr;
8446 
8447         addr = damap_id2addr(mapp, tgtid);
8448         SCSI_HBA_LOG((_LOGCFG, self, NULL, "%s @%s", damap_name(mapp), addr));
8449 
8450         return ((smp_hba_bus_config_taddr(self, addr) == NDI_SUCCESS) ?
8451             DAM_SUCCESS : DAM_FAILURE);
8452 }
8453 
8454 static int
8455 scsi_tgtmap_smp_unconfig(void *arg, damap_t *mapp, damap_id_t tgtid)
8456 {
8457         scsi_hba_tran_t *tran = (scsi_hba_tran_t *)arg;
8458         dev_info_t      *self = tran->tran_iport_dip;
8459         char            *addr;
8460         dev_info_t      *child;
8461         char            nameaddr[SCSI_MAXNAMELEN];
8462         int             circ;
8463 
8464         addr = damap_id2addr(mapp, tgtid);
8465         SCSI_HBA_LOG((_LOGUNCFG, self, NULL, "%s @%s", damap_name(mapp), addr));
8466 
8467         (void) snprintf(nameaddr, sizeof (nameaddr), "smp@%s", addr);
8468         scsi_hba_devi_enter(self, &circ);
8469         if ((child = ndi_devi_findchild(self, nameaddr)) == NULL) {
8470                 scsi_hba_devi_exit(self, circ);
8471                 return (DAM_SUCCESS);
8472         }
8473 
8474         if (ndi_devi_offline(child,
8475             NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE) == DDI_SUCCESS) {
8476                 SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
8477                     "devinfo smp@%s offlined and removed", addr));
8478         } else if (ndi_devi_device_remove(child)) {
8479                 /* Offline/remove failed, note new device_remove */
8480                 SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
8481                     "devinfo smp@%s offline failed, device_remove",
8482                     addr));
8483         }
8484         scsi_hba_devi_exit(self, circ);
8485         return (DAM_SUCCESS);
8486 }
8487 
8488 /* ARGSUSED1 */
8489 static void
8490 scsi_tgtmap_smp_activate(void *map_priv, char *tgt_addr, int addrid,
8491     void **tgt_privp)
8492 {
8493         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)map_priv;
8494         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8495 
8496         if (tgtmap->tgtmap_activate_cb) {
8497                 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s @%s activated",
8498                     damap_name(tgtmap->tgtmap_dam[SCSI_TGT_SMP_DEVICE]),
8499                     tgt_addr));
8500 
8501                 (*tgtmap->tgtmap_activate_cb)(tgtmap->tgtmap_mappriv,
8502                     tgt_addr, SCSI_TGT_SMP_DEVICE, tgt_privp);
8503         }
8504 }
8505 
8506 /* ARGSUSED1 */
8507 static void
8508 scsi_tgtmap_smp_deactivate(void *map_priv, char *tgt_addr, int addrid,
8509     void *tgt_privp, damap_deact_rsn_t damap_rsn)
8510 {
8511         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)map_priv;
8512         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8513         boolean_t               tgtmap_rereport;
8514         scsi_tgtmap_deact_rsn_t tgtmap_rsn;
8515 
8516         if (tgtmap->tgtmap_deactivate_cb) {
8517                 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s @%s deactivated %d",
8518                     damap_name(tgtmap->tgtmap_dam[SCSI_TGT_SMP_DEVICE]),
8519                     tgt_addr, damap_rsn));
8520 
8521                 if (damap_rsn == DAMAP_DEACT_RSN_GONE)
8522                         tgtmap_rsn = SCSI_TGT_DEACT_RSN_GONE;
8523                 else if (damap_rsn == DAMAP_DEACT_RSN_CFG_FAIL)
8524                         tgtmap_rsn = SCSI_TGT_DEACT_RSN_CFG_FAIL;
8525                 else if (damap_rsn == DAMAP_DEACT_RSN_UNSTBL)
8526                         tgtmap_rsn = SCSI_TGT_DEACT_RSN_UNSTBL;
8527                 else {
8528                         SCSI_HBA_LOG((_LOG(WARN), self, NULL,
8529                             "%s @%s deactivated with unknown rsn",
8530                             damap_name(tgtmap->tgtmap_dam[SCSI_TGT_SMP_DEVICE]),
8531                             tgt_addr));
8532                         return;
8533                 }
8534 
8535                 tgtmap_rereport = (*tgtmap->tgtmap_deactivate_cb)
8536                     (tgtmap->tgtmap_mappriv, tgt_addr,
8537                     SCSI_TGT_SMP_DEVICE, tgt_privp, tgtmap_rsn);
8538 
8539                 if ((tgtmap_rsn == SCSI_TGT_DEACT_RSN_CFG_FAIL) &&
8540                     (tgtmap_rereport == B_FALSE)) {
8541                         SCSI_HBA_LOG((_LOG(WARN), NULL, self,
8542                             "%s enumeration failed, no more retries until "
8543                             "config change occurs", tgt_addr));
8544                 }
8545         }
8546 }
8547 
8548 /* ARGSUSED1 */
8549 static void
8550 scsi_tgtmap_scsi_activate(void *map_priv, char *tgt_addr, int addrid,
8551     void **tgt_privp)
8552 {
8553         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)map_priv;
8554         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8555 
8556         if (tgtmap->tgtmap_activate_cb) {
8557                 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s @%s activated",
8558                     damap_name(tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]),
8559                     tgt_addr));
8560 
8561                 (*tgtmap->tgtmap_activate_cb)(tgtmap->tgtmap_mappriv,
8562                     tgt_addr, SCSI_TGT_SCSI_DEVICE, tgt_privp);
8563         }
8564 }
8565 
8566 /* ARGSUSED1 */
8567 static void
8568 scsi_tgtmap_scsi_deactivate(void *map_priv, char *tgt_addr, int addrid,
8569     void *tgt_privp, damap_deact_rsn_t damap_rsn)
8570 {
8571         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)map_priv;
8572         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8573         boolean_t               tgtmap_rereport;
8574         scsi_tgtmap_deact_rsn_t tgtmap_rsn;
8575 
8576         if (tgtmap->tgtmap_deactivate_cb) {
8577                 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s @%s deactivated %d",
8578                     damap_name(tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]),
8579                     tgt_addr, damap_rsn));
8580 
8581                 if (damap_rsn == DAMAP_DEACT_RSN_GONE)
8582                         tgtmap_rsn = SCSI_TGT_DEACT_RSN_GONE;
8583                 else if (damap_rsn == DAMAP_DEACT_RSN_CFG_FAIL)
8584                         tgtmap_rsn = SCSI_TGT_DEACT_RSN_CFG_FAIL;
8585                 else if (damap_rsn == DAMAP_DEACT_RSN_UNSTBL)
8586                         tgtmap_rsn = SCSI_TGT_DEACT_RSN_UNSTBL;
8587                 else {
8588                         SCSI_HBA_LOG((_LOG(WARN), self, NULL,
8589                             "%s @%s deactivated with unknown rsn", damap_name(
8590                             tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]),
8591                             tgt_addr));
8592                         return;
8593                 }
8594 
8595                 tgtmap_rereport = (*tgtmap->tgtmap_deactivate_cb)
8596                     (tgtmap->tgtmap_mappriv, tgt_addr,
8597                     SCSI_TGT_SCSI_DEVICE, tgt_privp, tgtmap_rsn);
8598 
8599                 if ((tgtmap_rsn == SCSI_TGT_DEACT_RSN_CFG_FAIL) &&
8600                     (tgtmap_rereport == B_FALSE)) {
8601                         SCSI_HBA_LOG((_LOG(WARN), NULL, self,
8602                             "%s enumeration failed, no more retries until "
8603                             "config change occurs", tgt_addr));
8604                 }
8605         }
8606 }
8607 
8608 
8609 int
8610 scsi_hba_tgtmap_create(dev_info_t *self, scsi_tgtmap_mode_t mode,
8611     int csync_usec, int settle_usec, void *tgtmap_priv,
8612     scsi_tgt_activate_cb_t activate_cb, scsi_tgt_deactivate_cb_t deactivate_cb,
8613     scsi_hba_tgtmap_t **handle)
8614 {
8615         scsi_hba_tran_t         *tran;
8616         damap_t                 *mapp;
8617         char                    context[64];
8618         impl_scsi_tgtmap_t      *tgtmap;
8619         damap_rptmode_t         rpt_style;
8620         char                    *scsi_binding_set;
8621         int                     optflags;
8622 
8623         if (self == NULL || csync_usec == 0 ||
8624             settle_usec == 0 || handle == NULL)
8625                 return (DDI_FAILURE);
8626 
8627         *handle = NULL;
8628 
8629         if (scsi_hba_iport_unit_address(self) == NULL)
8630                 return (DDI_FAILURE);
8631 
8632         switch (mode) {
8633         case SCSI_TM_FULLSET:
8634                 rpt_style = DAMAP_REPORT_FULLSET;
8635                 break;
8636         case SCSI_TM_PERADDR:
8637                 rpt_style = DAMAP_REPORT_PERADDR;
8638                 break;
8639         default:
8640                 return (DDI_FAILURE);
8641         }
8642 
8643         tran = (scsi_hba_tran_t *)ddi_get_driver_private(self);
8644         ASSERT(tran);
8645         if (tran == NULL)
8646                 return (DDI_FAILURE);
8647 
8648         tgtmap = kmem_zalloc(sizeof (*tgtmap), KM_SLEEP);
8649         tgtmap->tgtmap_tran = tran;
8650         tgtmap->tgtmap_activate_cb = activate_cb;
8651         tgtmap->tgtmap_deactivate_cb = deactivate_cb;
8652         tgtmap->tgtmap_mappriv = tgtmap_priv;
8653 
8654         tgtmap->tgtmap_create_window = 1;    /* start with window */
8655         tgtmap->tgtmap_create_time = ddi_get_lbolt64();
8656         tgtmap->tgtmap_create_csync_usec = csync_usec;
8657         tgtmap->tgtmap_settle_usec = settle_usec;
8658         tgtmap->tgtmap_sync_cnt = 0;
8659 
8660         optflags = (ddi_prop_get_int(DDI_DEV_T_ANY, self,
8661             DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, "scsi-enumeration",
8662             scsi_enumeration) & SCSI_ENUMERATION_MT_TARGET_DISABLE) ?
8663             DAMAP_SERIALCONFIG : DAMAP_MTCONFIG;
8664 
8665         (void) snprintf(context, sizeof (context), "%s%d.tgtmap.scsi",
8666             ddi_driver_name(self), ddi_get_instance(self));
8667         SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context));
8668         if (damap_create(context, rpt_style, optflags, settle_usec,
8669             tgtmap, scsi_tgtmap_scsi_activate, scsi_tgtmap_scsi_deactivate,
8670             tran, scsi_tgtmap_scsi_config, scsi_tgtmap_scsi_unconfig,
8671             &mapp) != DAM_SUCCESS) {
8672                 kmem_free(tgtmap, sizeof (*tgtmap));
8673                 return (DDI_FAILURE);
8674         }
8675         tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE] = mapp;
8676 
8677         (void) snprintf(context, sizeof (context), "%s%d.tgtmap.smp",
8678             ddi_driver_name(self), ddi_get_instance(self));
8679         SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context));
8680         if (damap_create(context, rpt_style, optflags,
8681             settle_usec, tgtmap, scsi_tgtmap_smp_activate,
8682             scsi_tgtmap_smp_deactivate,
8683             tran, scsi_tgtmap_smp_config, scsi_tgtmap_smp_unconfig,
8684             &mapp) != DAM_SUCCESS) {
8685                 damap_destroy(tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]);
8686                 kmem_free(tgtmap, sizeof (*tgtmap));
8687                 return (DDI_FAILURE);
8688         }
8689         tgtmap->tgtmap_dam[SCSI_TGT_SMP_DEVICE] = mapp;
8690 
8691         tran->tran_tgtmap = (scsi_hba_tgtmap_t *)tgtmap;
8692         *handle = (scsi_hba_tgtmap_t *)tgtmap;
8693 
8694         /*
8695          * We have now set tran_tgtmap, marking the tran as using tgtmap
8696          * enumeration services.  To prevent the generation of legacy spi
8697          * 'binding-set' compatible forms, remove the 'scsi-binding-set'
8698          * property.
8699          */
8700         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, self,
8701             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-binding-set",
8702             &scsi_binding_set) == DDI_PROP_SUCCESS) {
8703                 if (strcmp(scsi_binding_set, scsi_binding_set_spi) == 0)
8704                         (void) ndi_prop_remove(DDI_DEV_T_NONE, self,
8705                             "scsi-binding-set");
8706                 ddi_prop_free(scsi_binding_set);
8707         }
8708         return (DDI_SUCCESS);
8709 }
8710 
8711 void
8712 scsi_hba_tgtmap_destroy(scsi_hba_tgtmap_t *handle)
8713 {
8714         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)handle;
8715         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8716         int                     i;
8717 
8718         for (i = 0; i < SCSI_TGT_NTYPES; i++) {
8719                 if (tgtmap->tgtmap_dam[i]) {
8720                         SCSI_HBA_LOG((_LOGTGT, self, NULL,
8721                             "%s", damap_name(tgtmap->tgtmap_dam[i])));
8722                         damap_destroy(tgtmap->tgtmap_dam[i]);
8723                 }
8724         }
8725         kmem_free(tgtmap, sizeof (*tgtmap));
8726 }
8727 
8728 /* return 1 if all maps ended up syned */
8729 static int
8730 scsi_tgtmap_sync(scsi_hba_tgtmap_t *handle, int sync_usec)
8731 {
8732         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)handle;
8733         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8734         int                     all_synced = 1;
8735         int                     synced;
8736         int                     i;
8737 
8738         for (i = 0; i < SCSI_TGT_NTYPES; i++) {
8739                 if (tgtmap->tgtmap_dam[i]) {
8740                         SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s sync begin",
8741                             damap_name(tgtmap->tgtmap_dam[i])));
8742                         synced = damap_sync(tgtmap->tgtmap_dam[i], sync_usec);
8743                         all_synced &= synced;
8744                         SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s sync end %d",
8745                             damap_name(tgtmap->tgtmap_dam[i]), synced));
8746 
8747                 }
8748         }
8749         return (all_synced);
8750 }
8751 
8752 /* return 1 if all maps ended up empty */
8753 static int
8754 scsi_tgtmap_is_empty(scsi_hba_tgtmap_t *handle)
8755 {
8756         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)handle;
8757         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8758         int                     all_empty = 1;
8759         int                     empty;
8760         int                     i;
8761 
8762         for (i = 0; i < SCSI_TGT_NTYPES; i++) {
8763                 if (tgtmap->tgtmap_dam[i]) {
8764                         empty = damap_is_empty(tgtmap->tgtmap_dam[i]);
8765                         all_empty &= empty;
8766                         SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s is_empty %d",
8767                             damap_name(tgtmap->tgtmap_dam[i]), empty));
8768                 }
8769         }
8770 
8771         return (all_empty);
8772 }
8773 
8774 static int
8775 scsi_tgtmap_beginf(scsi_hba_tgtmap_t *handle, boolean_t do_begin)
8776 {
8777         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)handle;
8778         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8779         char                    *context;
8780         int                     rv = DAM_SUCCESS;
8781         int                     i;
8782 
8783         for (i = 0; i < SCSI_TGT_NTYPES; i++) {
8784                 if (tgtmap->tgtmap_dam[i] == NULL) {
8785                         continue;
8786                 }
8787 
8788                 context = damap_name(tgtmap->tgtmap_dam[i]);
8789                 if (do_begin == B_TRUE) {
8790                         if (i == SCSI_TGT_SCSI_DEVICE) {
8791                                 /*
8792                                  * In scsi_device context, so we have the
8793                                  * 'context' string, diagnose the case where
8794                                  * the tgtmap caller is failing to make
8795                                  * forward progress, i.e. the caller is never
8796                                  * completing an observation by calling
8797                                  * scsi_hbg_tgtmap_set_end. If this occurs,
8798                                  * the solaris target/lun state may be out
8799                                  * of sync with hardware.
8800                                  */
8801                                 if (tgtmap->tgtmap_reports++ >=
8802                                     scsi_hba_tgtmap_reports_max) {
8803                                         tgtmap->tgtmap_noisy++;
8804                                         if (tgtmap->tgtmap_noisy == 1) {
8805                                                 SCSI_HBA_LOG((_LOG(WARN),
8806                                                     self, NULL,
8807                                                     "%s: failing tgtmap begin",
8808                                                     context));
8809                                         }
8810                                 }
8811                         }
8812 
8813                         rv = damap_addrset_begin(tgtmap->tgtmap_dam[i]);
8814                 } else {
8815                         rv = damap_addrset_flush(tgtmap->tgtmap_dam[i]);
8816                 }
8817 
8818                 if (rv != DAM_SUCCESS) {
8819                         SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s FAIL", context));
8820                 } else {
8821                         SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context));
8822                 }
8823         }
8824 
8825         return ((rv == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
8826 }
8827 
8828 
8829 int
8830 scsi_hba_tgtmap_set_begin(scsi_hba_tgtmap_t *handle)
8831 {
8832         return (scsi_tgtmap_beginf(handle, B_TRUE));
8833 }
8834 
8835 int
8836 scsi_hba_tgtmap_set_flush(scsi_hba_tgtmap_t *handle)
8837 {
8838         return (scsi_tgtmap_beginf(handle, B_FALSE));
8839 }
8840 
8841 int
8842 scsi_hba_tgtmap_set_add(scsi_hba_tgtmap_t *handle,
8843     scsi_tgtmap_tgt_type_t tgt_type, char *tgt_addr, void *tgt_priv)
8844 {
8845         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)handle;
8846         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8847 
8848         if (tgt_type >= SCSI_TGT_NTYPES || !tgtmap->tgtmap_dam[tgt_type])
8849                 return (DDI_FAILURE);
8850 
8851         SCSI_HBA_LOG((_LOGTGT, self, NULL,
8852             "%s @%s", damap_name(tgtmap->tgtmap_dam[tgt_type]), tgt_addr));
8853 
8854         return ((damap_addrset_add(tgtmap->tgtmap_dam[tgt_type], tgt_addr,
8855             NULL, NULL, tgt_priv) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
8856 }
8857 
8858 /*ARGSUSED*/
8859 int
8860 scsi_hba_tgtmap_set_end(scsi_hba_tgtmap_t *handle, uint_t flags)
8861 {
8862         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)handle;
8863         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8864         char                    *context;
8865         int                     rv = DDI_SUCCESS;
8866         int                     i;
8867 
8868         tgtmap->tgtmap_reports = tgtmap->tgtmap_noisy = 0;
8869 
8870         for (i = 0; i < SCSI_TGT_NTYPES; i++) {
8871                 if (tgtmap->tgtmap_dam[i] == NULL)
8872                         continue;
8873                 context = damap_name(tgtmap->tgtmap_dam[i]);
8874                 if (damap_addrset_end(
8875                     tgtmap->tgtmap_dam[i], 0) != DAM_SUCCESS) {
8876                         SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s FAIL", context));
8877                         rv = DDI_FAILURE;
8878                         continue;
8879                 }
8880 
8881                 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context));
8882         }
8883         return (rv);
8884 }
8885 
8886 int
8887 scsi_hba_tgtmap_tgt_add(scsi_hba_tgtmap_t *handle,
8888     scsi_tgtmap_tgt_type_t tgt_type, char *tgt_addr, void *tgt_priv)
8889 
8890 {
8891         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)handle;
8892         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8893 
8894         if (tgt_type >= SCSI_TGT_NTYPES || !tgtmap->tgtmap_dam[tgt_type])
8895                 return (DDI_FAILURE);
8896 
8897         SCSI_HBA_LOG((_LOGTGT, self, NULL,
8898             "%s @%s", damap_name(tgtmap->tgtmap_dam[tgt_type]), tgt_addr));
8899 
8900         return ((damap_addr_add(tgtmap->tgtmap_dam[tgt_type], tgt_addr, NULL,
8901             NULL, tgt_priv) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
8902 }
8903 
8904 int
8905 scsi_hba_tgtmap_tgt_remove(scsi_hba_tgtmap_t *handle,
8906     scsi_tgtmap_tgt_type_t tgt_type, char *tgt_addr)
8907 {
8908         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)handle;
8909         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8910 
8911         if (tgt_type >= SCSI_TGT_NTYPES || !tgtmap->tgtmap_dam[tgt_type])
8912                 return (DDI_FAILURE);
8913 
8914         SCSI_HBA_LOG((_LOGTGT, self, NULL,
8915             "%s @%s", damap_name(tgtmap->tgtmap_dam[tgt_type]), tgt_addr));
8916 
8917         return ((damap_addr_del(tgtmap->tgtmap_dam[tgt_type],
8918             tgt_addr) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
8919 }
8920 
8921 int
8922 scsi_hba_tgtmap_lookup(scsi_hba_tgtmap_t *handle,
8923     char *tgt_addr, scsi_tgtmap_tgt_type_t *r_type)
8924 {
8925         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)handle;
8926         dev_info_t              *self = tgtmap->tgtmap_tran->tran_iport_dip;
8927         damap_id_t              tgtid;
8928         int                     i;
8929 
8930         for (i = 0; i < SCSI_TGT_NTYPES; i++) {
8931                 tgtid = damap_lookup(tgtmap->tgtmap_dam[i], tgt_addr);
8932                 if (tgtid != NODAM) {
8933                         *r_type = i;
8934                         SCSI_HBA_LOG((_LOG(3), self, NULL,
8935                             "%s @%s found: type %d",
8936                             damap_name(tgtmap->tgtmap_dam[i]), tgt_addr, i));
8937                         damap_id_rele(tgtmap->tgtmap_dam[i], tgtid);
8938                         return (DDI_SUCCESS);
8939                 }
8940         }
8941 
8942         SCSI_HBA_LOG((_LOG(3), self, NULL,
8943             "%s%d.tgtmap @%s not found",
8944             ddi_driver_name(self), ddi_get_instance(self), tgt_addr));
8945         return (DDI_FAILURE);
8946 }
8947 
8948 /*
8949  * Return the unit-address of an 'iport' node, or NULL for non-iport node.
8950  */
8951 char *
8952 scsi_hba_iport_unit_address(dev_info_t *self)
8953 {
8954         /*
8955          * NOTE: Since 'self' could be a SCSA iport node or a SCSA HBA node,
8956          * we can't use SCSA flavors: the flavor of a SCSA HBA node is not
8957          * established/owned by SCSA, it is established by the nexus that
8958          * created the SCSA HBA node (PCI) as a child.
8959          *
8960          * NOTE: If we want to support a node_name other than "iport" for
8961          * an iport node then we can add support for a "scsa-iport-node-name"
8962          * property on the SCSA HBA node.  A SCSA HBA driver would set this
8963          * property on the SCSA HBA node prior to using the iport API.
8964          */
8965         if (strcmp(ddi_node_name(self), "iport") == 0)
8966                 return (ddi_get_name_addr(self));
8967         else
8968                 return (NULL);
8969 }
8970 
8971 /*
8972  * Define a SCSI initiator port (bus/channel) for an HBA card that needs to
8973  * support multiple SCSI ports, but only has a single HBA devinfo node. This
8974  * function should be called from the HBA's attach(9E) implementation (when
8975  * processing the HBA devinfo node attach) after the number of SCSI ports on
8976  * the card is known or when the HBA driver DR handler detects a new port.
8977  * The function returns 0 on failure and 1 on success.
8978  *
8979  * The implementation will add the port value into the "scsi-iports" property
8980  * value maintained on the HBA node as. These properties are used by the generic
8981  * scsi bus_config implementation to dynamicaly enumerate the specified iport
8982  * children. The enumeration code will, on demand, create the appropriate
8983  * iport children with a SCSI_ADDR_PROP_IPORTUA unit address. This node will
8984  * bind to the same driver as the HBA node itself. This means that an HBA
8985  * driver that uses iports should expect probe(9E), attach(9E), and detach(9E)
8986  * calls on the iport children of the HBA.  If configuration for all ports was
8987  * already done during HBA node attach, the driver should just return
8988  * DDI_SUCCESS when confronted with an iport node.
8989  *
8990  * A maximum of 32 iport ports are supported per HBA devinfo node.
8991  *
8992  * A NULL "port" can be used to indicate that the framework should enumerate
8993  * target children on the HBA node itself, in addition to enumerating target
8994  * children on any iport nodes declared. There are two reasons that an HBA may
8995  * wish to have target children enumerated on both the HBA node and iport
8996  * node(s):
8997  *
8998  *   o  If, in the past, HBA hardware had only a single physical port but now
8999  *      supports multiple physical ports, the updated driver that supports
9000  *      multiple physical ports may want to avoid /devices path upgrade issues
9001  *      by enumerating the first physical port under the HBA instead of as a
9002  *      iport.
9003  *
9004  *   o  Some hardware RAID HBA controllers (mlx, chs, etc) support multiple
9005  *      SCSI physical ports configured so that various physical devices on
9006  *      the physical ports are amalgamated into virtual devices on a virtual
9007  *      port.  Amalgamated physical devices no longer appear to the host OS
9008  *      on the physical ports, but other non-amalgamated devices may still be
9009  *      visible on the physical ports.  These drivers use a model where the
9010  *      physical ports are iport nodes and the HBA node is the virtual port to
9011  *      the configured virtual devices.
9012  */
9013 int
9014 scsi_hba_iport_register(dev_info_t *self, char *port)
9015 {
9016         unsigned int ports = 0;
9017         int rval, i;
9018         char **iports, **newiports;
9019 
9020         ASSERT(self);
9021         if (self == NULL)
9022                 return (DDI_FAILURE);
9023 
9024         rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self,
9025             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports,
9026             &ports);
9027 
9028         if (ports >= SCSI_HBA_MAX_IPORTS) {
9029                 ddi_prop_free(iports);
9030                 return (DDI_FAILURE);
9031         }
9032 
9033         if (rval == DDI_PROP_SUCCESS) {
9034                 for (i = 0; i < ports; i++) {
9035                         if (strcmp(port, iports[i]) == 0) {
9036                                 /* iport already registered */
9037                                 ddi_prop_free(iports);
9038                                 return (DDI_SUCCESS);
9039                         }
9040                 }
9041         }
9042 
9043         newiports = kmem_alloc((sizeof (char *) * (ports + 1)), KM_SLEEP);
9044 
9045         for (i = 0; i < ports; i++) {
9046                 newiports[i] = strdup(iports[i]);
9047         }
9048         newiports[ports] = strdup(port);
9049         ports++;
9050 
9051         if (ddi_prop_update_string_array(DDI_DEV_T_NONE, self,
9052             "scsi-iports", newiports, ports) != DDI_PROP_SUCCESS) {
9053                 SCSI_HBA_LOG((_LOG(WARN), self, NULL,
9054                     "failed to establish %s %s",
9055                     SCSI_ADDR_PROP_IPORTUA, port));
9056                 rval = DDI_FAILURE;
9057         } else {
9058                 rval = DDI_SUCCESS;
9059         }
9060 
9061         /* If there is iport exist, free property */
9062         if (ports > 1)
9063                 ddi_prop_free(iports);
9064         for (i = 0; i < ports; i++) {
9065                 strfree(newiports[i]);
9066         }
9067         kmem_free(newiports, (sizeof (char *)) * ports);
9068 
9069         return (rval);
9070 }
9071 
9072 /*
9073  * Check if the HBA has any scsi_hba_iport_register()ed children.
9074  */
9075 int
9076 scsi_hba_iport_exist(dev_info_t *self)
9077 {
9078         unsigned int ports = 0;
9079         char **iports;
9080         int rval;
9081 
9082         rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self,
9083             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports,
9084             &ports);
9085 
9086         if (rval != DDI_PROP_SUCCESS)
9087                 return (0);
9088 
9089         /* If there is now at least 1 iport, then iports is valid */
9090         if (ports > 0) {
9091                 rval = 1;
9092         } else
9093                 rval = 0;
9094         ddi_prop_free(iports);
9095 
9096         return (rval);
9097 }
9098 
9099 dev_info_t *
9100 scsi_hba_iport_find(dev_info_t *self, char *portnm)
9101 {
9102         char            *addr = NULL;
9103         char            **iports;
9104         unsigned int    num_iports = 0;
9105         int             rval = DDI_FAILURE;
9106         int             i = 0;
9107         dev_info_t      *child = NULL;
9108 
9109         /* check to see if this is an HBA that defined scsi iports */
9110         rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self,
9111             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports,
9112             &num_iports);
9113 
9114         if (rval != DDI_SUCCESS) {
9115                 return (NULL);
9116         }
9117         ASSERT(num_iports > 0);
9118 
9119         /* check to see if this port was registered */
9120         for (i = 0; i < num_iports; i++) {
9121                 if (strcmp(iports[i], portnm) == 0)
9122                         break;
9123         }
9124 
9125         if (i == num_iports) {
9126                 child = NULL;
9127                 goto out;
9128         }
9129 
9130         addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
9131         (void) snprintf(addr, SCSI_MAXNAMELEN, "iport@%s", portnm);
9132         rval = ndi_devi_config_one(self, addr, &child, NDI_NO_EVENT);
9133         kmem_free(addr, SCSI_MAXNAMELEN);
9134 
9135         if (rval != DDI_SUCCESS) {
9136                 child = NULL;
9137         }
9138 out:
9139         ddi_prop_free(iports);
9140         return (child);
9141 }
9142 
9143 /*
9144  * Search/create the specified iport node
9145  */
9146 static dev_info_t *
9147 scsi_hba_bus_config_port(dev_info_t *self, char *nameaddr, scsi_enum_t se)
9148 {
9149         dev_info_t      *child;         /* iport child of HBA node */
9150         scsi_hba_tran_t *tran;
9151         char            *addr;
9152         char            *compat;
9153 
9154         /*
9155          * See if the iport node already exists.
9156          */
9157         addr = nameaddr + strlen("iport@");
9158         if (child = ndi_devi_findchild(self, nameaddr)) {
9159                 if (ndi_devi_device_isremoved(child)) {
9160                         if ((se == SE_HP) || !ndi_dev_is_hotplug_node(child)) {
9161                                 if (ndi_devi_device_insert(child))
9162                                         SCSI_HBA_LOG((_LOGCFG, self, NULL,
9163                                             "devinfo iport@%s device_reinsert",
9164                                             addr));
9165                         } else
9166                                 return (NULL);
9167                 }
9168                 return (child);
9169         }
9170 
9171 
9172         /*
9173          * If config based on scsi_hba_iportmap API, only allow create
9174          * from hotplug.
9175          */
9176         tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE);
9177         ASSERT(tran);
9178         if (tran->tran_iportmap && (se != SE_HP))
9179                 return (NULL);
9180 
9181         /* allocate and initialize a new "iport" node */
9182         ndi_devi_alloc_sleep(self, "iport",
9183             (se == SE_HP) ? DEVI_SID_HP_NODEID : DEVI_SID_NODEID,
9184             &child);
9185         ASSERT(child);
9186         /*
9187          * Set the flavor of the child to be IPORT flavored
9188          */
9189         ndi_flavor_set(child, SCSA_FLAVOR_IPORT);
9190 
9191         /*
9192          * Add the SCSI_ADDR_PROP_IPORTUA addressing property for this child.
9193          * This property is used to identify a iport node, and to represent the
9194          * nodes @addr form via node properties.
9195          *
9196          * Add "compatible" property to the "scsi-iport" node to cause it bind
9197          * to the same driver as the HBA  driver. Use the "driver" name
9198          * instead of the "binding name" to distinguish from hw node.
9199          *
9200          * Give the HBA a chance, via tran_set_name_prop, to set additional
9201          * iport node properties or to change the "compatible" binding
9202          * prior to init_child.
9203          *
9204          * NOTE: the order of these operations is important so that
9205          * scsi_hba_iport works when called.
9206          */
9207         compat = (char *)ddi_driver_name(self);
9208         if ((ndi_prop_update_string(DDI_DEV_T_NONE, child,
9209             SCSI_ADDR_PROP_IPORTUA, addr) != DDI_PROP_SUCCESS) ||
9210             (ndi_prop_update_string_array(DDI_DEV_T_NONE, child,
9211             "compatible", &compat, 1) != DDI_PROP_SUCCESS) ||
9212             ddi_pathname_obp_set(child, NULL) != DDI_SUCCESS) {
9213                 SCSI_HBA_LOG((_LOG_NF(WARN), "%s failed dynamic decoration",
9214                     nameaddr));
9215                 (void) ddi_remove_child(child, 0);
9216                 child = NULL;
9217         } else {
9218                 /*
9219                  * Online/attach in order to get events so devfsadm will
9220                  * create public names.
9221                  */
9222                 ndi_hold_devi(child);
9223                 if (ndi_devi_online(child, 0) != NDI_SUCCESS) {
9224                         ndi_rele_devi(child);
9225                         ndi_prop_remove_all(child);
9226                         (void) ndi_devi_free(child);
9227                         child = NULL;
9228                 } else
9229                         ndi_rele_devi(child);
9230         }
9231 
9232         return (child);
9233 }
9234 
9235 #ifdef  sparc
9236 /*
9237  * Future: When iportmap boot support is added, consider rewriting this to
9238  * perform a scsi_hba_bus_config(BUS_CONFIG_ALL) on self (HBA) followed by
9239  * a scsi_hba_bus_config(BUS_CONFIG_ONE) on each child of self (each iport).
9240  */
9241 /* ARGSUSED */
9242 static int
9243 scsi_hba_bus_config_prom_node(dev_info_t *self, uint_t flags,
9244     void *arg, dev_info_t **childp)
9245 {
9246         char            **iports;
9247         int             circ, i;
9248         int             ret = NDI_FAILURE;
9249         unsigned int    num_iports = 0;
9250         dev_info_t      *pdip = NULL;
9251         char            *addr = NULL;
9252 
9253         /* check to see if this is an HBA that defined scsi iports */
9254         ret = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self,
9255             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports,
9256             &num_iports);
9257 
9258         if (ret != DDI_SUCCESS) {
9259                 return (ret);
9260         }
9261 
9262         ASSERT(num_iports > 0);
9263 
9264         addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
9265 
9266         ret = NDI_FAILURE;
9267 
9268         scsi_hba_devi_enter(self, &circ);
9269 
9270         /* create iport nodes for each scsi port/bus */
9271         for (i = 0; i < num_iports; i++) {
9272                 bzero(addr, SCSI_MAXNAMELEN);
9273                 /* Prepend the iport name */
9274                 (void) snprintf(addr, SCSI_MAXNAMELEN, "iport@%s",
9275                     iports[i]);
9276                 if (pdip = scsi_hba_bus_config_port(self, addr, SE_BUSCONFIG)) {
9277                         if (ndi_busop_bus_config(self, NDI_NO_EVENT,
9278                             BUS_CONFIG_ONE, addr, &pdip, 0) !=
9279                             NDI_SUCCESS) {
9280                                 continue;
9281                         }
9282                         /*
9283                          * Try to configure child under iport see wehter
9284                          * request node is the child of the iport node
9285                          */
9286                         if (ndi_devi_config_one(pdip, arg, childp,
9287                             NDI_NO_EVENT) == NDI_SUCCESS) {
9288                                 ret = NDI_SUCCESS;
9289                                 break;
9290                         }
9291                 }
9292         }
9293 
9294         scsi_hba_devi_exit(self, circ);
9295 
9296         kmem_free(addr, SCSI_MAXNAMELEN);
9297 
9298         ddi_prop_free(iports);
9299 
9300         return (ret);
9301 }
9302 #endif
9303 
9304 /*
9305  * Perform iport port/bus bus_config.
9306  */
9307 static int
9308 scsi_hba_bus_config_iports(dev_info_t *self, uint_t flags,
9309     ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
9310 {
9311         char            *nameaddr, *addr;
9312         char            **iports;
9313         int             circ, i;
9314         int             ret = NDI_FAILURE;
9315         unsigned int    num_iports = 0;
9316 
9317         /* check to see if this is an HBA that defined scsi iports */
9318         ret = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self,
9319             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports,
9320             &num_iports);
9321 
9322         if (ret != DDI_SUCCESS) {
9323                 return (ret);
9324         }
9325 
9326         ASSERT(num_iports > 0);
9327 
9328         scsi_hba_devi_enter(self, &circ);
9329 
9330         switch (op) {
9331         case BUS_CONFIG_ONE:
9332                 /* return if this operation is not against an iport node */
9333                 nameaddr = (char *)arg;
9334                 if ((nameaddr == NULL) ||
9335                     (strncmp(nameaddr, "iport@", strlen("iport@")) != 0)) {
9336                         ret = NDI_FAILURE;
9337                         scsi_hba_devi_exit(self, circ);
9338                         ddi_prop_free(iports);
9339                         return (ret);
9340                 }
9341 
9342                 /* parse the port number from "iport@%s" */
9343                 addr = nameaddr + strlen("iport@");
9344 
9345                 /* check to see if this port was registered */
9346                 for (i = 0; i < num_iports; i++) {
9347                         if (strcmp((iports[i]), addr) == 0)
9348                                 break;
9349                 }
9350 
9351                 if (i == num_iports) {
9352                         ret = NDI_FAILURE;
9353                         break;
9354                 }
9355 
9356                 /* create the iport node child */
9357                 if (scsi_hba_bus_config_port(self, nameaddr, SE_BUSCONFIG)) {
9358                         ret = NDI_SUCCESS;
9359                 }
9360                 break;
9361 
9362         case BUS_CONFIG_ALL:
9363         case BUS_CONFIG_DRIVER:
9364                 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
9365                 /* create iport nodes for each scsi port/bus */
9366                 for (i = 0; i < num_iports; i++) {
9367                         bzero(addr, SCSI_MAXNAMELEN);
9368                         /* Prepend the iport name */
9369                         (void) snprintf(addr, SCSI_MAXNAMELEN, "iport@%s",
9370                             iports[i]);
9371                         (void) scsi_hba_bus_config_port(self, addr,
9372                             SE_BUSCONFIG);
9373                 }
9374 
9375                 kmem_free(addr, SCSI_MAXNAMELEN);
9376                 ret = NDI_SUCCESS;
9377                 break;
9378         }
9379         if (ret == NDI_SUCCESS) {
9380 #ifdef sparc
9381                 /*
9382                  * Mask NDI_PROMNAME since PROM doesn't have iport
9383                  * node at all.
9384                  */
9385                 flags &= (~NDI_PROMNAME);
9386 #endif
9387                 flags |= NDI_MDI_FALLBACK;      /* devinfo&pathinfo children */
9388                 ret = ndi_busop_bus_config(self, flags, op,
9389                     arg, childp, 0);
9390         }
9391         scsi_hba_devi_exit(self, circ);
9392 
9393         ddi_prop_free(iports);
9394 
9395         return (ret);
9396 }
9397 
9398 static int
9399 scsi_iportmap_config(void *arg, damap_t *mapp, damap_id_t tgtid)
9400 {
9401         dev_info_t      *self = (dev_info_t *)arg;
9402         int             circ;
9403         char            nameaddr[SCSI_MAXNAMELEN];
9404         char            *iport_addr;
9405         dev_info_t      *childp;
9406 
9407         scsi_hba_devi_enter(self, &circ);
9408 
9409         iport_addr = damap_id2addr(mapp, tgtid);
9410         SCSI_HBA_LOG((_LOGIPT, self, NULL,
9411             "%s @%s", damap_name(mapp), iport_addr));
9412 
9413         (void) snprintf(nameaddr, sizeof (nameaddr), "iport@%s", iport_addr);
9414         childp = scsi_hba_bus_config_port(self, nameaddr, SE_HP);
9415         scsi_hba_devi_exit(self, circ);
9416         return (childp != NULL ? DAM_SUCCESS : DAM_FAILURE);
9417 }
9418 
9419 static int
9420 scsi_iportmap_unconfig(void *arg, damap_t *mapp, damap_id_t tgtid)
9421 {
9422         dev_info_t      *self = arg;
9423         dev_info_t      *childp;        /* iport child of HBA node */
9424         int             circ, empty;
9425         char            *addr;
9426         char            nameaddr[SCSI_MAXNAMELEN];
9427         scsi_hba_tran_t *tran;
9428 
9429         addr = damap_id2addr(mapp, tgtid);
9430         SCSI_HBA_LOG((_LOGIPT, self, NULL, "%s @%s", damap_name(mapp), addr));
9431 
9432         (void) snprintf(nameaddr, sizeof (nameaddr), "iport@%s", addr);
9433         scsi_hba_devi_enter(self, &circ);
9434         if ((childp = ndi_devi_findchild(self, nameaddr)) == NULL) {
9435                 scsi_hba_devi_exit(self, circ);
9436                 return (DAM_FAILURE);
9437         }
9438 
9439         tran = ddi_get_driver_private(childp);
9440         ASSERT(tran);
9441 
9442         ndi_hold_devi(childp);
9443         scsi_hba_devi_exit(self, circ);
9444 
9445         /*
9446          * A begin/end (clear) against the iport's
9447          * tgtmap will trigger unconfigure of all
9448          * targets on the iport.
9449          *
9450          * Future: This bit of code only works if the
9451          * target map reporting style is are full
9452          * reports and not per-address. Maybe we
9453          * should plan on handling this by
9454          * auto-unconfiguration when destroying the
9455          * target map(s).
9456          */
9457         (void) scsi_hba_tgtmap_set_begin(tran->tran_tgtmap);
9458         (void) scsi_hba_tgtmap_set_end(tran->tran_tgtmap, 0);
9459 
9460         /* wait for unconfigure */
9461         (void) scsi_tgtmap_sync(tran->tran_tgtmap, 0);
9462         empty = scsi_tgtmap_is_empty(tran->tran_tgtmap);
9463 
9464         scsi_hba_devi_enter(self, &circ);
9465         ndi_rele_devi(childp);
9466 
9467         /* If begin/end/sync ends in empty map, offline/remove. */
9468         if (empty) {
9469                 if (ndi_devi_offline(childp,
9470                     NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE) == DDI_SUCCESS) {
9471                         SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
9472                             "devinfo iport@%s offlined and removed",
9473                             addr));
9474                 } else if (ndi_devi_device_remove(childp)) {
9475                         /* Offline/rem failed, note new device_remove */
9476                         SCSI_HBA_LOG((_LOGUNCFG, self, NULL,
9477                             "devinfo iport@%s offline failed, "
9478                             "device_remove", addr));
9479                 }
9480         }
9481         scsi_hba_devi_exit(self, circ);
9482         return (empty ? DAM_SUCCESS : DAM_FAILURE);
9483 }
9484 
9485 
9486 int
9487 scsi_hba_iportmap_create(dev_info_t *self, int csync_usec, int settle_usec,
9488     scsi_hba_iportmap_t **handle)
9489 {
9490         scsi_hba_tran_t         *tran;
9491         damap_t                 *mapp;
9492         char                    context[64];
9493         impl_scsi_iportmap_t    *iportmap;
9494 
9495         if (self == NULL || csync_usec == 0 ||
9496             settle_usec == 0 || handle == NULL)
9497                 return (DDI_FAILURE);
9498 
9499         *handle = NULL;
9500 
9501         if (scsi_hba_iport_unit_address(self) != NULL)
9502                 return (DDI_FAILURE);
9503 
9504         tran = (scsi_hba_tran_t *)ddi_get_driver_private(self);
9505         ASSERT(tran);
9506         if (tran == NULL)
9507                 return (DDI_FAILURE);
9508 
9509         (void) snprintf(context, sizeof (context), "%s%d.iportmap",
9510             ddi_driver_name(self), ddi_get_instance(self));
9511 
9512         if (damap_create(context, DAMAP_REPORT_PERADDR, DAMAP_SERIALCONFIG,
9513             settle_usec, NULL, NULL, NULL, self,
9514             scsi_iportmap_config, scsi_iportmap_unconfig, &mapp) !=
9515             DAM_SUCCESS) {
9516                 return (DDI_FAILURE);
9517         }
9518         iportmap = kmem_zalloc(sizeof (*iportmap), KM_SLEEP);
9519         iportmap->iportmap_hba_dip = self;
9520         iportmap->iportmap_dam = mapp;
9521 
9522         iportmap->iportmap_create_window = 1;        /* start with window */
9523         iportmap->iportmap_create_time = ddi_get_lbolt64();
9524         iportmap->iportmap_create_csync_usec = csync_usec;
9525         iportmap->iportmap_settle_usec = settle_usec;
9526         iportmap->iportmap_sync_cnt = 0;
9527 
9528         tran->tran_iportmap = (scsi_hba_iportmap_t *)iportmap;
9529         *handle = (scsi_hba_iportmap_t *)iportmap;
9530 
9531         SCSI_HBA_LOG((_LOGIPT, self, NULL, "%s", damap_name(mapp)));
9532         return (DDI_SUCCESS);
9533 }
9534 
9535 void
9536 scsi_hba_iportmap_destroy(scsi_hba_iportmap_t *handle)
9537 {
9538         impl_scsi_iportmap_t    *iportmap = (impl_scsi_iportmap_t *)handle;
9539         dev_info_t              *self = iportmap->iportmap_hba_dip;
9540 
9541         SCSI_HBA_LOG((_LOGIPT, self, NULL,
9542             "%s", damap_name(iportmap->iportmap_dam)));
9543 
9544         damap_destroy(iportmap->iportmap_dam);
9545         kmem_free(iportmap, sizeof (*iportmap));
9546 }
9547 
9548 int
9549 scsi_hba_iportmap_iport_add(scsi_hba_iportmap_t *handle,
9550     char *iport_addr, void *iport_priv)
9551 {
9552         impl_scsi_iportmap_t    *iportmap = (impl_scsi_iportmap_t *)handle;
9553         dev_info_t              *self = iportmap->iportmap_hba_dip;
9554 
9555         SCSI_HBA_LOG((_LOGIPT, self, NULL,
9556             "%s @%s", damap_name(iportmap->iportmap_dam), iport_addr));
9557 
9558         return ((damap_addr_add(iportmap->iportmap_dam, iport_addr, NULL,
9559             NULL, iport_priv) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
9560 }
9561 
9562 int
9563 scsi_hba_iportmap_iport_remove(scsi_hba_iportmap_t *handle,
9564     char *iport_addr)
9565 {
9566         impl_scsi_iportmap_t    *iportmap = (impl_scsi_iportmap_t *)handle;
9567         dev_info_t              *self = iportmap->iportmap_hba_dip;
9568 
9569         SCSI_HBA_LOG((_LOGIPT, self, NULL,
9570             "%s @%s", damap_name(iportmap->iportmap_dam), iport_addr));
9571 
9572         return ((damap_addr_del(iportmap->iportmap_dam,
9573             iport_addr) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
9574 }
9575 
9576 int
9577 scsi_hba_iportmap_lookup(scsi_hba_iportmap_t *handle,
9578     char *iport_addr)
9579 {
9580         impl_scsi_iportmap_t    *iportmap = (impl_scsi_iportmap_t *)handle;
9581         dev_info_t              *self = iportmap->iportmap_hba_dip;
9582         damap_id_t              iportid;
9583 
9584         iportid = damap_lookup(iportmap->iportmap_dam, iport_addr);
9585         if (iportid != NODAM) {
9586                 SCSI_HBA_LOG((_LOG(3), self, NULL,
9587                     "%s @%s found",
9588                     damap_name(iportmap->iportmap_dam), iport_addr));
9589                 damap_id_rele(iportmap->iportmap_dam, iportid);
9590                 return (DDI_SUCCESS);
9591         }
9592 
9593         SCSI_HBA_LOG((_LOG(3), self, NULL,
9594             "%s @%s not found",
9595             damap_name(iportmap->iportmap_dam), iport_addr));
9596         return (DDI_FAILURE);
9597 }
9598 
9599 
9600 static int
9601 scsi_lunmap_config(void *arg, damap_t *lundam, damap_id_t lunid)
9602 {
9603         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)arg;
9604         scsi_hba_tran_t         *tran = tgtmap->tgtmap_tran;
9605         dev_info_t              *self = tran->tran_iport_dip;
9606         char                    *addr;
9607 
9608         addr = damap_id2addr(lundam, lunid);
9609         SCSI_HBA_LOG((_LOGLUN, self, NULL,
9610             "%s @%s", damap_name(lundam), addr));
9611         if (scsi_hba_bus_configone_addr(self, addr, SE_HP) != NULL)
9612                 return (DAM_SUCCESS);
9613         else
9614                 return (DAM_FAILURE);
9615 }
9616 
9617 static int
9618 scsi_lunmap_unconfig(void *arg, damap_t *lundam, damap_id_t lunid)
9619 {
9620         impl_scsi_tgtmap_t      *tgtmap = (impl_scsi_tgtmap_t *)arg;
9621         scsi_hba_tran_t         *tran = tgtmap->tgtmap_tran;
9622         dev_info_t              *self = tran->tran_iport_dip;
9623         char                    *addr;
9624 
9625         addr = damap_id2addr(lundam, lunid);
9626         SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s @%s", damap_name(lundam),
9627             addr));
9628 
9629         scsi_hba_bus_unconfigone_addr(self, addr);
9630         return (DAM_SUCCESS);
9631 }
9632 
9633 static int
9634 scsi_lunmap_create(dev_info_t *self, impl_scsi_tgtmap_t *tgtmap, char *taddr)
9635 {
9636         char                    context[64];
9637         damap_t                 *tgtdam;
9638         damap_id_t              tgtid;
9639         damap_t                 *lundam;
9640         int                     optflags;
9641 
9642         (void) snprintf(context, sizeof (context), "%s%d.%s.lunmap",
9643             ddi_driver_name(self), ddi_get_instance(self), taddr);
9644 
9645         tgtdam = tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE];
9646         tgtid = damap_lookup(tgtdam, taddr);
9647         if (tgtid == NODAM) {
9648                 SCSI_HBA_LOG((_LOG(1), self, NULL,
9649                     "target %s not found", context));
9650                 return (DDI_FAILURE);
9651         }
9652 
9653         lundam = damap_id_priv_get(tgtdam, tgtid);
9654         if (lundam) {
9655                 SCSI_HBA_LOG((_LOG(1), self, NULL,
9656                     "lunmap %s already created", context));
9657                 damap_id_rele(tgtdam, tgtid);
9658                 return (DDI_FAILURE);
9659         }
9660 
9661         optflags = (ddi_prop_get_int(DDI_DEV_T_ANY, self,
9662             DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, "scsi-enumeration",
9663             scsi_enumeration) & SCSI_ENUMERATION_MT_LUN_DISABLE) ?
9664             DAMAP_SERIALCONFIG : DAMAP_MTCONFIG;
9665 
9666         /* NOTE: expected ref at tgtid/taddr: 2: caller + lookup. */
9667         ASSERT(damap_id_ref(tgtdam, tgtid) == 2);
9668         SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s creat, id %d ref %d",
9669             context, tgtid, damap_id_ref(tgtdam, tgtid)));
9670 
9671         /* create lundam */
9672         if (damap_create(context, DAMAP_REPORT_FULLSET, optflags, 1,
9673             NULL, NULL, NULL, tgtmap, scsi_lunmap_config, scsi_lunmap_unconfig,
9674             &lundam) != DAM_SUCCESS) {
9675                 SCSI_HBA_LOG((_LOG(1), self, NULL,
9676                     "%s create failed, id %d ref %d",
9677                     context, tgtid, damap_id_ref(tgtdam, tgtid)));
9678                 damap_id_rele(tgtdam, tgtid);
9679                 return (DDI_FAILURE);
9680         }
9681 
9682         /*
9683          * Return with damap_id_hold at tgtid/taddr from damap_lookup to
9684          * account for damap_id_prv_set below.
9685          */
9686         damap_id_priv_set(tgtdam, tgtid, lundam);
9687         return (DDI_SUCCESS);
9688 }
9689 
9690 static void
9691 scsi_lunmap_destroy(dev_info_t *self, impl_scsi_tgtmap_t *tgtmap, char *taddr)
9692 {
9693         char                    context[64];
9694         damap_t                 *tgtdam;
9695         damap_id_t              tgtid;
9696         damap_t                 *lundam;
9697 
9698         (void) snprintf(context, sizeof (context), "%s%d.%s.lunmap",
9699             ddi_driver_name(self), ddi_get_instance(self), taddr);
9700 
9701         tgtdam = tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE];
9702         tgtid = damap_lookup(tgtdam, taddr);
9703         if (tgtid == NODAM) {
9704                 SCSI_HBA_LOG((_LOG(1), self, NULL,
9705                     "target %s not found", context));
9706                 return;
9707         }
9708 
9709         lundam = (damap_t *)damap_id_priv_get(tgtdam, tgtid);
9710         if (lundam == NULL) {
9711                 damap_id_rele(tgtdam, tgtid);           /* from damap_lookup */
9712                 SCSI_HBA_LOG((_LOG(1), self, NULL,
9713                     "lunmap %s already destroyed", context));
9714                 return;
9715         }
9716 
9717         /* NOTE: expected ref at tgtid/taddr: 3: priv_set + caller + lookup. */
9718         ASSERT(damap_id_ref(tgtdam, tgtid) == 3);
9719         SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s, id %d ref %d",
9720             damap_name(lundam), tgtid, damap_id_ref(tgtdam, tgtid)));
9721 
9722         /*
9723          * A begin/end (clear) against a target's lunmap will trigger
9724          * unconfigure of all LUNs on the target.
9725          */
9726         scsi_lunmap_set_begin(self, lundam);
9727         scsi_lunmap_set_end(self, lundam);
9728 
9729         SCSI_HBA_LOG((_LOGLUN, self, NULL,
9730             "%s sync begin", damap_name(lundam)));
9731 
9732         (void) damap_sync(lundam, 0);   /* wait for unconfigure */
9733 
9734         SCSI_HBA_LOG((_LOGLUN, self, NULL,
9735             "%s sync end", damap_name(lundam)));
9736 
9737         damap_id_priv_set(tgtdam, tgtid, NULL);
9738 
9739         /* release hold established by damap_lookup above */
9740         damap_id_rele(tgtdam, tgtid);
9741 
9742         /* release hold established since scsi_lunmap_create() */
9743         damap_id_rele(tgtdam, tgtid);
9744 
9745         damap_destroy(lundam);
9746 }
9747 
9748 static void
9749 scsi_lunmap_set_begin(dev_info_t *self, damap_t *lundam)
9750 {
9751         SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s", damap_name(lundam)));
9752 
9753         (void) damap_addrset_begin(lundam);
9754 }
9755 
9756 static int
9757 scsi_lunmap_set_add(dev_info_t *self, damap_t *lundam,
9758     char *taddr, scsi_lun64_t lun64, int sfunc)
9759 {
9760         char    ua[SCSI_MAXNAMELEN];
9761 
9762         /* make unit address string form of "@taddr,lun[,sfunc]" */
9763         if (sfunc == -1)
9764                 (void) snprintf(ua, sizeof (ua), "%s,%" PRIx64, taddr, lun64);
9765         else
9766                 (void) snprintf(ua, sizeof (ua), "%s,%" PRIx64 ",%x",
9767                     taddr, lun64, sfunc);
9768 
9769         SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s @%s", damap_name(lundam), ua));
9770 
9771         return ((damap_addrset_add(lundam, ua, NULL, NULL,
9772             NULL) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
9773 }
9774 
9775 static void
9776 scsi_lunmap_set_end(dev_info_t *self, damap_t *lundam)
9777 {
9778         SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s", damap_name(lundam)));
9779 
9780         (void) damap_addrset_end(lundam, 0);
9781 }
9782 
9783 int
9784 scsi_lunmap_lookup(dev_info_t *self, damap_t *lundam, char *addr)
9785 {
9786         damap_id_t              lunid;
9787 
9788         if ((lunid = damap_lookup(lundam, addr)) != NODAM) {
9789                 SCSI_HBA_LOG((_LOG(3), self, NULL,
9790                     "%s @%s found", damap_name(lundam), addr));
9791                 damap_id_rele(lundam, lunid);
9792                 return (DDI_SUCCESS);
9793         }
9794 
9795         SCSI_HBA_LOG((_LOG(3), self, NULL,
9796             "%s @%s not found", damap_name(lundam), addr));
9797         return (DDI_FAILURE);
9798 }
9799 
9800 /*
9801  * phymap implementation
9802  *
9803  * We manage the timed aggregation of phys into a phy map * by creating a
9804  * SAS port construct (based upon 'name' of "local,remote" SAS addresses)
9805  * upon the first link up. As time goes on additional phys may join that port.
9806  * After an appropriate amount of settle time, we trigger the activation
9807  * callback which will then take the resultant bit mask of phys (phymask) in
9808  * the SAS port and use that to call back to the callback function
9809  * provided by the additional caller.
9810  *
9811  * We cross check to make sure that phys only exist in one SAS port at a
9812  * time by having soft state for each phy point back to the created
9813  * SAS port.
9814  *
9815  * NOTE: Make SAS_PHY_UA_LEN max(SAS_PHY_PHYMASK_LEN, SAS_PHY_NAME_LEN)
9816  * so we have enough space if sas_phymap_bitset2phymaskua phymask address
9817  * is already in use, and we end up using port name as unit address.
9818  */
9819 #define SAS_PHY_NAME_FMT        "%" PRIx64 ",%" PRIx64
9820 #define SAS_PHY_NAME_LEN        (16 + 1 + 16 + 1)
9821 #define SAS_PHY_NPHY            (SAS2_PHYNUM_MAX + 1)
9822 #define SAS_PHY_PHYMASK_LEN     ((roundup(SAS_PHY_NPHY, 4)) / 4)
9823 #if     (SAS_PHY_PHYMASK_LEN > SAS_PHY_NAME_LEN)
9824 #define SAS_PHY_UA_LEN          SAS_PHY_PHYMASK_LEN
9825 #else
9826 #define SAS_PHY_UA_LEN          SAS_PHY_NAME_LEN
9827 #endif
9828 typedef struct impl_sas_physet {        /* needed for name2phys destroy */
9829         struct impl_sas_physet          *physet_next;
9830         char                            *physet_name;
9831         bitset_t                        *physet_phys;
9832 } impl_sas_physet_t;
9833 typedef struct impl_sas_phymap {
9834         dev_info_t                      *phymap_self;
9835 
9836         kmutex_t                        phymap_lock;
9837         damap_t                         *phymap_dam;
9838         void                            *phymap_phy2name;
9839         ddi_soft_state_bystr            *phymap_name2phys;      /* bitset */
9840         ddi_soft_state_bystr            *phymap_name2ua;
9841         ddi_soft_state_bystr            *phymap_ua2name;
9842 
9843         /* Noisy phy information - ensure forward progress for noisy phys */
9844         int                             phymap_phy_max;         /* max phy# */
9845         int                             phymap_reports;         /* per period */
9846         int                             phymap_reports_max;     /* scales */
9847         int                             phymap_phys_noisy;      /* detected */
9848 
9849         /* These are for callbacks to the consumer. */
9850         sas_phymap_activate_cb_t        phymap_acp;
9851         sas_phymap_deactivate_cb_t      phymap_dcp;
9852         void                            *phymap_private;
9853 
9854         struct impl_sas_physet          *phymap_physets;
9855 } impl_sas_phymap_t;
9856 
9857 /* Detect noisy phy: max changes per stabilization period per phy. */
9858 static int sas_phymap_phy_max_factor = 16;
9859 
9860 /*
9861  * Convert bitset into a unit-address string. The maximum string length would
9862  * be the maximum number of phys, rounded up by 4 and divided by 4.
9863  */
9864 static void
9865 sas_phymap_bitset2phymaskua(bitset_t *phys, char *buf)
9866 {
9867         char                    *ptr;
9868         int                     grp;
9869         int                     cur;
9870         uint_t                  bit;
9871 
9872         bit = roundup(SAS_PHY_NPHY, 4);
9873         grp = 4;
9874         ptr = buf;
9875         cur = 0;
9876         do {
9877                 bit -= 1;
9878                 grp -= 1;
9879                 if (bitset_in_set(phys, bit)) {
9880                         cur |= (1 << grp);
9881                 }
9882                 if (grp == 0) {
9883                         grp = 4;
9884                         if (cur || ptr != buf) {
9885                                 *ptr++ = "0123456789abcdef"[cur];
9886                                 *ptr = 0;
9887                         }
9888                         cur = 0;
9889                 }
9890         } while (bit != 0);
9891         if (ptr == buf) {
9892                 *ptr++ = '0';
9893                 *ptr = 0;
9894         }
9895 }
9896 
9897 static int
9898 sas_phymap_config(void *arg, damap_t *phydam, damap_id_t phyid)
9899 {
9900         impl_sas_phymap_t       *phymap = (impl_sas_phymap_t *)arg;
9901         char                    *context = damap_name(phymap->phymap_dam);
9902         char                    *damn;
9903         char                    *name;
9904         bitset_t                *phys;
9905         char                    *ua;
9906         void                    *ua_priv;
9907 
9908         ASSERT(context);
9909 
9910         mutex_enter(&phymap->phymap_lock);
9911         phymap->phymap_reports = phymap->phymap_phys_noisy = 0;
9912 
9913         /* Get the name ("local,remote" address string) from damap. */
9914         damn = damap_id2addr(phydam, phyid);
9915 
9916         /* Get the bitset of phys currently forming the port. */
9917         phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, damn);
9918         if (phys == NULL) {
9919                 SCSI_HBA_LOG((_LOG_NF(WARN), "%s: %s: no phys",
9920                     context, damn));
9921                 mutex_exit(&phymap->phymap_lock);
9922                 return (DAM_FAILURE);
9923         }
9924 
9925         /* allocate, get, and initialize name index of name2ua map */
9926         if (ddi_soft_state_bystr_zalloc(phymap->phymap_name2ua, damn) !=
9927             DDI_SUCCESS) {
9928                 SCSI_HBA_LOG((_LOG_NF(WARN),
9929                     "%s: %s: failed name2ua alloc", context, damn));
9930                 mutex_exit(&phymap->phymap_lock);
9931                 return (DAM_FAILURE);
9932         }
9933         if (!(ua = ddi_soft_state_bystr_get(phymap->phymap_name2ua, damn))) {
9934                 SCSI_HBA_LOG((_LOG_NF(WARN),
9935                     "%s: %s: no name2ua", context, damn));
9936                 mutex_exit(&phymap->phymap_lock);
9937                 return (DAM_FAILURE);
9938         }
9939         sas_phymap_bitset2phymaskua(phys, ua);          /* set ua */
9940 
9941         /* see if phymask ua index already allocated in ua2name map */
9942         if (name = ddi_soft_state_bystr_get(phymap->phymap_ua2name, ua)) {
9943                 /*
9944                  * The 'phymask' sas_phymap_bitset2phymaskua ua is
9945                  * already in use. This means that original phys have
9946                  * formed into a new port, and that the original port
9947                  * still exists (it has migrated to some completely
9948                  * different set of phys). In this corner-case we use
9949                  * "local,remote" name as a 'temporary' unit address.
9950                  * Reset ua in name2ua map.
9951                  */
9952                 (void) strlcpy(ua, damn, SAS_PHY_NAME_LEN);
9953                 name = ddi_soft_state_bystr_get(phymap->phymap_ua2name, ua);
9954                 if (name) {
9955                         /* The "local,remote" ua should be new... */
9956                         SCSI_HBA_LOG((_LOG_NF(WARN),
9957                             "%s: %s ua already configured",
9958                             context, ua));
9959                         mutex_exit(&phymap->phymap_lock);
9960                         return (DAM_SUCCESS);
9961                 }
9962         }
9963 
9964         /* allocate, get, and init ua index of ua2name map */
9965         if (ddi_soft_state_bystr_zalloc(phymap->phymap_ua2name, ua) !=
9966             DDI_SUCCESS) {
9967                 ddi_soft_state_bystr_free(phymap->phymap_name2ua, damn);
9968                 SCSI_HBA_LOG((_LOG_NF(WARN), "%s: %s: failed ua2name alloc",
9969                     context, damn));
9970                 mutex_exit(&phymap->phymap_lock);
9971                 return (DAM_FAILURE);
9972         }
9973         name = ddi_soft_state_bystr_get(phymap->phymap_ua2name, ua);
9974         if (name == NULL) {
9975                 ddi_soft_state_bystr_free(phymap->phymap_name2ua, damn);
9976                 SCSI_HBA_LOG((_LOG_NF(WARN),
9977                     "%s: %s: no ua2name", context, ua));
9978                 mutex_exit(&phymap->phymap_lock);
9979                 return (DAM_FAILURE);
9980         }
9981 
9982         /* set name in ua2name map */
9983         (void) strlcpy(name, damn, SAS_PHY_NAME_LEN);
9984 
9985         SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL,
9986             "%s: %s: ua %s: activate", context, damn, ua));
9987 
9988         if (phymap->phymap_acp) {
9989                 /*
9990                  * drop our lock and invoke the activation callback
9991                  */
9992                 mutex_exit(&phymap->phymap_lock);
9993                 ua_priv = NULL;
9994                 (phymap->phymap_acp)(phymap->phymap_private, ua, &ua_priv);
9995                 mutex_enter(&phymap->phymap_lock);
9996                 damap_id_priv_set(phydam, phyid, ua_priv);
9997         }
9998         SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL,
9999             "%s: %s: ua %s: activate complete", context, damn, ua));
10000         mutex_exit(&phymap->phymap_lock);
10001         return (DAM_SUCCESS);
10002 }
10003 
10004 /*ARGSUSED*/
10005 static int
10006 sas_phymap_unconfig(void *arg, damap_t *phydam, damap_id_t phyid)
10007 {
10008         impl_sas_phymap_t       *phymap = (impl_sas_phymap_t *)arg;
10009         char                    *context = damap_name(phymap->phymap_dam);
10010         char                    *damn;
10011         char                    *ua;
10012         void                    *ua_priv;
10013 
10014         ASSERT(context);
10015 
10016         mutex_enter(&phymap->phymap_lock);
10017         phymap->phymap_reports = phymap->phymap_phys_noisy = 0;
10018 
10019         /* Get the name ("local,remote" address string) from damap. */
10020         damn = damap_id2addr(phydam, phyid);
10021 
10022         if (!(ua = ddi_soft_state_bystr_get(phymap->phymap_name2ua, damn))) {
10023                 SCSI_HBA_LOG((_LOG_NF(WARN),
10024                     "%s: %s: no name2ua", context, damn));
10025                 mutex_exit(&phymap->phymap_lock);
10026                 return (DAM_FAILURE);
10027         }
10028 
10029         SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL,
10030             "%s: %s: ua %s: deactivate", context, damn, ua));
10031         if (phymap->phymap_dcp) {
10032                 ua_priv = damap_id_priv_get(phydam, phyid);
10033                 mutex_exit(&phymap->phymap_lock);
10034                 (phymap->phymap_dcp)(phymap->phymap_private, ua, ua_priv);
10035                 mutex_enter(&phymap->phymap_lock);
10036         }
10037         SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL,
10038             "%s: %s: ua %s: deactivate complete", context, damn, ua));
10039 
10040         /* delete ua<->name mappings */
10041         ddi_soft_state_bystr_free(phymap->phymap_ua2name, ua);
10042         ddi_soft_state_bystr_free(phymap->phymap_name2ua, damn);
10043         mutex_exit(&phymap->phymap_lock);
10044         return (DAM_SUCCESS);
10045 }
10046 
10047 int
10048 sas_phymap_create(dev_info_t *self, int settle_usec,
10049     sas_phymap_mode_t mode, void *mode_argument, void *phymap_priv,
10050     sas_phymap_activate_cb_t  activate_cb,
10051     sas_phymap_deactivate_cb_t deactivate_cb,
10052     sas_phymap_t **handlep)
10053 {
10054         _NOTE(ARGUNUSED(mode_argument));
10055         char                    context[64];
10056         impl_sas_phymap_t       *phymap;
10057 
10058         if (self == NULL || settle_usec == 0 || handlep == NULL)
10059                 return (DDI_FAILURE);
10060 
10061         if (mode != PHYMAP_MODE_SIMPLE)
10062                 return (DDI_FAILURE);
10063 
10064         phymap = kmem_zalloc(sizeof (*phymap), KM_SLEEP);
10065         phymap->phymap_self = self;
10066         phymap->phymap_reports_max = 1 * sas_phymap_phy_max_factor;
10067         phymap->phymap_acp = activate_cb;
10068         phymap->phymap_dcp = deactivate_cb;
10069         phymap->phymap_private = phymap_priv;
10070         mutex_init(&phymap->phymap_lock, NULL, MUTEX_DRIVER, NULL);
10071 
10072         (void) snprintf(context, sizeof (context), "%s%d.phymap",
10073             ddi_driver_name(self), ddi_get_instance(self));
10074         SCSI_HBA_LOG((_LOGPHY, self, NULL, "%s", context));
10075 
10076         if (ddi_soft_state_init(&phymap->phymap_phy2name,
10077             SAS_PHY_NAME_LEN, SAS_PHY_NPHY) != 0)
10078                 goto fail;
10079         if (ddi_soft_state_bystr_init(&phymap->phymap_name2phys,
10080             sizeof (bitset_t), SAS_PHY_NPHY) != 0)
10081                 goto fail;
10082 
10083         if (ddi_soft_state_bystr_init(&phymap->phymap_name2ua,
10084             SAS_PHY_UA_LEN, SAS_PHY_NPHY) != 0)
10085                 goto fail;
10086         if (ddi_soft_state_bystr_init(&phymap->phymap_ua2name,
10087             SAS_PHY_NAME_LEN, SAS_PHY_NPHY) != 0)
10088                 goto fail;
10089 
10090         if (damap_create(context, DAMAP_REPORT_PERADDR, DAMAP_SERIALCONFIG,
10091             settle_usec, NULL, NULL, NULL,
10092             phymap, sas_phymap_config, sas_phymap_unconfig,
10093             &phymap->phymap_dam) != DAM_SUCCESS)
10094                 goto fail;
10095 
10096 
10097         *handlep = (sas_phymap_t *)phymap;
10098         return (DDI_SUCCESS);
10099 
10100 fail:   sas_phymap_destroy((sas_phymap_t *)phymap);
10101         *handlep = NULL;
10102         return (DDI_FAILURE);
10103 }
10104 
10105 void
10106 sas_phymap_destroy(sas_phymap_t *handle)
10107 {
10108         impl_sas_phymap_t       *phymap = (impl_sas_phymap_t *)handle;
10109         char                    *context;
10110         struct impl_sas_physet  *physet, *nphyset;
10111         bitset_t                *phys;
10112         char                    *name;
10113 
10114         context = phymap->phymap_dam ?
10115             damap_name(phymap->phymap_dam) : "unknown";
10116         SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, "%s", context));
10117 
10118         if (phymap->phymap_dam)
10119                 damap_destroy(phymap->phymap_dam);
10120 
10121         /* free the bitsets of allocated physets */
10122         for (physet = phymap->phymap_physets; physet; physet = nphyset) {
10123                 nphyset = physet->physet_next;
10124                 phys = physet->physet_phys;
10125                 name = physet->physet_name;
10126 
10127                 if (phys)
10128                         bitset_fini(phys);
10129                 if (name) {
10130                         ddi_soft_state_bystr_free(
10131                             phymap->phymap_name2phys, name);
10132                         strfree(name);
10133                 }
10134                 kmem_free(physet, sizeof (*physet));
10135         }
10136 
10137         /* free the maps */
10138         if (phymap->phymap_ua2name)
10139                 ddi_soft_state_bystr_fini(&phymap->phymap_ua2name);
10140         if (phymap->phymap_name2ua)
10141                 ddi_soft_state_bystr_fini(&phymap->phymap_name2ua);
10142 
10143         if (phymap->phymap_name2phys)
10144                 ddi_soft_state_bystr_fini(&phymap->phymap_name2phys);
10145         if (phymap->phymap_phy2name)
10146                 ddi_soft_state_fini(&phymap->phymap_phy2name);
10147 
10148         mutex_destroy(&phymap->phymap_lock);
10149         kmem_free(phymap, sizeof (*phymap));
10150 }
10151 
10152 
10153 int
10154 sas_phymap_phy_add(sas_phymap_t *handle,
10155     int phy, uint64_t local, uint64_t remote)
10156 {
10157         impl_sas_phymap_t       *phymap = (impl_sas_phymap_t *)handle;
10158         char                    *context = damap_name(phymap->phymap_dam);
10159         char                    port[SAS_PHY_NAME_LEN];
10160         char                    *name;
10161         int                     phy2name_allocated = 0;
10162         bitset_t                *phys;
10163         struct impl_sas_physet  *physet;
10164         int                     rv;
10165 
10166         /* Create the SAS port name from the local and remote addresses. */
10167         (void) snprintf(port, SAS_PHY_NAME_LEN, SAS_PHY_NAME_FMT,
10168             local, remote);
10169 
10170         mutex_enter(&phymap->phymap_lock);
10171         SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, "%s: %s: add phy %d",
10172             context, port, phy));
10173 
10174         /* Check for conflict in phy2name map */
10175         name = ddi_get_soft_state(phymap->phymap_phy2name, phy);
10176         if (name) {
10177                 if (strcmp(name, port) != 0)
10178                         SCSI_HBA_LOG((_LOG_NF(WARN), "%s: %s: add phy %d: "
10179                             "already in %s", context, port, phy, name));
10180                 else
10181                         SCSI_HBA_LOG((_LOG_NF(WARN), "%s: %s: add phy %d: "
10182                             "duplicate add", context, port, phy));
10183                 mutex_exit(&phymap->phymap_lock);
10184                 return (DDI_FAILURE);
10185         }
10186 
10187         /* allocate, get, and initialize phy index of phy2name map */
10188         if (ddi_soft_state_zalloc(
10189             phymap->phymap_phy2name, phy) != DDI_SUCCESS) {
10190                 SCSI_HBA_LOG((_LOG_NF(WARN),
10191                     "%s: %s: failed phy2name alloc", context, port));
10192                 goto fail;
10193         }
10194         name = ddi_get_soft_state(phymap->phymap_phy2name, phy);
10195         if (name == NULL) {
10196                 SCSI_HBA_LOG((_LOG_NF(WARN),
10197                     "%s: %s: no phy2name", context, port));
10198                 goto fail;
10199         }
10200         phy2name_allocated = 1;
10201         (void) strlcpy(name, port, SAS_PHY_NAME_LEN);   /* set name */
10202 
10203         /* Find/alloc, initialize name index of name2phys map */
10204         phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, name);
10205         if (phys == NULL) {
10206                 if (ddi_soft_state_bystr_zalloc(phymap->phymap_name2phys,
10207                     name) != DDI_SUCCESS) {
10208                         SCSI_HBA_LOG((_LOG_NF(WARN),
10209                             "%s: %s: failed name2phys alloc", context, name));
10210                         goto fail;
10211                 }
10212                 phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, name);
10213                 if (phys == NULL) {
10214                         SCSI_HBA_LOG((_LOG_NF(WARN),
10215                             "%s: %s: no name2phys", context, name));
10216                         goto fail;
10217                 }
10218 
10219                 /* Initialize bitset of phys. */
10220                 bitset_init(phys);
10221                 bitset_resize(phys, SAS_PHY_NPHY);
10222 
10223                 /* Keep a list of information for destroy. */
10224                 physet = kmem_zalloc(sizeof (*physet), KM_SLEEP);
10225                 physet->physet_name = strdup(name);
10226                 physet->physet_phys = phys;
10227                 physet->physet_next = phymap->phymap_physets;
10228                 phymap->phymap_physets = physet;
10229         }
10230         ASSERT(phys);
10231 
10232         /* Reflect 'add' in phys bitset. */
10233         if (bitset_atomic_test_and_add(phys, phy) < 0) {
10234                 /* It is an error if the phy was already recorded. */
10235                 SCSI_HBA_LOG((_LOG_NF(WARN),
10236                     "%s: %s: phy bit %d already in port", context, name, phy));
10237                 goto fail;
10238         }
10239 
10240         /*
10241          * Check to see if we have a new phy_max for this map, and if so
10242          * scale phymap_reports_max to the new number of phys.
10243          */
10244         if (phy > phymap->phymap_phy_max) {
10245                 phymap->phymap_phy_max = phy + 1;
10246                 phymap->phymap_reports_max = phymap->phymap_phy_max *
10247                     sas_phymap_phy_max_factor;
10248         }
10249 
10250         /*
10251          * If we have not reached phymap_reports_max, start/restart the
10252          * activate timer. Otherwise, if phymap->phymap_reports add/rem reports
10253          * ever exceeds phymap_reports_max due to noisy phys, then report the
10254          * noise and force stabilization by stopping reports into the damap.
10255          *
10256          * The first config/unconfig callout out of the damap will reset
10257          * phymap->phymap_reports.
10258          */
10259         rv = DDI_SUCCESS;
10260         if (phymap->phymap_reports++ < phymap->phymap_reports_max) {
10261                 if (damap_addr_add(phymap->phymap_dam, name,
10262                     NULL, NULL, NULL) == DAM_SUCCESS) {
10263                         SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL,
10264                             "%s: %s: damap_addr_add", context, name));
10265                 } else {
10266                         SCSI_HBA_LOG((_LOG_NF(WARN),
10267                             "%s: %s: damap_addr_add failed", context, name));
10268                         rv = DDI_FAILURE;
10269                 }
10270         } else {
10271                 phymap->phymap_phys_noisy++;
10272                 if (phymap->phymap_phys_noisy == 1)
10273                         SCSI_HBA_LOG((_LOG_NF(WARN),
10274                             "%s: %s: noisy phys", context, name));
10275         }
10276         mutex_exit(&phymap->phymap_lock);
10277         return (rv);
10278 
10279 fail:   if (phy2name_allocated)
10280                 ddi_soft_state_free(phymap->phymap_phy2name, phy);
10281         mutex_exit(&phymap->phymap_lock);
10282         return (DDI_FAILURE);
10283 }
10284 
10285 int
10286 sas_phymap_phy_rem(sas_phymap_t *handle, int phy)
10287 {
10288         impl_sas_phymap_t       *phymap = (impl_sas_phymap_t *)handle;
10289         char                    *context = damap_name(phymap->phymap_dam);
10290         char                    *name;
10291         bitset_t                *phys;
10292         int                     rv = DDI_FAILURE;
10293 
10294         ASSERT(context);
10295 
10296         mutex_enter(&phymap->phymap_lock);
10297         phymap->phymap_reports++;
10298 
10299         /* Find and free phy index of phy2name map */
10300         name = ddi_get_soft_state(phymap->phymap_phy2name, phy);
10301         if (name == NULL) {
10302                 SCSI_HBA_LOG((_LOG_NF(WARN), "%s: rem phy %d: never added",
10303                     context, phy));
10304                 goto fail;
10305         }
10306         /* NOTE: always free phy index of phy2name map before return... */
10307 
10308         SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, "%s: %s: rem phy %d",
10309             context, name, phy));
10310 
10311         /* Get bitset of phys currently associated with named port. */
10312         phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, name);
10313         if (phys == NULL) {
10314                 SCSI_HBA_LOG((_LOG_NF(WARN), "%s: %s: name2phys failed",
10315                     context, name));
10316                 goto fail;
10317         }
10318 
10319         /* Reflect 'rem' in phys bitset. */
10320         if (bitset_atomic_test_and_del(phys, phy) < 0) {
10321                 /* It is an error if the phy wasn't one of the port's phys. */
10322                 SCSI_HBA_LOG((_LOG_NF(WARN),
10323                     "%s: %s: phy bit %d not in port", context, name, phy));
10324                 goto fail;
10325         }
10326 
10327         /* If this was the last phy in the port, start the deactivate timer. */
10328         if (bitset_is_null(phys) &&
10329             (phymap->phymap_reports++ < phymap->phymap_reports_max)) {
10330                 if (damap_addr_del(phymap->phymap_dam, name) == DAM_SUCCESS) {
10331                         SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL,
10332                             "%s: %s: damap_addr_del", context, name));
10333                 } else {
10334                         SCSI_HBA_LOG((_LOG_NF(WARN),
10335                             "%s: %s: damap_addr_del failure", context, name));
10336                         goto fail;
10337                 }
10338         }
10339         rv = DDI_SUCCESS;
10340 
10341         /* free phy index of phy2name map */
10342 fail:   if (name)
10343                 ddi_soft_state_free(phymap->phymap_phy2name, phy); /* free */
10344         mutex_exit(&phymap->phymap_lock);
10345         return (rv);
10346 }
10347 
10348 char *
10349 sas_phymap_lookup_ua(sas_phymap_t *handle, uint64_t local, uint64_t remote)
10350 {
10351         impl_sas_phymap_t       *phymap = (impl_sas_phymap_t *)handle;
10352         char                    *context = damap_name(phymap->phymap_dam);
10353         char                    name[SAS_PHY_NAME_LEN];
10354         char                    *ua;
10355 
10356         ASSERT(context);
10357 
10358         (void) snprintf(name, SAS_PHY_NAME_LEN, SAS_PHY_NAME_FMT,
10359             local, remote);
10360 
10361         mutex_enter(&phymap->phymap_lock);
10362         ua = ddi_soft_state_bystr_get(phymap->phymap_name2ua, name);
10363         SCSI_HBA_LOG((_LOG(3), phymap->phymap_self, NULL,
10364             "%s: %s: ua %s", context, name, ua ? ua : "NULL"));
10365         mutex_exit(&phymap->phymap_lock);
10366         return (ua);
10367 }
10368 
10369 void *
10370 sas_phymap_lookup_uapriv(sas_phymap_t *handle, char *ua)
10371 {
10372         impl_sas_phymap_t       *phymap = (impl_sas_phymap_t *)handle;
10373         char                    *context = damap_name(phymap->phymap_dam);
10374         char                    *name;
10375         damap_id_t              phyid;
10376         void                    *ua_priv = NULL;
10377 
10378         ASSERT(context);
10379 
10380         mutex_enter(&phymap->phymap_lock);
10381         name = ddi_soft_state_bystr_get(phymap->phymap_ua2name, ua);
10382         if (name) {
10383                 phyid = damap_lookup(phymap->phymap_dam, name);
10384                 if (phyid != NODAM) {
10385                         ua_priv = damap_id_priv_get(phymap->phymap_dam, phyid);
10386                         damap_id_rele(phymap->phymap_dam, phyid);
10387                 }
10388         }
10389 
10390         SCSI_HBA_LOG((_LOG(3), phymap->phymap_self, NULL,
10391             "%s: %s: ua %s ua_priv %p", context, name,
10392             ua ? ua : "NULL", ua_priv));
10393         mutex_exit(&phymap->phymap_lock);
10394         return (ua_priv);
10395 }
10396 
10397 int
10398 sas_phymap_uahasphys(sas_phymap_t *handle, char *ua)
10399 {
10400         impl_sas_phymap_t       *phymap = (impl_sas_phymap_t *)handle;
10401         char                    *name;
10402         bitset_t                *phys;
10403         int                     n = 0;
10404 
10405         mutex_enter(&phymap->phymap_lock);
10406         name = ddi_soft_state_bystr_get(phymap->phymap_ua2name, ua);
10407         if (name) {
10408                 phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, name);
10409                 if (phys)
10410                         n = bitset_is_null(phys) ? 0 : 1;
10411         }
10412         mutex_exit(&phymap->phymap_lock);
10413         return (n);
10414 }
10415 
10416 sas_phymap_phys_t *
10417 sas_phymap_ua2phys(sas_phymap_t *handle, char *ua)
10418 {
10419         impl_sas_phymap_t       *phymap = (impl_sas_phymap_t *)handle;
10420         char                    *name;
10421         bitset_t                *phys;
10422         bitset_t                *cphys = NULL;
10423 
10424         mutex_enter(&phymap->phymap_lock);
10425         name = ddi_soft_state_bystr_get(phymap->phymap_ua2name, ua);
10426         if (name == NULL)
10427                 goto fail;
10428 
10429         phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, name);
10430         if (phys == NULL)
10431                 goto fail;
10432 
10433         /* dup the phys and return */
10434         cphys = kmem_alloc(sizeof (*cphys), KM_SLEEP);
10435         bitset_init(cphys);
10436         bitset_resize(cphys, SAS_PHY_NPHY);
10437         bitset_copy(phys, cphys);
10438 
10439 fail:   mutex_exit(&phymap->phymap_lock);
10440         return ((sas_phymap_phys_t *)cphys);
10441 }
10442 
10443 int
10444 sas_phymap_phys_next(sas_phymap_phys_t *phys)
10445 {
10446         bitset_t        *cphys = (bitset_t *)phys;
10447         int             phy;
10448 
10449         phy = bitset_find(cphys);
10450         if (phy != -1)
10451                 bitset_del(cphys, phy);
10452         return (phy);
10453 }
10454 
10455 void
10456 sas_phymap_phys_free(sas_phymap_phys_t *phys)
10457 {
10458         bitset_t        *cphys = (bitset_t *)phys;
10459 
10460         if (cphys) {
10461                 bitset_fini(cphys);
10462                 kmem_free(cphys, sizeof (*cphys));
10463         }
10464 }
10465 
10466 char *
10467 sas_phymap_phy2ua(sas_phymap_t *handle, int phy)
10468 {
10469         impl_sas_phymap_t       *phymap = (impl_sas_phymap_t *)handle;
10470         char                    *name;
10471         char                    *ua;
10472         char                    *rua = NULL;
10473 
10474         mutex_enter(&phymap->phymap_lock);
10475         name = ddi_get_soft_state(phymap->phymap_phy2name, phy);
10476         if (name == NULL)
10477                 goto fail;
10478         ua = ddi_soft_state_bystr_get(phymap->phymap_name2ua, name);
10479         if (ua == NULL)
10480                 goto fail;
10481 
10482         /* dup the ua and return */
10483         rua = strdup(ua);
10484 
10485 fail:   mutex_exit(&phymap->phymap_lock);
10486         return (rua);
10487 }
10488 
10489 void
10490 sas_phymap_ua_free(char *ua)
10491 {
10492         if (ua)
10493                 strfree(ua);
10494 }