Home | History | Annotate | Download | only in sys
      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