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