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 * 3564 * scsa.f: (failover form-group): 3565 * E Explicit Target_Port_Group: Used 3566 * when inq_tpgse is set and 'G' is 3567 * alse present. 3568 * G GUID: Used when a GUID can be 3569 * generated for the device. 3570 * I Implicit Target_Port_Group: Used 3571 * when inq_tpgs is set and 'G' is 3572 * also present. 3573 * 3574 * Forms using FFF are only be generated 3575 * if there are applicable flag 3576 * characters. 3577 * 3578 * b is the letter 'b'. Denotes the 3579 * beginning of BBBBBBBB. 3580 * 3581 * BBBBBBBB Binding-set. Operating System Specific: 3582 * scsi-binding-set property of HBA. 3583 */ 3584 #define NCOMPAT (1 + (13 + 2) + 1) 3585 #define COMPAT_LONGEST (strlen( \ 3586 "scsiclass,DDEEFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR" + 1)) 3587 3588 /* 3589 * Private version with extra device 'identity' arguments to allow code 3590 * to determine GUID FFF support. 3591 */ 3592 static void 3593 scsi_hba_ident_nodename_compatible_get(struct scsi_inquiry *inq, 3594 uchar_t *inq80, size_t inq80len, uchar_t *inq83, size_t inq83len, 3595 char *binding_set, int dtype_node, char *compat0, 3596 char **nodenamep, char **drivernamep, 3597 char ***compatiblep, int *ncompatiblep) 3598 { 3599 char vid[sizeof (inq->inq_vid) + 1 ]; 3600 char pid[sizeof (inq->inq_pid) + 1]; 3601 char rev[sizeof (inq->inq_revision) + 1]; 3602 char gf[sizeof ("R\0")]; 3603 char ff[sizeof ("EGI\0")]; 3604 int dtype_device; 3605 int ncompat; /* number of compatible */ 3606 char **compatp; /* compatible ptrs */ 3607 int i; 3608 char *nname; /* nodename */ 3609 char *dname; /* driver name */ 3610 char **csp; 3611 char *p; 3612 int tlen; 3613 int len; 3614 major_t major; 3615 ddi_devid_t devid; 3616 char *guid; 3617 3618 /* 3619 * Nodename_aliases: This table was originally designed to be 3620 * implemented via a new nodename_aliases file - a peer to the 3621 * driver_aliases that selects a nodename based on compatible 3622 * forms in much the same say driver_aliases is used to select 3623 * driver bindings from compatible forms. Each compatible form 3624 * is an 'alias'. Until a more general need for a 3625 * nodename_aliases file exists, which may never occur, the 3626 * scsi mappings are described here via a compiled in table. 3627 * 3628 * This table contains nodename mappings for self-identifying 3629 * scsi devices enumerated by the Solaris kernel. For a given 3630 * device, the highest precedence "compatible" form with a 3631 * mapping is used to select the nodename for the device. This 3632 * will typically be a generic nodename, however in some legacy 3633 * compatibility cases a driver nodename mapping may be selected. 3634 * 3635 * Because of possible breakage associated with switching SCSI 3636 * target devices from driver nodenames to generic nodenames, 3637 * we are currently unable to support generic nodenames for all 3638 * SCSI devices (binding-sets). Although /devices paths are 3639 * defined as unstable, avoiding possible breakage is 3640 * important. Some of the newer SCSI transports (USB) already 3641 * use generic nodenames. All new SCSI transports and target 3642 * devices should use generic nodenames. At times this decision 3643 * may be architecture dependent (sparc .vs. intel) based on when 3644 * a transport was supported on a particular architecture. 3645 * 3646 * We provide a base set of generic nodename mappings based on 3647 * scsiclass dtype and higher-precedence driver nodename 3648 * mappings based on scsa "binding-set" to cover legacy 3649 * issues. The binding-set is typically associated with 3650 * "scsi-binding-set" property value of the HBA. The legacy 3651 * mappings are provided independent of whether the driver they 3652 * refer to is installed. This allows a correctly named node 3653 * be created at discovery time, and binding to occur when/if 3654 * an add_drv of the legacy driver occurs. 3655 * 3656 * We also have mappings for legacy SUN hardware that 3657 * misidentifies itself (enclosure services which identify 3658 * themselves as processors). All future hardware should use 3659 * the correct dtype. 3660 * 3661 * As SCSI HBAs are modified to use the SCSA interfaces for 3662 * self-identifying SCSI target devices (PSARC/2004/116) the 3663 * nodename_aliases table (PSARC/2004/420) should be augmented 3664 * with legacy mappings in order to maintain compatibility with 3665 * existing /devices paths, especially for devices that house 3666 * an OS. Failure to do this may cause upgrade problems. 3667 * Additions for new target devices or transports should not 3668 * add scsa binding-set compatible mappings. 3669 */ 3670 static struct nodename_aliases { 3671 char *na_nodename; /* nodename */ 3672 char *na_alias; /* compatible form match */ 3673 } na[] = { 3674 /* # mapping to generic nodenames based on scsi dtype */ 3675 {"disk", "scsiclass,00"}, 3676 {"tape", "scsiclass,01"}, 3677 {"printer", "scsiclass,02"}, 3678 {"processor", "scsiclass,03"}, 3679 {"worm", "scsiclass,04"}, 3680 {"cdrom", "scsiclass,05"}, 3681 {"scanner", "scsiclass,06"}, 3682 {"optical-disk", "scsiclass,07"}, 3683 {"medium-changer", "scsiclass,08"}, 3684 {"obsolete", "scsiclass,09"}, 3685 {"prepress-a", "scsiclass,0a"}, 3686 {"prepress-b", "scsiclass,0b"}, 3687 {"array-controller", "scsiclass,0c"}, 3688 {"enclosure", "scsiclass,0d"}, 3689 {"disk", "scsiclass,0e"}, 3690 {"card-reader", "scsiclass,0f"}, 3691 {"bridge", "scsiclass,10"}, 3692 {"object-store", "scsiclass,11"}, 3693 {"reserved", "scsiclass,12"}, 3694 {"reserved", "scsiclass,13"}, 3695 {"reserved", "scsiclass,14"}, 3696 {"reserved", "scsiclass,15"}, 3697 {"reserved", "scsiclass,16"}, 3698 {"reserved", "scsiclass,17"}, 3699 {"reserved", "scsiclass,18"}, 3700 {"reserved", "scsiclass,19"}, 3701 {"reserved", "scsiclass,1a"}, 3702 {"reserved", "scsiclass,1b"}, 3703 {"reserved", "scsiclass,1c"}, 3704 {"reserved", "scsiclass,1d"}, 3705 {"well-known-lun", "scsiclass,1e"}, 3706 {"unknown", "scsiclass,1f"}, 3707 3708 #ifdef sparc 3709 /* # legacy mapping to driver nodenames for fcp binding-set */ 3710 {"ssd", "scsa,00.bfcp"}, 3711 {"st", "scsa,01.bfcp"}, 3712 {"sgen", "scsa,08.bfcp"}, 3713 {"ses", "scsa,0d.bfcp"}, 3714 3715 /* # legacy mapping to driver nodenames for vhci binding-set */ 3716 {"ssd", "scsa,00.bvhci"}, 3717 {"st", "scsa,01.bvhci"}, 3718 {"sgen", "scsa,08.bvhci"}, 3719 {"ses", "scsa,0d.bvhci"}, 3720 #else /* sparc */ 3721 /* # for x86 fcp and vhci use generic nodenames */ 3722 #endif /* sparc */ 3723 3724 /* # legacy mapping to driver nodenames for spi binding-set */ 3725 {"sd", "scsa,00.bspi"}, 3726 {"sd", "scsa,05.bspi"}, 3727 {"sd", "scsa,07.bspi"}, 3728 {"st", "scsa,01.bspi"}, 3729 {"ses", "scsa,0d.bspi"}, 3730 3731 /* # SUN misidentified spi hardware */ 3732 {"ses", "scsiclass,03.vSUN.pD2"}, 3733 {"ses", "scsiclass,03.vSYMBIOS.pD1000"}, 3734 3735 /* # legacy mapping to driver nodenames for atapi binding-set */ 3736 {"sd", "scsa,00.batapi"}, 3737 {"sd", "scsa,05.batapi"}, 3738 {"sd", "scsa,07.batapi"}, 3739 {"st", "scsa,01.batapi"}, 3740 {"unknown", "scsa,0d.batapi"}, 3741 3742 /* # legacy mapping to generic nodenames for usb binding-set */ 3743 {"disk", "scsa,05.busb"}, 3744 {"disk", "scsa,07.busb"}, 3745 {"changer", "scsa,08.busb"}, 3746 {"comm", "scsa,09.busb"}, 3747 {"array_ctlr", "scsa,0c.busb"}, 3748 {"esi", "scsa,0d.busb"}, 3749 3750 /* 3751 * mapping nodenames for mpt based on scsi dtype 3752 * for being compatible with the original node names 3753 * under mpt controller 3754 */ 3755 {"sd", "scsa,00.bmpt"}, 3756 {"sd", "scsa,05.bmpt"}, 3757 {"sd", "scsa,07.bmpt"}, 3758 {"st", "scsa,01.bmpt"}, 3759 {"ses", "scsa,0d.bmpt"}, 3760 {"sgen", "scsa,08.bmpt"}, 3761 {NULL, NULL} 3762 }; 3763 struct nodename_aliases *nap; 3764 3765 /* NOTE: drivernamep can be NULL */ 3766 ASSERT(nodenamep && compatiblep && ncompatiblep && 3767 (binding_set == NULL || (strlen(binding_set) <= 8))); 3768 if ((nodenamep == NULL) || (compatiblep == NULL) || 3769 (ncompatiblep == NULL)) 3770 return; 3771 3772 /* 3773 * In order to reduce runtime we allocate one block of memory that 3774 * contains both the NULL terminated array of pointers to compatible 3775 * forms and the individual compatible strings. This block is 3776 * somewhat larger than needed, but is short lived - it only exists 3777 * until the caller can transfer the information into the "compatible" 3778 * string array property and call scsi_hba_nodename_compatible_free. 3779 */ 3780 tlen = NCOMPAT * COMPAT_LONGEST; 3781 compatp = kmem_alloc((NCOMPAT * sizeof (char *)) + tlen, KM_SLEEP); 3782 3783 /* convert inquiry data from SCSI ASCII to 1275 string */ 3784 (void) string_scsi_to_1275(vid, inq->inq_vid, 3785 sizeof (inq->inq_vid)); 3786 (void) string_scsi_to_1275(pid, inq->inq_pid, 3787 sizeof (inq->inq_pid)); 3788 (void) string_scsi_to_1275(rev, inq->inq_revision, 3789 sizeof (inq->inq_revision)); 3790 ASSERT((strlen(vid) <= sizeof (inq->inq_vid)) && 3791 (strlen(pid) <= sizeof (inq->inq_pid)) && 3792 (strlen(rev) <= sizeof (inq->inq_revision))); 3793 3794 /* 3795 * Form flags in ***ALPHABETICAL*** order within form-group: 3796 * 3797 * NOTE: When adding a new flag to an existing form-group, careful 3798 * consideration must be given to not breaking existing bindings 3799 * based on that form-group. 3800 */ 3801 3802 /* 3803 * generic form-group flags 3804 * R removable: 3805 * Set when inq_rmb is set and for well known scsi dtypes. For a 3806 * bus where the entire device is removable (like USB), we expect 3807 * the HBA to intercept the inquiry data and set inq_rmb. 3808 * Since OBP does not distinguish removable media in its generic 3809 * name selection we avoid setting the 'R' flag if the root is not 3810 * yet mounted. 3811 */ 3812 i = 0; 3813 dtype_device = inq->inq_dtype & DTYPE_MASK; 3814 if (modrootloaded && (inq->inq_rmb || 3815 (dtype_device == DTYPE_WORM) || 3816 (dtype_device == DTYPE_RODIRECT) || 3817 (dtype_device == DTYPE_OPTICAL))) 3818 gf[i++] = 'R'; /* removable */ 3819 gf[i] = '\0'; 3820 3821 /* 3822 * failover form-group flags 3823 * E Explicit Target_Port_Group_Supported: 3824 * Set for a device that has a GUID if inq_tpgse also set. 3825 * G GUID: 3826 * Set when we have identity information, can determine a devid 3827 * from the identity information, and can generate a guid from 3828 * that devid. 3829 * I Implicit Target_Port_Group_Supported: 3830 * Set for a device that has a GUID if inq_tpgs also set. 3831 */ 3832 i = 0; 3833 if ((inq80 || inq83) && 3834 (ddi_devid_scsi_encode(DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, 3835 (uchar_t *)inq, sizeof (*inq), inq80, inq80len, inq83, inq83len, 3836 &devid) == DDI_SUCCESS)) { 3837 guid = ddi_devid_to_guid(devid); 3838 ddi_devid_free(devid); 3839 } else 3840 guid = NULL; 3841 if (guid && (inq->inq_tpgs & TPGS_FAILOVER_EXPLICIT)) 3842 ff[i++] = 'E'; /* EXPLICIT TPGS */ 3843 if (guid) 3844 ff[i++] = 'G'; /* GUID */ 3845 if (guid && (inq->inq_tpgs & TPGS_FAILOVER_IMPLICIT)) 3846 ff[i++] = 'I'; /* IMPLICIT TPGS */ 3847 ff[i] = '\0'; 3848 if (guid) 3849 ddi_devid_free_guid(guid); 3850 3851 /* 3852 * Construct all applicable compatible forms. See comment at the 3853 * head of the function for a description of the compatible forms. 3854 */ 3855 csp = compatp; 3856 p = (char *)(compatp + NCOMPAT); 3857 3858 /* ( 0) driver (optional, not documented in scsi(4)) */ 3859 if (compat0) { 3860 *csp++ = p; 3861 (void) snprintf(p, tlen, "%s", compat0); 3862 len = strlen(p) + 1; 3863 p += len; 3864 tlen -= len; 3865 } 3866 3867 /* ( 1) scsiclass,DDEEFFF.vV.pP.rR */ 3868 if ((dtype_device != dtype_node) && *gf && *vid && *pid && *rev) { 3869 *csp++ = p; 3870 (void) snprintf(p, tlen, "scsiclass,%02x%02x%s.v%s.p%s.r%s", 3871 dtype_node, dtype_device, gf, vid, pid, rev); 3872 len = strlen(p) + 1; 3873 p += len; 3874 tlen -= len; 3875 } 3876 3877 /* ( 2) scsiclass,DDEE.vV.pP.rR */ 3878 if ((dtype_device != dtype_node) && *vid && *pid && *rev) { 3879 *csp++ = p; 3880 (void) snprintf(p, tlen, "scsiclass,%02x%02x.v%s.p%s.r%s", 3881 dtype_node, dtype_device, vid, pid, rev); 3882 len = strlen(p) + 1; 3883 p += len; 3884 tlen -= len; 3885 } 3886 3887 /* ( 3) scsiclass,DDFFF.vV.pP.rR */ 3888 if (*gf && *vid && *pid && *rev) { 3889 *csp++ = p; 3890 (void) snprintf(p, tlen, "scsiclass,%02x%s.v%s.p%s.r%s", 3891 dtype_node, gf, vid, pid, rev); 3892 len = strlen(p) + 1; 3893 p += len; 3894 tlen -= len; 3895 } 3896 3897 /* ( 4) scsiclass,DD.vV.pP.rR */ 3898 if (*vid && *pid && rev) { 3899 *csp++ = p; 3900 (void) snprintf(p, tlen, "scsiclass,%02x.v%s.p%s.r%s", 3901 dtype_node, vid, pid, rev); 3902 len = strlen(p) + 1; 3903 p += len; 3904 tlen -= len; 3905 } 3906 3907 /* ( 5) scsiclass,DDEEFFF.vV.pP */ 3908 if ((dtype_device != dtype_node) && *gf && *vid && *pid) { 3909 *csp++ = p; 3910 (void) snprintf(p, tlen, "scsiclass,%02x%02x%s.v%s.p%s", 3911 dtype_node, dtype_device, gf, vid, pid); 3912 len = strlen(p) + 1; 3913 p += len; 3914 tlen -= len; 3915 } 3916 3917 /* ( 6) scsiclass,DDEE.vV.pP */ 3918 if ((dtype_device != dtype_node) && *vid && *pid) { 3919 *csp++ = p; 3920 (void) snprintf(p, tlen, "scsiclass,%02x%02x.v%s.p%s", 3921 dtype_node, dtype_device, vid, pid); 3922 len = strlen(p) + 1; 3923 p += len; 3924 tlen -= len; 3925 } 3926 3927 /* ( 7) scsiclass,DDFFF.vV.pP */ 3928 if (*gf && *vid && *pid) { 3929 *csp++ = p; 3930 (void) snprintf(p, tlen, "scsiclass,%02x%s.v%s.p%s", 3931 dtype_node, gf, vid, pid); 3932 len = strlen(p) + 1; 3933 p += len; 3934 tlen -= len; 3935 } 3936 3937 /* ( 8) scsiclass,DD.vV.pP */ 3938 if (*vid && *pid) { 3939 *csp++ = p; 3940 (void) snprintf(p, tlen, "scsiclass,%02x.v%s.p%s", 3941 dtype_node, vid, pid); 3942 len = strlen(p) + 1; 3943 p += len; 3944 tlen -= len; 3945 } 3946 3947 /* (8.5) scsa,DD.bB (not documented in scsi(4)) */ 3948 if (binding_set) { 3949 *csp++ = p; 3950 (void) snprintf(p, tlen, "scsa,%02x.b%s", 3951 dtype_node, binding_set); 3952 len = strlen(p) + 1; 3953 p += len; 3954 tlen -= len; 3955 } 3956 3957 /* ( 9) scsiclass,DDEEFFF */ 3958 if ((dtype_device != dtype_node) && *gf) { 3959 *csp++ = p; 3960 (void) snprintf(p, tlen, "scsiclass,%02x%02x%s", 3961 dtype_node, dtype_device, gf); 3962 len = strlen(p) + 1; 3963 p += len; 3964 tlen -= len; 3965 } 3966 3967 /* (10) scsiclass,DDEE */ 3968 if (dtype_device != dtype_node) { 3969 *csp++ = p; 3970 (void) snprintf(p, tlen, "scsiclass,%02x%02x", 3971 dtype_node, dtype_device); 3972 len = strlen(p) + 1; 3973 p += len; 3974 tlen -= len; 3975 } 3976 3977 /* (11) scsiclass,DDFFF */ 3978 if (*gf) { 3979 *csp++ = p; 3980 (void) snprintf(p, tlen, "scsiclass,%02x%s", 3981 dtype_node, gf); 3982 len = strlen(p) + 1; 3983 p += len; 3984 tlen -= len; 3985 } 3986 3987 /* (12) scsiclass,DD */ 3988 *csp++ = p; 3989 (void) snprintf(p, tlen, "scsiclass,%02x", dtype_node); 3990 len = strlen(p) + 1; 3991 p += len; 3992 tlen -= len; 3993 3994 /* (12.5) scsa.fFFF */ 3995 if (*ff) { 3996 *csp++ = p; 3997 (void) snprintf(p, tlen, "scsa.f%s", ff); 3998 len = strlen(p) + 1; 3999 p += len; 4000 tlen -= len; 4001 } 4002 4003 /* (13) scsiclass */ 4004 *csp++ = p; 4005 (void) snprintf(p, tlen, "scsiclass"); 4006 len = strlen(p) + 1; 4007 p += len; 4008 tlen -= len; 4009 ASSERT(tlen >= 0); 4010 4011 *csp = NULL; /* NULL terminate array of pointers */ 4012 ncompat = csp - compatp; 4013 4014 /* 4015 * When determining a nodename, a nodename_aliases specified 4016 * mapping has precedence over using a driver_aliases specified 4017 * driver binding as a nodename. 4018 * 4019 * See if any of the compatible forms have a nodename_aliases 4020 * specified nodename. These mappings are described by 4021 * nodename_aliases entries like: 4022 * 4023 * disk "scsiclass,00" 4024 * enclosure "scsiclass,03.vSYMBIOS.pD1000" 4025 * ssd "scsa,00.bfcp" 4026 * 4027 * All nodename_aliases mappings should idealy be to generic 4028 * names, however a higher precedence legacy mapping to a 4029 * driver name may exist. The highest precedence mapping 4030 * provides the nodename, so legacy driver nodename mappings 4031 * (if they exist) take precedence over generic nodename 4032 * mappings. 4033 */ 4034 for (nname = NULL, csp = compatp; (nname == NULL) && *csp; csp++) { 4035 for (nap = na; nap->na_nodename; nap++) { 4036 if (strcmp(*csp, nap->na_alias) == 0) { 4037 nname = nap->na_nodename; 4038 break; 4039 } 4040 } 4041 } 4042 4043 /* 4044 * Determine the driver name based on compatible (which may 4045 * have the passed in compat0 as the first item). The driver_aliases 4046 * file has entries like 4047 * 4048 * sd "scsiclass,00" 4049 * 4050 * that map compatible forms to specific drivers. These entries are 4051 * established by add_drv/update_drv. We use the most specific 4052 * driver binding as the nodename. This matches the eventual 4053 * ddi_driver_compatible_major() binding that will be 4054 * established by bind_node() 4055 */ 4056 for (dname = NULL, csp = compatp; *csp; csp++) { 4057 major = ddi_name_to_major(*csp); 4058 if ((major == DDI_MAJOR_T_NONE) || 4059 (devnamesp[major].dn_flags & DN_DRIVER_REMOVED)) 4060 continue; 4061 if (dname = ddi_major_to_name(major)) 4062 break; 4063 } 4064 4065 /* 4066 * If no nodename_aliases mapping exists then use the 4067 * driver_aliases specified driver binding as a nodename. 4068 */ 4069 if (nname == NULL) 4070 nname = dname; 4071 4072 /* return results */ 4073 if (nname) { 4074 *nodenamep = kmem_alloc(strlen(nname) + 1, KM_SLEEP); 4075 (void) strcpy(*nodenamep, nname); 4076 } else { 4077 *nodenamep = NULL; 4078 4079 /* 4080 * If no nodename could be determined return a special 4081 * 'compatible' to be used for a diagnostic message. This 4082 * compatible contains all compatible forms concatenated 4083 * into a single string pointed to by the first element. 4084 */ 4085 for (csp = compatp; *(csp + 1); csp++) 4086 *((*csp) + strlen(*csp)) = ' '; 4087 *(compatp + 1) = NULL; 4088 ncompat = 1; 4089 4090 } 4091 if (drivernamep) { 4092 if (dname) { 4093 *drivernamep = kmem_alloc(strlen(dname) + 1, KM_SLEEP); 4094 (void) strcpy(*drivernamep, dname); 4095 } else 4096 *drivernamep = NULL; 4097 } 4098 *compatiblep = compatp; 4099 *ncompatiblep = ncompat; 4100 } 4101 4102 /* 4103 * Free allocations associated with scsi_hba_ident_nodename_compatible_get. 4104 */ 4105 static void 4106 scsi_hba_ident_nodename_compatible_free(char *nodename, char *drivername, 4107 char **compatible) 4108 { 4109 if (nodename) 4110 kmem_free(nodename, strlen(nodename) + 1); 4111 if (drivername) 4112 kmem_free(drivername, strlen(drivername) + 1); 4113 if (compatible) 4114 kmem_free(compatible, (NCOMPAT * sizeof (char *)) + 4115 (NCOMPAT * COMPAT_LONGEST)); 4116 } 4117 4118 void 4119 scsi_hba_nodename_compatible_get(struct scsi_inquiry *inq, 4120 char *binding_set, int dtype_node, char *compat0, 4121 char **nodenamep, char ***compatiblep, int *ncompatiblep) 4122 { 4123 scsi_hba_ident_nodename_compatible_get(inq, 4124 NULL, 0, NULL, 0, binding_set, dtype_node, compat0, nodenamep, 4125 NULL, compatiblep, ncompatiblep); 4126 } 4127 4128 void 4129 scsi_hba_nodename_compatible_free(char *nodename, char **compatible) 4130 { 4131 scsi_hba_ident_nodename_compatible_free(nodename, NULL, compatible); 4132 } 4133 4134 /* return the unit_address associated with a scsi_device */ 4135 char * 4136 scsi_device_unit_address(struct scsi_device *sd) 4137 { 4138 mdi_pathinfo_t *pip; 4139 4140 ASSERT(sd && sd->sd_dev); 4141 if ((sd == NULL) || (sd->sd_dev == NULL)) 4142 return (NULL); 4143 4144 pip = (mdi_pathinfo_t *)sd->sd_pathinfo; 4145 if (pip) 4146 return (mdi_pi_get_addr(pip)); 4147 else 4148 return (ddi_get_name_addr(sd->sd_dev)); 4149 } 4150 4151 /* scsi_device property interfaces */ 4152 #define _TYPE_DEFINED(flags) \ 4153 (((flags & SCSI_DEVICE_PROP_TYPE_MSK) == SCSI_DEVICE_PROP_PATH) || \ 4154 ((flags & SCSI_DEVICE_PROP_TYPE_MSK) == SCSI_DEVICE_PROP_DEVICE)) 4155 4156 #define _DEVICE_PIP(sd, flags) \ 4157 ((((flags & SCSI_DEVICE_PROP_TYPE_MSK) == SCSI_DEVICE_PROP_PATH) && \ 4158 sd->sd_pathinfo) ? (mdi_pathinfo_t *)sd->sd_pathinfo : NULL) 4159 4160 int 4161 scsi_device_prop_get_int(struct scsi_device *sd, uint_t flags, 4162 char *name, int defval) 4163 { 4164 mdi_pathinfo_t *pip; 4165 int v = defval; 4166 int data; 4167 int rv; 4168 4169 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4170 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4171 !_TYPE_DEFINED(flags)) 4172 return (v); 4173 4174 pip = _DEVICE_PIP(sd, flags); 4175 if (pip) { 4176 rv = mdi_prop_lookup_int(pip, name, &data); 4177 if (rv == DDI_PROP_SUCCESS) 4178 v = data; 4179 } else 4180 v = ddi_prop_get_int(DDI_DEV_T_ANY, sd->sd_dev, 4181 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, name, v); 4182 return (v); 4183 } 4184 4185 4186 int64_t 4187 scsi_device_prop_get_int64(struct scsi_device *sd, uint_t flags, 4188 char *name, int64_t defval) 4189 { 4190 mdi_pathinfo_t *pip; 4191 int64_t v = defval; 4192 int64_t data; 4193 int rv; 4194 4195 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4196 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4197 !_TYPE_DEFINED(flags)) 4198 return (v); 4199 4200 pip = _DEVICE_PIP(sd, flags); 4201 if (pip) { 4202 rv = mdi_prop_lookup_int64(pip, name, &data); 4203 if (rv == DDI_PROP_SUCCESS) 4204 v = data; 4205 } else 4206 v = ddi_prop_get_int64(DDI_DEV_T_ANY, sd->sd_dev, 4207 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, name, v); 4208 return (v); 4209 } 4210 4211 int 4212 scsi_device_prop_lookup_byte_array(struct scsi_device *sd, uint_t flags, 4213 char *name, uchar_t **data, uint_t *nelements) 4214 { 4215 mdi_pathinfo_t *pip; 4216 int rv; 4217 4218 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4219 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4220 !_TYPE_DEFINED(flags)) 4221 return (DDI_PROP_INVAL_ARG); 4222 4223 pip = _DEVICE_PIP(sd, flags); 4224 if (pip) 4225 rv = mdi_prop_lookup_byte_array(pip, name, data, nelements); 4226 else 4227 rv = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, sd->sd_dev, 4228 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 4229 name, data, nelements); 4230 return (rv); 4231 } 4232 4233 int 4234 scsi_device_prop_lookup_int_array(struct scsi_device *sd, uint_t flags, 4235 char *name, int **data, uint_t *nelements) 4236 { 4237 mdi_pathinfo_t *pip; 4238 int rv; 4239 4240 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4241 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4242 !_TYPE_DEFINED(flags)) 4243 return (DDI_PROP_INVAL_ARG); 4244 4245 pip = _DEVICE_PIP(sd, flags); 4246 if (pip) 4247 rv = mdi_prop_lookup_int_array(pip, name, data, nelements); 4248 else 4249 rv = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, sd->sd_dev, 4250 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 4251 name, data, nelements); 4252 return (rv); 4253 } 4254 4255 4256 int 4257 scsi_device_prop_lookup_string(struct scsi_device *sd, uint_t flags, 4258 char *name, char **data) 4259 { 4260 mdi_pathinfo_t *pip; 4261 int rv; 4262 4263 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4264 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4265 !_TYPE_DEFINED(flags)) 4266 return (DDI_PROP_INVAL_ARG); 4267 4268 pip = _DEVICE_PIP(sd, flags); 4269 if (pip) 4270 rv = mdi_prop_lookup_string(pip, name, data); 4271 else 4272 rv = ddi_prop_lookup_string(DDI_DEV_T_ANY, sd->sd_dev, 4273 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 4274 name, data); 4275 return (rv); 4276 } 4277 4278 int 4279 scsi_device_prop_lookup_string_array(struct scsi_device *sd, uint_t flags, 4280 char *name, char ***data, uint_t *nelements) 4281 { 4282 mdi_pathinfo_t *pip; 4283 int rv; 4284 4285 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4286 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4287 !_TYPE_DEFINED(flags)) 4288 return (DDI_PROP_INVAL_ARG); 4289 4290 pip = _DEVICE_PIP(sd, flags); 4291 if (pip) 4292 rv = mdi_prop_lookup_string_array(pip, name, data, nelements); 4293 else 4294 rv = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, sd->sd_dev, 4295 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 4296 name, data, nelements); 4297 return (rv); 4298 } 4299 4300 int 4301 scsi_device_prop_update_byte_array(struct scsi_device *sd, uint_t flags, 4302 char *name, uchar_t *data, uint_t nelements) 4303 { 4304 mdi_pathinfo_t *pip; 4305 int rv; 4306 4307 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4308 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4309 !_TYPE_DEFINED(flags)) 4310 return (DDI_PROP_INVAL_ARG); 4311 4312 pip = _DEVICE_PIP(sd, flags); 4313 if (pip) 4314 rv = mdi_prop_update_byte_array(pip, name, data, nelements); 4315 else 4316 rv = ndi_prop_update_byte_array(DDI_DEV_T_NONE, sd->sd_dev, 4317 name, data, nelements); 4318 return (rv); 4319 } 4320 4321 int 4322 scsi_device_prop_update_int(struct scsi_device *sd, uint_t flags, 4323 char *name, int data) 4324 { 4325 mdi_pathinfo_t *pip; 4326 int rv; 4327 4328 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4329 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4330 !_TYPE_DEFINED(flags)) 4331 return (DDI_PROP_INVAL_ARG); 4332 4333 pip = _DEVICE_PIP(sd, flags); 4334 if (pip) 4335 rv = mdi_prop_update_int(pip, name, data); 4336 else 4337 rv = ndi_prop_update_int(DDI_DEV_T_NONE, sd->sd_dev, 4338 name, data); 4339 return (rv); 4340 } 4341 4342 int 4343 scsi_device_prop_update_int64(struct scsi_device *sd, uint_t flags, 4344 char *name, int64_t data) 4345 { 4346 mdi_pathinfo_t *pip; 4347 int rv; 4348 4349 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4350 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4351 !_TYPE_DEFINED(flags)) 4352 return (DDI_PROP_INVAL_ARG); 4353 4354 pip = _DEVICE_PIP(sd, flags); 4355 if (pip) 4356 rv = mdi_prop_update_int64(pip, name, data); 4357 else 4358 rv = ndi_prop_update_int64(DDI_DEV_T_NONE, sd->sd_dev, 4359 name, data); 4360 return (rv); 4361 } 4362 4363 int 4364 scsi_device_prop_update_int_array(struct scsi_device *sd, uint_t flags, 4365 char *name, int *data, uint_t nelements) 4366 { 4367 mdi_pathinfo_t *pip; 4368 int rv; 4369 4370 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4371 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4372 !_TYPE_DEFINED(flags)) 4373 return (DDI_PROP_INVAL_ARG); 4374 4375 pip = _DEVICE_PIP(sd, flags); 4376 if (pip) 4377 rv = mdi_prop_update_int_array(pip, name, data, nelements); 4378 else 4379 rv = ndi_prop_update_int_array(DDI_DEV_T_NONE, sd->sd_dev, 4380 name, data, nelements); 4381 return (rv); 4382 } 4383 4384 int 4385 scsi_device_prop_update_string(struct scsi_device *sd, uint_t flags, 4386 char *name, char *data) 4387 { 4388 mdi_pathinfo_t *pip; 4389 int rv; 4390 4391 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4392 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4393 !_TYPE_DEFINED(flags)) 4394 return (DDI_PROP_INVAL_ARG); 4395 4396 pip = _DEVICE_PIP(sd, flags); 4397 if (pip) 4398 rv = mdi_prop_update_string(pip, name, data); 4399 else 4400 rv = ndi_prop_update_string(DDI_DEV_T_NONE, sd->sd_dev, 4401 name, data); 4402 return (rv); 4403 } 4404 4405 int 4406 scsi_device_prop_update_string_array(struct scsi_device *sd, uint_t flags, 4407 char *name, char **data, uint_t nelements) 4408 { 4409 mdi_pathinfo_t *pip; 4410 int rv; 4411 4412 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4413 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4414 !_TYPE_DEFINED(flags)) 4415 return (DDI_PROP_INVAL_ARG); 4416 4417 pip = _DEVICE_PIP(sd, flags); 4418 if (pip) 4419 rv = mdi_prop_update_string_array(pip, name, data, nelements); 4420 else 4421 rv = ndi_prop_update_string_array(DDI_DEV_T_NONE, sd->sd_dev, 4422 name, data, nelements); 4423 return (rv); 4424 } 4425 4426 int 4427 scsi_device_prop_remove(struct scsi_device *sd, uint_t flags, char *name) 4428 { 4429 mdi_pathinfo_t *pip; 4430 int rv; 4431 4432 ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags)); 4433 if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) || 4434 !_TYPE_DEFINED(flags)) 4435 return (DDI_PROP_INVAL_ARG); 4436 4437 pip = _DEVICE_PIP(sd, flags); 4438 if (pip) 4439 rv = mdi_prop_remove(pip, name); 4440 else 4441 rv = ndi_prop_remove(DDI_DEV_T_NONE, sd->sd_dev, name); 4442 return (rv); 4443 } 4444 4445 void 4446 scsi_device_prop_free(struct scsi_device *sd, uint_t flags, void *data) 4447 { 4448 mdi_pathinfo_t *pip; 4449 4450 ASSERT(sd && data && sd->sd_dev && _TYPE_DEFINED(flags)); 4451 if ((sd == NULL) || (data == NULL) || (sd->sd_dev == NULL) || 4452 !_TYPE_DEFINED(flags)) 4453 return; 4454 4455 pip = _DEVICE_PIP(sd, flags); 4456 if (pip) 4457 (void) mdi_prop_free(data); 4458 else 4459 ddi_prop_free(data); 4460 } 4461 4462 /* 4463 * scsi_hba_ua_set: given "unit-address" string, set properties. 4464 * 4465 * Function to set the properties on a devinfo or pathinfo node from 4466 * the "unit-address" part of a "name@unit-address" /devices path 'name' 4467 * string. 4468 * 4469 * This function works in conjunction with scsi_ua_get()/scsi_hba_ua_get() 4470 * (and possibly with an HBA driver's tran_tgt_init() implementation). 4471 */ 4472 static int 4473 scsi_hba_ua_set(char *ua, dev_info_t *dchild, mdi_pathinfo_t *pchild) 4474 { 4475 char *p; 4476 int tgt; 4477 char *tgt_port_end; 4478 char *tgt_port; 4479 int tgt_port_len; 4480 int sfunc; 4481 scsi_lun64_t lun64; 4482 4483 /* Caller must choose to decorate devinfo *or* pathinfo */ 4484 ASSERT((dchild != NULL) ^ (pchild != NULL)); 4485 if (dchild && pchild) 4486 return (0); 4487 4488 /* 4489 * generic implementation based on "tgt,lun[,sfunc]" address form. 4490 * parse hex "tgt" part of "tgt,lun[,sfunc]" 4491 */ 4492 p = ua; 4493 tgt_port_end = NULL; 4494 for (tgt = 0; *p && *p != ','; p++) { 4495 if (*p >= '0' && *p <= '9') 4496 tgt = (tgt << 4) + (*p - '0'); 4497 else if (*p >= 'a' && *p <= 'f') 4498 tgt = (tgt << 4) + 10 + (*p - 'a'); 4499 else 4500 tgt = -1; /* non-numeric */ 4501 4502 /* 4503 * if non-numeric or our of range set tgt to -1 and 4504 * skip forward 4505 */ 4506 if (tgt < 0) { 4507 tgt = -1; 4508 for (; *p && *p != ','; p++) 4509 ; 4510 break; 4511 } 4512 } 4513 tgt_port_end = p; 4514 4515 /* parse hex ",lun" part of "tgt,lun[,sfunc]" */ 4516 if (*p) 4517 p++; 4518 for (lun64 = 0; *p && *p != ','; p++) { 4519 if (*p >= '0' && *p <= '9') 4520 lun64 = (lun64 << 4) + (*p - '0'); 4521 else if (*p >= 'a' && *p <= 'f') 4522 lun64 = (lun64 << 4) + 10 + (*p - 'a'); 4523 else 4524 return (0); 4525 } 4526 4527 /* parse hex ",sfunc" part of "tgt,lun[,sfunc]" */ 4528 if (*p) { 4529 p++; 4530 for (sfunc = 0; *p; p++) { 4531 if (*p >= '0' && *p <= '9') 4532 sfunc = (sfunc << 4) + (*p - '0'); 4533 else if (*p >= 'a' && *p <= 'f') 4534 sfunc = (sfunc << 4) + 10 + (*p - 'a'); 4535 else 4536 return (0); 4537 } 4538 } else 4539 sfunc = -1; 4540 4541 if (dchild) { 4542 /* 4543 * Decorate a devinfo node with unit address properties. 4544 * This adds the the addressing properties needed to 4545 * DDI_CTLOPS_UNINITCHILD the devinfo node (i.e. perform 4546 * the reverse operation - form unit address from properties). 4547 */ 4548 if ((tgt != -1) && (ndi_prop_update_int(DDI_DEV_T_NONE, dchild, 4549 SCSI_ADDR_PROP_TARGET, tgt) != DDI_PROP_SUCCESS)) 4550 return (0); 4551 4552 if (tgt_port_end) { 4553 tgt_port_len = tgt_port_end - ua + 1; 4554 tgt_port = kmem_alloc(tgt_port_len, KM_SLEEP); 4555 (void) strlcpy(tgt_port, ua, tgt_port_len); 4556 if (ndi_prop_update_string(DDI_DEV_T_NONE, dchild, 4557 SCSI_ADDR_PROP_TARGET_PORT, tgt_port) != 4558 DDI_PROP_SUCCESS) { 4559 kmem_free(tgt_port, tgt_port_len); 4560 return (0); 4561 } 4562 kmem_free(tgt_port, tgt_port_len); 4563 } 4564 4565 /* Set the appropriate lun properties. */ 4566 if (lun64 < SCSI_32LUNS_PER_TARGET) { 4567 if (ndi_prop_update_int(DDI_DEV_T_NONE, dchild, 4568 SCSI_ADDR_PROP_LUN, (int)lun64) != DDI_PROP_SUCCESS) 4569 return (0); 4570 } 4571 if (ndi_prop_update_int64(DDI_DEV_T_NONE, dchild, 4572 SCSI_ADDR_PROP_LUN64, lun64) != DDI_PROP_SUCCESS) 4573 return (0); 4574 4575 /* Set the sfunc property */ 4576 if ((sfunc != -1) && 4577 (ndi_prop_update_int(DDI_DEV_T_NONE, dchild, 4578 SCSI_ADDR_PROP_SFUNC, (int)sfunc) != DDI_PROP_SUCCESS)) 4579 return (0); 4580 } else if (pchild) { 4581 /* 4582 * Decorate a pathinfo node with unit address properties. 4583 */ 4584 if ((tgt != -1) && (mdi_prop_update_int(pchild, 4585 SCSI_ADDR_PROP_TARGET, tgt) != DDI_PROP_SUCCESS)) 4586 return (0); 4587 4588 if (tgt_port_end) { 4589 tgt_port_len = tgt_port_end - ua + 1; 4590 tgt_port = kmem_alloc(tgt_port_len, KM_SLEEP); 4591 (void) strlcpy(tgt_port, ua, tgt_port_len); 4592 if (mdi_prop_update_string(pchild, 4593 SCSI_ADDR_PROP_TARGET_PORT, tgt_port) != 4594 DDI_PROP_SUCCESS) { 4595 kmem_free(tgt_port, tgt_port_len); 4596 return (0); 4597 } 4598 kmem_free(tgt_port, tgt_port_len); 4599 } 4600 4601 /* Set the appropriate lun properties */ 4602 if (lun64 < SCSI_32LUNS_PER_TARGET) { 4603 if (mdi_prop_update_int(pchild, SCSI_ADDR_PROP_LUN, 4604 (int)lun64) != DDI_PROP_SUCCESS) 4605 return (0); 4606 } 4607 4608 if (mdi_prop_update_int64(pchild, SCSI_ADDR_PROP_LUN64, 4609 lun64) != DDI_PROP_SUCCESS) 4610 return (0); 4611 4612 /* Set the sfunc property */ 4613 if ((sfunc != -1) && 4614 (mdi_prop_update_int(pchild, 4615 SCSI_ADDR_PROP_SFUNC, (int)sfunc) != DDI_PROP_SUCCESS)) 4616 return (0); 4617 } 4618 return (1); 4619 } 4620 4621 /* 4622 * Private ndi_devi_find/mdi_pi_find implementation - find the child 4623 * dev_info/path_info of self whose phci name matches "name@caddr". 4624 * We have our own implementation because we need to search with both 4625 * forms of sibling lists (dev_info and path_info) and we need to be able 4626 * to search with a NULL name in order to find siblings already associated 4627 * with a given unit-address (same @addr). NOTE: NULL name search will never 4628 * return probe node. 4629 * 4630 * If pchildp is NULL and we find a pathinfo child, we return the client 4631 * devinfo node in *dchildp. 4632 * 4633 * The init flag argument should be clear when called from places where 4634 * recursion could occur (like scsi_busctl_initchild) and when the caller 4635 * has already performed a search for name@addr with init set (performance). 4636 * 4637 * Future: Integrate ndi_devi_findchild_by_callback into scsi_hba_find_child. 4638 */ 4639 static int 4640 scsi_hba_find_child(dev_info_t *self, char *name, char *addr, int init, 4641 dev_info_t **dchildp, mdi_pathinfo_t **pchildp, int *ppi) 4642 { 4643 dev_info_t *dchild; /* devinfo child */ 4644 mdi_pathinfo_t *pchild; /* pathinfo child */ 4645 int found = CHILD_TYPE_NONE; 4646 char *daddr; 4647 4648 ASSERT(self && DEVI_BUSY_OWNED(self)); 4649 ASSERT(addr && dchildp); 4650 if ((self == NULL) || (addr == NULL) || (dchildp == NULL)) 4651 return (CHILD_TYPE_NONE); 4652 4653 *dchildp = NULL; 4654 if (pchildp) 4655 *pchildp = NULL; 4656 if (ppi) 4657 *ppi = 0; 4658 4659 /* Walk devinfo child list to find a match */ 4660 for (dchild = ddi_get_child(self); dchild; 4661 dchild = ddi_get_next_sibling(dchild)) { 4662 if (i_ddi_node_state(dchild) < DS_INITIALIZED) 4663 continue; 4664 4665 daddr = ddi_get_name_addr(dchild); 4666 if (daddr && (strcmp(addr, daddr) == 0) && 4667 ((name == NULL) || 4668 (strcmp(name, DEVI(dchild)->devi_node_name) == 0))) { 4669 /* 4670 * If we are asked to find "anything" at a given 4671 * unit-address (name == NULL), we don't realy want 4672 * to find the 'probe' node. The existance of 4673 * a probe node on a 'name == NULL' search should 4674 * fail. This will trigger slow-path code where 4675 * we explicity look for, and synchronize against, 4676 * a node named "probe" at the unit-address. 4677 */ 4678 if ((name == NULL) && 4679 scsi_hba_devi_is_barrier(dchild)) { 4680 SCSI_HBA_LOG((_LOG(4), NULL, dchild, 4681 "%s@%s 'probe' devinfo found, skip", 4682 name ? name : "", addr)); 4683 continue; 4684 } 4685 4686 /* We have found a match. */ 4687 found |= CHILD_TYPE_DEVINFO; 4688 SCSI_HBA_LOG((_LOG(4), NULL, dchild, 4689 "%s@%s devinfo found", name ? name : "", addr)); 4690 *dchildp = dchild; /* devinfo found */ 4691 break; 4692 } 4693 } 4694 4695 /* 4696 * Walk pathinfo child list to find a match. 4697 * 4698 * NOTE: Unlike devinfo nodes, pathinfo nodes have a string searchable 4699 * unit-address from creation - so there is no need for an 'init' 4700 * search block of code for pathinfo nodes below. 4701 */ 4702 pchild = mdi_pi_find(self, NULL, addr); 4703 if (pchild) { 4704 /* 4705 * NOTE: If name specified and we match a pathinfo unit 4706 * address, we don't check the client node name. 4707 */ 4708 if (ppi) 4709 *ppi = mdi_pi_get_path_instance(pchild); 4710 found |= CHILD_TYPE_PATHINFO; 4711 4712 if (pchildp) { 4713 SCSI_HBA_LOG((_LOG(4), self, NULL, 4714 "%s pathinfo found", mdi_pi_spathname(pchild))); 4715 *pchildp = pchild; /* pathinfo found */ 4716 } else if (*dchildp == NULL) { 4717 /* 4718 * Did not find a devinfo node, found a pathinfo node, 4719 * but caller did not ask us to return a pathinfo node: 4720 * we return the 'client' devinfo node instead (but 4721 * with CHILD_TYPE_PATHINFO 'found' return value). 4722 */ 4723 dchild = mdi_pi_get_client(pchild); 4724 SCSI_HBA_LOG((_LOG(4), NULL, dchild, 4725 "%s pathinfo found, client switch", 4726 mdi_pi_spathname(pchild))); 4727 4728 /* 4729 * A pathinfo node always has a 'client' devinfo node, 4730 * but we need to ensure that the 'client' is 4731 * initialized and has a scsi_device structure too. 4732 */ 4733 ASSERT(dchild); 4734 if (i_ddi_node_state(dchild) < DS_INITIALIZED) { 4735 SCSI_HBA_LOG((_LOG(4), NULL, dchild, 4736 "%s found client, initchild", 4737 mdi_pi_spathname(pchild))); 4738 (void) ddi_initchild(ddi_get_parent(dchild), 4739 dchild); 4740 } 4741 if (i_ddi_node_state(dchild) >= DS_INITIALIZED) { 4742 /* client found and initialized */ 4743 *dchildp = dchild; 4744 } else { 4745 SCSI_HBA_LOG((_LOG(4), NULL, dchild, 4746 "%s found client, but failed initchild", 4747 mdi_pi_spathname(pchild))); 4748 } 4749 } 4750 } 4751 4752 /* Try devinfo again with initchild of uninitialized nodes */ 4753 if ((found == CHILD_TYPE_NONE) && init) { 4754 for (dchild = ddi_get_child(self); dchild; 4755 dchild = ddi_get_next_sibling(dchild)) { 4756 /* skip if checked above */ 4757 if (i_ddi_node_state(dchild) >= DS_INITIALIZED) 4758 continue; 4759 /* attempt initchild to establish unit-address */ 4760 (void) ddi_initchild(self, dchild); 4761 if (i_ddi_node_state(dchild) < DS_INITIALIZED) 4762 continue; 4763 daddr = ddi_get_name_addr(dchild); 4764 if (daddr && 4765 ((name == NULL) || (strcmp(name, 4766 DEVI(dchild)->devi_node_name) == 0)) && 4767 (strcmp(addr, daddr) == 0)) { 4768 found |= CHILD_TYPE_DEVINFO; 4769 SCSI_HBA_LOG((_LOG(4), NULL, dchild, 4770 "%s@%s devinfo found post initchild", 4771 name ? name : "", addr)); 4772 *dchildp = dchild; /* devinfo found */ 4773 break; /* node found */ 4774 } 4775 } 4776 } 4777 4778 /* 4779 * We should never find devinfo and pathinfo at the same 4780 * unit-address. 4781 */ 4782 ASSERT(found != (CHILD_TYPE_DEVINFO | CHILD_TYPE_PATHINFO)); 4783 if (found == (CHILD_TYPE_DEVINFO | CHILD_TYPE_PATHINFO)) { 4784 found = CHILD_TYPE_NONE; 4785 *dchildp = NULL; 4786 *pchildp = NULL; 4787 } 4788 return (found); 4789 } 4790 4791 /* 4792 * Given information about a child device (contained on probe node) construct 4793 * and return a pointer to the dynamic SID devinfo node associated with the 4794 * device. In the creation of this SID node a compatible property for the 4795 * device is formed and used to establish a nodename (via 4796 * /etc/nodename_aliases) and to bind a driver (via /etc/driver_aliases). 4797 * 4798 * If this routine is called then we got a response from a device and 4799 * obtained the inquiry data from the device. Some inquiry results indicate 4800 * that the specific LUN we addressed does not exist, and we don't want to 4801 * bind a standard target driver to the node we create. Even though the 4802 * specific LUN is not usable, the framework may still want to bind a 4803 * target driver to the device for internal communication with the device - 4804 * an example would be issuing a report_lun to enumerate other LUNs under a 4805 * DPQ_NEVER LUN0. Another example would be wanting to known that the 4806 * DPQ_NEVER LUN0 device exists in BUS_CONFIG_ONE for non-existent LUN 4807 * caching optimizations. To support this we let the caller specify a 4808 * compatible property (or driver). If LUN0 inquiry data indicates that the 4809 * LUN does not exist then we establish compat0 as the highest precedence(0) 4810 * compatible form. If used, this compat0 driver will never be called on to 4811 * issue external commands to the device. 4812 * 4813 * If no driver binds to the device using driver_alias we establish the driver 4814 * passed in as the node name. 4815 */ 4816 static int 4817 scsi_device_createchild(dev_info_t *self, char *addr, scsi_enum_t se, 4818 struct scsi_device *sdprobe, dev_info_t **dchildp, mdi_pathinfo_t **pchildp) 4819 { 4820 scsi_lun64_t lun64; 4821 int dtype; 4822 int dpq; 4823 int dpq_vu; 4824 int dtype_node; 4825 int lunexists; 4826 char *compat0; 4827 char *nname; 4828 char **compat = NULL; 4829 int ncompat; 4830 dev_info_t *dchild = NULL; 4831 mdi_pathinfo_t *pchild = NULL; 4832 dev_info_t *probe = sdprobe->sd_dev; 4833 struct scsi_inquiry *inq = sdprobe->sd_inq; 4834 uchar_t *inq80 = NULL; 4835 uchar_t *inq83 = NULL; 4836 uint_t inq80len, inq83len; 4837 char *binding_set = NULL; 4838 char *dname = NULL; 4839 ddi_devid_t devid; 4840 int have_devid = 0; 4841 char *devid_str; 4842 char *guid = NULL; 4843 4844 ASSERT(self && addr && *addr && DEVI_BUSY_OWNED(self)); 4845 ASSERT(dchildp && pchildp); 4846 4847 /* 4848 * Determine the lun and whether the lun exists. We may need to create 4849 * a node for LUN0 (with compat0 driver binding) even if the lun does 4850 * not exist - so we can run report_lun to find additional LUNs. 4851 */ 4852 lun64 = scsi_addr_to_lun64(addr); 4853 dtype = inq->inq_dtype & DTYPE_MASK; /* device */ 4854 dpq = inq->inq_dtype & DPQ_MASK; 4855 dpq_vu = inq->inq_dtype & DPQ_VUNIQ ? 1 : 0; 4856 4857 dtype_node = scsi_addr_to_sfunc(addr); /* secondary function */ 4858 if (dtype_node == -1) 4859 dtype_node = dtype; /* node for device */ 4860 4861 lunexists = (dtype != dtype_node) || /* override */ 4862 ((dpq_vu == 0) && (dpq == DPQ_POSSIBLE)) || /* ANSII */ 4863 (dpq_vu && (lun64 == 0)); /* VU LUN0 */ 4864 if (dtype == DTYPE_UNKNOWN) 4865 lunexists = 0; 4866 4867 SCSI_HBA_LOG((_LOG(4), self, NULL, 4868 "@%s dtype %x %x dpq_vu %d dpq %x: %d", 4869 addr, dtype, dtype_node, dpq_vu, dpq, lunexists)); 4870 4871 /* A non-existent LUN0 uses compatible_nodev. */ 4872 if (lunexists) { 4873 compat0 = NULL; /* compat0 not needed */ 4874 } else if (lun64 == 0) { 4875 compat0 = compatible_nodev; 4876 SCSI_HBA_LOG((_LOG(2), self, NULL, 4877 "@%s lun 0 with compat0 %s", addr, compat0)); 4878 } else 4879 goto out; /* no node created */ 4880 4881 /* Obtain identity information from probe node. */ 4882 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, probe, 4883 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "inquiry-page-80", 4884 &inq80, &inq80len) != DDI_PROP_SUCCESS) 4885 inq80 = NULL; 4886 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, probe, 4887 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "inquiry-page-83", 4888 &inq83, &inq83len) != DDI_PROP_SUCCESS) 4889 inq83 = NULL; 4890 4891 /* Get "scsi-binding-set" property (if there is one). */ 4892 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, self, 4893 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 4894 "scsi-binding-set", &binding_set) == DDI_PROP_SUCCESS) 4895 SCSI_HBA_LOG((_LOG(2), NULL, probe, 4896 "binding_set '%s'", binding_set)); 4897 4898 /* determine the node name and compatible information */ 4899 scsi_hba_ident_nodename_compatible_get(inq, 4900 inq80, inq80len, inq83, inq83len, binding_set, dtype_node, 4901 compat0, &nname, &dname, &compat, &ncompat); 4902 4903 if (nname == NULL) { 4904 /* 4905 * We will not be able to create a node because we could not 4906 * determine a node name. Print out a NODRIVER level warning 4907 * message with the compatible forms for the device. Note that 4908 * there may be a driver.conf node that attaches to the device, 4909 * which is why we only produce this warning message for debug 4910 * kernels. 4911 */ 4912 SCSI_HBA_LOG((_LOG(1), NULL, self, 4913 "no node_name for device @%s:\n compatible: %s", 4914 addr, *compat)); 4915 goto out; 4916 } 4917 4918 /* 4919 * FUTURE: some day we may want an accurate "compatible" on the probe 4920 * node so that vhci_is_dev_supported() in scsi_vhci could, at 4921 * least in part, determine/configure based on "compatible". 4922 * 4923 * if (ndi_prop_update_string_array(DDI_DEV_T_NONE, probe, 4924 * "compatible", compat, ncompat) != DDI_PROP_SUCCESS) { 4925 * SCSI_HBA_LOG((_LOG(3), self, NULL, 4926 * "%s@%s failed probe compatible decoration", 4927 * nname, addr)); 4928 * goto out; 4929 * } 4930 */ 4931 4932 /* Encode devid from identity information. */ 4933 if (ddi_devid_scsi_encode(DEVID_SCSI_ENCODE_VERSION_LATEST, dname, 4934 (uchar_t *)inq, sizeof (*inq), inq80, inq80len, inq83, inq83len, 4935 &devid) == DDI_SUCCESS) { 4936 have_devid = 1; 4937 4938 /* Attempt to form guid from devid. */ 4939 guid = ddi_devid_to_guid(devid); 4940 4941 /* Produce string devid for debug. */ 4942 devid_str = ddi_devid_str_encode(devid, NULL); 4943 SCSI_HBA_LOG((_LOG(3), self, probe, "devid '%s' guid '%s'", 4944 devid_str ? devid_str : "NULL", guid ? guid : "NULL")); 4945 ddi_devid_str_free(devid_str); 4946 } 4947 4948 4949 /* 4950 * Determine if the device should be enumerated as under the vHCI 4951 * (client node) or under the pHCI. By convention scsi_vhci expects 4952 * the "cinfo" argument identity information to be represented as a 4953 * devinfo node with the needed information (i.e. the pHCI probe node). 4954 */ 4955 if ((guid == NULL) || 4956 (mdi_is_dev_supported(MDI_HCI_CLASS_SCSI, self, sdprobe) != 4957 MDI_SUCCESS)) { 4958 SCSI_HBA_LOG((_LOG(3), self, probe, "==> devinfo")); 4959 4960 /* 4961 * Enumerate under pHCI: 4962 * 4963 * Create dynamic SID dchild node. No attempt is made to 4964 * transfer information (except the addressing and identity 4965 * information) from the probe node to the dynamic node since 4966 * there may be HBA specific side effects that the framework 4967 * does not known how to transfer. 4968 */ 4969 ndi_devi_alloc_sleep(self, nname, 4970 (se == SE_HP) ? DEVI_SID_HP_NODEID : DEVI_SID_NODEID, 4971 &dchild); 4972 ASSERT(dchild); 4973 4974 /* 4975 * Decorate new node with addressing properties (via 4976 * scsi_hba_ua_set()), compatible, identity information, and 4977 * class. 4978 */ 4979 if ((scsi_hba_ua_set(addr, dchild, NULL) == 0) || 4980 (ndi_prop_update_string_array(DDI_DEV_T_NONE, dchild, 4981 "compatible", compat, ncompat) != DDI_PROP_SUCCESS) || 4982 (inq80 && (ndi_prop_update_byte_array(DDI_DEV_T_NONE, 4983 dchild, "inquiry-page-80", inq80, inq80len) != 4984 DDI_PROP_SUCCESS)) || 4985 (inq83 && (ndi_prop_update_byte_array(DDI_DEV_T_NONE, 4986 dchild, "inquiry-page-83", inq83, inq83len) != 4987 DDI_PROP_SUCCESS)) || 4988 (ndi_prop_update_string(DDI_DEV_T_NONE, dchild, 4989 "class", "scsi") != DDI_PROP_SUCCESS)) { 4990 SCSI_HBA_LOG((_LOG(2), self, NULL, 4991 "@%s failed devinfo decoration", addr)); 4992 (void) scsi_hba_remove_node(dchild); 4993 dchild = NULL; 4994 goto out; 4995 } 4996 4997 /* Bind the driver */ 4998 if (ndi_devi_bind_driver(dchild, 0) != NDI_SUCCESS) { 4999 /* need to bind in order to register a devid */ 5000 SCSI_HBA_LOG((_LOGCFG, NULL, dchild, 5001 "devinfo @%s created, no driver-> " 5002 "no devid_register", addr)); 5003 goto out; 5004 } 5005 5006 /* Register devid */ 5007 if (have_devid) { 5008 if (ddi_devid_register(dchild, devid) == DDI_FAILURE) 5009 SCSI_HBA_LOG((_LOG(1), NULL, dchild, 5010 "devinfo @%s created, devid failed", addr)); 5011 else 5012 SCSI_HBA_LOG((_LOG(2), NULL, dchild, 5013 "devinfo @%s created devid", addr)); 5014 } else 5015 SCSI_HBA_LOG((_LOG(2), NULL, dchild, 5016 "devinfo @%s created, no devid", addr)); 5017 } else { 5018 /* 5019 * Enumerate under vHCI: 5020 * 5021 * Create a pathinfo pchild node. 5022 */ 5023 SCSI_HBA_LOG((_LOG(3), self, probe, "==>pathinfo")); 5024 5025 if (mdi_pi_alloc_compatible(self, nname, guid, addr, compat, 5026 ncompat, 0, &pchild) != MDI_SUCCESS) { 5027 SCSI_HBA_LOG((_LOG(2), self, probe, 5028 "pathinfo alloc failed")); 5029 goto out; 5030 } 5031 ASSERT(pchild); 5032 5033 /* 5034 * Decorate new node with addressing properties via 5035 * scsi_hba_ua_set(). 5036 */ 5037 if (scsi_hba_ua_set(addr, NULL, pchild) == 0) { 5038 SCSI_HBA_LOG((_LOG(1), self, NULL, 5039 "%s pathinfo decoration failed", 5040 mdi_pi_spathname(pchild))); 5041 5042 /* For hotplug, path exists even on failure. */ 5043 if (se != SE_HP) 5044 (void) mdi_pi_free(pchild, 0); 5045 goto out; 5046 } 5047 } 5048 5049 /* free the node name and compatible information */ 5050 out: if (have_devid) 5051 ddi_devid_free(devid); 5052 if (guid) 5053 ddi_devid_free_guid(guid); 5054 if (compat) 5055 scsi_hba_ident_nodename_compatible_free(nname, dname, compat); 5056 if (inq80) 5057 ddi_prop_free(inq80); 5058 if (inq83) 5059 ddi_prop_free(inq83); 5060 if (binding_set) 5061 ddi_prop_free(binding_set); 5062 5063 /* return child_type results */ 5064 ASSERT(!(dchild && pchild)); 5065 if (dchild) { 5066 *dchildp = dchild; 5067 *pchildp = NULL; 5068 return (CHILD_TYPE_DEVINFO); 5069 } 5070 if (pchild) { 5071 *dchildp = NULL; 5072 *pchildp = pchild; 5073 return (CHILD_TYPE_PATHINFO); 5074 } 5075 return (CHILD_TYPE_NONE); 5076 } 5077 5078 /* 5079 * Call scsi_device_createchild and then initchild the new node. 5080 */ 5081 static dev_info_t * 5082 scsi_device_configchild(dev_info_t *self, char *addr, scsi_enum_t se, 5083 struct scsi_device *sdprobe, int *circp, int *ppi) 5084 { 5085 int child_type; 5086 dev_info_t *dchild; 5087 mdi_pathinfo_t *pchild; 5088 dev_info_t *child; 5089 int rval; 5090 5091 ASSERT(self && addr && *addr && DEVI_BUSY_OWNED(self)); 5092 if (ppi) 5093 *ppi = 0; 5094 5095 child_type = scsi_device_createchild(self, addr, se, sdprobe, 5096 &dchild, &pchild); 5097 5098 /* 5099 * Prevent multiple initialized (tran_tgt_init) nodes associated with 5100 * the same @addr at the same time by calling tran_tgt_free() on the 5101 * probe node prior to promotion of the 'real' node. After the call 5102 * to scsi_hba_barrier_tran_tgt_free(), the HBA no longer has any 5103 * probe node context. 5104 */ 5105 scsi_hba_barrier_tran_tgt_free(sdprobe->sd_dev); 5106 5107 switch (child_type) { 5108 case CHILD_TYPE_NONE: 5109 child = NULL; 5110 break; 5111 5112 case CHILD_TYPE_PATHINFO: 5113 /* 5114 * Online pathinfo: Hold the path and exit the pHCI while 5115 * calling mdi_pi_online() to avoid deadlock with power 5116 * management of pHCI. 5117 */ 5118 ASSERT(MDI_PHCI(self)); 5119 mdi_hold_path(pchild); 5120 scsi_hba_devi_exit_phci(self, *circp); 5121 5122 rval = mdi_pi_online(pchild, 0); 5123 5124 scsi_hba_devi_enter_phci(self, circp); 5125 mdi_rele_path(pchild); 5126 5127 if (rval != MDI_SUCCESS) { 5128 SCSI_HBA_LOG((_LOG(2), self, NULL, 5129 "%s pathinfo online failed", 5130 mdi_pi_spathname(pchild))); 5131 5132 /* For hotplug, path exists even when online fails */ 5133 if (se != SE_HP) 5134 (void) mdi_pi_free(pchild, 0); 5135 return (NULL); 5136 } 5137 5138 /* 5139 * Return the path_instance of the pathinfo node. 5140 * 5141 * NOTE: We assume that sd_inq is not path-specific. 5142 */ 5143 if (ppi) 5144 *ppi = mdi_pi_get_path_instance(pchild); 5145 5146 5147 /* 5148 * Fallthrough into CHILD_TYPE_DEVINFO code to promote 5149 * the 'client' devinfo node as a dchild. 5150 */ 5151 dchild = mdi_pi_get_client(pchild); 5152 SCSI_HBA_LOG((_LOG(4), NULL, dchild, 5153 "pathinfo online successful")); 5154 /* FALLTHROUGH */ 5155 5156 case CHILD_TYPE_DEVINFO: 5157 /* 5158 * For now, we ndi_devi_online() the child because some other 5159 * parts of the IO framework, like degenerate devid code, 5160 * depend on bus_config driving nodes to DS_ATTACHED. At some 5161 * point in the future, to keep things light-weight, we would 5162 * like to change the ndi_devi_online call below to be 5163 * 5164 * if (ddi_initchild(self, dchild) != DDI_SUCCESS) 5165 * 5166 * This would promote the node so that framework code could 5167 * find the child with an @addr search, but does not incur 5168 * attach(9E) overhead for BUS_CONFIG_ALL cases where the 5169 * framework is not interested in attach of the node. 5170 * 5171 * NOTE: If the addr specified has incorrect syntax (busconfig 5172 * one of bogus /devices path) then call below can fail. 5173 */ 5174 if (ndi_devi_online(dchild, 0) != NDI_SUCCESS) { 5175 SCSI_HBA_LOG((_LOG(2), NULL, dchild, 5176 "devinfo online failed")); 5177 5178 /* failed online does not remove the node */ 5179 (void) scsi_hba_remove_node(dchild); 5180 return (NULL); 5181 } 5182 SCSI_HBA_LOG((_LOG(4), NULL, dchild, 5183 "devinfo initchild successful")); 5184 child = dchild; 5185 break; 5186 } 5187 return (child); 5188 } 5189 5190 void 5191 scsi_hba_pkt_comp(struct scsi_pkt *pkt) 5192 { 5193 scsi_hba_tran_t *tran; 5194 uint8_t *sensep; 5195 5196 ASSERT(pkt); 5197 if (pkt->pkt_comp == NULL) 5198 return; 5199 5200 /* 5201 * For HBA drivers that implement tran_setup_pkt(9E), if we are 5202 * completing a 'consistent' mode DMA operation then we must 5203 * perform dma_sync prior to calling pkt_comp to ensure that 5204 * the target driver sees the correct data in memory. 5205 */ 5206 ASSERT((pkt->pkt_flags & FLAG_NOINTR) == 0); 5207 if (((pkt->pkt_dma_flags & DDI_DMA_CONSISTENT) && 5208 (pkt->pkt_dma_flags & DDI_DMA_READ)) && 5209 ((P_TO_TRAN(pkt)->tran_setup_pkt) != NULL)) { 5210 scsi_sync_pkt(pkt); 5211 } 5212 5213 /* 5214 * If the HBA driver is using SCSAv3 scsi_hba_tgtmap_create enumeration 5215 * then we detect the special ASC/ASCQ completion codes that indicate 5216 * that the lun configuration of a target has changed. Since we need to 5217 * be determine scsi_device given scsi_address enbedded in 5218 * scsi_pkt (via scsi_address_device(9F)), we also require use of 5219 * SCSI_HBA_ADDR_COMPLEX. 5220 */ 5221 tran = pkt->pkt_address.a_hba_tran; 5222 ASSERT(tran); 5223 if ((tran->tran_tgtmap == NULL) || 5224 !(tran->tran_hba_flags & SCSI_HBA_ADDR_COMPLEX)) 5225 goto comp; /* not using tgtmap */ 5226 5227 /* 5228 * Check for lun-change notification and queue the scsi_pkt for 5229 * lunchg1 processing. The 'pkt_comp' call to the target driver 5230 * is part of lunchg1 processing. 5231 */ 5232 if ((pkt->pkt_reason == CMD_CMPLT) && 5233 (((*pkt->pkt_scbp) & STATUS_MASK) == STATUS_CHECK) && 5234 (pkt->pkt_state & STATE_ARQ_DONE)) { 5235 sensep = (uint8_t *)&(((struct scsi_arq_status *)(uintptr_t) 5236 (pkt->pkt_scbp))->sts_sensedata); 5237 if (((scsi_sense_key(sensep) == KEY_UNIT_ATTENTION) && 5238 (scsi_sense_asc(sensep) == 0x3f) && 5239 (scsi_sense_ascq(sensep) == 0x0e)) || 5240 5241 ((scsi_sense_key(sensep) == KEY_UNIT_ATTENTION) && 5242 (scsi_sense_asc(sensep) == 0x25) && 5243 (scsi_sense_ascq(sensep) == 0x00))) { 5244 /* 5245 * The host adaptor is done with the packet, we use 5246 * pkt_stmp stage-temporary to link the packet for 5247 * lunchg1 processing. 5248 * 5249 * NOTE: pkt_ha_private is not available since its use 5250 * extends to tran_teardown_pkt. 5251 */ 5252 mutex_enter(&scsi_lunchg1_mutex); 5253 pkt->pkt_stmp = scsi_lunchg1_list; 5254 scsi_lunchg1_list = pkt; 5255 if (pkt->pkt_stmp == NULL) 5256 (void) cv_signal(&scsi_lunchg1_cv); 5257 mutex_exit(&scsi_lunchg1_mutex); 5258 return; 5259 } 5260 } 5261 5262 comp: (*pkt->pkt_comp)(pkt); 5263 } 5264 5265 /* 5266 * return 1 if the specified node is a barrier/probe node 5267 */ 5268 static int 5269 scsi_hba_devi_is_barrier(dev_info_t *probe) 5270 { 5271 if (probe && (strcmp(ddi_node_name(probe), "probe") == 0)) 5272 return (1); 5273 return (0); 5274 } 5275 5276 /* 5277 * A host adapter driver is easier to write if we prevent multiple initialized 5278 * (tran_tgt_init) scsi_device structures to the same unit-address at the same 5279 * time. We prevent this from occurring all the time during the barrier/probe 5280 * node to real child hand-off by calling scsi_hba_barrier_tran_tgt_free 5281 * on the probe node prior to ddi_inichild of the 'real' node. As part of 5282 * this early tran_tgt_free implementation, we must also call this function 5283 * as we put a probe node on the scsi_hba_barrier_list. 5284 */ 5285 static void 5286 scsi_hba_barrier_tran_tgt_free(dev_info_t *probe) 5287 { 5288 struct scsi_device *sdprobe; 5289 dev_info_t *self; 5290 scsi_hba_tran_t *tran; 5291 5292 ASSERT(probe && scsi_hba_devi_is_barrier(probe)); 5293 5294 /* Return if we never called tran_tgt_init(9E). */ 5295 if (i_ddi_node_state(probe) < DS_INITIALIZED) 5296 return; 5297 5298 sdprobe = ddi_get_driver_private(probe); 5299 self = ddi_get_parent(probe); 5300 ASSERT(sdprobe && self); 5301 tran = ddi_get_driver_private(self); 5302 ASSERT(tran); 5303 5304 if (tran->tran_tgt_free) { 5305 /* 5306 * To correctly support TRAN_CLONE, we need to use the same 5307 * cloned scsi_hba_tran(9S) structure for both tran_tgt_init(9E) 5308 * and tran_tgt_free(9E). 5309 */ 5310 if (tran->tran_hba_flags & SCSI_HBA_TRAN_CLONE) 5311 tran = sdprobe->sd_address.a_hba_tran; 5312 SCSI_HBA_LOG((_LOG(4), NULL, probe, "tran_tgt_free EARLY")); 5313 5314 (*tran->tran_tgt_free) (self, probe, tran, sdprobe); 5315 } 5316 } 5317 5318 /* 5319 * Add an entry to the list of barrier nodes to be asynchronously deleted by 5320 * the scsi_hba_barrier_daemon after the specified timeout. Nodes on 5321 * the barrier list are used to implement the bus_config probe cache 5322 * of non-existent devices. The nodes are at DS_INITIALIZED, so their 5323 * @addr is established for searching. Since devi_ref of a DS_INITIALIZED 5324 * node will *not* prevent demotion, demotion is prevented by setting 5325 * sd_uninit_prevent. Devinfo snapshots attempt to attach probe cache 5326 * nodes, and on failure attempt to demote the node (without the participation 5327 * of bus_unconfig) to DS_BOUND - this demotion is prevented via 5328 * sd_uninit_prevent causing any attempted DDI_CTLOPS_UNINITCHILD to fail. 5329 * Probe nodes are bound to nulldriver. The list is sorted by 5330 * expiration time. 5331 * 5332 * NOTE: If we drove a probe node to DS_ATTACHED, we could use ndi_hold_devi() 5333 * to prevent demotion (instead of sd_uninit_prevent). 5334 */ 5335 static void 5336 scsi_hba_barrier_add(dev_info_t *probe, int seconds) 5337 { 5338 struct scsi_hba_barrier *nb; 5339 struct scsi_hba_barrier *b; 5340 struct scsi_hba_barrier **bp; 5341 clock_t endtime; 5342 5343 ASSERT(scsi_hba_devi_is_barrier(probe)); 5344 5345 /* HBA is no longer responsible for nodes on the barrier list. */ 5346 scsi_hba_barrier_tran_tgt_free(probe); 5347 5348 nb = kmem_alloc(sizeof (struct scsi_hba_barrier), KM_SLEEP); 5349 mutex_enter(&scsi_hba_barrier_mutex); 5350 endtime = ddi_get_lbolt() + drv_usectohz(seconds * MICROSEC); 5351 for (bp = &scsi_hba_barrier_list; (b = *bp) != NULL; 5352 bp = &b->barrier_next) 5353 if (b->barrier_endtime > endtime) 5354 break; 5355 nb->barrier_next = *bp; 5356 nb->barrier_endtime = endtime; 5357 nb->barrier_probe = probe; 5358 *bp = nb; 5359 if (bp == &scsi_hba_barrier_list) 5360 (void) cv_signal(&scsi_hba_barrier_cv); 5361 mutex_exit(&scsi_hba_barrier_mutex); 5362 } 5363 5364 /* 5365 * Attempt to remove devinfo node node, return 1 if removed. We don't 5366 * don't try to remove barrier nodes that have sd_uninit_prevent set 5367 * (even though they should fail device_uninitchild). 5368 */ 5369 static int 5370 scsi_hba_remove_node(dev_info_t *child) 5371 { 5372 dev_info_t *self = ddi_get_parent(child); 5373 struct scsi_device *sd; 5374 int circ; 5375 int remove = 1; 5376 int ret = 0; 5377 char na[SCSI_MAXNAMELEN]; 5378 5379 scsi_hba_devi_enter(self, &circ); 5380 5381 /* Honor sd_uninit_prevent on barrier nodes */ 5382 if (scsi_hba_devi_is_barrier(child)) { 5383 sd = ddi_get_driver_private(child); 5384 if (sd && sd->sd_uninit_prevent) 5385 remove = 0; 5386 } 5387 5388 if (remove) { 5389 (void) ddi_deviname(child, na); 5390 if (ddi_remove_child(child, 0) != DDI_SUCCESS) { 5391 SCSI_HBA_LOG((_LOG(2), NULL, child, 5392 "remove_node failed")); 5393 } else { 5394 child = NULL; /* child is gone */ 5395 SCSI_HBA_LOG((_LOG(4), self, NULL, 5396 "remove_node removed %s", *na ? &na[1] : na)); 5397 ret = 1; 5398 } 5399 } else { 5400 SCSI_HBA_LOG((_LOG(4), NULL, child, "remove_node prevented")); 5401 } 5402 scsi_hba_devi_exit(self, circ); 5403 return (ret); 5404 } 5405 5406 /* 5407 * The asynchronous barrier deletion daemon. Waits for a barrier timeout 5408 * to expire, then deletes the barrier (removes it as a child). 5409 */ 5410 /*ARGSUSED*/ 5411 static void 5412 scsi_hba_barrier_daemon(void *arg) 5413 { 5414 struct scsi_hba_barrier *b; 5415 dev_info_t *probe; 5416 callb_cpr_t cprinfo; 5417 int circ; 5418 dev_info_t *self; 5419 5420 CALLB_CPR_INIT(&cprinfo, &scsi_hba_barrier_mutex, 5421 callb_generic_cpr, "scsi_hba_barrier_daemon"); 5422 again: mutex_enter(&scsi_hba_barrier_mutex); 5423 for (;;) { 5424 b = scsi_hba_barrier_list; 5425 if (b == NULL) { 5426 /* all barriers expired, wait for barrier_add */ 5427 CALLB_CPR_SAFE_BEGIN(&cprinfo); 5428 (void) cv_wait(&scsi_hba_barrier_cv, 5429 &scsi_hba_barrier_mutex); 5430 CALLB_CPR_SAFE_END(&cprinfo, &scsi_hba_barrier_mutex); 5431 } else { 5432 if (ddi_get_lbolt() >= b->barrier_endtime) { 5433 /* 5434 * Drop and retry if ordering issue. Do this 5435 * before calling scsi_hba_remove_node() and 5436 * deadlocking. 5437 */ 5438 probe = b->barrier_probe; 5439 self = ddi_get_parent(probe); 5440 if (scsi_hba_devi_tryenter(self, &circ) == 0) { 5441 delay: mutex_exit(&scsi_hba_barrier_mutex); 5442 delay_random(5); 5443 goto again; 5444 } 5445 5446 /* process expired barrier */ 5447 if (!scsi_hba_remove_node(probe)) { 5448 /* remove failed, delay and retry */ 5449 SCSI_HBA_LOG((_LOG(4), NULL, probe, 5450 "delay expire")); 5451 scsi_hba_devi_exit(self, circ); 5452 goto delay; 5453 } 5454 scsi_hba_barrier_list = b->barrier_next; 5455 kmem_free(b, sizeof (struct scsi_hba_barrier)); 5456 scsi_hba_devi_exit(self, circ); 5457 } else { 5458 /* establish timeout for next barrier expire */ 5459 (void) cv_timedwait(&scsi_hba_barrier_cv, 5460 &scsi_hba_barrier_mutex, 5461 b->barrier_endtime); 5462 } 5463 } 5464 } 5465 } 5466 5467 /* 5468 * Remove all barriers associated with the specified HBA. This is called 5469 * from from the bus_unconfig implementation to remove probe nodes associated 5470 * with the specified HBA (self) so that probe nodes that have not expired 5471 * will not prevent DR of the HBA. 5472 */ 5473 static void 5474 scsi_hba_barrier_purge(dev_info_t *self) 5475 { 5476 struct scsi_hba_barrier **bp; 5477 struct scsi_hba_barrier *b; 5478 5479 mutex_enter(&scsi_hba_barrier_mutex); 5480 for (bp = &scsi_hba_barrier_list; (b = *bp) != NULL; ) { 5481 if (ddi_get_parent(b->barrier_probe) == self) { 5482 if (scsi_hba_remove_node(b->barrier_probe)) { 5483 *bp = b->barrier_next; 5484 kmem_free(b, sizeof (struct scsi_hba_barrier)); 5485 } else { 5486 SCSI_HBA_LOG((_LOG(4), NULL, b->barrier_probe, 5487 "skip purge")); 5488 } 5489 } else 5490 bp = &b->barrier_next; 5491 } 5492 5493 mutex_exit(&scsi_hba_barrier_mutex); 5494 } 5495 5496 /* 5497 * LUN-change processing daemons: processing occurs in two stages: 5498 * 5499 * Stage 1: Daemon waits for a lunchg1 queued scsi_pkt, dequeues the pkt, 5500 * forms the path, completes the scsi_pkt (pkt_comp), and 5501 * queues the path for stage 2 processing. The use of stage 1 5502 * avoids issues related to memory allocation in interrupt context 5503 * (scsi_hba_pkt_comp()). We delay the pkt_comp completion until 5504 * after lunchg1 processing forms the path for stage 2 - this is 5505 * done to prevent the target driver from detaching until the 5506 * path formation is complete (driver with outstanding commands 5507 * should not detach). 5508 * 5509 * Stage 2: Daemon waits for a lunchg2 queued request, dequeues the 5510 * request, and opens the path using ldi_open_by_name(). The 5511 * path opened uses a special "@taddr,*" unit address that will 5512 * trigger lun enumeration in scsi_hba_bus_configone(). We 5513 * trigger lun enumeration in stage 2 to avoid problems when 5514 * initial ASC/ASCQ trigger occurs during discovery. 5515 */ 5516 /*ARGSUSED*/ 5517 static void 5518 scsi_lunchg1_daemon(void *arg) 5519 { 5520 callb_cpr_t cprinfo; 5521 struct scsi_pkt *pkt; 5522 scsi_hba_tran_t *tran; 5523 dev_info_t *self; 5524 struct scsi_device *sd; 5525 char *ua, *p; 5526 char taddr[SCSI_MAXNAMELEN]; 5527 char path[MAXPATHLEN]; 5528 struct scsi_lunchg2 *lunchg2; 5529 5530 CALLB_CPR_INIT(&cprinfo, &scsi_lunchg1_mutex, 5531 callb_generic_cpr, "scsi_lunchg1_daemon"); 5532 mutex_enter(&scsi_lunchg1_mutex); 5533 for (;;) { 5534 pkt = scsi_lunchg1_list; 5535 if (pkt == NULL) { 5536 /* All lunchg1 processing requests serviced, wait. */ 5537 CALLB_CPR_SAFE_BEGIN(&cprinfo); 5538 (void) cv_wait(&scsi_lunchg1_cv, 5539 &scsi_lunchg1_mutex); 5540 CALLB_CPR_SAFE_END(&cprinfo, &scsi_lunchg1_mutex); 5541 continue; 5542 } 5543 5544 /* Unlink and perform lunchg1 processing on pkt. */ 5545 scsi_lunchg1_list = pkt->pkt_stmp; 5546 5547 /* Determine initiator port (self) from the pkt_address. */ 5548 tran = pkt->pkt_address.a_hba_tran; 5549 ASSERT(tran && tran->tran_tgtmap && tran->tran_iport_dip); 5550 self = tran->tran_iport_dip; 5551 5552 /* 5553 * Determine scsi_devie from pkt_address (depends on 5554 * SCSI_HBA_ADDR_COMPLEX). 5555 */ 5556 sd = scsi_address_device(&(pkt->pkt_address)); 5557 ASSERT(sd); 5558 if (sd == NULL) { 5559 (*pkt->pkt_comp)(pkt); 5560 continue; 5561 } 5562 5563 /* Determine unit-address from scsi_device. */ 5564 ua = scsi_device_unit_address(sd); 5565 5566 /* Extract taddr from the unit-address. */ 5567 for (p = taddr; (*ua != ',') && (*ua != '\0'); ) 5568 *p++ = *ua++; 5569 *p = '\0'; /* NULL terminate taddr */ 5570 5571 /* 5572 * Form path using special "@taddr,*" notation to trigger 5573 * lun enumeration. 5574 */ 5575 (void) ddi_pathname(self, path); 5576 (void) strcat(path, "/luns@"); 5577 (void) strcat(path, taddr); 5578 (void) strcat(path, ",*"); 5579 5580 /* 5581 * Now that we have the path, complete the pkt that 5582 * triggered lunchg1 processing. 5583 */ 5584 (*pkt->pkt_comp)(pkt); 5585 5586 /* Allocate element for stage2 processing queue. */ 5587 lunchg2 = kmem_alloc(sizeof (*lunchg2), KM_SLEEP); 5588 lunchg2->lunchg2_path = strdup(path); 5589 5590 /* Queue and dispatch to stage 2. */ 5591 SCSI_HBA_LOG((_LOG(2), self, NULL, 5592 "lunchg stage1: queue %s", lunchg2->lunchg2_path)); 5593 mutex_enter(&scsi_lunchg2_mutex); 5594 lunchg2->lunchg2_next = scsi_lunchg2_list; 5595 scsi_lunchg2_list = lunchg2; 5596 if (lunchg2->lunchg2_next == NULL) 5597 (void) cv_signal(&scsi_lunchg2_cv); 5598 mutex_exit(&scsi_lunchg2_mutex); 5599 } 5600 } 5601 5602 /*ARGSUSED*/ 5603 static void 5604 scsi_lunchg2_daemon(void *arg) 5605 { 5606 callb_cpr_t cprinfo; 5607 struct scsi_lunchg2 *lunchg2; 5608 ldi_ident_t li; 5609 ldi_handle_t lh; 5610 5611 CALLB_CPR_INIT(&cprinfo, &scsi_lunchg2_mutex, 5612 callb_generic_cpr, "scsi_lunchg2_daemon"); 5613 5614 li = ldi_ident_from_anon(); 5615 mutex_enter(&scsi_lunchg2_mutex); 5616 for (;;) { 5617 lunchg2 = scsi_lunchg2_list; 5618 if (lunchg2 == NULL) { 5619 /* All lunchg2 processing requests serviced, wait. */ 5620 CALLB_CPR_SAFE_BEGIN(&cprinfo); 5621 (void) cv_wait(&scsi_lunchg2_cv, 5622 &scsi_lunchg2_mutex); 5623 CALLB_CPR_SAFE_END(&cprinfo, &scsi_lunchg2_mutex); 5624 continue; 5625 } 5626 5627 /* Unlink and perform lunchg2 processing on pkt. */ 5628 scsi_lunchg2_list = lunchg2->lunchg2_next; 5629 5630 /* 5631 * Open and close the path to trigger lun enumeration. We 5632 * don't expect the open to succeed, but we do expect code in 5633 * scsi_hba_bus_configone() to trigger lun enumeration. 5634 */ 5635 SCSI_HBA_LOG((_LOG(2), NULL, NULL, 5636 "lunchg stage2: open %s", lunchg2->lunchg2_path)); 5637 if (ldi_open_by_name(lunchg2->lunchg2_path, 5638 FREAD, kcred, &lh, li) == 0) 5639 (void) ldi_close(lh, FREAD, kcred); 5640 5641 /* Free path and linked element. */ 5642 strfree(lunchg2->lunchg2_path); 5643 kmem_free(lunchg2, sizeof (*lunchg2)); 5644 } 5645 } 5646 5647 /* 5648 * Enumerate a child at the specified @addr. If a device exists @addr then 5649 * ensure that we have the appropriately named devinfo node for it. Name is 5650 * NULL in the bus_config_all case. This routine has no knowledge of the 5651 * format of an @addr string or associated addressing properties. 5652 * 5653 * The caller must guarantee that there is an open scsi_hba_devi_enter on the 5654 * parent. We return the scsi_device structure for the child device. This 5655 * scsi_device structure is valid until the caller scsi_hba_devi_exit the 5656 * parent. The caller can add do ndi_hold_devi of the child prior to the 5657 * scsi_hba_devi_exit to extend the validity of the child. 5658 * 5659 * In some cases the returned scsi_device structure may be used to drive 5660 * additional SCMD_REPORT_LUNS operations by bus_config_all callers. 5661 * 5662 * The first operation performed is to see if there is a dynamic SID nodes 5663 * already attached at the specified "name@addr". This is the fastpath 5664 * case for resolving a reference to a node that has already been created. 5665 * All other references are serialized for a given @addr prior to probing 5666 * to determine the type of device, if any, at the specified @addr. 5667 * If no device is present then NDI_FAILURE is returned. The fact that a 5668 * device does not exist may be determined via the barrier/probe cache, 5669 * minimizing the probes of non-existent devices. 5670 * 5671 * When there is a device present the dynamic SID node is created based on 5672 * the device found. If a driver.conf node exists for the same @addr it 5673 * will either merge into the dynamic SID node (if the SID node bound to 5674 * that driver), or exist independently. To prevent the actions of one driver 5675 * causing side effects in another, code prevents multiple SID nodes from 5676 * binding to the same "@addr" at the same time. There is autodetach code 5677 * to allow one device to be replaced with another at the same @addr for 5678 * slot addressed SCSI bus implementations (SPI). For compatibility with 5679 * legacy driver.conf behavior, the code does not prevent multiple driver.conf 5680 * nodes from attaching to the same @addr at the same time. 5681 * 5682 * This routine may have the side effect of creating nodes for devices other 5683 * than the one being sought. It is possible that there is a different type of 5684 * target device at that target/lun address than we were asking for. In that 5685 * It is the caller's responsibility to determine whether the device we found, 5686 * if any, at the specified address, is the one it really wanted. 5687 */ 5688 static struct scsi_device * 5689 scsi_device_config(dev_info_t *self, char *name, char *addr, scsi_enum_t se, 5690 int *circp, int *ppi) 5691 { 5692 dev_info_t *child = NULL; 5693 dev_info_t *probe = NULL; 5694 struct scsi_device *sdchild; 5695 struct scsi_device *sdprobe; 5696 dev_info_t *dsearch; 5697 mdi_pathinfo_t *psearch; 5698 major_t major; 5699 int sp; 5700 int pi = 0; 5701 int wait_msg = scsi_hba_wait_msg; 5702 int chg; 5703 5704 ASSERT(self && addr && DEVI_BUSY_OWNED(self)); 5705 5706 SCSI_HBA_LOG((_LOG(4), self, NULL, "%s@%s wanted", 5707 name ? name : "", addr)); 5708 5709 /* playing with "probe" node name is dangerous */ 5710 if (name && (strcmp(name, "probe") == 0)) 5711 return (NULL); 5712 5713 /* 5714 * NOTE: use 'goto done;' or 'goto fail;'. There should only be one 5715 * 'return' statement from here to the end of the function - the one 5716 * on the last line of the function. 5717 */ 5718 5719 /* 5720 * Fastpath: search to see if we are requesting a named SID node that 5721 * already exists (we already created) - probe node does not count. 5722 * scsi_hba_find_child() does not hold the returned devinfo node, but 5723 * this is OK since the caller has a scsi_hba_devi_enter on the 5724 * attached parent HBA (self). The caller is responsible for attaching 5725 * and placing a hold on the child (directly via ndi_hold_devi or 5726 * indirectly via ndi_busop_bus_config) before doing an 5727 * scsi_hba_devi_exit on the parent. 5728 * 5729 * NOTE: This fastpath prevents detecting a driver binding change 5730 * (autodetach) if the same nodename is used for old and new binding. 5731 */ 5732 /* first call is with init set */ 5733 (void) scsi_hba_find_child(self, name, addr, 5734 1, &dsearch, NULL, &pi); 5735 if (dsearch && scsi_hba_dev_is_sid(dsearch) && 5736 !scsi_hba_devi_is_barrier(dsearch)) { 5737 SCSI_HBA_LOG((_LOG(4), NULL, dsearch, 5738 "%s@%s devinfo fastpath", name ? name : "", addr)); 5739 child = dsearch; 5740 goto done; 5741 } 5742 5743 /* 5744 * Create a barrier devinfo node used to "probe" the device with. We 5745 * need to drive this node to DS_INITIALIZED so that the 5746 * DDI_CTLOPS_INITCHILD has occurred, bringing the SCSA transport to 5747 * a state useable state for issuing our "probe" commands. We establish 5748 * this barrier node with a node name of "probe" and compatible 5749 * property of "scsiprobe". The compatible property must be associated 5750 * in /etc/driver_aliases with a scsi target driver available in the 5751 * root file system (sd). 5752 * 5753 * The "probe" that we perform on the barrier node, after it is 5754 * DS_INITIALIZED, is used to find the information needed to create a 5755 * dynamic devinfo (SID) node. This "probe" is separate from the 5756 * probe(9E) call associated with the transition of a node from 5757 * DS_INITIALIZED to DS_PROBED. The probe(9E) call that eventually 5758 * occurs against the created SID node should find ddi_dev_is_sid and 5759 * just return DDI_PROBE_DONTCARE. 5760 * 5761 * Trying to avoid the use of a barrier node is not a good idea 5762 * because we may have an HBA driver that uses generic bus_config 5763 * (this code) but implements its own DDI_CTLOPS_INITCHILD with side 5764 * effects that we can't duplicate (such as the ATA nexus driver). 5765 * 5766 * The probe/barrier node plays an integral part of the locking scheme. 5767 * The objective is to single thread probes of the same device (same 5768 * @addr) while allowing parallelism for probes of different devices 5769 * with the same parent. At this point we are serialized on our self. 5770 * For parallelism we will need to release our self. Prior to release 5771 * we construct a barrier for probes of the same device to serialize 5772 * against. The "probe@addr" node acts as this barrier. An entering 5773 * thread must wait until the probe node does not exist - it can then 5774 * create and link the probe node - dropping the HBA (self) lock after 5775 * the node is linked and visible (after ddi_initchild). A side effect 5776 * of this is that transports should not "go over the wire" (i.e. do 5777 * things that incur significant delays) until after tran_target_init. 5778 * This means that the first "over the wire" operation should occur 5779 * at tran_target_probe time - when things are running in parallel 5780 * again. 5781 * 5782 * If the probe node exists then another probe with the same @addr is 5783 * in progress, we must wait until there is no probe in progress 5784 * before proceeding, and when we proceed we must continue to hold the 5785 * HBA (self) until we have linked a new probe node as a barrier. 5786 * 5787 * When a device is found to *not* exist, its probe/barrier node may be 5788 * marked with DEVICE_REMOVED with node deletion scheduled for some 5789 * future time (seconds). This asynchronous deletion allows the 5790 * framework to detect repeated requests to the same non-existent 5791 * device and avoid overhead associated with contacting a non-existent 5792 * device again and again. 5793 */ 5794 for (;;) { 5795 /* 5796 * Search for probe node - they should only exist as devinfo 5797 * nodes. 5798 */ 5799 (void) scsi_hba_find_child(self, "probe", addr, 5800 0, &probe, &psearch, NULL); 5801 if (probe == NULL) { 5802 if (psearch) 5803 SCSI_HBA_LOG((_LOG(2), self, 5804 mdi_pi_get_client(psearch), 5805 "???? @%s 'probe' search found " 5806 "pathinfo: %p", addr, (void *)psearch)); 5807 break; 5808 } 5809 5810 /* 5811 * The barrier node may cache the non-existence of a device 5812 * by leaving the barrier node in place (with 5813 * DEVI_DEVICE_REMOVED flag set ) for some amount of time after 5814 * the failure of a probe. This flag is used to fail 5815 * additional probes until the barrier probe node is deleted, 5816 * which will occur from a timeout some time after a failed 5817 * probe. The failed probe will use DEVI_SET_DEVICE_REMOVED 5818 * and schedule probe node deletion from a timeout. The callers 5819 * scsi_hba_devi_exit on the way out of the first failure will 5820 * do the cv_broadcast associated with the cv_wait below - this 5821 * handles threads that wait prior to DEVI_DEVICE_REMOVED being 5822 * set. 5823 */ 5824 if (DEVI_IS_DEVICE_REMOVED(probe)) { 5825 SCSI_HBA_LOG((_LOG(3), NULL, probe, 5826 "detected probe DEVICE_REMOVED")); 5827 probe = NULL; /* deletion already scheduled */ 5828 goto fail; 5829 } 5830 5831 /* 5832 * Drop the lock on the HBA (self) and wait until the probe in 5833 * progress has completed. A changes in the sibling list from 5834 * removing the probe node will cause cv_wait to return 5835 * (scsi_hba_devi_exit does the cv_broadcast). 5836 */ 5837 if (wait_msg) { 5838 wait_msg--; 5839 SCSI_HBA_LOG((_LOG(2), NULL, probe, 5840 "exists, probe already in progress: %s", wait_msg ? 5841 "waiting..." : "last msg, but still waiting...")); 5842 } 5843 5844 /* 5845 * NOTE: we could avoid rare case of one second delay by 5846 * implementing scsi_hba_devi_exit_and_wait based on 5847 * ndi/mdi_devi_exit_and_wait (and consider switching devcfg.c 5848 * code to use these ndi/mdi interfaces too). 5849 */ 5850 scsi_hba_devi_exit(self, *circp); 5851 mutex_enter(&DEVI(self)->devi_lock); 5852 (void) cv_timedwait(&DEVI(self)->devi_cv, 5853 &DEVI(self)->devi_lock, 5854 ddi_get_lbolt() + drv_usectohz(MICROSEC)); 5855 mutex_exit(&DEVI(self)->devi_lock); 5856 scsi_hba_devi_enter(self, circp); 5857 } 5858 ASSERT(probe == NULL); 5859 5860 /* 5861 * Search to see if we are requesting a SID node that already exists. 5862 * We hold the HBA (self) and there is not another probe in progress at 5863 * the same @addr. scsi_hba_find_child() does not hold the returned 5864 * devinfo node but this is OK since we hold the HBA (self). 5865 */ 5866 if (name) { 5867 (void) scsi_hba_find_child(self, name, addr, 5868 1, &dsearch, NULL, &pi); 5869 if (dsearch && scsi_hba_dev_is_sid(dsearch)) { 5870 SCSI_HBA_LOG((_LOG(4), NULL, dsearch, 5871 "%s@%s probe devinfo fastpath", 5872 name ? name : "", addr)); 5873 child = dsearch; 5874 goto done; 5875 } 5876 } 5877 5878 /* 5879 * We are looking for a SID node that does not exist or a driver.conf 5880 * node. 5881 * 5882 * To avoid probe side effects, before we probe the device at the 5883 * specified address we need to check to see if there is already an 5884 * initialized child "@addr". 5885 * 5886 * o If we find an initialized SID child and name is NULL or matches 5887 * the name or the name of the attached driver then we return the 5888 * existing node. 5889 * 5890 * o If we find a non-matching SID node, we will attempt to autodetach 5891 * and remove the node in preference to our new node. 5892 * 5893 * o If SID node found does not match and can't be autodetached, we 5894 * fail: we only allow one SID node at an address. 5895 * 5896 * NOTE: This code depends on SID nodes showing up prior to 5897 * driver.conf nodes in the sibling list. 5898 */ 5899 for (;;) { 5900 /* first NULL name call is with init set */ 5901 (void) scsi_hba_find_child(self, NULL, addr, 5902 1, &dsearch, NULL, &pi); 5903 if (dsearch == NULL) 5904 break; 5905 ASSERT(!scsi_hba_devi_is_barrier(dsearch)); 5906 5907 /* 5908 * To detect changes in driver binding that should attempt 5909 * autodetach we determine the major number of the driver 5910 * that should currently be associated with the device based 5911 * on the compatible property. 5912 */ 5913 major = DDI_MAJOR_T_NONE; 5914 if (scsi_hba_dev_is_sid(dsearch)) 5915 major = ddi_compatible_driver_major(dsearch, NULL); 5916 if ((major == DDI_MAJOR_T_NONE) && (name == NULL)) 5917 major = ddi_driver_major(dsearch); 5918 5919 if ((scsi_hba_dev_is_sid(dsearch) || 5920 (i_ddi_node_state(dsearch) >= DS_INITIALIZED)) && 5921 ((name == NULL) || 5922 (strcmp(ddi_node_name(dsearch), name) == 0) || 5923 (strcmp(ddi_driver_name(dsearch), name) == 0)) && 5924 (major == ddi_driver_major(dsearch))) { 5925 SCSI_HBA_LOG((_LOG(3), NULL, dsearch, 5926 "already attached @addr")); 5927 child = dsearch; 5928 goto done; 5929 } 5930 5931 if (!scsi_hba_dev_is_sid(dsearch)) 5932 break; /* driver.conf node */ 5933 5934 /* 5935 * Implement autodetach of SID node for situations like a 5936 * previously "scsinodev" LUN0 coming into existence (or a 5937 * disk/tape on an SPI transport at same addr but never both 5938 * powered on at the same time). Try to autodetach the existing 5939 * SID node @addr. If that works, search again - otherwise fail. 5940 */ 5941 SCSI_HBA_LOG((_LOG(2), NULL, dsearch, 5942 "looking for %s@%s: SID @addr exists, autodetach", 5943 name ? name : "", addr)); 5944 if (!scsi_hba_remove_node(dsearch)) { 5945 SCSI_HBA_LOG((_LOG(2), NULL, dsearch, 5946 "autodetach @%s failed: fail %s@%s", 5947 addr, name ? name : "", addr)); 5948 goto fail; 5949 } 5950 SCSI_HBA_LOG((_LOG(2), self, NULL, "autodetach @%s OK", addr)); 5951 } 5952 5953 /* 5954 * We will be creating a new SID node, allocate probe node 5955 * used to find out information about the device located @addr. 5956 * The probe node also acts as a barrier against additional 5957 * configuration at the same address, and in the case of non-existent 5958 * devices it will (for some amount of time) avoid re-learning that 5959 * the device does not exist on every reference. Once the probe 5960 * node is DS_LINKED we can drop the HBA (self). 5961 * 5962 * The probe node is allocated as a hidden node so that it does not 5963 * show up in devinfo snapshots. 5964 */ 5965 ndi_devi_alloc_sleep(self, "probe", 5966 (se == SE_HP) ? DEVI_SID_HP_HIDDEN_NODEID : DEVI_SID_HIDDEN_NODEID, 5967 &probe); 5968 ASSERT(probe); 5969 5970 /* 5971 * Decorate the probe node with the property representation of @addr 5972 * unit-address string prior to initchild so that initchild can 5973 * construct the name of the node from properties and tran_tgt_init 5974 * implementation can determine what LUN is being referenced. 5975 * 5976 * If the addr specified has incorrect syntax (busconfig one of bogus 5977 * /devices path) then scsi_hba_ua_set can fail. If the address 5978 * is not understood by the SCSA HBA driver then this operation will 5979 * work, but tran_tgt_init may still fail (for example the HBA 5980 * driver may not support secondary functions). 5981 */ 5982 if (scsi_hba_ua_set(addr, probe, NULL) == 0) { 5983 SCSI_HBA_LOG((_LOG(2), NULL, probe, 5984 "@%s failed scsi_hba_ua_set", addr)); 5985 goto fail; 5986 } 5987 5988 /* 5989 * Set the class property to "scsi". This is sufficient to distinguish 5990 * the node for HBAs that have multiple classes of children (like uata 5991 * - which has "dada" class for ATA children and "scsi" class for 5992 * ATAPI children) and may not use our scsi_busctl_initchild() 5993 * implementation. We also add a "compatible" property of "scsiprobe" 5994 * to select the probe driver. 5995 */ 5996 if ((ndi_prop_update_string(DDI_DEV_T_NONE, probe, 5997 "class", "scsi") != DDI_PROP_SUCCESS) || 5998 (ndi_prop_update_string_array(DDI_DEV_T_NONE, probe, 5999 "compatible", &compatible_probe, 1) != DDI_PROP_SUCCESS)) { 6000 SCSI_HBA_LOG((_LOG(1), NULL, probe, 6001 "@%s failed node decoration", addr)); 6002 goto fail; 6003 } 6004 6005 /* 6006 * Promote probe node to DS_INITIALIZED so that transport can be used 6007 * for scsi_probe. After this the node is linked and visible as a 6008 * barrier for serialization of other @addr operations. 6009 * 6010 * NOTE: If we attached the probe node, we could get rid of 6011 * uninit_prevent. 6012 */ 6013 if (ddi_initchild(self, probe) != DDI_SUCCESS) { 6014 SCSI_HBA_LOG((_LOG(2), NULL, probe, 6015 "@%s failed initchild", addr)); 6016 6017 /* probe node will be removed in fail exit path */ 6018 goto fail; 6019 } 6020 6021 /* get the scsi_device structure of the probe node */ 6022 sdprobe = ddi_get_driver_private(probe); 6023 ASSERT(sdprobe); 6024 6025 /* 6026 * Do scsi_probe. The probe node is linked and visible as a barrier. 6027 * We prevent uninitialization of the probe node and drop our HBA (self) 6028 * while we run scsi_probe() of this "@addr". This allows the framework 6029 * to support multiple scsi_probes for different devices attached to 6030 * the same HBA (self) in parallel. We prevent node demotion of the 6031 * probe node from DS_INITIALIZED by setting sd_uninit_prevent. The 6032 * probe node can not be successfully demoted below DS_INITIALIZED 6033 * (scsi_busctl_uninitchild will fail) until we zero sd_uninit_prevent 6034 * as we are freeing the node via scsi_hba_remove_node(probe). 6035 */ 6036 sdprobe->sd_uninit_prevent++; 6037 scsi_hba_devi_exit(self, *circp); 6038 sp = scsi_probe(sdprobe, SLEEP_FUNC); 6039 6040 /* Introduce a small delay here to increase parallelism. */ 6041 delay_random(5); 6042 6043 if (sp == SCSIPROBE_EXISTS) { 6044 /* 6045 * For a device that exists, while still running in parallel, 6046 * also get identity information from device. This is done 6047 * separate from scsi_probe/tran_tgt_probe/scsi_hba_probe 6048 * since the probe code path may still be used for HBAs 6049 * that don't use common bus_config services (we don't want 6050 * to expose that code path to a behavior change). This 6051 * operation is called 'identity' to avoid confusion with 6052 * deprecated identify(9E). 6053 * 6054 * Future: We may eventually want to allow HBA customization via 6055 * scsi_identity/tran_tgt_identity/scsi_device_identity, but for 6056 * now we just scsi_device_identity. 6057 * 6058 * The identity operation will establish additional properties 6059 * on the probe node related to device identity: 6060 * 6061 * "inquiry-page-80" byte array of SCSI page 80 6062 * "inquiry-page-83" byte array of SCSI page 83 6063 * 6064 * These properties will be used to generate a devid 6065 * (ddi_devid_scsi_encode) and guid - and to register 6066 * (ddi_devid_register) a devid for the device. 6067 * 6068 * If identify fails (non-zero return), the we had allocation 6069 * problems or the device returned inconsistent results then 6070 * we pretend that device does not exist. 6071 */ 6072 if (scsi_device_identity(sdprobe, SLEEP_FUNC)) { 6073 if (ndi_dev_is_hotplug_node(probe)) 6074 SCSI_HBA_LOG((_LOG(WARN), NULL, probe, 6075 "enumeration failed during identity")); 6076 else 6077 SCSI_HBA_LOG((_LOG(2), NULL, probe, 6078 "enumeration failed during identity")); 6079 sp = SCSIPROBE_FAILURE; 6080 } 6081 6082 /* 6083 * Future: Is there anything more we can do here to help avoid 6084 * serialization on iport parent during scsi_device attach(9E)? 6085 */ 6086 } 6087 scsi_hba_devi_enter(self, circp); 6088 sdprobe->sd_uninit_prevent--; 6089 6090 if (sp != SCSIPROBE_EXISTS) { 6091 if (ndi_dev_is_hotplug_node(probe)) 6092 SCSI_HBA_LOG((_LOG(WARN), NULL, probe, 6093 "enumeration failed during probe")); 6094 else 6095 SCSI_HBA_LOG((_LOG(2), NULL, probe, 6096 "enumeration failed durning probe")); 6097 6098 if (scsi_hba_barrier_timeout) { 6099 /* 6100 * Target does not exist. Mark the barrier probe node 6101 * as DEVICE_REMOVED and schedule an asynchronous 6102 * deletion of the node in scsi_hba_barrier_timeout 6103 * seconds. We keep our hold on the probe node 6104 * until we are ready perform the asynchronous node 6105 * deletion. 6106 */ 6107 SCSI_HBA_LOG((_LOG(3), NULL, probe, 6108 "set probe DEVICE_REMOVED")); 6109 mutex_enter(&DEVI(probe)->devi_lock); 6110 DEVI_SET_DEVICE_REMOVED(probe); 6111 mutex_exit(&DEVI(probe)->devi_lock); 6112 6113 scsi_hba_barrier_add(probe, scsi_hba_barrier_timeout); 6114 probe = NULL; 6115 } 6116 goto fail; 6117 } 6118 6119 /* Create the child node from the inquiry data in the probe node. */ 6120 if ((child = scsi_device_configchild(self, addr, se, sdprobe, 6121 circp, &pi)) == NULL) { 6122 /* 6123 * This may fail because there was no driver binding identified 6124 * via driver_alias. We may still have a conf node. 6125 */ 6126 if (name) { 6127 (void) scsi_hba_find_child(self, name, addr, 6128 0, &child, NULL, &pi); 6129 if (child) 6130 SCSI_HBA_LOG((_LOG(2), NULL, child, 6131 "using driver.conf driver binding")); 6132 } 6133 if (child == NULL) { 6134 SCSI_HBA_LOG((_LOG(2), NULL, probe, 6135 "device not configured")); 6136 goto fail; 6137 } 6138 } 6139 6140 /* 6141 * Transfer the inquiry data from the probe node to the child 6142 * SID node to avoid an extra scsi_probe. Callers depend on 6143 * established inquiry data for the returned scsi_device. 6144 */ 6145 sdchild = ddi_get_driver_private(child); 6146 if (sdchild && (sdchild->sd_inq == NULL)) { 6147 sdchild->sd_inq = sdprobe->sd_inq; 6148 sdprobe->sd_inq = NULL; 6149 } 6150 6151 /* 6152 * If we are doing a bus_configone and the node we created has the 6153 * wrong node and driver name then switch the return result to a 6154 * driver.conf node with the correct name - if such a node exists. 6155 */ 6156 if (name && (strcmp(ddi_node_name(child), name) != 0) && 6157 (strcmp(ddi_driver_name(child), name) != 0)) { 6158 (void) scsi_hba_find_child(self, name, addr, 6159 0, &dsearch, NULL, &pi); 6160 if (dsearch == NULL) { 6161 SCSI_HBA_LOG((_LOG(2), NULL, child, 6162 "wrong device configured %s@%s", name, addr)); 6163 /* 6164 * We can't remove when modrootloaded == 0 in case 6165 * boot-device a uses generic name and 6166 * scsi_hba_nodename_compatible_get() returned a 6167 * legacy binding-set driver oriented name. 6168 */ 6169 if (modrootloaded) { 6170 (void) scsi_hba_remove_node(child); 6171 child = NULL; 6172 goto fail; 6173 } 6174 } else { 6175 SCSI_HBA_LOG((_LOG(2), NULL, dsearch, 6176 "device configured, but switching to driver.conf")); 6177 child = dsearch; 6178 } 6179 } 6180 6181 /* get the scsi_device structure from the node */ 6182 SCSI_HBA_LOG((_LOG(3), NULL, child, "device configured")); 6183 6184 if (child) { 6185 done: ASSERT(child); 6186 sdchild = ddi_get_driver_private(child); 6187 ASSERT(sdchild); 6188 /* 6189 * We may have ended up here after promotion of a previously 6190 * demoted node, where demotion deleted sd_inq data in 6191 * scsi_busctl_uninitchild. We redo the scsi_probe() to 6192 * reestablish sd_inq. We also want to redo the scsi_probe 6193 * for devices are currently device_isremove in order to 6194 * detect new device_insert. 6195 */ 6196 if ((sdchild->sd_inq == NULL) || 6197 ndi_devi_device_isremoved(child)) { 6198 6199 /* hotplug_node can only be revived via hotplug. */ 6200 if ((se == SE_HP) || !ndi_dev_is_hotplug_node(child)) { 6201 SCSI_HBA_LOG((_LOG(3), NULL, child, 6202 "scsi_probe() demoted devinfo")); 6203 6204 sp = scsi_probe(sdchild, SLEEP_FUNC); 6205 6206 if (sp == SCSIPROBE_EXISTS) { 6207 ASSERT(sdchild->sd_inq); 6208 6209 /* 6210 * Devinfo child exists and we are 6211 * talking to the device, report 6212 * reinsert and note if this was a 6213 * new reinsert. 6214 */ 6215 chg = ndi_devi_device_insert(child); 6216 SCSI_HBA_LOG((_LOGCFG, self, NULL, 6217 "devinfo %s@%s device_reinsert%s", 6218 name ? name : "", addr, 6219 chg ? "" : "ed already")); 6220 } else { 6221 if (se == SE_HP) 6222 SCSI_HBA_LOG((_LOG(WARN), 6223 NULL, child, 6224 "enumeration failed during " 6225 "reprobe")); 6226 else 6227 SCSI_HBA_LOG((_LOG(2), 6228 NULL, child, 6229 "enumeration failed during " 6230 "reprobe")); 6231 6232 chg = ndi_devi_device_remove(child); 6233 SCSI_HBA_LOG((_LOG(2), NULL, child, 6234 "%s device_remove%s", 6235 (sp > (sizeof (scsi_probe_ascii) / 6236 sizeof (scsi_probe_ascii[0]))) ? 6237 "UNKNOWN" : scsi_probe_ascii[sp], 6238 chg ? "" : "ed already")); 6239 6240 child = NULL; 6241 sdchild = NULL; 6242 } 6243 } else { 6244 SCSI_HBA_LOG((_LOG(2), NULL, child, 6245 "no reprobe")); 6246 6247 child = NULL; 6248 sdchild = NULL; 6249 } 6250 } 6251 } else { 6252 fail: ASSERT(child == NULL); 6253 sdchild = NULL; 6254 } 6255 if (probe) { 6256 /* 6257 * Clean up probe node, destroying node if uninit_prevent 6258 * it is going to zero. Destroying the probe node (deleting 6259 * from the sibling list) will wake up any people waiting on 6260 * the probe node barrier. 6261 */ 6262 SCSI_HBA_LOG((_LOG(4), NULL, probe, "remove probe")); 6263 if (!scsi_hba_remove_node(probe)) { 6264 /* 6265 * Probe node removal should not fail, but if it 6266 * does we hand that responsibility over to the 6267 * async barrier deletion thread - other references 6268 * to the same unit-address can hang until the 6269 * probe node delete completes. 6270 */ 6271 SCSI_HBA_LOG((_LOG(4), NULL, probe, 6272 "remove probe failed, go async")); 6273 scsi_hba_barrier_add(probe, 1); 6274 } 6275 probe = NULL; 6276 } 6277 6278 /* 6279 * If we successfully resolved via a pathinfo node, we need to find 6280 * the pathinfo node and ensure that it is online (if possible). This 6281 * is done for the case where the device was open when 6282 * scsi_device_unconfig occurred, so mdi_pi_free did not occur. If the 6283 * device has now been reinserted, we want the path back online. 6284 * NOTE: This needs to occur after destruction of the probe node to 6285 * avoid ASSERT related to two nodes at the same unit-address. 6286 */ 6287 if (sdchild && pi && (probe == NULL)) { 6288 ASSERT(MDI_PHCI(self)); 6289 6290 (void) scsi_hba_find_child(self, NULL, addr, 6291 0, &dsearch, &psearch, NULL); 6292 ASSERT((psearch == NULL) || 6293 (mdi_pi_get_client(psearch) == child)); 6294 6295 if (psearch && mdi_pi_device_isremoved(psearch)) { 6296 /* 6297 * Verify that we can talk to the device, and if 6298 * so note if this is a new device_insert. 6299 * 6300 * NOTE: We depend on mdi_path_select(), when given 6301 * a specific path_instance, to select that path 6302 * even if the path is offline. 6303 * 6304 * NOTE: A Client node is not ndi_dev_is_hotplug_node(). 6305 */ 6306 if (se == SE_HP) { 6307 SCSI_HBA_LOG((_LOG(3), NULL, child, 6308 "%s scsi_probe() demoted pathinfo", 6309 mdi_pi_spathname(psearch))); 6310 6311 sp = scsi_hba_probe_pi(sdchild, SLEEP_FUNC, pi); 6312 6313 if (sp == SCSIPROBE_EXISTS) { 6314 /* 6315 * Pathinfo child exists and we are 6316 * talking to the device, report 6317 * reinsert and note if this 6318 * was a new reinsert. 6319 */ 6320 chg = mdi_pi_device_insert(psearch); 6321 SCSI_HBA_LOG((_LOGCFG, self, NULL, 6322 "pathinfo %s device_reinsert%s", 6323 mdi_pi_spathname(psearch), 6324 chg ? "" : "ed already")); 6325 6326 if (chg) 6327 (void) mdi_pi_online(psearch, 6328 0); 6329 6330 } else { 6331 SCSI_HBA_LOG((_LOG(WARN), NULL, child, 6332 "%s enumeration failed " 6333 "during reprobe", 6334 mdi_pi_spathname(psearch))); 6335 6336 child = NULL; 6337 sdchild = NULL; 6338 } 6339 6340 } else { 6341 SCSI_HBA_LOG((_LOG(2), NULL, child, 6342 "%s no reprobe", 6343 mdi_pi_spathname(psearch))); 6344 6345 child = NULL; 6346 sdchild = NULL; 6347 } 6348 } 6349 } 6350 6351 /* If asked for path_instance, return it. */ 6352 if (ppi) 6353 *ppi = pi; 6354 6355 return (sdchild); 6356 } 6357 6358 static void 6359 scsi_device_unconfig(dev_info_t *self, char *name, char *addr, int *circp) 6360 { 6361 dev_info_t *child = NULL; 6362 mdi_pathinfo_t *path = NULL; 6363 char *spathname; 6364 int rval; 6365 6366 ASSERT(self && addr && DEVI_BUSY_OWNED(self)); 6367 6368 /* 6369 * We have a catch-22. We may have a demoted node that we need to find 6370 * and offline/remove. To find the node it it isn't demoted, we 6371 * use scsi_hba_find_child. If it's demoted, we then use 6372 * ndi_devi_findchild_by_callback. 6373 */ 6374 (void) scsi_hba_find_child(self, name, addr, 0, &child, &path, NULL); 6375 6376 if ((child == NULL) && (path == NULL)) { 6377 child = ndi_devi_findchild_by_callback(self, name, addr, 6378 scsi_busctl_ua); 6379 if (child) { 6380 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 6381 "devinfo %s@%s found by callback", 6382 name ? name : "", addr)); 6383 ASSERT(ndi_flavor_get(child) == 6384 SCSA_FLAVOR_SCSI_DEVICE); 6385 if (ndi_flavor_get(child) != SCSA_FLAVOR_SCSI_DEVICE) { 6386 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 6387 "devinfo %s@%s not SCSI_DEVICE flavored", 6388 name ? name : "", addr)); 6389 child = NULL; 6390 } 6391 } 6392 } 6393 6394 if (child) { 6395 ASSERT(child && (path == NULL)); 6396 6397 /* Don't unconfig probe nodes. */ 6398 if (scsi_hba_devi_is_barrier(child)) { 6399 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 6400 "devinfo %s@%s is_barrier, skip", 6401 name ? name : "", addr)); 6402 return; 6403 } 6404 6405 /* Attempt to offline/remove the devinfo node */ 6406 if (ndi_devi_offline(child, 6407 NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE) == DDI_SUCCESS) { 6408 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 6409 "devinfo %s@%s offlined and removed", 6410 name ? name : "", addr)); 6411 } else if (ndi_devi_device_remove(child)) { 6412 /* Offline/remove failed, note new device_remove */ 6413 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 6414 "devinfo %s@%s offline failed, device_remove", 6415 name ? name : "", addr)); 6416 } 6417 } else if (path) { 6418 ASSERT(path && (child == NULL)); 6419 6420 /* 6421 * Attempt to offline/remove the pathinfo node. 6422 * 6423 * NOTE: mdi_pi_offline of last path will fail if the 6424 * device is open (i.e. the client can't be offlined). 6425 * 6426 * NOTE: For mdi there is no REMOVE flag for mdi_pi_offline(). 6427 * When mdi_pi_offline returns MDI_SUCCESS, we are responsible 6428 * for remove via mdi_pi_free(). 6429 */ 6430 mdi_hold_path(path); 6431 spathname = mdi_pi_spathname(path); /* valid after free */ 6432 scsi_hba_devi_exit_phci(self, *circp); 6433 rval = mdi_pi_offline(path, 0); 6434 scsi_hba_devi_enter_phci(self, circp); 6435 if (rval == MDI_SUCCESS) { 6436 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 6437 "pathinfo %s offlined and removed", spathname)); 6438 } else if (mdi_pi_device_remove(path)) { 6439 /* Offline/remove failed, note new device_remove */ 6440 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 6441 "pathinfo %s offline failed, " 6442 "device_remove", spathname)); 6443 } 6444 mdi_rele_path(path); 6445 if ((rval == MDI_SUCCESS) && 6446 (mdi_pi_free(path, 0) != MDI_SUCCESS)) { /* REMOVE */ 6447 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 6448 "pathinfo %s mdi_pi_free failed, " 6449 "device_remove", spathname)); 6450 (void) mdi_pi_device_remove(path); 6451 } 6452 } else { 6453 ASSERT((path == NULL) && (child == NULL)); 6454 6455 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 6456 "%s@%s not found", name ? name : "", addr)); 6457 } 6458 } 6459 6460 /* 6461 * configure the device at the specified "@addr" address. 6462 */ 6463 static struct scsi_device * 6464 scsi_hba_bus_configone_addr(dev_info_t *self, char *addr, scsi_enum_t se) 6465 { 6466 int circ; 6467 struct scsi_device *sd; 6468 6469 scsi_hba_devi_enter(self, &circ); 6470 sd = scsi_device_config(self, NULL, addr, se, &circ, NULL); 6471 scsi_hba_devi_exit(self, circ); 6472 return (sd); 6473 } 6474 6475 /* 6476 * unconfigure the device at the specified "@addr" address. 6477 */ 6478 static void 6479 scsi_hba_bus_unconfigone_addr(dev_info_t *self, char *addr) 6480 { 6481 int circ; 6482 6483 scsi_hba_devi_enter(self, &circ); 6484 (void) scsi_device_unconfig(self, NULL, addr, &circ); 6485 scsi_hba_devi_exit(self, circ); 6486 } 6487 6488 /* 6489 * The bus_config_all operations are multi-threaded for performance. A 6490 * separate thread per target and per LUN is used. The config handle is used 6491 * to coordinate all the threads at a given level and the config thread data 6492 * contains the required information for a specific thread to identify what it 6493 * is processing and the handle under which this is being processed. 6494 */ 6495 6496 /* multi-threaded config handle */ 6497 struct scsi_hba_mte_h { 6498 dev_info_t *h_self; /* initiator port */ 6499 int h_thr_count; 6500 kmutex_t h_lock; 6501 kcondvar_t h_cv; 6502 }; 6503 6504 /* target of 'self' config thread data */ 6505 struct scsi_hba_mte_td { 6506 struct scsi_hba_mte_h *td_h; 6507 char *td_taddr; /* target port */ 6508 int td_mt; 6509 scsi_enum_t td_se; 6510 }; 6511 6512 /* Invoke callback on a vector of taddrs from multiple threads */ 6513 static void 6514 scsi_hba_thread_taddrs(dev_info_t *self, char **taddrs, int mt, 6515 scsi_enum_t se, void (*callback)(void *arg)) 6516 { 6517 struct scsi_hba_mte_h *h; /* HBA header */ 6518 struct scsi_hba_mte_td *td; /* target data */ 6519 char **taddr; 6520 6521 /* allocate and initialize the handle */ 6522 h = kmem_zalloc(sizeof (*h), KM_SLEEP); 6523 mutex_init(&h->h_lock, NULL, MUTEX_DEFAULT, NULL); 6524 cv_init(&h->h_cv, NULL, CV_DEFAULT, NULL); 6525 h->h_self = self; 6526 6527 /* loop over all the targets */ 6528 for (taddr = taddrs; *taddr; taddr++) { 6529 /* allocate a thread data structure for target */ 6530 td = kmem_alloc(sizeof (*td), KM_SLEEP); 6531 td->td_h = h; 6532 td->td_taddr = *taddr; 6533 td->td_mt = mt; 6534 td->td_se = se; 6535 6536 /* process the target */ 6537 mutex_enter(&h->h_lock); 6538 h->h_thr_count++; 6539 mutex_exit(&h->h_lock); 6540 6541 mt |= scsi_hba_log_mt_disable; 6542 if (mt & SCSI_ENUMERATION_MT_LUN_DISABLE) 6543 callback((void *)td); 6544 else 6545 (void) thread_create(NULL, 0, callback, (void *)td, 6546 0, &p0, TS_RUN, minclsyspri); 6547 } 6548 6549 /* wait for all the target threads to complete */ 6550 mutex_enter(&h->h_lock); 6551 while (h->h_thr_count > 0) 6552 cv_wait(&h->h_cv, &h->h_lock); 6553 mutex_exit(&h->h_lock); 6554 6555 /* free the handle */ 6556 cv_destroy(&h->h_cv); 6557 mutex_destroy(&h->h_lock); 6558 kmem_free(h, sizeof (*h)); 6559 } 6560 6561 6562 /* lun/secondary function of lun0 config thread data */ 6563 struct scsi_hba_mte_ld { 6564 struct scsi_hba_mte_h *ld_h; 6565 char *ld_taddr; /* target port */ 6566 scsi_lun64_t ld_lun64; /* lun */ 6567 int ld_sfunc; /* secondary function */ 6568 scsi_enum_t ld_se; 6569 }; 6570 6571 /* 6572 * Enumerate the LUNs and secondary functions of the specified target. The 6573 * target portion of the "@addr" is already represented as a string in the 6574 * thread data, we add a ",lun" representation to this and perform a 6575 * bus_configone byte of enumeration on that "@addr". 6576 */ 6577 static void 6578 scsi_hba_enum_lsf_of_tgt_thr(void *arg) 6579 { 6580 struct scsi_hba_mte_ld *ld = (struct scsi_hba_mte_ld *)arg; 6581 struct scsi_hba_mte_h *h = ld->ld_h; 6582 dev_info_t *self = h->h_self; 6583 char addr[SCSI_MAXNAMELEN]; 6584 6585 /* make string form of "@taddr,lun[,sfunc]" and see if it exists */ 6586 if (ld->ld_sfunc == -1) 6587 (void) snprintf(addr, sizeof (addr), 6588 "%s,%" PRIx64, ld->ld_taddr, ld->ld_lun64); 6589 else 6590 (void) snprintf(addr, sizeof (addr), 6591 "%s,%" PRIx64 ",%x", 6592 ld->ld_taddr, ld->ld_lun64, ld->ld_sfunc); 6593 6594 /* configure device at that unit-address address */ 6595 (void) scsi_hba_bus_configone_addr(self, addr, ld->ld_se); 6596 6597 /* signal completion of this LUN thread to the target */ 6598 mutex_enter(&h->h_lock); 6599 if (--h->h_thr_count == 0) 6600 cv_broadcast(&h->h_cv); 6601 mutex_exit(&h->h_lock); 6602 6603 /* free config thread data */ 6604 kmem_free(ld, sizeof (*ld)); 6605 } 6606 6607 /* Format of SCSI REPORT_LUNS report */ 6608 typedef struct scsi_lunrpt { 6609 uchar_t lunrpt_len_msb; /* # LUNs being reported */ 6610 uchar_t lunrpt_len_mmsb; 6611 uchar_t lunrpt_len_mlsb; 6612 uchar_t lunrpt_len_lsb; 6613 uchar_t lunrpt_reserved[4]; 6614 scsi_lun_t lunrpt_luns[1]; /* LUNs, variable size */ 6615 } scsi_lunrpt_t; 6616 6617 /* 6618 * scsi_device_reportluns() 6619 * 6620 * Callers of this routine should ensure that the 'sd0' scsi_device structure 6621 * and 'pi' path_instance specified are associated with a responding LUN0. 6622 * This should not be called for SCSI-1 devices. 6623 * 6624 * To get a LUN report, we must allocate a buffer. To know how big to make the 6625 * buffer, we must know the number of LUNs. To know the number of LUNs, we must 6626 * get a LUN report. We first issue a SCMD_REPORT_LUNS command using a 6627 * reasonably sized buffer that's big enough to report all LUNs for most 6628 * typical devices. If it turns out that we needed a bigger buffer, we attempt 6629 * to allocate a buffer of sufficient size, and reissue the command. If the 6630 * first command succeeds, but the second fails, we return whatever we were 6631 * able to get the first time. We return enough information for the caller to 6632 * tell whether he got all the LUNs or only a subset. 6633 * 6634 * If successful, we allocate an array of scsi_lun_t to hold the results. The 6635 * caller must kmem_free(*lunarrayp, *sizep) when finished with it. Upon 6636 * successful return return value is NDI_SUCCESS and: 6637 * 6638 * *lunarrayp points to the allocated array, 6639 * *nlunsp is the number of valid LUN entries in the array, 6640 * *tlunsp is the total number of LUNs in the target, 6641 * *sizep is the size of the lunarrayp array, which must be freed. 6642 * 6643 * If the *nlunsp is less than *tlunsp, then we were only able to retrieve a 6644 * subset of the total set of LUNs in the target. 6645 */ 6646 static int 6647 scsi_device_reportluns(struct scsi_device *sd0, char *taddr, int pi, 6648 scsi_lun_t **lunarrayp, uint32_t *nlunsp, uint32_t *tlunsp, size_t *sizep) 6649 { 6650 struct buf *lunrpt_bp; 6651 struct scsi_pkt *lunrpt_pkt; 6652 scsi_lunrpt_t *lunrpt; 6653 uint32_t bsize; 6654 uint32_t tluns, nluns; 6655 int default_maxluns = scsi_lunrpt_default_max; 6656 dev_info_t *child; 6657 6658 ASSERT(sd0 && lunarrayp && nlunsp && tlunsp && sizep); 6659 6660 /* 6661 * NOTE: child should only be used in SCSI_HBA_LOG context since with 6662 * vHCI enumeration it may be the vHCI 'client' devinfo child instead 6663 * of a child of the 'self' pHCI we are enumerating. 6664 */ 6665 child = sd0->sd_dev; 6666 6667 /* first try, look for up to scsi_lunrpt_default_max LUNs */ 6668 nluns = default_maxluns; 6669 6670 again: bsize = sizeof (struct scsi_lunrpt) + 6671 ((nluns - 1) * sizeof (struct scsi_lun)); 6672 6673 lunrpt_bp = scsi_alloc_consistent_buf(&sd0->sd_address, 6674 (struct buf *)NULL, bsize, B_READ, SLEEP_FUNC, NULL); 6675 if (lunrpt_bp == NULL) { 6676 SCSI_HBA_LOG((_LOG(1), NULL, child, "failed alloc")); 6677 return (NDI_NOMEM); 6678 } 6679 6680 lunrpt_pkt = scsi_init_pkt(&sd0->sd_address, 6681 (struct scsi_pkt *)NULL, lunrpt_bp, CDB_GROUP5, 6682 sizeof (struct scsi_arq_status), 0, PKT_CONSISTENT, 6683 SLEEP_FUNC, NULL); 6684 if (lunrpt_pkt == NULL) { 6685 SCSI_HBA_LOG((_LOG(1), NULL, child, "failed init")); 6686 scsi_free_consistent_buf(lunrpt_bp); 6687 return (NDI_NOMEM); 6688 } 6689 6690 (void) scsi_setup_cdb((union scsi_cdb *)lunrpt_pkt->pkt_cdbp, 6691 SCMD_REPORT_LUNS, 0, bsize, 0); 6692 6693 lunrpt_pkt->pkt_time = scsi_lunrpt_timeout; 6694 6695 /* 6696 * When sd0 is a vHCI scsi device, we need reportlun to be issued 6697 * against a specific LUN0 path_instance that we are enumerating. 6698 */ 6699 lunrpt_pkt->pkt_path_instance = pi; 6700 lunrpt_pkt->pkt_flags |= FLAG_PKT_PATH_INSTANCE; 6701 6702 /* 6703 * NOTE: scsi_poll may not allow HBA specific recovery from TRAN_BUSY. 6704 */ 6705 if (scsi_poll(lunrpt_pkt) < 0) { 6706 SCSI_HBA_LOG((_LOG(2), NULL, child, "reportlun not supported")); 6707 scsi_destroy_pkt(lunrpt_pkt); 6708 scsi_free_consistent_buf(lunrpt_bp); 6709 return (NDI_FAILURE); 6710 } 6711 6712 scsi_destroy_pkt(lunrpt_pkt); 6713 6714 lunrpt = (scsi_lunrpt_t *)lunrpt_bp->b_un.b_addr; 6715 6716 /* Compute the total number of LUNs in the target */ 6717 tluns = (((uint_t)lunrpt->lunrpt_len_msb << 24) | 6718 ((uint_t)lunrpt->lunrpt_len_mmsb << 16) | 6719 ((uint_t)lunrpt->lunrpt_len_mlsb << 8) | 6720 ((uint_t)lunrpt->lunrpt_len_lsb)) >> 3; 6721 6722 if (tluns == 0) { 6723 /* Illegal response -- this target is broken */ 6724 SCSI_HBA_LOG((_LOG(1), NULL, child, "illegal tluns of zero")); 6725 scsi_free_consistent_buf(lunrpt_bp); 6726 return (DDI_NOT_WELL_FORMED); 6727 } 6728 6729 if (tluns > nluns) { 6730 /* have more than we allocated space for */ 6731 if (nluns == default_maxluns) { 6732 /* first time around, reallocate larger */ 6733 scsi_free_consistent_buf(lunrpt_bp); 6734 nluns = tluns; 6735 goto again; 6736 } 6737 6738 /* uh oh, we got a different tluns the second time! */ 6739 SCSI_HBA_LOG((_LOG(1), NULL, child, 6740 "tluns changed from %d to %d", nluns, tluns)); 6741 } else 6742 nluns = tluns; 6743 6744 /* 6745 * Now we have: 6746 * lunrpt_bp is the buffer we're using; 6747 * tluns is the total number of LUNs the target says it has; 6748 * nluns is the number of LUNs we were able to get into the buffer. 6749 * 6750 * Copy the data out of scarce iopb memory into regular kmem. 6751 * The caller must kmem_free(*lunarrayp, *sizep) when finished with it. 6752 */ 6753 *lunarrayp = (scsi_lun_t *)kmem_alloc( 6754 nluns * sizeof (scsi_lun_t), KM_SLEEP); 6755 if (*lunarrayp == NULL) { 6756 SCSI_HBA_LOG((_LOG(1), NULL, child, "NULL lunarray")); 6757 scsi_free_consistent_buf(lunrpt_bp); 6758 return (NDI_NOMEM); 6759 } 6760 6761 *sizep = nluns * sizeof (scsi_lun_t); 6762 *nlunsp = nluns; 6763 *tlunsp = tluns; 6764 bcopy((void *)&lunrpt->lunrpt_luns, (void *)*lunarrayp, *sizep); 6765 scsi_free_consistent_buf(lunrpt_bp); 6766 SCSI_HBA_LOG((_LOG(3), NULL, child, 6767 "@%s,0 path %d: %d/%d luns", taddr, pi, nluns, tluns)); 6768 return (NDI_SUCCESS); 6769 } 6770 6771 /* 6772 * Enumerate all the LUNs and secondary functions of the specified 'taddr' 6773 * target port as accessed via 'self' pHCI. Note that sd0 may be associated 6774 * with a child of the vHCI instead of 'self' - in this case the 'pi' 6775 * path_instance is used to ensure that the SCMD_REPORT_LUNS command is issued 6776 * through the 'self' pHCI path. 6777 * 6778 * We multi-thread across all the LUNs and secondary functions and enumerate 6779 * them. Which LUNs exist is based on SCMD_REPORT_LUNS data. 6780 * 6781 * The scsi_device we are called with should be for LUN0 and has been probed. 6782 * 6783 * This function is structured so that an HBA that has a different target 6784 * addressing structure can still use this function to enumerate the its 6785 * LUNs if it uses "taddr,lun" for its LUN space. 6786 * 6787 * We make assumptions about other LUNs associated with the target: 6788 * 6789 * For SCSI-2 and SCSI-3 target we will issue the SCSI report_luns 6790 * command. If this fails or we have a SCSI-1 then the number of 6791 * LUNs is determined based on SCSI_OPTIONS_NLUNS. For a SCSI-1 6792 * target we never probe above LUN 8, even if SCSI_OPTIONS_NLUNS 6793 * indicates we should. 6794 * 6795 * HBA drivers wanting a different set of assumptions should implement their 6796 * own LUN enumeration code. 6797 */ 6798 static int 6799 scsi_hba_enum_lsf_of_t(struct scsi_device *sd0, 6800 dev_info_t *self, char *taddr, int pi, int mt, scsi_enum_t se) 6801 { 6802 dev_info_t *child; 6803 scsi_hba_tran_t *tran; 6804 impl_scsi_tgtmap_t *tgtmap; 6805 damap_id_t tgtid; 6806 damap_t *tgtdam; 6807 damap_t *lundam = NULL; 6808 struct scsi_hba_mte_h *h; 6809 struct scsi_hba_mte_ld *ld; 6810 int aver; 6811 scsi_lun_t *lunp = NULL; 6812 int lun; 6813 uint32_t nluns; 6814 uint32_t tluns; 6815 size_t size; 6816 scsi_lun64_t lun64; 6817 int maxluns; 6818 6819 /* 6820 * If LUN0 failed then we have no other LUNs. 6821 * 6822 * NOTE: We need sd_inq to be valid to check ansi version. Since 6823 * scsi_unprobe is now a noop (sd_inq freeded in 6824 * scsi_busctl_uninitchild) sd_inq remains valid even if a target 6825 * driver detach(9E) occurs, resulting in a scsi_unprobe call 6826 * (sd_uninit_prevent keeps sd_inq valid by failing any 6827 * device_uninitchild attempts). 6828 */ 6829 ASSERT(sd0 && sd0->sd_uninit_prevent && sd0->sd_dev && sd0->sd_inq); 6830 if ((sd0 == NULL) || (sd0->sd_dev == NULL) || (sd0->sd_inq == NULL)) { 6831 SCSI_HBA_LOG((_LOG(1), NULL, sd0 ? sd0->sd_dev : NULL, 6832 "not setup correctly:%s%s%s", 6833 (sd0 == NULL) ? " device" : "", 6834 (sd0 && (sd0->sd_dev == NULL)) ? " dip" : "", 6835 (sd0 && (sd0->sd_inq == NULL)) ? " inq" : "")); 6836 return (DDI_FAILURE); 6837 } 6838 6839 /* 6840 * NOTE: child should only be used in SCSI_HBA_LOG context since with 6841 * vHCI enumeration it may be the vHCI 'client' devinfo child instead 6842 * of a child of the 'self' pHCI we are enumerating. 6843 */ 6844 child = sd0->sd_dev; 6845 6846 /* Determine if we are reporting lun observations into lunmap. */ 6847 tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE); 6848 tgtmap = (impl_scsi_tgtmap_t *)tran->tran_tgtmap; 6849 if (tgtmap) { 6850 tgtdam = tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]; 6851 tgtid = damap_lookup(tgtdam, taddr); 6852 if (tgtid != NODAM) { 6853 lundam = damap_id_priv_get(tgtdam, tgtid); 6854 damap_id_rele(tgtdam, tgtid); 6855 ASSERT(lundam); 6856 } 6857 } 6858 6859 if (lundam) { 6860 /* If using lunmap, start the observation */ 6861 scsi_lunmap_set_begin(self, lundam); 6862 } else { 6863 /* allocate and initialize the LUN handle */ 6864 h = kmem_zalloc(sizeof (*h), KM_SLEEP); 6865 mutex_init(&h->h_lock, NULL, MUTEX_DEFAULT, NULL); 6866 cv_init(&h->h_cv, NULL, CV_DEFAULT, NULL); 6867 h->h_self = self; 6868 } 6869 6870 /* See if SCMD_REPORT_LUNS works for SCSI-2 and beyond */ 6871 aver = sd0->sd_inq->inq_ansi; 6872 if ((aver >= SCSI_VERSION_2) && (scsi_device_reportluns(sd0, 6873 taddr, pi, &lunp, &nluns, &tluns, &size) == NDI_SUCCESS)) { 6874 6875 ASSERT(lunp && (size > 0) && (nluns > 0) && (tluns > 0)); 6876 6877 /* loop over the reported LUNs */ 6878 SCSI_HBA_LOG((_LOG(2), NULL, child, 6879 "@%s,0 path %d: enumerating %d reported lun%s", taddr, pi, 6880 nluns, nluns > 1 ? "s" : "")); 6881 6882 for (lun = 0; lun < nluns; lun++) { 6883 lun64 = scsi_lun_to_lun64(lunp[lun]); 6884 6885 if (lundam) { 6886 if (scsi_lunmap_set_add(self, lundam, 6887 taddr, lun64, -1) != DDI_SUCCESS) { 6888 SCSI_HBA_LOG((_LOG_NF(WARN), 6889 "@%s,%" PRIx64 " failed to create", 6890 taddr, lun64)); 6891 } 6892 } else { 6893 if (lun64 == 0) 6894 continue; 6895 6896 /* allocate a thread data structure for LUN */ 6897 ld = kmem_alloc(sizeof (*ld), KM_SLEEP); 6898 ld->ld_h = h; 6899 ld->ld_taddr = taddr; 6900 ld->ld_lun64 = lun64; 6901 ld->ld_sfunc = -1; 6902 ld->ld_se = se; 6903 6904 /* process the LUN */ 6905 mutex_enter(&h->h_lock); 6906 h->h_thr_count++; 6907 mutex_exit(&h->h_lock); 6908 6909 mt |= scsi_hba_log_mt_disable; 6910 if (mt & SCSI_ENUMERATION_MT_TARGET_DISABLE) 6911 scsi_hba_enum_lsf_of_tgt_thr( 6912 (void *)ld); 6913 else 6914 (void) thread_create(NULL, 0, 6915 scsi_hba_enum_lsf_of_tgt_thr, 6916 (void *)ld, 0, &p0, TS_RUN, 6917 minclsyspri); 6918 } 6919 } 6920 6921 /* free the LUN array allocated by scsi_device_reportluns */ 6922 kmem_free(lunp, size); 6923 } else { 6924 /* Couldn't get SCMD_REPORT_LUNS data */ 6925 if (aver >= SCSI_VERSION_3) { 6926 if (se == SE_HP) 6927 SCSI_HBA_LOG((_LOG(WARN), NULL, child, 6928 "enumeration failed during report_lun")); 6929 else 6930 SCSI_HBA_LOG((_LOG(2), NULL, child, 6931 "enumeration failed during report_lun")); 6932 } 6933 6934 /* Determine the number of LUNs to enumerate. */ 6935 maxluns = scsi_get_scsi_maxluns(sd0); 6936 6937 /* loop over possible LUNs, skipping LUN0 */ 6938 if (maxluns > 1) 6939 SCSI_HBA_LOG((_LOG(2), NULL, child, 6940 "@%s,0 path %d: enumerating luns 1-%d", taddr, pi, 6941 maxluns - 1)); 6942 else 6943 SCSI_HBA_LOG((_LOG(2), NULL, child, 6944 "@%s,0 path %d: enumerating just lun0", taddr, pi)); 6945 6946 for (lun64 = 0; lun64 < maxluns; lun64++) { 6947 if (lundam) { 6948 if (scsi_lunmap_set_add(self, lundam, 6949 taddr, lun64, -1) != DDI_SUCCESS) { 6950 SCSI_HBA_LOG((_LOG_NF(WARN), 6951 "@%s,%" PRIx64 " failed to create", 6952 taddr, lun64)); 6953 } 6954 } else { 6955 if (lun64 == 0) 6956 continue; 6957 6958 /* allocate a thread data structure for LUN */ 6959 ld = kmem_alloc(sizeof (*ld), KM_SLEEP); 6960 ld->ld_h = h; 6961 ld->ld_taddr = taddr; 6962 ld->ld_lun64 = lun64; 6963 ld->ld_sfunc = -1; 6964 ld->ld_se = se; 6965 6966 /* process the LUN */ 6967 mutex_enter(&h->h_lock); 6968 h->h_thr_count++; 6969 mutex_exit(&h->h_lock); 6970 6971 mt |= scsi_hba_log_mt_disable; 6972 if (mt & SCSI_ENUMERATION_MT_TARGET_DISABLE) 6973 scsi_hba_enum_lsf_of_tgt_thr( 6974 (void *)ld); 6975 else 6976 (void) thread_create(NULL, 0, 6977 scsi_hba_enum_lsf_of_tgt_thr, 6978 (void *)ld, 0, &p0, TS_RUN, 6979 minclsyspri); 6980 } 6981 } 6982 } 6983 6984 /* 6985 * If we have an embedded service as a secondary function on LUN0 and 6986 * the primary LUN0 function is different than the secondary function 6987 * then enumerate the secondary function. The sfunc value is the dtype 6988 * associated with the embedded service. 6989 * 6990 * inq_encserv: enclosure service and our dtype is not DTYPE_ESI 6991 * or DTYPE_UNKNOWN then create a separate DTYPE_ESI node for 6992 * enclosure service access. 6993 */ 6994 ASSERT(sd0->sd_inq); 6995 if (sd0->sd_inq->inq_encserv && 6996 ((sd0->sd_inq->inq_dtype & DTYPE_MASK) != DTYPE_UNKNOWN) && 6997 ((sd0->sd_inq->inq_dtype & DTYPE_MASK) != DTYPE_ESI) && 6998 ((sd0->sd_inq->inq_ansi >= SCSI_VERSION_3))) { 6999 if (lundam) { 7000 if (scsi_lunmap_set_add(self, lundam, 7001 taddr, 0, DTYPE_ESI) != DDI_SUCCESS) { 7002 SCSI_HBA_LOG((_LOG_NF(WARN), 7003 "@%s,0,%x failed to create", 7004 taddr, DTYPE_ESI)); 7005 } 7006 } else { 7007 /* allocate a thread data structure for sfunc */ 7008 ld = kmem_alloc(sizeof (*ld), KM_SLEEP); 7009 ld->ld_h = h; 7010 ld->ld_taddr = taddr; 7011 ld->ld_lun64 = 0; 7012 ld->ld_sfunc = DTYPE_ESI; 7013 ld->ld_se = se; 7014 7015 /* process the LUN */ 7016 mutex_enter(&h->h_lock); 7017 h->h_thr_count++; 7018 mutex_exit(&h->h_lock); 7019 7020 mt |= scsi_hba_log_mt_disable; 7021 if (mt & SCSI_ENUMERATION_MT_TARGET_DISABLE) 7022 scsi_hba_enum_lsf_of_tgt_thr((void *)ld); 7023 else 7024 (void) thread_create(NULL, 0, 7025 scsi_hba_enum_lsf_of_tgt_thr, (void *)ld, 7026 0, &p0, TS_RUN, minclsyspri); 7027 } 7028 } 7029 7030 /* 7031 * Future: Add secondary function support for: 7032 * inq_mchngr (DTYPE_CHANGER) 7033 * inq_sccs (DTYPE_ARRAY_CTRL) 7034 */ 7035 7036 if (lundam) { 7037 /* If using lunmap, end the observation */ 7038 scsi_lunmap_set_end(self, lundam); 7039 } else { 7040 /* wait for all the LUN threads of this target to complete */ 7041 mutex_enter(&h->h_lock); 7042 while (h->h_thr_count > 0) 7043 cv_wait(&h->h_cv, &h->h_lock); 7044 mutex_exit(&h->h_lock); 7045 7046 /* free the target handle */ 7047 cv_destroy(&h->h_cv); 7048 mutex_destroy(&h->h_lock); 7049 kmem_free(h, sizeof (*h)); 7050 } 7051 7052 return (DDI_SUCCESS); 7053 } 7054 7055 /* 7056 * Enumerate LUN0 and all other LUNs and secondary functions associated with 7057 * the specified target address. 7058 * 7059 * Return NDI_SUCCESS if we might have created a new node. 7060 * Return NDI_FAILURE if we definitely did not create a new node. 7061 */ 7062 static int 7063 scsi_hba_bus_config_taddr(dev_info_t *self, char *taddr, int mt, scsi_enum_t se) 7064 { 7065 char addr[SCSI_MAXNAMELEN]; 7066 struct scsi_device *sd; 7067 int circ; 7068 int ret; 7069 int pi; 7070 7071 /* See if LUN0 of the specified target exists. */ 7072 (void) snprintf(addr, sizeof (addr), "%s,0", taddr); 7073 7074 scsi_hba_devi_enter(self, &circ); 7075 sd = scsi_device_config(self, NULL, addr, se, &circ, &pi); 7076 7077 if (sd) { 7078 /* 7079 * LUN0 exists, enumerate all the other LUNs. 7080 * 7081 * With vHCI enumeration, when 'self' is a pHCI the sd 7082 * scsi_device may be associated with the vHCI 'client'. 7083 * In this case 'pi' is the path_instance needed to 7084 * continue enumeration communication LUN0 via 'self' 7085 * pHCI and specific 'taddr' target address. 7086 * 7087 * We prevent the removal of LUN0 until we are done with 7088 * prevent/allow because we must exit the parent for 7089 * multi-threaded scsi_hba_enum_lsf_of_t(). 7090 * 7091 * NOTE: scsi_unprobe is a noop, sd->sd_inq is valid until 7092 * device_uninitchild - so sd_uninit_prevent keeps sd_inq valid 7093 * by failing any device_uninitchild attempts. 7094 */ 7095 ret = NDI_SUCCESS; 7096 sd->sd_uninit_prevent++; 7097 scsi_hba_devi_exit(self, circ); 7098 7099 (void) scsi_hba_enum_lsf_of_t(sd, self, taddr, pi, mt, se); 7100 7101 scsi_hba_devi_enter(self, &circ); 7102 sd->sd_uninit_prevent--; 7103 } else 7104 ret = NDI_FAILURE; 7105 scsi_hba_devi_exit(self, circ); 7106 return (ret); 7107 } 7108 7109 /* Config callout from scsi_hba_thread_taddrs */ 7110 static void 7111 scsi_hba_taddr_config_thr(void *arg) 7112 { 7113 struct scsi_hba_mte_td *td = (struct scsi_hba_mte_td *)arg; 7114 struct scsi_hba_mte_h *h = td->td_h; 7115 7116 (void) scsi_hba_bus_config_taddr(h->h_self, td->td_taddr, 7117 td->td_mt, td->td_se); 7118 7119 /* signal completion of this target thread to the HBA */ 7120 mutex_enter(&h->h_lock); 7121 if (--h->h_thr_count == 0) 7122 cv_broadcast(&h->h_cv); 7123 mutex_exit(&h->h_lock); 7124 7125 /* free config thread data */ 7126 kmem_free(td, sizeof (*td)); 7127 } 7128 7129 /* 7130 * Enumerate all the children of the specified SCSI parallel interface (spi). 7131 * An HBA associated with a non-parallel scsi bus should be using another bus 7132 * level enumeration implementation (possibly their own) and calling 7133 * scsi_hba_bus_config_taddr to do enumeration of devices associated with a 7134 * particular target address. 7135 * 7136 * On an spi bus the targets are sequentially enumerated based on the 7137 * width of the bus. We also take care to try to skip the HBAs own initiator 7138 * id. See scsi_hba_enum_lsf_of_t() for LUN and secondary function enumeration. 7139 * 7140 * Return NDI_SUCCESS if we might have created a new node. 7141 * Return NDI_FAILURE if we definitely did not create a new node. 7142 * 7143 * Note: At some point we may want to expose this interface in transport.h 7144 * if we find an hba that implements bus_config but still uses spi-like target 7145 * addresses. 7146 */ 7147 static int 7148 scsi_hba_bus_configall_spi(dev_info_t *self, int mt) 7149 { 7150 int options; 7151 int ntargets; 7152 int id; 7153 int tgt; 7154 char **taddrs; 7155 char **taddr; 7156 char *tbuf; 7157 7158 /* 7159 * Find the number of targets supported on the bus. Look at the per 7160 * bus scsi-options property on the HBA node and check its 7161 * SCSI_OPTIONS_WIDE setting. 7162 */ 7163 options = ddi_prop_get_int(DDI_DEV_T_ANY, self, 7164 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, "scsi-options", -1); 7165 if ((options != -1) && ((options & SCSI_OPTIONS_WIDE) == 0)) 7166 ntargets = NTARGETS; /* 8 */ 7167 else 7168 ntargets = NTARGETS_WIDE; /* 16 */ 7169 7170 /* 7171 * Find the initiator-id for the HBA so we can skip that. We get the 7172 * cached value on the HBA node, established in scsi_hba_attach_setup. 7173 * If we were unable to determine the id then we rely on the HBA to 7174 * fail gracefully when asked to enumerate itself. 7175 */ 7176 id = ddi_prop_get_int(DDI_DEV_T_ANY, self, 7177 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, "scsi-initiator-id", -1); 7178 if (id > ntargets) { 7179 SCSI_HBA_LOG((_LOG(1), self, NULL, 7180 "'scsi-initiator-id' bogus for %d target bus: %d", 7181 ntargets, id)); 7182 id = -1; 7183 } 7184 SCSI_HBA_LOG((_LOG(2), self, NULL, 7185 "enumerating targets 0-%d skip %d", ntargets, id)); 7186 7187 /* form vector of target addresses */ 7188 taddrs = kmem_zalloc(sizeof (char *) * (ntargets + 1), KM_SLEEP); 7189 for (tgt = 0, taddr = taddrs; tgt < ntargets; tgt++) { 7190 /* skip initiator */ 7191 if (tgt == id) 7192 continue; 7193 7194 /* convert to string and enumerate the target address */ 7195 tbuf = kmem_alloc(((tgt/16) + 1) + 1, KM_SLEEP); 7196 (void) sprintf(tbuf, "%x", tgt); 7197 ASSERT(strlen(tbuf) == ((tgt/16) + 1)); 7198 *taddr++ = tbuf; 7199 } 7200 7201 /* null terminate vector of target addresses */ 7202 *taddr = NULL; 7203 7204 /* configure vector of target addresses */ 7205 scsi_hba_thread_taddrs(self, taddrs, mt, SE_BUSCONFIG, 7206 scsi_hba_taddr_config_thr); 7207 7208 /* free vector of target addresses */ 7209 for (taddr = taddrs; *taddr; taddr++) 7210 kmem_free(*taddr, strlen(*taddr) + 1); 7211 kmem_free(taddrs, sizeof (char *) * (ntargets + 1)); 7212 return (NDI_SUCCESS); 7213 } 7214 7215 /* 7216 * Transport independent bus_configone BUS_CONFIG_ONE implementation. Takes 7217 * same arguments, minus op, as scsi_hba_bus_config(), tran_bus_config(), 7218 * and scsi_hba_bus_config_spi(). 7219 */ 7220 int 7221 scsi_hba_bus_configone(dev_info_t *self, uint_t flags, char *arg, 7222 dev_info_t **childp) 7223 { 7224 int ret; 7225 int circ; 7226 char *name, *addr; 7227 char *lcp; 7228 char sc1, sc2; 7229 char nameaddr[SCSI_MAXNAMELEN]; 7230 extern int i_ndi_make_spec_children(dev_info_t *, uint_t); 7231 struct scsi_device *sd0, *sd; 7232 scsi_lun64_t lun64; 7233 int mt; 7234 7235 /* parse_name modifies arg1, we must duplicate "name@addr" */ 7236 (void) strcpy(nameaddr, arg); 7237 i_ddi_parse_name(nameaddr, &name, &addr, NULL); 7238 7239 /* verify the form of the node - we need an @addr */ 7240 if ((name == NULL) || (addr == NULL) || 7241 (*name == '\0') || (*addr == '\0')) { 7242 /* 7243 * OBP may create ill formed template/stub/wild-card 7244 * nodes (no @addr) for legacy driver loading methods - 7245 * ignore them. 7246 */ 7247 SCSI_HBA_LOG((_LOG(2), self, NULL, "%s ill formed", arg)); 7248 return (NDI_FAILURE); 7249 } 7250 7251 /* 7252 * Check to see if this is a non-scsi flavor configuration operation. 7253 */ 7254 if (strcmp(name, "smp") == 0) { 7255 /* 7256 * Configure the child, and if we're successful return with 7257 * active hold. 7258 */ 7259 return (smp_hba_bus_config(self, addr, childp)); 7260 } 7261 7262 /* 7263 * The framework does not ensure the creation of driver.conf 7264 * nodes prior to calling a nexus bus_config. For legacy 7265 * support of driver.conf file nodes we want to create our 7266 * driver.conf file children now so that we can detect if we 7267 * are being asked to bus_configone one of these nodes. 7268 * 7269 * Needing driver.conf file nodes prior to bus config is unique 7270 * to scsi_enumeration mixed mode (legacy driver.conf and 7271 * dynamic SID node) support. There is no general need for the 7272 * framework to make driver.conf children prior to bus_config. 7273 * 7274 * We enter our HBA (self) prior to scsi_device_config, and 7275 * pass it our circ. The scsi_device_config may exit the 7276 * HBA around scsi_probe() operations to allow for parallelism. 7277 * This is done after the probe node "@addr" is available as a 7278 * barrier to prevent parallel probes of the same device. The 7279 * probe node is also configured in a way that it can't be 7280 * removed by the framework until we are done with it. 7281 * 7282 * NOTE: The framework is currently preventing many parallel 7283 * sibling operations (such as attaches), so the parallelism 7284 * we are providing is of marginal use until that is improved. 7285 * The most logical way to solve this would be to have separate 7286 * target and lun nodes. This would be a large change in the 7287 * format of /devices paths and is not being pursued at this 7288 * time. The need for parallelism will become more of an issue 7289 * with top-down attach for mpxio/vhci and for iSCSI support. 7290 * We may want to eventually want a dual mode implementation, 7291 * where the HBA determines if we should construct separate 7292 * target and lun devinfo nodes. 7293 */ 7294 scsi_hba_devi_enter(self, &circ); 7295 SCSI_HBA_LOG((_LOG(4), self, NULL, "%s@%s config_one", name, addr)); 7296 (void) i_ndi_make_spec_children(self, flags); 7297 7298 /* 7299 * For bus_configone, we make sure that we can find LUN0 7300 * first. This allows the delayed probe/barrier deletion for a 7301 * non-existent LUN0 (if enabled in scsi_device_config) to 7302 * cover all LUNs on the target. This is done to minimize the 7303 * number of independent target selection timeouts that occur 7304 * when a target with many LUNs is no longer accessible 7305 * (powered off). This removes the need for target driver 7306 * probe cache implementations. 7307 * 7308 * This optimization may not be desirable in a pure bridge 7309 * environment where targets on the other side of the bridge 7310 * show up as LUNs to the host. If we ever need to support 7311 * such a configuration then we should consider implementing a 7312 * SCSI_OPTIONS_ILUN0 bit. 7313 * 7314 * NOTE: we are *not* applying any target limitation filtering 7315 * to bus_configone, which means that we are relying on the 7316 * HBA tran_tgt_init entry point invoked by scsi_busctl_initchild 7317 * to fail. 7318 */ 7319 sd0 = (struct scsi_device *)-1; 7320 lcp = strchr(addr, ','); /* "addr,lun[,sfunc]" */ 7321 if (lcp) { 7322 /* 7323 * With "tgt,lun[,sfunc]" addressing, multiple addressing levels 7324 * have been compressed into single devinfo node unit-address. 7325 * This presents a mismatch - there is no bus_config to discover 7326 * LUNs below a specific target, the only choice is to 7327 * BUS_CONFIG_ALL the HBA. To support BUS_CONFIG_ALL_LUNS below 7328 * a specific target, a bus_configone with lun address of "*" 7329 * triggers lun discovery below a target. 7330 */ 7331 if (*(lcp + 1) == '*') { 7332 mt = ddi_prop_get_int(DDI_DEV_T_ANY, self, 7333 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 7334 "scsi-enumeration", scsi_enumeration); 7335 SCSI_HBA_LOG((_LOG(2), self, NULL, 7336 "%s@%s lun enumeration triggered", name, addr)); 7337 *lcp = '\0'; /* turn ',' into '\0' */ 7338 scsi_hba_devi_exit(self, circ); 7339 (void) scsi_hba_bus_config_taddr(self, addr, 7340 mt, SE_BUSCONFIG); 7341 return (NDI_FAILURE); 7342 } 7343 7344 /* convert hex lun number from ascii */ 7345 lun64 = scsi_addr_to_lun64(lcp + 1); 7346 7347 if ((lun64 != 0) && (lun64 != SCSI_LUN64_ILLEGAL)) { 7348 /* 7349 * configure ",0" lun first, saving off 7350 * original lun characters. 7351 */ 7352 sc1 = *(lcp + 1); 7353 sc2 = *(lcp + 2); 7354 *(lcp + 1) = '0'; 7355 *(lcp + 2) = '\0'; 7356 sd0 = scsi_device_config(self, NULL, addr, 7357 SE_BUSCONFIG, &circ, NULL); 7358 7359 /* restore original lun */ 7360 *(lcp + 1) = sc1; 7361 *(lcp + 2) = sc2; 7362 7363 /* 7364 * Apply maxlun filtering. 7365 * 7366 * Future: We still have the kludged 7367 * scsi_check_ss2_LUN_limit() filtering off 7368 * scsi_probe() to catch bogus driver.conf 7369 * entries. 7370 */ 7371 if (sd0 && (lun64 < SCSI_32LUNS_PER_TARGET) && 7372 (lun64 >= scsi_get_scsi_maxluns(sd0))) { 7373 sd0 = NULL; 7374 SCSI_HBA_LOG((_LOG(4), self, NULL, 7375 "%s@%s filtered", name, addr)); 7376 } else 7377 SCSI_HBA_LOG((_LOG(4), self, NULL, 7378 "%s@%s lun 0 %s", name, addr, 7379 sd0 ? "worked" : "failed")); 7380 } 7381 } 7382 7383 /* 7384 * configure the requested device if LUN0 exists or we were 7385 * unable to determine the lun format to determine if LUN0 7386 * exists. 7387 */ 7388 if (sd0) { 7389 sd = scsi_device_config(self, name, addr, 7390 SE_BUSCONFIG, &circ, NULL); 7391 } else { 7392 sd = NULL; 7393 SCSI_HBA_LOG((_LOG(2), self, NULL, 7394 "%s@%s no lun 0 or filtered lun", name, addr)); 7395 } 7396 7397 /* 7398 * We know what we found, to reduce overhead we finish BUS_CONFIG_ONE 7399 * processing without calling back to the frameworks 7400 * ndi_busop_bus_config (unless we goto framework below). 7401 * 7402 * If the reference is to a driver name and we created a generic name 7403 * (bound to that driver) we will still succeed. This is important 7404 * for correctly resolving old drivername references to device that now 7405 * uses a generic names across the transition to generic naming. This 7406 * is effectively an internal implementation of the NDI_DRIVERNAME flag. 7407 * 7408 * We also need to special case the resolve_pathname OBP boot-device 7409 * case (modrootloaded == 0) where reference is to a generic name but 7410 * we created a legacy driver name node by returning just returning 7411 * the node created. 7412 */ 7413 if (sd && sd->sd_dev && 7414 ((strcmp(ddi_node_name(sd->sd_dev), name) == 0) || 7415 (strcmp(ddi_driver_name(sd->sd_dev), name) == 0) || 7416 (modrootloaded == 0)) && 7417 (ndi_devi_online(sd->sd_dev, 7418 flags & NDI_NO_EVENT) == NDI_SUCCESS)) { 7419 7420 /* device attached, return devinfo node with hold */ 7421 ret = NDI_SUCCESS; 7422 *childp = sd->sd_dev; 7423 ndi_hold_devi(sd->sd_dev); 7424 } else { 7425 /* 7426 * In the process of failing we may have added nodes to the HBA 7427 * (self), clearing DEVI_MADE_CHILDREN. To reduce the overhead 7428 * associated with the frameworks reaction to this we clear the 7429 * flag here. 7430 */ 7431 mutex_enter(&DEVI(self)->devi_lock); 7432 DEVI(self)->devi_flags &= ~DEVI_MADE_CHILDREN; 7433 mutex_exit(&DEVI(self)->devi_lock); 7434 ret = NDI_FAILURE; 7435 7436 /* 7437 * The framework may still be able to succeed with 7438 * with its GENERIC_PROP code. 7439 */ 7440 scsi_hba_devi_exit(self, circ); 7441 if (flags & NDI_DRV_CONF_REPROBE) 7442 flags |= NDI_CONFIG_REPROBE; 7443 flags |= NDI_MDI_FALLBACK; /* devinfo&pathinfo children */ 7444 return (ndi_busop_bus_config(self, flags, BUS_CONFIG_ONE, 7445 (void *)arg, childp, 0)); 7446 } 7447 7448 scsi_hba_devi_exit(self, circ); 7449 return (ret); 7450 } 7451 7452 /* 7453 * Perform SCSI Parallel Interconnect bus_config 7454 */ 7455 static int 7456 scsi_hba_bus_config_spi(dev_info_t *self, uint_t flags, 7457 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 7458 { 7459 int ret; 7460 int mt; 7461 7462 /* 7463 * Enumerate scsi target devices: See if we are doing generic dynamic 7464 * enumeration: if driver.conf has not specified the 'scsi-enumeration' 7465 * knob then use the global scsi_enumeration knob. 7466 */ 7467 mt = ddi_prop_get_int(DDI_DEV_T_ANY, self, 7468 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 7469 "scsi-enumeration", scsi_enumeration); 7470 if ((mt & SCSI_ENUMERATION_ENABLE) == 0) { 7471 /* 7472 * Static driver.conf file enumeration: 7473 * 7474 * Force reprobe for BUS_CONFIG_ONE or when manually 7475 * reconfiguring via devfsadm(1m) to emulate deferred attach. 7476 * Reprobe only discovers driver.conf enumerated nodes, more 7477 * dynamic implementations probably require their own 7478 * bus_config. 7479 */ 7480 if ((op == BUS_CONFIG_ONE) || (flags & NDI_DRV_CONF_REPROBE)) 7481 flags |= NDI_CONFIG_REPROBE; 7482 flags |= NDI_MDI_FALLBACK; /* devinfo&pathinfo children */ 7483 return (ndi_busop_bus_config(self, flags, op, arg, childp, 0)); 7484 } 7485 7486 if (scsi_hba_busconfig_debug) 7487 flags |= NDI_DEVI_DEBUG; 7488 7489 /* 7490 * Generic spi dynamic bus config enumeration to discover and enumerate 7491 * the target device nodes we are looking for. 7492 */ 7493 switch (op) { 7494 case BUS_CONFIG_ONE: /* enumerate the named child */ 7495 ret = scsi_hba_bus_configone(self, flags, (char *)arg, childp); 7496 break; 7497 7498 case BUS_CONFIG_ALL: /* enumerate all children on the bus */ 7499 case BUS_CONFIG_DRIVER: /* enumerate all children that bind to driver */ 7500 SCSI_HBA_LOG((_LOG(3), self, NULL, 7501 "BUS_CONFIG_%s mt %x", 7502 (op == BUS_CONFIG_ALL) ? "ALL" : "DRIVER", mt)); 7503 7504 /* 7505 * Enumerate targets on SCSI parallel interconnect and let the 7506 * framework finish the operation (attach the nodes). 7507 */ 7508 if ((ret = scsi_hba_bus_configall_spi(self, mt)) == NDI_SUCCESS) 7509 ret = ndi_busop_bus_config(self, flags, op, 7510 arg, childp, 0); 7511 break; 7512 7513 default: 7514 ret = NDI_FAILURE; 7515 break; 7516 } 7517 return (ret); 7518 } 7519 7520 /* 7521 * Perform SCSI Parallel Interconnect bus_unconfig 7522 */ 7523 static int 7524 scsi_hba_bus_unconfig_spi(dev_info_t *self, uint_t flags, 7525 ddi_bus_config_op_t op, void *arg) 7526 { 7527 int mt; 7528 int circ; 7529 int ret; 7530 7531 /* 7532 * See if we are doing generic dynamic enumeration: if driver.conf has 7533 * not specified the 'scsi-enumeration' knob then use the global 7534 * scsi_enumeration knob. 7535 */ 7536 mt = ddi_prop_get_int(DDI_DEV_T_ANY, self, 7537 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 7538 "scsi-enumeration", scsi_enumeration); 7539 if ((mt & SCSI_ENUMERATION_ENABLE) == 0) 7540 return (ndi_busop_bus_unconfig(self, flags, op, arg)); 7541 7542 if (scsi_hba_busconfig_debug) 7543 flags |= NDI_DEVI_DEBUG; 7544 7545 scsi_hba_devi_enter(self, &circ); 7546 switch (op) { 7547 case BUS_UNCONFIG_ONE: 7548 SCSI_HBA_LOG((_LOG(3), self, NULL, 7549 "unconfig one: %s", (char *)arg)); 7550 ret = NDI_SUCCESS; 7551 break; 7552 7553 case BUS_UNCONFIG_ALL: 7554 case BUS_UNCONFIG_DRIVER: 7555 ret = NDI_SUCCESS; 7556 break; 7557 7558 default: 7559 ret = NDI_FAILURE; 7560 break; 7561 } 7562 7563 /* Perform the generic default bus unconfig */ 7564 if (ret == NDI_SUCCESS) 7565 ret = ndi_busop_bus_unconfig(self, flags, op, arg); 7566 7567 scsi_hba_devi_exit(self, circ); 7568 7569 return (ret); 7570 } 7571 7572 static int 7573 scsi_hba_bus_config_tgtmap(dev_info_t *self, uint_t flags, 7574 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 7575 { 7576 int ret = NDI_FAILURE; 7577 7578 switch (op) { 7579 case BUS_CONFIG_ONE: 7580 ret = scsi_hba_bus_configone(self, flags, arg, childp); 7581 break; 7582 7583 case BUS_CONFIG_ALL: 7584 case BUS_CONFIG_DRIVER: 7585 ret = ndi_busop_bus_config(self, flags, op, arg, childp, 0); 7586 break; 7587 7588 default: 7589 break; 7590 } 7591 7592 return (ret); 7593 } 7594 7595 static int 7596 scsi_hba_bus_unconfig_tgtmap(dev_info_t *self, uint_t flags, 7597 ddi_bus_config_op_t op, void *arg) 7598 { 7599 int ret = NDI_FAILURE; 7600 7601 switch (op) { 7602 case BUS_UNCONFIG_ONE: 7603 case BUS_UNCONFIG_DRIVER: 7604 case BUS_UNCONFIG_ALL: 7605 ret = NDI_SUCCESS; 7606 break; 7607 default: 7608 break; 7609 } 7610 7611 if (ret == NDI_SUCCESS) { 7612 flags &= ~NDI_DEVI_REMOVE; 7613 ret = ndi_busop_bus_unconfig(self, flags, op, arg); 7614 } 7615 return (ret); 7616 } 7617 7618 static int 7619 scsi_hba_bus_config_iportmap(dev_info_t *self, uint_t flags, 7620 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 7621 { 7622 dev_info_t *child; 7623 int circ; 7624 int ret = NDI_FAILURE; 7625 7626 /* 7627 * MPXIO is never a sure thing (and we have mixed children), so 7628 * set NDI_NDI_FALLBACK so that ndi_busop_bus_config will 7629 * search for both devinfo and pathinfo children. 7630 * 7631 * Future: Remove NDI_MDI_FALLBACK since devcfg.c now looks for 7632 * devinfo/pathinfo children in parallel (instead of old way of 7633 * looking for one form of child and then doing "fallback" to 7634 * look for other form of child). 7635 */ 7636 flags |= NDI_MDI_FALLBACK; /* devinfo&pathinfo children */ 7637 switch (op) { 7638 case BUS_CONFIG_ONE: 7639 scsi_hba_devi_enter(self, &circ); 7640 /* create the iport node child */ 7641 if ((child = scsi_hba_bus_config_port(self, (char *)arg, 7642 SE_BUSCONFIG)) != NULL) { 7643 if (childp) { 7644 ndi_hold_devi(child); 7645 *childp = child; 7646 } 7647 ret = NDI_SUCCESS; 7648 } 7649 scsi_hba_devi_exit(self, circ); 7650 break; 7651 7652 case BUS_CONFIG_ALL: 7653 case BUS_CONFIG_DRIVER: 7654 ret = ndi_busop_bus_config(self, flags, op, arg, childp, 0); 7655 break; 7656 7657 default: 7658 break; 7659 } 7660 return (ret); 7661 } 7662 7663 static int 7664 scsi_hba_bus_unconfig_iportmap(dev_info_t *self, uint_t flags, 7665 ddi_bus_config_op_t op, void *arg) 7666 { 7667 flags &= ~NDI_DEVI_REMOVE; 7668 return (ndi_busop_bus_unconfig(self, flags, op, arg)); 7669 } 7670 7671 /* 7672 * SCSI HBA bus config enumeration entry point. Called via the bus_ops 7673 * bus_config entry point for all SCSA HBA drivers. 7674 * 7675 * o If an HBA implements its own bus_config via tran_bus_config then we 7676 * invoke it. An HBA that implements its own tran_bus_config entry point 7677 * may still call back into common SCSA code bus_config code for: 7678 * 7679 * o SPI bus_config (scsi_hba_bus_spi) 7680 * o LUN and secondary function enumeration (scsi_hba_enum_lsf_of_t()). 7681 * o configuration of a specific device (scsi_device_config). 7682 * o determining 1275 SCSI nodename and compatible property 7683 * (scsi_hba_nodename_compatible_get/_free). 7684 * 7685 * o Otherwise we implement a SCSI parallel interface (spi) bus config. 7686 * 7687 * Return NDI_SUCCESS if we might have created a new node. 7688 * Return NDI_FAILURE if we definitely did not create a new node. 7689 */ 7690 static int 7691 scsi_hba_bus_config(dev_info_t *self, uint_t flags, 7692 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 7693 { 7694 scsi_hba_tran_t *tran; 7695 int ret; 7696 7697 /* make sure that we will not disappear */ 7698 ASSERT(DEVI(self)->devi_ref); 7699 7700 tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE); 7701 if (tran == NULL) { 7702 /* NULL tran driver.conf config (used by cmdk). */ 7703 if ((op == BUS_CONFIG_ONE) || (flags & NDI_DRV_CONF_REPROBE)) 7704 flags |= NDI_CONFIG_REPROBE; 7705 return (ndi_busop_bus_config(self, flags, op, arg, childp, 0)); 7706 } 7707 7708 /* Check if self is HBA-only node. */ 7709 if (tran->tran_hba_flags & SCSI_HBA_HBA) { 7710 /* The bus_config request is to configure iports below HBA. */ 7711 7712 #ifdef sparc 7713 /* 7714 * Sparc's 'boot-device' OBP property value lacks an /iport@X/ 7715 * component. Prior to the mount of root, we drive a disk@ 7716 * BUS_CONFIG_ONE operatino down a level to resolve an 7717 * OBP 'boot-device' path. 7718 * 7719 * Future: Add (modrootloaded == 0) below, and insure that 7720 * all attempts bus_conf of 'bo_name' (in OBP form) occur 7721 * prior to 'modrootloaded = 1;' assignment in vfs_mountroot. 7722 */ 7723 if ((op == BUS_CONFIG_ONE) && 7724 (strncmp((char *)arg, "disk@", strlen("disk@")) == 0)) { 7725 return (scsi_hba_bus_config_prom_node(self, 7726 flags, arg, childp)); 7727 } 7728 #endif /* sparc */ 7729 7730 if (tran->tran_iportmap) { 7731 /* config based on scsi_hba_iportmap API */ 7732 ret = scsi_hba_bus_config_iportmap(self, 7733 flags, op, arg, childp); 7734 } else { 7735 /* config based on 'iport_register' API */ 7736 ret = scsi_hba_bus_config_iports(self, 7737 flags, op, arg, childp); 7738 } 7739 return (ret); 7740 } 7741 7742 /* Check to see how the iport/HBA does target/lun bus config. */ 7743 if (tran->tran_bus_config) { 7744 /* HBA config based on Sun-private/legacy tran_bus_config */ 7745 ret = tran->tran_bus_config(self, flags, op, arg, childp); 7746 } else if (tran->tran_tgtmap) { 7747 /* SCSAv3 config based on scsi_hba_tgtmap_*() API */ 7748 ret = scsi_hba_bus_config_tgtmap(self, flags, op, arg, childp); 7749 } else { 7750 /* SCSA config based on SCSI Parallel Interconnect */ 7751 ret = scsi_hba_bus_config_spi(self, flags, op, arg, childp); 7752 } 7753 return (ret); 7754 } 7755 7756 /* 7757 * Called via the bus_ops bus_unconfig entry point for SCSI HBA drivers. 7758 */ 7759 static int 7760 scsi_hba_bus_unconfig(dev_info_t *self, uint_t flags, 7761 ddi_bus_config_op_t op, void *arg) 7762 { 7763 int circ; 7764 scsi_hba_tran_t *tran; 7765 int ret; 7766 7767 tran = ddi_get_driver_private(self); 7768 if (tran == NULL) { 7769 /* NULL tran driver.conf unconfig (used by cmdk). */ 7770 return (ndi_busop_bus_unconfig(self, flags, op, arg)); 7771 } 7772 7773 /* 7774 * Purge barrier/probe node children. We do this prior to 7775 * tran_bus_unconfig in case the unconfig implementation calls back 7776 * into the common code at a different enumeration level, such a 7777 * scsi_device_config, which still creates barrier/probe nodes. 7778 */ 7779 scsi_hba_devi_enter(self, &circ); 7780 scsi_hba_barrier_purge(self); 7781 scsi_hba_devi_exit(self, circ); 7782 7783 /* Check if self is HBA-only node. */ 7784 if (tran->tran_hba_flags & SCSI_HBA_HBA) { 7785 /* The bus_config request is to unconfigure iports below HBA. */ 7786 if (tran->tran_iportmap) { 7787 /* unconfig based on scsi_hba_iportmap API */ 7788 ret = scsi_hba_bus_unconfig_iportmap(self, 7789 flags, op, arg); 7790 } 7791 return (ret); 7792 } 7793 7794 /* Check to see how the iport/HBA does target/lun bus unconfig. */ 7795 if (tran->tran_bus_unconfig) { 7796 /* HBA unconfig based on Sun-private/legacy tran_bus_unconfig */ 7797 ret = tran->tran_bus_unconfig(self, flags, op, arg); 7798 } else if (tran->tran_tgtmap) { 7799 /* SCSAv3 unconfig based on scsi_hba_tgtmap_*() API */ 7800 ret = scsi_hba_bus_unconfig_tgtmap(self, flags, op, arg); 7801 } else { 7802 /* SCSA unconfig based on SCSI Parallel Interconnect */ 7803 ret = scsi_hba_bus_unconfig_spi(self, flags, op, arg); 7804 } 7805 return (ret); 7806 } 7807 7808 static void 7809 scsi_tgtmap_scsi_config(void *arg, damap_t *mapp, damap_id_list_t id_list) 7810 { 7811 scsi_hba_tran_t *tran = (scsi_hba_tran_t *)arg; 7812 dev_info_t *self = tran->tran_iport_dip; 7813 impl_scsi_tgtmap_t *tgtmap; 7814 int mt; 7815 damap_id_t tgtid; 7816 int ntargets; 7817 char **tgt_addrv; 7818 char **tgt_addr; 7819 7820 tgtmap = (impl_scsi_tgtmap_t *)tran->tran_tgtmap; 7821 mt = ddi_prop_get_int(DDI_DEV_T_ANY, self, 7822 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 7823 "scsi-enumeration", scsi_enumeration); 7824 7825 /* count the number of targets we need to config */ 7826 for (ntargets = 0, 7827 tgtid = damap_id_next(mapp, id_list, NODAM); 7828 tgtid != NODAM; 7829 tgtid = damap_id_next(mapp, id_list, tgtid)) 7830 ntargets++; 7831 7832 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s %d target%s", 7833 damap_name(mapp), ntargets, (ntargets == 1) ? "" : "s")); 7834 if (ntargets == 0) 7835 return; 7836 7837 /* allocate and form vector of addresses */ 7838 tgt_addrv = kmem_zalloc(sizeof (char *) * (ntargets + 1), KM_SLEEP); 7839 for (tgt_addr = tgt_addrv, 7840 tgtid = damap_id_next(mapp, id_list, NODAM); 7841 tgtid != NODAM; 7842 tgtid = damap_id_next(mapp, id_list, tgtid), 7843 tgt_addr++) { 7844 *tgt_addr = damap_id2addr(mapp, tgtid); 7845 7846 if (scsi_lunmap_create(self, tgtmap, *tgt_addr) != DDI_SUCCESS) 7847 SCSI_HBA_LOG((_LOG_NF(WARN), 7848 "failed to create lunmap for %s", *tgt_addr)); 7849 else 7850 SCSI_HBA_LOG((_LOGTGT, self, NULL, 7851 "%s @%s", damap_name(mapp), *tgt_addr)); 7852 } 7853 7854 /* null terminate vector */ 7855 *tgt_addr = NULL; 7856 7857 /* configure vector of addresses (with multi-threading) */ 7858 scsi_hba_thread_taddrs(self, tgt_addrv, mt, SE_HP, 7859 scsi_hba_taddr_config_thr); 7860 7861 /* free vector */ 7862 kmem_free(tgt_addrv, sizeof (char *) * (ntargets + 1)); 7863 } 7864 7865 static void 7866 scsi_tgtmap_scsi_unconfig(void *arg, damap_t *mapp, damap_id_list_t id_list) 7867 { 7868 scsi_hba_tran_t *tran = (scsi_hba_tran_t *)arg; 7869 dev_info_t *self = tran->tran_iport_dip; 7870 impl_scsi_tgtmap_t *tgtmap; 7871 damap_id_t tgtid; 7872 char *tgt_addr; 7873 7874 tgtmap = (impl_scsi_tgtmap_t *)tran->tran_tgtmap; 7875 7876 for (tgtid = damap_id_next(mapp, id_list, NODAM); 7877 tgtid != NODAM; 7878 tgtid = damap_id_next(mapp, id_list, tgtid)) { 7879 tgt_addr = damap_id2addr(mapp, tgtid); 7880 7881 SCSI_HBA_LOG((_LOGTGT, self, NULL, 7882 "%s @%s", damap_name(mapp), tgt_addr)); 7883 scsi_lunmap_destroy(self, tgtmap, tgt_addr); 7884 } 7885 } 7886 7887 static void 7888 scsi_tgtmap_smp_config(void *arg, damap_t *mapp, damap_id_list_t id_list) 7889 { 7890 scsi_hba_tran_t *tran = (scsi_hba_tran_t *)arg; 7891 dev_info_t *self = tran->tran_iport_dip; 7892 damap_id_t tgtid; 7893 char *addr; 7894 7895 for (tgtid = damap_id_next(mapp, id_list, NODAM); 7896 tgtid != NODAM; 7897 tgtid = damap_id_next(mapp, id_list, tgtid)) { 7898 addr = damap_id2addr(mapp, tgtid); 7899 SCSI_HBA_LOG((_LOGTGT, self, NULL, 7900 "%s @%s", damap_name(mapp), addr)); 7901 7902 (void) smp_hba_bus_config_taddr(self, addr); 7903 } 7904 } 7905 7906 static void 7907 scsi_tgtmap_smp_unconfig(void *arg, damap_t *mapp, damap_id_list_t id_list) 7908 { 7909 scsi_hba_tran_t *tran = (scsi_hba_tran_t *)arg; 7910 dev_info_t *self = tran->tran_iport_dip; 7911 damap_id_t tgtid; 7912 char *addr; 7913 dev_info_t *child; 7914 char nameaddr[SCSI_MAXNAMELEN]; 7915 int circ; 7916 7917 for (tgtid = damap_id_next(mapp, id_list, NODAM); 7918 tgtid != NODAM; 7919 tgtid = damap_id_next(mapp, id_list, tgtid)) { 7920 addr = damap_id2addr(mapp, tgtid); 7921 SCSI_HBA_LOG((_LOGTGT, self, NULL, 7922 "%s @%s", damap_name(mapp), addr)); 7923 7924 (void) snprintf(nameaddr, sizeof (nameaddr), "smp@%s", addr); 7925 scsi_hba_devi_enter(self, &circ); 7926 if ((child = ndi_devi_findchild(self, nameaddr)) == NULL) { 7927 scsi_hba_devi_exit(self, circ); 7928 continue; 7929 } 7930 7931 if (ndi_devi_offline(child, 7932 NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE) == DDI_SUCCESS) { 7933 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 7934 "devinfo smp@%s offlined and removed", addr)); 7935 } else if (ndi_devi_device_remove(child)) { 7936 /* Offline/remove failed, note new device_remove */ 7937 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 7938 "devinfo smp@%s offline failed, device_remove", 7939 addr)); 7940 } 7941 scsi_hba_devi_exit(self, circ); 7942 } 7943 } 7944 7945 /* ARGSUSED1 */ 7946 static void 7947 scsi_tgtmap_smp_activate(void *map_priv, char *tgt_addr, int addrid, 7948 void **tgt_privp) 7949 { 7950 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)map_priv; 7951 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 7952 7953 if (tgtmap->tgtmap_activate_cb) { 7954 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s @%s activated", 7955 damap_name(tgtmap->tgtmap_dam[SCSI_TGT_SMP_DEVICE]), 7956 tgt_addr)); 7957 7958 (*tgtmap->tgtmap_activate_cb)(tgtmap->tgtmap_mappriv, 7959 tgt_addr, SCSI_TGT_SMP_DEVICE, tgt_privp); 7960 } 7961 } 7962 7963 /* ARGSUSED1 */ 7964 static void 7965 scsi_tgtmap_smp_deactivate(void *map_priv, char *tgt_addr, int addrid, 7966 void *tgt_privp) 7967 { 7968 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)map_priv; 7969 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 7970 7971 if (tgtmap->tgtmap_deactivate_cb) { 7972 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s @%s deactivated", 7973 damap_name(tgtmap->tgtmap_dam[SCSI_TGT_SMP_DEVICE]), 7974 tgt_addr)); 7975 7976 7977 (*tgtmap->tgtmap_deactivate_cb)(tgtmap->tgtmap_mappriv, 7978 tgt_addr, SCSI_TGT_SMP_DEVICE, tgt_privp); 7979 } 7980 } 7981 7982 /* ARGSUSED1 */ 7983 static void 7984 scsi_tgtmap_scsi_activate(void *map_priv, char *tgt_addr, int addrid, 7985 void **tgt_privp) 7986 { 7987 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)map_priv; 7988 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 7989 7990 if (tgtmap->tgtmap_activate_cb) { 7991 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s @%s activated", 7992 damap_name(tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]), 7993 tgt_addr)); 7994 7995 (*tgtmap->tgtmap_activate_cb)(tgtmap->tgtmap_mappriv, 7996 tgt_addr, SCSI_TGT_SCSI_DEVICE, tgt_privp); 7997 } 7998 } 7999 8000 /* ARGSUSED1 */ 8001 static void 8002 scsi_tgtmap_scsi_deactivate(void *map_priv, char *tgt_addr, int addrid, 8003 void *tgt_privp) 8004 { 8005 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)map_priv; 8006 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 8007 8008 if (tgtmap->tgtmap_deactivate_cb) { 8009 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s @%s deactivated", 8010 damap_name(tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]), 8011 tgt_addr)); 8012 8013 (*tgtmap->tgtmap_deactivate_cb)(tgtmap->tgtmap_mappriv, 8014 tgt_addr, SCSI_TGT_SCSI_DEVICE, tgt_privp); 8015 8016 } 8017 } 8018 8019 8020 int 8021 scsi_hba_tgtmap_create(dev_info_t *self, scsi_tgtmap_mode_t mode, 8022 clock_t settle, int n_entries, 8023 void *tgtmap_priv, scsi_tgt_activate_cb_t activate_cb, 8024 scsi_tgt_deactivate_cb_t deactivate_cb, 8025 scsi_hba_tgtmap_t **handle) 8026 { 8027 scsi_hba_tran_t *tran; 8028 damap_t *mapp; 8029 char context[64]; 8030 impl_scsi_tgtmap_t *tgtmap; 8031 damap_rptmode_t rpt_style; 8032 char *scsi_binding_set; 8033 8034 if (self == NULL || settle == 0 || n_entries == 0 || handle == NULL) 8035 return (DDI_FAILURE); 8036 8037 *handle = NULL; 8038 8039 if (scsi_hba_iport_unit_address(self) == NULL) 8040 return (DDI_FAILURE); 8041 8042 switch (mode) { 8043 case SCSI_TM_FULLSET: 8044 rpt_style = DAMAP_REPORT_FULLSET; 8045 break; 8046 case SCSI_TM_PERADDR: 8047 rpt_style = DAMAP_REPORT_PERADDR; 8048 break; 8049 default: 8050 return (DDI_FAILURE); 8051 } 8052 8053 tran = (scsi_hba_tran_t *)ddi_get_driver_private(self); 8054 ASSERT(tran); 8055 if (tran == NULL) 8056 return (DDI_FAILURE); 8057 8058 tgtmap = kmem_zalloc(sizeof (*tgtmap), KM_SLEEP); 8059 tgtmap->tgtmap_tran = tran; 8060 tgtmap->tgtmap_activate_cb = activate_cb; 8061 tgtmap->tgtmap_deactivate_cb = deactivate_cb; 8062 tgtmap->tgtmap_mappriv = tgtmap_priv; 8063 8064 (void) snprintf(context, sizeof (context), "%s%d.tgtmap.scsi", 8065 ddi_driver_name(self), ddi_get_instance(self)); 8066 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context)); 8067 if (damap_create(context, n_entries, rpt_style, settle, 8068 tgtmap, scsi_tgtmap_scsi_activate, scsi_tgtmap_scsi_deactivate, 8069 tran, scsi_tgtmap_scsi_config, scsi_tgtmap_scsi_unconfig, 8070 &mapp) != DAM_SUCCESS) { 8071 kmem_free(tgtmap, sizeof (*tgtmap)); 8072 return (DDI_FAILURE); 8073 } 8074 tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE] = mapp; 8075 8076 (void) snprintf(context, sizeof (context), "%s%d.tgtmap.smp", 8077 ddi_driver_name(self), ddi_get_instance(self)); 8078 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context)); 8079 if (damap_create(context, n_entries, rpt_style, settle, 8080 tgtmap, scsi_tgtmap_smp_activate, scsi_tgtmap_smp_deactivate, 8081 tran, scsi_tgtmap_smp_config, scsi_tgtmap_smp_unconfig, 8082 &mapp) != DAM_SUCCESS) { 8083 damap_destroy(tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]); 8084 kmem_free(tgtmap, sizeof (*tgtmap)); 8085 return (DDI_FAILURE); 8086 } 8087 tgtmap->tgtmap_dam[SCSI_TGT_SMP_DEVICE] = mapp; 8088 8089 tran->tran_tgtmap = (scsi_hba_tgtmap_t *)tgtmap; 8090 *handle = (scsi_hba_tgtmap_t *)tgtmap; 8091 8092 /* 8093 * We have now set tran_tgtmap, marking the tran as using tgtmap 8094 * enumeration services. To prevent the generation of legacy spi 8095 * 'binding-set' compatible forms, remove the 'scsi-binding-set' 8096 * property. 8097 */ 8098 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, self, 8099 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, "scsi-binding-set", 8100 &scsi_binding_set) == DDI_PROP_SUCCESS) { 8101 if (strcmp(scsi_binding_set, scsi_binding_set_spi) == 0) 8102 (void) ndi_prop_remove(DDI_DEV_T_NONE, self, 8103 "scsi-binding-set"); 8104 ddi_prop_free(scsi_binding_set); 8105 } 8106 return (DDI_SUCCESS); 8107 } 8108 8109 void 8110 scsi_hba_tgtmap_destroy(scsi_hba_tgtmap_t *handle) 8111 { 8112 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)handle; 8113 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 8114 int i; 8115 8116 for (i = 0; i < SCSI_TGT_NTYPES; i++) { 8117 if (tgtmap->tgtmap_dam[i]) { 8118 SCSI_HBA_LOG((_LOGTGT, self, NULL, 8119 "%s", damap_name(tgtmap->tgtmap_dam[i]))); 8120 8121 damap_destroy(tgtmap->tgtmap_dam[i]); 8122 } 8123 } 8124 kmem_free(tgtmap, sizeof (*tgtmap)); 8125 } 8126 8127 static int 8128 scsi_tgtmap_sync(scsi_hba_tgtmap_t *handle) 8129 { 8130 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)handle; 8131 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 8132 int empty = 1; 8133 int i; 8134 8135 for (i = 0; i < SCSI_TGT_NTYPES; i++) { 8136 if (tgtmap->tgtmap_dam[i]) { 8137 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s sync begin", 8138 damap_name(tgtmap->tgtmap_dam[i]))); 8139 8140 /* return 1 if all maps ended up empty */ 8141 empty &= damap_sync(tgtmap->tgtmap_dam[i]); 8142 8143 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s sync end", 8144 damap_name(tgtmap->tgtmap_dam[i]))); 8145 } 8146 } 8147 return (empty); 8148 } 8149 8150 int 8151 scsi_hba_tgtmap_set_begin(scsi_hba_tgtmap_t *handle) 8152 { 8153 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)handle; 8154 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 8155 char *context; 8156 int rv = DDI_SUCCESS; 8157 int i; 8158 8159 for (i = 0; i < SCSI_TGT_NTYPES; i++) { 8160 if (tgtmap->tgtmap_dam[i] == NULL) 8161 continue; 8162 8163 context = damap_name(tgtmap->tgtmap_dam[i]); 8164 8165 if (i == SCSI_TGT_SCSI_DEVICE) { 8166 /* 8167 * In scsi_device context, so we have the 'context' 8168 * string, diagnose the case where the tgtmap caller 8169 * is failing to make forward progress, i.e. the caller 8170 * is never completing an observation, and calling 8171 * scsi_hbg_tgtmap_set_end. If this occurs, the solaris 8172 * target/lun state may be out of sync with hardware. 8173 */ 8174 if (tgtmap->tgtmap_reports++ >= 8175 scsi_hba_tgtmap_reports_max) { 8176 tgtmap->tgtmap_noisy++; 8177 if (tgtmap->tgtmap_noisy == 1) 8178 SCSI_HBA_LOG((_LOG(WARN), self, NULL, 8179 "%s: failing to complete a tgtmap " 8180 "observation", context)); 8181 } 8182 } 8183 8184 if (damap_addrset_begin( 8185 tgtmap->tgtmap_dam[i]) != DAM_SUCCESS) { 8186 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s FAIL", context)); 8187 rv = DDI_FAILURE; 8188 continue; 8189 } 8190 8191 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context)); 8192 } 8193 return (rv); 8194 } 8195 8196 8197 int 8198 scsi_hba_tgtmap_set_add(scsi_hba_tgtmap_t *handle, 8199 scsi_tgtmap_tgt_type_t tgt_type, char *tgt_addr, void *tgt_priv) 8200 { 8201 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)handle; 8202 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 8203 8204 if (tgt_type >= SCSI_TGT_NTYPES || !tgtmap->tgtmap_dam[tgt_type]) 8205 return (DDI_FAILURE); 8206 8207 SCSI_HBA_LOG((_LOGTGT, self, NULL, 8208 "%s @%s", damap_name(tgtmap->tgtmap_dam[tgt_type]), tgt_addr)); 8209 8210 return ((damap_addrset_add(tgtmap->tgtmap_dam[tgt_type], tgt_addr, 8211 NULL, NULL, tgt_priv) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 8212 } 8213 8214 /*ARGSUSED*/ 8215 int 8216 scsi_hba_tgtmap_set_end(scsi_hba_tgtmap_t *handle, uint_t flags) 8217 { 8218 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)handle; 8219 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 8220 char *context; 8221 int rv = DDI_SUCCESS; 8222 int i; 8223 8224 tgtmap->tgtmap_reports = tgtmap->tgtmap_noisy = 0; 8225 8226 for (i = 0; i < SCSI_TGT_NTYPES; i++) { 8227 if (tgtmap->tgtmap_dam[i] == NULL) 8228 continue; 8229 8230 context = damap_name(tgtmap->tgtmap_dam[i]); 8231 if (damap_addrset_end( 8232 tgtmap->tgtmap_dam[i], 0) != DAM_SUCCESS) { 8233 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s FAIL", context)); 8234 rv = DDI_FAILURE; 8235 continue; 8236 } 8237 8238 SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context)); 8239 } 8240 return (rv); 8241 } 8242 8243 int 8244 scsi_hba_tgtmap_tgt_add(scsi_hba_tgtmap_t *handle, 8245 scsi_tgtmap_tgt_type_t tgt_type, char *tgt_addr, void *tgt_priv) 8246 8247 { 8248 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)handle; 8249 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 8250 8251 if (tgt_type >= SCSI_TGT_NTYPES || !tgtmap->tgtmap_dam[tgt_type]) 8252 return (DDI_FAILURE); 8253 8254 SCSI_HBA_LOG((_LOGTGT, self, NULL, 8255 "%s @%s", damap_name(tgtmap->tgtmap_dam[tgt_type]), tgt_addr)); 8256 8257 return ((damap_addr_add(tgtmap->tgtmap_dam[tgt_type], tgt_addr, NULL, 8258 NULL, tgt_priv) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 8259 } 8260 8261 int 8262 scsi_hba_tgtmap_tgt_remove(scsi_hba_tgtmap_t *handle, 8263 scsi_tgtmap_tgt_type_t tgt_type, char *tgt_addr) 8264 { 8265 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)handle; 8266 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 8267 8268 if (tgt_type >= SCSI_TGT_NTYPES || !tgtmap->tgtmap_dam[tgt_type]) 8269 return (DDI_FAILURE); 8270 8271 SCSI_HBA_LOG((_LOGTGT, self, NULL, 8272 "%s @%s", damap_name(tgtmap->tgtmap_dam[tgt_type]), tgt_addr)); 8273 8274 return ((damap_addr_del(tgtmap->tgtmap_dam[tgt_type], 8275 tgt_addr) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 8276 } 8277 8278 int 8279 scsi_hba_tgtmap_lookup(scsi_hba_tgtmap_t *handle, 8280 char *tgt_addr, scsi_tgtmap_tgt_type_t *r_type) 8281 { 8282 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)handle; 8283 dev_info_t *self = tgtmap->tgtmap_tran->tran_iport_dip; 8284 damap_id_t tgtid; 8285 int i; 8286 8287 for (i = 0; i < SCSI_TGT_NTYPES; i++) { 8288 tgtid = damap_lookup(tgtmap->tgtmap_dam[i], tgt_addr); 8289 if (tgtid != NODAM) { 8290 *r_type = i; 8291 SCSI_HBA_LOG((_LOG(3), self, NULL, 8292 "%s @%s found: type %d", 8293 damap_name(tgtmap->tgtmap_dam[i]), tgt_addr, i)); 8294 damap_id_rele(tgtmap->tgtmap_dam[i], tgtid); 8295 return (DDI_SUCCESS); 8296 } 8297 } 8298 8299 SCSI_HBA_LOG((_LOG(3), self, NULL, 8300 "%s%d.tgtmap @%s not found", 8301 ddi_driver_name(self), ddi_get_instance(self), tgt_addr)); 8302 return (DDI_FAILURE); 8303 } 8304 8305 /* 8306 * Return the unit-address of an 'iport' node, or NULL for non-iport node. 8307 */ 8308 char * 8309 scsi_hba_iport_unit_address(dev_info_t *self) 8310 { 8311 /* 8312 * NOTE: Since 'self' could be a SCSA iport node or a SCSA HBA node, 8313 * we can't use SCSA flavors: the flavor of a SCSA HBA node is not 8314 * established/owned by SCSA, it is established by the nexus that 8315 * created the SCSA HBA node (PCI) as a child. 8316 * 8317 * NOTE: If we want to support a node_name other than "iport" for 8318 * an iport node then we can add support for a "scsa-iport-node-name" 8319 * property on the SCSA HBA node. A SCSA HBA driver would set this 8320 * property on the SCSA HBA node prior to using the iport API. 8321 */ 8322 if (strcmp(ddi_node_name(self), "iport") == 0) 8323 return (ddi_get_name_addr(self)); 8324 else 8325 return (NULL); 8326 } 8327 8328 /* 8329 * Define a SCSI initiator port (bus/channel) for an HBA card that needs to 8330 * support multiple SCSI ports, but only has a single HBA devinfo node. This 8331 * function should be called from the HBA's attach(9E) implementation (when 8332 * processing the HBA devinfo node attach) after the number of SCSI ports on 8333 * the card is known or when the HBA driver DR handler detects a new port. 8334 * The function returns 0 on failure and 1 on success. 8335 * 8336 * The implementation will add the port value into the "scsi-iports" property 8337 * value maintained on the HBA node as. These properties are used by the generic 8338 * scsi bus_config implementation to dynamicaly enumerate the specified iport 8339 * children. The enumeration code will, on demand, create the appropriate 8340 * iport children with a SCSI_ADDR_PROP_IPORTUA unit address. This node will 8341 * bind to the same driver as the HBA node itself. This means that an HBA 8342 * driver that uses iports should expect probe(9E), attach(9E), and detach(9E) 8343 * calls on the iport children of the HBA. If configuration for all ports was 8344 * already done during HBA node attach, the driver should just return 8345 * DDI_SUCCESS when confronted with an iport node. 8346 * 8347 * A maximum of 32 iport ports are supported per HBA devinfo node. 8348 * 8349 * A NULL "port" can be used to indicate that the framework should enumerate 8350 * target children on the HBA node itself, in addition to enumerating target 8351 * children on any iport nodes declared. There are two reasons that an HBA may 8352 * wish to have target children enumerated on both the HBA node and iport 8353 * node(s): 8354 * 8355 * o If, in the past, HBA hardware had only a single physical port but now 8356 * supports multiple physical ports, the updated driver that supports 8357 * multiple physical ports may want to avoid /devices path upgrade issues 8358 * by enumerating the first physical port under the HBA instead of as a 8359 * iport. 8360 * 8361 * o Some hardware RAID HBA controllers (mlx, chs, etc) support multiple 8362 * SCSI physical ports configured so that various physical devices on 8363 * the physical ports are amalgamated into virtual devices on a virtual 8364 * port. Amalgamated physical devices no longer appear to the host OS 8365 * on the physical ports, but other non-amalgamated devices may still be 8366 * visible on the physical ports. These drivers use a model where the 8367 * physical ports are iport nodes and the HBA node is the virtual port to 8368 * the configured virtual devices. 8369 */ 8370 int 8371 scsi_hba_iport_register(dev_info_t *self, char *port) 8372 { 8373 unsigned int ports = 0; 8374 int rval, i; 8375 char **iports, **newiports; 8376 8377 ASSERT(self); 8378 if (self == NULL) 8379 return (DDI_FAILURE); 8380 8381 rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self, 8382 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports, 8383 &ports); 8384 8385 if (ports >= SCSI_HBA_MAX_IPORTS) { 8386 ddi_prop_free(iports); 8387 return (DDI_FAILURE); 8388 } 8389 8390 if (rval == DDI_PROP_SUCCESS) { 8391 for (i = 0; i < ports; i++) { 8392 if (strcmp(port, iports[i]) == 0) { 8393 /* iport already registered */ 8394 ddi_prop_free(iports); 8395 return (DDI_SUCCESS); 8396 } 8397 } 8398 } 8399 8400 newiports = kmem_alloc((sizeof (char *) * (ports + 1)), KM_SLEEP); 8401 8402 for (i = 0; i < ports; i++) { 8403 newiports[i] = strdup(iports[i]); 8404 } 8405 newiports[ports] = strdup(port); 8406 ports++; 8407 8408 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, self, 8409 "scsi-iports", newiports, ports) != DDI_PROP_SUCCESS) { 8410 SCSI_HBA_LOG((_LOG(WARN), self, NULL, 8411 "failed to establish %s %s", 8412 SCSI_ADDR_PROP_IPORTUA, port)); 8413 rval = DDI_FAILURE; 8414 } else { 8415 rval = DDI_SUCCESS; 8416 } 8417 8418 /* If there is iport exist, free property */ 8419 if (ports > 1) 8420 ddi_prop_free(iports); 8421 for (i = 0; i < ports; i++) { 8422 strfree(newiports[i]); 8423 } 8424 kmem_free(newiports, (sizeof (char *)) * ports); 8425 8426 return (rval); 8427 } 8428 8429 /* 8430 * Check if the HBA has any scsi_hba_iport_register()ed children. 8431 */ 8432 int 8433 scsi_hba_iport_exist(dev_info_t *self) 8434 { 8435 unsigned int ports = 0; 8436 char **iports; 8437 int rval; 8438 8439 rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self, 8440 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports, 8441 &ports); 8442 8443 if (rval != DDI_PROP_SUCCESS) 8444 return (0); 8445 8446 /* If there is now at least 1 iport, then iports is valid */ 8447 if (ports > 0) { 8448 rval = 1; 8449 } else 8450 rval = 0; 8451 ddi_prop_free(iports); 8452 8453 return (rval); 8454 } 8455 8456 dev_info_t * 8457 scsi_hba_iport_find(dev_info_t *self, char *portnm) 8458 { 8459 char *addr = NULL; 8460 char **iports; 8461 unsigned int num_iports = 0; 8462 int rval = DDI_FAILURE; 8463 int i = 0; 8464 dev_info_t *child = NULL; 8465 8466 /* check to see if this is an HBA that defined scsi iports */ 8467 rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self, 8468 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports, 8469 &num_iports); 8470 8471 if (rval != DDI_SUCCESS) { 8472 return (NULL); 8473 } 8474 ASSERT(num_iports > 0); 8475 8476 /* check to see if this port was registered */ 8477 for (i = 0; i < num_iports; i++) { 8478 if (strcmp(iports[i], portnm) == 0) 8479 break; 8480 } 8481 8482 if (i == num_iports) { 8483 child = NULL; 8484 goto out; 8485 } 8486 8487 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 8488 (void) snprintf(addr, SCSI_MAXNAMELEN, "iport@%s", portnm); 8489 rval = ndi_devi_config_one(self, addr, &child, NDI_NO_EVENT); 8490 kmem_free(addr, SCSI_MAXNAMELEN); 8491 8492 if (rval != DDI_SUCCESS) { 8493 child = NULL; 8494 } 8495 out: 8496 ddi_prop_free(iports); 8497 return (child); 8498 } 8499 8500 /* 8501 * Search/create the specified iport node 8502 */ 8503 static dev_info_t * 8504 scsi_hba_bus_config_port(dev_info_t *self, char *nameaddr, scsi_enum_t se) 8505 { 8506 dev_info_t *child; /* iport child of HBA node */ 8507 scsi_hba_tran_t *tran; 8508 char *addr; 8509 char *compat; 8510 8511 /* 8512 * See if the iport node already exists. 8513 */ 8514 addr = nameaddr + strlen("iport@"); 8515 if (child = ndi_devi_findchild(self, nameaddr)) { 8516 if (ndi_devi_device_isremoved(child)) { 8517 if ((se == SE_HP) || !ndi_dev_is_hotplug_node(child)) { 8518 if (ndi_devi_device_insert(child)) 8519 SCSI_HBA_LOG((_LOGCFG, self, NULL, 8520 "devinfo iport@%s device_reinsert", 8521 addr)); 8522 } else 8523 return (NULL); 8524 } 8525 return (child); 8526 } 8527 8528 8529 /* 8530 * If config based on scsi_hba_iportmap API, only allow create 8531 * from hotplug. 8532 */ 8533 tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE); 8534 ASSERT(tran); 8535 if (tran->tran_iportmap && (se != SE_HP)) 8536 return (NULL); 8537 8538 /* allocate and initialize a new "iport" node */ 8539 ndi_devi_alloc_sleep(self, "iport", 8540 (se == SE_HP) ? DEVI_SID_HP_NODEID : DEVI_SID_NODEID, 8541 &child); 8542 ASSERT(child); 8543 /* 8544 * Set the flavor of the child to be IPORT flavored 8545 */ 8546 ndi_flavor_set(child, SCSA_FLAVOR_IPORT); 8547 8548 /* 8549 * Add the SCSI_ADDR_PROP_IPORTUA addressing property for this child. 8550 * This property is used to identify a iport node, and to represent the 8551 * nodes @addr form via node properties. 8552 * 8553 * Add "compatible" property to the "scsi-iport" node to cause it bind 8554 * to the same driver as the HBA driver. Use the "driver" name 8555 * instead of the "binding name" to distinguish from hw node. 8556 * 8557 * Give the HBA a chance, via tran_set_name_prop, to set additional 8558 * iport node properties or to change the "compatible" binding 8559 * prior to init_child. 8560 * 8561 * NOTE: the order of these operations is important so that 8562 * scsi_hba_iport works when called. 8563 */ 8564 compat = (char *)ddi_driver_name(self); 8565 if ((ndi_prop_update_string(DDI_DEV_T_NONE, child, 8566 SCSI_ADDR_PROP_IPORTUA, addr) != DDI_PROP_SUCCESS) || 8567 (ndi_prop_update_string_array(DDI_DEV_T_NONE, child, 8568 "compatible", &compat, 1) != DDI_PROP_SUCCESS) || 8569 ddi_pathname_obp_set(child, NULL) != DDI_SUCCESS) { 8570 SCSI_HBA_LOG((_LOG_NF(WARN), "%s failed dynamic decoration", 8571 nameaddr)); 8572 (void) ddi_remove_child(child, 0); 8573 child = NULL; 8574 } else { 8575 /* 8576 * Online/attach in order to get events so devfsadm will 8577 * create public names. 8578 */ 8579 ndi_hold_devi(child); 8580 if (ndi_devi_online(child, 0) != NDI_SUCCESS) { 8581 ndi_rele_devi(child); 8582 ndi_prop_remove_all(child); 8583 (void) ndi_devi_free(child); 8584 child = NULL; 8585 } else 8586 ndi_rele_devi(child); 8587 } 8588 8589 return (child); 8590 } 8591 8592 #ifdef sparc 8593 /* 8594 * Future: When iportmap boot support is added, consider rewriting this to 8595 * perform a scsi_hba_bus_config(BUS_CONFIG_ALL) on self (HBA) followed by 8596 * a scsi_hba_bus_config(BUS_CONFIG_ONE) on each child of self (each iport). 8597 */ 8598 /* ARGSUSED */ 8599 static int 8600 scsi_hba_bus_config_prom_node(dev_info_t *self, uint_t flags, 8601 void *arg, dev_info_t **childp) 8602 { 8603 char **iports; 8604 int circ, i; 8605 int ret = NDI_FAILURE; 8606 unsigned int num_iports = 0; 8607 dev_info_t *pdip = NULL; 8608 char *addr = NULL; 8609 8610 /* check to see if this is an HBA that defined scsi iports */ 8611 ret = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self, 8612 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports, 8613 &num_iports); 8614 8615 if (ret != DDI_SUCCESS) { 8616 return (ret); 8617 } 8618 8619 ASSERT(num_iports > 0); 8620 8621 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 8622 8623 ret = NDI_FAILURE; 8624 8625 scsi_hba_devi_enter(self, &circ); 8626 8627 /* create iport nodes for each scsi port/bus */ 8628 for (i = 0; i < num_iports; i++) { 8629 bzero(addr, SCSI_MAXNAMELEN); 8630 /* Prepend the iport name */ 8631 (void) snprintf(addr, SCSI_MAXNAMELEN, "iport@%s", 8632 iports[i]); 8633 if (pdip = scsi_hba_bus_config_port(self, addr, SE_HP)) { 8634 if (ndi_busop_bus_config(self, NDI_NO_EVENT, 8635 BUS_CONFIG_ONE, addr, &pdip, 0) != 8636 NDI_SUCCESS) { 8637 continue; 8638 } 8639 /* 8640 * Try to configure child under iport see wehter 8641 * request node is the child of the iport node 8642 */ 8643 if (ndi_devi_config_one(pdip, arg, childp, 8644 NDI_NO_EVENT) == NDI_SUCCESS) { 8645 ret = NDI_SUCCESS; 8646 break; 8647 } 8648 } 8649 } 8650 8651 scsi_hba_devi_exit(self, circ); 8652 8653 kmem_free(addr, SCSI_MAXNAMELEN); 8654 8655 ddi_prop_free(iports); 8656 8657 return (ret); 8658 } 8659 #endif 8660 8661 /* 8662 * Perform iport port/bus bus_config. 8663 */ 8664 static int 8665 scsi_hba_bus_config_iports(dev_info_t *self, uint_t flags, 8666 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 8667 { 8668 char *nameaddr, *addr; 8669 char **iports; 8670 int circ, i; 8671 int ret = NDI_FAILURE; 8672 unsigned int num_iports = 0; 8673 8674 /* check to see if this is an HBA that defined scsi iports */ 8675 ret = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self, 8676 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports, 8677 &num_iports); 8678 8679 if (ret != DDI_SUCCESS) { 8680 return (ret); 8681 } 8682 8683 ASSERT(num_iports > 0); 8684 8685 scsi_hba_devi_enter(self, &circ); 8686 8687 switch (op) { 8688 case BUS_CONFIG_ONE: 8689 /* return if this operation is not against an iport node */ 8690 nameaddr = (char *)arg; 8691 if ((nameaddr == NULL) || 8692 (strncmp(nameaddr, "iport@", strlen("iport@")) != 0)) { 8693 ret = NDI_FAILURE; 8694 scsi_hba_devi_exit(self, circ); 8695 ddi_prop_free(iports); 8696 return (ret); 8697 } 8698 8699 /* parse the port number from "iport@%s" */ 8700 addr = nameaddr + strlen("iport@"); 8701 8702 /* check to see if this port was registered */ 8703 for (i = 0; i < num_iports; i++) { 8704 if (strcmp((iports[i]), addr) == 0) 8705 break; 8706 } 8707 8708 if (i == num_iports) { 8709 ret = NDI_FAILURE; 8710 break; 8711 } 8712 8713 /* create the iport node child */ 8714 if (scsi_hba_bus_config_port(self, nameaddr, SE_BUSCONFIG)) { 8715 ret = NDI_SUCCESS; 8716 } 8717 break; 8718 8719 case BUS_CONFIG_ALL: 8720 case BUS_CONFIG_DRIVER: 8721 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 8722 /* create iport nodes for each scsi port/bus */ 8723 for (i = 0; i < num_iports; i++) { 8724 bzero(addr, SCSI_MAXNAMELEN); 8725 /* Prepend the iport name */ 8726 (void) snprintf(addr, SCSI_MAXNAMELEN, "iport@%s", 8727 iports[i]); 8728 (void) scsi_hba_bus_config_port(self, addr, 8729 SE_BUSCONFIG); 8730 } 8731 8732 kmem_free(addr, SCSI_MAXNAMELEN); 8733 ret = NDI_SUCCESS; 8734 break; 8735 } 8736 if (ret == NDI_SUCCESS) { 8737 #ifdef sparc 8738 /* 8739 * Mask NDI_PROMNAME since PROM doesn't have iport 8740 * node at all. 8741 */ 8742 flags &= (~NDI_PROMNAME); 8743 #endif 8744 flags |= NDI_MDI_FALLBACK; /* devinfo&pathinfo children */ 8745 ret = ndi_busop_bus_config(self, flags, op, 8746 arg, childp, 0); 8747 } 8748 scsi_hba_devi_exit(self, circ); 8749 8750 ddi_prop_free(iports); 8751 8752 return (ret); 8753 } 8754 8755 typedef struct impl_scsi_iportmap { 8756 dev_info_t *iportmap_hba_dip; 8757 damap_t *iportmap_dam; 8758 } impl_scsi_iportmap_t; 8759 8760 static void 8761 scsi_iportmap_config(void *arg, damap_t *mapp, damap_id_list_t id_list) 8762 { 8763 dev_info_t *self = (dev_info_t *)arg; 8764 int circ; 8765 damap_id_t tgtid; 8766 char nameaddr[SCSI_MAXNAMELEN]; 8767 char *iport_addr; 8768 8769 scsi_hba_devi_enter(self, &circ); 8770 8771 for (tgtid = damap_id_next(mapp, id_list, NODAM); 8772 tgtid != NODAM; 8773 tgtid = damap_id_next(mapp, id_list, tgtid)) { 8774 iport_addr = damap_id2addr(mapp, tgtid); 8775 SCSI_HBA_LOG((_LOGIPT, self, NULL, 8776 "%s @%s", damap_name(mapp), iport_addr)); 8777 8778 (void) snprintf(nameaddr, sizeof (nameaddr), 8779 "iport@%s", iport_addr); 8780 (void) scsi_hba_bus_config_port(self, nameaddr, SE_HP); 8781 } 8782 8783 scsi_hba_devi_exit(self, circ); 8784 } 8785 8786 static void 8787 scsi_iportmap_unconfig(void *arg, damap_t *mapp, damap_id_list_t id_list) 8788 { 8789 dev_info_t *self = arg; 8790 dev_info_t *child; /* iport child of HBA node */ 8791 int circ; 8792 damap_id_t tgtid; 8793 char *addr; 8794 char nameaddr[SCSI_MAXNAMELEN]; 8795 scsi_hba_tran_t *tran; 8796 int empty; 8797 8798 for (tgtid = damap_id_next(mapp, id_list, NODAM); 8799 tgtid != NODAM; 8800 tgtid = damap_id_next(mapp, id_list, tgtid)) { 8801 addr = damap_id2addr(mapp, tgtid); 8802 SCSI_HBA_LOG((_LOGIPT, self, NULL, 8803 "%s @%s", damap_name(mapp), addr)); 8804 8805 (void) snprintf(nameaddr, sizeof (nameaddr), "iport@%s", addr); 8806 scsi_hba_devi_enter(self, &circ); 8807 if ((child = ndi_devi_findchild(self, nameaddr)) == NULL) { 8808 scsi_hba_devi_exit(self, circ); 8809 continue; 8810 } 8811 8812 tran = ddi_get_driver_private(child); 8813 ASSERT(tran); 8814 8815 ndi_hold_devi(child); 8816 scsi_hba_devi_exit(self, circ); 8817 8818 /* 8819 * A begin/end (clear) against the iport's 8820 * tgtmap will trigger unconfigure of all 8821 * targets on the iport. 8822 * 8823 * Future: This bit of code only works if the 8824 * target map reporting style is are full 8825 * reports and not per-address. Maybe we 8826 * should plan on handling this by 8827 * auto-unconfiguration when destroying the 8828 * target map(s). 8829 */ 8830 (void) scsi_hba_tgtmap_set_begin( 8831 tran->tran_tgtmap); 8832 (void) scsi_hba_tgtmap_set_end( 8833 tran->tran_tgtmap, 0); 8834 8835 /* wait for unconfigure */ 8836 empty = scsi_tgtmap_sync(tran->tran_tgtmap); 8837 8838 scsi_hba_devi_enter(self, &circ); 8839 ndi_rele_devi(child); 8840 8841 /* If begin/end/sync ends in empty map, offline/remove. */ 8842 if (empty) { 8843 if (ndi_devi_offline(child, 8844 NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE) == DDI_SUCCESS) { 8845 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 8846 "devinfo iport@%s offlined and removed", 8847 addr)); 8848 } else if (ndi_devi_device_remove(child)) { 8849 /* Offline/rem failed, note new device_remove */ 8850 SCSI_HBA_LOG((_LOGUNCFG, self, NULL, 8851 "devinfo iport@%s offline failed, " 8852 "device_remove", addr)); 8853 } 8854 } 8855 scsi_hba_devi_exit(self, circ); 8856 } 8857 8858 } 8859 8860 int 8861 scsi_hba_iportmap_create(dev_info_t *self, clock_t settle, int n_entries, 8862 scsi_hba_iportmap_t **handle) 8863 { 8864 scsi_hba_tran_t *tran; 8865 damap_t *mapp; 8866 char context[64]; 8867 impl_scsi_iportmap_t *iportmap; 8868 8869 if (self == NULL || settle == 0 || n_entries == 0 || handle == NULL) 8870 return (DDI_FAILURE); 8871 8872 *handle = NULL; 8873 8874 if (scsi_hba_iport_unit_address(self) != NULL) 8875 return (DDI_FAILURE); 8876 8877 tran = (scsi_hba_tran_t *)ddi_get_driver_private(self); 8878 ASSERT(tran); 8879 if (tran == NULL) 8880 return (DDI_FAILURE); 8881 8882 (void) snprintf(context, sizeof (context), "%s%d.iportmap", 8883 ddi_driver_name(self), ddi_get_instance(self)); 8884 8885 if (damap_create(context, n_entries, DAMAP_REPORT_PERADDR, settle, 8886 NULL, NULL, NULL, self, 8887 scsi_iportmap_config, scsi_iportmap_unconfig, &mapp) != 8888 DAM_SUCCESS) { 8889 return (DDI_FAILURE); 8890 } 8891 iportmap = kmem_zalloc(sizeof (*iportmap), KM_SLEEP); 8892 iportmap->iportmap_hba_dip = self; 8893 iportmap->iportmap_dam = mapp; 8894 8895 tran->tran_iportmap = (scsi_hba_iportmap_t *)iportmap; 8896 *handle = (scsi_hba_iportmap_t *)iportmap; 8897 8898 SCSI_HBA_LOG((_LOGIPT, self, NULL, "%s", damap_name(mapp))); 8899 return (DDI_SUCCESS); 8900 } 8901 8902 void 8903 scsi_hba_iportmap_destroy(scsi_hba_iportmap_t *handle) 8904 { 8905 impl_scsi_iportmap_t *iportmap = (impl_scsi_iportmap_t *)handle; 8906 dev_info_t *self = iportmap->iportmap_hba_dip; 8907 8908 SCSI_HBA_LOG((_LOGIPT, self, NULL, 8909 "%s", damap_name(iportmap->iportmap_dam))); 8910 8911 damap_destroy(iportmap->iportmap_dam); 8912 kmem_free(iportmap, sizeof (*iportmap)); 8913 } 8914 8915 int 8916 scsi_hba_iportmap_iport_add(scsi_hba_iportmap_t *handle, 8917 char *iport_addr, void *iport_priv) 8918 { 8919 impl_scsi_iportmap_t *iportmap = (impl_scsi_iportmap_t *)handle; 8920 dev_info_t *self = iportmap->iportmap_hba_dip; 8921 8922 SCSI_HBA_LOG((_LOGIPT, self, NULL, 8923 "%s @%s", damap_name(iportmap->iportmap_dam), iport_addr)); 8924 8925 return ((damap_addr_add(iportmap->iportmap_dam, iport_addr, NULL, 8926 NULL, iport_priv) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 8927 } 8928 8929 int 8930 scsi_hba_iportmap_iport_remove(scsi_hba_iportmap_t *handle, 8931 char *iport_addr) 8932 { 8933 impl_scsi_iportmap_t *iportmap = (impl_scsi_iportmap_t *)handle; 8934 dev_info_t *self = iportmap->iportmap_hba_dip; 8935 8936 SCSI_HBA_LOG((_LOGIPT, self, NULL, 8937 "%s @%s", damap_name(iportmap->iportmap_dam), iport_addr)); 8938 8939 return ((damap_addr_del(iportmap->iportmap_dam, 8940 iport_addr) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 8941 } 8942 8943 int 8944 scsi_hba_iportmap_lookup(scsi_hba_iportmap_t *handle, 8945 char *iport_addr) 8946 { 8947 impl_scsi_iportmap_t *iportmap = (impl_scsi_iportmap_t *)handle; 8948 dev_info_t *self = iportmap->iportmap_hba_dip; 8949 damap_id_t iportid; 8950 8951 iportid = damap_lookup(iportmap->iportmap_dam, iport_addr); 8952 if (iportid != NODAM) { 8953 SCSI_HBA_LOG((_LOG(3), self, NULL, 8954 "%s @%s found", 8955 damap_name(iportmap->iportmap_dam), iport_addr)); 8956 damap_id_rele(iportmap->iportmap_dam, iportid); 8957 return (DDI_SUCCESS); 8958 } 8959 8960 SCSI_HBA_LOG((_LOG(3), self, NULL, 8961 "%s @%s not found", 8962 damap_name(iportmap->iportmap_dam), iport_addr)); 8963 return (DDI_FAILURE); 8964 } 8965 8966 static void 8967 scsi_lunmap_config(void *arg, damap_t *lundam, damap_id_list_t id_list) 8968 { 8969 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)arg; 8970 scsi_hba_tran_t *tran = tgtmap->tgtmap_tran; 8971 dev_info_t *self = tran->tran_iport_dip; 8972 damap_id_t lunid; 8973 char *addr; 8974 8975 /* iterate over the LUNS we need to config */ 8976 for (lunid = damap_id_next(lundam, id_list, NODAM); 8977 lunid != NODAM; 8978 lunid = damap_id_next(lundam, id_list, lunid)) { 8979 addr = damap_id2addr(lundam, lunid); 8980 SCSI_HBA_LOG((_LOGLUN, self, NULL, 8981 "%s @%s", damap_name(lundam), addr)); 8982 8983 (void) scsi_hba_bus_configone_addr(self, addr, SE_HP); 8984 } 8985 } 8986 8987 static void 8988 scsi_lunmap_unconfig(void *arg, damap_t *lundam, damap_id_list_t id_list) 8989 { 8990 impl_scsi_tgtmap_t *tgtmap = (impl_scsi_tgtmap_t *)arg; 8991 scsi_hba_tran_t *tran = tgtmap->tgtmap_tran; 8992 dev_info_t *self = tran->tran_iport_dip; 8993 damap_id_t lunid; 8994 char *addr; 8995 8996 for (lunid = damap_id_next(lundam, id_list, NODAM); 8997 lunid != NODAM; 8998 lunid = damap_id_next(lundam, id_list, lunid)) { 8999 addr = damap_id2addr(lundam, lunid); 9000 SCSI_HBA_LOG((_LOGLUN, self, NULL, 9001 "%s @%s", damap_name(lundam), addr)); 9002 9003 scsi_hba_bus_unconfigone_addr(self, addr); 9004 } 9005 } 9006 9007 static int 9008 scsi_lunmap_create(dev_info_t *self, impl_scsi_tgtmap_t *tgtmap, char *taddr) 9009 { 9010 char context[64]; 9011 damap_t *tgtdam; 9012 damap_id_t tgtid; 9013 damap_t *lundam; 9014 9015 (void) snprintf(context, sizeof (context), "%s%d.%s.lunmap", 9016 ddi_driver_name(self), ddi_get_instance(self), taddr); 9017 9018 tgtdam = tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]; 9019 tgtid = damap_lookup(tgtdam, taddr); 9020 if (tgtid == NODAM) { 9021 SCSI_HBA_LOG((_LOG(1), self, NULL, 9022 "target %s not found", context)); 9023 return (DDI_FAILURE); 9024 } 9025 9026 lundam = damap_id_priv_get(tgtdam, tgtid); 9027 if (lundam) { 9028 SCSI_HBA_LOG((_LOG(1), self, NULL, 9029 "lunmap %s already created", context)); 9030 damap_id_rele(tgtdam, tgtid); 9031 return (DDI_FAILURE); 9032 } 9033 9034 /* NOTE: expected ref at tgtid/taddr: 2: caller + lookup. */ 9035 SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s creat, id %d ref %d", 9036 context, tgtid, damap_id_ref(tgtdam, tgtid))); 9037 9038 /* create lundam */ 9039 if (damap_create(context, LUNMAPSIZE, DAMAP_REPORT_FULLSET, 1, 9040 NULL, NULL, NULL, 9041 tgtmap, scsi_lunmap_config, scsi_lunmap_unconfig, 9042 &lundam) != DAM_SUCCESS) { 9043 SCSI_HBA_LOG((_LOG(1), self, NULL, 9044 "%s create failed, id %d ref %d", 9045 context, tgtid, damap_id_ref(tgtdam, tgtid))); 9046 damap_id_rele(tgtdam, tgtid); 9047 return (DDI_FAILURE); 9048 } 9049 9050 /* 9051 * Return with damap_id_hold at tgtid/taddr from damap_lookup to 9052 * account for damap_id_prv_set below. 9053 */ 9054 damap_id_priv_set(tgtdam, tgtid, lundam); 9055 return (DDI_SUCCESS); 9056 } 9057 9058 static void 9059 scsi_lunmap_destroy(dev_info_t *self, impl_scsi_tgtmap_t *tgtmap, char *taddr) 9060 { 9061 char context[64]; 9062 damap_t *tgtdam; 9063 damap_id_t tgtid; 9064 damap_t *lundam; 9065 9066 (void) snprintf(context, sizeof (context), "%s%d.%s.lunmap", 9067 ddi_driver_name(self), ddi_get_instance(self), taddr); 9068 9069 tgtdam = tgtmap->tgtmap_dam[SCSI_TGT_SCSI_DEVICE]; 9070 tgtid = damap_lookup(tgtdam, taddr); 9071 if (tgtid == NODAM) { 9072 SCSI_HBA_LOG((_LOG(1), self, NULL, 9073 "target %s not found", context)); 9074 return; 9075 } 9076 9077 lundam = (damap_t *)damap_id_priv_get(tgtdam, tgtid); 9078 if (lundam == NULL) { 9079 damap_id_rele(tgtdam, tgtid); /* from damap_lookup */ 9080 SCSI_HBA_LOG((_LOG(1), self, NULL, 9081 "lunmap %s already destroyed", context)); 9082 return; 9083 } 9084 9085 /* NOTE: expected ref at tgtid/taddr: 3: priv_set + caller + lookup. */ 9086 SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s, id %d ref %d", 9087 damap_name(lundam), tgtid, damap_id_ref(tgtdam, tgtid))); 9088 9089 /* 9090 * A begin/end (clear) against a target's lunmap will trigger 9091 * unconfigure of all LUNs on the target. 9092 */ 9093 scsi_lunmap_set_begin(self, lundam); 9094 scsi_lunmap_set_end(self, lundam); 9095 9096 SCSI_HBA_LOG((_LOGLUN, self, NULL, 9097 "%s sync begin", damap_name(lundam))); 9098 9099 (void) damap_sync(lundam); /* wait for unconfigure */ 9100 9101 SCSI_HBA_LOG((_LOGLUN, self, NULL, 9102 "%s sync end", damap_name(lundam))); 9103 9104 damap_id_priv_set(tgtdam, tgtid, NULL); 9105 9106 /* release hold established by damap_lookup above */ 9107 damap_id_rele(tgtdam, tgtid); 9108 9109 /* release hold established since scsi_lunmap_create() */ 9110 damap_id_rele(tgtdam, tgtid); 9111 9112 damap_destroy(lundam); 9113 } 9114 9115 static void 9116 scsi_lunmap_set_begin(dev_info_t *self, damap_t *lundam) 9117 { 9118 SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s", damap_name(lundam))); 9119 9120 (void) damap_addrset_begin(lundam); 9121 } 9122 9123 static int 9124 scsi_lunmap_set_add(dev_info_t *self, damap_t *lundam, 9125 char *taddr, scsi_lun64_t lun64, int sfunc) 9126 { 9127 char ua[SCSI_MAXNAMELEN]; 9128 9129 /* make unit address string form of "@taddr,lun[,sfunc]" */ 9130 if (sfunc == -1) 9131 (void) snprintf(ua, sizeof (ua), "%s,%" PRIx64, taddr, lun64); 9132 else 9133 (void) snprintf(ua, sizeof (ua), "%s,%" PRIx64 ",%x", 9134 taddr, lun64, sfunc); 9135 9136 SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s @%s", damap_name(lundam), ua)); 9137 9138 return ((damap_addrset_add(lundam, ua, NULL, NULL, 9139 NULL) == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 9140 } 9141 9142 static void 9143 scsi_lunmap_set_end(dev_info_t *self, damap_t *lundam) 9144 { 9145 SCSI_HBA_LOG((_LOGLUN, self, NULL, "%s", damap_name(lundam))); 9146 9147 (void) damap_addrset_end(lundam, 0); 9148 } 9149 9150 int 9151 scsi_lunmap_lookup(dev_info_t *self, damap_t *lundam, char *addr) 9152 { 9153 damap_id_t lunid; 9154 9155 if ((lunid = damap_lookup(lundam, addr)) != NODAM) { 9156 SCSI_HBA_LOG((_LOG(3), self, NULL, 9157 "%s @%s found", damap_name(lundam), addr)); 9158 damap_id_rele(lundam, lunid); 9159 return (DDI_SUCCESS); 9160 } 9161 9162 SCSI_HBA_LOG((_LOG(3), self, NULL, 9163 "%s @%s not found", damap_name(lundam), addr)); 9164 return (DDI_FAILURE); 9165 } 9166 9167 /* 9168 * phymap implementation 9169 * 9170 * We manage the timed aggregation of phys into a phy map * by creating a 9171 * SAS port construct (based upon 'name' of "local,remote" SAS addresses) 9172 * upon the first link up. As time goes on additional phys may join that port. 9173 * After an appropriate amount of settle time, we trigger the activation 9174 * callback which will then take the resultant bit mask of phys (phymask) in 9175 * the SAS port and use that to call back to the callback function 9176 * provided by the additional caller. 9177 * 9178 * We cross check to make sure that phys only exist in one SAS port at a 9179 * time by having soft state for each phy point back to the created 9180 * SAS port. 9181 * 9182 * NOTE: Make SAS_PHY_UA_LEN max(SAS_PHY_PHYMASK_LEN, SAS_PHY_NAME_LEN) 9183 * so we have enough space if sas_phymap_bitset2phymaskua phymask address 9184 * is already in use, and we end up using port name as unit address. 9185 */ 9186 #define SAS_PHY_NAME_FMT "%" PRIx64 ",%" PRIx64 9187 #define SAS_PHY_NAME_LEN (16 + 1 + 16 + 1) 9188 #define SAS_PHY_NPHY (SAS2_PHYNUM_MAX + 1) 9189 #define SAS_PHY_PHYMASK_LEN ((roundup(SAS_PHY_NPHY, 4)) / 4) 9190 #if (SAS_PHY_PHYMASK_LEN > SAS_PHY_NAME_LEN) 9191 #define SAS_PHY_UA_LEN SAS_PHY_PHYMASK_LEN 9192 #else 9193 #define SAS_PHY_UA_LEN SAS_PHY_NAME_LEN 9194 #endif 9195 typedef struct impl_sas_phymap { 9196 dev_info_t *phymap_self; 9197 9198 kmutex_t phymap_lock; 9199 damap_t *phymap_dam; 9200 void *phymap_phy2name; 9201 ddi_soft_state_bystr *phymap_name2phys; /* bitset */ 9202 ddi_soft_state_bystr *phymap_name2ua; 9203 ddi_soft_state_bystr *phymap_ua2name; 9204 9205 /* Noisy phy information - ensure forward progress for noisy phys */ 9206 int phymap_phy_max; /* max phy# */ 9207 int phymap_reports; /* per period */ 9208 int phymap_reports_max; /* scales */ 9209 int phymap_phys_noisy; /* detected */ 9210 9211 /* These are for callbacks to the consumer. */ 9212 sas_phymap_activate_cb_t phymap_acp; 9213 sas_phymap_deactivate_cb_t phymap_dcp; 9214 void *phymap_private; 9215 } impl_sas_phymap_t; 9216 9217 /* Detect noisy phy: max changes per stabilization period per phy. */ 9218 static int sas_phymap_phy_max_factor = 16; 9219 9220 /* 9221 * Convert bitset into a unit-address string. The maximum string length would 9222 * be the maximum number of phys, rounded up by 4 and divided by 4. 9223 */ 9224 static void 9225 sas_phymap_bitset2phymaskua(bitset_t *phys, char *buf) 9226 { 9227 char *ptr; 9228 int grp; 9229 int cur; 9230 uint_t bit; 9231 9232 bit = roundup(SAS_PHY_NPHY, 4); 9233 grp = 4; 9234 ptr = buf; 9235 cur = 0; 9236 do { 9237 bit -= 1; 9238 grp -= 1; 9239 if (bitset_in_set(phys, bit)) { 9240 cur |= (1 << grp); 9241 } 9242 if (grp == 0) { 9243 grp = 4; 9244 if (cur || ptr != buf) { 9245 *ptr++ = "0123456789abcdef"[cur]; 9246 *ptr = 0; 9247 } 9248 cur = 0; 9249 } 9250 } while (bit != 0); 9251 if (ptr == buf) { 9252 *ptr++ = '0'; 9253 *ptr = 0; 9254 } 9255 } 9256 9257 static void 9258 sas_phymap_config(void *arg, damap_t *phydam, damap_id_list_t dl) 9259 { 9260 impl_sas_phymap_t *phymap = (impl_sas_phymap_t *)arg; 9261 char *context = damap_name(phymap->phymap_dam); 9262 int pairs; 9263 damap_id_t phyid; 9264 char *damn; 9265 char *name; 9266 bitset_t *phys; 9267 char *ua; 9268 void *ua_priv; 9269 9270 ASSERT(context); 9271 9272 mutex_enter(&phymap->phymap_lock); 9273 phymap->phymap_reports = phymap->phymap_phys_noisy = 0; 9274 9275 /* count the number of local,remove pairs we need to config */ 9276 for (pairs = 0, phyid = damap_id_next(phydam, dl, NODAM); 9277 phyid != NODAM; 9278 phyid = damap_id_next(phydam, dl, phyid)) 9279 pairs++; 9280 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, 9281 "%s: config %d local,remote pairs", context, pairs)); 9282 9283 for (phyid = damap_id_next(phydam, dl, NODAM); 9284 phyid != NODAM; 9285 phyid = damap_id_next(phydam, dl, phyid)) { 9286 /* Get the name ("local,remote" address string) from damap. */ 9287 damn = damap_id2addr(phydam, phyid); 9288 9289 /* Get the bitset of phys currently forming the port. */ 9290 phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, damn); 9291 if (phys == NULL) { 9292 SCSI_HBA_LOG((_LOG_NF(WARN), 9293 "%s: %s: no phys", context, damn)); 9294 continue; 9295 } 9296 9297 /* allocate, get, and initialize name index of name2ua map */ 9298 if (ddi_soft_state_bystr_zalloc( 9299 phymap->phymap_name2ua, damn) != DDI_SUCCESS) { 9300 SCSI_HBA_LOG((_LOG_NF(WARN), 9301 "%s: %s: failed name2ua alloc", context, damn)); 9302 continue; 9303 } 9304 ua = ddi_soft_state_bystr_get(phymap->phymap_name2ua, damn); 9305 if (ua == NULL) { 9306 SCSI_HBA_LOG((_LOG_NF(WARN), 9307 "%s: %s: no name2ua", context, damn)); 9308 continue; 9309 } 9310 sas_phymap_bitset2phymaskua(phys, ua); /* set ua */ 9311 9312 /* see if phymask ua index already allocated in ua2name map */ 9313 name = ddi_soft_state_bystr_get(phymap->phymap_ua2name, ua); 9314 if (name) { 9315 /* 9316 * The 'phymask' sas_phymap_bitset2phymaskua ua is 9317 * already in use. This means that original phys have 9318 * formed into a new port, and that the original port 9319 * still exists (it has migrated to some completely 9320 * different set of phys). In this corner-case we use 9321 * "local,remote" name as a 'temporary' unit address. 9322 * Reset ua in name2ua map. 9323 */ 9324 (void) strlcpy(ua, damn, SAS_PHY_NAME_LEN); 9325 9326 name = ddi_soft_state_bystr_get( 9327 phymap->phymap_ua2name, ua); 9328 if (name) { 9329 /* The "local,remote" ua should be new... */ 9330 SCSI_HBA_LOG((_LOG_NF(WARN), 9331 "%s: %s ua already configured", 9332 context, ua)); 9333 continue; 9334 } 9335 } 9336 9337 /* allocate, get, and init ua index of ua2name map */ 9338 if (ddi_soft_state_bystr_zalloc( 9339 phymap->phymap_ua2name, ua) != DDI_SUCCESS) { 9340 ddi_soft_state_bystr_free( 9341 phymap->phymap_name2ua, damn); 9342 SCSI_HBA_LOG((_LOG_NF(WARN), 9343 "%s: %s: failed ua2name alloc", 9344 context, damn)); 9345 continue; 9346 } 9347 name = ddi_soft_state_bystr_get( 9348 phymap->phymap_ua2name, ua); 9349 if (name == NULL) { 9350 ddi_soft_state_bystr_free( 9351 phymap->phymap_name2ua, damn); 9352 SCSI_HBA_LOG((_LOG_NF(WARN), 9353 "%s: %s: no ua2name", context, ua)); 9354 continue; 9355 } 9356 9357 /* set name in ua2name map */ 9358 (void) strlcpy(name, damn, SAS_PHY_NAME_LEN); 9359 9360 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, 9361 "%s: %s: ua %s: activate", context, damn, ua)); 9362 if (phymap->phymap_acp) { 9363 mutex_exit(&phymap->phymap_lock); 9364 ua_priv = NULL; 9365 (phymap->phymap_acp)(phymap->phymap_private, 9366 ua, &ua_priv); 9367 mutex_enter(&phymap->phymap_lock); 9368 9369 damap_id_priv_set(phydam, phyid, ua_priv); 9370 } 9371 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, 9372 "%s: %s: ua %s: activate complete", context, damn, ua)); 9373 } 9374 9375 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, 9376 "%s: config complete", context)); 9377 mutex_exit(&phymap->phymap_lock); 9378 } 9379 9380 /*ARGSUSED*/ 9381 static void 9382 sas_phymap_unconfig(void *arg, damap_t *phydam, damap_id_list_t dl) 9383 { 9384 impl_sas_phymap_t *phymap = (impl_sas_phymap_t *)arg; 9385 char *context = damap_name(phymap->phymap_dam); 9386 int pairs; 9387 damap_id_t phyid; 9388 char *damn; 9389 char *ua; 9390 void *ua_priv; 9391 9392 ASSERT(context); 9393 9394 mutex_enter(&phymap->phymap_lock); 9395 phymap->phymap_reports = phymap->phymap_phys_noisy = 0; 9396 9397 /* count the number of local,remove pairs we need to unconfig */ 9398 for (pairs = 0, phyid = damap_id_next(phydam, dl, NODAM); 9399 phyid != NODAM; 9400 phyid = damap_id_next(phydam, dl, phyid)) 9401 pairs++; 9402 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, 9403 "%s: unconfig %d local,remote pairs", context, pairs)); 9404 9405 for (phyid = damap_id_next(phydam, dl, NODAM); 9406 phyid != NODAM; 9407 phyid = damap_id_next(phydam, dl, phyid)) { 9408 /* Get the name ("local,remote" address string) from damap. */ 9409 damn = damap_id2addr(phydam, phyid); 9410 9411 ua = ddi_soft_state_bystr_get(phymap->phymap_name2ua, damn); 9412 if (ua == NULL) { 9413 SCSI_HBA_LOG((_LOG_NF(WARN), 9414 "%s: %s: no name2ua", context, damn)); 9415 continue; 9416 } 9417 9418 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, 9419 "%s: %s: ua %s: deactivate", context, damn, ua)); 9420 if (phymap->phymap_dcp) { 9421 ua_priv = damap_id_priv_get(phydam, phyid); 9422 mutex_exit(&phymap->phymap_lock); 9423 (phymap->phymap_dcp)(phymap->phymap_private, 9424 ua, ua_priv); 9425 mutex_enter(&phymap->phymap_lock); 9426 } 9427 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, 9428 "%s: %s: ua %s: deactivate complete", context, damn, ua)); 9429 9430 /* delete ua<->name mappings */ 9431 ddi_soft_state_bystr_free(phymap->phymap_ua2name, ua); 9432 ddi_soft_state_bystr_free(phymap->phymap_name2ua, damn); 9433 } 9434 9435 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, 9436 "%s: unconfig complete", context)); 9437 mutex_exit(&phymap->phymap_lock); 9438 } 9439 9440 int 9441 sas_phymap_create(dev_info_t *self, clock_t settle, 9442 sas_phymap_mode_t mode, void *mode_argument, void *phymap_priv, 9443 sas_phymap_activate_cb_t activate_cb, 9444 sas_phymap_deactivate_cb_t deactivate_cb, 9445 sas_phymap_t **handlep) 9446 { 9447 _NOTE(ARGUNUSED(mode_argument)); 9448 char context[64]; 9449 impl_sas_phymap_t *phymap; 9450 9451 if (self == NULL || settle == 0 || handlep == NULL) 9452 return (DDI_FAILURE); 9453 9454 if (mode != PHYMAP_MODE_SIMPLE) 9455 return (DDI_FAILURE); 9456 9457 phymap = kmem_zalloc(sizeof (*phymap), KM_SLEEP); 9458 phymap->phymap_self = self; 9459 phymap->phymap_reports_max = 1 * sas_phymap_phy_max_factor; 9460 phymap->phymap_acp = activate_cb; 9461 phymap->phymap_dcp = deactivate_cb; 9462 phymap->phymap_private = phymap_priv; 9463 mutex_init(&phymap->phymap_lock, NULL, MUTEX_DRIVER, NULL); 9464 9465 (void) snprintf(context, sizeof (context), "%s%d.phymap", 9466 ddi_driver_name(self), ddi_get_instance(self)); 9467 SCSI_HBA_LOG((_LOGPHY, self, NULL, "%s", context)); 9468 9469 if (damap_create(context, SAS_PHY_NPHY, DAMAP_REPORT_PERADDR, settle, 9470 NULL, NULL, NULL, 9471 phymap, sas_phymap_config, sas_phymap_unconfig, 9472 &phymap->phymap_dam) != DAM_SUCCESS) 9473 goto fail; 9474 9475 if (ddi_soft_state_init(&phymap->phymap_phy2name, 9476 SAS_PHY_NAME_LEN, SAS_PHY_NPHY) != 0) 9477 goto fail; 9478 9479 if (ddi_soft_state_bystr_init(&phymap->phymap_name2phys, 9480 sizeof (bitset_t), SAS_PHY_NPHY) != 0) 9481 goto fail; 9482 9483 if (ddi_soft_state_bystr_init(&phymap->phymap_name2ua, 9484 SAS_PHY_UA_LEN, SAS_PHY_NPHY) != 0) 9485 goto fail; 9486 if (ddi_soft_state_bystr_init(&phymap->phymap_ua2name, 9487 SAS_PHY_NAME_LEN, SAS_PHY_NPHY) != 0) 9488 goto fail; 9489 9490 *handlep = (sas_phymap_t *)phymap; 9491 return (DDI_SUCCESS); 9492 9493 fail: sas_phymap_destroy((sas_phymap_t *)phymap); 9494 *handlep = NULL; 9495 return (DDI_FAILURE); 9496 } 9497 9498 void 9499 sas_phymap_destroy(sas_phymap_t *handle) 9500 { 9501 impl_sas_phymap_t *phymap = (impl_sas_phymap_t *)handle; 9502 char *context; 9503 9504 context = phymap->phymap_dam ? 9505 damap_name(phymap->phymap_dam) : "unknown"; 9506 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, "%s", context)); 9507 9508 if (phymap->phymap_ua2name) 9509 ddi_soft_state_bystr_fini(&phymap->phymap_ua2name); 9510 if (phymap->phymap_name2ua) 9511 ddi_soft_state_bystr_fini(&phymap->phymap_name2ua); 9512 9513 if (phymap->phymap_name2phys) 9514 ddi_soft_state_bystr_fini(&phymap->phymap_name2phys); 9515 9516 if (phymap->phymap_phy2name) 9517 ddi_soft_state_fini(&phymap->phymap_phy2name); 9518 9519 if (phymap->phymap_dam) 9520 damap_destroy(phymap->phymap_dam); 9521 mutex_destroy(&phymap->phymap_lock); 9522 kmem_free(phymap, sizeof (*phymap)); 9523 } 9524 9525 9526 int 9527 sas_phymap_phy_add(sas_phymap_t *handle, 9528 int phy, uint64_t local, uint64_t remote) 9529 { 9530 impl_sas_phymap_t *phymap = (impl_sas_phymap_t *)handle; 9531 char *context = damap_name(phymap->phymap_dam); 9532 char port[SAS_PHY_NAME_LEN]; 9533 char *name; 9534 bitset_t *phys; 9535 int phy2name_allocated = 0; 9536 int name2phys_allocated = 0; 9537 int rv; 9538 9539 /* Create the SAS port name from the local and remote addresses. */ 9540 (void) snprintf(port, SAS_PHY_NAME_LEN, SAS_PHY_NAME_FMT, 9541 local, remote); 9542 9543 mutex_enter(&phymap->phymap_lock); 9544 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, "%s: %s: add phy %d", 9545 context, port, phy)); 9546 9547 /* Check for conflict in phy2name map */ 9548 name = ddi_get_soft_state(phymap->phymap_phy2name, phy); 9549 if (name) { 9550 if (strcmp(name, port) != 0) 9551 SCSI_HBA_LOG((_LOG_NF(WARN), "%s: %s: add phy %d: " 9552 "already in %s", context, port, phy, name)); 9553 else 9554 SCSI_HBA_LOG((_LOG_NF(WARN), "%s: %s: add phy %d: " 9555 "duplicate add", context, port, phy)); 9556 mutex_exit(&phymap->phymap_lock); 9557 return (DDI_FAILURE); 9558 } 9559 9560 /* allocate, get, and initialize phy index of phy2name map */ 9561 if (ddi_soft_state_zalloc( 9562 phymap->phymap_phy2name, phy) != DDI_SUCCESS) { 9563 SCSI_HBA_LOG((_LOG_NF(WARN), 9564 "%s: %s: failed phy2name alloc", context, port)); 9565 goto fail; 9566 } 9567 name = ddi_get_soft_state(phymap->phymap_phy2name, phy); 9568 if (name == NULL) { 9569 SCSI_HBA_LOG((_LOG_NF(WARN), 9570 "%s: %s: no phy2name", context, port)); 9571 goto fail; 9572 } 9573 phy2name_allocated = 1; 9574 (void) strlcpy(name, port, SAS_PHY_NAME_LEN); /* set name */ 9575 9576 /* Find/alloc, initialize name index of name2phys map */ 9577 phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, name); 9578 if (phys == NULL) { 9579 if (ddi_soft_state_bystr_zalloc(phymap->phymap_name2phys, 9580 name) != DDI_SUCCESS) { 9581 SCSI_HBA_LOG((_LOG_NF(WARN), 9582 "%s: %s: failed name2phys alloc", context, name)); 9583 goto fail; 9584 } 9585 phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, name); 9586 if (phys == NULL) { 9587 SCSI_HBA_LOG((_LOG_NF(WARN), 9588 "%s: %s: no name2phys", context, name)); 9589 goto fail; 9590 } 9591 name2phys_allocated = 1; 9592 9593 /* Initialize bitset of phys */ 9594 bitset_init(phys); 9595 bitset_resize(phys, SAS_PHY_NPHY); 9596 9597 /* NOTE: no bitset_fini of phys needed */ 9598 } 9599 ASSERT(phys); 9600 9601 /* Reflect 'add' in phys bitset. */ 9602 if (bitset_atomic_test_and_add(phys, phy) < 0) { 9603 /* It is an error if the phy was already recorded. */ 9604 SCSI_HBA_LOG((_LOG_NF(WARN), 9605 "%s: %s: phy bit %d already in port", context, name, phy)); 9606 goto fail; 9607 } 9608 9609 /* 9610 * Check to see if we have a new phy_max for this map, and if so 9611 * scale phymap_reports_max to the new number of phys. 9612 */ 9613 if (phy > phymap->phymap_phy_max) { 9614 phymap->phymap_phy_max = phy + 1; 9615 phymap->phymap_reports_max = phymap->phymap_phy_max * 9616 sas_phymap_phy_max_factor; 9617 } 9618 9619 /* 9620 * If we have not reached phymap_reports_max, start/restart the 9621 * activate timer. Otherwise, if phymap->phymap_reports add/rem reports 9622 * ever exceeds phymap_reports_max due to noisy phys, then report the 9623 * noise and force stabilization by stopping reports into the damap. 9624 * 9625 * The first config/unconfig callout out of the damap will reset 9626 * phymap->phymap_reports. 9627 */ 9628 rv = DDI_SUCCESS; 9629 if (phymap->phymap_reports++ < phymap->phymap_reports_max) { 9630 if (damap_addr_add(phymap->phymap_dam, name, 9631 NULL, NULL, NULL) == DAM_SUCCESS) { 9632 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, 9633 "%s: %s: damap_addr_add", context, name)); 9634 } else { 9635 SCSI_HBA_LOG((_LOG_NF(WARN), 9636 "%s: %s: damap_addr_add failed", context, name)); 9637 rv = DDI_FAILURE; 9638 } 9639 } else { 9640 phymap->phymap_phys_noisy++; 9641 if (phymap->phymap_phys_noisy == 1) 9642 SCSI_HBA_LOG((_LOG_NF(WARN), 9643 "%s: %s: noisy phys", context, name)); 9644 } 9645 mutex_exit(&phymap->phymap_lock); 9646 return (rv); 9647 9648 fail: if (phy2name_allocated) 9649 ddi_soft_state_free(phymap->phymap_phy2name, phy); 9650 if (name2phys_allocated) 9651 ddi_soft_state_bystr_free(phymap->phymap_name2phys, name); 9652 mutex_exit(&phymap->phymap_lock); 9653 return (DDI_FAILURE); 9654 } 9655 9656 int 9657 sas_phymap_phy_rem(sas_phymap_t *handle, int phy) 9658 { 9659 impl_sas_phymap_t *phymap = (impl_sas_phymap_t *)handle; 9660 char *context = damap_name(phymap->phymap_dam); 9661 char *name; 9662 bitset_t *phys; 9663 int rv = DDI_FAILURE; 9664 9665 ASSERT(context); 9666 9667 mutex_enter(&phymap->phymap_lock); 9668 phymap->phymap_reports++; 9669 9670 /* Find and free phy index of phy2name map */ 9671 name = ddi_get_soft_state(phymap->phymap_phy2name, phy); 9672 if (name == NULL) { 9673 SCSI_HBA_LOG((_LOG_NF(WARN), "%s: rem phy %d: never added", 9674 context, phy)); 9675 goto fail; 9676 } 9677 /* NOTE: always free phy index of phy2name map before return... */ 9678 9679 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, "%s: %s: rem phy %d", 9680 context, name, phy)); 9681 9682 /* Get bitset of phys currently associated with named port. */ 9683 phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, name); 9684 if (phys == NULL) { 9685 SCSI_HBA_LOG((_LOG_NF(WARN), "%s: %s: name2phys failed", 9686 context, name)); 9687 goto fail; 9688 } 9689 9690 /* Reflect 'rem' in phys bitset. */ 9691 if (bitset_atomic_test_and_del(phys, phy) < 0) { 9692 /* It is an error if the phy wasn't one of the port's phys. */ 9693 SCSI_HBA_LOG((_LOG_NF(WARN), 9694 "%s: %s: phy bit %d not in port", context, name, phy)); 9695 goto fail; 9696 } 9697 9698 /* If this was the last phy in the port, start the deactivate timer. */ 9699 if (bitset_is_null(phys) && 9700 (phymap->phymap_reports++ < phymap->phymap_reports_max)) { 9701 if (damap_addr_del(phymap->phymap_dam, name) == DAM_SUCCESS) { 9702 SCSI_HBA_LOG((_LOGPHY, phymap->phymap_self, NULL, 9703 "%s: %s: damap_addr_del", context, name)); 9704 } else { 9705 SCSI_HBA_LOG((_LOG_NF(WARN), 9706 "%s: %s: damap_addr_del failure", context, name)); 9707 goto fail; 9708 } 9709 } 9710 rv = DDI_SUCCESS; 9711 9712 /* free phy index of phy2name map */ 9713 fail: if (name) 9714 ddi_soft_state_free(phymap->phymap_phy2name, phy); /* free */ 9715 mutex_exit(&phymap->phymap_lock); 9716 return (rv); 9717 } 9718 9719 char * 9720 sas_phymap_lookup_ua(sas_phymap_t *handle, uint64_t local, uint64_t remote) 9721 { 9722 impl_sas_phymap_t *phymap = (impl_sas_phymap_t *)handle; 9723 char *context = damap_name(phymap->phymap_dam); 9724 char name[SAS_PHY_NAME_LEN]; 9725 char *ua; 9726 9727 ASSERT(context); 9728 9729 (void) snprintf(name, SAS_PHY_NAME_LEN, SAS_PHY_NAME_FMT, 9730 local, remote); 9731 9732 mutex_enter(&phymap->phymap_lock); 9733 ua = ddi_soft_state_bystr_get(phymap->phymap_name2ua, name); 9734 SCSI_HBA_LOG((_LOG(3), phymap->phymap_self, NULL, 9735 "%s: %s: ua %s", context, name, ua ? ua : "NULL")); 9736 mutex_exit(&phymap->phymap_lock); 9737 return (ua); 9738 } 9739 9740 void * 9741 sas_phymap_lookup_uapriv(sas_phymap_t *handle, char *ua) 9742 { 9743 impl_sas_phymap_t *phymap = (impl_sas_phymap_t *)handle; 9744 char *context = damap_name(phymap->phymap_dam); 9745 char *name; 9746 damap_id_t phyid; 9747 void *ua_priv = NULL; 9748 9749 ASSERT(context); 9750 9751 mutex_enter(&phymap->phymap_lock); 9752 name = ddi_soft_state_bystr_get(phymap->phymap_ua2name, ua); 9753 if (name) { 9754 phyid = damap_lookup(phymap->phymap_dam, name); 9755 if (phyid != NODAM) { 9756 ua_priv = damap_id_priv_get(phymap->phymap_dam, phyid); 9757 damap_id_rele(phymap->phymap_dam, phyid); 9758 } 9759 } 9760 9761 SCSI_HBA_LOG((_LOG(3), phymap->phymap_self, NULL, 9762 "%s: %s: ua %s ua_priv %p", context, name, 9763 ua ? ua : "NULL", ua_priv)); 9764 mutex_exit(&phymap->phymap_lock); 9765 return (ua_priv); 9766 } 9767 9768 int 9769 sas_phymap_uahasphys(sas_phymap_t *handle, char *ua) 9770 { 9771 impl_sas_phymap_t *phymap = (impl_sas_phymap_t *)handle; 9772 char *name; 9773 bitset_t *phys; 9774 int n = 0; 9775 9776 mutex_enter(&phymap->phymap_lock); 9777 name = ddi_soft_state_bystr_get(phymap->phymap_ua2name, ua); 9778 if (name) { 9779 phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, name); 9780 if (phys) 9781 n = bitset_is_null(phys) ? 0 : 1; 9782 } 9783 mutex_exit(&phymap->phymap_lock); 9784 return (n); 9785 } 9786 9787 sas_phymap_phys_t * 9788 sas_phymap_ua2phys(sas_phymap_t *handle, char *ua) 9789 { 9790 impl_sas_phymap_t *phymap = (impl_sas_phymap_t *)handle; 9791 char *name; 9792 bitset_t *phys; 9793 bitset_t *cphys = NULL; 9794 9795 mutex_enter(&phymap->phymap_lock); 9796 name = ddi_soft_state_bystr_get(phymap->phymap_ua2name, ua); 9797 if (name == NULL) 9798 goto fail; 9799 9800 phys = ddi_soft_state_bystr_get(phymap->phymap_name2phys, name); 9801 if (phys == NULL) 9802 goto fail; 9803 9804 /* dup the phys and return */ 9805 cphys = kmem_alloc(sizeof (*cphys), KM_SLEEP); 9806 bitset_init(cphys); 9807 bitset_resize(cphys, SAS_PHY_NPHY); 9808 bitset_copy(phys, cphys); 9809 9810 fail: mutex_exit(&phymap->phymap_lock); 9811 return ((sas_phymap_phys_t *)cphys); 9812 } 9813 9814 int 9815 sas_phymap_phys_next(sas_phymap_phys_t *phys) 9816 { 9817 bitset_t *cphys = (bitset_t *)phys; 9818 int phy; 9819 9820 phy = bitset_find(cphys); 9821 if (phy != -1) 9822 bitset_del(cphys, phy); 9823 return (phy); 9824 } 9825 9826 void 9827 sas_phymap_phys_free(sas_phymap_phys_t *phys) 9828 { 9829 bitset_t *cphys = (bitset_t *)phys; 9830 9831 if (cphys) { 9832 bitset_fini(cphys); 9833 kmem_free(cphys, sizeof (*cphys)); 9834 } 9835 } 9836 9837 char * 9838 sas_phymap_phy2ua(sas_phymap_t *handle, int phy) 9839 { 9840 impl_sas_phymap_t *phymap = (impl_sas_phymap_t *)handle; 9841 char *name; 9842 char *ua; 9843 char *rua = NULL; 9844 9845 mutex_enter(&phymap->phymap_lock); 9846 name = ddi_get_soft_state(phymap->phymap_phy2name, phy); 9847 if (name == NULL) 9848 goto fail; 9849 ua = ddi_soft_state_bystr_get(phymap->phymap_name2ua, name); 9850 if (ua == NULL) 9851 goto fail; 9852 9853 /* dup the ua and return */ 9854 rua = strdup(ua); 9855 9856 fail: mutex_exit(&phymap->phymap_lock); 9857 return (rua); 9858 } 9859 9860 void 9861 sas_phymap_ua_free(char *ua) 9862 { 9863 if (ua) 9864 strfree(ua); 9865 } 9866