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