|
|
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: /* IOStub.m 1.0 01/29/91 (c) 1991 NeXT ! 25: * ! 26: * IOStub.m - Implementation for trivial I/O device subclass. ! 27: * ! 28: * HISTORY ! 29: * 29-Jan-91 Doug Mitchell at NeXT ! 30: * Created. ! 31: */ ! 32: ! 33: #import "IOStub.h" ! 34: #import "IOStubThread.h" ! 35: #import "IOStubPrivate.h" ! 36: #import <bsd/sys/types.h> ! 37: #import <driverkit/deviceCommon.h> ! 38: #import <driverkit/libIO.h> ! 39: #import <mach/mach_user_internal.h> ! 40: #import <bsd/sys/param.h> ! 41: #import <mach/vm_param.h> ! 42: #import <bsd/dev/ldd.h> ! 43: #import <mach/mach_interface.h> ! 44: #import <machkit/NXLock.h> ! 45: ! 46: #define STUB_BLOCK_SIZE 1024 ! 47: ! 48: @implementation IOStub ! 49: ! 50: /* ! 51: * Probe hardware for specified unit. ! 52: */ ! 53: + stubProbe :(int)Unit ! 54: { ! 55: id stubId; ! 56: int rtn; ! 57: ! 58: xpr_stub("stubProbe unit %d\n", Unit, 2,3,4,5); ! 59: if(Unit >= NUM_IOSTUBS) { ! 60: IOLog("stubProbe: bogus Unit (%d)\n", Unit); ! 61: return(nil); ! 62: } ! 63: stubId = [self alloc]; ! 64: if(rtn = [stubId stubInit:Unit]) { ! 65: xpr_stub("stubProbe: stubInit returned %d; aborting\n", ! 66: rtn, 2,3,4,5); ! 67: [stubId free]; ! 68: return nil; ! 69: } ! 70: ! 71: [stubId registerDevice]; ! 72: return(stubId); ! 73: } ! 74: ! 75: /* ! 76: * Initialize current instance. Returns non-zero on error. ! 77: */ ! 78: - (int)stubInit :(int)Unit ! 79: { ! 80: u_int block_size, dev_size; ! 81: ! 82: xpr_stub("stubInit Unit %d\n", Unit, 2,3,4,5); ! 83: [self setUnit:Unit]; ! 84: if(Unit == 0) { ! 85: /* ! 86: * read/write. ! 87: */ ! 88: [self setWriteProtected:NO]; ! 89: block_size = STUB_BLOCK_SIZE; ! 90: dev_size = 0x1000; ! 91: [self setDeviceName : "IOStub0"]; ! 92: } ! 93: else { ! 94: /* ! 95: * Make this one read-only. ! 96: */ ! 97: [self setWriteProtected:YES]; ! 98: block_size = STUB_BLOCK_SIZE; ! 99: dev_size = 0x800; ! 100: [self setDeviceName : "IOStub1"]; ! 101: } ! 102: [self setDeviceType:"Stub Device"]; ! 103: [self setDriveName:"Stub Device"]; ! 104: [self setLocation:NULL]; ! 105: [self setBlockSize:block_size]; ! 106: [self setDeviceSize:dev_size]; ! 107: [self setFormattedInt:1]; ! 108: ! 109: ! 110: /* ! 111: * Set up our instance's IOQueue. ! 112: */ ! 113: queueLock = [NXConditionLock new]; ! 114: [queueLock initWith:NO_WORK_AVAILABLE]; ! 115: queue_init(&ioQueue); ! 116: ! 117: /* ! 118: * Start up an I/O thread to perform the actual work of this device. ! 119: */ ! 120: IOForkThread((IOThreadFcn)IOStub_thread, self); ! 121: ! 122: [self initBufs]; ! 123: ! 124: /* ! 125: * Let superclass take care of initializing inherited instance ! 126: * variables. ! 127: */ ! 128: [super init]; ! 129: xpr_stub("stubInit returning success\n", 1,2,3,4,5); ! 130: return(0); ! 131: } ! 132: ! 133: /* ! 134: * Free resources consumed by this instance. ! 135: */ ! 136: - free ! 137: { ! 138: int data_size; ! 139: unsigned block_size, dev_size; ! 140: IOBuf *IOBuf; ! 141: ! 142: /* ! 143: * Kill the I/O thread. ! 144: */ ! 145: IOBuf = IOMalloc(sizeof(*IOBuf)); ! 146: IOBuf->cmd = STUB_ABORT; ! 147: IOBuf->waitLock = [NXConditionLock alloc]; ! 148: [IOBuf->waitLock initWith:NO]; ! 149: IOBuf->device = self; ! 150: [self enqueueIoBuf:IOBuf]; ! 151: [IOBuf->waitLock lockWhen:YES]; ! 152: [IOBuf->waitLock free]; ! 153: IOFree(IOBuf, sizeof(*IOBuf)); ! 154: ! 155: /* ! 156: * Free our "device" memory.. ! 157: */ ! 158: block_size = [self blockSize]; ! 159: dev_size = [self deviceSize]; ! 160: data_size = block_size * dev_size; ! 161: IOFree(stub_data, data_size); ! 162: [queueLock free]; ! 163: return([super free]); ! 164: } ! 165: ! 166: /* ! 167: * Initialize "device memory". ! 168: */ ! 169: - (int)initBufs ! 170: { ! 171: int data_size; ! 172: char *cp; ! 173: int i; ! 174: ! 175: /* ! 176: * allocate and initialize data for writing and reading. ! 177: */ ! 178: data_size = [self blockSize] * [self deviceSize]; ! 179: stub_data = IOMalloc(data_size); ! 180: if(stub_data == NULL) { ! 181: IOLog("***IOStub init: IOMalloc returned NULL"); ! 182: return 1; ! 183: } ! 184: ! 185: /* ! 186: * initial data: incrementing bytes for unit 0, decrementing ! 187: * bytes for others. ! 188: */ ! 189: cp = stub_data; ! 190: for(i=0; i<data_size; i++) { ! 191: if([self unit]) ! 192: *cp++ = 0 - (char)i; ! 193: else ! 194: *cp++ = i; ! 195: } ! 196: return 0; ! 197: } ! 198: ! 199: /* ! 200: * These are the exported I/O methods, from the DiskDeviceRw category. ! 201: * Their main task is: ! 202: * ! 203: * -- verify valid input parameters. ! 204: * -- set up and enqueue an IOBuf for servicing by the I/O thread. ! 205: * -- Wait for I/O complete if synchronous request. ! 206: */ ! 207: ! 208: - (IOReturn) readAt : (unsigned)offset ! 209: length : (unsigned)length ! 210: buffer : (out unsigned char *)buffer ! 211: actualLength : (out unsigned *)actualLength ! 212: client : (vm_task_t)client ! 213: { ! 214: IOReturn mrtn; ! 215: char *source; ! 216: IOBuf *IOBuf; ! 217: u_int block_size; ! 218: u_int dev_size; ! 219: ! 220: xpr_stub("IOStub read: unit %d offset 0x%x length 0x%x\n", ! 221: [self unit], offset, length, 4,5); ! 222: ! 223: block_size = [self blockSize]; ! 224: dev_size = [self deviceSize]; ! 225: ! 226: /* ! 227: * Verify legal parameters. ! 228: */ ! 229: source = stub_data + offset * block_size; ! 230: if((source + length) > (stub_data + (block_size * dev_size))) { ! 231: ! 232: xpr_stub("IOStub read: invalid offset/byte count\n", ! 233: 1,2,3,4,5); ! 234: return(IO_R_INVALIDARG); ! 235: } ! 236: ! 237: /* ! 238: * OK, queue up an IOBuf. ! 239: */ ! 240: IOBuf = IOMalloc(sizeof(*IOBuf)); ! 241: IOBuf->cmd = STUB_READ; ! 242: IOBuf->offset = offset; ! 243: IOBuf->bytesReq = length; ! 244: IOBuf->buf = buffer; ! 245: IOBuf->bytesXfr = 0; ! 246: IOBuf->status = IO_R_INVALID; ! 247: IOBuf->pending = NULL; ! 248: IOBuf->waitLock = [NXConditionLock alloc]; ! 249: [IOBuf->waitLock initWith:NO]; ! 250: IOBuf->device = self; ! 251: IOBuf->dirRead = 1; ! 252: IOBuf->client = IOVmTaskSelf(); ! 253: [self enqueueIoBuf:IOBuf]; ! 254: ! 255: /* ! 256: * Wait for I/O complete. ! 257: */ ! 258: [IOBuf->waitLock lockWhen:YES]; ! 259: xpr_stub("stub read: DONE\n", 1,2,3,4,5); ! 260: mrtn = IOBuf->status; ! 261: *actualLength = IOBuf->bytesXfr; ! 262: [IOBuf->waitLock free]; ! 263: IOFree(IOBuf, sizeof(*IOBuf)); ! 264: return(mrtn); ! 265: } ! 266: ! 267: - (IOReturn) readAsyncAt : (unsigned)offset ! 268: length : (unsigned)length ! 269: buffer : (out unsigned char *)buffer ! 270: pending : (unsigned)pending ! 271: client : (vm_task_t)client ! 272: { ! 273: char *source; ! 274: IOBuf *IOBuf; ! 275: u_int block_size; ! 276: u_int dev_size; ! 277: ! 278: xpr_stub("IOStub readAsync: unit %d offset 0x%x length 0x%x\n", ! 279: [self unit], offset, length, 4,5); ! 280: ! 281: block_size = [self blockSize]; ! 282: dev_size = [self deviceSize]; ! 283: ! 284: /* ! 285: * Verify legal parameters. ! 286: */ ! 287: source = stub_data + offset * block_size; ! 288: if((source + length) > (stub_data + (block_size * dev_size))) { ! 289: ! 290: xpr_stub("IOStub read: invalid offset/byte count\n", ! 291: 1,2,3,4,5); ! 292: return(IO_R_INVALIDARG); ! 293: } ! 294: ! 295: /* ! 296: * Just queue up an IOBuf. ! 297: */ ! 298: IOBuf = IOMalloc(sizeof(*IOBuf)); ! 299: IOBuf->cmd = STUB_READ; ! 300: IOBuf->offset = offset; ! 301: IOBuf->bytesReq = length; ! 302: IOBuf->buf = buffer; ! 303: IOBuf->status = IO_R_INVALID; /* must be filled in by ! 304: * I/O thread */ ! 305: IOBuf->pending = (void *)pending; ! 306: IOBuf->device = self; ! 307: IOBuf->dirRead = 1; ! 308: IOBuf->client = client; ! 309: [self enqueueIoBuf:IOBuf]; ! 310: ! 311: xpr_stub("stub readAsync: DONE\n", 1,2,3,4,5); ! 312: return(IO_R_SUCCESS); ! 313: } ! 314: ! 315: - (IOReturn) writeAt : (unsigned)offset ! 316: length : (unsigned)length ! 317: buffer : (in unsigned char *)buffer ! 318: actualLength : (out unsigned *)actualLength ! 319: client : (vm_task_t)client ! 320: { ! 321: IOReturn mrtn; ! 322: char *dest; ! 323: IOBuf *IOBuf; ! 324: u_int block_size; ! 325: u_int dev_size; ! 326: ! 327: xpr_stub("IOStub write: unit %d offset 0x%x length 0x%x\n", ! 328: [self unit], offset, length, 4,5); ! 329: ! 330: block_size = [self blockSize]; ! 331: dev_size = [self deviceSize]; ! 332: ! 333: /* ! 334: * Verify legal parameters. ! 335: */ ! 336: if([self writeProtected]) { ! 337: return IO_R_NOTWRITEABLE; ! 338: } ! 339: dest = stub_data + offset * block_size; ! 340: if((dest + length) > (stub_data + (block_size * dev_size))) { ! 341: ! 342: xpr_stub("IOStub dest: invalid offset/byte count\n", ! 343: 1,2,3,4,5); ! 344: return(IO_R_INVALIDARG); ! 345: } ! 346: ! 347: /* ! 348: * OK, queue up an IOBuf. ! 349: */ ! 350: IOBuf = IOMalloc(sizeof(*IOBuf)); ! 351: IOBuf->cmd = STUB_WRITE; ! 352: IOBuf->offset = offset; ! 353: IOBuf->bytesReq = length; ! 354: IOBuf->buf = buffer; ! 355: IOBuf->status = IO_R_INVALID; ! 356: IOBuf->pending = NULL; ! 357: IOBuf->waitLock = [NXConditionLock alloc]; ! 358: [IOBuf->waitLock initWith:NO]; ! 359: IOBuf->device = self; ! 360: IOBuf->dirRead = 0; ! 361: IOBuf->client = IOVmTaskSelf(); ! 362: [self enqueueIoBuf:IOBuf]; ! 363: ! 364: /* ! 365: * Wait for I/O complete. ! 366: */ ! 367: [IOBuf->waitLock lockWhen:YES]; ! 368: xpr_stub("stub write: DONE\n", 1,2,3,4,5); ! 369: mrtn = IOBuf->status; ! 370: *actualLength = IOBuf->bytesXfr; ! 371: [IOBuf->waitLock free]; ! 372: IOFree(IOBuf, sizeof(*IOBuf)); ! 373: return(mrtn); ! 374: } ! 375: ! 376: ! 377: - (IOReturn) writeAsyncAt : (unsigned)offset ! 378: length : (unsigned)length ! 379: buffer : (in unsigned char *)buffer ! 380: pending : (unsigned)pending ! 381: client : (vm_task_t)client ! 382: { ! 383: char *source; ! 384: IOBuf *IOBuf; ! 385: u_int block_size; ! 386: u_int dev_size; ! 387: ! 388: xpr_stub("IOStub writeAsync: unit %d offset 0x%x length 0x%x\n", ! 389: [self unit], offset, length, 4,5); ! 390: ! 391: block_size = [self blockSize]; ! 392: dev_size = [self deviceSize]; ! 393: ! 394: if([self writeProtected]) { ! 395: return IO_R_NOTWRITEABLE; ! 396: } ! 397: source = stub_data + offset * block_size; ! 398: if((source + length) > (stub_data + (block_size * dev_size))) { ! 399: ! 400: xpr_stub("IOStub write: invalid offset/byte count\n", ! 401: 1,2,3,4,5); ! 402: return(IO_R_INVALIDARG); ! 403: } ! 404: ! 405: /* ! 406: * Just queue up an IOBuf. ! 407: */ ! 408: IOBuf = IOMalloc(sizeof(*IOBuf)); ! 409: IOBuf->cmd = STUB_WRITE; ! 410: IOBuf->offset = offset; ! 411: IOBuf->bytesReq = length; ! 412: IOBuf->buf = buffer; ! 413: IOBuf->status = IO_R_INVALID; /* must be filled in by ! 414: * I/O thread */ ! 415: IOBuf->pending = (void *)pending; ! 416: IOBuf->device = self; ! 417: IOBuf->dirRead = 0; ! 418: IOBuf->client = client; ! 419: [self enqueueIoBuf:IOBuf]; ! 420: ! 421: xpr_stub("stub writeAsync: DONE\n", 1,2,3,4,5); ! 422: return(IO_R_SUCCESS); ! 423: } ! 424: ! 425: @end ! 426:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.