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