1/* 2 * Copyright (c) 2000-2014 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 bzero ( _packet.atapiCommandByte, sizeof ( _packet.atapiCommandByte ) ); 145 146 _packet.atapiPacketSize = 0; 147 148 getExtendedLBA()->zeroData(); 149 150} 151 152 153/*----------------------------------------------------------------------------- 154 * 155 * 156 *-----------------------------------------------------------------------------*/ 157void 158IOATACommand::setOpcode( ataOpcode inCode) 159{ 160 161 _opCode = inCode; 162 163} 164 165 166/*----------------------------------------------------------------------------- 167 * 168 * 169 *-----------------------------------------------------------------------------*/ 170 171void 172IOATACommand::setFlags( UInt32 inFlags) 173{ 174 175 _flags = inFlags; 176 177} 178 179 180/*----------------------------------------------------------------------------- 181 * 182 * 183 *-----------------------------------------------------------------------------*/ 184 185void 186IOATACommand::setUnit( ataUnitID inUnit) 187{ 188 189 _unit = inUnit; 190 191} 192 193 194/*----------------------------------------------------------------------------- 195 * 196 * 197 *-----------------------------------------------------------------------------*/ 198 199void 200IOATACommand::setTimeoutMS( UInt32 inMS) 201{ 202 203 _timeoutMS = inMS; 204 205} 206 207 208/*----------------------------------------------------------------------------- 209 * 210 * 211 *-----------------------------------------------------------------------------*/ 212 213void 214IOATACommand::setCallbackPtr (IOATACompletionFunction* inCompletion) 215{ 216 217 _callback = inCompletion; 218 219} 220 221 222/*----------------------------------------------------------------------------- 223 * 224 * 225 *-----------------------------------------------------------------------------*/ 226void 227IOATACommand::setRegMask( ataRegMask mask) 228{ 229 230 _regMask = mask; 231 232} 233 234/*----------------------------------------------------------------------------- 235 * 236 * 237 *-----------------------------------------------------------------------------*/ 238 239void 240IOATACommand::setBuffer ( IOMemoryDescriptor* inDesc) 241{ 242 243 _desc = inDesc; 244 245} 246 247 248 249/*----------------------------------------------------------------------------- 250 * 251 * 252 *-----------------------------------------------------------------------------*/ 253 254void 255IOATACommand::setPosition (IOByteCount fromPosition) 256{ 257 258 _position = fromPosition; 259 260} 261 262 263/*----------------------------------------------------------------------------- 264 * 265 * 266 *-----------------------------------------------------------------------------*/ 267 268void 269IOATACommand::setByteCount (IOByteCount numBytes) 270{ 271 272 _byteCount = numBytes; 273 274} 275 276/*----------------------------------------------------------------------------- 277 * 278 * 279 *-----------------------------------------------------------------------------*/ 280 281void 282IOATACommand::setTransferChunkSize (IOByteCount numBytes) 283{ 284 285 _logicalChunkSize = numBytes; 286 287} 288 289 290 291/*----------------------------------------------------------------------------- 292 * 293 * 294 *-----------------------------------------------------------------------------*/ 295 296void 297IOATACommand::setFeatures( UInt8 in) 298{ 299 300 _taskFile.taskFile.ataTFFeatures = in; 301 302} 303 304 305/*----------------------------------------------------------------------------- 306 * 307 * 308 *-----------------------------------------------------------------------------*/ 309 310UInt8 311IOATACommand::getErrorReg (void ) 312{ 313 314 return _taskFile.taskFile.ataTFFeatures; 315 316} 317 318 319/*----------------------------------------------------------------------------- 320 * 321 * 322 *-----------------------------------------------------------------------------*/ 323 324void 325IOATACommand::setSectorCount( UInt8 in) 326{ 327 328 _taskFile.taskFile.ataTFCount = in; 329 330} 331 332 333/*----------------------------------------------------------------------------- 334 * 335 * 336 *-----------------------------------------------------------------------------*/ 337 338UInt8 339IOATACommand::getSectorCount (void ) 340{ 341 342 return _taskFile.taskFile.ataTFCount; 343 344} 345 346 347/*----------------------------------------------------------------------------- 348 * 349 * 350 *-----------------------------------------------------------------------------*/ 351 352void 353IOATACommand::setSectorNumber( UInt8 in) 354{ 355 356 _taskFile.taskFile.ataTFSector = in; 357 358} 359 360 361/*----------------------------------------------------------------------------- 362 * 363 * 364 *-----------------------------------------------------------------------------*/ 365 366UInt8 367IOATACommand::getSectorNumber (void ) 368{ 369 370 return _taskFile.taskFile.ataTFSector; 371 372} 373 374 375/*----------------------------------------------------------------------------- 376 * 377 * 378 *-----------------------------------------------------------------------------*/ 379 380void 381IOATACommand::setCylLo ( UInt8 in) 382{ 383 384 _taskFile.taskFile.ataTFCylLo = in; 385 386} 387 388 389/*----------------------------------------------------------------------------- 390 * 391 * 392 *-----------------------------------------------------------------------------*/ 393 394 395UInt8 396IOATACommand::getCylLo (void ) 397{ 398 399 return _taskFile.taskFile.ataTFCylLo; 400 401} 402 403/*----------------------------------------------------------------------------- 404 * 405 * 406 *-----------------------------------------------------------------------------*/ 407void 408IOATACommand::setCylHi( UInt8 in) 409{ 410 411 _taskFile.taskFile.ataTFCylHigh = in; 412 413} 414 415 416/*----------------------------------------------------------------------------- 417 * 418 * 419 *-----------------------------------------------------------------------------*/ 420 421UInt8 422IOATACommand::getCylHi (void ) 423{ 424 425 return _taskFile.taskFile.ataTFCylHigh; 426 427} 428 429 430/*----------------------------------------------------------------------------- 431 * 432 * 433 *-----------------------------------------------------------------------------*/ 434 435void 436IOATACommand::setDevice_Head( UInt8 in) 437{ 438 439 _taskFile.taskFile.ataTFSDH = in; 440 441} 442 443 444/*----------------------------------------------------------------------------- 445 * 446 * 447 *-----------------------------------------------------------------------------*/ 448 449UInt8 450IOATACommand::getDevice_Head (void ) 451{ 452 453 return _taskFile.taskFile.ataTFSDH; 454 455} 456 457 458/*----------------------------------------------------------------------------- 459 * 460 * 461 *-----------------------------------------------------------------------------*/ 462 463void 464IOATACommand::setCommand ( UInt8 in) 465{ 466 467 _taskFile.taskFile.ataTFCommand = in; 468 469} 470 471 472/*----------------------------------------------------------------------------- 473 * 474 * 475 *-----------------------------------------------------------------------------*/ 476 477UInt8 478IOATACommand::getStatus (void ) 479{ 480 481 return _taskFile.taskFile.ataTFCommand; 482 483} 484 485 486/*----------------------------------------------------------------------------- 487 * 488 * 489 *-----------------------------------------------------------------------------*/ 490 491 492 493IOReturn 494IOATACommand::setPacketCommand( UInt16 packetSizeBytes, UInt8* packetBytes) 495{ 496// IOLog("ATACommand::setPacket size %d bytePtr = %lx\n", packetSizeBytes, packetBytes); 497 498 if( ( packetSizeBytes > 16 ) || (packetBytes == 0L)) 499 return -1; 500 501 UInt8* cmdBytes = (UInt8*) _packet.atapiCommandByte; 502 503 for( int i = 0; i < packetSizeBytes; i++ ) 504 { 505 cmdBytes[ i ] = packetBytes[ i ]; 506 } 507 508 _packet.atapiPacketSize = packetSizeBytes; 509 510 return kATANoErr; 511 512} 513 514 515 516/*----------------------------------------------------------------------------- 517 * 518 * 519 *-----------------------------------------------------------------------------*/ 520 521void 522IOATACommand::setDataReg ( UInt16 in) 523{ 524 525 _taskFile.ataDataRegister = in; 526 527} 528 529 530/*----------------------------------------------------------------------------- 531 * 532 * 533 *-----------------------------------------------------------------------------*/ 534 535 536UInt16 537IOATACommand::getDataReg (void ) 538{ 539 540 return _taskFile.ataDataRegister; 541 542} 543 544 545/*----------------------------------------------------------------------------- 546 * 547 * 548 *-----------------------------------------------------------------------------*/ 549 550 551 552void 553IOATACommand::setControl ( UInt8 in) 554{ 555 556 _taskFile.ataAltSDevCReg = in; 557 558} 559 560 561/*----------------------------------------------------------------------------- 562 * 563 * 564 *-----------------------------------------------------------------------------*/ 565 566 567UInt8 568IOATACommand::getAltStatus (void ) 569{ 570 571 return _taskFile.ataAltSDevCReg; 572 573} 574 575 576/*----------------------------------------------------------------------------- 577 * 578 * 579 *-----------------------------------------------------------------------------*/ 580 581 582 583 584IOReturn 585IOATACommand::getResult (void) 586{ 587 588 return _result; 589 590} 591 592 593/*----------------------------------------------------------------------------- 594 * 595 * 596 *-----------------------------------------------------------------------------*/ 597 598 599IOMemoryDescriptor* 600IOATACommand::getBuffer ( void ) 601{ 602 603 return _desc; 604 605} 606 607 608/*----------------------------------------------------------------------------- 609 * 610 * 611 *-----------------------------------------------------------------------------*/ 612 613 614IOByteCount 615IOATACommand::getActualTransfer ( void ) 616{ 617 618 return _actualByteCount; 619 620} 621 622 623/*----------------------------------------------------------------------------- 624 * 625 * 626 *-----------------------------------------------------------------------------*/ 627 628 629UInt8 630IOATACommand::getEndStatusReg (void) 631{ 632 633 return _status; 634 635} 636 637 638/*----------------------------------------------------------------------------- 639 * 640 * 641 *-----------------------------------------------------------------------------*/ 642 643 644 645UInt8 646IOATACommand::getEndErrorReg( void ) 647{ 648 649 return _errReg; 650 651} 652 653 654/*----------------------------------------------------------------------------- 655 * returns true if IOATAController is using the command. 656 * 657 *-----------------------------------------------------------------------------*/ 658 659bool 660IOATACommand::getCommandInUse( void ) 661{ 662 663 664 return _inUse; 665 666 667} 668 669/*----------------------------------------------------------------------------- 670 * 671 * 672 *-----------------------------------------------------------------------------*/ 673 674IOReturn 675IOATACommand::setLBA28( UInt32 lba, ataUnitID inUnit) 676{ 677 // param check the inputs 678 679 if( (lba & 0xF0000000) != 0x00000000 680 || !(inUnit == kATADevice0DeviceID || inUnit == kATADevice1DeviceID) ) 681 { 682 //param out of range 683 return -1; 684 } 685 686 687 setSectorNumber( (lba & 0xFF) ); //LBA 7:0 688 setCylLo( ((lba & 0xFF00) >> 8) ); // LBA 15:8 689 setCylHi( ((lba & 0x00FF0000) >> 16) ); // LBA 23:16 690 setDevice_Head(((lba & 0x0F000000) >> 24 ) | mATALBASelect |( ((UInt8) inUnit) << 4)); //LBA 27:24 691 692 return kATANoErr; 693 694} 695 696void 697IOATACommand::setEndResult(UInt8 inStatus, UInt8 endError ) 698{ 699 _status = inStatus; 700 _errReg = endError; 701} 702 703 704 705IOExtendedLBA* 706IOATACommand::getExtendedLBA(void) 707{ 708 709 return fExpansionData->extLBA; 710 711} 712 713 714 715//////////////////////////////////////////////////////////////////////// 716#pragma mark IOExtendedLBA 717#undef super 718 719#define super OSObject 720OSDefineMetaClassAndStructors( IOExtendedLBA, OSObject ) 721 722OSMetaClassDefineReservedUnused(IOExtendedLBA, 0) 723OSMetaClassDefineReservedUnused(IOExtendedLBA, 1) 724OSMetaClassDefineReservedUnused(IOExtendedLBA, 2); 725OSMetaClassDefineReservedUnused(IOExtendedLBA, 3); 726OSMetaClassDefineReservedUnused(IOExtendedLBA, 4); 727OSMetaClassDefineReservedUnused(IOExtendedLBA, 5); 728OSMetaClassDefineReservedUnused(IOExtendedLBA, 6); 729OSMetaClassDefineReservedUnused(IOExtendedLBA, 7); 730OSMetaClassDefineReservedUnused(IOExtendedLBA, 8); 731OSMetaClassDefineReservedUnused(IOExtendedLBA, 9); 732OSMetaClassDefineReservedUnused(IOExtendedLBA, 10); 733 734 735 736 737 738IOExtendedLBA* 739IOExtendedLBA::createIOExtendedLBA(IOATACommand* inOwner) 740{ 741 742 IOExtendedLBA* me = new IOExtendedLBA; 743 if( me == NULL) 744 { 745 return NULL; 746 } 747 748 me->owner = inOwner; 749 me->zeroData(); 750 751 return me; 752 753} 754 755 756 757void 758IOExtendedLBA::setLBALow16( UInt16 inLBALow) 759{ 760 lbaLow = inLBALow ; 761 762} 763 764 765UInt16 766IOExtendedLBA::getLBALow16 (void) 767{ 768 769 return lbaLow ; 770 771} 772 773void 774IOExtendedLBA::setLBAMid16 (UInt16 inLBAMid) 775{ 776 777 lbaMid = inLBAMid ; 778} 779 780 781UInt16 782IOExtendedLBA::getLBAMid16( void ) 783{ 784 785 return lbaMid; 786 787 788} 789 790void 791IOExtendedLBA::setLBAHigh16( UInt16 inLBAHigh ) 792{ 793 lbaHigh = inLBAHigh ; 794} 795 796 797UInt16 798IOExtendedLBA::getLBAHigh16( void ) 799{ 800 801 return lbaHigh; 802 803} 804 805void 806IOExtendedLBA::setSectorCount16( UInt16 inSectorCount ) 807{ 808 809 sectorCount = inSectorCount ; 810 811} 812 813UInt16 814IOExtendedLBA::getSectorCount16( void ) 815{ 816 return sectorCount; 817} 818 819void 820IOExtendedLBA::setFeatures16( UInt16 inFeatures ) 821{ 822 features = inFeatures; 823} 824 825UInt16 826IOExtendedLBA::getFeatures16( void ) 827{ 828 829 return features; 830 831} 832 833void 834IOExtendedLBA::setDevice( UInt8 inDevice ) 835{ 836 837 device = inDevice; 838 839} 840 841 842UInt8 843IOExtendedLBA::getDevice( void ) 844{ 845 846 847 return device; 848 849} 850 851void 852IOExtendedLBA::setCommand( UInt8 inCommand ) 853{ 854 855 856 command = inCommand; 857 858} 859 860 861UInt8 862IOExtendedLBA::getCommand( void ) 863{ 864 865 return command; 866} 867 868 869 870void 871IOExtendedLBA::setExtendedLBA( UInt32 inLBAHi, UInt32 inLBALo, ataUnitID inUnit, UInt16 extendedCount, UInt8 extendedCommand ) 872{ 873 874 UInt8 lba7, lba15, lba23, lba31, lba39, lba47; 875 lba7 = (inLBALo & 0xff); 876 lba15 = (inLBALo & 0xff00) >> 8; 877 lba23 = (inLBALo & 0xff0000) >> 16; 878 lba31 = (inLBALo & 0xff000000) >> 24; 879 lba39 = (inLBAHi & 0xff); 880 lba47 = (inLBAHi & 0xff00) >> 8; 881 882 setLBALow16( lba7 | (lba31 << 8) ); 883 setLBAMid16( lba15 | (lba39 << 8)); 884 setLBAHigh16( lba23 | (lba47 << 8)); 885 886 setSectorCount16( extendedCount ); 887 setCommand( extendedCommand ); 888 setDevice( mATALBASelect |( ((UInt8) inUnit) << 4)); // set the LBA bit and device select bits. The rest are reserved in extended addressing. 889 890} 891 892void 893IOExtendedLBA::getExtendedLBA( UInt32* outLBAHi, UInt32* outLBALo ) 894{ 895 896 897 898 *outLBALo = (getLBALow16() & 0xff) | ( (getLBAMid16() & 0xff) << 8) | ((getLBAHigh16() & 0xff) << 16) | ((getLBALow16() & 0xff00) << 16) ; 899 900 *outLBAHi = (getLBAHigh16() & 0xff00) | ((getLBAMid16() & 0xff00) >> 8) ; 901 902} 903 904void 905IOExtendedLBA::zeroData(void) 906{ 907 lbaLow = lbaMid = lbaHigh = sectorCount = features = device = command = 0; 908} 909 910 911