summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/fdc.h
blob: 7f209d240536e6aa17e302379150d00f78c3dd93 (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
/*
 * 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 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_FDC_H
#define	_SYS_FDC_H

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

#ifdef	__cplusplus
extern "C" {
#endif

#ifndef	OTYPCNT
#define	OTYPCNT	5
#endif

typedef struct xlate_tbl {
	int	value;
	uchar_t	code;
} xlate_tbl_t;

/*
 * the floppy disk minor device number is interpreted as follows:
 *
 *	 7 6 5 4 3 2 1 0
 * 	+---------+-----+
 * 	|  drive  | part|
 * 	+---------+-----+
 * where:
 *		drive = instance
 *		part = partition
 */
/*
 * Macros for partition/drive from floppy device number,
 * plus other manifest defines....
 */

#define	PARTITION(x)	(getminor(x) & 7)
#define	DRIVE(x)	(getminor(x) >> 3)
#define	FDUNIT(x)	((x) & 3)	/* unit on controller */
#define	FDCTLR(x)	((x) >> 2)	/* controller instance */
#define	NFDUN	4


/*
 * Floppy drive / diskette type numbers.
 */
#define	FMT_5H	  0
#define	FMT_5Q	  1
#define	FMT_5D9	  2
#define	FMT_5D8	  3
#define	FMT_5D4	  4
#define	FMT_5D16  5
#define	FMT_3E	  6
#define	FMT_3H	  7
#define	FMT_3I	  8
#define	FMT_3M	  9
#define	FMT_3D	  10
#define	FMT_AUTO  11
#define	FMT_MAX	  11
#define	FMT_UNKWN 11


/*
 * Mini- and Micro- Diskettes Attributes Structure
 */
struct fdattr {
	ushort_t fda_rotatespd;		/* rotational speed */
	ushort_t fda_intrlv;		/* interleave factor */

	uchar_t fda_gapl;		/* gap 3 length */
	uchar_t fda_gapf;		/* gap 3 length for format */
};

/*
 * Miscellaneous
 */
#define	FDWRITE	0			/* for fdrw() flag */
#define	FDREAD	1			/* for fdrw() flag */
#define	FDRDONE	86			/*  . read with no retries */

/*
 * Per floppy-drive / diskette state structure
 */

struct fdisk {
	struct fcu_obj	*d_obj;
	int		d_media;	/* drive media capacities */
	struct kstat 	*d_iostat;	/* pointer to iostat statistics */
	int		d_bpsshf;	/* shift count for bytes to sector */

	ksema_t		d_ocsem;	/* sem for serializing opens/closes */

	struct buf	*d_actf;	/* head of wait list */
	struct buf	*d_actl;	/* tail of wait list */
	struct buf	*d_current;	/* currently active buf */
	struct partition d_part[NDKMAP];	/* partitions descriptions */

	/*
	 * Regular open type flags.
	 * Open types BLK, MNT, CHR, SWP assumed to be values 0-3.
	 */
	ulong_t	d_regopen[OTYPCNT - 1];
	ulong_t	d_lyropen[NDKMAP];	/* Layered open counters */

	/*
	 * 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.
	 */
	ulong_t		d_exclmask;	/* set to indicate exclusive open */

	/*
	 * Current drive characteristics type.
	 * If -1, then it was set via an ioctl.  Note that a close
	 * and then an open loses the ioctl set characteristics.
	 */
	signed char	d_curfdtype;
	uchar_t		d_deffdtype;

	uchar_t		d_bsec;		/* encoded bytes_per_sector */
	uchar_t		d_drate;	/* encoded data_rate */
	uchar_t		d_motor;	/* motor-on bit */

	uchar_t		d_hutsrt;	/* encoded head unload & step_rate */
	uchar_t		d_hlt;		/* encoded head load time */
	uchar_t		d_dtl;		/* dtl code */

	int	d_media_timeout;	/* media detection timeout */
	timeout_id_t	d_media_timeout_id; /* media detection timeout id */
	enum dkio_state d_media_state;	/* up-to-date media state */
	int		d_ejected;
	kcondvar_t	d_statecv;	/* condition var for media state */

	ulong_t		d_vtoc_bootinfo[3];	/* from label */
	ulong_t		d_vtoc_version;
	time_t		d_vtoc_timestamp[NDKMAP];
	char		d_vtoc_volume[LEN_DKL_VVOL];
	char		d_vtoc_asciilabel[LEN_DKL_ASCII];
};


/* 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 */
};

/*
 * 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 command and gets rewritten
 * for each command.
 */

enum fxstate {
	FXS_START,
	FXS_MTRON,
	FXS_RCAL,
	FXS_DKCHGX,
	FXS_RESTART,
	FXS_RESEEK,
	FXS_SEEK,
	FXS_HDST,
	FXS_RDID,
	FXS_DOIT,
	FXS_DOWT,
	FXS_KILL,
	FXS_RESET,
	FXS_END
};

enum fmtrstate {
	FMS_OFF,
	FMS_START,
	FMS_KILLST,
	FMS_ON,
	FMS_DELAY,
	FMS_IDLE
};

enum fmtrinput {
	FMI_TIMER,
	FMI_STARTCMD,
	FMI_RSTARTCMD,
	FMI_DELAYCMD,
	FMI_IDLECMD
};

struct fdcsb {
	struct buf *csb_bufp;	/* associated buf */
	ddi_dma_handle_t csb_dmahandle;
	int csb_handle_bound;		/* DMA handle has been bound */
	uint_t csb_dmacookiecnt;	/* number of DMA cookies */
	uint_t csb_dmacurrcookie;	/* current cookie number */
	uint_t csb_dmawincnt;		/* number of DMA windows */
	uint_t csb_dmacurrwin;		/* current DMA window */
	ddi_dma_cookie_t csb_dmacookie;
	enum fxstate csb_xstate;	/* Current execution state */
	enum fxstate csb_oldxs;	/* old execution state */
	uchar_t	csb_npcyl;	/* new physical cylinder number */
	uchar_t	csb_drive;	/* floppy 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_timer;	/* op timer, in 0.1 sec */
	uchar_t	csb_maxretry;	/* maximum retries this operation */
	uchar_t	csb_retrys;	/* how may retrys done so far */
	uchar_t	csb_ourtrys;	/* how may over/underrun 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_cmd[10];	/* command to send to chip */
	uchar_t	csb_rslt[10];	/* results from chip */
};

/*
 * defines for csb_opflags
 */
#define	CSB_OFINRPT	0x01		/* generates an interrupt */
#define	CSB_OFDMARD	0x02		/* uses DMA for reading */
#define	CSB_OFDMAWT	0x04		/* uses DMA for writing */
#define	CSB_OFRESLT	0x08		/* generates results */
#define	CSB_OFRAWIOCTL	0x10		/* raw i/o control */

#define	CSB_CMDTO   0x01
#define	CSB_CMDDMA  0x03
#define	CSB_CMDNGNR 0x07


/*
 * 82077AA Controller modes
 */
enum fdcmode077 {
	FDCMODE_AT,
	FDCMODE_PS2,	/* not supported */
	FDCMODE_30
};

/*
 * Per controller data
 */

struct fdcntlr {
	kmutex_t	c_lock;		/* controller mutex */
	kmutex_t	c_dorlock;	/* digital_output_register mutex */
	kcondvar_t	c_iocv;		/* condition var for I/O done */
	ksema_t		c_selsem;	/* sem for select unit */

	dev_info_t	*c_dip;
	int		c_number;	/* logical controller number */
	int		c_regbase;	/* base i/o address */
	int		c_dmachan;	/* DMA channel number */
	int		c_intprio;	/* interrupt priority */
	int		c_intvec;	/* interrupt vector num */
	int		c_chip;
	enum fdcmode077	c_mode;		/* 82077 controller mode */

	ulong_t		c_flags;	/* state information */
	struct kstat	*c_intrstat;	/* interrupt stats pointer */
	struct	fdstat	fdstats;	/* statistics */

	ddi_iblock_cookie_t c_iblock;	/* returned from ddi_add_intr */
	ddi_idevice_cookie_t c_idevice;	/* returned from ddi_add_intr */

	int		c_curunit;	/* current/last selected unit */
	timeout_id_t	c_timeid;	/* watchdog timer id */

	struct	fcu_obj	*c_unit[NFDUN];	/* slave on controller */
	timeout_id_t	c_motort[NFDUN]; /* motor timer id */
	enum fmtrstate	c_mtrstate[NFDUN];
	int		c_curpcyl[NFDUN]; /* current physical cylinder */
	signed char	c_sekdir[NFDUN]; /* direction of last seek */

	struct	fdcsb	c_csb;		/* current csb */

	/*
	 * floppy controller register values
	 */
	uchar_t		c_digout;
	uchar_t		c_drate;	/* only 82072 and 82077AA controllers */
	uchar_t		c_config;	/* DSR on PC/AT with 8272A */
	uchar_t		c_mstat;
	uchar_t		c_data;
	uchar_t		c_digin;

	uchar_t		c_bsec;		/* encoded bytes_per_sector */
	uchar_t		c_hutsrt;	/* encoded head unload & step_rate */
	uchar_t		c_hlt;		/* encoded head load time */
};

/*
 * Controller flags
 */
#define	FCFLG_BUSY	0x01	/* operation in progress */
#define	FCFLG_WANT	0x02	/* csb structure wanted */
#define	FCFLG_WAITMR	0x10	/* waiting for motor to start I/O */
#define	FCFLG_WAITING	0x20	/* waiting on I/O completion */
#define	FCFLG_TIMEOUT	0x80	/* the current operation just timed out */
#define	FCFLG_DSOUT	0x100	/* DENSEL ouput is in use for speed ctl */
#define	FCFLG_3DMODE	0x800	/* ctlr is 3D Mode capable */


/*
 * FDC operations
 */

struct fcobjops {
	int	(*fco_start)();		/* controller start */
	int	(*fco_abort)();		/* controller abort */
	int	(*fco_getcap)();	/* capability retrieval */
	int	(*fco_setcap)();	/* capability establishment */
	int	(*fco_dkinfo)();	/* get disk controller info */

	int	(*fco_select)();	/* select / deselect unit */
	int	(*fco_getchng)();	/* get media change */
	int	(*fco_resetchng)();	/* reset media change */
	int	(*fco_rcseek)();	/* recal / seek */
	int	(*fco_rwbuf)();		/* read /write request */
	int	(*fco_rw)();		/* read /write sector */
	int	(*fco_format)();	/* format track */
	int	(*fco_rwioctl)();	/* raw ioctl */
};

/*
 * FDC unit object
 */

struct fcu_obj {
	ulong_t		fj_flags;	/* state information */
	kmutex_t 	fj_lock;	/* unit mutex */
	caddr_t		fj_data;
	struct fd_drive *fj_drive;	/* pointer to drive characteristics */
	struct fd_char	*fj_chars;	/* ptr to diskette characteristics */
	struct fdattr	*fj_attr;	/* additional diskette attributes */
	dev_info_t	*fj_dip;
	ushort_t	fj_rotspd;	/* rotational speed */
	ulong_t		fj_unit;
	struct fcobjops *fj_ops;
	struct fdcntlr	*fj_fdc;
	ddi_iblock_cookie_t *fj_iblock;
};

/* unit flags (state info) */
#define	FUNIT_DRVATCH		0x001	/* this is drive present */
#define	FUNIT_WPROT		0x004	/* diskette is read only */
#define	FUNIT_CHAROK		0x010	/* characteristics are known */
#define	FUNIT_LABELOK		0x020	/* label was read from disk */
#define	FUNIT_UNLABELED		0x040	/* no label using default */
#define	FUNIT_CHANGED		0x100	/* diskette was changed after open */
#define	FUNIT_CHGDET		0x200	/* diskette removal was detected */
#define	FUNIT_3DMODE		0x4000	/* unit is in fast speed mode */
#define	FUNIT_BUSY		0x8000	/* unit is busy */

#ifdef _VPIX
#define	DRV_NONE	0x00
#define	DRV_DBL		0x01
#define	DRV_QUAD	0x02
#define	DRV_720		0x04	/* LOW_35 gets changed to this for or'ing */
#define	DRV_144		0x08	/* HI35 gets changed to this for or'ing */

/* ioctl numbers used by VPIX */
#define	FIOC		('F'<<8)
#define	F_DTYP		(FIOC|60)	/* returns fd_drvtype */
#define	F_FCR		(FIOC|61)	/* output to Floppy Control Register */
#define	F_DOR		(FIOC|62)	/* output to Digital Output Register */
#define	F_RAW		(FIOC|63)	/* general raw controller interface */
#endif

#ifdef	__cplusplus
}
#endif

#endif	/* !_SYS_FDC_H */