Coherent4.2.10/include/sys/ft.h

#ifndef __FT_H__
#define __FT_H__

#include <common/__caddr.h>
#include <common/feature.h>
#include <common/ccompat.h>
#include <sys/types.h>
#include <kernel/timeout.h>

/* Constants describing the data format.				*/

#define	FT_SEG_SIZE	32768		/* bytes per QIC-80/40 segment	*/
#define	FT_BLK_SIZE	1024		/* bytes per QIC-80/40 block	*/
#define	FT_BLK_PER_SEG	32		/* 32 blocks per segment	*/
#define FT_NUM_ECC_BLKS 3		/* 3 ECC blocks per segment	*/
#define FT_SEC_PER_PTRK	128		/* Sectors per disk pseudotrack.*/

/*
 * Minor numbering.  Highest two bits must be 01 (see sys/fdc765.h).
 *
 *	01fr yxuu
 *
 *	f  = 0=QIC-40, 1=QIC-80
 *	r  = 0=rewind on close, 1=no rewind on close
 *
 *	y  = 0=205' tape length, 1=307.5'
 *	x    unused
 *	uu = FDC unit number (0..3)
 *
 *	Tunable parameters for soft select, CMS vs. A/M/S.
 */

#define FT_Q80_FORMAT(dev)	(dev & 0x20)
#define FT_NORWDCL(dev)		(dev & 0x10)
#define FT_LONGTAPE(dev)	(dev & 0x08)
#define FT_UNIT(dev)		(dev & 0x03)

/************************************************************************/
/*	  QIC 117 commands						*/
/************************************************************************/

#define	QIC_CMD_RST	1	/* reset				*/
#define	QIC_CMD_RNB	2	/* report next bit			*/
#define	QIC_CMD_PAUS	3	/* pause				*/
#define	QIC_CMD_MPAUS	4	/* micro step pause			*/
#define	QIC_CMD_ALTTO	5	/* alternate command timeout		*/
#define	QIC_CMD_STS	6	/* status				*/
#define	QIC_CMD_ECD	7	/* report error code			*/
#define	QIC_CMD_DRVCN	8	/* report drive configuration		*/
#define	QIC_CMD_ROMVN	9	/* report ROM version			*/
#define	QIC_CMD_FWD	10	/* logical forward			*/
#define	QIC_CMD_BOT	11	/* rewind to begining of tape		*/
#define	QIC_CMD_EOT	12	/* forward to end of tape		*/
#define	QIC_CMD_SEEK	13	/* seek head to track			*/
#define	QIC_CMD_CAL	14	/* rewind, calibrate drive		*/
#define	QIC_CMD_FMD	15	/* format mode				*/
#define	QIC_CMD_WRF	16	/* write reference bursts		*/
#define	QIC_CMD_VMD	17	/* verify mode				*/
#define	QIC_CMD_STOP	18	/* stop tape motion			*/
#define	QIC_CMD_HDUP	21	/* micro step head up			*/
#define	QIC_CMD_HDDN	22	/* micro step head down			*/
#define	QIC_CMD_SKPB	25	/* skip n segments back			*/
#define	QIC_CMD_SKPF	26	/* skip n segments forward		*/
#define	QIC_CMD_RATE	27	/* select rate				*/
#define	QIC_CMD_NMD	30	/* normal (primary) mode		*/
#define	QIC_CMD_VNDID	32	/* report vendor id			*/
#define	QIC_CMD_TPSTAT	33	/* report tape status			*/
#define	QIC_CMD_SKPBX	34	/* skip n segments back extended	*/
#define	QIC_CMD_SKPFX	35	/* skip n segments forward extended	*/

/* These are Archive/Mountain/Summit variants, not QIC standard. */
#define QIC_CMD_SS2	20	/* A/M/S soft select enable 2		*/
#define QIC_CMD_SS1	23	/* A/M/S soft select enable 1		*/
#define QIC_CMD_SS_OFF	24	/* A/M/S soft select disable		*/

/* These are CMS variants, not QIC standard. */
#define QIC_CMD_NWTP	45	/* CMS new tape				*/
#define QIC_CMD_CSS_ON	46	/* CMS soft select enable		*/
#define QIC_CMD_CSS_OFF	47	/* CMS soft select disable		*/

/************************************************************************/
/*	  QIC 117 Report Drive Status bits				*/
/************************************************************************/
#define QIC_STAT_RDY	0x01	/* drive ready or idle			*/
#define QIC_STAT_ERR	0x02	/* error detected			*/
#define QIC_STAT_PRSNT	0x04	/* cartridge present			*/
#define QIC_STAT_WPROT	0x08	/* cartridge write protected		*/
#define QIC_STAT_NEWCT	0x10	/* new cartridge			*/
#define QIC_STAT_REFD	0x20	/* cartridge referenced			*/
#define QIC_STAT_BOT	0x40	/* at physical BOT			*/
#define QIC_STAT_EOT	0x80	/* at physical EOT			*/

/************************************************************************/
/*	  QIC 117 error codes						*/
/************************************************************************/

/* command received while drive not ready */
#define	QIC_ERR_NOT_READY	1

/* cartridge not present or removed */
#define	QIC_ERR_NO_CART		2

/* motor speed error (not within 1%) */
#define	QIC_ERR_MOTOR_SPEED	3

/* motor speed fault (jammed, or gross speed error) */
#define	QIC_ERR_MOTOR_FAULT	4

/* cartridge write protected */
#define	QIC_ERR_WPROT		5

/* undefined or reserved command code */
#define	QIC_ERR_BAD_CMD		6

/* illegal track address specified for seek */
#define	QIC_ERR_SEEK_TRK	7

/* illegal command in report subcontext */
#define	QIC_ERR_RPT_CMD		8

/* illegal entry into a diagnostic mode */
#define	QIC_ERR_DIAG_ENTRY	9

/* broken tape detected (based on hole sensor) */
#define	QIC_ERR_BROKEN_TAPE	10

/* warning - read gain setting error */
#define	QIC_ERR_READ_GAIN	11

/* command received while error status pending (obsolete) */
#define	QIC_ERR_ESTAT		12

/* command received while new cartridge pending */
#define	QIC_ERR_NEW_CART	13

/* command illegal or undefined in primary mode */
#define	QIC_ERR_PRI_MODE	14

/* command illegal or undefined in format mode */
#define	QIC_ERR_FMT_MODE	15

/* command illegal or undefined in verify mode */
#define	QIC_ERR_VFY_MODE	16

/* logical forward not at logical BOT in format mode */
#define	QIC_ERR_LOG_FWD		17

/* logical EOT before all segments generated */
#define	QIC_ERR_LOG_EOT		18

/* command illegal when cartridge not referenced */
#define	QIC_ERR_NOT_REF		19

/* self-diagnostic failed (cannot be cleared) */
#define	QIC_ERR_SELF_DX		20

/* warning EEPROM not initialized, defaults set */
#define	QIC_ERR_EE_DFLT		21

/* EEPROM corrupt or hardware failure */
#define	QIC_ERR_EE_BAD		22

/* motion timeout error */
#define	QIC_ERR_MOTION_TO	23

/* data segment too long - logical forward or pause */
#define	QIC_ERR_TOO_LONG	24

/* transmit overrun (obsolete) */
#define	QIC_ERR_XMIT_OVR	25

/* power on reset occurred */
#define	QIC_ERR_POWER_ON	26

/* software reset occurred */
#define	QIC_ERR_SOFT_RST	27

/* diagnostic mode 1 error */
#define	QIC_ERR_DX_1		28

/* diagnostic mode 2 error */
#define	QIC_ERR_DX_2		29

/* command received during noninterruptible process */
#define	QIC_ERR_NON_IRPT	30

/* rate selection error */
#define	QIC_ERR_RATE_SEL	31

/* illegal command while in high speed mode */
#define	QIC_ERR_HIGH_SPD	32

/* illegal seek segment value */
#define	QIC_ERR_SEEK_SEG	33 


/*************************************************************************
 *	Constants for setting data rate at tape drive (QIC_CMD_RATE).
 *	Rates are in bits/second.
 ************************************************************************/

enum {
	FT_DATA_RATE_250K = 0,
	FT_DATA_RATE_500K = 2,
	FT_DATA_RATE_1MEG = 3,
	FT_DATA_RATE_2MEG = 1
};

#if _KERNEL

/* Command timeout values. */

enum {
	FT_CAL_SECS	= 120,	/* max # seconds for seek load point	*/
	FT_PAUSE_SECS	= 15,	/* max # seconds for pause		*/
	FT_XFER_SECS	= 10,	/* max # seconds for read		*/
	FT_RDY_SECS	= 120,	/* max # seconds for drive ready	*/
	FT_SEEK_SECS	= 15,	/* max # seconds for seek head to track	*/
	FT_SKIP_SECS	= 180,	/* max # seconds for skip fwd or back	*/
	FT_STOP_SECS	= 15,	/* max # seconds for tape stop		*/
	FT_WIND_SECS	= 180	/* max # seconds for wind or rewind	*/
};

/* Tape i/o retry limits. */

enum {
	FT_GET_HEADER_TRIES = 5,	/* # of segments we look at for hdr */
	FT_READ_ID_TRIES = 4,		/* # of tries reading FDC sector ID */
	FT_READ_BLK_RETRIES = 2,	/* # of tries reading FDC sector    */
	FT_SKIP_TRIES = 4,		/* # of tries skipping to a segment */
	FT_WRITE_BLK_RETRIES = 2	/* # of tries reading FDC sector    */
};

extern int	FT_BLAB;
extern int	FT_ACKBLAB;

extern int	FT_NBUF;
extern int	FT_CUSHION;

/* The following format enum's are bound to a table in ftCvt.c */

enum {
	FT_Q80_307 = 0,		/* QIC-80, 307.5'	*/
	FT_Q80_205 = 1,		/* QIC-80, 205'		*/
	FT_Q40_307 = 2,		/* QIC-40, 307.5'	*/
	FT_Q40_205 = 3		/* QIC-40, 205'		*/
};

/* Tape motion, as tracked by the driver. */

enum {
	FT_STOPPED,
	FT_MOVING,
	FT_WINDING		/* High speed mode.	*/
};

/* Physical tape coordinates used in QIC-117 commands. */

struct ftTapeLocn	{
	int	ftTLtrack;
	int	ftTLsegment;
	int	ftTLblock;
};

/* Tape segment i/o error tracking. */

#define FT_NUM_ERR_BLK 3	/* Allow 3 blocks with i/o err per segment. */

struct FtSegErr {
	unsigned char	se_errCount;
	unsigned char	se_errBlock [FT_NUM_ERR_BLK];
};

/* Diskette pseudo coordinates used in commands sent to FDC. */

struct ftDiskLocn	{
	unsigned char	ftDLcylinder;	/* "C" */
	unsigned char	ftDLhead;	/* "H" */
	unsigned char	ftDLsector;	/* "R" */
	unsigned char	ftDLsecsize;	/* For debugging - "N"	*/
};

/* Wait result status. */

enum FtWtRslt {
	FT_RESULT_OK		= 0,
	FT_RESULT_TIMED_OUT	= 1,
	FT_RESULT_SIGNALED	= 2
};

/* I/O direction for low-level block transfer routine. */
enum {
	FT_READ = 33,
	FT_WRITE = 34
};

/* Switch for using or ignoring Bad Block Table. */
enum {
	FT_USE_BBT,
	FT_DONT_USE_BBT
};

/* Driver state variables. */

struct FT {
	/* booleans */
	char	ft_wakeMeUp;		/* 1 = sleeping til next FDC IRQ */
	char	ft_ackNeeded;		/* 1 = awaiting ACK to rpt cmd	*/
	char	ft_ackMissed;		/* 1 = wanted ACK, didn't get	*/
	char	ft_ftruMissed;		/* 1 = missed FINAL TRUE BIT	*/
	char	ft_open;		/* 1 = device is open		*/
	char	ft_write;		/* 1 = open for write, 0=read	*/
	char	ft_hdrOk;		/* 1 = header segment read	*/
	char	ft_refOk;		/* 1 = reference burst found	*/
	char	ft_timedOut;		/* 1 = an FDC op timed out.	*/
	char	ft_seekAdj;		/* 1 = have previous seek adj.	*/
	char	ft_norwdcl;		/* 1 = NO rewind on close	*/

	/* very short ints */
	unsigned char	ft_pcn;		/* present cylinder #		*/
	unsigned char	ft_bitsNeeded;	/* # of Report Next Bit's to do	*/
	unsigned char	ft_bitsRcvd;	/* # of report bits received	*/
	unsigned char	ft_drv;		/* drive number, 0..3		*/
	unsigned char	ft_softsel;	/* soft select, 0,1,2		*/
	unsigned char	ft_qicstat;	/* result of QIC 117 status	*/

	/* short ints */
	unsigned short	ft_report;	/* where reported bits go	*/
	unsigned short	ft_errstat;	/* result of QIC 117 err status	*/

	unsigned short ft_firstDataSeg;	/* # of first data segment	*/
	unsigned short ft_lastDataSeg;	/* # of last data segment	*/

	int	ft_segment;		/* First segment in buffer.	*/
	int	ft_numSegs;		/* # of valid segments in buffer. */

	long	ft_lastseek;		/* just past last byte read/written */
	long	ft_segbase;		/* offset in segments for seeks */

	/* other structs */
	TIM	ft_tim;
};

extern struct FT ft;

/* Global ft driver functions. */

/* ft.c */
int		ftBBT		__PROTO ((int segment, unsigned int *bbtValp));
int		ftBufVtop	__PROTO ((__caddr_t vadd, __paddr_t * paddp));
int		ftCmd		__PROTO ((int cmd));
int		ftFwdTape	__PROTO ((void));
int		ftPauseTape	__PROTO ((void));
int		ftReadID	__PROTO ((struct ftDiskLocn * loc));
int		ftReadBlocks	__PROTO ((int logBlock, int numBlocks,
				  caddr_t readBuf));
int		ftReadyWait	__PROTO ((unsigned int seconds));
int		ftRewindTape	__PROTO ((void));
int		ftSeekTape	__PROTO ((int track));
void		ftSelect	__PROTO ((unsigned char drive,
				  unsigned char softsel));
int		ftSkipBack	__PROTO ((int segs));
int		ftSkipFwd	__PROTO ((int segs));
int		ftStopTape	__PROTO ((void));
int		ftStsWthErr	__PROTO ((void));
enum FtWtRslt	ftWaitWithTimeout __PROTO ((int ticks, char * reason));
int		ftWindTape	__PROTO ((void));

/* ftMotion.c */
int		ftMGetMtn	__PROTO ((void));
void		ftMNewTape	__PROTO ((void));
int		ftMPosTape	__PROTO ((int logSeg));
void		ftMSetMtn	__PROTO ((int motion));
void		ftMSetLoc	__PROTO ((struct ftDiskLocn * dl));
void		ftMSetLocB	__PROTO ((int blockno));

/* ftGRB.c */
int		ftGetRefBurst	__PROTO ((void));

/* ftCvt.c */
int		ftCBlocksLeft	__PROTO ((struct ftTapeLocn * tlp));
int		ftCBlksPerVol	__PROTO ((void));
int		ftCDLInc	__PROTO ((struct ftDiskLocn * dlp));
int		ftCDLtoSec	__PROTO ((struct ftDiskLocn * dlp,
		  int * sector));
int		ftCDLtoLS	__PROTO ((struct ftDiskLocn * dlp,
		  int * logicalSeg));
int		ftCLBtoDL	__PROTO ((int logicalBlk,
				  struct ftDiskLocn * dlp));
int		ftCLStoTL	__PROTO ((int logicalSegIn,
		  struct ftTapeLocn * tapeLocOut));
int		ftCSectoTL	__PROTO ((int sector,
		  struct ftTapeLocn * tapeLocOut));
int		ftCvtSetFmt	__PROTO ((int format));
void		ftCvtSetFtParms	__PROTO ((unsigned int spt, unsigned int tracks,
		  unsigned int heads, unsigned int cyls));
void		ftCvtUnsetFmt	__PROTO ((void));

/* ftx.c */

void		ftxIntr		__PROTO ((void));
int		ftXferFDC	__PROTO ((int logBlock, int numBlocks,
  caddr_t ioBuf, struct ftDiskLocn * dlp, int bbtSw, int ioDir, int retry));
void		ftxSetDrive	__PROTO ((unsigned char drive));

/* ecc */

void		initEcc		__PROTO ((void));
int		decodeEcc	__PROTO ((unsigned char * adr,
		  unsigned char nb, unsigned char errc, unsigned char err0,
		  unsigned char err1, unsigned char err2 ));
void		encodeEcc	__PROTO ((unsigned char * adr,
		  unsigned char nb));

#endif /* _KERNEL */

#endif /* __FT_H__ */