|
|
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.