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
32extern "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
89struct 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)
98union 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
112struct 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 */
167struct 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
367struct 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