2 * linux/drivers/char/mem.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
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/vmalloc.h>
19 #include <linux/mman.h>
21 #include <linux/random.h>
22 #include <linux/init.h>
23 #include <linux/joystick.h>
25 #include <asm/uaccess.h>
27 #include <asm/pgtable.h>
30 void soundcore_init(void);
31 #ifdef CONFIG_SOUND_OSS
32 void soundcard_init(void);
34 #ifdef CONFIG_DMASOUND
35 void dmasound_init(void);
41 #ifdef CONFIG_VIDEO_DEV
42 extern int videodev_init(void);
45 extern void fbmem_init(void);
48 static ssize_t
do_write_mem(struct file
* file
, void *p
, unsigned long realp
,
49 const char * buf
, size_t count
, loff_t
*ppos
)
54 #if defined(__sparc__) || defined(__mc68000__)
55 /* we don't have page 0 mapped on sparc and m68k.. */
56 if (realp
< PAGE_SIZE
) {
57 unsigned long sz
= PAGE_SIZE
-realp
;
58 if (sz
> count
) sz
= count
;
59 /* Hmm. Do something? */
66 if (copy_from_user(p
, buf
, count
))
75 * This funcion reads the *physical* memory. The f_pos points directly to the
78 static ssize_t
read_mem(struct file
* file
, char * buf
,
79 size_t count
, loff_t
*ppos
)
81 unsigned long p
= *ppos
;
82 unsigned long end_mem
;
85 end_mem
= __pa(high_memory
);
88 if (count
> end_mem
- p
)
91 #if defined(__sparc__) || defined(__mc68000__)
92 /* we don't have page 0 mapped on sparc and m68k.. */
94 unsigned long sz
= PAGE_SIZE
-p
;
98 if (clear_user(buf
, sz
))
107 if (copy_to_user(buf
, __va(p
), count
))
114 static ssize_t
write_mem(struct file
* file
, const char * buf
,
115 size_t count
, loff_t
*ppos
)
117 unsigned long p
= *ppos
;
118 unsigned long end_mem
;
120 end_mem
= __pa(high_memory
);
123 if (count
> end_mem
- p
)
125 return do_write_mem(file
, __va(p
), p
, buf
, count
, ppos
);
128 static int mmap_mem(struct file
* file
, struct vm_area_struct
* vma
)
130 unsigned long offset
= vma
->vm_offset
;
132 if (offset
& ~PAGE_MASK
)
134 #if defined(__i386__)
136 * hmm.. This disables high-memory caching, as the XFree86 team
137 * wondered about that at one time.
138 * The surround logic should disable caching for the high device
139 * addresses anyway, but right now this seems still needed.
141 if (boot_cpu_data
.x86
> 3 && offset
>= __pa(high_memory
))
142 pgprot_val(vma
->vm_page_prot
) |= _PAGE_PCD
;
145 if (offset
>= __pa(high_memory
))
146 pgprot_val(vma
->vm_page_prot
) |= _PAGE_NO_CACHE
|_PAGE_GUARDED
;
148 if (remap_page_range(vma
->vm_start
, offset
, vma
->vm_end
-vma
->vm_start
,
157 * This function reads the *virtual* memory as seen by the kernel.
159 static ssize_t
read_kmem(struct file
*file
, char *buf
,
160 size_t count
, loff_t
*ppos
)
162 unsigned long p
= *ppos
;
166 if (p
< (unsigned long) high_memory
) {
168 if (count
> (unsigned long) high_memory
- p
)
169 read
= (unsigned long) high_memory
- p
;
171 #if defined(__sparc__) || defined(__mc68000__)
172 /* we don't have page 0 mapped on sparc and m68k.. */
173 if (p
< PAGE_SIZE
&& read
> 0) {
174 size_t tmp
= PAGE_SIZE
- p
;
175 if (tmp
> read
) tmp
= read
;
176 clear_user(buf
, tmp
);
183 copy_to_user(buf
, (char *)p
, read
);
189 virtr
= vread(buf
, (char *)p
, count
);
197 * This function writes to the *virtual* memory as seen by the kernel.
199 static ssize_t
write_kmem(struct file
* file
, const char * buf
,
200 size_t count
, loff_t
*ppos
)
202 unsigned long p
= *ppos
;
204 if (p
>= (unsigned long) high_memory
)
206 if (count
> (unsigned long) high_memory
- p
)
207 count
= (unsigned long) high_memory
- p
;
208 return do_write_mem(file
, (void*)p
, p
, buf
, count
, ppos
);
211 static ssize_t
read_port(struct file
* file
, char * buf
,
212 size_t count
, loff_t
*ppos
)
214 unsigned long i
= *ppos
;
217 if (verify_area(VERIFY_WRITE
,buf
,count
))
219 while (count
-- > 0 && i
< 65536) {
220 if (__put_user(inb(i
),tmp
) < 0)
229 static ssize_t
write_port(struct file
* file
, const char * buf
,
230 size_t count
, loff_t
*ppos
)
232 unsigned long i
= *ppos
;
233 const char * tmp
= buf
;
235 if (verify_area(VERIFY_READ
,buf
,count
))
237 while (count
-- > 0 && i
< 65536) {
239 if (__get_user(c
, tmp
))
249 static ssize_t
read_null(struct file
* file
, char * buf
,
250 size_t count
, loff_t
*ppos
)
255 static ssize_t
write_null(struct file
* file
, const char * buf
,
256 size_t count
, loff_t
*ppos
)
262 * For fun, we are using the MMU for this.
264 static inline size_t read_zero_pagealigned(char * buf
, size_t size
)
266 struct mm_struct
*mm
;
267 struct vm_area_struct
* vma
;
268 unsigned long addr
=(unsigned long)buf
;
271 /* Oops, this was forgotten before. -ben */
274 /* For private mappings, just map in zero pages. */
275 for (vma
= find_vma(mm
, addr
); vma
; vma
= vma
->vm_next
) {
278 if (vma
->vm_start
> addr
|| (vma
->vm_flags
& VM_WRITE
) == 0)
280 if (vma
->vm_flags
& VM_SHARED
)
282 count
= vma
->vm_end
- addr
;
286 flush_cache_range(mm
, addr
, addr
+ count
);
287 zap_page_range(mm
, addr
, count
);
288 zeromap_page_range(addr
, count
, PAGE_COPY
);
289 flush_tlb_range(mm
, addr
, addr
+ count
);
300 /* The shared case is hard. Let's do the conventional zeroing. */
302 unsigned long unwritten
= clear_user(buf
, PAGE_SIZE
);
304 return size
+ unwritten
- PAGE_SIZE
;
305 if (current
->need_resched
)
317 static ssize_t
read_zero(struct file
* file
, char * buf
,
318 size_t count
, loff_t
*ppos
)
320 unsigned long left
, unwritten
, written
= 0;
325 if (!access_ok(VERIFY_WRITE
, buf
, count
))
330 /* do we want to be clever? Arbitrary cut-off */
331 if (count
>= PAGE_SIZE
*4) {
332 unsigned long partial
;
334 /* How much left of the page? */
335 partial
= (PAGE_SIZE
-1) & -(unsigned long) buf
;
336 unwritten
= clear_user(buf
, partial
);
337 written
= partial
- unwritten
;
342 unwritten
= read_zero_pagealigned(buf
, left
& PAGE_MASK
);
343 written
+= (left
& PAGE_MASK
) - unwritten
;
346 buf
+= left
& PAGE_MASK
;
349 unwritten
= clear_user(buf
, left
);
350 written
+= left
- unwritten
;
352 return written
? written
: -EFAULT
;
355 static int mmap_zero(struct file
* file
, struct vm_area_struct
* vma
)
357 if (vma
->vm_flags
& VM_SHARED
)
359 if (zeromap_page_range(vma
->vm_start
, vma
->vm_end
- vma
->vm_start
, vma
->vm_page_prot
))
364 static ssize_t
write_full(struct file
* file
, const char * buf
,
365 size_t count
, loff_t
*ppos
)
371 * Special lseek() function for /dev/null and /dev/zero. Most notably, you
372 * can fopen() both devices with "a" now. This was previously impossible.
376 static loff_t
null_lseek(struct file
* file
, loff_t offset
, int orig
)
378 return file
->f_pos
= 0;
382 * The memory devices use the full 32/64 bits of the offset, and so we cannot
383 * check against negative addresses: they are ok. The return value is weird,
384 * though, in that case (0).
386 * also note that seeking relative to the "end of file" isn't supported:
387 * it has no meaning, so it returns -EINVAL.
389 static loff_t
memory_lseek(struct file
* file
, loff_t offset
, int orig
)
393 file
->f_pos
= offset
;
396 file
->f_pos
+= offset
;
403 #define mmap_kmem mmap_mem
404 #define zero_lseek null_lseek
405 #define full_lseek null_lseek
406 #define write_zero write_null
407 #define read_full read_zero
409 static struct file_operations mem_fops
= {
413 NULL
, /* mem_readdir */
415 NULL
, /* mem_ioctl */
417 NULL
, /* no special open code */
419 NULL
, /* no special release code */
423 static struct file_operations kmem_fops
= {
427 NULL
, /* kmem_readdir */
428 NULL
, /* kmem_poll */
429 NULL
, /* kmem_ioctl */
431 NULL
, /* no special open code */
433 NULL
, /* no special release code */
437 static struct file_operations null_fops
= {
441 NULL
, /* null_readdir */
442 NULL
, /* null_poll */
443 NULL
, /* null_ioctl */
444 NULL
, /* null_mmap */
445 NULL
, /* no special open code */
447 NULL
, /* no special release code */
451 static struct file_operations port_fops
= {
455 NULL
, /* port_readdir */
456 NULL
, /* port_poll */
457 NULL
, /* port_ioctl */
458 NULL
, /* port_mmap */
459 NULL
, /* no special open code */
461 NULL
, /* no special release code */
465 static struct file_operations zero_fops
= {
469 NULL
, /* zero_readdir */
470 NULL
, /* zero_poll */
471 NULL
, /* zero_ioctl */
473 NULL
, /* no special open code */
475 NULL
/* no special release code */
478 static struct file_operations full_fops
= {
482 NULL
, /* full_readdir */
483 NULL
, /* full_poll */
484 NULL
, /* full_ioctl */
485 NULL
, /* full_mmap */
486 NULL
, /* no special open code */
488 NULL
/* no special release code */
491 static int memory_open(struct inode
* inode
, struct file
* filp
)
493 switch (MINOR(inode
->i_rdev
)) {
495 filp
->f_op
= &mem_fops
;
498 filp
->f_op
= &kmem_fops
;
501 filp
->f_op
= &null_fops
;
504 filp
->f_op
= &port_fops
;
507 filp
->f_op
= &zero_fops
;
510 filp
->f_op
= &full_fops
;
513 filp
->f_op
= &random_fops
;
516 filp
->f_op
= &urandom_fops
;
521 if (filp
->f_op
&& filp
->f_op
->open
)
522 return filp
->f_op
->open(inode
,filp
);
526 static struct file_operations memory_fops
= {
534 memory_open
, /* just a selector for the real open */
540 __initfunc(int chr_dev_init(void))
542 if (register_chrdev(MEM_MAJOR
,"mem",&memory_fops
))
543 printk("unable to get major %d for memory devs\n", MEM_MAJOR
);
545 #if defined (CONFIG_FB)
549 #ifdef CONFIG_PRINTER
552 #if defined (CONFIG_BUSMOUSE) || defined(CONFIG_UMISC) || \
553 defined (CONFIG_PSMOUSE) || defined (CONFIG_MS_BUSMOUSE) || \
554 defined (CONFIG_ATIXL_BUSMOUSE) || defined(CONFIG_SOFT_WATCHDOG) || \
555 defined (CONFIG_AMIGAMOUSE) || defined (CONFIG_ATARIMOUSE) || \
556 defined (CONFIG_MACMOUSE) || defined (CONFIG_PCWATCHDOG) || \
557 defined (CONFIG_APM) || defined (CONFIG_RTC) || \
558 defined (CONFIG_SUN_MOUSE) || defined (CONFIG_NVRAM)
563 #ifdef CONFIG_SOUND_OSS
566 #ifdef CONFIG_DMASOUND
570 #ifdef CONFIG_JOYSTICK
572 * Some joysticks only appear when the sound card they are
573 * connected to is configured. Keep the sound/joystick ordering.
577 #if CONFIG_QIC02_TAPE
586 #ifdef CONFIG_VIDEO_BT848
589 #ifdef CONFIG_VIDEO_DEV