Public Types | Public Member Functions | Private Attributes

data_Mode Class Reference
[SCSI Library]

Mode data class. More...

#include <data.h>

Inheritance diagram for data_Mode:
Inheritance graph
[legend]
Collaboration diagram for data_Mode:
Collaboration graph
[legend]

List of all members.

Public Types

enum  Page_t {
  pg_DEVCFG = 0x10, pg_PART = 0x11,
  pg_ELEMADDR = 0x1D, pg_AITCFG = 0x31,
  pg_AIT_APPENDPART = 0x32, pg_COMPRESSION = 0x0F
}
enum  MediumType_t {
  mt_HP_RW = 0x00, mt_HP_WORM = 0x01,
  mt_HP_CD_EMUL = 0x80, mt_IBM_ULTRIUM_3_WORM = 0x3C,
  mt_IBM_ULTRIUM_4_WORM = 0x4C
}

Public Member Functions

 data_Mode (Page_t a_what)
virtual ~data_Mode ()
Page_t GetPage () const
const data_Mode_tGetModeStruct () const
UInt8_t GetPartCount () const
UInt32_t GetPartSize (UInt8_t a_partNo) const
UInt8_t GetCurPartNumber () const
UInt8_t GetDensityCode () const
bool IsMediumWORM () const
bool GetCompressionStatus () const
void SetCompressionStatus (bool a_compression)
void SetPage (Page_t a_page)
void SetPartitions (vector< UInt32_t > a_partSizes)
 Prepare a tape partitioning MODE page (pg_PART) and appending partition (pg_AIT_APPENDPART).
void SetAITMode (Mode_t a_aitMode)
 Set AIT tape mode.
void SetAITUnloadAtPBOT (bool a_status)
 Set ulpbot bit.

Private Attributes

 log_CLASSID_m
data_Mode_t m_mode

Detailed Description

Mode data class.

Author:
Matej Kenda

Definition at line 142 of file data.h.


Member Enumeration Documentation

Enumerator:
mt_HP_RW 

Read/write medium.

mt_HP_WORM 

WORM medium.

mt_HP_CD_EMUL 

CD emulation mode.

mt_IBM_ULTRIUM_3_WORM 

See SCSI reference for IBM TotalStorage LTO Ultrium Tape Drive.

mt_IBM_ULTRIUM_4_WORM 

Definition at line 159 of file data.h.

                 {
        mt_HP_RW               = 0x00,
        mt_HP_WORM             = 0x01,
        mt_HP_CD_EMUL          = 0x80,

        mt_IBM_ULTRIUM_3_WORM  = 0x3C,
        mt_IBM_ULTRIUM_4_WORM  = 0x4C

    } MediumType_t;

Enumerator:
pg_DEVCFG 

For tape drive.

pg_PART 

For tape drive.

pg_ELEMADDR 

For exchanger.

pg_AITCFG 

AIT tape drive configuration.

pg_AIT_APPENDPART 

AIT: Append partition.

pg_COMPRESSION 

Compression.

Definition at line 144 of file data.h.

                 {
        pg_DEVCFG           = 0x10,
        pg_PART             = 0x11,
        pg_ELEMADDR         = 0x1D,
        pg_AITCFG           = 0x31,
        pg_AIT_APPENDPART   = 0x32,
        pg_COMPRESSION      = 0x0F
    } Page_t;


Constructor & Destructor Documentation

data_Mode::data_Mode ( Page_t  a_what  ) 

Definition at line 49 of file data_mode.cpp.

References data_ModePartitions_t::blkDesc, data_ModeHdr_t::blkDescLen, data_Mode_t::hdr, log_FUNC_m, m_mode, data_Mode_t::part, and SetPage().

                                  {
    log_FUNC_m(data_Mode);
    memset (&m_mode, 0, sizeof(m_mode));

    SetPage(a_what);

    m_mode.hdr.blkDescLen = sizeof(m_mode.part.blkDesc);
}

Here is the call graph for this function:

data_Mode::~data_Mode (  )  [virtual]

Definition at line 58 of file data_mode.cpp.

                      {
    // Empty
}


Member Function Documentation

bool data_Mode::GetCompressionStatus (  )  const

Definition at line 110 of file data_mode.cpp.

References data_ModeCompress_t::blkDesc, data_ModeHdr_t::blkDescLen, cmn_Num2Str(), data_Mode_t::compress, data_ModeCompress_t::compressPage, data_ModeCompressPage_t::dce, data_Mode_t::hdr, ie_INVALID_ARG, log_FUNC_m, and m_mode.

Referenced by Compression(), and bea_TapeMedium::RefreshCompressionState().

                                           {
    if (m_mode.hdr.blkDescLen != sizeof(m_mode.compress.blkDesc)) {
        log_FUNC_m(GetCompressionStatus);
        throw ivd_InternalError(
            ie_INVALID_ARG,
            "BUG: MODE Block Descriptor should be " +
            cmn_Num2Str(sizeof(m_mode.compress.blkDesc)) +
            " but is " +
              cmn_Num2Str(m_mode.hdr.blkDescLen) );
    }
    if (m_mode.compress.compressPage.dce) {
        return true;
    }
    else {
        return false;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

UInt8_t data_Mode::GetCurPartNumber (  )  const

Definition at line 148 of file data_mode.cpp.

References data_ModeDevCfgPage_t::activePart, data_ModeDevConfig_t::cfgPage, data_Mode_t::devcfg, GetPage(), ie_INVALID_ARG, ivd_Error, log_FUNC_m, m_mode, and pg_DEVCFG.

Referenced by Pn(), and bea_TapeMedium::ReadCurrentVolume().

                                          {
    if (GetPage() != pg_DEVCFG) {
        log_FUNC_m(GetCurPartNumber);
        throw ivd_Error(
            ie_INVALID_ARG,
            "Expected page DEVINFO, but not found.");
    }
    return (m_mode.devcfg.cfgPage.activePart);
}

Here is the call graph for this function:

Here is the caller graph for this function:

UInt8_t data_Mode::GetDensityCode (  )  const

Definition at line 158 of file data_mode.cpp.

References data_ModeDevConfig_t::blkDesc, data_ModeGenBlkDesc_t::densityCode, data_Mode_t::devcfg, GetPage(), ie_INVALID_ARG, ivd_Error, log_FUNC_m, m_mode, and pg_DEVCFG.

Referenced by bea_TapeMedium::RefreshTapeInfo().

                                        {
    if (GetPage() != pg_DEVCFG) {
        log_FUNC_m(GetDensityCode);
        throw ivd_Error(
            ie_INVALID_ARG,
            "Expected page DEVINFO, but not found.");
    }
    return (m_mode.devcfg.blkDesc.densityCode);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const data_Mode_t & data_Mode::GetModeStruct (  )  const
data_Mode::Page_t data_Mode::GetPage (  )  const

Definition at line 68 of file data_mode.cpp.

References data_ModePartitions_t::blkDesc, data_ModeHdr_t::blkDescLen, cmn_Num2Str(), data_ModePartPage_t::code, data_Mode_t::hdr, ie_INVALID_ARG, m_mode, data_Mode_t::part, and data_ModePartitions_t::partPage.

Referenced by cdb_ModeSense::cdb_ModeSense(), cdb_ModeSelect::GetBufferSize(), GetCurPartNumber(), GetDensityCode(), and IsMediumWORM().

                                         {
    if (m_mode.hdr.blkDescLen != sizeof(m_mode.part.blkDesc)) {
        throw ivd_InternalError(
            ie_INVALID_ARG,
            "BUG: MODE Block Descriptor should be " +
              cmn_Num2Str(sizeof(m_mode.part.blkDesc)) +
            " but is " +
              cmn_Num2Str(m_mode.hdr.blkDescLen) );
    }
    return (Page_t)(m_mode.part.partPage.code);
}

Here is the call graph for this function:

Here is the caller graph for this function:

UInt8_t data_Mode::GetPartCount (  )  const

Definition at line 85 of file data_mode.cpp.

References data_ModePartPage_t::addPart, data_ModePartitions_t::blkDesc, data_ModeHdr_t::blkDescLen, cmn_Num2Str(), data_ModePartPage_t::code, data_Mode_t::hdr, ie_INVALID_ARG, log_FUNC_m, m_mode, data_ModePartPage_t::maxAddPart, data_Mode_t::part, data_ModePartitions_t::partPage, and pg_PART.

Referenced by Append(), Ci(), Fmt(), GetCapacityInfo(), ParseTapeMedium(), Pi(), and bea_TapeMedium::RefreshTapeInfo().

                                      {

    if (m_mode.hdr.blkDescLen != sizeof(m_mode.part.blkDesc)) {
        log_FUNC_m(GetPartCount);
        throw ivd_InternalError(
            ie_INVALID_ARG,
            "BUG: MODE Block Descriptor should be " +
              cmn_Num2Str(sizeof(m_mode.part.blkDesc)) +
            " but is " +
              cmn_Num2Str(m_mode.hdr.blkDescLen) );
    }

    const data_ModePartPage_t &part = m_mode.part.partPage;

    if ((Page_t)part.code != pg_PART) {
        return 0;
    }

    if (part.maxAddPart == 0) {
        return 1;
    }

    return part.addPart + 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

UInt32_t data_Mode::GetPartSize ( UInt8_t  a_partNo  )  const

Definition at line 184 of file data_mode.cpp.

References data_ModePartitions_t::blkDesc, data_ModeHdr_t::blkDescLen, cmn_IntPow(), cmn_Num2Str(), data_ModePartPage_t::code, dbg_NORM, data_Mode_t::hdr, ie_INVALID_ARG, log_DBG_m, log_FUNC_m, m_mode, ntoh(), data_Mode_t::part, data_ModePartitions_t::partPage, data_ModePartPage_t::partUnits, pg_PART, data_ModePartPage_t::psum, data_ModePartitions_t::size, and size.

Referenced by Append(), Fmt(), ParseTapeMedium(), Pi(), and bea_TapeMedium::RefreshTapeInfo().

                                                      {
    log_FUNC_m(GetPartSize);

    if (m_mode.hdr.blkDescLen != sizeof(m_mode.part.blkDesc)) {
        throw ivd_InternalError(
            ie_INVALID_ARG,
            "BUG: MODE Block Descriptor should be " +
              cmn_Num2Str(sizeof(m_mode.part.blkDesc)) +
            " but is " +
              cmn_Num2Str(m_mode.hdr.blkDescLen) );
    }

    const data_ModePartitions_t &part = m_mode.part;

    if ((Page_t)part.partPage.code != pg_PART) {
        return 0;
    }

    UInt64_t    m;
    scsi_Wrapper16 size(part.size[a_partNo]);

    UInt64_t    ps = UInt64_t(ntoh(size));

    switch (part.partPage.psum) {
        case 0:
            m = 1;
            log_DBG_m(dbg_NORM, "Size in bytes: " << ps);
            break;
        case 1:
            m = 1024;
            log_DBG_m(dbg_NORM, "Size in kiB: " << ps);
            break;
        case 2:
            m = (1024 * 1024);
            log_DBG_m(dbg_NORM, "Size in MiB: " << ps);
            break;
        case 3:
            m = cmn_IntPow(UInt32_t(10), UInt32_t(part.partPage.partUnits));
            log_DBG_m(dbg_NORM,
                "Size in 10^" << UInt32_t(part.partPage.partUnits) <<
                ": " << ps);
            break;
        default: m = 0;
            m = 0;
            log_DBG_m(dbg_NORM, "Unknown size unit!!");
            break;
    }

    // Convert to MB.
    return ( (m * ps) / (1024 * 1024) );
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool data_Mode::IsMediumWORM (  )  const

Definition at line 168 of file data_mode.cpp.

References GetPage(), data_Mode_t::hdr, ie_INVALID_ARG, ivd_Error, log_FUNC_m, m_mode, data_ModeHdr_t::medType, mt_HP_WORM, mt_IBM_ULTRIUM_3_WORM, mt_IBM_ULTRIUM_4_WORM, and pg_DEVCFG.

Referenced by bea_TapeMedium::DetectLTOWORM(), and Mamisworm().

                                   {
    if (GetPage() != pg_DEVCFG) {
        log_FUNC_m(IsMediumWorm);
        throw ivd_Error(ie_INVALID_ARG,
            "Expected page DEVINFO, but not found.");
    }

    if (   (m_mode.hdr.medType == mt_HP_WORM) 
        || (m_mode.hdr.medType == mt_IBM_ULTRIUM_3_WORM)
        || (m_mode.hdr.medType == mt_IBM_ULTRIUM_4_WORM)    ) {
        return true;
    }

    return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void data_Mode::SetAITMode ( Mode_t  a_aitMode  ) 

Set AIT tape mode.

Definition at line 365 of file data_mode.cpp.

References data_ModeAITConfigPage_t::abs, data_ModeAITConfigPage_t::ait, data_Mode_t::ait, data_ModeAIT_t::aitPage, data_ModePartitions_t::blkDesc, data_ModeHdr_t::blkDescLen, cmn_Num2Str(), data_ModeAITConfigPage_t::code, data_ModeAITConfigPage_t::device, data_Mode_t::hdr, ie_INVALID_ARG, log_FUNC_m, log_WRN_m, m_mode, data_ModeHdr_t::medType, mode_DDS, data_ModeHdr_t::modeLen, data_Mode_t::part, pg_AITCFG, data_ModeAITConfigPage_t::span, data_ModeAITConfigPage_t::sysLogAlive, and data_ModeAITConfigPage_t::ulpbot.

Referenced by Fmt(), and bea_TapeMedium::Format().

                                           {
    log_FUNC_m(SetAITMode);

    if (m_mode.hdr.blkDescLen != sizeof(m_mode.part.blkDesc)) {
        throw ivd_InternalError(
            ie_INVALID_ARG,
            "BUG: MODE Block Descriptor should be " +
            cmn_Num2Str(sizeof(m_mode.part.blkDesc)) +
            " but is " +
            cmn_Num2Str(m_mode.hdr.blkDescLen) );
    }

    data_ModeAITConfigPage_t &ait = m_mode.ait.aitPage;

    if ((Page_t)ait.code != pg_AITCFG) {
        log_WRN_m(
            "Mode page is " << ait.code <<
            ". Expected " << pg_AITCFG);
        ait.code = pg_AITCFG;
    }

    // These two bytes are reserved (and must be 0) for MODE SELECT.
    m_mode.hdr.modeLen          = 0;
    m_mode.hdr.medType          = 0;

    if (a_aitMode == mode_DDS) {
        // AIT in DDS mode: AIT must be 0, DEVICE 0 and ULPBOT 1
        ait.ait            = 0;
        ait.device         = 0; // Do not create optional device area
        ait.ulpbot         = 1; // Load/unload must be performed at 
                                // the device area located at PBOT,
                                // even if there is an Optional Device Area.
    }
    else {
        //AIT in AIT mode: AIT must be 1, DEVICE 1 and ULPBOT 0
        ait.ait            = 1;
        ait.device         = 1; // Create optional device area
        ait.ulpbot         = 0; // Load/unload is performed at the Optional Device Area,
                                // except for partition 0, not in the beginning of tape
    }

    ait.abs            = 1; 
    ait.sysLogAlive    = 3; // BIN: 11
    ait.span           = 0x0a;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void data_Mode::SetAITUnloadAtPBOT ( bool  a_status  ) 

Set ulpbot bit.

Definition at line 414 of file data_mode.cpp.

References data_Mode_t::ait, data_ModeAIT_t::aitPage, log_FUNC_m, m_mode, and data_ModeAITConfigPage_t::ulpbot.

Referenced by bea_TapeMedium::Format().

Here is the caller graph for this function:

void data_Mode::SetCompressionStatus ( bool  a_compression  ) 

Definition at line 128 of file data_mode.cpp.

References data_ModeCompress_t::blkDesc, data_ModeHdr_t::blkDescLen, cmn_Num2Str(), data_Mode_t::compress, data_ModeCompress_t::compressPage, data_ModeCompressPage_t::dce, data_Mode_t::hdr, ie_INVALID_ARG, log_FUNC_m, m_mode, and data_ModeHdr_t::modeLen.

Referenced by Compression(), and bea_TapeMedium::RefreshCompressionState().

                                                             { //compress true <=> ON , false <=> OFF
    log_FUNC_m(SetCompressionStatus);
    if (m_mode.hdr.blkDescLen != sizeof(m_mode.compress.blkDesc)) {
        throw ivd_InternalError(
            ie_INVALID_ARG,
            "BUG: MODE Block Descriptor should be " +
              cmn_Num2Str(sizeof(m_mode.compress.blkDesc)) +
            " but is " +
              cmn_Num2Str(m_mode.hdr.blkDescLen) );
    }
    if (a_compression) {
        m_mode.compress.compressPage.dce = 1;
    }
    else {
        m_mode.compress.compressPage.dce = 0;
    }
    // needs to be set to 0, but log select sets it to 0x1B
    m_mode.hdr.modeLen = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void data_Mode::SetPage ( data_Mode::Page_t  a_page  ) 

Definition at line 62 of file data_mode.cpp.

References data_ModePartPage_t::code, m_mode, data_Mode_t::part, and data_ModePartitions_t::partPage.

Referenced by Append(), bea_TapeMedium::AppendVolume(), and data_Mode().

                                              {
    // First part of the union overlaps. It does not matter,
    // whether we use part or ait to set values.
    m_mode.part.partPage.code = static_cast<UInt8_t>(a_page);
}

Here is the caller graph for this function:

void data_Mode::SetPartitions ( vector< UInt32_t a_partSizes  ) 

Prepare a tape partitioning MODE page (pg_PART) and appending partition (pg_AIT_APPENDPART).

Values passed are in MB.

Definition at line 242 of file data_mode.cpp.

References data_ModePartPage_t::addp, data_ModePartPage_t::addPart, data_ModePartitions_t::blkDesc, data_ModeHdr_t::blkDescLen, data_ModePartPage_t::clear, cmn_Num2Str(), data_ModePartPage_t::code, dbg_LOW, dbg_NORM, data_ModePartPage_t::fdp, data_ModePartPage_t::fmtRec, data_Mode_t::hdr, hton(), data_ModePartPage_t::idp, ie_INVALID_ARG, ivd_Error, log_DBG_m, log_FUNC_m, log_WRN_m, m_mode, data_ModePartPage_t::maxAddPart, data_ModeHdr_t::medType, data_ModeHdr_t::modeLen, data_ModePartPage_t::pageLen, data_Mode_t::part, data_ModePartitions_t::partPage, data_ModePartPage_t::partUnits, pg_AIT_APPENDPART, pg_PART, data_ModePartPage_t::pofm, data_ModePartPage_t::psum, data_ModePartPage_t::sdp, size, and data_ModePartitions_t::size.

Referenced by Append(), bea_TapeMedium::AppendVolume(), Fmt(), and bea_TapeMedium::Format().

                                                           {
    log_FUNC_m(SetPartitions);

    if (m_mode.hdr.blkDescLen != sizeof(m_mode.part.blkDesc)) {
        throw ivd_InternalError(
            ie_INVALID_ARG,
            "BUG: MODE Block Descriptor should be " +
              cmn_Num2Str(sizeof(m_mode.part.blkDesc)) +
            " but is " +
              cmn_Num2Str(m_mode.hdr.blkDescLen) );
    }

    data_ModePartitions_t &part = m_mode.part;

    if (static_cast<Page_t>(part.partPage.code) == pg_AIT_APPENDPART) {
        if (a_partSizes.size() != 1) {
            throw ivd_Error(
                ie_INVALID_ARG,
                "Page pg_AIT_APPENDPART expects exactly one partition size.");
        }
    }
    else if ((Page_t)part.partPage.code != pg_PART) {
        log_WRN_m(
            "Mode page is " << static_cast<int>(part.partPage.code) <<
            ". Expected " << static_cast<int>(pg_PART) );
        part.partPage.code = pg_PART;
    }

    // ******************************************************************
    // Check for the unit that must be used to format this medium
    // AIT default units: MB
    // If any of the partitions exceeds 2^16-1 then a bigger unit must
    // be used.
    UInt16_t delimiter(1);
    UInt8_t  unit(0);
    static const UInt32_t mbLimit(0xFFFF);

    // Find the maximum values for the delimiter and unit
    for (UInt32_t i = 0; i < a_partSizes.size() ; i++) {
        if (a_partSizes[i] > mbLimit) {
            UInt16_t d = a_partSizes[i]/mbLimit;
            UInt16_t u(0);

            if (d < 10) { d = 10, u = 7; }
            else if(d < 100) { d = 100, u = 8; }
            else { d = 1000, u = 9; }

            if (d > delimiter) {
                delimiter = d, unit = u;
            }
        }
    };

    log_DBG_m(dbg_LOW,
        "Size delimiter: " << delimiter <<
        ", unit: " << int(unit) );

    if (delimiter > 1) {
        part.partPage.psum = 3;
    }
    else {
        part.partPage.psum = 2;
    };
    part.partPage.partUnits = unit;
    // ******************************************************************

    if (a_partSizes.size() <= 1) {
        log_DBG_m(dbg_NORM, "Number of additional partitions: 0" );
        part.partPage.addPart = 0;
        scsi_Wrapper16 sizeW(part.size[0]);
        sizeW = 0;
    }
    else {
        part.partPage.addPart = a_partSizes.size() - 1;
        log_DBG_m(dbg_NORM,
            "Number of additional partitions: " <<
            (int)(part.partPage.addPart));
    }

    if (   a_partSizes.size() > 1
        || static_cast<Page_t>(part.partPage.code) == pg_AIT_APPENDPART) {

        for (UInt32_t i = 0; i < a_partSizes.size() ; i++) {
            // Convert the sizes as determined above
            UInt16_t size = a_partSizes[i]/delimiter;
            UInt16_t netSize (hton(size));

            scsi_Wrapper16 sizeW(part.size[i]);
            sizeW = netSize;

            log_DBG_m(dbg_NORM, (i+1) << ". volume: " << size);
        }
    }

    // These two bytes are reserved (and must be 0) for MODE SELECT.
    m_mode.hdr.modeLen = 0;
    m_mode.hdr.medType = 0;

    if ( static_cast<Page_t>(part.partPage.code) == pg_AIT_APPENDPART ) {
        // Reset reserved fields for appending partition
        part.partPage.maxAddPart    = 0;
        part.partPage.addp          = 0;
        part.partPage.clear         = 0;
        part.partPage.pofm          = 0;
        part.partPage.idp           = 0;
        part.partPage.sdp           = 0;
        part.partPage.fdp           = 0;
        part.partPage.fmtRec        = 0;
    }
    else {
        part.partPage.idp     = 1;
    }

    // pageLen means the amount of data that follows pageLen field.
    // Therefore the "- 2".
    part.partPage.pageLen =
        sizeof(part.partPage) - 2 +
        (part.partPage.addPart+1) * sizeof(UInt16_t);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Reimplemented from scsi_Data.

Definition at line 194 of file data.h.


The documentation for this class was generated from the following files: