1
0
Files
irix-657m-src/irix/kern/sys/tpsc.h
2022-09-29 17:59:04 +03:00

1112 lines
43 KiB
C

/**************************************************************************
* *
* Copyright (C) 1986, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#ident "sys/tpsc.h: $Revision: 3.105 $"
/* This files contains the definitions and data structures specific to
* the SCSI tape drives (currently 1/4 inch cartridge, 8mm videotape,
* 9 track reel, DAT tape).
*/
/* Layout of the INQUIRY data */
/* max inquiry info we accept */
#define MAX_INQUIRY_DATA (sizeof (ct_g0inq_data_t))
#define INQ_PDT_CT 0x01 /* peripheral device type, for tape */
#define MAX_INQ_VID 8 /* # bytes for vendor ID */
#define MAX_INQ_PID 16 /* # bytes for product ID */
#define MAX_INQ_PRL 8 /* # bytes for product revision level */
/* NOTE: you can't enlarge this structure for drives that return more
* data without breaking old binaries since some of their data would
* be overwritten by an MTSCSIINQ ioctl. This structure is used in
* both user programs and in the driver. */
typedef struct {
#ifdef _MIPSEB
u_char id_pqt: 3, /* peripheral qual type */
id_pdt: 5; /* peripheral device type */
u_char id_rmb: 1, /* removable media bit */
id_dtq: 7; /* device type qualifier */
u_char id_iso: 2, /* ISO version */
id_ecma: 3, /* ECMA version */
id_ansi: 3; /* ANSI version */
u_char id_aenc: 1, /* supports async event notification */
id_termiop: 1, /* supports termiop msg */
id_rsv0: 2, /* reserved */
id_respfmt: 4; /* response format */
#else /* _MIPSEL */
u_char id_pdt: 5, /* peripheral device type */
id_pqt: 3; /* peripheral qual type */
u_char id_dtq: 7, /* device type qualifier */
id_rmb: 1; /* removable media bit */
u_char id_ansi: 3, /* ANSI version */
id_ecma: 3, /* ECMA version */
id_iso: 2; /* ISO version */
u_char id_respfmt: 4, /* response format */
id_rsv0: 2, /* reserved */
id_termiop: 1, /* supports termiop msg */
id_aenc: 1; /* supports async event notification */
#endif /* _MIPSEL */
u_char id_ailen; /* additional inquiry length */
u_char id_rsv1; /* reserved */
u_char id_rsv2; /* reserved */
/* next 8 bits valid only if id_respfmt 2 (scsi2) */
#ifdef _MIPSEB
u_char id_reladr: 1, /* supports relative addressing */
id_wide32: 1, /* supports 32 bit wide bus */
id_wide16: 1, /* supports 16 bit wide bus */
id_sync: 1, /* supports sync */
id_linked: 1, /* supports linked cmds */
id_rsv3: 1, /* reserved */
id_cmdq: 1, /* supports command queing */
id_softre: 1; /* supports soft reset */
#else /* _MIPSEL */
u_char id_softre: 1, /* supports soft reset */
id_cmdq: 1, /* supports command queing */
id_rsv3: 1, /* reserved */
id_linked: 1, /* supports linked cmds */
id_sync: 1, /* supports sync */
id_wide16: 1, /* supports 16 bit wide bus */
id_wide32: 1, /* supports 32 bit wide bus */
id_reladr: 1; /* supports relative addressing */
#endif /* _MIPSEL */
u_char id_vid[ MAX_INQ_VID ]; /* vendor ID */
u_char id_pid[ MAX_INQ_PID ]; /* product ID */
u_char id_prl[ MAX_INQ_PRL ]; /* product revision level*/
} ct_g0inq_data_t;
#ifdef _KERNEL
/*
** Layout of the various areas that receive/xmit info.
**
** Layout of the EXTENDED SENSE data
*/
#define MAX_SENSE_DATA (sizeof (ct_g0es_data_t)) /* max sense info */
struct exab_as { /* Exabyte add sense data */
u_char rs0[4]; /* reserved */
u_char as; /* add sense */
u_char aq; /* add sense qualifier */
u_char rs1[2]; /* reserved */
u_char errs[3]; /* recovered errs */
#ifdef _MIPSEB
u_char pf: 1, /* power fail/reset */
bpe: 1, /* bus parity error */
fpe: 1, /* buffer parity error */
me: 1, /* media error (uncorrectable) */
eco: 1, /* error counter (exerrs) overflow */
tme: 1, /* tape motion error */
tnp: 1, /* no tape in drive */
bot: 1; /* at BOT */
u_char xfr: 1, /* disconnect error (while trying to pause transfer) */
tmd: 1, /* error occured during SPACE */
wp: 1, /* write protected */
fmke: 1, /* error while writing FM */
ure: 1, /* data flow underrun from media error */
we1: 1, /* too many retries on write; media error */
sse: 1, /* hardware failure in servo system */
fe: 1; /* hardware failure in data formatter */
u_char rs2: 1, /* reserved */
ucln: 1, /* 8900 cleaning tape used up */
rrr: 1, /* 8900 froced to invoke retries */
clnd: 1, /* tape drive has been cleaned */
cln: 1, /* 8500 tape needs cleaning */
peot: 1, /* tape at physical end of tape */
wseb: 1, /* write splice error, blank tape (hardware) */
wse0: 1; /* write splice error, overshoot (hardware) */
#else /* _MIPSEL */
u_char bot: 1, /* at BOT */
tnp: 1, /* no tape in drive */
tme: 1, /* tape motion error */
eco: 1, /* error counter (exerrs) overflow */
me: 1, /* media error (uncorrectable) */
fpe: 1, /* buffer parity error */
bpe: 1, /* bus parity error */
pf: 1; /* power fail/reset */
u_char fe: 1, /* hardware failure in data formatter */
sse: 1, /* hardware failure in servo system */
we1: 1, /* too many retries on write; media error */
ure: 1, /* data flow underrun from media error */
fmke: 1, /* error while writing FM */
wp: 1, /* write protected */
tmd: 1, /* error occured during SPACE */
xfr: 1; /* disconnect error (while trying to pause transfer) */
u_char wse0: 1, /* write splice error, overshoot (hardware) */
wseb: 1, /* write splice error, blank tape (hardware) */
peot: 1, /* tape at physical end of tape */
cln: 1, /* 8500 tape needs cleaning */
clnd: 1, /* tape drive has been cleaned */
rrr: 1, /* 8900 froced to invoke retries */
ucln: 1, /* 8900 cleaning tape used up */
rs2: 1; /* reserved */
#endif /* _MIPSEL */
u_char rs3; /* reserved */
u_char left[3]; /* remaining tape in 1K blocks to LEOT */
};
struct ciph_as { /* Cipher add sense data */
u_char as; /* add sense */
u_char errs[2]; /* recovered errs */
};
struct viper_as { /* Viper add sense data */
u_char copysrc; /* copy source sense data pointer */
u_char copydst; /* copy destination sense data pointer */
u_char rs0[2]; /* reserved */
u_char errs[2]; /* recovered errs */
u_char copyst; /* copy target status*/
u_char copysns[8]; /* copy target sense data */
};
struct tand_as { /* Tandberg 36[246]0 add sense data */
u_char copysrc; /* copy source sense data pointer */
u_char copydst; /* copy destination sense data pointer */
u_char rs0[2]; /* reserved */
u_char errs[2]; /* recovered errs */
#ifdef _MIPSEB
u_char ercl: 4, ercd: 4; /* err class, and code */
#else /* _MIPSEL */
u_char ercd: 4, ercl: 4; /* err class, and code */
#endif /* _MIPSEL */
u_char exercd; /* extended error code */
u_char blkctr[3]; /* i/o blk cnt since open or space */
u_char fmctr[2]; /* FM cnt since open or space */
u_char underrun[2]; /* underrun cnt since open or space */
u_char margblk; /* marginal blks cnt since open or space */
u_char blksbuf; /* blocks unwritten in buffer after err */
/* up to 20 copy sense bytes follow, but we don't implement COPY */
};
struct kenn_as { /* Kennedy add sense data */
u_char rs0[4]; /* reserved */
u_char as; /* add sense */
u_char aq; /* add sense qualifier */
u_char rs1[2]; /* reserved */
};
struct scsi2_as { /* DAT and other drives in scsi2 mode */
u_char cmdspecific[4]; /* cmd specific; usually used only
for COPY cmd */
u_char as; /* add sense */
u_char aq; /* add sense qualifier */
u_char fru; /* field replaceable unit code (0 non-specific) */
#ifdef _MIPSEB
u_char sksv: 1, /* sense key specific valid */
cd: 1, /* err in cmd if set, otherwise in data out */
rsv: 2, /* reserved */
bpv: 1, /* if 1, bitptr is valid */
bitp: 3; /* if 1, bitptr is valid */
#else /* _MIPSEL */
u_char bitp: 3, /* if 1, bitptr is valid */
bpv: 1, /* if 1, bitptr is valid */
rsv: 2, /* reserved */
cd: 1, /* err in cmd if set, otherwise in data out */
sksv: 1; /* sense key specific valid */
#endif /* _MIPSEL */
u_char sensespecific[2]; /* if sksv, cmd/err specific */
#ifdef _MIPSEB
u_char dltisc: 7, /* DLT internal status code */
dltcln: 1; /* DLT clean me bit */
#else /* _MIPSEL */
u_char dltcln: 1, /* DLT clean me bit */
dltisc: 7; /* DLT internal status code */
#endif /* _MIPSEL */
};
typedef struct
{
#ifdef _MIPSEB
u_char esd_valid: 1, /* valid bit */
esd_errclass: 3, /* error class */
esd_mbz0: 3, /* must be zero */
esd_defer: 1; /* deferred err from prev cmd */
u_char esd_copyseg; /* seg from COPY cmd*/
u_char esd_fm: 1, /* file mark */
esd_eom: 1, /* logical EOM (CT_EW) */
esd_ili: 1, /* illegal length indicator */
esd_reserve: 1, /* unused for now */
esd_sensekey: 4; /* sense key */
#else /* _MIPSEL */
u_char esd_defer: 1, /* deferred err from prev cmd */
esd_mbz0: 3, /* must be zero */
esd_errclass: 3, /* error class */
esd_valid: 1; /* valid bit */
u_char esd_copyseg; /* seg from COPY cmd*/
u_char esd_sensekey: 4, /* sense key */
esd_reserve: 1, /* unused for now */
esd_ili: 1, /* illegal length indicator */
esd_eom: 1, /* logical EOM (CT_EW) */
esd_fm: 1; /* file mark */
#endif /* _MIPSEL */
u_char esd_resid[4]; /* residual length */
u_char esd_aslen; /* additional sense length */
union {
struct exab_as _exab; /* Exabyte */
struct ciph_as _ciph; /* Cipher 540 */
struct tand_as _tand; /* Tandberg 36[246]0 */
struct viper_as _viper; /* Viper 150,60 */
struct kenn_as _kenn; /* Kennedy 96X2 */
struct scsi2_as _rsscsi2; /* SCSI 2 DAT, etc. */
u_char as_extra[56]; /* gives 64 bytes total; this is the
minimum we will return (assuming the device returns that
much) with the MTSCSI_SENSE ioctl */
} asd;
} ct_g0es_data_t;
#define exab asd._exab
#define ciph asd._ciph
#define tand asd._tand
#define viper asd._viper
#define kenn asd._kenn
#define rsscsi2 asd._rsscsi2
/*
** Layout of the INQUIRY data
*/
/* used to set tape type from the inquiry cmd and info from master.d/tpsc.
This allows SGI and users to add new tape drives of known types without
re-compiling the driver. The assumption is that the SCSI commands,
block size, capablities, and request sense info are constant within
a type. This is rarely completely true, but is often close enough
to allow a drive to work.
*/
struct tpsc_types {
u_char tp_type; /* a type from the tape types below, used for
some capability, and some error code decoding */
u_char tp_hinv; /* a type from the TP* tape types in invent.h;
is returned by the MTCAPABILITY ioctl */
u_char tp_vlen; /* length of vendor string */
u_char tp_plen; /* length of product string */
u_char tp_vendor[MAX_INQ_VID]; /* vendor ID */
u_char tp_product[MAX_INQ_PID]; /* product ID */
u_char tp_msl_pglen; /* # of extra bytes transferred on modeselect
(does not include MSD_IND_SIZE). page 0 is only page done
currently, except for the partition stuff for DAT, which
follows SCSI 2 and so should not require any changes. */
u_char *tp_msl_data; /* values to ALWAYS put in msld_vend when
doing a mode select; ptr should be null if tp_msl_pglen is 0 */
u_char tp_density[4]; /* values for 4 possible densities; used
only when MTCAN_SETDEN is true; indexed by DENSITY_DEV() */
uint_t tp_capablity; /* capablities supported */
uint_t tp_xfr_divisor; /* transfer timeout; see XFER_TIMEO
(units are inverse ticks) */
uint_t tp_mintimeo; /* minimum timeout for any
* cmd; see XFER_TIMEO and
* SHORT_TIMEO (units are
* seconds) */
uint_t tp_spacetimeo; /* space cmd timeout; (units
* are in seconds), see
* SPACE_TIMEO() */
uint_t tp_rewtimeo; /* timeout for very long
* operations, like rewind,
* retension, erase; (units
* are in seconds); time is
* doubled for retension. */
uint_t tp_maxtimeo; /* maximum possible timeout
* for those commands
* potentially taking a very
* Very VERY long time,
* e.g. ERASE, SETPOS, etc. */
uint_t tp_dfltblksz; /* default (and often only) block size in
fixed block mode */
uint_t tp_recblksz; /* recommended blocking factor, used only for
MTIOCGETBLKINFO ioctl; note that it is given in bytes,
not as a multipier for the blocksize. */
uint_t tp_dens_count; /* Number of density/compression modes supported
by this device */
char **tp_hwg_dens_names; /* Canonical HWG component names of density/compression
devices */
char **tp_alias_dens_names; /* The alias suffixes of density/compression
devices */
u_char *tp_fpmsg_cdb; /* Template of CDB which
writes a message to
diagnostic display */
u_char tp_fpmsg_cdblen; /* Length of "message" CDB */
u_char tp_fpmsg_data_offset; /* Offset within "message" CDB
where data length is
specified */
u_char tp_fpmsg_datalen; /* Number of bytes required by
data length in "message"
CDB */
u_short tp_noissue_cmdlen; /* number of bytes in tp_noissue_cmd */
u_char *tp_noissue_cmd; /* list of scsi commands that should not be
* issued to the drive; check only if tp_noissue_cmdlen is
* non-zero. notice that this means
* that testuniready (cmd 0) must always be supported; currently
* the largest cmd is LOG_SENSE_CMD The array is checked as:
* if(opcode < ctinfo->tp_noissue_cmdlen &&
* ctinfo->noissue_cmd[opcode])
* errno = ENOSYS; (OLSON: ENOTSUP in 6.2)
* and the command is never issued if the value is
* non-zero. For example, to prevent command 2 from
* being used, you would set the tp_noissue_cmdlen
* field to 3, and the tp_noissue_cmd array would be
* "\0\0\1". description file This is primarily to
* allow 3rd party drives that implement
* "non-essential" commands in an "unexpected way"
* to function. It is not guaranteed that the drive
* will work if "essential" commands are marked this way.
*/
};
/*
** Layout of the MODE SELECT Parameter List
*/
/* maximum amount of mode select info we send */
#define MAX_MODE_SEL_DATA (sizeof (ct_g0msl_data_t))
#define MSD_IND_SIZE 12 /* # bytes in vendor independent mode select (no
page data, just header and block descr) */
#define MSLD_BDLEN 0x08 /* block descriptor cnt */
#define MSLD_BLKCNT_SZ 3 /* number of blocks */
#define MSLD_BLKLEN_SZ 3 /* length of a block */
#define MS_VEND_LEN 136 /* SCSI-2 standard */
typedef struct
{
/* 4 byte header */
u_char msld_mbz0; /* reserved, must be 0 */
u_char msld_mbz1; /* reserved, must be 0 */
#ifdef _MIPSEB
u_char msld_mbz2: 1, /* reserved, must be 0 */
msld_bfm: 3, /* buffered/unbuffered mode */
msld_speed: 4; /* speed */
#else /* _MIPSEL */
u_char msld_speed: 4, /* speed */
msld_bfm: 3, /* buffered/unbuffered mode */
msld_mbz2: 1; /* reserved, must be 0 */
#endif /* _MIPSEL */
u_char msld_bdlen; /* block descriptor length */
/* 8 byte block descr if bdlen is non-zero */
u_char msld_descode; /* density code */
u_char msld_blkcnt[ MSLD_BLKCNT_SZ ]; /* number of blocks */
u_char msld_mbz3; /* reserved, must be 0 */
u_char msld_blklen[ MSLD_BLKLEN_SZ ]; /* block size */
/* page data, including page # and page len */
u_char msld_vend[ MS_VEND_LEN ];
} ct_g0msl_data_t;
/*
** Layout of the MODE SENSE Data
*/
/* maximum amount of mode sense info we accept */
#define MAX_MODE_SENS_DATA (sizeof (ct_g0ms_data_t))
#define MSD_BDLEN 0x08 /* block descriptor length */
#define MSD_BLKCNT_SZ 3 /* number of blocks */
#define MSD_BLKLEN_SZ 3 /* length of a block */
typedef struct
{
/* 4 byte header */
u_char msd_len; /* sense data length */
u_char msd_mtype; /* medium type (0?) */
#ifdef _MIPSEB
u_char msd_wrp: 1, /* write protect */
msd_bfm: 3, /* buffered/nonbuffered mode */
msd_speed: 4; /* speed */
#else /* _MIPSEL */
u_char msd_speed: 4, /* speed */
msd_bfm: 3, /* buffered/nonbuffered mode */
msd_wrp: 1; /* write protect */
#endif /* _MIPSEL */
u_char msd_bdlen; /* block descriptor length */
/* 8 byte block descr if bdlen non-zero */
u_char msd_descode; /* density code */
u_char msd_blkcnt[ MSD_BLKCNT_SZ ]; /* number of blocks */
u_char msd_mbz0; /* reserved, must be 0 */
u_char msd_blklen[ MSD_BLKLEN_SZ ]; /* block size */
/* page data */
u_char msd_vend[MS_VEND_LEN];
} ct_g0ms_data_t;
/*
** Command Descriptor Block for Group 0 commands.
*/
typedef struct
{
u_char g0_opcode; /* group code/command code */
#ifdef _MIPSEB
u_char g0_lu: 3, /* logical unit number */
g0_cmd0: 5; /* command dependent 0 */
#else /* _MIPSEL */
u_char g0_cmd0: 5, /* command dependent 0 */
g0_lu: 3; /* logical unit number */
#endif /* _MIPSEL */
u_char g0_cmd1; /* command dependent 1 */
u_char g0_cmd2; /* command dependent 2 */
u_char g0_cmd3; /* command dependent 3 */
#ifdef _MIPSEB
u_char g0_vu67: 2, /* vendor unique bits 6 and 7 */
g0_mbz0: 4, /* must be zero */
g0_flag: 1, /* flag */
g0_link: 1; /* link */
#else /* _MIPSEL */
u_char g0_link: 1, /* link */
g0_flag: 1, /* flag */
g0_mbz0: 4, /* must be zero */
g0_vu67: 2; /* vendor unique bits 6 and 7 */
#endif /* _MIPSEL */
} ct_g0cdb_t;
/*
** Command Descriptor Block for Group 2 commands.
*/
typedef struct
{
u_char g2_opcode; /* group code/command code */
#ifdef _MIPSEB
u_char g2_lu: 3, /* logical unit number */
g2_cmd0: 5; /* command dependent 0 */
#else /* _MIPSEL */
u_char g2_cmd0: 5, /* command dependent 0 */
g2_lu: 3; /* logical unit number */
#endif /* _MIPSEL */
u_char g2_cmd1; /* command dependent 1 */
u_char g2_cmd2; /* command dependent 2 */
u_char g2_cmd3; /* command dependent 3 */
u_char g2_cmd4; /* command dependent 4 */
u_char g2_cmd5; /* command dependent 5 */
u_char g2_cmd6; /* command dependent 6 */
u_char g2_cmd7; /* command dependent 7 */
#ifdef _MIPSEB
u_char g2_vu67: 2, /* vendor unique bits 6 and 7 */
g2_mbz0: 4, /* must be zero */
g2_flag: 1, /* flag */
g2_link: 1; /* link */
#else /* _MIPSEL */
u_char g2_link: 1, /* link */
g2_flag: 1, /* flag */
g2_mbz0: 4, /* must be zero */
g2_vu67: 2; /* vendor unique bits 6 and 7 */
#endif /* _MIPSEL */
} ct_g2cdb_t;
/*
** Opcodes for Group 0 commands. These opcodes are composed of the
** group code and opcode.
*/
#define TST_UNIT_RDY_CMD 0x00
#define REWIND_CMD 0x01
#define REQ_BLKADDR 0x02
#define REQ_SENSE_CMD 0x03
#define REQ_BLKLIM_CMD 0x05
#define READ_CMD 0x08
#define WRITE_CMD 0x0a
#define SEEKBLK_CMD 0x0c
#define AMPEX_LOCATE_CMD 0x0e
#define WFM_CMD 0x10
#define SPACE_CMD 0x11
#define INQUIRY_CMD 0x12
#define MODE_SEL_CMD 0x15
#define RESERV_UNIT_CMD 0x16
#define REL_UNIT_CMD 0x17
#define ERASE_CMD 0x19
#define MODE_SENS_CMD 0x1a
#define L_UL_CMD 0x1b
#define PREV_MED_REMOV_CMD 0x1e /* not on Kennedy */
#define LOCATEBLK_CMD 0x2b
#define READ_POS_CMD 0x34 /* SCSI 2 (DAT) read position */
#define LOG_SELECT_CMD 0x4C /* SCSI 2 (DAT) set logging params */
#define LOG_SENSE_CMD 0x4D /* SCSI 2 (DAT) get logged info */
/*
** LED controll subfunctions
*/
#define CT_PREV_REMOV 0x01
#define CT_ALLOW_REMOV 0x00
/*
** Space sub-function codes
*/
#define SPACE_BLKS_CODE 0 /* space blocks code */
#define SPACE_FM_CODE 1 /* space filemarks code */
#define SPACE_SFM_CODE 2 /* space sequential filemarks code */
#define SPACE_EOM_CODE 3 /* space to end of recorded media code */
#define SPACE_SETM_CODE 4 /* space setmarks code */
/*
* Load sub-function bits.
*/
#define L_UL_RETENSION 0x02 /* bit to set in the load/unload CDB to do a */
/* retention */
#define L_UL_LOAD 0x01 /* bit to set if you want a load operation */
/*
*
* This structure contains the info for each unit.
* The arrangement of this structure is such that a hex dump is
* elatively easy to interpret, and minimize gaps.
* sub structures must follow an int or ptr, OR have an
* int or ptr as first member OR be part of union that has
* a long if they will be used for DMA, since compiler won't
* force quad alignment otherwise. (marked with DMA in comments)
*/
typedef struct
{
union {
ct_g0cdb_t g0cdb; /* group 0 command descriptor block (DMA) */
ct_g2cdb_t g2cdb; /* group 2 command descriptor block (DMA) */
} ct_cmd;
u_char ct_lastcmd; /* last command issued, except request sense */
u_char ct_openflags; /* flags from current open call */
u_char ct_partnum; /* for partitioned tapes, which partition. */
u_char ct_scsiv; /* scsi1 or scsi2, from inq */
u_char ct_cansync; /* set if scsiv >=2 and id_sync set */
uint ct_sili: 1, /* suppress illegal length error (MTCAN_SILI) */
ct_ilimode:1, /* overlength ILI reporting mode */
ct_buffmmode:1, /* buffered filemark writing mode */
ct_cipherrec: 1, /* cipher 540 report recovered errors */
ct_speed: 1, /* high or low speed if MTCAN_SETSP */
ct_density: 8, /* density value for modesel if MTCAN_SETDEN */
ct_logsense: 1; /* Log sense data on errors */
struct scsi_request *ct_req; /* pointer to allocated request */
struct scsi_target_info *ct_info; /* pointer to info struct */
sema_t ct_sema; /* command complete semaphore */
mutex_t ct_cmdsem; /* ctcmd in progress semaphore */
struct tpsc_types ct_typ; /* a copy of the tpsc_type struct, not
a pointer, because extra code to de-reference really adds up */
buf_t *ct_bp; /* pointer to allocated buf_t */
uint_t ct_state; /* state of the device */
ushort ct_state2; /* state of the device */
uint_t ct_tent_state; /* state of the device; set while performing
* immediate mode commands such as rew, unload, etc. When they
* complete successfully (drive no longer reports BUSY status;
* no abort command issued, etc.), then ct_tent_state is OR'ed
* into state and cleared. */
uint_t ct_recov_err; /* # recoverable errors */
uint_t ct_blksz; /* current blksz in bytes for fixed mode */
uint_t ct_fixblksz; /* blksz in bytes for fixed mode, set only
on first open (from dfltblksz), and by SETFIXED ioctl.
Used when switching between variable and fixed modes */
uint_t ct_cur_minsz; /* min size block drive supports, may be diff
than blkinfo value */
uint_t ct_cur_maxsz; /* max size block drive supports, may be diff
than blkinfo value */
int ct_reqcnt; /* request count in command */
int ct_complete; /* completed count */
uint_t ct_readcnt; /* reads on this tape load (not bytes) */
uint_t ct_writecnt; /* writes on this tape load (not bytes) */
uint_t ct_cblknum; /* block number calculated by tpsc */
uint_t ct_lastreq; /* last device request issued by user */
uint_t ct_extrabusy; /* extra 'delay' because an imm rewind in prog */
uint_t ct_regopens; /* number of "regular" opens (always 0 or 1 ) */
uint_t ct_statopens; /* number of "stat" opens */
ct_g0es_data_t *ct_es_data; /* extended sense info */
union ct_bufarea { /* info that isn't needed across commands */
int resid; /* for ctgetblklen */
ct_g0msl_data_t msl; /* mode select */
ct_g0ms_data_t ms; /* mode sense */
u_char *logdata; /* tmp log data buffer for RDLOG */
u_char posninfo[20]; /* tmp read buffer for READPOSN */
u_char blklenbuf[4]; /* tmp read buffer for GETBLKLEN */
u_char reqblkinfo[6]; /* get block limits */
struct vendor_specific_pos *vpos; /* Pointer to vendor-specific
* position data. */
u_char filler[64]; /* filler for additional page data */
} *ct_bufarea;
struct mtblkinfo blkinfo; /* from mtio.h */
mtscsi_rdlog_t ct_rdlog; /* from mtio.h */
} sa_ct_target_t;
typedef sa_ct_target_t ctinfo_t; /* keep old name for back compat,
but use shorter and more descriptive name */
#define ct_g0cdb ct_cmd.g0cdb
#define ct_g2cdb ct_cmd.g2cdb
#define ct_resid ct_bufarea->resid
#define ct_msl ct_bufarea->msl
#define ct_ms ct_bufarea->ms
#define ct_blklenbuf ct_bufarea->blklenbuf
#define ct_posninfo ct_bufarea->posninfo
#define ct_reqblkinfo ct_bufarea->reqblkinfo
#define ct_logdata ct_bufarea->logdata
#define ct_vpos ct_bufarea->vpos
/*
** Masks for the various bits of the minor device number
** See the use at the SCSIID_DEV(), etc. macros below.
*/
#define TPSCTLR_MSK 0x3ff00 /* mask for host adapter *after* remap */
#define TPSCTLR_SHIFT 8
#define SCSIID_MSK 0x07 /* mask for SCSI ID of target */
#define REWIND_MSK 0x20 /* mask for rewind/norewind bit */
#define SWAP_MSK 0x40 /* mask for swap/noswap bit */
#define VAR_MSK 0x80 /* mask for fixed/variable bit */
#define DENSITY_MSK 0x18 /* mask for density bits */
#define DENSITY_SHIFT 3
#define CT_LUNIT 0 /* only lun 0 supported */
/*
** Macros for convience sake (use tpsc internal version of minor #)
** Rewind devices rewind on close ONLY, unless media changed,
** in which case they rewind on next open also.
*/
#define SCSIID_DEV(dev) (TARG(TLI_INFO(dev)))
#define TPSCTLRID_DEV(dev) (ADAP(TLI_INFO(dev)))
#define ISTPSCREWIND_DEV(dev) (TP_REWIND(TLI_INFO(dev)->tli_prop) == 0)
#define ISSWAP_DEV(dev) (TP_SWAP(TLI_INFO(dev)->tli_prop))
#define ISVAR_DEV(dev) (TP_VAR(TLI_INFO(dev)->tli_prop) && \
(TLI_CTINFO_DEV(dev)->ct_typ.tp_capablity & MTCAN_VAR))
#define DENSITY_DEV(dev) (TP_DENSITY(TLI_INFO(dev)->tli_prop))
#define ISCOMPRESS_DEV(dev) (TP_COMPRESS(TLI_INFO(dev)->tli_prop))
/*
** Flag value passed by ctcmd() to the specific function routine
*/
#define CTCMD_SETUP 0 /* setup to issue cdb */
#define CTCMD_ERROR 1 /* error */
#define CTCMD_NO_ERROR 2 /* no error */
/* The transfer timeout needs to be proportional to the amount of i/o
being done. This is fairly easy for the fixed block devices.
For variable mode, one also needs to take into account the
size of the i/o, but since the max i/o size is much smaller,
this really isn't much of a problem. Loading and rewinding
tapes is more problematical, since we may not know where we
are. Exabyte tapes take a max of 2:15 sec, plus possible load
time of ~15 seconds. On Kennedy, rewind of 2400' tape is
aprox 4 minutes. Space commands are straight forward for
space block, but space filemark is something else. On
Exabyte, space is ~10 times as fast as i/o, so max would
be 20 minutes, while on Kennedy, for a 2400 ft tape, it
would be ~4 minutes. See tp_xfr_divisor and tp_spacetimeo also.
All times should be a bit on the generous side; the xfer
timeout should allow for retries, possible start/stop time,
and for held off reads/writes like the Kennedy will do.
*/
/* rewind, retension, erase, and load/unload timeouts */
#define REWIND_TIMEO (ctinfo->ct_typ.tp_rewtimeo)
/* tpsc_min_delay is for cmds that don't do media i/o,
and min for any i/o. This long because if tape isn't moving
some devices take considerably longer than you would expect;
and we want to be conservative. lbootable so customers can
more easily add non-standard drives.
*/
#define XFER_TIMEO(cnt) max(cnt/ctinfo->ct_typ.tp_xfr_divisor, \
ctinfo->ct_typ.tp_mintimeo)
/* this is only for space FM, and space to EOM; space record uses
* XFER_TIMEO, partly because some QIC drives implement them
* (particularly back spacing) as read and check, which is
* very slow. */
#define SPACE_TIMEO ctinfo->ct_typ.tp_spacetimeo
/* delay time between retries when status BUSY is returned */
#define BUSY_INTERVAL (2*HZ)
#define SHORT_TIMEO ctinfo->ct_typ.tp_mintimeo
#define MAXLONG_TIMEO ctinfo->ct_typ.tp_maxtimeo
#define DST_FMT_TIMEO (10800*HZ)
/* macros for determining drive type */
/*
* The CIPHER 540S drives have a couple of bothers:
* 1) they don't identify themselves through the INQUIRY command
* 2) by default, they report recoverable errors, however they
* do it incorrectly - if one for example is spacing forward
* and encounters a recoverable error, it issues a check-condition
* with the RECERR sense key - but the FILE MARK bit is NOT ON
* so we lose track of where we are.
* To get around this, we set the CIPHER specific SEC bit on
*/
#define IS_CIPHER(ctinfo) (ctinfo->ct_typ.tp_type == CIPHER540)
#define IS_TANDBERG(ctinfo) (ctinfo->ct_typ.tp_type == TANDBERG3660)
/*
* want to know if drive is a viper 150 because it can read 310 oersted
* tapes, but it can't write them.
*/
#define IS_VIPER150(ctinfo) (ctinfo->ct_typ.tp_type == VIPER150)
#define IS_VIPER60(ctinfo) (ctinfo->ct_typ.tp_type == VIPER60)
/* DAT, both DDS1 and DDS2 */
#define IS_DATTAPE(ctinfo) (ctinfo->ct_typ.tp_type == DATTAPE)
/*
** Exabyte uniquenesses:
** 1. does not support the RESERVE UNIT or RELEASE UNIT commands.
** 2. uses 1K blocks in fixed mode.
*/
#define IS_EXABYTE(ctinfo) ((ctinfo->ct_typ.tp_type == EXABYTE8200) || \
(ctinfo->ct_typ.tp_type == EXABYTE8500) || \
(ctinfo->ct_typ.tp_type == EXABYTE8900))
/* Kennedy 9 track drives */
#define IS_KENNEDY(ctinfo) (ctinfo->ct_typ.tp_type == KENNEDY96X2)
/* DLT uniquenesses:
* 1. uses 4k blocks in fixed mode
* 2. compression turned on through device config page of mode select
* 3. density code selected through 'density code' field of mode select.
* (DLT7000 only)
*/
#define IS_DLT(ctinfo) (ctinfo->ct_typ.tp_type == DECDLT)
/* Magstar (IBM 3570 & 3590) uniqueness:
* 1. SCSI load behaves differently with and w/o ACF - do not use load.
* 2. compression turned off through device config page of mode select
* 3. supports 1,8,16,24,... partitions.
*/
#define IS_MGSTR(ctinfo) (ctinfo->ct_typ.tp_type == IBMMGSTRMP || \
ctinfo->ct_typ.tp_type == IBMNTP)
/* STK uniqueness: (3490E style interface)
* 1. Wants BT bit on in ReadPosition and Locate SCSI commands.
* 2. 4781/4791 also has problems with LOAD command.
*/
#define IS_STK90(ctinfo) (ctinfo->ct_typ.tp_type == STK90)
#define IS_STKSD(ctinfo) (ctinfo->ct_typ.tp_type == STKSD)
#define IS_STK4781(ctinfo) (ctinfo->ct_typ.tp_type == STK4781)
#define IS_STK4791(ctinfo) (ctinfo->ct_typ.tp_type == STK4791)
#define IS_STK47XX(ctinfo) (IS_STK4781(ctinfo) || IS_STK4791(ctinfo))
#define IS_STK9840(ctinfo) (ctinfo->ct_typ.tp_type == STK9840)
/* Sony GY-10 drives */
#define IS_GY(ctinfo) (ctinfo->ct_typ.tp_type == SONYGY)
/* EXABYTE 8900 drives */
#define IS_EXA8900(ctinfo) (ctinfo->ct_typ.tp_type == EXABYTE8900)
/* Sony SDX-300, SDX-300C */
#define IS_SONYAIT(ctinfo) (ctinfo->ct_typ.tp_type == SONYAIT)
/* FUJITSU Diana-1, -2 and -3 3480/3490 drives */
#define IS_FUJD1(ctinfo) (ctinfo->ct_typ.tp_type == FUJDIANA1)
#define IS_FUJD2(ctinfo) (ctinfo->ct_typ.tp_type == FUJDIANA2)
#define IS_FUJD3(ctinfo) (ctinfo->ct_typ.tp_type == FUJDIANA3)
#define IS_FUJ3480(ctinfo) (IS_FUJD1(ctinfo) || IS_FUJD2(ctinfo) || IS_FUJD3(ctinfo))
/* Ampex DST/DIS uniqueness:
* 1. XXX - TO BE COMPLETED.
*/
#define IS_DST(ctinfo) (ctinfo->ct_typ.tp_type == AMPEXDST)
/* Philips drives (NCTP and TD3600) */
#define IS_NCTP(ctinfo) (ctinfo->ct_typ.tp_type == PHLSNCTP)
#define IS_TD3600(ctinfo) (ctinfo->ct_typ.tp_type == PHLS3600)
/* Overland Data drives (L490) */
#define IS_OVL490E(ctinfo) (ctinfo->ct_typ.tp_type == OVL490E)
#endif /* _KERNEL */
/* The values for ct_typ.tp_type, not same as hinv types */
#define TPUNKNOWN 0 /* type not known */
#define CIPHER540 1 /* cipher QIC24 */
#define TANDBERG3660 2 /* TANDBERG 3660 QIC150 */
#define VIPER150 3 /* VIPER 150 QIC150 */
#define KENNEDY96X2 4 /* Kennedy 96[16]2 1/2" 9 track */
#define EXABYTE8200 5 /* Exabyte EXB-8200 8mm cartridge tape */
#define VIPER60 6 /* VIPER 60 QIC24 */
#define DATTAPE 7 /* Digital Audio Tape */
#define EXABYTE8500 8 /* Exabyte EXB-8500 8mm cartridge tape */
#define DECDLT 9 /* DEC DLT 2000 */
#define IBMNTP 10 /* IBM Magstar 3590 */
#define STK90 11 /* STK 9490 Timberline */
#define STKSD 12 /* STK SD3 Redwood */
#define SONYGY 13 /* Sony GY-10 (aka Akebono) or GY-2120 */
#define EXABYTE8900 14
#define IBMMGSTRMP 15 /* IBM Magstar MP 3570 */
#define FUJDIANA1 16 /* Fujitsu Diana-1 3480 */
#define FUJDIANA2 17 /* Fujitsu Diana-2 3480/3490 */
#define FUJDIANA3 18 /* Fujitsu Diana-3 3480/3490 */
#define STK4781 19 /* STK 3480 controller */
#define STK4791 20 /* STK 3490 controller */
#define M49914 21 /* M4 Data 9914 9-track tape drive */
#define SONYAIT 22 /* Sony SDX300[C] */
#define AMPEXDST 23 /* Ampex DST/DIS Family */
#define PHLSNCTP 24 /* Philips NTCP */
#define PHLS3600 25 /* Philips TD3600 */
#define OVL490E 26 /* Overland Data L490E */
#define STK9840 27 /* StorageTek 9840 (Eagle) */
/* States for the logical unit (ct_state). states common with
mtio.h as much as possible. Note that for MTIOCGET, the position
bits get put in dposn, the low 16 bits in dsreg, and the upper 16
bits in erreg. These bits are all available to users now, so they
are no longer ifdef _KERNEL.
*/
#define CT_ONL MT_ONL /* drive is online */
#define CT_WRP MT_WPROT /* drive is write-protected */
#define CT_EOM MT_EOT /* drive is at end of media */
#define CT_BOT MT_BOT /* drive is at beginning of media */
#define CT_FM MT_FMK /* drive is at file mark */
#define CT_QIC24 MT_QIC24 /* tape is low density (310 oersted);
only set for Viper 150 drives */
#define CT_QIC120 MT_QIC120 /* tape is high density (550 oersted);
QIC120 15 tracks. */
#define CT_EOD MT_EOD /* at end of data, may also be EOT; sometimes,
in audio mode, we will set this (along with CT_AUD_MED) when
the drive is confused due to incorrect subcodes on the tape,
particularly at the leadin area. If both these bits are set
near BOT, then that is probably the problem. Both may legitimately
be set near EOD, particularly if audio was recorded on top of a
data tape, and doesn't extend past the end of the data portion.
See also CT_INCOMPAT_MEDIA for this case. */
/* beware the bits defined in mtio.h! */
#define CT_EW 0x08 /* hit early warning marker */
#define CT_GETBLKLEN 0x10 /* in the process of determining block
length of data on the tape */
#define CT_MOTION 0x20 /* a command has been performed that
(potentially) moves the tape since last tape change or reset */
#define CT_OPEN 0x200 /* device open; NBLOCK instead for stat dev */
#define CT_READ 0x400 /* opened for reading */
#define CT_WRITE 0x800 /* opened for writing */
#define CT_CHG 0x1000 /* unit attn occurred */
#define CT_DIDIO 0x2000 /* i/o or explictly requested tape movement
commands have been successfully done since open or space/rewind.
Used to handle case where first read after open hits a FM, in which
case we automatically skip over the FM. Driver no longer spaces
to a FM on first tape command after open, since that made mt [bf]sr
relatively worthless, with no way around it except writing a program
that does all the ioctls itself. This gets cleared on any of the
space, rewind, etc. commands, and by certain serious I/O errors. */
#define CT_NEEDBOT 0x10000 /* program needs to position at BOT
before doing any i/o. Set if opening Kennedy for diff
density/mode and not at BOT on open */
#define CT_LOADED 0x20000 /* The tape has been loaded, but is not
necessarily at BOT. */
#define CT_ANSI 0x40000 /* allow i/o after EOT marker for 9 track tapes.
This allows ANSI labels to be used. Works for QIC tapes also.
(see MTANSI in mtio.h) */
#define CT_SMK 0x80000 /* drive is at a setmark. Note that a skip
block or skip fm command will stop if a setmark is encountered. */
#define CT_AUDIO 0x100000 /* Drive is in audio mode; persists until
reset, tape change, or reboot */
#define CT_AUD_MED 0x200000 /* the media in the drive is in audio
format. Set if the drive tells us that we have audio media, or
when we are in audio mode and first write to the tape. Cleared
if we are not in audio mode, and we write to the tape. */
#define CT_MULTPART 0x400000 /* the media in the drive is a multi-
partition tape. Currently only DAT supports this */
#define CT_SEEKING 0x800000 /* a seek or rewind done with the
immediate bit set is still in progress; returned in the mt_erreg
field on MTIOCGET; never set in ct_state itself. Also set during
MTIOCGET if the drive is busy loading or unloading media.
This will currently happen only while in audio mode. */
#define CT_HITFMSHORT 0x1000000 /* in fixed blk mode, we hit a FM,
and returned a short count (not 0); the next read must return 0
(assuming no other intervening tape movement) so program knows a
FM has been reached. Can't happen in variable block mode */
#define CT_INCOMPAT_MEDIA 0x2000000 /* we have successfully read
data in audio mode with audio media, and have now gotten status
from the drive that tells us we have incompatible media. This
doesn't get set if we see incompat media near BOT, or if we aren't
in audio mode. It gets cleared on any tape motion command after it
was set. */
#define CT_CLEANHEADS 0x4000000 /* 8500 needs cleaning */
#define CT_COMPRESS 0x8000000 /* drive is in compression mode */
#define CT_NBLOCK 0x10000000 /* NOT USED: will go away in future */
#define CT_NBLOCKNA 0x20000000 /* NOT USED: will go away in future */
#define CT_MEDIA_ERR 0x40000000 /* a media error has occurred; cleared
on tape motion. */
/* States for the logical unit (ct_state2). */
#define CT_BAD_REQT 0x0001
#define CT_LARGE_BLK 0x0002
#define CT_LOAD_ERR 0x0004
#define CT_HWERR 0x0008
#define CT_NOT_READY 0x0010
#define CT_BLKLEN 0x0020
#define CT_INV_POS 0x0040 /* Ampex DST tape position
not established */
#ifdef _KERNEL
/* tape postion flags cleared on tape motion cmds and tape change */
#define CTPOS (CT_BOT|CT_EOM|CT_FM|CT_SMK|CT_EOD|CT_EW|CT_HITFMSHORT|\
CT_INCOMPAT_MEDIA|CT_MEDIA_ERR|CT_CHG)
/* states that persist across close/open. (if tape changes, etc.
some may be cleared at interrupt time). NBLOCK* is only cleared
excplictly for stat dev opens. */
#define CTKP_B (CTPOS|CT_LOADED|CT_MOTION|CT_ONL|CT_QIC24|CT_QIC120|CT_WRP\
|CT_MULTPART)
#define CTKEEP (CTKP_B|CT_AUDIO|CT_CLEANHEADS|CT_NBLOCK|CT_NBLOCKNA)
/* these states don't persist across a tape change */
#define CHGSTATES (CTKP_B|CT_NEEDBOT|CT_AUD_MED|CT_DIDIO)
/* these states get cleared on a rewind, load, or a space BSF */
#define BACKSTATES (CT_DIDIO|CT_NEEDBOT|CTPOS)
/* Function prototypes needed by various drivers: */
extern int tpsctapetype(ct_g0inq_data_t *, struct tpsc_types *);
void ct_alias_make(vertex_hdl_t, vertex_hdl_t,
struct tpsc_types *);
void ct_alias_make_non_fabric(vertex_hdl_t, vertex_hdl_t,
struct tpsc_types *);
void ct_alias_make_fabric(vertex_hdl_t, vertex_hdl_t,
struct tpsc_types *);
void ct_alias_remove_fabric(vertex_hdl_t);
void ct_alias_remove_non_fabric(vertex_hdl_t);
void ct_alias_remove_lun_ctrl_port(dev_t, uint64_t, int, char *,
int, uint64_t);
void ct_alias_remove_node_edge(dev_t, uint64_t);
void ct_make_fabric_alias(vertex_hdl_t, uint64_t, int, char *,
int, uint64_t, vertex_hdl_t);
extern struct tpsc_types tpsc_generic;
/* names of transition edges of the state machine for the various
* modes in which a tape can be open
*/
#define CT_SM_REWIND "rewind"
#define CT_SM_NOREWIND "norewind"
#define CT_SM_VAR "varblk"
#define CT_SM_FIXED "fixblk"
#define CT_SM_SWAP "swap"
#define CT_SM_NONSWAP "noswap"
#define CT_SM_COMPRESS_DENS_DAT "compress"
#define CT_SM_NORMAL_DENS_DAT "uncompress"
#define CT_SM_SPEED0 "100ips"
#define CT_SM_SPEED1 "50ips"
#define CT_SM_NAME_SEPERATOR ","
/* number of valid values for each of the properties below */
#define NUM_BLKSIZE_MODES(_ttp) (_ttp->tp_capablity & MTCAN_VAR ? 2 : 1)
#define NUM_SPEED_MODES(_ttp) (_ttp->tp_capablity & MTCAN_SETSP ? 2 : 1)
#define NUM_DENSITY_MODES(_ttp) (_ttp->tp_capablity & MTCAN_SETDEN ? MAX_DENSITIES : 1)
#define MAX_DENSITIES 4
#define MAX_STATES MAX_DENSITIES * 32
/* properties associated with a tape
* these are used to define the vertices of the
* state machine
*/
typedef int tape_prop_t;
typedef tape_prop_t ct_sm_state_t;
#define TP_DENSITY_SHIFT 5
#define TP_VAR_SHIFT 4
#define TP_SWAP_SHIFT 3
#define TP_REWIND_SHIFT 2
#define TP_SPEED_SHIFT 1
#define TP_COMPRESS_SHIFT 0
#define TP_DENSITY_MASK (3 << TP_DENSITY_SHIFT)
#define TP_VAR_MASK (1 << TP_VAR_SHIFT)
#define TP_SWAP_MASK (1 << TP_SWAP_SHIFT)
#define TP_REWIND_MASK (1 << TP_REWIND_SHIFT)
#define TP_SPEED_MASK (1 << TP_SPEED_SHIFT)
#define TP_COMPRESS_MASK (1 << TP_COMPRESS_SHIFT)
#define TP_DENSITY(_prop) ((_prop & TP_DENSITY_MASK) >> TP_DENSITY_SHIFT)
#define TP_VAR(_prop) ((_prop & TP_VAR_MASK) >> TP_VAR_SHIFT)
#define TP_SWAP(_prop) ((_prop & TP_SWAP_MASK) >> TP_SWAP_SHIFT)
#define TP_REWIND(_prop) ((_prop & TP_REWIND_MASK) >> TP_REWIND_SHIFT)
#define TP_SPEED(_prop) ((_prop & TP_SPEED_MASK) >> TP_SPEED_SHIFT)
#define TP_COMPRESS(_prop) ((_prop & TP_COMPRESS_MASK) >> TP_COMPRESS_SHIFT)
/* should be used only with bi-cardinal properties */
#define TP_BIT_SET(_prop,_n) (_prop | (1 << _n))
#define TP_BIT_CLR(_prop,_n) (_prop & ~(1 << _n))
#define TP_FLIP_BIT(_prop,_bit,_shift) (_bit(_prop) ? TP_BIT_CLR(_prop,_shift) : TP_BIT_SET(_prop,_shift))
#define TP_DENSITY_SET(_prop,_n) ((_prop & ~TP_DENSITY_MASK) | (_n << TP_DENSITY_SHIFT))
#define STAT_PROP 0xc
#define DEFAULT_STATE 0x
/* info hanging off the tpsc vertex .
* dev passed to entry points of the tpsc
* driver contains the vertex handle to this
* vertex
*/
typedef struct tpsc_local_info {
void *tli_unit_info; /* pointer to the unit info */
char tli_isstat; /* is this a stat device */
struct tpsc_types *tli_ttp; /* pointer to tape spec info */
tape_prop_t tli_prop; /* tape properties */
} tpsc_local_info_t;
#define TPSC_PREFIX "tpsc" /* driver prefix */
#define SCSI_TAPE_TYPE 1 /* scsi unit type = 0 -> disk , 1 -> tape */
#define TAPE_IDENT "ISTAPE" /* 3rd party tape driver label */
#define TPSC_STAT "stat" /* stat device */
#endif /* _KERNEL */
/*
* STK 4781/4791 hi-speed locate support.
*
* Position information returned by the driver is for hi-speed locate. The
* following macros allow the application to derive the information
* required to accomplish a normal SCSI II (on these, mostly, SCSI I devices)
* locate. Alternatively, (probably illegal) hi-speed locate information
* could be constructed.
*/
/*
* High speed locate bit mask: if these bits are set in the block number
* specificed for mt seek (MTSEEK) (ie, LOCATE: see ctseekblk() in atpsc.c),
*/
#define TPSC_STK_HS_BLKMASK 0x7F000000
#define TPSC_STK_LOGBLK(x) ((x) & 0x003FFFFF) /* log blk no */
#define TPSC_STK_FMT(x) ((x) & 0x00C00000) /* media fmt */
/*
* READ POSITION (MTIOCGET struct mtget.mt_blkno) includes tape format
* information. Test with ATPST_STK_FMT(mtget.mt_blkno) & masks below.
*/
#define TPSC_STK_FMT18T 0x00000000 /* 18 track */
#define TPSC_STK_FMT18TEXT 0x00800000 /* 18 track ext */
#define TPSC_STK_FMT36T 0x00400000 /* 36 track */
/*
* Information to be saved between requests.
*/
typedef struct ctsvinfo {
int ct_reqcnt;
int ct_complete;
ushort ct_state2;
} ctsvinfo_t;
#define TPSC_DEFAULT "default" /* default mode vertex of the tape device*/