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