- patches.suse/slab-handle-memoryless-nodes-v2a.patch: Refresh.
[linux-flexiantxendom0-3.2.10.git] / drivers / s390 / char / fs3270.c
index 097d384..31c59b0 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/smp_lock.h>
 
+#include <asm/compat.h>
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
 #include <asm/ebcdic.h>
@@ -38,6 +39,8 @@ struct fs3270 {
        size_t rdbuf_size;              /* size of data returned by RDBUF */
 };
 
+static DEFINE_MUTEX(fs3270_mutex);
+
 static void
 fs3270_wake_up(struct raw3270_request *rq, void *data)
 {
@@ -74,7 +77,7 @@ fs3270_do_io(struct raw3270_view *view, struct raw3270_request *rq)
                }
                rc = raw3270_start(view, rq);
                if (rc == 0) {
-                       /* Started sucessfully. Now wait for completion. */
+                       /* Started successfully. Now wait for completion. */
                        wait_event(fp->wait, raw3270_request_final(rq));
                }
        } while (rc == -EACCES);
@@ -320,6 +323,7 @@ fs3270_write(struct file *filp, const char __user *data, size_t count, loff_t *o
 static long
 fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
+       char __user *argp;
        struct fs3270 *fp;
        struct raw3270_iocb iocb;
        int rc;
@@ -327,8 +331,12 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        fp = filp->private_data;
        if (!fp)
                return -ENODEV;
+       if (is_compat_task())
+               argp = compat_ptr(arg);
+       else
+               argp = (char __user *)arg;
        rc = 0;
-       lock_kernel();
+       mutex_lock(&fs3270_mutex);
        switch (cmd) {
        case TUBICMD:
                fp->read_command = arg;
@@ -337,10 +345,10 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                fp->write_command = arg;
                break;
        case TUBGETI:
-               rc = put_user(fp->read_command, (char __user *) arg);
+               rc = put_user(fp->read_command, argp);
                break;
        case TUBGETO:
-               rc = put_user(fp->write_command,(char __user *) arg);
+               rc = put_user(fp->write_command, argp);
                break;
        case TUBGETMOD:
                iocb.model = fp->view.model;
@@ -349,12 +357,11 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                iocb.pf_cnt = 24;
                iocb.re_cnt = 20;
                iocb.map = 0;
-               if (copy_to_user((char __user *) arg, &iocb,
-                                sizeof(struct raw3270_iocb)))
+               if (copy_to_user(argp, &iocb, sizeof(struct raw3270_iocb)))
                        rc = -EFAULT;
                break;
        }
-       unlock_kernel();
+       mutex_unlock(&fs3270_mutex);
        return rc;
 }
 
@@ -437,7 +444,7 @@ fs3270_open(struct inode *inode, struct file *filp)
                minor = tty->index + RAW3270_FIRSTMINOR;
                tty_kref_put(tty);
        }
-       lock_kernel();
+       mutex_lock(&fs3270_mutex);
        /* Check if some other program is already using fullscreen mode. */
        fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
        if (!IS_ERR(fp)) {
@@ -465,7 +472,7 @@ fs3270_open(struct inode *inode, struct file *filp)
        if (IS_ERR(ib)) {
                raw3270_put_view(&fp->view);
                raw3270_del_view(&fp->view);
-               rc = PTR_ERR(fp);
+               rc = PTR_ERR(ib);
                goto out;
        }
        fp->rdbuf = ib;
@@ -478,7 +485,7 @@ fs3270_open(struct inode *inode, struct file *filp)
        }
        filp->private_data = fp;
 out:
-       unlock_kernel();
+       mutex_unlock(&fs3270_mutex);
        return rc;
 }
 
@@ -509,8 +516,8 @@ static const struct file_operations fs3270_fops = {
        .write           = fs3270_write,        /* write */
        .unlocked_ioctl  = fs3270_ioctl,        /* ioctl */
        .compat_ioctl    = fs3270_ioctl,        /* ioctl */
-       .open           = fs3270_open,          /* open */
-       .release        = fs3270_close,         /* release */
+       .open            = fs3270_open,         /* open */
+       .release         = fs3270_close,        /* release */
 };
 
 /*