Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / drivers / char / riscom8.c
index c4b51d3..657c0d8 100644 (file)
@@ -45,6 +45,8 @@
 #include <linux/fcntl.h>
 #include <linux/major.h>
 #include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/tty_flip.h>
 
 #include <asm/uaccess.h>
 
         ASYNC_SPD_HI       | ASYNC_SPEED_VHI    | ASYNC_SESSION_LOCKOUT | \
         ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
 
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
 #define RS_EVENT_WRITE_WAKEUP  0
 
 static struct riscom_board * IRQ_to_board[16];
 static struct tty_driver *riscom_driver;
 static unsigned char * tmp_buf;
-static DECLARE_MUTEX(tmp_buf_sem);
 
 static unsigned long baud_table[] =  {
        0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
@@ -107,18 +104,18 @@ static struct riscom_board rc_board[RC_NBOARD] =  {
 };
 
 static struct riscom_port rc_port[RC_NBOARD * RC_NPORT];
-               
+
 /* RISCom/8 I/O ports addresses (without address translation) */
 static unsigned short rc_ioport[] =  {
-#if 1  
+#if 1
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c,
-#else  
+#else
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10,
        0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62,
        0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101
-#endif 
+#endif
 };
-#define RC_NIOPORT     (sizeof(rc_ioport) / sizeof(rc_ioport[0]))
+#define RC_NIOPORT     ARRAY_SIZE(rc_ioport)
 
 
 static inline int rc_paranoia_check(struct riscom_port const * port,
@@ -357,28 +354,17 @@ static inline void rc_receive_exc(struct riscom_board const * bp)
        struct riscom_port *port;
        struct tty_struct *tty;
        unsigned char status;
-       unsigned char ch;
+       unsigned char ch, flag;
        
        if (!(port = rc_get_port(bp, "Receive")))
                return;
 
        tty = port->tty;
-       if (tty->flip.count >= TTY_FLIPBUF_SIZE)  {
-               printk(KERN_WARNING "rc%d: port %d: Working around flip "
-                                   "buffer overflow.\n",
-                      board_No(bp), port_No(port));
-               return;
-       }
        
 #ifdef RC_REPORT_OVERRUN       
        status = rc_in(bp, CD180_RCSR);
-       if (status & RCSR_OE)  {
+       if (status & RCSR_OE)
                port->overrun++;
-#if 0          
-               printk(KERN_ERR "rc%d: port %d: Overrun. Total %ld overruns\n", 
-                      board_No(bp), port_No(port), port->overrun);
-#endif         
-       }
        status &= port->mark_mask;
 #else  
        status = rc_in(bp, CD180_RCSR) & port->mark_mask;
@@ -396,25 +382,24 @@ static inline void rc_receive_exc(struct riscom_board const * bp)
        } else if (status & RCSR_BREAK)  {
                printk(KERN_INFO "rc%d: port %d: Handling break...\n",
                       board_No(bp), port_No(port));
-               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
+               flag = TTY_BREAK;
                if (port->flags & ASYNC_SAK)
                        do_SAK(tty);
                
        } else if (status & RCSR_PE) 
-               *tty->flip.flag_buf_ptr++ = TTY_PARITY;
+               flag = TTY_PARITY;
        
        else if (status & RCSR_FE) 
-               *tty->flip.flag_buf_ptr++ = TTY_FRAME;
+               flag = TTY_FRAME;
        
         else if (status & RCSR_OE)
-               *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+               flag = TTY_OVERRUN;
        
        else
-               *tty->flip.flag_buf_ptr++ = 0;
+               flag = TTY_NORMAL;
        
-       *tty->flip.char_buf_ptr++ = ch;
-       tty->flip.count++;
-       schedule_delayed_work(&tty->flip.work, 1);
+       tty_insert_flip_char(tty, ch, flag);
+       tty_flip_buffer_push(tty);
 }
 
 static inline void rc_receive(struct riscom_board const * bp)
@@ -435,17 +420,15 @@ static inline void rc_receive(struct riscom_board const * bp)
 #endif 
        
        while (count--)  {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)  {
+               if (tty_buffer_request_room(tty, 1) == 0)  {
                        printk(KERN_WARNING "rc%d: port %d: Working around "
                                            "flip buffer overflow.\n",
                               board_No(bp), port_No(port));
                        break;
                }
-               *tty->flip.char_buf_ptr++ = rc_in(bp, CD180_RDR);
-               *tty->flip.flag_buf_ptr++ = 0;
-               tty->flip.count++;
+               tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL);
        }
-       schedule_delayed_work(&tty->flip.work, 1);
+       tty_flip_buffer_push(tty);
 }
 
 static inline void rc_transmit(struct riscom_board const * bp)
@@ -483,7 +466,7 @@ static inline void rc_transmit(struct riscom_board const * bp)
                                rc_out(bp, CD180_TDR, CD180_C_SBRK);
                                port->COR2 &= ~COR2_ETC;
                        }
-                       count = MIN(port->break_length, 0xff);
+                       count = min_t(int, port->break_length, 0xff);
                        rc_out(bp, CD180_TDR, CD180_C_ESC);
                        rc_out(bp, CD180_TDR, CD180_C_DELAY);
                        rc_out(bp, CD180_TDR, count);
@@ -1118,8 +1101,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
                 */
                timeout = jiffies+HZ;
                while(port->IER & IER_TXEMPTY)  {
-                       current->state = TASK_INTERRUPTIBLE;
-                       schedule_timeout(port->timeout);
+                       msleep_interruptible(jiffies_to_msecs(port->timeout));
                        if (time_after(jiffies, timeout))
                                break;
                }
@@ -1127,15 +1109,14 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
        rc_shutdown_port(bp, port);
        if (tty->driver->flush_buffer)
                tty->driver->flush_buffer(tty);
-       if (tty->ldisc.flush_buffer)
-               tty->ldisc.flush_buffer(tty);
+       tty_ldisc_flush(tty);
+
        tty->closing = 0;
        port->event = 0;
-       port->tty = 0;
+       port->tty = NULL;
        if (port->blocked_open) {
                if (port->close_delay) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       schedule_timeout(port->close_delay);
+                       msleep_interruptible(jiffies_to_msecs(port->close_delay));
                }
                wake_up_interruptible(&port->open_wait);
        }
@@ -1144,7 +1125,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
 out:   restore_flags(flags);
 }
 
-static int rc_write(struct tty_struct * tty, int from_user, 
+static int rc_write(struct tty_struct * tty, 
                    const unsigned char *buf, int count)
 {
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
@@ -1161,54 +1142,23 @@ static int rc_write(struct tty_struct * tty, int from_user,
                return 0;
 
        save_flags(flags);
-       if (from_user) {
-               down(&tmp_buf_sem);
-               while (1) {
-                       cli();          
-                       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;
+       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);
-
-                       buf += c;
-                       count -= c;
-                       total += c;
+                       break;
                }
-               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);
+               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();
@@ -1301,9 +1251,7 @@ static void rc_flush_buffer(struct tty_struct *tty)
        restore_flags(flags);
        
        wake_up_interruptible(&tty->write_wait);
-       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-           tty->ldisc.write_wakeup)
-               (tty->ldisc.write_wakeup)(tty);
+       tty_wakeup(tty);
 }
 
 static int rc_tiocmget(struct tty_struct *tty, struct file *file)
@@ -1380,7 +1328,7 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length
 }
 
 static inline int rc_set_serial_info(struct riscom_port * port,
-                                    struct serial_struct * newinfo)
+                                    struct serial_struct __user * newinfo)
 {
        struct serial_struct tmp;
        struct riscom_board *bp = port_Board(port);
@@ -1427,7 +1375,7 @@ static inline int rc_set_serial_info(struct riscom_port * port,
 }
 
 static inline int rc_get_serial_info(struct riscom_port * port,
-                                    struct serial_struct retinfo)
+                                    struct serial_struct __user *retinfo)
 {
        struct serial_struct tmp;
        struct riscom_board *bp = port_Board(port);
@@ -1450,6 +1398,7 @@ static int rc_ioctl(struct tty_struct * tty, struct file * filp,
                    
 {
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
+       void __user *argp = (void __user *)arg;
        int retval;
                                
        if (rc_paranoia_check(port, tty->name, "rc_ioctl"))
@@ -1472,18 +1421,18 @@ static int rc_ioctl(struct tty_struct * tty, struct file * filp,
                rc_send_break(port, arg ? arg*(HZ/10) : HZ/4);
                break;
         case TIOCGSOFTCAR:
-               return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned int *) arg);
+               return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned __user *)argp);
         case TIOCSSOFTCAR:
-               if (get_user(arg,(unsigned int *) arg))
+               if (get_user(arg,(unsigned __user *) argp))
                        return -EFAULT;
                tty->termios->c_cflag =
                        ((tty->termios->c_cflag & ~CLOCAL) |
                        (arg ? CLOCAL : 0));
                break;
         case TIOCGSERIAL:      
-               return rc_get_serial_info(port, (struct serial_struct *) arg);
+               return rc_get_serial_info(port, argp);
         case TIOCSSERIAL:      
-               return rc_set_serial_info(port, (struct serial_struct *) arg);
+               return rc_set_serial_info(port, argp);
         default:
                return -ENOIOCTLCMD;
        }
@@ -1607,7 +1556,7 @@ static void rc_hangup(struct tty_struct * tty)
        port->event = 0;
        port->count = 0;
        port->flags &= ~ASYNC_NORMAL_ACTIVE;
-       port->tty = 0;
+       port->tty = NULL;
        wake_up_interruptible(&port->open_wait);
 }
 
@@ -1643,9 +1592,7 @@ static void do_softint(void *private_)
                return;
 
        if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
-               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                   tty->ldisc.write_wakeup)
-                       (tty->ldisc.write_wakeup)(tty);
+               tty_wakeup(tty);
                wake_up_interruptible(&tty->write_wait);
        }
 }
@@ -1796,10 +1743,10 @@ static int iobase;
 static int iobase1;
 static int iobase2;
 static int iobase3;
-MODULE_PARM(iobase, "i");
-MODULE_PARM(iobase1, "i");
-MODULE_PARM(iobase2, "i");
-MODULE_PARM(iobase3, "i");
+module_param(iobase, int, 0);
+module_param(iobase1, int, 0);
+module_param(iobase2, int, 0);
+module_param(iobase3, int, 0);
 
 MODULE_LICENSE("GPL");
 #endif /* MODULE */