This source file includes following definitions.
- read_ram
- write_ram
- read_mem
- write_mem
- read_kmem
- write_kmem
- read_port
- write_port
- mem_lseek
- mem_read
- mem_write
- mem_readdir
- chr_dev_init
1
2
3
4
5
6
7 #include <errno.h>
8 #include <sys/types.h>
9
10 #include <linux/sched.h>
11 #include <linux/kernel.h>
12 #include <linux/tty.h>
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 addr;
30 char *tmp;
31 unsigned long pde, pte, page;
32 int i;
33
34 if (count < 0)
35 return -EINVAL;
36 addr = file->f_pos;
37 tmp = buf;
38 while (count > 0) {
39 pde = (unsigned long) pg_dir + (addr >> 20 & 0xffc);
40 if (!((pte = *((unsigned long *) pde)) & 1))
41 break;
42 pte &= 0xfffff000;
43 pte += (addr >> 10) & 0xffc;
44 if (((page = *((unsigned long *) pte)) & 1) == 0)
45 break;
46
47
48
49
50 page &= 0xfffff000;
51 page += addr & 0xfff;
52 i = 4096-(addr & 0xfff);
53 if (i > count)
54 i = count;
55 memcpy_tofs(tmp,(void *) page,i);
56 addr += i;
57 tmp += i;
58 count -= i;
59 }
60 file->f_pos = addr;
61 return tmp-buf;
62 }
63
64 static int write_mem(struct inode * inode, struct file * file,char * buf, int count)
65 {
66 unsigned long addr;
67 char *tmp;
68 unsigned long pde, pte, page;
69 int i;
70
71 if (count < 0)
72 return -EINVAL;
73 addr = file->f_pos;
74 tmp = buf;
75 while (count > 0) {
76 pde = (unsigned long) pg_dir + (addr >> 20 & 0xffc);
77 if (!((pte = *((unsigned long *) pde)) & 1))
78 break;
79 pte &= 0xfffff000;
80 pte += (addr >> 10) & 0xffc;
81 if (((page = *((unsigned long *) pte)) & 1) == 0)
82 break;
83 if ((page & 2) == 0)
84 un_wp_page((unsigned long *) pte);
85 page &= 0xfffff000;
86 page += addr & 0xfff;
87 i = 4096-(addr & 0xfff);
88 if (i > count)
89 i = count;
90 memcpy_fromfs((void *) page,tmp,i);
91 addr += i;
92 tmp += i;
93 count -= i;
94 }
95 file->f_pos = addr;
96 return tmp-buf;
97 }
98
99 static int read_kmem(struct inode * inode, struct file * file,char * buf, int count)
100 {
101 unsigned long p = file->f_pos;
102
103 if (count < 0)
104 return -EINVAL;
105 if (p >= HIGH_MEMORY)
106 return 0;
107 if (count > HIGH_MEMORY - p)
108 count = HIGH_MEMORY - p;
109 memcpy_tofs(buf,(void *) p,count);
110 file->f_pos += count;
111 return count;
112 }
113
114 static int write_kmem(struct inode * inode, struct file * file,char * buf, int count)
115 {
116 unsigned long p = file->f_pos;
117
118 if (count < 0)
119 return -EINVAL;
120 if (p >= HIGH_MEMORY)
121 return 0;
122 if (count > HIGH_MEMORY - p)
123 count = HIGH_MEMORY - p;
124 memcpy_fromfs((void *) p,buf,count);
125 file->f_pos += count;
126 return count;
127 }
128
129 static int read_port(struct inode * inode,struct file * file,char * buf, int count)
130 {
131 unsigned int i = file->f_pos;
132 char * tmp = buf;
133
134 while (count-- > 0 && i < 65536) {
135 put_fs_byte(inb(i),tmp);
136 i++;
137 tmp++;
138 }
139 file->f_pos = i;
140 return tmp-buf;
141 }
142
143 static int write_port(struct inode * inode,struct file * file,char * buf, int count)
144 {
145 unsigned int i = file->f_pos;
146 char * tmp = buf;
147
148 while (count-- > 0 && i < 65536) {
149 outb(get_fs_byte(tmp),i);
150 i++;
151 tmp++;
152 }
153 file->f_pos = i;
154 return tmp-buf;
155 }
156
157
158
159
160
161
162
163
164
165 static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
166 {
167 switch (orig) {
168 case 0:
169 file->f_pos = offset;
170 return file->f_pos;
171 case 1:
172 file->f_pos += offset;
173 return file->f_pos;
174 default:
175 return -EINVAL;
176 }
177 if (file->f_pos < 0)
178 return 0;
179 return file->f_pos;
180 }
181
182 static int mem_read(struct inode * inode, struct file * file, char * buf, int count)
183 {
184 switch (MINOR(inode->i_rdev)) {
185 case 0:
186 return read_ram(inode,file,buf,count);
187 case 1:
188 return read_mem(inode,file,buf,count);
189 case 2:
190 return read_kmem(inode,file,buf,count);
191 case 3:
192 return 0;
193 case 4:
194 return read_port(inode,file,buf,count);
195 default:
196 return -ENODEV;
197 }
198 }
199
200 static int mem_write(struct inode * inode, struct file * file, char * buf, int count)
201 {
202 switch (MINOR(inode->i_rdev)) {
203 case 0:
204 return write_ram(inode,file,buf,count);
205 case 1:
206 return write_mem(inode,file,buf,count);
207 case 2:
208 return write_kmem(inode,file,buf,count);
209 case 3:
210 return count;
211 case 4:
212 return write_port(inode,file,buf,count);
213 default:
214 return -ENODEV;
215 }
216 }
217
218 static int mem_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
219 {
220 return -ENOTDIR;
221 }
222
223 static struct file_operations mem_fops = {
224 mem_lseek,
225 mem_read,
226 mem_write,
227 mem_readdir,
228 NULL,
229 NULL,
230 NULL
231 };
232
233 void chr_dev_init(void)
234 {
235 chrdev_fops[1] = &mem_fops;
236 tty_init();
237 lp_init();
238 }