X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fs390%2Fnet%2Fctctty.c;h=5cdcdbf92962ee89e8be5534ed5d5152f7a5a9a3;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=52d1da3cd697709bf5ecefe3f0354703f11fcef3;hpb=70790a4b5cd6c0291e5b1a2836e2832d46036ac6;p=linux-2.6.git diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c index 52d1da3cd..5cdcdbf92 100644 --- a/drivers/s390/net/ctctty.c +++ b/drivers/s390/net/ctctty.c @@ -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 @@ -25,8 +23,10 @@ #include #include #include +#include #include #include +#include #include #include #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);