void SCSIPathSet::removeObject ( const IOSCSIProtocolServices * interface ) { SCSITargetDevicePath * member = NULL; OSNumber * domainID = NULL; UInt32 index = 0; STATUS_LOG ( ( "+SCSIPathSet::removeObject\n" ) ); domainID = SCSITargetDevicePath::GetInterfaceDomainIdentifier ( interface ); for ( index = 0; index < count; index++ ) { member = ( SCSITargetDevicePath * ) array[index]; if ( member->GetDomainIdentifier ( )->isEqualTo ( domainID ) ) { super::removeObject ( index ); break; } } STATUS_LOG ( ( "-SCSIPathSet::removeObject\n" ) ); }
IOReturn IOATABlockStorageDriver::doSyncReadWrite ( IOMemoryDescriptor * buffer, UInt32 block, UInt32 nblks ) { IOReturn ret; IOATACommand * cmd = NULL; STATUS_LOG ( ( "IOATABlockStorageDriver::doSyncReadWrite entering\n" ) ); cmd = ataCommandReadWrite ( buffer, block, nblks ); if ( cmd == NULL ) { return kIOReturnNoMemory; } ret = syncExecute ( cmd ); STATUS_LOG ( ( "IOATABlockStorageDriver::doSyncReadWrite exiting ret = %ld.\n", ( UInt32 ) ret ) ); return ret; }
bool SCSIPathSet::setObject ( const SCSITargetDevicePath * path ) { bool result = false; STATUS_LOG ( ( "+SCSIPathSet::setObject\n" ) ); result = member ( path ); require ( ( result == false ), ErrorExit ); STATUS_LOG ( ( "calling super::setObject()\n" ) ); result = super::setObject ( path ); STATUS_LOG ( ( "-SCSIPathSet::setObject\n" ) ); return result; ErrorExit: result = false; STATUS_LOG ( ( "-SCSIPathSet::setObject\n" ) ); return result; }
bool SCSIPathSet::member ( const IOSCSIProtocolServices * interface ) const { bool result = false; OSNumber * domainID = NULL; SCSITargetDevicePath * element = NULL; UInt32 index = 0; STATUS_LOG ( ( "+SCSIPathSet::member\n" ) ); domainID = SCSITargetDevicePath::GetInterfaceDomainIdentifier ( interface ); for ( index = 0; index < count; index++ ) { element = ( SCSITargetDevicePath * ) array[index]; if ( element->GetDomainIdentifier ( )->isEqualTo ( domainID ) ) { STATUS_LOG ( ( "path is member\n" ) ); result = true; break; } } STATUS_LOG ( ( "-SCSIPathSet::member\n" ) ); return result; }
bool SCSIPathSet::member ( const SCSITargetDevicePath * path ) const { bool result = false; SCSITargetDevicePath * element = NULL; UInt32 index = 0; STATUS_LOG ( ( "+SCSIPathSet::member\n" ) ); for ( index = 0; index < count; index++ ) { element = ( SCSITargetDevicePath * ) array[index]; if ( element->GetDomainIdentifier ( )->isEqualTo ( path->GetDomainIdentifier ( ) ) ) { STATUS_LOG ( ( "path is member\n" ) ); result = true; break; } } STATUS_LOG ( ( "-SCSIPathSet::member\n" ) ); return result; }
SCSITargetDevicePath * SCSIPressurePathManager::PortBandwidthGlobals::AllocateBandwidth ( SCSIPathSet * pathSet, UInt64 bytes ) { SCSITargetDevicePath * path = NULL; SCSITargetDevicePath * result = NULL; UInt32 numPaths = 0; UInt32 index = 0; UInt32 resultIndex = 0; UInt64 bandwidth = 0xFFFFFFFFFFFFFFFFULL; STATUS_LOG ( ( "+PortBandwidthGlobals::AllocateBandwidth\n" ) ); // Grab the lock since we'll end up manipulating the table. IOLockLock ( fLock ); // Assume we're using the first path. result = pathSet->getObject ( index ); numPaths = pathSet->getCount ( ); // Loop over the passed in possible paths. for ( index = 0; index < numPaths; index++ ) { UInt32 domainID = 0; STATUS_LOG ( ( "Getting a path at index = %ld\n", index ) ); path = pathSet->getObject ( index ); domainID = path->GetDomainIdentifier ( )->unsigned32BitValue ( ); // Sanity check //check ( domainID < fCapacity ); if ( fListHead[domainID] < bandwidth ) { result = path; bandwidth = fListHead[domainID]; resultIndex = domainID; } } // Whichever path we chose, charge it with the bandwidth. fListHead[resultIndex] += bytes; // Done manipulating the table. Drop the lock. IOLockUnlock ( fLock ); STATUS_LOG ( ( "-PortBandwidthGlobals::AllocateBandwidth\n" ) ); return result; }
IOService * IOATABlockStorageDriver::instantiateNub ( void ) { STATUS_LOG ( ( "IOATABlockStorageDriver::instantiateNub entering.\n" ) ); IOService * nub = new IOATABlockStorageDevice; STATUS_LOG ( ( "IOATABlockStorageDriver::instantiateNub exiting nub = %p.\n", nub ) ); return nub; }
/* * DoSCSICommand() * Encapsulate super::SendCommand() to handle unexpected service and * task errors as well as hand off to SCSI SENSE interpreter. */ SCSITaskStatus IOSCSITape::DoSCSICommand( SCSITaskIdentifier request, UInt32 timeoutDuration) { SCSITaskStatus taskStatus = kSCSITaskStatus_DeliveryFailure; SCSIServiceResponse serviceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE; require((request != 0), ErrorExit); serviceResponse = SendCommand(request, timeoutDuration); sense_flags = 0; if (serviceResponse != kSCSIServiceResponse_TASK_COMPLETE) { STATUS_LOG("unknown service response: 0x%x", serviceResponse); goto ErrorExit; } else { taskStatus = GetTaskStatus(request); if (taskStatus == kSCSITaskStatus_CHECK_CONDITION) { /* Get and interpret SCSI SENSE information */ GetSense(request); } else if (taskStatus != kSCSITaskStatus_GOOD) { STATUS_LOG("unknown task status: 0x%x", taskStatus); } else if (taskStatus == kSCSITaskStatus_GOOD) { /* setup flags for device file closing */ if (flags & ST_WRITTEN_TOGGLE) flags |= ST_WRITTEN; else flags &= ~ST_WRITTEN; } } /* clear the write toggle bit in case the next command is not a * write */ flags &= ~ST_WRITTEN_TOGGLE; ErrorExit: return taskStatus; }
IOReturn IOATABlockStorageDriver::setWriteCacheState ( bool enabled ) { IOReturn status = kIOReturnSuccess; STATUS_LOG ( ( "IOATABlockStorageDriver::setWriteCacheState called.\n" ) ); if ( activityTickle ( kIOPMSuperclassPolicy1, ( UInt32 ) kIOATAPowerStateActive ) ) { status = ataCommandSetFeatures ( enabled ? kATAEnableWriteCache : kATADisableWriteCache, 0, 0, 0, 0, mATAFlagImmediate, true ); } else { status = kIOReturnNotResponding; } return status; }
IOReturn IOATABlockStorageDriver::getWriteCacheState ( bool * enabled ) { IOReturn status = kIOReturnSuccess; STATUS_LOG ( ( "IOATABlockStorageDriver::getWriteCacheState called.\n" ) ); if ( activityTickle ( kIOPMSuperclassPolicy1, ( UInt32 ) kIOATAPowerStateActive ) ) { status = identifyATADevice ( ); if ( status == kIOReturnSuccess ) { // Get write cache enabled bit. It's in word 85, bit 5 *enabled = fDeviceIdentifyData[kATAIdentifyCommandExtension2] & kATAWriteCacheEnabledMask; } } else { status = kIOReturnNotResponding; } return status; }
SCSIPathSet * SCSIPathSet::withCapacity ( unsigned int capacity ) { SCSIPathSet * set = NULL; bool result = false; STATUS_LOG ( ( "+SCSIPathSet::withCapacity\n" ) ); set = OSTypeAlloc ( SCSIPathSet ); require_nonzero ( set, ErrorExit ); result = set->initWithCapacity ( capacity ); require ( result, ReleaseSet ); return set; ReleaseSet: require_nonzero_quiet ( set, ErrorExit ); set->release ( ); set = NULL; ErrorExit: return set; }
void SCSIPressurePathManager::free ( void ) { STATUS_LOG ( ( "SCSIPressurePathManager::free\n" ) ); if ( fPathSet != NULL ) { fPathSet->release ( ); fPathSet = NULL; } if ( fInactivePathSet != NULL ) { fInactivePathSet->release ( ); fInactivePathSet = NULL; } if ( fLock != NULL ) { IOLockFree ( fLock ); fLock = NULL; } super::free ( ); }
SCSITargetDevicePath * SCSIPathSet::getObjectWithInterface ( const IOSCSIProtocolServices * interface ) const { SCSITargetDevicePath * element = NULL; SCSITargetDevicePath * result = NULL; OSNumber * domainID = NULL; UInt32 index = 0; STATUS_LOG ( ( "+SCSIPathSet::getObjectWithInterface\n" ) ); domainID = SCSITargetDevicePath::GetInterfaceDomainIdentifier ( interface ); for ( index = 0; index < count; index++ ) { element = ( SCSITargetDevicePath * ) array[index]; if ( element->GetDomainIdentifier ( )->isEqualTo ( domainID ) ) { result = element; break; } } return result; }
/* * GetSenseInformation * * Attempt to get SCSI sense information either from the Auto sense * mechanism or by querying manually. */ void IOSCSITape::GetSense(SCSITaskIdentifier request) { SCSI_Sense_Data senseBuffer = { 0 }; bool validSense = false; SCSIServiceResponse serviceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE; IOMemoryDescriptor *bufferDesc = IOMemoryDescriptor::withAddress((void *)&senseBuffer, sizeof(senseBuffer), kIODirectionIn); if (GetTaskStatus(request) == kSCSITaskStatus_CHECK_CONDITION) { validSense = GetAutoSenseData(request, &senseBuffer); if (validSense == false) { if (REQUEST_SENSE(request, bufferDesc, kSenseDefaultSize, 0) == true) serviceResponse = SendCommand(request, kTenSecondTimeoutInMS); if (serviceResponse == kSCSIServiceResponse_TASK_COMPLETE) validSense = true; } if (validSense == true) InterpretSense(&senseBuffer); else STATUS_LOG("invalid or unretrievable SCSI SENSE"); } bufferDesc->release(); }
AppleSCSIPDT03Emulator * AppleSCSIPDT03Emulator::Create ( void ) { AppleSCSIPDT03Emulator * logicalUnit = NULL; bool result = false; STATUS_LOG ( ( "AppleSCSIPDT03Emulator::Create\n" ) ); logicalUnit = OSTypeAlloc ( AppleSCSIPDT03Emulator ); require_nonzero ( logicalUnit, ErrorExit ); result = logicalUnit->init ( ); require ( result, ReleaseLogicalUnit ); return logicalUnit; ReleaseLogicalUnit: logicalUnit->release ( ); ErrorExit: return NULL; }
IOReturn IOATABlockStorageDriver::doFormatMedia ( UInt64 byteCapacity ) { STATUS_LOG ( ( "IOATABlockStorageDriver::doFormatMedia called.\n" ) ); return kIOReturnUnsupported; }
char * IOATABlockStorageDriver::getRevisionString ( void ) { STATUS_LOG ( ( "IOATABlockStorageDriver::getRevisionString called.\n" ) ); return fRevision; }
char * IOATABlockStorageDriver::getVendorString ( void ) { STATUS_LOG ( ( "IOATABlockStorageDriver::getVendorString called.\n" ) ); return NULL; }
char * IOATABlockStorageDriver::getAdditionalDeviceInfoString ( void ) { STATUS_LOG ( ( "IOATABlockStorageDriver::getAdditionalDeviceInfoString called.\n" ) ); return ( "[ATA]" ); }
char * IOATABlockStorageDriver::getProductString ( void ) { STATUS_LOG ( ( "IOATABlockStorageDriver::getProductString called.\n" ) ); return fModel; }
IOReturn IOATABlockStorageDriver::doStop ( void ) { STATUS_LOG ( ( "IOATABlockStorageDriver::doStop called.\n" ) ); return kIOReturnSuccess; }
IOReturn IOATABlockStorageDriver::doLockUnlockMedia ( bool doLock ) { STATUS_LOG ( ( "IOATABlockStorageDriver::doLockUnlockMedia called.\n" ) ); return kIOReturnUnsupported; // No removable ATA device support. }
bool SCSIPressurePathManager::AddPath ( IOSCSIProtocolServices * interface ) { bool result = false; SCSITargetDevicePath * path = NULL; OSDictionary * dict = NULL; PortBandwidthGlobals * bw = NULL; STATUS_LOG ( ( "SCSIPressurePathManager::AddPath\n" ) ); require_nonzero ( interface, ErrorExit ); path = SCSITargetDevicePath::Create ( this, interface ); require_nonzero ( path, ErrorExit ); bw = PortBandwidthGlobals::GetSharedInstance ( ); bw->AddSCSIPort ( path->GetDomainIdentifier ( )->unsigned32BitValue ( ) ); STATUS_LOG ( ( "Registering callback handler\n" ) ); interface->RegisterSCSITaskCompletionRoutine ( &SCSITargetDevicePathManager::PathTaskCallback ); dict = path->GetStatistics ( ); STATUS_LOG ( ( "Got path stats, count = %ld\n", dict->getCount ( ) ) ); fStatistics->setObject ( dict ); STATUS_LOG ( ( "fStatistics array has %ld members\n", fStatistics->getCount ( ) ) ); IOLockLock ( fLock ); result = fPathSet->setObject ( path ); IOLockUnlock ( fLock ); path->release ( ); path = NULL; ErrorExit: return result; }
void SCSIPressurePathManager::ActivatePath ( IOSCSIProtocolServices * interface ) { bool result = false; SCSITargetDevicePath * path = NULL; STATUS_LOG ( ( "SCSIPressurePathManager::ActivatePath\n" ) ); require_nonzero ( interface, ErrorExit ); IOLockLock ( fLock ); result = fInactivePathSet->member ( interface ); if ( result == true ) { path = fInactivePathSet->getObjectWithInterface ( interface ); if ( path != NULL ) { path->retain ( ); path->Activate ( ); fInactivePathSet->removeObject ( interface ); fPathSet->setObject ( path ); path->release ( ); path = NULL; } } else { result = fPathSet->member ( interface ); if ( result == false ) { IOLockUnlock ( fLock ); AddPath ( interface ); goto Exit; } } IOLockUnlock ( fLock ); ErrorExit: Exit: return; }
IOReturn IOATABlockStorageDriver::reportMaxValidBlock ( UInt64 * maxBlock ) { UInt64 diskCapacity = 0; assert ( fATADevice && maxBlock ); STATUS_LOG ( ( "IOATABlockStorageDriver::reportMaxValidBlock called.\n" ) ); doGetFormatCapacities ( &diskCapacity, 1 ); *maxBlock = ( diskCapacity / kATADefaultSectorSize ) - 1; STATUS_LOG ( ( "IOATABlockStorageDriver::reportMaxValidBlock maxBlock = %ld.\n", *maxBlock ) ); return kIOReturnSuccess; }
IOReturn IOATABlockStorageDriver::reportLockability ( bool * isLockable ) { STATUS_LOG ( ( "IOATABlockStorageDriver::reportLockability called.\n" ) ); *isLockable = false; return kIOReturnSuccess; }
IOReturn IOATABlockStorageDriver::reportEjectability ( bool * isEjectable ) { STATUS_LOG ( ( "IOATABlockStorageDriver::reportEjectability called.\n" ) ); *isEjectable = (fATASocketType == kPCCardSocket); return kIOReturnSuccess; }
IOReturn IOATABlockStorageDriver::reportWriteProtection ( bool * isWriteProtected ) { STATUS_LOG ( ( "IOATABlockStorageDriver::reportWriteProtection called.\n" ) ); *isWriteProtected = false; return kIOReturnSuccess; }
IOReturn IOATABlockStorageDriver::doSynchronizeCache ( void ) { IOReturn status = kIOReturnSuccess; IOATACommand * cmd = NULL; STATUS_LOG ( ( "IOATABlockStorageDriver::doSynchronizeCache called.\n" ) ); if ( fATASocketType == kPCCardSocket ) { // Device doesnÕt support flush cache. DonÕt send the command. fNumCommandsOutstanding--; status = kIOReturnSuccess; goto Exit; } cmd = ataCommandFlushCache ( ); // Do we have a valid command? if ( cmd == NULL ) { // Return no memory error. fNumCommandsOutstanding--; status = kIOReturnNoMemory; goto Exit; } // Send the command to flush the cache. status = syncExecute ( cmd, kATATimeout1Minute, 0 ); Exit: STATUS_LOG ( ( "IOATABlockStorageDriver::doSynchronizeCache returning status = %ld.\n", ( UInt32 ) status ) ); return status; }
IOReturn IOATABlockStorageDriver::reportBlockSize ( UInt64 * blockSize ) { STATUS_LOG ( ( "IOATABlockStorageDriver::reportBlockSize called.\n" ) ); *blockSize = kATADefaultSectorSize; return kIOReturnSuccess; }