diff options
Diffstat (limited to 'drivers/tty/synclink_gt.c')
| -rw-r--r-- | drivers/tty/synclink_gt.c | 119 |
1 files changed, 66 insertions, 53 deletions
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 18b48cd3b41..c359a91f734 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -73,7 +73,6 @@ #include <linux/hdlc.h> #include <linux/synclink.h> -#include <asm/system.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/dma.h> @@ -111,7 +110,7 @@ static struct pci_driver pci_driver = { .name = "synclink_gt", .id_table = pci_table, .probe = init_one, - .remove = __devexit_p(remove_one), + .remove = remove_one, }; static bool pci_registered; @@ -318,8 +317,7 @@ struct slgt_info { unsigned char *tx_buf; int tx_count; - char flag_buf[MAX_ASYNC_BUFFER_SIZE]; - char char_buf[MAX_ASYNC_BUFFER_SIZE]; + char *flag_buf; bool drop_rts_on_tx_done; struct _input_signal_events input_signal_events; @@ -654,7 +652,7 @@ static int open(struct tty_struct *tty, struct file *filp) unsigned long flags; line = tty->index; - if ((line < 0) || (line >= slgt_device_count)) { + if (line >= slgt_device_count) { DBGERR(("%s: open with invalid line #%d.\n", driver_name, line)); return -ENODEV; } @@ -676,15 +674,15 @@ static int open(struct tty_struct *tty, struct file *filp) /* If port is closing, signal caller to try again */ if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){ - if (info->port.flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->port.close_wait); + wait_event_interruptible_tty(tty, info->port.close_wait, + !(info->port.flags & ASYNC_CLOSING)); retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); goto cleanup; } mutex_lock(&info->port.mutex); - info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; + info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; spin_lock_irqsave(&info->netlock, flags); if (info->netcount) { @@ -786,8 +784,8 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) /* Handle transition to B0 status */ if (old_termios->c_cflag & CBAUD && - !(tty->termios->c_cflag & CBAUD)) { - info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + !(tty->termios.c_cflag & CBAUD)) { + info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); spin_lock_irqsave(&info->lock,flags); set_signals(info); spin_unlock_irqrestore(&info->lock,flags); @@ -795,9 +793,9 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && - tty->termios->c_cflag & CBAUD) { + tty->termios.c_cflag & CBAUD) { info->signals |= SerialSignal_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || + if (!(tty->termios.c_cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) { info->signals |= SerialSignal_RTS; } @@ -808,7 +806,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) /* Handle turning off CRTSCTS */ if (old_termios->c_cflag & CRTSCTS && - !(tty->termios->c_cflag & CRTSCTS)) { + !(tty->termios.c_cflag & CRTSCTS)) { tty->hw_stopped = 0; tx_release(tty); } @@ -1373,7 +1371,7 @@ static void throttle(struct tty_struct * tty) DBGINFO(("%s throttle\n", info->device_name)); if (I_IXOFF(tty)) send_xchar(tty, STOP_CHAR(tty)); - if (tty->termios->c_cflag & CRTSCTS) { + if (tty->termios.c_cflag & CRTSCTS) { spin_lock_irqsave(&info->lock,flags); info->signals &= ~SerialSignal_RTS; set_signals(info); @@ -1398,7 +1396,7 @@ static void unthrottle(struct tty_struct * tty) else send_xchar(tty, START_CHAR(tty)); } - if (tty->termios->c_cflag & CRTSCTS) { + if (tty->termios.c_cflag & CRTSCTS) { spin_lock_irqsave(&info->lock,flags); info->signals |= SerialSignal_RTS; set_signals(info); @@ -1562,8 +1560,8 @@ static int hdlcdev_open(struct net_device *dev) return rc; } - /* assert DTR and RTS, apply hardware settings */ - info->signals |= SerialSignal_RTS + SerialSignal_DTR; + /* assert RTS and DTR, apply hardware settings */ + info->signals |= SerialSignal_RTS | SerialSignal_DTR; program_hw(info); /* enable network layer transmit */ @@ -1856,7 +1854,6 @@ static void hdlcdev_exit(struct slgt_info *info) */ static void rx_async(struct slgt_info *info) { - struct tty_struct *tty = info->port.tty; struct mgsl_icount *icount = &info->icount; unsigned int start, end; unsigned char *p; @@ -1895,10 +1892,8 @@ static void rx_async(struct slgt_info *info) else if (status & BIT0) stat = TTY_FRAME; } - if (tty) { - tty_insert_flip_char(tty, ch, stat); - chars++; - } + tty_insert_flip_char(&info->port, ch, stat); + chars++; } if (i < count) { @@ -1919,8 +1914,8 @@ static void rx_async(struct slgt_info *info) break; } - if (tty && chars) - tty_flip_buffer_push(tty); + if (chars) + tty_flip_buffer_push(&info->port); } /* @@ -1962,8 +1957,6 @@ static void bh_handler(struct work_struct *work) struct slgt_info *info = container_of(work, struct slgt_info, task); int action; - if (!info) - return; info->bh_running = true; while((action = bh_action(info))) { @@ -2054,7 +2047,7 @@ static void cts_change(struct slgt_info *info, unsigned short status) wake_up_interruptible(&info->event_wait_q); info->pending_bh |= BH_STATUS; - if (info->port.flags & ASYNC_CTS_FLOW) { + if (tty_port_cts_enabled(&info->port)) { if (info->port.tty) { if (info->port.tty->hw_stopped) { if (info->signals & SerialSignal_CTS) { @@ -2184,7 +2177,7 @@ static void isr_serial(struct slgt_info *info) if (info->port.tty) { if (!(status & info->ignore_status_mask)) { if (info->read_status_mask & MASK_BREAK) { - tty_insert_flip_char(info->port.tty, 0, TTY_BREAK); + tty_insert_flip_char(&info->port, 0, TTY_BREAK); if (info->port.flags & ASYNC_SAK) do_SAK(info->port.tty); } @@ -2494,8 +2487,8 @@ static void shutdown(struct slgt_info *info) slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); - if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { - info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); + if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { + info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); set_signals(info); } @@ -2535,7 +2528,7 @@ static void program_hw(struct slgt_info *info) get_signals(info); if (info->netcount || - (info->port.tty && info->port.tty->termios->c_cflag & CREAD)) + (info->port.tty && info->port.tty->termios.c_cflag & CREAD)) rx_start(info); spin_unlock_irqrestore(&info->lock,flags); @@ -2549,18 +2542,18 @@ static void change_params(struct slgt_info *info) unsigned cflag; int bits_per_char; - if (!info->port.tty || !info->port.tty->termios) + if (!info->port.tty) return; DBGINFO(("%s change_params\n", info->device_name)); - cflag = info->port.tty->termios->c_cflag; + cflag = info->port.tty->termios.c_cflag; - /* if B0 rate (hangup) specified then negate DTR and RTS */ - /* otherwise assert DTR and RTS */ + /* if B0 rate (hangup) specified then negate RTS and DTR */ + /* otherwise assert RTS and DTR */ if (cflag & CBAUD) - info->signals |= SerialSignal_RTS + SerialSignal_DTR; + info->signals |= SerialSignal_RTS | SerialSignal_DTR; else - info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); /* byte size and parity */ @@ -3263,9 +3256,9 @@ static void dtr_rts(struct tty_port *port, int on) spin_lock_irqsave(&info->lock,flags); if (on) - info->signals |= SerialSignal_RTS + SerialSignal_DTR; + info->signals |= SerialSignal_RTS | SerialSignal_DTR; else - info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); set_signals(info); spin_unlock_irqrestore(&info->lock,flags); } @@ -3293,7 +3286,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, return 0; } - if (tty->termios->c_cflag & CLOCAL) + if (tty->termios.c_cflag & CLOCAL) do_clocal = true; /* Wait for carrier detect and the line to become @@ -3315,7 +3308,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, port->blocked_open++; while (1) { - if ((tty->termios->c_cflag & CBAUD)) + if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) tty_port_raise_dtr_rts(port); set_current_state(TASK_INTERRUPTIBLE); @@ -3337,9 +3330,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, } DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); - tty_unlock(); + tty_unlock(tty); schedule(); - tty_lock(); + tty_lock(tty); } set_current_state(TASK_RUNNING); @@ -3356,11 +3349,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, return retval; } +/* + * allocate buffers used for calling line discipline receive_buf + * directly in synchronous mode + * note: add 5 bytes to max frame size to allow appending + * 32-bit CRC and status byte when configured to do so + */ static int alloc_tmp_rbuf(struct slgt_info *info) { info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); if (info->tmp_rbuf == NULL) return -ENOMEM; + /* unused flag buffer to satisfy receive_buf calling interface */ + info->flag_buf = kzalloc(info->max_frame_size + 5, GFP_KERNEL); + if (!info->flag_buf) { + kfree(info->tmp_rbuf); + info->tmp_rbuf = NULL; + return -ENOMEM; + } return 0; } @@ -3368,6 +3374,8 @@ static void free_tmp_rbuf(struct slgt_info *info) { kfree(info->tmp_rbuf); info->tmp_rbuf = NULL; + kfree(info->flag_buf); + info->flag_buf = NULL; } /* @@ -3646,8 +3654,10 @@ static void device_init(int adapter_num, struct pci_dev *pdev) for (i=0; i < port_count; ++i) { port_array[i] = alloc_dev(adapter_num, i, pdev); if (port_array[i] == NULL) { - for (--i; i >= 0; --i) + for (--i; i >= 0; --i) { + tty_port_destroy(&port_array[i]->port); kfree(port_array[i]); + } return; } } @@ -3690,11 +3700,14 @@ static void device_init(int adapter_num, struct pci_dev *pdev) } } - for (i=0; i < port_count; ++i) - tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev)); + for (i = 0; i < port_count; ++i) { + struct slgt_info *info = port_array[i]; + tty_port_register_device(&info->port, serial_driver, info->line, + &info->pdev->dev); + } } -static int __devinit init_one(struct pci_dev *dev, +static int init_one(struct pci_dev *dev, const struct pci_device_id *ent) { if (pci_enable_device(dev)) { @@ -3706,7 +3719,7 @@ static int __devinit init_one(struct pci_dev *dev, return 0; } -static void __devexit remove_one(struct pci_dev *dev) +static void remove_one(struct pci_dev *dev) { } @@ -3771,6 +3784,7 @@ static void slgt_cleanup(void) release_resources(info); tmp = info; info = info->next_device; + tty_port_destroy(&tmp->port); kfree(tmp); } @@ -3795,7 +3809,6 @@ static int __init slgt_init(void) /* Initialize the tty_driver structure */ - serial_driver->owner = THIS_MODULE; serial_driver->driver_name = tty_driver_name; serial_driver->name = tty_dev_prefix; serial_driver->major = ttymajor; @@ -3924,7 +3937,7 @@ static void tdma_reset(struct slgt_info *info) */ static void enable_loopback(struct slgt_info *info) { - /* SCR (serial control) BIT2=looopback enable */ + /* SCR (serial control) BIT2=loopback enable */ wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT2)); if (info->params.mode != MGSL_MODE_ASYNC) { @@ -4106,7 +4119,7 @@ static void reset_port(struct slgt_info *info) tx_stop(info); rx_stop(info); - info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); + info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); set_signals(info); slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); @@ -4533,8 +4546,8 @@ static void get_signals(struct slgt_info *info) { unsigned short status = rd_reg16(info, SSR); - /* clear all serial signals except DTR and RTS */ - info->signals &= SerialSignal_DTR + SerialSignal_RTS; + /* clear all serial signals except RTS and DTR */ + info->signals &= SerialSignal_RTS | SerialSignal_DTR; if (status & BIT3) info->signals |= SerialSignal_DSR; |
