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