|
|
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:
25: /*
26: * Copyright 1997-1998 by Apple Computer, Inc., All rights reserved.
27: * Copyright 1994-1997 NeXT Software, Inc., All rights reserved.
28: *
29: * ATADisk.m - Exported methods for IDE/ATA Disk device class.
30: *
31: * HISTORY
32: * 07-Jul-1994 Rakesh Dubey at NeXT
33: * Created from original driver written by David Somayajulu.
34: */
35:
36: #import <driverkit/return.h>
37: #import <driverkit/driverTypes.h>
38: #import <driverkit/devsw.h>
39: #import <driverkit/generalFuncs.h>
40: #import <driverkit/kernelDiskMethods.h>
41: #import <driverkit/IODevice.h>
42: #import <machkit/NXLock.h>
43: #import <sys/systm.h>
44:
45: #import "ATADisk.h"
46: #import "ATADiskInternal.h"
47: #import "ATADiskKernel.h"
48:
49: //#define DEBUG
50:
51: static int diskUnit = 0;
52: static BOOL switchTableInited = NO;
53:
54: /*
55: * List of controllers that have been already probed. We need this since each
56: * Instance table lists ATADisk as well as IdeController classes. And we need
57: * to create instances of disks attached to each controller only once.
58: */
59: static int probedControllerCount = 0;
60: static id probedControllers[MAX_IDE_CONTROLLERS];
61:
62: @implementation ATADisk
63:
64: static Protocol *protocols[] = {
65: @protocol(IdeControllerPublic),
66: nil
67: };
68:
69: + (Protocol **)requiredProtocols
70: {
71: return protocols;
72: }
73:
74: + (IODeviceStyle)deviceStyle
75: {
76: return IO_IndirectDevice;
77: }
78:
79: /*
80: * IDE drives come with a built in controller on each drive. Hence we can
81: * have just one object per controller-disk pair. Probe is invoked at load
82: * time. It determines what drives are on the bus and alloc's and init:'s an
83: * instance of this class for each one.
84: *
85: */
86:
87: + (BOOL)probe : deviceDescription
88: {
89: id diskId;
90: IODevAndIdInfo *idMap = ide_idmap();
91: int unit, i;
92: id controllerId = [deviceDescription directDevice];
93:
94: #ifdef DEBUG
95: IOLog("ATADisk probed with controller id %x\n", controllerId);
96: #endif DEBUG
97:
98: for (i = 0; i < probedControllerCount; i++) {
99: if (probedControllers[i] == controllerId) {
100: IOLog("ATADisk already probed for controller %x\n", controllerId);
101: return YES;
102: }
103: }
104: probedControllers[probedControllerCount++] = controllerId;
105:
106: for (unit = 0; unit < MAX_IDE_DRIVES; unit++) {
107:
108: diskId = [[ATADisk alloc] initFromDeviceDescription:deviceDescription];
109: [diskId initResources:controllerId];
110: [diskId setDevAndIdInfo:&(idMap[diskUnit])];
111:
112: if ([diskId ideDiskInit:diskUnit target:unit] == NO) {
113: [diskId free];
114: continue;
115: }
116:
117: if (([self hd_devsw_init:deviceDescription]) == NO) {
118: [diskId free];
119: IOLog("ATADisk: failed to add to devsw tables.\n");
120: return NO;
121: }
122:
123: /*
124: * Success; we initialized a drive. Have DiskObject superclass take
125: * care of the rest.
126: */
127: [diskId setDeviceKind:"ATADisk"];
128: [diskId setIsPhysical:YES];
129: [diskId registerDevice];
130: diskUnit += 1;
131: }
132:
133: return YES;
134: }
135:
136:
137: - getDevicePath:(char *)path maxLength:(int)maxLen useAlias:(BOOL)doAlias
138: {
139: if( [super getDevicePath:path maxLength:maxLen useAlias:doAlias]) {
140:
141: char unitStr[ 12 ];
142: int len = maxLen - strlen( path);
143:
144: sprintf( unitStr, "/@%x", [self driveNum]);
145: len -= strlen( unitStr);
146: if( len < 0)
147: return( nil);
148: strcat( path, unitStr);
149: return( self);
150: }
151: return( nil);
152: }
153:
154: - (char *) matchDevicePath:(char *)matchPath
155: {
156: BOOL matches = NO;
157: char * unitStr;
158: extern long int strtol(const char *nptr, char **endptr, int base);
159:
160: unitStr = [super matchDevicePath:matchPath];
161: if( unitStr) {
162: unitStr = strchr( unitStr, '@');
163: if( unitStr) {
164: matches = ([self driveNum] == strtol( unitStr + 1, &unitStr, 16));
165: }
166: }
167: if( matches)
168: return( unitStr);
169: else
170: return( NULL);
171: }
172:
173: - property_IOUnit:(char *)result length:(unsigned int *)maxLen
174: {
175: sprintf( result, "%d", [self driveNum]);
176: }
177:
178:
179: /*
180: * Add our entry to the device switch tables.
181: */
182: + (BOOL)hd_devsw_init:deviceDescription
183: {
184: extern int seltrue();
185:
186: /*
187: * We get called once for each IDE controller in the system; we
188: * only have to call IOAddToCdevsw() once.
189: */
190: if (switchTableInited == YES) {
191: return YES;
192: }
193:
194: #if 0
195: if ([self addToCdevswFromDescription: deviceDescription
196: open: (IOSwitchFunc) ideopen
197: close: (IOSwitchFunc) ideclose
198: read: (IOSwitchFunc) ideread
199: write: (IOSwitchFunc) idewrite
200: ioctl: (IOSwitchFunc) ideioctl
201: stop: (IOSwitchFunc) eno_stop
202: reset: (IOSwitchFunc) nulldev
203: select: (IOSwitchFunc) seltrue
204: mmap: (IOSwitchFunc) eno_mmap
205: getc: (IOSwitchFunc) eno_getc
206: putc: (IOSwitchFunc) eno_putc] != YES)
207: {
208: return NO;
209: }
210:
211: if ([self addToBdevswFromDescription: deviceDescription
212: open: (IOSwitchFunc) ideopen
213: close: (IOSwitchFunc) ideclose
214: strategy: (IOSwitchFunc) idestrategy
215: ioctl: (IOSwitchFunc) ideioctl
216: dump: (IOSwitchFunc) eno_dump
217: psize: (IOSwitchFunc) idesize
218: isTape: FALSE] != YES)
219: {
220: return NO;
221: }
222: #endif
223:
224: if ( IOAddToCdevswAt( 15,
225: (IOSwitchFunc) ideopen,
226: (IOSwitchFunc) ideclose,
227: (IOSwitchFunc) ideread,
228: (IOSwitchFunc) idewrite,
229: (IOSwitchFunc) ideioctl,
230: (IOSwitchFunc) eno_stop,
231: (IOSwitchFunc) nulldev,
232: (IOSwitchFunc) seltrue,
233: (IOSwitchFunc) eno_mmap,
234: (IOSwitchFunc) eno_getc,
235: (IOSwitchFunc) eno_putc) < 0 )
236: {
237: return NO;
238: }
239: [self setCharacterMajor: 15];
240:
241: if ( IOAddToBdevswAt( 3,
242: (IOSwitchFunc) ideopen,
243: (IOSwitchFunc) ideclose,
244: (IOSwitchFunc) idestrategy,
245: (IOSwitchFunc) ideioctl,
246: (IOSwitchFunc) eno_dump,
247: (IOSwitchFunc) idesize,
248: FALSE ) < 0 )
249: {
250: return NO;
251: }
252: [self setBlockMajor: 3];
253:
254: ide_init_idmap(self);
255:
256: switchTableInited = YES;
257:
258: //#ifdef undef
259: IOLog("IDE: block major %d, character major %d\n",
260: [self blockMajor], [self characterMajor]);
261: //#endif undef
262:
263: return YES;
264: }
265:
266:
267: /*
268: * Common read/write methods. These are used directly in the kernel; user-level
269: * methods using remote objects as defined in IODevice.h in turn call these.
270: */
271: - (IOReturn) readAt : (unsigned)offset
272: length : (unsigned)length
273: buffer : (unsigned char *)buffer
274: actualLength : (unsigned *)actualLength
275: client : (vm_task_t)client
276: {
277: IOReturn rtn;
278:
279: rtn = [self deviceRwCommon : IDEC_READ
280: block : offset
281: length : length
282: buffer : buffer
283: client: client
284: pending : NULL
285: actualLength : actualLength];
286: return(rtn);
287: }
288:
289: - (IOReturn) readAsyncAt : (unsigned)offset
290: length : (unsigned)length
291: buffer : (unsigned char *)buffer
292: pending : (void *)pending
293: client : (vm_task_t)client
294: {
295: IOReturn rtn;
296:
297: rtn = [self deviceRwCommon : IDEC_READ
298: block : offset
299: length : length
300: buffer : buffer
301: client : client
302: pending : (void *)pending
303: actualLength : NULL];
304: return(rtn);
305: }
306:
307: - (IOReturn) writeAt : (unsigned)offset
308: length : (unsigned)length
309: buffer : (unsigned char *)buffer
310: actualLength : (unsigned *)actualLength
311: client : (vm_task_t)client
312: {
313: IOReturn rtn;
314:
315: rtn = [self deviceRwCommon : IDEC_WRITE
316: block : offset
317: length : length
318: buffer : buffer
319: client: client
320: pending : NULL
321: actualLength : actualLength];
322:
323: return(rtn);
324: }
325:
326: - (IOReturn) writeAsyncAt : (unsigned)offset
327: length : (unsigned)length
328: buffer : (unsigned char *)buffer
329: pending : (void *)pending
330: client : (vm_task_t)client
331: {
332: IOReturn rtn;
333:
334: rtn = [self deviceRwCommon : IDEC_WRITE
335: block : offset
336: length : length
337: buffer : buffer
338: client : client
339: pending : (void *)pending
340: actualLength : NULL];
341: return(rtn);
342: }
343:
344: - (IOReturn)updatePhysicalParameters
345: {
346: // we have got everything we need during initialization
347:
348: return(IO_R_SUCCESS);
349: }
350:
351: - (void)abortRequest
352: {
353: ideBuf_t *ideBuf;
354: IOReturn rtn;
355:
356: ideBuf = [self allocIdeBuf:NULL];
357: ideBuf->command = IDEC_ABORT;
358: ideBuf->buf = NULL;
359: ideBuf->needsDisk = 0;
360: ideBuf->oneWay = 0;
361: rtn = [self enqueueIdeBuf:ideBuf];
362: [self freeIdeBuf:ideBuf];
363: }
364:
365: - (void)diskBecameReady
366: {
367: [_ioQLock lock];
368: [_ioQLock unlockWith:WORK_AVAILABLE];
369: }
370:
371: - (IOReturn)isDiskReady : (BOOL)prompt
372: {
373: return(IO_R_SUCCESS);
374: }
375:
376: - (IODiskReadyState)updateReadyState
377: {
378: return([self lastReadyState]);
379: }
380:
381: - (IOReturn) ejectPhysical
382: {
383: return(IO_R_UNSUPPORTED);
384: }
385:
386: - (int)deviceOpen:(u_int)intentions
387: {
388: return(0);
389: }
390:
391: - (void)deviceClose
392: {
393: return;
394: }
395:
396: - (ideDriveInfo_t)ideGetDriveInfo
397: {
398: return(_ideInfo);
399: }
400:
401: - (id)cntrlr
402: {
403: return _cntrlr;
404: }
405:
406: - (unsigned)driveNum
407: {
408: return _driveNum;
409: }
410:
411: - (IOReturn)getIntValues:(unsigned int *)values
412: forParameter:(IOParameterName)parameter
413: count:(unsigned int *)count
414: {
415: int maxCount = *count;
416: int blockMajor, characterMajor;
417:
418: if (maxCount == 0) {
419: maxCount = IO_MAX_PARAMETER_ARRAY_LENGTH;
420: }
421:
422: if (strcmp(parameter, "BlockMajor") == 0) {
423: ide_block_char_majors(&blockMajor, &characterMajor);
424: values[0] = blockMajor;
425: *count = 1;
426: return IO_R_SUCCESS;
427: }
428: if (strcmp(parameter, "CharacterMajor") == 0) {
429: ide_block_char_majors(&blockMajor, &characterMajor);
430: values[0] = characterMajor;
431: *count = 1;
432: return IO_R_SUCCESS;
433: }
434:
435: /*
436: * Pass to superclass what we can't handle.
437: */
438: return [super getIntValues:values forParameter:parameter
439: count:&maxCount];
440: }
441:
442: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.