--------------------------------------------------------------------- CLASS: DriveDevice --JKH PUBLIC METHODS: DriveDevice() - Constructor. Takes device file pathname as argument. ~DriveDevice() - Destructor. Closes device. numSectors() - Returns the number of sectors on the device. sectorSize() - Returns the size, in bytes, of a sector on the device. read() - Read bytes into argument ByteArray from the given ExtentList. write() - Write bytes from argument ByteArray into the given ExtentList. writeWOE() - As write, but does a write-without-erase. verifyMode() - Setter: puts DriveDevice in write-with-verify mode. verifyMode() - Getter: returns write-with-verify mode flag. erase() - Erases the sectors specified by the given PhysExtent. checkValidity() - Returns whether the DriveDevice is in a valid state. error() - Returns the error state of the DriveDevice object. USAGE NOTES: none yet. ---------------------------------------------------------------------- --------------------------------------------------------------------- METHOD: DriveDevice::DriveDevice --JKH Constructor for the DriveDevice object. ARGUMENTS: devfile IN String reference containing pathname of the device file to which the DriveDevice object should be bound. RETURNS: None. PRECONDITIONS: --The pathname contained in the argument String devfile corresponds to a valid (i.e., existing) drive device. --The executing process must have read/write access to this device. --No other process must have the device opened in EXCLUSIVE mode. POSTCONDITIONS: --The device will be opened (and held open until the DriveDevice object is destructed) for read and write. --Capacity and sectorSize information will be stored in the object's data members. ERRORS: error_None: Function completed successfully. error_Empty_path_element: NULL devfile argument. error_File_not_found: Device file passed as argument cannot be opened. error_Capacity_failed: Cannot get numSectors_ information. ISSUE: DriveDevice::DriveDevice(): Should no media in drive be an error? Currently, this condition will not impede successful construction, though obviously no read/write/erase operation will subsequently be successful. ----------------------------------------------------------------------------- DriveDevice::DriveDevice( const NSR::String& devfile ) : verifyMode_(0) --------------------------------------------------------------------- METHOD: DriveDevice::~DriveDevice() --JKH Destructor for the DriveDevice object. ARGS: none RETURNS: none PRE-CONDS: none POST-CONDS: --The file descriptor corresponding to the drive device bound to this object, if open, will be closed. ----------------------------------------------------------------------------- DriveDevice::~DriveDevice() --------------------------------------------------------------------- METHOD: DriveDevice::read() --JKH This method reads the specified sectors from disk into the given buffer. ARGS: UINT32 start IN Starting sector use for read UINT32 nsectors IN Maximum number of sectors to read const ByteArrayRef& buf IN/OUT The buffer to store the data. Error& err OUT Error value to hold results of operation RETURNS: The function returns the number of bytes read. If -1 is returned, then an actual I/O error (not a blank check) occurred. If a blank check or read past EOM/EOLM condition occurred, a "short count" will be returned. PRE-CONDS: --The DriveDevice object was successfully constructed and contains media --The start parameter is in the range [0,numSectors_) --The nsectors parameter satisfies the following: start + nsectors < numSectors_ POST-CONDS: --The number of bytes specified in the length field of the argument ByteArrayRef buf will be read from disk and stored in the memory referred to by buf ERRORS: error_None: Function completed successfully. error_No_free_store: Could not allocate memory for buffering. error_Empty_path_element: Argument buffer is invalid. error_Drive_blank_check: A blank sector was encountered during the read. error_Read_EOM: Attempted to read past physical EOM error_Read_EOLM: Attempted to read past logical EOM error_Drive_read: Generic I/O failure on read NOTES: buf.length() indicates how many bytes to read; the sectors specified by start and nsectors only indicate which sectors may be used to satisfy the request. nsectors may be a greater number of bytes than specified by buf; this is not an error condition. If the request is not a sector-multiple, the last sector of the read must be buffered. This buffering requires dynamic allocation for the new buffer, and so may cause the entire read to fail due to no free store. ----------------------------------------------------------------------------- rv = ::read(fd_,bptr,((extsize < buf.length()) ? extsize : buf.length())); if(rv < (NSR::INT32 ) buf.length()) { Got a short count perror("read"); if(rv == extsize) { Extent too small err = dderror_ = NSR::error_Read_EOLM; return rv; } Extent was big enough, presumably, so we need to check for physical EOM if((offset + buf.length()) > numSectors_*sectorSize_) { err = dderror_ = NSR::error_Read_EOM; return rv; } We didn't fall off the edge of the physical media, so our last chance is a blank check. if(isBlankCheck()) { err = dderror_ = NSR::error_Drive_blank_check; return rv; } We didn't read past physical EOM, we didn't get a blank check, but we received a short count. According to the read(2) manpage, this condition is undefined, so we report a generic I/O error. err = dderror_ = NSR::error_Drive_read; return rv; } If we got here, then everything went smoothly: success! err = dderror_ = NSR::error_None; return rv; } ----------------------------------------------------------------------------- Alternate interface for DriveDevice::read(). ----------------------------------------------------------------------------- NSR::INT32 DriveDevice::read ( NSR::UINT32 start, NSR::UINT32 nbytes, NSR::BYTE_PTR buf, NSR::Error& err ) rv = ::read(fd_,buf,nbytes); if(rv < (NSR::INT32) nbytes) { Got a short count We need to check for physical EOM if((offset + nbytes) > numSectors_*sectorSize_) { err = dderror_ = NSR::error_Read_EOM; return rv; } We didn't fall off the edge of the physical media, so our last chance is a blank check. if(isBlankCheck()) { err = dderror_ = NSR::error_Drive_blank_check; return rv; } We didn't read past physical EOM, we didn't get a blank check, but we received a short count. According to the read(2) manpage, this condition is undefined, so we report a generic I/O error. err = dderror_ = NSR::error_Drive_read; return rv; } If we got here, then everything went smoothly: success! err = dderror_ = NSR::error_None; return rv; } ----------------------------------------------------------------------------- METHOD: DriveDevice::write() --JKH This method writes the specified sectors to disk from the given buffer. ARGS: UINT32 start IN Starting sector use for write UINT32 nsectors IN Maximum number of sectors to write const ByteArrayRef& buf IN/OUT The buffer to supply the data. Error& err OUT Error value to hold results of operation RETURNS: The function returns the number of bytes written. If -1 is returned, then an actual I/O error occurred. If a write past EOM/EOLM condition occurred, a "short count" will be returned. NOTE: if the DriveDevice is in verify mode, and the DriveDevice cannot successfully put itself in verify mode for the write, the write call will fail, returning -1 and setting error to error_Set_verify_failed. PRE-CONDS: --The DriveDevice object was successfully constructed and contains media --The start parameter is in the range [0,numSectors_) --The nsectors parameter satisfies the following: start + nsectors < numSectors_ --The device is writable (e.g., not write-protected and, if WORM, the sectors are unwritten). POST-CONDS: --The number of bytes specified in the length field of the argument ByteArrayRef buf will be written to disk and taken from the memory referred to by buf ERRORS: error_None: Function completed successfully. error_No_free_store: Could not allocate memory for buffering. error_Empty_path_element: Argument buffer is invalid. error_Write_EOM: Attempted to write past physical EOM error_Write_EOLM: Attempted to write past logical EOM error_Drive_write: Generic I/O failure on write error_Set_verify_failed: Cannot set verify mode. ----------------------------------------------------------------------------- NSR::INT32 DriveDevice::write ( NSR::UINT32 start, NSR::UINT32 nsectors, const NSR::ByteArrayRef& buf, NSR::Error& err ) --------------------------------------------------------------------- METHOD: DriveDevice::write() --JKH This method writes the specified sectors to disk from the given buffer. ARGS: UINT32 start IN Starting sector use for write UINT32 nsectors IN Maximum number of sectors to write const ByteArrayRef& buf IN/OUT The buffer to supply the data. Error& err OUT Error value to hold results of operation RETURNS: The function returns the number of bytes written. If -1 is returned, then an actual I/O error occurred. If a write past EOM/EOLM condition occurred, a "short count" will be returned. NOTE: if the DriveDevice is in verify mode, and the DriveDevice cannot successfully put itself in verify mode for the write, the write call will fail, returning -1 and setting error to error_Set_verify_failed. PRE-CONDS: --The DriveDevice object was successfully constructed and contains media --The start parameter is in the range [0,numSectors_) --The nsectors parameter satisfies the following: start + nsectors < numSectors_ --The device is writable (e.g., not write-protected and, if WORM, the sectors are unwritten). POST-CONDS: --The number of bytes specified in the length field of the argument ByteArrayRef buf will be written to disk and taken from the memory referred to by buf ERRORS: error_None: Function completed successfully. error_No_free_store: Could not allocate memory for buffering. error_Empty_path_element: Argument buffer is invalid. error_Write_EOM: Attempted to write past physical EOM error_Write_EOLM: Attempted to write past logical EOM error_Drive_write: Generic I/O failure on write error_Set_verify_failed: Cannot set verify mode. ----------------------------------------------------------------------------- rv = ::write(fd_,bptr,((extsize < buf.length()) ? extsize : buf.length())); if(verifyMode_) { Turn off verify mode (void) setVMode(VERIFY_OFF); } if(rv < (NSR::INT32) buf.length()) { Got a short count if(rv == extsize) { Extent too small err = dderror_ = NSR::error_Write_EOLM; return rv; } Extent was big enough, presumably, so we need to check for physical EOM if((offset + buf.length()) > numSectors_*sectorSize_) { err = dderror_ = NSR::error_Write_EOM; return rv; } We didn't fall off the edge of the physical media, so we got a mysterious short count. This condition is undefined by the write(2) man page, so we just report a generic I/O problem. err = dderror_ = NSR::error_Drive_write; return rv; } If we got here, then everything went smoothly: success! err = dderror_ = NSR::error_None; return rv; } ----------------------------------------------------------------------------- Alternate interface for DriveDevice::write(). ----------------------------------------------------------------------------- NSR::INT32 DriveDevice::write ( NSR::UINT32 start, NSR::UINT32 nbytes, NSR::CONST_BYTE_PTR buf, NSR::Error& err ) rv = ::write(fd_,buf,nbytes); if(verifyMode_) { Turn off verify mode (void) setVMode(VERIFY_OFF); } if(rv < (NSR::INT32) nbytes) { Got a short count We need to check for physical EOM if((offset + nbytes) > numSectors_*sectorSize_) { err = dderror_ = NSR::error_Write_EOM; return rv; } We didn't fall off the edge of the physical media, so we got a mysterious short count. This condition is undefined by the write(2) man page, so we just report a generic I/O problem. err = dderror_ = NSR::error_Drive_write; return rv; } If we got here, then everything went smoothly: success! err = dderror_ = NSR::error_None; return rv; } ----------------------------------------------------------------------------- METHOD: DriveDevice::writeWOE() --JKH This method writes the specified sectors to disk from the given buffer using write-without-erase. NOTE: if the sectors to be written without erase are NOT in fact already erased, they will be garbaged and henceforth unreadable, and no error will be detected during the write! It is very important that users using this method are sure that the sectors in question are actually erased. ARGS: UINT32 start IN Starting sector use for write UINT32 nsectors IN Maximum number of sectors to write const ByteArrayRef& buf IN/OUT The buffer to supply the data. Error& err OUT Error value to hold results of operation RETURNS: The function returns the number of bytes written. If -1 is returned, then an actual I/O error occurred. If a write past EOM/EOLM condition occurred, a "short count" will be returned. If the DriveDevice cannot be put into write-without-erase mode successfully, the call will proceed in normal write-with-erase mode, and will not flag an error. PRE-CONDS: --The DriveDevice object was successfully constructed and contains media --The PhysExtent is valid (i.e., valid values) --The device is writable (e.g., not write-protected and, if WORM, the sectors are unwritten). --The sectors specified by the PhysExtent are already erased. POST-CONDS: --The number of bytes specified in the length field of the argument ByteArrayRef buf will be written to disk and taken from the memory referred to by buf ERRORS: error_None: Function completed successfully. error_No_free_store: Could not allocate memory for buffering. error_Empty_path_element: Argument buffer is invalid. error_Write_EOM: Attempted to write past physical EOM error_Write_EOLM: Attempted to write past logical EOM error_Drive_write: Generic I/O failure on write ----------------------------------------------------------------------------- NSR::INT32 DriveDevice::writeWOE ( NSR::UINT32 start, NSR::UINT32 nsectors, const NSR::ByteArrayRef& arr, NSR::Error& err ) --------------------------------------------------------------------- METHOD: DriveDevice::writeWOE() --JKH This method writes the specified sectors to disk from the given buffer using write-without-erase. NOTE: if the sectors to be written without erase are NOT in fact already erased, they will be garbaged and henceforth unreadable, and no error will be detected during the write! It is very important that users using this method are sure that the sectors in question are actually erased. ARGS: UINT32 start IN Starting sector use for write UINT32 nsectors IN Maximum number of sectors to write const ByteArrayRef& buf IN/OUT The buffer to supply the data. Error& err OUT Error value to hold results of operation RETURNS: The function returns the number of bytes written. If -1 is returned, then an actual I/O error occurred. If a write past EOM/EOLM condition occurred, a "short count" will be returned. If the DriveDevice cannot be put into write-without-erase mode successfully, the call will proceed in normal write-with-erase mode, and will not flag an error. PRE-CONDS: --The DriveDevice object was successfully constructed and contains media --The PhysExtent is valid (i.e., valid values) --The device is writable (e.g., not write-protected and, if WORM, the sectors are unwritten). --The sectors specified by the PhysExtent are already erased. POST-CONDS: --The number of bytes specified in the length field of the argument ByteArrayRef buf will be written to disk and taken from the memory referred to by buf ERRORS: error_None: Function completed successfully. error_No_free_store: Could not allocate memory for buffering. error_Empty_path_element: Argument buffer is invalid. error_Write_EOM: Attempted to write past physical EOM error_Write_EOLM: Attempted to write past logical EOM error_Drive_write: Generic I/O failure on write ----------------------------------------------------------------------------- --------------------------------------------------------------------- METHOD: DriveDevice::erase() --JKH Erases the sectors in the argument PhysExtent. ARGS: UINT32 start IN Starting sector to erase UINT32 nsectors IN Number of sectors to erase Error& err OUT Error value to hold result of operation RETURNS: Returns 0 on success, -1 on failure. PRE-CONDS: --The DriveDevice object was successfully created and contains media --The executing process is the only process that has the drive open --The PhysExtent specifies a range of sectors physically accessible on the media --The media is erasable (e.g., not a hard disk, not WORM) POST-CONDS: --The sectors specified by the argument PhysExtent will be erased. ERRORS: error_None Function completed successfully. error_Bad_erase_size Extent size is not a multiple of the sector size. error_Erase_failed The erase failed due to an I/O error, or inability to put the drive in exclusive mode. NOTES: The erase capability provided by the SCSI-2 spec for MO drives only allows for erasing whole sectors. Therefore, the argument PhysExtent MUST be a multiple of sector size in length. If this condition is not met, the erase call will fail. ----------------------------------------------------------------------------- --------------------------------------------------------------------- METHOD: DriveDevice::checkValidity() --JKH This method checks whether the DriveDevice object in in question is valid--i.e, it was successfully constructed. ARGS: none RETURN VALUES: Returns an Error with one of the following values: error_None: object is valid. error_Empty_path_element: Construction failed because the argument String to the constructor was invalid. error_File_not_found: Construction failed; could not find specified device file. error_Capacity_found: Construction failed; could not get numSectors_. PRE-CONDS: none POST-CONDS: see return values ----------------------------------------------------------------------------- NSR::Error DriveDevice::checkValidity(void) const --------------------------------------------------------------------- METHOD: DriveDevice::error() --JKH This method returns an Error value corresponding to the results of the last call to the read(), write(), or erase() methods, or construction. ARGS: none RETURNS: Returns an Error object corresponding to the results of the last call to the read(), write(), or erase() methods, or construction. PRE-CONDS: none POST_CONDS: see return values ----------------------------------------------------------------------------- NSR::Error DriveDevice::error(void) const