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