Annotation of driverkit/Examples/KStub/IOStubUnix.m, revision 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: /*     Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved. 
        !            25:  *
        !            26:  * IOStubUnix.m - UNIX front end for kernel IOStub device. 
        !            27:  *
        !            28:  * HISTORY
        !            29:  * 22-Apr-91    Doug Mitchell at NeXT
        !            30:  *      Created. 
        !            31:  */
        !            32: 
        !            33: /*
        !            34:  * No IOTask RPCs here.
        !            35:  */
        !            36: #undef MACH_USER_API
        !            37: #define KERNEL_PRIVATE 1
        !            38: 
        !            39: #import "IOStub.h"
        !            40: #import "IOStubPrivate.h"
        !            41: #import "IOStubUnix.h"
        !            42: #import <bsd/sys/buf.h>
        !            43: #import <bsd/sys/conf.h>
        !            44: #import <bsd/sys/uio.h>
        !            45: #import <bsd/dev/ldd.h>
        !            46: #import <bsd/sys/errno.h>
        !            47: #import <bsd/sys/proc.h>
        !            48: #import <vm/vm_kern.h>
        !            49: 
        !            50: stub_object_t stub_object[NUM_IOSTUBS] = {
        !            51:        {NULL, nil},
        !            52:        {NULL, nil},
        !            53: };
        !            54: 
        !            55: /*
        !            56:  * prototypes for internal functions
        !            57:  */
        !            58: static unsigned stub_minphys(struct buf *bp);
        !            59: 
        !            60: 
        !            61: int stub_open(dev_t dev, int flag)
        !            62: {
        !            63:        int unit = STUB_UNIT(dev);
        !            64:        id diskObj = stub_object[unit].stub_id;
        !            65:        
        !            66:        xpr_stub("stub_open: unit %d\n", unit, 2,3,4,5);
        !            67:        if((unit >= NUM_IOSTUBS) || (diskObj == nil))
        !            68:                return(ENXIO);
        !            69:        /*
        !            70:         * Other device-dependent open stuff here. This device doesn't 
        !            71:         * have any, so...
        !            72:         */
        !            73:        return(0);
        !            74:        
        !            75: } /* stub_open() */
        !            76: 
        !            77: int stub_close(dev_t dev)
        !            78: {
        !            79:        int unit = STUB_UNIT(dev);
        !            80:        id diskObj = stub_object[unit].stub_id;
        !            81:        
        !            82:        xpr_stub("stub_close: unit %d\n", unit, 2,3,4,5);
        !            83:        if((unit >= NUM_IOSTUBS) || (diskObj == nil))
        !            84:                return(ENXIO);
        !            85:        /*
        !            86:         * Device-dependent close stuff here. This device doesn't have any,
        !            87:         * so...
        !            88:         */
        !            89:        return(0);
        !            90: 
        !            91: } /* stub_close() */
        !            92: 
        !            93: /*
        !            94:  * Raw I/O use standard UNIX physio routine, resulting in async I/O requests
        !            95:  * via stub_strategy().
        !            96:  */
        !            97: int stub_read(dev_t dev, struct uio *uiop)
        !            98: {
        !            99:        int unit = STUB_UNIT(dev);
        !           100:        stub_object_t *stub = &stub_object[unit];
        !           101:        u_int block_size;
        !           102:        char *localBuf;
        !           103:        int rtn;
        !           104:        void *userPtr;
        !           105:        int userCnt;
        !           106:        struct iovec *iov;
        !           107:        
        !           108:        if((unit >= NUM_IOSTUBS) || (stub->stub_id == nil))
        !           109:                return(ENXIO);
        !           110:        block_size = [stub->stub_id blockSize];
        !           111:        
        !           112:        /*
        !           113:         * Have IOStub device read into kernel memory, then copyout.
        !           114:         */
        !           115:        iov = uiop->uio_iov;
        !           116:        userPtr = iov->iov_base;
        !           117:        userCnt = iov->iov_len;
        !           118:        localBuf = IOMalloc(userCnt);
        !           119:        iov->iov_base = (caddr_t)localBuf;
        !           120:        uiop->uio_segflg = UIO_SYSSPACE;
        !           121:        rtn = physio(stub_strategy, 
        !           122:                stub->physbuf, 
        !           123:                dev, 
        !           124:                B_READ, 
        !           125:                stub_minphys, 
        !           126:                uiop, 
        !           127:                block_size);
        !           128:        copyout(localBuf, userPtr, userCnt);
        !           129:        IOFree(localBuf, userCnt);
        !           130:        return rtn;
        !           131:        
        !           132: } /* stub_read() */
        !           133: 
        !           134: int stub_write(dev_t dev, struct uio *uiop)
        !           135: {
        !           136:        int unit = STUB_UNIT(dev);
        !           137:        stub_object_t *stub = &stub_object[unit];
        !           138:        u_int block_size;
        !           139:        char *localBuf;
        !           140:        int rtn;
        !           141:        void *userPtr;
        !           142:        int userCnt;
        !           143:        struct iovec *iov;
        !           144:        
        !           145:        if((unit >= NUM_IOSTUBS) || (stub->stub_id == nil))
        !           146:                return(ENXIO);
        !           147:        block_size = [stub->stub_id blockSize];
        !           148:        
        !           149:        /*
        !           150:         * Copy user's data into local memory.
        !           151:         */
        !           152:        iov = uiop->uio_iov;
        !           153:        userPtr = iov->iov_base;
        !           154:        userCnt = iov->iov_len;
        !           155:        localBuf = IOMalloc(userCnt);
        !           156:        iov->iov_base = (caddr_t)localBuf;
        !           157:        uiop->uio_segflg = UIO_SYSSPACE;
        !           158:        copyin(userPtr, localBuf, userCnt);
        !           159:        rtn = physio(stub_strategy, 
        !           160:                stub->physbuf, 
        !           161:                dev, 
        !           162:                B_WRITE, 
        !           163:                stub_minphys, 
        !           164:                uiop, 
        !           165:                block_size);
        !           166:        IOFree(localBuf, userCnt);
        !           167:        return rtn;
        !           168:        
        !           169: } /* stub_write() */
        !           170: 
        !           171: int stub_strategy(struct buf *bp)
        !           172: {
        !           173:        int unit = STUB_UNIT(bp->b_dev);
        !           174:        id diskObj = stub_object[unit].stub_id;
        !           175:        u_int offset;
        !           176:        u_int bytes_req;
        !           177:        void *bufp;
        !           178:        u_int block_size;
        !           179:        IOReturn rtn;
        !           180:        vm_map_t client;
        !           181:        
        !           182:        /*
        !           183:         * returns 0/-1.
        !           184:         */
        !           185:        xpr_stub("stub_strategy: unit %d\n", unit, 2,3,4,5);
        !           186:        if((unit >= NUM_IOSTUBS) || (diskObj == nil)) {
        !           187:                xpr_stub("stub_strategy: bad unit\n", 1,2,3,4,5);
        !           188:                bp->b_error = ENXIO;
        !           189:                goto bad;
        !           190:        }
        !           191:        if((bp->b_flags & (B_PHYS|B_KERNSPACE)) == B_PHYS) {
        !           192:                /*
        !           193:                 * Physical I/O to user space.
        !           194:                 */
        !           195:                client = bp->b_proc->task->map;
        !           196:        }
        !           197:        else {
        !           198:                /*
        !           199:                 * Either block I/O (always kernel space) or physical I/O
        !           200:                 * to kernel space (e.g., loadable file system).
        !           201:                 */
        !           202:                client = kernel_map;
        !           203:        }
        !           204:        block_size = [diskObj blockSize];
        !           205:        offset = bp->b_blkno;
        !           206:        bytes_req = bp->b_bcount;
        !           207:        bufp = bp->b_un.b_addr;
        !           208:        if(bp->b_flags & B_READ) {
        !           209:                rtn = [diskObj readAsyncAt:offset
        !           210:                        length:bytes_req
        !           211:                        buffer:bufp
        !           212:                        pending:(unsigned)bp
        !           213:                        client:client];
        !           214:        }
        !           215:        else {
        !           216:                rtn = [diskObj writeAsyncAt:offset
        !           217:                        length:bytes_req
        !           218:                        buffer:bufp
        !           219:                        pending:(unsigned)bp
        !           220:                        client:client];
        !           221:        }
        !           222:        if(rtn) {
        !           223:                bp->b_error = EINVAL;
        !           224:                goto bad;
        !           225:        }
        !           226:        xpr_stub("stub_strategy: SUCCESS\n", 1,2,3,4,5);
        !           227:        return(0);
        !           228:        
        !           229: bad:
        !           230:        bp->b_flags |= B_ERROR;
        !           231:        rtn = -1;
        !           232:        biodone(bp);
        !           233:        xpr_stub("stub_strategy: COMMAND REJECT\n", 1,2,3,4,5);
        !           234:        return(rtn);
        !           235: 
        !           236: } /* stub_strategy() */
        !           237: 
        !           238: int stub_ioctl(dev_t dev, 
        !           239:        int cmd, 
        !           240:        caddr_t data, 
        !           241:        int flag)
        !           242: {
        !           243:        int unit = STUB_UNIT(dev);
        !           244:        id diskObj = stub_object[unit].stub_id;
        !           245:        int rtn = 0;
        !           246:        
        !           247:        xpr_stub("stub_ioctl: unit %d cmd = %d\n", unit, cmd, 3,4,5);
        !           248: 
        !           249:        switch (cmd) {
        !           250:            case DKIOCGFORMAT:
        !           251:                *(int *)data = [diskObj formatted];
        !           252:                break;
        !           253:                
        !           254:            case DKIOCGLABEL:
        !           255:                /* no label */
        !           256:                rtn = ENXIO;
        !           257:                break;
        !           258: 
        !           259:            case DKIOCINFO:
        !           260:                {
        !           261:                        struct drive_info info;
        !           262:                        
        !           263:                        bzero(&info, sizeof(info));
        !           264:                        strcpy(info.di_name, [diskObj driveName]);
        !           265:                        info.di_devblklen = [diskObj blockSize];
        !           266:                        info.di_maxbcount = STUB_MAX_PHYS_IO;
        !           267:                        *(struct drive_info *)data = info;
        !           268:                        break;
        !           269:                }
        !           270:                
        !           271:            case DKIOCBLKSIZE:
        !           272:                *(int *)data = [diskObj blockSize];
        !           273:                break;
        !           274:                
        !           275:            case DKIOCNUMBLKS:
        !           276:                *(int *)data = [diskObj deviceSize];
        !           277:                break;
        !           278:                
        !           279:            default:
        !           280:                rtn = EINVAL;
        !           281:        }
        !           282:        return rtn;
        !           283: } /* stub_ioctl() */
        !           284: 
        !           285: /*
        !           286:  * Called out from physio().
        !           287:  */
        !           288: static unsigned stub_minphys(struct buf *bp)
        !           289: {
        !           290:        if (bp->b_bcount > STUB_MAX_PHYS_IO)
        !           291:                bp->b_bcount = STUB_MAX_PHYS_IO;
        !           292:        return(bp->b_bcount);
        !           293: }
        !           294: 
        !           295: /* end of IOStubUnix.m */
        !           296: 

unix.superglobalmegacorp.com

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