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.c120
1 files changed, 48 insertions, 72 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 08911ed66494..53544e21f191 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -720,44 +720,9 @@ static void close(struct tty_struct *tty, struct file *filp)
720 return; 720 return;
721 DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count)); 721 DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count));
722 722
723 if (!info->port.count) 723 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; 724 goto cleanup;
745 725
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) 726 if (info->port.flags & ASYNC_INITIALIZED)
762 wait_until_sent(tty, info->timeout); 727 wait_until_sent(tty, info->timeout);
763 flush_buffer(tty); 728 flush_buffer(tty);
@@ -765,20 +730,8 @@ static void close(struct tty_struct *tty, struct file *filp)
765 730
766 shutdown(info); 731 shutdown(info);
767 732
768 tty->closing = 0; 733 tty_port_close_end(&info->port, tty);
769 info->port.tty = NULL; 734 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: 735cleanup:
783 DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count)); 736 DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count));
784} 737}
@@ -3132,6 +3085,29 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
3132 return 0; 3085 return 0;
3133} 3086}
3134 3087
3088static int carrier_raised(struct tty_port *port)
3089{
3090 unsigned long flags;
3091 struct slgt_info *info = container_of(port, struct slgt_info, port);
3092
3093 spin_lock_irqsave(&info->lock,flags);
3094 get_signals(info);
3095 spin_unlock_irqrestore(&info->lock,flags);
3096 return (info->signals & SerialSignal_DCD) ? 1 : 0;
3097}
3098
3099static void raise_dtr_rts(struct tty_port *port)
3100{
3101 unsigned long flags;
3102 struct slgt_info *info = container_of(port, struct slgt_info, port);
3103
3104 spin_lock_irqsave(&info->lock,flags);
3105 info->signals |= SerialSignal_RTS + SerialSignal_DTR;
3106 set_signals(info);
3107 spin_unlock_irqrestore(&info->lock,flags);
3108}
3109
3110
3135/* 3111/*
3136 * block current process until the device is ready to open 3112 * block current process until the device is ready to open
3137 */ 3113 */
@@ -3143,12 +3119,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3143 bool do_clocal = false; 3119 bool do_clocal = false;
3144 bool extra_count = false; 3120 bool extra_count = false;
3145 unsigned long flags; 3121 unsigned long flags;
3122 int cd;
3123 struct tty_port *port = &info->port;
3146 3124
3147 DBGINFO(("%s block_til_ready\n", tty->driver->name)); 3125 DBGINFO(("%s block_til_ready\n", tty->driver->name));
3148 3126
3149 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ 3127 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
3150 /* nonblock mode is set or port is not enabled */ 3128 /* nonblock mode is set or port is not enabled */
3151 info->port.flags |= ASYNC_NORMAL_ACTIVE; 3129 port->flags |= ASYNC_NORMAL_ACTIVE;
3152 return 0; 3130 return 0;
3153 } 3131 }
3154 3132
@@ -3157,46 +3135,38 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3157 3135
3158 /* Wait for carrier detect and the line to become 3136 /* Wait for carrier detect and the line to become
3159 * free (i.e., not in use by the callout). While we are in 3137 * 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 3138 * this loop, port->count is dropped by one, so that
3161 * close() knows when to free things. We restore it upon 3139 * close() knows when to free things. We restore it upon
3162 * exit, either normal or abnormal. 3140 * exit, either normal or abnormal.
3163 */ 3141 */
3164 3142
3165 retval = 0; 3143 retval = 0;
3166 add_wait_queue(&info->port.open_wait, &wait); 3144 add_wait_queue(&port->open_wait, &wait);
3167 3145
3168 spin_lock_irqsave(&info->lock, flags); 3146 spin_lock_irqsave(&info->lock, flags);
3169 if (!tty_hung_up_p(filp)) { 3147 if (!tty_hung_up_p(filp)) {
3170 extra_count = true; 3148 extra_count = true;
3171 info->port.count--; 3149 port->count--;
3172 } 3150 }
3173 spin_unlock_irqrestore(&info->lock, flags); 3151 spin_unlock_irqrestore(&info->lock, flags);
3174 info->port.blocked_open++; 3152 port->blocked_open++;
3175 3153
3176 while (1) { 3154 while (1) {
3177 if ((tty->termios->c_cflag & CBAUD)) { 3155 if ((tty->termios->c_cflag & CBAUD))
3178 spin_lock_irqsave(&info->lock,flags); 3156 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 3157
3184 set_current_state(TASK_INTERRUPTIBLE); 3158 set_current_state(TASK_INTERRUPTIBLE);
3185 3159
3186 if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){ 3160 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){
3187 retval = (info->port.flags & ASYNC_HUP_NOTIFY) ? 3161 retval = (port->flags & ASYNC_HUP_NOTIFY) ?
3188 -EAGAIN : -ERESTARTSYS; 3162 -EAGAIN : -ERESTARTSYS;
3189 break; 3163 break;
3190 } 3164 }
3191 3165
3192 spin_lock_irqsave(&info->lock,flags); 3166 cd = tty_port_carrier_raised(port);
3193 get_signals(info);
3194 spin_unlock_irqrestore(&info->lock,flags);
3195 3167
3196 if (!(info->port.flags & ASYNC_CLOSING) && 3168 if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd ))
3197 (do_clocal || (info->signals & SerialSignal_DCD)) ) {
3198 break; 3169 break;
3199 }
3200 3170
3201 if (signal_pending(current)) { 3171 if (signal_pending(current)) {
3202 retval = -ERESTARTSYS; 3172 retval = -ERESTARTSYS;
@@ -3208,14 +3178,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3208 } 3178 }
3209 3179
3210 set_current_state(TASK_RUNNING); 3180 set_current_state(TASK_RUNNING);
3211 remove_wait_queue(&info->port.open_wait, &wait); 3181 remove_wait_queue(&port->open_wait, &wait);
3212 3182
3213 if (extra_count) 3183 if (extra_count)
3214 info->port.count++; 3184 port->count++;
3215 info->port.blocked_open--; 3185 port->blocked_open--;
3216 3186
3217 if (!retval) 3187 if (!retval)
3218 info->port.flags |= ASYNC_NORMAL_ACTIVE; 3188 port->flags |= ASYNC_NORMAL_ACTIVE;
3219 3189
3220 DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); 3190 DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval));
3221 return retval; 3191 return retval;
@@ -3444,6 +3414,11 @@ static void add_device(struct slgt_info *info)
3444#endif 3414#endif
3445} 3415}
3446 3416
3417static const struct tty_port_operations slgt_port_ops = {
3418 .carrier_raised = carrier_raised,
3419 .raise_dtr_rts = raise_dtr_rts,
3420};
3421
3447/* 3422/*
3448 * allocate device instance structure, return NULL on failure 3423 * allocate device instance structure, return NULL on failure
3449 */ 3424 */
@@ -3458,6 +3433,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
3458 driver_name, adapter_num, port_num)); 3433 driver_name, adapter_num, port_num));
3459 } else { 3434 } else {
3460 tty_port_init(&info->port); 3435 tty_port_init(&info->port);
3436 info->port.ops = &slgt_port_ops;
3461 info->magic = MGSL_MAGIC; 3437 info->magic = MGSL_MAGIC;
3462 INIT_WORK(&info->task, bh_handler); 3438 INIT_WORK(&info->task, bh_handler);
3463 info->max_frame_size = 4096; 3439 info->max_frame_size = 4096;