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 int 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 */