daddef.h revision cd210bb4840e6add5921c775aa07cebd6891f738
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_DADA_TARGETS_DADDF_H
#define _SYS_DADA_TARGETS_DADDF_H
#include <sys/note.h>
#include <sys/cmlb.h>
#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->da_target)
#define Lun(devp) (devp->dcd_address->da_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 */