aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/synclink_gt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/synclink_gt.c')
-rw-r--r--drivers/char/synclink_gt.c136
1 files changed, 54 insertions, 82 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 08911ed66494..f329f459817c 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * $Id: synclink_gt.c,v 4.50 2007/07/25 19:29:25 paulkf Exp $
3 *
4 * Device driver for Microgate SyncLink GT serial adapters. 2 * Device driver for Microgate SyncLink GT serial adapters.
5 * 3 *
6 * written by Paul Fulghum for Microgate Corporation 4 * written by Paul Fulghum for Microgate Corporation
@@ -91,7 +89,6 @@
91 * module identification 89 * module identification
92 */ 90 */
93static char *driver_name = "SyncLink GT"; 91static char *driver_name = "SyncLink GT";
94static char *driver_version = "$Revision: 4.50 $";
95static char *tty_driver_name = "synclink_gt"; 92static char *tty_driver_name = "synclink_gt";
96static char *tty_dev_prefix = "ttySLG"; 93static char *tty_dev_prefix = "ttySLG";
97MODULE_LICENSE("GPL"); 94MODULE_LICENSE("GPL");
@@ -720,44 +717,9 @@ static void close(struct tty_struct *tty, struct file *filp)
720 return; 717 return;
721 DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count)); 718 DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count));
722 719
723 if (!info->port.count) 720 if (tty_port_close_start(&info->port, tty, filp) == 0)
724 return;
725
726 if (tty_hung_up_p(filp))
727 goto cleanup;
728
729 if ((tty->count == 1) && (info->port.count != 1)) {
730 /*
731 * tty->count is 1 and the tty structure will be freed.
732 * info->port.count should be one in this case.
733 * if it's not, correct it so that the port is shutdown.
734 */
735 DBGERR(("%s close: bad refcount; tty->count=1, "
736 "info->port.count=%d\n", info->device_name, info->port.count));
737 info->port.count = 1;
738 }
739
740 info->port.count--;
741
742 /* if at least one open remaining, leave hardware active */
743 if (info->port.count)
744 goto cleanup; 721 goto cleanup;
745 722
746 info->port.flags |= ASYNC_CLOSING;
747
748 /* set tty->closing to notify line discipline to
749 * only process XON/XOFF characters. Only the N_TTY
750 * discipline appears to use this (ppp does not).
751 */
752 tty->closing = 1;
753
754 /* wait for transmit data to clear all layers */
755
756 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
757 DBGINFO(("%s call tty_wait_until_sent\n", info->device_name));
758 tty_wait_until_sent(tty, info->port.closing_wait);
759 }
760
761 if (info->port.flags & ASYNC_INITIALIZED) 723 if (info->port.flags & ASYNC_INITIALIZED)
762 wait_until_sent(tty, info->timeout); 724 wait_until_sent(tty, info->timeout);
763 flush_buffer(tty); 725 flush_buffer(tty);
@@ -765,20 +727,8 @@ static void close(struct tty_struct *tty, struct file *filp)
765 727
766 shutdown(info); 728 shutdown(info);
767 729
768 tty->closing = 0; 730 tty_port_close_end(&info->port, tty);
769 info->port.tty = NULL; 731 info->port.tty = NULL;
770
771 if (info->port.blocked_open) {
772 if (info->port.close_delay) {
773 msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
774 }
775 wake_up_interruptible(&info->port.open_wait);
776 }
777
778 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
779
780 wake_up_interruptible(&info->port.close_wait);
781
782cleanup: 732cleanup:
783 DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count)); 733 DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count));
784} 734}
@@ -1356,7 +1306,7 @@ static int read_proc(char *page, char **start, off_t off, int count,
1356 off_t begin = 0; 1306 off_t begin = 0;
1357 struct slgt_info *info; 1307 struct slgt_info *info;
1358 1308
1359 len += sprintf(page, "synclink_gt driver:%s\n", driver_version); 1309 len += sprintf(page, "synclink_gt driver\n");
1360 1310
1361 info = slgt_device_list; 1311 info = slgt_device_list;
1362 while( info ) { 1312 while( info ) {
@@ -2488,7 +2438,7 @@ static void program_hw(struct slgt_info *info)
2488 info->ri_chkcount = 0; 2438 info->ri_chkcount = 0;
2489 info->dsr_chkcount = 0; 2439 info->dsr_chkcount = 0;
2490 2440
2491 slgt_irq_on(info, IRQ_DCD | IRQ_CTS | IRQ_DSR); 2441 slgt_irq_on(info, IRQ_DCD | IRQ_CTS | IRQ_DSR | IRQ_RI);
2492 get_signals(info); 2442 get_signals(info);
2493 2443
2494 if (info->netcount || 2444 if (info->netcount ||
@@ -3132,6 +3082,29 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
3132 return 0; 3082 return 0;
3133} 3083}
3134 3084
3085static int carrier_raised(struct tty_port *port)
3086{
3087 unsigned long flags;
3088 struct slgt_info *info = container_of(port, struct slgt_info, port);
3089
3090 spin_lock_irqsave(&info->lock,flags);
3091 get_signals(info);
3092 spin_unlock_irqrestore(&info->lock,flags);
3093 return (info->signals & SerialSignal_DCD) ? 1 : 0;
3094}
3095
3096static void raise_dtr_rts(struct tty_port *port)
3097{
3098 unsigned long flags;
3099 struct slgt_info *info = container_of(port, struct slgt_info, port);
3100
3101 spin_lock_irqsave(&info->lock,flags);
3102 info->signals |= SerialSignal_RTS + SerialSignal_DTR;
3103 set_signals(info);
3104 spin_unlock_irqrestore(&info->lock,flags);
3105}
3106
3107
3135/* 3108/*
3136 * block current process until the device is ready to open 3109 * block current process until the device is ready to open
3137 */ 3110 */
@@ -3143,12 +3116,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3143 bool do_clocal = false; 3116 bool do_clocal = false;
3144 bool extra_count = false; 3117 bool extra_count = false;
3145 unsigned long flags; 3118 unsigned long flags;
3119 int cd;
3120 struct tty_port *port = &info->port;
3146 3121
3147 DBGINFO(("%s block_til_ready\n", tty->driver->name)); 3122 DBGINFO(("%s block_til_ready\n", tty->driver->name));
3148 3123
3149 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ 3124 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
3150 /* nonblock mode is set or port is not enabled */ 3125 /* nonblock mode is set or port is not enabled */
3151 info->port.flags |= ASYNC_NORMAL_ACTIVE; 3126 port->flags |= ASYNC_NORMAL_ACTIVE;
3152 return 0; 3127 return 0;
3153 } 3128 }
3154 3129
@@ -3157,46 +3132,38 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3157 3132
3158 /* Wait for carrier detect and the line to become 3133 /* Wait for carrier detect and the line to become
3159 * free (i.e., not in use by the callout). While we are in 3134 * free (i.e., not in use by the callout). While we are in
3160 * this loop, info->port.count is dropped by one, so that 3135 * this loop, port->count is dropped by one, so that
3161 * close() knows when to free things. We restore it upon 3136 * close() knows when to free things. We restore it upon
3162 * exit, either normal or abnormal. 3137 * exit, either normal or abnormal.
3163 */ 3138 */
3164 3139
3165 retval = 0; 3140 retval = 0;
3166 add_wait_queue(&info->port.open_wait, &wait); 3141 add_wait_queue(&port->open_wait, &wait);
3167 3142
3168 spin_lock_irqsave(&info->lock, flags); 3143 spin_lock_irqsave(&info->lock, flags);
3169 if (!tty_hung_up_p(filp)) { 3144 if (!tty_hung_up_p(filp)) {
3170 extra_count = true; 3145 extra_count = true;
3171 info->port.count--; 3146 port->count--;
3172 } 3147 }
3173 spin_unlock_irqrestore(&info->lock, flags); 3148 spin_unlock_irqrestore(&info->lock, flags);
3174 info->port.blocked_open++; 3149 port->blocked_open++;
3175 3150
3176 while (1) { 3151 while (1) {
3177 if ((tty->termios->c_cflag & CBAUD)) { 3152 if ((tty->termios->c_cflag & CBAUD))
3178 spin_lock_irqsave(&info->lock,flags); 3153 tty_port_raise_dtr_rts(port);
3179 info->signals |= SerialSignal_RTS + SerialSignal_DTR;
3180 set_signals(info);
3181 spin_unlock_irqrestore(&info->lock,flags);
3182 }
3183 3154
3184 set_current_state(TASK_INTERRUPTIBLE); 3155 set_current_state(TASK_INTERRUPTIBLE);
3185 3156
3186 if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){ 3157 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){
3187 retval = (info->port.flags & ASYNC_HUP_NOTIFY) ? 3158 retval = (port->flags & ASYNC_HUP_NOTIFY) ?
3188 -EAGAIN : -ERESTARTSYS; 3159 -EAGAIN : -ERESTARTSYS;
3189 break; 3160 break;
3190 } 3161 }
3191 3162
3192 spin_lock_irqsave(&info->lock,flags); 3163 cd = tty_port_carrier_raised(port);
3193 get_signals(info);
3194 spin_unlock_irqrestore(&info->lock,flags);
3195 3164
3196 if (!(info->port.flags & ASYNC_CLOSING) && 3165 if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd ))
3197 (do_clocal || (info->signals & SerialSignal_DCD)) ) {
3198 break; 3166 break;
3199 }
3200 3167
3201 if (signal_pending(current)) { 3168 if (signal_pending(current)) {
3202 retval = -ERESTARTSYS; 3169 retval = -ERESTARTSYS;
@@ -3208,14 +3175,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3208 } 3175 }
3209 3176
3210 set_current_state(TASK_RUNNING); 3177 set_current_state(TASK_RUNNING);
3211 remove_wait_queue(&info->port.open_wait, &wait); 3178 remove_wait_queue(&port->open_wait, &wait);
3212 3179
3213 if (extra_count) 3180 if (extra_count)
3214 info->port.count++; 3181 port->count++;
3215 info->port.blocked_open--; 3182 port->blocked_open--;
3216 3183
3217 if (!retval) 3184 if (!retval)
3218 info->port.flags |= ASYNC_NORMAL_ACTIVE; 3185 port->flags |= ASYNC_NORMAL_ACTIVE;
3219 3186
3220 DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); 3187 DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval));
3221 return retval; 3188 return retval;
@@ -3444,6 +3411,11 @@ static void add_device(struct slgt_info *info)
3444#endif 3411#endif
3445} 3412}
3446 3413
3414static const struct tty_port_operations slgt_port_ops = {
3415 .carrier_raised = carrier_raised,
3416 .raise_dtr_rts = raise_dtr_rts,
3417};
3418
3447/* 3419/*
3448 * allocate device instance structure, return NULL on failure 3420 * allocate device instance structure, return NULL on failure
3449 */ 3421 */
@@ -3458,6 +3430,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
3458 driver_name, adapter_num, port_num)); 3430 driver_name, adapter_num, port_num));
3459 } else { 3431 } else {
3460 tty_port_init(&info->port); 3432 tty_port_init(&info->port);
3433 info->port.ops = &slgt_port_ops;
3461 info->magic = MGSL_MAGIC; 3434 info->magic = MGSL_MAGIC;
3462 INIT_WORK(&info->task, bh_handler); 3435 INIT_WORK(&info->task, bh_handler);
3463 info->max_frame_size = 4096; 3436 info->max_frame_size = 4096;
@@ -3600,7 +3573,7 @@ static void slgt_cleanup(void)
3600 struct slgt_info *info; 3573 struct slgt_info *info;
3601 struct slgt_info *tmp; 3574 struct slgt_info *tmp;
3602 3575
3603 printk("unload %s %s\n", driver_name, driver_version); 3576 printk(KERN_INFO "unload %s\n", driver_name);
3604 3577
3605 if (serial_driver) { 3578 if (serial_driver) {
3606 for (info=slgt_device_list ; info != NULL ; info=info->next_device) 3579 for (info=slgt_device_list ; info != NULL ; info=info->next_device)
@@ -3643,7 +3616,7 @@ static int __init slgt_init(void)
3643{ 3616{
3644 int rc; 3617 int rc;
3645 3618
3646 printk("%s %s\n", driver_name, driver_version); 3619 printk(KERN_INFO "%s\n", driver_name);
3647 3620
3648 serial_driver = alloc_tty_driver(MAX_DEVICES); 3621 serial_driver = alloc_tty_driver(MAX_DEVICES);
3649 if (!serial_driver) { 3622 if (!serial_driver) {
@@ -3674,9 +3647,8 @@ static int __init slgt_init(void)
3674 goto error; 3647 goto error;
3675 } 3648 }
3676 3649
3677 printk("%s %s, tty major#%d\n", 3650 printk(KERN_INFO "%s, tty major#%d\n",
3678 driver_name, driver_version, 3651 driver_name, serial_driver->major);
3679 serial_driver->major);
3680 3652
3681 slgt_device_count = 0; 3653 slgt_device_count = 0;
3682 if ((rc = pci_register_driver(&pci_driver)) < 0) { 3654 if ((rc = pci_register_driver(&pci_driver)) < 0) {