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