aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/keyspan.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/keyspan.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/keyspan.c')
-rw-r--r--drivers/usb/serial/keyspan.c138
1 files changed, 57 insertions, 81 deletions
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 11e439b90eac..a371c41bb3ab 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -244,20 +244,9 @@ static void __exit keyspan_exit (void)
244module_init(keyspan_init); 244module_init(keyspan_init);
245module_exit(keyspan_exit); 245module_exit(keyspan_exit);
246 246
247static void keyspan_rx_throttle (struct usb_serial_port *port) 247static void keyspan_break_ctl(struct tty_struct *tty, int break_state)
248{
249 dbg("%s - port %d", __func__, port->number);
250}
251
252
253static void keyspan_rx_unthrottle (struct usb_serial_port *port)
254{
255 dbg("%s - port %d", __func__, port->number);
256}
257
258
259static void keyspan_break_ctl (struct usb_serial_port *port, int break_state)
260{ 248{
249 struct usb_serial_port *port = tty->driver_data;
261 struct keyspan_port_private *p_priv; 250 struct keyspan_port_private *p_priv;
262 251
263 dbg("%s", __func__); 252 dbg("%s", __func__);
@@ -273,14 +262,13 @@ static void keyspan_break_ctl (struct usb_serial_port *port, int break_state)
273} 262}
274 263
275 264
276static void keyspan_set_termios (struct usb_serial_port *port, 265static void keyspan_set_termios (struct tty_struct *tty,
277 struct ktermios *old_termios) 266 struct usb_serial_port *port, struct ktermios *old_termios)
278{ 267{
279 int baud_rate, device_port; 268 int baud_rate, device_port;
280 struct keyspan_port_private *p_priv; 269 struct keyspan_port_private *p_priv;
281 const struct keyspan_device_details *d_details; 270 const struct keyspan_device_details *d_details;
282 unsigned int cflag; 271 unsigned int cflag;
283 struct tty_struct *tty = port->tty;
284 272
285 dbg("%s", __func__); 273 dbg("%s", __func__);
286 274
@@ -312,12 +300,11 @@ static void keyspan_set_termios (struct usb_serial_port *port,
312 keyspan_send_setup(port, 0); 300 keyspan_send_setup(port, 0);
313} 301}
314 302
315static int keyspan_tiocmget(struct usb_serial_port *port, struct file *file) 303static int keyspan_tiocmget(struct tty_struct *tty, struct file *file)
316{ 304{
305 struct usb_serial_port *port = tty->driver_data;
306 struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);
317 unsigned int value; 307 unsigned int value;
318 struct keyspan_port_private *p_priv;
319
320 p_priv = usb_get_serial_port_data(port);
321 308
322 value = ((p_priv->rts_state) ? TIOCM_RTS : 0) | 309 value = ((p_priv->rts_state) ? TIOCM_RTS : 0) |
323 ((p_priv->dtr_state) ? TIOCM_DTR : 0) | 310 ((p_priv->dtr_state) ? TIOCM_DTR : 0) |
@@ -329,18 +316,16 @@ static int keyspan_tiocmget(struct usb_serial_port *port, struct file *file)
329 return value; 316 return value;
330} 317}
331 318
332static int keyspan_tiocmset(struct usb_serial_port *port, struct file *file, 319static int keyspan_tiocmset(struct tty_struct *tty, struct file *file,
333 unsigned int set, unsigned int clear) 320 unsigned int set, unsigned int clear)
334{ 321{
335 struct keyspan_port_private *p_priv; 322 struct usb_serial_port *port = tty->driver_data;
336 323 struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);
337 p_priv = usb_get_serial_port_data(port);
338 324
339 if (set & TIOCM_RTS) 325 if (set & TIOCM_RTS)
340 p_priv->rts_state = 1; 326 p_priv->rts_state = 1;
341 if (set & TIOCM_DTR) 327 if (set & TIOCM_DTR)
342 p_priv->dtr_state = 1; 328 p_priv->dtr_state = 1;
343
344 if (clear & TIOCM_RTS) 329 if (clear & TIOCM_RTS)
345 p_priv->rts_state = 0; 330 p_priv->rts_state = 0;
346 if (clear & TIOCM_DTR) 331 if (clear & TIOCM_DTR)
@@ -349,16 +334,10 @@ static int keyspan_tiocmset(struct usb_serial_port *port, struct file *file,
349 return 0; 334 return 0;
350} 335}
351 336
352static int keyspan_ioctl(struct usb_serial_port *port, struct file *file, 337/* Write function is similar for the four protocols used
353 unsigned int cmd, unsigned long arg) 338 with only a minor change for usa90 (usa19hs) required */
354{ 339static int keyspan_write(struct tty_struct *tty,
355 return -ENOIOCTLCMD; 340 struct usb_serial_port *port, const unsigned char *buf, int count)
356}
357
358 /* Write function is similar for the four protocols used
359 with only a minor change for usa90 (usa19hs) required */
360static int keyspan_write(struct usb_serial_port *port,
361 const unsigned char *buf, int count)
362{ 341{
363 struct keyspan_port_private *p_priv; 342 struct keyspan_port_private *p_priv;
364 const struct keyspan_device_details *d_details; 343 const struct keyspan_device_details *d_details;
@@ -448,7 +427,7 @@ static void usa26_indat_callback(struct urb *urb)
448 } 427 }
449 428
450 port = urb->context; 429 port = urb->context;
451 tty = port->tty; 430 tty = port->port.tty;
452 if (tty && urb->actual_length) { 431 if (tty && urb->actual_length) {
453 /* 0x80 bit is error flag */ 432 /* 0x80 bit is error flag */
454 if ((data[0] & 0x80) == 0) { 433 if ((data[0] & 0x80) == 0) {
@@ -479,7 +458,7 @@ static void usa26_indat_callback(struct urb *urb)
479 458
480 /* Resubmit urb so we continue receiving */ 459 /* Resubmit urb so we continue receiving */
481 urb->dev = port->serial->dev; 460 urb->dev = port->serial->dev;
482 if (port->open_count) 461 if (port->port.count)
483 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { 462 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
484 dbg("%s - resubmit read urb failed. (%d)", __func__, err); 463 dbg("%s - resubmit read urb failed. (%d)", __func__, err);
485 } 464 }
@@ -496,7 +475,7 @@ static void usa2x_outdat_callback(struct urb *urb)
496 p_priv = usb_get_serial_port_data(port); 475 p_priv = usb_get_serial_port_data(port);
497 dbg ("%s - urb %d", __func__, urb == p_priv->out_urbs[1]); 476 dbg ("%s - urb %d", __func__, urb == p_priv->out_urbs[1]);
498 477
499 if (port->open_count) 478 if (port->port.count)
500 usb_serial_port_softint(port); 479 usb_serial_port_softint(port);
501} 480}
502 481
@@ -567,10 +546,10 @@ static void usa26_instat_callback(struct urb *urb)
567 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); 546 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
568 p_priv->ri_state = ((msg->ri) ? 1 : 0); 547 p_priv->ri_state = ((msg->ri) ? 1 : 0);
569 548
570 if (port->tty && !C_CLOCAL(port->tty) 549 if (port->port.tty && !C_CLOCAL(port->port.tty)
571 && old_dcd_state != p_priv->dcd_state) { 550 && old_dcd_state != p_priv->dcd_state) {
572 if (old_dcd_state) 551 if (old_dcd_state)
573 tty_hangup(port->tty); 552 tty_hangup(port->port.tty);
574 /* else */ 553 /* else */
575 /* wake_up_interruptible(&p_priv->open_wait); */ 554 /* wake_up_interruptible(&p_priv->open_wait); */
576 } 555 }
@@ -619,7 +598,7 @@ static void usa28_indat_callback(struct urb *urb)
619 p_priv = usb_get_serial_port_data(port); 598 p_priv = usb_get_serial_port_data(port);
620 data = urb->transfer_buffer; 599 data = urb->transfer_buffer;
621 600
622 tty = port->tty; 601 tty = port->port.tty;
623 if (urb->actual_length) { 602 if (urb->actual_length) {
624 for (i = 0; i < urb->actual_length ; ++i) { 603 for (i = 0; i < urb->actual_length ; ++i) {
625 tty_insert_flip_char(tty, data[i], 0); 604 tty_insert_flip_char(tty, data[i], 0);
@@ -629,7 +608,7 @@ static void usa28_indat_callback(struct urb *urb)
629 608
630 /* Resubmit urb so we continue receiving */ 609 /* Resubmit urb so we continue receiving */
631 urb->dev = port->serial->dev; 610 urb->dev = port->serial->dev;
632 if (port->open_count) 611 if (port->port.count)
633 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { 612 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
634 dbg("%s - resubmit read urb failed. (%d)", __func__, err); 613 dbg("%s - resubmit read urb failed. (%d)", __func__, err);
635 } 614 }
@@ -704,10 +683,10 @@ static void usa28_instat_callback(struct urb *urb)
704 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 683 p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
705 p_priv->ri_state = ((msg->ri) ? 1 : 0); 684 p_priv->ri_state = ((msg->ri) ? 1 : 0);
706 685
707 if (port->tty && !C_CLOCAL(port->tty) 686 if (port->port.tty && !C_CLOCAL(port->port.tty)
708 && old_dcd_state != p_priv->dcd_state) { 687 && old_dcd_state != p_priv->dcd_state) {
709 if (old_dcd_state) 688 if (old_dcd_state)
710 tty_hangup(port->tty); 689 tty_hangup(port->port.tty);
711 /* else */ 690 /* else */
712 /* wake_up_interruptible(&p_priv->open_wait); */ 691 /* wake_up_interruptible(&p_priv->open_wait); */
713 } 692 }
@@ -797,10 +776,10 @@ static void usa49_instat_callback(struct urb *urb)
797 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 776 p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
798 p_priv->ri_state = ((msg->ri) ? 1 : 0); 777 p_priv->ri_state = ((msg->ri) ? 1 : 0);
799 778
800 if (port->tty && !C_CLOCAL(port->tty) 779 if (port->port.tty && !C_CLOCAL(port->port.tty)
801 && old_dcd_state != p_priv->dcd_state) { 780 && old_dcd_state != p_priv->dcd_state) {
802 if (old_dcd_state) 781 if (old_dcd_state)
803 tty_hangup(port->tty); 782 tty_hangup(port->port.tty);
804 /* else */ 783 /* else */
805 /* wake_up_interruptible(&p_priv->open_wait); */ 784 /* wake_up_interruptible(&p_priv->open_wait); */
806 } 785 }
@@ -839,7 +818,7 @@ static void usa49_indat_callback(struct urb *urb)
839 } 818 }
840 819
841 port = urb->context; 820 port = urb->context;
842 tty = port->tty; 821 tty = port->port.tty;
843 if (tty && urb->actual_length) { 822 if (tty && urb->actual_length) {
844 /* 0x80 bit is error flag */ 823 /* 0x80 bit is error flag */
845 if ((data[0] & 0x80) == 0) { 824 if ((data[0] & 0x80) == 0) {
@@ -866,7 +845,7 @@ static void usa49_indat_callback(struct urb *urb)
866 845
867 /* Resubmit urb so we continue receiving */ 846 /* Resubmit urb so we continue receiving */
868 urb->dev = port->serial->dev; 847 urb->dev = port->serial->dev;
869 if (port->open_count) 848 if (port->port.count)
870 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { 849 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
871 dbg("%s - resubmit read urb failed. (%d)", __func__, err); 850 dbg("%s - resubmit read urb failed. (%d)", __func__, err);
872 } 851 }
@@ -904,7 +883,7 @@ static void usa49wg_indat_callback(struct urb *urb)
904 return; 883 return;
905 } 884 }
906 port = serial->port[data[i++]]; 885 port = serial->port[data[i++]];
907 tty = port->tty; 886 tty = port->port.tty;
908 len = data[i++]; 887 len = data[i++];
909 888
910 /* 0x80 bit is error flag */ 889 /* 0x80 bit is error flag */
@@ -912,7 +891,7 @@ static void usa49wg_indat_callback(struct urb *urb)
912 /* no error on any byte */ 891 /* no error on any byte */
913 i++; 892 i++;
914 for (x = 1; x < len ; ++x) 893 for (x = 1; x < len ; ++x)
915 if (port->open_count) 894 if (port->port.count)
916 tty_insert_flip_char(tty, 895 tty_insert_flip_char(tty,
917 data[i++], 0); 896 data[i++], 0);
918 else 897 else
@@ -930,13 +909,13 @@ static void usa49wg_indat_callback(struct urb *urb)
930 if (stat & RXERROR_PARITY) 909 if (stat & RXERROR_PARITY)
931 flag |= TTY_PARITY; 910 flag |= TTY_PARITY;
932 /* XXX should handle break (0x10) */ 911 /* XXX should handle break (0x10) */
933 if (port->open_count) 912 if (port->port.count)
934 tty_insert_flip_char(tty, 913 tty_insert_flip_char(tty,
935 data[i+1], flag); 914 data[i+1], flag);
936 i += 2; 915 i += 2;
937 } 916 }
938 } 917 }
939 if (port->open_count) 918 if (port->port.count)
940 tty_flip_buffer_push(tty); 919 tty_flip_buffer_push(tty);
941 } 920 }
942 } 921 }
@@ -978,7 +957,7 @@ static void usa90_indat_callback(struct urb *urb)
978 port = urb->context; 957 port = urb->context;
979 p_priv = usb_get_serial_port_data(port); 958 p_priv = usb_get_serial_port_data(port);
980 959
981 tty = port->tty; 960 tty = port->port.tty;
982 if (urb->actual_length) { 961 if (urb->actual_length) {
983 962
984 /* if current mode is DMA, looks like usa28 format 963 /* if current mode is DMA, looks like usa28 format
@@ -1021,7 +1000,7 @@ static void usa90_indat_callback(struct urb *urb)
1021 1000
1022 /* Resubmit urb so we continue receiving */ 1001 /* Resubmit urb so we continue receiving */
1023 urb->dev = port->serial->dev; 1002 urb->dev = port->serial->dev;
1024 if (port->open_count) 1003 if (port->port.count)
1025 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { 1004 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
1026 dbg("%s - resubmit read urb failed. (%d)", __func__, err); 1005 dbg("%s - resubmit read urb failed. (%d)", __func__, err);
1027 } 1006 }
@@ -1064,10 +1043,10 @@ static void usa90_instat_callback(struct urb *urb)
1064 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 1043 p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
1065 p_priv->ri_state = ((msg->ri) ? 1 : 0); 1044 p_priv->ri_state = ((msg->ri) ? 1 : 0);
1066 1045
1067 if (port->tty && !C_CLOCAL(port->tty) 1046 if (port->port.tty && !C_CLOCAL(port->port.tty)
1068 && old_dcd_state != p_priv->dcd_state) { 1047 && old_dcd_state != p_priv->dcd_state) {
1069 if (old_dcd_state) 1048 if (old_dcd_state)
1070 tty_hangup(port->tty); 1049 tty_hangup(port->port.tty);
1071 /* else */ 1050 /* else */
1072 /* wake_up_interruptible(&p_priv->open_wait); */ 1051 /* wake_up_interruptible(&p_priv->open_wait); */
1073 } 1052 }
@@ -1139,10 +1118,10 @@ static void usa67_instat_callback(struct urb *urb)
1139 p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); 1118 p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
1140 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); 1119 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
1141 1120
1142 if (port->tty && !C_CLOCAL(port->tty) 1121 if (port->port.tty && !C_CLOCAL(port->port.tty)
1143 && old_dcd_state != p_priv->dcd_state) { 1122 && old_dcd_state != p_priv->dcd_state) {
1144 if (old_dcd_state) 1123 if (old_dcd_state)
1145 tty_hangup(port->tty); 1124 tty_hangup(port->port.tty);
1146 /* else */ 1125 /* else */
1147 /* wake_up_interruptible(&p_priv->open_wait); */ 1126 /* wake_up_interruptible(&p_priv->open_wait); */
1148 } 1127 }
@@ -1177,8 +1156,9 @@ static void usa67_glocont_callback(struct urb *urb)
1177 } 1156 }
1178} 1157}
1179 1158
1180static int keyspan_write_room (struct usb_serial_port *port) 1159static int keyspan_write_room(struct tty_struct *tty)
1181{ 1160{
1161 struct usb_serial_port *port = tty->driver_data;
1182 struct keyspan_port_private *p_priv; 1162 struct keyspan_port_private *p_priv;
1183 const struct keyspan_device_details *d_details; 1163 const struct keyspan_device_details *d_details;
1184 int flip; 1164 int flip;
@@ -1210,13 +1190,8 @@ static int keyspan_write_room (struct usb_serial_port *port)
1210} 1190}
1211 1191
1212 1192
1213static int keyspan_chars_in_buffer (struct usb_serial_port *port) 1193static int keyspan_open(struct tty_struct *tty,
1214{ 1194 struct usb_serial_port *port, struct file *filp)
1215 return 0;
1216}
1217
1218
1219static int keyspan_open (struct usb_serial_port *port, struct file *filp)
1220{ 1195{
1221 struct keyspan_port_private *p_priv; 1196 struct keyspan_port_private *p_priv;
1222 struct keyspan_serial_private *s_priv; 1197 struct keyspan_serial_private *s_priv;
@@ -1225,7 +1200,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
1225 int i, err; 1200 int i, err;
1226 int baud_rate, device_port; 1201 int baud_rate, device_port;
1227 struct urb *urb; 1202 struct urb *urb;
1228 unsigned int cflag; 1203 unsigned int cflag = 0;
1229 1204
1230 s_priv = usb_get_serial_data(serial); 1205 s_priv = usb_get_serial_data(serial);
1231 p_priv = usb_get_serial_port_data(port); 1206 p_priv = usb_get_serial_port_data(port);
@@ -1271,19 +1246,19 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
1271 /* get the terminal config for the setup message now so we don't 1246 /* get the terminal config for the setup message now so we don't
1272 * need to send 2 of them */ 1247 * need to send 2 of them */
1273 1248
1274 cflag = port->tty->termios->c_cflag;
1275 device_port = port->number - port->serial->minor; 1249 device_port = port->number - port->serial->minor;
1276 1250 if (tty) {
1277 /* Baud rate calculation takes baud rate as an integer 1251 cflag = tty->termios->c_cflag;
1278 so other rates can be generated if desired. */ 1252 /* Baud rate calculation takes baud rate as an integer
1279 baud_rate = tty_get_baud_rate(port->tty); 1253 so other rates can be generated if desired. */
1280 /* If no match or invalid, leave as default */ 1254 baud_rate = tty_get_baud_rate(tty);
1281 if (baud_rate >= 0 1255 /* If no match or invalid, leave as default */
1282 && d_details->calculate_baud_rate(baud_rate, d_details->baudclk, 1256 if (baud_rate >= 0
1283 NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) { 1257 && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
1284 p_priv->baud = baud_rate; 1258 NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
1259 p_priv->baud = baud_rate;
1260 }
1285 } 1261 }
1286
1287 /* set CTS/RTS handshake etc. */ 1262 /* set CTS/RTS handshake etc. */
1288 p_priv->cflag = cflag; 1263 p_priv->cflag = cflag;
1289 p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none; 1264 p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
@@ -1301,7 +1276,8 @@ static inline void stop_urb(struct urb *urb)
1301 usb_kill_urb(urb); 1276 usb_kill_urb(urb);
1302} 1277}
1303 1278
1304static void keyspan_close(struct usb_serial_port *port, struct file *filp) 1279static void keyspan_close(struct tty_struct *tty,
1280 struct usb_serial_port *port, struct file *filp)
1305{ 1281{
1306 int i; 1282 int i;
1307 struct usb_serial *serial = port->serial; 1283 struct usb_serial *serial = port->serial;
@@ -1338,7 +1314,7 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
1338 stop_urb(p_priv->out_urbs[i]); 1314 stop_urb(p_priv->out_urbs[i]);
1339 } 1315 }
1340 } 1316 }
1341 port->tty = NULL; 1317 port->port.tty = NULL;
1342} 1318}
1343 1319
1344 /* download the firmware to a pre-renumeration device */ 1320 /* download the firmware to a pre-renumeration device */
@@ -2427,7 +2403,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
2427 } 2403 }
2428 /* Sending intermediate configs */ 2404 /* Sending intermediate configs */
2429 else { 2405 else {
2430 if (port->open_count) 2406 if (port->port.count)
2431 msg.portEnabled = 1; 2407 msg.portEnabled = 1;
2432 msg.txBreak = (p_priv->break_on); 2408 msg.txBreak = (p_priv->break_on);
2433 } 2409 }