|
|
1.1 root 1: /* $Header: /usr/src/sys/i8086/drv/RCS/shmcon.c,v 2.1 88/09/03 13:12:40 src Exp $
2: *
3: * The information contained herein is a trade secret of INETCO
4: * Systems, and is confidential information. It is provided under
5: * a license agreement, and may be copied or disclosed only under
6: * the terms of that agreement. Any reproduction or disclosure of
7: * this material without the express written authorization of
8: * INETCO Systems or persuant to the license agreement is unlawful.
9: *
10: * Copyright (c) 1987, 1985, 1984.
11: * An unpublished work by INETCO Systems, Ltd.
12: * All rights reserved.
13: */
14:
15: /*
16: * System V Compatible Shared Memory Device Driver
17: *
18: * This device driver provides System V compatible shared memory operations.
19: * Operations are performed through the shared memory device (/dev/shm).
20: * and are implemented as ioctl calls from shmctl, shmget, shmat, shmdt
21: * utilities.
22: *
23: * Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
24: *
25: * $Log: /usr/src/sys/i8086/drv/RCS/shmcon.c,v $
26: * Revision 2.1 88/09/03 13:12:40 src
27: * *** empty log message ***
28: *
29: * Revision 1.1 88/03/24 17:06:36 src
30: * Initial revision
31: *
32: * 87/03/02 Allan Cornish /usr/src/sys/i8086/drv/shmcon.c
33: * Shmioctl() now supports long key [was short] on SHMGET operations.
34: * This allows compatability with System V.
35: *
36: * 85/10/16 Allan Cornish
37: * Driver split into shmcon.c, shm.c [driver implementation, system V shm].
38: *
39: * 85/07/22 Allan Cornish
40: * Shmget, shmctl now return immediately if u.u_error is set.
41: *
42: * 85/07/19 Allan Cornish
43: * Separation of io_seek into shmid and off improved through type casting.
44: * Errno set to EFAULT if fucopy() or ufcopy() report no bytes transferred.
45: * This would occur if an user address fault occurred.
46: *
47: * 85/07/03 Allan Cornish
48: * Replaced use of EDOM with EIDRM.
49: * Replaced shmaccess() by calls to ipcaccess(), increasing shared ipc code.
50: * Eliminated shmlock() and shmunlock(), as shared memory use is synchronous.
51: *
52: * 84/09/30 Allan Cornish
53: * Initial Revision.
54: */
55:
56: #include <coherent.h>
57: #include <sched.h>
58: #include <types.h>
59: #include <uproc.h>
60: #include <errno.h>
61: #include <stat.h>
62: #include <con.h>
63: #include <seg.h>
64: #include <shm.h>
65:
66: #ifndef EIDRM
67: #define EIDRM EDOM
68: #endif
69:
70: /*
71: * Functions.
72: */
73:
74: int shmload();
75: int shmread();
76: int shmwrite();
77: int shmioctl();
78: int nulldev();
79: int nonedev();
80:
81: /*
82: * Device Configuration.
83: */
84:
85: CON shmcon = {
86: DFCHR, /* Flags */
87: 24, /* Major Index */
88: nulldev, /* Open */
89: nulldev, /* Close */
90: nonedev, /* Block */
91: shmread, /* Read */
92: shmwrite, /* Write */
93: shmioctl, /* Ioctl */
94: nulldev, /* Power fail */
95: nulldev, /* Timeout */
96: shmload, /* Load */
97: nulldev /* Unload */
98: };
99:
100: unsigned NSHMID = 16;
101: struct shmid_ds *shmids;
102: struct seg **shmsegs;
103:
104: /*
105: * Shared Memory Device Load.
106: */
107:
108: static
109: shmload()
110: {
111: register struct shmid_ds * idp;
112: register unsigned wanted;
113:
114: if ( NSHMID == 0 )
115: return 0;
116:
117: wanted = NSHMID * (sizeof(struct shmid_ds) + sizeof(struct seg *));
118:
119: if ( (shmids = kalloc( wanted )) == 0 ) {
120:
121: printf("couldn't kalloc %u shared memory ids\n", NSHMID );
122: NSHMID = 0;
123: return 0;
124: }
125: shmsegs = (struct seg *) &shmids[ NSHMID ];
126:
127: for ( idp = &shmids[NSHMID]; --idp >= shmids; )
128: idp->shm_perm.mode = 0;
129:
130: return 0;
131: }
132:
133: /*
134: ** Shared Memory Read.
135: */
136:
137: static
138: shmread( dev, iop )
139:
140: dev_t dev;
141: register IO *iop;
142:
143: {
144: register struct shmid_ds *idp;
145: int shmid;
146: unsigned off;
147: faddr_t faddr;
148:
149: off = ((unsigned *) &iop->io_seek)[0];
150: shmid = ((unsigned *) &iop->io_seek)[1];
151:
152: if ( shmid >= NSHMID ) {
153: u.u_error = EFAULT;
154: return -1;
155: }
156:
157: idp = &shmids[shmid];
158:
159: if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
160: u.u_error = EIDRM;
161: return -1;
162: }
163:
164: if ( (ipcaccess(&idp->shm_perm) & SHM_R) == 0 ) {
165: u.u_error = EACCES;
166: return -1;
167: }
168:
169: if ( ((long) off + iop->io_ioc) > idp->shm_segsz ) {
170: u.u_error = EFAULT;
171: return -1;
172: }
173:
174: FP_SEL(faddr) = FP_SEL(shmsegs[shmid]->s_faddr);
175: FP_OFF(faddr) = off;
176:
177: if ( ! fucopy( faddr, iop->io_base, iop->io_ioc ) ) {
178: u.u_error = EFAULT;
179: return -1;
180: }
181:
182: iop->io_ioc = 0;
183: return 0;
184: }
185:
186: /*
187: ** Shared Memory Write.
188: */
189:
190: static
191: shmwrite( dev, iop )
192:
193: dev_t dev;
194: register IO *iop;
195:
196: {
197: register struct shmid_ds *idp;
198: int shmid;
199: unsigned off;
200: faddr_t faddr;
201:
202: off = ((unsigned *) &iop->io_seek)[0];
203: shmid = ((unsigned *) &iop->io_seek)[1];
204:
205: if ( shmid >= NSHMID ) {
206: u.u_error = EFAULT;
207: return -1;
208: }
209:
210: idp = &shmids[shmid];
211:
212: if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
213: u.u_error = EIDRM;
214: return -1;
215: }
216:
217: if ( (ipcaccess(&idp->shm_perm) & SHM_W) == 0 ) {
218: u.u_error = EFAULT;
219: return -1;
220: }
221:
222: if ( ((long) off + iop->io_ioc) > idp->shm_segsz ) {
223: u.u_error = EFAULT;
224: return -1;
225: }
226:
227: FP_SEL(faddr) = FP_SEL(shmsegs[shmid]->s_faddr);
228: FP_OFF(faddr) = off;
229:
230: if ( ! ufcopy(iop->io_base, faddr, iop->io_ioc ) ) {
231: u.u_error = EFAULT;
232: return -1;
233: }
234:
235: iop->io_ioc = 0;
236: return 0;
237: }
238:
239: /*
240: * Shared Memory Device Ioctl.
241: *
242: * Input: dev = shared memory device (/dev/shm).
243: * com = command to perform (SHMCTL, SHMGET,SHMAT).
244: * vec = pointer to return value, followed by parameters.
245: *
246: * Action: Initiate command.
247: * Save commands return value in *vec.
248: */
249:
250: static
251: shmioctl( dev, com, vec )
252:
253: dev_t dev;
254: int com;
255: int *vec;
256:
257: {
258: switch ( com ) {
259:
260: case SHMCTL:
261: putuwd( vec+0,
262: ushmctl( getuwd( vec+1 ),
263: getuwd( vec+2 ),
264: getuwd( vec+3 ) ));
265: break;
266:
267: case SHMGET:
268: putuwd( vec+0,
269: ushmget( getuwd( vec+1 ),
270: getuwd( vec+2 ),
271: getuwd( vec+3 ),
272: getuwd( vec+4 ) ));
273: break;
274:
275: default:
276: u.u_error = EINVAL;
277: break;
278: }
279: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.