This source file includes following definitions.
- vcs_size
- vcs_lseek
- vcs_read
- vcs_write
- vcs_open
- vcs_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <linux/kernel.h>
20 #include <linux/major.h>
21 #include <linux/errno.h>
22 #include <linux/tty.h>
23 #include <linux/fs.h>
24 #include <asm/segment.h>
25 #include "vt_kern.h"
26 #include "selection.h"
27
28 #define HEADER_SIZE 4
29
30 static inline int
31 vcs_size(struct inode *inode)
32 {
33 int size = video_num_lines * video_num_columns;
34 if (MINOR(inode->i_rdev) & 128)
35 size = 2*size + HEADER_SIZE;
36 return size;
37 }
38
39 static int
40 vcs_lseek(struct inode *inode, struct file *file, off_t offset, int orig)
41 {
42 int size = vcs_size(inode);
43
44 switch (orig) {
45 case 0:
46 file->f_pos = offset;
47 break;
48 case 1:
49 file->f_pos += offset;
50 break;
51 case 2:
52 file->f_pos = size + offset;
53 break;
54 default:
55 return -EINVAL;
56 }
57 if (file->f_pos < 0 || file->f_pos > size)
58 return -EINVAL;
59 return file->f_pos;
60 }
61
62 static int
63 vcs_read(struct inode *inode, struct file *file, char *buf, int count)
64 {
65 unsigned long p = file->f_pos;
66 unsigned int cons = MINOR(inode->i_rdev);
67 int viewed, attr, size, read;
68 char *buf0;
69 unsigned short *org;
70
71 attr = (cons & 128);
72 cons = (cons & 127);
73 if (cons == 0) {
74 cons = fg_console;
75 viewed = 1;
76 } else {
77 cons--;
78 viewed = 0;
79 }
80 if (!vc_cons_allocated(cons))
81 return -ENXIO;
82
83 size = vcs_size(inode);
84 if (count < 0 || p > size)
85 return -EINVAL;
86 if (count > size - p)
87 count = size - p;
88
89 buf0 = buf;
90 if (!attr) {
91 org = screen_pos(cons, p, viewed);
92 while (count-- > 0)
93 put_user(scr_readw(org++) & 0xff, buf++);
94 } else {
95 if (p < HEADER_SIZE) {
96 char header[HEADER_SIZE];
97 header[0] = (char) video_num_lines;
98 header[1] = (char) video_num_columns;
99 getconsxy(cons, header+2);
100 while (p < HEADER_SIZE && count-- > 0)
101 put_user(header[p++], buf++);
102 }
103 p -= HEADER_SIZE;
104 org = screen_pos(cons, p/2, viewed);
105 if ((p & 1) && count-- > 0)
106 put_user(scr_readw(org++) >> 8, buf++);
107 while (count > 1) {
108 put_user(scr_readw(org++), (unsigned short *) buf);
109 buf += 2;
110 count -= 2;
111 }
112 if (count > 0)
113 put_user(scr_readw(org) & 0xff, buf++);
114 }
115 read = buf - buf0;
116 file->f_pos += read;
117 return read;
118 }
119
120 static int
121 vcs_write(struct inode *inode, struct file *file, const char *buf, int count)
122 {
123 unsigned long p = file->f_pos;
124 unsigned int cons = MINOR(inode->i_rdev);
125 int viewed, attr, size, written;
126 const char *buf0;
127 unsigned short *org;
128
129 attr = (cons & 128);
130 cons = (cons & 127);
131 if (cons == 0) {
132 cons = fg_console;
133 viewed = 1;
134 } else {
135 cons--;
136 viewed = 0;
137 }
138 if (!vc_cons_allocated(cons))
139 return -ENXIO;
140
141 size = vcs_size(inode);
142 if (count < 0 || p > size)
143 return -EINVAL;
144 if (count > size - p)
145 count = size - p;
146
147 buf0 = buf;
148 if (!attr) {
149 org = screen_pos(cons, p, viewed);
150 while (count-- > 0) {
151 scr_writew((scr_readw(org) & 0xff00) |
152 get_user(buf++), org);
153 org++;
154 }
155 } else {
156 if (p < HEADER_SIZE) {
157 char header[HEADER_SIZE];
158 getconsxy(cons, header+2);
159 while (p < HEADER_SIZE && count-- > 0)
160 header[p++] = get_user(buf++);
161 if (!viewed)
162 putconsxy(cons, header+2);
163 }
164 p -= HEADER_SIZE;
165 org = screen_pos(cons, p/2, viewed);
166 if ((p & 1) && count-- > 0) {
167 scr_writew((get_user(buf++) << 8) |
168 (scr_readw(org) & 0xff), org);
169 org++;
170 }
171 while (count > 1) {
172 scr_writew(get_user((const unsigned short *) buf), org++);
173 buf += 2;
174 count -= 2;
175 }
176 if (count > 0)
177 scr_writew((scr_readw(org) & 0xff00) |
178 get_user(buf++), org);
179 }
180 written = buf - buf0;
181 file->f_pos += written;
182 return written;
183 }
184
185 static int
186 vcs_open(struct inode *inode, struct file *filp)
187 {
188 unsigned int cons = (MINOR(inode->i_rdev) & 127);
189 if(cons && !vc_cons_allocated(cons-1))
190 return -ENXIO;
191 return 0;
192 }
193
194 static struct file_operations vcs_fops = {
195 vcs_lseek,
196 vcs_read,
197 vcs_write,
198 NULL,
199 NULL,
200 NULL,
201 NULL,
202 vcs_open,
203 NULL,
204 NULL
205 };
206
207 long vcs_init(long kmem_start)
208 {
209 if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
210 printk("unable to get major %d for vcs device", VCS_MAJOR);
211 return kmem_start;
212 }