|
|
1.1 root 1: /*
2: * linux/kernel/chr_drv/mem.c
3: *
1.1.1.4 root 4: * Copyright (C) 1991, 1992 Linus Torvalds
1.1 root 5: */
6:
1.1.1.4 root 7: #include <linux/types.h>
8: #include <linux/errno.h>
1.1 root 9: #include <linux/sched.h>
10: #include <linux/kernel.h>
11: #include <linux/tty.h>
1.1.1.4 root 12: #include <linux/mouse.h>
1.1 root 13:
14: #include <asm/segment.h>
15: #include <asm/io.h>
16:
17: static int read_ram(struct inode * inode, struct file * file,char * buf, int count)
18: {
19: return -EIO;
20: }
21:
22: static int write_ram(struct inode * inode, struct file * file,char * buf, int count)
23: {
24: return -EIO;
25: }
26:
27: static int read_mem(struct inode * inode, struct file * file,char * buf, int count)
28: {
29: unsigned long p = file->f_pos;
30:
31: if (count < 0)
32: return -EINVAL;
1.1.1.4 root 33: if (p >= high_memory)
1.1 root 34: return 0;
1.1.1.4 root 35: if (count > high_memory - p)
36: count = high_memory - p;
1.1 root 37: memcpy_tofs(buf,(void *) p,count);
38: file->f_pos += count;
39: return count;
40: }
41:
1.1.1.5 ! root 42: static int write_mem(struct inode * inode, struct file * file,char * buf, int count)
1.1 root 43: {
44: unsigned long p = file->f_pos;
45:
46: if (count < 0)
47: return -EINVAL;
1.1.1.4 root 48: if (p >= high_memory)
1.1 root 49: return 0;
1.1.1.4 root 50: if (count > high_memory - p)
51: count = high_memory - p;
1.1 root 52: memcpy_fromfs((void *) p,buf,count);
53: file->f_pos += count;
54: return count;
55: }
56:
57: static int read_port(struct inode * inode,struct file * file,char * buf, int count)
58: {
59: unsigned int i = file->f_pos;
60: char * tmp = buf;
61:
62: while (count-- > 0 && i < 65536) {
63: put_fs_byte(inb(i),tmp);
64: i++;
65: tmp++;
66: }
67: file->f_pos = i;
68: return tmp-buf;
69: }
70:
71: static int write_port(struct inode * inode,struct file * file,char * buf, int count)
72: {
73: unsigned int i = file->f_pos;
74: char * tmp = buf;
75:
76: while (count-- > 0 && i < 65536) {
77: outb(get_fs_byte(tmp),i);
78: i++;
79: tmp++;
80: }
81: file->f_pos = i;
82: return tmp-buf;
83: }
84:
1.1.1.2 root 85: static int read_zero(struct inode *node,struct file *file,char *buf,int count)
86: {
87: int left;
88:
89: for (left = count; left > 0; left--) {
90: put_fs_byte(0,buf);
91: buf++;
92: }
93: return count;
94: }
95:
1.1 root 96: /*
97: * The memory devices use the full 32 bits of the offset, and so we cannot
98: * check against negative addresses: they are ok. The return value is weird,
99: * though, in that case (0).
100: *
101: * also note that seeking relative to the "end of file" isn't supported:
102: * it has no meaning, so it returns -EINVAL.
103: */
104: static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
105: {
106: switch (orig) {
107: case 0:
108: file->f_pos = offset;
109: return file->f_pos;
110: case 1:
111: file->f_pos += offset;
112: return file->f_pos;
113: default:
114: return -EINVAL;
115: }
116: if (file->f_pos < 0)
117: return 0;
118: return file->f_pos;
119: }
120:
1.1.1.5 ! root 121: #define read_kmem read_mem
! 122: #define write_kmem write_mem
! 123:
1.1 root 124: static int mem_read(struct inode * inode, struct file * file, char * buf, int count)
125: {
126: switch (MINOR(inode->i_rdev)) {
127: case 0:
128: return read_ram(inode,file,buf,count);
129: case 1:
130: return read_mem(inode,file,buf,count);
131: case 2:
132: return read_kmem(inode,file,buf,count);
133: case 3:
134: return 0; /* /dev/null */
135: case 4:
136: return read_port(inode,file,buf,count);
1.1.1.2 root 137: case 5:
138: return read_zero(inode,file,buf,count);
1.1 root 139: default:
140: return -ENODEV;
141: }
142: }
143:
144: static int mem_write(struct inode * inode, struct file * file, char * buf, int count)
145: {
146: switch (MINOR(inode->i_rdev)) {
147: case 0:
148: return write_ram(inode,file,buf,count);
149: case 1:
150: return write_mem(inode,file,buf,count);
151: case 2:
152: return write_kmem(inode,file,buf,count);
153: case 3:
154: return count; /* /dev/null */
155: case 4:
156: return write_port(inode,file,buf,count);
1.1.1.2 root 157: case 5:
158: return count; /* /dev/zero */
1.1 root 159: default:
160: return -ENODEV;
161: }
162: }
163:
164: static struct file_operations mem_fops = {
165: mem_lseek,
166: mem_read,
167: mem_write,
168: NULL, /* mem_readdir */
169: NULL, /* mem_select */
170: NULL, /* mem_ioctl */
171: NULL, /* no special open code */
172: NULL /* no special release code */
173: };
174:
1.1.1.3 root 175: long chr_dev_init(long mem_start, long mem_end)
1.1 root 176: {
177: chrdev_fops[1] = &mem_fops;
1.1.1.3 root 178: mem_start = tty_init(mem_start);
179: mem_start = lp_init(mem_start);
1.1.1.4 root 180: mem_start = mouse_init(mem_start);
1.1.1.3 root 181: return mem_start;
1.1 root 182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.