Functions



RWCompletion

Abstract: Asynchronous read/write completion routine.
protected:

virtual void RWCompletion(struct context *cx) = 0;

A subclass must implement the read-write completion, called upon completion of an IO started by doAsyncReadWrite.

Parameters

NameDescription
cxA pointer to the context structure for the completing command.

allocateContext

Abstract: Allocate a context structure for use with the current IO operation.
protected:

virtual struct context * allocateContext(void);


allocateInquiryBuffer

Abstract: Allocate an inquiry buffer.
protected:

virtual IOReturn allocateInquiryBuffer(UInt8 **buf,UInt32 size);

Parameters

NameDescription
bufA pointer for the returned buffer pointer.
sizeThe requested size of the buffer, in bytes.

allocateReadCapacityBuffer

Abstract: Allocate a buffer for Read-Capacity data.
protected:

virtual IOReturn allocateReadCapacityBuffer(UInt8 **buf,UInt8 size);

Parameters

NameDescription
bufA pointer for the returned buffer pointer.
sizeThe requested size of the buffer, in bytes.

allocateTempBuffer

Abstract: Allocate a buffer for temporary use.
protected:

virtual IOReturn allocateTempBuffer(UInt8 **buf,UInt32 size);

Parameters

NameDescription
bufA pointer for the returned buffer pointer.
sizeThe requested size of the buffer, in bytes.

createReadCdb

Abstract: Create a SCSI CDB for a read operation.
protected:

virtual UInt32 createReadCdb( UInt8 *cdb, /* in */ UInt32 *cdbLength, /* out */ UInt32 block, /* in */ UInt32 nblks, /* in */ UInt32 *maxAutoSenseLength, /* out */ UInt32 *timeoutSeconds); /* out */

Override this to control the cdb created for a read operation. The default implementation creates a 10-byte read command with disconnect allowed, 8-byte autosense, and a 2-second timeout.

Parameters

NameDescription
cdbA pointer to the CDB bytes.
cdbLengthThe length of the CDB in bytes.
blockThe device block to be read.
nblksThe number of blocks to be transferred.
maxAutoSenseLengthThe maximum size of the autosense data, in bytes. A value of zero will disable autosense.
timeoutSecondsThe command timeout in seconds.
Result: The IOSCSICommandOptions returned will be used to issue the command.

createWriteCdb

Abstract: Create a SCSI CDB for a write operation.
protected:

virtual UInt32 createWriteCdb( UInt8 *cdb, /* in */ UInt32 *cdbLength, /* out */ UInt32 block, /* in */ UInt32 nblks, /* in */ UInt32 *maxAutoSenseLength, /* out */ UInt32 *timeoutSeconds); /* out */

Override this to control the cdb created for a write operation. The default implementation creates a 10-byte write command with disconnect allowed, 8-byte autosense, and a 2-second timeout.

Parameters

NameDescription
cdbA pointer to the CDB bytes.
cdbLengthThe length of the CDB in bytes.
blockThe device block to be written.
nblksThe number of blocks to be transferred.
maxAutoSenseLengthThe maximum size of the autosense data, in bytes. A value of zero will disable autosense.
timeoutSecondsThe command timeout in seconds.
Result: The IOSCSICommandOptions returned will be used to issue the command.

deleteContext

Abstract: Delete a context structure.
protected:

virtual void deleteContext(struct context *cx);

This method also issues a "release" for the IO buffer and/or lock, if any.

Parameters

NameDescription
cxA pointer to the context structure to be deleted.

deleteInquiryBuffer

Abstract: Delete an inquiry data buffer.
protected:

virtual void deleteInquiryBuffer(UInt8 *buf,UInt32 size);

Parameters

NameDescription
bufA pointer to the buffer.
sizeThe requested size of the buffer, in bytes.

deleteReadCapacityBuffer

Abstract: Delete a Read-Capacity data buffer.
protected:

virtual void deleteReadCapacityBuffer(UInt8 *buf,UInt32 len);

Parameters

NameDescription
bufA pointer to the buffer.
lenThe requested size of the buffer, in bytes.

deleteTempBuffer

Abstract: Delete a temporary data buffer.
protected:

virtual void deleteTempBuffer(UInt8 *buf,UInt32 len);

Parameters

NameDescription
bufA pointer to the buffer.
lenThe requested size of the buffer, in bytes.

dequeueCommands

Abstract: Dequeue commands previously enqueued awaiting the proper device power level.
protected:

virtual void dequeueCommands(void);

This method is called when a command is queued (from queueCommand), when a call completes (from RWCompletion), and when the device power level changes. All commands for which the device power level is proper are immediately dequeued.

Queued synchronous commands are simply "awakened" by unlocking a lock. The originating thread then continues and issues the command. Asynchronous commands are immediately dispatched via a call to standardAsyncReadWriteExecute.


deviceTypeMatches

Abstract: Determine if device type matches expected type.
public:

virtual bool deviceTypeMatches(UInt8 inqBuf[],UInt32 inqLen) = 0;

This method must be implemented by a device-specific subclass.

Parameters

NameDescription
inqBufA pointer to the SCSI inquiry data for the device.
inqLenThe size of the data in the inquiry buffer.
Result: True indicates a match; False indicates a failure.

doInquiry

Abstract: Obtain SCSI Inquiry data from the device.
protected:

virtual IOReturn doInquiry(UInt8 *inqBuf,UInt32 maxLen,UInt32 *actualLen);

This method issues a SCSI Inquiry command to the device, to obtain the result in the supplied buffer. The method first issues an inquiry with a 5-byte length, to obtain the full length of the devices inquiry data. The second Inquiry command is issued to get the full inquiry data (limited to maxLen, of course).

Parameters

NameDescription
inqBufA pointer to the buffer.
maxLenThe maximum number of bytes the buffer can contain.
actualLenA pointer to the returned byte count actually transferred.

doReadCapacity

protected:

virtual IOReturn doReadCapacity(UInt64 *blockSize,UInt64 *maxBlock);

The default implementation of this method issues a standard SCSI Read Capacity command. The block size and maximum valid block are extracted from the returned data in an endian-neutral way.

Parameters

NameDescription
blockSizeA pointer to the returned block size value.
maxBlockA pointer to the returned maximum block number.

executeCdb

public:

virtual IOReturn executeCdb(struct cdbParams *params);

This method is provided to allow developers to issue arbitrary commands to the device (via the Transport Driver). Expected uses might include vendor-specific commands to support device-based password-protection, or for other vendor features.

This method may not be supported by all Transport Drivers. For example, ATA devices do not have a CDB concept; those Transport Drivers will return kIOReturnUnsupported.

Parameters

NameDescription
paramsSee IOHDTypes.h for the layout of this data structure.

genericCompletion

Abstract: Generic IO completion function.
public:

virtual void genericCompletion(struct context *cx);

This method handles completion of a SCSI command. It implements a simple state machine to handle a Unit Attention condition on a command.

This method must be public so we can reach it from the C-language callback "glue" routine. It should not be called from outside this class. *

* If a Unit Attention condition occurs, we set the state to kHandlingUnitAttention and call handleUnitAttention to do whatever is necessary to clear the condition. Eventually, handleUnitAttention resets the state to kDoneHandlingUnitAttention, which will allow the state machine to reissue the original command.

If we are already processing a Unit Attention, then genericCompletion increments a step counter and calls handleUnitAttention. The step counter allows handleUnitAttention to issue multiple SCSI commands to clear the condition. The handleUnitAttention method is called repeatedly, until the state is set to kDoneHandlingUnitAttention.

If this operation is a normal asynchronous read or write (usually started by standardAsyncReadWrite, though this is not required), then a call is made to RWCompletion, followed by deletion of the context structure for the command. RWCompletion is implemented by the subclass of IOBasicSCSI, for example in IOSCSIHDDrive.

Parameters

NameDescription
cxA pointer to the context structure for the command.

getAdditionalDeviceInfoString

Abstract: Return additional informational string for the device.
public:

virtual char * getAdditionalDeviceInfoString(void);

Result: A pointer to a static character string. The default implementation returns "[SCSI]" .

getBlockSize

Abstract: Return the device block size.
protected:

virtual UInt64 getBlockSize(void);

This method obtains the block size from the Read-Capacity data. If RC data is not yet cached, a call is made to doReadCapacity to obtain the data.


getExecuteCDBPowerState

Abstract: Return the required device power level to execute a client CDB.
protected:

virtual UInt32 getExecuteCDBPowerState(void) = 0;


getInquiryPowerState

Abstract: Return the required device power level to issue an Inquiry command.
protected:

virtual UInt32 getInquiryPowerState(void) = 0;


getProductString

Abstract: Return Product Name string for the device.
public:

virtual char * getProductString(void);

Result: A pointer to a static character string, copied from the inquiry data.

getReadCapacityPowerState

Abstract: Return the required device power level to issue a Read Capacity command.
protected:

virtual UInt32 getReadCapacityPowerState(void) = 0;


getReadWritePowerState

Abstract: Return the required device power level to issue a data read or write.
protected:

virtual UInt32 getReadWritePowerState(void) = 0;


getReportWriteProtectionPowerState

Abstract: Return the required device power level to determine media write protection.
protected:

virtual UInt32 getReportWriteProtectionPowerState(void) = 0;


getRevisionString

Abstract: Return Product Revision string for the device.
public:

virtual char * getRevisionString(void);

Result: A pointer to a static character string, copied from the inquiry data.

getVendorString

Abstract: Return Vendor Name string
public:

virtual char * getVendorString(void);

Result: A pointer to a static character string, copied from the inquiry data.

handleUnitAttention

protected:

virtual void handleUnitAttention(struct context *cx);

Override this to perform any special processing required when a Unit-Attention condition is detected. The cx->step value starts at 1 and is incremented as each subsequent command is executed. HandleUnitAttention is then called again duirng the command completion, until cx->state is changed to kDoneHandlingUnitAttention. This repeated calling behavior allows handleUnitAttention to issue several commands to the device to recover from the Unit-Attention condition. Note that since handleUnitAttention is called on the SCSI completion thread, it must not issue blocking operations, but should instead call simpleAsyncIO.

The default implementation merely sets the state to kDoneHandlingUnitAttention, to allow the original command to be reissued.

Parameters

NameDescription
cxPointer to context for the current command.

powerTickle

Abstract: Check for the device power state currently being in the desired state.
protected:

virtual bool powerTickle(UInt32 desiredState) = 0;

A subclass must implement powerTickle, which is called when we desire power to execute a command. PowerTickle may handle generic or a subclass-expanded set of power states. The implementation will usually relay the call to the Power Management subsystem function activityTickle. For a device without power management capability, the implementation should always return True.

Parameters

NameDescription
desiredStateThe desired device power level.
Result: True if power is in the desired state (or better); False if the caller must wait until power is available.

probe

Abstract: Determine if device matches expected type.
public:

virtual IOService * probe(IOService * provider,SInt32 * score);

This method is responsible for matching the device type. It calls doInquiry to issue a SCSI Inquiry command to the device, then calls deviceTypeMatches to ensure that the device type matches the expected type. If the device type matches, then the Vendor, Product, and Revision strings are copied from the inquiry data, and "this" is returned. If the device type does not match, NULL is returned.

The default implementation ignores the score parameter, though that parameter is passed to the superclass probe method.


queueCommand

Abstract: Queue commands awaiting the proper device power level.
protected:

virtual void queueCommand(struct context *cx,bool isSync,UInt32 desiredPower);

This method is called prior to issuing any IO command, so that each command can be enqueued awaiting its desired device power level. After queuing the command, a call is made to dequeueCommands to attempt to dequeue any available command that can be executed (including the one just queued). Putting commands into the queue ensures that the proper sequence is maintained.

Parameters

NameDescription
cxThe context for the command being queued.
isSyncTrue if the command is synchronous; False if the command is asynchronous.
desiredPowerThe device power level needed before the command can execute.

reportBlockSize

Abstract: Report the block size for the device, in bytes.
public:

virtual IOReturn reportBlockSize(UInt64 *blockSize);

This method returns the block size for the media. The default implementation obtains the block size from the SCSI Read Capacity command. Since the result of the Read Capacity is used by this method and reportMaxValidBlock, this method either returns a cached value or calls doReadCapacity to issue the command and cache both values.

Parameters

NameDescription
blockSizePointer to returned block size value.

reportEjectability

Abstract: Report if the media is ejectable under software control.
public:

virtual IOReturn reportEjectability(bool *isEjectable);

This method reports whether the media is ejectable under software control. The default implementation always reports that removable media is ejectable.

This method should only be called if the media is known to be removable.

Parameters

NameDescription
isEjectablePointer to returned result. True indicates the media is ejectable, False indicates the media cannot be ejected under software control.

reportLockability

Abstract: Report if the media is lockable under software control.
public:

virtual IOReturn reportLockability(bool *isLockable);

This method reports whether the media can be locked under software control, to prevent the user from removing the media manually, e.g. by pressing a button on the drive. This method is only called by the generic driver when the media is known to be removable. The default implementation always returns true.

This method should only be called if the media is known to be removable.

Parameters

NameDescription
isLockablePointer to returned result. True indicates the media can be locked in place; False indicates the media cannot be locked by software.

reportMaxReadTransfer

Abstract: Report the maximum allowed byte transfer for read operations.
public:

virtual IOReturn reportMaxReadTransfer(UInt64 blocksize,UInt64 *max);

Some devices impose a maximum data transfer size. Because this limit may be determined by the size of a block-count field in a command, the limit may depend on the block size of the transfer. The default implementation reports blocksize * 65536, which is the maximum number of bytes that can be transferred in a SCSI command with a standard 16-bit block count field.

Parameters

NameDescription
blockSizeThe block size desired for the transfer.
maxPointer to returned result.

reportMaxValidBlock

Abstract: Report the highest valid block for the device.
public:

virtual IOReturn reportMaxValidBlock(UInt64 *maxBlock);

This method reports the maximum allowable block number. The default implementation obtains the block number from the SCSI Read Capacity command. Since the result of the Read Capacity is used by this method and reportBlockSize, this method either returns a cached value or calls doReadCapacity to issue the command and cache both values.

Parameters

NameDescription
maxBlockPointer to returned result

reportMaxWriteTransfer

Abstract: Report the maximum allowed byte transfer for write operations.
public:

virtual IOReturn reportMaxWriteTransfer(UInt64 blocksize,UInt64 *max);

Some devices impose a maximum data transfer size. Because this limit may be determined by the size of a block-count field in a command, the limit may depend on the block size of the transfer. The default implementation reports blocksize * 65536, which is the maximum number of bytes that can be transferred in a SCSI command with a standard 16-bit block count field.

Parameters

NameDescription
blockSizeThe block size desired for the transfer.
maxPointer to returned result.

reportPollRequirements

Abstract: Report if it's necessary to poll for media insertion, and if polling is expensive.
public:

virtual IOReturn reportPollRequirements(bool *pollRequired,bool *pollIsExpensive);

This method reports whether the device must be polled to detect media insertion, and whether a poll is expensive to perform.

The term "expensive" typically implies a device that must be spun-up to detect media, as on a PC floppy. Most devices can detect media inexpensively.

The default implementation of this method always reports an inexpensive poll (pollIsExpensive = false), and that all removable media must be polled.

Parameters

NameDescription
pollRequiredPointer to returned result. True indicates that polling is required; False indicates that polling is not required to detect media.
pollIsExpensivePointer to returned result. True indicates that the polling operation is expensive; False indicates that the polling operation is cheap.

reportRemovability

Abstract: Report whether the media is removable or not.
public:

virtual IOReturn reportRemovability(bool *isRemovable);

This method reports whether the media is removable, but it does not provide detailed information regarding software eject or lock/unlock capability.

The default implementation of this method examines the cached Inquiry data to determine if media is removable. If the RMB bit (0x80 of Inquiry data byte 1) is set, the media is removable. If there is no Inquiry data, the media is reported to be nonremovable.

This method also sets the instance variable _removable.

Parameters

NameDescription
isRemovablePointer to returned result. True indicates that the media is removable; False indicates the media is not removable.

reportWriteProtection

Abstract: Report whether the media is write-protected or not.
public:

virtual IOReturn reportWriteProtection(bool *isWriteProtected);

The default implementation of this method issues a SCSI Mode Sense command to test the WP bit( 0x80 of byte 2 of the Mode Sense Header data). A request is made for Mode Sense Page 1, though any valid page will return a header. If the bit is set, the media is considered write-protected.

Parameters

NameDescription
isWriteProtectedPointer to returned result. True indicates that the media is write-protected (it cannot be written); False indicates that the media is not write-protected (it is permissible to write).

simpleSynchIO

Abstract: Issue a simple synchronous SCSI command.
protected:

virtual IOReturn simpleSynchIO(struct context *cx);

This method issues a single SCSI command and waits for the command to complete. The SCSI command must already be set up in the context structure.

Parameters

NameDescription
cxA pointer to the context structure for the command.

standardAsyncReadWrite

Abstract: Start an asynchronous read or write operation.
protected:

virtual IOReturn standardAsyncReadWrite(IOMemoryDescriptor *buffer, UInt32 block,UInt32 nblks, gdCompletionFunction action, IOService *target,void *param);

This method starts an asynchronous read or write operation. No incoming parameters are validated. The default implementation calls createReadCdb or createWriteCdb, then issues a SCSI command to IOSCSIDevice. If the command is accepted, then the completion will be called at some future time.

Parameters

NameDescription
bufferAn IOMemoryDescriptor describing the data-transfer buffer. The data direction is contained in the IOMemoryDescriptor. Responsiblity for releasing the descriptor rests with the caller.
blockThe starting block number of the data transfer.
nblksThe integral number of blocks to be transferred.
actionThe C function called upon completion of the data transfer.
targetThe C++ class "this" pointer, passed as an argument to "action."
paramThis value is passed as an argument to "action." It is not validated or modified.
Result: The only possible returns from this method are:

kIOReturnSuccess, meaning that the IO was accepted by the transport drivers provider (e.g. IOSCSIDevice), and that the completion function will be called when the IO completes, i.e. target->action(param).

kIOReturnNoMemory, meaning that memory allocation failed.

Other kIOReturn codes from the provider which occurred because the IO was not accepted in that provider's queue. This might indicate a full queue or bad parameter.

standardAsyncReadWriteExecute

Abstract: Issue an asynchronous read/write operation after dequeuing.
protected:

virtual IOReturn standardAsyncReadWriteExecute(struct context *cx);

Parameters

NameDescription
cxA pointer to the context structure for the command.

standardSyncReadWrite

protected:

virtual IOReturn standardSyncReadWrite(IOMemoryDescriptor *buffer,UInt32 block,UInt32 nblks);

Perform a synchronous read or write operation.

Parameters

NameDescription
bufferAn IOMemoryDescriptor describing the data-transfer buffer. The data direction is contained in the IOMemoryDescriptor. Responsiblity for releasing the descriptor rests with the caller.
blockThe starting block number of the data transfer.
nblksThe integral number of blocks to be transferred.

stringFromState

Abstract: Return a string description of a state value.
protected:

virtual char * stringFromState(stateValue state);

Used for debugging.

Parameters

NameDescription
stateThe state to be converted to a string description.

© 2000 Apple Computer, Inc. — (Last Updated 2/23/2000)