---------------------------------------------------------------------
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