Annotation of kernel/bsd/dev/ppc/drvPPCATA/IdeCntInit.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: // Copyright 1997 by Apple Computer, Inc., all rights reserved.
                     26: /*
                     27:  * Copyright (c) 1994-1997 NeXT Software, Inc.  All rights reserved. 
                     28:  *
                     29:  * IdeCntInit.m - ATA controller initialization module. 
                     30:  *
                     31:  */
                     32: 
                     33: #import <driverkit/kernelDriver.h>
                     34: #import <driverkit/interruptMsg.h>
                     35: #import <mach/mach_interface.h>
                     36: #import <driverkit/IODevice.h>
                     37: #import <driverkit/ppc/IOTreeDevice.h>
                     38: #import <driverkit/ppc/IODBDMA.h>
                     39: #import <driverkit/align.h>
                     40: #import <machkit/NXLock.h>
                     41: #import "IdeDDM.h"
                     42: #import "io_inline.h"
                     43: #import <driverkit/return.h>
                     44: #import <mach/port.h>
                     45: #import <machdep/ppc/powermac.h>
                     46: #import <bsd/sys/systm.h>
                     47: 
                     48: #import "IdeCnt.h"
                     49: #import "IdeCntInit.h"
                     50: #import "IdeCntCmds.h"
                     51: #import "IdeCntDma.h"
                     52: #import "AtapiCntCmds.h"
                     53: 
                     54: 
                     55: #define IDE_SYSCLK_NS  30
                     56: 
                     57: typedef struct
                     58: {
                     59:     int                accessTime;
                     60:     int                cycleTime;
                     61: } ideModes_t;
                     62: 
                     63: static ideModes_t pioModes[] =
                     64: {
                     65:     { 165,    600 },   /* Mode 0 */
                     66:     { 125,    383 },   /*      1 */ 
                     67:     { 100,    240 },   /*      2 */
                     68:     {  80,    180 },   /*      3 */
                     69:     {  70,    120 }    /*      4 */
                     70: };
                     71: #define MAX_PIO_MODES  (sizeof(pioModes) / sizeof(ideModes_t))
                     72: 
                     73: static ideModes_t singleWordModes[] =
                     74: {
                     75:     { 480,    960 },   /* Mode 0 */
                     76:     { 100,    480 },   /*      1 */
                     77:     { 120,    240 }    /*      2 */
                     78: };
                     79: #define MAX_SINGLEWORD_MODES  (sizeof(singleWordModes) / sizeof(ideModes_t))
                     80: 
                     81: static ideModes_t multiWordModes[] =
                     82: {
                     83:     { 215,    480 },   /* Mode 0 */
                     84:     {  80,    150 },   /*      1 */
                     85:     {  70,    120 }    /*      2 */
                     86: };
                     87: #define MAX_MULTIWORD_MODES  (sizeof(multiWordModes) / sizeof(ideModes_t))
                     88: 
                     89: 
                     90: static ideModes_t ultraModes[] =
                     91: {
                     92:     {   0,    114 },   /* Mode 0 */
                     93:     {   0,     75 },   /*      1 */
                     94:     {   0,     55 }    /*      2 */
                     95: };
                     96: 
                     97: #define MAX_ULTRA_MODES  (sizeof(ultraModes) / sizeof(ideModes_t))
                     98: 
                     99: 
                    100: static void endianSwap16Bit( volatile u_int16_t *p16 )
                    101: {
                    102:     u_int16_t     tmp16;
                    103:     
                    104:     tmp16 = *p16;
                    105:     tmp16 = (tmp16 >> 8) | (tmp16 << 8);
                    106:     *p16  = tmp16;
                    107: }
                    108: 
                    109: static void endianSwap32Bit( volatile u_int32_t *p32 )
                    110: {
                    111:     u_int32_t     tmp32;
                    112:     
                    113:     tmp32 = *p32;
                    114: 
                    115:     tmp32 = ( ((tmp32 & 0x000000ff) << 24)
                    116:             | ((tmp32 & 0x0000ff00) <<  8)
                    117:             | ((tmp32 & 0x00ff0000) >>  8)
                    118:             | ((tmp32 & 0xff000000) >> 24) );
                    119: 
                    120:     *p32  = tmp32;
                    121: }
                    122: 
                    123: static int rnddiv( int x, int y )
                    124: {
                    125:     if ( x < 0 )
                    126:       return 0;
                    127:     else
                    128:       return ( (x / y) + (( x % y ) ? 1 : 0) );
                    129: }
                    130: 
                    131: @implementation IdeController(Initialize)
                    132: 
                    133: 
                    134: /*
                    135:  * Check for MediaBay 
                    136:  *
                    137:  * Returns: NO  - MediaBay implementation with non-ATA/ATAPI option installed
                    138:  *          YES - Non-MediaBay implementation or MediaBay with ATA/ATAPI option
                    139:  */
                    140: - (BOOL) checkMediaBayOption: (IOTreeDevice *)deviceDescription
                    141: {
                    142:     int                        n;
                    143:     u_int32_t          *heathrowIdReg;
                    144:     u_int32_t          heathrowIds;
                    145:     IOTreeDevice       *devDescParent;
                    146:     char               *nodeNameParent;
                    147: 
                    148:     /*
                    149:      * Check for MediaBay implementation 
                    150:      */
                    151:     devDescParent  = [[deviceDescription parent] deviceDescription];
                    152:     nodeNameParent = [devDescParent nodeName];
                    153: 
                    154:     if ( strcmp( nodeNameParent, "media-bay" ) )
                    155:     {
                    156:         return YES;    /* Non-MediaBay implementation */
                    157:     }
                    158:     if ( (n = [devDescParent numMemoryRanges]) < 1 )
                    159:     {
                    160:         return YES;    /* Misc OF Device Tree problem */
                    161:     }
                    162:        
                    163:     /* 
                    164:      * Check for ATA/ATAPI MediaBay option installed
                    165:      */
                    166:     heathrowIdReg = (u_int32_t *)[devDescParent memoryRangeList][0].start; 
                    167:     heathrowIds   = *heathrowIdReg;
                    168:     endianSwap32Bit( &heathrowIds );
                    169: 
                    170:     if ( (heathrowIds & MEDIA_BAY_ID_MASK) == MEDIA_BAY_ID_CDROM )
                    171:     {
                    172:         return YES;    /* Media Bay with ATA/ATAPI option */
                    173:     }
                    174: 
                    175:     return NO; 
                    176: }
                    177: 
                    178: #define ATAPI_SIGNATURE_LOW            0x14
                    179: #define ATAPI_SIGNATURE_HIGH           0xeb
                    180: 
                    181: #define ATA_SIGNATURE_LOW              0x00
                    182: #define ATA_SIGNATURE_HIGH             0x00
                    183: 
                    184: /*
                    185:  * This is called just after resetting the drives connected to this
                    186:  * controller. We read the drive registers to figure out if it is an ATAPI
                    187:  * drive. If it is then we make a note of it and return YES. 
                    188:  */
                    189: - (BOOL)controllerPresent
                    190: {
                    191:     unsigned char dh;
                    192:     unsigned char unit;
                    193:     
                    194:     unit = 0;
                    195:     
                    196:     dh = _addressMode[unit];
                    197:     
                    198:     dh |= (unit ? SEL_DRIVE1 : SEL_DRIVE0);
                    199:     outb(_ideRegsAddrs.drHead, dh);
                    200: 
                    201:     /*
                    202:      * Test with some data. 
                    203:      */
                    204:     
                    205:     if (unit == 0)     
                    206:     {
                    207:        outb(_ideRegsAddrs.cylLow, 0xaa);
                    208:        outb(_ideRegsAddrs.cylHigh, 0xbb);
                    209:     } 
                    210:     else 
                    211:     {
                    212:        outb(_ideRegsAddrs.cylLow, 0xba);
                    213:        outb(_ideRegsAddrs.cylHigh, 0xbe);
                    214:     }
                    215:     
                    216:     if (unit == 0) 
                    217:     {
                    218:        if ((inb(_ideRegsAddrs.cylLow) != 0xaa) ||
                    219:            (inb(_ideRegsAddrs.cylHigh) != 0xbb)) 
                    220:         {
                    221:            return NO;
                    222:        }
                    223:     } 
                    224:     else 
                    225:     {
                    226:        if ((inb(_ideRegsAddrs.cylLow) != 0xba) ||
                    227:            (inb(_ideRegsAddrs.cylHigh) != 0xbe)) 
                    228:         {
                    229:            return NO;
                    230:        }
                    231:     }
                    232:     
                    233:     return YES;
                    234: }
                    235: 
                    236: 
                    237: /*
                    238:  * One-time only init. Returns NO on failure. 
                    239:  */
                    240: - (BOOL)ideControllerInit:(IOTreeDevice *)deviceDescription
                    241: {
                    242:     int                unit;
                    243:     int                drivesPresent = 0;
                    244:     ns_time_t          time, startTime;
                    245: 
                    246:     if ([self enableInterrupt:0]) {
                    247:                IOLog("ideControllerInit: failed enableAllInterrupts\n");
                    248:                return NO;
                    249:     }
                    250: 
                    251:     
                    252:     if ((_ideCmdLock = [NXLock new]) == NULL) {
                    253:                IOLog("ideControllerInit: failed _ideCmdLock\n");
                    254:        return NO;
                    255:     }
                    256:     
                    257:     /*
                    258:      * We don't want to execute any IDE commands from Disk until
                    259:      * initialization is complete. 
                    260:      */
                    261:     [self ideCntrlrLock];
                    262:     
                    263:     /*
                    264:      * Initialize the register address values.
                    265:      */
                    266:     [self assignRegisterAddresses: deviceDescription];
                    267:         
                    268:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
                    269:        _atapiDevice[unit] = NO;
                    270:     }
                    271:     
                    272:     /*
                    273:      * We have to test here if the controller is present or else we will
                    274:      * block looking for a drive (in ideReset). 
                    275:      */
                    276:     
                    277:     if ([self controllerPresent] == NO)        
                    278:     {
                    279:        IOLog("%s: no devices detected at port 0x%0x\n", [self name],
                    280:                _ideRegsAddrs.data);
                    281:        [self ideCntrlrUnLock];
                    282:        return NO;
                    283:     } 
                    284:     else 
                    285:     {
                    286:        IOLog("%s: device detected at port 0x%x irq %d\n", [self name], 
                    287:                        _ideRegsAddrs.data, [deviceDescription interrupt]);
                    288:     }
                    289:     
                    290:     _ideInterruptPort = [self interruptPort];
                    291:     _ideDevicePort = [deviceDescription devicePort];
                    292: 
                    293:     [self setInterruptTimeOut:IDE_INTR_TIMEOUT];
                    294: 
                    295:     _multiSectorRequested = YES;
                    296: 
                    297:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) 
                    298:     {
                    299:        _addressMode[unit] = ADDRESS_MODE_LBA;
                    300:     }
                    301: 
                    302:     _driveNum = unit;
                    303:     
                    304:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) 
                    305:     {
                    306:     
                    307:        bzero(&_ideInfo[unit], sizeof(ideDriveInfo_t));
                    308:        
                    309:        [self ideReset];
                    310:        
                    311:         IOGetTimestamp(&startTime);
                    312:        if ([self ideDetectDrive:unit] == YES)  
                    313:         {
                    314:            _ideInfo[unit].type = 255;
                    315:        }
                    316:         IOGetTimestamp(&time);
                    317:         time = (time - startTime) / (1000*1000);
                    318:         kprintf( "Disk(ata) - ideDetectDrive:%d - %d ms\n\r", unit, (u_int32_t)time ); 
                    319:  
                    320:        /*
                    321:         * If we didn't find ATA drive then look for ATAPI device. 
                    322:         */
                    323:        if ((_ideInfo[unit].type == 0)  && ([self ideDetectATAPIDevice:unit] == YES)) 
                    324:         {
                    325:            _ideInfo[unit].type = 127;
                    326:        }
                    327: 
                    328:        if (_ideInfo[unit].type != 0)
                    329:            drivesPresent += 1 ;
                    330:     }
                    331:     
                    332:     if (drivesPresent == 0)    
                    333:     {
                    334:        [self ideCntrlrUnLock];
                    335:        IOLog("ideControllerInit: failed drivesPresent\n");
                    336:        return NO;
                    337:     }
                    338: 
                    339:     /*
                    340:      * Initialization was successful. We should release the lock so that the
                    341:      * controller can now execute commands from disk objects. 
                    342:      */
                    343:     
                    344:     [self resetAndInit];
                    345: 
                    346:     /*
                    347:      * Set drive power state to active.
                    348:      */
                    349:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) 
                    350:     {
                    351:        if (_ideInfo[unit].type != 0)
                    352:            [self setDrivePowerState:IDE_PM_ACTIVE];
                    353:     }
                    354:     
                    355:     _driveSleepRequest = NO;
                    356:     
                    357:     [self enableInterrupts];
                    358: 
                    359:     [self ideCntrlrUnLock];
                    360:     
                    361:     return YES;
                    362: }    
                    363: 
                    364: #define ATA_RESET_DELAY                (30 * 1000)             /* milliseconds */
                    365: 
                    366: /*
                    367:  * Determine the presence and type of drive (IDE/ATAPI) attached to this
                    368:  * controller. 
                    369:  *
                    370:  */
                    371: 
                    372: -(BOOL)ideDetectDrive:(unsigned int)unit
                    373: {
                    374:     unsigned char      dh = _addressMode[unit];
                    375:     int                i;
                    376:     unsigned char      status;
                    377:     BOOL               found = NO;
                    378: 
                    379:     [self disableInterrupts];
                    380:     
                    381:     dh |= (unit ? SEL_DRIVE1 : SEL_DRIVE0);
                    382:     outb(_ideRegsAddrs.drHead, dh);
                    383:     IODelay(10);
                    384: 
                    385:     status = inb(_ideRegsAddrs.status);
                    386:     if ( !(status & READY) )
                    387:     {
                    388:         return found;
                    389:     }
                    390:   
                    391:     outb(_ideRegsAddrs.command, IDE_IDENTIFY_DRIVE);
                    392: 
                    393:     for (i = 0; i < (ATA_RESET_DELAY * 5); i++) 
                    394:     {
                    395:        IODelay(200);
                    396:         status = inb(_ideRegsAddrs.status);
                    397: 
                    398:        if ((!(status & BUSY)) && (status & (ERROR | WRITE_FAULT | ERROR_CORRECTED)) )
                    399:         {
                    400:            break;                              /* certain failure */
                    401:        }
                    402:        
                    403:        if ((!(status & BUSY)) && (status & DREQUEST))  
                    404:         {
                    405:            found = YES;                        /* success */
                    406:            break;
                    407:        }    
                    408:     }
                    409: 
                    410:     return found;    
                    411: }
                    412: 
                    413: /*
                    414:  * We send the device ATAPI soft reset command and check for signature. This
                    415:  * is the first command that ATAPI devices need. 
                    416:  */
                    417: -(BOOL)ideDetectATAPIDevice:(unsigned int)unit
                    418: {
                    419:     unsigned char low, high;
                    420:     BOOL found = NO;
                    421:        
                    422:     [self atapiSoftReset:unit];
                    423: 
                    424:     low = inb(_ideRegsAddrs.cylLow);
                    425:     high = inb(_ideRegsAddrs.cylHigh);
                    426:     
                    427:     if ((low == ATAPI_SIGNATURE_LOW) && (high == ATAPI_SIGNATURE_HIGH))
                    428:     {
                    429:        _atapiDevice[unit] = YES;
                    430:        IOLog("%s: ATAPI device %d detected.\n", [self name], unit);
                    431:        found = YES;
                    432:     }
                    433:     /*
                    434:      * Clear ATAPI signature
                    435:      */
                    436:     outb(_ideRegsAddrs.cylLow, 0 );
                    437:     outb(_ideRegsAddrs.cylHigh, 0 );
                    438:     
                    439:     return found;    
                    440: }
                    441: 
                    442: 
                    443: -(ideDriveInfo_t *)getIdeDriveInfo:(unsigned int)unit
                    444: {
                    445:     return &_ideInfo[unit];
                    446: }
                    447: 
                    448: #define MAX_RESET_ATTEMPTS             2
                    449: 
                    450: - (void)ideReset
                    451: {
                    452:     int                count;
                    453:     int                delay;
                    454:     unsigned char      status;
                    455: 
                    456:     for ( count = 0; count < MAX_IDE_DRIVES; count++ )
                    457:     {
                    458:         _driveReset[count] = YES;
                    459:     }
                    460: 
                    461:     for (count = 0; count < MAX_RESET_ATTEMPTS; count++) 
                    462:     {
                    463:        outb(_ideRegsAddrs.deviceControl, DISK_RESET_ENABLE);
                    464:        IODelay(100);                   /* spec >= 25 us */
                    465:        outb(_ideRegsAddrs.deviceControl, 0x0);
                    466:        
                    467:        [self enableInterrupts];
                    468: 
                    469:        delay = 31 * 1000 * 1000;       /* thirty one seconds */
                    470:        
                    471:        IOSleep(1000);                  /* Enough time to assert busy */
                    472:        
                    473:        while (delay > 0) 
                    474:         {
                    475:            status = inb(_ideRegsAddrs.status);
                    476:            if (!(status & BUSY)) 
                    477:             {
                    478:                return;
                    479:            }
                    480:            
                    481:            IOSleep(1);
                    482:            delay -= 1000;
                    483:        }
                    484:        
                    485:        IOLog("%s: Reset failed, retrying..\n", [self name]);
                    486:        IOSleep(2000);
                    487:     }    
                    488: }
                    489: 
                    490: 
                    491: /*
                    492:  * Initialize the IDE interface. Find about drive capabilities (by
                    493:  * IDE_IDENTIFY_DRIVE command) and configure drive.
                    494:  * 
                    495:  * By the time we enter this routine we know about all devices connected to this controller. 
                    496:  */
                    497: - (void)resetAndInit
                    498: {
                    499:     int                        i;
                    500:     unsigned char              unit;
                    501:     ide_return_t               rtn;
                    502:     atapi_return_t             atapi_rtn;
                    503:     BOOL                       ataDevicePresent;
                    504: 
                    505:     /*
                    506:      * If there is at least one ATA drive connected to this controller then
                    507:      * is is not necessary to (ATA style) reset them. We use the ATAPI reset
                    508:      * instead. 
                    509:      */
                    510:     ataDevicePresent = NO;
                    511:     for (i = 0; i < MAX_IDE_DRIVES; i++)       
                    512:     {
                    513:        if ((_ideInfo[i].type != 0) && ([self isAtapiDevice:i] == NO))
                    514:         {
                    515:            ataDevicePresent = YES;
                    516:            break;
                    517:        }
                    518:     }
                    519: 
                    520:     if (ataDevicePresent == YES)       
                    521:     {
                    522:        [self ideReset];
                    523:     }
                    524:     
                    525:     /*
                    526:      * Send the controller necessary commands to set capabilities and then
                    527:      * set drive parameters. It is necessary to set drive parameters before
                    528:      * any data I/O can be done from the disk. 
                    529:      */
                    530:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) 
                    531:     {
                    532:        if (_ideInfo[unit].type == 0)   
                    533:         {
                    534:            continue;
                    535:        }
                    536:        
                    537:        _driveNum = unit;
                    538: 
                    539:         _cycleTimes[unit].pioMode = 0;
                    540:         _cycleTimes[unit].pioAccessTime  = pioModes[0].accessTime;
                    541:         _cycleTimes[unit].pioCycleTime   = pioModes[0].cycleTime;
                    542: 
                    543:         [self calcIdeConfig: unit];          
                    544:        
                    545:        if ( [self isAtapiDevice:unit] == YES ) 
                    546:         {
                    547:            [self atapiSoftReset:unit];
                    548: 
                    549:            /*
                    550:             * We have to do this test because of "task file shadow" bug
                    551:             * present in many ATAPI CD-ROMs. 
                    552:             */
                    553:            atapi_rtn = 
                    554:                [self atapiIdentifyDevice:(struct vm_map *)IOVmTaskSelf() 
                    555:                    addr:(unsigned char *)&_ideIdentifyInfo[unit] unit:unit];
                    556:                
                    557:            /* Too bad.. */
                    558:            if (atapi_rtn != IDER_SUCCESS)      
                    559:             {
                    560:                _atapiDevice[unit] = NO;
                    561:                _ideInfo[unit].type = 0;
                    562:                continue;
                    563:            }
                    564:                
                    565:             [self endianSwapIdentifyData: &_ideIdentifyInfo[unit]];
                    566: 
                    567:            [self printAtapiInfo:&_ideIdentifyInfo[unit] Device:unit];
                    568:            [self atapiInitParameters:&_ideIdentifyInfo[unit] Device:unit];
                    569:            continue;
                    570:        }
                    571: 
                    572:        rtn = [self setATADriveCapabilities:unit];
                    573:        if (rtn != IDER_SUCCESS)        
                    574:         {
                    575:                _ideInfo[unit].type = 0;
                    576:                continue;
                    577:        }
                    578:     }
                    579: }
                    580: 
                    581: /*
                    582:  * FIXME: Need to figure out multi-word DMA.
                    583:  */
                    584: - (ide_return_t)getTransferModes:(ideIdentifyInfo_t *)infoPtr Unit: (int)unit
                    585: {
                    586:     int                i, n;
                    587:      
                    588:     int         pioMode                = 0;
                    589:     int                pioCycleTime    = 0;
                    590:     int         dmaMode                = 0;
                    591:     int         dmaType                = IDE_DMA_NONE;
                    592:     int         dmaCycleTime   = 0;
                    593:     
                    594:     /*
                    595:      *  PIO Cycle timing......  
                    596:      *
                    597:      *  1. Try to match Word 51 (pioCycleTime) with cycle timings
                    598:      *     in our pioModes table to get mode/CycleTime. (Valid for Modes 0-2)
                    599:      *  2. If Words 64-68 are supported and Mode 3 or 4 supported check, 
                    600:      *     update CycleTime with Word 68 (CycleTimeWithIORDY).
                    601:      */
                    602: 
                    603:     pioCycleTime = infoPtr->pioDataTransferCyleTimingMode;
                    604: 
                    605:     if ( pioCycleTime > 2 )
                    606:     {
                    607:         for ( i=MAX_PIO_MODES-1; i != -1; i-- )
                    608:         {
                    609:             if ( pioCycleTime <= pioModes[i].cycleTime )
                    610:             {
                    611:                 pioMode = i;
                    612:                 break;
                    613:             }
                    614:          }
                    615: 
                    616:          if ( i == -1 )
                    617:          {
                    618:              pioCycleTime = pioModes[pioMode].cycleTime;
                    619:          }
                    620:     }
                    621:     else
                    622:     {
                    623:         pioMode      = pioCycleTime;
                    624:         pioCycleTime = pioModes[pioMode].cycleTime;
                    625:     }
                    626: 
                    627:     if (infoPtr->fieldValidity & IDE_WORDS64_TO_68_SUPPORTED) 
                    628:     {
                    629:        if (infoPtr->fcPioDataTransferCyleTimingMode & IDE_FC_PIO_MODE_4_SUPPORTED)
                    630:             pioMode = 4;
                    631:        else if (infoPtr->fcPioDataTransferCyleTimingMode & IDE_FC_PIO_MODE_3_SUPPORTED)
                    632:             pioMode = 3;
                    633: 
                    634:         if ( (pioMode >= 3) && infoPtr->MinPIOTransferCycleTimeWithIORDY )
                    635:         {
                    636:             pioCycleTime = infoPtr->MinPIOTransferCycleTimeWithIORDY;
                    637:         }
                    638:     }
                    639:     
                    640:     /* 
                    641:      *  Ultra DMA timing.....
                    642:      *
                    643:      */                                                                
                    644:     if ( (_controllerType == kControllerTypeCmd646X) && (infoPtr->fieldValidity & IDE_WORD_88_SUPPORTED) ) 
                    645:     {
                    646:         n = infoPtr->ultraDma & IDE_ULTRA_DMA_SUPPORTED;
                    647:         if ( n )
                    648:         {
                    649:             dmaType = IDE_DMA_ULTRA;
                    650:             for ( i=0; n; i++, n>>=1 )
                    651:               ;
                    652: 
                    653:             dmaMode = i - 1;
                    654:             if ( dmaMode > MAX_ULTRA_MODES-1 )
                    655:             {
                    656:                 dmaMode = MAX_ULTRA_MODES-1;
                    657:             }
                    658:             dmaCycleTime = ultraModes[dmaMode].cycleTime;
                    659: 
                    660:             goto getCycleTimes_exit;
                    661:         }
                    662:     }
                    663:             
                    664:     /* 
                    665:      *  Multiword DMA timing.....
                    666:      *
                    667:      *  1. Check Word 63(7:0) (Multiword DMA Modes Supported). Lookup
                    668:      *     CycleTime for highest mode we support.
                    669:      *  2. If Words 64-68 supported, update CycleTime from Word 66
                    670:      *     (RecommendedMultiWordCycleTime) if specified.
                    671:      */                                                                
                    672: 
                    673:     n = infoPtr->mwDma & IDE_MW_DMA_SUPPORTED;
                    674:     if ( n )
                    675:     {
                    676:         dmaType = IDE_DMA_MULTIWORD;
                    677:         for ( i=0; n; i++, n>>=1 )
                    678:           ;
                    679: 
                    680:         dmaMode = i - 1;
                    681:         if ( dmaMode > MAX_MULTIWORD_MODES-1 )
                    682:         {
                    683:             dmaMode = MAX_MULTIWORD_MODES-1;
                    684:         }
                    685:         dmaCycleTime = multiWordModes[dmaMode].cycleTime;
                    686: 
                    687:         if (infoPtr->fieldValidity & IDE_WORDS64_TO_68_SUPPORTED) 
                    688:         {
                    689:             if ( infoPtr->RecommendedMwDMACycleTime )
                    690:             {
                    691:                 dmaCycleTime = infoPtr->RecommendedMwDMACycleTime;
                    692:             }
                    693:         }
                    694:         goto getCycleTimes_exit;
                    695:     }
                    696: 
                    697:     /*
                    698:      *  Single Word DMA timing.....
                    699:      *
                    700:      *  1. If Word 64(7:0) (SingleWord DMA Modes supported) is non-zero,
                    701:      *     find highest supported mode and get CycleTime from table.
                    702:      *  2. If Word 64(7:0) (SingleWord DMA Modes supported) is zero,
                    703:      *     then match Word 52 (Single Word DMA Cycle Time) against
                    704:      *     cycle times in singleWordModes table.
                    705:      */          
                    706:        
                    707:     n = infoPtr->swDma & IDE_SW_DMA_SUPPORTED;
                    708:     if ( n )
                    709:     {
                    710:         dmaType = IDE_DMA_SINGLEWORD;
                    711:         for ( i=0; n; i++, n>>=1 )
                    712:           ;
                    713: 
                    714:         dmaMode = i - 1;
                    715:         if ( dmaMode > MAX_SINGLEWORD_MODES-1 )
                    716:         {
                    717:             dmaMode = MAX_SINGLEWORD_MODES-1;
                    718:         }
                    719:         dmaCycleTime = singleWordModes[dmaMode].cycleTime;
                    720:     }
                    721:     else
                    722:     {
                    723:         dmaCycleTime = infoPtr->dmaDataTransferCyleTimingMode;
                    724:         for ( i=MAX_SINGLEWORD_MODES-1; i != -1; i-- )
                    725:         {
                    726:             if ( dmaCycleTime <= singleWordModes[i].cycleTime )
                    727:             {
                    728:                 dmaType = IDE_DMA_SINGLEWORD;
                    729:                 dmaMode = i;
                    730:                 dmaCycleTime = singleWordModes[i].cycleTime;
                    731:                 break;
                    732:             }
                    733:         }
                    734:     }
                    735: 
                    736: 
                    737: getCycleTimes_exit: ;
                    738: 
                    739:     _cycleTimes[unit].pioCycleTime   = pioCycleTime;
                    740:     _cycleTimes[unit].pioAccessTime  = pioModes[pioMode].accessTime;
                    741:     _cycleTimes[unit].pioMode        = pioMode;
                    742: 
                    743:     if ( dmaType != IDE_DMA_NONE )
                    744:     {
                    745:         _cycleTimes[unit].dmaType        = dmaType;
                    746:         _cycleTimes[unit].dmaMode        = dmaMode;
                    747:         _cycleTimes[unit].dmaCycleTime   = dmaCycleTime;
                    748:         switch ( dmaMode )
                    749:         {
                    750:             case IDE_DMA_SINGLEWORD:
                    751:                 _cycleTimes[unit].dmaAccessTime = singleWordModes[dmaMode].accessTime;
                    752:                 break;
                    753:             case IDE_DMA_MULTIWORD:
                    754:                 _cycleTimes[unit].dmaAccessTime = multiWordModes[dmaMode].accessTime;
                    755:                 break;
                    756:             case IDE_DMA_ULTRA:
                    757:                 _cycleTimes[unit].dmaAccessTime = ultraModes[dmaMode].accessTime;
                    758:                 break;
                    759:         }    
                    760:     }
                    761: 
                    762:     [self calcIdeConfig: (int)unit];
                    763: 
                    764:     
                    765:     return IDER_SUCCESS;
                    766: }
                    767: 
                    768: -(void) calcIdeConfig:(int)unit
                    769: {
                    770:     _cycleTimes[unit].fChanged = YES;
                    771: 
                    772:     if ( _controllerType == kControllerTypeCmd646X )
                    773:     {
                    774:         [self calcIdeTimingsCmd646X:unit];
                    775:     }
                    776:     else
                    777:     {
                    778:         [self calcIdeTimingsDBDMA:unit];
                    779:     }
                    780: }
                    781: 
                    782: -(void) calcIdeTimingsCmd646X:(int) unit
                    783: {
                    784:     u_int32_t          cycleClks;
                    785:     u_int32_t          cycleTime,  accessTime;
                    786:     u_int32_t          drwActClks, drwRecClks;
                    787:     u_int32_t          drwActTime, drwRecTime;
                    788:    
                    789:     _cycleTimes[unit].ideConfig.cmd646XConfig.arttimReg  = 0x40;
                    790:     _cycleTimes[unit].ideConfig.cmd646XConfig.cmdtimReg  = 0xA9;
                    791: 
                    792:     accessTime = pioModes[_cycleTimes[unit].pioMode].accessTime;
                    793: 
                    794:     drwActClks    =  accessTime / IDE_SYSCLK_NS;
                    795:     drwActClks   += (accessTime % IDE_SYSCLK_NS) ? 1 : 0;
                    796:     drwActTime    = drwActClks * IDE_SYSCLK_NS;
                    797: 
                    798:     drwRecTime    = pioModes[_cycleTimes[unit].pioMode].cycleTime - drwActTime;
                    799:     drwRecClks    = drwRecTime / IDE_SYSCLK_NS;
                    800:     drwRecClks   += (drwRecTime % IDE_SYSCLK_NS) ? 1 : 0;
                    801: 
                    802:     if ( drwRecClks >= 16 ) 
                    803:         drwRecClks = 1;
                    804:     else if ( drwRecClks <= 1 )
                    805:         drwRecClks = 16;
                    806: 
                    807:     _cycleTimes[unit].ideConfig.cmd646XConfig.drwtimRegPIO = ((drwActClks & 0x0f) << 4) | ((drwRecClks-1)  & 0x0f);
                    808: 
                    809: 
                    810:     _cycleTimes[unit].ideConfig.cmd646XConfig.udidetcrReg = 0;      
                    811: 
                    812:     if ( _cycleTimes[unit].dmaType == IDE_DMA_ULTRA )
                    813:     {
                    814:         cycleTime = _cycleTimes[unit].dmaCycleTime;
                    815:         
                    816:         cycleClks  = cycleTime / IDE_SYSCLK_NS;
                    817:         cycleClks += (cycleTime % IDE_SYSCLK_NS) ? 1 : 0;
                    818: 
                    819:         _cycleTimes[unit].ideConfig.cmd646XConfig.udidetcrReg = (0x01 << unit) | ((cycleClks-1) << ((!unit) ? 4 : 6)) ;  
                    820:     }
                    821:     else if ( _cycleTimes[unit].dmaType != IDE_DMA_NONE )
                    822:     {
                    823:         accessTime    = _cycleTimes[unit].dmaAccessTime;
                    824: 
                    825:         drwActClks    =  accessTime / IDE_SYSCLK_NS;
                    826:         drwActClks   += (accessTime % IDE_SYSCLK_NS) ? 1 : 0;
                    827:         drwActTime    = drwActClks * IDE_SYSCLK_NS;
                    828: 
                    829:         drwRecTime    = _cycleTimes[unit].dmaCycleTime - drwActTime;
                    830:         drwRecClks    = drwRecTime / IDE_SYSCLK_NS;
                    831:         drwRecClks   += (drwRecTime % IDE_SYSCLK_NS) ? 1 : 0;
                    832: 
                    833:         if ( drwRecClks >= 16 ) 
                    834:             drwRecClks = 1;
                    835:         else if ( drwRecClks <= 1 )
                    836:             drwRecClks = 16;
                    837: 
                    838:         _cycleTimes[0].ideConfig.cmd646XConfig.drwtimRegDMA = ((drwActClks & 0x0f) << 4) | ((drwRecClks-1)  & 0x0f);        
                    839:     }
                    840: }
                    841:         
                    842:  
                    843: 
                    844: -(void) calcIdeTimingsDBDMA:(int) unit
                    845: {
                    846:     int                        accessTime;
                    847:     int                        accessTicks;
                    848:     int                recTime;
                    849:     int                        recTicks;
                    850:     int                        cycleTime;
                    851:     int                 cycleTimeOrig;
                    852:     int                halfTick = 0;
                    853:     uint                ideConfigWord = 0;
                    854: 
                    855:     /*
                    856:      * Calc PIO access time >= pioAccessTime in SYSCLK increments
                    857:      */
                    858:     accessTicks = rnddiv(_cycleTimes[unit].pioAccessTime, IDE_SYSCLK_NS);
                    859:     /*
                    860:      * Hardware limits access times to >= 120 ns 
                    861:      */
                    862:     accessTicks -= IDE_PIO_ACCESS_BASE;
                    863:     if (accessTicks < IDE_PIO_ACCESS_MIN )
                    864:     {
                    865:         accessTicks = IDE_PIO_ACCESS_MIN;
                    866:     }
                    867:     accessTime = (accessTicks + IDE_PIO_ACCESS_BASE) * IDE_SYSCLK_NS;
                    868: 
                    869:     /*
                    870:      * Calc recovery time in SYSCLK increments based on time remaining in cycle
                    871:      */
                    872:     recTime = _cycleTimes[unit].pioCycleTime - accessTime;
                    873:     recTicks = rnddiv( recTime, IDE_SYSCLK_NS );
                    874:     /*
                    875:      * Hardware limits recovery time to >= 150ns 
                    876:      */
                    877:     recTicks -= IDE_PIO_RECOVERY_BASE;
                    878:     if ( recTicks < IDE_PIO_RECOVERY_MIN )
                    879:     {
                    880:       recTicks = IDE_PIO_RECOVERY_MIN;
                    881:     }
                    882: 
                    883:     cycleTime = (recTicks + IDE_PIO_RECOVERY_BASE + accessTicks + IDE_PIO_ACCESS_BASE) * IDE_SYSCLK_NS;
                    884: 
                    885:     ideConfigWord = accessTicks | (recTicks << 5);
                    886: 
                    887:     kprintf("Disk(ata): Controller Base = %08x\n\r", _ideRegsAddrs.data );
                    888:     kprintf("Disk(ata): Unit %1d: PIO Requested Timings: Access: %3dns Cycle: %3dns \n\r", 
                    889:              unit, _cycleTimes[unit].pioAccessTime, _cycleTimes[unit].pioCycleTime);
                    890:     kprintf("Disk(ata):         PIO Actual    Timings: Access: %3dns Cycle: %3dns\n\r",
                    891:              accessTime, cycleTime );
                    892: 
                    893:     if ( _cycleTimes[unit].dmaType == IDE_DMA_NONE )
                    894:     {
                    895:       goto calcConfigWordDone;
                    896:     }
                    897: 
                    898:     /*
                    899:      * Calc DMA access time >= dmaAccessTime in SYSCLK increments
                    900:      */
                    901: 
                    902:     /*
                    903:      * OHare II erata - Cant handle write cycle times below 150ns
                    904:      */
                    905:     cycleTimeOrig = _cycleTimes[unit].dmaCycleTime;
                    906:     if ( IsPowerStar() )
                    907:     {
                    908:         if ( cycleTimeOrig < 150 ) _cycleTimes[unit].dmaCycleTime = 150;
                    909:     }
                    910: 
                    911:     accessTicks = rnddiv(_cycleTimes[unit].dmaAccessTime, IDE_SYSCLK_NS);
                    912: 
                    913:     accessTicks -= IDE_DMA_ACCESS_BASE;
                    914:     if ( accessTicks < IDE_DMA_ACCESS_MIN )
                    915:     {
                    916:         accessTicks = IDE_DMA_ACCESS_MIN;
                    917:     }
                    918:     accessTime = (accessTicks + IDE_DMA_ACCESS_BASE) * IDE_SYSCLK_NS;
                    919: 
                    920:     /*
                    921:      * Calc recovery time in SYSCLK increments based on time remaining in cycle
                    922:      */
                    923:     recTime = _cycleTimes[unit].dmaCycleTime - accessTime;    
                    924:     recTicks = rnddiv( recTime, IDE_SYSCLK_NS );
                    925: 
                    926:     recTicks -= IDE_DMA_RECOVERY_BASE;
                    927:     if ( recTicks < IDE_DMA_RECOVERY_MIN )
                    928:     {
                    929:         recTicks = IDE_DMA_RECOVERY_MIN;
                    930:     }
                    931:     cycleTime = (recTicks + IDE_DMA_RECOVERY_BASE + accessTicks + IDE_DMA_ACCESS_BASE) * IDE_SYSCLK_NS;
                    932:  
                    933:     /*
                    934:      * If our calculated access time is at least SYSCLK/2 > than what the disk requires, 
                    935:      * see if selecting the 1/2 Clock option will help. This adds SYSCLK/2 to 
                    936:      * the access time and subtracts SYSCLK/2 from the recovery time.
                    937:      * 
                    938:      * By setting the H-bit and subtracting one from the current access tick count,
                    939:      * we are reducing the current access time by SYSCLK/2 and the current recovery
                    940:      * time by SYSCLK/2. Now, check if the new cycle time still meets the disk's requirements.
                    941:      */  
                    942:     if ( (accessTicks > IDE_DMA_ACCESS_MIN) &&  ((accessTime - IDE_SYSCLK_NS/2) >= _cycleTimes[unit].dmaAccessTime) )
                    943:     {
                    944:         if ( (cycleTime - IDE_SYSCLK_NS) >= _cycleTimes[unit].dmaCycleTime )
                    945:         {
                    946:             halfTick    = 1;
                    947:             accessTicks--;
                    948:             accessTime -= IDE_SYSCLK_NS/2;
                    949:             cycleTime  -= IDE_SYSCLK_NS;
                    950:         }
                    951:     }
                    952: 
                    953:     ideConfigWord |= (accessTicks | (recTicks << 5) | (halfTick << 10)) << 11;
                    954: 
                    955:     kprintf("Disk(ata):         DMA Requested Timings: Access: %3dns Cycle: %3dns \n\r",  
                    956:              _cycleTimes[unit].dmaAccessTime, cycleTimeOrig);
                    957:     kprintf("Disk(ata):         DMA Actual    Timings: Access: %3dns Cycle: %3dns\n\r",   
                    958:              accessTime, cycleTime );
                    959: 
                    960: calcConfigWordDone: ;
                    961:     endianSwap32Bit( &ideConfigWord );
                    962:     _cycleTimes[unit].ideConfig.dbdmaConfig = ideConfigWord;
                    963: 
                    964: }
                    965: 
                    966: 
                    967: /*
                    968:  * Send the Set Parameters command to the drive and set multi-sector mode
                    969:  * etc. if the drive supports them. If biosInfo is YES, then we are using
                    970:  * drive geometry information from the BIOS else we use Identify command to
                    971:  * get this. 
                    972:  */
                    973: - (ide_return_t)setATADriveCapabilities:(unsigned int)unit     
                    974: {
                    975:     ideRegsVal_t               ideRegs;
                    976:     unsigned char              nSectors;
                    977:     char                       *buf;
                    978:     
                    979:     ideIdentifyInfo_t          *infoPtr = &_ideIdentifyInfo[unit];
                    980: 
                    981: 
                    982:     _multiSector[unit] = 0;
                    983:     _dmaSupported[unit] = NO;
                    984: 
                    985:     _ideIdentifyInfoSupported[unit] = YES;
                    986:     bzero(infoPtr, sizeof(ideIdentifyInfo_t));
                    987: 
                    988:     /*
                    989:      * Remember this command is optional. Failure means that either this
                    990:      * command is not supported or the drive is not present.
                    991:      */
                    992:     _driveNum = unit;
                    993: 
                    994:     [self setTransferRate: _driveNum UseDMA:NO];
                    995: 
                    996:     if ([self ideReadGetInfoCommon:&ideRegs 
                    997:                client:(struct vm_map *)IOVmTaskSelf() 
                    998:                addr:(unsigned char *)infoPtr
                    999:                command:IDE_IDENTIFY_DRIVE] != IDER_SUCCESS) 
                   1000:     {
                   1001:        _ideIdentifyInfoSupported[unit] = NO;
                   1002:        [self ideReset];        /* necessary */
                   1003:         return IDER_CMD_ERROR;
                   1004:     }
                   1005: 
                   1006:     [self endianSwapIdentifyData: infoPtr];
                   1007: 
                   1008:     /*
                   1009:      * Fill in this struct similar to which we would have gotten from CMOS. 
                   1010:      */
                   1011:     _ideInfo[unit].cylinders           = _ideIdentifyInfo[unit].cylinders;
                   1012:     _ideInfo[unit].heads               = _ideIdentifyInfo[unit].heads;
                   1013:     _ideInfo[unit].control_byte        = 0;
                   1014:     _ideInfo[unit].landing_zone        = 0;
                   1015:     _ideInfo[unit].sectors_per_trk     = _ideIdentifyInfo[unit].sectorsPerTrack;
                   1016:     _ideInfo[unit].bytes_per_sector    = IDE_SECTOR_SIZE;
                   1017: 
                   1018:     if ( infoPtr->capabilities & IDE_CAP_LBA_SUPPORTED)
                   1019:     {
                   1020:     _ideInfo[unit].total_sectors = infoPtr->userAddressableSectors;
                   1021:     }
                   1022:     else
                   1023:     {
                   1024:         _ideInfo[unit].total_sectors = _ideInfo[unit].sectors_per_trk  
                   1025:                                        * _ideInfo[unit].heads 
                   1026:                                        * _ideInfo[unit].cylinders;
                   1027:     }
                   1028: 
                   1029:     /*
                   1030:      * Set address mode. The only case in which we need to override user
                   1031:      * selection if the user chooses LBA and the drive supports only CHS. 
                   1032:      */
                   1033:     if ((infoPtr->capabilities & IDE_CAP_LBA_SUPPORTED) == 0x0)        
                   1034:     {
                   1035:        _addressMode[unit] = ADDRESS_MODE_CHS;
                   1036:     }
                   1037: 
                   1038:     /*
                   1039:      * Set disk parameters. 
                   1040:      */
                   1041:     [self ideSetParams:_ideInfo[unit].sectors_per_trk
                   1042:            numHeads:_ideInfo[unit].heads ForDrive:unit];
                   1043: 
                   1044:     /*
                   1045:      * Decide how are we going to do data transfers. Is DMA supported?
                   1046:      * Multisector support? Verify that the data transfer mode really works
                   1047:      * by doing a read operation in that mode. 
                   1048:      */
                   1049:     [self getTransferModes:infoPtr Unit:unit];
                   1050: 
                   1051:     /*
                   1052:      * Set the Disk/CDROM transfer mode (Set Features SC=3) 
                   1053:      */
                   1054:     [self setTransferMode: unit]; 
                   1055: 
                   1056:     if (infoPtr->capabilities & IDE_CAP_DMA_SUPPORTED) 
                   1057:     {
                   1058:         if ( [self allocDmaMemory] == IDER_SUCCESS )
                   1059:         { 
                   1060:             _dmaSupported[unit] = YES;
                   1061:             [self initIdeDma: unit];
                   1062:         }
                   1063:     }
                   1064: 
                   1065:     /*
                   1066:      * We don't expect errors here since the drive claims that it can do
                   1067:      * multiple sector transfers.
                   1068:      */
                   1069:     nSectors = infoPtr->multipleSectors & IDE_MULTI_SECTOR_MASK;
                   1070: 
                   1071:     if ( nSectors )    
                   1072:     {  
                   1073:        if ([self ideSetMultiSectorMode:&ideRegs
                   1074:                         numSectors:nSectors] == IDER_SUCCESS) 
                   1075:         {
                   1076: 
                   1077:             [self setTransferRate: unit UseDMA: NO];
                   1078: 
                   1079:            _multiSector[unit] = nSectors;
                   1080:            ideRegs = [self logToPhys:0 numOfBlocks:nSectors];
                   1081: 
                   1082:            buf = IOMalloc(nSectors * IDE_SECTOR_SIZE);
                   1083:            if ([self ideReadMultiple:&ideRegs 
                   1084:                        client:(struct vm_map *)IOVmTaskSelf()
                   1085:                        addr:buf] != IDER_SUCCESS)      
                   1086:             {
                   1087:                IOLog("%s: Read Multiple does not work!\n", [self name]);
                   1088:                _multiSector[unit] = 0;
                   1089:            }
                   1090:            IOFree(buf, nSectors * IDE_SECTOR_SIZE);
                   1091:        }
                   1092:     }
                   1093:     /*
                   1094:      * A drive may not support set features command. Do we need to do
                   1095:      * anything special if this command fails?
                   1096:      */
                   1097: 
                   1098:     return IDER_SUCCESS;
                   1099: }
                   1100: 
                   1101: -(ideIdentifyInfo_t *)getIdeIdentifyInfo:(unsigned int)unit
                   1102: {
                   1103:     return _ideIdentifyInfoSupported[unit] ? &_ideIdentifyInfo[unit] : NULL;
                   1104: }
                   1105: 
                   1106: -(void)endianSwapIdentifyData:(ideIdentifyInfo_t *)pID
                   1107: {
                   1108:     endianSwap16Bit(&pID->genConfig);
                   1109:     endianSwap16Bit(&pID->cylinders);
                   1110:     endianSwap16Bit(&pID->heads);
                   1111:     endianSwap16Bit(&pID->unformattedBytesPerTrack);
                   1112:     endianSwap16Bit(&pID->unformattedBytesPerSector);
                   1113:     endianSwap16Bit(&pID->sectorsPerTrack);
                   1114:     endianSwap16Bit(&pID->bufferType);
                   1115:     endianSwap16Bit(&pID->bufferSize); 
                   1116:     endianSwap16Bit(&pID->eccBytes); 
                   1117:     endianSwap16Bit(&pID->multipleSectors);
                   1118:     endianSwap16Bit(&pID->doubleWordIO);                       
                   1119:     endianSwap16Bit(&pID->capabilities);
                   1120:     endianSwap16Bit(&pID->pioDataTransferCyleTimingMode);
                   1121:     endianSwap16Bit(&pID->dmaDataTransferCyleTimingMode);
                   1122:     endianSwap16Bit(&pID->fieldValidity);      
                   1123:     endianSwap16Bit(&pID->currentCylinders);
                   1124:     endianSwap16Bit(&pID->currentHeads);
                   1125:     endianSwap16Bit(&pID->currentSectorsPerTrack);
                   1126:     endianSwap16Bit(&pID->capacity[0]);
                   1127:     endianSwap16Bit(&pID->capacity[1]);        
                   1128:     endianSwap16Bit(&pID->multiSectorInfo);
                   1129:     endianSwap32Bit(&pID->userAddressableSectors);             
                   1130:     endianSwap16Bit(&pID->swDma);      
                   1131:     endianSwap16Bit(&pID->mwDma);      
                   1132:     endianSwap16Bit(&pID->ultraDma);   
                   1133:     endianSwap16Bit(&pID->fcPioDataTransferCyleTimingMode); 
                   1134:     endianSwap16Bit(&pID->minMwDMATransferCycleTimePerWord);
                   1135:     endianSwap16Bit(&pID->RecommendedMwDMACycleTime);
                   1136:     endianSwap16Bit(&pID->MinPIOTransferCycleTimeWithoutFlowControl);
                   1137:     endianSwap16Bit(&pID->MinPIOTransferCycleTimeWithIORDY);
                   1138: } 
                   1139: 
                   1140: -(void) assignRegisterAddresses: (IOTreeDevice *) deviceDescription
                   1141: {
                   1142:   
                   1143:     if ( _controllerType == kControllerTypeCmd646X )
                   1144:     {
                   1145:         u_int32_t              pciRange1, pciRange2;
                   1146: 
                   1147:         [self mapMemoryRange: 0 to:(vm_address_t *)&pciRange1 findSpace:YES cache:IO_CacheOff];
                   1148:         [self mapMemoryRange: 1 to:(vm_address_t *)&pciRange2 findSpace:YES cache:IO_CacheOff];
                   1149: 
                   1150:         _ideRegsAddrs.data      = pciRange1;    
                   1151:         _ideRegsAddrs.error    = pciRange1 + 0x1;
                   1152:         _ideRegsAddrs.features         = pciRange1 + 0x1;
                   1153:         _ideRegsAddrs.sectCnt  = pciRange1 + 0x2;
                   1154:         _ideRegsAddrs.sectNum  = pciRange1 + 0x3;
                   1155:         _ideRegsAddrs.cylLow   = pciRange1 + 0x4;
                   1156:         _ideRegsAddrs.cylHigh  = pciRange1 + 0x5;
                   1157:         _ideRegsAddrs.drHead   = pciRange1 + 0x6;
                   1158:         _ideRegsAddrs.status   = pciRange1 + 0x7;
                   1159:         _ideRegsAddrs.command  = pciRange1 + 0x7;
                   1160: 
                   1161:         _ideRegsAddrs.deviceControl = pciRange2 + 0x2;
                   1162:         _ideRegsAddrs.altStatus     = pciRange2 + 0x2;
                   1163: 
                   1164:         [(IOPCIDevice *)deviceDescription configWriteLong:0x04 value:0x05];
                   1165: 
                   1166:     }
                   1167:     else
                   1168:     {
                   1169:         IORange                *IORanges;
                   1170: 
                   1171:         IORanges = [deviceDescription memoryRangeList];
                   1172: 
                   1173:         _ideRegsAddrs.data     = IORanges[0].start;
                   1174:         _ideRegsAddrs.error    = IORanges[0].start + 0x10;
                   1175:         _ideRegsAddrs.features         = IORanges[0].start + 0x10;
                   1176:         _ideRegsAddrs.sectCnt  = IORanges[0].start + 0x20;
                   1177:         _ideRegsAddrs.sectNum  = IORanges[0].start + 0x30;
                   1178:         _ideRegsAddrs.cylLow   = IORanges[0].start + 0x40;
                   1179:         _ideRegsAddrs.cylHigh  = IORanges[0].start + 0x50;
                   1180:         _ideRegsAddrs.drHead   = IORanges[0].start + 0x60;
                   1181:         _ideRegsAddrs.status   = IORanges[0].start + 0x70;
                   1182:         _ideRegsAddrs.command  = IORanges[0].start + 0x70;
                   1183:     
                   1184:         _ideRegsAddrs.deviceControl = IORanges[0].start + 0x160;
                   1185:         _ideRegsAddrs.altStatus     = IORanges[0].start + 0x160;
                   1186:  
                   1187:         _ideRegsAddrs.channelConfig = IORanges[0].start + 0x200;
                   1188: 
                   1189:         _ideDMARegs                = (IODBDMAChannelRegisters *)IORanges[1].start;
                   1190:     }
                   1191: }
                   1192: 
                   1193: 
                   1194: @end
                   1195: 

unix.superglobalmegacorp.com

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