aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/cypress_m8.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/cypress_m8.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/cypress_m8.c')
-rw-r--r--drivers/usb/serial/cypress_m8.c117
1 files changed, 64 insertions, 53 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 0230d3c0888a..6999d3372d85 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -167,18 +167,18 @@ static int cypress_earthmate_startup (struct usb_serial *serial);
167static int cypress_hidcom_startup (struct usb_serial *serial); 167static int cypress_hidcom_startup (struct usb_serial *serial);
168static int cypress_ca42v2_startup (struct usb_serial *serial); 168static int cypress_ca42v2_startup (struct usb_serial *serial);
169static void cypress_shutdown (struct usb_serial *serial); 169static void cypress_shutdown (struct usb_serial *serial);
170static int cypress_open (struct usb_serial_port *port, struct file *filp); 170static int cypress_open (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
171static void cypress_close (struct usb_serial_port *port, struct file *filp); 171static void cypress_close (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
172static int cypress_write (struct usb_serial_port *port, const unsigned char *buf, int count); 172static int cypress_write (struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count);
173static void cypress_send (struct usb_serial_port *port); 173static void cypress_send (struct usb_serial_port *port);
174static int cypress_write_room (struct usb_serial_port *port); 174static int cypress_write_room (struct tty_struct *tty);
175static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); 175static int cypress_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
176static void cypress_set_termios (struct usb_serial_port *port, struct ktermios * old); 176static void cypress_set_termios (struct tty_struct *tty, struct usb_serial_port *port, struct ktermios * old);
177static int cypress_tiocmget (struct usb_serial_port *port, struct file *file); 177static int cypress_tiocmget (struct tty_struct *tty, struct file *file);
178static int cypress_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); 178static int cypress_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
179static int cypress_chars_in_buffer (struct usb_serial_port *port); 179static int cypress_chars_in_buffer (struct tty_struct *tty);
180static void cypress_throttle (struct usb_serial_port *port); 180static void cypress_throttle (struct tty_struct *tty);
181static void cypress_unthrottle (struct usb_serial_port *port); 181static void cypress_unthrottle (struct tty_struct *tty);
182static void cypress_set_dead (struct usb_serial_port *port); 182static void cypress_set_dead (struct usb_serial_port *port);
183static void cypress_read_int_callback (struct urb *urb); 183static void cypress_read_int_callback (struct urb *urb);
184static void cypress_write_int_callback (struct urb *urb); 184static void cypress_write_int_callback (struct urb *urb);
@@ -322,8 +322,10 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
322 322
323 323
324/* This function can either set or retrieve the current serial line settings */ 324/* This function can either set or retrieve the current serial line settings */
325static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_rate, int data_bits, int stop_bits, 325static int cypress_serial_control (struct tty_struct *tty,
326 int parity_enable, int parity_type, int reset, int cypress_request_type) 326 struct usb_serial_port *port, speed_t baud_rate, int data_bits,
327 int stop_bits, int parity_enable, int parity_type, int reset,
328 int cypress_request_type)
327{ 329{
328 int new_baudrate = 0, retval = 0, tries = 0; 330 int new_baudrate = 0, retval = 0, tries = 0;
329 struct cypress_private *priv; 331 struct cypress_private *priv;
@@ -395,7 +397,7 @@ static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_ra
395 spin_unlock_irqrestore(&priv->lock, flags); 397 spin_unlock_irqrestore(&priv->lock, flags);
396 /* If we asked for a speed change encode it */ 398 /* If we asked for a speed change encode it */
397 if (baud_rate) 399 if (baud_rate)
398 tty_encode_baud_rate(port->tty, 400 tty_encode_baud_rate(tty,
399 new_baudrate, new_baudrate); 401 new_baudrate, new_baudrate);
400 } 402 }
401 break; 403 break;
@@ -611,7 +613,8 @@ static void cypress_shutdown (struct usb_serial *serial)
611} 613}
612 614
613 615
614static int cypress_open (struct usb_serial_port *port, struct file *filp) 616static int cypress_open(struct tty_struct *tty,
617 struct usb_serial_port *port, struct file *filp)
615{ 618{
616 struct cypress_private *priv = usb_get_serial_port_data(port); 619 struct cypress_private *priv = usb_get_serial_port_data(port);
617 struct usb_serial *serial = port->serial; 620 struct usb_serial *serial = port->serial;
@@ -636,14 +639,15 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
636 spin_unlock_irqrestore(&priv->lock, flags); 639 spin_unlock_irqrestore(&priv->lock, flags);
637 640
638 /* setting to zero could cause data loss */ 641 /* setting to zero could cause data loss */
639 port->tty->low_latency = 1; 642 if (tty)
643 tty->low_latency = 1;
640 644
641 /* raise both lines and set termios */ 645 /* raise both lines and set termios */
642 spin_lock_irqsave(&priv->lock, flags); 646 spin_lock_irqsave(&priv->lock, flags);
643 priv->line_control = CONTROL_DTR | CONTROL_RTS; 647 priv->line_control = CONTROL_DTR | CONTROL_RTS;
644 priv->cmd_ctrl = 1; 648 priv->cmd_ctrl = 1;
645 spin_unlock_irqrestore(&priv->lock, flags); 649 spin_unlock_irqrestore(&priv->lock, flags);
646 result = cypress_write(port, NULL, 0); 650 result = cypress_write(tty, port, NULL, 0);
647 651
648 if (result) { 652 if (result) {
649 dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __func__, result); 653 dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __func__, result);
@@ -651,7 +655,8 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
651 } else 655 } else
652 dbg("%s - success setting the control lines", __func__); 656 dbg("%s - success setting the control lines", __func__);
653 657
654 cypress_set_termios(port, &priv->tmp_termios); 658 if (tty)
659 cypress_set_termios(tty, port, &priv->tmp_termios);
655 660
656 /* setup the port and start reading from the device */ 661 /* setup the port and start reading from the device */
657 if(!port->interrupt_in_urb){ 662 if(!port->interrupt_in_urb){
@@ -674,7 +679,8 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
674} /* cypress_open */ 679} /* cypress_open */
675 680
676 681
677static void cypress_close(struct usb_serial_port *port, struct file * filp) 682static void cypress_close(struct tty_struct *tty,
683 struct usb_serial_port *port, struct file * filp)
678{ 684{
679 struct cypress_private *priv = usb_get_serial_port_data(port); 685 struct cypress_private *priv = usb_get_serial_port_data(port);
680 unsigned int c_cflag; 686 unsigned int c_cflag;
@@ -688,7 +694,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
688 spin_lock_irq(&priv->lock); 694 spin_lock_irq(&priv->lock);
689 timeout = CYPRESS_CLOSING_WAIT; 695 timeout = CYPRESS_CLOSING_WAIT;
690 init_waitqueue_entry(&wait, current); 696 init_waitqueue_entry(&wait, current);
691 add_wait_queue(&port->tty->write_wait, &wait); 697 add_wait_queue(&tty->write_wait, &wait);
692 for (;;) { 698 for (;;) {
693 set_current_state(TASK_INTERRUPTIBLE); 699 set_current_state(TASK_INTERRUPTIBLE);
694 if (cypress_buf_data_avail(priv->buf) == 0 700 if (cypress_buf_data_avail(priv->buf) == 0
@@ -701,7 +707,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
701 spin_lock_irq(&priv->lock); 707 spin_lock_irq(&priv->lock);
702 } 708 }
703 set_current_state(TASK_RUNNING); 709 set_current_state(TASK_RUNNING);
704 remove_wait_queue(&port->tty->write_wait, &wait); 710 remove_wait_queue(&tty->write_wait, &wait);
705 /* clear out any remaining data in the buffer */ 711 /* clear out any remaining data in the buffer */
706 cypress_buf_clear(priv->buf); 712 cypress_buf_clear(priv->buf);
707 spin_unlock_irq(&priv->lock); 713 spin_unlock_irq(&priv->lock);
@@ -713,19 +719,21 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
713 return; 719 return;
714 } 720 }
715 /* wait for characters to drain from device */ 721 /* wait for characters to drain from device */
716 bps = tty_get_baud_rate(port->tty); 722 if (tty) {
717 if (bps > 1200) 723 bps = tty_get_baud_rate(tty);
718 timeout = max((HZ*2560)/bps,HZ/10); 724 if (bps > 1200)
719 else 725 timeout = max((HZ*2560)/bps,HZ/10);
720 timeout = 2*HZ; 726 else
721 schedule_timeout_interruptible(timeout); 727 timeout = 2*HZ;
728 schedule_timeout_interruptible(timeout);
729 }
722 730
723 dbg("%s - stopping urbs", __func__); 731 dbg("%s - stopping urbs", __func__);
724 usb_kill_urb (port->interrupt_in_urb); 732 usb_kill_urb (port->interrupt_in_urb);
725 usb_kill_urb (port->interrupt_out_urb); 733 usb_kill_urb (port->interrupt_out_urb);
726 734
727 if (port->tty) { 735 if (tty) {
728 c_cflag = port->tty->termios->c_cflag; 736 c_cflag = tty->termios->c_cflag;
729 if (c_cflag & HUPCL) { 737 if (c_cflag & HUPCL) {
730 /* drop dtr and rts */ 738 /* drop dtr and rts */
731 priv = usb_get_serial_port_data(port); 739 priv = usb_get_serial_port_data(port);
@@ -733,7 +741,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
733 priv->line_control = 0; 741 priv->line_control = 0;
734 priv->cmd_ctrl = 1; 742 priv->cmd_ctrl = 1;
735 spin_unlock_irq(&priv->lock); 743 spin_unlock_irq(&priv->lock);
736 cypress_write(port, NULL, 0); 744 cypress_write(tty, port, NULL, 0);
737 } 745 }
738 } 746 }
739 747
@@ -744,7 +752,8 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
744} /* cypress_close */ 752} /* cypress_close */
745 753
746 754
747static int cypress_write(struct usb_serial_port *port, const unsigned char *buf, int count) 755static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
756 const unsigned char *buf, int count)
748{ 757{
749 struct cypress_private *priv = usb_get_serial_port_data(port); 758 struct cypress_private *priv = usb_get_serial_port_data(port);
750 unsigned long flags; 759 unsigned long flags;
@@ -878,8 +887,9 @@ send:
878 887
879 888
880/* returns how much space is available in the soft buffer */ 889/* returns how much space is available in the soft buffer */
881static int cypress_write_room(struct usb_serial_port *port) 890static int cypress_write_room(struct tty_struct *tty)
882{ 891{
892 struct usb_serial_port *port = tty->driver_data;
883 struct cypress_private *priv = usb_get_serial_port_data(port); 893 struct cypress_private *priv = usb_get_serial_port_data(port);
884 int room = 0; 894 int room = 0;
885 unsigned long flags; 895 unsigned long flags;
@@ -895,8 +905,9 @@ static int cypress_write_room(struct usb_serial_port *port)
895} 905}
896 906
897 907
898static int cypress_tiocmget (struct usb_serial_port *port, struct file *file) 908static int cypress_tiocmget(struct tty_struct *tty, struct file *file)
899{ 909{
910 struct usb_serial_port *port = tty->driver_data;
900 struct cypress_private *priv = usb_get_serial_port_data(port); 911 struct cypress_private *priv = usb_get_serial_port_data(port);
901 __u8 status, control; 912 __u8 status, control;
902 unsigned int result = 0; 913 unsigned int result = 0;
@@ -922,9 +933,10 @@ static int cypress_tiocmget (struct usb_serial_port *port, struct file *file)
922} 933}
923 934
924 935
925static int cypress_tiocmset (struct usb_serial_port *port, struct file *file, 936static int cypress_tiocmset(struct tty_struct *tty, struct file *file,
926 unsigned int set, unsigned int clear) 937 unsigned int set, unsigned int clear)
927{ 938{
939 struct usb_serial_port *port = tty->driver_data;
928 struct cypress_private *priv = usb_get_serial_port_data(port); 940 struct cypress_private *priv = usb_get_serial_port_data(port);
929 unsigned long flags; 941 unsigned long flags;
930 942
@@ -942,12 +954,14 @@ static int cypress_tiocmset (struct usb_serial_port *port, struct file *file,
942 priv->cmd_ctrl = 1; 954 priv->cmd_ctrl = 1;
943 spin_unlock_irqrestore(&priv->lock, flags); 955 spin_unlock_irqrestore(&priv->lock, flags);
944 956
945 return cypress_write(port, NULL, 0); 957 return cypress_write(tty, port, NULL, 0);
946} 958}
947 959
948 960
949static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) 961static int cypress_ioctl(struct tty_struct *tty, struct file * file,
962 unsigned int cmd, unsigned long arg)
950{ 963{
964 struct usb_serial_port *port = tty->driver_data;
951 struct cypress_private *priv = usb_get_serial_port_data(port); 965 struct cypress_private *priv = usb_get_serial_port_data(port);
952 966
953 dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); 967 dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
@@ -983,22 +997,18 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi
983 } 997 }
984 } 998 }
985 return 0; 999 return 0;
986 break;
987 default: 1000 default:
988 break; 1001 break;
989 } 1002 }
990
991 dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __func__, cmd); 1003 dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __func__, cmd);
992
993 return -ENOIOCTLCMD; 1004 return -ENOIOCTLCMD;
994} /* cypress_ioctl */ 1005} /* cypress_ioctl */
995 1006
996 1007
997static void cypress_set_termios (struct usb_serial_port *port, 1008static void cypress_set_termios(struct tty_struct *tty,
998 struct ktermios *old_termios) 1009 struct usb_serial_port *port, struct ktermios *old_termios)
999{ 1010{
1000 struct cypress_private *priv = usb_get_serial_port_data(port); 1011 struct cypress_private *priv = usb_get_serial_port_data(port);
1001 struct tty_struct *tty;
1002 int data_bits, stop_bits, parity_type, parity_enable; 1012 int data_bits, stop_bits, parity_type, parity_enable;
1003 unsigned cflag, iflag; 1013 unsigned cflag, iflag;
1004 unsigned long flags; 1014 unsigned long flags;
@@ -1007,8 +1017,6 @@ static void cypress_set_termios (struct usb_serial_port *port,
1007 1017
1008 dbg("%s - port %d", __func__, port->number); 1018 dbg("%s - port %d", __func__, port->number);
1009 1019
1010 tty = port->tty;
1011
1012 spin_lock_irqsave(&priv->lock, flags); 1020 spin_lock_irqsave(&priv->lock, flags);
1013 if (!priv->termios_initialized) { 1021 if (!priv->termios_initialized) {
1014 if (priv->chiptype == CT_EARTHMATE) { 1022 if (priv->chiptype == CT_EARTHMATE) {
@@ -1096,13 +1104,13 @@ static void cypress_set_termios (struct usb_serial_port *port,
1096 "%d data_bits (+5)", __func__, stop_bits, 1104 "%d data_bits (+5)", __func__, stop_bits,
1097 parity_enable, parity_type, data_bits); 1105 parity_enable, parity_type, data_bits);
1098 1106
1099 cypress_serial_control(port, tty_get_baud_rate(tty), data_bits, stop_bits, 1107 cypress_serial_control(tty, port, tty_get_baud_rate(tty), data_bits, stop_bits,
1100 parity_enable, parity_type, 0, CYPRESS_SET_CONFIG); 1108 parity_enable, parity_type, 0, CYPRESS_SET_CONFIG);
1101 1109
1102 /* we perform a CYPRESS_GET_CONFIG so that the current settings are 1110 /* we perform a CYPRESS_GET_CONFIG so that the current settings are
1103 * filled into the private structure this should confirm that all is 1111 * filled into the private structure this should confirm that all is
1104 * working if it returns what we just set */ 1112 * working if it returns what we just set */
1105 cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG); 1113 cypress_serial_control(tty, port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
1106 1114
1107 /* Here we can define custom tty settings for devices; the main tty 1115 /* Here we can define custom tty settings for devices; the main tty
1108 * termios flag base comes from empeg.c */ 1116 * termios flag base comes from empeg.c */
@@ -1142,14 +1150,15 @@ static void cypress_set_termios (struct usb_serial_port *port,
1142 /* if necessary, set lines */ 1150 /* if necessary, set lines */
1143 if (linechange) { 1151 if (linechange) {
1144 priv->cmd_ctrl = 1; 1152 priv->cmd_ctrl = 1;
1145 cypress_write(port, NULL, 0); 1153 cypress_write(tty, port, NULL, 0);
1146 } 1154 }
1147} /* cypress_set_termios */ 1155} /* cypress_set_termios */
1148 1156
1149 1157
1150/* returns amount of data still left in soft buffer */ 1158/* returns amount of data still left in soft buffer */
1151static int cypress_chars_in_buffer(struct usb_serial_port *port) 1159static int cypress_chars_in_buffer(struct tty_struct *tty)
1152{ 1160{
1161 struct usb_serial_port *port = tty->driver_data;
1153 struct cypress_private *priv = usb_get_serial_port_data(port); 1162 struct cypress_private *priv = usb_get_serial_port_data(port);
1154 int chars = 0; 1163 int chars = 0;
1155 unsigned long flags; 1164 unsigned long flags;
@@ -1165,8 +1174,9 @@ static int cypress_chars_in_buffer(struct usb_serial_port *port)
1165} 1174}
1166 1175
1167 1176
1168static void cypress_throttle (struct usb_serial_port *port) 1177static void cypress_throttle(struct tty_struct *tty)
1169{ 1178{
1179 struct usb_serial_port *port = tty->driver_data;
1170 struct cypress_private *priv = usb_get_serial_port_data(port); 1180 struct cypress_private *priv = usb_get_serial_port_data(port);
1171 unsigned long flags; 1181 unsigned long flags;
1172 1182
@@ -1178,8 +1188,9 @@ static void cypress_throttle (struct usb_serial_port *port)
1178} 1188}
1179 1189
1180 1190
1181static void cypress_unthrottle (struct usb_serial_port *port) 1191static void cypress_unthrottle(struct tty_struct *tty)
1182{ 1192{
1193 struct usb_serial_port *port = tty->driver_data;
1183 struct cypress_private *priv = usb_get_serial_port_data(port); 1194 struct cypress_private *priv = usb_get_serial_port_data(port);
1184 int actually_throttled, result; 1195 int actually_throttled, result;
1185 unsigned long flags; 1196 unsigned long flags;
@@ -1251,7 +1262,7 @@ static void cypress_read_int_callback(struct urb *urb)
1251 } 1262 }
1252 spin_unlock_irqrestore(&priv->lock, flags); 1263 spin_unlock_irqrestore(&priv->lock, flags);
1253 1264
1254 tty = port->tty; 1265 tty = port->port.tty;
1255 if (!tty) { 1266 if (!tty) {
1256 dbg("%s - bad tty pointer - exiting", __func__); 1267 dbg("%s - bad tty pointer - exiting", __func__);
1257 return; 1268 return;
@@ -1327,7 +1338,7 @@ static void cypress_read_int_callback(struct urb *urb)
1327 data[i]); 1338 data[i]);
1328 tty_insert_flip_char(tty, data[i], tty_flag); 1339 tty_insert_flip_char(tty, data[i], tty_flag);
1329 } 1340 }
1330 tty_flip_buffer_push(port->tty); 1341 tty_flip_buffer_push(port->port.tty);
1331 } 1342 }
1332 1343
1333 spin_lock_irqsave(&priv->lock, flags); 1344 spin_lock_irqsave(&priv->lock, flags);
@@ -1339,7 +1350,7 @@ continue_read:
1339 1350
1340 /* Continue trying to always read... unless the port has closed. */ 1351 /* Continue trying to always read... unless the port has closed. */
1341 1352
1342 if (port->open_count > 0 && priv->comm_is_ok) { 1353 if (port->port.count > 0 && priv->comm_is_ok) {
1343 usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, 1354 usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
1344 usb_rcvintpipe(port->serial->dev, 1355 usb_rcvintpipe(port->serial->dev,
1345 port->interrupt_in_endpointAddress), 1356 port->interrupt_in_endpointAddress),