This commit was generated by cvs2svn to compensate for changes in r1129,
[linux-2.6.git] / drivers / s390 / net / ctctty.c
index 52d1da3..5cdcdbf 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: ctctty.c,v 1.21 2004/07/02 16:31:22 ptiedem Exp $
- *
  * CTC / ESCON network driver, tty interface.
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/serial_reg.h>
 #include <linux/interrupt.h>
+#include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <linux/devfs_fs_kernel.h>
 #include "ctctty.h"
@@ -100,25 +100,17 @@ static spinlock_t ctc_tty_lock;
 static int
 ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb)
 {
-       int c;
        int len;
        struct tty_struct *tty;
 
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 5, __FUNCTION__);
        if ((tty = info->tty)) {
                if (info->mcr & UART_MCR_RTS) {
-                       c = TTY_FLIPBUF_SIZE - tty->flip.count;
                        len = skb->len;
-                       if (c >= len) {
-                               memcpy(tty->flip.char_buf_ptr, skb->data, len);
-                               memset(tty->flip.flag_buf_ptr, 0, len);
-                               tty->flip.count += len;
-                               tty->flip.char_buf_ptr += len;
-                               tty->flip.flag_buf_ptr += len;
-                               tty_flip_buffer_push(tty);
-                               kfree_skb(skb);
-                               return 1;
-                       }
+                       tty_insert_flip_string(tty, skb->data, len);
+                       tty_flip_buffer_push(tty);
+                       kfree_skb(skb);
+                       return 1;
                }
        }
        return 0;
@@ -134,28 +126,21 @@ ctc_tty_readmodem(ctc_tty_info *info)
        int ret = 1;
        struct tty_struct *tty;
 
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 5, __FUNCTION__);
        if ((tty = info->tty)) {
                if (info->mcr & UART_MCR_RTS) {
-                       int c = TTY_FLIPBUF_SIZE - tty->flip.count;
                        struct sk_buff *skb;
                        
-                       if ((c > 0) && (skb = skb_dequeue(&info->rx_queue))) {
+                       if ((skb = skb_dequeue(&info->rx_queue))) {
                                int len = skb->len;
-                               if (len > c)
-                                       len = c;
-                               memcpy(tty->flip.char_buf_ptr, skb->data, len);
+                               tty_insert_flip_string(tty, skb->data, len);
                                skb_pull(skb, len);
-                               memset(tty->flip.flag_buf_ptr, 0, len);
-                               tty->flip.count += len;
-                               tty->flip.char_buf_ptr += len;
-                               tty->flip.flag_buf_ptr += len;
                                tty_flip_buffer_push(tty);
                                if (skb->len > 0)
                                        skb_queue_head(&info->rx_queue, skb);
                                else {
                                        kfree_skb(skb);
-                                       ret = skb_queue_len(&info->rx_queue);
+                                       ret = !skb_queue_empty(&info->rx_queue);
                                }
                        }
                }
@@ -168,7 +153,7 @@ ctc_tty_setcarrier(struct net_device *netdev, int on)
 {
        int i;
 
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 4, __FUNCTION__);
        if ((!driver) || ctc_tty_shuttingdown)
                return;
        for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
@@ -189,7 +174,7 @@ ctc_tty_netif_rx(struct sk_buff *skb)
        int i;
        ctc_tty_info *info = NULL;
 
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 5, __FUNCTION__);
        if (!skb)
                return;
        if ((!skb->dev) || (!driver) || ctc_tty_shuttingdown) {
@@ -254,7 +239,7 @@ ctc_tty_tint(ctc_tty_info * info)
        int wake = 1;
        int rc;
 
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 4, __FUNCTION__);
        if (!info->netdev) {
                if (skb)
                        kfree_skb(skb);
@@ -306,10 +291,7 @@ ctc_tty_tint(ctc_tty_info * info)
 
                info->flags &= ~CTC_ASYNC_TX_LINESTAT;
                if (tty) {
-                       if (wake && (tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                           tty->ldisc.write_wakeup)
-                               (tty->ldisc.write_wakeup)(tty);
-                       wake_up_interruptible(&tty->write_wait);
+                       tty_wakeup(tty);
                }
        }
        return (skb_queue_empty(&info->tx_queue) ? 0 : 1);
@@ -347,7 +329,7 @@ ctc_tty_inject(ctc_tty_info *info, char c)
        int skb_res;
        struct sk_buff *skb;
        
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 4, __FUNCTION__);
        if (ctc_tty_shuttingdown)
                return;
        skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
@@ -368,7 +350,7 @@ ctc_tty_inject(ctc_tty_info *info, char c)
 static void
 ctc_tty_transmit_status(ctc_tty_info *info)
 {
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 5, __FUNCTION__);
        if (ctc_tty_shuttingdown)
                return;
        info->flags |= CTC_ASYNC_TX_LINESTAT;
@@ -382,7 +364,7 @@ ctc_tty_change_speed(ctc_tty_info * info)
        unsigned int quot;
        int i;
 
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 3, __FUNCTION__);
        if (!info->tty || !info->tty->termios)
                return;
        cflag = info->tty->termios->c_cflag;
@@ -421,7 +403,7 @@ ctc_tty_change_speed(ctc_tty_info * info)
 static int
 ctc_tty_startup(ctc_tty_info * info)
 {
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 3, __FUNCTION__);
        if (info->flags & CTC_ASYNC_INITIALIZED)
                return 0;
 #ifdef CTC_DEBUG_MODEM_OPEN
@@ -464,7 +446,7 @@ ctc_tty_stopdev(unsigned long data)
 static void
 ctc_tty_shutdown(ctc_tty_info * info)
 {
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 3, __FUNCTION__);
        if (!(info->flags & CTC_ASYNC_INITIALIZED))
                return;
 #ifdef CTC_DEBUG_MODEM_OPEN
@@ -491,13 +473,13 @@ ctc_tty_shutdown(ctc_tty_info * info)
  *  - If dialing, abort dial.
  */
 static int
-ctc_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int count)
+ctc_tty_write(struct tty_struct *tty, const u_char * buf, int count)
 {
        int c;
        int total = 0;
        ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
 
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 5, __FUNCTION__);
        if (ctc_tty_shuttingdown)
                goto ex;
        if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write"))
@@ -508,8 +490,6 @@ ctc_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int cou
                total = -ENODEV;
                goto ex;
        }
-       if (from_user)
-               down(&info->write_sem);
        while (1) {
                struct sk_buff *skb;
                int skb_res;
@@ -528,22 +508,16 @@ ctc_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int cou
                        break;
                }
                skb_reserve(skb, skb_res);
-               if (from_user)
-                       copy_from_user(skb_put(skb, c),
-                                       (const u_char __user *)buf, c);
-               else
-                       memcpy(skb_put(skb, c), buf, c);
+               memcpy(skb_put(skb, c), buf, c);
                skb_queue_tail(&info->tx_queue, skb);
                buf += c;
                total += c;
                count -= c;
        }
-       if (skb_queue_len(&info->tx_queue)) {
+       if (!skb_queue_empty(&info->tx_queue)) {
                info->lsr &= ~UART_LSR_TEMT;
                tasklet_schedule(&info->tasklet);
        }
-       if (from_user)
-               up(&info->write_sem);
 ex:
        DBF_TEXT(trace, 6, __FUNCTION__);
        return total;
@@ -575,7 +549,7 @@ ctc_tty_flush_buffer(struct tty_struct *tty)
        ctc_tty_info *info;
        unsigned long flags;
 
-       DBF_TEXT(trace, 2, __FUNCTION__);
+       DBF_TEXT(trace, 4, __FUNCTION__);
        if (!tty)
                goto ex;
        spin_lock_irqsave(&ctc_tty_lock, flags);
@@ -588,9 +562,7 @@ ctc_tty_flush_buffer(struct tty_struct *tty)
        info->lsr |= UART_LSR_TEMT;
        spin_unlock_irqrestore(&ctc_tty_lock, 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);
 ex:
        DBF_TEXT_(trace, 2, "ex: %s ", __FUNCTION__);
        return;
@@ -601,11 +573,12 @@ ctc_tty_flush_chars(struct tty_struct *tty)
 {
        ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
 
+       DBF_TEXT(trace, 4, __FUNCTION__);
        if (ctc_tty_shuttingdown)
                return;
        if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_chars"))
                return;
-       if (tty->stopped || tty->hw_stopped || (!skb_queue_len(&info->tx_queue)))
+       if (tty->stopped || tty->hw_stopped || skb_queue_empty(&info->tx_queue))
                return;
        tasklet_schedule(&info->tasklet);
 }
@@ -623,6 +596,7 @@ ctc_tty_throttle(struct tty_struct *tty)
 {
        ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
 
+       DBF_TEXT(trace, 4, __FUNCTION__);
        if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_throttle"))
                return;
        info->mcr &= ~UART_MCR_RTS;
@@ -636,6 +610,7 @@ ctc_tty_unthrottle(struct tty_struct *tty)
 {
        ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
 
+       DBF_TEXT(trace, 4, __FUNCTION__);
        if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_unthrottle"))
                return;
        info->mcr |= UART_MCR_RTS;
@@ -667,6 +642,7 @@ ctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value)
        uint result;
        ulong flags;
 
+       DBF_TEXT(trace, 4, __FUNCTION__);
        spin_lock_irqsave(&ctc_tty_lock, flags);
        status = info->lsr;
        spin_unlock_irqrestore(&ctc_tty_lock, flags);
@@ -684,6 +660,7 @@ static int ctc_tty_tiocmget(struct tty_struct *tty, struct file *file)
        uint result;
        ulong flags;
 
+       DBF_TEXT(trace, 4, __FUNCTION__);
        if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
                return -ENODEV;
        if (tty->flags & (1 << TTY_IO_ERROR))
@@ -708,6 +685,7 @@ ctc_tty_tiocmset(struct tty_struct *tty, struct file *file,
 {
        ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
 
+       DBF_TEXT(trace, 4, __FUNCTION__);
        if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
                return -ENODEV;
        if (tty->flags & (1 << TTY_IO_ERROR))
@@ -736,6 +714,7 @@ ctc_tty_ioctl(struct tty_struct *tty, struct file *file,
        int error;
        int retval;
 
+       DBF_TEXT(trace, 4, __FUNCTION__);
        if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
                return -ENODEV;
        if (tty->flags & (1 << TTY_IO_ERROR))
@@ -783,11 +762,10 @@ ctc_tty_ioctl(struct tty_struct *tty, struct file *file,
                        printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME,
                               info->line);
 #endif
-                       error = verify_area(VERIFY_WRITE, (void __user *) arg, sizeof(uint));
-                       if (error)
-                               return error;
-                       else
+                       if (access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(uint)))
                                return ctc_tty_get_lsr_info(info, (uint __user *) arg);
+                       else
+                               return -EFAULT;
                default:
 #ifdef CTC_DEBUG_MODEM_IOCTL
                        printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd,
@@ -803,6 +781,8 @@ ctc_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
 {
        ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
        unsigned int cflag = tty->termios->c_cflag;
+
+       DBF_TEXT(trace, 4, __FUNCTION__);
        ctc_tty_change_speed(info);
 
        /* Handle transition to B0 */
@@ -840,6 +820,7 @@ ctc_tty_block_til_ready(struct tty_struct *tty, struct file *filp, ctc_tty_info
        unsigned long flags;
        int retval;
 
+       DBF_TEXT(trace, 4, __FUNCTION__);
        /*
         * If the device is in the middle of being closed, then block
         * until it's done, and then try again.
@@ -944,6 +925,7 @@ ctc_tty_open(struct tty_struct *tty, struct file *filp)
        int retval,
         line;
 
+       DBF_TEXT(trace, 3, __FUNCTION__);
        line = tty->index;
        if (line < 0 || line > CTC_TTY_MAX_DEVICES)
                return -ENODEV;
@@ -990,7 +972,7 @@ ctc_tty_close(struct tty_struct *tty, struct file *filp)
        ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
        ulong flags;
        ulong timeout;
-
+       DBF_TEXT(trace, 3, __FUNCTION__);
        if (!info || ctc_tty_paranoia_check(info, tty->name, "ctc_tty_close"))
                return;
        spin_lock_irqsave(&ctc_tty_lock, flags);
@@ -1042,9 +1024,8 @@ ctc_tty_close(struct tty_struct *tty, struct file *filp)
                 */
                timeout = jiffies + HZ;
                while (!(info->lsr & UART_LSR_TEMT)) {
-                       set_current_state(TASK_INTERRUPTIBLE);
                        spin_unlock_irqrestore(&ctc_tty_lock, flags);
-                       schedule_timeout(HZ/2);
+                       msleep(500);
                        spin_lock_irqsave(&ctc_tty_lock, flags);
                        if (time_after(jiffies,timeout))
                                break;
@@ -1055,13 +1036,11 @@ ctc_tty_close(struct tty_struct *tty, struct file *filp)
                skb_queue_purge(&info->tx_queue);
                info->lsr |= UART_LSR_TEMT;
        }
-       if (tty->ldisc.flush_buffer)
-               tty->ldisc.flush_buffer(tty);
+       tty_ldisc_flush(tty);
        info->tty = 0;
        tty->closing = 0;
        if (info->blocked_open) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(HZ/2);
+               msleep_interruptible(500);
                wake_up_interruptible(&info->open_wait);
        }
        info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING);
@@ -1080,6 +1059,7 @@ ctc_tty_hangup(struct tty_struct *tty)
 {
        ctc_tty_info *info = (ctc_tty_info *)tty->driver_data;
        unsigned long saveflags;
+       DBF_TEXT(trace, 3, __FUNCTION__);
        if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_hangup"))
                return;
        ctc_tty_shutdown(info);
@@ -1103,6 +1083,7 @@ ctc_tty_task(unsigned long arg)
        unsigned long saveflags;
        int again;
 
+       DBF_TEXT(trace, 3, __FUNCTION__);
        spin_lock_irqsave(&ctc_tty_lock, saveflags);
        if ((!ctc_tty_shuttingdown) && info) {
                again = ctc_tty_tint(info);
@@ -1140,6 +1121,7 @@ ctc_tty_init(void)
        ctc_tty_info *info;
        struct tty_driver *device;
 
+       DBF_TEXT(trace, 2, __FUNCTION__);
        driver = kmalloc(sizeof(ctc_tty_driver), GFP_KERNEL);
        if (driver == NULL) {
                printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
@@ -1199,6 +1181,7 @@ ctc_tty_register_netdev(struct net_device *dev) {
        char *err;
        char *p;
 
+       DBF_TEXT(trace, 2, __FUNCTION__);
        if ((!dev) || (!dev->name)) {
                printk(KERN_WARNING
                       "ctc_tty_register_netdev called "
@@ -1246,6 +1229,7 @@ ctc_tty_unregister_netdev(struct net_device *dev) {
        unsigned long saveflags;
        ctc_tty_info *info = NULL;
 
+       DBF_TEXT(trace, 2, __FUNCTION__);
        spin_lock_irqsave(&ctc_tty_lock, saveflags);
        for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
                if (driver->info[i].netdev == dev) {
@@ -1264,6 +1248,7 @@ void
 ctc_tty_cleanup(void) {
        unsigned long saveflags;
        
+       DBF_TEXT(trace, 2, __FUNCTION__);
        spin_lock_irqsave(&ctc_tty_lock, saveflags);
        ctc_tty_shuttingdown = 1;
        spin_unlock_irqrestore(&ctc_tty_lock, saveflags);