aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/whiteheat.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-07-22 06:09:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-22 16:03:22 -0400
commit95da310e66ee8090119596c70ca8432e57f9a97f (patch)
tree7f18c30e9c9ad4d7d53df6453fa338be06f09a85 /drivers/usb/serial/whiteheat.c
parent1aa3692da57c773e5c76de55c5c4a953962d360e (diff)
usb_serial: API all change
USB serial likes to use port->tty back pointers for the real work it does and to do so without any actual locking. Unfortunately when you consider hangup events, hangup/parallel reopen or even worse hangup followed by parallel close events the tty->port and port->tty pointers are not guaranteed to be the same as port->tty is the active tty while tty->port is the port the tty may or may not still be attached to. So rework the entire API to pass the tty struct. For console cases we need to pass both for now. This shows up multiple drivers that immediately crash with USB console some of which have been fixed in the process. Longer term we need a proper tty as console abstraction Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial/whiteheat.c')
-rw-r--r--drivers/usb/serial/whiteheat.c102
1 files changed, 58 insertions, 44 deletions
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 665aa77a917b..b07d6a5cac31 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -142,18 +142,18 @@ static int whiteheat_firmware_attach (struct usb_serial *serial);
142/* function prototypes for the Connect Tech WhiteHEAT serial converter */ 142/* function prototypes for the Connect Tech WhiteHEAT serial converter */
143static int whiteheat_attach (struct usb_serial *serial); 143static int whiteheat_attach (struct usb_serial *serial);
144static void whiteheat_shutdown (struct usb_serial *serial); 144static void whiteheat_shutdown (struct usb_serial *serial);
145static int whiteheat_open (struct usb_serial_port *port, struct file *filp); 145static int whiteheat_open (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
146static void whiteheat_close (struct usb_serial_port *port, struct file *filp); 146static void whiteheat_close (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
147static int whiteheat_write (struct usb_serial_port *port, const unsigned char *buf, int count); 147static int whiteheat_write (struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count);
148static int whiteheat_write_room (struct usb_serial_port *port); 148static int whiteheat_write_room (struct tty_struct *tty);
149static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); 149static int whiteheat_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
150static void whiteheat_set_termios (struct usb_serial_port *port, struct ktermios * old); 150static void whiteheat_set_termios (struct tty_struct *tty, struct usb_serial_port *port, struct ktermios * old);
151static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file); 151static int whiteheat_tiocmget (struct tty_struct *tty, struct file *file);
152static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); 152static int whiteheat_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
153static void whiteheat_break_ctl (struct usb_serial_port *port, int break_state); 153static void whiteheat_break_ctl (struct tty_struct *tty, int break_state);
154static int whiteheat_chars_in_buffer (struct usb_serial_port *port); 154static int whiteheat_chars_in_buffer (struct tty_struct *tty);
155static void whiteheat_throttle (struct usb_serial_port *port); 155static void whiteheat_throttle (struct tty_struct *tty);
156static void whiteheat_unthrottle (struct usb_serial_port *port); 156static void whiteheat_unthrottle (struct tty_struct *tty);
157static void whiteheat_read_callback (struct urb *urb); 157static void whiteheat_read_callback (struct urb *urb);
158static void whiteheat_write_callback (struct urb *urb); 158static void whiteheat_write_callback (struct urb *urb);
159 159
@@ -246,7 +246,7 @@ static void rx_data_softint(struct work_struct *work);
246static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize); 246static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize);
247static int firm_open(struct usb_serial_port *port); 247static int firm_open(struct usb_serial_port *port);
248static int firm_close(struct usb_serial_port *port); 248static int firm_close(struct usb_serial_port *port);
249static int firm_setup_port(struct usb_serial_port *port); 249static int firm_setup_port(struct tty_struct *tty);
250static int firm_set_rts(struct usb_serial_port *port, __u8 onoff); 250static int firm_set_rts(struct usb_serial_port *port, __u8 onoff);
251static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff); 251static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff);
252static int firm_set_break(struct usb_serial_port *port, __u8 onoff); 252static int firm_set_break(struct usb_serial_port *port, __u8 onoff);
@@ -613,7 +613,8 @@ static void whiteheat_shutdown (struct usb_serial *serial)
613} 613}
614 614
615 615
616static int whiteheat_open (struct usb_serial_port *port, struct file *filp) 616static int whiteheat_open (struct tty_struct *tty,
617 struct usb_serial_port *port, struct file *filp)
617{ 618{
618 int retval = 0; 619 int retval = 0;
619 struct ktermios old_term; 620 struct ktermios old_term;
@@ -624,7 +625,8 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
624 if (retval) 625 if (retval)
625 goto exit; 626 goto exit;
626 627
627 port->tty->low_latency = 1; 628 if (tty)
629 tty->low_latency = 1;
628 630
629 /* send an open port command */ 631 /* send an open port command */
630 retval = firm_open(port); 632 retval = firm_open(port);
@@ -640,9 +642,11 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
640 goto exit; 642 goto exit;
641 } 643 }
642 644
643 old_term.c_cflag = ~port->tty->termios->c_cflag; 645 if (tty) {
644 old_term.c_iflag = ~port->tty->termios->c_iflag; 646 old_term.c_cflag = ~tty->termios->c_cflag;
645 whiteheat_set_termios(port, &old_term); 647 old_term.c_iflag = ~tty->termios->c_iflag;
648 whiteheat_set_termios(tty, port, &old_term);
649 }
646 650
647 /* Work around HCD bugs */ 651 /* Work around HCD bugs */
648 usb_clear_halt(port->serial->dev, port->read_urb->pipe); 652 usb_clear_halt(port->serial->dev, port->read_urb->pipe);
@@ -663,7 +667,8 @@ exit:
663} 667}
664 668
665 669
666static void whiteheat_close(struct usb_serial_port *port, struct file * filp) 670static void whiteheat_close(struct tty_struct *tty,
671 struct usb_serial_port *port, struct file * filp)
667{ 672{
668 struct whiteheat_private *info = usb_get_serial_port_data(port); 673 struct whiteheat_private *info = usb_get_serial_port_data(port);
669 struct whiteheat_urb_wrap *wrap; 674 struct whiteheat_urb_wrap *wrap;
@@ -681,7 +686,7 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
681 } 686 }
682 mutex_unlock(&port->serial->disc_mutex); 687 mutex_unlock(&port->serial->disc_mutex);
683 688
684 port->tty->closing = 1; 689 tty->closing = 1;
685 690
686/* 691/*
687 * Not currently in use; tty_wait_until_sent() calls 692 * Not currently in use; tty_wait_until_sent() calls
@@ -689,12 +694,12 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
689 * acquisition. This should be fixed at some point. Greg's been 694 * acquisition. This should be fixed at some point. Greg's been
690 * notified. 695 * notified.
691 if ((filp->f_flags & (O_NDELAY | O_NONBLOCK)) == 0) { 696 if ((filp->f_flags & (O_NDELAY | O_NONBLOCK)) == 0) {
692 tty_wait_until_sent(port->tty, CLOSING_DELAY); 697 tty_wait_until_sent(tty, CLOSING_DELAY);
693 } 698 }
694*/ 699*/
695 700
696 tty_driver_flush_buffer(port->tty); 701 tty_driver_flush_buffer(tty);
697 tty_ldisc_flush(port->tty); 702 tty_ldisc_flush(tty);
698 703
699 firm_report_tx_done(port); 704 firm_report_tx_done(port);
700 705
@@ -728,11 +733,12 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
728 733
729 stop_command_port(port->serial); 734 stop_command_port(port->serial);
730 735
731 port->tty->closing = 0; 736 tty->closing = 0;
732} 737}
733 738
734 739
735static int whiteheat_write(struct usb_serial_port *port, const unsigned char *buf, int count) 740static int whiteheat_write(struct tty_struct *tty,
741 struct usb_serial_port *port, const unsigned char *buf, int count)
736{ 742{
737 struct usb_serial *serial = port->serial; 743 struct usb_serial *serial = port->serial;
738 struct whiteheat_private *info = usb_get_serial_port_data(port); 744 struct whiteheat_private *info = usb_get_serial_port_data(port);
@@ -791,8 +797,9 @@ static int whiteheat_write(struct usb_serial_port *port, const unsigned char *bu
791} 797}
792 798
793 799
794static int whiteheat_write_room(struct usb_serial_port *port) 800static int whiteheat_write_room(struct tty_struct *tty)
795{ 801{
802 struct usb_serial_port *port = tty->driver_data;
796 struct whiteheat_private *info = usb_get_serial_port_data(port); 803 struct whiteheat_private *info = usb_get_serial_port_data(port);
797 struct list_head *tmp; 804 struct list_head *tmp;
798 int room = 0; 805 int room = 0;
@@ -811,8 +818,9 @@ static int whiteheat_write_room(struct usb_serial_port *port)
811} 818}
812 819
813 820
814static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file) 821static int whiteheat_tiocmget (struct tty_struct *tty, struct file *file)
815{ 822{
823 struct usb_serial_port *port = tty->driver_data;
816 struct whiteheat_private *info = usb_get_serial_port_data(port); 824 struct whiteheat_private *info = usb_get_serial_port_data(port);
817 unsigned int modem_signals = 0; 825 unsigned int modem_signals = 0;
818 826
@@ -828,9 +836,10 @@ static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file)
828} 836}
829 837
830 838
831static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file, 839static int whiteheat_tiocmset (struct tty_struct *tty, struct file *file,
832 unsigned int set, unsigned int clear) 840 unsigned int set, unsigned int clear)
833{ 841{
842 struct usb_serial_port *port = tty->driver_data;
834 struct whiteheat_private *info = usb_get_serial_port_data(port); 843 struct whiteheat_private *info = usb_get_serial_port_data(port);
835 844
836 dbg("%s - port %d", __func__, port->number); 845 dbg("%s - port %d", __func__, port->number);
@@ -851,8 +860,9 @@ static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file,
851} 860}
852 861
853 862
854static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) 863static int whiteheat_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
855{ 864{
865 struct usb_serial_port *port = tty->driver_data;
856 struct serial_struct serstruct; 866 struct serial_struct serstruct;
857 void __user *user_arg = (void __user *)arg; 867 void __user *user_arg = (void __user *)arg;
858 868
@@ -896,20 +906,21 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un
896} 906}
897 907
898 908
899static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios) 909static void whiteheat_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios)
900{ 910{
901 dbg("%s -port %d", __func__, port->number); 911 firm_setup_port(tty);
902 firm_setup_port(port);
903} 912}
904 913
905 914
906static void whiteheat_break_ctl(struct usb_serial_port *port, int break_state) { 915static void whiteheat_break_ctl(struct tty_struct *tty, int break_state) {
916 struct usb_serial_port *port = tty->driver_data;
907 firm_set_break(port, break_state); 917 firm_set_break(port, break_state);
908} 918}
909 919
910 920
911static int whiteheat_chars_in_buffer(struct usb_serial_port *port) 921static int whiteheat_chars_in_buffer(struct tty_struct *tty)
912{ 922{
923 struct usb_serial_port *port = tty->driver_data;
913 struct whiteheat_private *info = usb_get_serial_port_data(port); 924 struct whiteheat_private *info = usb_get_serial_port_data(port);
914 struct list_head *tmp; 925 struct list_head *tmp;
915 struct whiteheat_urb_wrap *wrap; 926 struct whiteheat_urb_wrap *wrap;
@@ -930,8 +941,9 @@ static int whiteheat_chars_in_buffer(struct usb_serial_port *port)
930} 941}
931 942
932 943
933static void whiteheat_throttle (struct usb_serial_port *port) 944static void whiteheat_throttle (struct tty_struct *tty)
934{ 945{
946 struct usb_serial_port *port = tty->driver_data;
935 struct whiteheat_private *info = usb_get_serial_port_data(port); 947 struct whiteheat_private *info = usb_get_serial_port_data(port);
936 unsigned long flags; 948 unsigned long flags;
937 949
@@ -945,8 +957,9 @@ static void whiteheat_throttle (struct usb_serial_port *port)
945} 957}
946 958
947 959
948static void whiteheat_unthrottle (struct usb_serial_port *port) 960static void whiteheat_unthrottle (struct tty_struct *tty)
949{ 961{
962 struct usb_serial_port *port = tty->driver_data;
950 struct whiteheat_private *info = usb_get_serial_port_data(port); 963 struct whiteheat_private *info = usb_get_serial_port_data(port);
951 int actually_throttled; 964 int actually_throttled;
952 unsigned long flags; 965 unsigned long flags;
@@ -1184,9 +1197,10 @@ static int firm_close(struct usb_serial_port *port) {
1184} 1197}
1185 1198
1186 1199
1187static int firm_setup_port(struct usb_serial_port *port) { 1200static int firm_setup_port(struct tty_struct *tty) {
1201 struct usb_serial_port *port = tty->driver_data;
1188 struct whiteheat_port_settings port_settings; 1202 struct whiteheat_port_settings port_settings;
1189 unsigned int cflag = port->tty->termios->c_cflag; 1203 unsigned int cflag = tty->termios->c_cflag;
1190 1204
1191 port_settings.port = port->number + 1; 1205 port_settings.port = port->number + 1;
1192 1206
@@ -1235,22 +1249,22 @@ static int firm_setup_port(struct usb_serial_port *port) {
1235 (port_settings.hflow & WHITEHEAT_HFLOW_DTR) ? "DTR" : ""); 1249 (port_settings.hflow & WHITEHEAT_HFLOW_DTR) ? "DTR" : "");
1236 1250
1237 /* determine software flow control */ 1251 /* determine software flow control */
1238 if (I_IXOFF(port->tty)) 1252 if (I_IXOFF(tty))
1239 port_settings.sflow = WHITEHEAT_SFLOW_RXTX; 1253 port_settings.sflow = WHITEHEAT_SFLOW_RXTX;
1240 else 1254 else
1241 port_settings.sflow = WHITEHEAT_SFLOW_NONE; 1255 port_settings.sflow = WHITEHEAT_SFLOW_NONE;
1242 dbg("%s - software flow control = %c", __func__, port_settings.sflow); 1256 dbg("%s - software flow control = %c", __func__, port_settings.sflow);
1243 1257
1244 port_settings.xon = START_CHAR(port->tty); 1258 port_settings.xon = START_CHAR(tty);
1245 port_settings.xoff = STOP_CHAR(port->tty); 1259 port_settings.xoff = STOP_CHAR(tty);
1246 dbg("%s - XON = %2x, XOFF = %2x", __func__, port_settings.xon, port_settings.xoff); 1260 dbg("%s - XON = %2x, XOFF = %2x", __func__, port_settings.xon, port_settings.xoff);
1247 1261
1248 /* get the baud rate wanted */ 1262 /* get the baud rate wanted */
1249 port_settings.baud = tty_get_baud_rate(port->tty); 1263 port_settings.baud = tty_get_baud_rate(tty);
1250 dbg("%s - baud rate = %d", __func__, port_settings.baud); 1264 dbg("%s - baud rate = %d", __func__, port_settings.baud);
1251 1265
1252 /* fixme: should set validated settings */ 1266 /* fixme: should set validated settings */
1253 tty_encode_baud_rate(port->tty, port_settings.baud, port_settings.baud); 1267 tty_encode_baud_rate(tty, port_settings.baud, port_settings.baud);
1254 /* handle any settings that aren't specified in the tty structure */ 1268 /* handle any settings that aren't specified in the tty structure */
1255 port_settings.lloop = 0; 1269 port_settings.lloop = 0;
1256 1270
@@ -1426,7 +1440,7 @@ static void rx_data_softint(struct work_struct *work)
1426 struct whiteheat_private *info = 1440 struct whiteheat_private *info =
1427 container_of(work, struct whiteheat_private, rx_work); 1441 container_of(work, struct whiteheat_private, rx_work);
1428 struct usb_serial_port *port = info->port; 1442 struct usb_serial_port *port = info->port;
1429 struct tty_struct *tty = port->tty; 1443 struct tty_struct *tty = port->port.tty;
1430 struct whiteheat_urb_wrap *wrap; 1444 struct whiteheat_urb_wrap *wrap;
1431 struct urb *urb; 1445 struct urb *urb;
1432 unsigned long flags; 1446 unsigned long flags;