/* * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // Includes //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // General IOKit includes #include #include // IOKit storage includes #include // SCSI Architecture Model Family includes #include #include // SCSI Parallel Family includes #include "IOSCSIParallelInterfaceDevice.h" //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // Macros //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ #define DEBUG 1 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "SPI Device" #if DEBUG #define SCSI_PARALLEL_DEVICE_DEBUGGING_LEVEL 3 #endif #include "IOSCSIParallelFamilyDebugging.h" #if ( SCSI_PARALLEL_DEVICE_DEBUGGING_LEVEL >= 1 ) #define PANIC_NOW(x) IOPanic x #else #define PANIC_NOW(x) #endif #if ( SCSI_PARALLEL_DEVICE_DEBUGGING_LEVEL >= 2 ) #define ERROR_LOG(x) IOLog x #else #define ERROR_LOG(x) #endif #if ( SCSI_PARALLEL_DEVICE_DEBUGGING_LEVEL >= 3 ) #define STATUS_LOG(x) IOLog x #else #define STATUS_LOG(x) #endif #define super IOSCSIProtocolServices OSDefineMetaClassAndStructors ( IOSCSIParallelInterfaceDevice, IOSCSIProtocolServices ); #define kIOPropertyIOUnitKey "IOUnit" #if 0 #pragma mark - #pragma mark ₯ IOKit Member Routines #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ start [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::start ( IOService * provider ) { OSDictionary * protocolDict = NULL; bool result = false; char unit[10]; fController = NULL; // Execute the inherited start result = super::start ( provider ); require ( result, PROVIDER_START_FAILURE ); // Save access to the controller object so that Tasks can be sent // for execution. fController = OSDynamicCast ( IOSCSIParallelInterfaceController, provider ); require_nonzero ( fController, PROVIDER_CAST_FAILURE ); // Open the controller, the provider. result = fController->open ( this ); require ( result, CONTROLLER_OPEN_FAILURE ); result = fController->InitializeTargetForID ( fTargetIdentifier ); require ( result, CONTROLLER_INIT_FAILURE ); // Setup power management for this object. InitializePowerManagement ( provider ); // Since the IOSCSIProtocolServices object will handle copying an existing // Protocol Characteristics dictionary from the provider, check if one exists // for this object. protocolDict = OSDynamicCast ( OSDictionary, getProperty ( kIOPropertyProtocolCharacteristicsKey ) ); if ( protocolDict == NULL ) { STATUS_LOG ( ( "Creating a new dictionary for this device\n" ) ); protocolDict = OSDictionary::withCapacity ( 1 ); } else { protocolDict->retain ( ); } if ( protocolDict != NULL ) { OSNumber * targetID = NULL; // Create an OSNumber object with the SCSI Target Identifier targetID = OSNumber::withNumber ( fTargetIdentifier, 64 ); if ( targetID != NULL ) { protocolDict->setObject ( kIOPropertySCSITargetIdentifierKey, targetID ); // Set the Unit number used to build the device tree path setProperty ( kIOPropertyIOUnitKey, targetID ); targetID->release ( ); } setProperty ( kIOPropertyProtocolCharacteristicsKey, protocolDict ); protocolDict->release ( ); } // Set the location to allow booting sprintf ( unit, "%x", ( int ) fTargetIdentifier ); setLocation ( unit ); // The device and this driver have been succesfully configured // and are ready to provide their services, call CreateSCSITargetDevice(). CreateSCSITargetDevice ( ); return true; CONTROLLER_INIT_FAILURE: CONTROLLER_OPEN_FAILURE: PROVIDER_CAST_FAILURE: PROVIDER_START_FAILURE: return false; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ stop [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::stop ( IOService * provider ) { super::stop ( provider ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ willTerminate [PUBLIC] [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::willTerminate ( IOService * provider, IOOptionBits options ) { ERROR_LOG ( ( "IOSCSIParallelInterfaceDevice::willTerminate\n" ) ); SendNotification_DeviceRemoved ( ); return true; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ didTerminate [PUBLIC] [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::didTerminate ( IOService * provider, IOOptionBits options, bool * defer ) { ERROR_LOG ( ( "IOSCSIParallelInterfaceDevice::didTerminate\n" ) ); if ( fController != NULL ) { fController->close ( this ); fController = NULL; } return true; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ message [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOReturn IOSCSIParallelInterfaceDevice::message ( UInt32 type, IOService * provider, void * argument ) { IOReturn result = kIOReturnSuccess; switch ( type ) { case kSCSIControllerNotificationBusReset: { // Bus reset occurred, disavow all negotiation settings // and force renegotiation for ( int index = 0; index < kSCSIParallelFeature_TotalFeatureCount; index++ ) { // Set each one to false. fFeatureIsNegotiated[index] = false; } // Message the SAM drivers to verify their device's state SendNotification_VerifyDeviceState ( ); } break; default: { result = super::message ( type, provider, argument ); } break; } return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ requestProbe [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOReturn IOSCSIParallelInterfaceDevice::requestProbe ( IOOptionBits options ) { // See if this device already has any opens on it. if ( isOpen ( ) == false ) { // The device and this driver have been succesfully configured // and are ready to provide their services, call CreateSCSITargetDevice(). CreateSCSITargetDevice ( ); return kIOReturnSuccess; } else { return kIOReturnNotPermitted; } } #if 0 #pragma mark - #pragma mark ₯ Device Object Management Member routines #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ CreateTarget - Creates an IOSCSIParallelInterfaceDevice for the // specified target ID. [STATIC][PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOSCSIParallelInterfaceDevice * IOSCSIParallelInterfaceDevice::CreateTarget ( SCSITargetIdentifier targetID, UInt32 sizeOfHBAData ) { IOSCSIParallelInterfaceDevice * newDevice = OSTypeAlloc ( IOSCSIParallelInterfaceDevice ); require_nonzero ( newDevice, DEVICE_CREATION_FAILURE ); // Set all of the fields to their defaults newDevice->fHBAData = NULL; newDevice->fHBADataSize = sizeOfHBAData; newDevice->fTargetIdentifier = targetID; newDevice->fPreviousParallelDevice = NULL; newDevice->fNextParallelDevice = NULL; newDevice->fOutstandingTaskList = NULL; newDevice->fQueueLock = NULL; newDevice->fResendTaskList = NULL; newDevice->fResendQueueLock = NULL; bzero ( newDevice->fFeatureIsNegotiated, kSCSIParallelFeature_TotalFeatureCount * sizeof ( bool ) ); bzero ( newDevice->fITNexusSupportsFeature, kSCSIParallelFeature_TotalFeatureCount * sizeof ( bool ) ); // Allocate the lock for the Task Queue newDevice->fQueueLock = IOSimpleLockAlloc ( ); require_nonzero ( newDevice->fQueueLock, LOCK_ALLOC_FAILURE ); newDevice->fResendQueueLock = IOSimpleLockAlloc ( ); require_nonzero ( newDevice->fResendQueueLock, LOCK_ALLOC_FAILURE ); if ( sizeOfHBAData != 0 ) { // Allocate the HBA specific data for the device object newDevice->fHBAData = IOMalloc ( sizeOfHBAData ); require_nonzero ( newDevice->fHBAData, HBA_DATA_ALLOC_FAILURE ); bzero ( newDevice->fHBAData, sizeOfHBAData ); } return newDevice; HBA_DATA_ALLOC_FAILURE: // Release the lock for the Task Queue. if ( newDevice->fQueueLock != NULL ) { // Free the SCSI Task queue access lock. IOSimpleLockFree ( newDevice->fQueueLock ); newDevice->fQueueLock = NULL; } // Release the lock for the Task Queue. if ( newDevice->fResendQueueLock != NULL ) { // Free the SCSI Task queue access lock. IOSimpleLockFree ( newDevice->fResendQueueLock ); newDevice->fResendQueueLock = NULL; } LOCK_ALLOC_FAILURE: require_nonzero_quiet ( newDevice, DEVICE_CREATION_FAILURE ); newDevice->release ( ); newDevice = NULL; DEVICE_CREATION_FAILURE: return NULL; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ DestroyTarget - Destroys an IOSCSIParallelInterfaceDevice. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::DestroyTarget ( void ) { // First walk the queue holding any Tasks that completed // with TASK_SET_FULL and reject each one // Release the HBA specific data if ( fHBAData != NULL ) { IOFree ( fHBAData, fHBADataSize ); fHBAData = NULL; fHBADataSize = 0; } // Release the lock for the Task Queue. if ( fQueueLock != NULL ) { // Free the SCSI Task queue access lock. IOSimpleLockFree ( fQueueLock ); fQueueLock = NULL; } // Release the lock for the Task Queue. if ( fResendQueueLock != NULL ) { // Free the SCSI Task queue access lock. IOSimpleLockFree ( fResendQueueLock ); fResendQueueLock = NULL; } } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetPreviousDeviceInList - Retrieves previous device in linked list. // [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOSCSIParallelInterfaceDevice * IOSCSIParallelInterfaceDevice::GetPreviousDeviceInList ( void ) { return fPreviousParallelDevice; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ SetPreviousDeviceInList - Sets previous device in linked list. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::SetPreviousDeviceInList ( IOSCSIParallelInterfaceDevice * newPrev ) { fPreviousParallelDevice = newPrev; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetNextDeviceInList - Retrieves next device in linked list. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOSCSIParallelInterfaceDevice * IOSCSIParallelInterfaceDevice::GetNextDeviceInList ( void ) { return fNextParallelDevice; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ SetNextDeviceInList - Sets next device in linked list. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::SetNextDeviceInList ( IOSCSIParallelInterfaceDevice * newNext ) { fNextParallelDevice = newNext; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ DetermineParallelFeatures - Determines parallel protocol features based // on INQUIRY data. [PRIVATE] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::DetermineParallelFeatures ( UInt8 * inqData ) { OSDictionary * dict = NULL; OSNumber * features = NULL; UInt64 deviceFeatures = 0; UInt64 ITNexusFeatures = 0; bool supported = false; UInt8 inqSCSIVersion = 0; UInt8 inqDataLength = 0; dict = ( OSDictionary * ) getProperty ( kIOPropertyProtocolCharacteristicsKey ); inqSCSIVersion = ( ( SCSICmd_INQUIRY_StandardData * ) inqData )->VERSION & kINQUIRY_ANSI_VERSION_Mask; inqDataLength = ( ( SCSICmd_INQUIRY_StandardData * ) inqData )->ADDITIONAL_LENGTH + 5; // Verify that the device is SCSI-2 compliant and the INQUIRY data is large // enough to contain the SCSI-2 feature flags if ( ( inqSCSIVersion >= kINQUIRY_ANSI_VERSION_SCSI_2_Compliant ) && ( inqDataLength > kINQUIRY_Byte7_Offset ) ) { if ( inqData[kINQUIRY_Byte7_Offset] & kINQUIRY_Byte7_SYNC_Mask ) { deviceFeatures |= (1 << kSCSIParallelFeature_SynchronousDataTransfer); supported = DoesHBASupportSCSIParallelFeature ( kSCSIParallelFeature_SynchronousDataTransfer ); if ( supported == true ) { fITNexusSupportsFeature[kSCSIParallelFeature_SynchronousDataTransfer] = true; ITNexusFeatures |= (1 << kSCSIParallelFeature_SynchronousDataTransfer); } } if ( inqData[kINQUIRY_Byte7_Offset] & kINQUIRY_Byte7_WBUS16_Mask ) { deviceFeatures |= (1 << kSCSIParallelFeature_WideDataTransfer); supported = DoesHBASupportSCSIParallelFeature ( kSCSIParallelFeature_WideDataTransfer ); if ( supported == true ) { fITNexusSupportsFeature[kSCSIParallelFeature_WideDataTransfer] = true; ITNexusFeatures |= (1 << kSCSIParallelFeature_WideDataTransfer); } } } // Verify that the device is SPC compliant and the INQUIRY data is large // enough to contain the SPI-3 feature flags if ( ( inqSCSIVersion >= kINQUIRY_ANSI_VERSION_SCSI_SPC_Compliant ) && ( inqDataLength > kINQUIRY_Byte56_Offset ) ) { if ( inqData[kINQUIRY_Byte56_Offset] & kINQUIRY_Byte56_IUS_Mask ) { deviceFeatures |= (1 << kSCSIParallelFeature_InformationUnitTransfers); supported = DoesHBASupportSCSIParallelFeature ( kSCSIParallelFeature_InformationUnitTransfers ); if ( supported == true ) { fITNexusSupportsFeature[kSCSIParallelFeature_InformationUnitTransfers] = true; ITNexusFeatures |= (1 << kSCSIParallelFeature_InformationUnitTransfers); } } if ( inqData[kINQUIRY_Byte56_Offset] & kINQUIRY_Byte56_QAS_Mask ) { deviceFeatures |= (1 << kSCSIParallelFeature_QuickArbitrationAndSelection); supported = DoesHBASupportSCSIParallelFeature( kSCSIParallelFeature_QuickArbitrationAndSelection ); if ( supported == true ) { fITNexusSupportsFeature[kSCSIParallelFeature_QuickArbitrationAndSelection] = true; ITNexusFeatures |= (1 << kSCSIParallelFeature_QuickArbitrationAndSelection); } } if ( ( ( inqData[kINQUIRY_Byte56_Offset] & kINQUIRY_Byte56_CLOCKING_Mask ) == kINQUIRY_Byte56_CLOCKING_ONLY_DT ) || ( ( inqData[kINQUIRY_Byte56_Offset] & kINQUIRY_Byte56_CLOCKING_Mask ) == kINQUIRY_Byte56_CLOCKING_ST_AND_DT ) ) { deviceFeatures |= (1 << kSCSIParallelFeature_DoubleTransitionDataTransfers); supported = DoesHBASupportSCSIParallelFeature ( kSCSIParallelFeature_DoubleTransitionDataTransfers ); if ( supported == true ) { fITNexusSupportsFeature[kSCSIParallelFeature_DoubleTransitionDataTransfers] = true; ITNexusFeatures |= (1 << kSCSIParallelFeature_DoubleTransitionDataTransfers); } } } features = OSNumber::withNumber ( deviceFeatures, 64 ); if ( features != NULL ) { dict->setObject ( kIOPropertySCSIDeviceFeaturesKey, features ); features->release ( ); features = NULL; } features = OSNumber::withNumber ( ITNexusFeatures, 64 ); if ( features != NULL ) { dict->setObject ( kIOPropertySCSI_I_T_NexusFeaturesKey, features ); features->release ( ); features = NULL; } } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetTargetIdentifier - Retrieves the SCSITargetIdentifier for this device. // [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSITargetIdentifier IOSCSIParallelInterfaceDevice::GetTargetIdentifier ( void ) { return fTargetIdentifier; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetHBADataPointer - Retrieves the pointer to the HBA Data for this device. // [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void * IOSCSIParallelInterfaceDevice::GetHBADataPointer ( void ) { return fHBAData; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetHBADataSize - Retrieves the HBA Data size for this device. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ UInt32 IOSCSIParallelInterfaceDevice::GetHBADataSize( void ) { return fHBADataSize; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ IsFeatureNegotiationNecessary - Checks if a feature negotiation is // necessary. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::IsFeatureNegotiationNecessary ( SCSIParallelFeature feature ) { // Verify that the requested feature is one that is known to // the device object. if ( feature >= kSCSIParallelFeature_TotalFeatureCount ) { return false; } return ( fITNexusSupportsFeature[feature] && ( fFeatureIsNegotiated[feature] == false ) ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ FindTaskForAddress - Find the outstanding task for the Task Address of // this Target and the specified Lun and Tag. // [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSIParallelTaskIdentifier IOSCSIParallelInterfaceDevice::FindTaskForAddress ( SCSILogicalUnitNumber theL, SCSITaggedTaskIdentifier theQ ) { SCSIParallelTask * tempTask; IOSimpleLockLock ( fQueueLock ); // Make sure that the queue lock is being held before setting // tempTask to the head element. tempTask = fOutstandingTaskList; while ( tempTask != NULL ) { if ( GetLogicalUnitNumber ( tempTask ) == theL ) //&& ( GetTaggedTaskedIdentifier ( tempTask ) == theQ ) { break; } tempTask = tempTask->GetNextTaskInList ( ); } IOSimpleLockUnlock ( fQueueLock ); return tempTask; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ FindTaskForControllerIdentifier - Find the outstanding task for the // identifier. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSIParallelTaskIdentifier IOSCSIParallelInterfaceDevice::FindTaskForControllerIdentifier ( UInt64 theIdentifier ) { SCSIParallelTask * tempTask; IOSimpleLockLock ( fQueueLock ); // Make sure that the queue lock is being held before setting // tempTask to the head element. tempTask = fOutstandingTaskList; while ( tempTask != NULL ) { // Check if the request is to return the first element on the queue if ( theIdentifier == kSCSIParallelTaskControllerIDQueueHead ) { // The request is for the first element on the queue, this will // break the first time through the while loop. break; } if ( GetControllerTaskIdentifier ( tempTask ) == theIdentifier ) { break; } tempTask = tempTask->GetNextTaskInList ( ); } IOSimpleLockUnlock ( fQueueLock ); return tempTask; } #if 0 #pragma mark - #pragma mark ₯ SCSI Protocol Services Member Routines #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ SendSCSICommand - Sends a command to the controller. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::SendSCSICommand ( SCSITaskIdentifier request, SCSIServiceResponse * serviceResponse, SCSITaskStatus * taskStatus ) { SCSIParallelTaskIdentifier parallelTask; // Set the defaults to an error state. *taskStatus = kSCSITaskStatus_No_Status; *serviceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE; // Verify that the task to execute is valid if ( request == NULL ) { // An invalid SCSI Task object was passed into here. Let the client // know by returning the default error for taskStatus and // serviceResponse and true to indicate that the command is completed. return true; } // Check if there is an SCSIParallelTask available to allow the request // to be sent to the device. parallelTask = GetSCSIParallelTask ( true ); if ( parallelTask == NULL ) { // A SCSI Parallel Task could not be gotten, report // that the task was not executed and wait for a task to complete. return false; } SetTargetIdentifier ( parallelTask, fTargetIdentifier ); SetSCSITaskIdentifier ( parallelTask, request ); // Set the Parallel SCSI transfer features. for ( UInt32 index = 0; index < kSCSIParallelFeature_TotalFeatureCount; index++ ) { // Set each one to false. if ( IsFeatureNegotiationNecessary ( ( SCSIParallelFeature ) index ) == true ) { SetSCSIParallelFeatureNegotiation ( parallelTask, ( SCSIParallelFeature ) index, kSCSIParallelFeature_AttemptNegotiation ); } } // Add the task to the outstanding Task list AddToOutstandingTaskList ( parallelTask ); *serviceResponse = ExecuteParallelTask ( parallelTask ); if ( *serviceResponse != kSCSIServiceResponse_Request_In_Process ) { // The task has already completed RemoveFromOutstandingTaskList ( parallelTask ); // Release the SCSI Parallel Task object FreeSCSIParallelTask ( parallelTask ); CommandCompleted ( request, *serviceResponse, *taskStatus ); } return true; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ CompleteSCSITask - Completes a command from the controller. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::CompleteSCSITask ( SCSIParallelTaskIdentifier completedTask, SCSIServiceResponse serviceResponse, SCSITaskStatus completionStatus ) { SCSITaskIdentifier clientRequest = NULL; if ( completedTask == NULL ) { // The driver was asked to complete an invalid task, // there is nothing it can do so just return. return; } // Check if the device rejected the task because its queue is full if ( ( serviceResponse == kSCSIServiceResponse_TASK_COMPLETE ) && ( completionStatus == kSCSITaskStatus_TASK_SET_FULL ) ) { // The task was not executed because the device reported that // a TASK_SET_FULL, place it on the resend queue and wait for // a task to complete with a status other than TASK_SET_FULL. AddToResendTaskList ( completedTask ); // Done for now. return; } // Make sure that the task is removed from the outstanding task list // so that the driver no longer sees this task as outstanding. RemoveFromOutstandingTaskList ( completedTask ); // Retrieve the original SCSI Task clientRequest = GetSCSITaskIdentifier ( completedTask ); if ( clientRequest == NULL ) { IOPanic ( "clientRequest is NULL in CompleteSCSITask\n" ); } // Set the appropriate fields in the SCSI Task IOSCSIProtocolServices::SetRealizedDataTransferCount ( clientRequest, GetRealizedDataTransferCount ( completedTask ) ); // Store any negotiations that were done. for ( UInt32 index = 0; index < kSCSIParallelFeature_TotalFeatureCount; index++ ) { // Set each one to false. if ( IsFeatureNegotiationNecessary ( ( SCSIParallelFeature ) index ) == true ) { if ( GetSCSIParallelFeatureNegotiationResult ( completedTask, ( SCSIParallelFeature ) index ) == kSCSIParallelFeature_NegotitiationSuccess ) { fFeatureIsNegotiated[index] = true; } } } // Release the SCSI Parallel Task object FreeSCSIParallelTask ( completedTask ); // If there are requests on the resend queue, send them first // Currently only the element at the head of the queue will be sent // If the desire is to allow all elements to be sent, the break // statement can be removed while ( fResendTaskList != NULL ) { SCSIParallelTaskIdentifier parallelTask; parallelTask = fResendTaskList; RemoveFromResendTaskList ( parallelTask); if ( ExecuteParallelTask ( parallelTask ) != kSCSIServiceResponse_Request_In_Process ) { SCSITaskIdentifier nextRequest = NULL; // The task has already completed RemoveFromOutstandingTaskList ( parallelTask ); nextRequest = GetSCSITaskIdentifier ( completedTask ); // Release the SCSI Parallel Task object FreeSCSIParallelTask ( parallelTask ); CommandCompleted ( nextRequest, kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE, kSCSITaskStatus_No_Status ); // Send this command has already completed, start the next // one on the queue. continue; } // A command was successfully sent, wait for it to complete // before sending the next one. break; } // Inform the client that the task has been executed. CommandCompleted ( clientRequest, serviceResponse, completionStatus ); } #if 0 #pragma mark - #pragma mark ₯ SCSI Protocol Service Feature routines #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ IsProtocolServiceSupported - Called by SCSI Application Layer to determine // if the protocol layer driver supports a // SCSIProtocolFeature. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::IsProtocolServiceSupported ( SCSIProtocolFeature feature, void * value ) { bool isSupported = false; switch ( feature ) { case kSCSIProtocolFeature_GetMaximumLogicalUnitNumber: { isSupported = true; *( UInt32 * ) value = ReportHBAHighestLogicalUnitNumber ( ); } break; case kSCSIProtocolFeature_SubmitDefaultInquiryData: { isSupported = true; } break; default: { // Since isSupported is set to false by default, there is // nothing that needs to be done for the default case. } break; } return isSupported; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ HandleProtocolServiceFeature - Called by SCSI Application Layer to handle // a SCSIProtocolFeature. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::HandleProtocolServiceFeature ( SCSIProtocolFeature feature, void * serviceValue ) { bool wasHandled = false; switch ( feature ) { case kSCSIProtocolFeature_SubmitDefaultInquiryData: { DetermineParallelFeatures ( ( UInt8 * ) serviceValue ); wasHandled = true; } break; default: { break; } } return wasHandled; } #if 0 #pragma mark - #pragma mark ₯ SCSI Management Functions #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ AbortSCSICommand - Not used. [₯OBSOLETE₯][PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSIServiceResponse IOSCSIParallelInterfaceDevice::AbortSCSICommand ( SCSITaskIdentifier request ) { return kSCSIServiceResponse_FUNCTION_REJECTED; } #if 0 #pragma mark - #pragma mark ₯ Controller Object Accessors #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ ExecuteParallelTask - Called to issue a task to the controller. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSIServiceResponse IOSCSIParallelInterfaceDevice::ExecuteParallelTask ( SCSIParallelTaskIdentifier parallelRequest ) { return fController->ExecuteParallelTask ( parallelRequest ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetSCSIParallelTask - Gets a SCSIParallelTaskIdentifier from the // controller's command pool. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSIParallelTaskIdentifier IOSCSIParallelInterfaceDevice::GetSCSIParallelTask ( bool blockForCommand ) { return fController->GetSCSIParallelTask ( blockForCommand ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ FreeSCSIParallelTask - Returns a SCSIParallelTaskIdentifier to the // controller's command pool. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::FreeSCSIParallelTask ( SCSIParallelTaskIdentifier returnTask ) { return fController->FreeSCSIParallelTask ( returnTask ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ ReportHBAHighestLogicalUnitNumber - Retrieves the highest supported // Logical Unit. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSILogicalUnitNumber IOSCSIParallelInterfaceDevice::ReportHBAHighestLogicalUnitNumber ( void ) { return fController->ReportHBAHighestLogicalUnitNumber ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ DoesHBASupportSCSIParallelFeature - Queries the controller if a // specific SCSIParallelFeature is // supported. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::DoesHBASupportSCSIParallelFeature ( SCSIParallelFeature theFeature ) { return fController->DoesHBASupportSCSIParallelFeature ( theFeature ); } #if 0 #pragma mark - #pragma mark ₯ SCSI Parallel Task Object Accessors #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ AddToOutstandingTaskList - Adds a task to the outstanding task list. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::AddToOutstandingTaskList ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return false; } IOSimpleLockLock ( fQueueLock ); if ( fOutstandingTaskList == NULL ) { // There are no tasks currently in the list, add this one to the // front. fOutstandingTaskList = tempTask; tempTask->SetPreviousTaskInList ( NULL ); tempTask->SetNextTaskInList ( NULL ); } else { // Add this task to the end of the list SCSIParallelTask * listTask; listTask = fOutstandingTaskList; while ( listTask->GetNextTaskInList ( ) != NULL ) { listTask = listTask->GetNextTaskInList ( ); } listTask->SetNextTaskInList ( tempTask ); tempTask->SetPreviousTaskInList ( listTask ); tempTask->SetNextTaskInList ( NULL ); } IOSimpleLockUnlock ( fQueueLock ); return true; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ RemoveFromOutstandingTaskList - Removes a task from the outstanding // task list. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::RemoveFromOutstandingTaskList ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; SCSIParallelTask * nextTask = NULL; SCSIParallelTask * prevTask = NULL; IOSimpleLockLock ( fQueueLock ); nextTask = tempTask->GetNextTaskInList ( ); prevTask = tempTask->GetPreviousTaskInList ( ); if ( prevTask != NULL ) { // There is a previous task, set it to the victim's next task prevTask->SetNextTaskInList ( nextTask ); } else { fOutstandingTaskList = nextTask; } if ( nextTask != NULL ) { // The next task is not NULL, set it to the victim's previous nextTask->SetPreviousTaskInList ( prevTask ); } // Clear out the victim's previous and next pointers tempTask->SetNextTaskInList ( NULL ); tempTask->SetPreviousTaskInList ( NULL ); IOSimpleLockUnlock ( fQueueLock ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ AddToResendTaskList - Adds a task to the resend (TASK_SET_FULL) task list. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::AddToResendTaskList ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return false; } IOSimpleLockLock ( fResendQueueLock ); if ( fResendTaskList == NULL ) { // There are no tasks currently in the list, add this one to the // front. fResendTaskList = tempTask; tempTask->SetPreviousResendTaskInList ( NULL ); tempTask->SetNextResendTaskInList ( NULL ); } else { // Add this task to the end of the list SCSIParallelTask * listTask; listTask = fResendTaskList; while ( listTask->GetNextResendTaskInList ( ) != NULL ) { listTask = listTask->GetNextResendTaskInList ( ); } listTask->SetNextResendTaskInList ( tempTask ); tempTask->SetPreviousResendTaskInList ( listTask ); tempTask->SetNextResendTaskInList( NULL ); } IOSimpleLockUnlock ( fResendQueueLock ); return true; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ RemoveFromOutstandingTaskList - Removes a task from the resend task // (TASK_SET_FULL) list. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::RemoveFromResendTaskList ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; SCSIParallelTask * nextTask = NULL; SCSIParallelTask * prevTask = NULL; IOSimpleLockLock ( fResendQueueLock ); nextTask = tempTask->GetNextResendTaskInList ( ); prevTask = tempTask->GetPreviousResendTaskInList ( ); if ( prevTask != NULL ) { // There is a previous task, set it to the victim's next task prevTask->SetNextResendTaskInList ( nextTask ); } else { fResendTaskList = nextTask; } if ( nextTask != NULL ) { // The next task is not NULL, set it to the victim's previous nextTask->SetPreviousResendTaskInList ( prevTask ); } // Clear out the victim's previous and next pointers tempTask->SetNextResendTaskInList ( NULL ); tempTask->SetPreviousResendTaskInList ( NULL ); IOSimpleLockUnlock ( fResendQueueLock ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ SetSCSITaskIdentifier - Sets the SCSITaskIdentifier in the // parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::SetSCSITaskIdentifier ( SCSIParallelTaskIdentifier parallelTask, SCSITaskIdentifier scsiRequest ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return false; } return tempTask->SetSCSITaskIdentifier ( scsiRequest ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ SetSCSITaskIdentifier - Retrieves the SCSITaskIdentifier from the // parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSITaskIdentifier IOSCSIParallelInterfaceDevice::GetSCSITaskIdentifier ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return NULL; } return tempTask->GetSCSITaskIdentifier ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ SetSCSITaskIdentifier - Sets the SCSITargetIdentifier in the // parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::SetTargetIdentifier ( SCSIParallelTaskIdentifier parallelTask, SCSITargetIdentifier theTargetID ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return false; } return tempTask->SetTargetIdentifier ( theTargetID ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ SetSCSITaskIdentifier - Retrieves the SCSITargetIdentifier from the // parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSITargetIdentifier IOSCSIParallelInterfaceDevice::GetTargetIdentifier ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return NULL; } return tempTask->GetTargetIdentifier ( ); } // ---- Methods for Accessing data in the client's SCSI Task Object ---- // Method to retrieve the LUN that identifies the Logical Unit whose Task // Set to which this task is to be added. // --> Currently this only supports Level 1 Addressing, complete // Hierachal LUN addressing will need to be added to the SCSI Task object // and the Peripheral Device Type objects which will represent Logical Units. // Since that will be completed before this is released, this method will be // changed at that time. //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetLogicalUnitNumber - Retrieves the SCSILogicalUnitNumber from the // parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSILogicalUnitNumber IOSCSIParallelInterfaceDevice::GetLogicalUnitNumber ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return 0; } return tempTask->GetLogicalUnitNumber ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetTaggedTaskIdentifier - Retrieves the SCSITaggedTaskIdentifier from the // parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSITaggedTaskIdentifier IOSCSIParallelInterfaceDevice::GetTaggedTaskIdentifier ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return kSCSIUntaggedTaskIdentifier; } return tempTask->GetTaggedTaskIdentifier ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetTaskAttribute - Retrieves the SCSITaskAttribute from the // parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSITaskAttribute IOSCSIParallelInterfaceDevice::GetTaskAttribute ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return kSCSITask_SIMPLE; } return tempTask->GetTaskAttribute ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetCommandDescriptorBlockSize - Retrieves the CDB size from the // parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ UInt8 IOSCSIParallelInterfaceDevice::GetCommandDescriptorBlockSize ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return 0; } return tempTask->GetCommandDescriptorBlockSize ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetCommandDescriptorBlockSize - Retrieves the CDB from the parallelTask. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::GetCommandDescriptorBlock ( SCSIParallelTaskIdentifier parallelTask, SCSICommandDescriptorBlock * cdbData ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return false; } return tempTask->GetCommandDescriptorBlock ( cdbData ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetDataTransferDirection - Retrieves the data transfer direction from // the parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ UInt8 IOSCSIParallelInterfaceDevice::GetDataTransferDirection ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return kSCSIDataTransfer_NoDataTransfer; } return tempTask->GetDataTransferDirection ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetRequestedDataTransferCount - Retrieves the requested data transfer // count from the parallelTask. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ UInt64 IOSCSIParallelInterfaceDevice::GetRequestedDataTransferCount ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return 0; } return tempTask->GetRequestedDataTransferCount ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetRequestedDataTransferCount - Retrieves the realized data transfer // count from the parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ UInt64 IOSCSIParallelInterfaceDevice::GetRealizedDataTransferCount ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return 0; } return tempTask->GetRealizedDataTransferCount ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetRequestedDataTransferCount - Sets the realized data transfer // count in the parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIParallelInterfaceDevice::SetRealizedDataTransferCount ( SCSIParallelTaskIdentifier parallelTask, UInt64 realizedTransferCountInBytes ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return false; } return tempTask->SetRealizedDataTransferCount ( realizedTransferCountInBytes ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetRequestedDataTransferCount - Increments the realized data transfer // count in the parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::IncrementRealizedDataTransferCount ( SCSIParallelTaskIdentifier parallelTask, UInt64 realizedTransferCountInBytes ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return; } return tempTask->IncrementRealizedDataTransferCount ( realizedTransferCountInBytes ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetRequestedDataTransferCount - Retrieves the data buffer in the // parallelTask. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOMemoryDescriptor * IOSCSIParallelInterfaceDevice::GetDataBuffer ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return NULL; } return tempTask->GetDataBuffer ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetDataBufferOffset - Retrieves the data buffer offset in the parallelTask. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ UInt64 IOSCSIParallelInterfaceDevice::GetDataBufferOffset ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return 0; } return tempTask->GetDataBufferOffset ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetTimeoutDuration - Retrieves the timeout duration in the parallelTask. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ UInt32 IOSCSIParallelInterfaceDevice::GetTimeoutDuration ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return 0; } return tempTask->GetTimeoutDuration ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ SetSCSIParallelFeatureNegotiation - Sets a feature negotiation request // in the specified task. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIParallelInterfaceDevice::SetSCSIParallelFeatureNegotiation ( SCSIParallelTaskIdentifier parallelTask, SCSIParallelFeature requestedFeature, SCSIParallelFeatureRequest newRequest ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return; } return tempTask->SetSCSIParallelFeatureNegotiation ( requestedFeature, newRequest ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetSCSIParallelFeatureNegotiation - Gets a feature negotiation request // in the specified task. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSIParallelFeatureRequest IOSCSIParallelInterfaceDevice::GetSCSIParallelFeatureNegotiation ( SCSIParallelTaskIdentifier parallelTask, SCSIParallelFeature requestedFeature ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return kSCSIParallelFeature_NoNegotiation; } return tempTask->GetSCSIParallelFeatureNegotiation ( requestedFeature ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetSCSIParallelFeatureNegotiationResult - Gets a feature negotiation // result in the specified task. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSIParallelFeatureResult IOSCSIParallelInterfaceDevice::GetSCSIParallelFeatureNegotiationResult ( SCSIParallelTaskIdentifier parallelTask, SCSIParallelFeature requestedFeature ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return kSCSIParallelFeature_NegotitiationUnchanged; } return tempTask->GetSCSIParallelFeatureNegotiationResult ( requestedFeature ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetControllerTaskIdentifier - Gets the identifier associated with the // task. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ UInt64 IOSCSIParallelInterfaceDevice::GetControllerTaskIdentifier ( SCSIParallelTaskIdentifier parallelTask) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return 0; } return tempTask->GetControllerTaskIdentifier ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetHBADataSize - Gets the size of HBA Data associated with a command. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ UInt32 IOSCSIParallelInterfaceDevice::GetHBADataSize ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return 0; } return tempTask->GetHBADataSize ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetHBADataPointer - Gets the HBA Data pointer associated with a command. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void * IOSCSIParallelInterfaceDevice::GetHBADataPointer ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return NULL; } return tempTask->GetHBADataPointer ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetHBADataDescriptor - Gets the HBA memory descriptor associated with // a command. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOMemoryDescriptor * IOSCSIParallelInterfaceDevice::GetHBADataDescriptor ( SCSIParallelTaskIdentifier parallelTask ) { SCSIParallelTask * tempTask = ( SCSIParallelTask * ) parallelTask; if ( tempTask == NULL ) { return NULL; } return tempTask->GetHBADataDescriptor ( ); }