Annotation of driverkit/Examples/KStub/IOStubUnix.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: /*     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.