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