fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / char / vc_screen.c
index c357ab7..2677651 100644 (file)
  *      - making it shorter - scr_readw are macros which expand in PRETTY long code
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
@@ -52,14 +50,17 @@ vcs_size(struct inode *inode)
        int size;
        int minor = iminor(inode);
        int currcons = minor & 127;
+       struct vc_data *vc;
+
        if (currcons == 0)
                currcons = fg_console;
        else
                currcons--;
        if (!vc_cons_allocated(currcons))
                return -ENXIO;
+       vc = vc_cons[currcons].d;
 
-       size = video_num_lines * video_num_columns;
+       size = vc->vc_rows * vc->vc_cols;
 
        if (minor & 128)
                size = 2*size + HEADER_SIZE;
@@ -70,11 +71,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
 {
        int size;
 
-       lock_kernel();
-       size = vcs_size(file->f_dentry->d_inode);
+       down(&con_buf_sem);
+       size = vcs_size(file->f_path.dentry->d_inode);
        switch (orig) {
                default:
-                       unlock_kernel();
+                       up(&con_buf_sem);
                        return -EINVAL;
                case 2:
                        offset += size;
@@ -85,28 +86,22 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
                        break;
        }
        if (offset < 0 || offset > size) {
-               unlock_kernel();
+               up(&con_buf_sem);
                return -EINVAL;
        }
        file->f_pos = offset;
-       unlock_kernel();
+       up(&con_buf_sem);
        return file->f_pos;
 }
 
-/* We share this temporary buffer with the console write code
- * so that we can easily avoid touching user space while holding the
- * console spinlock.
- */
-extern char con_buf[PAGE_SIZE];
-#define CON_BUF_SIZE   PAGE_SIZE
-extern struct semaphore con_buf_sem;
 
 static ssize_t
 vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
-       struct inode *inode = file->f_dentry->d_inode;
+       struct inode *inode = file->f_path.dentry->d_inode;
        unsigned int currcons = iminor(inode);
-       long pos = *ppos;
+       struct vc_data *vc;
+       long pos;
        long viewed, attr, read;
        int col, maxcol;
        unsigned short *org = NULL;
@@ -114,6 +109,8 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 
        down(&con_buf_sem);
 
+       pos = *ppos;
+
        /* Select the proper current console and verify
         * sanity of the situation under the console lock.
         */
@@ -131,6 +128,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
        ret = -ENXIO;
        if (!vc_cons_allocated(currcons))
                goto unlock_out;
+       vc = vc_cons[currcons].d;
 
        ret = -EINVAL;
        if (pos < 0)
@@ -164,15 +162,15 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 
                con_buf_start = con_buf0 = con_buf;
                orig_count = this_round;
-               maxcol = video_num_columns;
+               maxcol = vc->vc_cols;
                if (!attr) {
-                       org = screen_pos(currcons, p, viewed);
+                       org = screen_pos(vc, p, viewed);
                        col = p % maxcol;
                        p += maxcol - col;
                        while (this_round-- > 0) {
-                               *con_buf0++ = (vcs_scr_readw(currcons, org++) & 0xff);
+                               *con_buf0++ = (vcs_scr_readw(vc, org++) & 0xff);
                                if (++col == maxcol) {
-                                       org = screen_pos(currcons, p, viewed);
+                                       org = screen_pos(vc, p, viewed);
                                        col = 0;
                                        p += maxcol;
                                }
@@ -181,9 +179,9 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
                        if (p < HEADER_SIZE) {
                                size_t tmp_count;
 
-                               con_buf0[0] = (char) video_num_lines;
-                               con_buf0[1] = (char) video_num_columns;
-                               getconsxy(currcons, con_buf0 + 2);
+                               con_buf0[0] = (char)vc->vc_rows;
+                               con_buf0[1] = (char)vc->vc_cols;
+                               getconsxy(vc, con_buf0 + 2);
 
                                con_buf_start += p;
                                this_round += p;
@@ -219,7 +217,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
                                p /= 2;
                                col = p % maxcol;
 
-                               org = screen_pos(currcons, p, viewed);
+                               org = screen_pos(vc, p, viewed);
                                p += maxcol - col;
 
                                /* Buffer has even length, so we can always copy
@@ -229,10 +227,10 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
                                this_round = (this_round + 1) >> 1;
 
                                while (this_round) {
-                                       *tmp_buf++ = vcs_scr_readw(currcons, org++);
+                                       *tmp_buf++ = vcs_scr_readw(vc, org++);
                                        this_round --;
                                        if (++col == maxcol) {
-                                               org = screen_pos(currcons, p, viewed);
+                                               org = screen_pos(vc, p, viewed);
                                                col = 0;
                                                p += maxcol;
                                        }
@@ -273,9 +271,10 @@ unlock_out:
 static ssize_t
 vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
-       struct inode *inode = file->f_dentry->d_inode;
+       struct inode *inode = file->f_path.dentry->d_inode;
        unsigned int currcons = iminor(inode);
-       long pos = *ppos;
+       struct vc_data *vc;
+       long pos;
        long viewed, attr, size, written;
        char *con_buf0;
        int col, maxcol;
@@ -284,6 +283,8 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 
        down(&con_buf_sem);
 
+       pos = *ppos;
+
        /* Select the proper current console and verify
         * sanity of the situation under the console lock.
         */
@@ -302,6 +303,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
        ret = -ENXIO;
        if (!vc_cons_allocated(currcons))
                goto unlock_out;
+       vc = vc_cons[currcons].d;
 
        size = vcs_size(inode);
        ret = -EINVAL;
@@ -354,10 +356,10 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 
                con_buf0 = con_buf;
                orig_count = this_round;
-               maxcol = video_num_columns;
+               maxcol = vc->vc_cols;
                p = pos;
                if (!attr) {
-                       org0 = org = screen_pos(currcons, p, viewed);
+                       org0 = org = screen_pos(vc, p, viewed);
                        col = p % maxcol;
                        p += maxcol - col;
 
@@ -365,11 +367,11 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
                                unsigned char c = *con_buf0++;
 
                                this_round--;
-                               vcs_scr_writew(currcons,
-                                              (vcs_scr_readw(currcons, org) & 0xff00) | c, org);
+                               vcs_scr_writew(vc,
+                                              (vcs_scr_readw(vc, org) & 0xff00) | c, org);
                                org++;
                                if (++col == maxcol) {
-                                       org = screen_pos(currcons, p, viewed);
+                                       org = screen_pos(vc, p, viewed);
                                        col = 0;
                                        p += maxcol;
                                }
@@ -378,34 +380,34 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
                        if (p < HEADER_SIZE) {
                                char header[HEADER_SIZE];
 
-                               getconsxy(currcons, header + 2);
+                               getconsxy(vc, header + 2);
                                while (p < HEADER_SIZE && this_round > 0) {
                                        this_round--;
                                        header[p++] = *con_buf0++;
                                }
                                if (!viewed)
-                                       putconsxy(currcons, header + 2);
+                                       putconsxy(vc, header + 2);
                        }
                        p -= HEADER_SIZE;
                        col = (p/2) % maxcol;
                        if (this_round > 0) {
-                               org0 = org = screen_pos(currcons, p/2, viewed);
+                               org0 = org = screen_pos(vc, p/2, viewed);
                                if ((p & 1) && this_round > 0) {
                                        char c;
 
                                        this_round--;
                                        c = *con_buf0++;
 #ifdef __BIG_ENDIAN
-                                       vcs_scr_writew(currcons, c |
-                                            (vcs_scr_readw(currcons, org) & 0xff00), org);
+                                       vcs_scr_writew(vc, c |
+                                            (vcs_scr_readw(vc, org) & 0xff00), org);
 #else
-                                       vcs_scr_writew(currcons, (c << 8) |
-                                            (vcs_scr_readw(currcons, org) & 0xff), org);
+                                       vcs_scr_writew(vc, (c << 8) |
+                                            (vcs_scr_readw(vc, org) & 0xff), org);
 #endif
                                        org++;
                                        p++;
                                        if (++col == maxcol) {
-                                               org = screen_pos(currcons, p/2, viewed);
+                                               org = screen_pos(vc, p/2, viewed);
                                                col = 0;
                                        }
                                }
@@ -415,12 +417,12 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
                        while (this_round > 1) {
                                unsigned short w;
 
-                               w = get_unaligned(((const unsigned short *)con_buf0));
-                               vcs_scr_writew(currcons, w, org++);
+                               w = get_unaligned(((unsigned short *)con_buf0));
+                               vcs_scr_writew(vc, w, org++);
                                con_buf0 += 2;
                                this_round -= 2;
                                if (++col == maxcol) {
-                                       org = screen_pos(currcons, p, viewed);
+                                       org = screen_pos(vc, p, viewed);
                                        col = 0;
                                        p += maxcol;
                                }
@@ -430,9 +432,9 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 
                                c = *con_buf0++;
 #ifdef __BIG_ENDIAN
-                               vcs_scr_writew(currcons, (vcs_scr_readw(currcons, org) & 0xff) | (c << 8), org);
+                               vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org);
 #else
-                               vcs_scr_writew(currcons, (vcs_scr_readw(currcons, org) & 0xff00) | c, org);
+                               vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org);
 #endif
                        }
                }
@@ -441,7 +443,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
                buf += orig_count;
                pos += orig_count;
                if (org0)
-                       update_region(currcons, (unsigned long)(org0), org-org0);
+                       update_region(vc, (unsigned long)(org0), org - org0);
        }
        *ppos += written;
        ret = written;
@@ -463,43 +465,36 @@ vcs_open(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static struct file_operations vcs_fops = {
+static const struct file_operations vcs_fops = {
        .llseek         = vcs_lseek,
        .read           = vcs_read,
        .write          = vcs_write,
        .open           = vcs_open,
 };
 
-static struct class_simple *vc_class;
+static struct class *vc_class;
 
-void vcs_make_devfs(struct tty_struct *tty)
+void vcs_make_sysfs(struct tty_struct *tty)
 {
-       devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 1),
-                       S_IFCHR|S_IRUSR|S_IWUSR,
-                       "vcc/%u", tty->index + 1);
-       devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129),
-                       S_IFCHR|S_IRUSR|S_IWUSR,
-                       "vcc/a%u", tty->index + 1);
-       class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1);
-       class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1);
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
+                       "vcs%u", tty->index + 1);
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
+                       "vcsa%u", tty->index + 1);
 }
-void vcs_remove_devfs(struct tty_struct *tty)
+
+void vcs_remove_sysfs(struct tty_struct *tty)
 {
-       devfs_remove("vcc/%u", tty->index + 1);
-       devfs_remove("vcc/a%u", tty->index + 1);
-       class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 1));
-       class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 129));
+       device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
+       device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
 }
 
 int __init vcs_init(void)
 {
        if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
                panic("unable to get major %d for vcs device", VCS_MAJOR);
-       vc_class = class_simple_create(THIS_MODULE, "vc");
+       vc_class = class_create(THIS_MODULE, "vc");
 
-       devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0");
-       devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0");
-       class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
-       class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), "vcs");
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), "vcsa");
        return 0;
 }