Commit d2b7d4bf authored by Victor Kotlyar's avatar Victor Kotlyar
Browse files

added getCompression implementation for T10000 drive

parent 81dde87b
......@@ -82,7 +82,7 @@ namespace Tape {
std::string error;
/* TODO: error code. See gettperror and get_sk_msg in CAStor */
};
/**
* Class abstracting the tape drives. This class is templated to allow the use
* of unrelated test harness and real system. The test harness is made up of
......@@ -226,7 +226,7 @@ namespace Tape {
std::cout << "Re-doing a SCSI inquiry via st device:" << std::endl;
SCSI_inquiry(m_tapeFD);
}
private:
protected:
SCSI::DeviceInfo m_SCSIInfo;
int m_tapeFD;
int m_genericFD;
......@@ -270,4 +270,81 @@ namespace Tape {
<< SCSI::Structures::toString(*((SCSI::Structures::inquiryData_t *) dataBuff));
}
};
template <class sysWrapperClass>
class DriveT10000 : public Drive<sysWrapperClass> {
public:
DriveT10000(SCSI::DeviceInfo di, sysWrapperClass & sw): Drive<sysWrapperClass>(di, sw) {}
virtual compressionStats getCompression() throw (Exception) {
SCSI::Structures::logSenseCDB_t cdb;
compressionStats driveCompressionStats;
unsigned char dataBuff[1024];
unsigned char senseBuff[255];
memset (dataBuff, 0, sizeof (dataBuff));
memset (senseBuff, 0, sizeof (senseBuff));
cdb.pageCode = SCSI::logSensePages::sequentialAccessDevicePage;
cdb.PC = 0x01; // Current Comulative Values
cdb.allocationLength[0] = (sizeof(dataBuff) & 0xFF00) >> 8;
cdb.allocationLength[1] = sizeof(dataBuff) & 0x00FF;
SCSI::Structures::LinuxSGIO_t sgh;
sgh.setCDB(&cdb);
sgh.setDataBuffer(&dataBuff);
sgh.setSenseBuffer(&senseBuff);
sgh.dxfer_direction = SG_DXFER_FROM_DEV;
/* Manage both system error and SCSI errors. */
if (-1 == this->m_sysWrapper.ioctl(this->m_tapeFD, SG_IO, &sgh))
throw Tape::Exceptions::Errnum("Failed SG_IO ioctl");
if (SCSI::Status::GOOD != sgh.status)
throw Tape::Exception(std::string("SCSI error in getCompression: ") +
SCSI::statusToString(sgh.status));
SCSI::Structures::logSenseLogPageHeader_t & logPageHeader =
*(SCSI::Structures::logSenseLogPageHeader_t *) dataBuff;
unsigned char *endPage = dataBuff +
SCSI::Structures::toU16(logPageHeader.pageLength)+sizeof(logPageHeader);
unsigned char *logParameter = dataBuff+sizeof(logPageHeader);
while ( logParameter < endPage ) { /* values in bytes */
SCSI::Structures::logSenseParameter_t & logPageParam =
*(SCSI::Structures::logSenseParameter_t *) logParameter;
switch (SCSI::Structures::toU16(logPageParam.header.parameterCode)) {
case SCSI::sequentialAccessDevicePage::receivedFromInitiator:
driveCompressionStats.fromHost = SCSI::Structures::toU64(reinterpret_cast<unsigned char(&)[8]>(logPageParam.parameterValue));
break;
case SCSI::sequentialAccessDevicePage::writtenOnTape:
driveCompressionStats.toTape = SCSI::Structures::toU64(reinterpret_cast<unsigned char(&)[8]>(logPageParam.parameterValue));
break;
case SCSI::sequentialAccessDevicePage::readFromTape:
driveCompressionStats.fromTape = SCSI::Structures::toU64(reinterpret_cast<unsigned char(&)[8]>(logPageParam.parameterValue));
break;
case SCSI::sequentialAccessDevicePage::readByInitiator:
driveCompressionStats.toHost = SCSI::Structures::toU64(reinterpret_cast<unsigned char(&)[8]>(logPageParam.parameterValue));
break;
}
logParameter += logPageParam.header.parameterLength + sizeof(logPageParam.header);
}
return driveCompressionStats;
}
};
template <class sysWrapperClass>
class DriveLTO : public Drive<sysWrapperClass> {
public:
DriveLTO(SCSI::DeviceInfo di, sysWrapperClass & sw): Drive<sysWrapperClass>(di, sw) {}
virtual compressionStats getCompression() throw (Exception) { throw Exception("Not implemented"); }
};
template <class sysWrapperClass>
class DriveIBM3592 : public Drive<sysWrapperClass> {
public:
DriveIBM3592(SCSI::DeviceInfo di, sysWrapperClass & sw): Drive<sysWrapperClass>(di, sw) {}
virtual compressionStats getCompression() throw (Exception) { throw Exception("Not implemented"); }
};
}
......@@ -228,7 +228,22 @@ namespace SCSI {
class logSensePages {
public:
enum {
tapeAlert = 0x2e
tapeAlert = 0x2e,
sequentialAccessDevicePage = 0x0C
};
};
/**
* Sun StorageTekTM T10000 Tape Drive Fibre Channel Interface Reference Manual
*/
class sequentialAccessDevicePage {
public:
enum {
receivedFromInitiator = 0x0000, // write command
writtenOnTape = 0x0001,
readFromTape = 0x0002,
readByInitiator = 0x0003,
cleaning = 0x0100, // 000 no cleaning required, 001 cleaning required
leftOnTape = 0x8000 // number of 4k bytes left on tape from the current position
};
};
}; // namespace SCSI
......@@ -84,6 +84,17 @@ namespace SCSI {
sg_io_hdr_t * operator & () { return (sg_io_hdr_t *) this; }
};
/**
* Helper function to deal with endianness.
* @param t byte array in SCSI order representing a 64 bits number
* @return
*/
inline uint64_t toU64(const unsigned char(& t)[8])
{
/* Like network, SCSI is BigEndian */
return (uint64_t) ntohl ( (*(uint64_t *) t << 32) >> 32) << 32 | ntohl(*(uint64_t *) t >>32);
}
/**
* Helper function to deal with endianness.
* @param t byte array in SCSI order representing a 32 bits number
......@@ -218,7 +229,7 @@ namespace SCSI {
};
/**
* Log sense CDB as decribed in SPC-4,
* Log sense CDB as described in SPC-4,
*/
class logSenseCDB_t {
public:
......@@ -244,6 +255,65 @@ namespace SCSI {
logSenseCDB_t() { zeroStruct(this); opCode = SCSI::Commands::LOG_SENSE; }
};
/**
* Log sense Log Page Parameter Format as described in SPC-4,
*/
class logSenseParameterHeader_t {
public:
// bytes 0-1
unsigned char parameterCode [2];
// byte 2
unsigned char formatAndLinking : 2; // reserved and List Parameter bits
unsigned char TMC : 2; // Threshold Met Criteria
unsigned char ETC : 1; // Enable Threshold Comparison
unsigned char TSD : 1; // Target Save Disable
unsigned char : 1; // DS Disable Save for T10000
unsigned char DU : 1; // Disable Update
// byte 3
unsigned char parameterLength; // n-3
};
class logSenseParameter_t {
public:
// bytes 0-3
logSenseParameterHeader_t header;
// bytes 4-n
unsigned char parameterValue[1]; // parameters have variable length
};
/**
* Log sense Log Page Format as described in SPC-4,
*/
class logSenseLogPageHeader_t {
public:
// byte 0
unsigned char pageCode : 6;
unsigned char SPF: 1; // the Subpage format
unsigned char DS: 1; // the Disable Slave bit
// byte 1
unsigned char subPageCode;
// bytes 2-3
unsigned char pageLength[2]; // n-3 number of bytes without header
};
/**
* Log sense Log Page Format as described in SPC-4,
*/
class logSenseLogPage_t {
public:
// bytes 0-3
logSenseLogPageHeader_t header;
// bytes 4-n
logSenseParameter_t parameters [1]; // parameters have variable length
};
class tapeAlertLogParameter_t {
public:
unsigned char parameterCode [2];
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment