OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [drivers/] [char/] [vc_screen.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 * linux/arch/arm/drivers/char/vc_screen.c
3
 *
4
 * Provide access to virtual console memory.
5
 * /dev/vcs0: the screen as it is being viewed right now (possibly scrolled)
6
 * /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63)
7
 *            [minor: N]
8
 *
9
 * /dev/vcsaN: idem, but including attributes, and prefixed with
10
 *      the 4 bytes lines,columns,x,y (as screendump used to give)
11
 *            [minor: N+128]
12
 *
13
 * This replaces screendump and part of selection, so that the system
14
 * administrator can control access using file system permissions.
15
 *
16
 * aeb@cwi.nl - efter Friedas begravelse - 950211
17
 *
18
 * Modified by Russell King (01/01/96) [experimental + in development]
19
 */
20
 
21
#include <linux/kernel.h>
22
#include <linux/major.h>
23
#include <linux/errno.h>
24
#include <linux/tty.h>
25
#include <linux/fs.h>
26
#include <asm/segment.h>
27
 
28
#include "vt_kern.h"
29
#include "selection.h"
30
 
31
#define HEADER_SIZE     4
32
 
33
static inline int vcs_size (struct inode *inode)
34
{
35
    int size = vtdata.numrows * vtdata.numcolumns;
36
 
37
    if (MINOR(inode->i_rdev) & 128)
38
        size = sizeof (unsigned long) * size + HEADER_SIZE;
39
    return size;
40
}
41
 
42
static int vcs_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
43
{
44
    int size = vcs_size(inode);
45
 
46
    switch (orig) {
47
    case 0:
48
        file->f_pos = offset;
49
        break;
50
    case 1:
51
        file->f_pos += offset;
52
        break;
53
    case 2:
54
        file->f_pos = size + offset;
55
        break;
56
    default:
57
        return -EINVAL;
58
    }
59
    if (file->f_pos < 0 || file->f_pos > size)
60
        return -EINVAL;
61
    return file->f_pos;
62
}
63
 
64
static int vcs_read (struct inode *inode, struct file *file, char *buf, int count)
65
{
66
    struct vt *vt;
67
    unsigned long p = file->f_pos;
68
    unsigned int cons = MINOR(inode->i_rdev);
69
    int attr, size, read;
70
    char *buf0;
71
    unsigned long *org, d;
72
 
73
    attr = (cons & 128);
74
    cons = (cons & 127);
75
 
76
    if (cons == 0)
77
        vt = vtdata.fgconsole;
78
    else
79
        vt = vt_con_data + (cons - 1);
80
 
81
    if (!vt_allocated (vt))
82
        return -ENXIO;
83
 
84
    size = vcs_size(inode);
85
    if (count < 0 || p > size)
86
        return -EINVAL;
87
 
88
    if (count > size - p)
89
        count = size - p;
90
 
91
    buf0 = buf;
92
    if (!attr) {
93
        org = screen_pos (vt, p);
94
        while (count-- > 0)
95
            put_user (*org++ & 0xff, buf++);
96
    } else {
97
        if (p < HEADER_SIZE) {
98
            char header[HEADER_SIZE];
99
            header[0] = (char) vtdata.numrows;
100
            header[1] = (char) vtdata.numcolumns;
101
            getconsxy (vt, header + 2);
102
            while (p < HEADER_SIZE && count-- > 0)
103
                put_user (header[p++], buf++);
104
        }
105
        p -= HEADER_SIZE;
106
        org = screen_pos (vt, p >> 2);
107
 
108
        if (p & 3) {
109
            unsigned long d = *org++;
110
 
111
            switch (p & 3) {
112
            case 1:
113
                if (count-- > 0)
114
                    put_user ((d >> 8) & 255, buf++);
115
            case 2:
116
                if (count-- > 0)
117
                    put_user ((d >> 16) & 255, buf++);
118
            case 3:
119
                if (count-- > 0)
120
                    put_user (d >> 24, buf++);
121
            }
122
        }
123
 
124
        while (count > 3) {
125
            put_user (*org++, (unsigned long *) buf);
126
            buf += 4;
127
            count -= 4;
128
        }
129
 
130
        if (count > 0) {
131
            d = *org;
132
            put_user (d & 0xff, buf++);
133
            if (count > 1)
134
                put_user ((d >> 8) & 0xff, buf++);
135
            if (count > 2)
136
                put_user ((d >> 16) & 0xff, buf++);
137
        }
138
    }
139
    read = buf - buf0;
140
    file->f_pos += read;
141
    return read;
142
}
143
 
144
static int vcs_write (struct inode *inode, struct file *file, const char *buf, int count)
145
{
146
    struct vt *vt;
147
    unsigned long p = file->f_pos;
148
    unsigned int cons = MINOR(inode->i_rdev);
149
    int viewed, attr, size, written;
150
    const char *buf0;
151
    unsigned long *org;
152
 
153
    attr = (cons & 128);
154
    cons = (cons & 127);
155
 
156
    if (cons == 0) {
157
        vt = vtdata.fgconsole;
158
        viewed = 1;
159
    } else {
160
        vt = vt_con_data + (cons - 1);
161
        viewed = 0;
162
    }
163
 
164
    if (!vt_allocated (vt))
165
        return -ENXIO;
166
 
167
    size = vcs_size(inode);
168
 
169
    if (count < 0 || p > size)
170
        return -EINVAL;
171
 
172
    if (count > size - p)
173
        count = size - p;
174
 
175
    buf0 = buf;
176
    if (!attr) {
177
        org = screen_pos (vt, p);
178
        while (count-- > 0) {
179
            *org = (*org & 0xffffff00) | get_user (buf++);
180
            org++;
181
        }
182
    } else {
183
        if (p < HEADER_SIZE) {
184
            char header[HEADER_SIZE];
185
            getconsxy (vt, header+2);
186
 
187
            while (p < HEADER_SIZE && count-- > 0)
188
                header[p++] = get_user (buf++);
189
            if (!viewed)
190
                putconsxy (vt, header + 2);
191
        }
192
        p -= HEADER_SIZE;
193
        org = screen_pos (vt, p >> 2);
194
 
195
        if (p & 3) {
196
            unsigned long d = *org;
197
 
198
            switch (p & 3) {
199
            case 1:
200
                if (count-- > 0)
201
                    d = (d & 0xffff00ff) | (get_user (buf++) << 8);
202
            case 2:
203
                if (count-- > 0)
204
                    d = (d & 0xff00ffff) | (get_user (buf++) << 16);
205
            case 3:
206
                if (count-- > 0)
207
                    d = (d & 0x00ffffff) | (get_user (buf++) << 24);
208
            }
209
            *org ++ = d;
210
        }
211
 
212
        while (count > 3) {
213
            *org ++ = get_user ((const unsigned long *)buf);
214
            buf += 4;
215
            count -= 4;
216
        }
217
 
218
        if (count > 0) {
219
            unsigned long d;
220
 
221
            d = (*org >> (count * 8)) << (count * 8);
222
            d |= get_user (buf ++);
223
 
224
            if (count > 1)
225
                d |= get_user (buf ++) << 8;
226
 
227
            if (count > 2)
228
                d |= get_user (buf ++) << 16;
229
            *org = d;
230
        }
231
    }
232
    written = buf - buf0;
233
    update_scrmem (vt, file->f_pos >> 2, (written + 3) >> 2);
234
    file->f_pos += written;
235
    return written;
236
}
237
 
238
static int vcs_open (struct inode *inode, struct file *filp)
239
{
240
    unsigned int cons = (MINOR(inode->i_rdev) & 127);
241
 
242
    if (cons && !vt_allocated (vt_con_data + cons - 1))
243
        return -ENXIO;
244
    return 0;
245
}
246
 
247
static struct file_operations vcs_fops = {
248
        vcs_lseek,      /* lseek */
249
        vcs_read,       /* read */
250
        vcs_write,      /* write */
251
        NULL,           /* readdir */
252
        NULL,           /* select */
253
        NULL,           /* ioctl */
254
        NULL,           /* mmap */
255
        vcs_open,       /* open */
256
        NULL,           /* release */
257
        NULL            /* fsync */
258
};
259
 
260
int vcs_init(void)
261
{
262
    int error;
263
 
264
    error = register_chrdev(VCS_MAJOR, "vcs", &vcs_fops);
265
    if (error)
266
        printk("unable to get major %d for vcs device", VCS_MAJOR);
267
    return error;
268
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.