Annotation of drvEIDE/EIDE.drvproj/EIDE.lksproj/IdeCntInit.m, revision 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.0 (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-1998 by Apple Computer, Inc., All rights reserved.
        !            26:  * Copyright 1994-1997 NeXT Software, Inc., All rights reserved.
        !            27:  *
        !            28:  * IdeCntInit.m - ATA controller initialization module. 
        !            29:  *
        !            30:  * 1-Feb-1998  Joe Liu at Apple
        !            31:  *     Added "new style" device overrides, and matching inspector.
        !            32:  *  Report the transfer mode set for both drives.
        !            33:  *     Set PIO transfer mode for ATAPI drives as well.
        !            34:  *     getTransferModeFromCycleTime method now deals with Multiword DMA cases.
        !            35:  *
        !            36:  * 04-Mar-1997  Scott Vail at NeXT
        !            37:  *     Fixes made for modifications in ideDriveInfo_t struct.
        !            38:  *
        !            39:  * 04-Sep-1996  Becky Divinski at NeXT
        !            40:  *     Added code to ideControllerInit method handle Dual EIDE personality case.
        !            41:  *
        !            42:  * 3-Sept-1996 Becky Divinski at NeXT
        !            43:  *             Changed name of controllerPrersent method to 
        !            44:  *             controllerPresent.
        !            45:  *
        !            46:  * 30-Jan-1996         Rakesh Dubey at NeXT
        !            47:  *      Added forced device detection to fix PIONEER bug. 
        !            48:  *
        !            49:  * 13-Jul-1995         Rakesh Dubey at NeXT
        !            50:  *      Improved device detection. 
        !            51:  *
        !            52:  * 11-Aug-1994         Rakesh Dubey at NeXT
        !            53:  *      Created. 
        !            54:  */
        !            55: 
        !            56: #import "IdeCnt.h"
        !            57: #import "IdeCntInit.h"
        !            58: #import "IdeCntCmds.h"
        !            59: #import "IdePIIX.h"
        !            60: #import "AtapiCntCmds.h"
        !            61: #import "IdeShared.h"
        !            62: #import <driverkit/kernelDriver.h>
        !            63: #import <driverkit/interruptMsg.h>
        !            64: #if (IO_DRIVERKIT_VERSION != 330)
        !            65: #import <machdep/machine/pmap.h>        // XXX get rid of this
        !            66: #endif
        !            67: #import <mach/mach_interface.h>
        !            68: #import <driverkit/IODevice.h>
        !            69: #import <driverkit/align.h>
        !            70: #import <machkit/NXLock.h>
        !            71: #import "IdeDDM.h"
        !            72: #import <machdep/i386/io_inline.h>
        !            73: #import "DualEide.h"
        !            74: #import <driverkit/return.h>
        !            75: #import <mach/port.h>
        !            76: #import <stdlib.h>
        !            77: 
        !            78: 
        !            79: //#define DEBUG
        !            80: 
        !            81: /*
        !            82:  * The controller at base address 0x1f0-0x1f7 is always the first controller
        !            83:  * no matter when it gets probed, so we start the counter at 1. 
        !            84:  */
        !            85: static unsigned char controllerNum = 1;
        !            86: 
        !            87: /*
        !            88:  * There is no standard for channels 3 and 4 (channel 2 is almost there). We
        !            89:  * should stick to the following base address/IRQ pairings: 1F0/14, 170/15,
        !            90:  * 1E8/11, 168/10. 
        !            91:  */
        !            92: static __inline__
        !            93: unsigned int
        !            94: assignRegisterAddresses(ideRegsAddrs_t *ideRegsAddrs,
        !            95:             unsigned int baseAddress1)
        !            96: {
        !            97:     unsigned int baseAddress2;
        !            98:     unsigned char cntNum;
        !            99:     
        !           100:     switch (baseAddress1) {
        !           101:       case 0x1f0:
        !           102:        cntNum = 0;                     /* primary, always controller 0 */
        !           103:        break;
        !           104:       default:
        !           105:        cntNum = controllerNum++;
        !           106:        break;
        !           107:     }
        !           108:        
        !           109:     baseAddress2 = baseAddress1 +  0x206;
        !           110:     
        !           111:     ideRegsAddrs->data = baseAddress1;
        !           112:     ideRegsAddrs->error = baseAddress1 + 1;
        !           113:     ideRegsAddrs->features = baseAddress1 + 1;
        !           114:     ideRegsAddrs->sectCnt = baseAddress1 + 2;
        !           115:     ideRegsAddrs->sectNum = baseAddress1 + 3;
        !           116:     ideRegsAddrs->cylLow = baseAddress1 + 4;
        !           117:     ideRegsAddrs->cylHigh = baseAddress1 + 5;
        !           118:     ideRegsAddrs->drHead = baseAddress1 + 6;
        !           119:     ideRegsAddrs->status = baseAddress1 + 7;
        !           120:     ideRegsAddrs->command = baseAddress1 + 7;
        !           121:     
        !           122:     ideRegsAddrs->deviceControl = baseAddress2;
        !           123:     ideRegsAddrs->altStatus = baseAddress2;
        !           124: 
        !           125:     return cntNum;
        !           126: }
        !           127: 
        !           128: /*
        !           129:  * Function: ata_mode_to_num
        !           130:  *
        !           131:  * Convert ata_mode_t into a value. i.e.
        !           132:  *     0x01 ==> 0
        !           133:  *     0x02 ==> 1
        !           134:  */     
        !           135: extern unsigned char
        !           136: ata_mode_to_num(ata_mode_t mode)
        !           137: {
        !           138:        unsigned char tmp = 0;
        !           139:        if (mode == ATA_MODE_NONE) {
        !           140: //             IOLog("bad argument to ata_mode_to_num()\n");
        !           141:                return (0);
        !           142:        }
        !           143:        while (mode != 0x01) {
        !           144:                mode >>= 1;
        !           145:                tmp++;
        !           146:        }
        !           147:        return (tmp);
        !           148: }
        !           149: 
        !           150: /*
        !           151:  * Function: ata_mask_to_mode
        !           152:  *
        !           153:  * Return the most significant bit in a ata_mask_t mask. i.e.
        !           154:  *     0x03 ==> 0x02
        !           155:  *     0x07 ==> 0x04
        !           156:  */
        !           157: extern ata_mode_t
        !           158: ata_mask_to_mode(ata_mask_t mask)
        !           159: {
        !           160:        int i;
        !           161:        if (mask == 0)
        !           162:                return ATA_MODE_NONE;
        !           163:        for (i = 7; i >= 0; i--) {
        !           164:                if ((1 << i) & mask)
        !           165:                        return (1 << i);
        !           166:        }
        !           167:        return ATA_MODE_NONE;
        !           168: }
        !           169: 
        !           170: /*
        !           171:  * Function: ata_mode_to_mask
        !           172:  *
        !           173:  * Convert from a mode to a mask such that all less significant bits,
        !           174:  * including the mode bit is set.
        !           175:  */
        !           176: extern ata_mask_t
        !           177: ata_mode_to_mask(ata_mode_t mode)
        !           178: {
        !           179:        return ((mode == ATA_MODE_NONE) ? mode : (mode | (mode - 1)));
        !           180: }
        !           181: 
        !           182: @implementation IdeController(Initialize)
        !           183: 
        !           184: 
        !           185: #define ATAPI_SIGNATURE_LOW            0x14
        !           186: #define ATAPI_SIGNATURE_HIGH           0xeb
        !           187: 
        !           188: #define ATA_SIGNATURE_LOW              0x00
        !           189: #define ATA_SIGNATURE_HIGH             0x00
        !           190: 
        !           191: /*
        !           192:  * This is called just after resetting the drives connected to this
        !           193:  * controller. We read the drive registers to figure out if it is an ATAPI
        !           194:  * drive. If it is then we make a note of it and return YES. 
        !           195:  */
        !           196: - (BOOL)controllerPresent
        !           197: {
        !           198:     unsigned char dh;
        !           199:     unsigned char unit;
        !           200:     
        !           201:     unit = 0;
        !           202:     
        !           203:     dh = _drives[unit].addressMode;
        !           204:     
        !           205:     dh |= (unit ? SEL_DRIVE1 : SEL_DRIVE0);
        !           206:     outb(_ideRegsAddrs.drHead, dh);
        !           207: 
        !           208:     /*
        !           209:      * Test with some data. 
        !           210:      */
        !           211:     
        !           212:     if (unit == 0)     {
        !           213:        outb(_ideRegsAddrs.cylLow, 0xaa);
        !           214:        outb(_ideRegsAddrs.cylHigh, 0xbb);
        !           215:     } else {
        !           216:        outb(_ideRegsAddrs.cylLow, 0xba);
        !           217:        outb(_ideRegsAddrs.cylHigh, 0xbe);
        !           218:     }
        !           219:     
        !           220:     if (unit == 0) {
        !           221:        if ((inb(_ideRegsAddrs.cylLow) != 0xaa) ||
        !           222:            (inb(_ideRegsAddrs.cylHigh) != 0xbb)) {
        !           223:            return NO;
        !           224:        }
        !           225:     } else {
        !           226:        if ((inb(_ideRegsAddrs.cylLow) != 0xba) ||
        !           227:            (inb(_ideRegsAddrs.cylHigh) != 0xbe)) {
        !           228:            return NO;
        !           229:        }
        !           230:     }
        !           231:     
        !           232:     return YES;
        !           233: }
        !           234: 
        !           235: /*
        !           236:  * One-time only init. Returns NO on failure. 
        !           237:  */
        !           238: - (BOOL)ideControllerInit:(IODeviceDescription *)deviceDescription
        !           239: {
        !           240:     int        unit;
        !           241:     int        drivesPresent = 0;
        !           242:     const char  *params;
        !           243:     const char  *addressingMode, *multisectorMode;
        !           244:     IOEISADeviceDescription *eisaDeviceDescription =
        !           245:                (IOEISADeviceDescription *)deviceDescription;
        !           246:     IOConfigTable *configTable = [deviceDescription configTable];
        !           247:     int                override[MAX_IDE_DRIVES];
        !           248: 
        !           249: #if 0
        !           250:     _printWaitForNotBusy = NO;
        !           251: #endif 0
        !           252: 
        !           253:     if (dualEide) {
        !           254:        if (instanceNum)        
        !           255:             [super setDeviceDescription:deviceDescription];
        !           256:     } 
        !           257: 
        !           258:     if ([self enableAllInterrupts]) {
        !           259:                IOLog("ideControllerInit: failed enableAllInterrupts\n");
        !           260:                return NO;
        !           261:     }
        !           262:     
        !           263:     if ((_ideCmdLock = [NXLock new]) == NULL) {
        !           264:                IOLog("ideControllerInit: failed _ideCmdLock\n");
        !           265:                return NO;
        !           266:     }
        !           267:     
        !           268:     /*
        !           269:      * We don't want to execute any IDE commands from Disk until
        !           270:      * initialization is complete. 
        !           271:      */
        !           272:     [self ideCntrlrLock];
        !           273:     
        !           274:     /*
        !           275:      * Initialize the register address values.
        !           276:      */
        !           277:     _controllerNum = assignRegisterAddresses(&_ideRegsAddrs,
        !           278:                             [eisaDeviceDescription portRangeList][0].start);
        !           279: 
        !           280:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           281:                _drives[unit].atapiDevice = NO;
        !           282:     }
        !           283:     
        !           284:     /*
        !           285:      * We have to test here if the controller is present or else we will
        !           286:      * block looking for a drive (in ideReset). 
        !           287:      */
        !           288:     if ([self controllerPresent] == NO)        {
        !           289:                IOLog("%s: no devices detected at port 0x%0x\n", [self name],
        !           290:                        _ideRegsAddrs.data);
        !           291:                [self ideCntrlrUnLock];
        !           292:                return NO;
        !           293:     } else {
        !           294:                IOLog("%s: device detected at port 0x%x irq %d\n", [self name], 
        !           295:                        _ideRegsAddrs.data, [deviceDescription interrupt]);
        !           296:     }
        !           297:     
        !           298:     _ideInterruptPort = [self interruptPort];
        !           299:     _ideDevicePort = [deviceDescription devicePort];
        !           300: 
        !           301:     [self setInterruptTimeOut:IDE_INTR_TIMEOUT];
        !           302: 
        !           303:        _multiSectorRequested = NO;
        !           304:     multisectorMode = [configTable valueForStringKey:MULTIPLE_SECTORS_ENABLE];
        !           305:        if (multisectorMode) {
        !           306:                if ((*multisectorMode == 'Y') || (*multisectorMode == 'y'))
        !           307:                        _multiSectorRequested = YES;
        !           308:                [configTable freeString:multisectorMode];
        !           309:        }
        !           310: 
        !           311:     /*
        !           312:      * Select mode for addressing drives. The driver will fall back to CHS
        !           313:      * mode if LBA is unsupported by the drive.
        !           314:      */
        !           315:     addressingMode = [[deviceDescription configTable] 
        !           316:                                valueForStringKey: ADDRESS_MODE];
        !           317:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           318:         if ((addressingMode == NULL) || (strcmp(addressingMode, "LBA") != 0)){
        !           319:                        _drives[unit].addressMode = ADDRESS_MODE_CHS;
        !           320:                } else {
        !           321:                        _drives[unit].addressMode = ADDRESS_MODE_LBA;
        !           322:                }
        !           323:        }
        !           324:        if (addressingMode) [configTable freeString:addressingMode];
        !           325: 
        !           326: #ifdef DEBUG    
        !           327:     if (_addressMode[0] == ADDRESS_MODE_LBA)   {
        !           328:        IOLog("%s: Using Logical address mode..\n", [self name]);
        !           329:     }
        !           330: #endif DEBUG
        !           331:     
        !           332:     /*
        !           333:      * Find out from config table if we are not using BIOS parameters.
        !           334:      * Default is to use stored values in CMOS/BIOS.
        !           335:      */
        !           336:     params = [[deviceDescription configTable] 
        !           337:                        valueForStringKey: DRIVE_PARAMETERS];
        !           338:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           339:        if ((params == NULL) || ((*params != 'Y') && (*params != 'y')))
        !           340:            _drives[unit].biosGeometry = YES;
        !           341:        else
        !           342:            _drives[unit].biosGeometry = NO;
        !           343:     }
        !           344:        if (params) [configTable freeString:params];
        !           345: 
        !           346:     /*
        !           347:      * Same as DRIVE_PARAMETERS. See comment above.
        !           348:      */
        !           349:     params = [[deviceDescription configTable] 
        !           350:                        valueForStringKey: USE_DISK_GEOMETRY];
        !           351:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           352:                if (params && ((*params == 'Y') || (*params == 'y')))
        !           353:                _drives[unit].biosGeometry = NO;
        !           354:     }
        !           355:        if (params) [configTable freeString:params];
        !           356: 
        !           357:     /*
        !           358:      * Are we supporting ATAPI? 
        !           359:      */
        !           360:        _EIDESupport = YES;
        !           361:     params = [[deviceDescription configTable] 
        !           362:                        valueForStringKey: EIDE_SUPPORT];
        !           363:        if (params) {
        !           364:                if ((*params == 'N') || (*params == 'n'))
        !           365:                        _EIDESupport = NO;                      
        !           366:                [configTable freeString:params];
        !           367:        }
        !           368: 
        !           369:        /*
        !           370:         * Obtain the transfer type/mode mask. A user may have disabled
        !           371:         * certain type of transfer modes.
        !           372:         */
        !           373:        for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           374:                char *key;
        !           375:                _drives[unit].driveMasks.modes = 0x000000ff;    // enable all PIO modes
        !           376:                
        !           377:                if (dualEide && instanceNum) {
        !           378:                        if (unit)
        !           379:                                key = MODES_MASK_SLAVE_SEC;
        !           380:                        else
        !           381:                                key = MODES_MASK_MASTER_SEC;
        !           382:                }
        !           383:                else {
        !           384:                        if (unit)
        !           385:                                key = MODES_MASK_SLAVE;
        !           386:                        else
        !           387:                                key = MODES_MASK_MASTER;
        !           388:                }
        !           389:                
        !           390:        params = [[deviceDescription configTable] 
        !           391:                        valueForStringKey:key];         
        !           392:                if (params) {
        !           393:                        // Read the mask set by the user, however we assume that
        !           394:                        // PIO modes 0 is always available.
        !           395:                        unsigned int mask = strtoul(params, NULL, 16);
        !           396:                        _drives[unit].driveMasks.modes = mask | 
        !           397:                                ata_mode_to_mask(ATA_MODE_0);
        !           398:                        [configTable freeString:params];
        !           399:                }
        !           400:        }
        !           401: 
        !           402: #if 0
        !           403:     /*
        !           404:      * Does the host support IOCHRDY? There is no way for the driver to find
        !           405:      * this out. The user has to set this flag.
        !           406:      */
        !           407:     params = [[deviceDescription configTable] 
        !           408:                        valueForStringKey: HOST_IORDY_SUPPORT];
        !           409: 
        !           410:     if ((params == NULL) || (strcmp(params, "Yes") != 0))
        !           411:        _IOCHRDYSupport = NO;
        !           412:     else
        !           413:        _IOCHRDYSupport = YES;  
        !           414: #endif /* 0 */
        !           415: 
        !           416:     _transferWidth = IDE_TRANSFER_16_BIT;
        !           417: 
        !           418:     /*
        !           419:      * We acquire the disk geometry from either the BIOS or the disk itself.
        !           420:      * If we are using bios we get the values from it. If we are not using
        !           421:      * BIOS then we just determine presence of disk here. The actual geometry
        !           422:      * will be read later. However if the user has chosen "disk geometry"
        !           423:      * option and disk 0 is not detected then we fall back to BIOS for
        !           424:      * geometry. This is intended to save the user from getting hosed in case
        !           425:      * the disk does not support Identify drive command. 
        !           426:      */
        !           427: 
        !           428:     /*
        !           429:      * FIXME: This recovery strategy needs to thought over. 
        !           430:      */
        !           431:      
        !           432:     _driveNum = unit;
        !           433: 
        !           434:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++)
        !           435:                override[unit] = DEVICE_AUTO;
        !           436: 
        !           437:     // Old-style overrides remain here for compatibility
        !           438:     {
        !           439:        const char *tmp;
        !           440:        tmp = [configTable valueForStringKey:ATA_LOCATION];
        !           441:         if (tmp) {
        !           442:             if (strcmp(tmp, "Master")==0)
        !           443:                override[0]=DEVICE_ATA;
        !           444:             else if (strcmp(tmp, "Slave")==0)
        !           445:                override[1]=DEVICE_ATA;
        !           446:            [configTable freeString:tmp];
        !           447:         }
        !           448:        tmp = [configTable valueForStringKey:ATAPI_LOCATION];
        !           449:         if (tmp) {
        !           450:             if (strcmp(tmp, "Master")==0)
        !           451:                override[0]=DEVICE_ATAPI;
        !           452:             else if (strcmp(tmp, "Slave")==0)
        !           453:                override[1]=DEVICE_ATAPI;
        !           454:            [configTable freeString:tmp];
        !           455:         }
        !           456:     }
        !           457:        
        !           458:     // New-style overrides take precidence over Old-style overrides
        !           459:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           460:         const char *tmp;
        !           461:                
        !           462:                if (dualEide && instanceNum)
        !           463:                        tmp = [configTable valueForStringKey:
        !           464:                                (unit ? IDE_SLAVE_KEY_SEC : IDE_MASTER_KEY_SEC)];
        !           465:                else
        !           466:                tmp = [configTable valueForStringKey:
        !           467:                                (unit ? IDE_SLAVE_KEY : IDE_MASTER_KEY)];
        !           468:                
        !           469:                if (tmp == NULL)
        !           470:                        continue;
        !           471: 
        !           472:                if ( (strcmp(tmp, "")==0) ||
        !           473:                        (strcmp(tmp, overrideTable[DEVICE_AUTO])==0) )
        !           474:                        override[unit] = DEVICE_AUTO;   
        !           475:                else if (strcmp(tmp, overrideTable[DEVICE_NONE])==0)
        !           476:                        override[unit] = DEVICE_NONE;
        !           477:                else if ( (strcmp(tmp, overrideTable[DEVICE_ATA])==0) ||
        !           478:                        (strcmp(tmp, "IDE")==0) || (strcmp(tmp, "EIDE")==0) )
        !           479:                        override[unit] = DEVICE_ATA;
        !           480:                else if ( (strcmp(tmp, overrideTable[DEVICE_ATAPI])==0) ||
        !           481:                        (strcmp(tmp, "CD")==0) || (strcmp(tmp, "CDROM")==0) )
        !           482:                        override[unit] = DEVICE_ATAPI;
        !           483:                [configTable freeString:tmp];
        !           484:     }
        !           485: 
        !           486:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           487:         switch (override[unit]) {
        !           488:             case DEVICE_NONE:
        !           489:                                IOLog("%s: Drive %d scan will be skipped due to override.\n",
        !           490:                                        [self name], unit);
        !           491:                                break;
        !           492:             case DEVICE_ATA:
        !           493:                                IOLog("%s: Drive %d forced to ATA by override.\n",
        !           494:                                        [self name], unit);
        !           495:                                break;
        !           496:             case DEVICE_ATAPI:
        !           497:                                IOLog("%s: Drive %d forced to ATAPI by override.\n",
        !           498:                                        [self name], unit);
        !           499:                                break;
        !           500:             default :
        !           501:                                break;
        !           502:        }
        !           503:        bzero(&(_drives[unit].ideInfo), sizeof(ideDriveInfo_t));
        !           504:        
        !           505:        [self ideReset];
        !           506:        
        !           507:        /*
        !           508:         * We need to use the disk geometry (and override user selection) if
        !           509:         * the BIOS reports more than 16 heads. 
        !           510:         */
        !           511:        if (_drives[unit].biosGeometry == YES)  {
        !           512:            _drives[unit].ideInfo = [self getIdeInfoFromBIOS:unit];
        !           513:            if ((_drives[unit].ideInfo.type != 0) &&
        !           514:                        (_drives[unit].ideInfo.heads > 16)) {
        !           515:                        _drives[unit].biosGeometry = NO;
        !           516:                        _drives[unit].ideInfo.type = 0;
        !           517:                        IOLog("%s: WARNING: using disk geometry for drive %d.\n", 
        !           518:                            [self name], unit);
        !           519:            }
        !           520:        }
        !           521: 
        !           522:        /*
        !           523:         * If IDE_IDENTIFY_DRIVE command fails then we will override user
        !           524:         * selection and use BIOS geometry if this is the boot disk (first
        !           525:         * disk on first controller). 
        !           526:         */
        !           527:        if ((override[unit] == DEVICE_AUTO) || (override[unit] == DEVICE_ATA)) {
        !           528:            if (_drives[unit].biosGeometry == NO)       {
        !           529:                if ([self ideDetectDrive:unit override:override[unit]] == YES)  {
        !           530:                    _drives[unit].ideInfo.type = 255;
        !           531:                } else if ((_controllerNum == 0) && (unit == 0))        {
        !           532:                    _drives[unit].ideInfo = [self getIdeInfoFromBIOS:unit];
        !           533:                    if (_drives[unit].ideInfo.type != 0)        {
        !           534:                        _drives[unit].biosGeometry = YES;
        !           535:                        IOLog("%s: WARNING: using BIOS geometry for drive %d.\n", 
        !           536:                                    [self name], unit);
        !           537:                    }
        !           538:                }
        !           539:            }
        !           540:        }
        !           541: 
        !           542:        /*
        !           543:         * If we didn't find ATA drive then look for ATAPI device. 
        !           544:         */
        !           545:        if ((override[unit] == DEVICE_AUTO) || (override[unit] == DEVICE_ATAPI)) {
        !           546:            if ((_drives[unit].ideInfo.type == 0) && (_EIDESupport == YES) &&
        !           547:                ([self ideDetectATAPIDevice:unit override:override[unit]] == YES)){
        !           548:                _drives[unit].ideInfo.type = 127;
        !           549:            }
        !           550:        }
        !           551: 
        !           552:        if (_drives[unit].ideInfo.type != 0)
        !           553:            drivesPresent += 1 ;
        !           554:     }
        !           555:     
        !           556:     if (drivesPresent == 0)    {
        !           557:                [self ideCntrlrUnLock];
        !           558:                IOLog("ideControllerInit: failed drivesPresent\n");
        !           559:                return NO;
        !           560:     }
        !           561: 
        !           562:     /*
        !           563:      * Initialization was successful. We should release the lock so that the
        !           564:      * controller can now execute commands from disk objects. 
        !           565:      */
        !           566: 
        !           567:     [self resetAndInit];
        !           568: 
        !           569: #ifdef DDM_DEBUG
        !           570:     IOInitDDM(IDE_NUM_DDM_BUFS);
        !           571: #endif DDM_DEBUG
        !           572:     
        !           573:     /*
        !           574:      * Set drive power state to active.
        !           575:      */
        !           576:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           577:                if (_drives[unit].ideInfo.type != 0)
        !           578:                [self setDrivePowerState:IDE_PM_ACTIVE];
        !           579:     }
        !           580:     
        !           581:     _driveSleepRequest = NO;
        !           582:     [self enableInterrupts];
        !           583:     [self ideCntrlrUnLock];
        !           584:     return YES;
        !           585: }
        !           586: 
        !           587: /*
        !           588:  * Method: getControllerCapability
        !           589:  *
        !           590:  * Query the controller's transfer mode capability and record them
        !           591:  * to _controllerModes.
        !           592:  *
        !           593:  * Note that _controllerModes fields contain the mask of all modes that it
        !           594:  * supports. Not just the highest possible mode.
        !           595:  */
        !           596: - (void) getControllerCapability
        !           597: {
        !           598:        /*
        !           599:         * Set default values.
        !           600:         */
        !           601:        _controllerModes.mode.pio   = ATA_MODE_0;
        !           602:        _controllerModes.mode.swdma = ATA_MODE_NONE;
        !           603:        _controllerModes.mode.mwdma = ATA_MODE_NONE;
        !           604:        _controllerModes.mode.udma  = ATA_MODE_NONE;
        !           605:        
        !           606:        if (_controllerID != PCI_ID_NONE)
        !           607:                [self getPCIControllerCapabilities:(txferModes_t *)&_controllerModes];
        !           608:        else {
        !           609:                // Assume all IDE controllers are capable of PIO Mode 4
        !           610:                //
        !           611:                _controllerModes.mode.pio   = ata_mode_to_mask(ATA_MODE_4);
        !           612:        }
        !           613: }
        !           614: 
        !           615: #define ATA_RESET_DELAY                1500            /* milliseconds */
        !           616: 
        !           617: /*
        !           618:  * Determine the presence and type of drive (IDE/ATAPI) attached to this
        !           619:  * controller. We use this only if we are not using the info from CMOS/BIOS. 
        !           620:  *
        !           621:  * Even though this is an optional command it is safe to use since all ATA 
        !           622:  * disks support it. Vey old disks may not support it and they can be used 
        !           623:  * by the "Use BIOS Geometry" option. 
        !           624:  *
        !           625:  * Note Well: Some drives bail out immediately and return with ERR bit set in
        !           626:  * the status register. Some bail out after a minute and set ERR bit. However
        !           627:  * some simply return zero in the status register. I am sure there are other
        !           628:  * variants. Hence we check for DRQ (success) bit. Note that we would not get
        !           629:  * an interrupt since -registerDevice has not been called yet. This routine
        !           630:  * probably needs some more thinking. It is very important that this routine
        !           631:  * never detect ATAPI drives as ATA. 
        !           632:  */
        !           633: 
        !           634: /*
        !           635:  * In Micron machine, if there is one ATAPI CD-ROM, it returns 78 or 7a in the
        !           636:  * status register. Completely bogus. 
        !           637:  */
        !           638: -(BOOL)ideDetectDrive:(unsigned int)unit override:(int)override
        !           639: {
        !           640:     unsigned char dh = _drives[unit].addressMode;
        !           641:     int i;
        !           642:     unsigned char status;
        !           643:     BOOL found = NO;
        !           644:     
        !           645:     if ((override != DEVICE_AUTO) && (override != DEVICE_ATA))
        !           646:        return NO;
        !           647: 
        !           648:     IOLog("%s: Checking for ATA drive %d...  ", [self name], unit);
        !           649: #ifdef DEBUG
        !           650:     IOLog("\n");
        !           651: #endif DEBUG
        !           652:     
        !           653:     [self disableInterrupts];
        !           654:     
        !           655:     dh |= (unit ? SEL_DRIVE1 : SEL_DRIVE0);
        !           656:     outb(_ideRegsAddrs.drHead, dh);
        !           657:     
        !           658:     outb(_ideRegsAddrs.command, IDE_IDENTIFY_DRIVE);
        !           659: 
        !           660:     for (i = 0; i < (ATA_RESET_DELAY * 100); i++) {
        !           661:                IODelay(10);
        !           662:                status = inb(_ideRegsAddrs.status);
        !           663:                
        !           664:                if (status & BUSY)
        !           665:                        continue;
        !           666:                
        !           667:                if (status & ERROR) {
        !           668:                        break;                          /* certain failure */
        !           669:                }
        !           670:                if (unit && (status & WRITE_FAULT)) {
        !           671:                        break;                          /* failure as well */
        !           672:                }
        !           673:                if (status & DREQUEST) {
        !           674:                        found = YES;            /* success */
        !           675:                        break;
        !           676:                }    
        !           677:     }
        !           678: #ifdef DEBUG
        !           679:     IOLog("%s: ideDetectDrive: status %x\n", [self name], status);
        !           680: #endif DEBUG
        !           681:     
        !           682:     if (found) {
        !           683:         IOLog("Detected\n");
        !           684:        return YES;
        !           685:     }
        !           686:     
        !           687:     /*
        !           688:      * If we got here this means that the ATA device is not present or was
        !           689:      * not detected. Check if the user has told us that the drive is present. 
        !           690:      */
        !           691:     
        !           692:     if (override == DEVICE_ATA) {
        !           693:        IOLog("Not detected but proceeding\n");
        !           694:        return YES;
        !           695:     }
        !           696: 
        !           697:     IOLog("\n");
        !           698:     return NO;
        !           699: }
        !           700: 
        !           701: /*
        !           702:  * We send the device ATAPI soft reset command and check for signature. This
        !           703:  * is the first command that ATAPI devices need. 
        !           704:  */
        !           705: -(BOOL)ideDetectATAPIDevice:(unsigned int)unit override:(int)override
        !           706: {
        !           707:     unsigned char low, high;
        !           708: //  const char  *location;
        !           709:     BOOL found = NO;
        !           710:     
        !           711:     if ((override != DEVICE_AUTO) && (override != DEVICE_ATAPI))
        !           712:        return NO;
        !           713: 
        !           714:     IOLog("%s: Checking for ATAPI drive %d... ", [self name], unit);
        !           715: #ifdef DEBUG
        !           716:     IOLog("\n");
        !           717: #endif DEBUG
        !           718:        
        !           719:     [self atapiSoftReset:unit];
        !           720:        
        !           721:     low = inb(_ideRegsAddrs.cylLow);
        !           722:     high = inb(_ideRegsAddrs.cylHigh);
        !           723:     
        !           724:     if ((low == ATAPI_SIGNATURE_LOW) && (high == ATAPI_SIGNATURE_HIGH)) {
        !           725:                _drives[unit].atapiDevice = YES;
        !           726: #ifdef undef
        !           727:        IOLog("%s: ATAPI drive %d detected.\n", [self name], unit);
        !           728: #endif undef
        !           729:        found = YES;
        !           730:     } else if (_ide_debug) {
        !           731:        IOLog("%s: No ATAPI drive %d, low = %x high = %x\n", 
        !           732:                [self name], unit, low, high);
        !           733:     }
        !           734:     
        !           735:     if (found) {
        !           736:         IOLog("Detected\n");
        !           737:        return YES;
        !           738:     }
        !           739:     
        !           740:     /*
        !           741:      * If we got here this means that the ATAPI device is not present or was
        !           742:      * not detected. Check if the user has told us that the device is
        !           743:      * present. This will probably fail later but succeeds in case of some
        !           744:      * drives (like PIONEER DR-124X 1.02). It is definitely lame to work
        !           745:      * around firmware bugs in the driver but there seems to be no
        !           746:      * alternative.. 
        !           747:      */
        !           748:     if (override == DEVICE_ATAPI) {
        !           749:        _drives[unit].atapiDevice = YES;
        !           750:        IOLog("Not detected but proceeding\n");
        !           751:        return YES;
        !           752:     }
        !           753:     
        !           754:     IOLog("\n");
        !           755:     return NO;
        !           756: }
        !           757: 
        !           758: 
        !           759: -(ideDriveInfo_t)getIdeDriveInfo:(unsigned int)unit
        !           760: {
        !           761:     return _drives[unit].ideInfo;
        !           762: }
        !           763: 
        !           764: #define MAX_RESET_ATTEMPTS             2
        !           765: 
        !           766: - (void)ideReset
        !           767: {
        !           768:     int count;
        !           769:     int delay;
        !           770:     unsigned char status;
        !           771: 
        !           772: #ifdef DEBUG_TRACE
        !           773:     IOLog("%s: ideReset\n", [self name]);
        !           774: #endif DEBUG_TRACE
        !           775: 
        !           776:     for (count = 0; count < MAX_RESET_ATTEMPTS; count++) {
        !           777:     
        !           778:        outb(_ideRegsAddrs.deviceControl, DISK_RESET_ENABLE);
        !           779:        IODelay(100);                   /* spec >= 25 us */
        !           780:        outb(_ideRegsAddrs.deviceControl, 0x0);
        !           781:        
        !           782:        [self enableInterrupts];
        !           783: 
        !           784:        delay = 31 * 1000 * 1000;       /* thirty one seconds */
        !           785:        
        !           786:        IOSleep(1000);                  /* Enough time to assert busy */
        !           787:        
        !           788:        while (delay > 0) {
        !           789:        
        !           790:            status = inb(_ideRegsAddrs.status);
        !           791:            if (!(status & BUSY)) {
        !           792:                return;
        !           793:            }
        !           794:            
        !           795:            IOSleep(1);
        !           796:            delay -= 1000;
        !           797:        }
        !           798:        
        !           799:        IOLog("%s: Reset failed, retrying..\n", [self name]);
        !           800:        IOSleep(2000);
        !           801:     }
        !           802:     
        !           803:     /* FIXME: I don't think we should panic */
        !           804:     if (count == MAX_RESET_ATTEMPTS) {
        !           805:        IOLog("%s: can not reset.\n", [self name]);
        !           806:        IOPanic("IDE Reset");
        !           807:        /* NOT REACHED */
        !           808:     }
        !           809: }
        !           810: 
        !           811: /*
        !           812:  * Initialize the IDE interface. Find about drive capabilities (by
        !           813:  * IDE_IDENTIFY_DRIVE command) and configure drive. We either use CMOS/BIOS
        !           814:  * settings to program the drive or bypass CMOS/BIOS and use the values
        !           815:  * returned by the drive depending upon biosGeometry flag. By the time we
        !           816:  * enter this routine we know about all devices connected to this controller. 
        !           817:  */
        !           818: - (void)resetAndInit
        !           819: {
        !           820:     int i;
        !           821:     unsigned char unit;
        !           822:     ide_return_t rtn;
        !           823:     BOOL ataDevicePresent;
        !           824:        BOOL retry;
        !           825:        
        !           826:        /*
        !           827:         * Determine what transfer modes the controller is capable of.
        !           828:         */
        !           829:        [self getControllerCapability];
        !           830: 
        !           831:        /* Qualify the default mask for each drive with the
        !           832:         * controller's mask.
        !           833:         */
        !           834:        for (i = 0; i < MAX_IDE_DRIVES; i++) {
        !           835:                _drives[i].driveMasks.modes &= _controllerModes.modes;
        !           836:        }
        !           837:        
        !           838:        /*
        !           839:         * Loops through one cycle of the configuration process:
        !           840:         *
        !           841:         * 0. Get controller capability.
        !           842:         * 1. Revert controller back to compatibility timing.
        !           843:         * 2. Reset ATA/ATAPI.
        !           844:         * 3. Determine drive(s) capabilities.
        !           845:         * 4. Set drive(s) feature according to controller & drive capability.
        !           846:         * 5. Set controller timing and mode. (UDMA, PIO, etc...)
        !           847:         * 6. If DMA or Multisector mode, perform test.
        !           848:         * 7. If test failed, mask out the current mode, goto step 1.
        !           849:         */
        !           850: 
        !           851:        do {
        !           852:        
        !           853:        /*
        !           854:         * Reset the IDE controller to stop any transfer in progress, and
        !           855:         * revert back to the slowest timing settings.
        !           856:         */
        !           857:        [self resetController];
        !           858:        
        !           859:        retry = NO;
        !           860:     IOLog("%s: Resetting drives...\n", [self name]);
        !           861: 
        !           862:     /*
        !           863:      * If there is at least one ATA drive connected to this controller then
        !           864:      * is is necessary to (ATA style) reset them. Otherwise, We use the ATAPI 
        !           865:      * reset instead (in setATAPIDriveCapabilities: method below).
        !           866:      */
        !           867:     ataDevicePresent = NO;
        !           868:     for (i = 0; i < MAX_IDE_DRIVES; i++) {
        !           869:                if ((_drives[i].ideInfo.type != 0) && ([self isAtapiDevice:i] == NO)){
        !           870:                        ataDevicePresent = YES;
        !           871:                        break;
        !           872:                }
        !           873:     }
        !           874:     if (ataDevicePresent == YES) {
        !           875: #ifdef DEBUG
        !           876:         IOLog("%s: ATA device present on this controller\n", [self name]);
        !           877: #endif DEBUG
        !           878:                [self ideReset];
        !           879:     }
        !           880: 
        !           881:     /*
        !           882:      * Send the controller necessary commands to set capabilities and then
        !           883:      * set drive parameters. It is necessary to set drive parameters before
        !           884:      * any data I/O can be done from the disk. 
        !           885:      */
        !           886:     for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           887: 
        !           888:                if (_drives[unit].ideInfo.type == 0)    {
        !           889:                        //IOLog("%s: Drive %d not present.\n", [self name], unit);
        !           890:                        continue;
        !           891:                }
        !           892: 
        !           893:                /* Set default values.
        !           894:                 */
        !           895:                _drives[unit].multiSector  = 0;
        !           896:                _drives[unit].transferType = IDE_TRANSFER_PIO;
        !           897:                _drives[unit].transferMode = ATA_MODE_0;
        !           898: 
        !           899:                /*
        !           900:                 * ATAPI devices.
        !           901:                 */
        !           902:                if ([self isAtapiDevice:unit] == YES) {
        !           903:                        rtn = [self setATAPIDriveCapabilities:unit];
        !           904:                        if (rtn != IDER_SUCCESS) {
        !           905:                                IOLog("%s: ATAPI drive %d is not present.\n",
        !           906:                                        [self name], unit);
        !           907:                                _drives[unit].ideInfo.type = 0;
        !           908:                                _drives[unit].atapiDevice = NO;
        !           909:                        }
        !           910:                        continue;
        !           911:                }
        !           912:                
        !           913:                /*
        !           914:                 * ATA devices.
        !           915:                 */
        !           916:                if (_drives[unit].biosGeometry == YES)  {
        !           917:                        rtn = [self setATADriveCapabilities:unit withBIOSInfo:YES];
        !           918:                } else {
        !           919:                        rtn = [self setATADriveCapabilities:unit withBIOSInfo:NO];
        !           920:                        if (rtn != IDER_SUCCESS) {
        !           921:                                IOLog("%s: ATA drive %d is not present.\n", [self name], unit);
        !           922:                                _drives[unit].ideInfo.type = 0;
        !           923:                                continue;
        !           924:                        }
        !           925:                }
        !           926:     }
        !           927: 
        !           928:     /*
        !           929:      * Set IDE controller capabilities. This must be done after the disks are
        !           930:      * configured. 
        !           931:      */
        !           932:        [self setControllerCapabilities];
        !           933: 
        !           934:        /*
        !           935:         * Report the transfer mode set for both drives.
        !           936:         */
        !           937:        if (_controllerID != PCI_ID_NONE) {
        !           938:                const char *mode_string[] =
        !           939:                        {"PIO", "Single-word DMA", "Multiword DMA", "Ultra DMA"};
        !           940:                for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           941:                        if (_drives[unit].ideInfo.type == 0)
        !           942:                                continue;
        !           943:                        if (_drives[unit].multiSector)
        !           944:                                IOLog("%s: Drive %d: %s Mode %d (%d sectors)\n",
        !           945:                                        [self name], unit, mode_string[_drives[unit].transferType], 
        !           946:                                        ata_mode_to_num(_drives[unit].transferMode),
        !           947:                                        _drives[unit].multiSector);
        !           948:                        else                            
        !           949:                                IOLog("%s: Drive %d: %s Mode %d\n",
        !           950:                                        [self name], unit, mode_string[_drives[unit].transferType], 
        !           951:                                        ata_mode_to_num(_drives[unit].transferMode));
        !           952:                }
        !           953:        }
        !           954:        
        !           955:        /*
        !           956:         * After the drives and the controller are setup, we perform a read
        !           957:         * and make sure everything is OK. We do not perform this test for
        !           958:         * ATAPI or removable ATA devices (if they become supported).
        !           959:         *
        !           960:         * FIXME: perhaps instead of reading a block from the disk, we should
        !           961:         * consider using DMA on non-media commands. This will be needed when
        !           962:         * DMA is supported on removable media drives. Do those commands exist?
        !           963:         * It seems that ATA-3 defined a IDENTIFY DEVICE DMA command, but they
        !           964:         * no longer exist in ATA-4. Did they get dropped?
        !           965:         */
        !           966:        for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
        !           967: 
        !           968:                _driveNum = unit;
        !           969:                
        !           970:                // Don't test ATAPI devices.
        !           971:                //
        !           972:                if ([self isAtapiDevice:unit])
        !           973:                        continue;
        !           974:                
        !           975:                // Test DMA reads.
        !           976:                //
        !           977:                if ((_drives[unit].ideInfo.type != 0) &&        
        !           978:                        (_drives[unit].transferType != IDE_TRANSFER_PIO) &&
        !           979:                        ([self performDMATest] != IDER_SUCCESS)) {
        !           980:                        IOLog("%s: Drive %d: DMA read test FAILED\n", [self name], unit);
        !           981:                        /* Failure, mask out the current mode */
        !           982:                        _drives[unit].driveMasks.array.mode[_drives[unit].transferType] &= 
        !           983:                                ~_drives[unit].transferMode;
        !           984:                        retry = YES;
        !           985:                }
        !           986: 
        !           987:                // Test PIO multisector reads.
        !           988:                //
        !           989:                // FIXME - Test Fast PIO modes as well?
        !           990:                //
        !           991:                if ((_drives[unit].ideInfo.type != 0) &&
        !           992:                        (_drives[unit].transferType == IDE_TRANSFER_PIO) &&
        !           993:                        (_drives[unit].multiSector)) {
        !           994: 
        !           995:                        ideRegsVal_t ideRegs;
        !           996:                        char *buf;
        !           997:                        
        !           998:                        ideRegs = [self logToPhys:0 numOfBlocks:_drives[unit].multiSector];
        !           999:                        buf = IOMalloc(_drives[unit].multiSector * IDE_SECTOR_SIZE);
        !          1000:                        if ([self ideReadMultiple:&ideRegs 
        !          1001:                        client:(struct vm_map *)IOVmTaskSelf()
        !          1002:                        addr:buf] != IDER_SUCCESS) {
        !          1003:                        IOLog("%s: Drive %d: Read Multiple test FAILED\n",
        !          1004:                                        [self name], unit);
        !          1005:                                _multiSectorRequested = NO;
        !          1006:                                retry = YES;
        !          1007:                }
        !          1008:                IOFree(buf, _drives[unit].multiSector * IDE_SECTOR_SIZE);
        !          1009:                }
        !          1010:        }
        !          1011: 
        !          1012:        } while (retry);
        !          1013: }
        !          1014: 
        !          1015: /*
        !          1016:  * Method: resetController
        !          1017:  *
        !          1018:  * Reset the controller on the HOST side.
        !          1019:  */
        !          1020: - (void)resetController
        !          1021: {
        !          1022:        /*
        !          1023:         * Return the controller to the compatible timing mode.
        !          1024:         */
        !          1025:        [self resetPCIController];
        !          1026: }
        !          1027: 
        !          1028: /*
        !          1029:  * Method: getBestTransferMode
        !          1030:  *
        !          1031:  * Find the "best" mode given the txferModes_t structure for both the drive
        !          1032:  * and the controller. Recall that the txferModes_t type encodes all the
        !          1033:  * transfer modes that a device can attain. Certain modes may also be masked
        !          1034:  * so that they will never be used. This mask is stored in the driveMasks.
        !          1035:  */
        !          1036: -(void)getBestTransferMode:(ata_mode_t *)mode type:(ideTransferType_t *)type 
        !          1037:        forUnit:(unsigned int)unit
        !          1038: {
        !          1039:        txferModes_t m;         // store all the possible modes.
        !          1040: 
        !          1041:        m.modes = _drives[unit].driveModes.modes & _drives[unit].driveMasks.modes &
        !          1042:                _controllerModes.modes;
        !          1043: 
        !          1044:        /*
        !          1045:         * Test in the order of "best" to "worst" modes.
        !          1046:         */     
        !          1047:        if (m.mode.udma) {
        !          1048:                *type = IDE_TRANSFER_ULTRA_DMA;
        !          1049:                *mode = ata_mask_to_mode(m.mode.udma);
        !          1050:        }
        !          1051:        else if (m.mode.mwdma) {
        !          1052:                *type = IDE_TRANSFER_MW_DMA;
        !          1053:                *mode = ata_mask_to_mode(m.mode.mwdma);
        !          1054:        }
        !          1055:        else if (m.mode.swdma) {
        !          1056:                *type = IDE_TRANSFER_SW_DMA;
        !          1057:                *mode = ata_mask_to_mode(m.mode.swdma);
        !          1058:        }
        !          1059:        else if (m.mode.pio) {
        !          1060:                *type = IDE_TRANSFER_PIO;
        !          1061:                *mode = ata_mask_to_mode(m.mode.pio);
        !          1062:        }
        !          1063:        else {
        !          1064:                *type = IDE_TRANSFER_PIO;
        !          1065:                *mode = ATA_MODE_0;
        !          1066:        }
        !          1067: }
        !          1068: 
        !          1069: /*
        !          1070:  * Method: getTransferModes:fromInfo:
        !          1071:  *
        !          1072:  * Purpose:
        !          1073:  * Given an infoPtr which points to information from the IDE Identify Drive
        !          1074:  * command, determine the transfer modes that the drive is capable of.
        !          1075:  *
        !          1076:  */
        !          1077: - (void)getTransferModes:(txferModes_t *)modes
        !          1078:        fromInfo:(ideIdentifyInfo_t *)infoPtr 
        !          1079: {
        !          1080:        unsigned char n;
        !          1081:     ata_mode_t m = ATA_MODE_0;
        !          1082:        int i;
        !          1083: 
        !          1084:     /*
        !          1085:      * For PIO, check if we support the ATA-2 additions. 
        !          1086:      */
        !          1087:        if (infoPtr->fieldValidity & IDE_WORDS64_TO_70_SUPPORTED) {
        !          1088:                if (infoPtr->fcPioDataTransferCyleTimingMode &
        !          1089:                        IDE_FC_PIO_MODE_5_SUPPORTED)
        !          1090:                        m = ATA_MODE_5;
        !          1091:                else if (infoPtr->fcPioDataTransferCyleTimingMode &
        !          1092:                        IDE_FC_PIO_MODE_4_SUPPORTED)
        !          1093:                        m = ATA_MODE_4;
        !          1094:                else if (infoPtr->fcPioDataTransferCyleTimingMode &
        !          1095:                        IDE_FC_PIO_MODE_3_SUPPORTED)
        !          1096:                        m = ATA_MODE_3;
        !          1097:        }
        !          1098:        else {
        !          1099:                n = (infoPtr->pioDataTransferCyleTimingMode &
        !          1100:                        IDE_PIO_TIMING_MODE_MASK) >> 8;
        !          1101:                if (n >= 2) n = 2;
        !          1102:                m = (1 << n);   // convert number to mode
        !          1103:        }
        !          1104:                
        !          1105:        /* For mode 2 and above, IORDY must be supported. */
        !          1106:        if ((m > ATA_MODE_2) &&
        !          1107:                !(infoPtr->capabilities & IDE_CAP_IORDY_SUPPORTED))
        !          1108:                m = ATA_MODE_2;
        !          1109:        
        !          1110:        /*
        !          1111:         * A drive supporting a certain mode must also support slower modes
        !          1112:         * of the same transfer type.
        !          1113:         */
        !          1114:        modes->mode.pio = ata_mode_to_mask(m);
        !          1115:        
        !          1116:        /*
        !          1117:         * Drive must indicate that it supports DMA in Word 49 before
        !          1118:         * continuing.
        !          1119:         */
        !          1120:        if (!(infoPtr->capabilities & IDE_CAP_DMA_SUPPORTED)) {
        !          1121:                modes->mode.swdma = ATA_MODE_NONE;
        !          1122:                modes->mode.mwdma = ATA_MODE_NONE;
        !          1123:                modes->mode.udma  = ATA_MODE_NONE;
        !          1124:                return;
        !          1125:        }
        !          1126:        
        !          1127:        /*
        !          1128:         * Single word DMA. Read from Word 52.
        !          1129:         */
        !          1130:        n = (infoPtr->dmaDataTransferCyleTimingMode &
        !          1131:                IDE_DMA_TIMING_MODE_MASK) >> 8;
        !          1132:        if (n >= 2)
        !          1133:                n = 2;
        !          1134:        m = (1 << n);
        !          1135:        modes->mode.swdma = ata_mode_to_mask(m);        
        !          1136:        
        !          1137:        /*
        !          1138:         * Multiword DMA. Read Word 63.
        !          1139:         */
        !          1140:        m = ATA_MODE_NONE;
        !          1141:        for (i = 2; i >= 0; i--) {
        !          1142:                if (infoPtr->mwDma & (1 << i)) {
        !          1143:                        m = (1 << i);
        !          1144:                        break;
        !          1145:                }
        !          1146:        }
        !          1147:        /* Can't be Multiword DMA mode 1 and above and NOT support
        !          1148:         * Words 64 through 70.
        !          1149:         */
        !          1150:        if ((m >= ATA_MODE_1) &&
        !          1151:                !(infoPtr->fieldValidity & IDE_WORDS64_TO_70_SUPPORTED)) {
        !          1152:                m = ATA_MODE_0;
        !          1153:     }
        !          1154:        modes->mode.mwdma = ata_mode_to_mask(m);        
        !          1155:     
        !          1156:        /*
        !          1157:         * Ultra DMA. Read capability from Word 88.
        !          1158:         */
        !          1159:        m = ATA_MODE_NONE;
        !          1160:        if (infoPtr->fieldValidity & IDE_WORD88_SUPPORTED) {
        !          1161:                for (i = 2; i >= 0; i--) {
        !          1162:                        if (infoPtr->UDma & (1 << i)) {
        !          1163:                                m = (1 << i);
        !          1164:                                break;
        !          1165:                        }
        !          1166:                }
        !          1167:        }
        !          1168:        modes->mode.udma = ata_mode_to_mask(m);
        !          1169: 
        !          1170:     return;
        !          1171: }
        !          1172: 
        !          1173: /*
        !          1174:  * We do host dependent hardware initialization here. 
        !          1175:  */
        !          1176: - (BOOL) setControllerCapabilities
        !          1177: {
        !          1178:        if (_controllerID != PCI_ID_NONE) {
        !          1179:                if ([self setPCIControllerCapabilitiesForDrives:_drives] == NO)
        !          1180:                        return NO;
        !          1181:                _transferWidth = [self getPIOTransferWidth];
        !          1182:                return YES;
        !          1183:        }
        !          1184:        return YES;
        !          1185: }
        !          1186: 
        !          1187: /*
        !          1188:  * Method: setATADriveCapabilities
        !          1189:  *
        !          1190:  * Send the Set Parameters command to the drive and set multi-sector mode
        !          1191:  * etc. if the drive supports them. If biosInfo is YES, then we are using
        !          1192:  * drive geometry information from the BIOS else we use Identify command to
        !          1193:  * get this. 
        !          1194:  */
        !          1195: - (ide_return_t)setATADriveCapabilities:(unsigned int)unit     
        !          1196:                withBIOSInfo:(BOOL)biosInfo
        !          1197: {
        !          1198:     ideRegsVal_t ideRegs;
        !          1199:     unsigned char nSectors;
        !          1200:        ide_return_t rtn;
        !          1201:     ideIdentifyInfo_t *infoPtr = _drives[unit].ideIdentifyInfo;
        !          1202: 
        !          1203:     _drives[unit].ideIdentifyInfoSupported = YES;
        !          1204:     bzero(infoPtr, sizeof(ideIdentifyInfo_t));
        !          1205: 
        !          1206:     _driveNum = unit;
        !          1207: 
        !          1208:     /*
        !          1209:      * Remember this command is optional. Failure means that either this
        !          1210:      * command is not supported or the drive is not present.
        !          1211:      */
        !          1212:     if ([self ideReadGetInfoCommon:&ideRegs 
        !          1213:                client:(struct vm_map *)IOVmTaskSelf() 
        !          1214:                addr:(unsigned char *)infoPtr
        !          1215:                        command:IDE_IDENTIFY_DRIVE] != IDER_SUCCESS) {
        !          1216:                _drives[unit].ideIdentifyInfoSupported = NO;
        !          1217:                if (_ide_debug)
        !          1218:                IOLog("ATA: ideReadGetInfoCommon failed.\n");
        !          1219:                /*
        !          1220:                 * FIXME: If this is a slave device and we perform a reset. The
        !          1221:                 * master device will lose its configuration state.
        !          1222:                 */
        !          1223:                [self ideReset];        /* necessary */
        !          1224:         return IDER_CMD_ERROR;
        !          1225:     }
        !          1226: 
        !          1227:     /*
        !          1228:      * Fill in this struct similar to which we would have gotten from CMOS. 
        !          1229:      */
        !          1230:     if (biosInfo == NO)        {
        !          1231:                ideDriveInfo_t *ip = &(_drives[unit].ideInfo);
        !          1232:        
        !          1233:                ip->cylinders = _drives[unit].ideIdentifyInfo->cylinders;
        !          1234:                ip->heads = _drives[unit].ideIdentifyInfo->heads;
        !          1235:                ip->control_byte = 0;
        !          1236:                ip->landing_zone = 0;
        !          1237:                ip->sectors_per_trk = _drives[unit].ideIdentifyInfo->sectorsPerTrack;
        !          1238:                ip->bytes_per_sector = IDE_SECTOR_SIZE;
        !          1239:                if ([IODevice driverKitVersion] > 410) { 
        !          1240:                        ip->total_sectors = ip->sectors_per_trk *
        !          1241:                                                                ip->heads *
        !          1242:                                                                ip->cylinders;
        !          1243:                        
        !          1244:                        /* If disk supports LBA, and Words (61:60) indicates that the
        !          1245:                         * user-addressable logical sectors is larger than the number
        !          1246:                         * of sectors computed through CHS translation, then use the
        !          1247:                         * larger value. This will be needed for disks with more than
        !          1248:                         * 16,514,064 sectors. (16383 C x 16 H x 63 S)
        !          1249:                         */
        !          1250:                        if ((infoPtr->capabilities & IDE_CAP_LBA_SUPPORTED) &&
        !          1251:                                (infoPtr->userAddressableSectors > ip->total_sectors))
        !          1252:                                ip->total_sectors = infoPtr->userAddressableSectors;
        !          1253:                }
        !          1254:                else {
        !          1255:                // fake capacity for backward compatibility.
        !          1256:                        ip->total_sectors = ip->sectors_per_trk * ip->heads *
        !          1257:                        ip->cylinders * ip->bytes_per_sector;
        !          1258:                }
        !          1259:     }
        !          1260: 
        !          1261:     /*
        !          1262:      * Set address mode. The only case in which we need to override user
        !          1263:      * selection if the user chooses LBA and the drive supports only CHS. 
        !          1264:      */
        !          1265:     if (((infoPtr->capabilities & IDE_CAP_LBA_SUPPORTED) == 0x0) &&
        !          1266:                (_drives[unit].addressMode == ADDRESS_MODE_LBA)) {
        !          1267: #ifdef DEBUG
        !          1268:                IOLog("%s: WARNING: LBA mode is not supported by drive %d.\n",
        !          1269:                    [self name], unit);
        !          1270: #endif DEBUG
        !          1271:                _drives[unit].addressMode = ADDRESS_MODE_CHS;
        !          1272:        }
        !          1273: 
        !          1274:     /*
        !          1275:      * Set disk parameters (Initialize Device Parameters command). 
        !          1276:      */
        !          1277:     [self ideSetParams:_drives[unit].ideInfo.sectors_per_trk
        !          1278:                numHeads:_drives[unit].ideInfo.heads ForDrive:unit];
        !          1279:        
        !          1280:        /*
        !          1281:         * Determine the best transfer mode.
        !          1282:         */
        !          1283:        [self getTransferModes:&_drives[unit].driveModes fromInfo:infoPtr];
        !          1284:        [self getBestTransferMode:&_drives[unit].transferMode
        !          1285:                type:&_drives[unit].transferType
        !          1286:                forUnit:unit];
        !          1287: 
        !          1288:        /*
        !          1289:         * Determine the number of sectors for each Multiple Read/Write.
        !          1290:         */
        !          1291:        nSectors = infoPtr->multipleSectors & IDE_MULTI_SECTOR_MASK;
        !          1292:        if ((_drives[unit].transferType == IDE_TRANSFER_PIO) &&
        !          1293:                (nSectors) && (_multiSectorRequested == YES)) {
        !          1294:                if ([self ideSetMultiSectorMode:&ideRegs numSectors:nSectors] ==
        !          1295:                        IDER_SUCCESS) {
        !          1296:                        _drives[unit].multiSector = nSectors;
        !          1297:                }
        !          1298:        }
        !          1299: 
        !          1300: #if 0
        !          1301:        IOLog("Drive      modes: %08x\n", _driveModes[unit].modes);
        !          1302:        IOLog("Controller modes: %08x\n", _controllerModes.modes);
        !          1303:        IOLog("drive %d: MODE:0x%02x TYPE:%d\n", unit, _transferMode[unit],
        !          1304:                _transferType[unit]);
        !          1305: #endif
        !          1306: 
        !          1307:        /*
        !          1308:         * Set drive feature.
        !          1309:         */
        !          1310:        rtn = [self ideSetDriveFeature:FEATURE_SET_TRANSFER_MODE
        !          1311:                        value:_drives[unit].transferMode
        !          1312:                        transferType:_drives[unit].transferType];
        !          1313: 
        !          1314:        if (rtn != IDER_SUCCESS) {
        !          1315:                IOLog("%s: Drive %d: set transfer mode failed\n", [self name], unit);
        !          1316:                _drives[unit].transferType = IDE_TRANSFER_PIO;
        !          1317:                _drives[unit].transferMode = ATA_MODE_0;
        !          1318:        }
        !          1319: 
        !          1320:     return IDER_SUCCESS;
        !          1321: }
        !          1322: 
        !          1323: /*
        !          1324:  * Method: setATAPIDriveCapabilities
        !          1325:  *
        !          1326:  * Identify the ATAPI device and set its transfer type/mode.
        !          1327:  */
        !          1328: - (ide_return_t)setATAPIDriveCapabilities:(unsigned int)unit   
        !          1329: {
        !          1330:     atapi_return_t     rtn;
        !          1331: 
        !          1332:        _driveNum = unit;
        !          1333:                
        !          1334:        [self atapiSoftReset:unit];
        !          1335: 
        !          1336:        /*
        !          1337:         * We have to do this test because of "task file shadow" bug
        !          1338:         * present in many ATAPI CD-ROMs. 
        !          1339:         */
        !          1340:        rtn = [self atapiIdentifyDevice:(struct vm_map *)IOVmTaskSelf()
        !          1341:                        addr:(unsigned char *)_drives[unit].ideIdentifyInfo unit:unit];
        !          1342:                
        !          1343:        /* Too bad.. */
        !          1344:        if (rtn != IDER_SUCCESS)
        !          1345:                return rtn;
        !          1346: 
        !          1347:        [self printAtapiInfo:_drives[unit].ideIdentifyInfo Device:unit];
        !          1348:        [self atapiInitParameters:_drives[unit].ideIdentifyInfo Device:unit];
        !          1349: 
        !          1350:        _drives[unit].addressMode = ADDRESS_MODE_LBA;
        !          1351:        
        !          1352:        [self getTransferModes:&_drives[unit].driveModes
        !          1353:                fromInfo:_drives[unit].ideIdentifyInfo];
        !          1354:        [self getBestTransferMode:&_drives[unit].transferMode
        !          1355:                type:&_drives[unit].transferType forUnit:unit];
        !          1356: 
        !          1357:        rtn = [self ideSetDriveFeature:FEATURE_SET_TRANSFER_MODE
        !          1358:                        value:_drives[unit].transferMode
        !          1359:                        transferType:_drives[unit].transferType];
        !          1360:        if (rtn != IDER_SUCCESS) {
        !          1361:                IOLog("%s: Drive %d: set transfer mode failed\n",
        !          1362:                        [self name], unit);
        !          1363:                _drives[unit].transferMode = ATA_MODE_0;
        !          1364:                _drives[unit].transferType = IDE_TRANSFER_PIO;
        !          1365:        }
        !          1366: 
        !          1367:        return IDER_SUCCESS;
        !          1368: }
        !          1369: 
        !          1370: -(ideIdentifyInfo_t *)getIdeIdentifyInfo:(unsigned int)unit
        !          1371: {
        !          1372:     return _drives[unit].ideIdentifyInfoSupported ?
        !          1373:                _drives[unit].ideIdentifyInfo : NULL;
        !          1374: }
        !          1375: 
        !          1376: -(BOOL)isDiskGeometry:(unsigned int)unit
        !          1377: {
        !          1378:     return (_drives[unit].biosGeometry == YES) ? NO : YES;
        !          1379: }
        !          1380: 
        !          1381: 
        !          1382: - (ideDriveInfo_t)getIdeInfoFromBIOS:(unsigned)unit 
        !          1383: {
        !          1384:     caddr_t hdtbl;
        !          1385:     ideDriveInfo_t hdInfo;
        !          1386: 
        !          1387:     hdInfo.type = [self getIdeTypeFromCMOS:unit];
        !          1388:     if ((hdInfo.type == 0) || (hdInfo.type < MIN_CMOS_IDETYPE) ||
        !          1389:        (hdInfo.type > MAX_CMOS_IDETYPE)) {
        !          1390:        hdInfo.type = 0;
        !          1391:        return (hdInfo);
        !          1392:     }
        !          1393: 
        !          1394:     /*
        !          1395:      * Drive info (the drive characteristic table) for drive 0 is located at
        !          1396:      * INT41h and for drive 1 it is located at INT46h. 
        !          1397:      */
        !          1398:     if (unit == 0) {
        !          1399:        hdtbl = (caddr_t) (*(unsigned short *)(0x41 << 2) +
        !          1400:                        (*(unsigned short *)((0x41 << 2) + 2) << 4));
        !          1401:     } else if (unit == 1) {
        !          1402:        hdtbl = (caddr_t) (*(unsigned short *)(0x46 << 2) +
        !          1403:                        (*(unsigned short *)((0x46 << 2) + 2) << 4));
        !          1404:     } else {
        !          1405:        hdInfo.type = 0;
        !          1406:        return (hdInfo);
        !          1407:     }
        !          1408: 
        !          1409:     if (hdtbl == 0) {
        !          1410:        IOLog("%s: drive %d, type %d, using geometry from CMOS.\n",
        !          1411:                [self name], unit, hdInfo.type);
        !          1412:     } else {
        !          1413:        IOLog("%s: drive %d, type %d, using geometry from INT table.\n",
        !          1414:                [self name], unit, hdInfo.type);
        !          1415:     }
        !          1416:     
        !          1417:     if (hdtbl == 0) {
        !          1418:        hdtbl = (caddr_t) pmap_phys_to_kern(CMOS_IDE_TABLE);
        !          1419:        hdtbl += ((hdInfo.type - 1) * SIZE_OF_IDE_TABLE);
        !          1420:     }
        !          1421:     
        !          1422:     hdInfo.cylinders = *(unsigned short *)hdtbl;
        !          1423:     hdInfo.heads = *(hdtbl + 2);
        !          1424:     hdInfo.precomp = *(unsigned short *)(hdtbl + 5);
        !          1425:     hdInfo.control_byte = *(hdtbl + 8);
        !          1426:     hdInfo.landing_zone = *(unsigned short *)(hdtbl + 12);
        !          1427:     hdInfo.sectors_per_trk = *(hdtbl + 14);
        !          1428:     hdInfo.bytes_per_sector = IDE_SECTOR_SIZE;
        !          1429:     if([IODevice driverKitVersion] > 410) { 
        !          1430:        hdInfo.total_sectors = hdInfo.sectors_per_trk *
        !          1431:            hdInfo.heads * hdInfo.cylinders;
        !          1432:     }
        !          1433:     else {
        !          1434:        // fake capacity for backward compatibility.
        !          1435:        hdInfo.total_sectors = hdInfo.sectors_per_trk *
        !          1436:            hdInfo.heads * hdInfo.cylinders * hdInfo.bytes_per_sector;
        !          1437:     }
        !          1438: 
        !          1439: #ifdef DEBUG
        !          1440:     /*
        !          1441:      * FIXME: This is for testing only. Remove later. 
        !          1442:      */
        !          1443:     IOLog("%s: drive %d, %d cylinders, %d heads, %d sectors (BIOS).\n", 
        !          1444:        [self name], unit, hdInfo.cylinders, hdInfo.heads, 
        !          1445:        hdInfo.sectors_per_trk);
        !          1446: #endif DEBUG
        !          1447: 
        !          1448:     return hdInfo;
        !          1449: }
        !          1450: 
        !          1451: - (unsigned)getIdeTypeFromCMOS:(int)unit
        !          1452: {
        !          1453:     unsigned int hdtype;
        !          1454: 
        !          1455:     outb(CMOSADDR, HDTYPE);
        !          1456:     IODelay(10);
        !          1457:     hdtype = inb(CMOSDATA);
        !          1458: 
        !          1459:     if (unit == 0) {
        !          1460:        hdtype = hdtype >> 4;
        !          1461:        if (hdtype != 0xf) {
        !          1462:            return hdtype;
        !          1463:        } else {
        !          1464:            outb(CMOSADDR, HD0_EXTTYPE);
        !          1465:            IODelay(10);
        !          1466:            hdtype = inb(CMOSDATA);
        !          1467:        }
        !          1468:     } else {
        !          1469:        hdtype = hdtype & 0x0f;
        !          1470:        if (hdtype != 0xf) {
        !          1471:            return hdtype;
        !          1472:        } else {
        !          1473:            outb(CMOSADDR, HD1_EXTTYPE);
        !          1474:            IODelay(10);
        !          1475:            hdtype = inb(CMOSDATA);
        !          1476:        }
        !          1477:     }
        !          1478: 
        !          1479: 
        !          1480:     return hdtype;
        !          1481: }
        !          1482: 
        !          1483: @end
        !          1484: 

unix.superglobalmegacorp.com

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