Files
mtx/mtx-1.3.12/mtx.h

632 lines
18 KiB
C

/* MTX -- SCSI Tape Attached Medium Control Program
Copyright 1997-1998 Leonard N. Zubkoff <lnz@dandelion.com>
Changes 1999 Eric Lee Green to add support for multi-drive tape changers.
Copyright 2007-2008 by Robert Nelson <robertn@the-nelsons.org>
$Date: 2008-08-19 03:03:38 -0700 (Tue, 19 Aug 2008) $
$Revision: 193 $
See mtx.c for licensing information.
*/
#ifndef MTX_H /* protect against multiple includes... */
#define MTX_H 1
/* surround all the Unix-stuff w/ifndef VMS */
#ifdef VMS
#include "[.vms]defs.h"
#else /* all the Unix stuff: */
#ifdef _MSC_VER
#include "msvc/config.h" /* all the autoconf stuff. */
#else
#include "config.h" /* all the autoconf stuff. */
#endif
/* all the general Unix includes: */
#include <stdio.h>
#include <errno.h>
#if HAVE_STDLIB_H
# include <stdlib.h>
#endif
#if HAVE_FCNTL_H
# include <fcntl.h>
#endif
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#if HAVE_STDARG_H
# include <stdarg.h>
#endif
#if HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#if HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#if HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
/* Now greatly modified to use GNU Autoconf stuff: */
/* If we use the 'sg' interface, like Linux, do this: */
#if HAVE_SCSI_SG_H
# include <scsi/scsi.h>
# include <scsi/scsi_ioctl.h>
# include <scsi/sg.h>
typedef int DEVICE_TYPE; /* the sg interface uses this. */
# define HAVE_GET_ID_LUN 1 /* signal that we have it... */
#endif
/* Windows Native programs built using MinGW */
#if HAVE_DDK_NTDDSCSI_H
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <ddk/ntddscsi.h>
# undef DEVICE_TYPE
typedef int DEVICE_TYPE;
#endif
/* Windows Native programs built using Microsoft Visual C */
#ifdef _MSC_VER
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <winioctl.h>
# include <ntddscsi.h>
# undef DEVICE_TYPE
typedef int DEVICE_TYPE;
#endif
/* The 'cam' interface, like FreeBSD: */
#if HAVE_CAMLIB_H
# include <camlib.h> /* easy (?) access to the CAM user library. */
# include <cam/cam_ccb.h>
# include <cam/scsi/scsi_message.h> /* sigh sigh sigh! */
typedef struct cam_device *DEVICE_TYPE;
#endif
/* the 'uscsi' interface, as used on Solaris: */
#if HAVE_SYS_SCSI_IMPL_USCSI_H
#include <sys/scsi/impl/uscsi.h>
typedef int DEVICE_TYPE;
#endif
/* the scsi_ctl interface, as used on HP/UX: */
#if HAVE_SYS_SCSI_CTL_H
# include <sys/wsio.h>
# include <sys/spinlock.h>
# include <sys/scsi.h>
# include <sys/scsi_ctl.h>
typedef int DEVICE_TYPE;
# ifndef VERSION
# define VERSION "1.2.12 hbb"
# endif
#endif
/* the 'gsc' interface, as used on AIX: */
#if HAVE_SYS_GSCDDS_H
# include <sys/gscdds.h>
typedef int DEVICE_TYPE;
#endif
/* the 'dslib' interface, as used on SGI. */
#if HAVE_DSLIB_H
#include <dslib.h>
typedef dsreq_t *DEVICE_TYPE; /* 64-bit pointers/32bit int on later sgi? */
#endif
#if ((defined(__alpha) && defined(__osf__)) || \
defined(ultrix) || defined(__ultrix))
#include "du/defs.h"
#endif
#endif /* VMS protect. */
/* Do a test for LITTLE_ENDIAN_BITFIELDS. Use WORDS_BIGENDIAN as set
* by configure:
*/
#if WORDS_BIGENDIAN
# define BIG_ENDIAN_BITFIELDS
#else
# define LITTLE_ENDIAN_BITFIELDS
#endif
/* Get rid of some Hocky Pux defines: */
#ifdef S_NO_SENSE
#undef S_NO_SENSE
#endif
#ifdef S_RECOVERED_ERROR
#undef S_RECOVERED_ERROR
#endif
#ifdef S_NOT_READY
#undef S_NOT_READY
#endif
#ifdef S_MEDIUM_ERROR
#undef S_MEDIUM_ERROR
#endif
#ifdef S_HARDWARE_ERROR
#undef S_HARDWARE_ERROR
#endif
#ifdef S_UNIT_ATTENTION
#undef S_UNIT_ATTENTION
#endif
#ifdef S_BLANK_CHECK
#undef S_BLANK_CHECK
#endif
#ifdef S_VOLUME_OVERFLOW
#undef S_VOLUME_OVERFLOW
#endif
/* Note: These are only used for defaults for when we don't have
* the element assignment mode page to tell us real amount...
*/
#define MAX_STORAGE_ELEMENTS 64 /* for the BIG jukeboxes! */
#define MAX_TRANSFER_ELEMENTS 2 /* we just do dual-drive for now :-} */
#define MAX_TRANSPORT_ELEMENTS 1 /* we just do one arm for now... */
#define MTX_ELEMENTSTATUS_ORIGINAL 0
#define MTX_ELEMENTSTATUS_READALL 1
/* These are flags used for the READ_ELEMENT_STATUS and MOVE_MEDIUM
* commands:
*/
typedef struct SCSI_Flags_Struct
{
unsigned char eepos;
unsigned char invert;
unsigned char no_attached; /* ignore _attached bit */
unsigned char no_barcodes; /* don't try to get barcodes. */
int numbytes;
int elementtype;
int numelements;
int attached;
int has_barcodes;
int querytype; //MTX_ELEMENTSTATUS
unsigned char invert2; /* used for EXCHANGE command, sigh. */
int absolute_addressing; /* indicates that asolute addresses are required */
} SCSI_Flags_T;
#ifdef _MSC_VER
typedef unsigned char boolean;
#define false 0
#define true 1
typedef unsigned char Direction_T;
#define Input 0
#define Output 1
#else
typedef enum { false, true } boolean;
typedef enum { Input, Output } Direction_T;
#endif
typedef unsigned char CDB_T[12];
typedef struct Inquiry
{
#ifdef LITTLE_ENDIAN_BITFIELDS
unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */
unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */
unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */
boolean RMB:1; /* Byte 1 Bit 7 */
unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */
unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */
unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */
unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */
unsigned char :2; /* Byte 3 Bits 4-5 */
boolean TrmIOP:1; /* Byte 3 Bit 6 */
boolean AENC:1; /* Byte 3 Bit 7 */
#else
unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */
unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */
boolean RMB:1; /* Byte 1 Bit 7 */
unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */
unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */
unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */
unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */
boolean AENC:1; /* Byte 3 Bit 7 */
boolean TrmIOP:1; /* Byte 3 Bit 6 */
unsigned char :2; /* Byte 3 Bits 4-5 */
unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */
#endif
unsigned char AdditionalLength; /* Byte 4 */
unsigned char :8; /* Byte 5 */
#ifdef LITTLE_ENDIAN_BITFIELDS
boolean ADDR16:1; /* Byte 6 bit 0 */
boolean Obs6_1:1; /* Byte 6 bit 1 */
boolean Obs6_2:1; /* obsolete */ /* Byte 6 bit 2 */
boolean MChngr:1; /* Media Changer */ /* Byte 6 bit 3 */
boolean MultiP:1; /* Byte 6 bit 4 */
boolean VS:1; /* Byte 6 bit 5 */
boolean EncServ:1; /* Byte 6 bit 6 */
boolean BQue:1; /* Byte 6 bit 7 */
#else
boolean BQue:1; /* Byte 6 bit 7 */
boolean EncServ:1; /* Byte 6 bit 6 */
boolean VS:1; /* Byte 6 bit 5 */
boolean MultiP:1; /* Byte 6 bit 4 */
boolean MChngr:1; /* Media Changer */ /* Byte 6 bit 3 */
boolean Obs6_2:1; /* obsolete */ /* Byte 6 bit 2 */
boolean Obs6_1:1; /* Byte 6 bit 1 */
boolean ADDR16:1; /* Byte 6 bit 0 */
#endif
#ifdef LITTLE_ENDIAN_BITFIELDS
boolean SftRe:1; /* Byte 7 Bit 0 */
boolean CmdQue:1; /* Byte 7 Bit 1 */
boolean :1; /* Byte 7 Bit 2 */
boolean Linked:1; /* Byte 7 Bit 3 */
boolean Sync:1; /* Byte 7 Bit 4 */
boolean WBus16:1; /* Byte 7 Bit 5 */
boolean WBus32:1; /* Byte 7 Bit 6 */
boolean RelAdr:1; /* Byte 7 Bit 7 */
#else
boolean RelAdr:1; /* Byte 7 Bit 7 */
boolean WBus32:1; /* Byte 7 Bit 6 */
boolean WBus16:1; /* Byte 7 Bit 5 */
boolean Sync:1; /* Byte 7 Bit 4 */
boolean Linked:1; /* Byte 7 Bit 3 */
boolean :1; /* Byte 7 Bit 2 */
boolean CmdQue:1; /* Byte 7 Bit 1 */
boolean SftRe:1; /* Byte 7 Bit 0 */
#endif
unsigned char VendorIdentification[8]; /* Bytes 8-15 */
unsigned char ProductIdentification[16]; /* Bytes 16-31 */
unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */
unsigned char FullProductRevisionLevel[19]; /* bytes 36-54 */
unsigned char VendorFlags; /* byte 55 */
}
Inquiry_T;
typedef struct InquiryShort
{
unsigned char pad[2];
unsigned char VendorIdentification[8]; /* Bytes 8-15 */
unsigned char ProductIdentification[16]; /* Bytes 16-31 */
unsigned char SerialNumber[12]; /* Bytes 32-43 */
}
InquiryShort_T;
/* Hockey Pux may define these. If so, *UN*define them. */
#ifdef ILI
#undef ILI
#endif
#ifdef EOM
#undef EOM
#endif
typedef struct RequestSense
{
#ifdef LITTLE_ENDIAN_BITFIELDS
unsigned char ErrorCode:7; /* Byte 0 Bits 0-6 */
boolean Valid:1; /* Byte 0 Bit 7 */
#else
boolean Valid:1; /* Byte 0 Bit 7 */
unsigned char ErrorCode:7; /* Byte 0 Bits 0-6 */
#endif
unsigned char SegmentNumber; /* Byte 1 */
#ifdef LITTLE_ENDIAN_BITFIELDS
unsigned char SenseKey:4; /* Byte 2 Bits 0-3 */
unsigned char :1; /* Byte 2 Bit 4 */
boolean ILI:1; /* Byte 2 Bit 5 */
boolean EOM:1; /* Byte 2 Bit 6 */
boolean Filemark:1; /* Byte 2 Bit 7 */
#else
boolean Filemark:1; /* Byte 2 Bit 7 */
boolean EOM:1; /* Byte 2 Bit 6 */
boolean ILI:1; /* Byte 2 Bit 5 */
unsigned char :1; /* Byte 2 Bit 4 */
unsigned char SenseKey:4; /* Byte 2 Bits 0-3 */
#endif
unsigned char Information[4]; /* Bytes 3-6 */
unsigned char AdditionalSenseLength; /* Byte 7 */
unsigned char CommandSpecificInformation[4]; /* Bytes 8-11 */
unsigned char AdditionalSenseCode; /* Byte 12 */
unsigned char AdditionalSenseCodeQualifier; /* Byte 13 */
unsigned char :8; /* Byte 14 */
#ifdef LITTLE_ENDIAN_BITFIELDS
unsigned char BitPointer:3; /* Byte 15 */
boolean BPV:1;
unsigned char :2;
boolean CommandData :1;
boolean SKSV:1;
#else
boolean SKSV:1;
boolean CommandData :1;
unsigned char :2;
boolean BPV:1;
unsigned char BitPointer:3; /* Byte 15 */
#endif
unsigned char FieldData[2]; /* Byte 16,17 */
}
RequestSense_T;
/* Okay, now for the element status mode sense page (0x1d): */
typedef struct ElementModeSensePageHeader {
unsigned char PageCode; /* byte 0 */
unsigned char ParameterLengthList; /* byte 1; */
unsigned char MediumTransportStartHi; /* byte 2,3 */
unsigned char MediumTransportStartLo;
unsigned char NumMediumTransportHi; /* byte 4,5 */
unsigned char NumMediumTransportLo; /* byte 4,5 */
unsigned char StorageStartHi; /* byte 6,7 */
unsigned char StorageStartLo; /* byte 6,7 */
unsigned char NumStorageHi; /* byte 8,9 */
unsigned char NumStorageLo; /* byte 8,9 */
unsigned char ImportExportStartHi; /* byte 10,11 */
unsigned char ImportExportStartLo; /* byte 10,11 */
unsigned char NumImportExportHi; /* byte 12,13 */
unsigned char NumImportExportLo; /* byte 12,13 */
unsigned char DataTransferStartHi; /* byte 14,15 */
unsigned char DataTransferStartLo; /* byte 14,15 */
unsigned char NumDataTransferHi; /* byte 16,17 */
unsigned char NumDataTransferLo; /* byte 16,17 */
unsigned char Reserved1; /* byte 18, 19 */
unsigned char Reserved2; /* byte 18, 19 */
} ElementModeSensePage_T;
typedef struct ElementModeSenseHeader {
int MaxReadElementStatusData; /* 'nuff for all of below. */
int NumElements; /* total # of elements. */
int MediumTransportStart;
int NumMediumTransport;
int StorageStart;
int NumStorage;
int ImportExportStart;
int NumImportExport;
int DataTransferStart;
int NumDataTransfer;
} ElementModeSense_T;
#ifdef _MSC_VER
typedef char ElementTypeCode_T;
#define AllElementTypes 0
#define MediumTransportElement 1
#define StorageElement 2
#define ImportExportElement 3
#define DataTransferElement 4
#else
typedef enum ElementTypeCode
{
AllElementTypes = 0,
MediumTransportElement = 1,
StorageElement = 2,
ImportExportElement = 3,
DataTransferElement = 4
}
ElementTypeCode_T;
#endif
typedef struct ElementStatusDataHeader
{
unsigned char FirstElementAddressReported[2]; /* Bytes 0-1 */
unsigned char NumberOfElementsAvailable[2]; /* Bytes 2-3 */
unsigned char :8; /* Byte 4 */
unsigned char ByteCountOfReportAvailable[3]; /* Bytes 5-7 */
}
ElementStatusDataHeader_T;
typedef struct ElementStatusPage
{
ElementTypeCode_T ElementTypeCode:8; /* Byte 0 */
#ifdef LITTLE_ENDIAN_BITFIELDS
unsigned char :6; /* Byte 1 Bits 0-5 */
boolean AVolTag:1; /* Byte 1 Bit 6 */
boolean PVolTag:1; /* Byte 1 Bit 7 */
#else
boolean PVolTag:1; /* Byte 1 Bit 7 */
boolean AVolTag:1; /* Byte 1 Bit 6 */
unsigned char :6; /* Byte 1 Bits 0-5 */
#endif
unsigned char ElementDescriptorLength[2]; /* Bytes 2-3 */
unsigned char :8; /* Byte 4 */
unsigned char ByteCountOfDescriptorDataAvailable[3]; /* Bytes 5-7 */
}
ElementStatusPage_T;
typedef struct Element2StatusPage
{
ElementTypeCode_T ElementTypeCode:8; /* Byte 0 */
unsigned char VolBits ; /* byte 1 */
#define E2_PVOLTAG 0x80
#define E2_AVOLTAG 0x40
unsigned char ElementDescriptorLength[2]; /* Bytes 2-3 */
unsigned char :8; /* Byte 4 */
unsigned char ByteCountOfDescriptorDataAvailable[3]; /* Bytes 5-7 */
}
Element2StatusPage_T;
typedef struct TransportElementDescriptorShort
{
unsigned char ElementAddress[2]; /* Bytes 0-1 */
#ifdef LITTLE_ENDIAN_BITFIELDS
boolean Full:1; /* Byte 2 Bit 0 */
unsigned char :1; /* Byte 2 Bit 1 */
boolean Except:1; /* Byte 2 Bit 2 */
unsigned char :5; /* Byte 2 Bits 3-7 */
#else
unsigned char :5; /* Byte 2 Bits 3-7 */
boolean Except:1; /* Byte 2 Bit 2 */
unsigned char :1; /* Byte 2 Bit 1 */
boolean Full:1; /* Byte 2 Bit 0 */
#endif
unsigned char :8; /* Byte 3 */
unsigned char AdditionalSenseCode; /* Byte 4 */
unsigned char AdditionalSenseCodeQualifier; /* Byte 5 */
unsigned char :8; /* Byte 6 */
unsigned char :8; /* Byte 7 */
unsigned char :8; /* Byte 8 */
#ifdef LITTLE_ENDIAN_BITFIELDS
unsigned char :6; /* Byte 9 Bits 0-5 */
boolean SValid:1; /* Byte 9 Bit 6 */
boolean Invert:1; /* Byte 9 Bit 7 */
#else
boolean Invert:1; /* Byte 9 Bit 7 */
boolean SValid:1; /* Byte 9 Bit 6 */
unsigned char :6; /* Byte 9 Bits 0-5 */
#endif
unsigned char SourceStorageElementAddress[2]; /* Bytes 10-11 */
#ifdef HAS_LONG_DESCRIPTORS
unsigned char Reserved[4]; /* Bytes 12-15 */
#endif
}
TransportElementDescriptorShort_T;
typedef struct PhysicalLocation
{
unsigned char zone :1;
unsigned char : 3;
unsigned char row: 4;
unsigned char column :3;
unsigned char frame :5;
} PhysicalLocation_T;
typedef struct TransportElementDescriptor
{
unsigned char ElementAddress[2]; /* Bytes 0-1 */
#ifdef LITTLE_ENDIAN_BITFIELDS
boolean Full:1; /* Byte 2 Bit 0 */
unsigned char :1; /* Byte 2 Bit 1 */
boolean Except:1; /* Byte 2 Bit 2 */
unsigned char :5; /* Byte 2 Bits 3-7 */
#else
unsigned char :5; /* Byte 2 Bits 3-7 */
boolean Except:1; /* Byte 2 Bit 2 */
unsigned char :1; /* Byte 2 Bit 1 */
boolean Full:1; /* Byte 2 Bit 0 */
#endif
unsigned char :8; /* Byte 3 */
unsigned char AdditionalSenseCode; /* Byte 4 */
unsigned char AdditionalSenseCodeQualifier; /* Byte 5 */
unsigned char :8; /* Byte 6 */
unsigned char :8; /* Byte 7 */
unsigned char :8; /* Byte 8 */
#ifdef LITTLE_ENDIAN_BITFIELDS
unsigned char :6; /* Byte 9 Bits 0-5 */
boolean SValid:1; /* Byte 9 Bit 6 */
boolean Invert:1; /* Byte 9 Bit 7 */
#else
boolean Invert:1; /* Byte 9 Bit 7 */
boolean SValid:1; /* Byte 9 Bit 6 */
unsigned char :6; /* Byte 9 Bits 0-5 */
#endif
unsigned char SourceStorageElementAddress[2]; /* Bytes 10-11 */
unsigned char PrimaryVolumeTag[36]; /* barcode */
unsigned char AlternateVolumeTag[36];
#ifdef HAS_LONG_DESCRIPTORS
unsigned char Reserved[4]; /* 4 extra bytes? */
#endif
}
TransportElementDescriptor_T;
/* Now for element status data; */
typedef unsigned char barcode[37];
typedef unsigned char serialnumber[13];
typedef struct ElementStatus {
int StorageElementCount;
int ImportExportCount;
int DataTransferElementCount;
int *DataTransferElementAddress; /* array. */
int *DataTransferElementSourceStorageElementNumber; /* array */
int *DataTransferElementPhysicalLocation; /*array */
serialnumber *DataTransferElementSerialNumber; /*array */
barcode *StorageElementPhysicalLocation; /*array */
barcode *DataTransferPrimaryVolumeTag; /* array. */
barcode *DataTransferAlternateVolumeTag; /* array. */
barcode *PrimaryVolumeTag; /* array */
barcode *AlternateVolumeTag; /* array */
int *StorageElementAddress; /* array */
boolean *StorageElementIsImportExport; /* array */
int TransportElementAddress; /* assume only one of those... */
boolean *DataTransferElementFull; /* array */
boolean *StorageElementFull; /* array */
} ElementStatus_T;
/* Now for the SCSI ID and LUN information: */
typedef struct scsi_id {
int id;
int lun;
} scsi_id_t;
#define MEDIUM_CHANGER_TYPE 8 /* what type bits are set for medium changers. */
/* The following two structs are used for the brain-dead functions of the
* NSM jukebox.
*/
typedef struct NSM_Param {
unsigned char page_code;
unsigned char reserved;
unsigned char page_len_msb;
unsigned char page_len_lsb;
unsigned char allocation_msb;
unsigned char allocation_lsb;
unsigned char reserved2[2];
unsigned char command_code[4];
unsigned char command_params[2048]; /* egregious overkill. */
} NSM_Param_T;
extern RequestSense_T scsi_error_sense;
typedef struct NSM_Result {
unsigned char page_code;
unsigned char reserved;
unsigned char page_len_msb;
unsigned char page_len_lsb;
unsigned char command_code[4];
unsigned char ces_code[2];
unsigned char return_data[0xffff]; /* egregioius overkill */
} NSM_Result_T;
#endif /* of multi-include protection. */