This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / s390 / char / sclp_vt220.c
index 69aed79..cc143fa 100644 (file)
@@ -473,9 +473,33 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule,
  * number of characters actually accepted for writing.
  */
 static int
-sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count)
+sclp_vt220_write(struct tty_struct *tty, int from_user,
+                const unsigned char *buf, int count)
 {
-       return __sclp_vt220_write(buf, count, 1, 0);
+       int length;
+       int ret;
+
+       if (!from_user)
+               return __sclp_vt220_write(buf, count, 1, 0);
+       /* Use intermediate buffer to prevent calling copy_from_user() while
+        * holding a lock. */
+       ret = 0;
+       while (count > 0) {
+               length = count < SCLP_VT220_BUF_SIZE ?
+                        count : SCLP_VT220_BUF_SIZE;
+               length -= copy_from_user(tty->driver_data,
+                               (const unsigned char __user *)buf, length);
+               if (length == 0) {
+                       if (!ret)
+                               return -EFAULT;
+                       break;
+               }
+               length = __sclp_vt220_write(tty->driver_data, length, 1, 0);
+               buf += length;
+               count -= length;
+               ret += length;
+       }
+       return ret;
 }
 
 #define SCLP_VT220_SESSION_ENDED       0x01