diff options
Diffstat (limited to 'drivers/tty/synclink_gt.c')
-rw-r--r-- | drivers/tty/synclink_gt.c | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index aba1e59f4a88..aa9eece35c3b 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
@@ -317,8 +317,7 @@ struct slgt_info { | |||
317 | unsigned char *tx_buf; | 317 | unsigned char *tx_buf; |
318 | int tx_count; | 318 | int tx_count; |
319 | 319 | ||
320 | char flag_buf[MAX_ASYNC_BUFFER_SIZE]; | 320 | char *flag_buf; |
321 | char char_buf[MAX_ASYNC_BUFFER_SIZE]; | ||
322 | bool drop_rts_on_tx_done; | 321 | bool drop_rts_on_tx_done; |
323 | struct _input_signal_events input_signal_events; | 322 | struct _input_signal_events input_signal_events; |
324 | 323 | ||
@@ -683,7 +682,7 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
683 | } | 682 | } |
684 | 683 | ||
685 | mutex_lock(&info->port.mutex); | 684 | mutex_lock(&info->port.mutex); |
686 | info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 685 | info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
687 | 686 | ||
688 | spin_lock_irqsave(&info->netlock, flags); | 687 | spin_lock_irqsave(&info->netlock, flags); |
689 | if (info->netcount) { | 688 | if (info->netcount) { |
@@ -786,7 +785,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
786 | /* Handle transition to B0 status */ | 785 | /* Handle transition to B0 status */ |
787 | if (old_termios->c_cflag & CBAUD && | 786 | if (old_termios->c_cflag & CBAUD && |
788 | !(tty->termios.c_cflag & CBAUD)) { | 787 | !(tty->termios.c_cflag & CBAUD)) { |
789 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 788 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
790 | spin_lock_irqsave(&info->lock,flags); | 789 | spin_lock_irqsave(&info->lock,flags); |
791 | set_signals(info); | 790 | set_signals(info); |
792 | spin_unlock_irqrestore(&info->lock,flags); | 791 | spin_unlock_irqrestore(&info->lock,flags); |
@@ -1561,8 +1560,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
1561 | return rc; | 1560 | return rc; |
1562 | } | 1561 | } |
1563 | 1562 | ||
1564 | /* assert DTR and RTS, apply hardware settings */ | 1563 | /* assert RTS and DTR, apply hardware settings */ |
1565 | info->signals |= SerialSignal_RTS + SerialSignal_DTR; | 1564 | info->signals |= SerialSignal_RTS | SerialSignal_DTR; |
1566 | program_hw(info); | 1565 | program_hw(info); |
1567 | 1566 | ||
1568 | /* enable network layer transmit */ | 1567 | /* enable network layer transmit */ |
@@ -1855,7 +1854,6 @@ static void hdlcdev_exit(struct slgt_info *info) | |||
1855 | */ | 1854 | */ |
1856 | static void rx_async(struct slgt_info *info) | 1855 | static void rx_async(struct slgt_info *info) |
1857 | { | 1856 | { |
1858 | struct tty_struct *tty = info->port.tty; | ||
1859 | struct mgsl_icount *icount = &info->icount; | 1857 | struct mgsl_icount *icount = &info->icount; |
1860 | unsigned int start, end; | 1858 | unsigned int start, end; |
1861 | unsigned char *p; | 1859 | unsigned char *p; |
@@ -1894,10 +1892,8 @@ static void rx_async(struct slgt_info *info) | |||
1894 | else if (status & BIT0) | 1892 | else if (status & BIT0) |
1895 | stat = TTY_FRAME; | 1893 | stat = TTY_FRAME; |
1896 | } | 1894 | } |
1897 | if (tty) { | 1895 | tty_insert_flip_char(&info->port, ch, stat); |
1898 | tty_insert_flip_char(tty, ch, stat); | 1896 | chars++; |
1899 | chars++; | ||
1900 | } | ||
1901 | } | 1897 | } |
1902 | 1898 | ||
1903 | if (i < count) { | 1899 | if (i < count) { |
@@ -1918,8 +1914,8 @@ static void rx_async(struct slgt_info *info) | |||
1918 | break; | 1914 | break; |
1919 | } | 1915 | } |
1920 | 1916 | ||
1921 | if (tty && chars) | 1917 | if (chars) |
1922 | tty_flip_buffer_push(tty); | 1918 | tty_flip_buffer_push(&info->port); |
1923 | } | 1919 | } |
1924 | 1920 | ||
1925 | /* | 1921 | /* |
@@ -1961,8 +1957,6 @@ static void bh_handler(struct work_struct *work) | |||
1961 | struct slgt_info *info = container_of(work, struct slgt_info, task); | 1957 | struct slgt_info *info = container_of(work, struct slgt_info, task); |
1962 | int action; | 1958 | int action; |
1963 | 1959 | ||
1964 | if (!info) | ||
1965 | return; | ||
1966 | info->bh_running = true; | 1960 | info->bh_running = true; |
1967 | 1961 | ||
1968 | while((action = bh_action(info))) { | 1962 | while((action = bh_action(info))) { |
@@ -2183,7 +2177,7 @@ static void isr_serial(struct slgt_info *info) | |||
2183 | if (info->port.tty) { | 2177 | if (info->port.tty) { |
2184 | if (!(status & info->ignore_status_mask)) { | 2178 | if (!(status & info->ignore_status_mask)) { |
2185 | if (info->read_status_mask & MASK_BREAK) { | 2179 | if (info->read_status_mask & MASK_BREAK) { |
2186 | tty_insert_flip_char(info->port.tty, 0, TTY_BREAK); | 2180 | tty_insert_flip_char(&info->port, 0, TTY_BREAK); |
2187 | if (info->port.flags & ASYNC_SAK) | 2181 | if (info->port.flags & ASYNC_SAK) |
2188 | do_SAK(info->port.tty); | 2182 | do_SAK(info->port.tty); |
2189 | } | 2183 | } |
@@ -2494,7 +2488,7 @@ static void shutdown(struct slgt_info *info) | |||
2494 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); | 2488 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); |
2495 | 2489 | ||
2496 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { | 2490 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
2497 | info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 2491 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2498 | set_signals(info); | 2492 | set_signals(info); |
2499 | } | 2493 | } |
2500 | 2494 | ||
@@ -2554,12 +2548,12 @@ static void change_params(struct slgt_info *info) | |||
2554 | 2548 | ||
2555 | cflag = info->port.tty->termios.c_cflag; | 2549 | cflag = info->port.tty->termios.c_cflag; |
2556 | 2550 | ||
2557 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 2551 | /* if B0 rate (hangup) specified then negate RTS and DTR */ |
2558 | /* otherwise assert DTR and RTS */ | 2552 | /* otherwise assert RTS and DTR */ |
2559 | if (cflag & CBAUD) | 2553 | if (cflag & CBAUD) |
2560 | info->signals |= SerialSignal_RTS + SerialSignal_DTR; | 2554 | info->signals |= SerialSignal_RTS | SerialSignal_DTR; |
2561 | else | 2555 | else |
2562 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 2556 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2563 | 2557 | ||
2564 | /* byte size and parity */ | 2558 | /* byte size and parity */ |
2565 | 2559 | ||
@@ -3262,9 +3256,9 @@ static void dtr_rts(struct tty_port *port, int on) | |||
3262 | 3256 | ||
3263 | spin_lock_irqsave(&info->lock,flags); | 3257 | spin_lock_irqsave(&info->lock,flags); |
3264 | if (on) | 3258 | if (on) |
3265 | info->signals |= SerialSignal_RTS + SerialSignal_DTR; | 3259 | info->signals |= SerialSignal_RTS | SerialSignal_DTR; |
3266 | else | 3260 | else |
3267 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3261 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
3268 | set_signals(info); | 3262 | set_signals(info); |
3269 | spin_unlock_irqrestore(&info->lock,flags); | 3263 | spin_unlock_irqrestore(&info->lock,flags); |
3270 | } | 3264 | } |
@@ -3355,11 +3349,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3355 | return retval; | 3349 | return retval; |
3356 | } | 3350 | } |
3357 | 3351 | ||
3352 | /* | ||
3353 | * allocate buffers used for calling line discipline receive_buf | ||
3354 | * directly in synchronous mode | ||
3355 | * note: add 5 bytes to max frame size to allow appending | ||
3356 | * 32-bit CRC and status byte when configured to do so | ||
3357 | */ | ||
3358 | static int alloc_tmp_rbuf(struct slgt_info *info) | 3358 | static int alloc_tmp_rbuf(struct slgt_info *info) |
3359 | { | 3359 | { |
3360 | info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); | 3360 | info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); |
3361 | if (info->tmp_rbuf == NULL) | 3361 | if (info->tmp_rbuf == NULL) |
3362 | return -ENOMEM; | 3362 | return -ENOMEM; |
3363 | /* unused flag buffer to satisfy receive_buf calling interface */ | ||
3364 | info->flag_buf = kzalloc(info->max_frame_size + 5, GFP_KERNEL); | ||
3365 | if (!info->flag_buf) { | ||
3366 | kfree(info->tmp_rbuf); | ||
3367 | info->tmp_rbuf = NULL; | ||
3368 | return -ENOMEM; | ||
3369 | } | ||
3363 | return 0; | 3370 | return 0; |
3364 | } | 3371 | } |
3365 | 3372 | ||
@@ -3367,6 +3374,8 @@ static void free_tmp_rbuf(struct slgt_info *info) | |||
3367 | { | 3374 | { |
3368 | kfree(info->tmp_rbuf); | 3375 | kfree(info->tmp_rbuf); |
3369 | info->tmp_rbuf = NULL; | 3376 | info->tmp_rbuf = NULL; |
3377 | kfree(info->flag_buf); | ||
3378 | info->flag_buf = NULL; | ||
3370 | } | 3379 | } |
3371 | 3380 | ||
3372 | /* | 3381 | /* |
@@ -4110,7 +4119,7 @@ static void reset_port(struct slgt_info *info) | |||
4110 | tx_stop(info); | 4119 | tx_stop(info); |
4111 | rx_stop(info); | 4120 | rx_stop(info); |
4112 | 4121 | ||
4113 | info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 4122 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
4114 | set_signals(info); | 4123 | set_signals(info); |
4115 | 4124 | ||
4116 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); | 4125 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); |
@@ -4537,8 +4546,8 @@ static void get_signals(struct slgt_info *info) | |||
4537 | { | 4546 | { |
4538 | unsigned short status = rd_reg16(info, SSR); | 4547 | unsigned short status = rd_reg16(info, SSR); |
4539 | 4548 | ||
4540 | /* clear all serial signals except DTR and RTS */ | 4549 | /* clear all serial signals except RTS and DTR */ |
4541 | info->signals &= SerialSignal_DTR + SerialSignal_RTS; | 4550 | info->signals &= SerialSignal_RTS | SerialSignal_DTR; |
4542 | 4551 | ||
4543 | if (status & BIT3) | 4552 | if (status & BIT3) |
4544 | info->signals |= SerialSignal_DSR; | 4553 | info->signals |= SerialSignal_DSR; |