scsi_hba.c revision 9907:98086c85a8f7
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#include <sys/note.h>
27
28/*
29 * Generic SCSI Host Bus Adapter interface implementation
30 */
31#include <sys/scsi/scsi.h>
32#include <sys/file.h>
33#include <sys/ddi_impldefs.h>
34#include <sys/ndi_impldefs.h>
35#include <sys/ddi.h>
36#include <sys/sunmdi.h>
37#include <sys/epm.h>
38
39extern struct scsi_pkt *scsi_init_cache_pkt(struct scsi_address *,
40		    struct scsi_pkt *, struct buf *, int, int, int, int,
41		    int (*)(caddr_t), caddr_t);
42extern void scsi_free_cache_pkt(struct scsi_address *, struct scsi_pkt *);
43extern void scsi_cache_dmafree(struct scsi_address *, struct scsi_pkt *);
44extern void scsi_sync_cache_pkt(struct scsi_address *, struct scsi_pkt *);
45
46/*
47 * Round up all allocations so that we can guarantee
48 * long-long alignment.  This is the same alignment
49 * provided by kmem_alloc().
50 */
51#define	ROUNDUP(x)	(((x) + 0x07) & ~0x07)
52
53/* Magic number to track correct allocations in wrappers */
54#define	PKT_WRAPPER_MAGIC	0xa110ced	/* alloced correctly */
55
56kmutex_t	scsi_flag_nointr_mutex;
57kcondvar_t	scsi_flag_nointr_cv;
58kmutex_t	scsi_log_mutex;
59
60/*
61 * Prototypes for static functions
62 */
63static int	scsi_hba_bus_ctl(
64			dev_info_t		*self,
65			dev_info_t		*child,
66			ddi_ctl_enum_t		op,
67			void			*arg,
68			void			*result);
69
70static int	scsi_hba_map_fault(
71			dev_info_t		*self,
72			dev_info_t		*child,
73			struct hat		*hat,
74			struct seg		*seg,
75			caddr_t			addr,
76			struct devpage		*dp,
77			pfn_t			pfn,
78			uint_t			prot,
79			uint_t			lock);
80
81static int	scsi_hba_get_eventcookie(
82			dev_info_t		*self,
83			dev_info_t		*child,
84			char			*name,
85			ddi_eventcookie_t	*eventp);
86
87static int	scsi_hba_add_eventcall(
88			dev_info_t		*self,
89			dev_info_t		*child,
90			ddi_eventcookie_t	event,
91			void			(*callback)(
92				dev_info_t		*dip,
93				ddi_eventcookie_t	event,
94				void			*arg,
95				void			*bus_impldata),
96			void			*arg,
97			ddi_callback_id_t	*cb_id);
98
99static int	scsi_hba_remove_eventcall(
100			dev_info_t		*self,
101			ddi_callback_id_t	id);
102
103static int	scsi_hba_post_event(
104			dev_info_t		*self,
105			dev_info_t		*child,
106			ddi_eventcookie_t	event,
107			void			*bus_impldata);
108
109static int	scsi_hba_info(
110			dev_info_t		*self,
111			ddi_info_cmd_t		infocmd,
112			void			*arg,
113			void			**result);
114
115static int	scsi_hba_bus_config(
116			dev_info_t		*self,
117			uint_t			flags,
118			ddi_bus_config_op_t	op,
119			void			*arg,
120			dev_info_t		**childp);
121
122static int	scsi_hba_bus_unconfig(
123			dev_info_t		*self,
124			uint_t			flags,
125			ddi_bus_config_op_t	op,
126			void			*arg);
127
128static int	scsi_hba_fm_init_child(
129			dev_info_t		*self,
130			dev_info_t		*child,
131			int			cap,
132			ddi_iblock_cookie_t	*ibc);
133
134static int	scsi_hba_bus_power(
135			dev_info_t		*self,
136			void			*impl_arg,
137			pm_bus_power_op_t	op,
138			void			*arg,
139			void			*result);
140
141/* busops vector for SCSI HBA's. */
142static struct bus_ops scsi_hba_busops = {
143	BUSO_REV,
144	nullbusmap,			/* bus_map */
145	NULL,				/* bus_get_intrspec */
146	NULL,				/* bus_add_intrspec */
147	NULL,				/* bus_remove_intrspec */
148	scsi_hba_map_fault,		/* bus_map_fault */
149	ddi_dma_map,			/* bus_dma_map */
150	ddi_dma_allochdl,		/* bus_dma_allochdl */
151	ddi_dma_freehdl,		/* bus_dma_freehdl */
152	ddi_dma_bindhdl,		/* bus_dma_bindhdl */
153	ddi_dma_unbindhdl,		/* bus_unbindhdl */
154	ddi_dma_flush,			/* bus_dma_flush */
155	ddi_dma_win,			/* bus_dma_win */
156	ddi_dma_mctl,			/* bus_dma_ctl */
157	scsi_hba_bus_ctl,		/* bus_ctl */
158	ddi_bus_prop_op,		/* bus_prop_op */
159	scsi_hba_get_eventcookie,	/* bus_get_eventcookie */
160	scsi_hba_add_eventcall,		/* bus_add_eventcall */
161	scsi_hba_remove_eventcall,	/* bus_remove_eventcall */
162	scsi_hba_post_event,		/* bus_post_event */
163	NULL,				/* bus_intr_ctl */
164	scsi_hba_bus_config,		/* bus_config */
165	scsi_hba_bus_unconfig,		/* bus_unconfig */
166	scsi_hba_fm_init_child,		/* bus_fm_init */
167	NULL,				/* bus_fm_fini */
168	NULL,				/* bus_fm_access_enter */
169	NULL,				/* bus_fm_access_exit */
170	scsi_hba_bus_power		/* bus_power */
171};
172
173/* cb_ops for hotplug :devctl and :scsi support */
174static struct cb_ops scsi_hba_cbops = {
175	scsi_hba_open,
176	scsi_hba_close,
177	nodev,			/* strategy */
178	nodev,			/* print */
179	nodev,			/* dump */
180	nodev,			/* read */
181	nodev,			/* write */
182	scsi_hba_ioctl,		/* ioctl */
183	nodev,			/* devmap */
184	nodev,			/* mmap */
185	nodev,			/* segmap */
186	nochpoll,		/* poll */
187	ddi_prop_op,		/* prop_op */
188	NULL,			/* stream */
189	D_NEW|D_MP|D_HOTPLUG,	/* cb_flag */
190	CB_REV,			/* rev */
191	nodev,			/* int (*cb_aread)() */
192	nodev			/* int (*cb_awrite)() */
193};
194
195/*
196 * SCSI_HBA_LOG is used for all messages. A logging level is specified when
197 * generating a message. Some levels correspond directly to cmn_err levels,
198 * the others are associated with increasing levels diagnostic/debug output.
199 * For _LOG() messages, a __func__ prefix will identify the function origin
200 * of the message. For _LOG_NF messages, there is no function prefix or
201 * self/child context. Filtering of messages is provided based on logging
202 * level, but messages with cmn_err logging level and messages generated
203 * generated with _LOG_NF() are never filtered.
204 *
205 * For debugging, more complete information can be displayed with each message
206 * (full device path and pointer values) by adjusting scsi_hba_log_info.
207 */
208/* logging levels */
209#define	SCSI_HBA_LOGCONT	CE_CONT
210#define	SCSI_HBA_LOGNOTE	CE_NOTE
211#define	SCSI_HBA_LOGWARN	CE_WARN
212#define	SCSI_HBA_LOGPANIC	CE_PANIC
213#define	SCSI_HBA_LOGIGNORE	CE_IGNORE
214#define	SCSI_HBA_LOG_CE_MASK	0x0000000F	/* no filter for these levels */
215#define	SCSI_HBA_LOG1		0x00000010	/* DIAG1 level enable */
216#define	SCSI_HBA_LOG2		0x00000020	/* DIAG2 level enable */
217#define	SCSI_HBA_LOG3		0x00000040	/* DIAG3 level enable */
218#define	SCSI_HBA_LOG4		0x00000080	/* DIAG4 level enable */
219#define	SCSI_HBA_LOGTRACE	0x00000100	/* TRACE enable */
220#if (CE_CONT | CE_NOTE | CE_WARN | CE_PANIC | CE_IGNORE) > SCSI_HBA_LOG_CE_MASK
221Error, problem with CE_ definitions
222#endif
223
224/*
225 * Tunable log message augmentation and filters: filters do not apply to
226 * SCSI_HBA_LOG_CE_MASK level messages or LOG_NF() messages.
227 *
228 * An example set of /etc/system tunings to simplify debug a SCSA pHCI HBA
229 * driver called "pmcs", including "scsi_vhci" operation, might be:
230 *
231 * echo "set scsi:scsi_hba_log_filter_level=0xf0"		>> /etc/system
232 * echo "set scsi:scsi_hba_log_filter_phci=\"pmcs\""		>> /etc/system
233 * echo "set scsi:scsi_hba_log_filter_vhci=\"scsi_vhci\""	>> /etc/system
234 * echo "set scsi:scsi_hba_log_align=1"				>> /etc/system
235 * echo "set scsi:scsi_hba_log_fcif=0x21"			>> /etc/system
236 * echo "set scsi:scsi_hba_log_mt_disable=0x6"			>> /etc/system
237 * echo "set mtc_off=1"						>> /etc/system
238 * echo "set mdi_mtc_off=1"					>> /etc/system
239 */
240int		scsi_hba_log_filter_level =
241			SCSI_HBA_LOG1 |
242			0;
243char		*scsi_hba_log_filter_phci = "\0\0\0\0\0\0\0\0\0\0\0\0";
244char		*scsi_hba_log_filter_vhci = "\0\0\0\0\0\0\0\0\0\0\0\0";
245int		scsi_hba_log_align = 0;	/* NOTE: will not cause truncation */
246int		scsi_hba_log_fcif = '\0';	/* "^!?" first char in format */
247						/* ^==0x5e, !==0x21, ?==0x3F */
248						/* See cmn_err(9F) */
249int		scsi_hba_log_info =	/* augmentation: extra info output */
250			(0 << 0) |	/* 0x0001: process information */
251			(0 << 1) |	/* 0x0002: full /devices path */
252			(0 << 2);	/* 0x0004: devinfo pointer */
253
254int		scsi_hba_log_mt_disable =
255			/* SCSI_ENUMERATION_MT_LUN_DISABLE |	(ie 0x02) */
256			/* SCSI_ENUMERATION_MT_TARGET_DISABLE |	(ie 0x04) */
257			0;
258
259/* static data for HBA logging subsystem */
260static kmutex_t	scsi_hba_log_mutex;
261static char	scsi_hba_log_i[512];
262static char	scsi_hba_log_buf[512];
263static char	scsi_hba_fmt[512];
264
265/* Macros to use in scsi_hba.c source code below */
266#define	SCSI_HBA_LOG(x)	scsi_hba_log x
267#define	_LOG(level)	SCSI_HBA_LOG##level, __func__
268#define	_LOG_NF(level)	SCSI_HBA_LOG##level, NULL, NULL, NULL
269#define	_LOG_TRACE	_LOG(TRACE)
270
271/*PRINTFLIKE5*/
272void
273scsi_hba_log(int level, const char *func, dev_info_t *self, dev_info_t *child,
274    const char *fmt, ...)
275{
276	va_list		ap;
277	int		clevel;
278	int		align;
279	char		*info;
280	char		*f;
281	char		*ua;
282
283	/* derive self from child's parent */
284	if ((self == NULL) && child)
285		self = ddi_get_parent(child);
286
287	/* no filtering of SCSI_HBA_LOG_CE_MASK or LOG_NF messages */
288	if (((level & SCSI_HBA_LOG_CE_MASK) != level) && (func != NULL)) {
289		/* scsi_hba_log_filter_level: filter on level as bitmask */
290		if ((level & scsi_hba_log_filter_level) == 0)
291			return;
292
293		/* scsi_hba_log_filter_phci/vhci: on name of driver */
294		if (*scsi_hba_log_filter_phci &&
295		    ((self == NULL) ||
296		    (ddi_driver_name(self) == NULL) ||
297		    strcmp(ddi_driver_name(self), scsi_hba_log_filter_phci))) {
298			/* does not match pHCI, check vHCI */
299			if (*scsi_hba_log_filter_vhci &&
300			    ((self == NULL) ||
301			    (ddi_driver_name(self) == NULL) ||
302			    strcmp(ddi_driver_name(self),
303			    scsi_hba_log_filter_vhci))) {
304				/* does not match vHCI */
305				return;
306			}
307		}
308
309
310		/* passed filters, determine align */
311		align = scsi_hba_log_align;
312
313		/* shorten func for filtered output */
314		if (strncmp(func, "scsi_hba_", 9) == 0)
315			func += 9;
316		if (strncmp(func, "scsi_", 5) == 0)
317			func += 5;
318	} else {
319		/* don't align output that is never filtered */
320		align = 0;
321	}
322
323	/* determine the cmn_err form from the level */
324	clevel = ((level & SCSI_HBA_LOG_CE_MASK) == level) ? level : CE_CONT;
325
326	/* protect common buffers used to format output */
327	mutex_enter(&scsi_hba_log_mutex);
328
329	/* skip special first characters, we add them back below */
330	f = (char *)fmt;
331	if (*f && strchr("^!?", *f))
332		f++;
333	va_start(ap, fmt);
334	(void) vsprintf(scsi_hba_log_buf, f, ap);
335	va_end(ap);
336
337	/* augment message with 'information' */
338	info = scsi_hba_log_i;
339	*info = '\0';
340	if ((scsi_hba_log_info & 0x0001) && curproc && PTOU(curproc)->u_comm) {
341		(void) sprintf(info, "%s[%d]%p ",
342		    PTOU(curproc)->u_comm, curproc->p_pid, (void *)curthread);
343		info += strlen(info);
344	}
345	if (self) {
346		if ((scsi_hba_log_info & 0x0004) && (child || self)) {
347			(void) sprintf(info, "%p ",
348			    (void *)(child ? child : self));
349			info += strlen(info);
350		}
351		if (scsi_hba_log_info & 0x0002)	{
352			(void) ddi_pathname(child ? child : self, info);
353			(void) strcat(info, " ");
354			info += strlen(info);
355		}
356
357		/* always provide 'default' information about self &child */
358		(void) sprintf(info, "%s%d ", ddi_driver_name(self),
359		    ddi_get_instance(self));
360		info += strlen(info);
361		if (child) {
362			ua = ddi_get_name_addr(child);
363			(void) sprintf(info, "%s@%s ",
364			    ddi_node_name(child), (ua && *ua) ? ua : "");
365			info += strlen(info);
366		}
367	}
368
369	/* turn off alignment if truncation would occur */
370	if (align && ((strlen(func) > 18) || (strlen(scsi_hba_log_i) > 36)))
371		align = 0;
372
373	/* adjust for aligned output */
374	if (align) {
375		if (func == NULL)
376			func = "";
377		/* remove trailing blank with align output */
378		if ((info != scsi_hba_log_i) && (*(info -1) == '\b'))
379			*(info - 1) = '\0';
380	}
381
382	/* special "first character in format" must be in format itself */
383	f = scsi_hba_fmt;
384	if (fmt[0] && strchr("^!?", fmt[0]))
385		*f++ = fmt[0];
386	else if (scsi_hba_log_fcif)
387		*f++ = (char)scsi_hba_log_fcif;		/* add global fcif */
388	if (align)
389		(void) sprintf(f, "%s", "%-18.18s: %36.36s: %s%s");
390	else
391		(void) sprintf(f, "%s", func ? "%s: %s%s%s" : "%s%s%s");
392
393	if (func)
394		cmn_err(clevel, scsi_hba_fmt, func, scsi_hba_log_i,
395		    scsi_hba_log_buf, clevel == CE_CONT ? "\n" : "");
396	else
397		cmn_err(clevel, scsi_hba_fmt, scsi_hba_log_i,
398		    scsi_hba_log_buf, clevel == CE_CONT ? "\n" : "");
399	mutex_exit(&scsi_hba_log_mutex);
400}
401
402/*
403 * Called from _init() when loading "scsi" module
404 */
405void
406scsi_initialize_hba_interface()
407{
408	SCSI_HBA_LOG((_LOG_TRACE, NULL, NULL, __func__));
409
410	mutex_init(&scsi_log_mutex, NULL, MUTEX_DRIVER, NULL);
411	mutex_init(&scsi_flag_nointr_mutex, NULL, MUTEX_DRIVER, NULL);
412	cv_init(&scsi_flag_nointr_cv, NULL, CV_DRIVER, NULL);
413	mutex_init(&scsi_hba_log_mutex, NULL, MUTEX_DRIVER, NULL);
414}
415
416int
417scsi_hba_pkt_constructor(void *buf, void *arg, int kmflag)
418{
419	struct scsi_pkt_cache_wrapper *pktw;
420	struct scsi_pkt		*pkt;
421	scsi_hba_tran_t		*tran = (scsi_hba_tran_t *)arg;
422	int			pkt_len;
423	char			*ptr;
424
425	/*
426	 * allocate a chunk of memory for the following:
427	 * scsi_pkt
428	 * pcw_* fields
429	 * pkt_ha_private
430	 * pkt_cdbp, if needed
431	 * (pkt_private always null)
432	 * pkt_scbp, if needed
433	 */
434	pkt_len = tran->tran_hba_len + sizeof (struct scsi_pkt_cache_wrapper);
435	if (tran->tran_hba_flags & SCSI_HBA_TRAN_CDB)
436		pkt_len += DEFAULT_CDBLEN;
437	if (tran->tran_hba_flags & SCSI_HBA_TRAN_SCB)
438		pkt_len += DEFAULT_SCBLEN;
439	bzero(buf, pkt_len);
440
441	ptr = buf;
442	pktw = buf;
443	ptr += sizeof (struct scsi_pkt_cache_wrapper);
444	pkt = &(pktw->pcw_pkt);
445	pkt->pkt_ha_private = (opaque_t)ptr;
446
447	pktw->pcw_magic = PKT_WRAPPER_MAGIC;	/* alloced correctly */
448	/*
449	 * keep track of the granularity at the time this handle was
450	 * allocated
451	 */
452	pktw->pcw_granular = tran->tran_dma_attr.dma_attr_granular;
453
454	if (ddi_dma_alloc_handle(tran->tran_hba_dip,
455	    &tran->tran_dma_attr,
456	    kmflag == KM_SLEEP ? SLEEP_FUNC: NULL_FUNC, NULL,
457	    &pkt->pkt_handle) != DDI_SUCCESS) {
458
459		return (-1);
460	}
461	ptr += tran->tran_hba_len;
462	if (tran->tran_hba_flags & SCSI_HBA_TRAN_CDB) {
463		pkt->pkt_cdbp = (opaque_t)ptr;
464		ptr += DEFAULT_CDBLEN;
465	}
466	pkt->pkt_private = NULL;
467	if (tran->tran_hba_flags & SCSI_HBA_TRAN_SCB)
468		pkt->pkt_scbp = (opaque_t)ptr;
469	if (tran->tran_pkt_constructor)
470		return ((*tran->tran_pkt_constructor)(pkt, arg, kmflag));
471	else
472		return (0);
473}
474
475#define	P_TO_TRAN(pkt)	((pkt)->pkt_address.a_hba_tran)
476
477void
478scsi_hba_pkt_destructor(void *buf, void *arg)
479{
480	struct scsi_pkt_cache_wrapper *pktw = buf;
481	struct scsi_pkt		*pkt = &(pktw->pcw_pkt);
482	scsi_hba_tran_t		*tran = (scsi_hba_tran_t *)arg;
483
484	ASSERT(pktw->pcw_magic == PKT_WRAPPER_MAGIC);
485	ASSERT((pktw->pcw_flags & PCW_BOUND) == 0);
486	if (tran->tran_pkt_destructor)
487		(*tran->tran_pkt_destructor)(pkt, arg);
488
489	/* make sure nobody messed with our pointers */
490	ASSERT(pkt->pkt_ha_private == (opaque_t)((char *)pkt +
491	    sizeof (struct scsi_pkt_cache_wrapper)));
492	ASSERT(((tran->tran_hba_flags & SCSI_HBA_TRAN_SCB) == 0) ||
493	    (pkt->pkt_scbp == (opaque_t)((char *)pkt +
494	    tran->tran_hba_len +
495	    (((tran->tran_hba_flags & SCSI_HBA_TRAN_CDB) == 0) ?
496	    0 : DEFAULT_CDBLEN) +
497	    DEFAULT_PRIVLEN + sizeof (struct scsi_pkt_cache_wrapper))));
498	ASSERT(((tran->tran_hba_flags & SCSI_HBA_TRAN_CDB) == 0) ||
499	    (pkt->pkt_cdbp == (opaque_t)((char *)pkt +
500	    tran->tran_hba_len +
501	    sizeof (struct scsi_pkt_cache_wrapper))));
502	ASSERT(pkt->pkt_handle);
503	ddi_dma_free_handle(&pkt->pkt_handle);
504	pkt->pkt_handle = NULL;
505	pkt->pkt_numcookies = 0;
506	pktw->pcw_total_xfer = 0;
507	pktw->pcw_totalwin = 0;
508	pktw->pcw_curwin = 0;
509}
510
511/*
512 * Called by an HBA from _init() to plumb in common SCSA bus_ops and
513 * cb_ops for the HBA's :devctl and :scsi minor nodes.
514 */
515int
516scsi_hba_init(struct modlinkage *modlp)
517{
518	struct dev_ops *hba_dev_ops;
519
520	SCSI_HBA_LOG((_LOG_TRACE, NULL, NULL, __func__));
521
522	/*
523	 * Get a pointer to the dev_ops structure of the HBA and plumb our
524	 * bus_ops vector into the HBA's dev_ops structure.
525	 */
526	hba_dev_ops = ((struct modldrv *)(modlp->ml_linkage[0]))->drv_dev_ops;
527	ASSERT(hba_dev_ops->devo_bus_ops == NULL);
528	hba_dev_ops->devo_bus_ops = &scsi_hba_busops;
529
530	/*
531	 * Plumb our cb_ops vector into the HBA's dev_ops structure to
532	 * provide getinfo and hotplugging ioctl support if the HBA driver
533	 * does not already provide this support.
534	 */
535	if (hba_dev_ops->devo_cb_ops == NULL) {
536		hba_dev_ops->devo_cb_ops = &scsi_hba_cbops;
537	}
538	if (hba_dev_ops->devo_cb_ops->cb_open == scsi_hba_open) {
539		ASSERT(hba_dev_ops->devo_cb_ops->cb_close == scsi_hba_close);
540		hba_dev_ops->devo_getinfo = scsi_hba_info;
541	}
542	return (0);
543}
544
545/*
546 * Called by an HBA attach(9E) to allocate a scsi_hba_tran structure. An HBA
547 * driver will then initialize the structure and then call
548 * scsi_hba_attach_setup.
549 */
550/*ARGSUSED*/
551scsi_hba_tran_t *
552scsi_hba_tran_alloc(
553	dev_info_t		*self,
554	int			flags)
555{
556	scsi_hba_tran_t		*tran;
557
558	SCSI_HBA_LOG((_LOG_TRACE, self, NULL, __func__));
559
560	/* allocate SCSA flavors for self */
561	ndi_flavorv_alloc(self, SCSA_NFLAVORS);
562
563	tran = kmem_zalloc(sizeof (scsi_hba_tran_t),
564	    (flags & SCSI_HBA_CANSLEEP) ? KM_SLEEP : KM_NOSLEEP);
565
566	if (tran) {
567		tran->tran_interconnect_type = INTERCONNECT_PARALLEL;
568		tran->tran_hba_flags |= SCSI_HBA_SCSA_TA;
569	}
570
571	return (tran);
572}
573
574/*
575 * Called by an HBA to free a scsi_hba_tran structure
576 */
577void
578scsi_hba_tran_free(
579	scsi_hba_tran_t		*tran)
580{
581	SCSI_HBA_LOG((_LOG_TRACE, tran->tran_hba_dip, NULL, __func__));
582
583	kmem_free(tran, sizeof (scsi_hba_tran_t));
584}
585
586int
587scsi_tran_ext_alloc(
588	scsi_hba_tran_t		*tran,
589	size_t			length,
590	int			flags)
591{
592	void	*tran_ext;
593	int	ret = DDI_FAILURE;
594
595	tran_ext = kmem_zalloc(length,
596	    (flags & SCSI_HBA_CANSLEEP) ? KM_SLEEP : KM_NOSLEEP);
597	if (tran_ext != NULL) {
598		tran->tran_extension = tran_ext;
599		ret = DDI_SUCCESS;
600	}
601	return (ret);
602}
603
604void
605scsi_tran_ext_free(
606	scsi_hba_tran_t		*tran,
607	size_t			length)
608{
609	if (tran->tran_extension != NULL) {
610		kmem_free(tran->tran_extension, length);
611		tran->tran_extension = NULL;
612	}
613}
614
615/*
616 * Return the unit-address of an 'iport' node, or NULL for non-iport node.
617 */
618char *
619scsi_hba_iport_unit_address(dev_info_t *self)
620{
621	/*
622	 * NOTE: Since 'self' could be a SCSA iport node or a SCSA HBA node,
623	 * we can't use SCSA flavors: the flavor of a SCSA HBA node is not
624	 * established/owned by SCSA, it is established by the nexus that
625	 * created the SCSA HBA node (PCI) as a child.
626	 *
627	 * NOTE: If we want to support a node_name other than "iport" for
628	 * an iport node then we can add support for a "scsa-iport-node-name"
629	 * property on the SCSA HBA node.  A SCSA HBA driver would set this
630	 * property on the SCSA HBA node prior to using the iport API.
631	 */
632	if (strcmp(ddi_node_name(self), "iport") == 0)
633		return (ddi_get_name_addr(self));
634	else
635		return (NULL);
636}
637
638/*
639 * Define a SCSI initiator port (bus/channel) for an HBA card that needs to
640 * support multiple SCSI ports, but only has a single HBA devinfo node. This
641 * function should be called from the HBA's attach(9E) implementation (when
642 * processing the HBA devinfo node attach) after the number of SCSI ports on
643 * the card is known or DR handler once DR handler detects a new port added.
644 * The function returns 0 on failure and 1 on success.
645 *
646 * The implementation will add the port value into the "scsi-iports" property
647 * value maintained on the HBA node as. These properties are used by the generic
648 * scsi bus_config implementation to dynamicaly enumerate the specified iport
649 * children. The enumeration code will, on demand, create the appropriate
650 * iport children with a "scsi-iport" unit address. This node will bind to the
651 * same driver as the HBA node itself. This means that an HBA driver that
652 * uses iports should expect probe(9E), attach(9E), and detach(9E) calls on
653 * the iport children of the HBA.  If configuration for all ports was already
654 * done during HBA node attach, the driver should just return DDI_SUCCESS when
655 * confronted with an iport node.
656 *
657 * A maximum of 32 iport ports are supported per HBA devinfo node.
658 *
659 * A NULL "port" can be used to indicate that the framework should enumerate
660 * target children on the HBA node itself, in addition to enumerating target
661 * children on any iport nodes declared. There are two reasons that an HBA may
662 * wish to have target children enumerated on both the HBA node and iport
663 * node(s):
664 *
665 *   o  If, in the past, HBA hardware had only a single physical port but now
666 *      supports multiple physical ports, the updated driver that supports
667 *      multiple physical ports may want to avoid /devices path upgrade issues
668 *      by enumerating the first physical port under the HBA instead of as a
669 *      iport.
670 *
671 *   o  Some hardware RAID HBA controllers (mlx, chs, etc) support multiple
672 *      SCSI physical ports configured so that various physical devices on
673 *      the physical ports are amalgamated into virtual devices on a virtual
674 *      port.  Amalgamated physical devices no longer appear to the host OS
675 *      on the physical ports, but other non-amalgamated devices may still be
676 *      visible on the physical ports.  These drivers use a model where the
677 *      physical ports are iport nodes and the HBA node is the virtual port to
678 *      the configured virtual devices.
679 *
680 */
681
682int
683scsi_hba_iport_register(dev_info_t *self, char *port)
684{
685	unsigned int ports = 0;
686	int rval, i;
687	char **iports, **newiports;
688
689	ASSERT(self);
690	if (self == NULL)
691		return (DDI_FAILURE);
692
693	rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self,
694	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports,
695	    &ports);
696
697	if (ports == SCSI_HBA_MAX_IPORTS) {
698		ddi_prop_free(iports);
699		return (DDI_FAILURE);
700	}
701
702	if (rval == DDI_PROP_SUCCESS) {
703		for (i = 0; i < ports; i++) {
704			if (strcmp(port, iports[i]) == 0) {
705				ddi_prop_free(iports);
706				return (DDI_SUCCESS);
707			}
708		}
709	}
710
711	newiports = kmem_alloc((sizeof (char *) * (ports + 1)), KM_SLEEP);
712
713	for (i = 0; i < ports; i++) {
714		newiports[i] = strdup(iports[i]);
715	}
716	newiports[ports] = strdup(port);
717	ports++;
718
719	rval = 1;
720
721	if (ddi_prop_update_string_array(DDI_DEV_T_NONE, self,
722	    "scsi-iports", newiports, ports) != DDI_PROP_SUCCESS) {
723		SCSI_HBA_LOG((_LOG(WARN), self, NULL,
724		    "Failed to establish scsi-iport %s", port));
725		rval = DDI_FAILURE;
726	} else {
727		rval = DDI_SUCCESS;
728	}
729
730	/* If there is iport exist, free property */
731	if (ports > 1)
732		ddi_prop_free(iports);
733	for (i = 0; i < ports; i++) {
734		strfree(newiports[i]);
735	}
736	kmem_free(newiports, (sizeof (char *)) * ports);
737
738	return (rval);
739}
740
741/*
742 * Check if the HBA is with scsi-iport under it
743 */
744int
745scsi_hba_iport_exist(dev_info_t *self)
746{
747	unsigned int ports = 0;
748	char **iports;
749	int rval;
750
751	rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self,
752	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports,
753	    &ports);
754
755	if (rval != DDI_PROP_SUCCESS)
756		return (0);
757
758	/* If there is now at least 1 iport, then iports is valid */
759	if (ports > 0) {
760		rval = 1;
761	} else
762		rval = 0;
763	ddi_prop_free(iports);
764
765	return (rval);
766}
767
768dev_info_t *
769scsi_hba_iport_find(dev_info_t *self, char *portnm)
770{
771	char		*addr = NULL;
772	char		**iports;
773	unsigned int	num_iports = 0;
774	int		rval = DDI_FAILURE;
775	int		i = 0;
776	dev_info_t	*child = NULL;
777
778	/* check to see if this is an HBA that defined scsi iports */
779	rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self,
780	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports,
781	    &num_iports);
782
783	if (rval != DDI_SUCCESS) {
784		return (NULL);
785	}
786	ASSERT(num_iports > 0);
787
788	/* check to see if this port was registered */
789	for (i = 0; i < num_iports; i++) {
790		if (strcmp(iports[i], portnm) == 0)
791			break;
792	}
793
794	if (i == num_iports) {
795		child = NULL;
796		goto out;
797	}
798
799	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
800	(void) sprintf(addr, "iport@%s", portnm);
801	rval = ndi_devi_config_one(self, addr, &child, NDI_NO_EVENT);
802	kmem_free(addr, SCSI_MAXNAMELEN);
803
804	if (rval != DDI_SUCCESS) {
805		child = NULL;
806	}
807out:
808	ddi_prop_free(iports);
809	return (child);
810}
811
812/*
813 * Common nexus teardown code: used by both scsi_hba_detach() on SCSA HBA node
814 * and iport_devctl_uninitchild() on a SCSA HBA iport node (and for failure
815 * cleanup). Undo scsa_nexus_setup in reverse order.
816 */
817static void
818scsa_nexus_teardown(dev_info_t *self, scsi_hba_tran_t	*tran)
819{
820	if ((self == NULL) || (tran == NULL))
821		return;
822	/* Teardown FMA. */
823	if (tran->tran_hba_flags & SCSI_HBA_SCSA_FM) {
824		ddi_fm_fini(self);
825		tran->tran_hba_flags &= SCSI_HBA_SCSA_FM;
826	}
827}
828
829/*
830 * Common nexus setup code: used by both scsi_hba_attach_setup() on SCSA HBA
831 * node and iport_devctl_initchild() on a SCSA HBA iport node.
832 *
833 * This code makes no assumptions about tran use by scsi_device children.
834 */
835static int
836scsa_nexus_setup(dev_info_t *self, scsi_hba_tran_t *tran)
837{
838	int		capable;
839	int		scsa_minor;
840
841	/*
842	 * NOTE: SCSA maintains an 'fm-capable' domain, in tran_fm_capable,
843	 * that is not dependent (limited by) the capabilities of its parents.
844	 * For example a devinfo node in a branch that is not
845	 * DDI_FM_EREPORT_CAPABLE may report as capable, via tran_fm_capable,
846	 * to its scsi_device children.
847	 *
848	 * Get 'fm-capable' property from driver.conf, if present. If not
849	 * present, default to the scsi_fm_capable global (which has
850	 * DDI_FM_EREPORT_CAPABLE set by default).
851	 */
852	if (tran->tran_fm_capable == DDI_FM_NOT_CAPABLE)
853		tran->tran_fm_capable = ddi_prop_get_int(DDI_DEV_T_ANY, self,
854		    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
855		    "fm-capable", scsi_fm_capable);
856	/*
857	 * If an HBA is *not* doing its own fma support by calling
858	 * ddi_fm_init() prior to scsi_hba_attach_setup(), we provide a
859	 * minimal common SCSA implementation so that scsi_device children
860	 * can generate ereports via scsi_fm_ereport_post().  We use
861	 * ddi_fm_capable() to detect an HBA calling ddi_fm_init() prior to
862	 * scsi_hba_attach_setup().
863	 */
864	if (tran->tran_fm_capable &&
865	    (ddi_fm_capable(self) == DDI_FM_NOT_CAPABLE)) {
866		/*
867		 * We are capable of something, pass our capabilities up
868		 * the tree, but use a local variable so our parent can't
869		 * limit our capabilities (we don't want our parent to
870		 * clear DDI_FM_EREPORT_CAPABLE).
871		 *
872		 * NOTE: iblock cookies are not important because scsi
873		 * HBAs always interrupt below LOCK_LEVEL.
874		 */
875		capable = tran->tran_fm_capable;
876		ddi_fm_init(self, &capable, NULL);
877
878		/*
879		 * Set SCSI_HBA_SCSA_FM bit to mark us as usiung the
880		 * common minimal SCSA fm implementation -  we called
881		 * ddi_fm_init(), so we are responsible for calling
882		 * ddi_fm_fini() in scsi_hba_detach().
883		 * NOTE: if ddi_fm_init fails in any reason, SKIP.
884		 */
885		if (DEVI(self)->devi_fmhdl)
886			tran->tran_hba_flags |= SCSI_HBA_SCSA_FM;
887	}
888
889	/* If SCSA responsible for for minor nodes, create :devctl minor. */
890	scsa_minor = (ddi_get_driver(self)->devo_cb_ops->cb_open ==
891	    scsi_hba_open) ? 1 : 0;
892	if (scsa_minor && ((ddi_create_minor_node(self, "devctl", S_IFCHR,
893	    INST2DEVCTL(ddi_get_instance(self)), DDI_NT_SCSI_NEXUS, 0) !=
894	    DDI_SUCCESS))) {
895		SCSI_HBA_LOG((_LOG(WARN), self, NULL,
896		    "can't create devctl minor nodes"));
897		scsa_nexus_teardown(self, tran);
898		return (DDI_FAILURE);
899	}
900
901	return (DDI_SUCCESS);
902}
903
904/*
905 * Common tran teardown code: used by iport_devctl_uninitchild() on a SCSA HBA
906 * iport node and (possibly) by scsi_hba_detach() on SCSA HBA node (and for
907 * failure cleanup). Undo scsa_tran_setup in reverse order.
908 */
909/*ARGSUSED*/
910static void
911scsa_tran_teardown(dev_info_t *self, scsi_hba_tran_t *tran)
912{
913	if (tran == NULL)
914		return;
915	tran->tran_iport_dip = NULL;
916
917	/*
918	 * In the future, if PHCI was registered in the SCSA
919	 * scsa_tran_teardown is able to unregiter PHCI
920	 */
921}
922
923static int
924scsa_tran_setup(dev_info_t *self, scsi_hba_tran_t *tran)
925{
926	int			scsa_minor;
927	int			id;
928	static const char	*interconnect[] = INTERCONNECT_TYPE_ASCII;
929
930	/* If SCSA responsible for for minor nodes, create ":scsi" */
931	scsa_minor = (ddi_get_driver(self)->devo_cb_ops->cb_open ==
932	    scsi_hba_open) ? 1 : 0;
933	if (scsa_minor && (ddi_create_minor_node(self, "scsi", S_IFCHR,
934	    INST2SCSI(ddi_get_instance(self)),
935	    DDI_NT_SCSI_ATTACHMENT_POINT, 0) != DDI_SUCCESS)) {
936		SCSI_HBA_LOG((_LOG(WARN), self, NULL,
937		    "can't create scsi minor nodes"));
938		scsa_nexus_teardown(self, tran);
939		goto fail;
940	}
941
942	/*
943	 * If the property does not already exist on self then see if we can
944	 * pull it from further up the tree and define it on self. If the
945	 * property does not exist above (including options.conf) then use the
946	 * default value specified (global variable).
947	 */
948#define	CONFIG_INT_PROP(s, p, dv)	{				\
949	if ((ddi_prop_exists(DDI_DEV_T_ANY, s,				\
950	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, p) == 0) &&		\
951	    (ndi_prop_update_int(DDI_DEV_T_NONE, s, p,			\
952	    ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(s),		\
953	    DDI_PROP_NOTPROM, p, dv)) != DDI_PROP_SUCCESS))		\
954		SCSI_HBA_LOG((_LOG(WARN), NULL, s,	\
955		    "can't create property '%s'", p));			\
956	}
957
958	/*
959	 * Attach scsi configuration property parameters not already defined
960	 * via driver.conf to this instance of the HBA using global variable
961	 * value.  Pulling things down from above us to use
962	 * "DDI_PROP_NOTPROM | DDI_PROP_DONTPASS" for faster access.
963	 */
964	CONFIG_INT_PROP(self, "scsi-options", scsi_options);
965	CONFIG_INT_PROP(self, "scsi-reset-delay", scsi_reset_delay);
966	CONFIG_INT_PROP(self, "scsi-tag-age-limit", scsi_tag_age_limit);
967	CONFIG_INT_PROP(self, "scsi-watchdog-tick", scsi_watchdog_tick);
968	CONFIG_INT_PROP(self, "scsi-selection-timeout", scsi_selection_timeout);
969
970	/*
971	 * cache the scsi-initiator-id as an property defined further up
972	 * the tree or defined by OBP on the HBA node so can use
973	 * "DDI_PROP_NOTPROM | DDI_PROP_DONTPASS" during enumeration.
974	 * We perform the same type of operation that an HBA driver would
975	 * use to obtain the 'initiator-id' capability.
976	 */
977	id = ddi_prop_get_int(DDI_DEV_T_ANY, self, 0, "initiator-id", -1);
978	if (id == -1)
979		id = ddi_prop_get_int(DDI_DEV_T_ANY, self, 0,
980		    "scsi-initiator-id", -1);
981	if (id != -1)
982		CONFIG_INT_PROP(self, "scsi-initiator-id", id);
983
984	/* Establish 'initiator-interconnect-type' */
985	if ((tran->tran_hba_flags & SCSI_HBA_SCSA_TA) &&
986	    (tran->tran_interconnect_type > 0) &&
987	    (tran->tran_interconnect_type < INTERCONNECT_MAX)) {
988		if (ndi_prop_update_string(DDI_DEV_T_NONE, self,
989		    "initiator-interconnect-type",
990		    (char *)interconnect[tran->tran_interconnect_type])
991		    != DDI_PROP_SUCCESS) {
992			SCSI_HBA_LOG((_LOG(WARN), self, NULL,
993			    "failed to establish "
994			    "'initiator-interconnect-type'"));
995			return (DDI_FAILURE);
996		}
997	}
998
999	tran->tran_iport_dip = self;
1000	/*
1001	 * In the future SCSA v3, PHCI could be registered in the SCSA
1002	 * here.
1003	 */
1004	return (DDI_SUCCESS);
1005fail:
1006	scsa_tran_teardown(self, tran);
1007	return (DDI_FAILURE);
1008}
1009
1010/*
1011 * Obsolete: Called by an HBA to attach an instance of the driver
1012 * Implement this older interface in terms of the new.
1013 */
1014/*ARGSUSED*/
1015int
1016scsi_hba_attach(
1017	dev_info_t		*self,
1018	ddi_dma_lim_t		*hba_lim,
1019	scsi_hba_tran_t		*tran,
1020	int			flags,
1021	void			*hba_options)
1022{
1023	ddi_dma_attr_t		hba_dma_attr;
1024
1025	bzero(&hba_dma_attr, sizeof (ddi_dma_attr_t));
1026
1027	hba_dma_attr.dma_attr_burstsizes = hba_lim->dlim_burstsizes;
1028	hba_dma_attr.dma_attr_minxfer = hba_lim->dlim_minxfer;
1029
1030	return (scsi_hba_attach_setup(self, &hba_dma_attr, tran, flags));
1031}
1032
1033/*
1034 * Called by an HBA to attach an instance of the driver.
1035 */
1036int
1037scsi_hba_attach_setup(
1038	dev_info_t		*self,
1039	ddi_dma_attr_t		*hba_dma_attr,
1040	scsi_hba_tran_t		*tran,
1041	int			flags)
1042{
1043	SCSI_HBA_LOG((_LOG_TRACE, self, NULL, __func__));
1044
1045	/* Verify that we are a driver */
1046	if (ddi_get_driver(self) == NULL)
1047		return (DDI_FAILURE);
1048
1049	ASSERT(scsi_hba_iport_unit_address(self) == NULL);
1050	if (scsi_hba_iport_unit_address(self))
1051		return (DDI_FAILURE);
1052
1053	ASSERT(tran);
1054	if (tran == NULL)
1055		return (DDI_FAILURE);
1056
1057	/*
1058	 * Verify correct scsi_hba_tran_t form:
1059	 *   o	both or none of tran_get_name/tran_get_addr.
1060	 */
1061	if ((tran->tran_get_name == NULL) ^
1062	    (tran->tran_get_bus_addr == NULL)) {
1063		return (DDI_FAILURE);
1064	}
1065
1066	/*
1067	 * Save all the important HBA information that must be accessed
1068	 * later by scsi_hba_bus_ctl(), and scsi_hba_map().
1069	 */
1070	tran->tran_hba_dip = self;
1071	tran->tran_hba_flags &= SCSI_HBA_SCSA_TA;
1072	tran->tran_hba_flags |= (flags & ~SCSI_HBA_SCSA_TA);
1073
1074	/* Establish flavor of transport (and ddi_get_driver_private()) */
1075	ndi_flavorv_set(self, SCSA_FLAVOR_SCSI_DEVICE, tran);
1076
1077	/*
1078	 * Note: we only need dma_attr_minxfer and dma_attr_burstsizes
1079	 * from the DMA attributes. scsi_hba_attach(9f) only
1080	 * guarantees that these two fields are initialized properly.
1081	 * If this changes, be sure to revisit the implementation
1082	 * of scsi_hba_attach(9F).
1083	 */
1084	(void) memcpy(&tran->tran_dma_attr, hba_dma_attr,
1085	    sizeof (ddi_dma_attr_t));
1086
1087	/* create kmem_cache, if needed */
1088	if (tran->tran_setup_pkt) {
1089		char tmp[96];
1090		int hbalen;
1091		int cmdlen = 0;
1092		int statuslen = 0;
1093
1094		ASSERT(tran->tran_init_pkt == NULL);
1095		ASSERT(tran->tran_destroy_pkt == NULL);
1096
1097		tran->tran_init_pkt = scsi_init_cache_pkt;
1098		tran->tran_destroy_pkt = scsi_free_cache_pkt;
1099		tran->tran_sync_pkt = scsi_sync_cache_pkt;
1100		tran->tran_dmafree = scsi_cache_dmafree;
1101
1102		hbalen = ROUNDUP(tran->tran_hba_len);
1103		if (flags & SCSI_HBA_TRAN_CDB)
1104			cmdlen = ROUNDUP(DEFAULT_CDBLEN);
1105		if (flags & SCSI_HBA_TRAN_SCB)
1106			statuslen = ROUNDUP(DEFAULT_SCBLEN);
1107
1108		(void) snprintf(tmp, sizeof (tmp), "pkt_cache_%s_%d",
1109		    ddi_driver_name(self), ddi_get_instance(self));
1110		tran->tran_pkt_cache_ptr = kmem_cache_create(tmp,
1111		    sizeof (struct scsi_pkt_cache_wrapper) +
1112		    hbalen + cmdlen + statuslen, 8,
1113		    scsi_hba_pkt_constructor, scsi_hba_pkt_destructor,
1114		    NULL, tran, NULL, 0);
1115	}
1116
1117	/* Perform node setup independent of initiator role */
1118	if (scsa_nexus_setup(self, tran) != DDI_SUCCESS)
1119		goto fail;
1120
1121	/*
1122	 * The SCSI_HBA_HBA flag is passed to scsi_hba_attach_setup when the
1123	 * HBA driver knows that *all* children of the SCSA HBA node will be
1124	 * 'iports'. If the SCSA HBA node can have iport children and also
1125	 * function as an initiator for xxx_device children then it should
1126	 * not specify SCSI_HBA_HBA in its scsi_hba_attach_setup call. An
1127	 * HBA driver that does not manage iports should not set SCSA_HBA_HBA.
1128	 */
1129	if (tran->tran_hba_flags & SCSI_HBA_HBA) {
1130		/*
1131		 * Set the 'ddi-config-driver-node' property on the nexus
1132		 * node that notify attach_driver_nodes() to configure all
1133		 * immediate children so that nodes which bind to the
1134		 * same driver as parent are able to be added into per-driver
1135		 * list.
1136		 */
1137		if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
1138		    self, "ddi-config-driver-node") != DDI_PROP_SUCCESS)
1139			goto fail;
1140	} else {
1141		if (scsa_tran_setup(self, tran) != DDI_SUCCESS)
1142			goto fail;
1143	}
1144
1145	return (DDI_SUCCESS);
1146
1147fail:
1148	(void) scsi_hba_detach(self);
1149	return (DDI_FAILURE);
1150}
1151
1152/*
1153 * Called by an HBA to detach an instance of the driver
1154 */
1155int
1156scsi_hba_detach(dev_info_t *self)
1157{
1158	scsi_hba_tran_t	*tran;
1159
1160	SCSI_HBA_LOG((_LOG_TRACE, self, NULL, __func__));
1161
1162	ASSERT(scsi_hba_iport_unit_address(self) == NULL);
1163	if (scsi_hba_iport_unit_address(self))
1164		return (DDI_FAILURE);
1165
1166	tran = ndi_flavorv_get(self, SCSA_FLAVOR_SCSI_DEVICE);
1167	ASSERT(tran);
1168	if (tran == NULL)
1169		return (DDI_FAILURE);
1170
1171	ASSERT(tran->tran_open_flag == 0);
1172	if (tran->tran_open_flag)
1173		return (DDI_FAILURE);
1174
1175	if (!(tran->tran_hba_flags & SCSI_HBA_HBA))
1176		scsa_tran_teardown(self, tran);
1177	scsa_nexus_teardown(self, tran);
1178
1179	/*
1180	 * XXX - scsi_transport.h states that these data fields should not be
1181	 * referenced by the HBA. However, to be consistent with
1182	 * scsi_hba_attach(), they are being reset.
1183	 */
1184	tran->tran_hba_dip = (dev_info_t *)NULL;
1185	tran->tran_hba_flags = 0;
1186	(void) memset(&tran->tran_dma_attr, 0, sizeof (ddi_dma_attr_t));
1187
1188	if (tran->tran_pkt_cache_ptr != NULL) {
1189		kmem_cache_destroy(tran->tran_pkt_cache_ptr);
1190		tran->tran_pkt_cache_ptr = NULL;
1191	}
1192
1193	/* Teardown flavor of transport (and ddi_get_driver_private()) */
1194	ndi_flavorv_set(self, SCSA_FLAVOR_SCSI_DEVICE, NULL);
1195
1196	return (DDI_SUCCESS);
1197}
1198
1199/*
1200 * Called by an HBA from _fini()
1201 */
1202void
1203scsi_hba_fini(struct modlinkage *modlp)
1204{
1205	struct dev_ops *hba_dev_ops;
1206
1207	SCSI_HBA_LOG((_LOG_TRACE, NULL, NULL, __func__));
1208
1209	/* Get the devops structure of this module and clear bus_ops vector. */
1210	hba_dev_ops = ((struct modldrv *)(modlp->ml_linkage[0]))->drv_dev_ops;
1211
1212	if (hba_dev_ops->devo_cb_ops == &scsi_hba_cbops)
1213		hba_dev_ops->devo_cb_ops = NULL;
1214
1215	if (hba_dev_ops->devo_getinfo == scsi_hba_info)
1216		hba_dev_ops->devo_getinfo = NULL;
1217
1218	hba_dev_ops->devo_bus_ops = (struct bus_ops *)NULL;
1219}
1220
1221/*
1222 * SAS specific functions
1223 */
1224/*ARGSUSED*/
1225sas_hba_tran_t *
1226sas_hba_tran_alloc(
1227	dev_info_t		*self,
1228	int			flags)
1229{
1230	/* allocate SCSA flavors for self */
1231	ndi_flavorv_alloc(self, SCSA_NFLAVORS);
1232	return (kmem_zalloc(sizeof (sas_hba_tran_t), KM_SLEEP));
1233}
1234
1235void
1236sas_hba_tran_free(
1237	sas_hba_tran_t		*tran)
1238{
1239	kmem_free(tran, sizeof (sas_hba_tran_t));
1240}
1241
1242int
1243sas_hba_attach_setup(
1244	dev_info_t		*self,
1245	sas_hba_tran_t		*tran)
1246{
1247	ASSERT(scsi_hba_iport_unit_address(self) == NULL);
1248	if (scsi_hba_iport_unit_address(self))
1249		return (DDI_FAILURE);
1250	/*
1251	 * The owner of the this devinfo_t was responsible
1252	 * for informing the framework already about
1253	 * additional flavors.
1254	 */
1255	ndi_flavorv_set(self, SCSA_FLAVOR_SMP, tran);
1256	return (DDI_SUCCESS);
1257}
1258
1259int
1260sas_hba_detach(dev_info_t *self)
1261{
1262	ASSERT(scsi_hba_iport_unit_address(self) == NULL);
1263	if (scsi_hba_iport_unit_address(self))
1264		return (DDI_FAILURE);
1265
1266	ndi_flavorv_set(self, SCSA_FLAVOR_SMP, NULL);
1267	return (DDI_SUCCESS);
1268}
1269
1270/*
1271 * SMP child flavored functions
1272 */
1273
1274static int
1275smp_busctl_reportdev(dev_info_t *child)
1276{
1277	dev_info_t		*self = ddi_get_parent(child);
1278	char			*smp_wwn;
1279
1280	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
1281	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1282	    SMP_WWN, &smp_wwn) != DDI_SUCCESS) {
1283		return (DDI_FAILURE);
1284	}
1285	SCSI_HBA_LOG((_LOG_NF(CONT), "?%s%d at %s%d: wwn %s\n",
1286	    ddi_driver_name(child), ddi_get_instance(child),
1287	    ddi_driver_name(self), ddi_get_instance(self), smp_wwn));
1288	ddi_prop_free(smp_wwn);
1289	return (DDI_SUCCESS);
1290}
1291
1292static int
1293smp_busctl_initchild(dev_info_t *child)
1294{
1295	dev_info_t		*self = ddi_get_parent(child);
1296	sas_hba_tran_t		*tran = ndi_flavorv_get(self, SCSA_FLAVOR_SMP);
1297	struct smp_device	*smp;
1298	char			addr[SCSI_MAXNAMELEN];
1299	dev_info_t		*ndip;
1300	char			*smp_wwn = NULL;
1301	uint64_t		wwn;
1302
1303	ASSERT(tran);
1304	if (tran == NULL)
1305		return (DDI_FAILURE);
1306
1307	smp = kmem_zalloc(sizeof (struct smp_device), KM_SLEEP);
1308	smp->dip = child;
1309	smp->smp_addr.a_hba_tran = tran;
1310
1311	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
1312	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1313	    SMP_WWN, &smp_wwn) != DDI_SUCCESS) {
1314		goto failure;
1315	}
1316
1317	if (scsi_wwnstr_to_wwn(smp_wwn, &wwn)) {
1318		goto failure;
1319	}
1320
1321	bcopy(&wwn, smp->smp_addr.a_wwn, SAS_WWN_BYTE_SIZE);
1322	(void) snprintf(addr, SCSI_MAXNAMELEN, "w%s", smp_wwn);
1323
1324	/* Prevent duplicate nodes.  */
1325	ndip = ndi_devi_find(self, ddi_node_name(child), addr);
1326	if (ndip && (ndip != child)) {
1327		goto failure;
1328	}
1329
1330	ddi_set_name_addr(child, addr);
1331	ddi_set_driver_private(child, smp);
1332	ddi_prop_free(smp_wwn);
1333	return (DDI_SUCCESS);
1334
1335failure:
1336	kmem_free(smp, sizeof (struct smp_device));
1337	if (smp_wwn) {
1338		ddi_prop_free(smp_wwn);
1339	}
1340	return (DDI_FAILURE);
1341}
1342
1343/*ARGSUSED*/
1344static int
1345smp_busctl_uninitchild(dev_info_t *child)
1346{
1347	struct smp_device	*smp = ddi_get_driver_private(child);
1348
1349	ASSERT(smp);
1350	if (smp == NULL)
1351		return (DDI_FAILURE);
1352	kmem_free(smp, sizeof (*smp));
1353	ddi_set_driver_private(child, NULL);
1354	ddi_set_name_addr(child, NULL);
1355	return (DDI_SUCCESS);
1356}
1357
1358/*
1359 * Wrapper to scsi_get_name which takes a devinfo argument instead of a
1360 * scsi_device structure.
1361 */
1362static int
1363scsi_hba_name_child(dev_info_t *child, char *addr, int maxlen)
1364{
1365	struct scsi_device	*sd = ddi_get_driver_private(child);
1366
1367	/* nodes are named by tran_get_name or default "tgt,lun" */
1368	if (sd && (scsi_get_name(sd, addr, maxlen) == 1))
1369		return (DDI_SUCCESS);
1370
1371	return (DDI_FAILURE);
1372}
1373
1374static int
1375scsi_busctl_reportdev(dev_info_t *child)
1376{
1377	dev_info_t		*self = ddi_get_parent(child);
1378	scsi_hba_tran_t		*tran = ddi_get_driver_private(self);
1379	struct scsi_device	*sd = ddi_get_driver_private(child);
1380	char			ua[SCSI_MAXNAMELEN];
1381	char			ba[SCSI_MAXNAMELEN];
1382
1383	SCSI_HBA_LOG((_LOG_TRACE, NULL, child, __func__));
1384
1385	ASSERT(tran && sd);
1386	if ((tran == NULL) || (sd == NULL))
1387		return (DDI_FAILURE);
1388
1389	/* get the unit_address and bus_addr information */
1390	if ((scsi_get_name(sd, ua, sizeof (ua)) == 0) ||
1391	    (scsi_get_bus_addr(sd, ba, sizeof (ba)) == 0)) {
1392		SCSI_HBA_LOG((_LOG(WARN), NULL, child, "REPORTDEV failure"));
1393		return (DDI_FAILURE);
1394	}
1395
1396	if (tran->tran_get_name == NULL)
1397		SCSI_HBA_LOG((_LOG_NF(CONT), "?%s%d at %s%d: %s",
1398		    ddi_driver_name(child), ddi_get_instance(child),
1399		    ddi_driver_name(self), ddi_get_instance(self), ba));
1400	else
1401		SCSI_HBA_LOG((_LOG_NF(CONT),
1402		    "?%s%d at %s%d: unit-address %s: %s",
1403		    ddi_driver_name(child), ddi_get_instance(child),
1404		    ddi_driver_name(self), ddi_get_instance(self), ua, ba));
1405	return (DDI_SUCCESS);
1406}
1407
1408/*
1409 * scsi_busctl_initchild is called to initialize the SCSA transport for
1410 * communication with a particular child scsi target device. Successful
1411 * initialization requires properties on the node which describe the address
1412 * of the target device. If the address of the target device can't be
1413 * determined from properties then DDI_NOT_WELL_FORMED is returned. Nodes that
1414 * are DDI_NOT_WELL_FORMED are considered an implementation artifact.
1415 * The child may be one of the following types of devinfo nodes:
1416 *
1417 * OBP node:
1418 *	OBP does not enumerate target devices attached a SCSI bus. These
1419 *	template/stub/wildcard nodes are a legacy artifact for support of old
1420 *	driver loading methods. Since they have no properties,
1421 *	DDI_NOT_WELL_FORMED will be returned.
1422 *
1423 * SID node:
1424 *	The node may be either a:
1425 *	    o	probe/barrier SID node
1426 *	    o	a dynamic SID target node
1427 *
1428 * driver.conf node: The situation for this nexus is different than most.
1429 *	Typically a driver.conf node definition is used to either define a
1430 *	new child devinfo node or to further decorate (via merge) a SID
1431 *	child with properties. In our case we use the nodes for *both*
1432 *	purposes.
1433 *
1434 * In both the SID node and driver.conf node cases we must form the nodes
1435 * "@addr" from the well-known scsi(9P) device unit-address properties on
1436 * the node.
1437 *
1438 * For HBA drivers that implement the deprecated tran_get_name interface,
1439 * "@addr" construction involves having that driver interpret properties via
1440 * scsi_hba_name_child -> scsi_get_name -> tran_get_name: there is no
1441 * requiremnt for the property names to be well-known.
1442 */
1443static int
1444scsi_busctl_initchild(dev_info_t *child)
1445{
1446	dev_info_t		*self = ddi_get_parent(child);
1447	dev_info_t		*dup;
1448	scsi_hba_tran_t		*tran;
1449	struct scsi_device	*sd;
1450	scsi_hba_tran_t		*tran_clone;
1451	int			tgt = 0;
1452	int			lun = 0;
1453	int			sfunc = 0;
1454	int			err = DDI_FAILURE;
1455	char			addr[SCSI_MAXNAMELEN];
1456
1457	ASSERT(DEVI_BUSY_OWNED(self));
1458	SCSI_HBA_LOG((_LOG(4), NULL, child, "init begin"));
1459
1460	/*
1461	 * For a driver like fp with multiple upper-layer-protocols
1462	 * it is possible for scsi_hba_init in _init to plumb SCSA
1463	 * and have the load of fcp (which does scsi_hba_attach_setup)
1464	 * to fail.  In this case we may get here with a NULL hba.
1465	 */
1466	tran = ddi_get_driver_private(self);
1467	if (tran == NULL)
1468		return (DDI_NOT_WELL_FORMED);
1469
1470	/*
1471	 * OBP may create template/stub/wildcard nodes for legacy driver
1472	 * loading methods. These nodes have no properties, so we lack the
1473	 * addressing properties to initchild them. Hide the node and return
1474	 * DDI_NOT_WELL_FORMED.
1475	 *
1476	 * XXX need ndi_devi_has_properties(dip) type interface?
1477	 *
1478	 * XXX It would be nice if we could delete these ill formed nodes by
1479	 * implementing a DDI_NOT_WELL_FORMED_DELETE return code. This can't
1480	 * be done until leadville debug code removes its dependencies
1481	 * on the devinfo still being present after a failed ndi_devi_online.
1482	 */
1483	if ((DEVI(child)->devi_hw_prop_ptr == NULL) &&
1484	    (DEVI(child)->devi_drv_prop_ptr == NULL) &&
1485	    (DEVI(child)->devi_sys_prop_ptr == NULL)) {
1486		SCSI_HBA_LOG((_LOG(4), NULL, child,
1487		    "init failed: no properties"));
1488		return (DDI_NOT_WELL_FORMED);
1489	}
1490
1491	/* get legacy SPI addressing properties */
1492	sfunc = ddi_prop_get_int(DDI_DEV_T_ANY, child,
1493	    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, SCSI_ADDR_PROP_SFUNC, -1);
1494	lun = ddi_prop_get_int(DDI_DEV_T_ANY, child,
1495	    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, SCSI_ADDR_PROP_LUN, 0);
1496	if ((tgt = ddi_prop_get_int(DDI_DEV_T_ANY, child,
1497	    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
1498	    SCSI_ADDR_PROP_TARGET, -1)) == -1) {
1499		tgt = 0;
1500		/*
1501		 * A driver.conf node for merging always has a target= property,
1502		 * even if it is just a dummy that does not contain the real
1503		 * target address. However drivers that register devids may
1504		 * create stub driver.conf nodes without a target= property so
1505		 * that pathological devid resolution works.
1506		 */
1507		if (ndi_dev_is_persistent_node(child) == 0) {
1508			SCSI_HBA_LOG((_LOG(4), NULL, child,
1509			    "init failed: stub .conf node"));
1510			return (DDI_NOT_WELL_FORMED);
1511		}
1512	}
1513
1514	/*
1515	 * The scsi_address structure may not specify all the addressing
1516	 * information. For an old HBA that doesn't support tran_get_name
1517	 * (most pre-SCSI-3 HBAs) the scsi_address structure is still used,
1518	 * so the target property must exist and the LUN must be < 256.
1519	 */
1520	if ((tran->tran_get_name == NULL) &&
1521	    ((tgt >= USHRT_MAX) || (lun >= 256))) {
1522		SCSI_HBA_LOG((_LOG(1), NULL, child,
1523		    "init failed: illegal/missing properties"));
1524		return (DDI_NOT_WELL_FORMED);
1525	}
1526
1527	/*
1528	 * We need to initialize a fair amount of our environment to invoke
1529	 * tran_get_name (via scsi_hba_name_child and scsi_get_name) to
1530	 * produce the "@addr" name from addressing properties. Allocate and
1531	 * initialize scsi device structure.
1532	 */
1533	sd = kmem_zalloc(sizeof (struct scsi_device), KM_SLEEP);
1534	mutex_init(&sd->sd_mutex, NULL, MUTEX_DRIVER, NULL);
1535	sd->sd_dev = child;
1536	sd->sd_pathinfo = NULL;
1537	ddi_set_driver_private(child, sd);
1538
1539	if (tran->tran_hba_flags & SCSI_HBA_ADDR_COMPLEX) {
1540		/*
1541		 * For a SCSI_HBA_ADDR_COMPLEX transport we store a pointer to
1542		 * scsi_device in the scsi_address structure.  This allows an
1543		 * HBA driver to find its per-scsi_device private data
1544		 * (accessable to the HBA given just the scsi_address by using
1545		 *  scsi_address_device(9F)/scsi_device_hba_private_get(9F)).
1546		 */
1547		sd->sd_address.a.a_sd = sd;
1548		tran_clone = NULL;
1549	} else {
1550		/*
1551		 * Initialize the scsi_address so that a SCSI-2 target driver
1552		 * talking to a SCSI-2 device on a SCSI-3 bus (spi) continues
1553		 * to work. We skew the secondary function value so that we
1554		 * can tell from the address structure if we are processing
1555		 * a secondary function request.
1556		 */
1557		sd->sd_address.a_target = (ushort_t)tgt;
1558		sd->sd_address.a_lun = (uchar_t)lun;
1559		if (sfunc == -1)
1560			sd->sd_address.a_sublun = (uchar_t)0;
1561		else
1562			sd->sd_address.a_sublun = (uchar_t)sfunc + 1;
1563
1564		/*
1565		 * XXX TODO: apply target/lun limitation logic for SPI
1566		 * binding_set. If spi this is based on scsi_options WIDE
1567		 * NLUNS some forms of lun limitation are based on the
1568		 * device @lun 0
1569		 */
1570
1571		/*
1572		 * Deprecated: Use SCSI_HBA_ADDR_COMPLEX:
1573		 *   Clone transport structure if requested. Cloning allows
1574		 *   an HBA to maintain target-specific information if
1575		 *   necessary, such as target addressing information that
1576		 *   does not adhere to the scsi_address structure format.
1577		 */
1578		if (tran->tran_hba_flags & SCSI_HBA_TRAN_CLONE) {
1579			tran_clone = kmem_alloc(
1580			    sizeof (scsi_hba_tran_t), KM_SLEEP);
1581			bcopy((caddr_t)tran,
1582			    (caddr_t)tran_clone, sizeof (scsi_hba_tran_t));
1583			tran = tran_clone;
1584			tran->tran_sd = sd;
1585		} else {
1586			tran_clone = NULL;
1587			ASSERT(tran->tran_sd == NULL);
1588		}
1589	}
1590
1591	/* establish scsi_address pointer to the HBA's tran structure */
1592	sd->sd_address.a_hba_tran = tran;
1593
1594	/*
1595	 * This is a grotty hack that allows direct-access (non-scsa) drivers
1596	 * (like chs, ata, and mlx which all make cmdk children) to put its
1597	 * own vector in the 'a_hba_tran' field. When all the drivers that do
1598	 * this are fixed, please remove this hack.
1599	 *
1600	 * NOTE: This hack is also shows up in the DEVP_TO_TRAN implementation
1601	 * in scsi_confsubr.c.
1602	 */
1603	sd->sd_tran_safe = tran;
1604
1605	/* Establish the @addr name of the child. */
1606	*addr = '\0';
1607	if (scsi_hba_name_child(child, addr, SCSI_MAXNAMELEN) != DDI_SUCCESS) {
1608		/*
1609		 * Some driver.conf files add bogus target properties (relative
1610		 * to their nexus representation of target) to their stub
1611		 * nodes, causing the check above to not filter them.
1612		 */
1613		SCSI_HBA_LOG((_LOG(3), NULL, child,
1614		    "init failed: scsi_busctl_ua call"));
1615		err = DDI_NOT_WELL_FORMED;
1616		goto failure;
1617	}
1618	if (*addr == '\0') {
1619		SCSI_HBA_LOG((_LOG(2), NULL, child, "init failed: ua"));
1620		ndi_devi_set_hidden(child);
1621		err = DDI_NOT_WELL_FORMED;
1622		goto failure;
1623	}
1624
1625	/* set the node @addr string */
1626	ddi_set_name_addr(child, addr);
1627
1628	/* prevent sibling duplicates */
1629	dup = ndi_devi_find(self, ddi_node_name(child), addr);
1630	if (dup && (dup != child)) {
1631		SCSI_HBA_LOG((_LOG(4), NULL, child,
1632		    "init failed: detected duplicate %p", (void *)dup));
1633		goto failure;
1634	}
1635
1636	/* call HBA's target init entry point if it exists */
1637	if (tran->tran_tgt_init != NULL) {
1638		SCSI_HBA_LOG((_LOG(4), NULL, child, "init tran_tgt_init"));
1639		if ((*tran->tran_tgt_init)
1640		    (self, child, tran, sd) != DDI_SUCCESS) {
1641			SCSI_HBA_LOG((_LOG(2), NULL, child,
1642			    "init failed: tran_tgt_init failed"));
1643			goto failure;
1644		}
1645	}
1646
1647	SCSI_HBA_LOG((_LOG(3), NULL, child, "init successful"));
1648	return (DDI_SUCCESS);
1649
1650failure:
1651	if (tran_clone)
1652		kmem_free(tran_clone, sizeof (scsi_hba_tran_t));
1653	mutex_destroy(&sd->sd_mutex);
1654	kmem_free(sd, sizeof (*sd));
1655	ddi_set_driver_private(child, NULL);
1656	ddi_set_name_addr(child, NULL);
1657
1658	return (err);		/* remove the node */
1659}
1660
1661static int
1662scsi_busctl_uninitchild(dev_info_t *child)
1663{
1664	dev_info_t		*self = ddi_get_parent(child);
1665	scsi_hba_tran_t		*tran = ddi_get_driver_private(self);
1666	struct scsi_device	*sd = ddi_get_driver_private(child);
1667	scsi_hba_tran_t		*tran_clone;
1668
1669	ASSERT(DEVI_BUSY_OWNED(self));
1670
1671	ASSERT(tran && sd);
1672	if ((tran == NULL) || (sd == NULL))
1673		return (DDI_FAILURE);
1674
1675
1676	SCSI_HBA_LOG((_LOG(3), NULL, child, "uninit begin"));
1677
1678	if (tran->tran_hba_flags & SCSI_HBA_TRAN_CLONE) {
1679		tran_clone = sd->sd_address.a_hba_tran;
1680
1681		/* ... grotty hack, involving sd_tran_safe, continued. */
1682		if (tran_clone != sd->sd_tran_safe) {
1683			tran_clone = sd->sd_tran_safe;
1684#ifdef	DEBUG
1685			/*
1686			 * Complain so things get fixed and hack can, at
1687			 * some point in time, be removed.
1688			 */
1689			SCSI_HBA_LOG((_LOG(WARN), self, NULL,
1690			    "'%s' is corrupting a_hba_tran", sd->sd_dev ?
1691			    ddi_driver_name(sd->sd_dev) : "unknown_driver"));
1692#endif	/* DEBUG */
1693		}
1694
1695		ASSERT(tran_clone->tran_hba_flags & SCSI_HBA_TRAN_CLONE);
1696		ASSERT(tran_clone->tran_sd == sd);
1697		tran = tran_clone;
1698	} else {
1699		tran_clone = NULL;
1700		ASSERT(tran->tran_sd == NULL);
1701	}
1702
1703	/*
1704	 * To simplify host adapter drivers we guarantee that multiple
1705	 * tran_tgt_init(9E) calls of the same unit address are never
1706	 * active at the same time.
1707	 */
1708	if (tran->tran_tgt_free)
1709		(*tran->tran_tgt_free) (self, child, tran, sd);
1710
1711	/*
1712	 * If a inquiry data is still allocated (by scsi_probe()) we
1713	 * free the allocation here. This keeps scsi_inq valid for the
1714	 * same duration as the corresponding inquiry properties. It
1715	 * also allows a tran_tgt_init() implementation that establishes
1716	 * sd_inq (common/io/dktp/controller/ata/ata_disk.c) to deal
1717	 * with deallocation in its tran_tgt_free (setting sd_inq back
1718	 * to NULL) without upsetting the framework.
1719	 */
1720	if (sd->sd_inq) {
1721		kmem_free(sd->sd_inq, SUN_INQSIZE);
1722		sd->sd_inq = (struct scsi_inquiry *)NULL;
1723	}
1724
1725	mutex_destroy(&sd->sd_mutex);
1726	if (tran_clone)
1727		kmem_free(tran_clone, sizeof (scsi_hba_tran_t));
1728	kmem_free(sd, sizeof (*sd));
1729
1730	ddi_set_driver_private(child, NULL);
1731	SCSI_HBA_LOG((_LOG(3), NULL, child, "uninit complete"));
1732	ddi_set_name_addr(child, NULL);
1733	return (DDI_SUCCESS);
1734}
1735
1736static int
1737iport_busctl_reportdev(dev_info_t *child)
1738{
1739	dev_info_t	*self = ddi_get_parent(child);
1740	char		*iport;
1741
1742
1743	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
1744	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1745	    "scsi-iport", &iport) != DDI_SUCCESS)
1746		return (DDI_FAILURE);
1747
1748	SCSI_HBA_LOG((_LOG_NF(CONT), "?%s%d at %s%d: iport %s\n",
1749	    ddi_driver_name(child), ddi_get_instance(child),
1750	    ddi_driver_name(self), ddi_get_instance(self),
1751	    iport));
1752
1753	ddi_prop_free(iport);
1754	return (DDI_SUCCESS);
1755}
1756
1757/* uninitchild SCSA iport 'child' node */
1758static int
1759iport_busctl_uninitchild(dev_info_t *child)
1760{
1761	ddi_set_name_addr(child, NULL);
1762	return (DDI_SUCCESS);
1763}
1764
1765/* initchild SCSA iport 'child' node */
1766static int
1767iport_busctl_initchild(dev_info_t *child)
1768{
1769	dev_info_t	*self = ddi_get_parent(child);
1770	dev_info_t	*dup = NULL;
1771	char		addr[SCSI_MAXNAMELEN];
1772	char		*iport;
1773
1774
1775	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
1776	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1777	    "scsi-iport", &iport) != DDI_SUCCESS) {
1778		return (DDI_NOT_WELL_FORMED);
1779	}
1780
1781	(void) snprintf(addr, SCSI_MAXNAMELEN, "%s", iport);
1782	ddi_prop_free(iport);
1783
1784
1785	/* set the node @addr string */
1786	ddi_set_name_addr(child, addr);
1787
1788	/* Prevent duplicate nodes.  */
1789	dup = ndi_devi_find(self, ddi_node_name(child), addr);
1790	if (dup && (dup != child)) {
1791		ddi_set_name_addr(child, NULL);
1792		return (DDI_FAILURE);
1793	}
1794
1795	return (DDI_SUCCESS);
1796}
1797
1798/* Uninitialize scsi_device flavor of transport on SCSA iport 'child' node. */
1799static void
1800iport_postdetach_tran_scsi_device(dev_info_t *child)
1801{
1802	scsi_hba_tran_t		*tran;
1803
1804	tran = ndi_flavorv_get(child, SCSA_FLAVOR_SCSI_DEVICE);
1805	if (tran == NULL)
1806		return;
1807
1808	scsa_tran_teardown(child, tran);
1809	scsa_nexus_teardown(child, tran);
1810
1811	ndi_flavorv_set(child, SCSA_FLAVOR_SCSI_DEVICE, NULL);
1812	scsi_hba_tran_free(tran);
1813}
1814
1815/*
1816 * Initialize scsi_device flavor of transport on SCSA iport 'child' node.
1817 *
1818 * NOTE: Given our past history with SCSI_HBA_TRAN_CLONE (structure-copy tran
1819 * per scsi_device), using structure-copy of tran at the iport level should
1820 * not be a problem (the most risky thing is likely tran_hba_dip).
1821 */
1822static void
1823iport_preattach_tran_scsi_device(dev_info_t *child)
1824{
1825	dev_info_t	*hba = ddi_get_parent(child);
1826	scsi_hba_tran_t	*htran;
1827	scsi_hba_tran_t	*tran;
1828
1829	/* parent HBA node scsi_device tran is required */
1830	htran = ndi_flavorv_get(hba, SCSA_FLAVOR_SCSI_DEVICE);
1831	ASSERT(htran != NULL);
1832	if (htran == NULL)
1833		return;
1834
1835	/* Allocate iport child's scsi_device transport vector */
1836	tran = scsi_hba_tran_alloc(child, SCSI_HBA_CANSLEEP);
1837	if (tran == NULL)
1838		return;
1839
1840	/* Structure-copy scsi_device transport of HBA to iport. */
1841	*tran = *htran;
1842
1843	/*
1844	 * Reset scsi_device transport fields not shared with the
1845	 * parent, and not established below.
1846	 */
1847	tran->tran_open_flag = 0;
1848	tran->tran_hba_private = NULL;
1849	tran->tran_iport_dip = child;
1850
1851	/* Clear SCSI_HBA_SCSA flags (except TA) */
1852	tran->tran_hba_flags &= ~SCSI_HBA_SCSA_FM;	/* clear parent state */
1853	tran->tran_hba_flags |= SCSI_HBA_SCSA_TA;
1854	tran->tran_hba_flags &= ~SCSI_HBA_HBA;		/* never HBA */
1855
1856	/* Establish flavor of transport (and ddi_get_driver_private()) */
1857	ndi_flavorv_set(child, SCSA_FLAVOR_SCSI_DEVICE, tran);
1858
1859	/* Setup iport node */
1860	if ((scsa_nexus_setup(child, tran) != DDI_SUCCESS) ||
1861	    (scsa_tran_setup(child, tran) != DDI_SUCCESS)) {
1862		iport_postdetach_tran_scsi_device(child);
1863	}
1864}
1865
1866/* Uninitialize smp_device flavor of transport on SCSA iport 'child' node. */
1867static void
1868iport_postdetach_tran_smp_device(dev_info_t *child)
1869{
1870	sas_hba_tran_t	*tran;
1871
1872	tran = ndi_flavorv_get(child, SCSA_FLAVOR_SMP);
1873	if (tran == NULL)
1874		return;
1875
1876	ndi_flavorv_set(child, SCSA_FLAVOR_SMP, NULL);
1877	sas_hba_tran_free(tran);
1878}
1879
1880/* Initialize smp_device flavor of transport on SCSA iport 'child' node. */
1881static void
1882iport_preattach_tran_smp_device(dev_info_t *child)
1883{
1884	dev_info_t	*hba = ddi_get_parent(child);
1885	sas_hba_tran_t	*htran;
1886	sas_hba_tran_t	*tran;
1887
1888	/* parent HBA node smp_device tran is optional */
1889	htran = ndi_flavorv_get(hba, SCSA_FLAVOR_SMP);
1890	if (htran == NULL) {
1891		ndi_flavorv_set(child, SCSA_FLAVOR_SMP, NULL);
1892		return;
1893	}
1894
1895	/* Allocate iport child's smp_device transport vector */
1896	tran = sas_hba_tran_alloc(child, 0);
1897
1898	/* Structure-copy smp_device transport of HBA to iport. */
1899	*tran = *htran;
1900
1901	/* Establish flavor of transport */
1902	ndi_flavorv_set(child, SCSA_FLAVOR_SMP, tran);
1903}
1904
1905
1906/*
1907 * Generic bus_ctl operations for SCSI HBA's,
1908 * hiding the busctl interface from the HBA.
1909 */
1910/*ARGSUSED*/
1911static int
1912scsi_hba_bus_ctl(
1913	dev_info_t		*self,
1914	dev_info_t		*child,
1915	ddi_ctl_enum_t		op,
1916	void			*arg,
1917	void			*result)
1918{
1919	int			child_flavor = 0;
1920	int			val;
1921	ddi_dma_attr_t		*attr;
1922	scsi_hba_tran_t		*tran;
1923	struct attachspec	*as;
1924	struct detachspec	*ds;
1925
1926	/* For some ops, child is 'arg'. */
1927	if ((op == DDI_CTLOPS_INITCHILD) || (op == DDI_CTLOPS_UNINITCHILD))
1928		child = (dev_info_t *)arg;
1929
1930	/* Determine the flavor of the child: smp .vs. scsi */
1931	child_flavor = ndi_flavor_get(child);
1932
1933	switch (op) {
1934	case DDI_CTLOPS_INITCHILD:
1935		switch (child_flavor) {
1936		case SCSA_FLAVOR_IPORT:
1937			return (iport_busctl_initchild(child));
1938		case SCSA_FLAVOR_SMP:
1939			return (smp_busctl_initchild(child));
1940		default:
1941			return (scsi_busctl_initchild(child));
1942		}
1943	case DDI_CTLOPS_UNINITCHILD:
1944		switch (child_flavor) {
1945		case SCSA_FLAVOR_IPORT:
1946			return (iport_busctl_uninitchild(child));
1947		case SCSA_FLAVOR_SMP:
1948			return (smp_busctl_uninitchild(child));
1949		default:
1950			return (scsi_busctl_uninitchild(child));
1951		}
1952	case DDI_CTLOPS_REPORTDEV:
1953		switch (child_flavor) {
1954		case SCSA_FLAVOR_IPORT:
1955			return (iport_busctl_reportdev(child));
1956		case SCSA_FLAVOR_SMP:
1957			return (smp_busctl_reportdev(child));
1958		default:
1959			return (scsi_busctl_reportdev(child));
1960		}
1961	case DDI_CTLOPS_ATTACH:
1962		as = (struct attachspec *)arg;
1963
1964		if (child_flavor != SCSA_FLAVOR_IPORT)
1965			return (DDI_SUCCESS);
1966
1967		/* iport processing */
1968		if (as->when == DDI_PRE) {
1969			/* setup pre attach(9E) */
1970			iport_preattach_tran_scsi_device(child);
1971			iport_preattach_tran_smp_device(child);
1972		} else if ((as->when == DDI_POST) &&
1973		    (as->result != DDI_SUCCESS)) {
1974			/* cleanup if attach(9E) failed */
1975			iport_postdetach_tran_scsi_device(child);
1976			iport_postdetach_tran_smp_device(child);
1977		}
1978		return (DDI_SUCCESS);
1979	case DDI_CTLOPS_DETACH:
1980		ds = (struct detachspec *)arg;
1981
1982		if (child_flavor != SCSA_FLAVOR_IPORT)
1983			return (DDI_SUCCESS);
1984
1985		/* iport processing */
1986		if ((ds->when == DDI_POST) &&
1987		    (ds->result == DDI_SUCCESS)) {
1988			/* cleanup if detach(9E) was successful */
1989			iport_postdetach_tran_scsi_device(child);
1990			iport_postdetach_tran_smp_device(child);
1991		}
1992		return (DDI_SUCCESS);
1993	case DDI_CTLOPS_IOMIN:
1994		tran = ddi_get_driver_private(self);
1995		ASSERT(tran);
1996		if (tran == NULL)
1997			return (DDI_FAILURE);
1998
1999		/*
2000		 * The 'arg' value of nonzero indicates 'streaming'
2001		 * mode. If in streaming mode, pick the largest
2002		 * of our burstsizes available and say that that
2003		 * is our minimum value (modulo what minxfer is).
2004		 */
2005		attr = &tran->tran_dma_attr;
2006		val = *((int *)result);
2007		val = maxbit(val, attr->dma_attr_minxfer);
2008		*((int *)result) = maxbit(val, ((intptr_t)arg ?
2009		    (1<<ddi_ffs(attr->dma_attr_burstsizes)-1) :
2010		    (1<<(ddi_fls(attr->dma_attr_burstsizes)-1))));
2011
2012		return (ddi_ctlops(self, child, op, arg, result));
2013
2014	case DDI_CTLOPS_SIDDEV:
2015		return (ndi_dev_is_persistent_node(child) ?
2016		    DDI_SUCCESS : DDI_FAILURE);
2017
2018	/* XXX these should be handled */
2019	case DDI_CTLOPS_POWER:
2020		return (DDI_SUCCESS);
2021
2022	/*
2023	 * These ops correspond to functions that "shouldn't" be called
2024	 * by a SCSI target driver. So we whine when we're called.
2025	 */
2026	case DDI_CTLOPS_DMAPMAPC:
2027	case DDI_CTLOPS_REPORTINT:
2028	case DDI_CTLOPS_REGSIZE:
2029	case DDI_CTLOPS_NREGS:
2030	case DDI_CTLOPS_SLAVEONLY:
2031	case DDI_CTLOPS_AFFINITY:
2032	case DDI_CTLOPS_POKE:
2033	case DDI_CTLOPS_PEEK:
2034		SCSI_HBA_LOG((_LOG(WARN), self, NULL, "invalid op (%d)", op));
2035		return (DDI_FAILURE);
2036
2037	/* Everything else we pass up */
2038	case DDI_CTLOPS_PTOB:
2039	case DDI_CTLOPS_BTOP:
2040	case DDI_CTLOPS_BTOPR:
2041	case DDI_CTLOPS_DVMAPAGESIZE:
2042	default:
2043		return (ddi_ctlops(self, child, op, arg, result));
2044	}
2045}
2046
2047/*
2048 * Private wrapper for scsi_pkt's allocated via scsi_hba_pkt_alloc()
2049 */
2050struct scsi_pkt_wrapper {
2051	struct scsi_pkt		scsi_pkt;
2052	int			pkt_wrapper_magic;
2053	int			pkt_wrapper_len;
2054};
2055
2056#if !defined(lint)
2057_NOTE(SCHEME_PROTECTS_DATA("unique per thread", scsi_pkt_wrapper))
2058_NOTE(SCHEME_PROTECTS_DATA("Unshared Data", dev_ops))
2059#endif
2060
2061/*
2062 * Called by an HBA to allocate a scsi_pkt
2063 */
2064/*ARGSUSED*/
2065struct scsi_pkt *
2066scsi_hba_pkt_alloc(
2067	dev_info_t		*dip,
2068	struct scsi_address	*ap,
2069	int			cmdlen,
2070	int			statuslen,
2071	int			tgtlen,
2072	int			hbalen,
2073	int			(*callback)(caddr_t arg),
2074	caddr_t			arg)
2075{
2076	struct scsi_pkt		*pkt;
2077	struct scsi_pkt_wrapper	*hba_pkt;
2078	caddr_t			p;
2079	int			acmdlen, astatuslen, atgtlen, ahbalen;
2080	int			pktlen;
2081
2082	/* Sanity check */
2083	if (callback != SLEEP_FUNC && callback != NULL_FUNC)
2084		SCSI_HBA_LOG((_LOG(WARN), dip, NULL,
2085		    "callback must be SLEEP_FUNC or NULL_FUNC"));
2086
2087	/*
2088	 * Round up so everything gets allocated on long-word boundaries
2089	 */
2090	acmdlen = ROUNDUP(cmdlen);
2091	astatuslen = ROUNDUP(statuslen);
2092	atgtlen = ROUNDUP(tgtlen);
2093	ahbalen = ROUNDUP(hbalen);
2094	pktlen = sizeof (struct scsi_pkt_wrapper) +
2095	    acmdlen + astatuslen + atgtlen + ahbalen;
2096
2097	hba_pkt = kmem_zalloc(pktlen,
2098	    (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP);
2099	if (hba_pkt == NULL) {
2100		ASSERT(callback == NULL_FUNC);
2101		return (NULL);
2102	}
2103
2104	/*
2105	 * Set up our private info on this pkt
2106	 */
2107	hba_pkt->pkt_wrapper_len = pktlen;
2108	hba_pkt->pkt_wrapper_magic = PKT_WRAPPER_MAGIC;	/* alloced correctly */
2109	pkt = &hba_pkt->scsi_pkt;
2110
2111	/*
2112	 * Set up pointers to private data areas, cdb, and status.
2113	 */
2114	p = (caddr_t)(hba_pkt + 1);
2115	if (hbalen > 0) {
2116		pkt->pkt_ha_private = (opaque_t)p;
2117		p += ahbalen;
2118	}
2119	if (tgtlen > 0) {
2120		pkt->pkt_private = (opaque_t)p;
2121		p += atgtlen;
2122	}
2123	if (statuslen > 0) {
2124		pkt->pkt_scbp = (uchar_t *)p;
2125		p += astatuslen;
2126	}
2127	if (cmdlen > 0) {
2128		pkt->pkt_cdbp = (uchar_t *)p;
2129	}
2130
2131	/*
2132	 * Initialize the pkt's scsi_address
2133	 */
2134	pkt->pkt_address = *ap;
2135
2136	/*
2137	 * NB: It may not be safe for drivers, esp target drivers, to depend
2138	 * on the following fields being set until all the scsi_pkt
2139	 * allocation violations discussed in scsi_pkt.h are all resolved.
2140	 */
2141	pkt->pkt_cdblen = cmdlen;
2142	pkt->pkt_tgtlen = tgtlen;
2143	pkt->pkt_scblen = statuslen;
2144
2145	return (pkt);
2146}
2147
2148/*
2149 * Called by an HBA to free a scsi_pkt
2150 */
2151/*ARGSUSED*/
2152void
2153scsi_hba_pkt_free(
2154	struct scsi_address	*ap,
2155	struct scsi_pkt		*pkt)
2156{
2157	kmem_free(pkt, ((struct scsi_pkt_wrapper *)pkt)->pkt_wrapper_len);
2158}
2159
2160/*
2161 * Return 1 if the scsi_pkt used a proper allocator.
2162 *
2163 * The DDI does not allow a driver to allocate it's own scsi_pkt(9S), a
2164 * driver should not have *any* compiled in dependencies on "sizeof (struct
2165 * scsi_pkt)". While this has been the case for many years, a number of
2166 * drivers have still not been fixed. This function can be used to detect
2167 * improperly allocated scsi_pkt structures, and produce messages identifying
2168 * drivers that need to be fixed.
2169 *
2170 * While drivers in violation are being fixed, this function can also
2171 * be used by the framework to detect packets that violated allocation
2172 * rules.
2173 *
2174 * NB: It is possible, but very unlikely, for this code to return a false
2175 * positive (finding correct magic, but for wrong reasons).  Careful
2176 * consideration is needed for callers using this interface to condition
2177 * access to newer scsi_pkt fields (those after pkt_reason).
2178 *
2179 * NB: As an aid to minimizing the amount of work involved in 'fixing' legacy
2180 * drivers that violate scsi_*(9S) allocation rules, private
2181 * scsi_pkt_size()/scsi_size_clean() functions are available (see their
2182 * implementation for details).
2183 *
2184 * *** Non-legacy use of scsi_pkt_size() is discouraged. ***
2185 *
2186 * NB: When supporting broken HBA drivers is not longer a concern, this
2187 * code should be removed.
2188 */
2189int
2190scsi_pkt_allocated_correctly(struct scsi_pkt *pkt)
2191{
2192	struct scsi_pkt_wrapper	*hba_pkt = (struct scsi_pkt_wrapper *)pkt;
2193	int	magic;
2194	major_t	major;
2195#ifdef	DEBUG
2196	int	*pspwm, *pspcwm;
2197
2198	/*
2199	 * We are getting scsi packets from two 'correct' wrapper schemes,
2200	 * make sure we are looking at the same place in both to detect
2201	 * proper allocation.
2202	 */
2203	pspwm = &((struct scsi_pkt_wrapper *)0)->pkt_wrapper_magic;
2204	pspcwm = &((struct scsi_pkt_cache_wrapper *)0)->pcw_magic;
2205	ASSERT(pspwm == pspcwm);
2206#endif	/* DEBUG */
2207
2208
2209	/*
2210	 * Check to see if driver is scsi_size_clean(), assume it
2211	 * is using the scsi_pkt_size() interface everywhere it needs to
2212	 * if the driver indicates it is scsi_size_clean().
2213	 */
2214	major = ddi_driver_major(P_TO_TRAN(pkt)->tran_hba_dip);
2215	if (devnamesp[major].dn_flags & DN_SCSI_SIZE_CLEAN)
2216		return (1);		/* ok */
2217
2218	/*
2219	 * Special case crossing a page boundary. If the scsi_pkt was not
2220	 * allocated correctly, then across a page boundary we have a
2221	 * fault hazard.
2222	 */
2223	if ((((uintptr_t)(&hba_pkt->scsi_pkt)) & MMU_PAGEMASK) ==
2224	    (((uintptr_t)(&hba_pkt->pkt_wrapper_magic)) & MMU_PAGEMASK)) {
2225		/* fastpath, no cross-page hazard */
2226		magic = hba_pkt->pkt_wrapper_magic;
2227	} else {
2228		/* add protection for cross-page hazard */
2229		if (ddi_peek32((dev_info_t *)NULL,
2230		    &hba_pkt->pkt_wrapper_magic, &magic) == DDI_FAILURE) {
2231			return (0);	/* violation */
2232		}
2233	}
2234
2235	/* properly allocated packet always has correct magic */
2236	return ((magic == PKT_WRAPPER_MAGIC) ? 1 : 0);
2237}
2238
2239/*
2240 * Private interfaces to simplify conversion of legacy drivers so they don't
2241 * depend on scsi_*(9S) size. Instead of using these private interface, HBA
2242 * drivers should use DDI sanctioned allocation methods:
2243 *
2244 *	scsi_pkt	Use scsi_hba_pkt_alloc(9F), or implement
2245 *			tran_setup_pkt(9E).
2246 *
2247 *	scsi_device	You are doing something strange/special, a scsi_device
2248 *			structure should only be allocated by scsi_hba.c
2249 *			initchild code or scsi_vhci.c code.
2250 *
2251 *	scsi_hba_tran	Use scsi_hba_tran_alloc(9F).
2252 */
2253size_t
2254scsi_pkt_size()
2255{
2256	return (sizeof (struct scsi_pkt));
2257}
2258
2259size_t
2260scsi_hba_tran_size()
2261{
2262	return (sizeof (scsi_hba_tran_t));
2263}
2264
2265size_t
2266scsi_device_size()
2267{
2268	return (sizeof (struct scsi_device));
2269}
2270
2271/*
2272 * Legacy compliance to scsi_pkt(9S) allocation rules through use of
2273 * scsi_pkt_size() is detected by the 'scsi-size-clean' driver.conf property
2274 * or an HBA driver calling to scsi_size_clean() from attach(9E).  A driver
2275 * developer should only indicate that a legacy driver is clean after using
2276 * SCSI_SIZE_CLEAN_VERIFY to ensure compliance (see scsi_pkt.h).
2277 */
2278void
2279scsi_size_clean(dev_info_t *dip)
2280{
2281	major_t		major;
2282	struct devnames	*dnp;
2283
2284	ASSERT(dip);
2285	major = ddi_driver_major(dip);
2286	ASSERT(major < devcnt);
2287	if (major >= devcnt) {
2288		SCSI_HBA_LOG((_LOG(WARN), dip, NULL,
2289		    "scsi_pkt_size: bogus major: %d", major));
2290		return;
2291	}
2292
2293	/* Set DN_SCSI_SIZE_CLEAN flag in dn_flags. */
2294	dnp = &devnamesp[major];
2295	if ((dnp->dn_flags & DN_SCSI_SIZE_CLEAN) == 0) {
2296		LOCK_DEV_OPS(&dnp->dn_lock);
2297		dnp->dn_flags |= DN_SCSI_SIZE_CLEAN;
2298		UNLOCK_DEV_OPS(&dnp->dn_lock);
2299	}
2300}
2301
2302
2303/*
2304 * Called by an HBA to map strings to capability indices
2305 */
2306int
2307scsi_hba_lookup_capstr(
2308	char			*capstr)
2309{
2310	/*
2311	 * Capability strings: only add entries to mask the legacy
2312	 * '_' vs. '-' misery.  All new capabilities should use '-',
2313	 * and be captured be added to SCSI_CAP_ASCII.
2314	 */
2315	static struct cap_strings {
2316		char	*cap_string;
2317		int	cap_index;
2318	} cap_strings[] = {
2319		{ "dma_max",		SCSI_CAP_DMA_MAX		},
2320		{ "msg_out",		SCSI_CAP_MSG_OUT		},
2321		{ "wide_xfer",		SCSI_CAP_WIDE_XFER		},
2322		{ NULL,			0				}
2323	};
2324	static char		*cap_ascii[] = SCSI_CAP_ASCII;
2325	char			**cap;
2326	int			i;
2327	struct cap_strings	*cp;
2328
2329	for (cap = cap_ascii, i = 0; *cap != NULL; cap++, i++)
2330		if (strcmp(*cap, capstr) == 0)
2331			return (i);
2332
2333	for (cp = cap_strings; cp->cap_string != NULL; cp++)
2334		if (strcmp(cp->cap_string, capstr) == 0)
2335			return (cp->cap_index);
2336
2337	return (-1);
2338}
2339
2340/*
2341 * Called by an HBA to determine if the system is in 'panic' state.
2342 */
2343int
2344scsi_hba_in_panic()
2345{
2346	return (panicstr != NULL);
2347}
2348
2349/*
2350 * If a SCSI target driver attempts to mmap memory,
2351 * the buck stops here.
2352 */
2353/*ARGSUSED*/
2354static int
2355scsi_hba_map_fault(
2356	dev_info_t		*dip,
2357	dev_info_t		*child,
2358	struct hat		*hat,
2359	struct seg		*seg,
2360	caddr_t			addr,
2361	struct devpage		*dp,
2362	pfn_t			pfn,
2363	uint_t			prot,
2364	uint_t			lock)
2365{
2366	return (DDI_FAILURE);
2367}
2368
2369static int
2370scsi_hba_get_eventcookie(
2371	dev_info_t		*self,
2372	dev_info_t		*child,
2373	char			*name,
2374	ddi_eventcookie_t	*eventp)
2375{
2376	scsi_hba_tran_t		*tran;
2377
2378	tran = ddi_get_driver_private(self);
2379	if (tran->tran_get_eventcookie &&
2380	    ((*tran->tran_get_eventcookie)(self,
2381	    child, name, eventp) == DDI_SUCCESS)) {
2382		return (DDI_SUCCESS);
2383	}
2384
2385	return (ndi_busop_get_eventcookie(self, child, name, eventp));
2386}
2387
2388static int
2389scsi_hba_add_eventcall(
2390	dev_info_t		*self,
2391	dev_info_t		*child,
2392	ddi_eventcookie_t	event,
2393	void			(*callback)(
2394					dev_info_t *self,
2395					ddi_eventcookie_t event,
2396					void *arg,
2397					void *bus_impldata),
2398	void			*arg,
2399	ddi_callback_id_t	*cb_id)
2400{
2401	scsi_hba_tran_t		*tran;
2402
2403	tran = ddi_get_driver_private(self);
2404	if (tran->tran_add_eventcall &&
2405	    ((*tran->tran_add_eventcall)(self, child,
2406	    event, callback, arg, cb_id) == DDI_SUCCESS)) {
2407		return (DDI_SUCCESS);
2408	}
2409
2410	return (DDI_FAILURE);
2411}
2412
2413static int
2414scsi_hba_remove_eventcall(dev_info_t *self, ddi_callback_id_t cb_id)
2415{
2416	scsi_hba_tran_t		*tran;
2417	ASSERT(cb_id);
2418
2419	tran = ddi_get_driver_private(self);
2420	if (tran->tran_remove_eventcall &&
2421	    ((*tran->tran_remove_eventcall)(
2422	    self, cb_id) == DDI_SUCCESS)) {
2423		return (DDI_SUCCESS);
2424	}
2425
2426	return (DDI_FAILURE);
2427}
2428
2429static int
2430scsi_hba_post_event(
2431	dev_info_t		*self,
2432	dev_info_t		*child,
2433	ddi_eventcookie_t	event,
2434	void			*bus_impldata)
2435{
2436	scsi_hba_tran_t		*tran;
2437
2438	tran = ddi_get_driver_private(self);
2439	if (tran->tran_post_event &&
2440	    ((*tran->tran_post_event)(self,
2441	    child, event, bus_impldata) == DDI_SUCCESS)) {
2442		return (DDI_SUCCESS);
2443	}
2444
2445	return (DDI_FAILURE);
2446}
2447
2448/*
2449 * Default getinfo(9e) for scsi_hba
2450 */
2451/* ARGSUSED */
2452static int
2453scsi_hba_info(dev_info_t *self, ddi_info_cmd_t infocmd, void *arg,
2454    void **result)
2455{
2456	int error = DDI_SUCCESS;
2457
2458	switch (infocmd) {
2459	case DDI_INFO_DEVT2INSTANCE:
2460		*result = (void *)(intptr_t)(MINOR2INST(getminor((dev_t)arg)));
2461		break;
2462	default:
2463		error = DDI_FAILURE;
2464	}
2465	return (error);
2466}
2467
2468/*
2469 * Default open and close routine for scsi_hba
2470 */
2471/* ARGSUSED */
2472int
2473scsi_hba_open(dev_t *devp, int flags, int otyp, cred_t *credp)
2474{
2475	dev_info_t	*self;
2476	scsi_hba_tran_t	*tran;
2477	int		rv = 0;
2478
2479	if (otyp != OTYP_CHR)
2480		return (EINVAL);
2481
2482	if ((self = e_ddi_hold_devi_by_dev(*devp, 0)) == NULL)
2483		return (ENXIO);
2484
2485	tran = ddi_get_driver_private(self);
2486	if (tran == NULL) {
2487		ddi_release_devi(self);
2488		return (ENXIO);
2489	}
2490
2491	/*
2492	 * tran_open_flag bit field:
2493	 *	0:	closed
2494	 *	1:	shared open by minor at bit position
2495	 *	1 at 31st bit:	exclusive open
2496	 */
2497	mutex_enter(&(tran->tran_open_lock));
2498	if (flags & FEXCL) {
2499		if (tran->tran_open_flag != 0) {
2500			rv = EBUSY;		/* already open */
2501		} else {
2502			tran->tran_open_flag = TRAN_OPEN_EXCL;
2503		}
2504	} else {
2505		if (tran->tran_open_flag == TRAN_OPEN_EXCL) {
2506			rv = EBUSY;		/* already excl. open */
2507		} else {
2508			int minor = getminor(*devp) & TRAN_MINOR_MASK;
2509			tran->tran_open_flag |= (1 << minor);
2510			/*
2511			 * Ensure that the last framework reserved minor
2512			 * is unused. Otherwise, the exclusive open
2513			 * mechanism may break.
2514			 */
2515			ASSERT(minor != 31);
2516		}
2517	}
2518	mutex_exit(&(tran->tran_open_lock));
2519
2520	ddi_release_devi(self);
2521	return (rv);
2522}
2523
2524/* ARGSUSED */
2525int
2526scsi_hba_close(dev_t dev, int flag, int otyp, cred_t *credp)
2527{
2528	dev_info_t	*self;
2529	scsi_hba_tran_t	*tran;
2530
2531	if (otyp != OTYP_CHR)
2532		return (EINVAL);
2533
2534	if ((self = e_ddi_hold_devi_by_dev(dev, 0)) == NULL)
2535		return (ENXIO);
2536
2537	tran = ddi_get_driver_private(self);
2538	if (tran == NULL) {
2539		ddi_release_devi(self);
2540		return (ENXIO);
2541	}
2542
2543	mutex_enter(&(tran->tran_open_lock));
2544	if (tran->tran_open_flag == TRAN_OPEN_EXCL) {
2545		tran->tran_open_flag = 0;
2546	} else {
2547		int minor = getminor(dev) & TRAN_MINOR_MASK;
2548		tran->tran_open_flag &= ~(1 << minor);
2549	}
2550	mutex_exit(&(tran->tran_open_lock));
2551
2552	ddi_release_devi(self);
2553	return (0);
2554}
2555
2556/*
2557 * standard ioctl commands for SCSI hotplugging
2558 */
2559/* ARGSUSED */
2560int
2561scsi_hba_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
2562	int *rvalp)
2563{
2564	dev_info_t		*self;
2565	struct devctl_iocdata	*dcp = NULL;
2566	dev_info_t		*child = NULL;
2567	struct scsi_device	*sd;
2568	scsi_hba_tran_t		*tran;
2569	uint_t			bus_state;
2570	int			rv = 0;
2571	int			circ;
2572
2573	if ((self = e_ddi_hold_devi_by_dev(dev, 0)) == NULL) {
2574		rv = ENXIO;
2575		goto out;
2576	}
2577
2578	if ((tran = ddi_get_driver_private(self)) == NULL) {
2579		rv = ENXIO;
2580		goto out;
2581	}
2582
2583	/* Ioctls for which the generic implementation suffices. */
2584	switch (cmd) {
2585	case DEVCTL_DEVICE_GETSTATE:
2586	case DEVCTL_DEVICE_ONLINE:
2587	case DEVCTL_DEVICE_OFFLINE:
2588	case DEVCTL_DEVICE_REMOVE:
2589	case DEVCTL_BUS_GETSTATE:
2590		rv = ndi_devctl_ioctl(self, cmd, arg, mode, 0);
2591		goto out;
2592	}
2593
2594	/* read devctl ioctl data */
2595	if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS) {
2596		rv = EFAULT;
2597		goto out;
2598	}
2599
2600	/* Ioctls that require child identification */
2601	switch (cmd) {
2602	case DEVCTL_DEVICE_RESET:
2603		/* child identification from unit-address */
2604		if (ndi_dc_getname(dcp) == NULL ||
2605		    ndi_dc_getaddr(dcp) == NULL) {
2606			rv = EINVAL;
2607			goto out;
2608		}
2609
2610		ndi_devi_enter(self, &circ);
2611		child = ndi_devi_find(self,
2612		    ndi_dc_getname(dcp), ndi_dc_getaddr(dcp));
2613		if (child == NULL) {
2614			ndi_devi_exit(self, circ);
2615			rv = ENXIO;
2616			goto out;
2617		}
2618		ndi_hold_devi(child);
2619		ndi_devi_exit(self, circ);
2620		break;
2621
2622	case DEVCTL_BUS_RESETALL:
2623		/*
2624		 * Find a child's scsi_address so we can invoke tran_reset
2625		 * below.
2626		 *
2627		 * XXX If no child exists, one may to able to fake a child.
2628		 *	This will be a enhancement for the future.
2629		 *	For now, we fall back to BUS_RESET.
2630		 * XXX We sould be looking at node state to get one
2631		 *	that is initialized...
2632		 */
2633		ndi_devi_enter(self, &circ);
2634		child = ddi_get_child(self);
2635		sd = NULL;
2636		while (child) {
2637			/* XXX verify scsi_device 'flavor' of child */
2638			if ((sd = ddi_get_driver_private(child)) != NULL) {
2639				ndi_hold_devi(child);
2640				break;
2641			}
2642			child = ddi_get_next_sibling(child);
2643		}
2644		ndi_devi_exit(self, circ);
2645		break;
2646	}
2647
2648	switch (cmd) {
2649	case DEVCTL_DEVICE_RESET:
2650		ASSERT(child);
2651		if (tran->tran_reset == NULL)
2652			rv = ENOTSUP;
2653		else {
2654			sd = ddi_get_driver_private(child);
2655			/* XXX verify scsi_device 'flavor' of child */
2656			if ((sd == NULL) ||
2657			    (tran->tran_reset(&sd->sd_address,
2658			    RESET_TARGET) != 1))
2659				rv = EIO;
2660		}
2661		break;
2662
2663	case DEVCTL_BUS_QUIESCE:
2664		if ((ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) &&
2665		    (bus_state == BUS_QUIESCED))
2666			rv = EALREADY;
2667		else if (tran->tran_quiesce == NULL)
2668			rv = ENOTSUP;
2669		else if ((*tran->tran_quiesce)(self) != 0)
2670			rv = EIO;
2671		else
2672			(void) ndi_set_bus_state(self, BUS_QUIESCED);
2673		break;
2674
2675	case DEVCTL_BUS_UNQUIESCE:
2676		if ((ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) &&
2677		    (bus_state == BUS_ACTIVE))
2678			rv = EALREADY;
2679		else if (tran->tran_unquiesce == NULL)
2680			rv = ENOTSUP;
2681		else if ((*tran->tran_unquiesce)(self) != 0)
2682			rv = EIO;
2683		else
2684			(void) ndi_set_bus_state(self, BUS_ACTIVE);
2685		break;
2686
2687	case DEVCTL_BUS_RESET:
2688		if (tran->tran_bus_reset == NULL)
2689			rv = ENOTSUP;
2690		else if ((*tran->tran_bus_reset)(self, RESET_BUS) != 1)
2691			rv = EIO;
2692		break;
2693
2694	case DEVCTL_BUS_RESETALL:
2695		if (tran->tran_reset == NULL) {
2696			rv = ENOTSUP;
2697		} else {
2698			if (sd) {
2699				if ((*tran->tran_reset)
2700				    (&sd->sd_address, RESET_ALL) != 1)
2701					rv = EIO;
2702			} else {
2703				if ((tran->tran_bus_reset == NULL) ||
2704				    ((*tran->tran_bus_reset)
2705				    (self, RESET_BUS) != 1))
2706					rv = EIO;
2707			}
2708		}
2709		break;
2710
2711	case DEVCTL_BUS_CONFIGURE:
2712		if (ndi_devi_config(self, NDI_DEVFS_CLEAN|
2713		    NDI_DEVI_PERSIST|NDI_CONFIG_REPROBE) != NDI_SUCCESS) {
2714			rv = EIO;
2715		}
2716		break;
2717
2718	case DEVCTL_BUS_UNCONFIGURE:
2719		if (ndi_devi_unconfig(self,
2720		    NDI_DEVI_REMOVE|NDI_DEVFS_CLEAN) != NDI_SUCCESS) {
2721			rv = EBUSY;
2722		}
2723		break;
2724
2725	default:
2726		rv = ENOTTY;
2727	}
2728
2729out:	if (child)
2730		ndi_rele_devi(child);
2731	if (dcp)
2732		ndi_dc_freehdl(dcp);
2733	if (self)
2734		ddi_release_devi(self);
2735	return (rv);
2736}
2737
2738/*ARGSUSED*/
2739static int
2740scsi_hba_fm_init_child(dev_info_t *self, dev_info_t *child, int cap,
2741    ddi_iblock_cookie_t *ibc)
2742{
2743	scsi_hba_tran_t	*tran = ddi_get_driver_private(self);
2744
2745	return (tran ? tran->tran_fm_capable : scsi_fm_capable);
2746}
2747
2748static int
2749scsi_hba_bus_power(dev_info_t *self, void *impl_arg, pm_bus_power_op_t op,
2750    void *arg, void *result)
2751{
2752	scsi_hba_tran_t	*tran;
2753
2754	tran = ddi_get_driver_private(self);
2755	if (tran && tran->tran_bus_power) {
2756		return (tran->tran_bus_power(self, impl_arg,
2757		    op, arg, result));
2758	}
2759
2760	return (pm_busop_bus_power(self, impl_arg, op, arg, result));
2761}
2762
2763/*
2764 * Return the lun from an address string. Either the lun is after the
2765 * first ',' or the entire addr is the lun. Return SCSI_LUN64_ILLEGAL
2766 * if the format is incorrect.
2767 *
2768 * If the addr specified has incorrect syntax (busconfig one of
2769 * bogus /devices path) then scsi_addr_to_lun64 can return SCSI_LUN64_ILLEGAL.
2770 */
2771scsi_lun64_t
2772scsi_addr_to_lun64(char *addr)
2773{
2774	scsi_lun64_t	lun64;
2775	char		*s;
2776	int		i;
2777
2778	if (addr) {
2779		s = strchr(addr, ',');			/* "addr,lun[,sfunc]" */
2780		if (s)
2781			s++;				/* skip ',' */
2782		else
2783			s = addr;			/* "lun" */
2784
2785		for (lun64 = 0, i = 0; *s && (i < 16); s++, i++) {
2786			if (*s >= '0' && *s <= '9')
2787				lun64 = (lun64 << 4) + (*s - '0');
2788			else if (*s >= 'A' && *s <= 'F')
2789				lun64 = (lun64 << 4) + 10 + (*s - 'A');
2790			else if (*s >= 'a' && *s <= 'f')
2791				lun64 = (lun64 << 4) + 10 + (*s - 'a');
2792			else
2793				break;
2794		}
2795		if (*s && (*s != ','))		/* addr,lun[,sfunc] is OK */
2796			lun64 = SCSI_LUN64_ILLEGAL;
2797	} else
2798		lun64 = SCSI_LUN64_ILLEGAL;
2799
2800	if (lun64 == SCSI_LUN64_ILLEGAL)
2801		SCSI_HBA_LOG((_LOG(2), NULL, NULL,
2802		    "addr_to_lun64 %s lun %" PRIlun64,
2803		    addr ? addr : "NULL", lun64));
2804	return (lun64);
2805}
2806
2807/*
2808 * Convert scsi ascii string data to NULL terminated (semi) legal IEEE 1275
2809 * "compatible" (name) property form.
2810 *
2811 * For ASCII INQUIRY data, a one-way conversion algorithm is needed to take
2812 * SCSI_ASCII (20h - 7Eh) to a 1275-like compatible form. The 1275 spec allows
2813 * letters, digits, one ",", and ". _ + -", all limited by a maximum 31
2814 * character length. Since ", ." are used as separators in the compatible
2815 * string itself, they are converted to "_". All SCSI_ASCII characters that
2816 * are illegal in 1275, as well as any illegal SCSI_ASCII characters
2817 * encountered, are converted to "_". To reduce length, trailing blanks are
2818 * trimmed from SCSI_ASCII fields prior to conversion.
2819 *
2820 * Example: SCSI_ASCII "ST32550W SUN2.1G" -> "ST32550W_SUN2_1G"
2821 *
2822 * NOTE: the 1275 string form is always less than or equal to the scsi form.
2823 */
2824static char *
2825string_scsi_to_1275(char *s_1275, char *s_scsi, int len)
2826{
2827	(void) strncpy(s_1275, s_scsi, len);
2828	s_1275[len--] = '\0';
2829
2830	while (len >= 0) {
2831		if (s_1275[len] == ' ')
2832			s_1275[len--] = '\0';	/* trim trailing " " */
2833		else
2834			break;
2835	}
2836
2837	while (len >= 0) {
2838		if (((s_1275[len] >= 'a') && (s_1275[len] <= 'z')) ||
2839		    ((s_1275[len] >= 'A') && (s_1275[len] <= 'Z')) ||
2840		    ((s_1275[len] >= '0') && (s_1275[len] <= '9')) ||
2841		    (s_1275[len] == '_') ||
2842		    (s_1275[len] == '+') ||
2843		    (s_1275[len] == '-'))
2844			len--;			/* legal 1275  */
2845		else
2846			s_1275[len--] = '_';	/* illegal SCSI_ASCII | 1275 */
2847	}
2848
2849	return (s_1275);
2850}
2851
2852/*
2853 * Given the inquiry data, binding_set, and dtype_node for a scsi device,
2854 * return the nodename and compatible property for the device. The "compatible"
2855 * concept comes from IEEE-1275. The compatible information is returned is in
2856 * the correct form for direct use defining the "compatible" string array
2857 * property. Internally, "compatible" is also used to determine the nodename
2858 * to return.
2859 *
2860 * This function is provided as a separate entry point for use by drivers that
2861 * currently issue their own non-SCSA inquiry command and perform their own
2862 * node creation based their own private compiled in tables. Converting these
2863 * drivers to use this interface provides a quick easy way of obtaining
2864 * consistency as well as the flexibility associated with the 1275 techniques.
2865 *
2866 * The dtype_node is passed as a separate argument (instead of having the
2867 * implementation use inq_dtype). It indicates that information about
2868 * a secondary function embedded service should be produced.
2869 *
2870 * Callers must always use scsi_hba_nodename_compatible_free, even if
2871 * *nodenamep is null, to free the nodename and compatible information
2872 * when done.
2873 *
2874 * If a nodename can't be determined then **compatiblep will point to a
2875 * diagnostic string containing all the compatible forms.
2876 *
2877 * NOTE: some compatible strings may violate the 31 character restriction
2878 * imposed by IEEE-1275. This is not a problem because Solaris does not care
2879 * about this 31 character limit.
2880 *
2881 * Each compatible form belongs to a form-group.  The form-groups currently
2882 * defined are generic ("scsiclass"), binding-set ("scsa.b"), and failover
2883 * ("scsa.f").
2884 *
2885 * The following compatible forms, in high to low precedence
2886 * order, are defined for SCSI target device nodes.
2887 *
2888 *  scsiclass,DDEEFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR	(1 *1&2)
2889 *  scsiclass,DDEE.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR	(2 *1)
2890 *  scsiclass,DDFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR	(3 *2)
2891 *  scsiclass,DD.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR	(4)
2892 *  scsiclass,DDEEFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP	(5 *1&2)
2893 *  scsiclass,DDEE.vVVVVVVVV.pPPPPPPPPPPPPPPPP		(6 *1)
2894 *  scsiclass,DDFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP		(7 *2)
2895 *  scsiclass,DD.vVVVVVVVV.pPPPPPPPPPPPPPPPP		(8)
2896 *  scsa,DD.bBBBBBBBB					(8.5 *3)
2897 *  scsiclass,DDEEFFF					(9 *1&2)
2898 *  scsiclass,DDEE					(10 *1)
2899 *  scsiclass,DDFFF					(11 *2)
2900 *  scsiclass,DD					(12)
2901 *  scsa.fFFF						(12.5 *4)
2902 *  scsiclass						(13)
2903 *
2904 *	  *1 only produced on a secondary function node
2905 *	  *2 only produced when generic form-group flags exist.
2906 *	  *3 only produced when binding-set form-group legacy support is needed
2907 *	  *4 only produced when failover form-group flags exist.
2908 *
2909 *	where:
2910 *
2911 *	v                       is the letter 'v'. Denotest the
2912 *				beginning of VVVVVVVV.
2913 *
2914 *	VVVVVVVV                Translated scsi_vendor.
2915 *
2916 *	p                       is the letter 'p'. Denotes the
2917 *				beginning of PPPPPPPPPPPPPPPP.
2918 *
2919 *	PPPPPPPPPPPPPPPP	Translated scsi_product.
2920 *
2921 *	r                       is the letter 'r'. Denotes the
2922 *				beginning of RRRR.
2923 *
2924 *	RRRR                    Translated scsi_revision.
2925 *
2926 *	DD                      is a two digit ASCII hexadecimal
2927 *				number. The value of the two digits is
2928 *				based one the SCSI "Peripheral device
2929 *				type" command set associated with the
2930 *				node. On a primary node this is the
2931 *				scsi_dtype of the primary command set,
2932 *				on a secondary node this is the
2933 *				scsi_dtype associated with the embedded
2934 *				function command set.
2935 *
2936 *	EE                      Same encoding used for DD. This form is
2937 *				only generated on secondary function
2938 *				nodes. The DD function is embedded in
2939 *				an EE device.
2940 *
2941 *	FFF                     Concatenation, in alphabetical order,
2942 *				of the flag characters within a form-group.
2943 *				For a given form-group, the following
2944 *				flags are defined.
2945 *
2946 *				scsiclass: (generic form-group):
2947 *				  R	Removable_Media: Used when
2948 *					inq_rmb is set.
2949 *
2950 *				scsa.f:	(failover form-group):
2951 *				  E	Explicit Target_Port_Group: Used
2952 *					when inq_tpgse is set and 'G' is
2953 *					alse present.
2954 *				  G	GUID: Used when a GUID can be
2955 *					generated for the device.
2956 *				  I	Implicit Target_Port_Group: Used
2957 *					when inq_tpgs is set and 'G' is
2958 *					also present.
2959 *
2960 *				Forms using FFF are only be generated
2961 *				if there are applicable flag
2962 *				characters.
2963 *
2964 *	b                       is the letter 'b'. Denotes the
2965 *				beginning of BBBBBBBB.
2966 *
2967 *	BBBBBBBB                Binding-set. Operating System Specific:
2968 *				scsi-binding-set property of HBA.
2969 */
2970#define	NCOMPAT		(1 + (13 + 2) + 1)
2971#define	COMPAT_LONGEST	(strlen( \
2972	"scsiclass,DDEEFFF.vVVVVVVVV.pPPPPPPPPPPPPPPPP.rRRRR" + 1))
2973
2974/*
2975 * Private version with extra device 'identity' arguments to allow code
2976 * to determine GUID FFF support.
2977 */
2978static void
2979scsi_hba_identity_nodename_compatible_get(struct scsi_inquiry *inq,
2980    uchar_t *inq80, size_t inq80len, uchar_t *inq83, size_t inq83len,
2981    char *binding_set, int dtype_node, char *compat0,
2982    char **nodenamep, char ***compatiblep, int *ncompatiblep)
2983{
2984	char		vid[sizeof (inq->inq_vid) + 1 ];
2985	char		pid[sizeof (inq->inq_pid) + 1];
2986	char		rev[sizeof (inq->inq_revision) + 1];
2987	char		gf[sizeof ("R\0")];
2988	char		ff[sizeof ("EGI\0")];
2989	int		dtype_device;
2990	int		ncompat;		/* number of compatible */
2991	char		**compatp;		/* compatible ptrs */
2992	int		i;
2993	char		*nname;			/* nodename */
2994	char		*dname;			/* driver name */
2995	char		**csp;
2996	char		*p;
2997	int		tlen;
2998	int		len;
2999	major_t		major;
3000	ddi_devid_t	devid;
3001	char		*guid;
3002
3003	/*
3004	 * Nodename_aliases: This table was originally designed to be
3005	 * implemented via a new nodename_aliases file - a peer to the
3006	 * driver_aliases that selects a nodename based on compatible
3007	 * forms in much the same say driver_aliases is used to select
3008	 * driver bindings from compatible forms. Each compatible form
3009	 * is an 'alias'. Until a more general need for a
3010	 * nodename_aliases file exists, which may never occur, the
3011	 * scsi mappings are described here via a compiled in table.
3012	 *
3013	 * This table contains nodename mappings for self-identifying
3014	 * scsi devices enumerated by the Solaris kernel. For a given
3015	 * device, the highest precedence "compatible" form with a
3016	 * mapping is used to select the nodename for the device. This
3017	 * will typically be a generic nodename, however in some legacy
3018	 * compatibility cases a driver nodename mapping may be selected.
3019	 *
3020	 * Because of possible breakage associated with switching SCSI
3021	 * target devices from driver nodenames to generic nodenames,
3022	 * we are currently unable to support generic nodenames for all
3023	 * SCSI devices (binding-sets). Although /devices paths are
3024	 * defined as unstable, avoiding possible breakage is
3025	 * important. Some of the newer SCSI transports (USB) already
3026	 * use generic nodenames. All new SCSI transports and target
3027	 * devices should use generic nodenames. At times this decision
3028	 * may be architecture dependent (sparc .vs. intel) based on when
3029	 * a transport was supported on a particular architecture.
3030	 *
3031	 * We provide a base set of generic nodename mappings based on
3032	 * scsiclass dtype and higher-precedence driver nodename
3033	 * mappings based on scsa "binding-set" to cover legacy
3034	 * issues. The binding-set is typically associated with
3035	 * "scsi-binding-set" property value of the HBA. The legacy
3036	 * mappings are provided independent of whether the driver they
3037	 * refer to is installed. This allows a correctly named node
3038	 * be created at discovery time, and binding to occur when/if
3039	 * an add_drv of the legacy driver occurs.
3040	 *
3041	 * We also have mappings for legacy SUN hardware that
3042	 * misidentifies itself (enclosure services which identify
3043	 * themselves as processors). All future hardware should use
3044	 * the correct dtype.
3045	 *
3046	 * As SCSI HBAs are modified to use the SCSA interfaces for
3047	 * self-identifying SCSI target devices (PSARC/2004/116) the
3048	 * nodename_aliases table (PSARC/2004/420) should be augmented
3049	 * with legacy mappings in order to maintain compatibility with
3050	 * existing /devices paths, especially for devices that house
3051	 * an OS. Failure to do this may cause upgrade problems.
3052	 * Additions for new target devices or transports should not
3053	 * add scsa binding-set compatible mappings.
3054	 */
3055	static struct nodename_aliases {
3056		char	*na_nodename;		/* nodename */
3057		char	*na_alias;		/* compatible form match */
3058	} na[] = {
3059	/* # mapping to generic nodenames based on scsi dtype */
3060		{"disk",		"scsiclass,00"},
3061		{"tape",		"scsiclass,01"},
3062		{"printer",		"scsiclass,02"},
3063		{"processor",		"scsiclass,03"},
3064		{"worm",		"scsiclass,04"},
3065		{"cdrom",		"scsiclass,05"},
3066		{"scanner",		"scsiclass,06"},
3067		{"optical-disk",	"scsiclass,07"},
3068		{"medium-changer",	"scsiclass,08"},
3069		{"obsolete",		"scsiclass,09"},
3070		{"prepress-a",		"scsiclass,0a"},
3071		{"prepress-b",		"scsiclass,0b"},
3072		{"array-controller",	"scsiclass,0c"},
3073		{"enclosure",		"scsiclass,0d"},
3074		{"disk",		"scsiclass,0e"},
3075		{"card-reader",		"scsiclass,0f"},
3076		{"bridge",		"scsiclass,10"},
3077		{"object-store",	"scsiclass,11"},
3078		{"reserved",		"scsiclass,12"},
3079		{"reserved",		"scsiclass,13"},
3080		{"reserved",		"scsiclass,14"},
3081		{"reserved",		"scsiclass,15"},
3082		{"reserved",		"scsiclass,16"},
3083		{"reserved",		"scsiclass,17"},
3084		{"reserved",		"scsiclass,18"},
3085		{"reserved",		"scsiclass,19"},
3086		{"reserved",		"scsiclass,1a"},
3087		{"reserved",		"scsiclass,1b"},
3088		{"reserved",		"scsiclass,1c"},
3089		{"reserved",		"scsiclass,1d"},
3090		{"well-known-lun",	"scsiclass,1e"},
3091		{"unknown",		"scsiclass,1f"},
3092
3093#ifdef	sparc
3094	/* # legacy mapping to driver nodenames for fcp binding-set */
3095		{"ssd",			"scsa,00.bfcp"},
3096		{"st",			"scsa,01.bfcp"},
3097		{"sgen",		"scsa,08.bfcp"},
3098		{"ses",			"scsa,0d.bfcp"},
3099
3100	/* # legacy mapping to driver nodenames for vhci binding-set */
3101		{"ssd",			"scsa,00.bvhci"},
3102		{"st",			"scsa,01.bvhci"},
3103		{"sgen",		"scsa,08.bvhci"},
3104		{"ses",			"scsa,0d.bvhci"},
3105#else	/* sparc */
3106	/* # for x86 fcp and vhci use generic nodenames */
3107#endif	/* sparc */
3108
3109#ifdef  notdef
3110	/*
3111	 * The following binding-set specific mappings are not being
3112	 * delivered at this time, but are listed here as an examples of
3113	 * the type of mappings needed.
3114	 */
3115
3116	/* # legacy mapping to driver nodenames for spi binding-set */
3117		{"sd",			"scsa,00.bspi"},
3118		{"sd",			"scsa,05.bspi"},
3119		{"sd",			"scsa,07.bspi"},
3120		{"st",			"scsa,01.bspi"},
3121		{"ses",			"scsa,0d.bspi"},
3122
3123	/* #				SUN misidentified spi hardware */
3124		{"ses",			"scsiclass,03.vSUN.pD2"},
3125		{"ses",			"scsiclass,03.vSYMBIOS.pD1000"},
3126
3127	/* # legacy mapping to driver nodenames for atapi binding-set */
3128		{"sd",			"scsa,00.batapi"},
3129		{"sd",			"scsa,05.batapi"},
3130		{"sd",			"scsa,07.batapi"},
3131		{"st",			"scsa,01.batapi"},
3132		{"unknown",		"scsa,0d.batapi"},
3133
3134	/* # legacy mapping to generic nodenames for usb binding-set */
3135		{"disk",		"scsa,05.busb"},
3136		{"disk",		"scsa,07.busb"},
3137		{"changer",		"scsa,08.busb"},
3138		{"comm",		"scsa,09.busb"},
3139		{"array_ctlr",		"scsa,0c.busb"},
3140		{"esi",			"scsa,0d.busb"},
3141#endif  /* notdef */
3142
3143	/*
3144	 * mapping nodenames for mpt based on scsi dtype
3145	 * for being compatible with the original node names
3146	 * under mpt controller
3147	 */
3148		{"sd",			"scsa,00.bmpt"},
3149		{"sd",			"scsa,05.bmpt"},
3150		{"sd",			"scsa,07.bmpt"},
3151		{"st",			"scsa,01.bmpt"},
3152		{"ses",			"scsa,0d.bmpt"},
3153		{"sgen",		"scsa,08.bmpt"},
3154		{NULL,		NULL}
3155	};
3156	struct nodename_aliases *nap;
3157
3158	ASSERT(nodenamep && compatiblep && ncompatiblep &&
3159	    (binding_set == NULL || (strlen(binding_set) <= 8)));
3160	if ((nodenamep == NULL) || (compatiblep == NULL) ||
3161	    (ncompatiblep == NULL))
3162		return;
3163
3164	/*
3165	 * In order to reduce runtime we allocate one block of memory that
3166	 * contains both the NULL terminated array of pointers to compatible
3167	 * forms and the individual compatible strings. This block is
3168	 * somewhat larger than needed, but is short lived - it only exists
3169	 * until the caller can transfer the information into the "compatible"
3170	 * string array property and call scsi_hba_nodename_compatible_free.
3171	 */
3172	tlen = NCOMPAT * COMPAT_LONGEST;
3173	compatp = kmem_alloc((NCOMPAT * sizeof (char *)) + tlen, KM_SLEEP);
3174
3175	/* convert inquiry data from SCSI ASCII to 1275 string */
3176	(void) string_scsi_to_1275(vid, inq->inq_vid,
3177	    sizeof (inq->inq_vid));
3178	(void) string_scsi_to_1275(pid, inq->inq_pid,
3179	    sizeof (inq->inq_pid));
3180	(void) string_scsi_to_1275(rev, inq->inq_revision,
3181	    sizeof (inq->inq_revision));
3182	ASSERT((strlen(vid) <= sizeof (inq->inq_vid)) &&
3183	    (strlen(pid) <= sizeof (inq->inq_pid)) &&
3184	    (strlen(rev) <= sizeof (inq->inq_revision)));
3185
3186	/*
3187	 * Form flags in ***ALPHABETICAL*** order within form-group:
3188	 *
3189	 * NOTE: When adding a new flag to an existing form-group, carefull
3190	 * consideration must be given to not breaking existing bindings
3191	 * based on that form-group.
3192	 */
3193
3194	/*
3195	 * generic form-group flags
3196	 *   R	removable:
3197	 *	Set when inq_rmb is set and for well known scsi dtypes. For a
3198	 *	bus where the entire device is removable (like USB), we expect
3199	 *	the HBA to intercept the inquiry data and set inq_rmb.
3200	 *	Since OBP does not distinguish removable media in its generic
3201	 *	name selection we avoid setting the 'R' flag if the root is not
3202	 *	yet mounted.
3203	 */
3204	i = 0;
3205	dtype_device = inq->inq_dtype & DTYPE_MASK;
3206	if (rootvp && (inq->inq_rmb ||
3207	    (dtype_device == DTYPE_WORM) ||
3208	    (dtype_device == DTYPE_RODIRECT) ||
3209	    (dtype_device == DTYPE_OPTICAL)))
3210		gf[i++] = 'R';			/* removable */
3211	gf[i] = '\0';
3212
3213	/*
3214	 * failover form-group flags
3215	 *   E	Explicit Target_Port_Group_Supported:
3216	 *	Set for a device that has a GUID if inq_tpgse also set.
3217	 *   G	GUID:
3218	 *	Set when we have identity information, can determine a devid
3219	 *	from the identity information, and can generate a guid from
3220	 *	that devid.
3221	 *   I	Implicit Target_Port_Group_Supported:
3222	 *	Set for a device that has a GUID if inq_tpgs also set.
3223	 */
3224	i = 0;
3225	if ((inq80 || inq83) &&
3226	    (ddi_devid_scsi_encode(DEVID_SCSI_ENCODE_VERSION_LATEST, NULL,
3227	    (uchar_t *)inq, sizeof (*inq), inq80, inq80len, inq83, inq83len,
3228	    &devid) == DDI_SUCCESS)) {
3229		guid = ddi_devid_to_guid(devid);
3230		ddi_devid_free(devid);
3231	} else
3232		guid = NULL;
3233	if (guid && (inq->inq_tpgs & TPGS_FAILOVER_EXPLICIT))
3234		ff[i++] = 'E';			/* EXPLICIT TPGS */
3235	if (guid)
3236		ff[i++] = 'G';			/* GUID */
3237	if (guid && (inq->inq_tpgs & TPGS_FAILOVER_IMPLICIT))
3238		ff[i++] = 'I';			/* IMPLICIT TPGS */
3239	ff[i] = '\0';
3240	if (guid)
3241		ddi_devid_free_guid(guid);
3242
3243	/*
3244	 * Construct all applicable compatible forms. See comment at the
3245	 * head of the function for a description of the compatible forms.
3246	 */
3247	csp = compatp;
3248	p = (char *)(compatp + NCOMPAT);
3249
3250	/* ( 0) driver (optional, not documented in scsi(4)) */
3251	if (compat0) {
3252		*csp++ = p;
3253		(void) snprintf(p, tlen, "%s", compat0);
3254		len = strlen(p) + 1;
3255		p += len;
3256		tlen -= len;
3257	}
3258
3259	/* ( 1) scsiclass,DDEEFFF.vV.pP.rR */
3260	if ((dtype_device != dtype_node) && *gf && *vid && *pid && *rev) {
3261		*csp++ = p;
3262		(void) snprintf(p, tlen, "scsiclass,%02x%02x%s.v%s.p%s.r%s",
3263		    dtype_node, dtype_device, gf, vid, pid, rev);
3264		len = strlen(p) + 1;
3265		p += len;
3266		tlen -= len;
3267	}
3268
3269	/* ( 2) scsiclass,DDEE.vV.pP.rR */
3270	if ((dtype_device != dtype_node) && *vid && *pid && *rev) {
3271		*csp++ = p;
3272		(void) snprintf(p, tlen, "scsiclass,%02x%02x.v%s.p%s.r%s",
3273		    dtype_node, dtype_device, vid, pid, rev);
3274		len = strlen(p) + 1;
3275		p += len;
3276		tlen -= len;
3277	}
3278
3279	/* ( 3) scsiclass,DDFFF.vV.pP.rR */
3280	if (*gf && *vid && *pid && *rev) {
3281		*csp++ = p;
3282		(void) snprintf(p, tlen, "scsiclass,%02x%s.v%s.p%s.r%s",
3283		    dtype_node, gf, vid, pid, rev);
3284		len = strlen(p) + 1;
3285		p += len;
3286		tlen -= len;
3287	}
3288
3289	/* ( 4) scsiclass,DD.vV.pP.rR */
3290	if (*vid && *pid && rev) {
3291		*csp++ = p;
3292		(void) snprintf(p, tlen, "scsiclass,%02x.v%s.p%s.r%s",
3293		    dtype_node, vid, pid, rev);
3294		len = strlen(p) + 1;
3295		p += len;
3296		tlen -= len;
3297	}
3298
3299	/* ( 5) scsiclass,DDEEFFF.vV.pP */
3300	if ((dtype_device != dtype_node) && *gf && *vid && *pid) {
3301		*csp++ = p;
3302		(void) snprintf(p, tlen, "scsiclass,%02x%02x%s.v%s.p%s",
3303		    dtype_node, dtype_device, gf, vid, pid);
3304		len = strlen(p) + 1;
3305		p += len;
3306		tlen -= len;
3307	}
3308
3309	/* ( 6) scsiclass,DDEE.vV.pP */
3310	if ((dtype_device != dtype_node) && *vid && *pid) {
3311		*csp++ = p;
3312		(void) snprintf(p, tlen, "scsiclass,%02x%02x.v%s.p%s",
3313		    dtype_node, dtype_device, vid, pid);
3314		len = strlen(p) + 1;
3315		p += len;
3316		tlen -= len;
3317	}
3318
3319	/* ( 7) scsiclass,DDFFF.vV.pP */
3320	if (*gf && *vid && *pid) {
3321		*csp++ = p;
3322		(void) snprintf(p, tlen, "scsiclass,%02x%s.v%s.p%s",
3323		    dtype_node, gf, vid, pid);
3324		len = strlen(p) + 1;
3325		p += len;
3326		tlen -= len;
3327	}
3328
3329	/* ( 8) scsiclass,DD.vV.pP */
3330	if (*vid && *pid) {
3331		*csp++ = p;
3332		(void) snprintf(p, tlen, "scsiclass,%02x.v%s.p%s",
3333		    dtype_node, vid, pid);
3334		len = strlen(p) + 1;
3335		p += len;
3336		tlen -= len;
3337	}
3338
3339	/* (8.5) scsa,DD.bB (not documented in scsi(4)) */
3340	if (binding_set) {
3341		*csp++ = p;
3342		(void) snprintf(p, tlen, "scsa,%02x.b%s",
3343		    dtype_node, binding_set);
3344		len = strlen(p) + 1;
3345		p += len;
3346		tlen -= len;
3347	}
3348
3349	/* ( 9) scsiclass,DDEEFFF */
3350	if ((dtype_device != dtype_node) && *gf) {
3351		*csp++ = p;
3352		(void) snprintf(p, tlen, "scsiclass,%02x%02x%s",
3353		    dtype_node, dtype_device, gf);
3354		len = strlen(p) + 1;
3355		p += len;
3356		tlen -= len;
3357	}
3358
3359	/* (10) scsiclass,DDEE */
3360	if (dtype_device != dtype_node) {
3361		*csp++ = p;
3362		(void) snprintf(p, tlen, "scsiclass,%02x%02x",
3363		    dtype_node, dtype_device);
3364		len = strlen(p) + 1;
3365		p += len;
3366		tlen -= len;
3367	}
3368
3369	/* (11) scsiclass,DDFFF */
3370	if (*gf) {
3371		*csp++ = p;
3372		(void) snprintf(p, tlen, "scsiclass,%02x%s",
3373		    dtype_node, gf);
3374		len = strlen(p) + 1;
3375		p += len;
3376		tlen -= len;
3377	}
3378
3379	/* (12) scsiclass,DD */
3380	*csp++ = p;
3381	(void) snprintf(p, tlen, "scsiclass,%02x", dtype_node);
3382	len = strlen(p) + 1;
3383	p += len;
3384	tlen -= len;
3385
3386	/* (12.5) scsa.fFFF */
3387	if (*ff) {
3388		*csp++ = p;
3389		(void) snprintf(p, tlen, "scsa.f%s", ff);
3390		len = strlen(p) + 1;
3391		p += len;
3392		tlen -= len;
3393	}
3394
3395	/* (13) scsiclass */
3396	*csp++ = p;
3397	(void) snprintf(p, tlen, "scsiclass");
3398	len = strlen(p) + 1;
3399	p += len;
3400	tlen -= len;
3401	ASSERT(tlen >= 0);
3402
3403	*csp = NULL;			/* NULL terminate array of pointers */
3404	ncompat = csp - compatp;
3405
3406	/*
3407	 * When determining a nodename, a nodename_aliases specified
3408	 * mapping has precedence over using a driver_aliases specified
3409	 * driver binding as a nodename.
3410	 *
3411	 * See if any of the compatible forms have a nodename_aliases
3412	 * specified nodename. These mappings are described by
3413	 * nodename_aliases entries like:
3414	 *
3415	 *	disk		"scsiclass,00"
3416	 *	enclosure	"scsiclass,03.vSYMBIOS.pD1000"
3417	 *	ssd		"scsa,00.bfcp"
3418	 *
3419	 * All nodename_aliases mappings should idealy be to generic
3420	 * names, however a higher precedence legacy mapping to a
3421	 * driver name may exist. The highest precedence mapping
3422	 * provides the nodename, so legacy driver nodename mappings
3423	 * (if they exist) take precedence over generic nodename
3424	 * mappings.
3425	 */
3426	for (nname = NULL, csp = compatp; (nname == NULL) && *csp; csp++) {
3427		for (nap = na; nap->na_nodename; nap++) {
3428			if (strcmp(*csp, nap->na_alias) == 0) {
3429				nname = nap->na_nodename;
3430				break;
3431			}
3432		}
3433	}
3434
3435	/*
3436	 * If no nodename_aliases mapping exists then use the
3437	 * driver_aliases specified driver binding as a nodename.
3438	 * Determine the driver based on compatible (which may
3439	 * have the passed in compat0 as the first item). The
3440	 * driver_aliases file has entries like
3441	 *
3442	 *	sd	"scsiclass,00"
3443	 *
3444	 * that map compatible forms to specific drivers. These
3445	 * entries are established by add_drv. We use the most specific
3446	 * driver binding as the nodename. This matches the eventual
3447	 * ddi_driver_compatible_major() binding that will be
3448	 * established by bind_node()
3449	 */
3450	if (nname == NULL) {
3451		for (dname = NULL, csp = compatp; *csp; csp++) {
3452			major = ddi_name_to_major(*csp);
3453			if ((major == (major_t)-1) ||
3454			    (devnamesp[major].dn_flags & DN_DRIVER_REMOVED))
3455				continue;
3456			if (dname = ddi_major_to_name(major))
3457				break;
3458		}
3459		nname = dname;
3460	}
3461
3462	/* return results */
3463	if (nname) {
3464		*nodenamep = kmem_alloc(strlen(nname) + 1, KM_SLEEP);
3465		(void) strcpy(*nodenamep, nname);
3466	} else {
3467		*nodenamep = NULL;
3468
3469		/*
3470		 * If no nodename could be determined return a special
3471		 * 'compatible' to be used for a diagnostic message. This
3472		 * compatible contains all compatible forms concatenated
3473		 * into a single string pointed to by the first element.
3474		 */
3475		if (nname == NULL) {
3476			for (csp = compatp; *(csp + 1); csp++)
3477				*((*csp) + strlen(*csp)) = ' ';
3478			*(compatp + 1) = NULL;
3479			ncompat = 1;
3480		}
3481
3482	}
3483	*compatiblep = compatp;
3484	*ncompatiblep = ncompat;
3485}
3486
3487void
3488scsi_hba_nodename_compatible_get(struct scsi_inquiry *inq,
3489    char *binding_set, int dtype_node, char *compat0,
3490    char **nodenamep, char ***compatiblep, int *ncompatiblep)
3491{
3492	scsi_hba_identity_nodename_compatible_get(inq,
3493	    NULL, 0, NULL, 0, binding_set, dtype_node, compat0, nodenamep,
3494	    compatiblep, ncompatiblep);
3495}
3496
3497/*
3498 * Free allocations associated with scsi_hba_nodename_compatible_get or
3499 * scsi_hba_identity_nodename_compatible_get use.
3500 */
3501void
3502scsi_hba_nodename_compatible_free(char *nodename, char **compatible)
3503{
3504	if (nodename)
3505		kmem_free(nodename, strlen(nodename) + 1);
3506
3507	if (compatible)
3508		kmem_free(compatible, (NCOMPAT * sizeof (char *)) +
3509		    (NCOMPAT * COMPAT_LONGEST));
3510}
3511
3512/* scsi_device property interfaces */
3513#define	_TYPE_DEFINED(flags)						\
3514	(((flags & SCSI_DEVICE_PROP_TYPE_MSK) == SCSI_DEVICE_PROP_PATH) || \
3515	((flags & SCSI_DEVICE_PROP_TYPE_MSK) == SCSI_DEVICE_PROP_DEVICE))
3516
3517#define	_DEVICE_PIP(sd, flags)						\
3518	((((flags & SCSI_DEVICE_PROP_TYPE_MSK) == SCSI_DEVICE_PROP_PATH) && \
3519	sd->sd_pathinfo) ? (mdi_pathinfo_t *)sd->sd_pathinfo : NULL)
3520
3521/* return the unit_address associated with a scsi_device */
3522char *
3523scsi_device_unit_address(struct scsi_device *sd)
3524{
3525	mdi_pathinfo_t	*pip;
3526
3527	ASSERT(sd && sd->sd_dev);
3528	if ((sd == NULL) || (sd->sd_dev == NULL))
3529		return (NULL);
3530
3531	pip = _DEVICE_PIP(sd, SCSI_DEVICE_PROP_PATH);
3532	if (pip)
3533		return (mdi_pi_get_addr(pip));
3534	else
3535		return (ddi_get_name_addr(sd->sd_dev));
3536}
3537
3538int
3539scsi_device_prop_get_int(struct scsi_device *sd, uint_t flags,
3540    char *name, int defval)
3541{
3542	mdi_pathinfo_t	*pip;
3543	int		v = defval;
3544	int		data;
3545	int		rv;
3546
3547	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3548	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3549	    !_TYPE_DEFINED(flags))
3550		return (v);
3551
3552	pip = _DEVICE_PIP(sd, flags);
3553	if (pip) {
3554		rv = mdi_prop_lookup_int(pip, name, &data);
3555		if (rv == DDI_PROP_SUCCESS)
3556			v = data;
3557	} else
3558		v = ddi_prop_get_int(DDI_DEV_T_ANY, sd->sd_dev,
3559		    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, name, v);
3560	return (v);
3561}
3562
3563
3564int64_t
3565scsi_device_prop_get_int64(struct scsi_device *sd, uint_t flags,
3566    char *name, int64_t defval)
3567{
3568	mdi_pathinfo_t	*pip;
3569	int64_t		v = defval;
3570	int64_t		data;
3571	int		rv;
3572
3573	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3574	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3575	    !_TYPE_DEFINED(flags))
3576		return (v);
3577
3578	pip = _DEVICE_PIP(sd, flags);
3579	if (pip) {
3580		rv = mdi_prop_lookup_int64(pip, name, &data);
3581		if (rv == DDI_PROP_SUCCESS)
3582			v = data;
3583	} else
3584		v = ddi_prop_get_int64(DDI_DEV_T_ANY, sd->sd_dev,
3585		    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, name, v);
3586	return (v);
3587}
3588
3589int
3590scsi_device_prop_lookup_byte_array(struct scsi_device *sd, uint_t flags,
3591    char *name, uchar_t **data, uint_t *nelements)
3592{
3593	mdi_pathinfo_t	*pip;
3594	int		rv;
3595
3596	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3597	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3598	    !_TYPE_DEFINED(flags))
3599		return (DDI_PROP_INVAL_ARG);
3600
3601	pip = _DEVICE_PIP(sd, flags);
3602	if (pip)
3603		rv = mdi_prop_lookup_byte_array(pip, name, data, nelements);
3604	else
3605		rv = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, sd->sd_dev,
3606		    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
3607		    name, data, nelements);
3608	return (rv);
3609}
3610
3611int
3612scsi_device_prop_lookup_int_array(struct scsi_device *sd, uint_t flags,
3613    char *name, int **data, uint_t *nelements)
3614{
3615	mdi_pathinfo_t	*pip;
3616	int		rv;
3617
3618	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3619	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3620	    !_TYPE_DEFINED(flags))
3621		return (DDI_PROP_INVAL_ARG);
3622
3623	pip = _DEVICE_PIP(sd, flags);
3624	if (pip)
3625		rv = mdi_prop_lookup_int_array(pip, name, data, nelements);
3626	else
3627		rv = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, sd->sd_dev,
3628		    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
3629		    name, data, nelements);
3630	return (rv);
3631}
3632
3633
3634int
3635scsi_device_prop_lookup_string(struct scsi_device *sd, uint_t flags,
3636    char *name, char **data)
3637{
3638	mdi_pathinfo_t	*pip;
3639	int		rv;
3640
3641	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3642	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3643	    !_TYPE_DEFINED(flags))
3644		return (DDI_PROP_INVAL_ARG);
3645
3646	pip = _DEVICE_PIP(sd, flags);
3647	if (pip)
3648		rv = mdi_prop_lookup_string(pip, name, data);
3649	else
3650		rv = ddi_prop_lookup_string(DDI_DEV_T_ANY, sd->sd_dev,
3651		    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
3652		    name, data);
3653	return (rv);
3654}
3655
3656int
3657scsi_device_prop_lookup_string_array(struct scsi_device *sd, uint_t flags,
3658    char *name, char ***data, uint_t *nelements)
3659{
3660	mdi_pathinfo_t	*pip;
3661	int		rv;
3662
3663	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3664	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3665	    !_TYPE_DEFINED(flags))
3666		return (DDI_PROP_INVAL_ARG);
3667
3668	pip = _DEVICE_PIP(sd, flags);
3669	if (pip)
3670		rv = mdi_prop_lookup_string_array(pip, name, data, nelements);
3671	else
3672		rv = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, sd->sd_dev,
3673		    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
3674		    name, data, nelements);
3675	return (rv);
3676}
3677
3678int
3679scsi_device_prop_update_byte_array(struct scsi_device *sd, uint_t flags,
3680    char *name, uchar_t *data, uint_t nelements)
3681{
3682	mdi_pathinfo_t	*pip;
3683	int		rv;
3684
3685	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3686	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3687	    !_TYPE_DEFINED(flags))
3688		return (DDI_PROP_INVAL_ARG);
3689
3690	pip = _DEVICE_PIP(sd, flags);
3691	if (pip)
3692		rv = mdi_prop_update_byte_array(pip, name, data, nelements);
3693	else
3694		rv = ndi_prop_update_byte_array(DDI_DEV_T_NONE, sd->sd_dev,
3695		    name, data, nelements);
3696	return (rv);
3697}
3698
3699int
3700scsi_device_prop_update_int(struct scsi_device *sd, uint_t flags,
3701    char *name, int data)
3702{
3703	mdi_pathinfo_t	*pip;
3704	int		rv;
3705
3706	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3707	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3708	    !_TYPE_DEFINED(flags))
3709		return (DDI_PROP_INVAL_ARG);
3710
3711	pip = _DEVICE_PIP(sd, flags);
3712	if (pip)
3713		rv = mdi_prop_update_int(pip, name, data);
3714	else
3715		rv = ndi_prop_update_int(DDI_DEV_T_NONE, sd->sd_dev,
3716		    name, data);
3717	return (rv);
3718}
3719
3720int
3721scsi_device_prop_update_int64(struct scsi_device *sd, uint_t flags,
3722    char *name, int64_t data)
3723{
3724	mdi_pathinfo_t	*pip;
3725	int		rv;
3726
3727	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3728	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3729	    !_TYPE_DEFINED(flags))
3730		return (DDI_PROP_INVAL_ARG);
3731
3732	pip = _DEVICE_PIP(sd, flags);
3733	if (pip)
3734		rv = mdi_prop_update_int64(pip, name, data);
3735	else
3736		rv = ndi_prop_update_int64(DDI_DEV_T_NONE, sd->sd_dev,
3737		    name, data);
3738	return (rv);
3739}
3740
3741int
3742scsi_device_prop_update_int_array(struct scsi_device *sd, uint_t flags,
3743    char *name, int *data, uint_t nelements)
3744{
3745	mdi_pathinfo_t	*pip;
3746	int		rv;
3747
3748	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3749	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3750	    !_TYPE_DEFINED(flags))
3751		return (DDI_PROP_INVAL_ARG);
3752
3753	pip = _DEVICE_PIP(sd, flags);
3754	if (pip)
3755		rv = mdi_prop_update_int_array(pip, name, data, nelements);
3756	else
3757		rv = ndi_prop_update_int_array(DDI_DEV_T_NONE, sd->sd_dev,
3758		    name, data, nelements);
3759	return (rv);
3760}
3761
3762int
3763scsi_device_prop_update_string(struct scsi_device *sd, uint_t flags,
3764    char *name, char *data)
3765{
3766	mdi_pathinfo_t	*pip;
3767	int		rv;
3768
3769	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3770	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3771	    !_TYPE_DEFINED(flags))
3772		return (DDI_PROP_INVAL_ARG);
3773
3774	pip = _DEVICE_PIP(sd, flags);
3775	if (pip)
3776		rv = mdi_prop_update_string(pip, name, data);
3777	else
3778		rv = ndi_prop_update_string(DDI_DEV_T_NONE, sd->sd_dev,
3779		    name, data);
3780	return (rv);
3781}
3782
3783int
3784scsi_device_prop_update_string_array(struct scsi_device *sd, uint_t flags,
3785    char *name, char **data, uint_t nelements)
3786{
3787	mdi_pathinfo_t	*pip;
3788	int		rv;
3789
3790	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3791	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3792	    !_TYPE_DEFINED(flags))
3793		return (DDI_PROP_INVAL_ARG);
3794
3795	pip = _DEVICE_PIP(sd, flags);
3796	if (pip)
3797		rv = mdi_prop_update_string_array(pip, name, data, nelements);
3798	else
3799		rv = ndi_prop_update_string_array(DDI_DEV_T_NONE, sd->sd_dev,
3800		    name, data, nelements);
3801	return (rv);
3802}
3803
3804int
3805scsi_device_prop_remove(struct scsi_device *sd, uint_t flags, char *name)
3806{
3807	mdi_pathinfo_t	*pip;
3808	int		rv;
3809
3810	ASSERT(sd && name && sd->sd_dev && _TYPE_DEFINED(flags));
3811	if ((sd == NULL) || (name == NULL) || (sd->sd_dev == NULL) ||
3812	    !_TYPE_DEFINED(flags))
3813		return (DDI_PROP_INVAL_ARG);
3814
3815	pip = _DEVICE_PIP(sd, flags);
3816	if (pip)
3817		rv = mdi_prop_remove(pip, name);
3818	else
3819		rv = ndi_prop_remove(DDI_DEV_T_NONE, sd->sd_dev, name);
3820	return (rv);
3821}
3822
3823void
3824scsi_device_prop_free(struct scsi_device *sd, uint_t flags, void *data)
3825{
3826	mdi_pathinfo_t	*pip;
3827
3828	ASSERT(sd && data && sd->sd_dev && _TYPE_DEFINED(flags));
3829	if ((sd == NULL) || (data == NULL) || (sd->sd_dev == NULL) ||
3830	    !_TYPE_DEFINED(flags))
3831		return;
3832
3833	pip = _DEVICE_PIP(sd, flags);
3834	if (pip)
3835		(void) mdi_prop_free(data);
3836	else
3837		ddi_prop_free(data);
3838}
3839
3840/*ARGSUSED*/
3841/*
3842 * Search/create the specified iport node
3843 */
3844static dev_info_t *
3845scsi_hba_bus_config_port(dev_info_t *self, char *nameaddr)
3846{
3847	dev_info_t	*child;
3848	char		*mcompatible, *addr;
3849
3850	/*
3851	 * See if the iport node already exists.
3852	 */
3853
3854	if (child = ndi_devi_findchild(self, nameaddr)) {
3855		return (child);
3856	}
3857
3858	/* allocate and initialize a new "iport" node */
3859	ndi_devi_alloc_sleep(self, "iport", DEVI_SID_NODEID, &child);
3860	ASSERT(child);
3861	/*
3862	 * Set the flavor of the child to be IPORT flavored
3863	 */
3864	ndi_flavor_set(child, SCSA_FLAVOR_IPORT);
3865
3866	/*
3867	 * Add the "scsi-iport" addressing property for this child. This
3868	 * property is used to identify a iport node, and to represent the
3869	 * nodes @addr form via node properties.
3870	 *
3871	 * Add "compatible" property to the "scsi-iport" node to cause it bind
3872	 * to the same driver as the HBA  driver.
3873	 *
3874	 * Give the HBA a chance, via tran_set_name_prop, to set additional
3875	 * iport node properties or to change the "compatible" binding
3876	 * prior to init_child.
3877	 *
3878	 * NOTE: the order of these operations is important so that
3879	 * scsi_hba_iport works when called.
3880	 */
3881	mcompatible = ddi_binding_name(self);
3882	addr = nameaddr + strlen("iport@");
3883
3884	if ((ndi_prop_update_string(DDI_DEV_T_NONE, child,
3885	    "scsi-iport", addr) != DDI_PROP_SUCCESS) ||
3886	    (ndi_prop_update_string_array(DDI_DEV_T_NONE, child,
3887	    "compatible", &mcompatible, 1) != DDI_PROP_SUCCESS) ||
3888	    ddi_pathname_obp_set(child, NULL) != DDI_SUCCESS) {
3889		SCSI_HBA_LOG((_LOG(WARN), self, NULL,
3890		    "scsi_hba_bus_config_port:%s failed dynamic decoration",
3891		    nameaddr));
3892		(void) ddi_remove_child(child, 0);
3893		child = NULL;
3894	} else {
3895		if (ddi_initchild(self, child) != DDI_SUCCESS) {
3896			ndi_prop_remove_all(child);
3897			(void) ndi_devi_free(child);
3898			child = NULL;
3899		}
3900	}
3901
3902	return (child);
3903}
3904
3905#ifdef	sparc
3906/* ARGSUSED */
3907static int
3908scsi_hba_bus_config_prom_node(dev_info_t *self, uint_t flags,
3909    void *arg, dev_info_t **childp)
3910{
3911	char		**iports;
3912	int		circ, i;
3913	int		ret = NDI_FAILURE;
3914	unsigned int	num_iports = 0;
3915	dev_info_t	*pdip = NULL;
3916	char		*addr = NULL;
3917
3918	/* check to see if this is an HBA that defined scsi iports */
3919	ret = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self,
3920	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports,
3921	    &num_iports);
3922
3923	if (ret != DDI_SUCCESS) {
3924		return (ret);
3925	}
3926
3927	ASSERT(num_iports > 0);
3928
3929	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
3930
3931	ret = NDI_FAILURE;
3932
3933	ndi_devi_enter(self, &circ);
3934
3935	/* create iport nodes for each scsi port/bus */
3936	for (i = 0; i < num_iports; i++) {
3937		bzero(addr, SCSI_MAXNAMELEN);
3938		/* Prepend the iport name */
3939		(void) snprintf(addr, SCSI_MAXNAMELEN, "iport@%s",
3940		    iports[i]);
3941		if (pdip = scsi_hba_bus_config_port(self, addr)) {
3942			if (ndi_busop_bus_config(self, NDI_NO_EVENT,
3943			    BUS_CONFIG_ONE, addr, &pdip, 0) !=
3944			    NDI_SUCCESS) {
3945				continue;
3946			}
3947			/*
3948			 * Try to configure child under iport see wehter
3949			 * request node is the child of the iport node
3950			 */
3951			if (ndi_devi_config_one(pdip, arg, childp,
3952			    NDI_NO_EVENT) == NDI_SUCCESS) {
3953				ret = NDI_SUCCESS;
3954				break;
3955			}
3956		}
3957	}
3958
3959	ndi_devi_exit(self, circ);
3960
3961	kmem_free(addr, SCSI_MAXNAMELEN);
3962
3963	ddi_prop_free(iports);
3964
3965	return (ret);
3966}
3967#endif
3968
3969/*
3970 * Perform iport port/bus bus_config.
3971 */
3972static int
3973scsi_hba_bus_config_iports(dev_info_t *self, uint_t flags,
3974    ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
3975{
3976	char		*nameaddr, *addr;
3977	char		**iports;
3978	int		circ, i;
3979	int		ret = NDI_FAILURE;
3980	unsigned int	num_iports = 0;
3981
3982	/* check to see if this is an HBA that defined scsi iports */
3983	ret = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, self,
3984	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "scsi-iports", &iports,
3985	    &num_iports);
3986
3987	if (ret != DDI_SUCCESS) {
3988		return (ret);
3989	}
3990
3991	ASSERT(num_iports > 0);
3992
3993	ndi_devi_enter(self, &circ);
3994
3995	switch (op) {
3996	case BUS_CONFIG_ONE:
3997		/* return if this operation is not against an iport node */
3998		nameaddr = (char *)arg;
3999		if ((nameaddr == NULL) ||
4000		    (strncmp(nameaddr, "iport@", strlen("iport@")) != 0)) {
4001			ret = NDI_FAILURE;
4002			ndi_devi_exit(self, circ);
4003			ddi_prop_free(iports);
4004			return (ret);
4005		}
4006
4007		/*
4008		 * parse the port number from "iport@%x"
4009		 * XXX use atoi (hex)
4010		 */
4011		addr = nameaddr + strlen("iport@");
4012
4013		/* check to see if this port was registered */
4014		for (i = 0; i < num_iports; i++) {
4015			if (strcmp((iports[i]), addr) == 0)
4016				break;
4017		}
4018
4019		if (i == num_iports) {
4020			ret = NDI_FAILURE;
4021			break;
4022		}
4023
4024		/* create the iport node */
4025		if (scsi_hba_bus_config_port(self, nameaddr)) {
4026			ret = NDI_SUCCESS;
4027		}
4028		break;
4029	case BUS_CONFIG_ALL:
4030	case BUS_CONFIG_DRIVER:
4031		addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
4032		/* create iport nodes for each scsi port/bus */
4033		for (i = 0; i < num_iports; i++) {
4034			bzero(addr, SCSI_MAXNAMELEN);
4035			/* Prepend the iport name */
4036			(void) snprintf(addr, SCSI_MAXNAMELEN, "iport@%s",
4037			    iports[i]);
4038			(void) scsi_hba_bus_config_port(self, addr);
4039		}
4040
4041		kmem_free(addr, SCSI_MAXNAMELEN);
4042		ret = NDI_SUCCESS;
4043		break;
4044	}
4045	if (ret == NDI_SUCCESS) {
4046#ifdef sparc
4047		/*
4048		 * Mask NDI_PROMNAME since PROM doesn't have iport
4049		 * node at all.
4050		 */
4051		flags &= (~NDI_PROMNAME);
4052#endif
4053		ret = ndi_busop_bus_config(self, flags, op,
4054		    arg, childp, 0);
4055	}
4056	ndi_devi_exit(self, circ);
4057
4058	ddi_prop_free(iports);
4059
4060	return (ret);
4061}
4062
4063
4064/*ARGSUSED*/
4065static int
4066scsi_hba_bus_config(dev_info_t *self, uint_t flag, ddi_bus_config_op_t op,
4067    void *arg, dev_info_t **childp)
4068{
4069	scsi_hba_tran_t	*tran = NULL;
4070
4071	tran = ddi_get_driver_private(self);
4072
4073	if (tran && (tran->tran_hba_flags & SCSI_HBA_HBA)) {
4074#ifdef	sparc
4075		char *nameaddr = NULL;
4076		nameaddr = (char *)arg;
4077		switch (op) {
4078		case BUS_CONFIG_ONE:
4079			if (nameaddr == NULL)
4080				return (NDI_FAILURE);
4081			if (strncmp(nameaddr, "iport", strlen("iport")) == 0) {
4082				break;
4083			}
4084			/*
4085			 * If this operation is not against an iport node, it's
4086			 * possible the operation is requested to configure
4087			 * root disk by OBP. Unfortunately, prom path is without
4088			 * iport string in the boot path.
4089			 */
4090			if (strncmp(nameaddr, "disk@", strlen("disk@")) == 0) {
4091				return (scsi_hba_bus_config_prom_node(self,
4092				    flag, arg, childp));
4093			}
4094			break;
4095		default:
4096			break;
4097		}
4098#endif
4099		/*
4100		 * The request is to configure multi-port HBA.
4101		 * Now start to configure iports, for the end
4102		 * devices attached to iport, should be configured
4103		 * by bus_configure routine of iport
4104		 */
4105		return (scsi_hba_bus_config_iports(self, flag, op, arg,
4106		    childp));
4107	}
4108
4109#ifdef sparc
4110	if (scsi_hba_iport_unit_address(self)) {
4111		flag &= (~NDI_PROMNAME);
4112	}
4113#endif
4114	if (tran && tran->tran_bus_config) {
4115		return (tran->tran_bus_config(self, flag, op, arg, childp));
4116	}
4117
4118	/*
4119	 * Force reprobe for BUS_CONFIG_ONE or when manually reconfiguring
4120	 * via devfsadm(1m) to emulate deferred attach.
4121	 * Reprobe only discovers driver.conf enumerated nodes, more
4122	 * dynamic implementations probably require their own bus_config.
4123	 */
4124	if ((op == BUS_CONFIG_ONE) || (flag & NDI_DRV_CONF_REPROBE))
4125		flag |= NDI_CONFIG_REPROBE;
4126
4127	return (ndi_busop_bus_config(self, flag, op, arg, childp, 0));
4128}
4129
4130static int
4131scsi_hba_bus_unconfig(dev_info_t *self, uint_t flag, ddi_bus_config_op_t op,
4132    void *arg)
4133{
4134	scsi_hba_tran_t	*tran = NULL;
4135
4136	tran = ddi_get_driver_private(self);
4137
4138	if (tran && tran->tran_bus_unconfig) {
4139		return (tran->tran_bus_unconfig(self, flag, op, arg));
4140	}
4141	return (ndi_busop_bus_unconfig(self, flag, op, arg));
4142}
4143
4144void
4145scsi_hba_pkt_comp(struct scsi_pkt *pkt)
4146{
4147	ASSERT(pkt);
4148	if (pkt->pkt_comp == NULL)
4149		return;
4150
4151	/*
4152	 * For HBA drivers that implement tran_setup_pkt(9E), if we are
4153	 * completing a 'consistent' mode DMA operation then we must
4154	 * perform dma_sync prior to calling pkt_comp to ensure that
4155	 * the target driver sees the correct data in memory.
4156	 */
4157	ASSERT((pkt->pkt_flags & FLAG_NOINTR) == 0);
4158	if (((pkt->pkt_dma_flags & DDI_DMA_CONSISTENT) &&
4159	    (pkt->pkt_dma_flags & DDI_DMA_READ)) &&
4160	    ((P_TO_TRAN(pkt)->tran_setup_pkt) != NULL)) {
4161		scsi_sync_pkt(pkt);
4162	}
4163	(*pkt->pkt_comp)(pkt);
4164}
4165