/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION  1986,1987,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header: /usr/src/sys/rtio/RCS/fdvar.h,v 1.3 1993/10/30 20:52:23 md Exp $ */
/* $ACIS:fdvar.h 12.0$ */
/* $Source: /usr/src/sys/rtio/RCS/fdvar.h,v $ */

#ifndef lint
static char *rcsidfdvar = "$Header: /usr/src/sys/rtio/RCS/fdvar.h,v 1.3 1993/10/30 20:52:23 md Exp $";
#endif

#define	b_cylin	b_resid
#define	FD_SPL()	_spl4()			/* CPU level 4 */
#define FD_ERROR_RETRY	6			/* number of retries after errors */
#define FD_REDUCE_XFER	3			/* number of retries before reducing the size of the transfer */
#define FD_UNIT_MASK	0x0F			/* bitmask for drive unit */
#define	FDUNIT(dev)	(minor(dev) & FD_UNIT_MASK)
#define FD_TYPE_MASK	0xF0			/* bitmask for drive type */
#define	FDTYPE(dev)	(minor(dev) & FD_TYPE_MASK)
#define	FDBPS		512			/* # bytes per sector */
#define	FDSECSIZE	FDBPS / 256
#define	FDWAITTIME 	300			/* Time until FDWAIT gives up */
#define	B_CTRL		0x80000000		/* control (format) request */
#define	B_SETUP		0x40000000		/* read drive status (open) */
#define B_VERIFY	0x20000000		/* Verify a write operation */
#define	FDDBLSTEP	2			/* Double step cylinder */
#define	FDSECBASE	0xff			/* magic base for sector size*/
#define	FDFORMREQ	0x0b			/* magic flgs for fdformat */
#define FDINFOREQ	0x09
#define	FDWAITREAD	0xff			/* read results even if err */
#define	FDRECALDELAY	((hz/8)*30)		/* delay after recalibrate */
#define	FDHDSETTLE	(hz/1000*18)		/* 18 ms (head settle time) */
#define	FDPRI		PZERO+5
#define	FDCTRLMASK	0xfc			/* Mask out slave number */
#define	FDOTHERUNIT(unit) (unit ^ 0x01)		/* get the unit of the other */
						/* slave on the current ctlr */
#define	BSIZE		DEV_BSIZE

/* per-controller data */
struct	fd_ctlr {
	volatile int	fdc_state;	/* controller state */
#define	FDS_READ	1	/* read started */
#define	FDS_WRITE	2	/* write started */
#define	FDS_FORMAT	3	/* format started */
#define	FDS_IDLE	4	/* device is idle */
#define	FDS_SEEK	5	/* device is seeking */
#define	FDS_SETUP	6	/* set up for density */
#define	FDS_DONE	7	/* done with setup */
#define	FDS_SKDON	8	/* done with seek */
#define	FDS_RECAL	9	/* done with recalibrate */
#define	FDS_SLAVE	10	/* interupt generated by fdslave */
#define	FDS_VERIFY	11	/* write block ready to be verified */
#define	FDS_VER_DONE	12	/* block has been verified */
#define	FDS_VER_ERROR	13	/* error detected in block by verify */
	volatile int	fdc_tocnt;	/* for watchdog routine */
#define	FD_MAXTIMEOUT	10	/* # seconds to wait before giving up */
	char	fdc_ctrl;	/* last control command sent to the ctlr */
	int	fdc_lstdens;	/* last density set by motor on */
	int	fdc_drives;	/* the number of open drives on ctlr */
};

/* per-drive data */
struct 	fd_softc {
	int	sc_flags;	/* drive status flags */
#define	FDF_DEVTYPE	0x07	/* mapping flags */
#define	FDF_LOCK	0x10	/* exclusive use */
#define	FDF_FORMAT	0x80	/* format in progress */
#define FDF_INFO	0x40	/* Informational ioctl in progress */
#define	FDF_TIMEOUT	0x200	/* Device has timed out waiting for intr */
	int	sc_open;	/* count number of opens */
	int	sc_bopen;	/* count number of block opens */
	int	sc_copen;	/* count number of character opens */
	int	sc_dens;	/* density of floppy */
#define FD360K1200K		0
#define FD1200K1200K		1
#define	FD360K360K		2
#define FD720K1440K		3
#define FD1440K1440K		4
#define FD720K720K		5
#define	FDMAXTYPE		5		/* max floppy type (index) */
	volatile int	sc_motor;	/* Motor on, time until motor is off */
#define	FDMOTORWAIT	3	/* delay before motor off */
	int	sc_error;	/* Low level routine error flage */
	int	sc_errcnt;	/* Autodensity error count flag XXX */
	int	sc_retries;	/* Retry count in Autodensity XXX */
	int	sc_reduce;	/* flag reduce transfer length because of hw */
#define	FDFORMRETRIES	5	/* # of retries for format in autodensity */
#define	FDRETRIES	8	/* number of disk retries for autodensity */
	int	sc_drive;	/* floppy drive type */
#define	FDUNKNOWN	0
#define	FD1200K		1
#define	FD360K		2
#define FD1440K		3
#define FD720K		4
	int	sc_sr0;		/* Adapter status register 0 */
#define	FDSR0	"\20\10Invalid\7ComNotDon\6SeekEnd\5NoTrack0\4NotReady\3HeadAddr\2Unit2\1Unit1"
#define	FDSR0MASK	0xc0
	int	sc_sr1;		/* Adapter status register 1 */
#define	FDSR1 "\20\10EndOfCyl\7NU\6DataCRCError\5Overrun\4NU\3IdNotFound\2NoWrite\1MissAddrMark"
	int	sc_sr2;		/* Adapter status register 2 */
#define	FDSR2 "\20\10NU\7CtrlMark\6DataField\5WrongCyl\4ScanEqualHit\3ScanNotSat\2BadCyl\1MissAddr"
	int	sc_sr3;		/* Adapter status register 3 */
#define	FDSR3 "\20\10Fault\7WriteProt\6Ready\5Track0\4TwoSided\3Head1\2Unit2\1Unit1"
#define	FDTRAK0		0x10
#define	FDNOWRITE	0x40
#define	FDREADY		0x20
	int	sc_curcyl;	/* Current cylinder */
	int	sc_hrdcyl;	/* Cylinder position reported by adapter */
	int	sc_hrdhd;	/* Head position reported by adapter */
	int	sc_hrdsc;	/* Sector position reported by adapter */
	int	sc_size;	/* Sector size reported by adapter */
	int	sc_suppress;	/* 1 = Suppress hardware error printf */
	/*
	 * The following is for write verification. Since it is possible for
	 * writes to fail without giving any error indication (sigh), we must
	 * read-verify all writes. This is were state information is stored
	 * so that the verification is handled "transparently" whenever we
	 * request a write operation.
	 */
	struct buf *sc_verify;	/* the original buffer we need to verify */
	struct buf *sc_verbuf;	/* the temp buffer we read into to verify */
	int	sc_write_retry;	/* number of write retries outstanding */
	/*
	 * The rest of this structure is used to 
	 * store temporaries while simulating multi 
	 * sector transfers
	 */
	caddr_t	sc_uaddr;	/* Save starting xfer address */
	long	sc_bcnt;	/* total transfer count */
	long	sc_resid;	/* no. of bytes left to transfer */
	long	sc_trunc;	/* number of bytes that have been truncated */
	char	sc_cyl;		/* requested cylinder # */
	char	sc_sec;		/* requested sector # */
	char	sc_head;	/* requested head # */
	int	sc_maxbyt;	/* number of bytes left on track */
};

/*
 * Drive description table.
 */
struct 	fdst {
	short	nsect;		/* # sectors/track */
	short	ntrak;		/* # surfaces or heads */
	short	nspc;		/* # sectors/cylinder */
	short	ncyl;		/* # cylinders */
	long	nbpd;		/* # bytes per disk */
	char	gpl;		/* Gap length */
	char	fgpl;		/* Format Gap length */
	char	step;		/* Stepping rate and head unload time */
	char	xfer;		/* Data transfer rate */
	int	drive;		/* Drive type */
	char	*name;		/* name of device type */
	int		delay;		/* factor for delay times */
};
struct 	fdformdata {
	char	fdtrack;	/* track to format */
	char	fdhead;		/* head to format */
	char	fdsect;		/* sector to format */
	char	fdsize;		/* sector size */
};

struct 	statestring {
	char	*value;
	} statestring[] = {
	{"Zero"},
	{"Read"},
	{"Write"},
	{"Format"},
	{"Idle"},
	{"Seek"},
	{"Setup"},
	{"Done"},
	{"SkDone"},
	{"Recal"},
	{"Slave"},
	{"Verify"},
	{"VrDone"},
	{"VrErr"},
	};
