1/* 2 * Copyright (c) 2002-2007 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 25//----------------------------------------------------------------------------- 26// Includes 27//----------------------------------------------------------------------------- 28 29// SCSI Parallel Family includes 30#include "SCSIParallelTask.h" 31 32// General IOKit includes 33#include <IOKit/IOLib.h> 34#include <IOKit/IOBufferMemoryDescriptor.h> 35#include <IOKit/IODMACommand.h> 36 37 38//----------------------------------------------------------------------------- 39// Macros 40//----------------------------------------------------------------------------- 41 42#define DEBUG 0 43#define DEBUG_ASSERT_COMPONENT_NAME_STRING "SCSIParallelTask" 44 45#if DEBUG 46#define SCSI_PARALLEL_TASK_DEBUGGING_LEVEL 0 47#endif 48 49 50// This module needs SPI_MODULE defined in order to pick up the 51// static debugging function. 52#define SPI_MODULE 1 53 54#include "IOSCSIParallelFamilyDebugging.h" 55 56 57#if ( SCSI_PARALLEL_TASK_DEBUGGING_LEVEL >= 1 ) 58#define PANIC_NOW(x) panic x 59#else 60#define PANIC_NOW(x) 61#endif 62 63#if ( SCSI_PARALLEL_TASK_DEBUGGING_LEVEL >= 2 ) 64#define ERROR_LOG(x) kprintf x 65#else 66#define ERROR_LOG(x) 67#endif 68 69#if ( SCSI_PARALLEL_TASK_DEBUGGING_LEVEL >= 3 ) 70#define STATUS_LOG(x) kprintf x 71#else 72#define STATUS_LOG(x) 73#endif 74 75 76#define super IODMACommand 77OSDefineMetaClassAndStructors ( SCSIParallelTask, IODMACommand ); 78 79 80#if 0 81#pragma mark - 82#pragma mark Public Methods 83#pragma mark - 84#endif 85 86 87//----------------------------------------------------------------------------- 88// Create - Creates a SCSIParallelTask [STATIC][PUBLIC] 89//----------------------------------------------------------------------------- 90 91SCSIParallelTask * 92SCSIParallelTask::Create ( UInt32 sizeOfHBAData, UInt64 alignmentMask ) 93{ 94 95 SCSIParallelTask * newTask = NULL; 96 bool result = false; 97 98 newTask = OSTypeAlloc ( SCSIParallelTask ); 99 require_nonzero ( newTask, ErrorExit ); 100 101 result = newTask->InitWithSize ( sizeOfHBAData, alignmentMask ); 102 require ( result, ReleaseTask ); 103 104 return newTask; 105 106 107ReleaseTask: 108 109 110 newTask->release ( ); 111 newTask = NULL; 112 113 114ErrorExit: 115 116 117 return NULL; 118 119} 120 121 122//----------------------------------------------------------------------------- 123// InitWithSize - Initializes the object with requested HBA data size. 124// [PUBLIC] 125//----------------------------------------------------------------------------- 126 127bool 128SCSIParallelTask::InitWithSize ( 129 UInt32 sizeOfHBAData, 130 UInt64 alignmentMask ) 131{ 132 133 IOBufferMemoryDescriptor * buffer = NULL; 134 IOReturn status = kIOReturnSuccess; 135 136 fCommandChain.next = NULL; 137 fCommandChain.prev = NULL; 138 139 fResendTaskChain.next = NULL; 140 fResendTaskChain.prev = NULL; 141 142 fTimeoutChain.next = NULL; 143 fTimeoutChain.prev = NULL; 144 145 fHBADataSize = sizeOfHBAData; 146 147 buffer = IOBufferMemoryDescriptor::inTaskWithPhysicalMask ( 148 kernel_task, 149 kIODirectionOutIn | kIOMemoryPhysicallyContiguous, 150 fHBADataSize, 151 alignmentMask ); 152 require_nonzero ( buffer, ErrorExit ); 153 154 status = buffer->prepare ( kIODirectionOutIn ); 155 require_success ( status, FreeHBAData ); 156 157 fHBAData = buffer->getBytesNoCopy ( ); 158 require_nonzero ( fHBAData, CompleteHBAData ); 159 160 bzero ( fHBAData, fHBADataSize ); 161 162 fHBADataDescriptor = buffer; 163 164 return true; 165 166 167CompleteHBAData: 168 169 170 buffer->complete ( ); 171 172 173FreeHBAData: 174 175 176 buffer->release ( ); 177 buffer = NULL; 178 179 180ErrorExit: 181 182 183 return false; 184 185} 186 187 188//----------------------------------------------------------------------------- 189// free - Frees any resources allocated. [PUBLIC] 190//----------------------------------------------------------------------------- 191 192void 193SCSIParallelTask::free ( void ) 194{ 195 196 if ( fHBADataDescriptor != NULL ) 197 { 198 199 fHBADataDescriptor->complete ( ); 200 fHBADataDescriptor->release ( ); 201 fHBADataDescriptor = NULL; 202 203 } 204 205 super::free ( ); 206 207} 208 209 210//----------------------------------------------------------------------------- 211// ResetForNewTask - Resets the task for execution. [PUBLIC] 212//----------------------------------------------------------------------------- 213 214void 215SCSIParallelTask::ResetForNewTask ( void ) 216{ 217 218 fTargetID = 0; 219 fDevice = NULL; 220 fSCSITask = NULL; 221 fRealizedTransferCount = 0; 222 fControllerTaskIdentifier = 0; 223 fTaskRetryCount = 0; 224 225 fSCSIParallelFeatureRequestCount = 0; 226 fSCSIParallelFeatureRequestResultCount = 0; 227 228 // Set the feature arrays to their default values 229 for ( int loop = 0; loop < kSCSIParallelFeature_TotalFeatureCount; loop++ ) 230 { 231 232 fSCSIParallelFeatureRequest[loop] = kSCSIParallelFeature_NoNegotiation; 233 fSCSIParallelFeatureResult[loop] = kSCSIParallelFeature_NegotitiationUnchanged; 234 235 } 236 237} 238 239 240//----------------------------------------------------------------------------- 241// SetSCSITaskIdentifier - Sets SCSITaskIdentifier for this task. [PUBLIC] 242//----------------------------------------------------------------------------- 243 244bool 245SCSIParallelTask::SetSCSITaskIdentifier ( SCSITaskIdentifier scsiRequest ) 246{ 247 248 fSCSITask = scsiRequest; 249 return true; 250 251} 252 253 254//----------------------------------------------------------------------------- 255// GetSCSITaskIdentifier - Gets SCSITaskIdentifier for this task. [PUBLIC] 256//----------------------------------------------------------------------------- 257 258SCSITaskIdentifier 259SCSIParallelTask::GetSCSITaskIdentifier ( void ) 260{ 261 return fSCSITask; 262} 263 264 265//----------------------------------------------------------------------------- 266// SetTargetIdentifier - Sets SCSITargetIdentifier for this task. [PUBLIC] 267//----------------------------------------------------------------------------- 268 269bool 270SCSIParallelTask::SetTargetIdentifier ( SCSITargetIdentifier theTargetID ) 271{ 272 fTargetID = theTargetID; 273 return true; 274} 275 276 277//----------------------------------------------------------------------------- 278// GetTargetIdentifier - Gets SCSITargetIdentifier for this task. [PUBLIC] 279//----------------------------------------------------------------------------- 280 281SCSITargetIdentifier 282SCSIParallelTask::GetTargetIdentifier ( void ) 283{ 284 return fTargetID; 285} 286 287 288//----------------------------------------------------------------------------- 289// SetDevice - Sets device for this task. [PUBLIC] 290//----------------------------------------------------------------------------- 291 292bool 293SCSIParallelTask::SetDevice ( IOSCSIParallelInterfaceDevice * device ) 294{ 295 fDevice = device; 296 return true; 297} 298 299 300//----------------------------------------------------------------------------- 301// GetDevice - Gets device for this task. [PUBLIC] 302//----------------------------------------------------------------------------- 303 304IOSCSIParallelInterfaceDevice * 305SCSIParallelTask::GetDevice ( void ) 306{ 307 return fDevice; 308} 309 310 311//----------------------------------------------------------------------------- 312// GetLogicalUnitNumber - Gets SCSILogicalUnitNumber for this task. [PUBLIC] 313//----------------------------------------------------------------------------- 314 315SCSILogicalUnitNumber 316SCSIParallelTask::GetLogicalUnitNumber ( void ) 317{ 318 return ( ( SCSITask * ) fSCSITask )->GetLogicalUnitNumber ( ); 319} 320 321//----------------------------------------------------------------------------- 322// GetLogicalUnitBytes - Gets SCSILogicalUnitBytes for this task. [PUBLIC] 323//----------------------------------------------------------------------------- 324 325void 326SCSIParallelTask::GetLogicalUnitBytes ( SCSILogicalUnitBytes * logicalUnitBytes ) 327{ 328 return ( ( SCSITask * ) fSCSITask )->GetLogicalUnitBytes ( logicalUnitBytes ); 329} 330 331//----------------------------------------------------------------------------- 332// GetTaskAttribute - Gets SCSITaskAttribute for this task. [PUBLIC] 333//----------------------------------------------------------------------------- 334 335SCSITaskAttribute 336SCSIParallelTask::GetTaskAttribute ( void ) 337{ 338 return ( ( SCSITask * ) fSCSITask )->GetTaskAttribute ( ); 339} 340 341 342//----------------------------------------------------------------------------- 343// GetTaggedTaskIdentifier - Gets SCSITaggedTaskIdentifier for this task. 344// [PUBLIC] 345//----------------------------------------------------------------------------- 346 347SCSITaggedTaskIdentifier 348SCSIParallelTask::GetTaggedTaskIdentifier( void ) 349{ 350 return ( ( SCSITask * ) fSCSITask )->GetTaggedTaskIdentifier ( ); 351} 352 353 354//----------------------------------------------------------------------------- 355// GetCommandDescriptorBlockSize - Gets cdb size for this task. [PUBLIC] 356//----------------------------------------------------------------------------- 357 358UInt8 359SCSIParallelTask::GetCommandDescriptorBlockSize ( void ) 360{ 361 return ( ( SCSITask * ) fSCSITask )->GetCommandDescriptorBlockSize ( ); 362} 363 364 365//----------------------------------------------------------------------------- 366// GetCommandDescriptorBlock - Gets cdb for this task. [PUBLIC] 367//----------------------------------------------------------------------------- 368 369bool 370SCSIParallelTask::GetCommandDescriptorBlock ( 371 SCSICommandDescriptorBlock * cdbData ) 372{ 373 return ( ( SCSITask * ) fSCSITask )->GetCommandDescriptorBlock ( cdbData ); 374} 375 376 377//----------------------------------------------------------------------------- 378// GetDataTransferDirection - Gets transfer direction for this task. [PUBLIC] 379//----------------------------------------------------------------------------- 380 381UInt8 382SCSIParallelTask::GetDataTransferDirection ( void ) 383{ 384 return ( ( SCSITask * ) fSCSITask )->GetDataTransferDirection ( ); 385} 386 387 388//----------------------------------------------------------------------------- 389// GetRequestedDataTransferCount - Gets transfer count for this task. [PUBLIC] 390//----------------------------------------------------------------------------- 391 392UInt64 393SCSIParallelTask::GetRequestedDataTransferCount ( void ) 394{ 395 return ( ( SCSITask * ) fSCSITask )->GetRequestedDataTransferCount ( ); 396} 397 398 399//----------------------------------------------------------------------------- 400// IncrementRealizedDataTransferCount - Adds value to the realized transfer 401// count for this task. [PUBLIC] 402//----------------------------------------------------------------------------- 403 404void 405SCSIParallelTask::IncrementRealizedDataTransferCount ( 406 UInt64 realizedTransferCountInBytes ) 407{ 408 fRealizedTransferCount += realizedTransferCountInBytes; 409} 410 411 412//----------------------------------------------------------------------------- 413// SetRealizedDataTransferCount - Sets the realized transfer count for 414// this task. [PUBLIC] 415//----------------------------------------------------------------------------- 416 417bool 418SCSIParallelTask::SetRealizedDataTransferCount ( 419 UInt64 realizedTransferCountInBytes ) 420{ 421 422 fRealizedTransferCount = realizedTransferCountInBytes; 423 return true; 424 425} 426 427 428//----------------------------------------------------------------------------- 429// GetRealizedDataTransferCount - Gets the realized transfer count for 430// this task. [PUBLIC] 431//----------------------------------------------------------------------------- 432 433UInt64 434SCSIParallelTask::GetRealizedDataTransferCount ( void ) 435{ 436 return fRealizedTransferCount; 437} 438 439 440//----------------------------------------------------------------------------- 441// GetDataBuffer - Gets the data buffer associated with this task. [PUBLIC] 442//----------------------------------------------------------------------------- 443 444IOMemoryDescriptor * 445SCSIParallelTask::GetDataBuffer ( void ) 446{ 447 return ( ( SCSITask * ) fSCSITask )->GetDataBuffer ( ); 448} 449 450 451//----------------------------------------------------------------------------- 452// GetDataBufferOffset - Gets the data buffer offset associated with this 453// task. [PUBLIC] 454//----------------------------------------------------------------------------- 455 456UInt64 457SCSIParallelTask::GetDataBufferOffset ( void ) 458{ 459 return ( ( SCSITask * ) fSCSITask )->GetDataBufferOffset ( ); 460} 461 462 463//----------------------------------------------------------------------------- 464// GetTimeoutDuration - Gets the timeout duration associated with this 465// task. [PUBLIC] 466//----------------------------------------------------------------------------- 467 468UInt32 469SCSIParallelTask::GetTimeoutDuration ( void ) 470{ 471 return ( ( SCSITask * ) fSCSITask )->GetTimeoutDuration ( ); 472} 473 474 475//----------------------------------------------------------------------------- 476// SetAutoSenseData - Sets the auto-sense data. [PUBLIC] 477//----------------------------------------------------------------------------- 478 479bool 480SCSIParallelTask::SetAutoSenseData ( 481 SCSI_Sense_Data * senseData, 482 UInt8 senseDataSize ) 483{ 484 return ( ( SCSITask * ) fSCSITask )->SetAutoSenseData ( senseData, senseDataSize ); 485} 486 487 488//----------------------------------------------------------------------------- 489// GetAutoSenseData - Gets the auto-sense data. [PUBLIC] 490//----------------------------------------------------------------------------- 491 492bool 493SCSIParallelTask::GetAutoSenseData ( 494 SCSI_Sense_Data * receivingBuffer, 495 UInt8 senseDataSize ) 496{ 497 return ( ( SCSITask * ) fSCSITask )->GetAutoSenseData ( receivingBuffer, senseDataSize ); 498} 499 500 501//----------------------------------------------------------------------------- 502// GetAutoSenseDataSize - Gets the auto-sense data size. [PUBLIC] 503//----------------------------------------------------------------------------- 504 505UInt8 506SCSIParallelTask::GetAutoSenseDataSize ( void ) 507{ 508 return ( ( SCSITask * ) fSCSITask )->GetAutoSenseDataSize ( ); 509} 510 511 512//----------------------------------------------------------------------------- 513// SetSCSIParallelFeatureNegotiation - Sets a feature negotiation request. 514// [PUBLIC] 515//----------------------------------------------------------------------------- 516 517void 518SCSIParallelTask::SetSCSIParallelFeatureNegotiation ( 519 SCSIParallelFeature requestedFeature, 520 SCSIParallelFeatureRequest newRequest ) 521{ 522 523 // Check to see if this is a known feature. Since the feature definitions 524 // are zero based if the request is greater or equal than the total number 525 // of features it is undefined. 526 if ( requestedFeature >= kSCSIParallelFeature_TotalFeatureCount ) 527 { 528 529 ERROR_LOG ( ( "Unknown feature request: %ld\n", ( int ) requestedFeature ) ); 530 531 // The object does not know of this feature, so it will 532 // ignore this request. 533 return; 534 535 } 536 537 // If this request is either to negotiate or clear a negotiation, 538 // increment the requested feature count. 539 if ( newRequest != kSCSIParallelFeature_NoNegotiation ) 540 { 541 fSCSIParallelFeatureRequestCount++; 542 } 543 544 fSCSIParallelFeatureRequest[requestedFeature] = newRequest; 545 546} 547 548 549//----------------------------------------------------------------------------- 550// GetSCSIParallelFeatureNegotiation - Gets a feature negotiation request. 551// [PUBLIC] 552//----------------------------------------------------------------------------- 553 554SCSIParallelFeatureRequest 555SCSIParallelTask::GetSCSIParallelFeatureNegotiation ( 556 SCSIParallelFeature requestedFeature ) 557{ 558 559 // Check to see if this is a known feature. Since the feature definitions 560 // are zero based if the request is greater or equal than the total number 561 // of features it is undefined. 562 if ( requestedFeature >= kSCSIParallelFeature_TotalFeatureCount ) 563 { 564 565 ERROR_LOG ( ( "Unknown feature request: %ld\n", ( int ) requestedFeature ) ); 566 567 // The object does not know of this feature, so it will 568 // return that negotation is not requested. 569 return kSCSIParallelFeature_NoNegotiation; 570 571 } 572 573 return fSCSIParallelFeatureRequest[requestedFeature]; 574 575} 576 577 578//----------------------------------------------------------------------------- 579// GetSCSIParallelFeatureNegotiationCount - Gets feature negotiation request count. 580// [PUBLIC] 581//----------------------------------------------------------------------------- 582 583UInt64 584SCSIParallelTask::GetSCSIParallelFeatureNegotiationCount ( void ) 585{ 586 return fSCSIParallelFeatureRequestCount; 587} 588 589 590//----------------------------------------------------------------------------- 591// SetSCSIParallelFeatureNegotiationResult - Sets feature negotiation result. 592// [PUBLIC] 593//----------------------------------------------------------------------------- 594 595void 596SCSIParallelTask::SetSCSIParallelFeatureNegotiationResult ( 597 SCSIParallelFeature requestedFeature, 598 SCSIParallelFeatureResult newResult ) 599{ 600 601 // Check to see if this is a known feature. Since the feature definitions 602 // are zero based if the request is greater or equal than the total number 603 // of features it is undefined. 604 if ( requestedFeature >= kSCSIParallelFeature_TotalFeatureCount ) 605 { 606 607 ERROR_LOG ( ( "Unknown feature request: %ld\n", ( int ) requestedFeature ) ); 608 609 // The object does not know of this feature, so it will 610 // ignore this request. 611 return; 612 613 } 614 615 if ( newResult != kSCSIParallelFeature_NegotitiationUnchanged ) 616 { 617 fSCSIParallelFeatureRequestResultCount++; 618 } 619 620 fSCSIParallelFeatureResult[requestedFeature] = newResult; 621 622} 623 624 625//----------------------------------------------------------------------------- 626// GetSCSIParallelFeatureNegotiationResult - Gets feature negotiation result. 627// [PUBLIC] 628//----------------------------------------------------------------------------- 629 630SCSIParallelFeatureResult 631SCSIParallelTask::GetSCSIParallelFeatureNegotiationResult ( 632 SCSIParallelFeature requestedFeature ) 633{ 634 635 // Check to see if this is a known feature. Since the feature definitions 636 // are zero based if the request is greater or equal than the total number 637 // of features it is undefined. 638 if ( requestedFeature >= kSCSIParallelFeature_TotalFeatureCount ) 639 { 640 641 ERROR_LOG ( ( "Unknown feature request: %ld\n", ( int ) requestedFeature ) ); 642 643 // The object does not know of this feature, so it will 644 // return that negotation is unchanged. 645 return kSCSIParallelFeature_NegotitiationUnchanged; 646 647 } 648 649 return fSCSIParallelFeatureResult[requestedFeature]; 650 651} 652 653 654//----------------------------------------------------------------------------- 655// GetSCSIParallelFeatureNegotiationResultCount - Gets feature negotiation 656// result count. [PUBLIC] 657//----------------------------------------------------------------------------- 658 659UInt64 660SCSIParallelTask::GetSCSIParallelFeatureNegotiationResultCount ( void ) 661{ 662 return fSCSIParallelFeatureRequestResultCount; 663} 664 665 666//----------------------------------------------------------------------------- 667// SetControllerTaskIdentifier - Sets controller unique identifier. [PUBLIC] 668//----------------------------------------------------------------------------- 669 670void 671SCSIParallelTask::SetControllerTaskIdentifier ( UInt64 newIdentifier ) 672{ 673 fControllerTaskIdentifier = newIdentifier; 674} 675 676 677//----------------------------------------------------------------------------- 678// GetControllerTaskIdentifier - Gets controller unique identifier. [PUBLIC] 679//----------------------------------------------------------------------------- 680 681UInt64 682SCSIParallelTask::GetControllerTaskIdentifier ( void ) 683{ 684 return fControllerTaskIdentifier; 685} 686 687 688//----------------------------------------------------------------------------- 689// GetHBADataSize - Gets data size of HBA specific data. [PUBLIC] 690//----------------------------------------------------------------------------- 691 692UInt32 693SCSIParallelTask::GetHBADataSize ( void ) 694{ 695 return fHBADataSize; 696} 697 698 699//----------------------------------------------------------------------------- 700// GetHBADataPointer - Gets virtual address of HBA specific data. [PUBLIC] 701//----------------------------------------------------------------------------- 702 703void * 704SCSIParallelTask::GetHBADataPointer ( void ) 705{ 706 return fHBAData; 707} 708 709 710//----------------------------------------------------------------------------- 711// GetHBADataDescriptor - Gets IOMemoryDescriptor of HBA specific data. 712// [PUBLIC] 713//----------------------------------------------------------------------------- 714 715IOMemoryDescriptor * 716SCSIParallelTask::GetHBADataDescriptor ( void ) 717{ 718 return fHBADataDescriptor; 719} 720 721 722//----------------------------------------------------------------------------- 723// GetTimeoutDeadline - Gets the timeout deadline in AbsoluteTime. [PUBLIC] 724//----------------------------------------------------------------------------- 725 726AbsoluteTime 727SCSIParallelTask::GetTimeoutDeadline ( void ) 728{ 729 return fTimeoutDeadline; 730} 731 732 733//----------------------------------------------------------------------------- 734// SetTimeoutDeadline - Sets the timeout deadline in AbsoluteTime. [PUBLIC] 735//----------------------------------------------------------------------------- 736 737void 738SCSIParallelTask::SetTimeoutDeadline ( AbsoluteTime time ) 739{ 740 fTimeoutDeadline = time; 741} 742 743 744#if 0 745#pragma mark - 746#pragma mark Static Debugging Assertion Method 747#pragma mark - 748#endif 749 750 751//----------------------------------------------------------------------------- 752// IOSCSIParallelFamilyDebugAssert - Assertion routine. 753//----------------------------------------------------------------------------- 754 755void 756IOSCSIParallelFamilyDebugAssert ( const char * componentNameString, 757 const char * assertionString, 758 const char * exceptionLabelString, 759 const char * errorString, 760 const char * fileName, 761 long lineNumber, 762 int errorCode ) 763{ 764 765 kprintf ( "%s Assert failed: %s ", componentNameString, assertionString ); 766 767 if ( exceptionLabelString != NULL ) 768 kprintf ( "%s ", exceptionLabelString ); 769 770 if ( errorString != NULL ) 771 kprintf ( "%s ", errorString ); 772 773 if ( fileName != NULL ) 774 kprintf ( "file: %s ", fileName ); 775 776 if ( lineNumber != 0 ) 777 kprintf ( "line: %ld ", lineNumber ); 778 779 if ( ( long ) errorCode != 0 ) 780 kprintf ( "error: %ld ", ( long ) errorCode ); 781 782 kprintf ( "\n" ); 783 784} 785