|
|
1.1 root 1: /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
2: *
3: * IOLogicalDisk.m
4: *
5: * HISTORY
6: * 05-Mar-91 Doug Mitchell at NeXT
7: * Created.
8: */
9:
10: #import <driverkit/return.h>
11: #import <driverkit/IODisk.h>
12: #ifdef KERNEL
13: #import <kernserv/prototypes.h>
14: #import <mach/mach_interface.h>
15: #import <driverkit/kernelDiskMethods.h>
16: #else KERNEL
17: #import <mach/mach.h>
18: #import <bsd/libc.h>
19: #endif KERNEL
20: #import <driverkit/IOLogicalDisk.h>
21: #import <driverkit/Device_ddm.h>
22: #import <driverkit/generalFuncs.h>
23:
24: @interface IOLogicalDisk(private)
25: - (IOReturn)_diskParamCommon :(u_int)logicalOffset
26: length : (u_int)bytesReq
27: deviceOffset : (u_int *)deviceOffset
28: bytesToMove : (u_int *)bytesToMove;
29:
30:
31: @end
32:
33: @implementation IOLogicalDisk
34:
35: /*
36: * Standard IODiskDeviceReadingAndWriting methods. We translate into raw device
37: * parameters and pass along to _physicalDisk.
38: */
39: #ifdef KERNEL
40:
41: - (IOReturn) readAt : (unsigned)offset
42: length : (unsigned)length
43: buffer : (unsigned char *)buffer
44: actualLength : (unsigned *)actualLength
45: client : (vm_task_t)client
46: {
47: unsigned deviceBlock;
48: IOReturn rtn;
49: unsigned bytesToMove;
50:
51: if(rtn = [self _diskParamCommon:offset
52: length : length
53: deviceOffset : &deviceBlock
54: bytesToMove:&bytesToMove])
55: return(rtn);
56: return([_physicalDisk readAt:deviceBlock
57: length:bytesToMove
58: buffer:buffer
59: actualLength:actualLength
60: client:client]);
61: }
62:
63: - (IOReturn) readAsyncAt : (unsigned)offset
64: length : (unsigned)length
65: buffer : (unsigned char *)buffer
66: pending : (void *)pending
67: client : (vm_task_t)client
68: {
69: unsigned deviceBlock;
70: IOReturn rtn;
71: unsigned bytesToMove;
72:
73: if(rtn = [self _diskParamCommon:offset
74: length : length
75: deviceOffset : &deviceBlock
76: bytesToMove:&bytesToMove])
77: return(rtn);
78: return([_physicalDisk readAsyncAt:deviceBlock
79: length:bytesToMove
80: buffer:buffer
81: pending:pending
82: client:client]);
83: }
84:
85: - (IOReturn) writeAt : (unsigned)offset
86: length : (unsigned)length
87: buffer : (unsigned char *)buffer
88: actualLength : (unsigned *)actualLength
89: client : (vm_task_t)client
90: {
91: unsigned deviceBlock;
92: IOReturn rtn;
93: unsigned bytesToMove;
94:
95: if(rtn = [self _diskParamCommon:offset
96: length : length
97: deviceOffset : &deviceBlock
98: bytesToMove:&bytesToMove])
99: return(rtn);
100: return([_physicalDisk writeAt:deviceBlock
101: length:bytesToMove
102: buffer:buffer
103: actualLength:actualLength
104: client:client]);
105: }
106:
107: - (IOReturn) writeAsyncAt : (unsigned)offset
108: length : (unsigned)length
109: buffer : (unsigned char *)buffer
110: pending : (void *)pending
111: client : (vm_task_t)client
112: {
113: unsigned deviceBlock;
114: IOReturn rtn;
115: unsigned bytesToMove;
116:
117: if(rtn = [self _diskParamCommon:offset
118: length : length
119: deviceOffset : &deviceBlock
120: bytesToMove:&bytesToMove])
121: return(rtn);
122: return([_physicalDisk writeAsyncAt:deviceBlock
123: length:bytesToMove
124: buffer:buffer
125: pending:pending
126: client:client]);
127: }
128:
129:
130: #else KERNEL
131:
132: - (IOReturn) readAt : (unsigned)offset
133: length : (unsigned)length
134: buffer : (unsigned char *)buffer
135: actualLength : (unsigned *)actualLength
136: {
137: unsigned deviceBlock;
138: IOReturn rtn;
139: unsigned bytesToMove;
140:
141: if(rtn = [self _diskParamCommon:offset
142: length : length
143: deviceOffset : &deviceBlock
144: bytesToMove:&bytesToMove])
145: return(rtn);
146: return([_physicalDisk readAt:deviceBlock
147: length:bytesToMove
148: buffer:buffer
149: actualLength:actualLength]);
150: }
151:
152: - (IOReturn) readAsyncAt : (unsigned)offset
153: length : (unsigned)length
154: buffer : (unsigned char *)buffer
155: pending : (void *)pending
156: {
157: unsigned deviceBlock;
158: IOReturn rtn;
159: unsigned bytesToMove;
160:
161: if(rtn = [self _diskParamCommon:offset
162: length : length
163: deviceOffset : &deviceBlock
164: bytesToMove:&bytesToMove])
165: return(rtn);
166: return([_physicalDisk readAsyncAt:deviceBlock
167: length:bytesToMove
168: buffer:buffer
169: pending:pending]);
170: }
171:
172: - (IOReturn) writeAt : (unsigned)offset
173: length : (unsigned)length
174: buffer : (unsigned char *)buffer
175: actualLength : (unsigned *)actualLength
176: {
177: unsigned deviceBlock;
178: IOReturn rtn;
179: unsigned bytesToMove;
180:
181: if(rtn = [self _diskParamCommon:offset
182: length : length
183: deviceOffset : &deviceBlock
184: bytesToMove:&bytesToMove])
185: return(rtn);
186: return([_physicalDisk writeAt:deviceBlock
187: length:bytesToMove
188: buffer:buffer
189: actualLength:actualLength]);
190: }
191:
192: - (IOReturn) writeAsyncAt : (unsigned)offset
193: length : (unsigned)length
194: buffer : (unsigned char *)buffer
195: pending : (void *)pending
196: {
197: unsigned deviceBlock;
198: IOReturn rtn;
199: unsigned bytesToMove;
200:
201: if(rtn = [self _diskParamCommon:offset
202: length : length
203: deviceOffset : &deviceBlock
204: bytesToMove:&bytesToMove])
205: return(rtn);
206: return([_physicalDisk writeAsyncAt:deviceBlock
207: length:bytesToMove
208: buffer:buffer
209: pending:pending]);
210: }
211:
212: #endif KERNEL
213:
214: - (IODiskReadyState)updateReadyState
215: {
216: return [_physicalDisk updateReadyState];
217: }
218:
219: /*
220: * Open a connection to physDevice. FIXME: when do we close??
221: */
222: - (IOReturn)connectToPhysicalDisk : physicalDisk
223: {
224: IOReturn rtn = IO_R_SUCCESS;
225: unsigned removable_flag;
226: unsigned formatted_flag;
227:
228: xpr_disk("connectToPhysicalDiskice\n", 1,2,3,4,5);
229: _physicalDisk = physicalDisk;
230: [self setIsPhysical:0];
231:
232: /*
233: * Get some instance variables which must be the same as the
234: * physDevice's.
235: */
236: _physicalBlockSize = [physicalDisk blockSize];
237: removable_flag = [physicalDisk isRemovable];
238: [self setRemovable:removable_flag];
239: formatted_flag = [physicalDisk isFormatted];
240: [self setFormattedInternal:formatted_flag];
241: [self setLogicalDisk:nil];
242: #ifdef KERNEL
243: [self setDevAndIdInfo:[physicalDisk devAndIdInfo]];
244: #endif KERNEL
245: return(rtn);
246: }
247:
248: - (void)setPartitionBase : (unsigned)partBase
249: {
250: _partitionBase = partBase;
251: }
252:
253:
254: /*
255: * Determine if this LogicalDisk (or any other LogicalDisks in the
256: * logicalDisk list) are currently open. Returns NO if none open, else
257: * YES.
258: */
259: - (BOOL)isOpen
260: {
261: if([self isInstanceOpen])
262: return(YES);
263: else if([self nextLogicalDisk])
264: return([[self nextLogicalDisk] isOpen]);
265: else
266: return(NO);
267: }
268:
269: /*
270: * Free self and any objects in logicalDisk chain.
271: */
272: - free
273: {
274: id nextLd;
275:
276: nextLd = [self nextLogicalDisk];
277: if(nextLd) {
278: [nextLd free];
279: }
280: return([super free]);
281: }
282:
283: - physicalDisk
284: {
285: return(_physicalDisk);
286: }
287:
288: - (unsigned)physicalBlockSize
289: {
290: return(_physicalBlockSize);
291: }
292:
293: - (void)setPhysicalBlockSize : (unsigned)size
294: {
295: _physicalBlockSize = size;
296: }
297:
298: /*
299: * Pass this on to _physicalDisk.
300: */
301: - (IOReturn)isDiskReady : (BOOL)prompt
302: {
303: return [_physicalDisk isDiskReady:prompt];
304: }
305:
306: /*
307: * Determine if any logical disks in the _logicalDisk chain except
308: * for self are open.
309: */
310: - (BOOL)isAnyOtherOpen
311: {
312: id logDisk = [_physicalDisk nextLogicalDisk];
313: while(logDisk) {
314: if((logDisk != self) && [logDisk isInstanceOpen]) {
315: return YES;
316: }
317: logDisk = [logDisk nextLogicalDisk];
318: }
319: return NO;
320: }
321:
322: - (BOOL)isInstanceOpen
323: {
324: return _instanceOpen;
325: }
326:
327: - (void)setInstanceOpen : (BOOL)isOpen
328: {
329: _instanceOpen = (isOpen ? YES : NO);
330: }
331:
332: /*
333: * Generate device-specific parameters from logical parameters.
334: */
335: @implementation IOLogicalDisk(private)
336:
337: #define CRASHER_DEBUG 1
338: #if CRASHER_DEBUG
339: int crash_index = 33;
340: #endif CRASHER_DEBUG
341:
342: - (IOReturn)_diskParamCommon :(unsigned)logicalOffset
343: length : (unsigned)length
344: deviceOffset : (unsigned *)deviceOffset
345: bytesToMove : (unsigned *)bytesToMove
346: {
347: unsigned ratio = 0; // bogus compiler warning
348: int deviceBlocks;
349: int logicalBlocks;
350: unsigned block_size;
351: unsigned dev_size;
352: IOReturn rtn;
353: const char *name = [self name];
354:
355: #if CRASHER_DEBUG
356: if((unsigned)(self->isa->cache->buckets[crash_index]) > 0xf0000000) {
357: panic("Yeah!");
358: }
359: #endif CRASHER_DEBUG
360:
361: /*
362: * Note we have to 'fault in' a possible non-present physical disk in
363: * order to get its physical parameters...
364: */
365: rtn = [_physicalDisk isDiskReady:YES];
366: switch(rtn) {
367: case IO_R_SUCCESS:
368: break;
369: case IO_R_NO_DISK:
370: xpr_err("%s diskParamCommon: disk not present\n",
371: name, 2,3,4,5);
372: return(rtn);
373: default:
374: IOLog("%s deviceRwCommon: bogus return from isDiskReady "
375: "(%s)\n",
376: name, [self stringFromReturn:rtn]);
377: return(rtn);
378: }
379:
380: block_size = [self blockSize];
381: dev_size = [self diskSize];
382:
383: if(length % block_size) {
384: IOLog("%s: Bytes requested not multiple of block size\n",
385: name);
386: return(IO_R_INVALID_ARG);
387: }
388: logicalBlocks = length / block_size;
389: if((logicalOffset + logicalBlocks) > dev_size) {
390: if(logicalOffset >= dev_size)
391: return(IO_R_INVALID_ARG);
392:
393: /*
394: * Truncate.
395: */
396: logicalBlocks = dev_size - logicalOffset;
397: }
398: ratio = block_size / _physicalBlockSize;
399: deviceBlocks = logicalBlocks * ratio;
400: *deviceOffset = (logicalOffset * ratio) + _partitionBase;
401: *bytesToMove = deviceBlocks * _physicalBlockSize;
402: return(IO_R_SUCCESS);
403: }
404:
405: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.