This source file includes following definitions.
- read_ram
- write_ram
- read_mem
- write_mem
- mmap_mem
- read_kmem
- read_port
- write_port
- read_null
- write_null
- read_zero
- mmap_zero
- read_full
- write_full
- null_lseek
- memory_lseek
- memory_open
- chr_dev_init
1
2
3
4
5
6
7 #include <linux/config.h>
8 #include <linux/types.h>
9 #include <linux/errno.h>
10 #include <linux/sched.h>
11 #include <linux/kernel.h>
12 #include <linux/major.h>
13 #include <linux/tty.h>
14 #include <linux/miscdevice.h>
15 #include <linux/tpqic02.h>
16 #include <linux/ftape.h>
17 #include <linux/malloc.h>
18 #include <linux/mman.h>
19 #include <linux/mm.h>
20 #include <linux/random.h>
21
22 #include <asm/segment.h>
23 #include <asm/io.h>
24 #include <asm/pgtable.h>
25
26 #ifdef CONFIG_SOUND
27 void soundcard_init(void);
28 #endif
29 #ifdef CONFIG_ISDN
30 void isdn_init(void);
31 #endif
32
33 static int read_ram(struct inode * inode, struct file * file, char * buf, int count)
34 {
35 return -EIO;
36 }
37
38 static int write_ram(struct inode * inode, struct file * file, const char * buf, int count)
39 {
40 return -EIO;
41 }
42
43 static int read_mem(struct inode * inode, struct file * file, char * buf, int count)
44 {
45 unsigned long p = file->f_pos;
46 int read;
47
48 p += PAGE_OFFSET;
49 if (count < 0)
50 return -EINVAL;
51 if (MAP_NR(p) >= MAP_NR(high_memory))
52 return 0;
53 if (count > high_memory - p)
54 count = high_memory - p;
55 read = 0;
56 #if defined(__i386__)
57 while (p < PAGE_OFFSET + PAGE_SIZE && count > 0) {
58 put_user(0,buf);
59 buf++;
60 p++;
61 count--;
62 read++;
63 }
64 #endif
65 memcpy_tofs(buf, (void *) p, count);
66 read += count;
67 file->f_pos += read;
68 return read;
69 }
70
71 static int write_mem(struct inode * inode, struct file * file, const char * buf, int count)
72 {
73 unsigned long p = file->f_pos;
74 int written;
75
76 p += PAGE_OFFSET;
77 if (count < 0)
78 return -EINVAL;
79 if (MAP_NR(p) >= MAP_NR(high_memory))
80 return 0;
81 if (count > high_memory - p)
82 count = high_memory - p;
83 written = 0;
84 #if defined(__i386__)
85 while (PAGE_OFFSET + p < PAGE_SIZE && count > 0) {
86
87 buf++;
88 p++;
89 count--;
90 written++;
91 }
92 #endif
93 memcpy_fromfs((void *) p, buf, count);
94 written += count;
95 file->f_pos += written;
96 return count;
97 }
98
99 static int mmap_mem(struct inode * inode, struct file * file, struct vm_area_struct * vma)
100 {
101 if (vma->vm_offset & ~PAGE_MASK)
102 return -ENXIO;
103 #if defined(__i386__)
104
105
106
107
108
109
110 if (x86 > 3 && vma->vm_offset >= high_memory)
111 pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
112 #endif
113 if (remap_page_range(vma->vm_start, vma->vm_offset, vma->vm_end - vma->vm_start, vma->vm_page_prot))
114 return -EAGAIN;
115 vma->vm_inode = inode;
116 inode->i_count++;
117 return 0;
118 }
119
120 static int read_kmem(struct inode *inode, struct file *file, char *buf, int count)
121 {
122 int read1, read2;
123
124 read1 = read_mem(inode, file, buf, count);
125 if (read1 < 0)
126 return read1;
127 read2 = vread(buf + read1, (char *) ((unsigned long) file->f_pos), count - read1);
128 if (read2 < 0)
129 return read2;
130 file->f_pos += read2;
131 return read1 + read2;
132 }
133
134 static int read_port(struct inode * inode, struct file * file,char * buf, int count)
135 {
136 unsigned int i = file->f_pos;
137 char * tmp = buf;
138
139 while (count-- > 0 && i < 65536) {
140 put_user(inb(i),tmp);
141 i++;
142 tmp++;
143 }
144 file->f_pos = i;
145 return tmp-buf;
146 }
147
148 static int write_port(struct inode * inode, struct file * file, const char * buf, int count)
149 {
150 unsigned int i = file->f_pos;
151 const char * tmp = buf;
152
153 while (count-- > 0 && i < 65536) {
154 outb(get_user(tmp),i);
155 i++;
156 tmp++;
157 }
158 file->f_pos = i;
159 return tmp-buf;
160 }
161
162 static int read_null(struct inode * node, struct file * file, char * buf, int count)
163 {
164 return 0;
165 }
166
167 static int write_null(struct inode * inode, struct file * file, const char * buf, int count)
168 {
169 return count;
170 }
171
172 static int read_zero(struct inode * node, struct file * file, char * buf, int count)
173 {
174 int left;
175
176 for (left = count; left > 0; left--) {
177 put_user(0,buf);
178 buf++;
179 }
180 return count;
181 }
182
183 static int mmap_zero(struct inode * inode, struct file * file, struct vm_area_struct * vma)
184 {
185 if (vma->vm_flags & VM_SHARED)
186 return -EINVAL;
187 if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
188 return -EAGAIN;
189 return 0;
190 }
191
192 static int read_full(struct inode * node, struct file * file, char * buf,int count)
193 {
194 return count;
195 }
196
197 static int write_full(struct inode * inode, struct file * file, const char * buf, int count)
198 {
199 return -ENOSPC;
200 }
201
202
203
204
205
206
207 static int null_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
208 {
209 return file->f_pos=0;
210 }
211
212
213
214
215
216
217
218
219 static int memory_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
220 {
221 switch (orig) {
222 case 0:
223 file->f_pos = offset;
224 return file->f_pos;
225 case 1:
226 file->f_pos += offset;
227 return file->f_pos;
228 default:
229 return -EINVAL;
230 }
231 if (file->f_pos < 0)
232 return 0;
233 return file->f_pos;
234 }
235
236 #define write_kmem write_mem
237 #define mmap_kmem mmap_mem
238 #define zero_lseek null_lseek
239 #define write_zero write_null
240
241 static struct file_operations ram_fops = {
242 memory_lseek,
243 read_ram,
244 write_ram,
245 NULL,
246 NULL,
247 NULL,
248 NULL,
249 NULL,
250 NULL,
251 NULL
252 };
253
254 static struct file_operations mem_fops = {
255 memory_lseek,
256 read_mem,
257 write_mem,
258 NULL,
259 NULL,
260 NULL,
261 mmap_mem,
262 NULL,
263 NULL,
264 NULL
265 };
266
267 static struct file_operations kmem_fops = {
268 memory_lseek,
269 read_kmem,
270 write_kmem,
271 NULL,
272 NULL,
273 NULL,
274 mmap_kmem,
275 NULL,
276 NULL,
277 NULL
278 };
279
280 static struct file_operations null_fops = {
281 null_lseek,
282 read_null,
283 write_null,
284 NULL,
285 NULL,
286 NULL,
287 NULL,
288 NULL,
289 NULL,
290 NULL
291 };
292
293 static struct file_operations port_fops = {
294 memory_lseek,
295 read_port,
296 write_port,
297 NULL,
298 NULL,
299 NULL,
300 NULL,
301 NULL,
302 NULL,
303 NULL
304 };
305
306 static struct file_operations zero_fops = {
307 zero_lseek,
308 read_zero,
309 write_zero,
310 NULL,
311 NULL,
312 NULL,
313 mmap_zero,
314 NULL,
315 NULL
316 };
317
318 static struct file_operations full_fops = {
319 memory_lseek,
320 read_full,
321 write_full,
322 NULL,
323 NULL,
324 NULL,
325 NULL,
326 NULL,
327 NULL
328 };
329
330 static int memory_open(struct inode * inode, struct file * filp)
331 {
332 switch (MINOR(inode->i_rdev)) {
333 case 0:
334 filp->f_op = &ram_fops;
335 break;
336 case 1:
337 filp->f_op = &mem_fops;
338 break;
339 case 2:
340 filp->f_op = &kmem_fops;
341 break;
342 case 3:
343 filp->f_op = &null_fops;
344 break;
345 case 4:
346 filp->f_op = &port_fops;
347 break;
348 case 5:
349 filp->f_op = &zero_fops;
350 break;
351 case 7:
352 filp->f_op = &full_fops;
353 break;
354 case 8:
355 filp->f_op = &random_fops;
356 break;
357 case 9:
358 filp->f_op = &urandom_fops;
359 break;
360 default:
361 return -ENODEV;
362 }
363 if (filp->f_op && filp->f_op->open)
364 return filp->f_op->open(inode,filp);
365 return 0;
366 }
367
368 static struct file_operations memory_fops = {
369 NULL,
370 NULL,
371 NULL,
372 NULL,
373 NULL,
374 NULL,
375 NULL,
376 memory_open,
377 NULL,
378 NULL
379 };
380
381 int chr_dev_init(void)
382 {
383 if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
384 printk("unable to get major %d for memory devs\n", MEM_MAJOR);
385 rand_initialize();
386 tty_init();
387 #ifdef CONFIG_PRINTER
388 lp_init();
389 #endif
390 #if defined (CONFIG_BUSMOUSE) || defined(CONFIG_UMISC) || \
391 defined (CONFIG_PSMOUSE) || defined (CONFIG_MS_BUSMOUSE) || \
392 defined (CONFIG_ATIXL_BUSMOUSE) || defined(CONFIG_SOFT_WATCHDOG)
393 misc_init();
394 #endif
395 #ifdef CONFIG_SOUND
396 soundcard_init();
397 #endif
398 #if CONFIG_QIC02_TAPE
399 qic02_tape_init();
400 #endif
401 #if CONFIG_ISDN
402 isdn_init();
403 #endif
404 #ifdef CONFIG_FTAPE
405 ftape_init();
406 #endif
407 return 0;
408 }