diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/cyclades.c | 45 |
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)) { |