Annotation of XNU/iokit/Drivers/ata/drvAppleATA/AppleATAPPC.cpp, revision 1.1.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.