#include <scsi_io.h>


Successors of this class implement actual communication.
Definition at line 41 of file scsi_io.h.
Public Member Functions | |
| scsi_IO (const string &a_deviceID) | |
| Device identification is passed in constructor:. | |
| virtual | ~scsi_IO () |
| void | Open () |
| Open SCSI device. | |
| void | SkipAttAndDeferred () |
| void | WaitToBecomeReady () |
| virtual bool | IsOpen ()=0 |
| virtual void | Close ()=0 |
| virtual scsi_Status_e | GetCDBStatus ()=0 |
| virtual bool | IsSenseValid ()=0 |
| virtual void | IOCtl (const scsi_CDB &a_cdb, UInt32_t a_timeout=scsi_TIMEOUT_NORMAL_d) |
| void | SetDeviceID (string a_deviceID) |
| UInt32_t | GetPort () const |
| UInt32_t | GetChannel () const |
| UInt32_t | GetID () const |
| UInt32_t | GetLUN () const |
| string | GetSCSIID () const |
| const string & | GetDeviceName () const |
| scsi_DeviceType_e | GetDeviceType () const |
| const string & | GetVendorID () const |
| const string & | GetProductID () const |
| const string & | GetProductRevision () const |
| const string & | GetProductSerialNumber () const |
| UInt8_t | GetStandard () const |
| bool | GetPossibleMediumChange () const |
| const data_Sense_t * | GetSense () const |
| UInt32_t | GetSenseSize () const |
| UInt32_t | GetReadDifference () const |
| The difference between the requested and read data if SILI bit is set. | |
Protected Member Functions | |
| void | TestUnitReady () |
| virtual void | OpenByDeviceName ()=0 |
| Open SCSI device by its (platform specific!) name. | |
| virtual void | OpenBySCSIID ()=0 |
| Open SCSI device by its (current) SCSI ID. | |
| virtual void | OpenBySerialNumber ()=0 |
| Open SCSI device by its unique identification. | |
| virtual void | InqSCSIID ()=0 |
| Get SCSI ID of the currently opened device. | |
| void | InqStandard () |
| Do standard inquiry. | |
| void | InqSerialNumber () |
| Do inquiries necessary to get the serial number of the device. | |
| virtual int | DoIOCtl (const scsi_CDB &a_cdb, UInt32_t a_timeout)=0 |
| Function to actually execute CDB commands. | |
| virtual void | CheckDriverStatus (UInt8_t a_cdbCode) |
| Checks the status of the driver after the execution of CDB. | |
| virtual void | CheckHostStatus (UInt8_t a_cdbCode) |
| Checks the status of the host (if available) after the execution of CDB. | |
| void | CheckStatusAndSense (const scsi_CDB &a_cdb) |
| Checks the execution status and sense structure. | |
| void | Inquiry () |
Protected Attributes | |
| string | m_deviceID |
| Unique device identification, passed in constructor or SetDeviceID. | |
| string | m_deviceName |
| Device name. | |
| UInt32_t | m_port |
| Also known as bus or host. | |
| UInt32_t | m_channel |
| UInt32_t | m_id |
| UInt32_t | m_lun |
| string | m_strSCSIID |
| string | m_vendorID |
| string | m_productID |
| string | m_productSerialNumber |
| const scsi_SenseVnd * | m_vndSenseText |
| string | m_productRevision |
| scsi_DeviceType_e | m_deviceType |
| vector< data_Inquiry::inq_Page_t > | m_supportedPages |
| UInt8_t | m_standard |
| bool | m_possibleMediumChange |
| data_Sense_t | m_sense |
| bool | m_pdDirectMode |
| Direct passthrough mode can be disabled via env variable. | |
| UInt32_t | m_timeoutOverride |
| Default timeouts can be overridden with env. | |
| UInt32_t | m_testHWErrProbability |
| UInt32_t | m_testMedErrProbability |
Private Member Functions | |
| bool | IsPageSupported (data_Inquiry::inq_Page_t a_page) |
Private Attributes | |
| log_CLASSID_m | |
| scsi_IO::scsi_IO | ( | const string & | a_deviceID | ) |
Device identification is passed in constructor:.
sn:VENDOR_ID:DEVICE_ID:SERIAL_NUMBER .. open by serial numberid:PORT:CHANNEL:ID:LUN .. open by SCSI ID/dev/sgX) Definition at line 64 of file scsi_io.cpp.
References cmn_GetEnvVariable(), dbg_LOW, log_DBG_m, log_FUNC_A_m, m_pdDirectMode, m_testHWErrProbability, m_testMedErrProbability, m_timeoutOverride, NULL, scsi_ptDirect_c(), scsi_testHWerror_c(), scsi_testMederror_c(), scsi_testProbUnit(), and scsi_timeout_c().
00065 : m_deviceID(a_deviceID), 00066 m_deviceName(""), 00067 m_port(0xFF), 00068 m_channel(0xFF), 00069 m_id(0xFF), 00070 m_lun(0xFF), 00071 m_vendorID(""), 00072 m_productID(""), 00073 m_productSerialNumber(""), 00074 m_vndSenseText(NULL), 00075 m_productRevision(""), 00076 m_deviceType(dt_NO_LUN), 00077 m_standard(0), 00078 m_possibleMediumChange(false), 00079 m_pdDirectMode(true), 00080 m_timeoutOverride(0), 00081 m_testHWErrProbability(0), 00082 m_testMedErrProbability(0) { 00083 00084 log_FUNC_A_m(scsi_IO, "device: " << a_deviceID); 00085 00086 string ptDirect = cmn_GetEnvVariable(scsi_ptDirect_c); 00087 if (ptDirect == "no" || ptDirect == "false") { 00088 log_DBG_m(dbg_LOW, 00089 scsi_ptDirect_c << " = " << ptDirect << 00090 ". SCSI passthrough direct mode disabled."); 00091 00092 m_pdDirectMode = false; 00093 } 00094 00095 string timeout = cmn_GetEnvVariable(scsi_timeout_c); 00096 if (timeout.length() > 0) { 00097 log_DBG_m(dbg_LOW, scsi_timeout_c << " = " << timeout << " sec."); 00098 00099 m_timeoutOverride = atol(timeout.c_str()) * 1000; 00100 log_DBG_m(dbg_LOW, "SCSI timeout overridden value (ms): " << m_timeoutOverride); 00101 } 00102 00103 #ifdef scsi_SIMULATE_ERRORS_d 00104 // Reading env variables for simulating hardware/medium errors. 00105 string hwErr = cmn_GetEnvVariable(scsi_testHWerror_c); 00106 if (hwErr.length() > 0) { 00107 log_DBG_m(dbg_LOW, 00108 scsi_testHWerror_c << " = " << hwErr << 00109 " (1/" << scsi_testProbUnit << ")."); 00110 m_testHWErrProbability = atol(hwErr.c_str()); 00111 } 00112 00113 string medErr = cmn_GetEnvVariable(scsi_testMederror_c); 00114 if (medErr.length() > 0) { 00115 log_DBG_m(dbg_LOW, 00116 scsi_testMederror_c << " = " << medErr << 00117 " (1/" << scsi_testProbUnit << ")."); 00118 m_testMedErrProbability = atol(medErr.c_str()); 00119 } 00120 00121 // Set seed for better random 00122 if (m_testHWErrProbability > 0 || m_testMedErrProbability > 0) { 00123 time_t now = time(NULL); 00124 srand(now); 00125 } 00126 #endif 00127 00128 }

| scsi_IO::~scsi_IO | ( | ) | [virtual] |
Definition at line 130 of file scsi_io.cpp.
References log_FUNC_m.
00130 { 00131 log_FUNC_m(~scsi_IO); 00132 }
| void scsi_IO::Open | ( | ) |
Open SCSI device.
Calls one of the OpenBy.. functions..
Definition at line 224 of file scsi_io.cpp.
References dbg_LOW, idPrefix_c, ie_INVALID_ARG, ivd_Error, log_DBG_m, log_FUNC_m, m_channel, m_deviceID, m_deviceName, m_deviceType, m_id, m_lun, m_port, m_possibleMediumChange, m_productID, m_productRevision, m_productSerialNumber, m_standard, m_vendorID, OpenByDeviceName(), OpenBySCSIID(), OpenBySerialNumber(), scsi_GetDeviceTypeText(), and snPrefix_c.
Referenced by la_SCSILibrary::EjectMedium(), main(), la_SCSILibrary::Open(), ParseTapeMedium(), and STapeOpen().
00224 { 00225 log_FUNC_m(Open); 00226 00227 log_DBG_m(dbg_LOW, "Opening device ID: " << m_deviceID); 00228 00229 m_possibleMediumChange = false; 00230 00231 if (m_deviceID.substr(0, 3) == snPrefix_c) { 00232 // 00233 // Device should be open by its serial number. 00234 // Name is: 00235 // sn:VENDOR:PRODUCT:SERIAL_NUMBER 00236 // 00237 string::size_type start = snPrefix_c.length(); 00238 string::size_type end = m_deviceID.find(":", start); 00239 if (end == string::npos) { 00240 goto lbl_error; 00241 } 00242 m_vendorID = m_deviceID.substr(start, end-start); 00243 00244 start = end + 1; 00245 end = m_deviceID.find(":", start); 00246 if (end == string::npos) { 00247 goto lbl_error; 00248 } 00249 m_productID = m_deviceID.substr(start, end-start); 00250 00251 start = end + 1; 00252 m_productSerialNumber = m_deviceID.substr(start); 00253 00254 OpenBySerialNumber(); 00255 } 00256 else if (m_deviceID.substr(0, 3) == idPrefix_c) { 00257 // 00258 // Device should be open by its SCSI ID. 00259 // Name is: 00260 // id:PORT:CHANNEL:ID:LUN 00261 // 00262 string::size_type start = idPrefix_c.length(); 00263 string::size_type end = m_deviceID.find(":", start); 00264 if (end == string::npos) { 00265 goto lbl_error; 00266 } 00267 m_port = atoi(m_deviceID.substr(start, end-start).c_str()); 00268 00269 start = end + 1; 00270 end = m_deviceID.find(":", start); 00271 if (end == string::npos) { 00272 goto lbl_error; 00273 } 00274 m_channel = atoi(m_deviceID.substr(start, end-start).c_str()); 00275 00276 start = end + 1; 00277 end = m_deviceID.find(":", start); 00278 if (end == string::npos) { 00279 goto lbl_error; 00280 } 00281 m_id = atoi(m_deviceID.substr(start, end-start).c_str()); 00282 00283 start = end + 1; 00284 m_lun = atoi(m_deviceID.substr(start).c_str()); 00285 00286 OpenBySCSIID(); 00287 } 00288 else { 00289 // 00290 // Device should be open by its name directly. 00291 // 00292 m_deviceName = m_deviceID; 00293 00294 OpenByDeviceName(); 00295 } 00296 00297 log_DBG_m(dbg_LOW, endl << 00298 "** Device parameters **" << endl << 00299 "devName : " << "\'" << m_deviceName << "\'" << endl << endl << 00300 "port : " << m_port << endl << 00301 "channel : " << m_channel << endl << 00302 "id : " << m_id << endl << 00303 "lun : " << m_lun << endl << endl << 00304 "vendorID : " << "\'" << m_vendorID << "\'" << endl << 00305 "prodID : " << "\'" << m_productID << "\'" << endl << 00306 "prodSN : " << "\'" << m_productSerialNumber << "\'" << endl << 00307 "prodRev : " << "\'" << m_productRevision << "\'" << endl << endl << 00308 "devType : " << scsi_GetDeviceTypeText(m_deviceType) << endl << 00309 "standard : " << (int)m_standard); 00310 00311 return; 00312 00313 lbl_error: 00314 throw ivd_Error( 00315 ie_INVALID_ARG, 00316 "Invalid device name format: " + m_deviceID); 00317 }


| void scsi_IO::SkipAttAndDeferred | ( | ) |
Definition at line 387 of file scsi_io.cpp.
References dbg_NORM, ivd_BaseException::GetError(), GetSense(), ie_SCSI_UNIT_ATT, ivd_USleep, log_DBG_m, log_FUNC_m, log_WRN_m, m_deviceID, m_deviceName, m_vendorID, NULL, data_Sense_t::responseCode, sns_DEFERRED, and TestUnitReady().
Referenced by main(), and WaitToBecomeReady().
00387 { 00388 log_FUNC_m(SkipAttAndDeferred); 00389 00390 UInt32_t c_timeout = 60 * 20; // Timeout to finish TUR: 20 minutes 00391 ivd_Time_t timeStart = time(NULL); 00392 00393 log_DBG_m(dbg_NORM, "Skipping ATTENTION and old senses..."); 00394 00395 while(1) { 00396 try { 00397 TestUnitReady(); 00398 break; 00399 } 00400 catch (ivd_Error &ie) { 00401 ivd_Time_t now = time(NULL); 00402 00403 if (now - timeStart > c_timeout) { 00404 log_WRN_m( 00405 "Timeout doing TEST UNIT READY. " << 00406 "Device ID: " << m_deviceID << " " << 00407 "Device Name: " << m_deviceName << " " << 00408 "Vendor: " << m_vendorID); 00409 00410 throw; 00411 } 00412 00413 if (ie.GetError() == ie_SCSI_UNIT_ATT || 00414 GetSense()->responseCode == sns_DEFERRED) { 00415 log_DBG_m(dbg_NORM, 00416 "Skipping UNIT ATTENTION and DEFERRED senses."); 00417 00418 ivd_USleep(1000 * 10); // 1/100 s 00419 } 00420 else { 00421 throw; 00422 } 00423 } 00424 }; // while 00425 }


| void scsi_IO::WaitToBecomeReady | ( | ) |
Definition at line 321 of file scsi_io.cpp.
References data_Sense_t::additionalLen, data_Sense_t::asc, data_Sense_t::ascq, cmn_HexDump(), dbg_NORM, ivd_BaseException::GetError(), ie_SCSI_HWERR, ie_SCSI_NOT_READY, ie_SCSI_RETRY, ivd_Error, ivd_Sleep, log_DBG_m, log_FUNC_m, log_WRN_m, m_deviceID, m_deviceName, m_deviceType, m_productID, m_productRevision, m_productSerialNumber, m_sense, m_vendorID, m_vndSenseText, NULL, scsi_GetASCText(), scsi_GetSenseKeyText(), scsi_GetSenseText(), data_Sense_t::senseKey, SkipAttAndDeferred(), and TestUnitReady().
Referenced by la_SCSILibrary::EjectMedium(), bea_TapeVolume::GetPosition(), la_SCSILibrary::Inventory(), la_SCSILibrary::Load(), la_SCSILibrary::Open(), bea_TapeVolume::Rewind(), bea_TapeVolume::SeekBlock(), bea_TapeVolume::SeekEOD(), STapeOpen(), and la_SCSILibrary::Unload().
00321 { 00322 log_FUNC_m(WaitToBecomeReady); 00323 00324 UInt32_t c_timeout = 60 * 20; // Timeout to become ready: 20 minutes 00325 ivd_Time_t timeStart = time(NULL); 00326 00327 log_DBG_m(dbg_NORM, "Waiting to become ready..."); 00328 00329 while(1) { 00330 try { 00331 SkipAttAndDeferred(); 00332 TestUnitReady(); 00333 break; 00334 } 00335 catch (ivd_Error &ie) { 00336 ivd_Time_t now = time(NULL); 00337 00338 if (now - timeStart > c_timeout) { 00339 00340 if (m_sense.asc == 0x04 && 00341 m_sense.ascq == 0x00) { 00342 00343 string senseTxt = scsi_GetSenseText(m_sense, m_deviceType, m_vndSenseText); 00344 00345 ostringstream shortText; 00346 shortText 00347 << scsi_GetSenseKeyText((scsi_SenseKey_e)m_sense.senseKey) 00348 << " (" << scsi_GetASCText(m_sense, m_vndSenseText) << ")"; 00349 00350 // Detailed dump 00351 ostringstream dump; 00352 dump 00353 << "Device: " << m_vendorID << " " << m_productID << " " 00354 << m_productRevision << " s/n: " << m_productSerialNumber << endl 00355 << senseTxt << endl 00356 << "Sense dump (" << static_cast<UInt32_t>(m_sense.additionalLen+8) << " bytes) :" << endl 00357 << cmn_HexDump( 00358 reinterpret_cast<const void*>(&m_sense), m_sense.additionalLen+8, 8, true) << endl; 00359 00360 throw ivd_Error(ie_SCSI_HWERR, shortText.str(), dump.str()); 00361 } 00362 00363 log_WRN_m( 00364 "Timeout waiting device to become ready. " << 00365 "Device ID: " << m_deviceID << " " << 00366 "Device Name: " << m_deviceName << " " << 00367 "Vendor: " << m_vendorID); 00368 00369 throw; 00370 } 00371 00372 if ( ie.GetError() == ie_SCSI_NOT_READY 00373 || ie.GetError() == ie_SCSI_RETRY) { 00374 00375 log_DBG_m(dbg_NORM, "Device not ready yet. Retrying."); 00376 00377 ivd_Sleep(2); 00378 } 00379 else { 00380 throw; 00381 } 00382 } 00383 }; // while 00384 00385 }


| virtual bool scsi_IO::IsOpen | ( | ) | [pure virtual] |
Implemented in scsi_LnxSG, and scsi_WinSG.
Referenced by la_SCSILibrary::Close(), IOCtl(), and SetDeviceID().

| virtual void scsi_IO::Close | ( | ) | [pure virtual] |
Implemented in scsi_LnxSG, and scsi_WinSG.
Referenced by la_SCSILibrary::Close(), la_SCSILibrary::EjectMedium(), main(), la_SCSILibrary::Open(), ParseTapeMedium(), STapeClose(), and STapeOpen().

| virtual scsi_Status_e scsi_IO::GetCDBStatus | ( | ) | [pure virtual] |
Implemented in scsi_LnxSG, and scsi_WinSG.
Referenced by CheckStatusAndSense(), and scsi_WinSG::IsSenseValid().

| virtual bool scsi_IO::IsSenseValid | ( | ) | [pure virtual] |
Implemented in scsi_LnxSG, and scsi_WinSG.
Referenced by CheckStatusAndSense().

| void scsi_IO::IOCtl | ( | const scsi_CDB & | a_cdb, | |
| UInt32_t | a_timeout = scsi_TIMEOUT_NORMAL_d | |||
| ) | [virtual] |
################### DoIOCtl ###################
################### DoIOCtl ###################
Definition at line 433 of file scsi_io.cpp.
References data_Sense_t::additionalLen, CheckDriverStatus(), CheckHostStatus(), CheckStatusAndSense(), cmn_HexDump(), cmn_Num2Str(), dbg_DETAIL, dbg_GetLevel(), dbg_IsActive(), dbg_NORM, DoIOCtl(), evt_WARNING, scsi_CDB::GetBufferPointer(), scsi_CDB::GetBufferSize(), scsi_CDB::GetCmdPointer(), scsi_CDB::GetCmdSize(), ie_INVALID_ARG, ie_SCSI_HWERR, ie_SCSI_MEDERR, IsOpen(), data_Sense_t::isValid, ivd_Error, log_DBG_m, log_FUNC_m, log_MARKLINE_m, log_WriteEvent(), m_deviceID, m_sense, m_strSCSIID, m_testHWErrProbability, m_testMedErrProbability, m_timeoutOverride, op_READ_10, op_READ_6, op_WRITE_10, op_WRITE_6, data_Sense_t::responseCode, scsi_CommandSize(), scsi_GetOpcodeText(), scsi_testProbUnit(), data_Sense_t::senseKey, and size.
Referenced by Ait(), Append(), bea_TapeMedium::AppendVolume(), bea_TapeMedium::ChangeVolume(), CheckIVDHeader(), Ci(), Compression(), Cp(), Dens(), bea_MicMemory::Detect(), bea_TapeMedium::DetectAITWORM(), bea_TapeMedium::DetectLTOWORM(), Ea(), la_SCSILibrary::EjectMedium(), Eod(), Erase(), bea_TapeVolume::Erase(), FMSeek(), Fmt(), bea_TapeMedium::Format(), bea_MicMemory::GetAvailable(), bea_MamMemory::GetAvailable(), GetCapacityInfo(), bea_MicMemory::GetChecksum(), bea_MicMemory::GetManufacturer(), bea_MamMemory::GetManufacturer(), GetPos(), bea_TapeVolume::GetPosition(), bea_MicMemory::GetSecondaryID(), bea_MicMemory::GetSerialNumber(), bea_MamMemory::GetSerialNumber(), bea_MicMemory::GetSize(), InqSerialNumber(), InqStandard(), la_SCSILibrary::Inventory(), Inventory(), la_SCSILibrary::Load(), Load(), main(), Mamcapacity(), Mamdetect(), Mamfree(), Mamisworm(), Mamrmedinfo(), Mamrvolinfo(), Mamserial(), Mamwmedinfo(), Mamwvolinfo(), Micfree(), Micnote(), Micnotelen(), Micnotemap(), Micnotesize(), Micserial(), Micwritenote(), Mv(), ParseMICMediumNote(), ParseMICVolNote(), ParseTapeMedium(), ParseTapeMediumVolume(), ParseTapeMediumVolumeData(), ParseTapeMediumVolumeFRI(), ParseTapeMediumVolumeHeader(), Pi(), Pn(), Pos(), Rate(), Rd(), bea_MicMemory::Read(), bea_MamMemory::Read(), bea_MamMemory::ReadAttributeList(), ReadBlockPos(), bea_TapeMedium::ReadCurrentVolume(), la_SCSILibrary::ReadElementAssignment(), bea_TapeVolume::ReadEstimSizes(), ReadFromMedium(), ReadOneBackupFromMedium(), bea_TapeVolume::ReadRaw(), bea_TapeMedium::RefreshCompressionState(), bea_TapeMedium::RefreshTapeInfo(), Rewind(), bea_TapeVolume::Rewind(), RewindMedium(), Seek(), bea_TapeVolume::SeekBlock(), bea_TapeVolume::SeekEOD(), bea_TapeVolume::SeekFileMark(), SeekLastBackupFM(), Space(), Spacefm(), STapeOpen(), STapeWriteFileMark(), la_SCSILibrary::Status(), Status(), TestUnitReady(), la_SCSILibrary::Unload(), Unload(), Wfm(), bea_MicMemory::Write(), bea_MamMemory::Write(), bea_TapeVolume::WriteFileMarks(), bea_TapeVolume::WriteRaw(), WriteScsi(), and WriteToMedium().
00433 { 00434 log_FUNC_m(IOCtl); 00435 00436 if (!IsOpen()) { 00437 throw ivd_Error( 00438 ie_INVALID_ARG, "Device is not open. " + m_deviceID); 00439 } 00440 00441 UInt8_t cdbCode = a_cdb.GetCmdPointer()[0]; 00442 log_DBG_m(dbg_NORM, 00443 "CDB: " << scsi_GetOpcodeText(cdbCode) << 00444 " size: " << a_cdb.GetCmdSize()); 00445 00446 if (a_cdb.GetCmdSize() != scsi_CommandSize(cdbCode)) { 00447 log_MARKLINE_m; 00448 throw ivd_InternalError( 00449 ie_INVALID_ARG, 00450 string("Expected cdb size ") + cmn_Num2Str(scsi_CommandSize(cdbCode)) + 00451 string(" for CDB ") + scsi_GetOpcodeText(cdbCode)); 00452 } 00453 00454 // Init sense structure. 00455 m_sense.responseCode = 0, m_sense.isValid = 0, 00456 m_sense.senseKey = 0, m_sense.additionalLen = 0; 00457 00458 UInt32_t timeout(a_timeout); 00459 if (m_timeoutOverride > 0) { 00460 timeout = m_timeoutOverride; 00461 } 00462 00463 log_DBG_m(dbg_DETAIL, "Timeout = " << (timeout/1000/60) << " min.") 00464 00465 if (dbg_IsActive()) { 00466 // HEX dump of a command. 00467 const UInt8_t *cdb = a_cdb.GetCmdPointer(); 00468 UInt32_t size = a_cdb.GetCmdSize(); 00469 string dump = cmn_HexDump((const void*)cdb, size, 8, true); 00470 log_DBG_m(dbg_DETAIL, 00471 endl << "**** CDB HEX DUMP: ****" << endl << dump); 00472 } 00473 00475 int result = DoIOCtl(a_cdb, timeout); 00477 if (result != 0) { 00478 log_MARKLINE_m; 00479 throw ivd_SysError(result, scsi_GetOpcodeText(cdbCode), true); 00480 }; 00481 00482 // Do hex dump of data for non read/write operations. 00483 if ( cdbCode != op_READ_6 00484 && cdbCode != op_READ_10 00485 && cdbCode != op_WRITE_6 00486 && cdbCode != op_WRITE_10 00487 && dbg_IsActive()) { 00488 // HEX dump of data. 00489 UInt8_t *data = a_cdb.GetBufferPointer(); 00490 UInt32_t size = a_cdb.GetBufferSize(); 00491 00492 log_DBG_m(dbg_NORM, "DATA length " << a_cdb.GetBufferSize()); 00493 if (size > 0 && dbg_GetLevel() >= dbg_DETAIL) { 00494 string dump = cmn_HexDump( 00495 (const void*)data, (size < 256)? size : 256, 16, true); 00496 log_DBG_m(dbg_DETAIL, 00497 endl << "**** DATA HEX DUMP: ****" << endl << dump); 00498 } 00499 } 00500 00501 // Checks and throws 00502 CheckDriverStatus(cdbCode); 00503 // Checks and throws 00504 CheckHostStatus(cdbCode); 00505 // Checks and throws 00506 CheckStatusAndSense(a_cdb); 00507 00508 #ifdef scsi_SIMULATE_ERRORS_d 00509 if (m_testHWErrProbability > 0) { 00510 if ( cdbCode == op_READ_6 || cdbCode == op_READ_10 00511 || cdbCode == op_WRITE_6 || cdbCode == op_WRITE_10) { 00512 00513 if ( (rand() % scsi_testProbUnit) < m_testHWErrProbability ) { 00514 log_WriteEvent( 00515 evt_WARNING, "Simulated HW error.", "SCSI", 0, m_strSCSIID); 00516 throw ivd_Error(ie_SCSI_HWERR, "Triggered HW error for testing.", true); 00517 } 00518 } 00519 } 00520 00521 if (m_testMedErrProbability > 0) { 00522 if ( cdbCode == op_READ_6 || cdbCode == op_READ_10 00523 || cdbCode == op_WRITE_6 || cdbCode == op_WRITE_10) { 00524 00525 if ( (rand() % scsi_testProbUnit) < m_testMedErrProbability ) { 00526 log_WriteEvent( 00527 evt_WARNING, "Simulated medium error.", "SCSI", 0, m_strSCSIID); 00528 throw ivd_Error(ie_SCSI_MEDERR, "Triggered medium error for testing.", true); 00529 } 00530 } 00531 } 00532 #endif 00533 00534 }

| void scsi_IO::SetDeviceID | ( | string | a_deviceID | ) |
Definition at line 134 of file scsi_io.cpp.
References ie_INVALID_ARG, IsOpen(), ivd_Error, log_FUNC_A_m, and m_deviceID.
Referenced by la_SCSILibrary::SetDeviceID().
00134 { 00135 log_FUNC_A_m(SetDeviceID, "device: " << a_deviceID); 00136 00137 if (IsOpen()) { 00138 throw ivd_Error( 00139 ie_INVALID_ARG, "Trying to change device's ID while open."); 00140 } 00141 m_deviceID = a_deviceID; 00142 }


| UInt32_t scsi_IO::GetPort | ( | ) | const |
Definition at line 156 of file scsi_io.cpp.
References m_port.
Referenced by main(), and STapeOpen().
00156 { 00157 return m_port; 00158 }

| UInt32_t scsi_IO::GetChannel | ( | ) | const |
Definition at line 152 of file scsi_io.cpp.
References m_channel.
Referenced by main(), and STapeOpen().
00152 { 00153 return m_channel; 00154 }

| UInt32_t scsi_IO::GetID | ( | ) | const |
Definition at line 145 of file scsi_io.cpp.
References m_id.
Referenced by main(), and STapeOpen().
00145 { 00146 return m_id; 00147 }

| UInt32_t scsi_IO::GetLUN | ( | ) | const |
Definition at line 149 of file scsi_io.cpp.
References m_lun.
Referenced by main(), and STapeOpen().
00149 { 00150 return m_lun; 00151 }

| string scsi_IO::GetSCSIID | ( | ) | const |
Definition at line 160 of file scsi_io.cpp.
References m_channel, m_id, m_lun, and m_port.
Referenced by la_SCSILibrary::GetSCSIID(), and scsi_LnxSG::InqSCSIID().
00160 { 00161 ostringstream sstr; 00162 sstr 00163 << "id:" 00164 << m_port << ":" 00165 << m_channel << ":" 00166 << m_id << ":" 00167 << m_lun; 00168 00169 return sstr.str(); 00170 }

| const string & scsi_IO::GetDeviceName | ( | ) | const |
Definition at line 172 of file scsi_io.cpp.
References m_deviceName.
Referenced by main().
00172 { 00173 return m_deviceName; 00174 }

| scsi_DeviceType_e scsi_IO::GetDeviceType | ( | ) | const |
Definition at line 176 of file scsi_io.cpp.
References m_deviceType.
Referenced by la_SCSILibrary::EjectMedium(), main(), la_SCSILibrary::Open(), and STapeOpen().
00176 { 00177 return m_deviceType; 00178 }

| const string & scsi_IO::GetVendorID | ( | ) | const |
Definition at line 180 of file scsi_io.cpp.
References m_vendorID.
Referenced by Append(), Fmt(), bea_TapeMedium::Format(), la_SCSILibrary::GetVendorID(), main(), la_SCSILibrary::Open(), ParseMICMediumNote(), and ParseMICVolNote().
00180 { 00181 return m_vendorID; 00182 }

| const string & scsi_IO::GetProductID | ( | ) | const |
Definition at line 184 of file scsi_io.cpp.
References m_productID.
Referenced by Append(), Fmt(), bea_TapeMedium::Format(), la_SCSILibrary::GetProductID(), main(), and la_SCSILibrary::Open().
00184 { 00185 return m_productID; 00186 }

| const string & scsi_IO::GetProductRevision | ( | ) | const |
Definition at line 188 of file scsi_io.cpp.
References m_productRevision.
Referenced by bea_TapeMedium::Format(), la_SCSILibrary::GetProductRevision(), and main().
00188 { 00189 return m_productRevision; 00190 }

| const string & scsi_IO::GetProductSerialNumber | ( | ) | const |
Definition at line 191 of file scsi_io.cpp.
References m_productSerialNumber.
Referenced by bea_TapeMedium::Format(), la_SCSILibrary::GetSerialNumber(), and main().
00191 { 00192 return m_productSerialNumber; 00193 }

| UInt8_t scsi_IO::GetStandard | ( | ) | const |
Definition at line 195 of file scsi_io.cpp.
References m_standard.
Referenced by main().
00195 { 00196 return m_standard; 00197 }

| bool scsi_IO::GetPossibleMediumChange | ( | ) | const |
Definition at line 199 of file scsi_io.cpp.
References m_possibleMediumChange.
00199 { 00200 return m_possibleMediumChange; 00201 }
| const data_Sense_t * scsi_IO::GetSense | ( | ) | const |
Definition at line 204 of file scsi_io.cpp.
References m_sense.
Referenced by scsi_LnxSG::DoIOCtl(), ParseTapeMedium(), and SkipAttAndDeferred().
00204 { 00205 return &m_sense; 00206 }

| UInt32_t scsi_IO::GetSenseSize | ( | ) | const |
Definition at line 208 of file scsi_io.cpp.
References m_sense.
Referenced by scsi_LnxSG::DoIOCtl().
00208 { 00209 return sizeof(m_sense); 00210 }

| UInt32_t scsi_IO::GetReadDifference | ( | ) | const |
The difference between the requested and read data if SILI bit is set.
Definition at line 212 of file scsi_io.cpp.
References data_Sense_t::incorrectLength, data_Sense_t::infoBytes, data_Sense_t::isValid, m_sense, and ntoh().
Referenced by Rd(), and ReadOneBackupFromMedium().
00212 { 00213 if (m_sense.incorrectLength == 0 || m_sense.isValid == 0) { 00214 return 0; 00215 } 00216 return static_cast<UInt32_t>(ntoh(m_sense.infoBytes)); 00217 }


| void scsi_IO::TestUnitReady | ( | ) | [protected] |
Definition at line 427 of file scsi_io.cpp.
References IOCtl().
Referenced by SkipAttAndDeferred(), and WaitToBecomeReady().
00427 { 00428 cdb_TestUnitReady tur; 00429 IOCtl(tur); 00430 }


| virtual void scsi_IO::OpenByDeviceName | ( | ) | [protected, pure virtual] |
Open SCSI device by its (platform specific!) name.
Implemented in scsi_LnxSG, and scsi_WinSG.
Referenced by Open().

| virtual void scsi_IO::OpenBySCSIID | ( | ) | [protected, pure virtual] |
Open SCSI device by its (current) SCSI ID.
Implemented in scsi_LnxSG, and scsi_WinSG.
Referenced by Open().

| virtual void scsi_IO::OpenBySerialNumber | ( | ) | [protected, pure virtual] |
Open SCSI device by its unique identification.
Implemented in scsi_LnxSG, and scsi_WinSG.
Referenced by Open().

| virtual void scsi_IO::InqSCSIID | ( | ) | [protected, pure virtual] |
| void scsi_IO::InqStandard | ( | ) | [protected] |
Do standard inquiry.
It gets:
Definition at line 791 of file scsi_io.cpp.
References data_StdInquiry_t::ansi, cmn_Num2Str(), dbg_DETAIL, dbg_LOW, dbg_NORM, dt_MEDIUM_CHANGER, dt_TAPE, ivd_BaseException::GetFriendly(), cdb_Inquiry::GetInquiry(), data_Inquiry::GetInquiryData(), data_Inquiry::inq_PAGES, data_Inquiry_t::inqstd, inqstd_PROD_REVISION_LEN_d, inqstd_PRODUCT_ID_LEN_d, inqstd_VENDOR_ID_LEN_d, IOCtl(), log_DBG_m, log_FUNC_m, m_deviceType, m_productID, m_productRevision, m_standard, m_supportedPages, m_vendorID, m_vndSenseText, data_InqPages_t::pageLen, data_InqPages_t::pages, data_StdInquiry_t::productID, data_StdInquiry_t::productRevision, scsi_GetDeviceTypeText(), scsi_GetVndAddSnsTbl(), data_Inquiry_t::supportedPages, data_StdInquiry_t::type, and data_StdInquiry_t::vendorID.
Referenced by scsi_LnxSG::OpenByDeviceName().
00791 { 00792 log_FUNC_m(InqStandard); 00793 00794 { 00795 log_DBG_m(dbg_NORM, "Standard INQ:") 00796 // Standard inquiry 00797 00798 cdb_Inquiry scsistd; 00799 IOCtl(scsistd); 00800 const data_Inquiry_t &inquiry = scsistd.GetInquiry().GetInquiryData(); 00801 00802 this->m_deviceType = scsi_DeviceType_e(inquiry.inqstd.type); 00803 log_DBG_m(dbg_DETAIL, "Device type: " 00804 << scsi_GetDeviceTypeText(m_deviceType) 00805 << "(" << m_deviceType << ")"); 00806 m_vendorID = string( 00807 (const char*)inquiry.inqstd.vendorID, inqstd_VENDOR_ID_LEN_d); 00808 m_productID = string( 00809 (const char*)inquiry.inqstd.productID, inqstd_PRODUCT_ID_LEN_d); 00810 m_productRevision = string( 00811 (const char*)inquiry.inqstd.productRevision, inqstd_PROD_REVISION_LEN_d); 00812 m_standard = inquiry.inqstd.ansi; 00813 } 00814 00815 try { 00816 if ( (m_deviceType == dt_MEDIUM_CHANGER) || (m_deviceType == dt_TAPE)) { 00817 // Supported pages 00818 cdb_Inquiry pages(data_Inquiry::inq_PAGES); 00819 IOCtl(pages); 00820 00821 const data_Inquiry_t &inquiry = pages.GetInquiry().GetInquiryData(); 00822 string strpages; 00823 00824 for (int i = 0; i < inquiry.supportedPages.pageLen; i++) { 00825 strpages += cmn_Num2Str(inquiry.supportedPages.pages[i], true) + " "; 00826 m_supportedPages.push_back( 00827 (data_Inquiry::inq_Page_t)inquiry.supportedPages.pages[i]); 00828 } 00829 log_DBG_m(dbg_LOW, "Supported INQUIRY pages " << strpages); 00830 } 00831 else { 00832 log_DBG_m(dbg_LOW, "Device type (" 00833 << scsi_GetDeviceTypeText(m_deviceType) 00834 << ") not supported. => INQUIRY pages empty"); 00835 } 00836 } 00837 catch (const ivd_Error& ie) { 00838 log_DBG_m(dbg_NORM, 00839 "Vital product data not supported by this device." << 00840 ie.GetFriendly()); 00841 } 00842 00843 m_vndSenseText = scsi_GetVndAddSnsTbl(m_vendorID, m_productID); 00844 }


| void scsi_IO::InqSerialNumber | ( | ) | [protected] |
Do inquiries necessary to get the serial number of the device.
Do inquiries necessary to get the serial number of the SCSI device.
Definition at line 847 of file scsi_io.cpp.
References dbg_DETAIL, dbg_LOW, dbg_NORM, data_InqDeviceID_t::devID, data_Inquiry_t::devID, cdb_Inquiry::GetInquiry(), data_Inquiry::GetInquiryData(), id, data_InqDevId_t::idType, ie_NYI, ie_SCSI_INVRESULT, data_InqDevId_t::ieee, data_Inquiry::inq_DEVID, data_Inquiry::inq_SERNO, IOCtl(), IsPageSupported(), log_DBG_m, log_ERR_m, log_FUNC_m, log_WRN_m, m_productSerialNumber, data_InqDeviceID_t::pageLen, data_InqSerialNo_t::pageLen, data_InqDevId_t::pcph, data_Inquiry::pg_DEVID, data_Inquiry::pg_SERNO, data_InqSerialNo_t::serNumber, data_Inquiry_t::serNumber, and data_InqDevId_t::vendor.
Referenced by scsi_LnxSG::OpenByDeviceName().
00847 { 00848 log_FUNC_m(InqSerialNumber); 00849 00850 try { 00851 if (IsPageSupported(data_Inquiry::pg_SERNO)) { 00852 // Serial number page 00853 cdb_Inquiry ser(data_Inquiry::inq_SERNO); 00854 IOCtl(ser); 00855 const data_Inquiry_t &inquiry = ser.GetInquiry().GetInquiryData(); 00856 log_DBG_m(dbg_DETAIL, 00857 "serNumber.pageLen = " << (int)(inquiry.serNumber.pageLen)); 00858 00859 if (inquiry.serNumber.pageLen > 0) { 00860 00861 m_productSerialNumber = string( 00862 (const char*)inquiry.serNumber.serNumber, 00863 inquiry.serNumber.pageLen); 00864 00865 // strip potentional trailing blanks 00866 string::size_type last = m_productSerialNumber.find_last_not_of(string(" \0",2)); 00867 if ( (last != string::npos) && ((last+1) < m_productSerialNumber.size())) { 00868 m_productSerialNumber.erase(last+1); 00869 } 00870 00871 log_DBG_m(dbg_LOW, 00872 "Device serial number " << m_productSerialNumber); 00873 } 00874 else { 00875 log_WRN_m( 00876 "Serial number page supported but it does not contain any info"); 00877 } 00878 } 00879 else if (IsPageSupported(data_Inquiry::pg_DEVID)) { 00880 // Device ID 00881 log_WRN_m("pg_DEVID is untested. Will it work??"); 00882 cdb_Inquiry id(data_Inquiry::inq_DEVID); 00883 IOCtl(id); 00884 const data_Inquiry_t &inquiry = id.GetInquiry().GetInquiryData(); 00885 if (inquiry.devID.pageLen > 0) { 00886 switch (inquiry.devID.devID.idType) { 00887 case 1: 00888 log_DBG_m(dbg_NORM, "Serial number from DEV ID."); 00889 m_productSerialNumber = string( 00890 (const char*)inquiry.devID.devID.vendor.serialNo, 00891 inquiry.devID.pageLen-8-16); 00892 break; 00893 case 2: 00894 log_ERR_m("IEEE INQ page not supported: " << 00895 string((const char*)inquiry.devID.devID.ieee, 64) ); 00896 throw ivd_InternalError(ie_SCSI_INVRESULT); 00897 break; 00898 case 3: 00899 log_ERR_m("PCPH INQ page not supported: " << 00900 string((const char*)inquiry.devID.devID.pcph, 64) ); 00901 throw ivd_InternalError(ie_SCSI_INVRESULT); 00902 break; 00903 default: 00904 log_ERR_m("Unknown DEV ID Type " << inquiry.devID.devID.idType); 00905 throw ivd_InternalError(ie_SCSI_INVRESULT); 00906 break; 00907 } 00908 log_DBG_m(dbg_LOW, "Device serial number " << m_productSerialNumber); 00909 throw ivd_InternalError(ie_NYI, "Device ID Inquiry"); 00910 } 00911 else { 00912 log_WRN_m( 00913 "Device ID page supported but it does not contain any info."); 00914 } 00915 } // if (IsPage... 00916 else { 00917 log_DBG_m(dbg_LOW, "Device does not support serial number."); 00918 } 00919 } 00920 catch (ivd_Error &ie) { 00921 log_DBG_m(dbg_NORM, "Error doing device version inquiry: " << endl << ie); 00922 throw; 00923 } 00924 catch (ivd_SysError &ie) { 00925 log_DBG_m(dbg_NORM, "Error doing device version inquiry: " << endl << ie); 00926 throw; 00927 } 00928 }


| virtual int scsi_IO::DoIOCtl | ( | const scsi_CDB & | a_cdb, | |
| UInt32_t | a_timeout | |||
| ) | [protected, pure virtual] |
Function to actually execute CDB commands.
Implemented in scsi_LnxSG, and scsi_WinSG.
Referenced by IOCtl().

| virtual void scsi_IO::CheckDriverStatus | ( | UInt8_t | a_cdbCode | ) | [inline, protected, virtual] |
Checks the status of the driver after the execution of CDB.
Reimplemented in scsi_LnxSG, and scsi_WinSG.
Definition at line 137 of file scsi_io.h.
Referenced by IOCtl().

| virtual void scsi_IO::CheckHostStatus | ( | UInt8_t | a_cdbCode | ) | [inline, protected, virtual] |
Checks the status of the host (if available) after the execution of CDB.
Reimplemented in scsi_LnxSG, and scsi_WinSG.
Definition at line 144 of file scsi_io.h.
Referenced by IOCtl().

| void scsi_IO::CheckStatusAndSense | ( | const scsi_CDB & | a_cdb | ) | [protected] |
Checks the execution status and sense structure.
Analysing the SCSI sense buffer.
Platform independent check.
| ivd_Error | Throws different exceptions for each of the statuses. |
Definition at line 540 of file scsi_io.cpp.
References data_Sense_t::additionalLen, data_Sense_t::ait, data_Sense_t::asc, data_Sense_t::ascq, data_AIT_Sense_t::clean, cmn_HexDump(), dbg_DETAIL, dt_TAPE, data_Sense_t::eom, evt_CRITICAL, evt_ERROR, evt_WARNING, data_Sense_t::fileMark, scsi_CDB::GetBufferPointer(), scsi_CDB::GetBufferSize(), GetCDBStatus(), scsi_CDB::GetCmdPointer(), scsi_CDB::GetCmdSize(), ie_SCSI_BLANK, ie_SCSI_DESTFULL, ie_SCSI_EOD, ie_SCSI_EOM, ie_SCSI_FILEMARK, ie_SCSI_HWERR, ie_SCSI_ILENGTH, ie_SCSI_ILREQ, ie_SCSI_MEDERR, ie_SCSI_NO_MEDIUM, ie_SCSI_NOT_READY, ie_SCSI_OVERFLOW, ie_SCSI_PROTECTED, ie_SCSI_RETRY, ie_SCSI_SENSE, ie_SCSI_SRCEMPTY, ie_SCSI_STATUS, ie_SCSI_UNIT_ATT, data_Sense_t::incorrectLength, IsSenseValid(), ivd_Error, log_DBG_m, log_FUNC_m, log_MARKLINE_m, log_WriteEvent(), log_WRN_m, m_deviceType, m_possibleMediumChange, m_productID, m_productRevision, m_productSerialNumber, m_sense, m_strSCSIID, m_vendorID, m_vndSenseText, data_AIT_Sense_t::mew, scsi_GetASCText(), scsi_GetOpcodeText(), scsi_GetSenseKeyText(), scsi_GetSenseText(), scsi_GetStatusText(), data_Sense_t::senseKey, sk_ABORTED_COMMAND, sk_BLANK_CHECK, sk_COPY_ABORTED, sk_DATA_PROTECT, sk_HARDWARE_ERROR, sk_ILLEGAL_REQUEST, sk_MEDIUM_ERROR, sk_MISCOMPARE, sk_NO_SENSE, sk_NOT_READY, sk_OBSOLETE, sk_RECOVERED_ERROR, sk_RESERVED, sk_UNIT_ATTENTION, sk_VENDOR_SPECIFIC, sk_VOLUME_OVERFLOW, st_ACA_ACTIVE, st_BUSY, st_CHECK_CONDITION, st_COMMAND_TERMINATED, st_CONDITION_GOOD, st_GOOD, st_INTERMEDIATE_C_GOOD, st_INTERMEDIATE_GOOD, st_QUEUE_FULL, and st_RESERVATION_CONFLICT.
Referenced by IOCtl().
00540 { 00541 00542 if (!IsSenseValid()) { 00543 return; 00544 } 00545 00546 log_FUNC_m(CheckStatusAndSense); 00547 00548 scsi_Status_e status = GetCDBStatus(); 00549 00550 log_DBG_m(dbg_DETAIL, 00551 "CDB Status: 0x" << 00552 hex << status << dec << " " << 00553 scsi_GetStatusText(status) 00554 ); 00555 00556 // HEX dump of a command. 00557 const UInt8_t *cdb = a_cdb.GetCmdPointer(); 00558 UInt8_t cdbCode = cdb[0]; 00559 UInt32_t cdbSize = a_cdb.GetCmdSize(); 00560 // HEX dump of data. 00561 UInt8_t *data = a_cdb.GetBufferPointer(); 00562 UInt32_t dataSize = a_cdb.GetBufferSize(); 00563 00564 string senseTxt = scsi_GetSenseText(m_sense, m_deviceType, m_vndSenseText); 00565 00566 ostringstream shortText; 00567 shortText 00568 << scsi_GetSenseKeyText((scsi_SenseKey_e)m_sense.senseKey) 00569 << " (" << scsi_GetASCText(m_sense, m_vndSenseText) << ")"; 00570 00571 // Detailed dump 00572 ostringstream dump; 00573 dump 00574 << "Device: " << m_vendorID << " " << m_productID << " " 00575 << m_productRevision << " s/n: " << m_productSerialNumber << endl 00576 << senseTxt << endl 00577 << "Sense dump (" << static_cast<UInt32_t>(m_sense.additionalLen+8) << " bytes) :" << endl 00578 << cmn_HexDump( 00579 reinterpret_cast<const void*>(&m_sense), m_sense.additionalLen+8, 8, true) << endl 00580 00581 << "CDB: " << scsi_GetOpcodeText(cdbCode) << endl 00582 << cmn_HexDump( 00583 reinterpret_cast<const void*>(cdb), cdbSize, 8, true) << endl 00584 00585 << "DATA length: " << dataSize << endl 00586 << "DATA:" << endl 00587 << cmn_HexDump( 00588 reinterpret_cast<const void*>(data), (dataSize < 256)? dataSize : 256, 16, true); 00589 00590 00591 switch (status) { 00592 case st_GOOD: 00593 break; 00594 case st_CHECK_CONDITION: 00595 case st_BUSY: 00596 case st_COMMAND_TERMINATED: 00597 break; 00598 case st_RESERVATION_CONFLICT: 00599 log_MARKLINE_m; 00600 throw ivd_InternalError( 00601 ie_SCSI_STATUS, "Reservation not used.", dump.str()); 00602 break; 00603 00604 case st_CONDITION_GOOD: 00605 case st_INTERMEDIATE_GOOD: 00606 case st_INTERMEDIATE_C_GOOD: 00607 case st_QUEUE_FULL: 00608 case st_ACA_ACTIVE: 00609 default: 00610 log_MARKLINE_m; 00611 throw ivd_InternalError( 00612 ie_SCSI_STATUS, scsi_GetStatusText(status), dump.str()); 00613 break; 00614 } 00615 00616 // 00617 // Detect and log cleaning and media warning (works for AIT tape drives) 00618 // 00619 if (m_deviceType == dt_TAPE && m_sense.additionalLen > 19) { 00620 if (m_sense.ait.clean != 0) { 00621 ostringstream sstr; 00622 sstr 00623 << "Device: " << m_vendorID << " " << m_productID << " " 00624 << m_productRevision << " s/n: " << m_productSerialNumber 00625 << " is requesting cleaning."; 00626 log_WriteEvent( 00627 evt_WARNING, sstr.str(), "SCSI", 0, m_strSCSIID); 00628 } 00629 if (m_sense.ait.mew != 0) { 00630 ostringstream sstr; 00631 sstr 00632 << "Device: " << m_vendorID << " " << m_productID << " " 00633 << m_productRevision << " s/n: " << m_productSerialNumber 00634 << " is reporting media warning."; 00635 log_WriteEvent( 00636 evt_WARNING, sstr.str(), "SCSI", 0, m_strSCSIID); 00637 } 00638 } 00639 00640 // Decode sense information 00641 if (status == st_BUSY || status == st_COMMAND_TERMINATED) { 00642 log_MARKLINE_m; 00643 throw ivd_Error(ie_SCSI_RETRY, shortText.str(), dump.str(), true); 00644 } 00645 switch (m_sense.senseKey) { 00646 case sk_ILLEGAL_REQUEST: 00647 log_MARKLINE_m; 00648 if (m_sense.asc == 0x3B && m_sense.ascq == 0x0D) { 00649 log_WriteEvent( 00650 evt_WARNING, 00651 shortText.str(), "SCSI", 0, m_strSCSIID); 00652 throw ivd_Error(ie_SCSI_DESTFULL, shortText.str(), dump.str()); 00653 } 00654 else if (m_sense.asc == 0x3B && m_sense.ascq == 0x0E) { 00655 log_WriteEvent( 00656 evt_WARNING, 00657 shortText.str(), "SCSI", 0, m_strSCSIID); 00658 throw ivd_Error(ie_SCSI_SRCEMPTY, shortText.str(), dump.str()); 00659 } 00660 log_WriteEvent( 00661 evt_ERROR, 00662 shortText.str(), "SCSI", 0, m_strSCSIID); 00663 throw ivd_Error(ie_SCSI_ILREQ, shortText.str(), dump.str(), true); 00664 break; 00665 case sk_NOT_READY: 00666 log_MARKLINE_m; 00667 if (m_sense.asc == 0x3A) { 00668 throw ivd_Error(ie_SCSI_NO_MEDIUM, shortText.str(), dump.str()); 00669 } 00670 throw ivd_Error(ie_SCSI_NOT_READY, shortText.str(), dump.str()); 00671 break; 00672 case sk_RECOVERED_ERROR: 00673 log_MARKLINE_m; 00674 // See SCSI documentation (or scsi_err.cpp) for details. 00675 if (m_sense.asc == 0x00 && m_sense.ascq == 0x01) { 00676 throw ivd_Error(ie_SCSI_FILEMARK, shortText.str(), dump.str()); 00677 } 00678 if (m_sense.asc == 0x00 && m_sense.ascq == 0x02) { 00679 throw ivd_Error(ie_SCSI_EOM, shortText.str(), dump.str()); 00680 } 00681 // Else log and check file mark, etc after the switch. 00682 log_WRN_m("RECOVERED ERROR: " << dump.str()); 00683 break; 00684 case sk_MEDIUM_ERROR: 00685 log_MARKLINE_m; 00686 log_WriteEvent(evt_ERROR, shortText.str(), "SCSI", 0, m_strSCSIID); 00687 throw ivd_Error(ie_SCSI_MEDERR, shortText.str(), dump.str(), true); 00688 break; 00689 case sk_HARDWARE_ERROR: 00690 log_MARKLINE_m; 00691 log_WriteEvent(evt_ERROR, shortText.str(), "SCSI", 0, m_strSCSIID); 00692 throw ivd_Error(ie_SCSI_HWERR, shortText.str(), dump.str(), true); 00693 break; 00694 case sk_UNIT_ATTENTION: 00695 log_MARKLINE_m; 00696 // See SCSI documentation (or scsi_err.cpp) for details. 00697 if ( ((m_sense.asc == 0x28) && (m_sense.ascq == 0x00)) 00698 || ((m_sense.asc == 0x29) && (m_sense.ascq == 0x00)) ) { 00699 // 28: Not ready to transition (medium may have changed) 00700 // 29: Power on, reset, or bus device reset occurred 00701 m_possibleMediumChange = true; 00702 } 00703 throw ivd_Error(ie_SCSI_UNIT_ATT, shortText.str(), dump.str()); 00704 break; 00705 case sk_DATA_PROTECT: 00706 log_MARKLINE_m; 00707 throw ivd_Error(ie_SCSI_PROTECTED, shortText.str(), dump.str(), true); 00708 break; 00709 case sk_BLANK_CHECK: 00710 log_MARKLINE_m; 00711 // See SCSI documentation (or scsi_err.cpp) for details. 00712 if (m_sense.asc == 0x00 && m_sense.ascq == 0x05) { 00713 throw ivd_Error(ie_SCSI_EOD, shortText.str(), dump.str()); 00714 } 00715 throw ivd_Error(ie_SCSI_BLANK, shortText.str(), dump.str()); 00716 break; 00717 case sk_VOLUME_OVERFLOW: 00718 log_MARKLINE_m; 00719 log_WriteEvent( 00720 evt_WARNING, 00721 shortText.str() + " Physical end of medium or media volume", 00722 "SCSI", 0, m_strSCSIID); 00723 throw ivd_Error(ie_SCSI_OVERFLOW, shortText.str(), dump.str(), true); 00724 break; 00725 00726 // The following sense codes are treated as critical. 00727 case sk_VENDOR_SPECIFIC: 00728 log_MARKLINE_m; 00729 // 00730 // Throw ivd_Error for: 00731 // AIT: MIC exists but is not used. 00732 // 00733 if (m_sense.asc == 0x83 && 00734 m_sense.ascq == 0x83) { 00735 throw ivd_Error(ie_SCSI_SENSE, shortText.str(), dump.str()); 00736 } 00737 00738 log_WriteEvent( 00739 evt_CRITICAL, 00740 shortText.str(), "SCSI", 0, m_strSCSIID); 00741 00742 throw ivd_Error(ie_SCSI_SENSE, shortText.str(), dump.str(), true); 00743 break; 00744 case sk_COPY_ABORTED: 00745 case sk_ABORTED_COMMAND: 00746 case sk_OBSOLETE: 00747 case sk_MISCOMPARE: 00748 case sk_RESERVED: 00749 log_MARKLINE_m; 00750 00751 log_WriteEvent( 00752 evt_CRITICAL, 00753 shortText.str(), "SCSI", 0, m_strSCSIID); 00754 00755 throw ivd_Error(ie_SCSI_SENSE, shortText.str(), dump.str(), true); 00756 break; 00757 case sk_NO_SENSE: 00758 log_MARKLINE_m; 00759 log_DBG_m(dbg_DETAIL, "No sense."); 00760 break; 00761 default: 00762 log_MARKLINE_m; 00763 00764 log_WriteEvent( 00765 evt_CRITICAL, 00766 shortText.str(), "SCSI", 0, m_strSCSIID); 00767 00768 throw ivd_InternalError( 00769 ie_SCSI_SENSE, 00770 string("Unknown sense key! ") + shortText.str(), dump.str()); 00771 break; 00772 } 00773 00774 // sk_NO_SENSE 00775 00776 // We prefer to have file mark reported over the early end of medium 00777 if (m_sense.fileMark) { 00778 log_MARKLINE_m; 00779 throw ivd_Error(ie_SCSI_FILEMARK, shortText.str(), dump.str()); 00780 } 00781 if (m_sense.eom) { 00782 log_MARKLINE_m; 00783 throw ivd_Error(ie_SCSI_EOM, shortText.str(), dump.str()); 00784 } 00785 if (m_sense.incorrectLength) { 00786 log_MARKLINE_m; 00787 throw ivd_Error(ie_SCSI_ILENGTH, shortText.str(), dump.str()); 00788 } 00789 }


| void scsi_IO::Inquiry | ( | ) | [protected] |
| bool scsi_IO::IsPageSupported | ( | data_Inquiry::inq_Page_t | a_page | ) | [inline, private] |
Definition at line 205 of file scsi_io.h.
Referenced by InqSerialNumber().
00205 { 00206 for (unsigned int i = 0; i < m_supportedPages.size(); i++) { 00207 if (m_supportedPages[i] == a_page) { 00208 return true; 00209 } 00210 } 00211 return false; 00212 }

string scsi_IO::m_deviceID [protected] |
Unique device identification, passed in constructor or SetDeviceID.
Definition at line 158 of file scsi_io.h.
Referenced by scsi_LnxSG::Close(), IOCtl(), Open(), SetDeviceID(), SkipAttAndDeferred(), and WaitToBecomeReady().
string scsi_IO::m_deviceName [protected] |
Device name.
It can be a file system entry or whatever name that uniquely identifies the SCSI device on a certain platform.
Definition at line 164 of file scsi_io.h.
Referenced by GetDeviceName(), Open(), scsi_LnxSG::OpenByDeviceName(), scsi_LnxSG::SGOpen(), SkipAttAndDeferred(), WaitToBecomeReady(), and scsi_LnxSG::~scsi_LnxSG().
UInt32_t scsi_IO::m_port [protected] |
Also known as bus or host.
Definition at line 167 of file scsi_io.h.
Referenced by GetPort(), GetSCSIID(), scsi_LnxSG::InqSCSIID(), Open(), and scsi_LnxSG::OpenBySCSIID().
UInt32_t scsi_IO::m_channel [protected] |
Definition at line 168 of file scsi_io.h.
Referenced by GetChannel(), GetSCSIID(), scsi_LnxSG::InqSCSIID(), Open(), and scsi_LnxSG::OpenBySCSIID().
UInt32_t scsi_IO::m_id [protected] |
Definition at line 169 of file scsi_io.h.
Referenced by GetID(), GetSCSIID(), scsi_LnxSG::InqSCSIID(), Open(), and scsi_LnxSG::OpenBySCSIID().
UInt32_t scsi_IO::m_lun [protected] |
Definition at line 170 of file scsi_io.h.
Referenced by GetLUN(), GetSCSIID(), scsi_LnxSG::InqSCSIID(), Open(), and scsi_LnxSG::OpenBySCSIID().
string scsi_IO::m_strSCSIID [protected] |
Definition at line 172 of file scsi_io.h.
Referenced by scsi_LnxSG::CheckDriverStatus(), scsi_LnxSG::CheckHostStatus(), CheckStatusAndSense(), scsi_LnxSG::InqSCSIID(), and IOCtl().
string scsi_IO::m_vendorID [protected] |
Definition at line 175 of file scsi_io.h.
Referenced by CheckStatusAndSense(), GetVendorID(), InqStandard(), Open(), scsi_LnxSG::OpenBySerialNumber(), SkipAttAndDeferred(), and WaitToBecomeReady().
string scsi_IO::m_productID [protected] |
Definition at line 176 of file scsi_io.h.
Referenced by CheckStatusAndSense(), GetProductID(), InqStandard(), Open(), scsi_LnxSG::OpenBySerialNumber(), and WaitToBecomeReady().
string scsi_IO::m_productSerialNumber [protected] |
Definition at line 177 of file scsi_io.h.
Referenced by CheckStatusAndSense(), GetProductSerialNumber(), InqSerialNumber(), Open(), scsi_LnxSG::OpenBySerialNumber(), and WaitToBecomeReady().
const scsi_SenseVnd* scsi_IO::m_vndSenseText [protected] |
Definition at line 178 of file scsi_io.h.
Referenced by CheckStatusAndSense(), InqStandard(), and WaitToBecomeReady().
string scsi_IO::m_productRevision [protected] |
Definition at line 180 of file scsi_io.h.
Referenced by CheckStatusAndSense(), GetProductRevision(), InqStandard(), Open(), and WaitToBecomeReady().
scsi_DeviceType_e scsi_IO::m_deviceType [protected] |
Definition at line 182 of file scsi_io.h.
Referenced by CheckStatusAndSense(), GetDeviceType(), InqStandard(), Open(), and WaitToBecomeReady().
vector<data_Inquiry::inq_Page_t> scsi_IO::m_supportedPages [protected] |
UInt8_t scsi_IO::m_standard [protected] |
bool scsi_IO::m_possibleMediumChange [protected] |
Definition at line 187 of file scsi_io.h.
Referenced by CheckStatusAndSense(), GetPossibleMediumChange(), and Open().
data_Sense_t scsi_IO::m_sense [protected] |
Definition at line 189 of file scsi_io.h.
Referenced by CheckStatusAndSense(), GetReadDifference(), GetSense(), GetSenseSize(), IOCtl(), and WaitToBecomeReady().
bool scsi_IO::m_pdDirectMode [protected] |
Direct passthrough mode can be disabled via env variable.
Definition at line 192 of file scsi_io.h.
Referenced by scsi_LnxSG::DoIOCtl(), and scsi_IO().
UInt32_t scsi_IO::m_timeoutOverride [protected] |
UInt32_t scsi_IO::m_testHWErrProbability [protected] |
UInt32_t scsi_IO::m_testMedErrProbability [protected] |
scsi_IO::log_CLASSID_m [private] |
1.5.6