aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/istallion.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/istallion.c')
-rw-r--r--drivers/char/istallion.c185
1 files changed, 64 insertions, 121 deletions
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 402838f4083e..4cd6c527ee41 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -213,7 +213,6 @@ static int stli_shared;
213 * with the slave. Most of them need to be updated atomically, so always 213 * with the slave. Most of them need to be updated atomically, so always
214 * use the bit setting operations (unless protected by cli/sti). 214 * use the bit setting operations (unless protected by cli/sti).
215 */ 215 */
216#define ST_INITIALIZING 1
217#define ST_OPENING 2 216#define ST_OPENING 2
218#define ST_CLOSING 3 217#define ST_CLOSING 3
219#define ST_CMDING 4 218#define ST_CMDING 4
@@ -621,7 +620,7 @@ static int stli_brdinit(struct stlibrd *brdp);
621static int stli_startbrd(struct stlibrd *brdp); 620static int stli_startbrd(struct stlibrd *brdp);
622static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); 621static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp);
623static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); 622static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp);
624static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); 623static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg);
625static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); 624static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp);
626static void stli_poll(unsigned long arg); 625static void stli_poll(unsigned long arg);
627static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); 626static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp);
@@ -704,7 +703,7 @@ static const struct file_operations stli_fsiomem = {
704 .owner = THIS_MODULE, 703 .owner = THIS_MODULE,
705 .read = stli_memread, 704 .read = stli_memread,
706 .write = stli_memwrite, 705 .write = stli_memwrite,
707 .ioctl = stli_memioctl, 706 .unlocked_ioctl = stli_memioctl,
708}; 707};
709 708
710/*****************************************************************************/ 709/*****************************************************************************/
@@ -783,13 +782,32 @@ static int stli_parsebrd(struct stlconf *confp, char **argp)
783 782
784/*****************************************************************************/ 783/*****************************************************************************/
785 784
785/*
786 * On the first open of the device setup the port hardware, and
787 * initialize the per port data structure. Since initializing the port
788 * requires several commands to the board we will need to wait for any
789 * other open that is already initializing the port.
790 *
791 * Locking: protected by the port mutex.
792 */
793
794static int stli_activate(struct tty_port *port, struct tty_struct *tty)
795{
796 struct stliport *portp = container_of(port, struct stliport, port);
797 struct stlibrd *brdp = stli_brds[portp->brdnr];
798 int rc;
799
800 if ((rc = stli_initopen(tty, brdp, portp)) >= 0)
801 clear_bit(TTY_IO_ERROR, &tty->flags);
802 wake_up_interruptible(&portp->raw_wait);
803 return rc;
804}
805
786static int stli_open(struct tty_struct *tty, struct file *filp) 806static int stli_open(struct tty_struct *tty, struct file *filp)
787{ 807{
788 struct stlibrd *brdp; 808 struct stlibrd *brdp;
789 struct stliport *portp; 809 struct stliport *portp;
790 struct tty_port *port;
791 unsigned int minordev, brdnr, portnr; 810 unsigned int minordev, brdnr, portnr;
792 int rc;
793 811
794 minordev = tty->index; 812 minordev = tty->index;
795 brdnr = MINOR2BRD(minordev); 813 brdnr = MINOR2BRD(minordev);
@@ -809,95 +827,56 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
809 return -ENODEV; 827 return -ENODEV;
810 if (portp->devnr < 1) 828 if (portp->devnr < 1)
811 return -ENODEV; 829 return -ENODEV;
812 port = &portp->port; 830 return tty_port_open(&portp->port, tty, filp);
813
814/*
815 * On the first open of the device setup the port hardware, and
816 * initialize the per port data structure. Since initializing the port
817 * requires several commands to the board we will need to wait for any
818 * other open that is already initializing the port.
819 *
820 * Review - locking
821 */
822 tty_port_tty_set(port, tty);
823 tty->driver_data = portp;
824 port->count++;
825
826 wait_event_interruptible(portp->raw_wait,
827 !test_bit(ST_INITIALIZING, &portp->state));
828 if (signal_pending(current))
829 return -ERESTARTSYS;
830
831 if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
832 set_bit(ST_INITIALIZING, &portp->state);
833 if ((rc = stli_initopen(tty, brdp, portp)) >= 0) {
834 /* Locking */
835 port->flags |= ASYNC_INITIALIZED;
836 clear_bit(TTY_IO_ERROR, &tty->flags);
837 }
838 clear_bit(ST_INITIALIZING, &portp->state);
839 wake_up_interruptible(&portp->raw_wait);
840 if (rc < 0)
841 return rc;
842 }
843 return tty_port_block_til_ready(&portp->port, tty, filp);
844} 831}
845 832
833
846/*****************************************************************************/ 834/*****************************************************************************/
847 835
848static void stli_close(struct tty_struct *tty, struct file *filp) 836static void stli_shutdown(struct tty_port *port)
849{ 837{
850 struct stlibrd *brdp; 838 struct stlibrd *brdp;
851 struct stliport *portp; 839 unsigned long ftype;
852 struct tty_port *port;
853 unsigned long flags; 840 unsigned long flags;
841 struct stliport *portp = container_of(port, struct stliport, port);
854 842
855 portp = tty->driver_data; 843 if (portp->brdnr >= stli_nrbrds)
856 if (portp == NULL)
857 return; 844 return;
858 port = &portp->port; 845 brdp = stli_brds[portp->brdnr];
859 846 if (brdp == NULL)
860 if (tty_port_close_start(port, tty, filp) == 0)
861 return; 847 return;
862 848
863/* 849 /*
864 * May want to wait for data to drain before closing. The BUSY flag 850 * May want to wait for data to drain before closing. The BUSY
865 * keeps track of whether we are still transmitting or not. It is 851 * flag keeps track of whether we are still transmitting or not.
866 * updated by messages from the slave - indicating when all chars 852 * It is updated by messages from the slave - indicating when all
867 * really have drained. 853 * chars really have drained.
868 */ 854 */
869 spin_lock_irqsave(&stli_lock, flags);
870 if (tty == stli_txcooktty)
871 stli_flushchars(tty);
872 spin_unlock_irqrestore(&stli_lock, flags);
873
874 /* We end up doing this twice for the moment. This needs looking at
875 eventually. Note we still use portp->closing_wait as a result */
876 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
877 tty_wait_until_sent(tty, portp->closing_wait);
878 855
879 /* FIXME: port locking here needs attending to */ 856 if (!test_bit(ST_CLOSING, &portp->state))
880 port->flags &= ~ASYNC_INITIALIZED; 857 stli_rawclose(brdp, portp, 0, 0);
881 858
882 brdp = stli_brds[portp->brdnr]; 859 spin_lock_irqsave(&stli_lock, flags);
883 stli_rawclose(brdp, portp, 0, 0);
884 if (tty->termios->c_cflag & HUPCL) {
885 stli_mkasysigs(&portp->asig, 0, 0);
886 if (test_bit(ST_CMDING, &portp->state))
887 set_bit(ST_DOSIGS, &portp->state);
888 else
889 stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig,
890 sizeof(asysigs_t), 0);
891 }
892 clear_bit(ST_TXBUSY, &portp->state); 860 clear_bit(ST_TXBUSY, &portp->state);
893 clear_bit(ST_RXSTOP, &portp->state); 861 clear_bit(ST_RXSTOP, &portp->state);
894 set_bit(TTY_IO_ERROR, &tty->flags); 862 spin_unlock_irqrestore(&stli_lock, flags);
895 tty_ldisc_flush(tty);
896 set_bit(ST_DOFLUSHRX, &portp->state);
897 stli_flushbuffer(tty);
898 863
899 tty_port_close_end(port, tty); 864 ftype = FLUSHTX | FLUSHRX;
900 tty_port_tty_set(port, NULL); 865 stli_cmdwait(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0);
866}
867
868static void stli_close(struct tty_struct *tty, struct file *filp)
869{
870 struct stliport *portp = tty->driver_data;
871 unsigned long flags;
872 if (portp == NULL)
873 return;
874 spin_lock_irqsave(&stli_lock, flags);
875 /* Flush any internal buffering out first */
876 if (tty == stli_txcooktty)
877 stli_flushchars(tty);
878 spin_unlock_irqrestore(&stli_lock, flags);
879 tty_port_close(&portp->port, tty, filp);
901} 880}
902 881
903/*****************************************************************************/ 882/*****************************************************************************/
@@ -1724,6 +1703,7 @@ static void stli_start(struct tty_struct *tty)
1724 1703
1725/*****************************************************************************/ 1704/*****************************************************************************/
1726 1705
1706
1727/* 1707/*
1728 * Hangup this port. This is pretty much like closing the port, only 1708 * Hangup this port. This is pretty much like closing the port, only
1729 * a little more brutal. No waiting for data to drain. Shutdown the 1709 * a little more brutal. No waiting for data to drain. Shutdown the
@@ -1733,47 +1713,8 @@ static void stli_start(struct tty_struct *tty)
1733 1713
1734static void stli_hangup(struct tty_struct *tty) 1714static void stli_hangup(struct tty_struct *tty)
1735{ 1715{
1736 struct stliport *portp; 1716 struct stliport *portp = tty->driver_data;
1737 struct stlibrd *brdp; 1717 tty_port_hangup(&portp->port);
1738 struct tty_port *port;
1739 unsigned long flags;
1740
1741 portp = tty->driver_data;
1742 if (portp == NULL)
1743 return;
1744 if (portp->brdnr >= stli_nrbrds)
1745 return;
1746 brdp = stli_brds[portp->brdnr];
1747 if (brdp == NULL)
1748 return;
1749 port = &portp->port;
1750
1751 spin_lock_irqsave(&port->lock, flags);
1752 port->flags &= ~ASYNC_INITIALIZED;
1753 spin_unlock_irqrestore(&port->lock, flags);
1754
1755 if (!test_bit(ST_CLOSING, &portp->state))
1756 stli_rawclose(brdp, portp, 0, 0);
1757
1758 spin_lock_irqsave(&stli_lock, flags);
1759 if (tty->termios->c_cflag & HUPCL) {
1760 stli_mkasysigs(&portp->asig, 0, 0);
1761 if (test_bit(ST_CMDING, &portp->state)) {
1762 set_bit(ST_DOSIGS, &portp->state);
1763 set_bit(ST_DOFLUSHTX, &portp->state);
1764 set_bit(ST_DOFLUSHRX, &portp->state);
1765 } else {
1766 stli_sendcmd(brdp, portp, A_SETSIGNALSF,
1767 &portp->asig, sizeof(asysigs_t), 0);
1768 }
1769 }
1770
1771 clear_bit(ST_TXBUSY, &portp->state);
1772 clear_bit(ST_RXSTOP, &portp->state);
1773 set_bit(TTY_IO_ERROR, &tty->flags);
1774 spin_unlock_irqrestore(&stli_lock, flags);
1775
1776 tty_port_hangup(port);
1777} 1718}
1778 1719
1779/*****************************************************************************/ 1720/*****************************************************************************/
@@ -4311,7 +4252,7 @@ static int stli_getbrdstruct(struct stlibrd __user *arg)
4311 * reset it, and start/stop it. 4252 * reset it, and start/stop it.
4312 */ 4253 */
4313 4254
4314static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) 4255static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
4315{ 4256{
4316 struct stlibrd *brdp; 4257 struct stlibrd *brdp;
4317 int brdnr, rc, done; 4258 int brdnr, rc, done;
@@ -4356,7 +4297,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
4356 * Now handle the board specific ioctls. These all depend on the 4297 * Now handle the board specific ioctls. These all depend on the
4357 * minor number of the device they were called from. 4298 * minor number of the device they were called from.
4358 */ 4299 */
4359 brdnr = iminor(ip); 4300 brdnr = iminor(fp->f_dentry->d_inode);
4360 if (brdnr >= STL_MAXBRDS) 4301 if (brdnr >= STL_MAXBRDS)
4361 return -ENODEV; 4302 return -ENODEV;
4362 brdp = stli_brds[brdnr]; 4303 brdp = stli_brds[brdnr];
@@ -4420,6 +4361,8 @@ static const struct tty_operations stli_ops = {
4420static const struct tty_port_operations stli_port_ops = { 4361static const struct tty_port_operations stli_port_ops = {
4421 .carrier_raised = stli_carrier_raised, 4362 .carrier_raised = stli_carrier_raised,
4422 .dtr_rts = stli_dtr_rts, 4363 .dtr_rts = stli_dtr_rts,
4364 .activate = stli_activate,
4365 .shutdown = stli_shutdown,
4423}; 4366};
4424 4367
4425/*****************************************************************************/ 4368/*****************************************************************************/