Annotation of drvEIDE/EIDE.drvproj/EIDE.lksproj/DualEide.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.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:  * DualEide.m - Dual EIDE controller initialization. 
                     29:  *
                     30:  * HISTORY
                     31:  *
                     32:  * 1-Feb-1998  Joe Liu at Apple
                     33:  *             Tweaked code to support PIIX which uses the DualEIDE but with a PCI
                     34:  *             bus. Not sure if this change will work under 3.3.
                     35:  *
                     36:  * 18-Aug-1996         Becky Divinski at NeXT
                     37:  *      Created. 
                     38:  */
                     39: 
                     40: #import <sys/systm.h>
                     41: 
                     42: #import <driverkit/KernBus.h>
                     43: #import <driverkit/KernDevice.h>
                     44: #import <driverkit/KernDeviceDescription.h>
                     45: #import <driverkit/IODeviceDescription.h>
                     46: #import <driverkit/IODeviceDescriptionPrivate.h>
                     47: 
                     48: #import "DualEide.h"
                     49: #import "IdeCnt.h"
                     50: #import "IdeDisk.h"
                     51: #import "AtapiCnt.h"
                     52: 
                     53: /* Some mach stuff to create a mach port, kernel/driverkit/driverServerXXX.m */
                     54: extern port_t create_dev_port(KernDevice *kernDevice);
                     55: 
                     56: #define BUS_TYPE_KEY           "Bus Type"
                     57: #define KERN_BUS_FORMAT                "%sKernBus"
                     58: #define DEVICE_DESCR_FORMAT    "IO%sDeviceDescription"
                     59: #define DEFAULT_BUS                    "EISA"  // don't change this! (see comment below)
                     60: #define NAME_BUF_LEN           128
                     61: 
                     62: __private_extern__ unsigned int        instanceNum = 0;
                     63: __private_extern__ BOOL         dualEide = NO;
                     64: 
                     65: #if (IO_DRIVERKIT_VERSION >= 400)
                     66: 
                     67: static IOEISADeviceDescription *getBusDescription(IOConfigTable *configTable)
                     68: {
                     69:     id         deviceDescription, ioDeviceDescription = nil;
                     70:     id         busClass, defaultBusClass, busDescriptionClass;
                     71:     id         defaultBus;
                     72:     const char *busType, *busTypeString;
                     73:     char       *nameBuf = NULL;
                     74:     id         device;
                     75: 
                     76:     defaultBusClass = [KernBus lookupBusClassWithName:DEFAULT_BUS];    
                     77:     // XXX
                     78:     if (defaultBusClass == nil) {
                     79:         sprintf(nameBuf, "Missing %s kernel bus class", DEFAULT_BUS);
                     80:         panic(nameBuf);
                     81:     }
                     82: 
                     83:     defaultBus = [KernBus lookupBusInstanceWithName:DEFAULT_BUS busId:0];
                     84: 
                     85:     nameBuf = (char *)IOMalloc(NAME_BUF_LEN);
                     86: 
                     87:     busTypeString = [configTable valueForStringKey:BUS_TYPE_KEY];
                     88: 
                     89:     if (busTypeString == NULL || *busTypeString == '\0')
                     90:         busType = DEFAULT_BUS;
                     91:     else
                     92:         busType = busTypeString;
                     93: 
                     94:     sprintf(nameBuf, KERN_BUS_FORMAT, busType);
                     95:     busClass = objc_getClass((const char *)nameBuf);
                     96: 
                     97:     if (busClass == nil)       {
                     98:         busClass = defaultBusClass;
                     99:         busType = DEFAULT_BUS;
                    100:     }
                    101: 
                    102:        /*
                    103:         * Instead of messaging the 'busClass', we call defaultBusClass
                    104:         * to create a new deviceDescription for us.
                    105:         * This is because PCI for some reason does not allocate resources
                    106:         * for the "I/O Ports" and the "IRQ Levels" key.
                    107:         * The defaultBusClass, which is EISA, does allocate the resources.
                    108:         */
                    109:     deviceDescription = [defaultBusClass 
                    110:                        deviceDescriptionFromConfigTable:configTable];  
                    111:     if (deviceDescription == nil) {
                    112:         IOLog("getBusDescription: deviceDescriptionFromConfigTable failed");
                    113:                return nil;
                    114:     }
                    115: 
                    116:        /*
                    117:         * Force the bus to be always EISA.
                    118:         */
                    119: //     if ([deviceDescription bus] == nil) {
                    120:         [deviceDescription setBus:defaultBus];
                    121: //    }
                    122: 
                    123:     device = [[KernDevice alloc] initWithDeviceDescription:deviceDescription];
                    124:     if (device == nil) {
                    125:         IOLog("getBusDescription: initWithDeviceDescription failed ");
                    126:         return nil;    
                    127:     }
                    128: 
                    129:     [deviceDescription setDevice: device];
                    130:        
                    131:     sprintf(nameBuf, "IO%sDeviceDescription", busType);
                    132:     busDescriptionClass = objc_getClass((const char *)nameBuf);
                    133: 
                    134:     ioDeviceDescription = [[busDescriptionClass alloc]
                    135:                                 _initWithDelegate: deviceDescription];
                    136:     [ioDeviceDescription setDevicePort:create_dev_port(device)];
                    137: 
                    138:     return (IOEISADeviceDescription *) ioDeviceDescription;
                    139: }
                    140: 
                    141: #else /* IO_DRIVERKIT_VERSION < 400 */
                    142: 
                    143: id             EISABusClass, theEISABus;
                    144: 
                    145: static IOEISADeviceDescription *getBusDescription(IOConfigTable *configTable)
                    146: {
                    147:     id         deviceDescription, ioDeviceDescription = nil;
                    148:     id         busClass, defaultBusClass, busDescriptionClass;
                    149:     id         defaultBus;
                    150:     id         device;
                    151:     char       *nameBuf;
                    152:     const char *busType;
                    153:     char       busClassName[128];
                    154: 
                    155:     EISABusClass = objc_getClass("EISAKernBus");
                    156:     if (EISABusClass == nil)
                    157:         panic("Missing EISA kernel bus class");
                    158:     theEISABus = [[EISABusClass alloc] init];
                    159: 
                    160:     busType = [configTable valueForStringKey:"Bus Type"];
                    161: 
                    162:     if (busType) {
                    163:         sprintf(busClassName, "%sKernBus", busType);
                    164:         busClass = objc_getClass((const char *)busClassName);
                    165:     } else {
                    166:         busClass = nil;
                    167:     }
                    168: 
                    169:     if (busClass == nil)
                    170:         busClass = objc_getClass("EISAKernBus");
                    171: 
                    172:     deviceDescription = [theEISABus
                    173:                             deviceDescriptionFromConfigTable:configTable];     
                    174: 
                    175:     if (deviceDescription == nil) {
                    176:         IOLog("configureDriver: initFromConfigTable failed");
                    177:         return nil;
                    178:     }
                    179: 
                    180:     device = [[KernDevice alloc]
                    181:                     initWithDeviceDescription: deviceDescription];
                    182: 
                    183:     if (device == nil) {
                    184:         IOLog("configureDriver: initFromDeviceDescription failed");
                    185:         return nil;            
                    186:     }
                    187: 
                    188:     [deviceDescription setDevice:device];
                    189: 
                    190:     if (busType) {
                    191:         sprintf(busClassName, "IO%sDeviceDescription",
                    192:                 busType);
                    193:         busDescriptionClass =
                    194:             objc_getClass((const char *)busClassName);
                    195:     } else {
                    196:         busDescriptionClass = nil;
                    197:     }
                    198: 
                    199:     if (busDescriptionClass == nil)
                    200:         busDescriptionClass =
                    201:             objc_getClass("IOEISADeviceDescription");
                    202: 
                    203:     ioDeviceDescription = [[busDescriptionClass alloc]
                    204:                                 _initWithDelegate: deviceDescription];
                    205:     [ioDeviceDescription setDevicePort: create_dev_port(device)];
                    206: 
                    207:     return (IOEISADeviceDescription *) ioDeviceDescription;
                    208: }
                    209: #endif IO_DRIVERKIT_VERSION >= 400
                    210: 
                    211: @implementation DualEide
                    212: 
                    213: +(BOOL)probe:(IODeviceDescription *)devDesc
                    214: {
                    215:     IOEISADeviceDescription *primaryEISADeviceDescr;
                    216:        IOEISADeviceDescription *secondaryEISADeviceDescr;
                    217:     IORange            primaryPortRange;
                    218:        IORange         secondaryPortRange;
                    219:     IORange    *portRangeList;
                    220: 
                    221:     unsigned int       numPortRanges;
                    222:     unsigned int       numInterrupts;
                    223: 
                    224:     unsigned int primaryInterrupt;
                    225:        unsigned int secondaryInterrupt;
                    226:     unsigned int *interruptList;
                    227:        unsigned int probeFailedCount = 0;
                    228: 
                    229:        IOReturn rtn;
                    230:     dualEide = YES;
                    231:        
                    232:     /*
                    233:      * Need to create a second device description to send to the second
                    234:      * instance.  Start with primary instance's configTable to create another
                    235:      * device description.
                    236:      */
                    237:     primaryEISADeviceDescr   = (IOEISADeviceDescription *) devDesc;
                    238:     secondaryEISADeviceDescr = getBusDescription([devDesc configTable]);
                    239:     if (secondaryEISADeviceDescr == nil) {
                    240:         return NO;
                    241:        }
                    242: 
                    243:     // Get the interrupts from the primary device description.
                    244:     numInterrupts = [primaryEISADeviceDescr numInterrupts];
                    245:     interruptList = [primaryEISADeviceDescr interruptList];    
                    246: 
                    247:     primaryInterrupt = *interruptList;
                    248:        ++interruptList;
                    249:     secondaryInterrupt = *interruptList;
                    250: 
                    251:     // Get the port ranges from the primary device description.
                    252:     numPortRanges = [primaryEISADeviceDescr numPortRanges];
                    253:     portRangeList = [primaryEISADeviceDescr portRangeList];    
                    254: 
                    255:     primaryPortRange.start   = portRangeList->start;
                    256:     primaryPortRange.size    = portRangeList->size;
                    257:        ++portRangeList;
                    258:     secondaryPortRange.start = portRangeList->start;
                    259:     secondaryPortRange.size  = portRangeList->size;
                    260: 
                    261:     // Put the correct interrupt into each device description  
                    262:     [primaryEISADeviceDescr setInterruptList:&primaryInterrupt num:1];
                    263:     rtn = [secondaryEISADeviceDescr setInterruptList:&secondaryInterrupt
                    264:                num:1];
                    265:        if (rtn != IO_R_SUCCESS) {
                    266:            IOLog("%s: Error in setInterruptList (%s)\n", [self name],
                    267:                        [self stringFromReturn:rtn]);
                    268:        }
                    269: 
                    270:     // Put the correct port range into each device description
                    271:     [primaryEISADeviceDescr setPortRangeList:&primaryPortRange num:1];
                    272:     rtn = [secondaryEISADeviceDescr setPortRangeList:&secondaryPortRange
                    273:                num:1];
                    274:        if (rtn != IO_R_SUCCESS) {
                    275:            IOLog("%s: Error in setPortRangeList (%s)\n", [self name],
                    276:                        [self stringFromReturn:rtn]);
                    277:        }
                    278:        
                    279:     // Probe the two instances of this Dual EIDE personality.
                    280: 
                    281:        instanceNum = 0;        // start with instance 0
                    282:        if (![IdeController probe: primaryEISADeviceDescr]) {
                    283: #if 0
                    284:                IOLog("Instance 0 of Dual EIDE failed the probe.\n");
                    285:                dualEide = NO;
                    286:                return NO;
                    287: #else
                    288:                probeFailedCount++;
                    289: #endif
                    290:        }
                    291: 
                    292:        instanceNum++;          // advance to instance 1
                    293:        if (![IdeController probe: secondaryEISADeviceDescr]) {
                    294: #if 0
                    295:                IOLog("Instance 1 of Dual EIDE failed the probe.\n");
                    296:                dualEide = NO;
                    297: #else
                    298:                probeFailedCount++;     
                    299: #endif
                    300:        }
                    301:        
                    302:        if (probeFailedCount == 2)
                    303:                return NO;
                    304:        
                    305:     return YES;
                    306: }
                    307: 
                    308: @end

unix.superglobalmegacorp.com

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