1/* 2 * Copyright (c) 2002-2008 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#ifndef __IOKIT_IO_SCSI_PARALLEL_INTERFACE_CONTROLLER_H__ 25#define __IOKIT_IO_SCSI_PARALLEL_INTERFACE_CONTROLLER_H__ 26 27 28 /*! 29 @header IOSCSIParallelInterfaceController 30 The IOSCSIParallelInterfaceController class and the associated HBA child 31 class is responsible for the management of all related hardware. This 32 includes the onboard HBA controller chip and the physical state of the 33 bus. These classes are not responsible for any of the management of 34 the SCSI Devices on the bus with the exception of maintaining the queue that 35 holds the objects representing those SCSI Devices. 36*/ 37 38 39//----------------------------------------------------------------------------- 40// Includes 41//----------------------------------------------------------------------------- 42 43// General IOKit includes 44#include <IOKit/IOService.h> 45#include <IOKit/IOWorkLoop.h> 46#include <IOKit/IOCommandGate.h> 47#include <IOKit/IODMACommand.h> 48#include <IOKit/IOInterruptEventSource.h> 49#include <IOKit/IOFilterInterruptEventSource.h> 50#include <IOKit/IOTimerEventSource.h> 51#include <IOKit/IOCommandPool.h> 52 53// IOKit SCSI ArchitectureModel Family includes 54#include <IOKit/scsi/SCSITask.h> 55#include <IOKit/scsi/SCSICmds_REQUEST_SENSE_Defs.h> 56#include <IOKit/scsi/SCSIPort.h> 57 58//----------------------------------------------------------------------------- 59// Constants 60//----------------------------------------------------------------------------- 61 62 63#define kIOPropertySCSIDeviceFeaturesKey "SCSI Device Features" 64#define kIOPropertySCSI_I_T_NexusFeaturesKey "SCSI I_T Nexus Features" 65 66// Set this key with a value of true in ReportHBAConstraints() to indicate support 67// for full 8-byte LUN addressing and use GetLogicalUnitBytes() to obtain the 68// full 8-byte LUN when processing commands in ProcessParallelTask(). 69#define kIOHierarchicalLogicalUnitSupportKey "SCSI Hierarchical Logical Unit Support" 70 71// This is the alignment mask used when allocating per-task HBA data. It allows 72// the HBA to declare whether or not it supports 64-bit addressability and what the 73// minimum byte alignment is for the data. E.g. By specifying 0x0000FFFFFFFFFFFEULL, 74// the controller would be indicating that it supports 48-bits of addressability, but 75// at a minimum of being 2-byte aligned. 76#define kIOMinimumHBADataAlignmentMaskKey "HBA Data Alignment" 77 78// The Feature Selectors used to identify features of the SCSI Parallel 79// Interface. These are used by the DoesHBASupportSCSIParallelFeature 80// to report whether the HBA supports a given SCSI Parallel Interface 81// feature and are used for requesting negotiation and reporting negotiation 82// results between the controller and the device. 83 84// When the DoesHBASupportSCSIParallelFeature() member routine of the controller 85// child class is called, it will return true if the HBA that it controls 86// supports the specified SCSIParallelFeature or false if it does not. 87typedef enum SCSIParallelFeature 88{ 89 // The selector for support of Wide Data Transfers. Only Wide16 is supported 90 // as Wide32 has been obsoleted by the SPI-3 specification. 91 kSCSIParallelFeature_WideDataTransfer = 0, 92 93 // The selector for support of Synchronous Data Transfers. 94 kSCSIParallelFeature_SynchronousDataTransfer = 1, 95 96 // The selector for support of Quick Arbitration and Selection (QAS). 97 kSCSIParallelFeature_QuickArbitrationAndSelection = 2, 98 99 // The selector for support of Double Transition (DT) data transfers. 100 kSCSIParallelFeature_DoubleTransitionDataTransfers = 3, 101 102 // The selector for SPI Information Unit (IU) transfers. 103 kSCSIParallelFeature_InformationUnitTransfers = 4, 104 105 // Since the Feature selectors are zero base, this will always have the 106 // correct total. 107 kSCSIParallelFeature_TotalFeatureCount 108} SCSIParallelFeature; 109 110 111typedef enum SCSIParallelFeatureRequest 112{ 113 // This selector indicates that current negotiation 114 // should be used. 115 kSCSIParallelFeature_NoNegotiation = 0, 116 117 // This selector indicates that the controller 118 // should attempt negotiation for the feature 119 kSCSIParallelFeature_AttemptNegotiation = 1, 120 121 // This selector indicates that the controller 122 // should clear any negotiation for the feature 123 kSCSIParallelFeature_ClearNegotiation = 2 124} SCSIParallelFeatureRequest; 125 126typedef enum SCSIParallelFeatureResult 127{ 128 kSCSIParallelFeature_NegotitiationUnchanged = 0, 129 kSCSIParallelFeature_NegotitiationCleared = 1, 130 kSCSIParallelFeature_NegotitiationSuccess = 2 131} SCSIParallelFeatureResult; 132 133 134// The SCSI Message Codes used for MESSAGE IN and MESSAGE OUT phases. 135enum SCSIParallelMessages 136{ 137 // Link Control Messages 138 kSCSIParallelMessage_TASK_COMPLETE = 0x00, 139 kSCSIParallelMessage_EXTENDED_MESSAGE = 0x01, 140 kSCSIParallelMessage_SAVE_DATA_POINTER = 0x02, 141 kSCSIParallelMessage_RESTORE_POINTERS = 0x03, 142 kSCSIParallelMessage_DISCONNECT = 0x04, 143 kSCSIParallelMessage_INITIATOR_DETECTED_ERROR = 0x05, 144 kSCSIParallelMessage_MESSAGE_REJECT = 0x07, 145 kSCSIParallelMessage_NO_OPERATION = 0x08, 146 kSCSIParallelMessage_MESSAGE_PARITY_ERROR = 0x09, 147 kSCSIParallelMessage_IGNORE_WIDE_RESIDUE = 0x23, 148 kSCSIParallelMessage_QAS_REQUEST = 0x55, 149 kSCSIParallelMessage_IDENTIFY = 0x80, 150 151 // The Message Codes used in the EXTENDED_MESSAGE message. 152 kSCSIParallelMessage_MODIFY_DATA_POINTER = 0x00, 153 kSCSIParallelMessage_SYNCHONOUS_DATA_TRANSFER_REQUEST = 0x01, 154 // Reserved = 0x02 155 kSCSIParallelMessage_WIDE_DATA_TRANSFER_REQUEST = 0x03, 156 kSCSIParallelMessage_PARALLEL_PROTOCOL_REQUEST = 0x04, 157 // Reserved = 0x05 through 0xFF 158 159 // Task Attribute Message Codes 160 kSCSIParallelMessage_ACA = 0x24, 161 kSCSIParallelMessage_HEAD_OF_QUEUE = 0x21, 162 kSCSIParallelMessage_LINKED_COMMAND_COMPLETE = 0x0A, 163 kSCSIParallelMessage_ORDERED = 0x22, 164 kSCSIParallelMessage_SIMPLE = 0x20, 165 166 // Task Management Message Codes 167 kSCSIParallelMessage_ABORT_TASK = 0x0D, 168 kSCSIParallelMessage_ABORT_TASK_SET = 0x06, 169 kSCSIParallelMessage_CLEAR_ACA = 0x16, 170 kSCSIParallelMessage_CLEAR_TASK_SET = 0x0E, 171 kSCSIParallelMessage_LOGICAL_UNIT_RESET = 0x17, 172 kSCSIParallelMessage_TARGET_RESET = 0x0C 173}; 174 175enum 176{ 177 kSCSIParallelTaskControllerIDQueueHead = 0 178}; 179 180// Notifications 181enum 182{ 183 kSCSIControllerNotificationBusReset = 0x68000000 184}; 185 186// Forward declaration for the internally used Parallel Device object. 187class IOSCSIParallelInterfaceDevice; 188 189// This is the identifier that is used to specify a given parallel Task. 190typedef OSObject * SCSIParallelTaskIdentifier; 191 192 193//----------------------------------------------------------------------------- 194// Class Declarations 195//----------------------------------------------------------------------------- 196 197/*! @class IOSCSIParallelInterfaceController 198 @abstract Class that represents a SCSI Host Bus Adapter. 199 @discussion Class that represents a SCSI Host Bus Adapter. 200*/ 201class IOSCSIParallelInterfaceController : public IOService 202{ 203 204 OSDeclareAbstractStructors ( IOSCSIParallelInterfaceController ) 205 206#if 0 207#pragma mark - 208#pragma mark Client API 209#endif 210 211 212public: 213 214 /*! 215 @function GetSCSIParallelTask 216 @abstract Method to allow the client to get a SCSIParallelTask 217 @discussion Get a SCSIParallelTask from the controller so that a request 218 can be issued to the HBA driver. 219 @param blockForCommand If the blockForCommand parameter is set to false 220 and there are no free SCSIParallelTasks, this method will return NULL, 221 otherwise it will wait for one to become available before returning. 222 @result If there is a SCSI Parallel Task available, a reference to it 223 will be returned. 224 */ 225 226 SCSIParallelTaskIdentifier GetSCSIParallelTask ( bool blockForCommand ); 227 228 /*! 229 @function FreeSCSIParallelTask 230 @abstract Method to allow the client to release a SCSIParallelTask 231 @discussion The FreeSCSIParallelTask method is called by the client when 232 a SCSIParallelTask has been completed and the associated returnTask 233 needs to be returned to the pool. 234 @param returnTask is a reference to the SCSIParallelTaskIdentifier to be 235 returned. 236 */ 237 238 void FreeSCSIParallelTask ( SCSIParallelTaskIdentifier returnTask ); 239 240 /*! 241 @function FindTaskForAddress 242 @abstract Find a task for a given Task Address, if one exists. 243 @discussion If a valid Tagged Task Identifier is specified, this method 244 will return the task specified by the Tagged Task Address if one is 245 found, or else NULL will be returned. If zero is used as the Tagged 246 Task Identifier, then this routine will search for an outstanding task 247 based on the Untagged Task Address and return the task or else, if one 248 is not found, return NULL. 249 @param theT is the Target component of the I_T_L or I_T_L_Q nexus. 250 @param theL is the Logical Unit component of the I_T_L or I_T_L_Q nexus. 251 @param theQ is the Queue Tag component of the I_T_L_Q nexus. If this is 252 an I_T_L nexus, then the kSCSIUntaggedTaskIdentifier constant should be 253 used for theQ. 254 @result returns a valid SCSIParallelTaskIdentifier or NULL if none 255 found. 256 */ 257 258 SCSIParallelTaskIdentifier FindTaskForAddress ( 259 SCSIDeviceIdentifier theT, 260 SCSILogicalUnitNumber theL, 261 SCSITaggedTaskIdentifier theQ ); 262 263 264 /*! 265 @function FindTaskForControllerIdentifier 266 @abstract Find a task for a given Target and Controller Task Identifier 267 @discussion Allows the controller child class to find an outstanding task 268 for a specified target and controller task identifier 269 @param theTarget is the Target that the task . 270 @param theIdentifier is the controller task identifier set using the SCSI 271 Parallel Task's SetControllerTaskIdentifier() method. 272 @result returns a valid SCSIParallelTaskIdentifier or NULL if none 273 found. 274 */ 275 276 SCSIParallelTaskIdentifier FindTaskForControllerIdentifier ( 277 SCSIDeviceIdentifier theTarget, 278 UInt64 theIdentifier ); 279 280 281 /*! 282 @function ExecuteParallelTask 283 @abstract Submit a SCSIParallelTask for execution. 284 @discussion The ExecuteParallelTask call is made by the client to submit 285 a SCSIParallelTask for execution. 286 @param parallelRequest is a reference to the SCSIParallelTaskIdentifier 287 to be executed. 288 @result is an appropriate SCSIServiceResponse which are defined in the 289 file <IOKit/scsi/SCSITask.h>. 290 */ 291 292 SCSIServiceResponse ExecuteParallelTask ( 293 SCSIParallelTaskIdentifier parallelRequest ); 294 295 // --- Public API methods provided by HBA child classes ---- 296 297 /*! 298 @function ReportHBAHighestLogicalUnitNumber 299 @abstract Gets the Highest Logical Unit Number. 300 @discussion This method is used to query the HBA child class to 301 determine what the highest Logical Unit Number that the controller can 302 address. 303 @result returns a valid 64-bit logical unit number. 304 */ 305 306 virtual SCSILogicalUnitNumber ReportHBAHighestLogicalUnitNumber ( void ) = 0; 307 308 /*! 309 @function DoesHBASupportSCSIParallelFeature 310 @abstract Queries the HBA child class to determine if it supports a 311 specific SPI feature. 312 @discussion Queries the HBA child class to determine if it supports the 313 specified feature as defined by the SCSI Parallel Interconnect 314 specifications. 315 @result Returns true if requested feature is supported. 316 */ 317 318 virtual bool DoesHBASupportSCSIParallelFeature ( 319 SCSIParallelFeature theFeature ) = 0; 320 321 /*! 322 @function InitializeTargetForID 323 @abstract Called to initialize a target device. 324 @discussion This method will be called to initialize a target device in 325 a single-threaded manner. The HBA can use this method to probe the 326 target or do anything else necessary before the device object is 327 registered with IOKit for matching. 328 @result Returns true if the target was successfully initialized. 329 */ 330 331 virtual bool InitializeTargetForID ( 332 SCSITargetIdentifier targetID ) = 0; 333 334 // The SCSI Task Management Functions as defined in the SCSI Architecture 335 // Model - 2 (SAM-2) specification. These are used by the client to request 336 // the specified function. The controller can complete these immmediately 337 // by returning the appropriate SCSIServiceResponse, or these can be completed 338 // asyncronously by the controller returning a SCSIServiceResponse of 339 // kSCSIServiceResponse_Request_In_Process and then calling the appropriate 340 // function complete member routine listed in the child class API section. 341 342 virtual SCSIServiceResponse AbortTaskRequest ( 343 SCSITargetIdentifier theT, 344 SCSILogicalUnitNumber theL, 345 SCSITaggedTaskIdentifier theQ ) = 0; 346 347 virtual SCSIServiceResponse AbortTaskSetRequest ( 348 SCSITargetIdentifier theT, 349 SCSILogicalUnitNumber theL ) = 0; 350 351 virtual SCSIServiceResponse ClearACARequest ( 352 SCSITargetIdentifier theT, 353 SCSILogicalUnitNumber theL ) = 0; 354 355 virtual SCSIServiceResponse ClearTaskSetRequest ( 356 SCSITargetIdentifier theT, 357 SCSILogicalUnitNumber theL ) = 0; 358 359 virtual SCSIServiceResponse LogicalUnitResetRequest ( 360 SCSITargetIdentifier theT, 361 SCSILogicalUnitNumber theL ) = 0; 362 363 virtual SCSIServiceResponse TargetResetRequest ( 364 SCSITargetIdentifier theT ) = 0; 365 366 367 368 /*! 369 @function DoesHBAPerformAutoSense 370 @abstract Queries the HBA child class to determine if it automatically 371 performs AutoSense and provides AutoSense data for each I/O. If the HBA 372 allocates space for AutoSense in its HBA specific data region on a per 373 task basis, the HBA should respond true. 374 @discussion Queries the HBA child class to determine if it automatically 375 performs AutoSense and provides AutoSense data for each I/O. If the HBA 376 allocates space for AutoSense in its HBA specific data region on a per 377 task basis, the HBA should respond true. 378 @result Return true if HBA performs AutoSense into its own private data 379 buffer. 380 */ 381 382 OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 1 ); 383 384 virtual bool DoesHBAPerformAutoSense ( void ); 385 386 /*! 387 @function ReportHBAConstraints 388 @abstract Called to report the I/O constraints for this controller. 389 A list of valid keys includes: 390 kIOMaximumSegmentCountReadKey, (required) 391 kIOMaximumSegmentCountWriteKey, (required) 392 kIOMaximumSegmentByteCountReadKey, (required) 393 kIOMaximumSegmentByteCountWriteKey, (required) 394 kIOMinimumSegmentAlignmentByteCountKey, (required) 395 kIOMaximumSegmentAddressableBitCountKey, (required) 396 kIOMinimumHBADataAlignmentMaskKey (required) 397 kIOHierarchicalLogicalUnitSupportKey (optional). 398 NB: These keys and their values are described in this header and <IOKit/IOKitKeys.h> 399 @param constraints. An OSDictionary object used to aggregate the key/value pairs. 400 Subclasses must set the required keys if they override this method. If a subclass does 401 not provide the required keys, the system will panic. 402 */ 403 OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 2 ); 404 405 virtual void ReportHBAConstraints ( OSDictionary * constraints ); 406 407 /*! 408 @function DoesHBASupportMultiPathing 409 @abstract Queries the HBA child class to determine if it supports 410 Multi-Pathing. 411 @discussion Queries the HBA child class to determine if it supports 412 Multi-Pathing. 413 @result Returns true if requested feature is supported. 414 */ 415 OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 3 ); 416 417 virtual bool DoesHBASupportMultiPathing ( void ); 418 419 420 // Padding for the Client API 421 OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 4 ); 422 OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 5 ); 423 OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 6 ); 424 OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 7 ); 425 OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 8 ); 426 427 428#if 0 429#pragma mark - 430#pragma mark Child Class API 431#endif 432 433 434protected: 435 436 // ---- Target Creation and Destruction methods --- 437 438 /*! 439 @function CreateTargetForID 440 @abstract Method to perform device creation. 441 @discussion For HBA child classes that report true to the 442 DoesHBAPerformDeviceManagement() method, the child class will be 443 responsible for all device management by using these methods; 444 otherwise, the superclass will be responsible for all device management. 445 This method must be used to perform SCSI Parallel Device creation and 446 cannot be overridden. 447 @param targetID SCSIDeviceIdentifier of desired targetID. 448 @result returns true if successful. 449 */ 450 451 bool CreateTargetForID ( SCSIDeviceIdentifier targetID ); 452 453 /*! 454 @function CreateTargetForID 455 @abstract Method to perform device creation. 456 @discussion For HBA child classes that report true to the 457 DoesHBAPerformDeviceManagement() method, the child class will be 458 responsible for all device management by using these methods; 459 otherwise, the superclass will be responsible for all device management. 460 This method must be used to perform SCSI Parallel Device creation and 461 cannot be overridden. 462 @param targetID SCSIDeviceIdentifier of desired targetID. 463 @param properties A dictionary of properties to associate with the device 464 upon creation. The list of valid property keys is as follows: 465 kIOPropertySASAddressKey, 466 kIOPropertyFibreChannelNodeWorldWideNameKey, 467 kIOPropertyFibreChannelPortWorldWideNameKey, 468 kIOPropertyFibreChannelAddressIdentifierKey, 469 kIOPropertyFibreChannelALPAKey, and 470 kIOPropertyRetryCountKey 471 These keys are defined in 472 <IOKit/storage/IOStorageProtocolCharacteristics.h> and the values 473 associated with these keys must be of the proper type/size, 474 or the target creation will not succeed. 475 @result returns true if successful. 476 */ 477 478 bool CreateTargetForID ( SCSIDeviceIdentifier targetID, 479 OSDictionary * properties ); 480 481 /*! 482 @function DestroyTargetForID 483 @abstract Method to perform device destruction. 484 @discussion For HBA child classes that report true to the 485 DoesHBAPerformDeviceManagement() method, the child class will be 486 responsible for all device management by using these methods; otherwise, 487 the superclass will be responsible for all device management. 488 This method must be used to perform SCSI Parallel Device destruction and 489 cannot be overridden. 490 @param targetID SCSIDeviceIdentifier of desired targetID. 491 */ 492 493 void DestroyTargetForID ( SCSIDeviceIdentifier targetID ); 494 495 /*! 496 @function GetTargetForID 497 @abstract Accessor for getting pointer to IOSCSIParallelInterfaceDevice. 498 @param targetID SCSIDeviceIdentifier of desired targetID. 499 @result returns pointer to IOSCSIParallelInterfaceDevice or NULL if not 500 found. 501 */ 502 503 IOSCSIParallelInterfaceDevice * GetTargetForID ( 504 SCSIDeviceIdentifier targetID ); 505 506 /*! 507 @function SetTargetProperty 508 @abstract Accessor for setting a property for a specific target. 509 @param device A pointer to a valid IOSCSIParallelInterfaceDevice. 510 @param key A pointer to a valid OSString object which represents the key. 511 A list of valid keys includes: 512 kIOPropertySASAddressKey, 513 kIOPropertyFibreChannelNodeWorldWideNameKey, 514 kIOPropertyFibreChannelPortWorldWideNameKey, 515 kIOPropertyFibreChannelAddressIdentifierKey, and 516 kIOPropertyFibreChannelALPAKey. 517 NB: These keys and their values are described in <IOKit/storage/IOStorageProtocolCharacteristics.h> 518 @param value Pointer to an OSObject (one of type OSData, OSString, etc.) 519 which represents the value for the property. The value must be of the proper type 520 and size for the specified key. 521 @result returns true if identifier was properly set, otherwise false. 522 */ 523 524 bool SetTargetProperty ( SCSIDeviceIdentifier targetID, 525 const char * key, 526 OSObject * value ); 527 528 /*! 529 @function RemoveTargetProperty 530 @abstract Accessor for removing a property from a specific target. 531 @param device A pointer to a valid IOSCSIParallelInterfaceDevice. 532 @param key A pointer to a valid OSString object which represents the key. 533 */ 534 535 void RemoveTargetProperty ( SCSIDeviceIdentifier targetID, 536 const char * key ); 537 538 // ---- Methods for HBA specifics. ---- 539 540 /*! 541 @function SetHBAProperty 542 @abstract Accessor for setting a property for this object. 543 @param key A pointer to a valid OSString object which represents the key. 544 A list of valid keys includes: 545 kIOPropertyVendorNameKey, 546 kIOPropertyProductNameKey, 547 kIOPropertyProductRevisionLevelKey, 548 kIOPropertyPortDescriptionKey, 549 kIOPropertyPortSpeedKey, 550 kIOPropertyPortTopologyKey, 551 kIOPropertySCSIParallelSignalingTypeKey, 552 kIOPropertyFibreChannelCableDescriptionKey, 553 kIOPropertyFibreChannelNodeWorldWideNameKey, 554 kIOPropertyFibreChannelPortWorldWideNameKey, 555 kIOPropertyFibreChannelAddressIdentifierKey, 556 kIOPropertyFibreChannelALPAKey, and 557 kIOPropertySASAddressKey. 558 NB: These keys and their values are described in <IOKit/storage/IOStorageDeviceCharacteristics.h> 559 and <IOKit/storage/IOStorageProtocolCharacteristics.h> 560 @param value Pointer to an OSObject (one of type OSData, OSString, etc.) 561 which represents the value for the property. The value must be of the proper type, 562 and/or size for the specified key. 563 @result returns true if identifier was properly set, otherwise false. 564 */ 565 566 bool SetHBAProperty ( const char * key, 567 OSObject * value ); 568 569 /*! 570 @function RemoveHBAProperty 571 @abstract Accessor for removing a property for this object. 572 @param key A pointer to a valid OSString object which represents the key. 573 See the SetHBAProperty() method for a list of valid keys. 574 */ 575 576 void RemoveHBAProperty ( const char * key ); 577 578 // These methods will not be called before the InitializeController() call, 579 // and will not be called after the TerminateController() call. But in the 580 // interval between those calls, they shall report the correct requested 581 // information. They are implemented as seperate pure virtual methods 582 // instead of a selector driven method because the HBA child class is 583 // required to report this information. 584 585 /*! 586 @function ReportInitiatorIdentifier 587 @abstract Get the SCSI Device Identifier for the HBA. 588 @discussion This method will be called to determine the SCSI Device 589 Identifier that the Initiator has assigned for this HBA. 590 @result returns SCSIInitiatorIdentifier. 591 */ 592 593 virtual SCSIInitiatorIdentifier ReportInitiatorIdentifier ( void ) = 0; 594 595 /*! 596 @function ReportHighestSupportedDeviceID 597 @abstract Get the highest supported SCSI Device Identifier. 598 @discussion This method will be called to determine the value of the 599 highest SCSI Device Identifier supported by the HBA. This value will be 600 used to determine the last ID to process. 601 @result returns highest SCSIDeviceIdentifier 602 */ 603 604 virtual SCSIDeviceIdentifier ReportHighestSupportedDeviceID ( void ) = 0; 605 606 /*! 607 @function ReportMaximumTaskCount 608 @abstract Report Maximum Task Count 609 @discussion This method will be called to retrieve the maximum number of 610 outstanding tasks the HBA can process. This number must be greater than 611 zero or the controller driver will fail to match and load. 612 @result returns maximum (non-zero) task count. 613 */ 614 615 virtual UInt32 ReportMaximumTaskCount ( void ) = 0; 616 617 /*! 618 @function ReportHBASpecificTaskDataSize 619 @abstract Determine memory needed for HBA Task specific use. 620 @discussion This method is used to retrieve the amount of memory that 621 will be allocated in the SCSI Parallel Task for HBA specific use. 622 @result returns memory required in bytes 623 */ 624 625 virtual UInt32 ReportHBASpecificTaskDataSize ( void ) = 0; 626 627 /*! 628 @function ReportHBASpecificDeviceDataSize 629 @abstract Determine memory needed for HBA Device specific use. 630 @discussion This method is used to retrieve the amount of memory that 631 will be allocated in the SCSI Parallel Device for HBA specific use. 632 @result returns memory required in bytes 633 */ 634 635 virtual UInt32 ReportHBASpecificDeviceDataSize ( void ) = 0; 636 637 /*! 638 @function DoesHBAPerformDeviceManagement 639 @abstract Determine if HBA will manage devices. 640 @discussion This method is used to determine if the HBA will manage 641 target device creation and destruction. 642 @result return true means objects for target devices will only be 643 created when the child class calls the CreateTargetForID method. 644 */ 645 646 virtual bool DoesHBAPerformDeviceManagement ( void ) = 0; 647 648 // ---- Initialize and Terminate methods for the subclass to implement ----- 649 // The subclass shall not override the IOKit init and terminate methods, 650 // but shall instead rely on these methods for initialization and 651 // termination. 652 653 // This is done to allow for this superclass to manage all IOKit specifics 654 // and to require only a Family specific API to be implemented by the 655 // subclass drivers. 656 657 /*! 658 @function InitializeController 659 @abstract Called to initialize the controller 660 @discussion It is guaranteed that the InitializeController() will only be 661 called once per instantiation. The InitializeController() methods allows 662 the subclass driver to do all the necessary initialization required by 663 the hardware before it is able to accept requests to execute. All 664 necessary allocation of resources should be made during this method 665 call. This is the first method that will be called in the subclass. 666 @result return true means that initialization was successful. 667 */ 668 669 virtual bool InitializeController ( void ) = 0; 670 671 /*! 672 @function TerminateController 673 @abstract Called to terminate the controller 674 @discussion It is guaranteed that the TerminateController() will only be 675 called once and only after the InitializeController() method and only if 676 true was returned in response to the InitializeController() method. 677 The TerminateController() method allows the subclass to release all 678 resources that were acquired for operation of the hardware and shutdown 679 all hardware services. 680 This is the last method of the subclass that will be called before the 681 class is destroyed. 682 */ 683 684 virtual void TerminateController ( void ) = 0; 685 686 // ---- Start and Stop methods for the subclass ---- 687 688 /*! 689 @function StartController 690 @abstract Called to start the controller 691 @discussion The StartController will always be called before any 692 requests are sent to the driver for execution. This method is called 693 after an initialize to start the services provided by the specific HBA 694 driver or called after a StopController call to restart those services. 695 After this call completes, all services provided by the HBA driver are 696 available to the client. 697 @result return true means that start was successful. 698 */ 699 700 virtual bool StartController ( void ) = 0; 701 702 /*! 703 @function StopController 704 @abstract Called to stop the controller 705 @discussion The StopController method will be called any time that the 706 system wants the card to stop accepting requests. ( See StartController 707 discussion ). The subclass should disable the hardware interrupt for 708 the particular controller (if possible) in this method. 709 */ 710 711 virtual void StopController ( void ) = 0; 712 713 // ---- Suspend and Resume Methods for the subclass ---- 714 715 /*! 716 @function SuspendServices 717 @abstract Called to suspend controller services 718 @discussion Method will be called when the system wants to suspend the 719 services that are provided by the HBA driver. This call is not a reset 720 and the driver shall retain all state data between this so that if a 721 ResumeServices call is received, the driver can continue providing 722 services without a visible difference to the client. The driver may 723 receive multiple SuspendServices calls without receiving a 724 ResumeServices call and should ignore any after the first until a 725 ResumeServices call is received. 726 */ 727 728 virtual void SuspendServices ( void ); 729 730 /*! 731 @function ResumeServices 732 @abstract Called to resume controller services 733 @discussion Method that will be called to resume services 734 provided by the driver. ( See SuspendServices discussion ) 735 */ 736 737 virtual void ResumeServices ( void ); 738 739 /*! 740 @function HandleInterruptRequest 741 @abstract Handle Interrupt Request 742 @discussion The HandleInterruptRequest is used to notify an HBA 743 specific subclass that an interrupt request needs to be serviced. It is 744 called on the workloop (it holds the gate) at secondary interrupt level. 745 */ 746 747 virtual void HandleInterruptRequest ( void ) = 0; 748 749 /*! 750 @function EnableInterrupt 751 @abstract Enable Interrupt 752 @discussion Method that the HBA child class can call to enable 753 the associated IOInterruptEventSource. 754 */ 755 756 void EnableInterrupt ( void ); 757 758 /*! 759 @function DisableInterrupt 760 @abstract Disable Interrupt 761 @discussion Method that the HBA child class can call to disable 762 the associated IOInterruptEventSource. 763 */ 764 765 void DisableInterrupt ( void ); 766 767 /*! 768 @function SignalInterrupt 769 @abstract Signals that an interrupt has occurred. 770 @discussion Subclasses of IOSCSIParallelInterfaceController 771 should call this method in order to get the secondary interrupt 772 thread scheduled if and only if they will be returning false from 773 their overriden FilterInterruptRequest() method. See the 774 discussion for the FilterInterruptRequest() method for more 775 details. 776 777 NOTE: This method should only be called from within the 778 FilterInterruptRequest() method and at no other time. 779 780 Available in 10.3.3 or later. 781 782 */ 783 784 void SignalInterrupt ( void ); 785 786 /*! 787 @function ProcessParallelTask 788 @abstract Called by client to process a parallel task. 789 @discussion This method is called to process a parallel task (i.e. put 790 the command on the bus). The HBA specific sublcass must implement this 791 method. 792 @param parallelRequest A valid SCSIParallelTaskIdentifier. 793 @result serviceResponse (see <IOKit/scsi/SCSITask.h>) 794 */ 795 796 virtual SCSIServiceResponse ProcessParallelTask ( 797 SCSIParallelTaskIdentifier parallelRequest ) = 0; 798 799 /*! 800 @function CompleteParallelTask 801 @abstract Parallel Task Completion 802 @discussion The HBA specific sublcass inherits the CompleteParallelTask() 803 method which shall be called when the HBA has completed the processing 804 of a parallel task. 805 @param parallelTask A valid SCSIParallelTaskIdentifier. 806 @param completionStatus The status of the SCSI bus. 807 @param serviceResponse (see <IOKit/scsi/SCSITask.h>) 808 */ 809 810 void CompleteParallelTask ( 811 SCSIParallelTaskIdentifier parallelRequest, 812 SCSITaskStatus completionStatus, 813 SCSIServiceResponse serviceResponse ); 814 815 816 // Completion routines for the SCSI Task Management functions as described 817 // in the SCSI ArchitectureModel - 2 (SAM-2) specification. Each of these 818 // correspond to a client request for the specific Task Management functions. 819 // If the Controller Child Class completed the request by returning a 820 // SCSIServiceResponse of anything other than kSCSIServiceResponse_Request_In_Process, 821 // then the controller class does not need to call the completion member routine. 822 // If the controller did not complete the request immediately, then it will 823 // need to call the appropriate completion member routine listed here. 824 void CompleteAbortTask ( 825 SCSITargetIdentifier theT, 826 SCSILogicalUnitNumber theL, 827 SCSITaggedTaskIdentifier theQ, 828 SCSIServiceResponse serviceResponse ); 829 830 void CompleteAbortTaskSet ( 831 SCSITargetIdentifier theT, 832 SCSILogicalUnitNumber theL, 833 SCSIServiceResponse serviceResponse ); 834 835 void CompleteClearACA ( 836 SCSITargetIdentifier theT, 837 SCSILogicalUnitNumber theL, 838 SCSIServiceResponse serviceResponse ); 839 840 void CompleteClearTaskSet ( 841 SCSITargetIdentifier theT, 842 SCSILogicalUnitNumber theL, 843 SCSIServiceResponse serviceResponse ); 844 845 void CompleteLogicalUnitReset ( 846 SCSITargetIdentifier theT, 847 SCSILogicalUnitNumber theL, 848 SCSIServiceResponse serviceResponse ); 849 850 void CompleteTargetReset ( 851 SCSITargetIdentifier theT, 852 SCSIServiceResponse serviceResponse ); 853 854 /*! 855 @function NotifyClientsOfBusReset 856 @abstract Method called to notify clients that a bus reset has occurred. 857 @discussion This method is used by the HBA child class to inform the 858 parent class and any clients that a bus reset has occurred. 859 */ 860 861 void NotifyClientsOfBusReset ( void ); 862 863 /*! 864 @function NotifyClientsOfPortStatusChange 865 @abstract Method called to notify clients of port status change events. 866 @discussion This method is used by the HBA child class to inform the 867 parent class and any clients that a port has changed status. 868 */ 869 870 void NotifyClientsOfPortStatusChange ( SCSIPortStatus newStatus ); 871 872 /*! 873 @function GetSCSIDomainIdentifier 874 @abstract Accessor method to get the SCSI Domain Identifier. 875 @discussion Accessor method to get the SCSI Domain Identifier. 876 @result returns SCSI Domain Identifier. 877 */ 878 879 SInt32 GetSCSIDomainIdentifier ( void ); 880 881 /*! 882 @function GetProvider 883 @abstract Accessor method to get the IOService which is the controller's 884 provider. 885 @discussion Accessor method to get the IOService which is the 886 controller's provider. 887 @result returns pointer to IOService. 888 */ 889 890 IOService * GetProvider ( void ); 891 892 /*! 893 @function GetWorkLoop 894 @abstract Accessor method to get the IOWorkLoop associated with this 895 HBA. 896 @discussion Accessor method to get the IOWorkLoop associated with this 897 HBA. 898 @result returns pointer to IOWorkLoop. 899 */ 900 901 IOWorkLoop * GetWorkLoop ( void ) const; 902 903 /*! 904 @function GetCommandGate 905 @abstract Accessor to get an IOCommandGate associated with the workloop. 906 @discussion Accessor to get an IOCommandGate associated with the 907 workloop. 908 @result returns pointer to IOCommandGate. 909 */ 910 911 IOCommandGate * GetCommandGate ( void ); 912 913 // ---- SCSI Parallel Task Object Accessors ---- 914 915 /*! 916 @function GetSCSITaskIdentifier 917 @abstract Method to retrieve a SCSITaskIdentifier from a valid 918 SCSIParallelTaskIdentifier. 919 @discussion Method to retrieve a SCSITaskIdentifier from a valid 920 SCSIParallelTaskIdentifier. 921 @param parallelTask A valid SCSIParallelTaskIdentifier. 922 @result returns SCSITaskIdentifier that represents the original request 923 from the SCSI Application Layer client. 924 */ 925 926 SCSITaskIdentifier GetSCSITaskIdentifier ( 927 SCSIParallelTaskIdentifier parallelTask ); 928 929 /*! 930 @function GetTargetIdentifier 931 @abstract Method to get the SCSITargetIdentifier associated with a 932 request. 933 @discussion Method to get the SCSITargetIdentifier associated with a 934 request. 935 @param parallelTask A valid SCSIParallelTaskIdentifier. 936 @result returns SCSITargetIdentifier 937 */ 938 939 SCSITargetIdentifier GetTargetIdentifier ( 940 SCSIParallelTaskIdentifier parallelTask ); 941 942 // ---- Methods for Accessing data in the client's SCSI Task Object ---- 943 // Method to retrieve the LUN that identifies the Logical Unit whose Task 944 // Set to which this task is to be added. 945 946 /*! 947 @function GetLogicalUnitNumber 948 @abstract Method to get the logical unit number associated with a 949 request. 950 @discussion Method to get the logical unit number associated with a 951 request. 952 @param parallelTask A valid SCSIParallelTaskIdentifier. 953 @result returns a valid 64-bit logical unit number. 954 */ 955 956 SCSILogicalUnitNumber GetLogicalUnitNumber ( 957 SCSIParallelTaskIdentifier parallelTask ); // DEPRECATED, use GetLogicalUnitBytes instead. 958 959 /*! 960 @function GetLogicalUnitBytes 961 @abstract Method to get the logical unit bytes associated with a 962 request. 963 @discussion Method to get the logical unit bytes associated with a 964 request. 965 @param parallelTask A valid SCSIParallelTaskIdentifier. 966 @result returns a valid 8-byte logical unit address. 967 */ 968 969 void GetLogicalUnitBytes ( 970 SCSIParallelTaskIdentifier parallelTask, 971 SCSILogicalUnitBytes * logicalUnitBytes ); 972 973 /*! 974 @function GetTaggedTaskIdentifier 975 @abstract Method to retrieve the SCSI Tagged Task Identifier of the 976 task. If the returned value is equal to kSCSIUntaggedTaskIdentifier, 977 then this task is untagged. 978 @param parallelTask A valid SCSIParallelTaskIdentifier. 979 @result an SCSITaskAttribute value. 980 */ 981 982 SCSITaggedTaskIdentifier GetTaggedTaskIdentifier ( 983 SCSIParallelTaskIdentifier parallelTask ); 984 985 /*! 986 @function GetTaskAttribute 987 @abstract Method to retrieve the SCSI Task Attribute of the task 988 @param parallelTask A valid SCSIParallelTaskIdentifier. 989 @result an SCSITaskAttribute value. 990 */ 991 992 SCSITaskAttribute GetTaskAttribute ( 993 SCSIParallelTaskIdentifier parallelTask ); 994 995 /*! 996 @function GetCommandDescriptorBlockSize 997 @abstract Method to retrieve the size of the SCSI Command Descriptor 998 Block (CDB). 999 @param parallelTask A valid SCSIParallelTaskIdentifier. 1000 @result returns the size of the SCSI Command Descriptor Block in bytes. 1001 */ 1002 1003 UInt8 GetCommandDescriptorBlockSize ( 1004 SCSIParallelTaskIdentifier parallelTask ); 1005 1006 /*! 1007 @function GetCommandDescriptorBlock 1008 @abstract Method to retrieve the SCSI Command Descriptor Block (CDB). 1009 @discussion This will always return a 16 Byte CDB. If the Protocol Layer 1010 driver does not support 16 Byte CDBs, it will have to create a local 1011 SCSICommandDescriptorBlock variable to get the CDB data and then 1012 transfer the needed bytes from there. 1013 @param parallelTask A valid SCSIParallelTaskIdentifier. 1014 @param cdbData is a SCSICommandDescriptorBlock pointer to 16 byte CDB 1015 @result returns true if data was copied to cdbData pointer 1016 */ 1017 1018 bool GetCommandDescriptorBlock ( 1019 SCSIParallelTaskIdentifier parallelTask, 1020 SCSICommandDescriptorBlock * cdbData ); 1021 1022 /*! 1023 @function GetDataTransferDirection 1024 @abstract Retrieves the data transfer direction for any data associated 1025 with the request. 1026 @param parallelTask A valid SCSIParallelTaskIdentifier. 1027 @result One of the valid data transfer directions described in 1028 <IOKit/scsi/SCSITask.h> 1029 */ 1030 1031 UInt8 GetDataTransferDirection ( SCSIParallelTaskIdentifier parallelTask ); 1032 1033 /*! 1034 @function GetRequestedDataTransferCount 1035 @abstract Retrieves the requested data transfer count for any data 1036 associated with the request. 1037 @param parallelTask A valid SCSIParallelTaskIdentifier. 1038 @result The requested data transfer count in bytes. 1039 */ 1040 1041 UInt64 GetRequestedDataTransferCount ( 1042 SCSIParallelTaskIdentifier parallelTask ); 1043 1044 /*! 1045 @function GetRealizedDataTransferCount 1046 @abstract Retrieves the realized data transfer count for any data 1047 associated with the request. 1048 @param parallelTask A valid SCSIParallelTaskIdentifier. 1049 @result The realized data transfer count in bytes. 1050 */ 1051 1052 UInt64 GetRealizedDataTransferCount ( 1053 SCSIParallelTaskIdentifier parallelTask ); 1054 1055 /*! 1056 @function SetRealizedDataTransferCount 1057 @abstract Sets the realized data transfer count in bytes. 1058 @param parallelTask A valid SCSIParallelTaskIdentifier. 1059 @param realizedTransferCountInBytes is the number of bytes actually 1060 transferred. 1061 @result true means the data transfer count was successfully set. 1062 */ 1063 1064 bool SetRealizedDataTransferCount ( 1065 SCSIParallelTaskIdentifier parallelTask, 1066 UInt64 realizedTransferCountInBytes ); 1067 1068 /*! 1069 @function IncrementRealizedDataTransferCount 1070 @abstract Increments the realized data transfer count. This method is 1071 helpful for when the HBA has to do multiple passes of DMA because there 1072 are more scatter-gather elements than it can process in one pass. 1073 @param parallelTask A valid SCSIParallelTaskIdentifier. 1074 @param realizedTransferCountInBytes is the number of bytes to add to the 1075 realized data count for the task. 1076 */ 1077 1078 void IncrementRealizedDataTransferCount ( 1079 SCSIParallelTaskIdentifier parallelTask, 1080 UInt64 realizedTransferCountInBytes ); 1081 1082 /*! 1083 @function GetDataBuffer 1084 @abstract Method to retrieve client buffer from the request. 1085 @param parallelTask A valid SCSIParallelTaskIdentifier. 1086 @result returns pointer to an IOMemoryDescriptor which represents the 1087 buffer. 1088 */ 1089 1090 IOMemoryDescriptor * GetDataBuffer ( 1091 SCSIParallelTaskIdentifier parallelTask ); 1092 1093 /*! 1094 @function GetDataBufferOffset 1095 @abstract Method to retrieve offset into client buffer at which to start 1096 processing. 1097 @param parallelTask A valid SCSIParallelTaskIdentifier. 1098 @result returns offset in bytes 1099 */ 1100 1101 UInt64 GetDataBufferOffset ( SCSIParallelTaskIdentifier parallelTask ); 1102 1103 /*! 1104 @function GetDMACommand 1105 @abstract Method to retrieve a pointer to an IODMACommand from the request. 1106 @discussion For devices utilizing DMA, the IODMACommand object should be 1107 obtained via GetDMACommand(). The subclass is responsible for calling prepare() 1108 on the IODMACommand object using the proper offset obtained via GetDataBufferOffset() 1109 and correct size obtained via GetRequestedDataTransferCount(). The subclass 1110 is further responsible for calling complete() on the IODMACommand object once 1111 all DMA operations have finished. 1112 NB: Subclasses should not call IODMACommand::setMemoryDescriptor(). 1113 @param parallelTask A valid SCSIParallelTaskIdentifier. 1114 @result returns pointer to an IODMACommand which is used in conjunction 1115 with the task. 1116 */ 1117 1118 IODMACommand * GetDMACommand ( 1119 SCSIParallelTaskIdentifier parallelTask ); 1120 1121 /*! 1122 @function GetTimeoutDuration 1123 @abstract Method to retrieve the timeout duration in milliseconds for a 1124 request. 1125 @discussion Method to retrieve the timeout duration in milliseconds for 1126 a request. A value of zero represents an infinite timeout, or on 1127 hardware where infinite timeouts are not possible, substitute the 1128 longest timeout possible. 1129 @param parallelTask A valid SCSIParallelTaskIdentifier. 1130 @result returns timeout duration in milliseconds 1131 */ 1132 1133 UInt32 GetTimeoutDuration ( SCSIParallelTaskIdentifier parallelTask ); 1134 1135 /*! 1136 @function SetAutoSenseData 1137 @abstract Method to set the auto sense data buffer associated with a 1138 request. 1139 @param parallelTask A valid SCSIParallelTaskIdentifier. 1140 @param newSensedata pointer to auto sense data buffer 1141 @result returns true if data in newSenseData was succesfully into the 1142 task object 1143 */ 1144 1145 bool SetAutoSenseData ( 1146 SCSIParallelTaskIdentifier parallelTask, 1147 SCSI_Sense_Data * newSenseData, 1148 UInt8 senseDataSize ); 1149 1150 /*! 1151 @function GetAutoSenseData 1152 @abstract Method to retrieve auto sense data buffer associated with a 1153 request. 1154 @param parallelTask A valid SCSIParallelTaskIdentifier. 1155 @param receivingBuffer pointer to auto sense data buffer 1156 @result returns true if successfully copied data into receivingBuffer 1157 */ 1158 1159 bool GetAutoSenseData ( 1160 SCSIParallelTaskIdentifier parallelTask, 1161 SCSI_Sense_Data * receivingBuffer, 1162 UInt8 senseDataSize ); 1163 1164 /*! 1165 @function GetAutoSenseDataSize 1166 @abstract Method to retrieve auto sense data buffer size associated with a 1167 request. 1168 @param parallelTask A valid SCSIParallelTaskIdentifier. 1169 @result returns Size of auto sense data buffer. 1170 */ 1171 1172 UInt8 GetAutoSenseDataSize ( 1173 SCSIParallelTaskIdentifier parallelTask ); 1174 1175 1176 /*! 1177 @function GetSCSIParallelFeatureNegotiation 1178 @abstract Method to retrieve the requested value for negotiation of the. 1179 @discussion Query as to whether the SCSI Parallel Device object has 1180 negotiated wide data transfers. 1181 @param parallelTask A valid SCSIParallelTaskIdentifier. 1182 @result A valid SCSIParallelFeatureControl. 1183 */ 1184 1185 SCSIParallelFeatureRequest GetSCSIParallelFeatureNegotiation ( 1186 SCSIParallelTaskIdentifier parallelTask, 1187 SCSIParallelFeature requestedFeature ); 1188 1189 /*! 1190 @function GetSCSIParallelFeatureNegotiationCount 1191 @abstract Method to retrieve the number of requested negotiations. 1192 @discussion Query as to the number of SCSI Parallel Features that are 1193 requested to either be negotitated or cleared. These are all features 1194 that are set to either kSCSIParallelFeature_AttemptNegotiation or 1195 kSCSIParallelFeature_ClearNegotiation. If the return value is zero, 1196 then all features are set to kSCSIParallelFeature_NoNegotiation 1197 and all feature negotiations are to remain as they currently exist. 1198 @param parallelTask A valid SCSIParallelTaskIdentifier. 1199 @result an unsigned integer up to 64 bits in size. 1200 */ 1201 1202 UInt64 GetSCSIParallelFeatureNegotiationCount ( 1203 SCSIParallelTaskIdentifier parallelTask); 1204 1205 /*! 1206 @function SetSCSIParallelFeatureNegotiationResult 1207 @abstract Method to set the wide data transfer negotiation result. 1208 @discussion Method to set the wide data transfer negotiation result. 1209 @param parallelTask A valid SCSIParallelTaskIdentifier. 1210 @param requestedFeature The SCSIParallelFeature that the has been set to 1211 newResult. 1212 @param newResult A valid SCSIParallelFeatureResult value. 1213 */ 1214 1215 void SetSCSIParallelFeatureNegotiationResult ( 1216 SCSIParallelTaskIdentifier parallelTask, 1217 SCSIParallelFeature requestedFeature, 1218 SCSIParallelFeatureResult newResult ); 1219 1220 /*! 1221 @function GetSCSIParallelFeatureNegotiationResult 1222 @abstract Method to retrieve the result of any wide transfer 1223 negotiations. 1224 @discussion Query as to whether the SCSI Parallel Controller object has 1225 negotiated wide data transfers. 1226 @param parallelTask A valid SCSIParallelTaskIdentifier. 1227 @result A valid SCSIParallelFeatureResult. 1228 */ 1229 1230 SCSIParallelFeatureResult GetSCSIParallelFeatureNegotiationResult ( 1231 SCSIParallelTaskIdentifier parallelTask, 1232 SCSIParallelFeature requestedFeature ); 1233 1234 /*! 1235 @function GetSCSIParallelFeatureNegotiationResultCount 1236 @abstract Method to retrieve the number of changed negotiations. 1237 @discussion Query as to the number of SCSI Parallel Features that have 1238 been changed to either negotitated or cleared. These are all features 1239 that are set to either kSCSIParallelFeature_NegotitiationCleared or 1240 kSCSIParallelFeature_NegotitiationSuccess. If the return value is zero, 1241 then all features are set to kSCSIParallelFeature_NegotitiationUnchanged. 1242 @param parallelTask A valid SCSIParallelTaskIdentifier. 1243 @result an unsigned integer up to 64 bits in size. 1244 */ 1245 1246 UInt64 GetSCSIParallelFeatureNegotiationResultCount ( 1247 SCSIParallelTaskIdentifier parallelTask); 1248 1249 // Controller Task Identifier related member routines 1250 1251 /*! 1252 @function SetControllerTaskIdentifier 1253 @abstract Method to set the Controller Task Identifier. 1254 @discussion This method allows the Controller Child Class 1255 driver to set a unique identifier to associate with the specified 1256 SCSI Parallel Task. This identifier is designed to be used by 1257 controllers that do not have access to the LUN and Tag information 1258 when notified by the HBA that a request has completed. 1259 If the kSCSIParallelTaskControllerIDQueueHead is used, this 1260 member routine will return the first Task on the queue. 1261 @param parallelTask A valid SCSIParallelTaskIdentifier. 1262 @param newIdentifier unsigned 64 bit integer token. 1263 @result none 1264 */ 1265 1266 void SetControllerTaskIdentifier ( 1267 SCSIParallelTaskIdentifier parallelTask, 1268 UInt64 newIdentifier ); 1269 1270 UInt64 GetControllerTaskIdentifier ( 1271 SCSIParallelTaskIdentifier parallelTask); 1272 1273 1274 // The HBA Data related fields 1275 1276 /*! 1277 @function GetHBADataSize 1278 @abstract Method to retrieve the HBA Data Size in bytes. 1279 @discussion Method to retrieve the HBA Data Size in bytes. 1280 @param parallelTask A valid SCSIParallelTaskIdentifier. 1281 @result returns HBA Data size in bytes. 1282 */ 1283 1284 UInt32 GetHBADataSize ( SCSIParallelTaskIdentifier parallelTask ); 1285 1286 /*! 1287 @function GetHBADataPointer 1288 @abstract Method to retrieve the HBA Data pointer. 1289 @discussion Method to retrieve the HBA Data pointer. 1290 @param parallelTask A valid SCSIParallelTaskIdentifier. 1291 @result returns pointer to buffer for HBA specific data, NULL if 1292 none found or GetHBADataSize() returns zero. 1293 */ 1294 1295 void * GetHBADataPointer ( SCSIParallelTaskIdentifier parallelTask ); 1296 1297 /*! 1298 @function GetHBADataDescriptor 1299 @abstract Method to retrieve the IOMemoryDescriptor associated with 1300 the HBA Data. 1301 @discussion Method to retrieve the IOMemoryDescriptor associated with 1302 the HBA Data. 1303 @param parallelTask A valid SCSIParallelTaskIdentifier. 1304 @result returns pointer to an IOMemoryDescriptor that wraps the HBA 1305 specific data buffer, NULL if none found or GetHBADataSize() returns zero. 1306 */ 1307 1308 IOMemoryDescriptor * GetHBADataDescriptor ( 1309 SCSIParallelTaskIdentifier parallelTask ); 1310 1311 // ---- SCSI Parallel Device Object Accessors ---- 1312 1313 // The HBA Data related fields 1314 1315 /*! 1316 @function GetHBATargetDataSize 1317 @abstract Method to retrieve the HBA Data Size in bytes. 1318 @discussion Method to retrieve the HBA Data Size in bytes. 1319 @param targetDevice A valid SCSITargetIdentifier. 1320 @result returns HBA Data size in bytes. 1321 */ 1322 1323 UInt32 GetHBATargetDataSize ( SCSITargetIdentifier targetID ); 1324 1325 /*! 1326 @function GetHBATargetDataPointer 1327 @abstract Method to retrieve the HBA Data pointer. 1328 @discussion Method to retrieve the HBA Data pointer. 1329 @param targetDevice A valid SCSITargetIdentifier. 1330 @result returns pointer to buffer for HBA specific data, NULL if 1331 none found or GetHBADataSize is zero. 1332 */ 1333 1334 void * GetHBATargetDataPointer ( SCSITargetIdentifier targetID ); 1335 1336 1337#if 0 1338#pragma mark - 1339#pragma mark Additional Child Class APIs 1340#endif 1341 1342 1343 // ---- Timeout Related Methods ---- 1344 1345 /*! 1346 @function SetTimeoutForTask 1347 @abstract Method to set the timeout duration in milliseconds for a 1348 request. 1349 @discussion Method to set the timeout duration in milliseconds for a 1350 request. 1351 @param parallelTask A valid SCSIParallelTaskIdentifier. 1352 @param timeoutOverride A timeout value in milliseconds in case the 1353 HBA driver wishes to override the default value provided in the 1354 parallelTask. 1355 */ 1356 1357 void SetTimeoutForTask ( SCSIParallelTaskIdentifier parallelTask, 1358 UInt32 timeoutOverride = 0 ); 1359 1360 /*! 1361 @function HandleTimeout 1362 @abstract Method to handle command timeouts. 1363 @discussion Method to handle command timeouts. This should 1364 be overridden by the child class in order to clean up HBA 1365 specific structures after a timeout has occurred. This method 1366 is called on the workloop (it holds the gate). 1367 @param parallelRequest A valid SCSIParallelTaskIdentifier. 1368 */ 1369 1370 OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 9 ); 1371 1372 virtual void HandleTimeout ( 1373 SCSIParallelTaskIdentifier parallelRequest ); 1374 1375 1376 // ---- Filter Interrupt ---- 1377 1378 /*! 1379 @function FilterInterruptRequest 1380 @abstract Filter method called at primary interrupt time. 1381 @discussion Filter method called at primary interrupt time. 1382 This should only be overridden by the child class in order 1383 to determine if an interrupt occurred for this controller instance. 1384 Since all work occurs at primary interrupt time, this routine 1385 should be quick and efficient and defer as much processing as 1386 possible to the HandleInterruptRequest() method. 1387 1388 NOTE: Unlike the HandleInterruptRequest() and HandleTimeout() 1389 methods, FilterInterruptRequest() is NOT called with the 1390 workloop lock held. 1391 1392 If the value returned by FilterInterruptRequest() is true, the 1393 secondary interrupt thread will be scheduled and the hardware 1394 interrupt line will be disabled. If the controller instance shares 1395 that interrupt line with other devices, it can cause large 1396 interrupt latencies. If the controller instance can disable the 1397 interrupt in the chip itself, the following can be done to reduce 1398 interrupt latencies: 1399 1400 - Interrupt occurs 1401 - FilterInterruptRequest() method is called. 1402 - If the interrupt is not for this controller, return false 1403 immediately. 1404 - If the interrupt is for this controller, and the controller 1405 can disable interrupts for this chip, the controller should 1406 disable the interrupts for this chip, call SignalInterrupt(), 1407 and return false. This causes the secondary interrupt thread 1408 to get scheduled, yet does not disable the interrupt line for 1409 all devices tied to that interrupt. This effectively allows 1410 other devices to process their interrrupts, thus reducing 1411 interrupt latency for those devices. 1412 - HandleInterruptRequest() method is called. 1413 - Controller processes interrupt and completes I/O requests. 1414 - Controller re-enables interrupts for the device. 1415 1416 NOTE: If you use this approach, the interrupting condition MUST be 1417 cleared from the hardware, otherwise an infinite process interrupt 1418 loop will occur. 1419 1420 If the controller cannot disable interrupts on the chip, it should 1421 simply return true if an interrupt has occurred for its device. 1422 1423 @result True if the hardware interrupt line should be disabled, 1424 otherwise false. 1425 */ 1426 1427 OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 10 ); 1428 1429 virtual bool FilterInterruptRequest ( void ); 1430 1431 /*! 1432 @function InitializeDMASpecification 1433 @abstract Called to initialize an IODMACommand with a DMA specification. 1434 @param command A pointer to a valid IODMACommand object. Subclasses 1435 should override this method and call IODMACommand::initWithSpecification() 1436 supplying the proper arguments to that method based on the DMA strategy. 1437 @result boolean value indicating success or failure. 1438 */ 1439 OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 11 ); 1440 1441 virtual bool InitializeDMASpecification ( IODMACommand * command ); 1442 1443 /*! 1444 @function CreateDeviceInterrupt 1445 @abstract Called to create an IOInterruptEventSource for the device. Subclasses 1446 may wish to use a different interrupt index than 0 (e.g. for using PCI Message 1447 Signaled Interrupts) or might not need an interrupt at all (virtual HBA). 1448 @param action A pointer to the action routine that should be passed to either 1449 IOInterruptEventSource::interruptEventSource() or 1450 IOFilterInterruptEventSource::filterInterruptEventSource as the method to call 1451 when an interrupt occurs for the device (sometimes called the "deferred procedure call" 1452 or the "secondary context method". By passing this routine along, it will 1453 properly wire up the HandleInterruptRequest() method you should override to handle 1454 interrupts. 1455 @param filter A pointer to the filter routine that should be passed to 1456 IOFilterInterruptEventSource::filterInterruptEventSource as the method to call 1457 at primary interrupt time when an interrupt occurs for the device. 1458 By passing this routine along, it will properly wire up the 1459 FilterInterruptRequest() method you may override to handle primary interrupts. 1460 @result IOInterruptEventSource. May return NULL if and only if there is no 1461 hardware interrupt associated with this device. 1462 */ 1463 OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 12 ); 1464 1465 virtual IOInterruptEventSource * CreateDeviceInterrupt ( 1466 IOInterruptEventSource::Action action, 1467 IOFilterInterruptEventSource::Filter filter, 1468 IOService * provider ); 1469 1470 // Padding for the Child Class API 1471 OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 13 ); 1472 OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 14 ); 1473 OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 15 ); 1474 OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 16 ); 1475 1476 1477#if 0 1478#pragma mark - 1479#pragma mark Internal Use Only 1480#endif 1481 1482private: 1483 1484 // binary compatibility instance variable expansion 1485 struct ExpansionData { }; 1486 ExpansionData * fIOSCSIParallelInterfaceControllerExpansionData; 1487 1488 IOService * fProvider; 1489 OSSet * fClients; 1490 1491 static SInt32 fSCSIParallelDomainCount; 1492 SInt32 fSCSIDomainIdentifier; 1493 1494 // The HBA attributes 1495 SCSIInitiatorIdentifier fInitiatorIdentifier; 1496 1497 // The maximum SCSI Device Identifier support by the HBA 1498 // This is retreived from the child class via the 1499 SCSIDeviceIdentifier fHighestSupportedDeviceID; 1500 1501 // The total number of tasks that the HBA can proccess at a time. 1502 // This is retrieved from the child class via ReportMaximumTaskCount 1503 UInt32 fSupportedTaskCount; 1504 1505 // The Number of requests that are currently outstanding for the current 1506 // instantiation. 1507 UInt16 fOutstandingRequests; 1508 1509 // The member variable to indicate if the current instantiation has been 1510 // succesfully intialized. 1511 bool fHBAHasBeenInitialized; 1512 1513 // The member variable to indicate if the current instantiation is running. 1514 // A true means that the last or only Start call made was successful. A 1515 // false value means that either a successful Start has not been made or a 1516 // Stop call has been made. 1517 bool fHBACanAcceptClientRequests; 1518 1519 // The pool for the available SCSI Parallel Task objects 1520 IOCommandPool * fParallelTaskPool; 1521 1522 // WorkLoop variables 1523 IOWorkLoop * fWorkLoop; 1524 IOTimerEventSource * fTimerEvent; 1525 IOInterruptEventSource * fDispatchEvent; 1526 1527 IOCommandGate * fControllerGate; 1528 1529 bool AllocateSCSIParallelTasks ( void ); 1530 void DeallocateSCSIParallelTasks ( void ); 1531 1532 IOWorkLoop * getWorkLoop ( void ) const; 1533 bool CreateWorkLoop ( IOService * provider ); 1534 void ReleaseWorkLoop ( void ); 1535 1536 // SCSI Parallel Device List 1537 // The SCSI Parallel Device List will consist of 16 elements to represent 1538 // identifiers that end in 0h through Fh. Each array element will point 1539 // to a device object that represents the beginning of a linked list of 1540 // device objects. By using an array of linked lists, the traversal time 1541 // to find an object on a bus that supports a large number of devices, such 1542 // as Fibre Channel, will be significantly lower than having to walk a list 1543 // that is comprised of all devices on the bus. For parallel wide and 1544 // narrow busses, which support 16 and 8 devices respectively, this will act 1545 // like a simple array of device objects. 1546 enum 1547 { 1548 kSCSIParallelDeviceListArrayCount = 16, 1549 kSCSIParallelDeviceListIndexMask = 0x0F 1550 }; 1551 1552 IOSimpleLock * fDeviceLock; 1553 IOSCSIParallelInterfaceDevice * 1554 fParallelDeviceList[kSCSIParallelDeviceListArrayCount]; 1555 1556 void InitializeDeviceList ( void ); 1557 void AddDeviceToTargetList ( 1558 IOSCSIParallelInterfaceDevice * newDevice ); 1559 void RemoveDeviceFromTargetList ( 1560 IOSCSIParallelInterfaceDevice * victimDevice ); 1561 1562 // The Interrupt Service Routine for the controller. 1563 static void ServiceInterrupt ( 1564 OSObject * theObject, 1565 IOInterruptEventSource * theSource, 1566 int count ); 1567 1568 static void TimeoutOccurred ( OSObject * owner, IOTimerEventSource * sender ); 1569 1570 static bool FilterInterrupt ( 1571 OSObject * theObject, 1572 IOFilterInterruptEventSource * theSource ); 1573 1574 // IOService support methods 1575 // These shall not be overridden by the HBA child classes. 1576 bool start ( IOService * provider ); 1577 void stop ( IOService * provider ); 1578 1579 1580protected: 1581 1582 // These may be overriden by the HBA child classes if necessary, but should 1583 // call the superclass implementation. 1584 virtual bool handleOpen ( 1585 IOService * client, 1586 IOOptionBits options, 1587 void * arg ); 1588 1589 virtual void handleClose ( 1590 IOService * client, 1591 IOOptionBits options ); 1592 1593 virtual bool handleIsOpen ( 1594 const IOService * client ) const; 1595 1596 virtual bool willTerminate ( IOService * provider, IOOptionBits options ); 1597 virtual bool didTerminate ( IOService * provider, IOOptionBits options, bool * defer ); 1598 virtual void free ( void ); 1599 1600 1601}; 1602 1603 1604#endif /* __IOKIT_IO_SCSI_PARALLEL_INTERFACE_CONTROLLER_H__ */