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 * Enclosure Services Device target driver 23 * 24 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 /* 28 * Copyright 2020 RackTop Systems, Inc. 29 */ 30 31 #ifndef _SYS_SCSI_TARGETS_SES_H 32 #define _SYS_SCSI_TARGETS_SES_H 33 34 #include <sys/note.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 41 /* 42 * Useful defines and typedefs 43 */ 44 #define EOK 0 45 46 #define INVOP 0x10 47 48 #define BP_PKT(bp) ((struct scsi_pkt *)(bp)->av_back) 49 #define SET_BP_PKT(bp, s) (bp)->av_back = (struct buf *)(s) 50 51 #define SCBP(pkt) ((struct scsi_status *)(pkt)->pkt_scbp) 52 #define SCBP_C(pkt) ((*(pkt)->pkt_scbp) & STATUS_MASK) 53 #define Scsidevp struct scsi_device * 54 #define Scsipktp struct scsi_pkt * 55 #define Uscmd struct uscsi_cmd 56 57 #define SES_SCSI_DEVP (un->ses_scsi_devp) 58 #define SES_DEVP(softc) ((softc)->ses_devp) 59 #define SES_DEVINFO(softc) (SES_DEVP(softc)->sd_dev) 60 #define SES_RQSENSE(softc) (SES_DEVP(softc)->sd_sense) 61 #define SES_ROUTE(softc) (&SES_DEVP(softc)->sd_address) 62 #define SES_MUTEX (&ssc->ses_devp->sd_mutex) 63 64 #define ISOPEN(softc) ((softc)->ses_lyropen || (softc)->ses_oflag) 65 #define UNUSED_PARAMETER(x) x = x 66 67 68 /* 69 * SAF-TE specific defines- Mandatory ones only... 70 */ 71 72 /* 73 * READ BUFFER ('get' commands) IDs- placed in offset 2 of cdb 74 */ 75 #define SAFTE_RD_RDCFG 0x00 /* read enclosure configuration */ 76 #define SAFTE_RD_RDESTS 0x01 /* read enclosure status */ 77 #define SAFTE_RD_RDDSTS 0x04 /* read drive slot status */ 78 79 /* 80 * WRITE BUFFER ('set' commands) IDs- placed in offset 0 of databuf 81 */ 82 #define SAFTE_WT_DSTAT 0x10 /* write device slot status */ 83 #define SAFTE_WT_SLTOP 0x12 /* perform slot operation */ 84 #define SAFTE_WT_FANSPD 0x13 /* set fan speed */ 85 #define SAFTE_WT_ACTPWS 0x14 /* turn on/off power supply */ 86 #define SAFTE_WT_GLOBAL 0x15 /* send global command */ 87 88 89 /* 90 * Includes 91 */ 92 #include <sys/scsi/targets/sesio.h> 93 94 95 /* 96 * Private info (Device Info. Private) 97 * 98 * Pointed to by the un_private pointer 99 * of one of the SCSI_DEVICE structures. 100 */ 101 typedef struct ses_softc ses_softc_t; 102 103 typedef struct { 104 int (*softc_init)(ses_softc_t *, int); 105 int (*init_enc)(ses_softc_t *); 106 int (*get_encstat)(ses_softc_t *, int); 107 int (*set_encstat)(ses_softc_t *, uchar_t, int); 108 int (*get_objstat)(ses_softc_t *, ses_objarg *, int); 109 int (*set_objstat)(ses_softc_t *, ses_objarg *, int); 110 } encvec; 111 112 typedef enum { SES_TYPE, SAFT_TYPE, SEN_TYPE } enctyp; 113 114 typedef struct { 115 uchar_t enctype; /* enclosure type */ 116 uchar_t subenclosure; /* subenclosure id */ 117 ushort_t svalid : 1, /* enclosure information valid */ 118 priv : 15; /* private data, per object */ 119 uchar_t encstat[4]; /* state && stats */ 120 } encobj; 121 122 123 /* 124 * Overall Status is bits 0..3- status validity reserved at bit 7 125 */ 126 #define ENCI_SVALID 0x80 127 128 struct ses_softc { 129 enctyp ses_type; /* type of enclosure */ 130 encvec ses_vec; /* vector to handlers */ 131 uint_t ses_nobjects; /* number of objects */ 132 void * ses_private; /* private data */ 133 encobj * ses_objmap; /* objects */ 134 uchar_t ses_encstat; /* overall status */ 135 Scsidevp ses_devp; /* backpointer to owning SCSI device */ 136 struct buf *ses_rqbp; /* request sense buf pointer */ 137 Scsipktp ses_rqpkt; /* SCSI Request Sense Packet */ 138 struct buf *ses_sbufp; /* for use in internal io */ 139 timeout_id_t ses_restart_id; /* restart timeout id */ 140 kcondvar_t ses_sbufcv; /* cv on sbuf */ 141 uchar_t ses_sbufbsy; /* sbuf busy flag */ 142 uchar_t ses_oflag; /* nonzero if opened (nonlayered) */ 143 uchar_t ses_present; /* device present */ 144 uchar_t ses_suspended; /* nonzero if suspended */ 145 uchar_t ses_arq; /* auto request sense enabled */ 146 uint_t ses_lyropen; /* layered open count */ 147 int ses_retries; /* retry count */ 148 ddi_devid_t ses_dev_id; /* device id */ 149 /* 150 * Associated storage for the special buf. 151 * Since we're single threaded on sbuf anyway, 152 * we might as well save ourselves a pile of 153 * grief and allocate local uscsicmd and 154 * ancillary storage here. 155 */ 156 Uscmd ses_uscsicmd; 157 uchar_t ses_srqcdb[CDB_SIZE]; 158 uchar_t ses_srqsbuf[MAX_SENSE_LENGTH]; 159 }; 160 161 #ifndef __lint /* no warlock for X86 */ 162 #ifdef _KERNEL 163 _NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, ses_softc)) 164 _NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, ses_softc::ses_lyropen)) 165 166 _NOTE(SCHEME_PROTECTS_DATA("not shared", scsi_arq_status)) 167 _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_restart_id)) 168 _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_retries)) 169 _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_present)) 170 _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_suspended)) 171 _NOTE(SCHEME_PROTECTS_DATA("stable data", 172 ses_softc::ses_type 173 ses_softc::ses_vec 174 ses_softc::ses_nobjects 175 ses_softc::ses_devp 176 ses_softc::ses_arq)) 177 178 _NOTE(SCHEME_PROTECTS_DATA("sbufp cv", 179 ses_softc::ses_sbufp 180 ses_softc::ses_rqpkt 181 ses_softc::ses_rqbp 182 ses_softc::ses_sbufbsy 183 ses_softc::ses_uscsicmd 184 ses_softc::ses_srqcdb 185 ses_softc::ses_srqsbuf 186 ses_softc::ses_uscsicmd)) 187 188 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt buf uio scsi_cdb)) 189 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_extended_sense scsi_status)) 190 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", uscsi_cmd)) 191 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device)) 192 193 _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_encstat)) 194 _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_objmap)) 195 _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_private)) 196 _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_lyropen)) 197 _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_oflag)) 198 199 _NOTE(SCHEME_PROTECTS_DATA("absurdities", ses_objarg)) 200 #endif /* _KERNEL */ 201 #endif /* __lint */ 202 203 204 /* 205 * Compile options to turn on debugging code 206 */ 207 #ifdef DEBUG 208 #define SES_DEBUG 209 #endif /* DEBUG */ 210 211 #if defined(_KERNEL) || defined(_KMEMUSER) 212 213 #define SES_CE_DEBUG ((1 << 8) | CE_CONT) 214 #define SES_CE_DEBUG1 ((2 << 8) | CE_CONT) 215 #define SES_CE_DEBUG2 ((3 << 8) | CE_CONT) 216 #define SES_CE_DEBUG3 ((4 << 8) | CE_CONT) 217 #define SES_CE_DEBUG4 ((5 << 8) | CE_CONT) 218 #define SES_CE_DEBUG5 ((6 << 8) | CE_CONT) 219 #define SES_CE_DEBUG6 ((7 << 8) | CE_CONT) 220 #define SES_CE_DEBUG7 ((8 << 8) | CE_CONT) 221 #define SES_CE_DEBUG8 ((9 << 8) | CE_CONT) 222 #define SES_CE_DEBUG9 ((10 << 8) | CE_CONT) 223 224 #ifndef SES_DEBUG 225 #define ses_debug 0 226 #endif /* SES_DEBUG */ 227 228 #define SES_LOG if (ses_debug) ses_log 229 #define SES_DEBUG_ENTER if (ses_debug) debug_enter 230 231 232 /* 233 * Various I/O timeouts. 234 * 235 * These are hard-coded and not adjustable. The restart macro 236 * time input is in milliseconds with 1 msec. the minimum setting. 237 * 238 */ 239 #define SES_IO_TIME 60 /* standard I/O time (sec.) */ 240 #define SES_RESTART_TIME 100 /* I/O restart time (ms.) */ 241 #define SES_BUSY_TIME 500 /* I/O busy restart time (ms.) */ 242 243 #define SES_ENABLE_RESTART(ms_time, pkt) { \ 244 ssc->ses_restart_id = timeout(ses_restart, (void *) pkt, \ 245 (ms_time)? (drv_usectohz(ms_time * 1000)) : \ 246 drv_usectohz(1000)); \ 247 } 248 249 250 /* 251 * Number of times we'll retry a normal operation. 252 * 253 * Note, retries have differnt weights to max retries. 254 * Unit Attention and request sense have the most retries. 255 * Command retries have the least. 256 * 257 * For no auto-request sense operation, the SES_RETRY_MULTIPLIER 258 * must be greater than the command RETRY_COUNT. Then the request 259 * sense commands won't impact the command retries. 260 */ 261 #define SES_RETRY_COUNT 4 262 #define SES_RETRY_MULTIPLIER 8 263 264 #define SES_CMD_RETRY SES_RETRY_MULTIPLIER 265 #define SES_NO_RETRY 0 266 #define SES_SENSE_RETRY 1 267 #define SES_BUSY_RETRY 4 268 269 /* Retry weight is 1 */ 270 #define SES_CMD_RETRY1(retry) \ 271 retry += (retry > 0)? (SES_RETRY_MULTIPLIER -1) : 0; 272 273 /* Retry weight is 2 */ 274 #define SES_CMD_RETRY2(retry) \ 275 retry += (retry > 0)? (SES_RETRY_MULTIPLIER -2) : 0; 276 277 /* Retry weight is 4 */ 278 #define SES_CMD_RETRY4(retry) \ 279 retry += (retry > 0)? (SES_RETRY_MULTIPLIER -4) : 0; 280 281 282 /* 283 * ses_present definitions 284 */ 285 #define SES_CLOSED 0 286 #define SES_OPENING 1 287 #define SES_OPEN 2 288 289 290 /* 291 * ses_callback action codes 292 */ 293 #define COMMAND_DONE 0 294 #define COMMAND_DONE_ERROR 1 295 #define QUE_COMMAND_NOW 3 296 #define QUE_COMMAND 4 297 #define QUE_SENSE 5 298 299 300 /* 301 * PF bit for RECEIVE DIAG command; 302 * needed for RSM first release hw. 303 */ 304 #define SCSI_ESI_PF 0x10 305 #define SEN_ID "UNISYS SUN_SEN" 306 #define SEN_ID_LEN 24 307 308 #define SET_BP_ERROR(bp, err) bioerror(bp, err); 309 310 /* 311 * Common Driver Functions 312 */ 313 #if defined(_KERNEL) 314 extern void ses_log(ses_softc_t *, int, const char *, ...); 315 extern int ses_runcmd(ses_softc_t *, Uscmd *); 316 extern int ses_uscsi_cmd(ses_softc_t *, Uscmd *, int); 317 extern int ses_io_time; 318 319 #ifdef DEBUG 320 extern int ses_debug; 321 #endif /* DEBUG */ 322 323 #endif /* defined(_KERNEL) */ 324 325 326 #endif /* defined(_KERNEL) || defined(_KMEMUSER) */ 327 328 #ifdef __cplusplus 329 } 330 #endif 331 332 #endif /* _SYS_SCSI_TARGETS_SES_H */ 333