aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/isicom.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-02 08:45:05 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:38 -0500
commit31f35939d1d9bcfb3099b32c67b896d2792603f9 (patch)
tree39b6ceaf0e7477e0357ff8235814f579adad3f28 /drivers/char/isicom.c
parentc9b3976e3fec266be25c5001a70aa0a890b6c476 (diff)
tty_port: Add a port level carrier detect operation
This is the first step to generalising the various pieces of waiting logic duplicated in all sorts of serial drivers. 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.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 04e4549299ba..b3da4858fd4a 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -830,20 +830,28 @@ static int isicom_setup_port(struct tty_struct *tty)
830 return 0; 830 return 0;
831} 831}
832 832
833static int isicom_carrier_raised(struct tty_port *port)
834{
835 struct isi_port *ip = container_of(port, struct isi_port, port);
836 return (ip->status & ISI_DCD)?1 : 0;
837}
838
833static int block_til_ready(struct tty_struct *tty, struct file *filp, 839static int block_til_ready(struct tty_struct *tty, struct file *filp,
834 struct isi_port *port) 840 struct isi_port *ip)
835{ 841{
836 struct isi_board *card = port->card; 842 struct isi_board *card = ip->card;
843 struct tty_port *port = &ip->port;
837 int do_clocal = 0, retval; 844 int do_clocal = 0, retval;
838 unsigned long flags; 845 unsigned long flags;
839 DECLARE_WAITQUEUE(wait, current); 846 DECLARE_WAITQUEUE(wait, current);
847 int cd;
840 848
841 /* block if port is in the process of being closed */ 849 /* block if port is in the process of being closed */
842 850
843 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) { 851 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
844 pr_dbg("block_til_ready: close in progress.\n"); 852 pr_dbg("block_til_ready: close in progress.\n");
845 interruptible_sleep_on(&port->port.close_wait); 853 interruptible_sleep_on(&port->close_wait);
846 if (port->port.flags & ASYNC_HUP_NOTIFY) 854 if (port->flags & ASYNC_HUP_NOTIFY)
847 return -EAGAIN; 855 return -EAGAIN;
848 else 856 else
849 return -ERESTARTSYS; 857 return -ERESTARTSYS;
@@ -854,7 +862,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
854 if ((filp->f_flags & O_NONBLOCK) || 862 if ((filp->f_flags & O_NONBLOCK) ||
855 (tty->flags & (1 << TTY_IO_ERROR))) { 863 (tty->flags & (1 << TTY_IO_ERROR))) {
856 pr_dbg("block_til_ready: non-block mode.\n"); 864 pr_dbg("block_til_ready: non-block mode.\n");
857 port->port.flags |= ASYNC_NORMAL_ACTIVE; 865 port->flags |= ASYNC_NORMAL_ACTIVE;
858 return 0; 866 return 0;
859 } 867 }
860 868
@@ -864,29 +872,29 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
864 /* block waiting for DCD to be asserted, and while 872 /* block waiting for DCD to be asserted, and while
865 callout dev is busy */ 873 callout dev is busy */
866 retval = 0; 874 retval = 0;
867 add_wait_queue(&port->port.open_wait, &wait); 875 add_wait_queue(&port->open_wait, &wait);
868 876
869 spin_lock_irqsave(&card->card_lock, flags); 877 spin_lock_irqsave(&card->card_lock, flags);
870 if (!tty_hung_up_p(filp)) 878 if (!tty_hung_up_p(filp))
871 port->port.count--; 879 port->count--;
872 port->port.blocked_open++; 880 port->blocked_open++;
873 spin_unlock_irqrestore(&card->card_lock, flags); 881 spin_unlock_irqrestore(&card->card_lock, flags);
874 882
875 while (1) { 883 while (1) {
876 raise_dtr_rts(port); 884 raise_dtr_rts(ip);
877 885
878 set_current_state(TASK_INTERRUPTIBLE); 886 set_current_state(TASK_INTERRUPTIBLE);
879 if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) { 887 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
880 if (port->port.flags & ASYNC_HUP_NOTIFY) 888 if (port->flags & ASYNC_HUP_NOTIFY)
881 retval = -EAGAIN; 889 retval = -EAGAIN;
882 else 890 else
883 retval = -ERESTARTSYS; 891 retval = -ERESTARTSYS;
884 break; 892 break;
885 } 893 }
886 if (!(port->port.flags & ASYNC_CLOSING) && 894 cd = tty_port_carrier_raised(port);
887 (do_clocal || (port->status & ISI_DCD))) { 895 if (!(port->flags & ASYNC_CLOSING) &&
896 (do_clocal || cd))
888 break; 897 break;
889 }
890 if (signal_pending(current)) { 898 if (signal_pending(current)) {
891 retval = -ERESTARTSYS; 899 retval = -ERESTARTSYS;
892 break; 900 break;
@@ -894,15 +902,15 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
894 schedule(); 902 schedule();
895 } 903 }
896 set_current_state(TASK_RUNNING); 904 set_current_state(TASK_RUNNING);
897 remove_wait_queue(&port->port.open_wait, &wait); 905 remove_wait_queue(&port->open_wait, &wait);
898 spin_lock_irqsave(&card->card_lock, flags); 906 spin_lock_irqsave(&card->card_lock, flags);
899 if (!tty_hung_up_p(filp)) 907 if (!tty_hung_up_p(filp))
900 port->port.count++; 908 port->count++;
901 port->port.blocked_open--; 909 port->blocked_open--;
902 spin_unlock_irqrestore(&card->card_lock, flags); 910 spin_unlock_irqrestore(&card->card_lock, flags);
903 if (retval) 911 if (retval)
904 return retval; 912 return retval;
905 port->port.flags |= ASYNC_NORMAL_ACTIVE; 913 port->flags |= ASYNC_NORMAL_ACTIVE;
906 return 0; 914 return 0;
907} 915}
908 916
@@ -1452,6 +1460,10 @@ static const struct tty_operations isicom_ops = {
1452 .break_ctl = isicom_send_break, 1460 .break_ctl = isicom_send_break,
1453}; 1461};
1454 1462
1463static const struct tty_port_operations isicom_port_ops = {
1464 .carrier_raised = isicom_carrier_raised,
1465};
1466
1455static int __devinit reset_card(struct pci_dev *pdev, 1467static int __devinit reset_card(struct pci_dev *pdev,
1456 const unsigned int card, unsigned int *signature) 1468 const unsigned int card, unsigned int *signature)
1457{ 1469{
@@ -1794,6 +1806,7 @@ static int __init isicom_init(void)
1794 spin_lock_init(&isi_card[idx].card_lock); 1806 spin_lock_init(&isi_card[idx].card_lock);
1795 for (channel = 0; channel < 16; channel++, port++) { 1807 for (channel = 0; channel < 16; channel++, port++) {
1796 tty_port_init(&port->port); 1808 tty_port_init(&port->port);
1809 port->port.ops = &isicom_port_ops;
1797 port->magic = ISICOM_MAGIC; 1810 port->magic = ISICOM_MAGIC;
1798 port->card = &isi_card[idx]; 1811 port->card = &isi_card[idx];
1799 port->channel = channel; 1812 port->channel = channel;