10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 53368Slh195018 * Common Development and Distribution License (the "License"). 63368Slh195018 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 220Sstevel@tonic-gate * Enclosure Services Device target driver 230Sstevel@tonic-gate * 246948Sjmcp * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 250Sstevel@tonic-gate * Use is subject to license terms. 260Sstevel@tonic-gate */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #ifndef _SYS_SCSI_TARGETS_SES_H 290Sstevel@tonic-gate #define _SYS_SCSI_TARGETS_SES_H 300Sstevel@tonic-gate 310Sstevel@tonic-gate #include <sys/note.h> 320Sstevel@tonic-gate 330Sstevel@tonic-gate #ifdef __cplusplus 340Sstevel@tonic-gate extern "C" { 350Sstevel@tonic-gate #endif 360Sstevel@tonic-gate 370Sstevel@tonic-gate 380Sstevel@tonic-gate /* 390Sstevel@tonic-gate * Useful defines and typedefs 400Sstevel@tonic-gate */ 410Sstevel@tonic-gate #define EOK 0 420Sstevel@tonic-gate 430Sstevel@tonic-gate #define INVOP 0x10 440Sstevel@tonic-gate 450Sstevel@tonic-gate #define BP_PKT(bp) ((struct scsi_pkt *)(bp)->av_back) 460Sstevel@tonic-gate #define SET_BP_PKT(bp, s) (bp)->av_back = (struct buf *)(s) 470Sstevel@tonic-gate 480Sstevel@tonic-gate #define SCBP(pkt) ((struct scsi_status *)(pkt)->pkt_scbp) 490Sstevel@tonic-gate #define SCBP_C(pkt) ((*(pkt)->pkt_scbp) & STATUS_MASK) 500Sstevel@tonic-gate #define Scsidevp struct scsi_device * 510Sstevel@tonic-gate #define Scsipktp struct scsi_pkt * 520Sstevel@tonic-gate #define Uscmd struct uscsi_cmd 530Sstevel@tonic-gate 540Sstevel@tonic-gate #define SES_SCSI_DEVP (un->ses_scsi_devp) 550Sstevel@tonic-gate #define SES_DEVP(softc) ((softc)->ses_devp) 560Sstevel@tonic-gate #define SES_DEVINFO(softc) (SES_DEVP(softc)->sd_dev) 570Sstevel@tonic-gate #define SES_RQSENSE(softc) (SES_DEVP(softc)->sd_sense) 580Sstevel@tonic-gate #define SES_ROUTE(softc) (&SES_DEVP(softc)->sd_address) 590Sstevel@tonic-gate #define SES_MUTEX (&ssc->ses_devp->sd_mutex) 600Sstevel@tonic-gate 610Sstevel@tonic-gate #define ISOPEN(softc) ((softc)->ses_lyropen || (softc)->ses_oflag) 620Sstevel@tonic-gate #define UNUSED_PARAMETER(x) x = x 630Sstevel@tonic-gate 640Sstevel@tonic-gate 650Sstevel@tonic-gate /* 660Sstevel@tonic-gate * SAF-TE specific defines- Mandatory ones only... 670Sstevel@tonic-gate */ 680Sstevel@tonic-gate 690Sstevel@tonic-gate /* 700Sstevel@tonic-gate * READ BUFFER ('get' commands) IDs- placed in offset 2 of cdb 710Sstevel@tonic-gate */ 720Sstevel@tonic-gate #define SAFTE_RD_RDCFG 0x00 /* read enclosure configuration */ 730Sstevel@tonic-gate #define SAFTE_RD_RDESTS 0x01 /* read enclosure status */ 740Sstevel@tonic-gate #define SAFTE_RD_RDDSTS 0x04 /* read drive slot status */ 750Sstevel@tonic-gate 760Sstevel@tonic-gate /* 770Sstevel@tonic-gate * WRITE BUFFER ('set' commands) IDs- placed in offset 0 of databuf 780Sstevel@tonic-gate */ 790Sstevel@tonic-gate #define SAFTE_WT_DSTAT 0x10 /* write device slot status */ 800Sstevel@tonic-gate #define SAFTE_WT_SLTOP 0x12 /* perform slot operation */ 810Sstevel@tonic-gate #define SAFTE_WT_FANSPD 0x13 /* set fan speed */ 820Sstevel@tonic-gate #define SAFTE_WT_ACTPWS 0x14 /* turn on/off power supply */ 830Sstevel@tonic-gate #define SAFTE_WT_GLOBAL 0x15 /* send global command */ 840Sstevel@tonic-gate 850Sstevel@tonic-gate 860Sstevel@tonic-gate /* 870Sstevel@tonic-gate * Includes 880Sstevel@tonic-gate */ 890Sstevel@tonic-gate #include <sys/scsi/targets/sesio.h> 900Sstevel@tonic-gate 910Sstevel@tonic-gate 920Sstevel@tonic-gate /* 930Sstevel@tonic-gate * Private info (Device Info. Private) 940Sstevel@tonic-gate * 950Sstevel@tonic-gate * Pointed to by the un_private pointer 960Sstevel@tonic-gate * of one of the SCSI_DEVICE structures. 970Sstevel@tonic-gate */ 980Sstevel@tonic-gate typedef struct ses_softc ses_softc_t; 990Sstevel@tonic-gate 1000Sstevel@tonic-gate typedef struct { 1010Sstevel@tonic-gate int (*softc_init)(ses_softc_t *, int); 1020Sstevel@tonic-gate int (*init_enc)(ses_softc_t *); 1030Sstevel@tonic-gate int (*get_encstat)(ses_softc_t *, int); 1040Sstevel@tonic-gate int (*set_encstat)(ses_softc_t *, uchar_t, int); 1050Sstevel@tonic-gate int (*get_objstat)(ses_softc_t *, ses_objarg *, int); 1060Sstevel@tonic-gate int (*set_objstat)(ses_softc_t *, ses_objarg *, int); 1070Sstevel@tonic-gate } encvec; 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate typedef enum { SES_TYPE, SAFT_TYPE, SEN_TYPE } enctyp; 1100Sstevel@tonic-gate 1110Sstevel@tonic-gate typedef struct { 1120Sstevel@tonic-gate uchar_t enctype; /* enclosure type */ 1130Sstevel@tonic-gate uchar_t subenclosure; /* subenclosure id */ 1140Sstevel@tonic-gate ushort_t svalid : 1, /* enclosure information valid */ 1150Sstevel@tonic-gate priv : 15; /* private data, per object */ 1160Sstevel@tonic-gate uchar_t encstat[4]; /* state && stats */ 1170Sstevel@tonic-gate } encobj; 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate #ifndef __lint /* no warlock for X86 */ 1200Sstevel@tonic-gate #ifdef _KERNEL 1210Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, encobj)) 1220Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(encobj::priv)) 1230Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(encobj::svalid)) 1240Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(encobj::enctype)) 1250Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(encobj::encstat)) 1260Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(encobj::subenclosure)) 1270Sstevel@tonic-gate #endif /* _KERNEL */ 1280Sstevel@tonic-gate #endif /* __lint */ 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate /* 1320Sstevel@tonic-gate * Overall Status is bits 0..3- status validity reserved at bit 7 1330Sstevel@tonic-gate */ 1340Sstevel@tonic-gate #define ENCI_SVALID 0x80 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate struct ses_softc { 1370Sstevel@tonic-gate enctyp ses_type; /* type of enclosure */ 1380Sstevel@tonic-gate encvec ses_vec; /* vector to handlers */ 1390Sstevel@tonic-gate uint_t ses_nobjects; /* number of objects */ 1400Sstevel@tonic-gate void * ses_private; /* private data */ 1410Sstevel@tonic-gate encobj * ses_objmap; /* objects */ 1420Sstevel@tonic-gate uchar_t ses_encstat; /* overall status */ 1430Sstevel@tonic-gate Scsidevp ses_devp; /* backpointer to owning SCSI device */ 1440Sstevel@tonic-gate struct buf *ses_rqbp; /* request sense buf pointer */ 1450Sstevel@tonic-gate Scsipktp ses_rqpkt; /* SCSI Request Sense Packet */ 1460Sstevel@tonic-gate struct buf *ses_sbufp; /* for use in internal io */ 1470Sstevel@tonic-gate timeout_id_t ses_restart_id; /* restart timeout id */ 1480Sstevel@tonic-gate kcondvar_t ses_sbufcv; /* cv on sbuf */ 1490Sstevel@tonic-gate uchar_t ses_sbufbsy; /* sbuf busy flag */ 1500Sstevel@tonic-gate uchar_t ses_oflag; /* nonzero if opened (nonlayered) */ 1510Sstevel@tonic-gate uchar_t ses_present; /* device present */ 1520Sstevel@tonic-gate uchar_t ses_suspended; /* nonzero if suspended */ 1530Sstevel@tonic-gate uchar_t ses_arq; /* auto request sense enabled */ 1540Sstevel@tonic-gate uint_t ses_lyropen; /* layered open count */ 1550Sstevel@tonic-gate int ses_retries; /* retry count */ 1560Sstevel@tonic-gate /* 1570Sstevel@tonic-gate * Associated storage for the special buf. 1580Sstevel@tonic-gate * Since we're single threaded on sbuf anyway, 1590Sstevel@tonic-gate * we might as well save ourselves a pile of 1600Sstevel@tonic-gate * grief and allocate local uscsicmd and 1610Sstevel@tonic-gate * ancillary storage here. 1620Sstevel@tonic-gate */ 1630Sstevel@tonic-gate Uscmd ses_uscsicmd; 1640Sstevel@tonic-gate uchar_t ses_srqcdb[CDB_SIZE]; 165*7424SLi.He@Sun.COM uchar_t ses_srqsbuf[MAX_SENSE_LENGTH]; 1660Sstevel@tonic-gate }; 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate #ifndef __lint /* no warlock for X86 */ 1690Sstevel@tonic-gate #ifdef _KERNEL 1700Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, ses_softc)) 1710Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, ses_softc::ses_lyropen)) 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("not shared", scsi_arq_status)) 1740Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_restart_id)) 1750Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_retries)) 1760Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_present)) 1770Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("not shared", ses_softc::ses_suspended)) 1780Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("stable data", 1790Sstevel@tonic-gate ses_softc::ses_type 1800Sstevel@tonic-gate ses_softc::ses_vec 1810Sstevel@tonic-gate ses_softc::ses_nobjects 1820Sstevel@tonic-gate ses_softc::ses_devp 1830Sstevel@tonic-gate ses_softc::ses_arq)) 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("sbufp cv", 1860Sstevel@tonic-gate ses_softc::ses_sbufp 1870Sstevel@tonic-gate ses_softc::ses_rqpkt 1880Sstevel@tonic-gate ses_softc::ses_rqbp 1890Sstevel@tonic-gate ses_softc::ses_sbufbsy 1900Sstevel@tonic-gate ses_softc::ses_uscsicmd 1910Sstevel@tonic-gate ses_softc::ses_srqcdb 1920Sstevel@tonic-gate ses_softc::ses_srqsbuf 1930Sstevel@tonic-gate ses_softc::ses_uscsicmd)) 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt buf uio scsi_cdb)) 1960Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_extended_sense scsi_status)) 1970Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", uscsi_cmd)) 1980Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device)) 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_encstat)) 2010Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_objmap)) 2020Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_private)) 2030Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_lyropen)) 2040Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ses_softc::ses_oflag)) 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("absurdities", ses_objarg)) 2070Sstevel@tonic-gate #endif /* _KERNEL */ 2080Sstevel@tonic-gate #endif /* __lint */ 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate /* 2120Sstevel@tonic-gate * Compile options to turn on debugging code 2130Sstevel@tonic-gate */ 2140Sstevel@tonic-gate #ifdef DEBUG 2150Sstevel@tonic-gate #define SES_DEBUG 2160Sstevel@tonic-gate #endif /* DEBUG */ 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate #if defined(_KERNEL) || defined(_KMEMUSER) 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate #define SES_CE_DEBUG ((1 << 8) | CE_CONT) 2210Sstevel@tonic-gate #define SES_CE_DEBUG1 ((2 << 8) | CE_CONT) 2220Sstevel@tonic-gate #define SES_CE_DEBUG2 ((3 << 8) | CE_CONT) 2230Sstevel@tonic-gate #define SES_CE_DEBUG3 ((4 << 8) | CE_CONT) 2240Sstevel@tonic-gate #define SES_CE_DEBUG4 ((5 << 8) | CE_CONT) 2250Sstevel@tonic-gate #define SES_CE_DEBUG5 ((6 << 8) | CE_CONT) 2260Sstevel@tonic-gate #define SES_CE_DEBUG6 ((7 << 8) | CE_CONT) 2270Sstevel@tonic-gate #define SES_CE_DEBUG7 ((8 << 8) | CE_CONT) 2280Sstevel@tonic-gate #define SES_CE_DEBUG8 ((9 << 8) | CE_CONT) 2290Sstevel@tonic-gate #define SES_CE_DEBUG9 ((10 << 8) | CE_CONT) 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate #ifndef SES_DEBUG 2320Sstevel@tonic-gate #define ses_debug 0 2330Sstevel@tonic-gate #endif /* SES_DEBUG */ 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate #define SES_LOG if (ses_debug) ses_log 2360Sstevel@tonic-gate #define SES_DEBUG_ENTER if (ses_debug) debug_enter 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate /* 2400Sstevel@tonic-gate * Various I/O timeouts. 2410Sstevel@tonic-gate * 2420Sstevel@tonic-gate * These are hard-coded and not adjustable. The restart macro 2430Sstevel@tonic-gate * time input is in milliseconds with 1 msec. the minimum setting. 2440Sstevel@tonic-gate * 2450Sstevel@tonic-gate */ 2460Sstevel@tonic-gate #define SES_IO_TIME 60 /* standard I/O time (sec.) */ 2470Sstevel@tonic-gate #define SES_RESTART_TIME 100 /* I/O restart time (ms.) */ 2486948Sjmcp #define SES_BUSY_TIME 500 /* I/O busy restart time (ms.) */ 2490Sstevel@tonic-gate 2500Sstevel@tonic-gate #define SES_ENABLE_RESTART(ms_time, pkt) { \ 2510Sstevel@tonic-gate ssc->ses_restart_id = timeout(ses_restart, (void *) pkt, \ 2526948Sjmcp (ms_time)? (drv_usectohz(ms_time * 1000)) : \ 2536948Sjmcp drv_usectohz(1000)); \ 2540Sstevel@tonic-gate } 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate /* 2580Sstevel@tonic-gate * Number of times we'll retry a normal operation. 2590Sstevel@tonic-gate * 2600Sstevel@tonic-gate * Note, retries have differnt weights to max retries. 2610Sstevel@tonic-gate * Unit Attention and request sense have the most retries. 2620Sstevel@tonic-gate * Command retries have the least. 2630Sstevel@tonic-gate * 2640Sstevel@tonic-gate * For no auto-request sense operation, the SES_RETRY_MULTIPLIER 2650Sstevel@tonic-gate * must be greater than the command RETRY_COUNT. Then the request 2660Sstevel@tonic-gate * sense commands won't impact the command retries. 2670Sstevel@tonic-gate */ 2680Sstevel@tonic-gate #define SES_RETRY_COUNT 4 2690Sstevel@tonic-gate #define SES_RETRY_MULTIPLIER 8 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate #define SES_CMD_RETRY SES_RETRY_MULTIPLIER 2720Sstevel@tonic-gate #define SES_NO_RETRY 0 2730Sstevel@tonic-gate #define SES_SENSE_RETRY 1 2746948Sjmcp #define SES_BUSY_RETRY 4 2750Sstevel@tonic-gate 2760Sstevel@tonic-gate /* Retry weight is 1 */ 2770Sstevel@tonic-gate #define SES_CMD_RETRY1(retry) \ 2780Sstevel@tonic-gate retry += (retry > 0)? (SES_RETRY_MULTIPLIER -1) : 0; 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate /* Retry weight is 2 */ 2810Sstevel@tonic-gate #define SES_CMD_RETRY2(retry) \ 2820Sstevel@tonic-gate retry += (retry > 0)? (SES_RETRY_MULTIPLIER -2) : 0; 2830Sstevel@tonic-gate 2840Sstevel@tonic-gate /* Retry weight is 4 */ 2850Sstevel@tonic-gate #define SES_CMD_RETRY4(retry) \ 2860Sstevel@tonic-gate retry += (retry > 0)? (SES_RETRY_MULTIPLIER -4) : 0; 2870Sstevel@tonic-gate 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate /* 2900Sstevel@tonic-gate * ses_present definitions 2910Sstevel@tonic-gate */ 2920Sstevel@tonic-gate #define SES_CLOSED 0 2930Sstevel@tonic-gate #define SES_OPENING 1 2940Sstevel@tonic-gate #define SES_OPEN 2 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate /* 2980Sstevel@tonic-gate * ses_callback action codes 2990Sstevel@tonic-gate */ 3000Sstevel@tonic-gate #define COMMAND_DONE 0 3010Sstevel@tonic-gate #define COMMAND_DONE_ERROR 1 3020Sstevel@tonic-gate #define QUE_COMMAND_NOW 3 3030Sstevel@tonic-gate #define QUE_COMMAND 4 3040Sstevel@tonic-gate #define QUE_SENSE 5 3050Sstevel@tonic-gate 3060Sstevel@tonic-gate 3070Sstevel@tonic-gate /* 3080Sstevel@tonic-gate * PF bit for RECEIVE DIAG command; 3090Sstevel@tonic-gate * needed for RSM first release hw. 3100Sstevel@tonic-gate */ 3110Sstevel@tonic-gate #define SCSI_ESI_PF 0x10 3120Sstevel@tonic-gate #define SEN_ID "UNISYS SUN_SEN" 3130Sstevel@tonic-gate #define SEN_ID_LEN 24 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate #define SET_BP_ERROR(bp, err) bioerror(bp, err); 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate /* 3180Sstevel@tonic-gate * Common Driver Functions 3190Sstevel@tonic-gate */ 3200Sstevel@tonic-gate #if defined(_KERNEL) 3210Sstevel@tonic-gate extern void ses_log(ses_softc_t *, int, const char *, ...); 3220Sstevel@tonic-gate extern int ses_runcmd(ses_softc_t *, Uscmd *); 3233368Slh195018 extern int ses_uscsi_cmd(ses_softc_t *, Uscmd *, int); 3240Sstevel@tonic-gate extern int ses_io_time; 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate #ifdef DEBUG 3270Sstevel@tonic-gate extern int ses_debug; 3280Sstevel@tonic-gate #endif /* DEBUG */ 3290Sstevel@tonic-gate 3300Sstevel@tonic-gate #endif /* defined(_KERNEL) */ 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate #endif /* defined(_KERNEL) || defined(_KMEMUSER) */ 3340Sstevel@tonic-gate 3350Sstevel@tonic-gate #ifdef __cplusplus 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate #endif 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate #endif /* _SYS_SCSI_TARGETS_SES_H */ 340