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 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  *
  25  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  26  */
  27 
  28 #ifndef _SYS_SCSI_SCSI_PKT_H
  29 #define _SYS_SCSI_SCSI_PKT_H
  30 
  31 #include <sys/scsi/scsi_types.h>
  32 
  33 #ifdef  __cplusplus
  34 extern "C" {
  35 #endif
  36 
  37 #ifdef  _KERNEL
  38 /*
  39  * SCSI packet definition.
  40  *
  41  *      This structure defines the packet which is allocated by a library
  42  *      function and handed to a target driver. The target driver fills
  43  *      in some information, and passes it to the library for transport
  44  *      to an addressed SCSI device. The host adapter found by
  45  *      the library fills in some other information as the command is
  46  *      processed. When the command completes (or can be taken no further)
  47  *      the function specified in the packet is called with a pointer to
  48  *      the packet as it argument. From fields within the packet, the target
  49  *      driver can determine the success or failure of the command.
  50  */
  51 struct scsi_pkt {
  52         opaque_t pkt_ha_private;        /* private data for host adapter */
  53         struct scsi_address pkt_address;        /* destination packet is for */
  54         opaque_t pkt_private;           /* private data for target driver */
  55         void    (*pkt_comp)(struct scsi_pkt *); /* completion routine */
  56         uint_t  pkt_flags;              /* flags */
  57         int     pkt_time;               /* time allotted to complete command */
  58         uchar_t *pkt_scbp;              /* pointer to status block */
  59         uchar_t *pkt_cdbp;              /* pointer to command block */
  60         ssize_t pkt_resid;              /* data bytes not transferred */
  61         uint_t  pkt_state;              /* state of command */
  62         uint_t  pkt_statistics;         /* statistics */
  63         uchar_t pkt_reason;             /* reason completion called */
  64 
  65         /*
  66          * The DDI does not allow a driver to allocate it's own scsi_pkt(9S),
  67          * a driver should not have *any* compiled in dependencies on
  68          * "sizeof (struct scsi_pkt)". If the driver has such dependencies, it
  69          * limits SCSA's ability to evolve. The proper way for an HBA to
  70          * allocate a scsi_pkt is via scsi_hba_pkt_alloc(9F), or the newer
  71          * tran_setup_pkt(9E) interfaces. Allocation rules have been in place
  72          * for many years, unfortunately a significant number of drivers
  73          * are still broken.
  74          *
  75          * NB: Until we can trust drivers to follow DDI scsi_pkt(9S) allocation
  76          * rules, access to all fields below require special consideration.
  77          * Access to these fields is limited to code paths that 'know' correct
  78          * scsi_pkt allocation interfaces must have been used. This means that
  79          * any target driver access to these fields is suspect, since a target
  80          * knows nothing about how an HBA drivers performs scsi_pkt allocation.
  81          *
  82          * NB: A private scsi_pkt_size() interface has been added to simplify
  83          * 'fixing' legacy HBA drivers.  Use of scsi_pkt_size() is only
  84          * appropriate when the effort/cost of fixing a legacy driver to use
  85          * proper DDI scsi_pkt allocation interfaces is too great given the
  86          * remaining driver life. New HBA drivers should *not* use
  87          * scsi_pkt_size().
  88          *
  89          * NB: While HBA drivers with violations are being fixed, in
  90          * rare cases access conditioned by scsi_pkt_allocated_correctly() is
  91          * permitted.
  92          */
  93         /* HBA driver only, iff scsi_hba_pkt_alloc(9F)|tran_seup_pkt(9E) used */
  94         uint_t  pkt_cdblen;             /* length of pkt_cdbp */
  95         uint_t  pkt_tgtlen;             /* length of pkt_private */
  96         uint_t  pkt_scblen;             /* lenght of pkt_scbp */
  97 
  98         /* HBA driver only, iff tran_seup_pkt(9E) used */
  99         ddi_dma_handle_t pkt_handle;    /* private */
 100         uint_t  pkt_numcookies;         /* number of DMA cookies */
 101         off_t   pkt_dma_offset;         /* private */
 102         size_t  pkt_dma_len;            /* private */
 103         uint_t  pkt_dma_flags;          /* DMA flags */
 104         ddi_dma_cookie_t *pkt_cookies;  /* array of DMA cookies */
 105 
 106         /* private: iff scsi_pkt_allocated_correctly() */
 107         int     pkt_path_instance;      /* pHCI transport path */
 108 
 109         /* stage-temporary: iff scsi_pkt_allocated_correctly() */
 110         void    *pkt_stmp;              /* temporary for current pkt stage */
 111         hrtime_t pkt_start;
 112         hrtime_t pkt_stop;
 113 
 114 #ifdef  SCSI_SIZE_CLEAN_VERIFY
 115         /*
 116          * Must be last: Building a driver with-and-without
 117          * -DSCSI_SIZE_CLEAN_VERIFY, and checking driver modules for
 118          * differences with a tools like 'wsdiff' allows a developer to verify
 119          * that their driver has no dependencies on scsi*(9S) size.
 120          */
 121         int                     i_pkt_pad[8];
 122 #endif  /* SCSI_SIZE_CLEAN_VERIFY */
 123 };
 124 #endif  /* _KERNEL */
 125 
 126 /*
 127  * Definitions for the pkt_flags field.
 128  */
 129 
 130 /*
 131  * Following defines are generic.
 132  */
 133 #define FLAG_STAG       0x4000  /* Run command with Simple attribute */
 134 #define FLAG_OTAG       0x2000  /* Run command with Ordered attribute */
 135 #define FLAG_HTAG       0x1000  /* Run command with Head of Queue attribute */
 136 #define FLAG_TAGMASK    (FLAG_HTAG|FLAG_OTAG|FLAG_STAG)
 137 
 138 #define FLAG_ACA        0x0100  /* internal; do not use */
 139 #define FLAG_HEAD       0x8000  /* This cmd should be put at the head   */
 140                                 /* of the HBA driver's queue            */
 141 #define FLAG_SENSING    0x0400  /* Running request sense for failed pkt */
 142 #define FLAG_NOINTR     0x0001  /* Run command with no cmd completion   */
 143                                 /* callback; command has been completed */
 144                                 /* upon return from scsi_transport(9F)  */
 145 
 146 /*
 147  * Following defines are appropriate for SCSI parallel bus.
 148  */
 149 #define FLAG_NODISCON   0x0002  /* Run command without disconnects      */
 150 #define FLAG_NOPARITY   0x0008  /* Run command without parity checking  */
 151 #define FLAG_RENEGOTIATE_WIDE_SYNC \
 152                         0x1000000 /* Do wide and sync renegotiation before */
 153                                 /* transporting this command to target */
 154 
 155 /*
 156  * Following defines are internal i.e. not part of DDI.
 157  */
 158 #define FLAG_IMMEDIATE_CB \
 159                         0x0800  /* Immediate callback on command */
 160                                 /* completion, ie. do not defer */
 161 
 162 /*
 163  * Following defines are for USCSI options.
 164  */
 165 #define FLAG_SILENT             0x00010000
 166 #define FLAG_DIAGNOSE           0x00020000
 167 #define FLAG_ISOLATE            0x00040000
 168 
 169 /*
 170  * pkg_flag for TLR
 171  */
 172 #define FLAG_TLR                0x00080000
 173 
 174 
 175 /*
 176  * Following define is for scsi_vhci.
 177  *   NOQUEUE            If pHCI cannot transport the command to the device,
 178  *                      do not queue the pkt in pHCI. Return immediately with
 179  *                      TRAN_BUSY.
 180  *   PATH_INSTANCE      Select specific path (pkt_path_instance).
 181  *                      We need both a pkt_path_instance field and flag bit so
 182  *                      that a retry after a path failure, which sets
 183  *                      pkt_path_instance to failed path, does not select the
 184  *                      failed path.
 185  */
 186 #define FLAG_NOQUEUE            0x80000000
 187 #define FLAG_PKT_PATH_INSTANCE  0x40000000      /* Tell vhci the path to use */
 188 #define FLAG_PKT_COMP_CALLED    0x20000000      /* Set once pkt_comp called */
 189 
 190 /* Extended flags. */
 191 #define FLAG_PKT_BUSY           0x04000000      /* Reject packet immediately. */
 192 #define FLAG_PKT_TIMEOUT        0x08000000      /* Timed-out packet. */
 193 
 194 /*
 195  * Definitions for the pkt_reason field.
 196  */
 197 
 198 /*
 199  * Following defines are generic.
 200  */
 201 #define CMD_CMPLT       0       /* no transport errors- normal completion */
 202 #define CMD_INCOMPLETE  1       /* transport stopped with not normal state */
 203 #define CMD_DMA_DERR    2       /* dma direction error occurred */
 204 #define CMD_TRAN_ERR    3       /* unspecified transport error */
 205 #define CMD_RESET       4       /* Target completed hard reset sequence */
 206 #define CMD_ABORTED     5       /* Command transport aborted on request */
 207 #define CMD_TIMEOUT     6       /* Command timed out */
 208 #define CMD_DATA_OVR    7       /* Data Overrun */
 209 #define CMD_CMD_OVR     8       /* Command Overrun */
 210 #define CMD_STS_OVR     9       /* Status Overrun */
 211 #define CMD_TERMINATED  22      /* Command transport terminated on request */
 212 #define CMD_TLR_OFF     23      /* don't support TLR */
 213 
 214 /*
 215  * Following defines are appropriate for SCSI parallel bus.
 216  */
 217 #define CMD_BADMSG      10      /* Message not Command Complete */
 218 #define CMD_NOMSGOUT    11      /* Target refused to go to Message Out phase */
 219 #define CMD_XID_FAIL    12      /* Extended Identify message rejected */
 220 #define CMD_IDE_FAIL    13      /* Initiator Detected Error message rejected */
 221 #define CMD_ABORT_FAIL  14      /* Abort message rejected */
 222 #define CMD_REJECT_FAIL 15      /* Reject message rejected */
 223 #define CMD_NOP_FAIL    16      /* No Operation message rejected */
 224 #define CMD_PER_FAIL    17      /* Message Parity Error message rejected */
 225 #define CMD_BDR_FAIL    18      /* Bus Device Reset message rejected */
 226 #define CMD_ID_FAIL     19      /* Identify message rejected */
 227 #define CMD_UNX_BUS_FREE        20      /* Unexpected Bus Free Phase occurred */
 228 #define CMD_TAG_REJECT  21      /* Target rejected our tag message */
 229 #define CMD_DEV_GONE    24      /* The device has been removed */
 230 
 231 /* Used by scsi_rname(9F) */
 232 #define CMD_REASON_ASCII        { \
 233             "cmplt", "incomplete", "dma_derr", "tran_err", "reset", \
 234             "aborted", "timeout", "data_ovr", "cmd_ovr", "sts_ovr", \
 235             "badmsg", "nomsgout", "xid_fail", "ide_fail", "abort_fail", \
 236             "reject_fail", "nop_fail", "per_fail", "bdr_fail", "id_fail", \
 237             "unexpected_bus_free", "tag reject", "terminated", "", "gone", \
 238             NULL }
 239 
 240 /*
 241  * Definitions for the pkt_state field
 242  */
 243 #define STATE_GOT_BUS           0x01    /* Success in getting SCSI bus */
 244 #define STATE_GOT_TARGET        0x02    /* Successfully connected with target */
 245 #define STATE_SENT_CMD          0x04    /* Command successfully sent */
 246 #define STATE_XFERRED_DATA      0x08    /* Data transfer took place */
 247 #define STATE_GOT_STATUS        0x10    /* SCSI status received */
 248 #define STATE_ARQ_DONE          0x20    /* auto rqsense took place */
 249 #define STATE_XARQ_DONE         0X40    /* extra auto rqsense took place */
 250 
 251 /*
 252  * Definitions for the pkt_statistics field
 253  */
 254 
 255 /*
 256  * Following defines are generic.
 257  */
 258 #define STAT_BUS_RESET  0x8     /* Reset operation on interconnect */
 259 #define STAT_DEV_RESET  0x10    /* Target completed hard reset sequence */
 260 #define STAT_ABORTED    0x20    /* Command was aborted */
 261 #define STAT_TERMINATED 0x80    /* Command was terminated */
 262 #define STAT_TIMEOUT    0x40    /* Command experienced a timeout */
 263 
 264 /*
 265  * Following defines are appropriate for SCSI parallel bus.
 266  */
 267 #define STAT_DISCON     0x1     /* Command experienced a disconnect */
 268 #define STAT_SYNC       0x2     /* Command did a synchronous data transfer */
 269 #define STAT_PERR       0x4     /* Command experienced a SCSI parity error */
 270 
 271 /*
 272  * Definitions for what scsi_transport returns
 273  */
 274 #define TRAN_ACCEPT             1
 275 #define TRAN_BUSY               0
 276 #define TRAN_BADPKT             -1
 277 #define TRAN_FATAL_ERROR        -2      /* HBA cannot accept any pkts */
 278 
 279 #ifdef  _KERNEL
 280 /*
 281  * Kernel function declarations
 282  */
 283 int     scsi_transport(struct scsi_pkt *pkt);
 284 
 285 #define pkt_transport   scsi_transport
 286 
 287 #define SCSI_POLL_TIMEOUT       60
 288 
 289 #endif  /* _KERNEL */
 290 
 291 #ifdef  __cplusplus
 292 }
 293 #endif
 294 
 295 #endif  /* _SYS_SCSI_SCSI_PKT_H */