This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / sbus / char / aurora.c
index a433252..1ff81be 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/oplib.h>
 #include <asm/system.h>
+#include <asm/bitops.h>
 #include <asm/kdebug.h>
 #include <asm/sbus.h>
 #include <asm/uaccess.h>
@@ -1550,7 +1550,7 @@ static void aurora_close(struct tty_struct * tty, struct file * filp)
 #endif
 }
 
-static int aurora_write(struct tty_struct * tty, 
+static int aurora_write(struct tty_struct * tty, int from_user, 
                        const unsigned char *buf, int count)
 {
        struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
@@ -1573,22 +1573,51 @@ static int aurora_write(struct tty_struct * tty,
                return 0;
 
        save_flags(flags);
-       while (1) {
-               cli();
-               c = MIN(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) {
+                       c = MIN(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(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;
                }
-               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);
+               up(&tmp_buf_sem);
+       } else {
+               while (1) {
+                       cli();
+                       c = MIN(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);
 
-               buf += c;
-               count -= c;
-               total += c;
+                       buf += c;
+                       count -= c;
+                       total += c;
+               }
        }
 
        cli();
@@ -2339,10 +2368,10 @@ int irq  = 0;
 int irq1 = 0;
 int irq2 = 0;
 int irq3 = 0;
-module_param(irq , int, 0);
-module_param(irq1, int, 0);
-module_param(irq2, int, 0);
-module_param(irq3, int, 0);
+MODULE_PARM(irq , "i");
+MODULE_PARM(irq1, "i");
+MODULE_PARM(irq2, "i");
+MODULE_PARM(irq3, "i");
 
 static int __init aurora_init(void) 
 {