Annotation of XNU/iokit/Drivers/ata/drvAppleATA/AppleATAPPC.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:  *    AppleATAPPC.cpp
        !            25:  *
        !            26:  */
        !            27: #include "AppleATAPPC.h"
        !            28: 
        !            29: #undef super
        !            30: #define super AppleATA
        !            31: 
        !            32: extern pmap_t  kernel_pmap;
        !            33: 
        !            34: OSDefineMetaClassAndStructors( AppleATAPPC, AppleATA )
        !            35: 
        !            36: static inline int rnddiv( int x, int y )
        !            37: {
        !            38:     if ( x < 0 )
        !            39:       return 0;
        !            40:     else
        !            41:       return ( (x / y) + (( x % y ) ? 1 : 0) );
        !            42: }
        !            43: 
        !            44: 
        !            45: /*
        !            46:  *
        !            47:  *
        !            48:  */
        !            49: bool AppleATAPPC::configure( IOService *forProvider, UInt32 *controllerDataSize )
        !            50: {
        !            51:     *controllerDataSize = 0;
        !            52: 
        !            53:     provider = forProvider;
        !            54: 
        !            55:     if ( identifyController() == false )
        !            56:     {
        !            57:         return false;
        !            58:     }
        !            59: 
        !            60:     ioMapATA = provider->mapDeviceMemoryWithIndex(0);
        !            61:     if ( ioMapATA == NULL ) return false;
        !            62:     ioBaseATA = (volatile UInt32 *)ioMapATA->getVirtualAddress();
        !            63: 
        !            64:     ioMapDMA = provider->mapDeviceMemoryWithIndex(1);
        !            65:     if ( ioMapDMA == NULL ) return false;
        !            66:     ioBaseDMA = (volatile IODBDMAChannelRegisters *)ioMapDMA->getVirtualAddress();
        !            67: 
        !            68:     dmaDescriptors = (IODBDMADescriptor *)kalloc(page_size);
        !            69:     if ( dmaDescriptors == 0 )
        !            70:     {
        !            71:         return false;
        !            72:     }
        !            73:     
        !            74:     dmaDescriptorsPhys = (UInt32) pmap_extract(kernel_pmap, (vm_offset_t) dmaDescriptors);
        !            75: 
        !            76:     if ( (UInt32)dmaDescriptors & (page_size - 1) )
        !            77:     {
        !            78:         IOLog("AppleATAPPC::%s() - DMA Descriptor memory not page aligned!!", __FUNCTION__);
        !            79:         return false;
        !            80:     }
        !            81:   
        !            82:     bzero( dmaDescriptors, page_size );
        !            83: 
        !            84:     numDescriptors = page_size/sizeof(IODBDMADescriptor);
        !            85: 
        !            86:     dmaMemoryCursor = IOBigMemoryCursor::withSpecification( 64*1024-2, 0xffffffff );
        !            87:     if ( dmaMemoryCursor == NULL )
        !            88:     {
        !            89:         return false;
        !            90:     } 
        !            91: 
        !            92:     bitBucketAddr = IOMalloc(32);
        !            93:     if ( bitBucketAddr == 0 )
        !            94:     {
        !            95:         return false;
        !            96:     }
        !            97:     bitBucketAddrPhys = (UInt32) pmap_extract(kernel_pmap, (vm_offset_t) (((UInt32)bitBucketAddr + 0xf) & ~0x0f));
        !            98: 
        !            99:     return true;
        !           100: }
        !           101: 
        !           102: 
        !           103: /*
        !           104:  *
        !           105:  *
        !           106:  */
        !           107: bool AppleATAPPC::identifyController()
        !           108: {
        !           109:     OSData             *compatibleEntry, *modelEntry;
        !           110: 
        !           111:     do    
        !           112:     {
        !           113:         controllerType = kControllerTypeDBDMAVersion1;
        !           114: 
        !           115:         compatibleEntry  = OSDynamicCast( OSData, provider->getProperty( "compatible" ) );
        !           116:         if ( compatibleEntry == 0 ) break;
        !           117: 
        !           118:         if ( compatibleEntry->isEqualTo( "keylargo-ata", sizeof("keylargo-ata")-1 ) == true ) 
        !           119:         {
        !           120:             controllerType = kControllerTypeDBDMAVersion2;
        !           121: 
        !           122:             modelEntry = OSDynamicCast( OSData, provider->getProperty("model") );  
        !           123:             if ( modelEntry == 0 ) break;
        !           124:       
        !           125:             if ( modelEntry->isEqualTo( "ata-4", sizeof("ata-4")-1 ) == true ) 
        !           126:             {
        !           127:                 controllerType = kControllerTypeUltra66DBDMA;
        !           128:             }
        !           129:         }    
        !           130:     } while ( 0 );
        !           131: 
        !           132:     return true;
        !           133: }    
        !           134: 
        !           135: 
        !           136: /*
        !           137:  *
        !           138:  *
        !           139:  */
        !           140: bool AppleATAPPC::createWorkLoop( IOWorkLoop **workLoop )
        !           141: {
        !           142:     if ( super::createWorkLoop( workLoop ) != true )
        !           143:     {
        !           144:         return false;
        !           145:     }
        !           146:     
        !           147:     interruptEventSource = IOInterruptEventSource::interruptEventSource( (OSObject *)             this,
        !           148:                                                                          (IOInterruptEventAction) &AppleATAPPC::interruptOccurred,
        !           149:                                                                         (IOService *)            provider,
        !           150:                                                                         (int)                    0 );
        !           151: 
        !           152:     if ( interruptEventSource == NULL )
        !           153:     {
        !           154:         return false;
        !           155:     }
        !           156: 
        !           157:     disableControllerInterrupts();
        !           158: 
        !           159:     (*workLoop)->addEventSource( interruptEventSource ); 
        !           160: 
        !           161:     timerEventSource = IOTimerEventSource::timerEventSource( this, (IOTimerEventSource::Action) &AppleATAPPC::ataTimer );
        !           162:     if ( timerEventSource == NULL )
        !           163:     {
        !           164:         return false;
        !           165:     }
        !           166:     (*workLoop)->addEventSource( timerEventSource ); 
        !           167:  
        !           168:     ataTimer( timerEventSource ); 
        !           169: 
        !           170:     return true;
        !           171: }
        !           172: 
        !           173: 
        !           174: /*
        !           175:  *
        !           176:  *
        !           177:  */
        !           178: bool AppleATAPPC::provideProtocols( ATAProtocol *protocolsSupported )
        !           179: {
        !           180:     return false;
        !           181: }
        !           182: 
        !           183: 
        !           184: /*
        !           185:  *
        !           186:  *
        !           187:  */
        !           188: bool AppleATAPPC::provideTimings( UInt32 *numTimings, ATATiming *timingsSupported )
        !           189: {
        !           190:     return false;
        !           191: }
        !           192: 
        !           193: 
        !           194: /*
        !           195:  *
        !           196:  *
        !           197:  */
        !           198: bool AppleATAPPC::calculateTiming( UInt32 deviceNum, ATATiming *pTiming )
        !           199: {
        !           200:     bool               rc = false;
        !           201: 
        !           202:     switch ( controllerType )
        !           203:     {
        !           204:         case kControllerTypeDBDMAVersion1:
        !           205:         case kControllerTypeDBDMAVersion2:
        !           206:             switch ( pTiming->timingProtocol )
        !           207:             {
        !           208:                 case ataTimingPIO:
        !           209:                     rc = calculatePIOTiming( deviceNum, pTiming );
        !           210:                     break;
        !           211: 
        !           212:                 case ataTimingDMA:
        !           213:                     rc = calculateDMATiming( deviceNum, pTiming );
        !           214:                     break;
        !           215:  
        !           216:                 default:
        !           217:                     ;
        !           218:             }
        !           219:             break;
        !           220: 
        !           221:         case kControllerTypeUltra66DBDMA:
        !           222:             switch ( pTiming->timingProtocol )
        !           223:             {
        !           224:                 case ataTimingPIO:
        !           225:                     rc = calculateUltra66PIOTiming( deviceNum, pTiming );
        !           226:                     break;
        !           227: 
        !           228:                 case ataTimingDMA:
        !           229:                     rc = calculateUltra66DMATiming( deviceNum, pTiming );
        !           230:                     break;
        !           231:  
        !           232:                 case ataTimingUltraDMA66:
        !           233:                     rc = calculateUltra66UDMATiming( deviceNum, pTiming );
        !           234:                     break;
        !           235: 
        !           236:                 default:
        !           237:                     ;
        !           238:             }
        !           239:             break;
        !           240: 
        !           241:         default:
        !           242:             ;
        !           243:     }
        !           244: 
        !           245:     return rc;
        !           246: }
        !           247: 
        !           248: 
        !           249: /*
        !           250:  *
        !           251:  *
        !           252:  */
        !           253: bool AppleATAPPC::calculatePIOTiming( UInt32 unitNum, ATATiming *pTiming )
        !           254: {
        !           255:     int                        accessTime;
        !           256:     int                        accessTicks;
        !           257:     int                recTime;
        !           258:     int                        recTicks;
        !           259:     int                        cycleTime;
        !           260: 
        !           261:     /*
        !           262:      * Calc PIO access time >= minDataAccess in SYSCLK increments
        !           263:      */
        !           264:     accessTicks = rnddiv(pTiming->minDataAccess, IDE_SYSCLK_NS);
        !           265:     /*
        !           266:      * Hardware limits access times to >= 120 ns 
        !           267:      */
        !           268:     accessTicks -= IDE_PIO_ACCESS_BASE;
        !           269:     if (accessTicks < IDE_PIO_ACCESS_MIN )
        !           270:     {
        !           271:         accessTicks = IDE_PIO_ACCESS_MIN;
        !           272:     }
        !           273:     accessTime = (accessTicks + IDE_PIO_ACCESS_BASE) * IDE_SYSCLK_NS;
        !           274: 
        !           275:     /*
        !           276:      * Calc recovery time in SYSCLK increments based on time remaining in cycle
        !           277:      */
        !           278:     recTime = pTiming->minDataCycle - accessTime;
        !           279:     recTicks = rnddiv( recTime, IDE_SYSCLK_NS );
        !           280:     /*
        !           281:      * Hardware limits recovery time to >= 150ns 
        !           282:      */
        !           283:     recTicks -= IDE_PIO_RECOVERY_BASE;
        !           284:     if ( recTicks < IDE_PIO_RECOVERY_MIN )
        !           285:     {
        !           286:       recTicks = IDE_PIO_RECOVERY_MIN;
        !           287:     }
        !           288: 
        !           289:     cycleTime = (recTicks + IDE_PIO_RECOVERY_BASE + accessTicks + IDE_PIO_ACCESS_BASE) * IDE_SYSCLK_NS;
        !           290: 
        !           291:     ideTimingWord[unitNum] &= ~0x7ff;
        !           292:     ideTimingWord[unitNum] |= accessTicks | (recTicks << 5);
        !           293: 
        !           294: #if 0
        !           295:     IOLog("AppleATAPPC::%s() Unit %1d PIO Requested Timings: Access: %3dns Cycle: %3dns \n\r", 
        !           296:              __FUNCTION__, (int)unitNum, (int)pTiming->minDataAccess, (int)pTiming->minDataCycle);
        !           297:     IOLog("AppleATAPPC::%s()        PIO Actual    Timings: Access: %3dns Cycle: %3dns\n\r",
        !           298:              __FUNCTION__, accessTime, cycleTime );
        !           299: #endif
        !           300: 
        !           301:     return true;
        !           302: }
        !           303: 
        !           304: 
        !           305: /*
        !           306:  *
        !           307:  *
        !           308:  */
        !           309: bool AppleATAPPC::calculateDMATiming( UInt32 unitNum, ATATiming *pTiming )
        !           310: {
        !           311:     int                        accessTime;
        !           312:     int                        accessTicks;
        !           313:     int                recTime;
        !           314:     int                        recTicks;
        !           315:     int                        cycleTime;
        !           316:     int                 cycleTimeOrig;
        !           317:     int                halfTick = 0;
        !           318: 
        !           319:     /*
        !           320:      * Calc DMA access time >= minDataAccess in SYSCLK increments
        !           321:      */
        !           322: 
        !           323:     /*
        !           324:      * OHare II erata - Cant handle write cycle times below 150ns
        !           325:      */
        !           326:     cycleTimeOrig = pTiming->minDataCycle;
        !           327: #if 0
        !           328:     if ( IsPowerStar() )
        !           329:     {
        !           330:         if ( cycleTimeOrig < 150 ) pTiming->minDataCycle = 150;
        !           331:     }
        !           332: #endif
        !           333: 
        !           334:     accessTicks = rnddiv(pTiming->minDataAccess, IDE_SYSCLK_NS);
        !           335: 
        !           336:     accessTicks -= IDE_DMA_ACCESS_BASE;
        !           337:     if ( accessTicks < IDE_DMA_ACCESS_MIN )
        !           338:     {
        !           339:         accessTicks = IDE_DMA_ACCESS_MIN;
        !           340:     }
        !           341:     accessTime = (accessTicks + IDE_DMA_ACCESS_BASE) * IDE_SYSCLK_NS;
        !           342: 
        !           343:     /*
        !           344:      * Calc recovery time in SYSCLK increments based on time remaining in cycle
        !           345:      */
        !           346:     recTime = pTiming->minDataCycle - accessTime;    
        !           347:     recTicks = rnddiv( recTime, IDE_SYSCLK_NS );
        !           348: 
        !           349:     recTicks -= IDE_DMA_RECOVERY_BASE;
        !           350:     if ( recTicks < IDE_DMA_RECOVERY_MIN )
        !           351:     {
        !           352:         recTicks = IDE_DMA_RECOVERY_MIN;
        !           353:     }
        !           354:     cycleTime = (recTicks + IDE_DMA_RECOVERY_BASE + accessTicks + IDE_DMA_ACCESS_BASE) * IDE_SYSCLK_NS;
        !           355:  
        !           356:     /*
        !           357:      * If our calculated access time is at least SYSCLK/2 > than what the disk requires, 
        !           358:      * see if selecting the 1/2 Clock option will help. This adds SYSCLK/2 to 
        !           359:      * the access time and subtracts SYSCLK/2 from the recovery time.
        !           360:      * 
        !           361:      * By setting the H-bit and subtracting one from the current access tick count,
        !           362:      * we are reducing the current access time by SYSCLK/2 and the current recovery
        !           363:      * time by SYSCLK/2. Now, check if the new cycle time still meets the disk's requirements.
        !           364:      */  
        !           365:     if ( controllerType == kControllerTypeDBDMAVersion1 )
        !           366:     {
        !           367:         if ( (accessTicks > IDE_DMA_ACCESS_MIN) &&  ((UInt32)(accessTime - IDE_SYSCLK_NS/2) >= pTiming->minDataAccess) )
        !           368:         {
        !           369:             if ( (UInt32)(cycleTime - IDE_SYSCLK_NS) >= pTiming->minDataCycle )
        !           370:             {
        !           371:                 halfTick    = 1;
        !           372:                 accessTicks--;
        !           373:                 accessTime -= IDE_SYSCLK_NS/2;
        !           374:                 cycleTime  -= IDE_SYSCLK_NS;
        !           375:             }
        !           376:         }
        !           377:     }
        !           378: 
        !           379:     ideTimingWord[unitNum] &= ~0xffff800;
        !           380:     ideTimingWord[unitNum] |= (accessTicks | (recTicks << 5) | (halfTick << 10)) << 11;
        !           381: 
        !           382: #if 0
        !           383:     IOLog("AppleATAPPC::%s() Unit %1d DMA Requested Timings: Access: %3dns Cycle: %3dns \n\r",  
        !           384:              __FUNCTION__, (int)unitNum, (int)pTiming->minDataAccess, (int)cycleTimeOrig);
        !           385:     IOLog("AppleATAPPC::%s()        DMA Actual    Timings: Access: %3dns Cycle: %3dns\n\r",   
        !           386:              __FUNCTION__, accessTime, cycleTime );
        !           387:     IOLog("AppleATAPPC::%s() Ide DMA Timings = %08lx\n\r", __FUNCTION__, ideTimingWord[unitNum] );
        !           388: #endif
        !           389: 
        !           390:     return true;
        !           391: }
        !           392: 
        !           393: 
        !           394: /*
        !           395:  *
        !           396:  *
        !           397:  */
        !           398: bool AppleATAPPC::calculateUltra66PIOTiming( UInt32 unitNum, ATATiming *pTiming )
        !           399: {
        !           400:     int                        accessTime;
        !           401:     int                        accessTicks;
        !           402:     int                recTime;
        !           403:     int                        recTicks;
        !           404:     int                        cycleTime;
        !           405: 
        !           406:     /*
        !           407:      * Calc PIO access time >= pioAccessTime in SYSCLK increments
        !           408:      */
        !           409:     accessTicks = rnddiv(pTiming->minDataAccess * 1000, IDE_ULTRA66_CLOCK_PS );
        !           410:     accessTime = accessTicks * IDE_ULTRA66_CLOCK_PS;
        !           411: 
        !           412:     /*
        !           413:      * Calc recovery time in SYSCLK increments based on time remaining in cycle
        !           414:      */
        !           415:     recTime = pTiming->minDataCycle * 1000 - accessTime;
        !           416:     recTicks = rnddiv( recTime, IDE_ULTRA66_CLOCK_PS );
        !           417: 
        !           418:     cycleTime = (recTicks + accessTicks ) * IDE_ULTRA66_CLOCK_PS;
        !           419: 
        !           420:     ideTimingWord[unitNum] &= ~0xe00003ff;
        !           421:     ideTimingWord[unitNum] |= accessTicks | (recTicks << 5);
        !           422: 
        !           423: #if 0
        !           424:     IOLog("AppleATAPPC::%s()  Unit %1d PIO Requested Timings: Access: %3dns Cycle: %3dns \n\r",  
        !           425:              __FUNCTION__, (int)unitNum, (int)pTiming->minDataAccess, (int)pTiming->minDataCycle);
        !           426:     IOLog("AppleATAPPC::%s()         PIO Actual    Timings: Access: %3dns Cycle: %3dns\n\r",   
        !           427:              __FUNCTION__, accessTime / 1000, cycleTime / 1000 );
        !           428:     IOLog("AppleATAPPC::%s()  Ide PIO Timings = %08lx\n\r", __FUNCTION__, ideTimingWord[unitNum] );
        !           429: #endif
        !           430: 
        !           431:     return true;
        !           432: }
        !           433: 
        !           434: 
        !           435: /*
        !           436:  *
        !           437:  *
        !           438:  */
        !           439: bool AppleATAPPC::calculateUltra66DMATiming( UInt32 unitNum, ATATiming *pTiming )
        !           440: {
        !           441:     int                        accessTime;
        !           442:     int                        accessTicks;
        !           443:     int                recTime;
        !           444:     int                        recTicks;
        !           445:     int                        cycleTime;
        !           446: 
        !           447:     /*
        !           448:      * Calc DMA access time >= dmaAccessTime in SYSCLK increments
        !           449:      */
        !           450:     accessTicks = rnddiv(pTiming->minDataAccess * 1000, IDE_ULTRA66_CLOCK_PS);
        !           451:     accessTime = accessTicks * IDE_ULTRA66_CLOCK_PS;
        !           452: 
        !           453:     /*
        !           454:      * Calc recovery time in SYSCLK increments based on time remaining in cycle
        !           455:      */
        !           456:     recTime = pTiming->minDataCycle * 1000 - accessTime;    
        !           457:     recTicks = rnddiv( recTime, IDE_ULTRA66_CLOCK_PS );
        !           458: 
        !           459:     cycleTime = (recTicks + accessTicks) * IDE_ULTRA66_CLOCK_PS;
        !           460: 
        !           461:     ideTimingWord[unitNum] &= ~0x001ffc00;
        !           462:     ideTimingWord[unitNum] |= (accessTicks | (recTicks << 5)) << 10;
        !           463: 
        !           464: #if 0
        !           465:     IOLog("AppleATAPPC::%s()  Unit %1d DMA Requested Timings: Access: %3dns Cycle: %3dns \n\r",  
        !           466:              __FUNCTION__, (int)unitNum, (int)pTiming->minDataAccess, (int)pTiming->minDataCycle);
        !           467:     IOLog("AppleATAPPC::%s()         DMA Actual    Timings: Access: %3dns Cycle: %3dns\n\r",   
        !           468:              __FUNCTION__, accessTime / 1000, cycleTime / 1000 );
        !           469:     IOLog("AppleATAPPC::%s()  Ide DMA Timings = %08lx\n\r", __FUNCTION__, ideTimingWord[unitNum] );
        !           470: #endif
        !           471: 
        !           472:     return true;
        !           473: }
        !           474: 
        !           475: 
        !           476: /*
        !           477:  *
        !           478:  *
        !           479:  */
        !           480: bool AppleATAPPC::calculateUltra66UDMATiming( UInt32 unitNum, ATATiming *pTiming )
        !           481: {
        !           482:     int                        rdyToPauseTicks;
        !           483:     int                        rdyToPauseTime;
        !           484:     int                        cycleTime;
        !           485:     int                        cycleTicks;
        !           486: 
        !           487:     /*
        !           488:      * Ready to Pause delay in PCI_66_CLOCK / 2 increments
        !           489:      */
        !           490:     rdyToPauseTicks = rnddiv(pTiming->minDataAccess * 1000, IDE_ULTRA66_CLOCK_PS);
        !           491:     rdyToPauseTime  = rdyToPauseTicks * IDE_ULTRA66_CLOCK_PS;
        !           492: 
        !           493:     /*
        !           494:      * Calculate cycle time in PCI_66_CLOCK / 2 increments
        !           495:      */
        !           496:     cycleTicks = rnddiv(pTiming->minDataCycle * 1000, IDE_ULTRA66_CLOCK_PS);
        !           497:     cycleTime  = cycleTicks * IDE_ULTRA66_CLOCK_PS;
        !           498: 
        !           499:     ideTimingWord[unitNum] &= ~0x1ff00000;
        !           500:     ideTimingWord[unitNum] |= ((rdyToPauseTicks << 5) | (cycleTicks << 1) | 1) << 20;
        !           501: 
        !           502: #if 0
        !           503:     IOLog("AppleATAPPC::%s() Unit %1d UDMA66 Requested Timings: ReadyToPause: %3dns Cycle: %3dns \n\r",  
        !           504:              __FUNCTION__, (int)unitNum, (int)pTiming->minDataAccess, (int)pTiming->minDataCycle);
        !           505:     IOLog("AppleATAPPC::%s()        UDMA66 Actual    Timings: ReadyToPause: %3dns Cycle: %3dns\n\r",   
        !           506:              __FUNCTION__, rdyToPauseTime / 1000, cycleTime / 1000 );
        !           507:     IOLog("AppleATAPPC::%s() Ide DMA Timings = %08lx\n\r", __FUNCTION__, ideTimingWord[unitNum] );
        !           508: #endif
        !           509: 
        !           510:     return true;
        !           511: }
        !           512: 
        !           513: 
        !           514: /*
        !           515:  *
        !           516:  *
        !           517:  */
        !           518: void AppleATAPPC::newDeviceSelected( IOATADevice *newDevice )
        !           519: {    
        !           520:     OSWriteSwapInt32( ioBaseATA, 0x200, ideTimingWord[newDevice->getUnit()] );
        !           521:     eieio();
        !           522: }
        !           523: 
        !           524: 
        !           525: /*
        !           526:  *
        !           527:  *
        !           528:  */
        !           529: bool AppleATAPPC::selectTiming( UInt32 unitNum, ATATimingProtocol timingProtocol )
        !           530: {
        !           531:     if ( controllerType == kControllerTypeUltra66DBDMA )
        !           532:     {
        !           533:         switch ( timingProtocol )
        !           534:         {
        !           535:              case ataTimingUltraDMA66:
        !           536:                  ideTimingWord[unitNum] |=  0x00100000;
        !           537:                  break;
        !           538:              case ataTimingDMA:   
        !           539:                  ideTimingWord[unitNum] &= ~0x00100000;
        !           540:                  break;
        !           541:              default:
        !           542:                   ;
        !           543:         }        
        !           544:     }
        !           545: 
        !           546:     currentDevice = (IOATADevice *)NULL;
        !           547:     return true;
        !           548: }
        !           549: 
        !           550: 
        !           551: /*
        !           552:  *
        !           553:  *
        !           554:  */
        !           555: void AppleATAPPC::ataTimer( IOTimerEventSource * /* sender */ )
        !           556: {
        !           557:     if ( xferCmdTimer != 0 )
        !           558:     {
        !           559:         if ( --xferCmdTimer == 0 )
        !           560:         {
        !           561:             IOLog("AppleATAPPC::%s() - Timeout occurred\n\r", __FUNCTION__ );
        !           562: 
        !           563:             if ( xferCmdSave != NULL )
        !           564:             {
        !           565:                 xferCmd     = xferCmdSave;
        !           566:                 xferCmdSave = NULL;
        !           567:             }
        !           568: 
        !           569:             updateCmdStatus( xferCmd, ataReturnErrorInterruptTimeout, xferCount );
        !           570: 
        !           571:             resetBusRequest();
        !           572: 
        !           573:             completeCmd( xferCmd );
        !           574:         }
        !           575:     }
        !           576: 
        !           577:     timerEventSource->setTimeoutMS(ATATimerIntervalmS);
        !           578: }
        !           579: 
        !           580: /*
        !           581:  *
        !           582:  *
        !           583:  */
        !           584: bool AppleATAPPC::programDma( IOATACommand *cmd )
        !           585: {
        !           586:     IOMemoryDescriptor                 *memoryDesc;
        !           587:     IODBDMADescriptor                  *dmaDesc;
        !           588:     UInt32                             dmaCmd;
        !           589:     bool                               isWrite;
        !           590:     IOPhysicalSegment                  physSeg;
        !           591:     IOByteCount                                offset;
        !           592:     UInt32                             i;
        !           593: 
        !           594:     IODBDMAReset( ioBaseDMA );
        !           595: 
        !           596:     cmd->getPointers( &memoryDesc, &dmaReqLength, &isWrite );
        !           597: 
        !           598:     if ( dmaReqLength == 0 )
        !           599:     {
        !           600:         return true;
        !           601:     }
        !           602: 
        !           603:     offset = 0;
        !           604: 
        !           605:     dmaCmd  = (isWrite == true) ? kdbdmaOutputMore : kdbdmaInputMore;
        !           606:     dmaDesc = dmaDescriptors;
        !           607: 
        !           608:    for ( i = 0; i < numDescriptors; i++, dmaDesc++ )
        !           609:     {
        !           610:         if ( dmaMemoryCursor->getPhysicalSegments( memoryDesc, offset, &physSeg, 1 ) != 1 )
        !           611:         {
        !           612:             break;
        !           613:         }
        !           614: 
        !           615:         IOMakeDBDMADescriptor( dmaDesc,
        !           616:                                dmaCmd,
        !           617:                               kdbdmaKeyStream0,
        !           618:                               kdbdmaIntNever,
        !           619:                               kdbdmaBranchNever,
        !           620:                               kdbdmaWaitNever,
        !           621:                                physSeg.length,
        !           622:                                physSeg.location );
        !           623:        offset += physSeg.length;
        !           624:     }
        !           625: 
        !           626:     if ( i == numDescriptors )
        !           627:     {
        !           628:         return false;
        !           629:     }
        !           630: 
        !           631:     /*
        !           632:      * Note: ATAPI always transfers even byte-counts. Send the extra byte to/from the bit-bucket
        !           633:      *       if the requested transfer length is odd.
        !           634:      */
        !           635:     if ( dmaReqLength & 1 )
        !           636:     {
        !           637:         i++;
        !           638:         IOMakeDBDMADescriptor( dmaDesc++,
        !           639:                               dmaCmd,
        !           640:                               kdbdmaKeyStream0,
        !           641:                               kdbdmaIntNever,
        !           642:                               kdbdmaBranchNever,
        !           643:                               kdbdmaWaitNever,
        !           644:                               1,
        !           645:                               bitBucketAddrPhys );
        !           646:     }
        !           647: 
        !           648: 
        !           649:     if ( i == numDescriptors )
        !           650:     {
        !           651:         return false;
        !           652:     }
        !           653: 
        !           654: 
        !           655:     IOMakeDBDMADescriptor( dmaDesc,
        !           656:                            kdbdmaStop,
        !           657:                            kdbdmaKeyStream0,
        !           658:                           kdbdmaIntNever,
        !           659:                           kdbdmaBranchNever,
        !           660:                           kdbdmaWaitNever,
        !           661:                            0,
        !           662:                            0 );
        !           663: 
        !           664:     IOSetDBDMACommandPtr( ioBaseDMA, dmaDescriptorsPhys );
        !           665: 
        !           666: 
        !           667:     return true;
        !           668: }                      
        !           669: 
        !           670:  
        !           671: /*
        !           672:  *
        !           673:  *
        !           674:  */
        !           675: bool AppleATAPPC::startDma( IOATACommand * )
        !           676: {
        !           677:     if ( dmaReqLength != 0 )
        !           678:     {
        !           679:         IODBDMAContinue( ioBaseDMA );
        !           680:     }
        !           681:     return true;
        !           682: }
        !           683: 
        !           684: 
        !           685: /*
        !           686:  *
        !           687:  *
        !           688:  */
        !           689: bool AppleATAPPC::stopDma( IOATACommand *, UInt32 *transferCount )
        !           690: {
        !           691:     UInt32                     i;
        !           692:     UInt32                     ccResult;
        !           693:     UInt32                     byteCount = 0;
        !           694: 
        !           695:     *transferCount = 0;
        !           696: 
        !           697:     if ( dmaReqLength == 0 )
        !           698:     {
        !           699:         return true;
        !           700:     }
        !           701: 
        !           702:     IODBDMAStop( ioBaseDMA );
        !           703: 
        !           704:     for ( i=0; i < numDescriptors; i++ )
        !           705:     {
        !           706:         ccResult = IOGetCCResult( &dmaDescriptors[i] );
        !           707:     
        !           708:         if ( !(ccResult & kdbdmaStatusRun) )
        !           709:         {
        !           710:             break;
        !           711:         } 
        !           712:         byteCount += (IOGetCCOperation( &dmaDescriptors[i] ) & kdbdmaReqCountMask) - (ccResult & kdbdmaResCountMask); 
        !           713:     }
        !           714: 
        !           715:     *transferCount = byteCount;
        !           716: 
        !           717:     return true;
        !           718: }
        !           719:  
        !           720: /*
        !           721:  *
        !           722:  *
        !           723:  */
        !           724: void AppleATAPPC::disableControllerInterrupts()
        !           725: {
        !           726:     interruptEventSource->disable();
        !           727: }
        !           728: 
        !           729: /*
        !           730:  *
        !           731:  *
        !           732:  */
        !           733: void AppleATAPPC::enableControllerInterrupts()
        !           734: {
        !           735:     interruptEventSource->enable();
        !           736: }
        !           737: 
        !           738: /*
        !           739:  *
        !           740:  *
        !           741:  */
        !           742: void AppleATAPPC::free()
        !           743: {
        !           744:     if ( interruptEventSource != 0 )
        !           745:     {
        !           746:         interruptEventSource->disable();
        !           747:         interruptEventSource->release();
        !           748:     }
        !           749:   
        !           750:     if ( timerEventSource != 0 )
        !           751:     {
        !           752:         timerEventSource->release();
        !           753:     }
        !           754: 
        !           755:     if ( ioMapATA != 0 )
        !           756:     {
        !           757:         ioMapATA->release();
        !           758:     }
        !           759:  
        !           760:     if ( ioMapDMA != 0 )
        !           761:     {
        !           762:         ioMapDMA->release();
        !           763:     }
        !           764: 
        !           765:     if ( bitBucketAddr != 0 )
        !           766:     {
        !           767:         IOFree( bitBucketAddr, 32 );
        !           768:     }
        !           769: 
        !           770:     if ( dmaDescriptors != 0 )
        !           771:     {
        !           772:         kfree( (void *)dmaDescriptors, page_size );
        !           773:     } 
        !           774: }
        !           775: 
        !           776: /*
        !           777:  *
        !           778:  *
        !           779:  */
        !           780: void AppleATAPPC::writeATAReg( UInt32 regIndex, UInt32 regValue )
        !           781: {
        !           782:     regIndex += (regIndex >= ataRegDeviceControl ) ? (kCS3RegBase - ataRegDeviceControl + 6) : 0;
        !           783: 
        !           784:     if ( regIndex )
        !           785:     {
        !           786:         *((volatile UInt8 *)ioBaseATA + (regIndex<<4)) = regValue;
        !           787:     }
        !           788:     else
        !           789:     {
        !           790:         *(volatile UInt16 *)ioBaseATA = regValue;
        !           791:     }     
        !           792:     eieio();
        !           793: }
        !           794: 
        !           795: UInt32 AppleATAPPC::readATAReg( UInt32 regIndex )
        !           796: {
        !           797:     regIndex += (regIndex >= ataRegAltStatus ) ? (kCS3RegBase - ataRegAltStatus + 6) : 0;
        !           798: 
        !           799:     if ( regIndex )
        !           800:     { 
        !           801:         return *((volatile UInt8 *)ioBaseATA + (regIndex<<4));
        !           802:     }
        !           803:     else
        !           804:     {
        !           805:         return *(volatile UInt16 *)ioBaseATA;
        !           806:     }
        !           807: }

unix.superglobalmegacorp.com

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