Annotation of driverkit/Examples/KStub/IOStub.m, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.