aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/isicom.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-02 08:46:10 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:39 -0500
commit36c621d82b956ff6ff72273f848af53e6c581aba (patch)
treeedd387d8275a8f25277d264ffed94e8d1c2ba048 /drivers/char/isicom.c
parent3b6826b250633361f08a6427a4ac0035e5d88c72 (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.c79
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
841static 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
917static int isicom_open(struct tty_struct *tty, struct file *filp) 841static 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