xref: /illumos-gate/usr/src/uts/common/sys/scsi/impl/transport.h (revision 5df5713f81d69c1a0797f99b13e95e220da00ef9)
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 #ifndef	_SYS_SCSI_IMPL_TRANSPORT_H
27 #define	_SYS_SCSI_IMPL_TRANSPORT_H
28 
29 /*
30  * Include the loadable module wrapper.
31  */
32 #include <sys/modctl.h>
33 #include <sys/note.h>
34 
35 #ifdef	__cplusplus
36 extern "C" {
37 #endif
38 
39 #ifdef	_KERNEL
40 
41 /*
42  * SCSI transport structures
43  *
44  *	As each Host Adapter makes itself known to the system,
45  *	it will create and register with the library the structure
46  *	described below. This is so that the library knows how to route
47  *	packets, resource control requests, and capability requests
48  *	for any particular host adapter. The 'a_hba_tran' field of a
49  *	scsi_address structure made known to a Target driver will
50  *	point to one of these transport structures.
51  */
52 
53 typedef struct scsi_hba_tran	scsi_hba_tran_t;
54 
55 struct scsi_hba_tran {
56 	/*
57 	 * Ptr to the device info structure for this particular HBA.
58 	 */
59 	dev_info_t	*tran_hba_dip;
60 
61 	/*
62 	 * Private fields for use by the HBA itself.
63 	 */
64 	void		*tran_hba_private;	/* HBA softstate */
65 
66 	/*
67 	 * The following two fields are only used in the SCSI_HBA_TRAN_CLONE
68 	 * case. Consider using SCSI_HBA_ADDR_COMPLEX instead.
69 	 */
70 	void			*tran_tgt_private;
71 	struct scsi_device	*tran_sd;
72 
73 	/*
74 	 * Vectors to point to specific HBA entry points
75 	 */
76 	int		(*tran_tgt_init)(
77 				dev_info_t		*hba_dip,
78 				dev_info_t		*tgt_dip,
79 				scsi_hba_tran_t		*tran,
80 				struct scsi_device	*sd);
81 
82 	int		(*tran_tgt_probe)(
83 				struct scsi_device	*sd,
84 				int			(*callback)(
85 								void));
86 	void		(*tran_tgt_free)(
87 				dev_info_t		*hba_dip,
88 				dev_info_t		*tgt_dip,
89 				scsi_hba_tran_t		*tran,
90 				struct scsi_device	*sd);
91 
92 	int		(*tran_start)(
93 				struct scsi_address	*ap,
94 				struct scsi_pkt		*pkt);
95 
96 	int		(*tran_reset)(
97 				struct scsi_address	*ap,
98 				int			level);
99 
100 	int		(*tran_abort)(
101 				struct scsi_address	*ap,
102 				struct scsi_pkt		*pkt);
103 
104 	int		(*tran_getcap)(
105 				struct scsi_address	*ap,
106 				char			*cap,
107 				int			whom);
108 
109 	int		(*tran_setcap)(
110 				struct scsi_address	*ap,
111 				char			*cap,
112 				int			value,
113 				int			whom);
114 
115 	struct scsi_pkt	*(*tran_init_pkt)(
116 				struct scsi_address	*ap,
117 				struct scsi_pkt		*pkt,
118 				struct buf		*bp,
119 				int			cmdlen,
120 				int			statuslen,
121 				int			tgtlen,
122 				int			flags,
123 				int			(*callback)(
124 								caddr_t	arg),
125 				caddr_t			callback_arg);
126 
127 	void		(*tran_destroy_pkt)(
128 				struct scsi_address	*ap,
129 				struct scsi_pkt		*pkt);
130 
131 	void		(*tran_dmafree)(
132 				struct scsi_address	*ap,
133 				struct scsi_pkt		*pkt);
134 
135 	void		(*tran_sync_pkt)(
136 				struct scsi_address	*ap,
137 				struct scsi_pkt		*pkt);
138 
139 	int		(*tran_reset_notify)(
140 				struct scsi_address	*ap,
141 				int			flag,
142 				void			(*callback)(caddr_t),
143 				caddr_t			arg);
144 
145 	int		(*tran_get_bus_addr)(
146 				struct scsi_device	*sd,
147 				char			*name,
148 				int			len);
149 
150 	int		(*tran_get_name)(
151 				struct scsi_device	*sd,
152 				char			*name,
153 				int			len);
154 
155 	int		(*tran_clear_aca)(
156 				struct scsi_address	*ap);
157 
158 	int		(*tran_clear_task_set)(
159 				struct scsi_address	*ap);
160 
161 	int		(*tran_terminate_task)(
162 				struct scsi_address	*ap,
163 				struct scsi_pkt		*pkt);
164 
165 	int		(*tran_get_eventcookie)(
166 				dev_info_t		*hba_dip,
167 				dev_info_t		*tgt_dip,
168 				char			*name,
169 				ddi_eventcookie_t	*eventp);
170 
171 	int		(*tran_add_eventcall)(
172 				dev_info_t		*hba_dip,
173 				dev_info_t		*tgt_dip,
174 				ddi_eventcookie_t	event,
175 				void			(*callback)(
176 						dev_info_t *tgt_dip,
177 						ddi_eventcookie_t event,
178 						void *arg,
179 						void *bus_impldata),
180 				void			*arg,
181 				ddi_callback_id_t *cb_id);
182 
183 	int		(*tran_remove_eventcall)(dev_info_t *devi,
184 			ddi_callback_id_t cb_id);
185 
186 	int		(*tran_post_event)(
187 				dev_info_t		*hba_dip,
188 				dev_info_t		*tgt_dip,
189 				ddi_eventcookie_t	event,
190 				void			*bus_impldata);
191 
192 	int		(*tran_quiesce)(
193 				dev_info_t		*hba_dip);
194 
195 	int		(*tran_unquiesce)(
196 				dev_info_t		*hba_dip);
197 
198 	int		(*tran_bus_reset)(
199 				dev_info_t		*hba_dip,
200 				int			level);
201 
202 	/*
203 	 * Implementation-private specifics.
204 	 * No HBA should refer to any of the fields below.
205 	 * This information can and will change.
206 	 */
207 	int			tran_hba_flags;		/* flag options */
208 
209 	uint_t			tran_obs1;
210 	uchar_t			tran_obs2;
211 	uchar_t			tran_obs3;
212 
213 	/*
214 	 * open_lock: protect tran_minor_isopen
215 	 * open_flag: bit field indicating which minor nodes are open.
216 	 *	0 = closed, 1 = shared open, all bits 1 = excl open.
217 	 *
218 	 * XXX Unused if hba driver chooses to implement own
219 	 *	xxopen(9e) entry point
220 	 */
221 	kmutex_t		tran_open_lock;
222 	uint64_t		tran_open_flag;
223 
224 	/*
225 	 * bus_config vectors - ON Consolidation Private
226 	 * These interfaces are subject to change.
227 	 */
228 	int		(*tran_bus_config)(
229 				dev_info_t		*hba_dip,
230 				uint_t			flag,
231 				ddi_bus_config_op_t	op,
232 				void			*arg,
233 				dev_info_t		**tgt_dipp);
234 
235 	int		(*tran_bus_unconfig)(
236 				dev_info_t		*hba_dip,
237 				uint_t			flag,
238 				ddi_bus_config_op_t	op,
239 				void			*arg);
240 
241 	int		(*tran_bus_power)(
242 				dev_info_t		*dip,
243 				void			*impl_arg,
244 				pm_bus_power_op_t	op,
245 				void			*arg,
246 				void			*result);
247 
248 	/*
249 	 * Inter-Connect type of trasnport as defined in
250 	 * usr/src/uts/common/sys/scsi/impl/services.h
251 	 */
252 	int		tran_interconnect_type;
253 
254 	/* tran_setup_pkt(9E) related scsi_pkt fields */
255 	int		(*tran_pkt_constructor)(
256 				struct scsi_pkt		*pkt,
257 				scsi_hba_tran_t		*tran,
258 				int			kmflag);
259 	void		(*tran_pkt_destructor)(
260 				struct scsi_pkt		*pkt,
261 				scsi_hba_tran_t		*tran);
262 	kmem_cache_t	*tran_pkt_cache_ptr;
263 	uint_t		tran_hba_len;
264 	int		(*tran_setup_pkt)(
265 				struct scsi_pkt		*pkt,
266 				int			(*callback)(
267 								caddr_t	arg),
268 				caddr_t			callback_arg);
269 	void		(*tran_teardown_pkt)(
270 				struct scsi_pkt		*pkt);
271 	ddi_dma_attr_t	tran_dma_attr;
272 
273 	void		*tran_extension;
274 
275 	/*
276 	 * An fm_capable HBA driver can set tran_fm_capable prior to
277 	 * scsi_hba_attach_setup(). If not set, SCSA provides a default
278 	 * implementation.
279 	 */
280 	int		tran_fm_capable;
281 
282 	/*
283 	 * Ptr to the device info structure for initiator port. If a SCSA HBA
284 	 * driver separates initiator port function from HBA function, this
285 	 * field still refers to the initiator port.
286 	 */
287 	dev_info_t	*tran_iport_dip;
288 
289 #ifdef	SCSI_SIZE_CLEAN_VERIFY
290 	/*
291 	 * Must be last: Building a driver with-and-without
292 	 * -DSCSI_SIZE_CLEAN_VERIFY, and checking driver modules for
293 	 * differences with a tools like 'wsdiff' allows a developer to verify
294 	 * that their driver has no dependencies on scsi*(9S) size.
295 	 */
296 	int		_pad[8];
297 #endif	/* SCSI_SIZE_CLEAN_VERIFY */
298 };
299 size_t	scsi_hba_tran_size();			/* private */
300 
301 #ifdef __lock_lint
302 _NOTE(SCHEME_PROTECTS_DATA("stable data",
303 	scsi_hba_tran::tran_sd
304 	scsi_hba_tran::tran_hba_dip
305 	scsi_hba_tran::tran_hba_flags
306 	scsi_hba_tran::tran_open_flag
307 	scsi_hba_tran::tran_pkt_cache_ptr))
308 /*
309  * we only modify the dma atributes (like dma_attr_granular) upon
310  * attach and in response to a setcap. It is also up to the target
311  * driver to not have any outstanding I/Os when it is changing the
312  * capabilities of the transport.
313  */
314 _NOTE(SCHEME_PROTECTS_DATA("serialized by target driver", \
315 	scsi_hba_tran::tran_dma_attr.dma_attr_granular))
316 #endif
317 
318 /*
319  * Prototypes for SCSI HBA interface functions
320  *
321  * All these functions are public interfaces, with the
322  * exception of:
323  *	interface				called by
324  *	scsi_initialize_hba_interface()		_init() of scsi module
325  *	scsi_uninitialize_hba_interface()	_fini() of scsi module
326  */
327 
328 void		scsi_initialize_hba_interface(void);
329 
330 #ifdef	NO_SCSI_FINI_YET
331 void		scsi_uninitialize_hba_interface(void);
332 #endif	/* NO_SCSI_FINI_YET */
333 
334 int		scsi_hba_init(
335 				struct modlinkage	*modlp);
336 
337 void		scsi_hba_fini(
338 				struct modlinkage	*modlp);
339 
340 int		scsi_hba_attach(
341 				dev_info_t		*hba_dip,
342 				ddi_dma_lim_t		*hba_lim,
343 				scsi_hba_tran_t		*tran,
344 				int			flags,
345 				void			*hba_options);
346 
347 int		scsi_hba_attach_setup(
348 				dev_info_t		*hba_dip,
349 				ddi_dma_attr_t		*hba_dma_attr,
350 				scsi_hba_tran_t		*tran,
351 				int			flags);
352 
353 int		scsi_hba_detach(
354 				dev_info_t		*hba_dip);
355 
356 scsi_hba_tran_t	*scsi_hba_tran_alloc(
357 				dev_info_t		*hba_dip,
358 				int			flags);
359 
360 int		scsi_tran_ext_alloc(
361 				scsi_hba_tran_t		*tran,
362 				size_t			length,
363 				int			flags);
364 
365 void		scsi_tran_ext_free(
366 				scsi_hba_tran_t		*tran,
367 				size_t			length);
368 
369 void		scsi_hba_tran_free(
370 				scsi_hba_tran_t		*tran);
371 
372 int		scsi_hba_probe(
373 				struct scsi_device	*sd,
374 				int			(*callback)(void));
375 
376 char			*scsi_get_device_type_string(
377 				char			*prop_name,
378 				dev_info_t		*hba_dip,
379 				struct scsi_device	*sd);
380 
381 int		scsi_get_scsi_maxluns(
382 				struct scsi_device	*sd);
383 
384 int		scsi_get_scsi_options(
385 				struct scsi_device	*sd,
386 				int			default_scsi_options);
387 
388 int		scsi_get_device_type_scsi_options(
389 				dev_info_t		*hba_dip,
390 				struct scsi_device	*sd,
391 				int			default_scsi_options);
392 
393 struct scsi_pkt	*scsi_hba_pkt_alloc(
394 				dev_info_t		*hba_dip,
395 				struct scsi_address	*ap,
396 				int			cmdlen,
397 				int			statuslen,
398 				int			tgtlen,
399 				int			hbalen,
400 				int			(*callback)(caddr_t),
401 				caddr_t			arg);
402 
403 void		scsi_hba_pkt_free(
404 				struct scsi_address	*ap,
405 				struct scsi_pkt		*pkt);
406 
407 
408 int		scsi_hba_lookup_capstr(
409 				char			*capstr);
410 
411 int		scsi_hba_in_panic(void);
412 
413 int		scsi_hba_open(
414 				dev_t			*devp,
415 				int			flags,
416 				int			otyp,
417 				cred_t			*credp);
418 
419 int		scsi_hba_close(
420 				dev_t			dev,
421 				int			flag,
422 				int			otyp,
423 				cred_t			*credp);
424 
425 int		scsi_hba_ioctl(
426 				dev_t			dev,
427 				int			cmd,
428 				intptr_t		arg,
429 				int			mode,
430 				cred_t			*credp,
431 				int			*rvalp);
432 
433 void		scsi_hba_nodename_compatible_get(
434 				struct scsi_inquiry	*inq,
435 				char			*binding_set,
436 				int			dtype_node,
437 				char			*compat0,
438 				char			**nodenamep,
439 				char			***compatiblep,
440 				int			*ncompatiblep);
441 
442 void		scsi_hba_nodename_compatible_free(
443 				char			*nodename,
444 				char			**compatible);
445 
446 
447 int		scsi_hba_prop_update_inqstring(
448 				struct scsi_device	*sd,
449 				char			*name,
450 				char			*data,
451 				size_t			len);
452 
453 void		scsi_hba_pkt_comp(
454 				struct scsi_pkt		*pkt);
455 
456 char		*scsi_hba_iport_unit_address(
457 				dev_info_t		*self);
458 
459 int		scsi_hba_iport_register(
460 				dev_info_t		*dip,
461 				char			*port);
462 
463 int		scsi_hba_iport_exist(
464 				dev_info_t		*dip);
465 
466 dev_info_t	*scsi_hba_iport_find(
467 				dev_info_t		*pdip,
468 				char			*portnm);
469 /*
470  * Flags for scsi_hba_attach
471  *
472  * SCSI_HBA_ADDR_SPI		The host adapter driver wants the
473  *				scsi_address(9S) structure to be maintained
474  *				in legacy SPI 'a_target'/'a_lun' form (default).
475  *
476  * SCSI_HBA_ADDR_COMPLEX	The host adapter has a complex unit-address
477  *				space, and the HBA driver wants to maintain
478  *				per-scsi_device(9S) HBA private data using
479  *				scsi_address_device(9F) and
480  *				scsi_device_hba_private_[gs]et(9F).  The HBA
481  *				driver must maintain a private representation
482  *				of the scsi_device(9S) unit-address - typically
483  *				established during tran_tgt_init(9F) based on
484  *				property values.
485  *
486  * SCSI_HBA_TRAN_PHCI		The host adapter is an mpxio/scsi_vhci pHCI.
487  *				The framework should take care of
488  *				mdi_phci_register() stuff.
489  *
490  * SCSI_HBA_HBA			The host adapter node (associated with a PCI
491  *				function) is just an HBA, all SCSI initiator
492  *				port function is provided by separate 'iport'
493  *				children of the host adapter node.  These iport
494  *				children bind to the same driver as the host
495  *				adapter node. Both nodes are managed by the
496  *				same driver. The driver can distinguish context
497  *				by calling scsi_hba_iport_unit_address().
498  *
499  * SCSI_HBA_TRAN_CLONE		Consider using SCSI_HBA_ADDR_COMPLEX instead.
500  *				SCSI_HBA_TRAN_CLONE is a KLUDGE to address
501  *				limitations of the scsi_address(9S) structure
502  *				via duplication of scsi_hba_tran(9S) and
503  *				use of tran_tgt_private.
504  *
505  */
506 #define	SCSI_HBA_TRAN_CLONE	0x01	/* Deprecated */
507 #define	SCSI_HBA_TRAN_PHCI	0x02	/* treat HBA as mpxio 'pHCI' */
508 #define	SCSI_HBA_TRAN_CDB	0x04	/* allocate cdb */
509 #define	SCSI_HBA_TRAN_SCB	0x08	/* allocate sense */
510 
511 #define	SCSI_HBA_ADDR_SPI	0x20	/* scsi_address in SPI form */
512 #define	SCSI_HBA_ADDR_COMPLEX	0x40	/* scsi_address is COMPLEX */
513 #define	SCSI_HBA_HBA		0x80	/* all HBA children are iport */
514 
515 /* upper bits used to record SCSA configuration state */
516 #define	SCSI_HBA_SCSA_PHCI	0x10000	/* need mdi_phci_unregister */
517 #define	SCSI_HBA_SCSA_TA	0x20000	/* scsi_hba_tran_alloc used */
518 #define	SCSI_HBA_SCSA_FM	0x40000	/* using common ddi_fm_* */
519 
520 /*
521  * Flags for scsi_hba allocation functions
522  */
523 #define	SCSI_HBA_CANSLEEP	0x01		/* can sleep */
524 
525 /*
526  * Support extra flavors for SCSA children
527  */
528 #define	SCSA_FLAVOR_SCSI_DEVICE	NDI_FLAVOR_VANILLA
529 #define	SCSA_FLAVOR_IPORT	1
530 #define	SCSA_FLAVOR_SMP		2
531 #define	SCSA_NFLAVORS		3
532 
533 /*
534  * Maximum number of iport nodes under PCI function
535  */
536 #define	SCSI_HBA_MAX_IPORTS	32
537 
538 /*
539  * For minor nodes created by the SCSA framework, minor numbers are
540  * formed by left-shifting instance by INST_MINOR_SHIFT and OR in a
541  * number less than 64.
542  *
543  * - Numbers 0 - 31 are reserved by the framework, part of the range are
544  *	in use, as defined below.
545  *
546  * - Numbers 32 - 63 are available for HBA driver use.
547  */
548 #define	INST_MINOR_SHIFT	6
549 #define	TRAN_MINOR_MASK		((1 << INST_MINOR_SHIFT) - 1)
550 #define	TRAN_OPEN_EXCL		(uint64_t)-1
551 
552 #define	DEVCTL_MINOR		0
553 #define	SCSI_MINOR		1
554 
555 #define	INST2DEVCTL(x)		(((x) << INST_MINOR_SHIFT) | DEVCTL_MINOR)
556 #define	INST2SCSI(x)		(((x) << INST_MINOR_SHIFT) | SCSI_MINOR)
557 #define	MINOR2INST(x)		((x) >> INST_MINOR_SHIFT)
558 
559 #endif	/* _KERNEL */
560 
561 #ifdef	__cplusplus
562 }
563 #endif
564 
565 #endif	/* _SYS_SCSI_IMPL_TRANSPORT_H */
566