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 (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 
     26 #ifndef	_SYS_FDC_H
     27 #define	_SYS_FDC_H
     28 
     29 #ifdef	__cplusplus
     30 extern "C" {
     31 #endif
     32 
     33 #ifndef	OTYPCNT
     34 #define	OTYPCNT	5
     35 #endif
     36 
     37 typedef struct xlate_tbl {
     38 	int	value;
     39 	uchar_t	code;
     40 } xlate_tbl_t;
     41 
     42 /*
     43  * the floppy disk minor device number is interpreted as follows:
     44  *
     45  *	 7 6 5 4 3 2 1 0
     46  * 	+---------+-----+
     47  * 	|  drive  | part|
     48  * 	+---------+-----+
     49  * where:
     50  *		drive = instance
     51  *		part = partition
     52  */
     53 /*
     54  * Macros for partition/drive from floppy device number,
     55  * plus other manifest defines....
     56  */
     57 
     58 #define	PARTITION(x)	(getminor(x) & 7)
     59 #define	DRIVE(x)	(getminor(x) >> 3)
     60 #define	FDUNIT(x)	((x) & 3)	/* unit on controller */
     61 #define	FDCTLR(x)	((x) >> 2)	/* controller instance */
     62 #define	NFDUN	4
     63 
     64 
     65 /*
     66  * Floppy drive / diskette type numbers.
     67  */
     68 #define	FMT_5H	  0
     69 #define	FMT_5Q	  1
     70 #define	FMT_5D9	  2
     71 #define	FMT_5D8	  3
     72 #define	FMT_5D4	  4
     73 #define	FMT_5D16  5
     74 #define	FMT_3E	  6
     75 #define	FMT_3H	  7
     76 #define	FMT_3I	  8
     77 #define	FMT_3M	  9
     78 #define	FMT_3D	  10
     79 #define	FMT_AUTO  11
     80 #define	FMT_MAX	  11
     81 #define	FMT_UNKWN 11
     82 
     83 
     84 /*
     85  * Mini- and Micro- Diskettes Attributes Structure
     86  */
     87 struct fdattr {
     88 	ushort_t fda_rotatespd;		/* rotational speed */
     89 	ushort_t fda_intrlv;		/* interleave factor */
     90 
     91 	uchar_t fda_gapl;		/* gap 3 length */
     92 	uchar_t fda_gapf;		/* gap 3 length for format */
     93 };
     94 
     95 /*
     96  * Miscellaneous
     97  */
     98 #define	FDWRITE	0			/* for fdrw() flag */
     99 #define	FDREAD	1			/* for fdrw() flag */
    100 #define	FDRDONE	86			/*  . read with no retries */
    101 
    102 /*
    103  * Per floppy-drive / diskette state structure
    104  */
    105 
    106 struct fdisk {
    107 	struct fcu_obj	*d_obj;
    108 	int		d_media;	/* drive media capacities */
    109 	struct kstat 	*d_iostat;	/* pointer to iostat statistics */
    110 	int		d_bpsshf;	/* shift count for bytes to sector */
    111 
    112 	ksema_t		d_ocsem;	/* sem for serializing opens/closes */
    113 
    114 	struct buf	*d_actf;	/* head of wait list */
    115 	struct buf	*d_actl;	/* tail of wait list */
    116 	struct buf	*d_current;	/* currently active buf */
    117 	struct partition d_part[NDKMAP];	/* partitions descriptions */
    118 
    119 	/*
    120 	 * Regular open type flags.
    121 	 * Open types BLK, MNT, CHR, SWP assumed to be values 0-3.
    122 	 */
    123 	ulong_t	d_regopen[OTYPCNT - 1];
    124 	ulong_t	d_lyropen[NDKMAP];	/* Layered open counters */
    125 
    126 	/*
    127 	 * Exclusive open flags (per partition).
    128 	 *
    129 	 * The rules are that in order to open a partition exclusively,
    130 	 * the partition must be completely closed already. Once any
    131 	 * partition of the device is opened exclusively, no other open
    132 	 * on that partition may succeed until the partition is closed.
    133 	 */
    134 	ulong_t		d_exclmask;	/* set to indicate exclusive open */
    135 
    136 	/*
    137 	 * Current drive characteristics type.
    138 	 * If -1, then it was set via an ioctl.  Note that a close
    139 	 * and then an open loses the ioctl set characteristics.
    140 	 */
    141 	signed char	d_curfdtype;
    142 	uchar_t		d_deffdtype;
    143 
    144 	uchar_t		d_bsec;		/* encoded bytes_per_sector */
    145 	uchar_t		d_drate;	/* encoded data_rate */
    146 	uchar_t		d_motor;	/* motor-on bit */
    147 
    148 	uchar_t		d_hutsrt;	/* encoded head unload & step_rate */
    149 	uchar_t		d_hlt;		/* encoded head load time */
    150 	uchar_t		d_dtl;		/* dtl code */
    151 
    152 	int	d_media_timeout;	/* media detection timeout */
    153 	timeout_id_t	d_media_timeout_id; /* media detection timeout id */
    154 	enum dkio_state d_media_state;	/* up-to-date media state */
    155 	int		d_ejected;
    156 	kcondvar_t	d_statecv;	/* condition var for media state */
    157 
    158 	ulong_t		d_vtoc_bootinfo[3];	/* from label */
    159 	ulong_t		d_vtoc_version;
    160 	time_t		d_vtoc_timestamp[NDKMAP];
    161 	char		d_vtoc_volume[LEN_DKL_VVOL];
    162 	char		d_vtoc_asciilabel[LEN_DKL_ASCII];
    163 };
    164 
    165 
    166 /* a place to keep some statistics on what's going on */
    167 struct fdstat {
    168 	/* first operations */
    169 	int rd;		/* count reads */
    170 	int wr;		/* count writes */
    171 	int recal;	/* count recalibrates */
    172 	int form;	/* count format_tracks */
    173 	int other;	/* count other ops */
    174 
    175 	/* then errors */
    176 	int reset;	/* count resets */
    177 	int to;		/* count timeouts */
    178 	int run;	/* count overrun/underrun */
    179 	int de;		/* count data errors */
    180 	int bfmt;	/* count bad format errors */
    181 };
    182 
    183 /*
    184  * floppy disk command and status block.
    185  *
    186  * Needed to execute a command. Since the floppy chip is
    187  * single threaded with respect to having only one drive
    188  * active at a time, this block of information is only
    189  * valid for the length of a command and gets rewritten
    190  * for each command.
    191  */
    192 
    193 enum fxstate {
    194 	FXS_START,
    195 	FXS_MTRON,
    196 	FXS_RCAL,
    197 	FXS_DKCHGX,
    198 	FXS_RESTART,
    199 	FXS_RESEEK,
    200 	FXS_SEEK,
    201 	FXS_HDST,
    202 	FXS_RDID,
    203 	FXS_DOIT,
    204 	FXS_DOWT,
    205 	FXS_KILL,
    206 	FXS_RESET,
    207 	FXS_END
    208 };
    209 
    210 enum fmtrstate {
    211 	FMS_OFF,
    212 	FMS_START,
    213 	FMS_KILLST,
    214 	FMS_ON,
    215 	FMS_DELAY,
    216 	FMS_IDLE
    217 };
    218 
    219 enum fmtrinput {
    220 	FMI_TIMER,
    221 	FMI_STARTCMD,
    222 	FMI_RSTARTCMD,
    223 	FMI_DELAYCMD,
    224 	FMI_IDLECMD
    225 };
    226 
    227 struct fdcsb {
    228 	struct buf *csb_bufp;	/* associated buf */
    229 	ddi_dma_handle_t csb_dmahandle;
    230 	int csb_handle_bound;		/* DMA handle has been bound */
    231 	uint_t csb_dmacookiecnt;	/* number of DMA cookies */
    232 	uint_t csb_dmacurrcookie;	/* current cookie number */
    233 	uint_t csb_dmawincnt;		/* number of DMA windows */
    234 	uint_t csb_dmacurrwin;		/* current DMA window */
    235 	ddi_dma_cookie_t csb_dmacookie;
    236 	enum fxstate csb_xstate;	/* Current execution state */
    237 	enum fxstate csb_oldxs;	/* old execution state */
    238 	uchar_t	csb_npcyl;	/* new physical cylinder number */
    239 	uchar_t	csb_drive;	/* floppy unit number */
    240 	uchar_t	csb_ncmds;	/* how many command bytes to send */
    241 	uchar_t	csb_nrslts;	/* number of result bytes gotten */
    242 	uchar_t	csb_opflags;	/* opflags, see below */
    243 	uchar_t	csb_timer;	/* op timer, in 0.1 sec */
    244 	uchar_t	csb_maxretry;	/* maximum retries this operation */
    245 	uchar_t	csb_retrys;	/* how may retrys done so far */
    246 	uchar_t	csb_ourtrys;	/* how may over/underrun retrys done so far */
    247 	uchar_t	csb_status;	/* status returned from hwintr */
    248 	uchar_t	csb_cmdstat;	/* if 0 then success, else failure */
    249 	uchar_t	csb_cmd[10];	/* command to send to chip */
    250 	uchar_t	csb_rslt[10];	/* results from chip */
    251 };
    252 
    253 /*
    254  * defines for csb_opflags
    255  */
    256 #define	CSB_OFINRPT	0x01		/* generates an interrupt */
    257 #define	CSB_OFDMARD	0x02		/* uses DMA for reading */
    258 #define	CSB_OFDMAWT	0x04		/* uses DMA for writing */
    259 #define	CSB_OFRESLT	0x08		/* generates results */
    260 #define	CSB_OFRAWIOCTL	0x10		/* raw i/o control */
    261 
    262 #define	CSB_CMDTO   0x01
    263 #define	CSB_CMDDMA  0x03
    264 #define	CSB_CMDNGNR 0x07
    265 
    266 
    267 /*
    268  * 82077AA Controller modes
    269  */
    270 enum fdcmode077 {
    271 	FDCMODE_AT,
    272 	FDCMODE_PS2,	/* not supported */
    273 	FDCMODE_30
    274 };
    275 
    276 /*
    277  * Per controller data
    278  */
    279 
    280 struct fdcntlr {
    281 	kmutex_t	c_lock;		/* controller mutex */
    282 	kmutex_t	c_dorlock;	/* digital_output_register mutex */
    283 	kcondvar_t	c_iocv;		/* condition var for I/O done */
    284 	ksema_t		c_selsem;	/* sem for select unit */
    285 	boolean_t	c_suspended;	/* if DDI_SUSPENDed */
    286 
    287 	dev_info_t	*c_dip;
    288 	int		c_number;	/* logical controller number */
    289 	int		c_regbase;	/* base i/o address */
    290 	int		c_dmachan;	/* DMA channel number */
    291 	int		c_intprio;	/* interrupt priority */
    292 	int		c_intvec;	/* interrupt vector num */
    293 	int		c_chip;
    294 	enum fdcmode077	c_mode;		/* 82077 controller mode */
    295 
    296 	ulong_t		c_flags;	/* state information */
    297 	struct kstat	*c_intrstat;	/* interrupt stats pointer */
    298 	struct	fdstat	fdstats;	/* statistics */
    299 
    300 	ddi_iblock_cookie_t c_iblock;	/* returned from ddi_add_intr */
    301 	ddi_idevice_cookie_t c_idevice;	/* returned from ddi_add_intr */
    302 
    303 	int		c_curunit;	/* current/last selected unit */
    304 	timeout_id_t	c_timeid;	/* watchdog timer id */
    305 
    306 	struct	fcu_obj	*c_unit[NFDUN];	/* slave on controller */
    307 	timeout_id_t	c_motort[NFDUN]; /* motor timer id */
    308 	enum fmtrstate	c_mtrstate[NFDUN];
    309 	int		c_curpcyl[NFDUN]; /* current physical cylinder */
    310 	signed char	c_sekdir[NFDUN]; /* direction of last seek */
    311 
    312 	struct	fdcsb	c_csb;		/* current csb */
    313 
    314 	/*
    315 	 * floppy controller register values
    316 	 */
    317 	uchar_t		c_digout;
    318 	uchar_t		c_drate;	/* only 82072 and 82077AA controllers */
    319 	uchar_t		c_config;	/* DSR on PC/AT with 8272A */
    320 	uchar_t		c_mstat;
    321 	uchar_t		c_data;
    322 	uchar_t		c_digin;
    323 
    324 	uchar_t		c_bsec;		/* encoded bytes_per_sector */
    325 	uchar_t		c_hutsrt;	/* encoded head unload & step_rate */
    326 	uchar_t		c_hlt;		/* encoded head load time */
    327 };
    328 
    329 /*
    330  * Controller flags
    331  */
    332 #define	FCFLG_BUSY	0x01	/* operation in progress */
    333 #define	FCFLG_WANT	0x02	/* csb structure wanted */
    334 #define	FCFLG_WAITMR	0x10	/* waiting for motor to start I/O */
    335 #define	FCFLG_WAITING	0x20	/* waiting on I/O completion */
    336 #define	FCFLG_TIMEOUT	0x80	/* the current operation just timed out */
    337 #define	FCFLG_DSOUT	0x100	/* DENSEL ouput is in use for speed ctl */
    338 #define	FCFLG_3DMODE	0x800	/* ctlr is 3D Mode capable */
    339 
    340 
    341 /*
    342  * FDC operations
    343  */
    344 
    345 struct fcobjops {
    346 	int	(*fco_abort)();		/* controller abort */
    347 	int	(*fco_dkinfo)();	/* get disk controller info */
    348 
    349 	int	(*fco_select)();	/* select / deselect unit */
    350 	int	(*fco_getchng)();	/* get media change */
    351 	int	(*fco_resetchng)();	/* reset media change */
    352 	int	(*fco_rcseek)();	/* recal / seek */
    353 	int	(*fco_rwbuf)();		/* read /write request */
    354 	int	(*fco_rw)();		/* read /write sector */
    355 	int	(*fco_format)();	/* format track */
    356 	int	(*fco_rwioctl)();	/* raw ioctl */
    357 };
    358 
    359 /*
    360  * FDC unit object
    361  */
    362 
    363 struct fcu_obj {
    364 	ulong_t		fj_flags;	/* state information */
    365 	kmutex_t 	fj_lock;	/* unit mutex */
    366 	caddr_t		fj_data;
    367 	struct fd_drive *fj_drive;	/* pointer to drive characteristics */
    368 	struct fd_char	*fj_chars;	/* ptr to diskette characteristics */
    369 	struct fdattr	*fj_attr;	/* additional diskette attributes */
    370 	dev_info_t	*fj_dip;
    371 	ushort_t	fj_rotspd;	/* rotational speed */
    372 	ulong_t		fj_unit;
    373 	struct fcobjops *fj_ops;
    374 	struct fdcntlr	*fj_fdc;
    375 	ddi_iblock_cookie_t *fj_iblock;
    376 };
    377 
    378 /* unit flags (state info) */
    379 #define	FUNIT_DRVATCH		0x001	/* this is drive present */
    380 #define	FUNIT_WPROT		0x004	/* diskette is read only */
    381 #define	FUNIT_CHAROK		0x010	/* characteristics are known */
    382 #define	FUNIT_LABELOK		0x020	/* label was read from disk */
    383 #define	FUNIT_UNLABELED		0x040	/* no label using default */
    384 #define	FUNIT_CHANGED		0x100	/* diskette was changed after open */
    385 #define	FUNIT_CHGDET		0x200	/* diskette removal was detected */
    386 #define	FUNIT_3DMODE		0x4000	/* unit is in fast speed mode */
    387 #define	FUNIT_BUSY		0x8000	/* unit is busy */
    388 
    389 #ifdef _VPIX
    390 #define	DRV_NONE	0x00
    391 #define	DRV_DBL		0x01
    392 #define	DRV_QUAD	0x02
    393 #define	DRV_720		0x04	/* LOW_35 gets changed to this for or'ing */
    394 #define	DRV_144		0x08	/* HI35 gets changed to this for or'ing */
    395 
    396 /* ioctl numbers used by VPIX */
    397 #define	FIOC		('F'<<8)
    398 #define	F_DTYP		(FIOC|60)	/* returns fd_drvtype */
    399 #define	F_FCR		(FIOC|61)	/* output to Floppy Control Register */
    400 #define	F_DOR		(FIOC|62)	/* output to Digital Output Register */
    401 #define	F_RAW		(FIOC|63)	/* general raw controller interface */
    402 #endif
    403 
    404 #ifdef	__cplusplus
    405 }
    406 #endif
    407 
    408 #endif	/* !_SYS_FDC_H */
    409