/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DADA_TARGETS_DADDF_H #define _SYS_DADA_TARGETS_DADDF_H #pragma ident "%Z%%M% %I% %E% SMI" #include #include #ifdef __cplusplus extern "C" { #endif /* * Defines for SCSI direct access devices */ #define FIXEDFIRMWARE /* fixed firmware for volume control */ #if defined(_KERNEL) || defined(_KMEMUSER) /* * Local definitions, for clarity of code */ #define DCD_DCD_DEVP (un->un_dcd) #define DCD_DEVINFO (DCD_DCD_DEVP->dcd_dev) #define DCD_IDENTIFY (DCD_DCD_DEVP->dcd_ident) #define DCD_MUTEX (&DCD_DCD_DEVP->dcd_mutex) #define ROUTE (DCD_DCD_DEVP->dcd_address) #define SECDIV (un->un_secdiv) #define SECSIZE (un->un_secsize) #define SCBP(pkt) ((struct dcd_status *)(pkt)->pkt_scbp) #define SCBP_C(pkt) ((*(pkt)->pkt_scbp) & STATUS_ATA_MASK) #define CDBP(pkt) ((union scsi_cdb *)(pkt)->pkt_cdbp) #define NO_PKT_ALLOCATED ((struct buf *)0) #define ALLOCATING_PKT ((struct buf *)-1) #define BP_PKT(bp) ((struct dcd_pkt *)bp->av_back) #define BP_HAS_NO_PKT(bp) (bp->av_back == NO_PKT_ALLOCATED) #define MAX_ATA_XFER_SIZE (256*DEV_BSIZE) #define STATUS_SCBP_C(statusp) (*(uchar_t *)(statusp) & STATUS_ATA_MASK) #define Tgt(devp) (devp->dcd_address->a_target) #define Lun(devp) (devp->dcd_address->a_lun) #define New_state(un, s) \ (un)->un_last_state = (un)->un_state, (un)->un_state = (s) #define Restore_state(un) \ { uchar_t tmp = (un)->un_last_state; New_state((un), tmp); } #define CTYPE_DISK 2 /* * Structure for recording whether a device is fully open or closed. * Assumptions: * * + There are only 8 partitions possible. * + BLK, MNT, CHR, SWP don't change in some future release! * */ #define DCDUNIT_SHIFT 3 #define DCDPART_MASK 7 #define DCDUNIT(dev) (getminor((dev))>>DCDUNIT_SHIFT) #define DCDPART(dev) (getminor((dev)) & DCDPART_MASK) struct ocinfo { /* * Types BLK, MNT, CHR, SWP, * assumed to be types 0-3. */ ulong_t lyr_open[NDKMAP]; uchar_t reg_open[OTYPCNT - 1]; }; #define OCSIZE sizeof (struct ocinfo) union ocmap { uchar_t chkd[OCSIZE]; struct ocinfo rinfo; }; #define lyropen rinfo.lyr_open #define regopen rinfo.reg_open /* * Private info for dcd disks. * * Pointed to by the un_private pointer * of one of the dcd_device structures. */ struct dcd_disk { struct dcd_device *un_dcd; /* back pointer to dcd_device */ struct dcd_drivetype *un_dp; /* drive type table */ struct buf *un_sbufp; /* for use in special io */ char *un_srqbufp; /* sense buffer for special io */ kcondvar_t un_sbuf_cv; /* Conditional Variable on sbufp */ kcondvar_t un_state_cv; /* Conditional variable for state */ union ocmap un_ocmap; /* open partition map, block && char */ uchar_t un_last_pkt_reason; /* used for suppressing multiple msgs */ struct diskhd un_utab; /* for queuing */ struct kstat *un_stats; /* for statistics */ struct kstat *un_pstats[NDKMAP]; /* for partition statistics */ ksema_t un_semoclose; /* lock for serializing opens/closes */ uint_t un_err_blkno; /* disk block where error occurred */ int un_diskcapacity; /* capacity as returned by drive */ int un_lbasize; /* logical (i.e. device) block size */ int un_lbadiv; /* log2 of lbasize */ int un_blknoshift; /* log2 of multiple of DEV_BSIZE */ /* blocks making up a logical block */ int un_secsize; /* sector size (allow request on */ /* this boundry) */ int un_secdiv; /* log2 of secsize */ uchar_t un_exclopen; /* exclusive open bits */ uchar_t un_mediastate; /* Is it really needed XXX */ uchar_t un_state; /* current state */ uchar_t un_last_state; /* last state */ uchar_t un_format_in_progress; /* disk is formatting currently */ uchar_t un_flush_not_supported; /* disk doesn't support flush cmd */ uchar_t un_write_cache_enabled; /* disk has write caching enabled */ clock_t un_timestamp; /* Time of last device access */ short un_ncmds; /* number of cmds in transport */ short un_throttle; /* This is used for throttling if */ /* HBA has queuing */ short un_sbuf_busy; /* Busy wait flag for the sbuf */ int un_cmd_flags; /* cache some frequently used values */ int un_cmd_stat_size; /* in make_sd_cmd */ int un_dcvb_timeid; /* timeout id for dlyd cv broadcast */ void *un_devid; /* device id */ uint_t un_max_xfer_size; /* max transfer size */ uchar_t un_bus_master; /* Indicates that the HBA enables */ /* Bus master capability */ timeout_id_t un_reissued_timeid; /* This is used in busy handler */ kstat_t *un_errstats; /* For Error statsistics */ kcondvar_t un_suspend_cv; /* Cond Var on power management */ kcondvar_t un_disk_busy_cv; /* Cond var to wait for IO */ short un_power_level; /* Power Level */ short un_save_state; /* Save the state for suspend/resume */ cmlb_handle_t un_dklbhandle; /* Handle for disk label */ tg_attribute_t un_tgattribute; }; /* * device error statistics */ struct dcd_errstats { struct kstat_named dcd_softerrs; /* Collecting Softerrs */ struct kstat_named dcd_harderrs; /* Collecting harderrs */ struct kstat_named dcd_transerrs; /* Collecting Transfer errs */ struct kstat_named dcd_model; /* model # of the disk */ struct kstat_named dcd_revision; /* The disk revision */ struct kstat_named dcd_serial; /* The disk serial number */ struct kstat_named dcd_capacity; /* Capacity of the disk */ struct kstat_named dcd_rq_media_err; /* Any media err seen */ struct kstat_named dcd_rq_ntrdy_err; /* Not ready errs */ struct kstat_named dcd_rq_nodev_err; /* No device errs */ struct kstat_named dcd_rq_recov_err; /* Recovered errs */ struct kstat_named dcd_rq_illrq_err; /* Illegal requests */ }; #define DCD_MAX_XFER_SIZE (1 * 512) _NOTE(MUTEX_PROTECTS_DATA(dcd_device::dcd_mutex, dcd_disk)) _NOTE(READ_ONLY_DATA(dcd_disk::un_dcd)) _NOTE(READ_ONLY_DATA(dcd_disk::un_cmd_stat_size)) _NOTE(SCHEME_PROTECTS_DATA("Save Sharing", dcd_disk::un_state dcd_disk::un_dklbhandle dcd_disk::un_format_in_progress)) _NOTE(SCHEME_PROTECTS_DATA("stable data", dcd_disk::un_max_xfer_size dcd_disk::un_secdiv dcd_disk::un_secsize dcd_disk::un_cmd_flags dcd_disk::un_cmd_stat_size)) _NOTE(SCHEME_PROTECTS_DATA("cv", dcd_disk::un_sbufp dcd_disk::un_srqbufp dcd_disk::un_sbuf_busy)) _NOTE(SCHEME_PROTECTS_DATA("Unshared data", dk_cinfo uio buf dcd_pkt udcd_cmd dcd_capacity dcd_cmd dk_label dk_map32)) _NOTE(SCHEME_PROTECTS_DATA("stable data", dcd_device)) _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", dcd_cmd)) #endif /* defined(_KERNEL) || defined(_KMEMUSER) */ /* * Disk driver states */ #define DCD_STATE_NORMAL 0 #define DCD_STATE_OFFLINE 1 #define DCD_STATE_RWAIT 2 #define DCD_STATE_DUMPING 3 #define DCD_STATE_SUSPENDED 4 #define DCD_STATE_FATAL 5 #define DCD_STATE_PM_SUSPENDED 6 /* * Disk power levels. */ #define DCD_DEVICE_ACTIVE 0x2 #define DCD_DEVICE_IDLE 0x1 #define DCD_DEVICE_STANDBY 0x0 /* * Macros used in obtaining the device ID for the disk. */ #define DCD_SERIAL_NUMBER_LENGTH 20 #define DCD_MODEL_NUMBER_LENGTH 40 /* * The table is to be interpreted as follows: The rows lists all the states * and each column is a state that a state in each row *can* reach. The entries * in the table list the event that cause that transition to take place. * For e.g.: To go from state RWAIT to SUSPENDED, event (d)-- which is the * invocation of DDI_SUSPEND-- has to take place. Note the same event could * cause the transition from one state to two different states. e.g., from * state SUSPENDED, when we get a DDI_RESUME, we just go back to the *last * state* whatever that might be. (NORMAL or OFFLINE). * * * State Transition Table: * * NORMAL OFFLINE RWAIT DUMPING SUSPENDED * * NORMAL - (a) (b) (c) (d) * * OFFLINE (e) - (e) (c) (d) * * RWAIT (f) NP - (c) (d) * * DUMPING NP NP NP - NP * * SUSPENDED (g) (g) (b) NP* - * * * NP: Not Possible. * (a): Disk does not respond. * (b): Packet Allocation Fails * (c): Panic - Crash dump * (d): DDI_SUSPEND is called. * (e): Disk has a successful I/O completed. * (f): sdrunout() calls sdstart() which sets it NORMAL * (g): DDI_RESUME is called. * * : When suspended, we dont change state during panic dump */ /* * Error levels */ #define DCDERR_ALL 0 #define DCDERR_UNKNOWN 1 #define DCDERR_INFORMATIONAL 2 #define DCDERR_RECOVERED 3 #define DCDERR_RETRYABLE 4 #define DCDERR_FATAL 5 /* * Parameters */ /* * 60 seconds is a *very* reasonable amount of time for most slow CD * operations. */ #define DCD_IO_TIME 60 /* * Timeout value for ATA_FLUSH_CACHE used in DKIOCFLUSHWRITECACHE */ #define DCD_FLUSH_TIME 60 /* * 2 hours is an excessively reasonable amount of time for format operations. */ #define DCD_FMT_TIME 120*60 /* * 5 seconds is what we'll wait if we get a Busy Status back */ #define DCD_BSY_TIMEOUT (drv_usectohz(5 * 1000000)) /* * Number of times we'll retry a normal operation. * * This includes retries due to transport failure * (need to distinguish between Target and Transport failure) */ #define DCD_RETRY_COUNT 5 /* * Maximum number of units we can support * (controlled by room in minor device byte) * XXX: this is out of date! */ #define DCD_MAXUNIT 32 /* * 30 seconds is what we will wait for the IO to finish * before we fail the DDI_SUSPEND */ #define DCD_WAIT_CMDS_COMPLETE 30 /* * dcdintr action codes */ #define COMMAND_DONE 0 #define COMMAND_DONE_ERROR 1 #define QUE_COMMAND 2 #define QUE_SENSE 3 #define JUST_RETURN 4 /* * Indicator for Soft and hard errors */ #define COMMAND_SOFT_ERROR 1 #define COMMAND_HARD_ERROR 2 /* * Drive Types (and characteristics) */ #define VIDMAX 8 #define PIDMAX 16 struct dcd_drivetype { char *name; /* for debug purposes */ char ctype; /* controller type */ char options; /* drive options */ ushort_t block_factor; /* Block mode factor */ char pio_mode; /* This the Pio mode number */ char dma_mode; /* Multi word dma mode */ }; /* * The options values */ #define DMA_SUPPORTTED 0x01 #define BLOCK_MODE 0x02 #ifndef LOG_EMERG #define LOG_WARNING CE_NOTE #define LOG_NOTICE CE_NOTE #define LOG_CRIT CE_WARN #define LOG_ERR CE_WARN #define LOG_INFO CE_NOTE #define log cmn_err #endif /* * Some internal error codes for driver functions. */ #define DCD_EACCES 1 /* * Error returns from sd_validate_geometry() */ #define DCD_BAD_LABEL -1 #define DCD_NO_MEM_FOR_LABEL -2 #ifdef __cplusplus } #endif #endif /* _SYS_DADA_TARGETS_DADDF_H */