Home | History | Annotate | Download | only in targets
      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  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 #ifndef	_SYS_DADA_TARGETS_DADDF_H
     26 #define	_SYS_DADA_TARGETS_DADDF_H
     27 
     28 #include <sys/note.h>
     29 #include <sys/cmlb.h>
     30 
     31 #ifdef	__cplusplus
     32 extern "C" {
     33 #endif
     34 
     35 /*
     36  * Defines for SCSI direct access devices
     37  */
     38 
     39 #define	FIXEDFIRMWARE	/* fixed firmware for volume control */
     40 
     41 #if	defined(_KERNEL) || defined(_KMEMUSER)
     42 
     43 
     44 /*
     45  * Local definitions, for clarity of code
     46  */
     47 #define	DCD_DCD_DEVP	(un->un_dcd)
     48 #define	DCD_DEVINFO	(DCD_DCD_DEVP->dcd_dev)
     49 #define	DCD_IDENTIFY	(DCD_DCD_DEVP->dcd_ident)
     50 #define	DCD_MUTEX	(&DCD_DCD_DEVP->dcd_mutex)
     51 #define	ROUTE		(DCD_DCD_DEVP->dcd_address)
     52 #define	SECDIV		(un->un_secdiv)
     53 #define	SECSIZE		(un->un_secsize)
     54 #define	SCBP(pkt)	((struct dcd_status *)(pkt)->pkt_scbp)
     55 #define	SCBP_C(pkt)	((*(pkt)->pkt_scbp) & STATUS_ATA_MASK)
     56 #define	CDBP(pkt)	((union scsi_cdb *)(pkt)->pkt_cdbp)
     57 #define	NO_PKT_ALLOCATED ((struct buf *)0)
     58 #define	ALLOCATING_PKT	((struct buf *)-1)
     59 #define	BP_PKT(bp)	((struct dcd_pkt *)bp->av_back)
     60 #define	BP_HAS_NO_PKT(bp) (bp->av_back == NO_PKT_ALLOCATED)
     61 #define	MAX_ATA_XFER_SIZE (256*DEV_BSIZE)
     62 
     63 #define	STATUS_SCBP_C(statusp)	(*(uchar_t *)(statusp) & STATUS_ATA_MASK)
     64 
     65 #define	Tgt(devp)	(devp->dcd_address->da_target)
     66 #define	Lun(devp)	(devp->dcd_address->da_lun)
     67 
     68 #define	New_state(un, s)	\
     69 	(un)->un_last_state = (un)->un_state,  (un)->un_state = (s)
     70 #define	Restore_state(un)	\
     71 	{ uchar_t tmp = (un)->un_last_state; New_state((un), tmp); }
     72 
     73 
     74 #define	CTYPE_DISK	 2
     75 /*
     76  * Structure for recording whether a device is fully open or closed.
     77  * Assumptions:
     78  *
     79  *	+ There are only 8 partitions possible.
     80  *	+ BLK, MNT, CHR, SWP don't change in some future release!
     81  *
     82  */
     83 
     84 #define	DCDUNIT_SHIFT	3
     85 #define	DCDPART_MASK	7
     86 #define	DCDUNIT(dev)	(getminor((dev))>>DCDUNIT_SHIFT)
     87 #define	DCDPART(dev)	(getminor((dev)) & DCDPART_MASK)
     88 
     89 struct ocinfo {
     90 	/*
     91 	 * Types BLK, MNT, CHR, SWP,
     92 	 * assumed to be types 0-3.
     93 	 */
     94 	ulong_t  lyr_open[NDKMAP];
     95 	uchar_t  reg_open[OTYPCNT - 1];
     96 };
     97 #define	OCSIZE  sizeof (struct ocinfo)
     98 union ocmap {
     99 	uchar_t chkd[OCSIZE];
    100 	struct ocinfo rinfo;
    101 };
    102 #define	lyropen rinfo.lyr_open
    103 #define	regopen rinfo.reg_open
    104 
    105 /*
    106  * Private info for dcd disks.
    107  *
    108  * Pointed to by the un_private pointer
    109  * of one of the dcd_device structures.
    110  */
    111 
    112 struct dcd_disk {
    113 	struct dcd_device *un_dcd;	/* back pointer to dcd_device */
    114 	struct dcd_drivetype *un_dp;	/* drive type table */
    115 	struct	buf *un_sbufp;		/* for use in special io */
    116 	char		*un_srqbufp;	/* sense buffer for special io */
    117 	kcondvar_t	un_sbuf_cv;	/* Conditional Variable on sbufp */
    118 	kcondvar_t	un_state_cv;	/* Conditional variable for state */
    119 	union	ocmap un_ocmap;		/* open partition map, block && char */
    120 	uchar_t	un_last_pkt_reason;	/* used for suppressing multiple msgs */
    121 	struct	diskhd un_utab;		/* for queuing */
    122 	struct	kstat *un_stats;	/* for statistics */
    123 	struct	kstat *un_pstats[NDKMAP]; /* for partition statistics */
    124 	ksema_t	un_semoclose;		/* lock for serializing opens/closes */
    125 	uint_t	un_err_blkno;		/* disk block where error occurred */
    126 	int	un_diskcapacity;	/* capacity as returned by drive */
    127 	int	un_lbasize;		/* logical (i.e. device) block size */
    128 	int	un_lbadiv;		/* log2 of lbasize */
    129 	int	un_blknoshift;		/* log2 of multiple of DEV_BSIZE */
    130 					/* blocks making up a logical block */
    131 	int	un_secsize;		/* sector size (allow request on */
    132 					/* this boundry) */
    133 	int	un_secdiv;		/* log2 of secsize */
    134 	uchar_t	un_exclopen;		/* exclusive open bits */
    135 	uchar_t	un_mediastate;		/* Is it really needed  XXX */
    136 	uchar_t	un_state;		/* current state */
    137 	uchar_t	un_last_state;		/* last state */
    138 	uchar_t	un_format_in_progress;	/* disk is formatting currently */
    139 	uchar_t un_flush_not_supported;	/* disk doesn't support flush cmd */
    140 	uchar_t	un_write_cache_enabled;	/* disk has write caching enabled */
    141 	clock_t un_timestamp;		/* Time of last device access */
    142 	short	un_ncmds;		/* number of cmds in transport */
    143 	short	un_throttle;		/* This is used for throttling if */
    144 					/* HBA has queuing		  */
    145 	short	un_sbuf_busy;		/* Busy wait flag for the sbuf */
    146 	int	un_cmd_flags;		/* cache some frequently used values */
    147 	int	un_cmd_stat_size;	/* in make_sd_cmd */
    148 	int	un_dcvb_timeid;		/* timeout id for dlyd cv broadcast */
    149 	void 	*un_devid;		/* device id */
    150 	uint_t	un_max_xfer_size;	/* max transfer size */
    151 	uchar_t	un_bus_master;		/* Indicates that the HBA  enables  */
    152 					/* Bus master capability */
    153 	timeout_id_t	un_reissued_timeid;
    154 					/* This is used in busy handler */
    155 	kstat_t	*un_errstats;		/* For Error statsistics */
    156 	kcondvar_t	un_suspend_cv;	/* Cond Var on power management */
    157 	kcondvar_t	un_disk_busy_cv; /* Cond var to wait for IO */
    158 	short	un_power_level;		/* Power Level */
    159 	short	un_save_state;		/* Save the state for suspend/resume */
    160 	cmlb_handle_t   un_dklbhandle;  /* Handle for disk label */
    161 	tg_attribute_t un_tgattribute;
    162 };
    163 
    164 /*
    165  * device error statistics
    166  */
    167 struct dcd_errstats {
    168 	struct kstat_named	dcd_softerrs;	/* Collecting Softerrs */
    169 	struct kstat_named	dcd_harderrs;	/* Collecting harderrs */
    170 	struct kstat_named	dcd_transerrs;	/* Collecting Transfer errs */
    171 	struct kstat_named	dcd_model;	/* model # of the disk */
    172 	struct kstat_named	dcd_revision;	/* The disk revision */
    173 	struct kstat_named	dcd_serial;	/* The disk serial number */
    174 	struct kstat_named	dcd_capacity;	/* Capacity of the disk */
    175 	struct kstat_named	dcd_rq_media_err; /* Any media err seen */
    176 	struct kstat_named	dcd_rq_ntrdy_err; /* Not ready errs */
    177 	struct kstat_named	dcd_rq_nodev_err; /* No device errs */
    178 	struct kstat_named	dcd_rq_recov_err; /* Recovered errs */
    179 	struct kstat_named	dcd_rq_illrq_err; /* Illegal requests */
    180 };
    181 #define	DCD_MAX_XFER_SIZE	(1 * 512)
    182 
    183 _NOTE(MUTEX_PROTECTS_DATA(dcd_device::dcd_mutex, dcd_disk))
    184 _NOTE(READ_ONLY_DATA(dcd_disk::un_dcd))
    185 _NOTE(READ_ONLY_DATA(dcd_disk::un_cmd_stat_size))
    186 _NOTE(SCHEME_PROTECTS_DATA("Save Sharing",
    187 	dcd_disk::un_state
    188 	dcd_disk::un_dklbhandle
    189 	dcd_disk::un_format_in_progress))
    190 
    191 _NOTE(SCHEME_PROTECTS_DATA("stable data",
    192 	dcd_disk::un_max_xfer_size
    193 	dcd_disk::un_secdiv
    194 	dcd_disk::un_secsize
    195 	dcd_disk::un_cmd_flags
    196 	dcd_disk::un_cmd_stat_size))
    197 
    198 _NOTE(SCHEME_PROTECTS_DATA("cv",
    199 	dcd_disk::un_sbufp
    200 	dcd_disk::un_srqbufp
    201 	dcd_disk::un_sbuf_busy))
    202 
    203 _NOTE(SCHEME_PROTECTS_DATA("Unshared data",
    204 	dk_cinfo
    205 	uio
    206 	buf
    207 	dcd_pkt
    208 	udcd_cmd
    209 	dcd_capacity
    210 	dcd_cmd
    211 	dk_label
    212 	dk_map32))
    213 
    214 _NOTE(SCHEME_PROTECTS_DATA("stable data", dcd_device))
    215 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", dcd_cmd))
    216 
    217 #endif	/* defined(_KERNEL) || defined(_KMEMUSER) */
    218 
    219 
    220 /*
    221  * Disk driver states
    222  */
    223 
    224 #define	DCD_STATE_NORMAL	0
    225 #define	DCD_STATE_OFFLINE	1
    226 #define	DCD_STATE_RWAIT		2
    227 #define	DCD_STATE_DUMPING	3
    228 #define	DCD_STATE_SUSPENDED	4
    229 #define	DCD_STATE_FATAL		5
    230 #define	DCD_STATE_PM_SUSPENDED	6
    231 
    232 /*
    233  * Disk power levels.
    234  */
    235 #define	DCD_DEVICE_ACTIVE	0x2
    236 #define	DCD_DEVICE_IDLE		0x1
    237 #define	DCD_DEVICE_STANDBY	0x0
    238 
    239 /*
    240  * Macros used in obtaining the device ID for the disk.
    241  */
    242 #define	DCD_SERIAL_NUMBER_LENGTH	20
    243 #define	DCD_MODEL_NUMBER_LENGTH		40
    244 
    245 /*
    246  * The table is to be interpreted as follows: The rows lists all the states
    247  * and each column is a state that a state in each row *can* reach. The entries
    248  * in the table list the event that cause that transition to take place.
    249  * For e.g.: To go from state RWAIT to SUSPENDED, event (d)-- which is the
    250  * invocation of DDI_SUSPEND-- has to take place. Note the same event could
    251  * cause the transition from one state to two different states. e.g., from
    252  * state SUSPENDED, when we get a DDI_RESUME, we just go back to the *last
    253  * state* whatever that might be. (NORMAL or OFFLINE).
    254  *
    255  *
    256  * State Transition Table:
    257  *
    258  *			NORMAL  OFFLINE  RWAIT  DUMPING  SUSPENDED
    259  *
    260  *	NORMAL		-	(a)	(b)	(c)	(d)
    261  *
    262  *	OFFLINE		(e)	-	(e)	(c)	(d)
    263  *
    264  *	RWAIT		(f)	NP	-	(c)	(d)
    265  *
    266  *	DUMPING		NP	NP	NP	-	NP
    267  *
    268  *	SUSPENDED	(g)	(g)	(b)	NP*	-
    269  *
    270  *
    271  *	NP:	Not Possible.
    272  *	(a):	Disk does not respond.
    273  *	(b):	Packet Allocation Fails
    274  *	(c):	Panic - Crash dump
    275  *	(d):	DDI_SUSPEND is called.
    276  *	(e):	Disk has a successful I/O completed.
    277  *	(f):	sdrunout() calls sdstart() which sets it NORMAL
    278  *	(g):	DDI_RESUME is called.
    279  *	* :	When suspended, we dont change state during panic dump
    280  */
    281 
    282 
    283 /*
    284  * Error levels
    285  */
    286 
    287 #define	DCDERR_ALL		0
    288 #define	DCDERR_UNKNOWN		1
    289 #define	DCDERR_INFORMATIONAL	2
    290 #define	DCDERR_RECOVERED	3
    291 #define	DCDERR_RETRYABLE	4
    292 #define	DCDERR_FATAL		5
    293 
    294 /*
    295  * Parameters
    296  */
    297 
    298 /*
    299  * 60 seconds is a *very* reasonable amount of time for most slow CD
    300  * operations.
    301  */
    302 
    303 #define	DCD_IO_TIME	60
    304 
    305 /*
    306  * Timeout value for ATA_FLUSH_CACHE used in DKIOCFLUSHWRITECACHE
    307  */
    308 #define	DCD_FLUSH_TIME	60
    309 
    310 /*
    311  * 2 hours is an excessively reasonable amount of time for format operations.
    312  */
    313 
    314 #define	DCD_FMT_TIME	120*60
    315 
    316 /*
    317  * 5 seconds is what we'll wait if we get a Busy Status back
    318  */
    319 
    320 #define	DCD_BSY_TIMEOUT		(drv_usectohz(5 * 1000000))
    321 
    322 /*
    323  * Number of times we'll retry a normal operation.
    324  *
    325  * This includes retries due to transport failure
    326  * (need to distinguish between Target and Transport failure)
    327  */
    328 
    329 #define	DCD_RETRY_COUNT		5
    330 
    331 
    332 /*
    333  * Maximum number of units we can support
    334  * (controlled by room in minor device byte)
    335  * XXX: this is out of date!
    336  */
    337 #define	DCD_MAXUNIT		32
    338 
    339 /*
    340  * 30 seconds is what we will wait for the IO to finish
    341  * before we fail the DDI_SUSPEND
    342  */
    343 #define	DCD_WAIT_CMDS_COMPLETE	30
    344 
    345 /*
    346  * dcdintr action codes
    347  */
    348 
    349 #define	COMMAND_DONE		0
    350 #define	COMMAND_DONE_ERROR	1
    351 #define	QUE_COMMAND		2
    352 #define	QUE_SENSE		3
    353 #define	JUST_RETURN		4
    354 
    355 /*
    356  * Indicator for Soft and hard errors
    357  */
    358 #define	COMMAND_SOFT_ERROR	1
    359 #define	COMMAND_HARD_ERROR	2
    360 
    361 /*
    362  * Drive Types (and characteristics)
    363  */
    364 #define	VIDMAX 8
    365 #define	PIDMAX 16
    366 
    367 struct dcd_drivetype {
    368 	char 	*name;		/* for debug purposes */
    369 	char	ctype;		/* controller type */
    370 	char	options;	/* drive options */
    371 	ushort_t block_factor;	/* Block mode factor */
    372 	char	pio_mode;	/* This the Pio mode number */
    373 	char 	dma_mode;	/* Multi word dma mode */
    374 };
    375 
    376 /*
    377  * The options values
    378  */
    379 #define	DMA_SUPPORTTED	0x01
    380 #define	BLOCK_MODE	0x02
    381 
    382 #ifndef	LOG_EMERG
    383 #define	LOG_WARNING	CE_NOTE
    384 #define	LOG_NOTICE	CE_NOTE
    385 #define	LOG_CRIT	CE_WARN
    386 #define	LOG_ERR		CE_WARN
    387 #define	LOG_INFO	CE_NOTE
    388 #define	log	cmn_err
    389 #endif
    390 
    391 /*
    392  * Some internal error codes for driver functions.
    393  */
    394 #define	DCD_EACCES	1
    395 
    396 /*
    397  * Error returns from sd_validate_geometry()
    398  */
    399 #define	DCD_BAD_LABEL		-1
    400 #define	DCD_NO_MEM_FOR_LABEL	-2
    401 
    402 #ifdef	__cplusplus
    403 }
    404 #endif
    405 
    406 #endif	/* _SYS_DADA_TARGETS_DADDF_H */
    407