/* rcsid[]="$Header: isreg.h,v 820.1 86/12/04 19:55:45 root Exp $" */
/* sccsid[]="%W% %Y% %Q% %G%" */

/************************************************************************
*									*
*				Copyright 1984				*
*			VALID LOGIC SYSTEMS INCORPORATED		*
*									*
*	This listing contains confidential proprietary information	*
*	which is not to be disclosed to unauthorized persons without	*
*	written consent of an officer of Valid Logic Systems 		*
*	Incorporated.							*
*									*
*	The copyright notice appearing above is included to provide	*
*	statutory protection in the event of unauthorized or 		*
*	unintentional public disclosure.				*
*									*
************************************************************************/

/*
 * Interphase SMD 2190 / Storager controller
 */

#define IS_2190_NSLAVE	4	/* drives / controller -- SMD 2190 ctlr */
#define IS_STRGR_NSLAVE	2	/* hard drives / controller -- Storager ctlr */
#define IS_MAX_NSLAVE	4	/* hard drives / controller -- maximum */

#define idunit(dev)	(minor(dev) >> 4 & 15)		/* unit # */
#define idpart(dev)	(minor(dev) & 15)		/* partition # */
#define idmkdev(u, p)	(makedev(0, (u) << 4 | (p)))

/*
 * 2190/Storager controller registers.
 */

struct is_device {
	u_char ispb2;		/* iopb address, byte 2 */
	u_char iscsr;		/* command-status register */
	u_char ispb0;		/* iopb address, byte 0 */
	u_char ispb1;		/* iopb address, byte 1 */
	/* Storager only */
#define isintunit ispb2		/* interrupting unit */
#define istprdy ispb1		/* tape ready status */
	/* end Storager only */
};

	/* iscsr command bits */
#define ISCSR_RESET	0x80	/* reset */
#define ISCSR_BUS	0x20	/* word mode dma */
#define ISCSR_CLRI	0x02	/* clear iscsr intr status */
#define ISCSR_GO	0x01	/* go */
#define ISCSR_ZERO	0x00	/* clear multibus interrupt */
	/* Storager only */
#define ISCSR_ABORT	0x40	/* abort command in progress */
#define ISCSR_INTRDIS	0x10	/* disable interrupts for this command */
	/* end Storager only */

	/* iscsr status bits */
#define ISCSR_RDY	0xf0	/* drive ready bits */
#define ISCSR_RDYSHIFT	4	/* shift factor */
#define ISCSR_RDYBIT	(1 << ISCSR_RDYSHIFT)
#define ISCSR_SI	0x04	/* status change interrupt */
#define ISCSR_CI	0x02	/* command completion interrupt */
#define ISCSR_BUSY	0x01	/* controller busy bit */
/*
 * An explanation of bit string encoding:
#ifdef notdef
 * \20 marks the fields as binary
 * \<num> is the bit number in OCTAL.
#else  notdef
 * \20 gives the base (octal 20 = 16 dec, therefore base is hex)
 * \<num> is the bit number in the base (hex here).
#endif notdef
 */
#define ISCSR_BITS	"\20\10DR3\7DR2\6DR1\5DR0\4ERR\3SI\2CI\1BUSY"

	/* Storager only */
#define ISCSR_ERROR	0x08	/* error occured */
	/* isintunit bit mask */
#define ISINTUNIT_BITS	0x07	/* interrupting unit */
	/* istprdy bit mask */
#define ISTPRDY_BITS	0x0f	/* tape drive ready bits */
	/* end Storager only */


	/* 
	 * The iopb (i/o parameter block)
	 * - called is_param for historical reasons 
	 */

struct is_param {
	u_char ip_opt;		/* options */
	u_char ip_cmd;		/* command */
	u_char ip_err;		/* error */
	u_char ip_stat;		/* status */
	u_char ip_head;		/* head select */
#define ip_flavor ip_head	/* controller flavor: 2190 or Storager */
#define ip_tapeopt ip_head	/* Storager only - tape config options */
	u_char ip_drive;	/* drive select */
	u_char ip_cyl0;		/* cylinder select, byte 0 */
	u_char ip_cyl1;		/* cylinder select, byte 1 */
	u_char ip_sec0;		/* sector select, byte 0 */
	u_char ip_sec1;		/* sector select, byte 1 */
#define ip_thead ip_sec0	/* target head select, map command */
	u_char ip_nsec0;	/* sector count, byte 0 */
	u_char ip_nsec1;	/* sector count, byte 1 */
#define ip_tcyl ip_nsec0	/* target cylinder select, map comand */
	u_char ip_buf2;		/* buffer address, byte 2 */
	u_char ip_dma;		/* dma burst size */
#define	ip_tapetimeout ip_dma	/* Storager only - tape time out (10s incr) */
	u_char ip_buf0;		/* buffer address, byte 0 */
	u_char ip_buf1;		/* buffer address, byte 1 */
	u_char ip_ioaddr0;	/* IO address of isdevice, byte 0 */
	u_char ip_ioaddr1;	/* IO address of isdevice, byte 1 */
	u_char ip_reladdr0;	/* relative address, byte 0 */
	u_char ip_reladdr1;	/* relative address, byte 1 */
	u_char ip_pb2;		/* linked iobp address, byte 2 */
	u_char ip_reserved;
	/* Storager only */
#define ip_tpunit ip_reserved	/* tape unit number for copy commands */
	/* end Storager only */
	u_char ip_pb0;		/* linked iobp address, byte 0 */
	u_char ip_pb1;		/* linked iobp address, byte 1 */
};

	/* ip_cmd values */
#define IPCMD_READ	0x81	/* read */
#define IPCMD_WRITE	0x82	/* write */
#define IPCMD_VERIFY	0x83	/* verify */
#define IPCMD_FORMAT	0x84	/* format track */
#define IPCMD_MAP	0x85	/* map track */
#define IPCMD_CONFIG	0x86	/* report configuration */
#define IPCMD_INIT	0x87	/* initialize controller */
#define IPCMD_RESTORE	0x89	/* restore drive head */
#define IPCMD_SEEK	0x8a	/* seek */
#define IPCMD_MOTORCTL	0x8e	/* motor control for ESDI spin-up */
#define IPCMD_RESET	0x8f	/* reset controller */
#define IPCMD_DREAD	0x91	/* direct read */
#define IPCMD_DWRITE	0x92	/* direct write */
#define IPCMD_AREAD	0x93	/* absolute read */
#define IPCMD_NCREAD	0x94	/* non-cached read */
#define IPCMD_BAD	0x00	/* bad command, for isprobe() */
	/* following are Storager only commands */
#define IPCMD_DIAG	0x70	/* run diagnostics */
#define IPCMD_READLONG	0x71	/* read long */
#define IPCMD_WRITELONG	0x72	/* write long */
#define IPCMD_SECTIME	0x73	/* sector time */
#define IPCMD_READHDR	0x74	/* read headers */
#define IPCMD_READUIB	0x77	/* report back uib */
#define IPCMD_DISK2TAPE	0x88	/* disk to tape transfer */
#define IPCMD_REFORMAT	0x8b	/* re-format */
#define IPCMD_FMTSECDAT	0x8c	/* format with sector data */
#define IPCMD_TAPE2DISK	0x8d	/* tape to disk transfer */
#define IPCMD_MOTORCNTL	0x8e	/* motor control (floppy) */
#define IPCMD_MAPBADSEC	0x90	/* map bad sector */
#define IPCMD_READLOG	0x95	/* read logical sector */
#define IPCMD_WRITELOG	0x96	/* write logical sector */
#define IPCMD_VERFYLOG	0x97	/* verify logical sector */
#define IPCMD_RETENTION	0xa0	/* retention tape */
#define IPCMD_READTAPE	0xa1	/* read tape */
#define IPCMD_WRITETAPE	0xa2	/* write tape */
#define IPCMD_VERFYTAPE	0xa3	/* verify tape */
#define IPCMD_ERASETAPE	0xa4	/* erase tape */
#define IPCMD_WRITEFM	0xa5	/* write file mark */
#define IPCMD_TAPESTAT	0xa6	/* report tape status */
#define IPCMD_TAPECONF	0xa7	/* configure tape */
#define IPCMD_REWIND	0xa9	/* rewind tape */
#define IPCMD_READFM	0xaa	/* read file marks */
#define IPCMD_SEEKTAPE	0xab	/* seek tape */
#define IPCMD_PASSTHRU	0xac	/* command pass through */
	/* end Storager only */


	/* ip_opt bits */
#define IPOPT_LINK	0x80	/* linked transaction */
#define IPOPT_RI	0x60	/* relocation mode for next iobp */
#define IPOPT_RISHIFT	5
#define IPOPT_BI	0x10	/* bus bit for next iobp (word dma) */
#define IPOPT_RESERVE	0x80	/* reserve dual ported drive */
#define IPOPT_RB	0x06	/* relocation mode for buffer */
#define IPOPT_RBSHIFT	1
#define IPOPT_BB	0x01	/* bus bit for buffer (word dma) */
	/* relocation modes */
#define IPOPT_REL_ABS	0	/* absolute */
#define IPOPT_REL_REL	1	/* memory sector relative */
	/* for normal operations */
#define IPOPT_NORMAL	(IPOPT_REL_ABS<<IPOPT_RISHIFT | IPOPT_BI \
				| IPOPT_REL_ABS<<IPOPT_RBSHIFT | IPOPT_BB)

	/* ip_stat values */
#define IPSTAT_DONE	0x80	/* done, success */
#define IPSTAT_BUSY	0x81	/* busy */
#define IPSTAT_ERR	0x82	/* done, error */

	/* ip_err bits, if ip_stat == IPSTAT_RDY */
#define IPERR_ECC	0x80	/* error corrected */
#define IPERR_RESEEK	0x40	/* restore and seek done */
#define IPERR_BADDATA	0x10	/* bad data copied */
#define IPERR_RETRY	0x0f	/* number of retries */
#define IPERR_BITS	"\10\10ECC\7RESEEK\5BADDATA"
	/* ip_err, if ip_stat == IPSTAT_ERR */
#define IPERR_MIN	0x01	/* start of valid error codes */
#define IPERR_MAX	0x94	/* last valid error code */

	/* Storager only */
#define IPERR_COPYEOT	0x01	/* end of tape encountered during copy */
#define IPERR_FILEMARK	0x02	/* file mark after this block - not really 
				    an error. */
	/* end Storager only */
#define IPERR_NOTRDY	0x10	/* drive not ready */
#define IPERR_DBADADDR	0x11	/* disk bad address (unit) */
#define IPERR_SEEK	0x12	/* seek error */
	/* Storager only */
#define IPERR_ECCCRC	0x13	/* ecc/crc error - data field */
#define IPERR_BADCMD	0x14	/* invalid command */
#define IPERR_BADCYLNUM	0x15	/* bad cylinder number in iopb */
#define IPERR_BADSECNUM	0x16	/* bad sector number in iopb */
#define IPERR_BUSTIME	0x18	/* bus timeout */
	/* end Storager only */
#define IPERR_NOTSELECT	0x1b	/* drive not selected */
	/* Storager only */
#define IPERR_HDRMARK	0x1c	/* no address mark - header field */
#define IPERR_DATAMARK	0x1d	/* no address mark - data field */
	/* end Storager only */
#define IPERR_FAULT	0x1e	/* drive faulted */
	/* Storager only */
#define IPERR_SURFOVER	0x20	/* disk surface overrun */
#define IPERR_IDSECTOR	0x21	/* ID field error - wrong sector */
#define IPERR_CRC	0x22	/* CRC error - ID field */
	/* end Storager only */
#define IPERR_HARD	0x23	/* uncorrectable data error */
	/* Storager only */
#define IPERR_SECPULSE	0x26	/* missing sector pulse */
#define IPERR_FMTTIME	0x27	/* format timeout */
#define IPERR_NOINDEX	0x28	/* no index pulse found during format */
	/* end Storager only */
#define IPERR_NOSEC	0x29	/* sector not found */
	/* Storager only */
#define IPERR_IDHEAD	0x2a	/* ID field error - wrong head */
	/* end Storager only */
#define IPERR_SEEKTIM	0x2d	/* seek time out */
#define IPERR_NOTCYL	0x2f	/* not on cylinder */
	/* Storager only */
#define IPERR_RESTORTIM	0x30	/* restore timeout */
#define IPERR_UNITINIT	0x40	/* unit not initialized */
#define IPERR_GAPSPEC	0x42	/* gap specification error */
	/* end Storager only */
#define IPERR_DSEEK	0x4b	/* drive reports seek error */
	/* Storager only */
#define IPERR_MAPPEDHDR	0x4c	/* mapped header error */
#define IPERR_SECPERTRK	0x50	/* sectors per track specification error */
#define IPERR_BYTPERSEC	0x51	/* bytes per sector specification error */
#define IPERR_INTERLV	0x52	/* interleave specification error */
#define IPERR_BADHDNUM	0x53	/* invalid head number in iopb */
#define IPERR_PROTTIM	0x60	/* protection timeout */
#define IPERR_MAXCYLNUM	0x61	/* maximum cyl number specification error */
#define IPERR_HDNUM	0x62	/* number of heads specification error */
#define IPERR_STEPPULSE	0x63	/* step pulse specification error */
#define IPERR_RESBYTE	0x64	/* reserved byte specification error */
#define IPERR_RAMODD	0x65	/* ram failure - odd byte */
#define IPERR_RAMEVEN	0x66	/* ram failure - even byte */
#define IPERR_EVENTRAMN	0x67	/* event ram failure */
#define IPERR_PREVRECAL	0x68	/* device not previously recalibrated */
#define IPERR_CTLR	0x69	/* controller error */
#define IPERR_BADSEC	0x6a	/* invalid sector number */
#define IPERR_TIMERFAIL	0x6b	/* timer failure */
#define IPERR_ROMODD	0x6c	/* rom failure - odd byte */
#define IPERR_ROMEVEN	0x6d	/* rom failure - even byte */
#define IPERR_TPNOTSEL	0x80	/* tape drive not selected */
#define IPERR_TPNOTRDY	0x81	/* tape drive not ready */
#define IPERR_TPNOTONL	0x82	/* tape drive not online */
#define IPERR_CARTRIDGE	0x83	/* cartridge not in place */
#define IPERR_BOT	0x84	/* unexpected beginning of tape */
#define IPERR_EOT	0x85	/* unexpected end of tape */
#define IPERR_FM	0x86	/* unexpected file mark */
#define IPERR_UNRCVDATA	0x87	/* unrecoverable data error */
#define IPERR_BLKNOTLOC	0x88	/* block in error not located */
#define IPERR_NODATA	0x89	/* no data detected */
#define IPERR_WRTPROT	0x8a	/* write protected */
#define IPERR_ILLCMD	0x8b	/* illegal command */
#define IPERR_CMDSEQTIM	0x8c	/* command sequence timeout */
#define IPERR_STASEQTIM	0x8d	/* status sequence timeout */
#define IPERR_BLKXFRTIM	0x8e	/* block transfer timeout */
#define IPERR_FMSRCHTIM	0x8f	/* filemark search timeout */
#define IPERR_EXCEPTION	0x90	/* unexpected exception */
#define IPERR_BADTPUNIT	0x91	/* invalid tape unit address */
#define IPERR_RDYTIM	0x92	/* ready timeout */
#define IPERR_TIMSPECIF	0x93	/* tape timeout specification error */
#define IPERR_BLKCNT	0x94	/* invalid block count */

	/* ip_flavor (controller type) */

	/*
	 * Note: I'm not 100% sure that the 2190 actually tells you
	 * what flavor it is reliably.  However, the Storager always does,
	 * so just assume that !Storager implies 2190.
	 */

#define IPFLAVOR_2190		0x39	/* 2190 controller (usually shows up) */
#define IPFLAVOR_STRGR		0x47	/* Storager controller -- Rev. I  */
#define IPFLAVOR_NEWSTRGR	0x58	/* Storager controller -- Rev. II */

	/* ip_tapeopt fields - Storager only */
#define IPTAPEOPT_SI	0x01	/* enable status change interrupts */
#define IPTAPEOPT_DENS	0x02	/* reduced density enable */
#define IPTAPEOPT_UPDAT	0x04	/* update iopb enable */
#define IPTAPEOPT_PARAM	0x08	/* pass parameters to tape drive */
#define IPTAPEOPT_NORMAL (IPTAPEOPT_SI|IPTAPEOPT_UPDAT)	/* normal mode */

	/* Storager only - record returned by IPCMD_TAPESTAT */
struct is_tapestat {
	u_char it_byte1;	/* status byte 1 */
	u_char it_byte0;	/* status byte 0 */
	u_char it_rewrite1;	/* write operations: blocks rewritten byte 1 */
	u_char it_rewrite0;	/* write operations: blocks rewritten byte 0 */
#define it_soft1 it_rewrite1	/* read operations: soft errors byte 1 */
#define it_soft0 it_rewrite0	/* read operations: soft errors byte 0 */
	u_char it_writeunder1;	/* write operations: write underruns byte 1 */
	u_char it_writeunder0;	/* write operations: write underruns byte 0 */
#define it_readunder1 it_rewrite1	/* read: underruns byte 1 */
#define it_readunder0 it_rewrite0	/* read: underruns byte 0 */
};

#define ISTPSTAT0_BITS	"\20\7EX0\6NOCART\5UNSEL\4WPROT\3EOM\2HARDERR\1NL\0FM"
#define ISTPSTAT1_BITS	"\20\7EX1\6ILL\5NODATA\4MARGINAL\3BOM\0RESET"

#define IPBYTE0_EXBYTE0	0x80	/* exception in byte 0 */
#define IPBYTE0_CART	0x40	/* no cartridge in place */
#define IPBYTE0_OFFLINE	0x20	/* drive offline */
#define IPBYTE0_WRTPROT	0x10	/* write protected */

	/* unit initialization block */
struct is_uib {
	u_char iu_nsec;		/* sectors / track */
	u_char iu_nhead;	/* heads / drive */
	u_char iu_secsiz1;	/* bytes / sector, byte 1 */
	u_char iu_secsiz0;	/* bytes / sector, byte 0 */
	u_char iu_gap2;		/* bytes in gap 2 */
	u_char iu_gap1;		/* bytes in gap 1 */
	u_char iu_retry;	/* max retry count */
	u_char iu_il;		/* interleave factor */
	u_char iu_rs;		/* reseek enable */
	u_char iu_ec;		/* error correction enable */
	u_char iu_ih;		/* increment by head enable */
	u_char iu_bd;		/* move bad data enable */
	u_char iu_si;		/* status change interrupt enable */
	u_char iu_2port;	/* dual port drive - 2190 only */
	u_char iu_grpsiz;	/* group size - 2190 only */
	u_char iu_skew;		/* skew factor */
	/* following are all Storager only */
	u_char iu_opoption;	/* operation options */
	u_char iu_motoroff;	/* motor off and head unload */
	u_char iu_gap3;		/* bytes in gap 3 */
	u_char iu_drivedesc;	/* drive descriptor */
	u_char iu_stepwidth;	/* step pulse width */
	u_char iu_stepcontrol;	/* step and motor control */
	u_char iu_stepinter1;	/* step pulse interval, byte 1 */
	u_char iu_stepinter0;	/* step pulse interval, byte 0 */
	u_char iu_seektime;	/* track to track seek time */
	u_char iu_headloadtime;	/* head load time */
	u_char iu_ncyl1;	/* number of cylinders, byte 1 */
	u_char iu_ncyl0;	/* number of cylinders, byte 0 */
	u_char iu_precomp1;	/* write precompensation, byte 1 */
	u_char iu_precomp0;	/* write precompensation, byte 0 */
	u_char iu_redwrite1;	/* reduced write current, byte 1 */
	u_char iu_redwrite0;	/* reduced write current, byte 0 */
};

	/* iu_il bits */
#define IUIL_GRP	0x80	/* group format */
#define IUIL_CE		0x40	/* cache mode */
#define IUIL_IL		0x3f	/* interleave factor */

	/* iu_opoption bits */
#define IUOPT_ZEROLATENCY	0x02	/* zero latency mode */
#define IUOPT_NORMAL		0x05	/* normally update iopb, cache enable */

	/* iu_stepcontrol bits */
#define IUSTEPCNTL_BUFSTEP	0x20	/* drive allows buffered stepping */

	/* iu_drivedesc (drive descriptor) bits for various drive types */
#define IUDDESC_ST506		0x06	/* standard ST506 mode */
#define IUDDESC_ESDI_ADDRMK	0x27	/* ESDI, address mark */
#define IUDDESC_ESDI_SECTPULSE	0x2f	/* ESDI, sector pulse */
#define IUDDESC_ESDI_BYTECLK	0x37	/* ESDI, byte clock */

#ifdef ISERRORLOGGING
/*
 * Handydandies for the logging of disk errors according to Ed & Ross' 
 * criteria of 4/21/1986.
 */
#define IPERR_NCLASSES	3
#define IPERR_CLASS1	0
#define IPERR_CLASS2	1
#define IPERR_CLASS3	2
#endif ISERRORLOGGING
