aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/pl2303.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/pl2303.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/pl2303.c')
-rw-r--r--drivers/usb/serial/pl2303.c76
1 files changed, 41 insertions, 35 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 2a0dd1b50dc4..a0016725d314 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -458,8 +458,8 @@ static void pl2303_send(struct usb_serial_port *port)
458 usb_serial_port_softint(port); 458 usb_serial_port_softint(port);
459} 459}
460 460
461static int pl2303_write(struct usb_serial_port *port, const unsigned char *buf, 461static int pl2303_write(struct tty_struct *tty, struct usb_serial_port *port,
462 int count) 462 const unsigned char *buf, int count)
463{ 463{
464 struct pl2303_private *priv = usb_get_serial_port_data(port); 464 struct pl2303_private *priv = usb_get_serial_port_data(port);
465 unsigned long flags; 465 unsigned long flags;
@@ -478,8 +478,9 @@ static int pl2303_write(struct usb_serial_port *port, const unsigned char *buf,
478 return count; 478 return count;
479} 479}
480 480
481static int pl2303_write_room(struct usb_serial_port *port) 481static int pl2303_write_room(struct tty_struct *tty)
482{ 482{
483 struct usb_serial_port *port = tty->driver_data;
483 struct pl2303_private *priv = usb_get_serial_port_data(port); 484 struct pl2303_private *priv = usb_get_serial_port_data(port);
484 int room = 0; 485 int room = 0;
485 unsigned long flags; 486 unsigned long flags;
@@ -494,8 +495,9 @@ static int pl2303_write_room(struct usb_serial_port *port)
494 return room; 495 return room;
495} 496}
496 497
497static int pl2303_chars_in_buffer(struct usb_serial_port *port) 498static int pl2303_chars_in_buffer(struct tty_struct *tty)
498{ 499{
500 struct usb_serial_port *port = tty->driver_data;
499 struct pl2303_private *priv = usb_get_serial_port_data(port); 501 struct pl2303_private *priv = usb_get_serial_port_data(port);
500 int chars = 0; 502 int chars = 0;
501 unsigned long flags; 503 unsigned long flags;
@@ -510,8 +512,8 @@ static int pl2303_chars_in_buffer(struct usb_serial_port *port)
510 return chars; 512 return chars;
511} 513}
512 514
513static void pl2303_set_termios(struct usb_serial_port *port, 515static void pl2303_set_termios(struct tty_struct *tty,
514 struct ktermios *old_termios) 516 struct usb_serial_port *port, struct ktermios *old_termios)
515{ 517{
516 struct usb_serial *serial = port->serial; 518 struct usb_serial *serial = port->serial;
517 struct pl2303_private *priv = usb_get_serial_port_data(port); 519 struct pl2303_private *priv = usb_get_serial_port_data(port);
@@ -526,11 +528,10 @@ static void pl2303_set_termios(struct usb_serial_port *port,
526 528
527 spin_lock_irqsave(&priv->lock, flags); 529 spin_lock_irqsave(&priv->lock, flags);
528 if (!priv->termios_initialized) { 530 if (!priv->termios_initialized) {
529 *(port->tty->termios) = tty_std_termios; 531 *(tty->termios) = tty_std_termios;
530 port->tty->termios->c_cflag = B9600 | CS8 | CREAD | 532 tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
531 HUPCL | CLOCAL; 533 tty->termios->c_ispeed = 9600;
532 port->tty->termios->c_ispeed = 9600; 534 tty->termios->c_ospeed = 9600;
533 port->tty->termios->c_ospeed = 9600;
534 priv->termios_initialized = 1; 535 priv->termios_initialized = 1;
535 } 536 }
536 spin_unlock_irqrestore(&priv->lock, flags); 537 spin_unlock_irqrestore(&priv->lock, flags);
@@ -539,16 +540,16 @@ static void pl2303_set_termios(struct usb_serial_port *port,
539 serial settings even to the same values as before. Thus 540 serial settings even to the same values as before. Thus
540 we actually need to filter in this specific case */ 541 we actually need to filter in this specific case */
541 542
542 if (!tty_termios_hw_change(port->tty->termios, old_termios)) 543 if (!tty_termios_hw_change(tty->termios, old_termios))
543 return; 544 return;
544 545
545 cflag = port->tty->termios->c_cflag; 546 cflag = tty->termios->c_cflag;
546 547
547 buf = kzalloc(7, GFP_KERNEL); 548 buf = kzalloc(7, GFP_KERNEL);
548 if (!buf) { 549 if (!buf) {
549 dev_err(&port->dev, "%s - out of memory.\n", __func__); 550 dev_err(&port->dev, "%s - out of memory.\n", __func__);
550 /* Report back no change occurred */ 551 /* Report back no change occurred */
551 *port->tty->termios = *old_termios; 552 *tty->termios = *old_termios;
552 return; 553 return;
553 } 554 }
554 555
@@ -569,7 +570,7 @@ static void pl2303_set_termios(struct usb_serial_port *port,
569 dbg("%s - data bits = %d", __func__, buf[6]); 570 dbg("%s - data bits = %d", __func__, buf[6]);
570 } 571 }
571 572
572 baud = tty_get_baud_rate(port->tty);; 573 baud = tty_get_baud_rate(tty);
573 dbg("%s - baud = %d", __func__, baud); 574 dbg("%s - baud = %d", __func__, baud);
574 if (baud) { 575 if (baud) {
575 buf[0] = baud & 0xff; 576 buf[0] = baud & 0xff;
@@ -646,12 +647,13 @@ static void pl2303_set_termios(struct usb_serial_port *port,
646 647
647 /* FIXME: Need to read back resulting baud rate */ 648 /* FIXME: Need to read back resulting baud rate */
648 if (baud) 649 if (baud)
649 tty_encode_baud_rate(port->tty, baud, baud); 650 tty_encode_baud_rate(tty, baud, baud);
650 651
651 kfree(buf); 652 kfree(buf);
652} 653}
653 654
654static void pl2303_close(struct usb_serial_port *port, struct file *filp) 655static void pl2303_close(struct tty_struct *tty,
656 struct usb_serial_port *port, struct file *filp)
655{ 657{
656 struct pl2303_private *priv = usb_get_serial_port_data(port); 658 struct pl2303_private *priv = usb_get_serial_port_data(port);
657 unsigned long flags; 659 unsigned long flags;
@@ -666,7 +668,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
666 spin_lock_irqsave(&priv->lock, flags); 668 spin_lock_irqsave(&priv->lock, flags);
667 timeout = PL2303_CLOSING_WAIT; 669 timeout = PL2303_CLOSING_WAIT;
668 init_waitqueue_entry(&wait, current); 670 init_waitqueue_entry(&wait, current);
669 add_wait_queue(&port->tty->write_wait, &wait); 671 add_wait_queue(&tty->write_wait, &wait);
670 for (;;) { 672 for (;;) {
671 set_current_state(TASK_INTERRUPTIBLE); 673 set_current_state(TASK_INTERRUPTIBLE);
672 if (pl2303_buf_data_avail(priv->buf) == 0 || 674 if (pl2303_buf_data_avail(priv->buf) == 0 ||
@@ -678,7 +680,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
678 spin_lock_irqsave(&priv->lock, flags); 680 spin_lock_irqsave(&priv->lock, flags);
679 } 681 }
680 set_current_state(TASK_RUNNING); 682 set_current_state(TASK_RUNNING);
681 remove_wait_queue(&port->tty->write_wait, &wait); 683 remove_wait_queue(&tty->write_wait, &wait);
682 /* clear out any remaining data in the buffer */ 684 /* clear out any remaining data in the buffer */
683 pl2303_buf_clear(priv->buf); 685 pl2303_buf_clear(priv->buf);
684 spin_unlock_irqrestore(&priv->lock, flags); 686 spin_unlock_irqrestore(&priv->lock, flags);
@@ -690,7 +692,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
690 /* for lower rates we should really know how much */ 692 /* for lower rates we should really know how much */
691 /* data is in the buffer to compute a delay */ 693 /* data is in the buffer to compute a delay */
692 /* that is not unnecessarily long) */ 694 /* that is not unnecessarily long) */
693 bps = tty_get_baud_rate(port->tty); 695 bps = tty_get_baud_rate(tty);
694 if (bps > 1200) 696 if (bps > 1200)
695 timeout = max((HZ*2560)/bps,HZ/10); 697 timeout = max((HZ*2560)/bps,HZ/10);
696 else 698 else
@@ -703,8 +705,8 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
703 usb_kill_urb(port->read_urb); 705 usb_kill_urb(port->read_urb);
704 usb_kill_urb(port->interrupt_in_urb); 706 usb_kill_urb(port->interrupt_in_urb);
705 707
706 if (port->tty) { 708 if (tty) {
707 c_cflag = port->tty->termios->c_cflag; 709 c_cflag = tty->termios->c_cflag;
708 if (c_cflag & HUPCL) { 710 if (c_cflag & HUPCL) {
709 /* drop DTR and RTS */ 711 /* drop DTR and RTS */
710 spin_lock_irqsave(&priv->lock, flags); 712 spin_lock_irqsave(&priv->lock, flags);
@@ -715,7 +717,8 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
715 } 717 }
716} 718}
717 719
718static int pl2303_open(struct usb_serial_port *port, struct file *filp) 720static int pl2303_open(struct tty_struct *tty,
721 struct usb_serial_port *port, struct file *filp)
719{ 722{
720 struct ktermios tmp_termios; 723 struct ktermios tmp_termios;
721 struct usb_serial *serial = port->serial; 724 struct usb_serial *serial = port->serial;
@@ -734,9 +737,8 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp)
734 } 737 }
735 738
736 /* Setup termios */ 739 /* Setup termios */
737 if (port->tty) { 740 if (tty)
738 pl2303_set_termios(port, &tmp_termios); 741 pl2303_set_termios(tty, port, &tmp_termios);
739 }
740 742
741 //FIXME: need to assert RTS and DTR if CRTSCTS off 743 //FIXME: need to assert RTS and DTR if CRTSCTS off
742 744
@@ -746,7 +748,7 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp)
746 if (result) { 748 if (result) {
747 dev_err(&port->dev, "%s - failed submitting read urb," 749 dev_err(&port->dev, "%s - failed submitting read urb,"
748 " error %d\n", __func__, result); 750 " error %d\n", __func__, result);
749 pl2303_close(port, NULL); 751 pl2303_close(tty, port, NULL);
750 return -EPROTO; 752 return -EPROTO;
751 } 753 }
752 754
@@ -756,15 +758,16 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp)
756 if (result) { 758 if (result) {
757 dev_err(&port->dev, "%s - failed submitting interrupt urb," 759 dev_err(&port->dev, "%s - failed submitting interrupt urb,"
758 " error %d\n", __func__, result); 760 " error %d\n", __func__, result);
759 pl2303_close(port, NULL); 761 pl2303_close(tty, port, NULL);
760 return -EPROTO; 762 return -EPROTO;
761 } 763 }
762 return 0; 764 return 0;
763} 765}
764 766
765static int pl2303_tiocmset(struct usb_serial_port *port, struct file *file, 767static int pl2303_tiocmset(struct tty_struct *tty, struct file *file,
766 unsigned int set, unsigned int clear) 768 unsigned int set, unsigned int clear)
767{ 769{
770 struct usb_serial_port *port = tty->driver_data;
768 struct pl2303_private *priv = usb_get_serial_port_data(port); 771 struct pl2303_private *priv = usb_get_serial_port_data(port);
769 unsigned long flags; 772 unsigned long flags;
770 u8 control; 773 u8 control;
@@ -787,8 +790,9 @@ static int pl2303_tiocmset(struct usb_serial_port *port, struct file *file,
787 return set_control_lines(port->serial->dev, control); 790 return set_control_lines(port->serial->dev, control);
788} 791}
789 792
790static int pl2303_tiocmget(struct usb_serial_port *port, struct file *file) 793static int pl2303_tiocmget(struct tty_struct *tty, struct file *file)
791{ 794{
795 struct usb_serial_port *port = tty->driver_data;
792 struct pl2303_private *priv = usb_get_serial_port_data(port); 796 struct pl2303_private *priv = usb_get_serial_port_data(port);
793 unsigned long flags; 797 unsigned long flags;
794 unsigned int mcr; 798 unsigned int mcr;
@@ -853,9 +857,10 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
853 return 0; 857 return 0;
854} 858}
855 859
856static int pl2303_ioctl(struct usb_serial_port *port, struct file *file, 860static int pl2303_ioctl(struct tty_struct *tty, struct file *file,
857 unsigned int cmd, unsigned long arg) 861 unsigned int cmd, unsigned long arg)
858{ 862{
863 struct usb_serial_port *port = tty->driver_data;
859 dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); 864 dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
860 865
861 switch (cmd) { 866 switch (cmd) {
@@ -871,8 +876,9 @@ static int pl2303_ioctl(struct usb_serial_port *port, struct file *file,
871 return -ENOIOCTLCMD; 876 return -ENOIOCTLCMD;
872} 877}
873 878
874static void pl2303_break_ctl(struct usb_serial_port *port, int break_state) 879static void pl2303_break_ctl(struct tty_struct *tty, int break_state)
875{ 880{
881 struct usb_serial_port *port = tty->driver_data;
876 struct usb_serial *serial = port->serial; 882 struct usb_serial *serial = port->serial;
877 u16 state; 883 u16 state;
878 int result; 884 int result;
@@ -1001,7 +1007,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
1001 1007
1002 if (status) { 1008 if (status) {
1003 dbg("%s - urb status = %d", __func__, status); 1009 dbg("%s - urb status = %d", __func__, status);
1004 if (!port->open_count) { 1010 if (!port->port.count) {
1005 dbg("%s - port is closed, exiting.", __func__); 1011 dbg("%s - port is closed, exiting.", __func__);
1006 return; 1012 return;
1007 } 1013 }
@@ -1044,7 +1050,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
1044 tty_flag = TTY_FRAME; 1050 tty_flag = TTY_FRAME;
1045 dbg("%s - tty_flag = %d", __func__, tty_flag); 1051 dbg("%s - tty_flag = %d", __func__, tty_flag);
1046 1052
1047 tty = port->tty; 1053 tty = port->port.tty;
1048 if (tty && urb->actual_length) { 1054 if (tty && urb->actual_length) {
1049 tty_buffer_request_room(tty, urb->actual_length + 1); 1055 tty_buffer_request_room(tty, urb->actual_length + 1);
1050 /* overrun is special, not associated with a char */ 1056 /* overrun is special, not associated with a char */
@@ -1056,7 +1062,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
1056 } 1062 }
1057 1063
1058 /* Schedule the next read _if_ we are still open */ 1064 /* Schedule the next read _if_ we are still open */
1059 if (port->open_count) { 1065 if (port->port.count) {
1060 urb->dev = port->serial->dev; 1066 urb->dev = port->serial->dev;
1061 result = usb_submit_urb(urb, GFP_ATOMIC); 1067 result = usb_submit_urb(urb, GFP_ATOMIC);
1062 if (result) 1068 if (result)