summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun/sys/fdvar.h
blob: 6a2d87d6366fc1bae118e4e6f660358a7ce6a8cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (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 (c) 1989-1994,1997-1998,2000 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef	_SYS_FDVAR_H
#define	_SYS_FDVAR_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef	__cplusplus
extern "C" {
#endif

#ifndef	OTYPCNT
#define	OTYPCNT	5
#endif
#ifndef	NDKMAP
#define	NDKMAP	8
#endif

/*
 * Compile with our without high level interrupt in trap window
 */

/* #define	NO_TRAPWIN_INTR	*/

/*
 * Macros for partition/unit from floppy device number,
 * plus other manifest defines....
 */

#define	FDUNITSHIFT	(3)
#define	FDINSTSHIFT	(2 + FDUNITSHIFT)
#define	FDPARTITION(x)	(getminor(x) & 0x7)
#define	FDUNIT(x)	((getminor(x) >> FDUNITSHIFT) & 0x3)

#define	FDCTLR(x)	(getminor(x) >> FDINSTSHIFT)	/* instance */

/*
 * Structure definitions for the floppy driver.
 */

/*
 * floppy disk command and status block.
 *
 * Needed to execute a command. Since the floppy chip is
 * single threaded with respect to having only one drive
 * active at a time, this block of information is only
 * valid for the length of a commnand and gets rewritten
 * for each command.
 */

#ifndef	_ASM
struct fdcsb {
	caddr_t	csb_addr;	/* Data buffer address */
	uint_t	csb_len;	/* Data buffer Length */
	caddr_t	csb_raddr;	/* modified data buffer address */
	uint_t	csb_rlen;	/* modified data buffer len (resid) */
	uchar_t	csb_opmode;	/* Current operating mode */
	uchar_t	csb_unit;	/* floppy slave unit number */
	uchar_t	csb_ncmds;	/* how many command bytes to send */
	uchar_t	csb_nrslts;	/* number of result bytes gotten */
	uchar_t	csb_opflags;	/* opflags, see below */
	uchar_t	csb_maxretry;	/* maximum retries this opertion */
	uchar_t	csb_retrys;	/* how may retrys done so far */
	uchar_t	csb_status;	/* status returned from hwintr */
	uchar_t	csb_cmdstat;	/* if 0 then success, else failure */
	uchar_t	csb_cmds[10];	/* commands to send to chip */
	uchar_t	csb_rslt[10];	/* results from chip */
	uchar_t  csb_dcsr_rslt;  /* set to 1 if there's an error in the DCSR */
	uchar_t	csb_dma_rslt;	/* set to 1 if there's an error with the DMA */
	ddi_dma_cookie_t csb_dmacookie; /* DMA cookie */

	uint_t	csb_ccount;	/* no. of DMA cookies for current window */
	uint_t	csb_nwin;	/* no. of DMA windows */
	uint_t	csb_windex;	/* DMA window currently in use */
	uint_t	csb_read;	/* indicates read or write */
};
#endif	/* !_ASM */

/*
 * defines for csb_opflags
 */
#define	CSB_OFIMMEDIATE	0x01		/* grab results immediately */
#define	CSB_OFSEEKOPS	0x02		/* seek/recal type cmd */
#define	CSB_OFXFEROPS	0x04		/* read/write type cmd */
#define	CSB_OFRAWIOCTL	0x10		/* raw ioctl - no recovery */
#define	CSB_OFNORESULTS	0x20		/* no results at all */
#define	CSB_OFTIMEIT	0x40		/* timeout (timer) */

#define	CSB_CMDTO 0x01

/*
 * csb_read flags
 */
#define	CSB_NULL	0x0
#define	CSB_READ	0x1
#define	CSB_WRITE	0x2

#ifndef	_ASM
#ifndef	_GENASSYM

/*
 * Define a structure to hold the packed default labels,
 * based on the real dk_label structure - but shorter
 * than 512 bytes. Now only used to define default info
 */
struct packed_label {
	char		dkl_vname[128];	/* for ascii compatibility */
	unsigned short	dkl_rpm;	/* rotations per minute */
	unsigned short	dkl_pcyl;	/* # physical cylinders */
	unsigned short	dkl_apc;	/* alternates per cylinder */
	unsigned short	dkl_intrlv;	/* interleave factor */
	unsigned short	dkl_ncyl;	/* # of data cylinders */
	unsigned short	dkl_acyl;	/* # of alternate cylinders */
	unsigned short	dkl_nhead;	/* # of heads in this partition */
	unsigned short	dkl_nsect;	/* # of 512 byte sectors per track */
	struct dk_map32	dkl_map[NDKMAP]; /* partition map, see dkio.h */
	struct dk_vtoc  dkl_vtoc;	/* vtoc stuff from AT&T SVr4 */
};

/*
 * Per drive data
 */
struct fdunit {

	/*
	 * Packed label for this unit
	 */
	struct	dk_label un_label;

	/*
	 * Pointer to iostat statistics
	 */
	struct kstat *un_iostat;	/* iostat numbers */

	/*
	 * Layered open counters
	 */
	uint_t	un_lyropen[NDKMAP];

	/*
	 * Regular open type flags. If
	 * NDKMAP gets > 8, change the
	 * uchar_t type.
	 *
	 * Open types BLK, MNT, CHR, SWP
	 * assumed to be values 0-3.
	 */
	uchar_t	un_regopen[OTYPCNT - 1];

	/*
	 * Exclusive open flags (per partition).
	 *
	 * The rules are that in order to open
	 * a partition exclusively, the partition
	 * must be completely closed already. Once
	 * any partition of the device is opened
	 * exclusively, no other open on that
	 * partition may succeed until the partition
	 * is closed.
	 *
	 * If NDKMAP gets > 8, this must change.
	 */
	uchar_t	un_exclmask;		/* set to indicate exclusive open */

	struct	fd_char *un_chars;	/* ptr to diskette characteristics */
	char	un_curfdtype;		/* current driver characteristics */
					/* type. If -1, then it was set */
					/* via an ioctl. Note that a close */
					/* and then and open loses the */
					/* ioctl set characteristics. */

	struct fd_drive *un_drive;	/* ptr to drive characteristics */
	int	un_unit_no;		/* drive id number */
	uchar_t	un_flags;		/* state information */
	clock_t	un_media_timeout;	/* media detection timeout */
	timeout_id_t un_media_timeout_id; /* media detection timeout id */
	enum dkio_state	un_media_state;	/* up-to-date media state */
	int	un_ejected;
	short	un_state;		/* Current power level of drive */
};

/* unit flags (state info) */
#define	FDUNIT_DRVCHECKED	0x01	/* this is drive present */
#define	FDUNIT_DRVPRESENT	0x02	/* this is drive present */
/* (the presence of a diskette is another matter) */
#define	FDUNIT_CHAROK		0x04	/* characteristics are known */
#define	FDUNIT_UNLABELED	0x10	/* no label using default */
#define	FDUNIT_CHANGED		0x20	/* diskette was changed after open */
#define	FDUNIT_MEDIUM		0x40	/* fd drive is in medium density */
#define	FDUNIT_SET_SPEED	0x80	/* Flag to force updating the */
					/* registers with current speed */

#endif	/* !_GENASSYM */

/* unit flags for power (un_power) */
#define	FD_STATE_NORMAL		0x0 /* Normal running state */
#define	FD_STATE_SUSPENDED	0x1 /* Device suspended for cpr */
#define	FD_STATE_STOPPED	0x2 /* Device is stopped, can be turned off */

/*
 * --------|   fd_detach:DDI_SUSPEND ncmds may be != 0 |-----------|
 * |running|------------------------------------------>|           |
 * |NORMAL |  fd_attach:DDI_RESUME                     |           |
 * |       |<------------------------------------------| SUSPENDED |
 * |       |                                           |           |
 * |       |                                           -------------
 * |       |                                                ^
 * |       |                                                |DDI_SUSPEND
 * |       |                                                |
 * |       | fd_power: PM_LEVEL_OFF, ncmds == 0         -------------
 * |       |------------------------------------------->|STOPPED     |
 * |       | fd_power: PM_LEVEL_ON                      |            |
 * |       |<-------------------------------------------|            |
 * --------                                              ------------|
 *
 * running => FD_STATE_NORMAL
 *
 */

/* flags for power levels for auto power management */
#define	PM_LEVEL_ON	0x1   /* Changes the state to FD_STATE_STOPPED */
#define	PM_LEVEL_OFF	0x0   /* Changes the state to FD_STATE_NORMAL */

/* a place to keep some statistics on what's going on */
struct fdstat {
	/* first operations */
	int rd;		/* count reads */
	int wr;		/* count writes */
	int recal;	/* count recalibrates */
	int form;	/* count format_tracks */
	int other;	/* count other ops */

	/* then errors */
	int reset;	/* count resets */
	int to;		/* count timeouts */
	int run;	/* count overrun/underrun */
	int de;		/* count data errors */
	int bfmt;	/* count bad format errors */
};

/*
 * Per controller data
 */

struct fdctlr {
	struct	fdctlr	*c_next;	/* next in a linked list */
	union  fdcreg   *c_reg;		/* controller registers */
	volatile uchar_t *c_control; 	/* addr of c_reg->fdc_control */
	uchar_t		*c_fifo;	/* addr of c_reg->fdc_fifo */
	uchar_t		*c_dor;		/* addr of c_reg->fdc_dor (077) */
	uchar_t		*c_dir;		/* addr of c_reg->fdc_dir (077) */
	caddr_t		*c_dma_regs;	/* DMA engine registers */
	uint_t		c_fdtype;	/* type of ctlr */
	uint_t		*c_hiintct;	/* for convenience.. */
	uint_t		c_softic;	/* for use by hi level interrupt */
	uchar_t		c_fasttrap;	/* 1 if fast traps enabled, else 0 */
	struct	fdcsb	c_csb;		/* current csb */
	kmutex_t	c_hilock;	/* high level mutex */
	kmutex_t	c_lolock;	/* low level mutex */
	kcondvar_t	c_iocv;		/* condition var for I/O done */
	kcondvar_t	c_csbcv;	/* condition var for owning csb */
	kcondvar_t	c_motoncv;	/* condition var for motor on */
	kcondvar_t	c_statecv;	/* condition var for media state */
	kcondvar_t	c_suspend_cv;  /* Cond Var on power management */
	ksema_t		c_ocsem;	/* sem for serializing opens/closes */
	ddi_iblock_cookie_t c_block;	/* returned from ddi_add_fastintr */
	ddi_softintr_t	c_softid;	/* returned from ddi_add_softintr */
	dev_info_t	*c_dip;		/* controller's dev_info node */
	timeout_id_t	c_timeid;	/* watchdog timer id */
	timeout_id_t	c_mtimeid;	/* motor off timer id */
	struct	fdunit	*c_un;		/* unit on controller */
	struct	buf	*c_actf;	/* head of wait list */
	struct	buf	*c_actl;	/* tail of wait list */
	struct	buf	*c_current;	/* currently active buf */
	struct kstat	*c_intrstat;	/* interrupt stats pointer */
	struct	fdstat	fdstats;	/* statistics */
	uchar_t		c_flags;	/* state information */
	caddr_t		c_auxiova;	/* auxio virtual address */
	uchar_t		c_auxiodata;	/* auxio data to enable TC */
	uchar_t		c_auxiodata2;	/* auxio data to disable TC */
	ddi_acc_handle_t c_handlep_cont;
					/* data access handle for controller */
	ddi_acc_handle_t c_handlep_dma; /* data access handle for DMA engine */
	ddi_acc_handle_t c_handlep_aux;  /* data access handle for aux regs */
	ddi_dma_handle_t c_dmahandle; 	/* DMA handle */
	uint_t		 *c_auxio_reg; 	/* auxio registers */
	ddi_dma_attr_t 	c_fd_dma_lim;	/* DMA limit structure */
	caddr_t		dma_buf;	/* Temporary DMAble buffer */
	ddi_acc_handle_t c_dma_buf_handle; /* DMA handle for dma_buf */
	uint_t		sb_dma_channel; /* 8237 dma channel no. */
	uchar_t		sb_dma_lock;	/* Status of DMA lock by isadma */
};
#endif	/* !_ASM */

/* types of controllers supported by this driver */
#define	FDCTYPE_82072	0x0001
#define	FDCTYPE_82077   0x0002
#define	FDCTYPE_CTRLMASK 0x000f

/* types of io chips which indicates the type of auxio register */
#define	FDCTYPE_MACHIO		0x0010
#define	FDCTYPE_SLAVIO		0x0020
#define	FDCTYPE_CHEERIO		0x0040
#define	FDCTYPE_SB		0x0080
#define	FDCTYPE_AUXIOMASK 	0x00f0

/* Method used for transferring data */
#define	FDCTYPE_DMA		0x1000	/* supports DMA for the floppy */
#define	FDCTYPE_DMA8237		FDCTYPE_DMA	/* 8237 DMA controller */
#define	FDCTYPE_TRNSFER_MASTK	0xf000

/*
 * Early revs of the 82077 have a bug by which they
 * will not respond to the TC (Terminal count) signal.
 * Because this behavior is exhibited on the clone machines
 * for which the 077 code has been targeted, special workaround
 * logic has had to implemented for read/write commands.
 */
#define	FDCTYPE_TCBUG	0x0100
#define	FDCTYPE_BUGMASK	0x0f00

/*
 * Controller flags
 */
#define	FDCFLG_BUSY	0x01	/* operation in progress */
#define	FDCFLG_WANT	0x02	/* csb structure wanted */
#define	FDCFLG_WAITING	0x04	/* waiting on I/O completion */
#define	FDCFLG_TIMEDOUT	0x08	/* the current operation just timed out */


#ifndef	_ASM
/*
 * Miscellaneous
 */
#define	FDREAD	1			/* for fdrw() flag */
#define	FDWRITE	2			/* for fdrw() flag */
#define	FD_CRETRY 1000000		/* retry while sending comand */
#define	FD_RRETRY 1000000		/* retry while getting results */
#define	FDXC_SLEEP	0x1		/* tell fdexec to sleep 'till done */
#define	FDXC_CHECKCHG	0x2		/* tell fdexec to check disk chnged */
#define	FD_SB_DMA_ALIGN	0x10000		/* DMA alignment for South Bridge */


/*
 * flags/masks for error printing.
 * the levels are for severity
 */
#define	FDEP_L0		0	/* chatty as can be - for debug! */
#define	FDEP_L1		1	/* best for debug */
#define	FDEP_L2		2	/* minor errors - retries, etc. */
#define	FDEP_L3		3	/* major errors */
#define	FDEP_L4		4	/* catastophic errors, don't mask! */
#define	FDEP_LMAX	4	/* catastophic errors, don't mask! */
#define	FDERRPRINT(l, m, args)	\
	{ if (((l) >= fderrlevel) && ((m) & fderrmask)) cmn_err args; }

/*
 * for each function, we can mask off its printing by clearing its bit in
 * the fderrmask.  Some functions (attach, ident) share a mask bit
 */
#define	FDEM_IDEN 0x00000001	/* fdidentify */
#define	FDEM_ATTA 0x00000001	/* fdattach */
#define	FDEM_SIZE 0x00000002	/* fdsize */
#define	FDEM_OPEN 0x00000004	/* fdopen */
#define	FDEM_GETL 0x00000008	/* fdgetlabel */
#define	FDEM_CLOS 0x00000010	/* fdclose */
#define	FDEM_STRA 0x00000020	/* fdstrategy */
#define	FDEM_STRT 0x00000040	/* fdstart */
#define	FDEM_RDWR 0x00000080	/* fdrdwr */
#define	FDEM_CMD  0x00000100	/* fdcmd */
#define	FDEM_EXEC 0x00000200	/* fdexec */
#define	FDEM_RECO 0x00000400	/* fdrecover */
#define	FDEM_INTR 0x00000800	/* fdintr */
#define	FDEM_WATC 0x00001000	/* fdwatch */
#define	FDEM_IOCT 0x00002000	/* fdioctl */
#define	FDEM_RAWI 0x00004000	/* fdrawioctl */
#define	FDEM_DUMP 0x00008000	/* fddump */
#define	FDEM_GETC 0x00010000	/* fdgetcsb */
#define	FDEM_RETC 0x00020000	/* fdretcsb */
#define	FDEM_RESE 0x00040000	/* fdreset */
#define	FDEM_RECA 0x00080000	/* fdrecalseek */
#define	FDEM_FORM 0x00100000	/* fdformat */
#define	FDEM_RW   0x00200000	/* fdrw */
#define	FDEM_CHEK 0x00400000	/* fdcheckdisk */
#define	FDEM_DSEL 0x00800000	/* fdselect */
#define	FDEM_EJEC 0x01000000	/* fdeject */
#define	FDEM_SCHG 0x02000000	/* fdsense_chng */
#define	FDEM_PACK 0x04000000	/* fdpacklabel */
#define	FDEM_MODS 0x08000000	/* _init, _info, _fini */
#define	FDEM_MOFF 0x10000000	/* fdmotoff */
#define	FDEM_SDMA 0x20000000    /* fdstart_dma */
#define	FDEM_PWR  0x40000000	/* fd power management */
#define	FDEM_ALL  0xFFFFFFFF	/* all */

#endif	/* !_ASM */

#ifdef	__cplusplus
}
#endif

#endif	/* !_SYS_FDVAR_H */