mirror of
https://github.com/moibenko/mtx.git
synced 2026-01-11 06:00:13 +00:00
Compare commits
10 Commits
fnal_patch
...
absolute_a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfc1a886e5 | ||
|
|
60a1e55727 | ||
|
|
b338d5f9a0 | ||
|
|
71e237e6e8 | ||
|
|
8767727b15 | ||
|
|
7b8da461e5 | ||
|
|
963faa172c | ||
|
|
a13704f62f | ||
|
|
2c95a251e4 | ||
|
|
4bf05d31c5 |
2
README.md
Normal file
2
README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# mtx
|
||||
The MTX program controls the robotic mechanism in autoloaders and tape libraries. Taken from Souceforge, patches from centOS were applied, plus my changes to allow to use mtx over library calls.
|
||||
BIN
mtx-1.3.12.tgz
BIN
mtx-1.3.12.tgz
Binary file not shown.
@@ -31,7 +31,7 @@
|
||||
Near complete re-write Feb 2000 Eric Lee Green <eric@badtux.org> to add support for
|
||||
multi-drive tape changers, extract out library stuff into mtxl.c,
|
||||
and otherwise bring things up to date for dealing with LARGE tape jukeboxes
|
||||
and other such enterprise-class storage subsystems.
|
||||
and other such enterprise-class storage subsystems.
|
||||
*/
|
||||
|
||||
char *argv0;
|
||||
@@ -39,7 +39,7 @@ char *argv0;
|
||||
#include "mtx.h" /* various defines for bit order etc. */
|
||||
#include "mtxl.h"
|
||||
|
||||
/* A table for printing out the peripheral device type as ASCII. */
|
||||
/* A table for printing out the peripheral device type as ASCII. */
|
||||
static char *PeripheralDeviceType[32] =
|
||||
{
|
||||
"Disk Drive", /* 0 */
|
||||
@@ -49,10 +49,10 @@ static char *PeripheralDeviceType[32] =
|
||||
"Write-once", /* 4 */
|
||||
"CD-ROM", /* 5 */
|
||||
"Scanner", /* 6 */
|
||||
"Optical", /* 7 */
|
||||
"Optical", /* 7 */
|
||||
"Medium Changer", /* 8 */
|
||||
"Communications", /* 9 */
|
||||
"ASC IT8", /* a */
|
||||
"ASC IT8", /* a */
|
||||
"ASC IT8", /* b */
|
||||
"RAID Array", /* c */
|
||||
"Enclosure Services", /* d */
|
||||
@@ -80,7 +80,7 @@ static int argc;
|
||||
static char **argv;
|
||||
|
||||
char *device=NULL; /* the device name passed as argument */
|
||||
int absolute_addressing=0; /* if not 0 - use absolute adresses of storage and tranport elements as known to the robot */
|
||||
int absolute_addressing=1; /* if not 0 - use absolute adresses of storage and tranport elements as known to the robot */
|
||||
|
||||
/* Unfortunately this must be true for SGI, because SGI does not
|
||||
use an int :-(.
|
||||
@@ -113,7 +113,7 @@ static void Transfer(void);
|
||||
static void Eepos(void);
|
||||
static void NoAttach(void);
|
||||
static void Version(void);
|
||||
static void do_Inventory(void);
|
||||
static void do_Inventory(void);
|
||||
static void do_Unload(void);
|
||||
static void do_Erase(void);
|
||||
static void NoBarCode(void);
|
||||
@@ -150,7 +150,7 @@ command_table[] =
|
||||
{ 0, "erase", do_Erase, 1, 0},
|
||||
{ 0, "nobarcode", NoBarCode, 0,0},
|
||||
{ 1, "position", do_Position, 1, 1},
|
||||
{ 0, "invert2", Invert2, 0, 0},
|
||||
{ 0, "invert2", Invert2, 0, 0},
|
||||
{ 3, "exchange", Exchange, 1, 1 },
|
||||
{ 0, "altres", AltReadElementStatus, 0,0},
|
||||
{ 0, NULL, NULL }
|
||||
@@ -185,7 +185,7 @@ static void Usage()
|
||||
static void Version(void)
|
||||
{
|
||||
fprintf(stderr, "mtx version %s\n\n", VERSION);
|
||||
Usage();
|
||||
Usage();
|
||||
}
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ static void First(void)
|
||||
arg1 = ElementStatus->DataTransferElementSourceStorageElementNumber[driveno] + 1;
|
||||
if (arg1 == 1)
|
||||
{
|
||||
printf("loading...done.\n"); /* it already has tape #1 in it! */
|
||||
printf("loading...done.\n"); /* it already has tape #1 in it! */
|
||||
return;
|
||||
}
|
||||
arg2 = driveno;
|
||||
@@ -293,7 +293,7 @@ static void Last(void)
|
||||
arg1 = ElementStatus->DataTransferElementSourceStorageElementNumber[driveno] + 1;
|
||||
if (arg1 >= (ElementStatus->StorageElementCount - ElementStatus->ImportExportCount))
|
||||
{
|
||||
printf("loading...done.\n"); /* it already has last tape in it! */
|
||||
printf("loading...done.\n"); /* it already has last tape in it! */
|
||||
return;
|
||||
}
|
||||
arg2 = driveno;
|
||||
@@ -393,7 +393,7 @@ static void Next(void)
|
||||
FatalError("No More Media\n"); /* last slot */
|
||||
}
|
||||
|
||||
static void do_Inventory(void)
|
||||
static void do_Inventory(void)
|
||||
{
|
||||
if (Inventory(MediumChangerFD) < 0)
|
||||
{
|
||||
@@ -421,7 +421,7 @@ static void do_Erase(void)
|
||||
exit(1); /* exit with an error status. */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This should eject a tape or magazine, depending upon the device sent
|
||||
* to.
|
||||
@@ -442,12 +442,12 @@ static void ReportInquiry(void)
|
||||
int i;
|
||||
|
||||
Inquiry = RequestInquiry(MediumChangerFD,&RequestSense);
|
||||
if (Inquiry == NULL)
|
||||
if (Inquiry == NULL)
|
||||
{
|
||||
PrintRequestSense(&RequestSense);
|
||||
FatalError("INQUIRY Command Failed\n");
|
||||
}
|
||||
|
||||
|
||||
printf("Product Type: %s\n", PeripheralDeviceType[Inquiry->PeripheralDeviceType]);
|
||||
printf("Vendor ID: '");
|
||||
for (i = 0; i < sizeof(Inquiry->VendorIdentification); i++)
|
||||
@@ -485,6 +485,7 @@ static void Status(void)
|
||||
{
|
||||
int StorageElementNumber;
|
||||
int TransferElementNumber;
|
||||
PhysicalLocation_T *phys_loc;
|
||||
|
||||
printf( " Storage Changer %s:%d Drives, %d Slots ( %d Import/Export )\n",
|
||||
device,
|
||||
@@ -493,7 +494,7 @@ static void Status(void)
|
||||
ElementStatus->ImportExportCount);
|
||||
|
||||
|
||||
for (TransferElementNumber = 0;
|
||||
for (TransferElementNumber = 0;
|
||||
TransferElementNumber < ElementStatus->DataTransferElementCount;
|
||||
TransferElementNumber++)
|
||||
{
|
||||
@@ -501,7 +502,13 @@ static void Status(void)
|
||||
printf("Data Transfer Element %d:", TransferElementNumber);
|
||||
}
|
||||
else {
|
||||
printf("Data Transfer Element %d :", ElementStatus->DataTransferElementAddress[TransferElementNumber]);
|
||||
printf("Data Transfer Element %d ", ElementStatus->DataTransferElementAddress[TransferElementNumber]);
|
||||
phys_loc = (PhysicalLocation_T *) &ElementStatus->DataTransferElementPhysicalLocation[TransferElementNumber];
|
||||
printf("Phys Loc F%u,C%u,R%u,Z%u SN%s ID %s:",
|
||||
phys_loc->frame, phys_loc->column, phys_loc->row, phys_loc->zone,
|
||||
ElementStatus->DataTransferElementSerialNumber[TransferElementNumber],
|
||||
ElementStatus->DataTransferElementProductId[TransferElementNumber]
|
||||
);
|
||||
}
|
||||
if (ElementStatus->DataTransferElementFull[TransferElementNumber])
|
||||
{
|
||||
@@ -528,7 +535,7 @@ static void Status(void)
|
||||
|
||||
if (ElementStatus->DataTransferAlternateVolumeTag[TransferElementNumber][0])
|
||||
{
|
||||
printf(":AlternateVolumeTag = %s", ElementStatus->DataTransferAlternateVolumeTag[TransferElementNumber]);
|
||||
printf(":AlternateVolumeTag = %s", ElementStatus->DataTransferAlternateVolumeTag[TransferElementNumber]);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
@@ -548,10 +555,11 @@ static void Status(void)
|
||||
(ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty"));
|
||||
}
|
||||
else {
|
||||
printf( " Storage Element %d%s:%s", ElementStatus->StorageElementAddress[StorageElementNumber],
|
||||
(ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "",
|
||||
(ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty"));
|
||||
}
|
||||
printf( " Storage Element %d Phys Loc %s %s:%s ", ElementStatus->StorageElementAddress[StorageElementNumber],
|
||||
ElementStatus->StorageElementPhysicalLocation[StorageElementNumber],
|
||||
(ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "",
|
||||
(ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty"));
|
||||
}
|
||||
|
||||
if (ElementStatus->PrimaryVolumeTag[StorageElementNumber][0])
|
||||
{
|
||||
@@ -580,7 +588,7 @@ void Position(int dest)
|
||||
|
||||
void Move(int src, int dest) {
|
||||
RequestSense_T *result; /* from MoveMedium */
|
||||
|
||||
|
||||
result = MoveMedium(MediumChangerFD, src, dest, ElementStatus, inquiry_info, &SCSI_Flags);
|
||||
if (result)
|
||||
{
|
||||
@@ -638,7 +646,7 @@ static void Load(void)
|
||||
if (!device_opened)
|
||||
{
|
||||
FatalError("No Media Changer Device Specified\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (arg1 < 0 || arg1 >= ElementStatus->StorageElementCount)
|
||||
{
|
||||
@@ -742,7 +750,7 @@ static void Exchange(void)
|
||||
src = ElementStatus->StorageElementAddress[arg1 - 1];
|
||||
dest = ElementStatus->StorageElementAddress[arg2 - 1];
|
||||
dest2 = ElementStatus->StorageElementAddress[arg3 - 1];
|
||||
|
||||
|
||||
result = ExchangeMedium(MediumChangerFD, src, dest, dest2, ElementStatus, &SCSI_Flags);
|
||||
if (result)
|
||||
{
|
||||
@@ -801,7 +809,7 @@ static void Unload(void)
|
||||
if (!device_opened)
|
||||
{
|
||||
FatalError("No Media Changer Device Specified\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* okay, we should be there: */
|
||||
if (arg1 < 0)
|
||||
@@ -858,7 +866,7 @@ static void Unload(void)
|
||||
}
|
||||
|
||||
fprintf(stdout, "Unloading drive %d into Storage Element %d...", arg2, arg1 + 1);
|
||||
fflush(stdout); /* make it real-time :-( */
|
||||
fflush(stdout); /* make it real-time :-( */
|
||||
|
||||
Move(src,dest);
|
||||
|
||||
@@ -870,7 +878,7 @@ static void Unload(void)
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
** ARGUMENT PARSING SUBROUTINES: Parse arguments, dispatch.
|
||||
** ARGUMENT PARSING SUBROUTINES: Parse arguments, dispatch.
|
||||
*****************************************************************/
|
||||
|
||||
/* ***
|
||||
@@ -878,9 +886,9 @@ static void Unload(void)
|
||||
*
|
||||
* If we have an actual argument at the index position indicated (i.e. we
|
||||
* have not gone off the edge of the world), we return
|
||||
* its number. If we don't, or it's not a numeric argument,
|
||||
* we return -1. Note that 'get_arg' is kind of misleading, we only accept
|
||||
* numeric arguments, not any other kind.
|
||||
* its number. If we don't, or it's not a numeric argument,
|
||||
* we return -1. Note that 'get_arg' is kind of misleading, we only accept
|
||||
* numeric arguments, not any other kind.
|
||||
*/
|
||||
int get_arg(int idx)
|
||||
{
|
||||
@@ -916,12 +924,11 @@ void open_device(void)
|
||||
|
||||
|
||||
/* we see if we've got a file open. If not, we open one :-(. Then
|
||||
* we execute the actual command. Or not :-(.
|
||||
*/
|
||||
* we execute the actual command. Or not :-(.
|
||||
*/
|
||||
void execute_command(struct command_table_struct *command)
|
||||
{
|
||||
RequestSense_T RequestSense;
|
||||
|
||||
if (device == NULL && command->need_device)
|
||||
{
|
||||
/* try to get it from TAPE environment variable... */
|
||||
@@ -936,6 +943,11 @@ void execute_command(struct command_table_struct *command)
|
||||
}
|
||||
open_device();
|
||||
}
|
||||
if (command->need_status && absolute_addressing)
|
||||
{
|
||||
FreeElementData(ElementStatus);
|
||||
ElementStatus = NULL;
|
||||
}
|
||||
if (!ElementStatus && command->need_status)
|
||||
{
|
||||
inquiry_info = RequestInquiry(MediumChangerFD,&RequestSense);
|
||||
@@ -949,7 +961,7 @@ void execute_command(struct command_table_struct *command)
|
||||
if (!ElementStatus)
|
||||
{
|
||||
PrintRequestSense(&RequestSense);
|
||||
FatalError("READ ELEMENT STATUS Command Failed\n");
|
||||
FatalError("READ ELEMENT STATUS Command Failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -963,8 +975,8 @@ void execute_command(struct command_table_struct *command)
|
||||
* load in another tape into drive 0, and we execute these commands one
|
||||
* at a time as we come to them. If we don't have a -f at the start, we
|
||||
* barf. If we leave out a drive #, we default to drive 0 (the first drive
|
||||
* in the cabinet).
|
||||
*/
|
||||
* in the cabinet).
|
||||
*/
|
||||
|
||||
int parse_args(void)
|
||||
{
|
||||
@@ -1025,7 +1037,7 @@ int parse_args(void)
|
||||
|
||||
if (command->num_args>=2 && arg1 != -1)
|
||||
{
|
||||
arg2 = get_arg(i);
|
||||
arg2 = get_arg(i);
|
||||
if (arg2 != -1)
|
||||
{
|
||||
i++;
|
||||
@@ -1081,7 +1093,7 @@ int main(int ArgCount, char *ArgVector[])
|
||||
if (!ElementStatus)
|
||||
{
|
||||
PrintRequestSense(&RequestSense);
|
||||
FatalError("READ ELEMENT STATUS Command Failed\n");
|
||||
FatalError("READ ELEMENT STATUS Command Failed\n");
|
||||
}
|
||||
VMS_DefineStatusSymbols();
|
||||
SCSI_CloseDevice(device, MediumChangerFD);
|
||||
|
||||
@@ -209,6 +209,7 @@ typedef struct SCSI_Flags_Struct
|
||||
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
|
||||
@@ -306,6 +307,16 @@ typedef struct Inquiry
|
||||
}
|
||||
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
|
||||
@@ -499,6 +510,15 @@ typedef struct TransportElementDescriptorShort
|
||||
}
|
||||
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
|
||||
{
|
||||
@@ -545,6 +565,7 @@ TransportElementDescriptor_T;
|
||||
/* Now for element status data; */
|
||||
|
||||
typedef unsigned char barcode[37];
|
||||
typedef unsigned char serialnumber[13];
|
||||
|
||||
typedef struct ElementStatus {
|
||||
|
||||
@@ -553,6 +574,10 @@ typedef struct ElementStatus {
|
||||
int DataTransferElementCount;
|
||||
int *DataTransferElementAddress; /* array. */
|
||||
int *DataTransferElementSourceStorageElementNumber; /* array */
|
||||
int *DataTransferElementPhysicalLocation; /*array */
|
||||
serialnumber *DataTransferElementProductId; /*array */
|
||||
serialnumber *DataTransferElementSerialNumber; /*array */
|
||||
barcode *StorageElementPhysicalLocation; /*array */
|
||||
barcode *DataTransferPrimaryVolumeTag; /* array. */
|
||||
barcode *DataTransferAlternateVolumeTag; /* array. */
|
||||
barcode *PrimaryVolumeTag; /* array */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Name: mtx
|
||||
Version: 1.3.12
|
||||
Release: 14fnal%{?dist}
|
||||
Release: 15fnal%{?dist}
|
||||
Summary: SCSI media changer control program
|
||||
License: GPLv2
|
||||
Group: Applications/System
|
||||
@@ -51,6 +51,9 @@ rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
|
||||
%changelog
|
||||
* Wed Jan 23 2019 Alexander Moibenko <moibenko@fnal.gov> - 1.3.12-15fnal
|
||||
- For absolute_addressing refresh elements data when status command is executed. This is needed to update tape library infortion in the calling program.
|
||||
- Changes to allow to use mtx as library and show absolute transfer and storage elements as output of status call
|
||||
* Wed Aug 1 2018 Alexander Moibenko <moibenko@fnal.gov> - 1.3.12-14fnal
|
||||
- All patches applied to code and new source mtx.tgz created to build rpm
|
||||
- Changes to allow to use mtx as library and show absolute transfer and storage elements as output of status call
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "mtxl.h"
|
||||
|
||||
/* #define DEBUG_NSM 1 */
|
||||
|
||||
/* #define DEBUG_BARCODE */
|
||||
/* #define DEBUG_MODE_SENSE 1 */
|
||||
/* #define DEBUG */
|
||||
/* #define DEBUG_SCSI */
|
||||
@@ -523,10 +523,18 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void FreeElementData(ElementStatus_T *data)
|
||||
void FreeElementData(ElementStatus_T *data)
|
||||
{
|
||||
if (!data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
free(data->DataTransferElementAddress);
|
||||
free(data->DataTransferElementSourceStorageElementNumber);
|
||||
free(data->DataTransferElementPhysicalLocation);
|
||||
free(data->DataTransferElementProductId);
|
||||
free(data->DataTransferElementSerialNumber);
|
||||
free(data->StorageElementPhysicalLocation);
|
||||
free(data->DataTransferPrimaryVolumeTag);
|
||||
free(data->DataTransferAlternateVolumeTag);
|
||||
free(data->PrimaryVolumeTag);
|
||||
@@ -552,6 +560,14 @@ static ElementStatus_T *AllocateElementData(ElementModeSense_T *mode_sense)
|
||||
(int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1));
|
||||
retval->DataTransferElementSourceStorageElementNumber =
|
||||
(int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1));
|
||||
retval->DataTransferElementPhysicalLocation =
|
||||
(int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1));
|
||||
retval->DataTransferElementProductId =
|
||||
(serialnumber *)xzmalloc(sizeof(serialnumber) * (mode_sense->NumDataTransfer + 1));
|
||||
retval->DataTransferElementSerialNumber =
|
||||
(serialnumber *)xzmalloc(sizeof(serialnumber) * (mode_sense->NumDataTransfer + 1));
|
||||
retval->StorageElementPhysicalLocation =
|
||||
(barcode *)xzmalloc(sizeof(barcode) * (mode_sense->NumStorage + 1));
|
||||
retval->DataTransferPrimaryVolumeTag =
|
||||
(barcode *)xzmalloc(sizeof(barcode) * (mode_sense->NumDataTransfer + 1));
|
||||
retval->DataTransferAlternateVolumeTag =
|
||||
@@ -591,6 +607,34 @@ void copy_barcode(unsigned char *src, unsigned char *dest)
|
||||
*dest = 0; /* null-terminate */
|
||||
}
|
||||
|
||||
void copy_physical_location(unsigned char *src, unsigned char *dest)
|
||||
{
|
||||
while ((*src< 32) || (*src > 127)) {
|
||||
src++;
|
||||
}
|
||||
strcpy((char *)dest, (char *)src);
|
||||
}
|
||||
|
||||
void copy_char_buffer(unsigned char *src, unsigned char *dest, int num)
|
||||
{
|
||||
int i;
|
||||
while ((*src< 32) || (*src > 127)) {
|
||||
src++;
|
||||
}
|
||||
for (i=0; i < num; i++)
|
||||
{
|
||||
*dest = *src++;
|
||||
|
||||
if ((*dest < 32) || (*dest > 127))
|
||||
{
|
||||
*dest = 0;
|
||||
break;
|
||||
}
|
||||
dest++;
|
||||
}
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
/* This #%!@# routine has more parameters than I can count! */
|
||||
static unsigned char *SendElementStatusRequestActual(
|
||||
DEVICE_TYPE MediumChangerFD,
|
||||
@@ -654,6 +698,9 @@ static unsigned char *SendElementStatusRequestActual(
|
||||
CDB[5]= (unsigned char)NumElements;
|
||||
|
||||
CDB[6] = 0; /* Reserved */
|
||||
if (((flags->elementtype == DataTransferElement || flags->elementtype == StorageElement)) && (flags->absolute_addressing == 1)) {
|
||||
CDB[6] = 0x01; /* set DVCID to read physical location */
|
||||
}
|
||||
|
||||
/* allocation length */
|
||||
CDB[7]= (unsigned char)(NumBytes >> 16);
|
||||
@@ -722,7 +769,7 @@ static unsigned char *SendElementStatusRequestActual(
|
||||
/* print a bunch of extra debug data :-(. */
|
||||
PrintRequestSense(RequestSense); /* see what it sez :-(. */
|
||||
fprintf(stderr,"Data:\n");
|
||||
PrintHex(2, DataBuffer, 40);
|
||||
PrintHex(2, DataBuffer, 100);
|
||||
#endif
|
||||
return DataBuffer; /* we succeeded! */
|
||||
}
|
||||
@@ -806,12 +853,13 @@ unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD,
|
||||
*/
|
||||
|
||||
static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||
int *EmptyStorageElementCount,
|
||||
unsigned char *DataBuffer,
|
||||
ElementStatus_T *ElementStatus,
|
||||
ElementModeSense_T *mode_sense,
|
||||
int *pNextElement
|
||||
)
|
||||
int *EmptyStorageElementCount,
|
||||
unsigned char *DataBuffer,
|
||||
ElementStatus_T *ElementStatus,
|
||||
ElementModeSense_T *mode_sense,
|
||||
int *pNextElement,
|
||||
boolean absolute_address
|
||||
)
|
||||
{
|
||||
unsigned char *DataPointer = DataBuffer;
|
||||
TransportElementDescriptor_T TEBuf;
|
||||
@@ -987,12 +1035,6 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||
ElementStatus->StorageElementCount; /* slot idx. */
|
||||
/* ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount]; */
|
||||
}
|
||||
if ((TransportElementDescriptorLength > 11) &&
|
||||
(ElementStatusPage->VolBits & E2_AVOLTAG))
|
||||
{
|
||||
copy_barcode(TransportElementDescriptor->AlternateVolumeTag,
|
||||
ElementStatus->AlternateVolumeTag[ElementStatus->StorageElementCount]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ElementStatus->AlternateVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */;
|
||||
@@ -1007,7 +1049,11 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||
{
|
||||
ElementStatus->PrimaryVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */
|
||||
}
|
||||
|
||||
|
||||
if (absolute_address){
|
||||
copy_physical_location(TransportElementDescriptor->AlternateVolumeTag, ElementStatus->StorageElementPhysicalLocation[ElementStatus->StorageElementCount]);
|
||||
}
|
||||
|
||||
ElementStatus->StorageElementCount++;
|
||||
/*
|
||||
Note that the original mtx had no check here for
|
||||
@@ -1052,19 +1098,29 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||
continue;
|
||||
*/
|
||||
|
||||
if (absolute_address){
|
||||
ElementStatus->DataTransferElementPhysicalLocation[ElementStatus->DataTransferElementCount] =
|
||||
BigEndian16(TransportElementDescriptor->SourceStorageElementAddress);
|
||||
InquiryShort_T *inqs;
|
||||
inqs = (InquiryShort_T *) TransportElementDescriptor->PrimaryVolumeTag;
|
||||
copy_char_buffer(inqs->SerialNumber, ElementStatus->DataTransferElementSerialNumber[ElementStatus->DataTransferElementCount], 12);
|
||||
copy_char_buffer(inqs->ProductIdentification+2, ElementStatus->DataTransferElementProductId[ElementStatus->DataTransferElementCount], 12);
|
||||
ElementStatus->DataTransferElementCount++;
|
||||
break;
|
||||
}
|
||||
ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount] =
|
||||
BigEndian16(TransportElementDescriptor->ElementAddress);
|
||||
ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount] =
|
||||
TransportElementDescriptor->Full;
|
||||
ElementStatus->DataTransferElementSourceStorageElementNumber[ElementStatus->DataTransferElementCount] =
|
||||
BigEndian16(TransportElementDescriptor->SourceStorageElementAddress);
|
||||
BigEndian16(TransportElementDescriptor->SourceStorageElementAddress);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "%d: ElementAddress = %d, Full = %d, SourceElement = %d\n",
|
||||
ElementStatus->DataTransferElementCount,
|
||||
ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount],
|
||||
ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount],
|
||||
ElementStatus->DataTransferElementSourceStorageElementNumber[ElementStatus->DataTransferElementCount]);
|
||||
ElementStatus->DataTransferElementCount,
|
||||
ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount],
|
||||
ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount],
|
||||
ElementStatus->DataTransferElementSourceStorageElementNumber[ElementStatus->DataTransferElementCount]);
|
||||
#endif
|
||||
if (ElementStatus->DataTransferElementCount >= mode_sense->NumDataTransfer)
|
||||
{
|
||||
@@ -1213,6 +1269,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||
fprintf(stderr,"Storage start %d, Num %d, max %d\n", mode_sense->StorageStart, mode_sense->NumStorage - mode_sense->NumImportExport, mode_sense->MaxReadElementStatusData);
|
||||
#endif
|
||||
flags->elementtype = StorageElement; /* sigh! */
|
||||
flags->absolute_addressing = 1;
|
||||
|
||||
NumElements = mode_sense->NumStorage - mode_sense->NumImportExport;
|
||||
FirstElem = mode_sense->StorageStart;
|
||||
@@ -1244,13 +1301,14 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||
fprintf(stderr, "Parsing storage elements\n");
|
||||
#endif
|
||||
ParseElementStatus(EmptyStorageElementAddress, &EmptyStorageElementCount,
|
||||
DataBuffer,ElementStatus,mode_sense,NULL);
|
||||
DataBuffer,ElementStatus,mode_sense,NULL, true);
|
||||
|
||||
free(DataBuffer); /* sigh! */
|
||||
FirstElem += SCSI_RES_ELEMENTS;
|
||||
NumElements -= SCSI_RES_ELEMENTS;
|
||||
} while ( NumElements > 0 );
|
||||
|
||||
|
||||
flags->absolute_addressing = 0;
|
||||
/* --------------IMPORT/EXPORT--------------- */
|
||||
/* Next let's see if we need to do Import/Export: */
|
||||
if (mode_sense->NumImportExport > 0)
|
||||
@@ -1283,7 +1341,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||
dump_data(DataBuffer, 100); /* dump some data :-(. */
|
||||
#endif
|
||||
ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount,
|
||||
DataBuffer, ElementStatus, mode_sense, NULL);
|
||||
DataBuffer, ElementStatus, mode_sense, NULL, false);
|
||||
free(DataBuffer);
|
||||
ElementStatus->StorageElementCount += ElementStatus->ImportExportCount;
|
||||
}
|
||||
@@ -1294,6 +1352,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||
fprintf(stderr,"Sending request for data transfer element (drive) status\n");
|
||||
#endif
|
||||
flags->elementtype = DataTransferElement; /* sigh! */
|
||||
flags->absolute_addressing = 0;
|
||||
DataBuffer = SendElementStatusRequest( MediumChangerFD, RequestSense,
|
||||
inquiry_info, flags,
|
||||
mode_sense->DataTransferStart,
|
||||
@@ -1316,7 +1375,31 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||
fprintf(stderr,"Parsing data for data transfer element (drive) status\n");
|
||||
#endif
|
||||
ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount,
|
||||
DataBuffer,ElementStatus, mode_sense, NULL);
|
||||
DataBuffer,ElementStatus, mode_sense, NULL, false);
|
||||
|
||||
free(DataBuffer); /* sigh! */
|
||||
|
||||
flags->absolute_addressing = 1;
|
||||
DataBuffer = SendElementStatusRequest( MediumChangerFD, RequestSense,
|
||||
inquiry_info, flags,
|
||||
mode_sense->DataTransferStart,
|
||||
mode_sense->NumDataTransfer,
|
||||
SCSI_RES_ELEMENTS * 52 +120);
|
||||
if (!DataBuffer)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"No data transfer element status.");
|
||||
#endif
|
||||
/* darn. Free up stuff and return. */
|
||||
#ifdef DEBUG_MODE_SENSE
|
||||
PrintRequestSense(RequestSense);
|
||||
#endif
|
||||
FreeElementData(ElementStatus);
|
||||
return NULL;
|
||||
}
|
||||
ElementStatus->DataTransferElementCount = 0;
|
||||
ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount,
|
||||
DataBuffer,ElementStatus, mode_sense, NULL, true);
|
||||
|
||||
free(DataBuffer); /* sigh! */
|
||||
|
||||
@@ -1354,10 +1437,11 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||
fprintf(stderr,"Parsing robot arm data\n");
|
||||
#endif
|
||||
ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount,
|
||||
DataBuffer, ElementStatus, mode_sense, NULL);
|
||||
DataBuffer, ElementStatus, mode_sense, NULL, false);
|
||||
|
||||
free(DataBuffer);
|
||||
}
|
||||
flags->absolute_addressing = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1400,7 +1484,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||
nLastEl = nNextEl;
|
||||
|
||||
ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount,
|
||||
DataBuffer, ElementStatus, mode_sense, &nNextEl);
|
||||
DataBuffer, ElementStatus, mode_sense, &nNextEl, false);
|
||||
|
||||
free(DataBuffer); /* sigh! */
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ ElementStatus_T *ReadElementStatus( DEVICE_TYPE MediumChangerFD,
|
||||
RequestSense_T *RequestSense,
|
||||
Inquiry_T *inquiry_info,
|
||||
SCSI_Flags_T *flags);
|
||||
void FreeElementData(ElementStatus_T *data);
|
||||
|
||||
Inquiry_T *RequestInquiry( DEVICE_TYPE fd,
|
||||
RequestSense_T *RequestSense);
|
||||
|
||||
Reference in New Issue
Block a user