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