Annotation of XNU/iokit/Families/IOATABus/IOATADevice.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, 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:  * IOATADevice.cpp
        !            25:  *
        !            26:  */
        !            27: 
        !            28: #include <IOKit/IOSyncer.h>
        !            29: #include <IOKit/ata/IOATA.h>
        !            30: #include <IOKit/ata/IOATAController.h>
        !            31: #include "ATAPrivate.h"
        !            32: 
        !            33: #undef  super
        !            34: #define super IOService
        !            35: 
        !            36: OSDefineMetaClassAndStructors( IOATADevice, IOService );
        !            37: 
        !            38: extern EndianTable             AppleIdentifyEndianTable[];
        !            39: 
        !            40: extern UInt32                  AppleNumPIOModes;
        !            41: extern ATAModeTable            ApplePIOModes[];
        !            42: extern UInt32                  AppleNumDMAModes;
        !            43: extern ATAModeTable            AppleDMAModes[];
        !            44: extern UInt32                  AppleNumUltraModes;
        !            45: extern ATAModeTable            AppleUltraModes[];
        !            46: 
        !            47: /*
        !            48:  *
        !            49:  *
        !            50:  */
        !            51: bool IOATADevice::probeDevice()
        !            52: {
        !            53:     OSDictionary               *propTable = 0;
        !            54: 
        !            55:     if ( open( this ) != true )
        !            56:     {
        !            57:         goto probeDevice_error;
        !            58:     }
        !            59: 
        !            60:     if ( doIdentify( (void **)&identifyData ) != ataReturnNoError )
        !            61:     {
        !            62:         goto probeDevice_error;
        !            63:     }
        !            64: 
        !            65:     if ( deviceType == ataDeviceATA )
        !            66:     {
        !            67:         doSpinUp();
        !            68:     }
        !            69: 
        !            70:     else if ( deviceType == ataDeviceATAPI )
        !            71:     {
        !            72:         atapiPktInt = ((identifyData->generalConfiguration & atapiPktProtocolIntDRQ) != 0);
        !            73:       
        !            74:         if ( doInquiry( (void **)&inquiryData ) != ataReturnNoError )
        !            75:         {
        !            76:             goto probeDevice_error;
        !            77:         }
        !            78: 
        !            79:         reqSenseCmd = allocCommand();
        !            80:     }      
        !            81: 
        !            82:     if ( getATATimings() != true )
        !            83:     {
        !            84:         goto probeDevice_error;
        !            85:     }
        !            86:     
        !            87:     propTable = createProperties();
        !            88:     if ( !propTable )
        !            89:     {
        !            90:         goto probeDevice_error;
        !            91:     }
        !            92:     
        !            93:     setPropertyTable( propTable );
        !            94: 
        !            95:     propTable->release();
        !            96:  
        !            97:     close( this );
        !            98: 
        !            99:     return true; 
        !           100: 
        !           101: probeDevice_error: ;
        !           102:     close( this );
        !           103:     return false;
        !           104: }
        !           105: 
        !           106: /*
        !           107:  *
        !           108:  *
        !           109:  *
        !           110:  */
        !           111: ATADeviceType IOATADevice::probeDeviceType()
        !           112: {
        !           113:     ATATaskfile         taskfile;
        !           114:     ATAResults          results;
        !           115: 
        !           116:     bzero( (void *)&taskfile, sizeof(taskfile) );
        !           117: 
        !           118:     taskfile.protocol     = ataProtocolSetRegs;
        !           119:     taskfile.regmask      = ATARegtoMask(ataRegDriveHead);  
        !           120: 
        !           121:     taskfile.resultmask   = ATARegtoMask(ataRegSectorCount)
        !           122:                           | ATARegtoMask(ataRegSectorNumber)
        !           123:                           | ATARegtoMask(ataRegCylinderLow)
        !           124:                           | ATARegtoMask(ataRegCylinderHigh)
        !           125:                           | ATARegtoMask(ataRegStatus);
        !           126: 
        !           127:     taskfile.ataRegs[ataRegDriveHead] = ataModeLBA | (getUnit() << 4);
        !           128: 
        !           129:     utilCmd->setTaskfile( &taskfile );
        !           130:     utilCmd->execute();
        !           131: 
        !           132:     if ( utilCmd->getResults( &results ) != ataReturnNoError )     
        !           133:     {
        !           134:         return (deviceType = ataDeviceNone);
        !           135:     }
        !           136:  
        !           137:     if ( results.ataRegs[ataRegSectorCount] == ataSignatureSectorCount
        !           138:           && results.ataRegs[ataRegSectorNumber] == ataSignatureSectorNumber
        !           139:              && results.ataRegs[ataRegCylinderLow] == ataSignatureCylinderLow
        !           140:                 && results.ataRegs[ataRegCylinderHigh] == ataSignatureCylinderHigh )
        !           141:     { 
        !           142:         if ( !(results.ataRegs[ataRegStatus] & ataStatusBSY)  
        !           143:                  && (results.ataRegs[ataRegStatus] & ataStatusDRDY) )
        !           144:         {
        !           145:             return (deviceType = ataDeviceATA);
        !           146:         }
        !           147:     }
        !           148:             
        !           149:     if ( results.ataRegs[ataRegCylinderLow] == atapiSignatureCylinderLow
        !           150:                 && results.ataRegs[ataRegCylinderHigh] == atapiSignatureCylinderHigh )
        !           151:     {
        !           152:         return (deviceType = ataDeviceATAPI);
        !           153:     }       
        !           154:   
        !           155:     return (deviceType = ataDeviceNone);
        !           156: }
        !           157: 
        !           158: 
        !           159: /*
        !           160:  *
        !           161:  *
        !           162:  *
        !           163:  */
        !           164: ATAReturnCode IOATADevice::doSpinUp()
        !           165: {
        !           166:     void               *buffer = NULL;
        !           167:     ATAReturnCode      rc;
        !           168: 
        !           169:     rc = doSectorCommand( ataCommandReadSector, 0, 1, &buffer );
        !           170: 
        !           171:     if ( rc != ataReturnNoError )
        !           172:     {
        !           173:         return rc;
        !           174:     }
        !           175: 
        !           176:     IOFree( buffer, 512 );
        !           177: 
        !           178:     return rc ; 
        !           179: }    
        !           180: 
        !           181: /*
        !           182:  *
        !           183:  *
        !           184:  *
        !           185:  */
        !           186: ATAReturnCode IOATADevice::doIdentify( void **dataPtr )
        !           187: {   
        !           188:     ATACommand         ataCmd;
        !           189:     ATAReturnCode      rc;
        !           190:  
        !           191:     ataCmd = (deviceType == ataDeviceATA) ? ataCommandIdentify : atapiCommandIdentify;
        !           192: 
        !           193:     rc = doSectorCommand( ataCmd, 0, 1, dataPtr );
        !           194: 
        !           195:     if ( rc != ataReturnNoError )
        !           196:     {
        !           197:         return rc;
        !           198:     }
        !           199:  
        !           200:     endianConvertData( *dataPtr, AppleIdentifyEndianTable );
        !           201: 
        !           202:     return rc;
        !           203: }
        !           204: 
        !           205: 
        !           206: 
        !           207: /*
        !           208:  *
        !           209:  *
        !           210:  *
        !           211:  */
        !           212: ATAReturnCode IOATADevice::doSectorCommand( ATACommand ataCmd, UInt32 ataLBA, UInt32 ataCount, void **dataPtr )
        !           213: {
        !           214:     ATATaskfile                        taskfile;
        !           215:     ATAResults                 result;
        !           216:     IOMemoryDescriptor         *desc;
        !           217:     UInt32                     size;
        !           218:     void                       *data;
        !           219:     UInt32                     i;
        !           220:     ATAReturnCode              rc;
        !           221: 
        !           222:     *dataPtr = NULL;
        !           223: 
        !           224:     size = ataCount * 512;
        !           225: 
        !           226:     if ( !(data = (void *)IOMalloc(size)) )
        !           227:     {
        !           228:         return ataReturnNoResource;
        !           229:     }
        !           230: 
        !           231:     bzero( &taskfile, sizeof(taskfile) );
        !           232: 
        !           233:     desc = IOMemoryDescriptor::withAddress( data, size, kIODirectionIn );
        !           234:     if ( desc == NULL )
        !           235:     {
        !           236:         rc = ataReturnNoResource;
        !           237:         goto doSectorCommand_error;
        !           238:     }
        !           239: 
        !           240:     
        !           241:     taskfile.protocol                  = ataProtocolPIO;
        !           242:     taskfile.regmask                   = ATARegtoMask(ataRegDriveHead)
        !           243:                                        | ATARegtoMask(ataRegSectorCount)
        !           244:                                        | ATARegtoMask(ataRegSectorNumber)
        !           245:                                        | ATARegtoMask(ataRegCylinderLow)
        !           246:                                        | ATARegtoMask(ataRegCylinderHigh)
        !           247:                                        | ATARegtoMask(ataRegFeatures)
        !           248:                                        | ATARegtoMask(ataRegCommand);
        !           249: 
        !           250: 
        !           251:     taskfile.resultmask                        = ATARegtoMask(ataRegError) 
        !           252:                                         | ATARegtoMask(ataRegStatus);
        !           253: 
        !           254:     taskfile.ataRegs[ataRegSectorCount]   = ataCount;
        !           255:     taskfile.ataRegs[ataRegSectorNumber]  = ataLBA         & 0xff;
        !           256:     taskfile.ataRegs[ataRegCylinderLow]   = (ataLBA >> 8)  & 0xff;
        !           257:     taskfile.ataRegs[ataRegCylinderHigh]  = (ataLBA >> 16) & 0xff;
        !           258:     taskfile.ataRegs[ataRegDriveHead]     = (ataLBA >> 24) & 0x0f;
        !           259: 
        !           260:     taskfile.ataRegs[ataRegDriveHead]   |= ataModeLBA | (getUnit() << 4);
        !           261:     taskfile.ataRegs[ataRegCommand]      = ataCmd;
        !           262: 
        !           263:     for ( i = 0; i < 2; i++ )
        !           264:     { 
        !           265:         utilCmd->setTimeout( 25000 );
        !           266:         utilCmd->setTaskfile( &taskfile );
        !           267:         utilCmd->setPointers( desc, size, false ); 
        !           268:         submitCommand( utilCmd );
        !           269:     
        !           270:         rc  = utilCmd->getResults( &result );
        !           271:         if ( rc == ataReturnNoError )
        !           272:         {
        !           273:             break;
        !           274:         }
        !           275:     }
        !           276: 
        !           277: 
        !           278: doSectorCommand_error: ;
        !           279: 
        !           280:     desc->release();
        !           281: 
        !           282:     if ( rc != ataReturnNoError )
        !           283:     {
        !           284:         IOFree( data, size );
        !           285:         return result.returnCode;
        !           286:     }
        !           287: 
        !           288:     *dataPtr = data;
        !           289: 
        !           290:     return ataReturnNoError;
        !           291: }
        !           292: 
        !           293: 
        !           294: /*
        !           295:  *
        !           296:  *
        !           297:  */
        !           298: ATAReturnCode IOATADevice::doInquiry( void **dataPtr )
        !           299: {
        !           300:     ATATaskfile                        taskfile;
        !           301:     ATAPICmd                   atapiCmd;
        !           302:     ATAResults                 result;
        !           303:     void                        *data;
        !           304:     IOMemoryDescriptor         *desc;
        !           305:     UInt32                     size = sizeof(ATAPIInquiry);
        !           306: 
        !           307:     *dataPtr = 0;
        !           308: 
        !           309:     if ( !(data = (void *)IOMalloc(size)) )
        !           310:     {
        !           311:         return ataReturnNoResource;;
        !           312:     }
        !           313: 
        !           314:     bzero( &taskfile, sizeof(taskfile) );
        !           315:     bzero( &atapiCmd, sizeof(atapiCmd) );
        !           316: 
        !           317:     desc = IOMemoryDescriptor::withAddress( data, size, kIODirectionIn );
        !           318:     
        !           319:     taskfile.protocol                  = atapiProtocolPIO;
        !           320:     taskfile.regmask                   = ATARegtoMask(atapiRegDeviceSelect) 
        !           321:                                        | ATARegtoMask(atapiRegCommand)
        !           322:                                         | ATARegtoMask(atapiRegByteCountLow)
        !           323:                                         | ATARegtoMask(atapiRegByteCountHigh)
        !           324:                                         | ATARegtoMask(atapiRegFeatures);
        !           325:     taskfile.ataRegs[atapiRegDeviceSelect]  = ataModeLBA | (getUnit() << 4);
        !           326:     taskfile.ataRegs[atapiRegCommand]       = atapiCommandPacket;
        !           327:     taskfile.ataRegs[atapiRegFeatures]      = 0;
        !           328:     taskfile.ataRegs[atapiRegByteCountLow]  = 0xfe;
        !           329:     taskfile.ataRegs[atapiRegByteCountHigh] = 0xff;
        !           330: 
        !           331:     atapiCmd.cdbLength = 12;  // Fix 16 byte cmdpkts??
        !           332:     atapiCmd.cdb[0]    = 0x12;
        !           333:     atapiCmd.cdb[4]    = size;
        !           334: 
        !           335:     utilCmd->setATAPICmd( &atapiCmd, 0, 0 );
        !           336:     utilCmd->setTaskfile( &taskfile );
        !           337:     utilCmd->setPointers( desc, size, false );
        !           338:     utilCmd->setTimeout( 5000 ); 
        !           339:     submitCommand( utilCmd );
        !           340:  
        !           341:     if ( utilCmd->getResults(&result) == ataReturnNoError )
        !           342:     {
        !           343:         *dataPtr = data;
        !           344:     }
        !           345:     else
        !           346:     {
        !           347:         IOFree( data, size );
        !           348:     }
        !           349: 
        !           350:     desc->release();
        !           351: 
        !           352:     return result.returnCode;
        !           353: }
        !           354: 
        !           355: /*
        !           356:  *
        !           357:  *
        !           358:  */
        !           359: bool IOATADevice::getDeviceCapacity( UInt32 *blockMax, UInt32 *blockSize )
        !           360: {
        !           361:     UInt32             i;
        !           362:     UInt32             data[2];
        !           363: 
        !           364:     if ( deviceType == ataDeviceATA )
        !           365:     {
        !           366:         if ( identifyData != NULL )
        !           367:         {
        !           368:             *blockMax = *(UInt32 *)identifyData->userAddressableSectors - 1;
        !           369:             *blockSize  = 512;
        !           370:             return true;
        !           371:         }
        !           372:     }
        !           373:     
        !           374:     if ( deviceType == ataDeviceATAPI )
        !           375:     {
        !           376:         for ( i=0; i < 8; i++ )
        !           377:         {
        !           378:             if ( doTestUnitReady() == ataReturnNoError )
        !           379:             {
        !           380:                 break;
        !           381:             }
        !           382:         }
        !           383: 
        !           384:         if ( doReadCapacity( data ) == ataReturnNoError )
        !           385:         {
        !           386:             *blockMax   = OSSwapBigToHostInt32( data[0] );
        !           387:             *blockSize  = OSSwapBigToHostInt32( data[1] );
        !           388:             return true;
        !           389:         }      
        !           390:     }
        !           391: 
        !           392:     return false;
        !           393: }
        !           394: 
        !           395: 
        !           396: ATAReturnCode IOATADevice::doTestUnitReady()
        !           397: {
        !           398:     ATATaskfile                        taskfile;
        !           399:     ATAPICmd                   atapiCmd;
        !           400:     ATAResults                 result;
        !           401: 
        !           402:     bzero( &taskfile, sizeof(taskfile) );
        !           403:     bzero( &atapiCmd, sizeof(atapiCmd) );
        !           404: 
        !           405:     taskfile.protocol                  = atapiProtocolPIO;
        !           406: 
        !           407:     taskfile.regmask                   = ATARegtoMask(atapiRegDeviceSelect) 
        !           408:                                        | ATARegtoMask(atapiRegCommand)
        !           409:                                         | ATARegtoMask(atapiRegByteCountLow)
        !           410:                                         | ATARegtoMask(atapiRegByteCountHigh)
        !           411:                                         | ATARegtoMask(atapiRegFeatures);
        !           412: 
        !           413:     taskfile.ataRegs[atapiRegDeviceSelect]  = ataModeLBA | (getUnit() << 4);
        !           414:     taskfile.ataRegs[atapiRegCommand]       = atapiCommandPacket;
        !           415:     taskfile.ataRegs[atapiRegFeatures]      = 0;
        !           416:     taskfile.ataRegs[atapiRegByteCountLow]  = 0xfe;
        !           417:     taskfile.ataRegs[atapiRegByteCountHigh] = 0xff;
        !           418: 
        !           419:     atapiCmd.cdbLength = 12;  // Fix 16 byte cmdpkts??
        !           420:     atapiCmd.cdb[0]    = 0x00;
        !           421: 
        !           422:     utilCmd->setATAPICmd( &atapiCmd );
        !           423:     utilCmd->setTaskfile( &taskfile );
        !           424:     utilCmd->setPointers( (IOMemoryDescriptor *)NULL, 0, false ); 
        !           425:     utilCmd->setTimeout( 5000 );
        !           426:     submitCommand( utilCmd );
        !           427:     utilCmd->getResults(&result);
        !           428:  
        !           429:     return result.returnCode;
        !           430: }
        !           431: 
        !           432: 
        !           433: /*
        !           434:  *
        !           435:  *
        !           436:  */
        !           437: ATAReturnCode IOATADevice::doReadCapacity( void *data )
        !           438: {
        !           439:     ATATaskfile                        taskfile;
        !           440:     ATAPICmd                   atapiCmd;
        !           441:     ATAResults                 result;
        !           442:     IOMemoryDescriptor         *dataDesc;
        !           443:     UInt32                     size = 8;
        !           444: 
        !           445: 
        !           446:     bzero( &taskfile, sizeof(taskfile) );
        !           447:     bzero( &atapiCmd, sizeof(atapiCmd) );
        !           448: 
        !           449:     dataDesc = IOMemoryDescriptor::withAddress( data, size, kIODirectionIn );
        !           450:     if ( dataDesc == NULL )
        !           451:     {
        !           452:         return ataReturnNoResource;
        !           453:     }
        !           454:     
        !           455:     taskfile.protocol                  = atapiProtocolPIO;
        !           456:     taskfile.regmask                   = ATARegtoMask(atapiRegDeviceSelect) 
        !           457:                                        | ATARegtoMask(atapiRegCommand)
        !           458:                                         | ATARegtoMask(atapiRegByteCountLow)
        !           459:                                         | ATARegtoMask(atapiRegByteCountHigh)
        !           460:                                         | ATARegtoMask(atapiRegFeatures);
        !           461:     taskfile.ataRegs[atapiRegDeviceSelect]  = ataModeLBA | (getUnit() << 4);
        !           462:     taskfile.ataRegs[atapiRegCommand]       = atapiCommandPacket;
        !           463:     taskfile.ataRegs[atapiRegFeatures]      = 0;
        !           464:     taskfile.ataRegs[atapiRegByteCountLow]  = 0xfe;
        !           465:     taskfile.ataRegs[atapiRegByteCountHigh] = 0xff;
        !           466: 
        !           467:     atapiCmd.cdbLength = 12;  // Fix 16 byte cmdpkts??
        !           468:     atapiCmd.cdb[0]    = 0x25;
        !           469: 
        !           470:     utilCmd->setATAPICmd( &atapiCmd );
        !           471:     utilCmd->setTaskfile( &taskfile );
        !           472:     utilCmd->setPointers( dataDesc, size, false ); 
        !           473:     utilCmd->setTimeout( 5000 );
        !           474:     submitCommand( utilCmd );
        !           475:     
        !           476:     utilCmd->getResults(&result);
        !           477: 
        !           478:     dataDesc->release();
        !           479:  
        !           480:     return result.returnCode;
        !           481: }
        !           482: 
        !           483: 
        !           484: /*
        !           485:  *
        !           486:  *
        !           487:  */
        !           488: IOATACommand *IOATADevice::makeRequestSense( IOATACommand *origCmd )
        !           489: {
        !           490:     ATATaskfile                        taskfile;
        !           491:     ATAPICmd                   atapiCmd;
        !           492: 
        !           493:     if ( reqSenseCmd == NULL )
        !           494:     {
        !           495:         return NULL;
        !           496:     }
        !           497: 
        !           498:     bzero( &taskfile, sizeof(taskfile) );
        !           499:     bzero( &atapiCmd, sizeof(atapiCmd) );
        !           500: 
        !           501:     taskfile.protocol                  = atapiProtocolPIO;
        !           502:  
        !           503:     taskfile.regmask                   = ATARegtoMask(atapiRegDeviceSelect) 
        !           504:                                        | ATARegtoMask(atapiRegCommand)
        !           505:                                         | ATARegtoMask(atapiRegByteCountLow)
        !           506:                                         | ATARegtoMask(atapiRegByteCountHigh)
        !           507:                                         | ATARegtoMask(atapiRegFeatures);
        !           508: 
        !           509:     taskfile.ataRegs[atapiRegDeviceSelect]  = ataModeLBA | (getUnit() << 4);
        !           510:     taskfile.ataRegs[atapiRegCommand]       = atapiCommandPacket;
        !           511:     taskfile.ataRegs[atapiRegFeatures]      = 0;
        !           512:     taskfile.ataRegs[atapiRegByteCountLow]  = origCmd->senseLength & 0xff;
        !           513:     taskfile.ataRegs[atapiRegByteCountHigh] = 0;
        !           514: 
        !           515:     atapiCmd.cdbLength   = 12;  // Fix 16 byte cmdpkts??
        !           516:     atapiCmd.cdb[0]      = 0x03;
        !           517:     atapiCmd.cdb[4]      = origCmd->senseLength;
        !           518: 
        !           519:     reqSenseCmd->setATAPICmd( &atapiCmd, 0, 0 );
        !           520:     reqSenseCmd->setTaskfile( &taskfile );
        !           521:     reqSenseCmd->setPointers( origCmd->senseData, origCmd->senseLength, false ); 
        !           522: 
        !           523:     return reqSenseCmd;
        !           524: }
        !           525: 
        !           526: /*
        !           527:  *
        !           528:  *
        !           529:  */
        !           530: bool IOATADevice::completeRequestSense( IOATACommand *origCmd, IOATACommand  *reqSense )
        !           531: {
        !           532:     ATAResults         result;
        !           533: 
        !           534:     if ( reqSense->getResults(&result) != ataReturnNoError )
        !           535:     {
        !           536:         return false;
        !           537:     }
        !           538:     
        !           539:     origCmd->results.senseLength = result.bytesTransferred;
        !           540:     return true;
        !           541: }
        !           542: 
        !           543: 
        !           544: /*
        !           545:  *
        !           546:  *
        !           547:  */ 
        !           548: bool IOATADevice::getTimingsSupported( ATATimingProtocol *timingsSupported )
        !           549: {
        !           550:     UInt32                     i;
        !           551: 
        !           552:     *(UInt32 *)timingsSupported = 0;
        !           553:  
        !           554:     for ( i=0; i < numTimings; i++ )
        !           555:     {
        !           556:         *(UInt32 *) timingsSupported |= (UInt32)ataTimings[i].timingProtocol; 
        !           557:     }
        !           558: 
        !           559:     return true;
        !           560: }
        !           561: 
        !           562: /*
        !           563:  *
        !           564:  *
        !           565:  */ 
        !           566: bool IOATADevice::getTiming( ATATimingProtocol *timingProtocol, ATATiming *timing )
        !           567: {
        !           568:     UInt32                     i;
        !           569: 
        !           570:     for ( i=0; i < numTimings; i++ )
        !           571:     {
        !           572:         if ( ataTimings[i].timingProtocol == *timingProtocol )
        !           573:         {
        !           574:             bcopy( &ataTimings[i], timing, sizeof(ATATiming) );
        !           575:             return true;
        !           576:         }
        !           577:     }
        !           578: 
        !           579:     return false;
        !           580: }
        !           581: 
        !           582: 
        !           583: /*
        !           584:  *
        !           585:  *
        !           586:  */ 
        !           587: bool IOATADevice::selectTiming( ATATimingProtocol timingProtocol )
        !           588: {
        !           589:     ATATaskfile                        taskfile;
        !           590:     ATAResults                 result;
        !           591:     bool                       rc = false;
        !           592:     UInt32                     i;
        !           593: 
        !           594:     for ( i=0; i < numTimings; i++ )
        !           595:     {
        !           596:         if ( ataTimings[i].timingProtocol == timingProtocol )
        !           597:         {
        !           598:             rc = true;
        !           599:             break;
        !           600:         }
        !           601:     }
        !           602: 
        !           603:     if ( rc == false ) return rc;
        !           604:     
        !           605:     if ( controller->selectTiming( getUnit(), timingProtocol ) == false )
        !           606:     {
        !           607:         return false;
        !           608:     }
        !           609:      
        !           610:     bzero( &taskfile, sizeof(taskfile) );
        !           611:     bzero( &result, sizeof(result) );
        !           612: 
        !           613:     taskfile.protocol                  = ataProtocolPIO;
        !           614:     taskfile.regmask                   = ATARegtoMask(ataRegFeatures) 
        !           615:                                        | ATARegtoMask(ataRegSectorCount) 
        !           616:                                        | ATARegtoMask(ataRegDriveHead) 
        !           617:                                        | ATARegtoMask(ataRegCommand);
        !           618:  
        !           619:     taskfile.ataRegs[ataRegSectorCount]  = ataTimings[i].featureSetting;
        !           620:     taskfile.ataRegs[ataRegFeatures]     = ataFeatureTransferMode;
        !           621:     taskfile.ataRegs[ataRegDriveHead]    = ataModeLBA | (getUnit() << 4);
        !           622:     taskfile.ataRegs[ataRegCommand]      = ataCommandSetFeatures;
        !           623: 
        !           624:     utilCmd->setTaskfile( &taskfile );
        !           625:     utilCmd->setPointers( (IOMemoryDescriptor *)NULL, 0, false );
        !           626:     utilCmd->setTimeout( 5000 );
        !           627:     utilCmd->setCallback(); 
        !           628:     submitCommand( utilCmd );
        !           629:  
        !           630:     if ( utilCmd->getResults( &result ) != ataReturnNoError )
        !           631:     {
        !           632:         rc = false;
        !           633:     }
        !           634:     return rc;
        !           635: }
        !           636:     
        !           637: 
        !           638: /*
        !           639:  *
        !           640:  *
        !           641:  */ 
        !           642: bool IOATADevice::getATATimings()
        !           643: {
        !           644:     int                        i, n;
        !           645:     UInt32             mode            = 0;
        !           646:     UInt32                     cycleTime       = 0;
        !           647: 
        !           648:     ATATiming          *pTimings;
        !           649: 
        !           650:     pTimings = ataTimings;
        !           651: 
        !           652:     /*
        !           653:      *  PIO Cycle timing......  
        !           654:      *
        !           655:      *  1. Try to match Word 51 (pioCycleTime) with cycle timings
        !           656:      *     in our pioModes table to get mode/CycleTime. (Valid for Modes 0-2)
        !           657:      *  2. If Words 64-68 are supported and Mode 3 or 4 supported check, 
        !           658:      *     update CycleTime with Word 68 (CycleTimeWithIORDY).
        !           659:      */
        !           660: 
        !           661:     cycleTime = identifyData->pioMode;
        !           662: 
        !           663:     if ( cycleTime > 2 )
        !           664:     {
        !           665:         for ( i=AppleNumPIOModes-1; i != -1; i-- )
        !           666:         {
        !           667:             if ( cycleTime <= ApplePIOModes[i].minDataCycle )
        !           668:             {
        !           669:                 mode = i;
        !           670:                 break;
        !           671:             }
        !           672:          }
        !           673: 
        !           674:          if ( i == -1 )
        !           675:          {
        !           676:              cycleTime = ApplePIOModes[mode].minDataCycle;
        !           677:          }
        !           678:     }
        !           679:     else
        !           680:     {
        !           681:         mode      = cycleTime;
        !           682:         cycleTime = ApplePIOModes[mode].minDataCycle;
        !           683:     }
        !           684: 
        !           685: 
        !           686:     if ( identifyData->validFields & identifyWords_64to70_Valid ) 
        !           687:     {
        !           688:        if (identifyData->advancedPIOModes & advPIOModes_Mode4_Supported)
        !           689:             mode = 4;
        !           690:        else if (identifyData->advancedPIOModes & advPIOModes_Mode3_Supported)
        !           691:             mode = 3;
        !           692: 
        !           693:         if ( (mode >= 3) && identifyData->minPIOCyclcTimeIORDY )
        !           694:         {
        !           695:             cycleTime = identifyData->minPIOCyclcTimeIORDY;
        !           696:         }
        !           697:     }
        !           698:     
        !           699:     pTimings->timingProtocol = ataTimingPIO;
        !           700:     pTimings->mode           = mode;
        !           701:     pTimings->featureSetting  = mode | ataTransferModePIOwFC;
        !           702:     pTimings->minDataCycle    = cycleTime;
        !           703:     pTimings->minDataAccess   = ApplePIOModes[mode].minDataAccess;
        !           704: 
        !           705:     if ( controller->calculateTiming( getUnit(), pTimings ) == false )
        !           706:     {
        !           707:         IOLog("IOATADevice::%s() - Controller driver must support PIO timings\n\r", __FUNCTION__);
        !           708:         return false;
        !           709:     }
        !           710: 
        !           711:     pTimings++;
        !           712:     numTimings++;
        !           713: 
        !           714:     /* 
        !           715:      *  Multiword DMA timing.....
        !           716:      *
        !           717:      *  1. Check Word 63(7:0) (Multiword DMA Modes Supported). Lookup
        !           718:      *     CycleTime for highest mode we support.
        !           719:      *  2. If Words 64-68 supported, update CycleTime from Word 66
        !           720:      *     (RecommendedMultiWordCycleTime) if specified.
        !           721:      */                                                                
        !           722: 
        !           723:     n = identifyData->dmaModes & dmaModes_Supported;
        !           724:     if ( n )
        !           725:     {
        !           726:         for ( i=0; n; i++, n>>=1 )
        !           727:           ;
        !           728: 
        !           729:         mode = i - 1;
        !           730:         if ( mode > AppleNumDMAModes-1 )
        !           731:         {
        !           732:             mode = AppleNumDMAModes-1;
        !           733:         }
        !           734:         cycleTime = AppleDMAModes[mode].minDataCycle;
        !           735: 
        !           736:         if (identifyData->validFields & identifyWords_64to70_Valid) 
        !           737:         {
        !           738:             if ( identifyData->recDMACycleTime )
        !           739:             {
        !           740:                 cycleTime = identifyData->recDMACycleTime;
        !           741:             }
        !           742:         }
        !           743:         pTimings->timingProtocol = ataTimingDMA;
        !           744:         pTimings->mode          = mode;
        !           745:         pTimings->featureSetting = mode | ataTransferModeDMA;
        !           746:         pTimings->minDataCycle   = cycleTime;
        !           747:         pTimings->minDataAccess  = AppleDMAModes[mode].minDataAccess;
        !           748: 
        !           749:         if ( controller->calculateTiming( getUnit(), pTimings ) == true )
        !           750:         {
        !           751:             pTimings++;
        !           752:             numTimings++;
        !           753:         }
        !           754:     }
        !           755: 
        !           756:     /* 
        !           757:      *  Ultra DMA timing.....
        !           758:      *
        !           759:      */                                                                
        !           760:     if ( identifyData->validFields & identifyWords_88to88_Valid ) 
        !           761:     {
        !           762:         n = identifyData->ultraDMAModes & ultraDMAModes_Supported;
        !           763:         if ( n )
        !           764:         {
        !           765:             for ( i=0; n; i++, n>>=1 )
        !           766:               ;
        !           767: 
        !           768:             mode = i - 1;
        !           769:             if ( mode > AppleNumUltraModes-1 )
        !           770:             {
        !           771:                 mode = AppleNumUltraModes-1;
        !           772:             }
        !           773: 
        !           774:             /*
        !           775:              * Build a separate timing entry for Ultra DMA/33 (mode <= 2) and Ultra DMA/66
        !           776:              */
        !           777:             while ( 1 )
        !           778:             { 
        !           779:                 cycleTime = AppleUltraModes[mode].minDataCycle;
        !           780: 
        !           781:                 pTimings->timingProtocol = (mode > 2) ? ataTimingUltraDMA66 : ataTimingUltraDMA33;
        !           782:                 pTimings->mode          = mode;
        !           783:                 pTimings->featureSetting = mode | ataTransferModeUltraDMA33;
        !           784:                 pTimings->minDataCycle   = cycleTime;
        !           785:                 pTimings->minDataAccess  = AppleUltraModes[mode].minDataAccess;
        !           786:   
        !           787:                 if ( controller->calculateTiming( getUnit(), pTimings ) == true )
        !           788:                 {
        !           789:                     pTimings++;
        !           790:                     numTimings++;
        !           791:                 }
        !           792:                 
        !           793:                 if ( mode < 3 ) break; 
        !           794:            
        !           795:                 mode = 2;
        !           796:             }
        !           797:         }
        !           798:     }
        !           799: 
        !           800:     return true;            
        !           801: }
        !           802: 
        !           803: /*
        !           804:  *
        !           805:  *
        !           806:  */
        !           807: void IOATADevice::submitCommand( IOATACommand *cmd )
        !           808: {
        !           809:     cmd->execute();
        !           810:     IOWriteLock( resetSem );
        !           811:     IORWUnlock( resetSem );
        !           812: }
        !           813: 
        !           814: /*
        !           815:  *
        !           816:  *
        !           817:  */
        !           818: bool IOATADevice::executeCommand( IOATACommand *cmd )
        !           819: {
        !           820:     bool               isSync;
        !           821: 
        !           822:     isSync = !(cmd->flags & IOATACommand::atacmdCallbackValid);
        !           823: 
        !           824:     if ( isSync )
        !           825:     {
        !           826:         cmd->completionInfo.sync.syncer = IOSyncer::create();
        !           827:     }
        !           828: 
        !           829:     cmd->deviceQueue = deviceQueue;
        !           830: 
        !           831:     controller->executeCommand( cmd );
        !           832:     
        !           833:     if ( isSync )
        !           834:     {
        !           835:         cmd->completionInfo.sync.syncer->wait();
        !           836:     }
        !           837: 
        !           838:     return true;
        !           839: }
        !           840: 
        !           841: /*
        !           842:  *
        !           843:  *
        !           844:  */
        !           845: void IOATADevice::completeCommand( IOATACommand *cmd )
        !           846: {
        !           847:     ATATaskfile                tf;
        !           848:     ATAResults         res;
        !           849:     UInt32             i;
        !           850: 
        !           851:     cmd->getTaskfile(&tf);
        !           852:     cmd->getResults(&res);
        !           853: 
        !           854: #if 0
        !           855:     IOLog("ATA command = %02x, RegMask = %04x ResultMask = %04x ReturnCode = %04x\n\r", 
        !           856:            tf.protocol, (int)tf.regmask, (int)tf.resultmask, (int)res.returnCode );
        !           857: 
        !           858:     IOLog("ATA command regs:      ");
        !           859: 
        !           860:     for (i=0; i < MAX_ATA_REGS; i++ )
        !           861:     {
        !           862:         IOLog("%04x ", tf.ataRegs[i]);
        !           863:     }
        !           864: 
        !           865:     IOLog("\n\rATA result regs:       ");
        !           866: 
        !           867:     for (i=0; i < MAX_ATA_REGS; i++ )
        !           868:     {
        !           869:         IOLog("%04x ", res.ataRegs[i]);
        !           870:     }
        !           871:     IOLog("\n\r");
        !           872: #endif
        !           873: 
        !           874:     if ( cmd->flags & IOATACommand::atacmdCallbackValid )
        !           875:     {
        !           876:         (*cmd->completionInfo.async.ataDoneFn)(              cmd->completionInfo.async.target, 
        !           877:                                                 (IOService *)this, 
        !           878:                                                              cmd, 
        !           879:                                                              cmd->completionInfo.async.refcon );
        !           880:     }
        !           881:     else
        !           882:     {
        !           883:         cmd->completionInfo.sync.syncer->signal();
        !           884:     }
        !           885: }
        !           886: 
        !           887: /*
        !           888:  *
        !           889:  *
        !           890:  */
        !           891: IOReturn IOATADevice::message( UInt32 p0, IOService *p1, void *p2 )
        !           892: {
        !           893:     UInt32                     msgId;
        !           894:     IOATADevice                        *ataDev;    
        !           895: 
        !           896:     msgId  = (UInt32) p0;
        !           897:     ataDev = (IOATADevice *)p1;
        !           898: 
        !           899:     switch ( msgId )
        !           900:     {
        !           901:         case ataMessageResetStarted:
        !           902:             lock_init( resetSem, true, NULL, NULL );
        !           903:             IORWLockWrite( resetSem );
        !           904:             break;
        !           905:         
        !           906:         case ataMessageResetComplete:
        !           907:             IORWLockUnlock( resetSem );
        !           908:             break;
        !           909:  
        !           910:         default:
        !           911:             ;
        !           912:     }
        !           913: 
        !           914:     return kIOReturnSuccess;
        !           915: }
        !           916: 
        !           917: /*
        !           918:  *
        !           919:  *
        !           920:  */
        !           921: UInt32 IOATADevice::getUnit()
        !           922: {
        !           923:     return unit;
        !           924: }
        !           925: 
        !           926: /*
        !           927:  *
        !           928:  *
        !           929:  */
        !           930: IOCommandQueue  *IOATADevice::getDeviceQueue()
        !           931: {
        !           932:     return deviceQueue;
        !           933: }
        !           934: 
        !           935: 
        !           936: /*
        !           937:  *
        !           938:  *
        !           939:  */
        !           940: ATADeviceType IOATADevice::getDeviceType()
        !           941: {
        !           942:     return deviceType;
        !           943: }
        !           944: 
        !           945: /*
        !           946:  *
        !           947:  *
        !           948:  */
        !           949: bool IOATADevice::getATAPIPktInt()
        !           950: {
        !           951:     return atapiPktInt;
        !           952: }
        !           953: 
        !           954: /*
        !           955:  *
        !           956:  *
        !           957:  */
        !           958: bool IOATADevice::getIdentifyData( ATAIdentify *identifyBuffer )
        !           959: {
        !           960:     if ( identifyData == NULL )
        !           961:     {
        !           962:         bzero( identifyBuffer, sizeof(ATAIdentify) );
        !           963:         return false;
        !           964:     }
        !           965: 
        !           966:     bcopy( identifyData, identifyBuffer, sizeof(ATAIdentify) );
        !           967:     return true;
        !           968: }
        !           969: 
        !           970: /*
        !           971:  *
        !           972:  *
        !           973:  */
        !           974: bool IOATADevice::getInquiryData( UInt32 inquiryBufLength, ATAPIInquiry *inquiryBuffer )
        !           975: {        
        !           976:     bzero( inquiryBuffer, inquiryBufLength );
        !           977: 
        !           978:     if ( inquiryData == NULL )
        !           979:     {
        !           980:         return false;
        !           981:     }
        !           982: 
        !           983:     bcopy( inquiryData, inquiryBuffer, inquiryBufLength );
        !           984: 
        !           985:     return true;
        !           986: }
        !           987: 
        !           988: /*
        !           989:  *
        !           990:  *
        !           991:  */
        !           992: bool IOATADevice::init( UInt32 unitNum, IOATAController *ctlr )
        !           993: {
        !           994:     controller = ctlr;
        !           995:     unit       = unitNum;
        !           996: 
        !           997:     if ( super::init() != true )
        !           998:     {
        !           999:         return false;
        !          1000:     }
        !          1001: 
        !          1002:     deviceQueue = controller->createDeviceQueue( this ); 
        !          1003:     if ( deviceQueue == NULL )
        !          1004:     {
        !          1005:         return false;
        !          1006:     }
        !          1007: 
        !          1008:     utilCmd = allocCommand();
        !          1009:     if ( utilCmd == NULL )
        !          1010:     {
        !          1011:         return false;
        !          1012:     }
        !          1013: 
        !          1014:     resetSem = IORWLockAlloc();
        !          1015:     if ( resetSem == NULL )
        !          1016:     {
        !          1017:         return false;
        !          1018:     }
        !          1019: 
        !          1020:     return true;
        !          1021: }
        !          1022: 
        !          1023: 
        !          1024: /*
        !          1025:  *
        !          1026:  *
        !          1027:  */
        !          1028: OSDictionary *IOATADevice::createProperties()
        !          1029: {
        !          1030:     OSDictionary       *propTable = 0;
        !          1031:     OSObject           *regObj;
        !          1032:     char               tmpbuf[81];
        !          1033:     char               *s, *d;
        !          1034:    
        !          1035: 
        !          1036:     propTable = OSDictionary::withCapacity(ATAMaxProperties);
        !          1037:     if ( propTable == NULL )
        !          1038:     {
        !          1039:         return NULL;
        !          1040:     }
        !          1041: 
        !          1042:     s = (deviceType == ataDeviceATA) ? ATAPropertyProtocolATA : ATAPropertyProtocolATAPI;
        !          1043:     regObj = (OSObject *)OSString::withCString( s );
        !          1044:     if ( addToRegistry( propTable, regObj, ATAPropertyProtocol ) != true )
        !          1045:     {
        !          1046:         goto createprop_error;
        !          1047:     }
        !          1048: 
        !          1049:     regObj = (OSObject *)OSNumber::withNumber(unit,32);
        !          1050:     if ( addToRegistry( propTable, regObj, ATAPropertyDeviceNumber ) != true )
        !          1051:     {
        !          1052:         goto createprop_error;
        !          1053:     }
        !          1054: 
        !          1055:     regObj = (OSObject *)OSNumber::withNumber(unit,32);
        !          1056:     if ( addToRegistry( propTable, regObj, ATAPropertyLocation ) != true )
        !          1057:     {
        !          1058:         goto createprop_error;
        !          1059:     }
        !          1060: 
        !          1061:     d = tmpbuf;
        !          1062:     stripBlanks( d, identifyData->modelNumber, sizeof(identifyData->modelNumber));
        !          1063:     regObj = (OSObject *)OSString::withCString( d );
        !          1064:     if ( addToRegistry( propTable, regObj, ATAPropertyModelNumber ) != true )
        !          1065:     {
        !          1066:         goto createprop_error;
        !          1067:     }
        !          1068: 
        !          1069:     d = tmpbuf;
        !          1070:     stripBlanks( d, identifyData->firmwareRevision, sizeof(identifyData->firmwareRevision));
        !          1071:     regObj = (OSObject *)OSString::withCString( d );
        !          1072:     if ( addToRegistry( propTable, regObj, ATAPropertyFirmwareRev ) != true )
        !          1073:     {
        !          1074:         goto createprop_error;
        !          1075:     }
        !          1076: 
        !          1077:     if ( inquiryData )
        !          1078:     {
        !          1079:         stripBlanks( d, inquiryData->vendorName, sizeof(inquiryData->vendorName) );
        !          1080:         regObj = (OSObject *)OSString::withCString( d );
        !          1081:         if ( addToRegistry( propTable, regObj, ATAPropertyVendorName ) != true )
        !          1082:         {
        !          1083:             goto createprop_error;
        !          1084:         }
        !          1085: 
        !          1086:         stripBlanks( d, inquiryData->productName, sizeof(inquiryData->productName) );
        !          1087:         regObj = (OSObject *)OSString::withCString( d );
        !          1088:         if ( addToRegistry( propTable, regObj, ATAPropertyProductName ) != true )
        !          1089:         {
        !          1090:             goto createprop_error;
        !          1091:         }
        !          1092: 
        !          1093:         stripBlanks( d, inquiryData->productRevision, sizeof(inquiryData->productRevision) );
        !          1094:         regObj = (OSObject *)OSString::withCString( d );
        !          1095:         if ( addToRegistry( propTable, regObj, ATAPropertyProductRevision ) != true )
        !          1096:         {
        !          1097:             goto createprop_error;
        !          1098:         }
        !          1099:     }
        !          1100:     return propTable;
        !          1101: 
        !          1102: createprop_error: ;
        !          1103:     propTable->release();
        !          1104:     return NULL;
        !          1105: }
        !          1106: 
        !          1107: /*
        !          1108:  *
        !          1109:  *
        !          1110:  */
        !          1111: 
        !          1112: bool IOATADevice::matchPropertyTable( OSDictionary * table )
        !          1113: {
        !          1114:   return( controller->matchNubWithPropertyTable( this, table ));
        !          1115: }
        !          1116: 
        !          1117: IOService *IOATADevice::matchLocation( IOService * )
        !          1118: {
        !          1119: //    IOLog( "IOATADevice::%s - called\n\r", __FUNCTION__ );
        !          1120: 
        !          1121:     return this;
        !          1122: }
        !          1123: 
        !          1124: /*
        !          1125:  *
        !          1126:  *
        !          1127:  */
        !          1128: bool IOATADevice::open( IOService *customer )
        !          1129: {
        !          1130:     bool               rc;
        !          1131: 
        !          1132:     rc = super::open( customer );
        !          1133:     
        !          1134:     if ( rc == true )
        !          1135:     {
        !          1136:         client = customer;
        !          1137:     }
        !          1138:     
        !          1139:     return rc;
        !          1140: }
        !          1141: 
        !          1142: 
        !          1143: /*
        !          1144:  *
        !          1145:  *
        !          1146:  */
        !          1147: void IOATADevice::close( IOService *customer )
        !          1148: {
        !          1149:     super::close( customer );
        !          1150:     client = NULL;
        !          1151: }
        !          1152: 
        !          1153: 
        !          1154: /*
        !          1155:  *
        !          1156:  *
        !          1157:  */
        !          1158: void IOATADevice::free()
        !          1159: {
        !          1160:     if ( identifyData ) IOFree( identifyData, sizeof(*identifyData) );
        !          1161:     if ( inquiryData  ) IOFree( inquiryData,  sizeof(*inquiryData)  );
        !          1162:     if ( utilCmd )      utilCmd->release();
        !          1163:     if ( reqSenseCmd )  reqSenseCmd->release();
        !          1164:     if ( deviceQueue )  deviceQueue->release();
        !          1165:     if ( resetSem )    IORWLockFree( resetSem );
        !          1166: 
        !          1167:     super::free();
        !          1168: }
        !          1169:     
        !          1170: /*
        !          1171:  *
        !          1172:  *
        !          1173:  */
        !          1174: IOService *IOATADevice::getClient()
        !          1175: {
        !          1176:     return client;
        !          1177: }
        !          1178: 
        !          1179: 
        !          1180: /*
        !          1181:  *
        !          1182:  *
        !          1183:  */
        !          1184: IOATACommand *IOATADevice::allocCommand( UInt32 clientDataSize )
        !          1185: {
        !          1186:     IOATACommand       *cmd;
        !          1187: 
        !          1188:     if ( (cmd = controller->allocCommand( clientDataSize )) )
        !          1189:     {
        !          1190:         cmd->setDevice( this );
        !          1191:     }
        !          1192:     return cmd;
        !          1193: }
        !          1194: 
        !          1195: /*
        !          1196:  *
        !          1197:  *
        !          1198:  */
        !          1199: bool IOATADevice::addToRegistry( OSDictionary *propTable, OSObject *regObj, char *key )
        !          1200: {
        !          1201:     bool ret;
        !          1202: 
        !          1203:     if ( regObj == NULL )
        !          1204:     {
        !          1205:         return false;
        !          1206:     }
        !          1207: 
        !          1208:     ret = propTable->setObject( key, regObj );
        !          1209: 
        !          1210:     regObj->release();
        !          1211: 
        !          1212:     return ret;
        !          1213: }
        !          1214:            
        !          1215: /*
        !          1216:  *
        !          1217:  *
        !          1218:  */
        !          1219: void IOATADevice::stripBlanks( char *d, char *s, UInt32 l )
        !          1220: {
        !          1221:     char       *p, c;
        !          1222: 
        !          1223:     for ( p = d, c = *s; l && c ; l--)
        !          1224:     {
        !          1225:         c = (*d++ = *s++);
        !          1226:         if ( c != ' ' )
        !          1227:         {
        !          1228:             p = d;
        !          1229:         }
        !          1230:     }
        !          1231:     *p = 0;
        !          1232: }   
        !          1233: 
        !          1234: 
        !          1235: /*
        !          1236:  *
        !          1237:  *
        !          1238:  */
        !          1239: void IOATADevice::endianConvertData( void *data, void *endianTable )
        !          1240: {
        !          1241:     EndianTable                *t;
        !          1242: 
        !          1243:     union EndianPtr 
        !          1244:     {
        !          1245:         void            *voidPtr;
        !          1246:         UInt8          *bytePtr;
        !          1247:         UInt16         *shortPtr;
        !          1248:         UInt32         *longPtr;
        !          1249:         UInt64         *longlongPtr;
        !          1250:     } p;
        !          1251: 
        !          1252:     UInt32             i,j;
        !          1253: 
        !          1254:     p.voidPtr = data;
        !          1255: 
        !          1256:     t = (EndianTable *)endianTable;
        !          1257: 
        !          1258:     for ( ; t->type; t++ )
        !          1259:     {
        !          1260:         i = t->size/t->type;
        !          1261: 
        !          1262:         switch ( t->type )
        !          1263:         {
        !          1264:         
        !          1265:             /* Note:
        !          1266:              *
        !          1267:              * The ATA standard defines identify strings as arrays of short ints,
        !          1268:              * with the left-most character of the string as the most significant  
        !          1269:              * byte of the short int. Strings are not normally affected by the host
        !          1270:              * endianess. However, the way ATA defines strings would cause strings
        !          1271:              * to appear byte reversed. We do a manditory short int byte-swap here, 
        !          1272:              * although strictly speaking this is not an endian issue.
        !          1273:              *
        !          1274:              */
        !          1275:             case sizeof(UInt8):
        !          1276:               for ( j = 0; j < i/2; j++ )
        !          1277:               {
        !          1278:                   *p.shortPtr++ = OSSwapInt16(*p.shortPtr);
        !          1279:               }  
        !          1280:               
        !          1281:               break;
        !          1282:         
        !          1283:             case sizeof(UInt16):
        !          1284:               for ( j = 0; j < i; j++ )
        !          1285:               {
        !          1286:                   *p.shortPtr++ = OSSwapLittleToHostInt16(*p.shortPtr);
        !          1287:               }  
        !          1288:               break;
        !          1289: 
        !          1290:             case sizeof(UInt32):
        !          1291:               for ( j = 0; j < i; j++ )
        !          1292:               {
        !          1293:                   *p.longPtr++ = OSSwapLittleToHostInt32(*p.longPtr);
        !          1294:               }  
        !          1295:               break;
        !          1296: 
        !          1297:             case sizeof(UInt64):
        !          1298:               for ( j = 0; j < i; j++ )
        !          1299:               {
        !          1300:                   *p.longlongPtr++ = OSSwapLittleToHostInt64(*p.longlongPtr);
        !          1301:               }  
        !          1302:               break;
        !          1303: 
        !          1304:             default:
        !          1305:               ;
        !          1306:         }
        !          1307:     } 
        !          1308: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.