aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/cyclades.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/cyclades.c')
-rw-r--r--drivers/char/cyclades.c45
1 files changed, 16 insertions, 29 deletions
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 9bec4ef876f2..c236e9f7d8e7 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -947,7 +947,7 @@ do_softint(struct work_struct *work)
947 tty_wakeup(tty); 947 tty_wakeup(tty);
948#ifdef Z_WAKE 948#ifdef Z_WAKE
949 if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) 949 if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
950 wake_up_interruptible(&info->shutdown_wait); 950 complete(&info->shutdown_wait);
951#endif 951#endif
952} /* do_softint */ 952} /* do_softint */
953 953
@@ -2324,9 +2324,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2324 * until it's done, and then try again. 2324 * until it's done, and then try again.
2325 */ 2325 */
2326 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { 2326 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2327 if (info->flags & ASYNC_CLOSING) { 2327 wait_event_interruptible(info->close_wait,
2328 interruptible_sleep_on(&info->close_wait); 2328 !(info->flags & ASYNC_CLOSING));
2329 }
2330 return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; 2329 return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
2331 } 2330 }
2332 2331
@@ -2597,8 +2596,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2597 * If the port is the middle of closing, bail out now 2596 * If the port is the middle of closing, bail out now
2598 */ 2597 */
2599 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { 2598 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2600 if (info->flags & ASYNC_CLOSING) 2599 wait_event_interruptible(info->close_wait,
2601 interruptible_sleep_on(&info->close_wait); 2600 !(info->flags & ASYNC_CLOSING));
2602 return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; 2601 return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
2603 } 2602 }
2604 2603
@@ -2805,7 +2804,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2805 "ttyC%d was %x\n", info->line, retval); 2804 "ttyC%d was %x\n", info->line, retval);
2806 } 2805 }
2807 CY_UNLOCK(info, flags); 2806 CY_UNLOCK(info, flags);
2808 interruptible_sleep_on(&info->shutdown_wait); 2807 wait_for_completion_interruptible(&info->shutdown_wait);
2809 CY_LOCK(info, flags); 2808 CY_LOCK(info, flags);
2810 } 2809 }
2811#endif 2810#endif
@@ -4091,32 +4090,20 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
4091 case TIOCMIWAIT: 4090 case TIOCMIWAIT:
4092 CY_LOCK(info, flags); 4091 CY_LOCK(info, flags);
4093 /* note the counters on entry */ 4092 /* note the counters on entry */
4094 cprev = info->icount; 4093 cnow = info->icount;
4095 CY_UNLOCK(info, flags); 4094 CY_UNLOCK(info, flags);
4096 while (1) { 4095 ret_val = wait_event_interruptible(info->delta_msr_wait, ({
4097 interruptible_sleep_on(&info->delta_msr_wait); 4096 cprev = cnow;
4098 /* see if a signal did it */
4099 if (signal_pending(current)) {
4100 return -ERESTARTSYS;
4101 }
4102
4103 CY_LOCK(info, flags); 4097 CY_LOCK(info, flags);
4104 cnow = info->icount; /* atomic copy */ 4098 cnow = info->icount; /* atomic copy */
4105 CY_UNLOCK(info, flags); 4099 CY_UNLOCK(info, flags);
4106 4100
4107 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 4101 ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
4108 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { 4102 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
4109 return -EIO; /* no change => error */ 4103 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
4110 } 4104 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
4111 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || 4105 }));
4112 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || 4106 break;
4113 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
4114 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
4115 return 0;
4116 }
4117 cprev = cnow;
4118 }
4119 /* NOTREACHED */
4120 4107
4121 /* 4108 /*
4122 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) 4109 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
@@ -4534,7 +4521,7 @@ static void __devinit cy_init_card(struct cyclades_card *cinfo)
4534 INIT_WORK(&info->tqueue, do_softint); 4521 INIT_WORK(&info->tqueue, do_softint);
4535 init_waitqueue_head(&info->open_wait); 4522 init_waitqueue_head(&info->open_wait);
4536 init_waitqueue_head(&info->close_wait); 4523 init_waitqueue_head(&info->close_wait);
4537 init_waitqueue_head(&info->shutdown_wait); 4524 init_completion(&info->shutdown_wait);
4538 init_waitqueue_head(&info->delta_msr_wait); 4525 init_waitqueue_head(&info->delta_msr_wait);
4539 4526
4540 if (IS_CYC_Z(*cinfo)) { 4527 if (IS_CYC_Z(*cinfo)) {