|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.