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