IOFireWireSBP2LSIWorkaroundDescriptor

Inherits from
IOGeneralMemoryDescriptor
Availability
Available in OS X v10.0 through OS X v10.6.
Declared in
IOFireWireSBP2LSIWorkaroundDescriptor.h

Overview

This is a subclass of IOGeneralMemoryDescriptor. It is designed to work around a hardware problem in a common SBP2 target. It takes a memory descriptor as an argument. It retains this descriptor and returns a new one with resegmented physical segments and potentially some "unfixable" segments double buffered.

If the transfer will cause data to be sent from the Mac, syncBuffersForOutput must be called before the transfer.

If the transfer will cause data to be recieve by the Mac, syncBuffersForInput must be called after the transfer.

This class calculates the new segmentation only once when it is created. Any changes to the structure of the original memory descriptor will render this one useless. It must be released and a new IOFireWireSBP2LSIWorkaroundDescriptor can be created.

LSI Bridge Workaround Algorithm Details

Goals: 1. Avoid LSI Logic "< 16 byte" bug - prevent any data packet smaller than 16 bytes 2. Minimize double-buffering 3. Support non-multiple-of-512-byte devices, e.g. CD Audio

Solution: Write a page table such that the bridge will nor use packets smaller than 16 bytes. In other words, rearrange the memory descriptor to avoid the bug, and do it such that the SBP-2 layer will not break up a segment (du ro the 64k-1 limit) and re-introduces the problem

SBP-2 defines the kFWSBP2MaxPageClusterSize constant. We simply make sure none of our segments are larger than this size and SBP-2 will not break them up when it writes the SBP-2 page table.

Notes: - Some double buffering is unavoidable. Discontiguous pages may yield page fragments at the start or end of the buffer (or both, with non-512x buffers). solution uses less than 33 bytes of double-buffer per segment in original memory descriptor. - If driver must break up IO to meet ATA limit of 255 (250?) blocks, assume the driver does this at a higher level (before applying workaround). - It is expected that the original memory descriptor has been prepared (wired)

Tasks

Miscellaneous

Instance Methods

initWithDescriptor

Initialize an IOFireWireSBP2LSIWorkaroundDescriptor with the given descriptor.

virtual bool initWithDescriptor( IOMemoryDescriptor *desc, IOByteCount offset = 0, IOByteCount len = 0, IODirection direction = kIODirectionOutIn );
Parameters
desc

Original memory descriptor.

offset

Offset of data to "fix" in bytes from beginning of descriptor.

len

Length of data in bytes to "fix"

direction

IODirection of data transfer.

Return Value

Returns true if the initialization was successful.

Discussion

Initialize the workaround descriptor with the given descriptor.

syncBuffersForInput

Synchronize the buffers for input.

virtual IOReturn syncBuffersForInput( void );
Return Value

Returns kIOReturnSuccess if sync was successful.

Discussion

Since double buffering may be invovled in the workaround. The driver needs to indicate when these buffers should be syncronized with the original descriptor. For data that will be input syncBuffersForOutput should be called after receiving completion status for the ORB.

syncBuffersForOutput

Synchronize the buffers for output.

virtual IOReturn syncBuffersForOutput( void );
Return Value

Returns kIOReturnSuccess if sync was successful.

Discussion

Since double buffering may be invovled in the workaround. The driver needs to indicate when these buffers should be syncronized with the original descriptor. For data that will be output syncBuffersForOutput should be called before submiting the ORB.

withCapacity

Create a new descriptor with possibly a permanent capacity.

static IOFireWireSBP2LSIWorkaroundDescriptor * withCapacity ( UInt32 permanentRanges, IOByteCount permanentBufferSpace, bool fixedCapacity );
Parameters
permanentRanges

Count of permanent ranges.

permanentBufferSpace

Byte count of permanent buffers.

fixedCapacity

bool indicating if dynamic allocations can be made.

Return Value

Returns true if the initialization was successful.

Discussion

Create and IOFireWireSBP2LSIWorkaroundDescriptor with a permanent fixed capacity. You should call initWithDescriptor afterward. permanentRanges is number of ranges to keep permanently allocated for use by the algorithm. If fixedCapacity is false additional ranges may be allocated and deallocated dyanmicly if needed. The algorithm may require more or less ranges than either the original descriptor or the final fixed may decriptor contain. permanentBufferSpace is the number of bytes of permanent buffer to keep arround. If fixedCapacity is false additional buffer space may be allocated and deallocated dynamically. permanentBufferSpace should generally be set to 32 * maximum number of ranges. fixedCapacity is a flag indicating whether dynamic allocations are allowed. When making decisions about the maximum amount of buffer space to keep around, it should be noted tha the maximum number of ranges maybe different from permanentRanges if fixedCapcity is false.

withDescriptor

Creates a new IOFireWireSBP2LSIWorkaroundDescriptor.

static IOFireWireSBP2LSIWorkaroundDescriptor * withDescriptor ( IOMemoryDescriptor *desc, IOByteCount offset = 0, IOByteCount len = 0, IODirection direction = kIODirectionOutIn );
Parameters
desc

Original memory descriptor.

offset

Offset of data to "fix" in bytes from beginning of descriptor.

len

Length of data in bytes to "fix"

direction

IODirection of data transfer.

Return Value

Returns a new IOFireWireSBP2LSIWorkaroundDescriptor if successful.

Discussion

Create a IOFireWireSBP2LSIWorkaroundDescriptor with no permanent capacity then inits it the given descriptor. This is basicly a short cut for calling withCapacity( 0, 0, false) and the initWithDescriptor()