|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: /* Copyright (c) 1993 NeXT Computer, Inc. All rights reserved.
25: *
26: * User level implementation of IOConfigTable.
27: *
28: * HISTORY
29: * 27-Jan-93 Doug Mitchell at NeXT
30: * Created.
31: */
32:
33: #import <driverkit/IOConfigTable.h>
34: #import <driverkit/IODevice.h>
35: #import <driverkit/configTablePrivate.h>
36: #import <driverkit/generalFuncs.h>
37: #import <driverkit/driverServer.h>
38: #import <driverkit/driverTypesPrivate.h>
39: #import <streams/streams.h>
40: #import <objc/NXStringTable.h>
41: #import <libc.h>
42:
43: static void parseDriverList(const char *driverList, List *list);
44:
45: @interface IOConfigTable(Private)
46: + openForFile : (const char *)filename;
47: @end
48:
49: /*
50: * The _private ivar points to one of these.
51: */
52: typedef struct {
53: NXStringTable *stringTable;
54: const char *bundleName; // associated directory
55: } _configPriv;
56:
57: @implementation IOConfigTable
58:
59: - free
60: {
61: _configPriv *configPriv = _private;
62:
63: if(configPriv) {
64: if(configPriv->stringTable) {
65: [configPriv->stringTable free];
66: }
67: if(configPriv->bundleName) {
68: IOFree((void *)configPriv->bundleName,
69: strlen(configPriv->bundleName) + 1);
70: }
71: IOFree(configPriv, sizeof(_configPriv));
72: }
73: return [super free];
74: }
75:
76: /*
77: * Obtain the system-wide configuration table.
78: */
79: #define SYSTEM_CONFIG_FROM_RPC 1
80:
81: + newFromSystemConfig
82: {
83: #if SYSTEM_CONFIG_FROM_RPC
84:
85: IOReturn rtn;
86: IOConfigData configData;
87: unsigned size = IO_CONFIG_TABLE_SIZE;
88: NXStream *stream;
89: NXStringTable *stringTable;
90: int len;
91: IOConfigTable *newObj = [self alloc];
92: port_t deviceMaster = device_master_self();
93: _configPriv *configPriv;
94:
95: /*
96: * Get system config data from the kernel.
97: */
98: rtn = _IOGetSystemConfig(deviceMaster,
99: IO_CONFIG_TABLE_SIZE,
100: configData,
101: &size);
102: if(rtn) {
103: IOLog("IOConfigTable: _IOGetSystemConfig: %s\n",
104: [IODevice stringFromReturn:rtn]);
105: return nil;
106: }
107:
108: /*
109: * Create a stream, write raw table to it.
110: */
111: stream = NXOpenMemory(NULL, 0, NX_READWRITE);
112: len = strlen(configData);
113: NXWrite(stream, configData, len);
114: NXSeek(stream, 0, NX_FROMSTART);
115:
116: /*
117: * Create string table, write stream to it.
118: */
119: stringTable = [[NXStringTable alloc] init];
120: if([stringTable readFromStream:stream] == nil) {
121: IOLog("IOConfigTable: readFromStream returned nil\n");
122: [stringTable free];
123: return nil;
124: }
125: configPriv = newObj->_private = IOMalloc(sizeof(_configPriv));
126: configPriv->stringTable = stringTable;
127: configPriv->bundleName = NULL;
128: return newObj;
129:
130: #else SYSTEM_CONFIG_FROM_RPC
131: return [self openForFile:IO_SYSTEM_CONFIG_FILE];
132: #endif SYSTEM_CONFIG_FROM_RPC
133: }
134:
135: /*
136: * Obtain the configuration table for a specified device and unit number.
137: * ("Unit number" is terminology from IODevice.h. We've been calling it
138: * "instance number" in the context of system config and startup.)
139: */
140: + newForDriver : (const char *)driverName
141: unit : (int)unit
142: {
143: char filename[200];
144: IOConfigTable *newObj;
145: _configPriv *configPriv;
146: int length;
147: char *bundleName;
148:
149: sprintf(filename, "%s%s%s/Instance%d%s",
150: IO_CONFIG_DIR, driverName, IO_BUNDLE_EXTENSION,
151: unit, IO_TABLE_EXTENSION);
152: newObj = (IOConfigTable *)[self openForFile:filename];
153: if(newObj == nil) {
154: return nil;
155: }
156: configPriv = newObj->_private;
157: sprintf(filename, "%s%s%s",
158: IO_CONFIG_DIR, driverName, IO_BUNDLE_EXTENSION);
159: length = strlen(filename) + 1;
160: bundleName = IOMalloc(length);
161: strcpy(bundleName, filename);
162: configPriv->bundleName = bundleName;
163: return newObj;
164: }
165:
166: + newDefaultTableForDriver : (const char *)driverName
167: {
168: char filename[200];
169: IOConfigTable *newObj;
170: _configPriv *configPriv;
171: int length;
172: char *bundleName;
173:
174: sprintf(filename, "%s%s%s/%s",
175: IO_CONFIG_DIR, driverName, IO_BUNDLE_EXTENSION,
176: IO_DEFAULT_TABLE_FILENAME);
177: newObj = (IOConfigTable *)[self openForFile:filename];
178: if(newObj == nil) {
179: return nil;
180: }
181: configPriv = newObj->_private;
182: sprintf(filename, "%s%s%s",
183: IO_CONFIG_DIR, driverName, IO_BUNDLE_EXTENSION);
184: length = strlen(filename) + 1;
185: bundleName = IOMalloc(length);
186: strcpy(bundleName, filename);
187: configPriv->bundleName = bundleName;
188: return newObj;
189: }
190:
191:
192: /*
193: * Obtain a list of instances of IOConfigTable, one per {boot, active}
194: * device on the system.
195: */
196: + (List *) tablesForInstalledDrivers
197: {
198: List *list;
199: IOConfigTable *systemConfig;
200: const char *drivers;
201:
202: list = [[List alloc] init];
203: systemConfig = [self newFromSystemConfig];
204: if(systemConfig == nil) {
205: IOLog("tablesForInstalledDrivers: no system config file"
206: " found\n");
207: return nil;
208: }
209: drivers = [systemConfig valueForStringKey:"Boot Drivers"];
210: parseDriverList(drivers, list);
211: drivers = [systemConfig valueForStringKey:"Active Drivers"];
212: parseDriverList(drivers, list);
213: if([list count] == 0) {
214: IOLog("installedDrivers: no drivers found\n");
215: }
216: return list;
217: }
218:
219: /*
220: * Obtain a list of instances of IOConfigTable, one per driver
221: * loaded by the booter.
222: */
223: + (List *) tablesForBootDrivers
224: {
225: List *list;
226: IOReturn rtn;
227: int i;
228: IOConfigData configData;
229: unsigned size;
230: port_t deviceMaster = device_master_self();
231: NXStream *stream;
232: NXStringTable *stringTable;
233: int len;
234: IOConfigTable *newTable;
235: _configPriv *configPriv;
236:
237: list = [[List alloc] init];
238: for (i=1; ; i++) {
239: /*
240: * Get system config data from the kernel.
241: */
242: size = IO_CONFIG_TABLE_SIZE;
243: rtn = _IOGetDriverConfig(deviceMaster,
244: i,
245: IO_CONFIG_TABLE_SIZE,
246: configData,
247: &size);
248: if(rtn != IO_R_SUCCESS) {
249: if (rtn != IO_R_NO_DEVICE) {
250: IOLog("IOConfigTable: _IOGetDriverConfig: %s\n",
251: [IODevice stringFromReturn:rtn]);
252: [list free];
253: return nil;
254: }
255: break;
256: }
257:
258: /*
259: * Create a stream, write raw table to it.
260: */
261: stream = NXOpenMemory(NULL, 0, NX_READWRITE);
262: len = strlen(configData);
263: NXWrite(stream, configData, len);
264: NXSeek(stream, 0, NX_FROMSTART);
265:
266: /*
267: * Create string table, write stream to it.
268: */
269: stringTable = [[NXStringTable alloc] init];
270: if([stringTable readFromStream:stream] == nil) {
271: IOLog("IOConfigTable: readFromStream returned nil\n");
272: [stringTable free];
273: return nil;
274: }
275: newTable = [self alloc];
276: configPriv = newTable->_private = IOMalloc(sizeof(_configPriv));
277: configPriv->stringTable = stringTable;
278: configPriv->bundleName = NULL;
279: [list addObject:newTable];
280: }
281: return list;
282: }
283:
284: /*
285: * Obtain an NXBundle for a driver associated with current IOConfigTable
286: * instance.
287: */
288: - (NXBundle *)driverBundle;
289:
290: {
291: NXBundle *bundle;
292: _configPriv *configPriv = _private;
293:
294: if(configPriv->bundleName == NULL) {
295: /*
296: * Must be system config; no can do.
297: */
298: return nil;
299: }
300: bundle = [NXBundle alloc];
301: return [bundle initForDirectory:configPriv->bundleName];
302: }
303:
304:
305: /*
306: * Obtain value for specified string key, string and unsigned int versions.
307: *
308: * String version. Returns NULL if key not found.
309: */
310: - (const char *)valueForStringKey:(const char *)key
311: {
312: _configPriv *configPriv = _private;
313: NXStringTable *stringTable = configPriv->stringTable;
314:
315: return [stringTable valueForStringKey:key];
316: }
317:
318: @end
319:
320: @implementation IOConfigTable(Private)
321:
322: + openForFile : (const char *)filename
323: {
324: IOConfigTable *newObj = [self alloc];
325: NXStringTable *stringTable = [[NXStringTable alloc] init];
326: _configPriv *configPriv;
327:
328: newObj->_private = nil;
329: if([stringTable readFromFile:filename] == nil) {
330: [newObj free];
331: [stringTable free];
332: return nil;
333: }
334: configPriv = newObj->_private = IOMalloc(sizeof(_configPriv));
335: configPriv->stringTable = stringTable;
336: configPriv->bundleName = NULL;
337: return newObj;
338: }
339:
340:
341: @end
342:
343: /*
344: * parse driverList string; get an IOConfigTable for each unit
345: * of each device in the string; add each IOConfigTable to list.
346: */
347: static void
348: parseDriverList(const char *driverList,
349: List *list)
350: {
351: IOConfigTable *driverConfig;
352: char driverName[100];
353: const char *stringP; // --> activeDrivers
354: char *nameP; // --> driverName
355: int unit;
356: BOOL gotName;
357:
358: if(driverList == NULL) {
359: return;
360: }
361: nameP = driverName;
362: gotName = NO;
363: stringP = driverList;
364: while(1) {
365: if((*stringP == ' ') || (*stringP == '\0')) {
366: if(!gotName) {
367: /*
368: * Skip spaces (we haven't gotten a name yet).
369: */
370: if(*stringP == '\0') {
371: break; // trailing spaces
372: }
373: goto nextChar;
374: }
375: *nameP = '\0'; // null-terminate driverName
376:
377: /*
378: * Reset...
379: */
380: nameP = driverName;
381: gotName = NO;
382:
383: /*
384: * Get an IOCongTable for each possible
385: * instance of the driver.
386: */
387: for(unit=0; ; unit++) {
388: driverConfig = [IOConfigTable newForDriver:driverName
389: unit:unit];
390: if(driverConfig) {
391: [list addObject:driverConfig];
392: }
393: else {
394: /*
395: * No more instances.
396: */
397: if(*stringP) {
398: goto nextChar;
399: }
400: else {
401: goto out;
402: }
403: }
404: } /* for unit */
405: } /* space */
406: else {
407: gotName = YES;
408: *nameP++ = *stringP;
409: }
410: nextChar:
411: stringP++;
412: }
413: out:
414: return;
415: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.