xref: /illumos-gate/usr/src/uts/sun/sys/fdvar.h (revision 1f5207b7604fb44407eb4342aff613f7c4508508)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1989-1994,1997-1998,2000 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #ifndef	_SYS_FDVAR_H
28 #define	_SYS_FDVAR_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 #ifndef	OTYPCNT
37 #define	OTYPCNT	5
38 #endif
39 #ifndef	NDKMAP
40 #define	NDKMAP	8
41 #endif
42 
43 /*
44  * Compile with our without high level interrupt in trap window
45  */
46 
47 /* #define	NO_TRAPWIN_INTR	*/
48 
49 /*
50  * Macros for partition/unit from floppy device number,
51  * plus other manifest defines....
52  */
53 
54 #define	FDUNITSHIFT	(3)
55 #define	FDINSTSHIFT	(2 + FDUNITSHIFT)
56 #define	FDPARTITION(x)	(getminor(x) & 0x7)
57 #define	FDUNIT(x)	((getminor(x) >> FDUNITSHIFT) & 0x3)
58 
59 #define	FDCTLR(x)	(getminor(x) >> FDINSTSHIFT)	/* instance */
60 
61 /*
62  * Structure definitions for the floppy driver.
63  */
64 
65 /*
66  * floppy disk command and status block.
67  *
68  * Needed to execute a command. Since the floppy chip is
69  * single threaded with respect to having only one drive
70  * active at a time, this block of information is only
71  * valid for the length of a commnand and gets rewritten
72  * for each command.
73  */
74 
75 #ifndef	_ASM
76 struct fdcsb {
77 	caddr_t	csb_addr;	/* Data buffer address */
78 	uint_t	csb_len;	/* Data buffer Length */
79 	caddr_t	csb_raddr;	/* modified data buffer address */
80 	uint_t	csb_rlen;	/* modified data buffer len (resid) */
81 	uchar_t	csb_opmode;	/* Current operating mode */
82 	uchar_t	csb_unit;	/* floppy slave unit number */
83 	uchar_t	csb_ncmds;	/* how many command bytes to send */
84 	uchar_t	csb_nrslts;	/* number of result bytes gotten */
85 	uchar_t	csb_opflags;	/* opflags, see below */
86 	uchar_t	csb_maxretry;	/* maximum retries this opertion */
87 	uchar_t	csb_retrys;	/* how may retrys done so far */
88 	uchar_t	csb_status;	/* status returned from hwintr */
89 	uchar_t	csb_cmdstat;	/* if 0 then success, else failure */
90 	uchar_t	csb_cmds[10];	/* commands to send to chip */
91 	uchar_t	csb_rslt[10];	/* results from chip */
92 	uchar_t  csb_dcsr_rslt;  /* set to 1 if there's an error in the DCSR */
93 	uchar_t	csb_dma_rslt;	/* set to 1 if there's an error with the DMA */
94 	ddi_dma_cookie_t csb_dmacookie; /* DMA cookie */
95 
96 	uint_t	csb_ccount;	/* no. of DMA cookies for current window */
97 	uint_t	csb_nwin;	/* no. of DMA windows */
98 	uint_t	csb_windex;	/* DMA window currently in use */
99 	uint_t	csb_read;	/* indicates read or write */
100 };
101 #endif	/* !_ASM */
102 
103 /*
104  * defines for csb_opflags
105  */
106 #define	CSB_OFIMMEDIATE	0x01		/* grab results immediately */
107 #define	CSB_OFSEEKOPS	0x02		/* seek/recal type cmd */
108 #define	CSB_OFXFEROPS	0x04		/* read/write type cmd */
109 #define	CSB_OFRAWIOCTL	0x10		/* raw ioctl - no recovery */
110 #define	CSB_OFNORESULTS	0x20		/* no results at all */
111 #define	CSB_OFTIMEIT	0x40		/* timeout (timer) */
112 
113 #define	CSB_CMDTO 0x01
114 
115 /*
116  * csb_read flags
117  */
118 #define	CSB_NULL	0x0
119 #define	CSB_READ	0x1
120 #define	CSB_WRITE	0x2
121 
122 #ifndef	_ASM
123 #ifndef	_GENASSYM
124 
125 /*
126  * Define a structure to hold the packed default labels,
127  * based on the real dk_label structure - but shorter
128  * than 512 bytes. Now only used to define default info
129  */
130 struct packed_label {
131 	char		dkl_vname[128];	/* for ascii compatibility */
132 	unsigned short	dkl_rpm;	/* rotations per minute */
133 	unsigned short	dkl_pcyl;	/* # physical cylinders */
134 	unsigned short	dkl_apc;	/* alternates per cylinder */
135 	unsigned short	dkl_intrlv;	/* interleave factor */
136 	unsigned short	dkl_ncyl;	/* # of data cylinders */
137 	unsigned short	dkl_acyl;	/* # of alternate cylinders */
138 	unsigned short	dkl_nhead;	/* # of heads in this partition */
139 	unsigned short	dkl_nsect;	/* # of 512 byte sectors per track */
140 	struct dk_map32	dkl_map[NDKMAP]; /* partition map, see dkio.h */
141 	struct dk_vtoc  dkl_vtoc;	/* vtoc stuff from AT&T SVr4 */
142 };
143 
144 /*
145  * Per drive data
146  */
147 struct fdunit {
148 
149 	/*
150 	 * Packed label for this unit
151 	 */
152 	struct	dk_label un_label;
153 
154 	/*
155 	 * Pointer to iostat statistics
156 	 */
157 	struct kstat *un_iostat;	/* iostat numbers */
158 
159 	/*
160 	 * Layered open counters
161 	 */
162 	uint_t	un_lyropen[NDKMAP];
163 
164 	/*
165 	 * Regular open type flags. If
166 	 * NDKMAP gets > 8, change the
167 	 * uchar_t type.
168 	 *
169 	 * Open types BLK, MNT, CHR, SWP
170 	 * assumed to be values 0-3.
171 	 */
172 	uchar_t	un_regopen[OTYPCNT - 1];
173 
174 	/*
175 	 * Exclusive open flags (per partition).
176 	 *
177 	 * The rules are that in order to open
178 	 * a partition exclusively, the partition
179 	 * must be completely closed already. Once
180 	 * any partition of the device is opened
181 	 * exclusively, no other open on that
182 	 * partition may succeed until the partition
183 	 * is closed.
184 	 *
185 	 * If NDKMAP gets > 8, this must change.
186 	 */
187 	uchar_t	un_exclmask;		/* set to indicate exclusive open */
188 
189 	struct	fd_char *un_chars;	/* ptr to diskette characteristics */
190 	char	un_curfdtype;		/* current driver characteristics */
191 					/* type. If -1, then it was set */
192 					/* via an ioctl. Note that a close */
193 					/* and then and open loses the */
194 					/* ioctl set characteristics. */
195 
196 	struct fd_drive *un_drive;	/* ptr to drive characteristics */
197 	int	un_unit_no;		/* drive id number */
198 	uchar_t	un_flags;		/* state information */
199 	clock_t	un_media_timeout;	/* media detection timeout */
200 	timeout_id_t un_media_timeout_id; /* media detection timeout id */
201 	enum dkio_state	un_media_state;	/* up-to-date media state */
202 	int	un_ejected;
203 	short	un_state;		/* Current power level of drive */
204 };
205 
206 /* unit flags (state info) */
207 #define	FDUNIT_DRVCHECKED	0x01	/* this is drive present */
208 #define	FDUNIT_DRVPRESENT	0x02	/* this is drive present */
209 /* (the presence of a diskette is another matter) */
210 #define	FDUNIT_CHAROK		0x04	/* characteristics are known */
211 #define	FDUNIT_UNLABELED	0x10	/* no label using default */
212 #define	FDUNIT_CHANGED		0x20	/* diskette was changed after open */
213 #define	FDUNIT_MEDIUM		0x40	/* fd drive is in medium density */
214 #define	FDUNIT_SET_SPEED	0x80	/* Flag to force updating the */
215 					/* registers with current speed */
216 
217 #endif	/* !_GENASSYM */
218 
219 /* unit flags for power (un_power) */
220 #define	FD_STATE_NORMAL		0x0 /* Normal running state */
221 #define	FD_STATE_SUSPENDED	0x1 /* Device suspended for cpr */
222 #define	FD_STATE_STOPPED	0x2 /* Device is stopped, can be turned off */
223 
224 /*
225  * --------|   fd_detach:DDI_SUSPEND ncmds may be != 0 |-----------|
226  * |running|------------------------------------------>|           |
227  * |NORMAL |  fd_attach:DDI_RESUME                     |           |
228  * |       |<------------------------------------------| SUSPENDED |
229  * |       |                                           |           |
230  * |       |                                           -------------
231  * |       |                                                ^
232  * |       |                                                |DDI_SUSPEND
233  * |       |                                                |
234  * |       | fd_power: PM_LEVEL_OFF, ncmds == 0         -------------
235  * |       |------------------------------------------->|STOPPED     |
236  * |       | fd_power: PM_LEVEL_ON                      |            |
237  * |       |<-------------------------------------------|            |
238  * --------                                              ------------|
239  *
240  * running => FD_STATE_NORMAL
241  *
242  */
243 
244 /* flags for power levels for auto power management */
245 #define	PM_LEVEL_ON	0x1   /* Changes the state to FD_STATE_STOPPED */
246 #define	PM_LEVEL_OFF	0x0   /* Changes the state to FD_STATE_NORMAL */
247 
248 /* a place to keep some statistics on what's going on */
249 struct fdstat {
250 	/* first operations */
251 	int rd;		/* count reads */
252 	int wr;		/* count writes */
253 	int recal;	/* count recalibrates */
254 	int form;	/* count format_tracks */
255 	int other;	/* count other ops */
256 
257 	/* then errors */
258 	int reset;	/* count resets */
259 	int to;		/* count timeouts */
260 	int run;	/* count overrun/underrun */
261 	int de;		/* count data errors */
262 	int bfmt;	/* count bad format errors */
263 };
264 
265 /*
266  * Per controller data
267  */
268 
269 struct fdctlr {
270 	struct	fdctlr	*c_next;	/* next in a linked list */
271 	union  fdcreg   *c_reg;		/* controller registers */
272 	volatile uchar_t *c_control; 	/* addr of c_reg->fdc_control */
273 	uchar_t		*c_fifo;	/* addr of c_reg->fdc_fifo */
274 	uchar_t		*c_dor;		/* addr of c_reg->fdc_dor (077) */
275 	uchar_t		*c_dir;		/* addr of c_reg->fdc_dir (077) */
276 	caddr_t		*c_dma_regs;	/* DMA engine registers */
277 	uint_t		c_fdtype;	/* type of ctlr */
278 	uint_t		*c_hiintct;	/* for convenience.. */
279 	uint_t		c_softic;	/* for use by hi level interrupt */
280 	uchar_t		c_fasttrap;	/* 1 if fast traps enabled, else 0 */
281 	struct	fdcsb	c_csb;		/* current csb */
282 	kmutex_t	c_hilock;	/* high level mutex */
283 	kmutex_t	c_lolock;	/* low level mutex */
284 	kcondvar_t	c_iocv;		/* condition var for I/O done */
285 	kcondvar_t	c_csbcv;	/* condition var for owning csb */
286 	kcondvar_t	c_motoncv;	/* condition var for motor on */
287 	kcondvar_t	c_statecv;	/* condition var for media state */
288 	kcondvar_t	c_suspend_cv;  /* Cond Var on power management */
289 	ksema_t		c_ocsem;	/* sem for serializing opens/closes */
290 	ddi_iblock_cookie_t c_block;	/* returned from ddi_add_fastintr */
291 	ddi_softintr_t	c_softid;	/* returned from ddi_add_softintr */
292 	dev_info_t	*c_dip;		/* controller's dev_info node */
293 	timeout_id_t	c_timeid;	/* watchdog timer id */
294 	timeout_id_t	c_mtimeid;	/* motor off timer id */
295 	struct	fdunit	*c_un;		/* unit on controller */
296 	struct	buf	*c_actf;	/* head of wait list */
297 	struct	buf	*c_actl;	/* tail of wait list */
298 	struct	buf	*c_current;	/* currently active buf */
299 	struct kstat	*c_intrstat;	/* interrupt stats pointer */
300 	struct	fdstat	fdstats;	/* statistics */
301 	uchar_t		c_flags;	/* state information */
302 	caddr_t		c_auxiova;	/* auxio virtual address */
303 	uchar_t		c_auxiodata;	/* auxio data to enable TC */
304 	uchar_t		c_auxiodata2;	/* auxio data to disable TC */
305 	ddi_acc_handle_t c_handlep_cont;
306 					/* data access handle for controller */
307 	ddi_acc_handle_t c_handlep_dma; /* data access handle for DMA engine */
308 	ddi_acc_handle_t c_handlep_aux;  /* data access handle for aux regs */
309 	ddi_dma_handle_t c_dmahandle; 	/* DMA handle */
310 	uint_t		 *c_auxio_reg; 	/* auxio registers */
311 	ddi_dma_attr_t 	c_fd_dma_lim;	/* DMA limit structure */
312 	caddr_t		dma_buf;	/* Temporary DMAble buffer */
313 	ddi_acc_handle_t c_dma_buf_handle; /* DMA handle for dma_buf */
314 	uint_t		sb_dma_channel; /* 8237 dma channel no. */
315 	uchar_t		sb_dma_lock;	/* Status of DMA lock by isadma */
316 };
317 #endif	/* !_ASM */
318 
319 /* types of controllers supported by this driver */
320 #define	FDCTYPE_82072	0x0001
321 #define	FDCTYPE_82077   0x0002
322 #define	FDCTYPE_CTRLMASK 0x000f
323 
324 /* types of io chips which indicates the type of auxio register */
325 #define	FDCTYPE_MACHIO		0x0010
326 #define	FDCTYPE_SLAVIO		0x0020
327 #define	FDCTYPE_CHEERIO		0x0040
328 #define	FDCTYPE_SB		0x0080
329 #define	FDCTYPE_AUXIOMASK 	0x00f0
330 
331 /* Method used for transferring data */
332 #define	FDCTYPE_DMA		0x1000	/* supports DMA for the floppy */
333 #define	FDCTYPE_DMA8237		FDCTYPE_DMA	/* 8237 DMA controller */
334 #define	FDCTYPE_TRNSFER_MASTK	0xf000
335 
336 /*
337  * Early revs of the 82077 have a bug by which they
338  * will not respond to the TC (Terminal count) signal.
339  * Because this behavior is exhibited on the clone machines
340  * for which the 077 code has been targeted, special workaround
341  * logic has had to implemented for read/write commands.
342  */
343 #define	FDCTYPE_TCBUG	0x0100
344 #define	FDCTYPE_BUGMASK	0x0f00
345 
346 /*
347  * Controller flags
348  */
349 #define	FDCFLG_BUSY	0x01	/* operation in progress */
350 #define	FDCFLG_WANT	0x02	/* csb structure wanted */
351 #define	FDCFLG_WAITING	0x04	/* waiting on I/O completion */
352 #define	FDCFLG_TIMEDOUT	0x08	/* the current operation just timed out */
353 
354 
355 #ifndef	_ASM
356 /*
357  * Miscellaneous
358  */
359 #define	FDREAD	1			/* for fdrw() flag */
360 #define	FDWRITE	2			/* for fdrw() flag */
361 #define	FD_CRETRY 1000000		/* retry while sending comand */
362 #define	FD_RRETRY 1000000		/* retry while getting results */
363 #define	FDXC_SLEEP	0x1		/* tell fdexec to sleep 'till done */
364 #define	FDXC_CHECKCHG	0x2		/* tell fdexec to check disk chnged */
365 #define	FD_SB_DMA_ALIGN	0x10000		/* DMA alignment for South Bridge */
366 
367 
368 /*
369  * flags/masks for error printing.
370  * the levels are for severity
371  */
372 #define	FDEP_L0		0	/* chatty as can be - for debug! */
373 #define	FDEP_L1		1	/* best for debug */
374 #define	FDEP_L2		2	/* minor errors - retries, etc. */
375 #define	FDEP_L3		3	/* major errors */
376 #define	FDEP_L4		4	/* catastophic errors, don't mask! */
377 #define	FDEP_LMAX	4	/* catastophic errors, don't mask! */
378 #define	FDERRPRINT(l, m, args)	\
379 	{ if (((l) >= fderrlevel) && ((m) & fderrmask)) cmn_err args; }
380 
381 /*
382  * for each function, we can mask off its printing by clearing its bit in
383  * the fderrmask.  Some functions (attach, ident) share a mask bit
384  */
385 #define	FDEM_IDEN 0x00000001	/* fdidentify */
386 #define	FDEM_ATTA 0x00000001	/* fdattach */
387 #define	FDEM_SIZE 0x00000002	/* fdsize */
388 #define	FDEM_OPEN 0x00000004	/* fdopen */
389 #define	FDEM_GETL 0x00000008	/* fdgetlabel */
390 #define	FDEM_CLOS 0x00000010	/* fdclose */
391 #define	FDEM_STRA 0x00000020	/* fdstrategy */
392 #define	FDEM_STRT 0x00000040	/* fdstart */
393 #define	FDEM_RDWR 0x00000080	/* fdrdwr */
394 #define	FDEM_CMD  0x00000100	/* fdcmd */
395 #define	FDEM_EXEC 0x00000200	/* fdexec */
396 #define	FDEM_RECO 0x00000400	/* fdrecover */
397 #define	FDEM_INTR 0x00000800	/* fdintr */
398 #define	FDEM_WATC 0x00001000	/* fdwatch */
399 #define	FDEM_IOCT 0x00002000	/* fdioctl */
400 #define	FDEM_RAWI 0x00004000	/* fdrawioctl */
401 #define	FDEM_DUMP 0x00008000	/* fddump */
402 #define	FDEM_GETC 0x00010000	/* fdgetcsb */
403 #define	FDEM_RETC 0x00020000	/* fdretcsb */
404 #define	FDEM_RESE 0x00040000	/* fdreset */
405 #define	FDEM_RECA 0x00080000	/* fdrecalseek */
406 #define	FDEM_FORM 0x00100000	/* fdformat */
407 #define	FDEM_RW   0x00200000	/* fdrw */
408 #define	FDEM_CHEK 0x00400000	/* fdcheckdisk */
409 #define	FDEM_DSEL 0x00800000	/* fdselect */
410 #define	FDEM_EJEC 0x01000000	/* fdeject */
411 #define	FDEM_SCHG 0x02000000	/* fdsense_chng */
412 #define	FDEM_PACK 0x04000000	/* fdpacklabel */
413 #define	FDEM_MODS 0x08000000	/* _init, _info, _fini */
414 #define	FDEM_MOFF 0x10000000	/* fdmotoff */
415 #define	FDEM_SDMA 0x20000000    /* fdstart_dma */
416 #define	FDEM_PWR  0x40000000	/* fd power management */
417 #define	FDEM_ALL  0xFFFFFFFF	/* all */
418 
419 #endif	/* !_ASM */
420 
421 #ifdef	__cplusplus
422 }
423 #endif
424 
425 #endif	/* !_SYS_FDVAR_H */
426