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 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
27  */
28 
29 /*
30  * SCSI device structure.
31  *
32  * All SCSI target drivers will have one of these per target/lun/sfunc.
33  * It is allocated and initialized by the framework SCSA HBA nexus code
34  * for each SCSI target dev_info_t node during HBA nexus DDI_CTLOPS_INITCHILD
35  * processing of a child device node just prior to tran_tgt_init(9E).  A
36  * pointer the the scsi_device(9S) structure is stored in the
37  * driver-private data field of the target device's dev_info_t node (in
38  * 'devi_driver_data') and can be retrieved by ddi_get_driver_private(9F).
39  */
40 #ifndef	_SYS_SCSI_CONF_DEVICE_H
41 #define	_SYS_SCSI_CONF_DEVICE_H
42 
43 #include <sys/scsi/scsi_types.h>
44 
45 #ifdef	__cplusplus
46 extern "C" {
47 #endif
48 
49 struct scsi_device {
50 	/*
51 	 * Routing information for a SCSI device (target/lun/sfunc).
52 	 *
53 	 * The scsi_address(9S) structure contains a pointer to the
54 	 * scsi_hba_tran(9S) of the transport.
55 	 *
56 	 * For devices below an HBA that uses SCSI_HBA_ADDR_SPI
57 	 * unit-addressing, the scsi_address(9S) information contains
58 	 * decoded target/lun addressing information.
59 	 *
60 	 * For devices below an HBA that uses SCSI_HBA_ADDR_COMPLEX
61 	 * unit-addressing, the scsi_address(9S) information contains a
62 	 * pointer to the scsi_device(9S) structure and the HBA can maintain
63 	 * its private per-unit-address/per-scsi_device information using
64 	 * scsi_address_device(9F) and scsi_device_hba_private_[gs]et(9F).
65 	 *
66 	 * NOTE: The scsi_address(9S) structure gets structure-copied into
67 	 * the scsi_pkt(9S) 'pkt_address' field. Having a pointer to the
68 	 * scsi_device(9S) structure within the scsi_address(9S) allows
69 	 * the SCSA framework to reflect generic changes in device state
70 	 * at scsi_pkt_comp(9F) time (given just a scsi_pkt(9S) pointer).
71 	 *
72 	 * NOTE: The older SCSI_HBA_TRAN_CLONE method of supporting
73 	 * SCSI-3 devices is still supported, but use is discouraged.
74 	 */
75 	struct scsi_address	sd_address;
76 
77 	/* Cross-reference to target device's dev_info_t. */
78 	dev_info_t		*sd_dev;
79 
80 	/*
81 	 * Target driver mutex for this device. Initialized by SCSA HBA
82 	 * framework code prior to probe(9E) or attach(9E) of scsi_device.
83 	 */
84 	kmutex_t		sd_mutex;
85 
86 	/*
87 	 * SCSA private: use is associated with implementation of
88 	 * SCSI_HBA_ADDR_COMPLEX scsi_device_hba_private_[gs]et(9F).
89 	 * The HBA driver can store a pointer to per-scsi_device(9S)
90 	 * HBA private data during its tran_tgt_init(9E) implementation
91 	 * by calling scsi_device_hba_private_set(9F), and free that
92 	 * pointer during tran_tgt_fini(9E). At tran_send(9E) time, the
93 	 * HBA driver can use scsi_address_device(9F) to obtain a pointer
94 	 * to the scsi_device(9S) structure, and then gain access to
95 	 * its per-scsi_device(9S) hba private data by calling
96 	 * scsi_device_hba_private_get(9F).
97 	 */
98 	void			*sd_hba_private;
99 
100 	/*
101 	 * If scsi_slave is used to probe out this device, a scsi_inquiry data
102 	 * structure will be allocated and an INQUIRY command will be run to
103 	 * fill it in.
104 	 *
105 	 * The inquiry data is allocated/refreshed by scsi_probe/scsi_slave
106 	 * and freed by uninitchild (inquiry data is no longer freed by
107 	 * scsi_unprobe/scsi_unslave).
108 	 *
109 	 * NOTE: Additional device identity information may be available
110 	 * as properties of sd_dev.
111 	 */
112 	struct scsi_inquiry	*sd_inq;
113 
114 	/*
115 	 * Place to point to an extended request sense buffer.
116 	 * The target driver is responsible for managing this.
117 	 */
118 	struct scsi_extended_sense	*sd_sense;
119 
120 	/*
121 	 * Target driver 'private' information. Typically a pointer to target
122 	 * driver private ddi_soft_state(9F) information for the device.  This
123 	 * information is typically established in target driver attach(9E),
124 	 * and freed in the target driver detach(9E).
125 	 *
126 	 * LEGACY: For a scsi_device structure allocated by scsi_vhci during
127 	 * online of a path, this was set by scsi_vhci to point to the
128 	 * pathinfo node. Please use sd_pathinfo instead.
129 	 */
130 	void			*sd_private;
131 
132 	/*
133 	 * FMA capabilities of scsi_device.
134 	 */
135 	int			sd_fm_capable;
136 
137 	/*
138 	 * mdi_pathinfo_t pointer to pathinfo node for scsi_device structure
139 	 * allocated by the scsi_vhci for transport to a specific pHCI path.
140 	 */
141 	void			*sd_pathinfo;
142 
143 	/*
144 	 * sd_uninit_prevent - Counter that prevents demotion of
145 	 * DS_INITIALIZED node (esp loss of devi_addr) by causing
146 	 * DDI_CTLOPS_UNINITCHILD failure - devi_ref will not protect
147 	 * demotion of DS_INITIALIZED node.
148 	 *
149 	 * sd_tran_tgt_free_done - in some cases SCSA will call
150 	 * tran_tgt_free(9E) independent of devinfo node state, this means
151 	 * that uninitchild code should not call tran_tgt_free(9E).
152 	 */
153 	unsigned		sd_uninit_prevent:16,
154 				sd_tran_tgt_free_done:1,
155 				sd_flags_pad:15;
156 
157 	/*
158 	 * The 'sd_tran_safe' field is a grotty hack that allows direct-access
159 	 * (non-scsa) drivers (like chs, ata, and mlx - which all make cmdk
160 	 * children) to *illegally* put their own vector in the scsi_address(9S)
161 	 * 'a_hba_tran' field. When all the drivers that overwrite
162 	 * 'a_hba_tran' are fixed, we can remove sd_tran_safe (and make
163 	 * scsi_hba.c code trust that the 'sd_address.a_hba_tran' established
164 	 * during initchild is still valid when uninitchild occurs).
165 	 *
166 	 * NOTE: This hack is also shows up in the DEVP_TO_TRAN implementation
167 	 * in scsi_confsubr.c.
168 	 *
169 	 * NOTE: The 'sd_tran_safe' field is only referenced by SCSA framework
170 	 * code, so always keeping it at the end of the scsi_device structure
171 	 * (until it can be removed) is OK.  It use to be called 'sd_reserved'.
172 	 */
173 	struct scsi_hba_tran	*sd_tran_safe;
174 
175 #ifdef	SCSI_SIZE_CLEAN_VERIFY
176 	/*
177 	 * Must be last: Building a driver with-and-without
178 	 * -DSCSI_SIZE_CLEAN_VERIFY, and checking driver modules for
179 	 * differences with a tools like 'wsdiff' allows a developer to verify
180 	 * that their driver has no dependencies on scsi*(9S) size.
181 	 */
182 	int			_pad[8];
183 #endif	/* SCSI_SIZE_CLEAN_VERIFY */
184 };
185 
186 #ifdef	_KERNEL
187 
188 /* ==== The following interfaces are public ==== */
189 
190 int	scsi_probe(struct scsi_device *sd, int (*callback)(void));
191 void	scsi_unprobe(struct scsi_device *sd);
192 
193 /* ==== The following interfaces are private (currently) ==== */
194 
195 char	*scsi_device_unit_address(struct scsi_device *sd);
196 
197 /*
198  * scsi_device_prop_*() property interfaces: flags
199  *
200  *   SCSI_DEVICE_PROP_PATH: property of path-to-device.
201  *	The property is associated with the sd_pathinfo pathinfo node
202  *	as established by scsi_vhci. If sd_pathinfo is NULL then the
203  *	property is associated with the sd_dev devinfo node.
204  *	Implementation uses mdi_prop_*() interfaces applied to
205  *	mdi_pathinfo_t (sd_pathinfo) nodes.
206  *
207  *   SCSI_DEVICE_PROP_DEVICE: property of device.
208  *	The property is always associated with the sd_dev devinfo
209  *	node.  Implementation uses ndi_prop_*() interfaces applied
210  *	dev_info_t (sd_dev) nodes.
211  */
212 #define	SCSI_DEVICE_PROP_PATH		0x1	/* type is property-of-path */
213 #define	SCSI_DEVICE_PROP_DEVICE		0x2	/* type is property-of-device */
214 #define	SCSI_DEVICE_PROP_TYPE_MSK	0xF
215 
216 int	scsi_device_prop_get_int(struct scsi_device *sd,
217 	    uint_t flags, char *name, int defvalue);
218 int64_t	scsi_device_prop_get_int64(struct scsi_device *,
219 	    uint_t flags, char *name, int64_t defvalue);
220 
221 int	scsi_device_prop_lookup_byte_array(struct scsi_device *sd,
222 	    uint_t flags, char *name, uchar_t **, uint_t *);
223 int	scsi_device_prop_lookup_int_array(struct scsi_device *sd,
224 	    uint_t flags, char *name, int **, uint_t *);
225 int	scsi_device_prop_lookup_string(struct scsi_device *sd,
226 	    uint_t flags, char *name, char **);
227 int	scsi_device_prop_lookup_string_array(struct scsi_device *sd,
228 	    uint_t flags, char *name, char ***, uint_t *);
229 
230 int	scsi_device_prop_update_byte_array(struct scsi_device *sd,
231 	    uint_t flags, char *name, uchar_t *, uint_t);
232 int	scsi_device_prop_update_int(struct scsi_device *sd,
233 	    uint_t flags, char *name, int);
234 int	scsi_device_prop_update_int64(struct scsi_device *sd,
235 	    uint_t flags, char *name, int64_t);
236 int	scsi_device_prop_update_int_array(struct scsi_device *sd,
237 	    uint_t flags, char *name, int *, uint_t);
238 int	scsi_device_prop_update_string(struct scsi_device *sd,
239 	    uint_t flags, char *name, char *);
240 int	scsi_device_prop_update_string_array(struct scsi_device *sd,
241 	    uint_t flags, char *name, char **, uint_t);
242 
243 int	scsi_device_prop_remove(struct scsi_device *sd,
244 	    uint_t flags, char *name);
245 void	scsi_device_prop_free(struct scsi_device *sd,
246 	    uint_t flags, void *data);
247 
248 /* SCSI_HBA_ADDR_COMPLEX interfaces */
249 struct scsi_device	*scsi_address_device(struct scsi_address *sa);
250 void	scsi_device_hba_private_set(struct scsi_device *sd, void *data);
251 void	*scsi_device_hba_private_get(struct scsi_device *sd);
252 
253 /* ==== The following interfaces are private ==== */
254 
255 size_t	scsi_device_size();
256 
257 /* ==== The following interfaces are obsolete ==== */
258 
259 int	scsi_slave(struct scsi_device *sd, int (*callback)(void));
260 void	scsi_unslave(struct scsi_device *sd);
261 
262 #endif	/* _KERNEL */
263 
264 #ifdef	__cplusplus
265 }
266 #endif
267 
268 #endif	/* _SYS_SCSI_CONF_DEVICE_H */
269