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