This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / char / riscom8.c
index 55a3a01..a35ea03 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/fcntl.h>
 #include <linux/major.h>
 #include <linux/init.h>
-#include <linux/delay.h>
 
 #include <asm/uaccess.h>
 
@@ -1115,7 +1114,8 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
                 */
                timeout = jiffies+HZ;
                while(port->IER & IER_TXEMPTY)  {
-                       msleep_interruptible(jiffies_to_msecs(port->timeout));
+                       current->state = TASK_INTERRUPTIBLE;
+                       schedule_timeout(port->timeout);
                        if (time_after(jiffies, timeout))
                                break;
                }
@@ -1130,7 +1130,8 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
        port->tty = NULL;
        if (port->blocked_open) {
                if (port->close_delay) {
-                       msleep_interruptible(jiffies_to_msecs(port->close_delay));
+                       current->state = TASK_INTERRUPTIBLE;
+                       schedule_timeout(port->close_delay);
                }
                wake_up_interruptible(&port->open_wait);
        }
@@ -1139,7 +1140,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
 out:   restore_flags(flags);
 }
 
-static int rc_write(struct tty_struct * tty, 
+static int rc_write(struct tty_struct * tty, int from_user, 
                    const unsigned char *buf, int count)
 {
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
@@ -1156,23 +1157,54 @@ static int rc_write(struct tty_struct * tty,
                return 0;
 
        save_flags(flags);
-       while (1) {
-               cli();          
-               c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
-                                         SERIAL_XMIT_SIZE - port->xmit_head));
-               if (c <= 0) {
+       if (from_user) {
+               down(&tmp_buf_sem);
+               while (1) {
+                       cli();          
+                       c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+                                                 SERIAL_XMIT_SIZE - port->xmit_head));
+                       if (c <= 0)
+                               break;
+
+                       c -= copy_from_user(tmp_buf, buf, c);
+                       if (!c) {
+                               if (!total)
+                                       total = -EFAULT;
+                               break;
+                       }
+
+                       cli();
+                       c = min_t(int, c, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+                                        SERIAL_XMIT_SIZE - port->xmit_head));
+                       memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c);
+                       port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+                       port->xmit_cnt += c;
                        restore_flags(flags);
-                       break;
+
+                       buf += c;
+                       count -= c;
+                       total += c;
                }
+               up(&tmp_buf_sem);
+       } else {
+               while (1) {
+                       cli();          
+                       c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+                                                 SERIAL_XMIT_SIZE - port->xmit_head));
+                       if (c <= 0) {
+                               restore_flags(flags);
+                               break;
+                       }
 
-               memcpy(port->xmit_buf + port->xmit_head, buf, c);
-               port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
-               port->xmit_cnt += c;
-               restore_flags(flags);
+                       memcpy(port->xmit_buf + port->xmit_head, buf, c);
+                       port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+                       port->xmit_cnt += c;
+                       restore_flags(flags);
 
-               buf += c;
-               count -= c;
-               total += c;
+                       buf += c;
+                       count -= c;
+                       total += c;
+               }
        }
 
        cli();