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