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 34extern "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 */ 98typedef struct ses_softc ses_softc_t; 99 100typedef 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 109typedef enum { SES_TYPE, SAFT_TYPE, SEN_TYPE } enctyp; 110 111typedef 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 136struct 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) 321extern void ses_log(ses_softc_t *, int, const char *, ...); 322extern int ses_runcmd(ses_softc_t *, Uscmd *); 323extern int ses_uscsi_cmd(ses_softc_t *, Uscmd *, int); 324extern int ses_io_time; 325 326#ifdef DEBUG 327extern 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