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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Enclosure Services Device target driver 24 * 25 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #ifndef _SYS_SCSI_TARGETS_SES_H 30 #define _SYS_SCSI_TARGETS_SES_H 31 32 #pragma ident "%Z%%M% %I% %E% SMI" 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 #ifndef __lint /* no warlock for X86 */ 123 #ifdef _KERNEL 124 _NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, encobj)) 125 _NOTE(DATA_READABLE_WITHOUT_LOCK(encobj::priv)) 126 _NOTE(DATA_READABLE_WITHOUT_LOCK(encobj::svalid)) 127 _NOTE(DATA_READABLE_WITHOUT_LOCK(encobj::enctype)) 128 _NOTE(DATA_READABLE_WITHOUT_LOCK(encobj::encstat)) 129 _NOTE(DATA_READABLE_WITHOUT_LOCK(encobj::subenclosure)) 130 #endif /* _KERNEL */ 131 #endif /* __lint */ 132 133 134 /* 135 * Overall Status is bits 0..3- status validity reserved at bit 7 136 */ 137 #define ENCI_SVALID 0x80 138 139 struct ses_softc { 140 enctyp ses_type; /* type of enclosure */ 141 encvec ses_vec; /* vector to handlers */ 142 uint_t ses_nobjects; /* number of objects */ 143 void * ses_private; /* private data */ 144 encobj * ses_objmap; /* objects */ 145 uchar_t ses_encstat; /* overall status */ 146 Scsidevp ses_devp; /* backpointer to owning SCSI device */ 147 struct buf *ses_rqbp; /* request sense buf pointer */ 148 Scsipktp ses_rqpkt; /* SCSI Request Sense Packet */ 149 struct buf *ses_sbufp; /* for use in internal io */ 150 timeout_id_t ses_restart_id; /* restart timeout id */ 151 kcondvar_t ses_sbufcv; /* cv on sbuf */ 152 uchar_t ses_sbufbsy; /* sbuf busy flag */ 153 uchar_t ses_oflag; /* nonzero if opened (nonlayered) */ 154 uchar_t ses_present; /* device present */ 155 uchar_t ses_suspended; /* nonzero if suspended */ 156 uchar_t ses_arq; /* auto request sense enabled */ 157 uint_t ses_lyropen; /* layered open count */ 158 int ses_retries; /* retry count */ 159 /* 160 * Associated storage for the special buf. 161 * Since we're single threaded on sbuf anyway, 162 * we might as well save ourselves a pile of 163 * grief and allocate local uscsicmd and 164 * ancillary storage here. 165 */ 166 Uscmd ses_uscsicmd; 167 uchar_t ses_srqcdb[CDB_SIZE]; 168 uchar_t ses_srqsbuf[SENSE_LENGTH]; 169 }; 170 171 #ifndef __lint /* no warlock for X86 */ 172 #ifdef _KERNEL 173 _NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, ses_softc)) 174 _NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, ses_softc::ses_lyropen)) 175 176 _NOTE(SCHEME_PROTECTS_DATA("not shared", scsi_arq_status)) 177 _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_restart_id)) 178 _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_retries)) 179 _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_present)) 180 _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_suspended)) 181 _NOTE(SCHEME_PROTECTS_DATA("stable data", 182 ses_softc::ses_type 183 ses_softc::ses_vec 184 ses_softc::ses_nobjects 185 ses_softc::ses_devp 186 ses_softc::ses_arq)) 187 188 _NOTE(SCHEME_PROTECTS_DATA("sbufp cv", 189 ses_softc::ses_sbufp 190 ses_softc::ses_rqpkt 191 ses_softc::ses_rqbp 192 ses_softc::ses_sbufbsy 193 ses_softc::ses_uscsicmd 194 ses_softc::ses_srqcdb 195 ses_softc::ses_srqsbuf 196 ses_softc::ses_uscsicmd)) 197 198 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt buf uio scsi_cdb)) 199 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_extended_sense scsi_status)) 200 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", uscsi_cmd)) 201 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device)) 202 203 _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_encstat)) 204 _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_objmap)) 205 _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_private)) 206 _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_lyropen)) 207 _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_oflag)) 208 209 _NOTE(SCHEME_PROTECTS_DATA("absurdities", ses_objarg)) 210 #endif /* _KERNEL */ 211 #endif /* __lint */ 212 213 214 /* 215 * Compile options to turn on debugging code 216 */ 217 #ifdef DEBUG 218 #define SES_DEBUG 219 #endif /* DEBUG */ 220 221 #if defined(_KERNEL) || defined(_KMEMUSER) 222 223 #define SES_CE_DEBUG ((1 << 8) | CE_CONT) 224 #define SES_CE_DEBUG1 ((2 << 8) | CE_CONT) 225 #define SES_CE_DEBUG2 ((3 << 8) | CE_CONT) 226 #define SES_CE_DEBUG3 ((4 << 8) | CE_CONT) 227 #define SES_CE_DEBUG4 ((5 << 8) | CE_CONT) 228 #define SES_CE_DEBUG5 ((6 << 8) | CE_CONT) 229 #define SES_CE_DEBUG6 ((7 << 8) | CE_CONT) 230 #define SES_CE_DEBUG7 ((8 << 8) | CE_CONT) 231 #define SES_CE_DEBUG8 ((9 << 8) | CE_CONT) 232 #define SES_CE_DEBUG9 ((10 << 8) | CE_CONT) 233 234 #ifndef SES_DEBUG 235 #define ses_debug 0 236 #endif /* SES_DEBUG */ 237 238 #define SES_LOG if (ses_debug) ses_log 239 #define SES_DEBUG_ENTER if (ses_debug) debug_enter 240 241 242 /* 243 * Various I/O timeouts. 244 * 245 * These are hard-coded and not adjustable. The restart macro 246 * time input is in milliseconds with 1 msec. the minimum setting. 247 * 248 */ 249 #define SES_IO_TIME 60 /* standard I/O time (sec.) */ 250 #define SES_RESTART_TIME 100 /* I/O restart time (ms.) */ 251 #define SES_BUSY_TIME 5000 /* I/O busy restart time (ms.) */ 252 253 #define SES_ENABLE_RESTART(ms_time, pkt) { \ 254 ssc->ses_restart_id = timeout(ses_restart, (void *) pkt, \ 255 (ms_time)? (ms_time * drv_usectohz(1000)): 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 2 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, int, int, 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