Chameleon

Chameleon Svn Source Tree

Root/branches/Chimera/i386/include/IOKit/sbp2/IOFireWireSBP2LSIWorkaroundDescriptor.h

1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#if __ppc__
24
25/*!
26 @header IOFireWireSBP2LSIWorkaroundDescriptor
27 Contains the class definition for IOFireWireSBP2LSIWorkaroundDescriptor.
28*/
29
30#ifndef _IOKIT_IOFIREWIRESBP2LSIWORKAROUNDDESCRIPTOR_H
31#define _IOKIT_IOFIREWIRESBP2LSIWORKAROUNDDESCRIPTOR_H
32
33#include <IOKit/IOMemoryDescriptor.h>
34
35class IOFireWireSBP2LSIRange;
36
37/*!
38 @class IOFireWireSBP2LSIWorkaroundDescriptor
39 @abstract This is a subclass of IOGeneralMemoryDescriptor. It is designed to work around
40 a hardware problem in a common SBP2 target. It takes a memory descriptor as
41an argument. It retains this descriptor and returns a new one with resegmented
42physical segments and potentially some "unfixable" segments double buffered.
43
44 If the transfer will cause data to be sent from the Mac, syncBuffersForOutput
45 must be called before the transfer.
46
47 If the transfer will cause data to be recieve by the Mac, syncBuffersForInput
48 must be called after the transfer.
49
50 This class calculates the new segmentation only once when it is created.
51 Any changes to the structure of the original memory descriptor will render
52 this one useless. It must be released and a new IOFireWireSBP2LSIWorkaroundDescriptor
53 can be created.
54
55 LSI Bridge Workaround Algorithm Details
56
57 Goals:
58 1. Avoid LSI Logic "< 16 byte" bug - prevent any data packet smaller than 16 bytes
59 2. Minimize double-buffering
60 3. Support non-multiple-of-512-byte devices, e.g. CD Audio
61
62 Solution:
63 Write a page table such that the bridge will nor use packets smaller than 16 bytes.
64 In other words, rearrange the memory descriptor to avoid the bug, and do it such
65 that the SBP-2 layer will not break up a segment (du ro the 64k-1 limit) and
66 re-introduces the problem
67
68 SBP-2 defines the kFWSBP2MaxPageClusterSize constant. We simply make sure
69 none of our segments are larger than this size and SBP-2 will not break them
70 up when it writes the SBP-2 page table.
71
72 Notes:
73 - Some double buffering is unavoidable. Discontiguous pages may yield page
74 fragments at the start or end of the buffer (or both, with non-512x buffers).
75 solution uses less than 33 bytes of double-buffer per segment in original
76 memory descriptor.
77 - If driver must break up IO to meet ATA limit of 255 (250?) blocks, assume
78 the driver does this at a higher level (before applying workaround).
79 - It is expected that the original memory descriptor has been prepared (wired)
80*/
81
82class IOFireWireSBP2LSIWorkaroundDescriptor : public IOGeneralMemoryDescriptor
83{
84OSDeclareDefaultStructors(IOFireWireSBP2LSIWorkaroundDescriptor)
85
86friend class IOFireWireSBP2LSIRange;
87
88protected:
89
90 // reserved for future use
91 struct ExpansionData { };
92 ExpansionData *reserved;
93
94boolfFixedCapacity; // for both allocators
95
96//////////////////////////////////////
97// for range allocator
98
99OSArray *fPermanentRanges;
100UInt32fAllocatedRangesCount;
101
102virtual IOReturn rangeAllocatorInitialize( UInt32 rangeCount );
103virtual void rangeAllocatorDeallocateAllRanges( void );
104virtual IOFireWireSBP2LSIRange * rangeAllocatorNewRange( void );
105virtual void rangeAllocatorFree( void );
106
107//////////////////////////////////////
108// for buffer allocator
109
110OSArray *fBufferDescriptors;
111UInt32fPermanentPages;
112IOByteCountfAllocatedBytesCount;
113
114virtual IOReturn bufferAllocatorInitialize( IOByteCount requestedBufferSize );
115virtual void bufferAllocatorDeallocateAllBuffers( void );
116virtual void * bufferAllocatorNewBuffer( IOPhysicalAddress * address );
117virtual void bufferAllocatorFree( void );
118
119//////////////////////////////////////
120// for range table allocator
121
122IOPhysicalRange * fRangeTable;
123IOByteCountfRangeTableSize;
124
125virtual IOReturn rangeTableAllocatorInitialize( UInt32 requestedBufferSize );
126virtual IOPhysicalRange * rangeTableAllocatorNewTable( UInt32 entries );
127virtual void rangeTableAllocatorFree( void );
128
129//////////////////////////////////////
130// for workaround
131
132IOMemoryDescriptor * fOriginalDesc;
133OSArray *fRanges;
134IOByteCount fOffset;
135IOByteCountfLength;
136IODirectionfDirection;
137
138
139virtual bool initWithCapacity
140( UInt32 permanentRanges, IOByteCount permanentBufferSpace, bool fixedCapacity );
141
142virtual void free();
143
144virtual IOReturn resetToInitialCapacity( void );
145virtual IOReturn initializeRangesArray( void );
146virtual IOReturn recalculateSmallSegments( void );
147virtual IOReturn splitLargeSegments( void );
148virtual IOReturn resegmentOddLengthSegments( void );
149virtual IOReturn initializeBuffers( void );
150
151virtual bool initWithAddress( void * address, /* not supported */
152 IOByteCount withLength,
153 IODirection withDirection );
154
155 virtual bool initWithAddress( vm_address_t address, /* not supported */
156 IOByteCount withLength,
157 IODirection withDirection,
158 task_t withTask );
159
160 virtual bool initWithPhysicalAddress(
161 IOPhysicalAddress address, /* not supported */
162 IOByteCount withLength,
163 IODirection withDirection );
164
165 virtual bool initWithPhysicalRanges(
166 IOPhysicalRange * ranges, /* not supported */
167 UInt32 withCount,
168 IODirection withDirection,
169 bool asReference = false );
170
171 virtual bool initWithRanges( IOVirtualRange * ranges, /* not supported */
172 UInt32 withCount,
173 IODirection withDirection,
174 task_t withTask,
175 bool asReference = false );
176
177public:
178
179// static factory methods and intializers
180
181//
182// create a new instance
183//
184
185
186 /*!
187@function withDescriptor
188@abstract Creates a new IOFireWireSBP2LSIWorkaroundDescriptor.
189@discussionCreate a IOFireWireSBP2LSIWorkaroundDescriptor with no permanent capacity then
190 inits it the given descriptor. This is basicly a short cut for calling
191 withCapacity( 0, 0, false) and the initWithDescriptor()
192 @param desc Original memory descriptor.
193 @param offset Offset of data to "fix" in bytes from beginning of descriptor.
194 @param len Length of data in bytes to "fix"
195 @param direction IODirection of data transfer.
196 @result Returns a new IOFireWireSBP2LSIWorkaroundDescriptor if successful.
197*/
198
199static IOFireWireSBP2LSIWorkaroundDescriptor * withDescriptor
200( IOMemoryDescriptor * desc, IOByteCount offset = 0,
201 IOByteCount len = 0, IODirection direction = kIODirectionOutIn );
202
203// initialize with descriptor
204
205 /*!
206@function initWithDescriptor
207@abstract Initialize an IOFireWireSBP2LSIWorkaroundDescriptor with the given descriptor.
208@discussionInitialize the workaround descriptor with the given descriptor.
209 @param desc Original memory descriptor.
210 @param offset Offset of data to "fix" in bytes from beginning of descriptor.
211 @param len Length of data in bytes to "fix"
212 @param direction IODirection of data transfer.
213 @result Returns true if the initialization was successful.
214*/
215
216 virtual bool initWithDescriptor( IOMemoryDescriptor * desc, IOByteCount offset = 0,
217 IOByteCount len = 0, IODirection direction = kIODirectionOutIn );
218
219
220///////////////////////////////////
221
222
223 /*!
224@function withCapacity
225@abstract Create a new descriptor with possibly a permanent capacity.
226@discussionCreate and IOFireWireSBP2LSIWorkaroundDescriptor with a permanent fixed capacity.
227 You should call initWithDescriptor afterward. permanentRanges is number of ranges to keep
228 permanently allocated for use by the algorithm. If fixedCapacity is false additional ranges
229 may be allocated and deallocated dyanmicly if needed. The algorithm may require more or less
230 ranges than either the original descriptor or the final fixed may decriptor contain.
231 permanentBufferSpace is the number of bytes of permanent buffer to keep arround. If fixedCapacity
232 is false additional buffer space may be allocated and deallocated dynamically. permanentBufferSpace
233 should generally be set to 32 * maximum number of ranges. fixedCapacity is a flag indicating
234 whether dynamic allocations are allowed. When making decisions about the maximum amount of
235 buffer space to keep around, it should be noted tha the maximum number of ranges maybe different
236 from permanentRanges if fixedCapcity is false.
237 @param permanentRanges Count of permanent ranges.
238 @param permanentBufferSpace Byte count of permanent buffers.
239 @param fixedCapacity bool indicating if dynamic allocations can be made.
240 @result Returns true if the initialization was successful.
241*/
242
243static IOFireWireSBP2LSIWorkaroundDescriptor * withCapacity
244( UInt32 permanentRanges, IOByteCount permanentBufferSpace, bool fixedCapacity );
245
246
247///////////////////////////////////
248
249//
250// manipulate buffers for IO
251//
252
253 /*!
254@function syncBuffersForOutput
255@abstract Synchronize the buffers for output.
256@discussionSince double buffering may be invovled in the workaround. The driver needs to
257 indicate when these buffers should be syncronized with the original descriptor. For data
258 that will be output syncBuffersForOutput should be called before submiting the ORB.
259 @result Returns kIOReturnSuccess if sync was successful.
260*/
261
262virtual IOReturn syncBuffersForOutput( void ); // call before output
263
264 /*!
265@function syncBuffersForInput
266@abstract Synchronize the buffers for input.
267@discussionSince double buffering may be invovled in the workaround. The driver needs to
268 indicate when these buffers should be syncronized with the original descriptor. For data
269 that will be input syncBuffersForOutput should be called after receiving completion status
270 for the ORB.
271 @result Returns kIOReturnSuccess if sync was successful.
272*/
273
274 virtual IOReturn syncBuffersForInput( void );// call after input
275
276private:
277
278 OSMetaClassDeclareReservedUnused(IOFireWireSBP2LSIWorkaroundDescriptor, 0);
279 OSMetaClassDeclareReservedUnused(IOFireWireSBP2LSIWorkaroundDescriptor, 1);
280 OSMetaClassDeclareReservedUnused(IOFireWireSBP2LSIWorkaroundDescriptor, 2);
281 OSMetaClassDeclareReservedUnused(IOFireWireSBP2LSIWorkaroundDescriptor, 3);
282 OSMetaClassDeclareReservedUnused(IOFireWireSBP2LSIWorkaroundDescriptor, 4);
283 OSMetaClassDeclareReservedUnused(IOFireWireSBP2LSIWorkaroundDescriptor, 5);
284 OSMetaClassDeclareReservedUnused(IOFireWireSBP2LSIWorkaroundDescriptor, 6);
285 OSMetaClassDeclareReservedUnused(IOFireWireSBP2LSIWorkaroundDescriptor, 7);
286 OSMetaClassDeclareReservedUnused(IOFireWireSBP2LSIWorkaroundDescriptor, 8);
287
288};
289
290#endif
291
292#endif
293

Archive Download this file

Revision: 1340