* 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