*BSD News Article 20556


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!munnari.oz.au!constellation!convex!convex!convex!darwin.sura.net!howland.reston.ans.net!noc.near.net!ceylon!genesis!steve2
From: steve2@genesis.nred.ma.us
Newsgroups: comp.os.386bsd.development
Subject: ft dist0.2 part 01/03
Message-ID: <CCtK2x.36z@genesis.nred.ma.us>
Date: 4 Sep 93 07:42:32 GMT
Organization: Genesis Public Access Unix  +1 508 664 0149
Lines: 619

Here is the latest version of my QIC-40/80 tape driver.  While it's
still not as functional as I would like, I wanted to get this to the
masses before my wedding consumes my next few weeks.

See the README file enclosed below for details.

Enjoy!
- Steve Gerakines
steve2@genesis.nred.ma.us

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	README
#	driver
#	driver/fd.c.diff
#	driver/ftape.h
#	driver/ftreg.h
#
echo x - README
sed 's/^X//' >README << 'END-of-README'
XQIC-40/80 floppy tape driver for 386BSD
XSteve Gerakines <steve2@genesis.nred.ma.us>
X08/24/93 v0.2
X
XHere's the latest and greatest version of my floppy tape driver for
X386bsd, along with the basis for a simple QIC-40/80 backup program.
XThere have been significant changes between the last release and this
Xone.  Some highlights are:
X
X	- I/O using read() and write() was abandonded in favor of doing
X	  all I/O using ioctl()'s
X
X	- all I/O is now segment based instead of by sector
X
X	- the segment hunting algorithm has been greatly improved
X
X	- support for different tape lengths and QIC-40 added
X
X	- error correction/badmap support was added
X
X	- streaming I/O seems much more stable
X
XWhat it can't do yet:
X
X	- formatting/verifying is close but still incomplete
X
X	- error correction is functional but is not robust
X
XWhat you need before installing:
X
X	- an accurate timer
X
X	- something to reduce interrupt latency
X
XBoth of these have been provided in the 0.2.3 patchkit and are highly
Xrecommended.
X
X---------------------------------------------------------
X
XThe installation comes with three directories:  qtar, driver, and
Xtools.
X
XDriver Installtion:
X
X1. Place the ft.c and ftreg.h files in your /sys/i386/isa directory.
X
X2. Place the ftape.h file in your /usr/include/sys directory.
X
X3. Apply the patch file fd.c.diff to your existing fd.c file.  This
X   patch is identical to the one in the v0.1 release of the driver,
X   so skip this step if it's already applied.  For example:
X
X 	# cp fd.c.diff /sys/i386/isa
X	# cd /sys/i386/isa
X	# patch < fd.c.diff
X
X   If you're not using the stock 0.1 fd driver, you may have to
X   apply this by hand.  In any case sure that the NFD values in
X   ft.c and fd.c agree.
X
X4. Modify your /sys/i386/conf/files.i386 file to contain:
X
X	i386/isa/ft.c	optional ft device-driver
X
X5. Modify your config file to have lines like this:
X
X	controller fd0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
X	disk	   fd0 at fd0 drive 0
X	disk	   fd1 at fd0 drive 1
X	tape	   ft0 at fd0 drive 2
X
X6. Create the necessary devices.  The rmt* devices specified in the 0.1
X   release should no longer be used with the floppy tape driver.
X
X	% cd /dev
X	% mknod  ft0a b 2 16
X	% mknod rft0a c 9 16
X
X   Where 2 and 9 are the major numbers for the fd driver.  Minor number 16
X   is unit number 2 (minor/8 in fd and ft drivers).
X
X7. Recompile your kernel and reboot.
X
X	% cd /sys/i386/conf
X	% config CONFIG
X	% cd /sys/compile/CONFIG
X	% make clean depend; make
X
X---------------------------------------------------------
X
XTools and qtar:
X
Xqtar is the basis for a QIC-40/80 backup program.  It's command line
Xdriven, very similar to tar.  Once the driver is installed, you should
Xonly have to go to the qtar directory and type "make" to build the
Xprogram.
X
XCurrently the program will only list volumes and give you a table of
Xcontents of a tape.  Some examples of how it's used:
X
X	qtar t 			- list the file set directory
X	qtar tvL -V "foo"	- list the file set directory for volume "foo"
X	qtar -lv		- list the volumes on the current tape
X
XIn the tools directory you'll find a program to read tape segments and
Xwrite them to stdout, and another that tests the segment hunting algorithm.
X
X---------------------------------------------------------
X
XPlease report your problems as well as successes to me at
Xsteve2@genesis.nred.ma.us.  Sending any debugging information along
Xwith your problem is extremely helpful.  I have a Colorado drive, so
XI'm very interested in hearing from other compatible drive owners.
X
XThe current focus of my work is qtar and the error correction stuff.
XI don't expect the driver to have any more radical changes, with the
Xexception of some added functionality.  The internal workings of
Xqtar will definitely undergo some major overhauls, so don't expect
Xtoo much of it for now.
X
XUntil the next release,
X- Steve
Xsteve2@genesis.nred.ma.us
END-of-README
echo c - driver
mkdir driver > /dev/null 2>&1
echo x - driver/fd.c.diff
sed 's/^X//' >driver/fd.c.diff << 'END-of-driver/fd.c.diff'
X*** ../fd.c.tape	Wed Feb 10 18:46:22 1993
X--- fd.c	Sat Jun  5 12:36:22 1993
X***************
X*** 47,67 ****
X  #include "ioctl.h"
X  #include "buf.h"
X  #include "uio.h"
X  #include "i386/isa/isa_device.h"
X  #include "i386/isa/fdreg.h"
X  #include "i386/isa/icu.h"
X  #include "i386/isa/rtc.h"
X  #undef NFD
X  #define NFD 2
X  
X! #define	FDUNIT(s)	((s>>3)&1)
X  #define	FDTYPE(s)	((s)&7)
X  
X  #define b_cylin b_resid
X  #define b_step b_resid
X  #define FDBLK 512
X  #define NUMTYPES 4
X  
X  struct fd_type {
X  	int	sectrac;		/* sectors per track         */
X  	int	secsize;		/* size code for sectors     */
X--- 47,76 ----
X  #include "ioctl.h"
X  #include "buf.h"
X  #include "uio.h"
X  #include "i386/isa/isa_device.h"
X  #include "i386/isa/fdreg.h"
X  #include "i386/isa/icu.h"
X  #include "i386/isa/rtc.h"
X  #undef NFD
X  #define NFD 2
X  
X! #define NFT 1
X! #if NFT > 0
X! extern ftintr(), ftopen(), ftattach();
X! extern int ft_type;
X! enum { FT_NONE, FT_MOUNTAIN, FT_COLORADO };
X! extern int fdc_mode;
X! enum { FDC_TAPE_MODE, FDC_DISK_MODE };
X! #endif
X! 
X! #define	FDUNIT(s)	((s>>3)&3)
X  #define	FDTYPE(s)	((s)&7)
X  
X  #define b_cylin b_resid
X  #define b_step b_resid
X  #define FDBLK 512
X  #define NUMTYPES 4
X  
X  struct fd_type {
X  	int	sectrac;		/* sectors per track         */
X  	int	secsize;		/* size code for sectors     */
X***************
X*** 184,203 ****
X--- 193,220 ----
X  		}
X  
X  		fdt <<= 4;
X  		fd_turnoff(i);
X  		hdr = 1;
X  	}
X  
X  	/* Set transfer to 500kbps */
X  	outb(fdc+fdctl,0);
X  	fd_turnoff(0);
X+ 
X+ #if NFT > 0
X+ 	ftattach(fdc);
X+ 	if (ft_type == FT_COLORADO)
X+ 		printf(", %d: Jumbo tape", i);
X+ 	else if (ft_type == FT_MOUNTAIN)
X+ 		printf(", %d: Summit tape", i);
X+ #endif
X  }
X  
X  int
X  fdsize(dev)
X  dev_t	dev;
X  {
X  	return(0);
X  }
X  
X  /****************************************************************************/
X***************
X*** 315,342 ****
X  	while ((inb(fdc+fdsts) & NE7_RQM) == 0 && i-- > 0);
X  	if (i <= 0) return (-1);
X  	outb(fdc+fddata,x);
X  	return (0);
X  }
X  
X  static fdopenf;
X  /****************************************************************************/
X  /*                           fdopen/fdclose                                 */
X  /****************************************************************************/
X! Fdopen(dev, flags)
X! 	dev_t	dev;
X! 	int	flags;
X  {
X!  	int unit = FDUNIT(minor(dev));
X!  	/*int type = FDTYPE(minor(dev));*/
X  	int s;
X  
X  	fdopenf = 1;
X  	/* check bounds */
X  	if (unit >= NFD) return(ENXIO);
X  	/*if (type >= NUMTYPES) return(ENXIO);*/
X  
X  	/* Set proper disk type, only allow one type */
X  	return 0;
X  }
X  
X  fdclose(dev, flags)
X--- 332,360 ----
X  	while ((inb(fdc+fdsts) & NE7_RQM) == 0 && i-- > 0);
X  	if (i <= 0) return (-1);
X  	outb(fdc+fddata,x);
X  	return (0);
X  }
X  
X  static fdopenf;
X  /****************************************************************************/
X  /*                           fdopen/fdclose                                 */
X  /****************************************************************************/
X! Fdopen(int dev, int flags, int devtype, struct proc *p)
X  {
X! 	int unit = FDUNIT(minor(dev));
X! 	/*int type = FDTYPE(minor(dev));*/
X  	int s;
X  
X+ #if NFT > 0
X+ 	if (unit == NFD) return(ftopen(dev, flags, devtype, p));
X+ #endif
X  	fdopenf = 1;
X  	/* check bounds */
X  	if (unit >= NFD) return(ENXIO);
X  	/*if (type >= NUMTYPES) return(ENXIO);*/
X  
X  	/* Set proper disk type, only allow one type */
X  	return 0;
X  }
X  
X  fdclose(dev, flags)
X***************
X*** 426,445 ****
X--- 444,467 ----
X  /****************************************************************************/
X  /*                                 fdintr                                   */
X  /****************************************************************************/
X  fdintr(unit)
X  {
X  	register struct buf *dp,*bp;
X  	struct buf *dpother;
X  	int read,head,trac,sec,i,s,sectrac,cyl,st0;
X  	unsigned long blknum;
X  	struct fd_type *ft;
X+ 
X+ #if NFT > 0
X+ 	if (fdc_mode == FDC_TAPE_MODE) return(ftintr(unit));
X+ #endif
X  
X  #ifdef FDTEST
X  	printf("state %d, unit %d, dr %d|",fd_state,unit,fd_drive);
X  #endif
X  
X  	if (!fdopenf) return;
X  	dp = &fd_unit[fd_drive].head;
X  	bp = dp->b_actf;
X  	read = bp->b_flags & B_READ;
X   	/*ft = &fd_types[FDTYPE(bp->b_dev)];*/
END-of-driver/fd.c.diff
echo x - driver/ftape.h
sed 's/^X//' >driver/ftape.h << 'END-of-driver/ftape.h'
X/*
X *  Copyright (c) 1993 Steve Gerakines
X *
X *  This is freely redistributable software.  You may do anything you
X *  wish with it, so long as the above notice stays intact.
X *
X *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
X *  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
X *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
X *  DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
X *  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
X *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
X *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
X *  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
X *  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
X *  POSSIBILITY OF SUCH DAMAGE.
X *
X *  ftape.h - floppy tape driver functions
X *  08/07/93 v0.2
X *  Header file that sits in /sys/sys, first revision.  Support for
X *  ioctl functions added.
X */
X
X#ifndef	_FTAPE_H_
X#define	_FTAPE_H_
X
X#ifndef _IOCTL_H_
X#include <sys/ioctl.h>
X#endif
X
X/* Miscellaneous constant values */
X#define QCV_BLKSIZE	1024		/* Size of a block */
X#define QCV_SEGSIZE	32768		/* Size of a segment */
X#define QCV_BLKSEG	32		/* Blocks per segment */
X#define QCV_ECCSIZE	3072		/* Bytes ecc eats */
X#define QCV_ECCBLKS	3		/* Blocks ecc eats */
X#define QCV_NFMT	3		/* Number of tape formats */
X#define QCV_NLEN	5		/* Number of tape lengths */
X#define UCHAR		unsigned char
X#define USHORT		unsigned short
X#define ULONG		unsigned long
X
X/* Segment request structure. */
Xtypedef struct qic_segment {
X	ULONG sg_trk;		/* Track number */
X	ULONG sg_seg;		/* Segment number */
X	ULONG sg_crcmap;	/* Returned bitmap of CRC errors */
X	ULONG sg_badmap;	/* Map of known bad sectors */
X	UCHAR *sg_data;		/* Segment w/bad blocks discarded */
X} QIC_Segment;
X
X/* Tape geometry structure. */
Xtypedef struct tapegeom {
X	int g_fmtno;			/* Format number */
X	int g_lenno;			/* Length number */
X	char g_fmtdesc[16];		/* Format text description */
X	char g_lendesc[16];		/* Length text description */
X	int g_trktape;			/* Number of tracks per tape */
X	int g_segtrk;			/* Number of segments per track */
X	int g_blktrk;			/* Number of blocks per track */
X	int g_fdtrk;			/* Floppy disk tracks */
X	int g_fdside;			/* Floppy disk sectors/side */
X} QIC_Geom;
X
X/* Various ioctl() routines. */
X#define QIOREAD		_IOWR('q', 1, QIC_Segment)	/* Read segment     */
X#define QIOWRITE	_IOW('q', 2, QIC_Segment)	/* Write segment    */
X#define QIOREWIND	_IO('q', 3)			/* Rewind tape      */
X#define QIOBOT		_IO('q', 4)			/* Seek beg of trk  */
X#define QIOEOT		_IO('q', 5)			/* Seek end of trk  */
X#define QIOTRACK	_IOW('q', 6, int)		/* Seek to track    */
X#define QIOSEEKLP	_IO('q', 7)			/* Seek load point  */
X#define QIOFORWARD	_IO('q', 8)			/* Move tape fwd    */
X#define QIOSTOP		_IO('q', 9)			/* Stop tape	    */
X#define QIOPRIMARY	_IO('q', 10)			/* Primary mode     */
X#define QIOFORMAT	_IO('q', 11)			/* Format mode      */
X#define QIOVERIFY	_IO('q', 12)			/* Verify mode      */
X#define QIOWRREF	_IO('q', 13)			/* Write ref burst  */
X#define QIOSTATUS	_IOR('q', 14, int)		/* Get drive status */
X#define QIOCONFIG	_IOR('q', 15, int)		/* Get tape config  */
X#define QIOGEOM		_IOR('q', 16, QIC_Geom)		/* Get geometry	    */
X
X/* QIC drive status bits. */
X#define QS_READY			0x01	/* Drive ready */
X#define QS_ERROR			0x02	/* Error detected */
X#define QS_CART				0x04	/* Tape in drive */
X#define QS_RDONLY			0x08	/* Write protect */
X#define QS_NEWCART			0x10	/* New tape inserted */
X#define QS_FMTOK			0x20	/* Tape is formatted */
X#define QS_BOT				0x40	/* Tape at beginning */
X#define QS_EOT				0x80	/* Tape at end */
X
X/* QIC configuration bits. */
X#define QCF_RTMASK			0x18	/* Rate mask */
X#define QCF_RT250			0x00	/* 250K bps */
X#define QCF_RT2				0x01	/* 2M bps */
X#define QCF_RT500			0x02	/* 500K bps */
X#define QCF_RT1				0x03	/* 1M bps */
X#define QCF_EXTRA			0x40	/* Extra length tape */
X#define QCF_QIC80			0x80	/* QIC-80 detected */
X
X/* QIC tape status bits. */
X#define QTS_FMMASK			0x0f	/* Tape format mask */
X#define QTS_LNMASK			0xf0	/* Tape length mask */
X#define QTS_QIC40			0x01	/* QIC-40 tape */
X#define QTS_QIC80			0x02	/* QIC-80 tape */
X#define QTS_QIC500			0x03	/* QIC-500 tape */
X#define QTS_LEN1			0x10	/* 205 ft/550 Oe */
X#define QTS_LEN2			0x20	/* 307.5 ft/550 Oe */
X#define QTS_LEN3			0x30	/* 295 ft/900 Oe */
X#define QTS_LEN4			0x40	/* 1100 ft/550 Oe */
X#define QTS_LEN5			0x50	/* 1100 ft/900 Oe */
X
X/* Tape header segment structure */
Xtypedef struct qic_header {
X	ULONG qh_sig;		/* Header signature 0x55aa55aa */
X	UCHAR qh_fmtc;		/* Format code */
X	UCHAR qh_unused1;
X	USHORT qh_hseg;		/* Header segment number */
X	USHORT qh_dhseg;	/* Duplicate header segment number */
X	USHORT qh_first;	/* First logical area data segment */
X	USHORT qh_last;		/* Last logical area data segment */
X	UCHAR qh_fmtdate[4];	/* Most recent format date */
X	UCHAR qh_chgdate[4];	/* Most recent tape change date */
X	UCHAR qh_unused2[2];
X	USHORT qh_tstrk;	/* Tape segments per track */
X	UCHAR qh_ttcart;	/* Tape tracks per cartridge */
X	UCHAR qh_mfside;	/* Max floppy sides */
X	UCHAR qh_mftrk;		/* Max floppy tracks */
X	UCHAR qh_mfsect;	/* Max floppy sector */
X	char qh_tname[44];	/* Tape name (ASCII, space filled) */
X	UCHAR qh_namdate[4];	/* Date tape was given a name */
X	USHORT qh_cprseg;	/* Compression map start segment */
X	UCHAR qh_unused3[48];
X	UCHAR qh_refmt;		/* Re-format flag */
X	UCHAR qh_unused4;
X	UCHAR qh_iocount[4];	/* I/O count for life of tape */
X	UCHAR qh_unused5[4];
X	UCHAR qh_ffmtdate[4];	/* Date first formatted */
X	USHORT qh_fmtcount;	/* Number of times formatted */
X	USHORT qh_badsect;	/* Failed sector count */
X	char qh_mfname[44];	/* Manufacturer name if pre-formatted */
X	char qh_mflot[44];	/* Manufacturer lot code */
X	UCHAR qh_unused6[22];
X	ULONG qh_fail[448];	/* Failed sector log */
X	ULONG qh_badmap[6912];	/* Bad sector map */
X} QIC_Header;
X
X/* Volume table of contents entry structure. */
Xtypedef struct qic_vtbl {
X	UCHAR vt_sig[4];	/* Signature "VTBL" if entry used */
X	USHORT vt_first;	/* Starting segment */
X	USHORT vt_last;		/* Ending segment */
X	char vt_vname[44];	/* Set name */
X	UCHAR vt_savdate[4];	/* Date saved */
X	UCHAR vt_flags;		/* Volume flags */
X	UCHAR vt_multi;		/* Multi cartidge sequence no. */
X	UCHAR vt_vext[26];	/* Extension data */
X	char vt_passwd[8];	/* Password for volume */
X	UCHAR vt_dirsize[4];	/* Directory section size */
X	UCHAR vt_dtasize[4];	/* Data section size */
X	USHORT vt_osver;	/* Operating System version */
X	char vt_label[16];	/* Source drive label */
X	UCHAR vt_ldev;		/* Logical device origin */
X	UCHAR vt_pdev;		/* Physical device origin */
X	UCHAR vt_cprtype;	/* Compression type */
X	UCHAR vt_ostype;	/* Operating System type */
X	UCHAR vt_ostype2;	/* Always zero ?? */
X	UCHAR vt_isocpr;	/* ISO compression type */
X	UCHAR vt_unused1[4];
X} QIC_VTbl;
X
X/* Data compression map structure. */
Xtypedef struct qic_dcmap {
X	UCHAR dc_sig[4];	/* Siguature "DCMS" */
X	USHORT dc_mlen;		/* Total map length */
X	UCHAR dc_unused1[6];
X	ULONG dc_offset[7421];	/* Byte offsets to segments */
X} QIC_DCMap;
X
X/* System specific file set structures - Unix */
Xtypedef struct qic_unix_set {
X	UCHAR fsu_perm;		/* Permissions */
X	UCHAR fsu_attr2;	/* More attributes */
X	UCHAR fsu_ctime[4];	/* Creation time */
X	UCHAR fsu_atime[4];	/* Last access time */
X	UCHAR fsu_inode[4];	/* i-node number */
X	UCHAR fsu_user[4];	/* User number */
X	UCHAR fsu_group[4];	/* Group number */
X	UCHAR fsu_major;	/* Major device number */
X	UCHAR fsu_minor;	/* Minor device number */
X	UCHAR fsu_nsize;	/* Name size */
X	UCHAR fsu_name;		/* Entry name starts here */
X} QIC_Unix_Set;
X
X/* File set structure */
Xtypedef struct qic_fileset {
X	UCHAR fs_size;		/* Size of fixed + system size - 1 */
X	UCHAR fs_attr;		/* Attributes */
X	UCHAR fs_mtime;		/* Modification time */
X	UCHAR fs_dsize[4];	/* Data size */
X} QIC_FileSet;
X
X#endif	/* _FTAPE_H_ */
END-of-driver/ftape.h
echo x - driver/ftreg.h
sed 's/^X//' >driver/ftreg.h << 'END-of-driver/ftreg.h'
X/*
X *  Copyright (c) 1993 Steve Gerakines
X *
X *  This is freely redistributable software.  You may do anything you
X *  wish with it, so long as the above notice stays intact.
X *
X *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
X *  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
X *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
X *  DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
X *  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
X *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
X *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
X *  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
X *  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
X *  POSSIBILITY OF SUCH DAMAGE.
X *
X *  ftreg.h - floppy tape driver
X *
X *  08/07/93 v0.2 release
X *  Things that should've been here in the first place were moved.
X *  Tape geometry and segment request types were added.
X *
X *  06/03/93 v0.1 Alpha release
X *  Base release.  Many more things should be moved here.
X */
X
X/* QIC-117 command set. */
X#define QC_RESET			1	/* reset */
X#define QC_NEXTBIT			2	/* report next bit */
X#define QC_PAUSE			3	/* pause */
X#define QC_STPAUSE			4	/* step pause */
X#define QC_TIMEOUT			5	/* alt timeout */
X#define QC_STATUS			6	/* report status */
X#define QC_ERRCODE			7	/* report error code */
X#define QC_CONFIG			8	/* report config */
X#define QC_VERSION			9	/* report version */
X#define QC_FORWARD			10	/* logical forward */
X#define QC_SEEKSTART			11	/* seek to track start */
X#define QC_SEEKEND			12	/* seek to track end */
X#define QC_SEEKTRACK			13	/* seek head to track */
X#define QC_SEEKLOAD			14	/* seek load point */
X#define QC_FORMAT			15	/* format mode */
X#define QC_WRITEREF			16	/* write reference */
X#define QC_VERIFY			17	/* verify mode */
X#define QC_STOP				18	/* stop tape */
X#define QC_STEPUP			21	/* step head up */
X#define QC_STEPDOWN			22	/* step head down */
X#define QC_SEEKREV			25	/* seek reverse */
X#define QC_SEEKFWD			26	/* seek forward */
X#define QC_RATE				27	/* select data rate */
X#define QC_DIAG1			28	/* diagnostic mode 1 */
X#define QC_DIAG2			29	/* diagnostic mode 2 */
X#define QC_PRIMARY			30	/* primary mode */
X#define QC_VENDORID			32	/* vendor id */
X#define QC_TSTATUS			33	/* report tape status */
X#define QC_EXTREV			34	/* extended skip reverse */
X#define QC_EXTFWD			35	/* extended skip forward */
X
X/* Colorado enable/disable. */
X#define QC_COL_ENABLE1			46	/* enable */
X#define QC_COL_ENABLE2			2	/* null-op */
X#define QC_COL_DISABLE			47	/* disable */
X
X/* Mountain enable/disable. */
X#define QC_MTN_ENABLE1			23	/* enable 1 */
X#define QC_MTN_ENABLE2			20	/* enable 2 */
X#define QC_MTN_DISABLE			24	/* disable */
X
X/* Segment I/O request. */
Xtypedef struct segq {
X	unsigned char buff[QCV_SEGSIZE];/* Segment data; first for alignment */
X	int reqtype;			/* Request type */
X	long reqcrc;			/* CRC Errors found */
X	long reqbad;			/* Bad sector map */
X	long reqblk;			/* Block request starts at */
X	int reqcan;			/* Cancel read-ahead */
X} SegReq;
END-of-driver/ftreg.h
exit