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