aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/sierra.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/sierra.c')
-rw-r--r--drivers/usb/serial/sierra.c198
1 files changed, 119 insertions, 79 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 6b192e602ce0..6f7f01eb556a 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -58,6 +58,7 @@ struct sierra_intf_private {
58 spinlock_t susp_lock; 58 spinlock_t susp_lock;
59 unsigned int suspended:1; 59 unsigned int suspended:1;
60 int in_flight; 60 int in_flight;
61 unsigned int open_ports;
61}; 62};
62 63
63static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) 64static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
@@ -315,7 +316,6 @@ struct sierra_port_private {
315 int dsr_state; 316 int dsr_state;
316 int dcd_state; 317 int dcd_state;
317 int ri_state; 318 int ri_state;
318 unsigned int opened:1;
319}; 319};
320 320
321static int sierra_send_setup(struct usb_serial_port *port) 321static int sierra_send_setup(struct usb_serial_port *port)
@@ -364,20 +364,13 @@ static int sierra_send_setup(struct usb_serial_port *port)
364 if (retval < 0) 364 if (retval < 0)
365 return retval; 365 return retval;
366 366
367 retval = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 367 retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
368 0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT); 368 0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT);
369 usb_autopm_put_interface(serial->interface); 369 usb_autopm_put_interface(serial->interface);
370 370
371 return retval; 371 return retval;
372} 372}
373 373
374static void sierra_set_termios(struct tty_struct *tty,
375 struct usb_serial_port *port, struct ktermios *old_termios)
376{
377 tty_termios_copy_hw(&tty->termios, old_termios);
378 sierra_send_setup(port);
379}
380
381static int sierra_tiocmget(struct tty_struct *tty) 374static int sierra_tiocmget(struct tty_struct *tty)
382{ 375{
383 struct usb_serial_port *port = tty->driver_data; 376 struct usb_serial_port *port = tty->driver_data;
@@ -418,9 +411,7 @@ static int sierra_tiocmset(struct tty_struct *tty,
418 411
419static void sierra_release_urb(struct urb *urb) 412static void sierra_release_urb(struct urb *urb)
420{ 413{
421 struct usb_serial_port *port;
422 if (urb) { 414 if (urb) {
423 port = urb->context;
424 kfree(urb->transfer_buffer); 415 kfree(urb->transfer_buffer);
425 usb_free_urb(urb); 416 usb_free_urb(urb);
426 } 417 }
@@ -433,7 +424,7 @@ static void sierra_outdat_callback(struct urb *urb)
433 struct sierra_intf_private *intfdata; 424 struct sierra_intf_private *intfdata;
434 int status = urb->status; 425 int status = urb->status;
435 426
436 intfdata = port->serial->private; 427 intfdata = usb_get_serial_data(port->serial);
437 428
438 /* free up the transfer buffer, as usb_free_urb() does not do this */ 429 /* free up the transfer buffer, as usb_free_urb() does not do this */
439 kfree(urb->transfer_buffer); 430 kfree(urb->transfer_buffer);
@@ -470,7 +461,7 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
470 return 0; 461 return 0;
471 462
472 portdata = usb_get_serial_port_data(port); 463 portdata = usb_get_serial_port_data(port);
473 intfdata = serial->private; 464 intfdata = usb_get_serial_data(serial);
474 465
475 dev_dbg(&port->dev, "%s: write (%zd bytes)\n", __func__, writesize); 466 dev_dbg(&port->dev, "%s: write (%zd bytes)\n", __func__, writesize);
476 spin_lock_irqsave(&portdata->lock, flags); 467 spin_lock_irqsave(&portdata->lock, flags);
@@ -674,6 +665,23 @@ static int sierra_write_room(struct tty_struct *tty)
674 return 2048; 665 return 2048;
675} 666}
676 667
668static int sierra_chars_in_buffer(struct tty_struct *tty)
669{
670 struct usb_serial_port *port = tty->driver_data;
671 struct sierra_port_private *portdata = usb_get_serial_port_data(port);
672 unsigned long flags;
673 int chars;
674
675 /* NOTE: This overcounts somewhat. */
676 spin_lock_irqsave(&portdata->lock, flags);
677 chars = portdata->outstanding_urbs * MAX_TRANSFER;
678 spin_unlock_irqrestore(&portdata->lock, flags);
679
680 dev_dbg(&port->dev, "%s - %d\n", __func__, chars);
681
682 return chars;
683}
684
677static void sierra_stop_rx_urbs(struct usb_serial_port *port) 685static void sierra_stop_rx_urbs(struct usb_serial_port *port)
678{ 686{
679 int i; 687 int i;
@@ -729,9 +737,6 @@ static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint,
729 struct urb *urb; 737 struct urb *urb;
730 u8 *buf; 738 u8 *buf;
731 739
732 if (endpoint == -1)
733 return NULL;
734
735 urb = usb_alloc_urb(0, mem_flags); 740 urb = usb_alloc_urb(0, mem_flags);
736 if (!urb) 741 if (!urb)
737 return NULL; 742 return NULL;
@@ -758,40 +763,48 @@ static void sierra_close(struct usb_serial_port *port)
758 int i; 763 int i;
759 struct usb_serial *serial = port->serial; 764 struct usb_serial *serial = port->serial;
760 struct sierra_port_private *portdata; 765 struct sierra_port_private *portdata;
761 struct sierra_intf_private *intfdata = port->serial->private; 766 struct sierra_intf_private *intfdata = usb_get_serial_data(serial);
767 struct urb *urb;
762 768
763 portdata = usb_get_serial_port_data(port); 769 portdata = usb_get_serial_port_data(port);
764 770
765 portdata->rts_state = 0; 771 /*
766 portdata->dtr_state = 0; 772 * Need to take susp_lock to make sure port is not already being
767 773 * resumed, but no need to hold it due to ASYNC_INITIALIZED.
768 mutex_lock(&serial->disc_mutex); 774 */
769 if (!serial->disconnected) { 775 spin_lock_irq(&intfdata->susp_lock);
776 if (--intfdata->open_ports == 0)
770 serial->interface->needs_remote_wakeup = 0; 777 serial->interface->needs_remote_wakeup = 0;
771 /* odd error handling due to pm counters */ 778 spin_unlock_irq(&intfdata->susp_lock);
772 if (!usb_autopm_get_interface(serial->interface))
773 sierra_send_setup(port);
774 else
775 usb_autopm_get_interface_no_resume(serial->interface);
776 779
780 for (;;) {
781 urb = usb_get_from_anchor(&portdata->delayed);
782 if (!urb)
783 break;
784 kfree(urb->transfer_buffer);
785 usb_free_urb(urb);
786 usb_autopm_put_interface_async(serial->interface);
787 spin_lock(&portdata->lock);
788 portdata->outstanding_urbs--;
789 spin_unlock(&portdata->lock);
777 } 790 }
778 mutex_unlock(&serial->disc_mutex);
779 spin_lock_irq(&intfdata->susp_lock);
780 portdata->opened = 0;
781 spin_unlock_irq(&intfdata->susp_lock);
782 791
783 sierra_stop_rx_urbs(port); 792 sierra_stop_rx_urbs(port);
793 usb_kill_anchored_urbs(&portdata->active);
794
784 for (i = 0; i < portdata->num_in_urbs; i++) { 795 for (i = 0; i < portdata->num_in_urbs; i++) {
785 sierra_release_urb(portdata->in_urbs[i]); 796 sierra_release_urb(portdata->in_urbs[i]);
786 portdata->in_urbs[i] = NULL; 797 portdata->in_urbs[i] = NULL;
787 } 798 }
799
800 usb_autopm_get_interface_no_resume(serial->interface);
788} 801}
789 802
790static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port) 803static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
791{ 804{
792 struct sierra_port_private *portdata; 805 struct sierra_port_private *portdata;
793 struct usb_serial *serial = port->serial; 806 struct usb_serial *serial = port->serial;
794 struct sierra_intf_private *intfdata = serial->private; 807 struct sierra_intf_private *intfdata = usb_get_serial_data(serial);
795 int i; 808 int i;
796 int err; 809 int err;
797 int endpoint; 810 int endpoint;
@@ -799,11 +812,6 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
799 812
800 portdata = usb_get_serial_port_data(port); 813 portdata = usb_get_serial_port_data(port);
801 814
802 /* Set some sane defaults */
803 portdata->rts_state = 1;
804 portdata->dtr_state = 1;
805
806
807 endpoint = port->bulk_in_endpointAddress; 815 endpoint = port->bulk_in_endpointAddress;
808 for (i = 0; i < portdata->num_in_urbs; i++) { 816 for (i = 0; i < portdata->num_in_urbs; i++) {
809 urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port, 817 urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port,
@@ -816,23 +824,26 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
816 usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN); 824 usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN);
817 825
818 err = sierra_submit_rx_urbs(port, GFP_KERNEL); 826 err = sierra_submit_rx_urbs(port, GFP_KERNEL);
819 if (err) { 827 if (err)
820 /* get rid of everything as in close */ 828 goto err_submit;
821 sierra_close(port);
822 /* restore balance for autopm */
823 if (!serial->disconnected)
824 usb_autopm_put_interface(serial->interface);
825 return err;
826 }
827 sierra_send_setup(port);
828 829
829 serial->interface->needs_remote_wakeup = 1;
830 spin_lock_irq(&intfdata->susp_lock); 830 spin_lock_irq(&intfdata->susp_lock);
831 portdata->opened = 1; 831 if (++intfdata->open_ports == 1)
832 serial->interface->needs_remote_wakeup = 1;
832 spin_unlock_irq(&intfdata->susp_lock); 833 spin_unlock_irq(&intfdata->susp_lock);
833 usb_autopm_put_interface(serial->interface); 834 usb_autopm_put_interface(serial->interface);
834 835
835 return 0; 836 return 0;
837
838err_submit:
839 sierra_stop_rx_urbs(port);
840
841 for (i = 0; i < portdata->num_in_urbs; i++) {
842 sierra_release_urb(portdata->in_urbs[i]);
843 portdata->in_urbs[i] = NULL;
844 }
845
846 return err;
836} 847}
837 848
838 849
@@ -928,6 +939,7 @@ static int sierra_port_remove(struct usb_serial_port *port)
928 struct sierra_port_private *portdata; 939 struct sierra_port_private *portdata;
929 940
930 portdata = usb_get_serial_port_data(port); 941 portdata = usb_get_serial_port_data(port);
942 usb_set_serial_port_data(port, NULL);
931 kfree(portdata); 943 kfree(portdata);
932 944
933 return 0; 945 return 0;
@@ -944,6 +956,8 @@ static void stop_read_write_urbs(struct usb_serial *serial)
944 for (i = 0; i < serial->num_ports; ++i) { 956 for (i = 0; i < serial->num_ports; ++i) {
945 port = serial->port[i]; 957 port = serial->port[i];
946 portdata = usb_get_serial_port_data(port); 958 portdata = usb_get_serial_port_data(port);
959 if (!portdata)
960 continue;
947 sierra_stop_rx_urbs(port); 961 sierra_stop_rx_urbs(port);
948 usb_kill_anchored_urbs(&portdata->active); 962 usb_kill_anchored_urbs(&portdata->active);
949 } 963 }
@@ -951,58 +965,84 @@ static void stop_read_write_urbs(struct usb_serial *serial)
951 965
952static int sierra_suspend(struct usb_serial *serial, pm_message_t message) 966static int sierra_suspend(struct usb_serial *serial, pm_message_t message)
953{ 967{
954 struct sierra_intf_private *intfdata; 968 struct sierra_intf_private *intfdata = usb_get_serial_data(serial);
955 int b;
956 969
970 spin_lock_irq(&intfdata->susp_lock);
957 if (PMSG_IS_AUTO(message)) { 971 if (PMSG_IS_AUTO(message)) {
958 intfdata = serial->private; 972 if (intfdata->in_flight) {
959 spin_lock_irq(&intfdata->susp_lock);
960 b = intfdata->in_flight;
961
962 if (b) {
963 spin_unlock_irq(&intfdata->susp_lock); 973 spin_unlock_irq(&intfdata->susp_lock);
964 return -EBUSY; 974 return -EBUSY;
965 } else {
966 intfdata->suspended = 1;
967 spin_unlock_irq(&intfdata->susp_lock);
968 } 975 }
969 } 976 }
977 intfdata->suspended = 1;
978 spin_unlock_irq(&intfdata->susp_lock);
979
970 stop_read_write_urbs(serial); 980 stop_read_write_urbs(serial);
971 981
972 return 0; 982 return 0;
973} 983}
974 984
985/* Caller must hold susp_lock. */
986static int sierra_submit_delayed_urbs(struct usb_serial_port *port)
987{
988 struct sierra_port_private *portdata = usb_get_serial_port_data(port);
989 struct sierra_intf_private *intfdata;
990 struct urb *urb;
991 int ec = 0;
992 int err;
993
994 intfdata = usb_get_serial_data(port->serial);
995
996 for (;;) {
997 urb = usb_get_from_anchor(&portdata->delayed);
998 if (!urb)
999 break;
1000
1001 usb_anchor_urb(urb, &portdata->active);
1002 intfdata->in_flight++;
1003 err = usb_submit_urb(urb, GFP_ATOMIC);
1004 if (err) {
1005 dev_err(&port->dev, "%s - submit urb failed: %d",
1006 __func__, err);
1007 ec++;
1008 intfdata->in_flight--;
1009 usb_unanchor_urb(urb);
1010 kfree(urb->transfer_buffer);
1011 usb_free_urb(urb);
1012
1013 spin_lock(&portdata->lock);
1014 portdata->outstanding_urbs--;
1015 spin_unlock(&portdata->lock);
1016 }
1017 }
1018
1019 if (ec)
1020 return -EIO;
1021
1022 return 0;
1023}
1024
975static int sierra_resume(struct usb_serial *serial) 1025static int sierra_resume(struct usb_serial *serial)
976{ 1026{
977 struct usb_serial_port *port; 1027 struct usb_serial_port *port;
978 struct sierra_intf_private *intfdata = serial->private; 1028 struct sierra_intf_private *intfdata = usb_get_serial_data(serial);
979 struct sierra_port_private *portdata;
980 struct urb *urb;
981 int ec = 0; 1029 int ec = 0;
982 int i, err; 1030 int i, err;
983 1031
984 spin_lock_irq(&intfdata->susp_lock); 1032 spin_lock_irq(&intfdata->susp_lock);
985 for (i = 0; i < serial->num_ports; i++) { 1033 for (i = 0; i < serial->num_ports; i++) {
986 port = serial->port[i]; 1034 port = serial->port[i];
987 portdata = usb_get_serial_port_data(port);
988 1035
989 while ((urb = usb_get_from_anchor(&portdata->delayed))) { 1036 if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
990 usb_anchor_urb(urb, &portdata->active); 1037 continue;
991 intfdata->in_flight++;
992 err = usb_submit_urb(urb, GFP_ATOMIC);
993 if (err < 0) {
994 intfdata->in_flight--;
995 usb_unanchor_urb(urb);
996 usb_scuttle_anchored_urbs(&portdata->delayed);
997 break;
998 }
999 }
1000 1038
1001 if (portdata->opened) { 1039 err = sierra_submit_delayed_urbs(port);
1002 err = sierra_submit_rx_urbs(port, GFP_ATOMIC); 1040 if (err)
1003 if (err) 1041 ec++;
1004 ec++; 1042
1005 } 1043 err = sierra_submit_rx_urbs(port, GFP_ATOMIC);
1044 if (err)
1045 ec++;
1006 } 1046 }
1007 intfdata->suspended = 0; 1047 intfdata->suspended = 0;
1008 spin_unlock_irq(&intfdata->susp_lock); 1048 spin_unlock_irq(&intfdata->susp_lock);
@@ -1029,7 +1069,7 @@ static struct usb_serial_driver sierra_device = {
1029 .dtr_rts = sierra_dtr_rts, 1069 .dtr_rts = sierra_dtr_rts,
1030 .write = sierra_write, 1070 .write = sierra_write,
1031 .write_room = sierra_write_room, 1071 .write_room = sierra_write_room,
1032 .set_termios = sierra_set_termios, 1072 .chars_in_buffer = sierra_chars_in_buffer,
1033 .tiocmget = sierra_tiocmget, 1073 .tiocmget = sierra_tiocmget,
1034 .tiocmset = sierra_tiocmset, 1074 .tiocmset = sierra_tiocmset,
1035 .attach = sierra_startup, 1075 .attach = sierra_startup,