- struct isi_board *card = port->card;
- int do_clocal = 0, retval;
- unsigned long flags;
- DECLARE_WAITQUEUE(wait, current);
-
- /* block if port is in the process of being closed */
-
- if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
- pr_dbg("block_til_ready: close in progress.\n");
- interruptible_sleep_on(&port->close_wait);
- if (port->flags & ASYNC_HUP_NOTIFY)
- return -EAGAIN;
- else
- return -ERESTARTSYS;
- }
-
- /* if non-blocking mode is set ... */
-
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
- pr_dbg("block_til_ready: non-block mode.\n");
- port->flags |= ASYNC_NORMAL_ACTIVE;
- return 0;
- }
-
- if (C_CLOCAL(tty))
- do_clocal = 1;
-
- /* block waiting for DCD to be asserted, and while
- callout dev is busy */
- retval = 0;
- add_wait_queue(&port->open_wait, &wait);
-
- spin_lock_irqsave(&card->card_lock, flags);
- if (!tty_hung_up_p(filp))
- port->count--;
- port->blocked_open++;
- spin_unlock_irqrestore(&card->card_lock, flags);
-
- while (1) {
- raise_dtr_rts(port);
-
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
- if (port->flags & ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
- break;
- }
- if (!(port->flags & ASYNC_CLOSING) &&
- (do_clocal || (port->status & ISI_DCD))) {
- break;
- }
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- schedule();
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&port->open_wait, &wait);
- spin_lock_irqsave(&card->card_lock, flags);
- if (!tty_hung_up_p(filp))
- port->count++;
- port->blocked_open--;
- spin_unlock_irqrestore(&card->card_lock, flags);
- if (retval)
- return retval;
- port->flags |= ASYNC_NORMAL_ACTIVE;
- return 0;