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 /*
  27  * SCSI device structure.
  28  *
  29  * All SCSI target drivers will have one of these per target/lun/sfunc.
  30  * It is allocated and initialized by the framework SCSA HBA nexus code
  31  * for each SCSI target dev_info_t node during HBA nexus DDI_CTLOPS_INITCHILD
  32  * processing of a child device node just prior to tran_tgt_init(9E).  A
  33  * pointer the the scsi_device(9S) structure is stored in the
  34  * driver-private data field of the target device's dev_info_t node (in
  35  * 'devi_driver_data') and can be retrieved by ddi_get_driver_private(9F).
  36  */
  37 #ifndef _SYS_SCSI_CONF_DEVICE_H
  38 #define _SYS_SCSI_CONF_DEVICE_H
  39 
  40 #include <sys/scsi/scsi_types.h>
  41 
  42 #ifdef  __cplusplus
  43 extern "C" {
  44 #endif
  45 
  46 struct scsi_device {
  47         /*
  48          * Routing information for a SCSI device (target/lun/sfunc).
  49          *
  50          * The scsi_address(9S) structure contains a pointer to the
  51          * scsi_hba_tran(9S) of the transport.
  52          *
  53          * For devices below an HBA that uses SCSI_HBA_ADDR_SPI
  54          * unit-addressing, the scsi_address(9S) information contains
  55          * decoded target/lun addressing information.
  56          *
  57          * For devices below an HBA that uses SCSI_HBA_ADDR_COMPLEX
  58          * unit-addressing, the scsi_address(9S) information contains a
  59          * pointer to the scsi_device(9S) structure and the HBA can maintain
  60          * its private per-unit-address/per-scsi_device information using
  61          * scsi_address_device(9F) and scsi_device_hba_private_[gs]et(9F).
  62          *
  63          * NOTE: The scsi_address(9S) structure gets structure-copied into
  64          * the scsi_pkt(9S) 'pkt_address' field. Having a pointer to the
  65          * scsi_device(9S) structure within the scsi_address(9S) allows
  66          * the SCSA framework to reflect generic changes in device state
  67          * at scsi_pkt_comp(9F) time (given just a scsi_pkt(9S) pointer).
  68          *
  69          * NOTE: The older SCSI_HBA_TRAN_CLONE method of supporting
  70          * SCSI-3 devices is still supported, but use is discouraged.
  71          */
  72         struct scsi_address     sd_address;
  73 
  74         /* Cross-reference to target device's dev_info_t. */
  75         dev_info_t              *sd_dev;
  76 
  77         /*
  78          * Target driver mutex for this device. Initialized by SCSA HBA
  79          * framework code prior to probe(9E) or attach(9E) of scsi_device.
  80          */
  81         kmutex_t                sd_mutex;
  82 
  83         /*
  84          * SCSA private: use is associated with implementation of
  85          * SCSI_HBA_ADDR_COMPLEX scsi_device_hba_private_[gs]et(9F).
  86          * The HBA driver can store a pointer to per-scsi_device(9S)
  87          * HBA private data during its tran_tgt_init(9E) implementation
  88          * by calling scsi_device_hba_private_set(9F), and free that
  89          * pointer during tran_tgt_fini(9E). At tran_send(9E) time, the
  90          * HBA driver can use scsi_address_device(9F) to obtain a pointer
  91          * to the scsi_device(9S) structure, and then gain access to
  92          * its per-scsi_device(9S) hba private data by calling
  93          * scsi_device_hba_private_get(9F).
  94          */
  95         void                    *sd_hba_private;
  96 
  97         /*
  98          * If scsi_slave is used to probe out this device, a scsi_inquiry data
  99          * structure will be allocated and an INQUIRY command will be run to
 100          * fill it in.
 101          *
 102          * The allocation will be done via ddi_iopb_alloc, so any manual
 103          * freeing may be done by ddi_iopb_free.
 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 */