1/* 2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23/* 24 * 25 * IOATACommand.cpp 26 * 27 */ 28 29 30#include<IOKit/IOTypes.h> 31#include <IOKit/IOLib.h> 32 33#include"IOATATypes.h" 34#include"IOATACommand.h" 35 36#ifdef DLOG 37#undef DLOG 38#endif 39 40#ifdef ATA_DEBUG 41#define DLOG(fmt, args...) IOLog(fmt, ## args) 42#else 43#define DLOG(fmt, args...) 44#endif 45 46//--------------------------------------------------------------------------- 47 48#define super IOCommand 49 50OSDefineMetaClass( IOATACommand, IOCommand ) 51OSDefineAbstractStructors( IOATACommand, IOCommand ) 52 53 OSMetaClassDefineReservedUsed(IOATACommand, 0) //setendResult() 54 OSMetaClassDefineReservedUsed(IOATACommand, 1) // getExtendedLBAPtr() 55 OSMetaClassDefineReservedUnused(IOATACommand, 2); 56 OSMetaClassDefineReservedUnused(IOATACommand, 3); 57 OSMetaClassDefineReservedUnused(IOATACommand, 4); 58 OSMetaClassDefineReservedUnused(IOATACommand, 5); 59 OSMetaClassDefineReservedUnused(IOATACommand, 6); 60 OSMetaClassDefineReservedUnused(IOATACommand, 7); 61 OSMetaClassDefineReservedUnused(IOATACommand, 8); 62 OSMetaClassDefineReservedUnused(IOATACommand, 9); 63 OSMetaClassDefineReservedUnused(IOATACommand, 10); 64 OSMetaClassDefineReservedUnused(IOATACommand, 11); 65 OSMetaClassDefineReservedUnused(IOATACommand, 12); 66 OSMetaClassDefineReservedUnused(IOATACommand, 13); 67 OSMetaClassDefineReservedUnused(IOATACommand, 14); 68 OSMetaClassDefineReservedUnused(IOATACommand, 15); 69 OSMetaClassDefineReservedUnused(IOATACommand, 16); 70 OSMetaClassDefineReservedUnused(IOATACommand, 17); 71 OSMetaClassDefineReservedUnused(IOATACommand, 18); 72 OSMetaClassDefineReservedUnused(IOATACommand, 19); 73 OSMetaClassDefineReservedUnused(IOATACommand, 20); 74 75 76 77/*----------------------------------------------------------------------------- 78 * 79 * 80 *-----------------------------------------------------------------------------*/ 81bool 82IOATACommand::init() 83{ 84 fExpansionData = (ExpansionData*) IOMalloc( sizeof( ExpansionData) ); 85 fExpansionData->extLBA = IOExtendedLBA::createIOExtendedLBA( this ); 86 87 if( ! super::init() || fExpansionData == NULL || fExpansionData->extLBA == NULL ) 88 return false; 89 90 zeroCommand(); 91 92 return true; 93 94} 95 96/*--------------------------------------------------------------------------- 97 * free() - the pseudo destructor. Let go of what we don't need anymore. 98 * 99 * 100 ---------------------------------------------------------------------------*/ 101void 102IOATACommand::free() 103{ 104 105 getExtendedLBA()->release(); 106 IOFree( fExpansionData, sizeof( ExpansionData) ); 107 super::free(); 108 109} 110/*----------------------------------------------------------------------------- 111 * 112 * 113 *-----------------------------------------------------------------------------*/ 114void 115IOATACommand::zeroCommand(void) 116{ 117 118 _opCode = kATANoOp; 119 _flags = 0; 120 _unit = kATAInvalidDeviceID; 121 _timeoutMS = 0; 122 _desc = 0L; 123 _position = 0; 124 _byteCount = 0; 125 _regMask = (ataRegMask) 0; 126 _callback = 0L ; 127 _result = 0; 128 _actualByteCount = 0; 129 _status = 0; 130 _errReg = 0; 131 _logicalChunkSize = kATADefaultSectorSize; 132 _inUse = false; 133 134 _taskFile.ataDataRegister = 0x0000; 135 _taskFile.ataAltSDevCReg = 0x00; 136 _taskFile.taskFile.ataTFFeatures = 0; 137 _taskFile.taskFile.ataTFCount = 0; 138 _taskFile.taskFile.ataTFSector = 0; 139 _taskFile.taskFile.ataTFCylLo = 0; 140 _taskFile.taskFile.ataTFCylHigh = 0; 141 _taskFile.taskFile.ataTFSDH = 0; 142 _taskFile.taskFile.ataTFCommand = 0; 143 144 145 for( int i = 0; i < 16 ; i += 2 ) 146 { 147 _packet.atapiCommandByte[ i ] = 0x000; 148 } 149 150 _packet.atapiPacketSize = 0; 151 152 getExtendedLBA()->zeroData(); 153 154} 155 156 157/*----------------------------------------------------------------------------- 158 * 159 * 160 *-----------------------------------------------------------------------------*/ 161void 162IOATACommand::setOpcode( ataOpcode inCode) 163{ 164 165 _opCode = inCode; 166 167} 168 169 170/*----------------------------------------------------------------------------- 171 * 172 * 173 *-----------------------------------------------------------------------------*/ 174 175void 176IOATACommand::setFlags( UInt32 inFlags) 177{ 178 179 _flags = inFlags; 180 181} 182 183 184/*----------------------------------------------------------------------------- 185 * 186 * 187 *-----------------------------------------------------------------------------*/ 188 189void 190IOATACommand::setUnit( ataUnitID inUnit) 191{ 192 193 _unit = inUnit; 194 195} 196 197 198/*----------------------------------------------------------------------------- 199 * 200 * 201 *-----------------------------------------------------------------------------*/ 202 203void 204IOATACommand::setTimeoutMS( UInt32 inMS) 205{ 206 207 _timeoutMS = inMS; 208 209} 210 211 212/*----------------------------------------------------------------------------- 213 * 214 * 215 *-----------------------------------------------------------------------------*/ 216 217void 218IOATACommand::setCallbackPtr (IOATACompletionFunction* inCompletion) 219{ 220 221 _callback = inCompletion; 222 223} 224 225 226/*----------------------------------------------------------------------------- 227 * 228 * 229 *-----------------------------------------------------------------------------*/ 230void 231IOATACommand::setRegMask( ataRegMask mask) 232{ 233 234 _regMask = mask; 235 236} 237 238/*----------------------------------------------------------------------------- 239 * 240 * 241 *-----------------------------------------------------------------------------*/ 242 243void 244IOATACommand::setBuffer ( IOMemoryDescriptor* inDesc) 245{ 246 247 _desc = inDesc; 248 249} 250 251 252 253/*----------------------------------------------------------------------------- 254 * 255 * 256 *-----------------------------------------------------------------------------*/ 257 258void 259IOATACommand::setPosition (IOByteCount fromPosition) 260{ 261 262 _position = fromPosition; 263 264} 265 266 267/*----------------------------------------------------------------------------- 268 * 269 * 270 *-----------------------------------------------------------------------------*/ 271 272void 273IOATACommand::setByteCount (IOByteCount numBytes) 274{ 275 276 _byteCount = numBytes; 277 278} 279 280/*----------------------------------------------------------------------------- 281 * 282 * 283 *-----------------------------------------------------------------------------*/ 284 285void 286IOATACommand::setTransferChunkSize (IOByteCount numBytes) 287{ 288 289 _logicalChunkSize = numBytes; 290 291} 292 293 294 295/*----------------------------------------------------------------------------- 296 * 297 * 298 *-----------------------------------------------------------------------------*/ 299 300void 301IOATACommand::setFeatures( UInt8 in) 302{ 303 304 _taskFile.taskFile.ataTFFeatures = in; 305 306} 307 308 309/*----------------------------------------------------------------------------- 310 * 311 * 312 *-----------------------------------------------------------------------------*/ 313 314UInt8 315IOATACommand::getErrorReg (void ) 316{ 317 318 return _taskFile.taskFile.ataTFFeatures; 319 320} 321 322 323/*----------------------------------------------------------------------------- 324 * 325 * 326 *-----------------------------------------------------------------------------*/ 327 328void 329IOATACommand::setSectorCount( UInt8 in) 330{ 331 332 _taskFile.taskFile.ataTFCount = in; 333 334} 335 336 337/*----------------------------------------------------------------------------- 338 * 339 * 340 *-----------------------------------------------------------------------------*/ 341 342UInt8 343IOATACommand::getSectorCount (void ) 344{ 345 346 return _taskFile.taskFile.ataTFCount; 347 348} 349 350 351/*----------------------------------------------------------------------------- 352 * 353 * 354 *-----------------------------------------------------------------------------*/ 355 356void 357IOATACommand::setSectorNumber( UInt8 in) 358{ 359 360 _taskFile.taskFile.ataTFSector = in; 361 362} 363 364 365/*----------------------------------------------------------------------------- 366 * 367 * 368 *-----------------------------------------------------------------------------*/ 369 370UInt8 371IOATACommand::getSectorNumber (void ) 372{ 373 374 return _taskFile.taskFile.ataTFSector; 375 376} 377 378 379/*----------------------------------------------------------------------------- 380 * 381 * 382 *-----------------------------------------------------------------------------*/ 383 384void 385IOATACommand::setCylLo ( UInt8 in) 386{ 387 388 _taskFile.taskFile.ataTFCylLo = in; 389 390} 391 392 393/*----------------------------------------------------------------------------- 394 * 395 * 396 *-----------------------------------------------------------------------------*/ 397 398 399UInt8 400IOATACommand::getCylLo (void ) 401{ 402 403 return _taskFile.taskFile.ataTFCylLo; 404 405} 406 407/*----------------------------------------------------------------------------- 408 * 409 * 410 *-----------------------------------------------------------------------------*/ 411void 412IOATACommand::setCylHi( UInt8 in) 413{ 414 415 _taskFile.taskFile.ataTFCylHigh = in; 416 417} 418 419 420/*----------------------------------------------------------------------------- 421 * 422 * 423 *-----------------------------------------------------------------------------*/ 424 425UInt8 426IOATACommand::getCylHi (void ) 427{ 428 429 return _taskFile.taskFile.ataTFCylHigh; 430 431} 432 433 434/*----------------------------------------------------------------------------- 435 * 436 * 437 *-----------------------------------------------------------------------------*/ 438 439void 440IOATACommand::setDevice_Head( UInt8 in) 441{ 442 443 _taskFile.taskFile.ataTFSDH = in; 444 445} 446 447 448/*----------------------------------------------------------------------------- 449 * 450 * 451 *-----------------------------------------------------------------------------*/ 452 453UInt8 454IOATACommand::getDevice_Head (void ) 455{ 456 457 return _taskFile.taskFile.ataTFSDH; 458 459} 460 461 462/*----------------------------------------------------------------------------- 463 * 464 * 465 *-----------------------------------------------------------------------------*/ 466 467void 468IOATACommand::setCommand ( UInt8 in) 469{ 470 471 _taskFile.taskFile.ataTFCommand = in; 472 473} 474 475 476/*----------------------------------------------------------------------------- 477 * 478 * 479 *-----------------------------------------------------------------------------*/ 480 481UInt8 482IOATACommand::getStatus (void ) 483{ 484 485 return _taskFile.taskFile.ataTFCommand; 486 487} 488 489 490/*----------------------------------------------------------------------------- 491 * 492 * 493 *-----------------------------------------------------------------------------*/ 494 495 496 497IOReturn 498IOATACommand::setPacketCommand( UInt16 packetSizeBytes, UInt8* packetBytes) 499{ 500// IOLog("ATACommand::setPacket size %d bytePtr = %lx\n", packetSizeBytes, packetBytes); 501 502 if( ( packetSizeBytes > 16 ) || (packetBytes == 0L)) 503 return -1; 504 505 UInt8* cmdBytes = (UInt8*) _packet.atapiCommandByte; 506 507 for( int i = 0; i < packetSizeBytes; i++ ) 508 { 509 cmdBytes[ i ] = packetBytes[ i ]; 510 } 511 512 _packet.atapiPacketSize = packetSizeBytes; 513 514 return kATANoErr; 515 516} 517 518 519 520/*----------------------------------------------------------------------------- 521 * 522 * 523 *-----------------------------------------------------------------------------*/ 524 525void 526IOATACommand::setDataReg ( UInt16 in) 527{ 528 529 _taskFile.ataDataRegister = in; 530 531} 532 533 534/*----------------------------------------------------------------------------- 535 * 536 * 537 *-----------------------------------------------------------------------------*/ 538 539 540UInt16 541IOATACommand::getDataReg (void ) 542{ 543 544 return _taskFile.ataDataRegister; 545 546} 547 548 549/*----------------------------------------------------------------------------- 550 * 551 * 552 *-----------------------------------------------------------------------------*/ 553 554 555 556void 557IOATACommand::setControl ( UInt8 in) 558{ 559 560 _taskFile.ataAltSDevCReg = in; 561 562} 563 564 565/*----------------------------------------------------------------------------- 566 * 567 * 568 *-----------------------------------------------------------------------------*/ 569 570 571UInt8 572IOATACommand::getAltStatus (void ) 573{ 574 575 return _taskFile.ataAltSDevCReg; 576 577} 578 579 580/*----------------------------------------------------------------------------- 581 * 582 * 583 *-----------------------------------------------------------------------------*/ 584 585 586 587 588IOReturn 589IOATACommand::getResult (void) 590{ 591 592 return _result; 593 594} 595 596 597/*----------------------------------------------------------------------------- 598 * 599 * 600 *-----------------------------------------------------------------------------*/ 601 602 603IOMemoryDescriptor* 604IOATACommand::getBuffer ( void ) 605{ 606 607 return _desc; 608 609} 610 611 612/*----------------------------------------------------------------------------- 613 * 614 * 615 *-----------------------------------------------------------------------------*/ 616 617 618IOByteCount 619IOATACommand::getActualTransfer ( void ) 620{ 621 622 return _actualByteCount; 623 624} 625 626 627/*----------------------------------------------------------------------------- 628 * 629 * 630 *-----------------------------------------------------------------------------*/ 631 632 633UInt8 634IOATACommand::getEndStatusReg (void) 635{ 636 637 return _status; 638 639} 640 641 642/*----------------------------------------------------------------------------- 643 * 644 * 645 *-----------------------------------------------------------------------------*/ 646 647 648 649UInt8 650IOATACommand::getEndErrorReg( void ) 651{ 652 653 return _errReg; 654 655} 656 657 658/*----------------------------------------------------------------------------- 659 * returns true if IOATAController is using the command. 660 * 661 *-----------------------------------------------------------------------------*/ 662 663bool 664IOATACommand::getCommandInUse( void ) 665{ 666 667 668 return _inUse; 669 670 671} 672 673/*----------------------------------------------------------------------------- 674 * 675 * 676 *-----------------------------------------------------------------------------*/ 677 678IOReturn 679IOATACommand::setLBA28( UInt32 lba, ataUnitID inUnit) 680{ 681 // param check the inputs 682 683 if( (lba & 0xF0000000) != 0x00000000 684 || !(inUnit == kATADevice0DeviceID || inUnit == kATADevice1DeviceID) ) 685 { 686 //param out of range 687 return -1; 688 } 689 690 691 setSectorNumber( (lba & 0xFF) ); //LBA 7:0 692 setCylLo( ((lba & 0xFF00) >> 8) ); // LBA 15:8 693 setCylHi( ((lba & 0x00FF0000) >> 16) ); // LBA 23:16 694 setDevice_Head(((lba & 0x0F000000) >> 24 ) | mATALBASelect |( ((UInt8) inUnit) << 4)); //LBA 27:24 695 696 return kATANoErr; 697 698} 699 700void 701IOATACommand::setEndResult(UInt8 inStatus, UInt8 endError ) 702{ 703 _status = inStatus; 704 _errReg = endError; 705} 706 707 708 709IOExtendedLBA* 710IOATACommand::getExtendedLBA(void) 711{ 712 713 return fExpansionData->extLBA; 714 715} 716 717 718 719//////////////////////////////////////////////////////////////////////// 720#pragma mark IOExtendedLBA 721#undef super 722 723#define super OSObject 724OSDefineMetaClassAndStructors( IOExtendedLBA, OSObject ) 725 726OSMetaClassDefineReservedUnused(IOExtendedLBA, 0) 727OSMetaClassDefineReservedUnused(IOExtendedLBA, 1) 728OSMetaClassDefineReservedUnused(IOExtendedLBA, 2); 729OSMetaClassDefineReservedUnused(IOExtendedLBA, 3); 730OSMetaClassDefineReservedUnused(IOExtendedLBA, 4); 731OSMetaClassDefineReservedUnused(IOExtendedLBA, 5); 732OSMetaClassDefineReservedUnused(IOExtendedLBA, 6); 733OSMetaClassDefineReservedUnused(IOExtendedLBA, 7); 734OSMetaClassDefineReservedUnused(IOExtendedLBA, 8); 735OSMetaClassDefineReservedUnused(IOExtendedLBA, 9); 736OSMetaClassDefineReservedUnused(IOExtendedLBA, 10); 737 738 739 740 741 742IOExtendedLBA* 743IOExtendedLBA::createIOExtendedLBA(IOATACommand* inOwner) 744{ 745 746 IOExtendedLBA* me = new IOExtendedLBA; 747 if( me == NULL) 748 { 749 return NULL; 750 } 751 752 me->owner = inOwner; 753 me->zeroData(); 754 755 return me; 756 757} 758 759 760 761void 762IOExtendedLBA::setLBALow16( UInt16 inLBALow) 763{ 764 lbaLow = inLBALow ; 765 766} 767 768 769UInt16 770IOExtendedLBA::getLBALow16 (void) 771{ 772 773 return lbaLow ; 774 775} 776 777void 778IOExtendedLBA::setLBAMid16 (UInt16 inLBAMid) 779{ 780 781 lbaMid = inLBAMid ; 782} 783 784 785UInt16 786IOExtendedLBA::getLBAMid16( void ) 787{ 788 789 return lbaMid; 790 791 792} 793 794void 795IOExtendedLBA::setLBAHigh16( UInt16 inLBAHigh ) 796{ 797 lbaHigh = inLBAHigh ; 798} 799 800 801UInt16 802IOExtendedLBA::getLBAHigh16( void ) 803{ 804 805 return lbaHigh; 806 807} 808 809void 810IOExtendedLBA::setSectorCount16( UInt16 inSectorCount ) 811{ 812 813 sectorCount = inSectorCount ; 814 815} 816 817UInt16 818IOExtendedLBA::getSectorCount16( void ) 819{ 820 return sectorCount; 821} 822 823void 824IOExtendedLBA::setFeatures16( UInt16 inFeatures ) 825{ 826 features = inFeatures; 827} 828 829UInt16 830IOExtendedLBA::getFeatures16( void ) 831{ 832 833 return features; 834 835} 836 837void 838IOExtendedLBA::setDevice( UInt8 inDevice ) 839{ 840 841 device = inDevice; 842 843} 844 845 846UInt8 847IOExtendedLBA::getDevice( void ) 848{ 849 850 851 return device; 852 853} 854 855void 856IOExtendedLBA::setCommand( UInt8 inCommand ) 857{ 858 859 860 command = inCommand; 861 862} 863 864 865UInt8 866IOExtendedLBA::getCommand( void ) 867{ 868 869 return command; 870} 871 872 873 874void 875IOExtendedLBA::setExtendedLBA( UInt32 inLBAHi, UInt32 inLBALo, ataUnitID inUnit, UInt16 extendedCount, UInt8 extendedCommand ) 876{ 877 878 UInt8 lba7, lba15, lba23, lba31, lba39, lba47; 879 lba7 = (inLBALo & 0xff); 880 lba15 = (inLBALo & 0xff00) >> 8; 881 lba23 = (inLBALo & 0xff0000) >> 16; 882 lba31 = (inLBALo & 0xff000000) >> 24; 883 lba39 = (inLBAHi & 0xff); 884 lba47 = (inLBAHi & 0xff00) >> 8; 885 886 setLBALow16( lba7 | (lba31 << 8) ); 887 setLBAMid16( lba15 | (lba39 << 8)); 888 setLBAHigh16( lba23 | (lba47 << 8)); 889 890 setSectorCount16( extendedCount ); 891 setCommand( extendedCommand ); 892 setDevice( mATALBASelect |( ((UInt8) inUnit) << 4)); // set the LBA bit and device select bits. The rest are reserved in extended addressing. 893 894} 895 896void 897IOExtendedLBA::getExtendedLBA( UInt32* outLBAHi, UInt32* outLBALo ) 898{ 899 900 901 902 *outLBALo = (getLBALow16() & 0xff) | ( (getLBAMid16() & 0xff) << 8) | ((getLBAHigh16() & 0xff) << 16) | ((getLBALow16() & 0xff00) << 16) ; 903 904 *outLBAHi = (getLBAHigh16() & 0xff00) | ((getLBAMid16() & 0xff00) >> 8) ; 905 906} 907 908void 909IOExtendedLBA::zeroData(void) 910{ 911 lbaLow = lbaMid = lbaHigh = sectorCount = features = device = command = 0; 912} 913 914 915