diff options
author | Alan Cox <alan@redhat.com> | 2009-01-02 08:46:10 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:39 -0500 |
commit | 36c621d82b956ff6ff72273f848af53e6c581aba (patch) | |
tree | edd387d8275a8f25277d264ffed94e8d1c2ba048 /drivers/char/isicom.c | |
parent | 3b6826b250633361f08a6427a4ac0035e5d88c72 (diff) |
tty: Introduce a tty_port generic block_til_ready
Start sucking more commonality out of the drivers into a single piece of
core code.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/isicom.c')
-rw-r--r-- | drivers/char/isicom.c | 79 |
1 files changed, 2 insertions, 77 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index db53db91ae4a..bac55cf44243 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -838,82 +838,6 @@ static int isicom_carrier_raised(struct tty_port *port) | |||
838 | return (ip->status & ISI_DCD)?1 : 0; | 838 | return (ip->status & ISI_DCD)?1 : 0; |
839 | } | 839 | } |
840 | 840 | ||
841 | static int block_til_ready(struct tty_struct *tty, struct file *filp, | ||
842 | struct isi_port *ip) | ||
843 | { | ||
844 | struct tty_port *port = &ip->port; | ||
845 | int do_clocal = 0, retval; | ||
846 | unsigned long flags; | ||
847 | DECLARE_WAITQUEUE(wait, current); | ||
848 | int cd; | ||
849 | |||
850 | /* block if port is in the process of being closed */ | ||
851 | |||
852 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { | ||
853 | pr_dbg("block_til_ready: close in progress.\n"); | ||
854 | interruptible_sleep_on(&port->close_wait); | ||
855 | if (port->flags & ASYNC_HUP_NOTIFY) | ||
856 | return -EAGAIN; | ||
857 | else | ||
858 | return -ERESTARTSYS; | ||
859 | } | ||
860 | |||
861 | /* if non-blocking mode is set ... */ | ||
862 | |||
863 | if ((filp->f_flags & O_NONBLOCK) || | ||
864 | (tty->flags & (1 << TTY_IO_ERROR))) { | ||
865 | pr_dbg("block_til_ready: non-block mode.\n"); | ||
866 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
867 | return 0; | ||
868 | } | ||
869 | |||
870 | if (C_CLOCAL(tty)) | ||
871 | do_clocal = 1; | ||
872 | |||
873 | /* block waiting for DCD to be asserted, and while | ||
874 | callout dev is busy */ | ||
875 | retval = 0; | ||
876 | add_wait_queue(&port->open_wait, &wait); | ||
877 | |||
878 | spin_lock_irqsave(&port->lock, flags); | ||
879 | if (!tty_hung_up_p(filp)) | ||
880 | port->count--; | ||
881 | port->blocked_open++; | ||
882 | spin_unlock_irqrestore(&port->lock, flags); | ||
883 | |||
884 | while (1) { | ||
885 | tty_port_raise_dtr_rts(port); | ||
886 | |||
887 | set_current_state(TASK_INTERRUPTIBLE); | ||
888 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { | ||
889 | if (port->flags & ASYNC_HUP_NOTIFY) | ||
890 | retval = -EAGAIN; | ||
891 | else | ||
892 | retval = -ERESTARTSYS; | ||
893 | break; | ||
894 | } | ||
895 | cd = tty_port_carrier_raised(port); | ||
896 | if (!(port->flags & ASYNC_CLOSING) && | ||
897 | (do_clocal || cd)) | ||
898 | break; | ||
899 | if (signal_pending(current)) { | ||
900 | retval = -ERESTARTSYS; | ||
901 | break; | ||
902 | } | ||
903 | schedule(); | ||
904 | } | ||
905 | set_current_state(TASK_RUNNING); | ||
906 | remove_wait_queue(&port->open_wait, &wait); | ||
907 | spin_lock_irqsave(&port->lock, flags); | ||
908 | if (!tty_hung_up_p(filp)) | ||
909 | port->count++; | ||
910 | port->blocked_open--; | ||
911 | if (retval == 0) | ||
912 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
913 | spin_unlock_irqrestore(&port->lock, flags); | ||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | static int isicom_open(struct tty_struct *tty, struct file *filp) | 841 | static int isicom_open(struct tty_struct *tty, struct file *filp) |
918 | { | 842 | { |
919 | struct isi_port *port; | 843 | struct isi_port *port; |
@@ -940,12 +864,13 @@ static int isicom_open(struct tty_struct *tty, struct file *filp) | |||
940 | 864 | ||
941 | isicom_setup_board(card); | 865 | isicom_setup_board(card); |
942 | 866 | ||
867 | /* FIXME: locking on port.count etc */ | ||
943 | port->port.count++; | 868 | port->port.count++; |
944 | tty->driver_data = port; | 869 | tty->driver_data = port; |
945 | tty_port_tty_set(&port->port, tty); | 870 | tty_port_tty_set(&port->port, tty); |
946 | error = isicom_setup_port(tty); | 871 | error = isicom_setup_port(tty); |
947 | if (error == 0) | 872 | if (error == 0) |
948 | error = block_til_ready(tty, filp, port); | 873 | error = tty_port_block_til_ready(&port->port, tty, filp); |
949 | return error; | 874 | return error; |
950 | } | 875 | } |
951 | 876 | ||