|
|
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.