|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.