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/*! 24 @header IOFireWireSBP2ORB 25 Contains the class definition for IOFireWireSBP2ORB. 26*/ 27 28#ifndef _IOKIT_IOFIREWIRESBP2ORB_H 29#define _IOKIT_IOFIREWIRESBP2ORB_H 30 31#include <IOKit/firewire/IOFireWireUnit.h> 32 33#include <IOKit/IOBufferMemoryDescriptor.h> 34#include <IOKit/IOUserClient.h> 35#include <IOKit/IODMACommand.h> 36 37enum 38{ 39 kFWSBP2ConstraintForceDoubleBuffer = (1 << 0) 40}; 41 42// login option flags 43enum 44{ 45 kFWSBP2CommandCompleteNotify = (1 << 0), 46 kFWSBP2CommandTransferDataFromTarget = (1 << 1), 47 kFWSBP2CommandImmediate = (1 << 2), 48 49 kFWSBP2CommandNormalORB = (1 << 5), 50 kFWSBP2CommandReservedORB = (1 << 6), 51 kFWSBP2CommandVendorORB = (1 << 7), 52 kFWSBP2CommandDummyORB = (1 << 8), 53 kFWSBP2CommandCheckGeneration = (1 << 9), 54 55 kFWSBP2CommandFixedSize = (1 << 10), 56 kFWSBP2CommandVirtualORBs = (1 << 11) // handy for debugging 57}; 58 59enum 60{ 61 kFWSBP2MaxPageClusterSize = 0xf000 62}; 63 64class IOFireWireSBP2ORB; 65class IOFireWireSBP2LUN; 66class IOFireWireSBP2Login; 67 68/*! 69 @class IOFireWireSBP2ORB 70 @abstract Represents an SBP2 normal command ORB. Supplies the APIs for configuring normal 71 command ORBs. This includes setting the command block and writing the page tables for I/O. 72 The ORBs are executed using the submitORB method in IOFireWireSBP2Login. 73*/ 74 75class IOFireWireSBP2ORB : public IOCommand 76{ 77 OSDeclareDefaultStructors( IOFireWireSBP2ORB ) 78 79 friend class IOFireWireSBP2Login; 80 friend class IOFireWireSBP2ManagementORB; 81 82protected: 83 84 typedef struct 85 { 86 UInt32 nextORBAddressHi; 87 UInt32 nextORBAddressLo; 88 UInt32 dataDescriptorHi; 89 UInt32 dataDescriptorLo; 90 UInt16 options; 91 UInt16 dataSize; 92 UInt32 commandBlock[1]; // will be variable sized 93 } FWSBP2ORB; 94 95 typedef struct 96 { 97 UInt16 segmentLength; 98 UInt16 segmentBaseAddressHi; 99 UInt32 segmentBaseAddressLo; 100 } FWSBP2PTE; 101 102private: 103 104 OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 0); 105 OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 1); 106 OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 2); 107 OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 3); 108 OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 4); 109 OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 5); 110 OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 6); 111 OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 7); 112 OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 8); 113 114protected: 115 116 virtual void deallocateBufferAddressSpace( void ); 117 virtual IOReturn allocateTimer( void ); 118 virtual void deallocateTimer( void ); 119 120 /*! 121 @function deallocatePageTable 122 @abstract Frees up memory allocated for the page table. 123 @discussion Frees all memory associated with the page table. Undoes what allocatePageTable does. 124 Calling allocatePageTable again will automatically deallocate the existing page table before 125 allocating a new one, so this method is not used in most cases. 126 */ 127 128 virtual void deallocatePageTable( void ); 129 130protected: 131 132 // IOFireWireSBP2Login methods 133 virtual bool initWithLogin( IOFireWireSBP2Login * login ); 134 virtual void setNextORBAddress( FWAddress address ); 135 136public: 137 138 /*! 139 @function allocatePageTable 140 @abstract Allocates memory for the page table. 141 @discussion Page table allocation is handle automatically by the ORB, except if the 142 kFWSBP2CommandFixedSize flags is set. In this case we will fail to write a page table if we 143 need more page table space than we have already. This method is exposed so these drivers 144 can preallocate as much page table as they need. This is useful if your driver is part of 145 the paging path and cannot allow allocations to occur. 146 @param entryCount number of entries of page table to be allocated. 147 */ 148 149 virtual IOReturn allocatePageTable( UInt32 entryCount ); 150 151protected: 152 153 virtual bool isTimerSet( void ); 154 virtual void cancelTimer( void ); 155 156protected: 157 158 // reserved for future use 159 struct ExpansionData { }; 160 ExpansionData *reserved; 161 162 IOFireWireSBP2Login * fLogin; 163 IOFireWireSBP2LUN * fLUN; 164 IOFireWireUnit * fUnit; 165 IOFireWireController * fControl; 166 IODMACommand * fDMACommand; 167 void * fUnused2; 168 169 UInt32 fCommandFlags; 170 UInt32 fMaxPayloadSize; 171 UInt32 fTimeoutDuration; 172 UInt32 fGeneration; 173 UInt64 fRefCon; 174 175 // 176 // orb 177 // 178 179 IOMemoryDescriptor * fORBDescriptor; 180 FWSBP2ORB * fORBBuffer; 181 182 FWAddress fORBPseudoAddress; 183 IOFWAddressSpace * fORBPseudoAddressSpace; 184 185 IOFWAddressSpace * fORBPhysicalAddressSpace; 186 FWAddress fORBPhysicalAddress; 187 188 // 189 // page table 190 // 191 192 UInt32 fPageTableSize; 193 IOBufferMemoryDescriptor * fPageTableDescriptor; 194 195 IOFWAddressSpace * fPageTablePhysicalAddressSpace; 196 FWAddress fPageTablePhysicalAddress; 197 UInt32 fPageTablePhysicalLength; 198 199 IOFWAddressSpace * fPageTablePseudoAddressSpace; 200 FWAddress fPageTablePseudoAddress; 201 202 // 203 // buffers 204 // 205 206 IOFWAddressSpace * fBufferAddressSpace; 207 bool fBufferAddressSpaceAllocated; 208 IOMemoryDescriptor * fBufferDescriptor; 209 210 // 211 // timer 212 // 213 214 IOFWDelayCommand * fTimeoutCommand; 215 bool fTimeoutTimerSet; 216 217 bool fInProgress; 218 bool fIsAppended; 219 220 UInt32 fFetchAgentWriteRetries; 221 UInt32 fPTECount; 222 UInt32 fFetchAgentWriteRetryInterval; 223 224 UInt32 fConstraintOptions; 225 226 virtual IOReturn allocateResources( void ); 227 virtual void free( void ); 228 229 // orb timeout handler 230 static void orbTimeoutStatic( void *refcon, IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd ); 231 virtual void orbTimeout( IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd ); 232 233 // login friend class wrappers 234 virtual IOFireWireUnit * getFireWireUnit( void ); 235 virtual IOFireWireSBP2LUN * getFireWireLUN( void ); 236 virtual void deallocateORB( void ); 237 virtual IOReturn allocateORB( UInt32 orbSize ); 238 virtual IOReturn removeORB( IOFireWireSBP2ORB * orb ); 239 virtual void prepareORBForExecution( void ); 240 virtual void startTimer( void ); 241 virtual void sendTimeoutNotification( IOFireWireSBP2ORB * orb ); 242 243public: 244 245 /*! 246 @function release 247 @abstract Primary implementation of the release mechanism. 248 @discussion See OSObject.h for more information. 249 @param when When retainCount == when then call free(). 250 */ 251 252 virtual void release() const; 253 254 /*! 255 @function getLogin 256 @abstract Gets the login associated with this ORB. 257 @discussion Returns the IOFireWireSBP2Login object associated with this ORB. 258 @result Returns a pointer to an IOFireWireSBP2Login. 259 */ 260 261 virtual IOFireWireSBP2Login * getLogin( void ); 262 263 /*! 264 @function setCommandBuffersAsRanges 265 @abstract Creates a page table from a list of ranges. 266 @discussion Creates a page table with the given parameters. Any addresses mapped by this method 267 must remain valid until setCommandBuffers is called again or releaseCommandBuffers is called. 268 The SBP2 services do not release references to the command buffers just because the command 269 has completed. 270 @param ranges An array of ranges representing the data to be transfered. 271 @param withCount The number of ranges in the ranges array. 272 @param withDirection An IODirection indicating the direction of data transfer. 273 @param withTask The task that these adressses reside in. 274 @param offset Offset in bytes into data to begin writing table at. 275 @param length Number of bytes of data to map from offset. 276 @result Returns KIOReturnSuccess if the page table was written successfully. 277 */ 278 279 virtual IOReturn setCommandBuffersAsRanges( IOVirtualRange * ranges, 280 UInt32 withCount, 281 IODirection withDirection, 282 task_t withTask, 283 UInt32 offset = 0, 284 UInt32 length = 0 ); 285 /*! 286 @function setCommandBuffersAsRanges 287 @abstract Creates a page table from a list of ranges. 288 @discussion Creates a page table with the given parameters. Any addresses mapped by this method 289 must remain valid until setCommandBuffers is called again or releaseCommandBuffers is called. 290 The SBP2 services do not release references to the command buffers just because the command 291 has completed. 292 @param memoryDescriptor IOMemoryDescriptor describe ranges to be written to a page table. 293 @param offset Offset in bytes into data to begin writing table at. 294 @param length Number of bytes of data to map from offset. 295 @result Returns KIOReturnSuccess if the page table was written successfully. 296 */ 297 298 virtual IOReturn setCommandBuffers( IOMemoryDescriptor * memoryDescriptor, UInt32 offset = 0, 299 UInt32 length = 0 ); 300 301 302 /*! 303 @function releaseCommandBuffers 304 @abstract Releases SBP2's reference to the command buffers. 305 @discussion When you create a page table with one of the variants of setCommandBuffers. 306 SBP2 holds on to a reference to the buffers until this method is called. This means that 307 if a command completed and you manipulated the memory descriptor or released the buffers 308 without calling this method you could leave FW in an inconsistent state. 309 @result Returns KIOReturnSuccess if the page table was cleared successfully. 310 */ 311 312 virtual IOReturn releaseCommandBuffers( void ); 313 314 /*! 315 @function setCommandBlock 316 @abstract Sets the command block portion of the ORB. 317 @discussion Copys the data provided in the buffer to the command block portion of the ORB. 318 @param buffer Pointer to buffer to copy command block from. 319 @param length Number of bytes of data to copy. 320 @result Returns KIOReturnSuccess if the command block was updated successfully. 321 */ 322 323 virtual IOReturn setCommandBlock( void * buffer, UInt32 length ); 324 325 /*! 326 @function setCommandBlock 327 @abstract Sets the command block portion of the ORB. 328 @discussion Copys the data provided in the buffer to the command block portion of the ORB. 329 @param memory IOMemoryDescriptor representing the command block buffer. 330 @result Returns KIOReturnSuccess if the command block was updated successfully. 331 */ 332 333 virtual IOReturn setCommandBlock( IOMemoryDescriptor * memory ); 334 335 /*! 336 @function getCommandBufferDescriptor 337 @abstract Returns the memory descriptor representing the command buffer. 338 @discussion Returns the IOMemoryDescriptor for the data mapped by setCommandBuffer variants. 339 Works for setCommandBuffersAsRanges too. 340 @result Returns memory descriptor representing mapped data buffers. 341 */ 342 343 virtual IOMemoryDescriptor * getCommandBufferDescriptor( void ); 344 345 // accessors 346 347 /*! 348 @function setCommandFlags 349 @abstract Sets configuration flags for the ORB. 350 @discussion Sets the configuration flags for the ORB. These can be any of the following: 351 <p>kFWSBP2CommandCompleteNotify - Set the notify bit as specified in SBP2 standard. Set to receive completion/timeout notification on this ORB. You almost always want to set this.</p> 352 <p>kFWSBP2CommandTransferDataFromTarget - Transfer direction as specified in SBP2 standard. Set if data is to be written by the device into the host's memory.</p> 353 <p>kFWSBP2CommandImmediate - Immediate Append. ORB address will be written to fetch agent and not chained. It is only legal to have one immediate ORB in progress at a time.</p> 354 <p>kFWSBP2CommandNormalORB - ORB format 0 - Format specified by SBP2 standard. Set this for most ORBs.</p> 355 <p>kFWSBP2CommandReservedORB - ORB format 1 - Format reserved by SBP2 standard for future standardization.</p> 356 <p>kFWSBP2CommandVendorORB - ORB format 2 - Format specified by SBP2 standard for vendor dependent ORBs.</p> 357 <p>kFWSBP2CommandDummyORB - ORB format 3 - Format specified by SBP2 standard for dummy ORBs.</p> 358 <p>kFWSBP2CommandCheckGeneration - If set upon submitORB, the ORB will only be appended if generation set with setCommandGeneration() matches the current generation. Pretty much all SBP2 drivers need sophisticated logic to track login state, so this is generally not used. </p> 359 <p>kFWSBP2CommandFixedSize - Do not allocate more memory for page table if needed. If there is not enough space in the currently allocated page table, the setCommandBuffers call will fail. This is important to set if your device is the backing store, as we don't want to cause memory allocations on the paging path. </p> 360 <p>kFWSBP2CommandVirtualORBs - Normally ORBs are backed by physical address spaces. Setting this flag makes this ORB backed by a pseudo address space. This can make ORBs easier to see in a bus trace. Virtual ORBs will have an address in the form of ffcX.XXXX.0000.0000. Pseudo address space backed ORBs are slower, so you won't want to set for deployment builds.</p> 361 @param flags The flags to be set. 362 */ 363 364 virtual void setCommandFlags( UInt32 flags ); 365 366 /*! 367 @function getCommandFlags 368 @abstract Sets configuration flags for the ORB. 369 @discussion Returns the current configuration flags set on this ORB. 370 @result Return The current ORB flags. 371 */ 372 373 virtual UInt32 getCommandFlags( void ); 374 375 /*! 376 @function setMaxPayloadSize 377 @abstract Sets max payload size for the ORB. 378 @discussion This sets the maximum payload size for this ORB only. This size is clipped by 379 the global max payload size set in the login object. 380 @param maxPayloadSize The maximum payload size in bytes. 381 */ 382 383 virtual void setMaxPayloadSize( UInt32 maxPayloadSize ); 384 385 /*! 386 @function getMaxPayloadSize 387 @abstract Gets max payload size for the ORB. 388 @discussion This gets the maximum payload size for this ORB only. 389 @result Returns the maximum payload size in bytes. 390 */ 391 392 virtual UInt32 getMaxPayloadSize( void ); 393 394 /*! 395 @function setCommandTimeout 396 @abstract Sets the timeout of the ORB. 397 @discussion This sets the timeout for the ORB in milliseconds. Note that ORBs without timeouts 398 can be "lost." You will obviously not recieve timeout notification for timeouts of zero. But 399 perhaps less obviously you will not recieve orb reset notification, which is really a sort of 400 accelerated timeout notification for bus reset situations. 401 @param timeout The timeout duration in milliseconds. 402 */ 403 404 virtual void setCommandTimeout( UInt32 timeout ); 405 406 /*! 407 @function getCommandTimeout 408 @abstract Gets the timeout of the ORB. 409 @discussion This method gets the timeout for this ORB in milliseconds. 410 @result Returns the timeout for the orb in milliseconds. 411 */ 412 413 virtual UInt32 getCommandTimeout( void ); 414 415 416 /*! 417 @function setCommandGeneration 418 @abstract Sets the command generation. 419 @discussion This sets the bus generation this ORB should be appended in. It is only meaningful 420 when combined with the kFWSBP2CommandCheckGeneration flags above. 421 @param gen The bus generation for command execution. 422 */ 423 424 virtual void setCommandGeneration( UInt32 gen ); 425 426 /*! 427 @function getCommandGeneration 428 @abstract Gets the command generation. 429 @discussion This gets the bus generation this ORB should be appended in. 430 @result Returns the bus generation for command execution. 431 */ 432 433 virtual UInt32 getCommandGeneration( void ); 434 435 /*! 436 @function setRefCon 437 @abstract Sets the ORB refCon. 438 @discussion Sets a user defined value on the ORB that can be retrieved later with the 439 method getRefCon. 440 @param refCon a user defined value. 441 */ 442 443 virtual void setRefCon( void * refCon ); 444 445 /*! 446 @function getRefCon 447 @abstract Returns the refCon set with setRefCon. 448 @discussion Returns the user defined value previously stored in the ORB with setRefCon. 449 @result Returns the previously stored user defined value. 450 */ 451 452 virtual void * getRefCon( void ); 453 454protected: 455 456 virtual void setToDummy( void ); 457 458public: 459 /*! 460 @function getORBAddress 461 @abstract Returns the FireWire address of this ORB. 462 @discussion Returns the FireWire bus address of this ORB. This is not the same as the Macintosh 463 address for the IOFireWireSBP2ORB. 464 @result Returns the FireWire address of this ORB. 465 */ 466 467 virtual void getORBAddress( FWAddress * address ); 468 469protected: 470 471 virtual bool isAppended( void ); 472 virtual void setIsAppended( bool state ); 473 virtual UInt32 getFetchAgentWriteRetries( void ); 474 virtual void setFetchAgentWriteRetries( UInt32 retries ); 475 476 virtual void prepareFastStartPacket( IOBufferMemoryDescriptor * descriptor ); 477 478 UInt32 getFetchAgentWriteRetryInterval( void ); 479 void setFetchAgentWriteRetryInterval( UInt32 interval ); 480 481 IOReturn completeBufferAddressSpace( void ); 482 IOReturn prepareBufferAddressSpace( IOMemoryDescriptor * memoryDescriptor ); 483 484public: 485 486 /*! 487 @function setBufferConstraints 488 @abstract Configures page table generation parameters 489 @discussion Sets the maximums size of any page table segment and the required alignemnt. Double buffering 490 may be used to satisfy these constraints. The only supported option is kFWSBP2ConstraintForceDoubleBuffer which 491 forces a page aligned double buffering of the entire descriptor. 492 @result May return an error if there is a problem allocating the underlying resources or if buffers are currently attached. 493 */ 494 495 IOReturn setBufferConstraints( UInt64 maxSegmentSize, UInt32 alignment, UInt32 options = 0); 496 497 498 /*! 499 @function setCommandBuffersAsRanges64 500 @abstract Creates a page table from a list of 64 bit ranges. 501 @discussion Creates a page table with the given parameters. Any addresses mapped by this method 502 must remain valid until setCommandBuffers is called again or releaseCommandBuffers is called. 503 The SBP2 services do not release references to the command buffers just because the command 504 has completed. This is a 64 bit compatible version of setCommandBuffersAsRanges. 505 @param ranges An array of ranges representing the data to be transfered. 506 @param withCount The number of ranges in the ranges array. 507 @param withDirection An IODirection indicating the direction of data transfer. 508 @param withTask The task that these adressses reside in. 509 @param offset Offset in bytes into data to begin writing table at. 510 @param length Number of bytes of data to map from offset. 511 @result Returns KIOReturnSuccess if the page table was written successfully. 512 */ 513 514 IOReturn setCommandBuffersAsRanges64( IOAddressRange * ranges, 515 uint64_t withCount, 516 IODirection withDirection, 517 task_t withTask, 518 uint64_t offset = 0, 519 uint64_t length = 0); 520 521 /*! 522 @function setRefCon64 523 @abstract Sets the ORB refCon as a 64 bit value. 524 @discussion Sets a user defined value on the ORB that can be retrieved later with the 525 method getRefCon. 526 @param refCon a user defined value. 527 */ 528 529 virtual void setRefCon64( UInt64 refCon ); 530 531 /*! 532 @function getRefCon64 533 @abstract Returns the 64 bit refCon set with setRefCon64. 534 @discussion Returns the user defined value previously stored in the ORB with setRefCon. 535 @result Returns the previously stored user defined value. 536 */ 537 538 virtual UInt64 getRefCon64( void ); 539 540protected: 541 542 UInt32 calculateTransferSizeLog( bool * clipping ); 543 544 545}; 546 547#endif 548