diff options
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/aircable.c | 10 | ||||
-rw-r--r-- | drivers/usb/serial/cp210x.c | 1 | ||||
-rw-r--r-- | drivers/usb/serial/cypress_m8.c | 12 | ||||
-rw-r--r-- | drivers/usb/serial/digi_acceleport.c | 8 | ||||
-rw-r--r-- | drivers/usb/serial/empeg.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 422 | ||||
-rw-r--r-- | drivers/usb/serial/garmin_gps.c | 12 | ||||
-rw-r--r-- | drivers/usb/serial/generic.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/ipaq.c | 9 | ||||
-rw-r--r-- | drivers/usb/serial/keyspan_pda.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/kl5kusb105.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/mct_u232.c | 14 | ||||
-rw-r--r-- | drivers/usb/serial/opticon.c | 13 | ||||
-rw-r--r-- | drivers/usb/serial/option.c | 4 | ||||
-rw-r--r-- | drivers/usb/serial/oti6858.c | 6 | ||||
-rw-r--r-- | drivers/usb/serial/pl2303.c | 8 | ||||
-rw-r--r-- | drivers/usb/serial/sierra.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/symbolserial.c | 22 | ||||
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 10 | ||||
-rw-r--r-- | drivers/usb/serial/visor.c | 28 | ||||
-rw-r--r-- | drivers/usb/serial/whiteheat.c | 10 |
21 files changed, 227 insertions, 372 deletions
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 2cbfab3716e5..b10ac8409411 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -554,13 +554,12 @@ static void aircable_throttle(struct tty_struct *tty) | |||
554 | { | 554 | { |
555 | struct usb_serial_port *port = tty->driver_data; | 555 | struct usb_serial_port *port = tty->driver_data; |
556 | struct aircable_private *priv = usb_get_serial_port_data(port); | 556 | struct aircable_private *priv = usb_get_serial_port_data(port); |
557 | unsigned long flags; | ||
558 | 557 | ||
559 | dbg("%s - port %d", __func__, port->number); | 558 | dbg("%s - port %d", __func__, port->number); |
560 | 559 | ||
561 | spin_lock_irqsave(&priv->rx_lock, flags); | 560 | spin_lock_irq(&priv->rx_lock); |
562 | priv->rx_flags |= THROTTLED; | 561 | priv->rx_flags |= THROTTLED; |
563 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 562 | spin_unlock_irq(&priv->rx_lock); |
564 | } | 563 | } |
565 | 564 | ||
566 | /* Based on ftdi_sio.c unthrottle */ | 565 | /* Based on ftdi_sio.c unthrottle */ |
@@ -569,14 +568,13 @@ static void aircable_unthrottle(struct tty_struct *tty) | |||
569 | struct usb_serial_port *port = tty->driver_data; | 568 | struct usb_serial_port *port = tty->driver_data; |
570 | struct aircable_private *priv = usb_get_serial_port_data(port); | 569 | struct aircable_private *priv = usb_get_serial_port_data(port); |
571 | int actually_throttled; | 570 | int actually_throttled; |
572 | unsigned long flags; | ||
573 | 571 | ||
574 | dbg("%s - port %d", __func__, port->number); | 572 | dbg("%s - port %d", __func__, port->number); |
575 | 573 | ||
576 | spin_lock_irqsave(&priv->rx_lock, flags); | 574 | spin_lock_irq(&priv->rx_lock); |
577 | actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; | 575 | actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; |
578 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); | 576 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); |
579 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 577 | spin_unlock_irq(&priv->rx_lock); |
580 | 578 | ||
581 | if (actually_throttled) | 579 | if (actually_throttled) |
582 | schedule_work(&priv->rx_work); | 580 | schedule_work(&priv->rx_work); |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 4a208fe85bc9..698252a4dc5d 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -113,6 +113,7 @@ static struct usb_device_id id_table [] = { | |||
113 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ | 113 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ |
114 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ | 114 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ |
115 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | 115 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ |
116 | { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ | ||
116 | { } /* Terminating Entry */ | 117 | { } /* Terminating Entry */ |
117 | }; | 118 | }; |
118 | 119 | ||
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index e0a8b715f2f2..a591ebec0f89 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -1155,13 +1155,12 @@ static void cypress_throttle(struct tty_struct *tty) | |||
1155 | { | 1155 | { |
1156 | struct usb_serial_port *port = tty->driver_data; | 1156 | struct usb_serial_port *port = tty->driver_data; |
1157 | struct cypress_private *priv = usb_get_serial_port_data(port); | 1157 | struct cypress_private *priv = usb_get_serial_port_data(port); |
1158 | unsigned long flags; | ||
1159 | 1158 | ||
1160 | dbg("%s - port %d", __func__, port->number); | 1159 | dbg("%s - port %d", __func__, port->number); |
1161 | 1160 | ||
1162 | spin_lock_irqsave(&priv->lock, flags); | 1161 | spin_lock_irq(&priv->lock); |
1163 | priv->rx_flags = THROTTLED; | 1162 | priv->rx_flags = THROTTLED; |
1164 | spin_unlock_irqrestore(&priv->lock, flags); | 1163 | spin_unlock_irq(&priv->lock); |
1165 | } | 1164 | } |
1166 | 1165 | ||
1167 | 1166 | ||
@@ -1170,14 +1169,13 @@ static void cypress_unthrottle(struct tty_struct *tty) | |||
1170 | struct usb_serial_port *port = tty->driver_data; | 1169 | struct usb_serial_port *port = tty->driver_data; |
1171 | struct cypress_private *priv = usb_get_serial_port_data(port); | 1170 | struct cypress_private *priv = usb_get_serial_port_data(port); |
1172 | int actually_throttled, result; | 1171 | int actually_throttled, result; |
1173 | unsigned long flags; | ||
1174 | 1172 | ||
1175 | dbg("%s - port %d", __func__, port->number); | 1173 | dbg("%s - port %d", __func__, port->number); |
1176 | 1174 | ||
1177 | spin_lock_irqsave(&priv->lock, flags); | 1175 | spin_lock_irq(&priv->lock); |
1178 | actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; | 1176 | actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; |
1179 | priv->rx_flags = 0; | 1177 | priv->rx_flags = 0; |
1180 | spin_unlock_irqrestore(&priv->lock, flags); | 1178 | spin_unlock_irq(&priv->lock); |
1181 | 1179 | ||
1182 | if (!priv->comm_is_ok) | 1180 | if (!priv->comm_is_ok) |
1183 | return; | 1181 | return; |
@@ -1185,7 +1183,7 @@ static void cypress_unthrottle(struct tty_struct *tty) | |||
1185 | if (actually_throttled) { | 1183 | if (actually_throttled) { |
1186 | port->interrupt_in_urb->dev = port->serial->dev; | 1184 | port->interrupt_in_urb->dev = port->serial->dev; |
1187 | 1185 | ||
1188 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 1186 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
1189 | if (result) { | 1187 | if (result) { |
1190 | dev_err(&port->dev, "%s - failed submitting read urb, " | 1188 | dev_err(&port->dev, "%s - failed submitting read urb, " |
1191 | "error %d\n", __func__, result); | 1189 | "error %d\n", __func__, result); |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index ab3dd991586b..68e80be6b9e1 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -898,16 +898,16 @@ static void digi_rx_unthrottle(struct tty_struct *tty) | |||
898 | 898 | ||
899 | spin_lock_irqsave(&priv->dp_port_lock, flags); | 899 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
900 | 900 | ||
901 | /* turn throttle off */ | ||
902 | priv->dp_throttled = 0; | ||
903 | priv->dp_throttle_restart = 0; | ||
904 | |||
905 | /* restart read chain */ | 901 | /* restart read chain */ |
906 | if (priv->dp_throttle_restart) { | 902 | if (priv->dp_throttle_restart) { |
907 | port->read_urb->dev = port->serial->dev; | 903 | port->read_urb->dev = port->serial->dev; |
908 | ret = usb_submit_urb(port->read_urb, GFP_ATOMIC); | 904 | ret = usb_submit_urb(port->read_urb, GFP_ATOMIC); |
909 | } | 905 | } |
910 | 906 | ||
907 | /* turn throttle off */ | ||
908 | priv->dp_throttled = 0; | ||
909 | priv->dp_throttle_restart = 0; | ||
910 | |||
911 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); | 911 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
912 | 912 | ||
913 | if (ret) | 913 | if (ret) |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 33c9e9cf9eb2..7dd0e3eadbe6 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -391,7 +391,7 @@ static void empeg_unthrottle(struct tty_struct *tty) | |||
391 | dbg("%s - port %d", __func__, port->number); | 391 | dbg("%s - port %d", __func__, port->number); |
392 | 392 | ||
393 | port->read_urb->dev = port->serial->dev; | 393 | port->read_urb->dev = port->serial->dev; |
394 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | 394 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); |
395 | if (result) | 395 | if (result) |
396 | dev_err(&port->dev, | 396 | dev_err(&port->dev, |
397 | "%s - failed submitting read urb, error %d\n", | 397 | "%s - failed submitting read urb, error %d\n", |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 4f883b1773d0..9c60d6d4908a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -76,13 +76,7 @@ struct ftdi_private { | |||
76 | unsigned long last_dtr_rts; /* saved modem control outputs */ | 76 | unsigned long last_dtr_rts; /* saved modem control outputs */ |
77 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | 77 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
78 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ | 78 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ |
79 | __u8 rx_flags; /* receive state flags (throttling) */ | ||
80 | spinlock_t rx_lock; /* spinlock for receive state */ | ||
81 | struct delayed_work rx_work; | ||
82 | struct usb_serial_port *port; | 79 | struct usb_serial_port *port; |
83 | int rx_processed; | ||
84 | unsigned long rx_bytes; | ||
85 | |||
86 | __u16 interface; /* FT2232C, FT2232H or FT4232H port interface | 80 | __u16 interface; /* FT2232C, FT2232H or FT4232H port interface |
87 | (0 for FT232/245) */ | 81 | (0 for FT232/245) */ |
88 | 82 | ||
@@ -737,10 +731,6 @@ static const char *ftdi_chip_name[] = { | |||
737 | /* Constants for read urb and write urb */ | 731 | /* Constants for read urb and write urb */ |
738 | #define BUFSZ 512 | 732 | #define BUFSZ 512 |
739 | 733 | ||
740 | /* rx_flags */ | ||
741 | #define THROTTLED 0x01 | ||
742 | #define ACTUALLY_THROTTLED 0x02 | ||
743 | |||
744 | /* Used for TIOCMIWAIT */ | 734 | /* Used for TIOCMIWAIT */ |
745 | #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) | 735 | #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) |
746 | #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) | 736 | #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) |
@@ -763,7 +753,7 @@ static int ftdi_write_room(struct tty_struct *tty); | |||
763 | static int ftdi_chars_in_buffer(struct tty_struct *tty); | 753 | static int ftdi_chars_in_buffer(struct tty_struct *tty); |
764 | static void ftdi_write_bulk_callback(struct urb *urb); | 754 | static void ftdi_write_bulk_callback(struct urb *urb); |
765 | static void ftdi_read_bulk_callback(struct urb *urb); | 755 | static void ftdi_read_bulk_callback(struct urb *urb); |
766 | static void ftdi_process_read(struct work_struct *work); | 756 | static void ftdi_process_read(struct usb_serial_port *port); |
767 | static void ftdi_set_termios(struct tty_struct *tty, | 757 | static void ftdi_set_termios(struct tty_struct *tty, |
768 | struct usb_serial_port *port, struct ktermios *old); | 758 | struct usb_serial_port *port, struct ktermios *old); |
769 | static int ftdi_tiocmget(struct tty_struct *tty, struct file *file); | 759 | static int ftdi_tiocmget(struct tty_struct *tty, struct file *file); |
@@ -1234,7 +1224,6 @@ static int set_serial_info(struct tty_struct *tty, | |||
1234 | (new_serial.flags & ASYNC_FLAGS)); | 1224 | (new_serial.flags & ASYNC_FLAGS)); |
1235 | priv->custom_divisor = new_serial.custom_divisor; | 1225 | priv->custom_divisor = new_serial.custom_divisor; |
1236 | 1226 | ||
1237 | tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | ||
1238 | write_latency_timer(port); | 1227 | write_latency_timer(port); |
1239 | 1228 | ||
1240 | check_and_exit: | 1229 | check_and_exit: |
@@ -1527,7 +1516,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1527 | } | 1516 | } |
1528 | 1517 | ||
1529 | kref_init(&priv->kref); | 1518 | kref_init(&priv->kref); |
1530 | spin_lock_init(&priv->rx_lock); | ||
1531 | spin_lock_init(&priv->tx_lock); | 1519 | spin_lock_init(&priv->tx_lock); |
1532 | init_waitqueue_head(&priv->delta_msr_wait); | 1520 | init_waitqueue_head(&priv->delta_msr_wait); |
1533 | /* This will push the characters through immediately rather | 1521 | /* This will push the characters through immediately rather |
@@ -1549,7 +1537,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1549 | port->read_urb->transfer_buffer_length = BUFSZ; | 1537 | port->read_urb->transfer_buffer_length = BUFSZ; |
1550 | } | 1538 | } |
1551 | 1539 | ||
1552 | INIT_DELAYED_WORK(&priv->rx_work, ftdi_process_read); | ||
1553 | priv->port = port; | 1540 | priv->port = port; |
1554 | 1541 | ||
1555 | /* Free port's existing write urb and transfer buffer. */ | 1542 | /* Free port's existing write urb and transfer buffer. */ |
@@ -1686,6 +1673,26 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) | |||
1686 | return 0; | 1673 | return 0; |
1687 | } | 1674 | } |
1688 | 1675 | ||
1676 | static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | ||
1677 | { | ||
1678 | struct urb *urb = port->read_urb; | ||
1679 | struct usb_serial *serial = port->serial; | ||
1680 | int result; | ||
1681 | |||
1682 | usb_fill_bulk_urb(urb, serial->dev, | ||
1683 | usb_rcvbulkpipe(serial->dev, | ||
1684 | port->bulk_in_endpointAddress), | ||
1685 | urb->transfer_buffer, | ||
1686 | urb->transfer_buffer_length, | ||
1687 | ftdi_read_bulk_callback, port); | ||
1688 | result = usb_submit_urb(urb, mem_flags); | ||
1689 | if (result) | ||
1690 | dev_err(&port->dev, | ||
1691 | "%s - failed submitting read urb, error %d\n", | ||
1692 | __func__, result); | ||
1693 | return result; | ||
1694 | } | ||
1695 | |||
1689 | static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | 1696 | static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) |
1690 | { /* ftdi_open */ | 1697 | { /* ftdi_open */ |
1691 | struct usb_device *dev = port->serial->dev; | 1698 | struct usb_device *dev = port->serial->dev; |
@@ -1700,12 +1707,6 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1700 | spin_lock_irqsave(&priv->tx_lock, flags); | 1707 | spin_lock_irqsave(&priv->tx_lock, flags); |
1701 | priv->tx_bytes = 0; | 1708 | priv->tx_bytes = 0; |
1702 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1709 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1703 | spin_lock_irqsave(&priv->rx_lock, flags); | ||
1704 | priv->rx_bytes = 0; | ||
1705 | spin_unlock_irqrestore(&priv->rx_lock, flags); | ||
1706 | |||
1707 | if (tty) | ||
1708 | tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | ||
1709 | 1710 | ||
1710 | write_latency_timer(port); | 1711 | write_latency_timer(port); |
1711 | 1712 | ||
@@ -1725,23 +1726,14 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1725 | ftdi_set_termios(tty, port, tty->termios); | 1726 | ftdi_set_termios(tty, port, tty->termios); |
1726 | 1727 | ||
1727 | /* Not throttled */ | 1728 | /* Not throttled */ |
1728 | spin_lock_irqsave(&priv->rx_lock, flags); | 1729 | spin_lock_irqsave(&port->lock, flags); |
1729 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); | 1730 | port->throttled = 0; |
1730 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 1731 | port->throttle_req = 0; |
1732 | spin_unlock_irqrestore(&port->lock, flags); | ||
1731 | 1733 | ||
1732 | /* Start reading from the device */ | 1734 | /* Start reading from the device */ |
1733 | priv->rx_processed = 0; | 1735 | result = ftdi_submit_read_urb(port, GFP_KERNEL); |
1734 | usb_fill_bulk_urb(port->read_urb, dev, | 1736 | if (!result) |
1735 | usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress), | ||
1736 | port->read_urb->transfer_buffer, | ||
1737 | port->read_urb->transfer_buffer_length, | ||
1738 | ftdi_read_bulk_callback, port); | ||
1739 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
1740 | if (result) | ||
1741 | dev_err(&port->dev, | ||
1742 | "%s - failed submitting read urb, error %d\n", | ||
1743 | __func__, result); | ||
1744 | else | ||
1745 | kref_get(&priv->kref); | 1737 | kref_get(&priv->kref); |
1746 | 1738 | ||
1747 | return result; | 1739 | return result; |
@@ -1787,10 +1779,6 @@ static void ftdi_close(struct usb_serial_port *port) | |||
1787 | 1779 | ||
1788 | dbg("%s", __func__); | 1780 | dbg("%s", __func__); |
1789 | 1781 | ||
1790 | |||
1791 | /* cancel any scheduled reading */ | ||
1792 | cancel_delayed_work_sync(&priv->rx_work); | ||
1793 | |||
1794 | /* shutdown our bulk read */ | 1782 | /* shutdown our bulk read */ |
1795 | usb_kill_urb(port->read_urb); | 1783 | usb_kill_urb(port->read_urb); |
1796 | kref_put(&priv->kref, ftdi_sio_priv_release); | 1784 | kref_put(&priv->kref, ftdi_sio_priv_release); |
@@ -2013,271 +2001,121 @@ static int ftdi_chars_in_buffer(struct tty_struct *tty) | |||
2013 | return buffered; | 2001 | return buffered; |
2014 | } | 2002 | } |
2015 | 2003 | ||
2016 | static void ftdi_read_bulk_callback(struct urb *urb) | 2004 | static int ftdi_process_packet(struct tty_struct *tty, |
2005 | struct usb_serial_port *port, struct ftdi_private *priv, | ||
2006 | char *packet, int len) | ||
2017 | { | 2007 | { |
2018 | struct usb_serial_port *port = urb->context; | 2008 | int i; |
2019 | struct tty_struct *tty; | 2009 | char status; |
2020 | struct ftdi_private *priv; | 2010 | char flag; |
2021 | unsigned long countread; | 2011 | char *ch; |
2022 | unsigned long flags; | ||
2023 | int status = urb->status; | ||
2024 | |||
2025 | if (urb->number_of_packets > 0) { | ||
2026 | dev_err(&port->dev, "%s transfer_buffer_length %d " | ||
2027 | "actual_length %d number of packets %d\n", __func__, | ||
2028 | urb->transfer_buffer_length, | ||
2029 | urb->actual_length, urb->number_of_packets); | ||
2030 | dev_err(&port->dev, "%s transfer_flags %x\n", __func__, | ||
2031 | urb->transfer_flags); | ||
2032 | } | ||
2033 | 2012 | ||
2034 | dbg("%s - port %d", __func__, port->number); | 2013 | dbg("%s - port %d", __func__, port->number); |
2035 | 2014 | ||
2036 | if (port->port.count <= 0) | 2015 | if (len < 2) { |
2037 | return; | 2016 | dbg("malformed packet"); |
2038 | 2017 | return 0; | |
2039 | tty = tty_port_tty_get(&port->port); | ||
2040 | if (!tty) { | ||
2041 | dbg("%s - bad tty pointer - exiting", __func__); | ||
2042 | return; | ||
2043 | } | 2018 | } |
2044 | 2019 | ||
2045 | priv = usb_get_serial_port_data(port); | 2020 | /* Compare new line status to the old one, signal if different/ |
2046 | if (!priv) { | 2021 | N.B. packet may be processed more than once, but differences |
2047 | dbg("%s - bad port private data pointer - exiting", __func__); | 2022 | are only processed once. */ |
2048 | goto out; | 2023 | status = packet[0] & FTDI_STATUS_B0_MASK; |
2024 | if (status != priv->prev_status) { | ||
2025 | priv->diff_status |= status ^ priv->prev_status; | ||
2026 | wake_up_interruptible(&priv->delta_msr_wait); | ||
2027 | priv->prev_status = status; | ||
2049 | } | 2028 | } |
2050 | 2029 | ||
2051 | if (urb != port->read_urb) | 2030 | /* |
2052 | dev_err(&port->dev, "%s - Not my urb!\n", __func__); | 2031 | * Although the device uses a bitmask and hence can have multiple |
2053 | 2032 | * errors on a packet - the order here sets the priority the error is | |
2054 | if (status) { | 2033 | * returned to the tty layer. |
2055 | /* This will happen at close every time so it is a dbg not an | 2034 | */ |
2056 | err */ | 2035 | flag = TTY_NORMAL; |
2057 | dbg("(this is ok on close) nonzero read bulk status received: %d", status); | 2036 | if (packet[1] & FTDI_RS_OE) { |
2058 | goto out; | 2037 | flag = TTY_OVERRUN; |
2038 | dbg("OVERRRUN error"); | ||
2039 | } | ||
2040 | if (packet[1] & FTDI_RS_BI) { | ||
2041 | flag = TTY_BREAK; | ||
2042 | dbg("BREAK received"); | ||
2043 | usb_serial_handle_break(port); | ||
2044 | } | ||
2045 | if (packet[1] & FTDI_RS_PE) { | ||
2046 | flag = TTY_PARITY; | ||
2047 | dbg("PARITY error"); | ||
2048 | } | ||
2049 | if (packet[1] & FTDI_RS_FE) { | ||
2050 | flag = TTY_FRAME; | ||
2051 | dbg("FRAMING error"); | ||
2059 | } | 2052 | } |
2060 | 2053 | ||
2061 | /* count data bytes, but not status bytes */ | 2054 | len -= 2; |
2062 | countread = urb->actual_length; | 2055 | if (!len) |
2063 | countread -= 2 * DIV_ROUND_UP(countread, priv->max_packet_size); | 2056 | return 0; /* status only */ |
2064 | spin_lock_irqsave(&priv->rx_lock, flags); | 2057 | ch = packet + 2; |
2065 | priv->rx_bytes += countread; | 2058 | |
2066 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 2059 | if (!(port->console && port->sysrq) && flag == TTY_NORMAL) |
2067 | 2060 | tty_insert_flip_string(tty, ch, len); | |
2068 | ftdi_process_read(&priv->rx_work.work); | 2061 | else { |
2069 | out: | 2062 | for (i = 0; i < len; i++, ch++) { |
2070 | tty_kref_put(tty); | 2063 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) |
2071 | } /* ftdi_read_bulk_callback */ | 2064 | tty_insert_flip_char(tty, *ch, flag); |
2072 | 2065 | } | |
2066 | } | ||
2067 | return len; | ||
2068 | } | ||
2073 | 2069 | ||
2074 | static void ftdi_process_read(struct work_struct *work) | 2070 | static void ftdi_process_read(struct usb_serial_port *port) |
2075 | { /* ftdi_process_read */ | 2071 | { |
2076 | struct ftdi_private *priv = | 2072 | struct urb *urb = port->read_urb; |
2077 | container_of(work, struct ftdi_private, rx_work.work); | ||
2078 | struct usb_serial_port *port = priv->port; | ||
2079 | struct urb *urb; | ||
2080 | struct tty_struct *tty; | 2073 | struct tty_struct *tty; |
2081 | char error_flag; | 2074 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2082 | unsigned char *data; | 2075 | char *data = (char *)urb->transfer_buffer; |
2083 | |||
2084 | int i; | 2076 | int i; |
2085 | int result; | 2077 | int len; |
2086 | int need_flip; | 2078 | int count = 0; |
2087 | int packet_offset; | ||
2088 | unsigned long flags; | ||
2089 | |||
2090 | dbg("%s - port %d", __func__, port->number); | ||
2091 | |||
2092 | if (port->port.count <= 0) | ||
2093 | return; | ||
2094 | 2079 | ||
2095 | tty = tty_port_tty_get(&port->port); | 2080 | tty = tty_port_tty_get(&port->port); |
2096 | if (!tty) { | 2081 | if (!tty) |
2097 | dbg("%s - bad tty pointer - exiting", __func__); | ||
2098 | return; | 2082 | return; |
2099 | } | ||
2100 | |||
2101 | priv = usb_get_serial_port_data(port); | ||
2102 | if (!priv) { | ||
2103 | dbg("%s - bad port private data pointer - exiting", __func__); | ||
2104 | goto out; | ||
2105 | } | ||
2106 | |||
2107 | urb = port->read_urb; | ||
2108 | if (!urb) { | ||
2109 | dbg("%s - bad read_urb pointer - exiting", __func__); | ||
2110 | goto out; | ||
2111 | } | ||
2112 | |||
2113 | data = urb->transfer_buffer; | ||
2114 | 2083 | ||
2115 | if (priv->rx_processed) { | 2084 | for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { |
2116 | dbg("%s - already processed: %d bytes, %d remain", __func__, | 2085 | len = min_t(int, urb->actual_length - i, priv->max_packet_size); |
2117 | priv->rx_processed, | 2086 | count += ftdi_process_packet(tty, port, priv, &data[i], len); |
2118 | urb->actual_length - priv->rx_processed); | ||
2119 | } else { | ||
2120 | /* The first two bytes of every read packet are status */ | ||
2121 | if (urb->actual_length > 2) | ||
2122 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
2123 | urb->actual_length, data); | ||
2124 | else | ||
2125 | dbg("Status only: %03oo %03oo", data[0], data[1]); | ||
2126 | } | 2087 | } |
2127 | 2088 | ||
2128 | 2089 | if (count) | |
2129 | /* TO DO -- check for hung up line and handle appropriately: */ | ||
2130 | /* send hangup */ | ||
2131 | /* See acm.c - you do a tty_hangup - eg tty_hangup(tty) */ | ||
2132 | /* if CD is dropped and the line is not CLOCAL then we should hangup */ | ||
2133 | |||
2134 | need_flip = 0; | ||
2135 | for (packet_offset = priv->rx_processed; | ||
2136 | packet_offset < urb->actual_length; packet_offset += priv->max_packet_size) { | ||
2137 | int length; | ||
2138 | |||
2139 | /* Compare new line status to the old one, signal if different/ | ||
2140 | N.B. packet may be processed more than once, but differences | ||
2141 | are only processed once. */ | ||
2142 | char new_status = data[packet_offset + 0] & | ||
2143 | FTDI_STATUS_B0_MASK; | ||
2144 | if (new_status != priv->prev_status) { | ||
2145 | priv->diff_status |= | ||
2146 | new_status ^ priv->prev_status; | ||
2147 | wake_up_interruptible(&priv->delta_msr_wait); | ||
2148 | priv->prev_status = new_status; | ||
2149 | } | ||
2150 | |||
2151 | length = min_t(u32, priv->max_packet_size, urb->actual_length-packet_offset)-2; | ||
2152 | if (length < 0) { | ||
2153 | dev_err(&port->dev, "%s - bad packet length: %d\n", | ||
2154 | __func__, length+2); | ||
2155 | length = 0; | ||
2156 | } | ||
2157 | |||
2158 | if (priv->rx_flags & THROTTLED) { | ||
2159 | dbg("%s - throttled", __func__); | ||
2160 | break; | ||
2161 | } | ||
2162 | if (tty_buffer_request_room(tty, length) < length) { | ||
2163 | /* break out & wait for throttling/unthrottling to | ||
2164 | happen */ | ||
2165 | dbg("%s - receive room low", __func__); | ||
2166 | break; | ||
2167 | } | ||
2168 | |||
2169 | /* Handle errors and break */ | ||
2170 | error_flag = TTY_NORMAL; | ||
2171 | /* Although the device uses a bitmask and hence can have | ||
2172 | multiple errors on a packet - the order here sets the | ||
2173 | priority the error is returned to the tty layer */ | ||
2174 | |||
2175 | if (data[packet_offset+1] & FTDI_RS_OE) { | ||
2176 | error_flag = TTY_OVERRUN; | ||
2177 | dbg("OVERRRUN error"); | ||
2178 | } | ||
2179 | if (data[packet_offset+1] & FTDI_RS_BI) { | ||
2180 | error_flag = TTY_BREAK; | ||
2181 | dbg("BREAK received"); | ||
2182 | usb_serial_handle_break(port); | ||
2183 | } | ||
2184 | if (data[packet_offset+1] & FTDI_RS_PE) { | ||
2185 | error_flag = TTY_PARITY; | ||
2186 | dbg("PARITY error"); | ||
2187 | } | ||
2188 | if (data[packet_offset+1] & FTDI_RS_FE) { | ||
2189 | error_flag = TTY_FRAME; | ||
2190 | dbg("FRAMING error"); | ||
2191 | } | ||
2192 | if (length > 0) { | ||
2193 | for (i = 2; i < length+2; i++) { | ||
2194 | /* Note that the error flag is duplicated for | ||
2195 | every character received since we don't know | ||
2196 | which character it applied to */ | ||
2197 | if (!usb_serial_handle_sysrq_char(tty, port, | ||
2198 | data[packet_offset + i])) | ||
2199 | tty_insert_flip_char(tty, | ||
2200 | data[packet_offset + i], | ||
2201 | error_flag); | ||
2202 | } | ||
2203 | need_flip = 1; | ||
2204 | } | ||
2205 | |||
2206 | #ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW | ||
2207 | /* if a parity error is detected you get status packets forever | ||
2208 | until a character is sent without a parity error. | ||
2209 | This doesn't work well since the application receives a | ||
2210 | never ending stream of bad data - even though new data | ||
2211 | hasn't been sent. Therefore I (bill) have taken this out. | ||
2212 | However - this might make sense for framing errors and so on | ||
2213 | so I am leaving the code in for now. | ||
2214 | */ | ||
2215 | else { | ||
2216 | if (error_flag != TTY_NORMAL) { | ||
2217 | dbg("error_flag is not normal"); | ||
2218 | /* In this case it is just status - if that is | ||
2219 | an error send a bad character */ | ||
2220 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
2221 | tty_flip_buffer_push(tty); | ||
2222 | tty_insert_flip_char(tty, 0xff, error_flag); | ||
2223 | need_flip = 1; | ||
2224 | } | ||
2225 | } | ||
2226 | #endif | ||
2227 | } /* "for(packet_offset=0..." */ | ||
2228 | |||
2229 | /* Low latency */ | ||
2230 | if (need_flip) | ||
2231 | tty_flip_buffer_push(tty); | 2090 | tty_flip_buffer_push(tty); |
2091 | tty_kref_put(tty); | ||
2092 | } | ||
2232 | 2093 | ||
2233 | if (packet_offset < urb->actual_length) { | 2094 | static void ftdi_read_bulk_callback(struct urb *urb) |
2234 | /* not completely processed - record progress */ | 2095 | { |
2235 | priv->rx_processed = packet_offset; | 2096 | struct usb_serial_port *port = urb->context; |
2236 | dbg("%s - incomplete, %d bytes processed, %d remain", | 2097 | unsigned long flags; |
2237 | __func__, packet_offset, | ||
2238 | urb->actual_length - packet_offset); | ||
2239 | /* check if we were throttled while processing */ | ||
2240 | spin_lock_irqsave(&priv->rx_lock, flags); | ||
2241 | if (priv->rx_flags & THROTTLED) { | ||
2242 | priv->rx_flags |= ACTUALLY_THROTTLED; | ||
2243 | spin_unlock_irqrestore(&priv->rx_lock, flags); | ||
2244 | dbg("%s - deferring remainder until unthrottled", | ||
2245 | __func__); | ||
2246 | goto out; | ||
2247 | } | ||
2248 | spin_unlock_irqrestore(&priv->rx_lock, flags); | ||
2249 | /* if the port is closed stop trying to read */ | ||
2250 | if (port->port.count > 0) | ||
2251 | /* delay processing of remainder */ | ||
2252 | schedule_delayed_work(&priv->rx_work, 1); | ||
2253 | else | ||
2254 | dbg("%s - port is closed", __func__); | ||
2255 | goto out; | ||
2256 | } | ||
2257 | |||
2258 | /* urb is completely processed */ | ||
2259 | priv->rx_processed = 0; | ||
2260 | 2098 | ||
2261 | /* if the port is closed stop trying to read */ | 2099 | dbg("%s - port %d", __func__, port->number); |
2262 | if (port->port.count > 0) { | ||
2263 | /* Continue trying to always read */ | ||
2264 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
2265 | usb_rcvbulkpipe(port->serial->dev, | ||
2266 | port->bulk_in_endpointAddress), | ||
2267 | port->read_urb->transfer_buffer, | ||
2268 | port->read_urb->transfer_buffer_length, | ||
2269 | ftdi_read_bulk_callback, port); | ||
2270 | 2100 | ||
2271 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | 2101 | if (urb->status) { |
2272 | if (result) | 2102 | dbg("%s - nonzero read bulk status received: %d", |
2273 | dev_err(&port->dev, | 2103 | __func__, urb->status); |
2274 | "%s - failed resubmitting read urb, error %d\n", | 2104 | return; |
2275 | __func__, result); | ||
2276 | } | 2105 | } |
2277 | out: | ||
2278 | tty_kref_put(tty); | ||
2279 | } /* ftdi_process_read */ | ||
2280 | 2106 | ||
2107 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
2108 | urb->actual_length, urb->transfer_buffer); | ||
2109 | ftdi_process_read(port); | ||
2110 | |||
2111 | spin_lock_irqsave(&port->lock, flags); | ||
2112 | port->throttled = port->throttle_req; | ||
2113 | if (!port->throttled) { | ||
2114 | spin_unlock_irqrestore(&port->lock, flags); | ||
2115 | ftdi_submit_read_urb(port, GFP_ATOMIC); | ||
2116 | } else | ||
2117 | spin_unlock_irqrestore(&port->lock, flags); | ||
2118 | } | ||
2281 | 2119 | ||
2282 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | 2120 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state) |
2283 | { | 2121 | { |
@@ -2609,33 +2447,31 @@ static int ftdi_ioctl(struct tty_struct *tty, struct file *file, | |||
2609 | static void ftdi_throttle(struct tty_struct *tty) | 2447 | static void ftdi_throttle(struct tty_struct *tty) |
2610 | { | 2448 | { |
2611 | struct usb_serial_port *port = tty->driver_data; | 2449 | struct usb_serial_port *port = tty->driver_data; |
2612 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
2613 | unsigned long flags; | 2450 | unsigned long flags; |
2614 | 2451 | ||
2615 | dbg("%s - port %d", __func__, port->number); | 2452 | dbg("%s - port %d", __func__, port->number); |
2616 | 2453 | ||
2617 | spin_lock_irqsave(&priv->rx_lock, flags); | 2454 | spin_lock_irqsave(&port->lock, flags); |
2618 | priv->rx_flags |= THROTTLED; | 2455 | port->throttle_req = 1; |
2619 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 2456 | spin_unlock_irqrestore(&port->lock, flags); |
2620 | } | 2457 | } |
2621 | 2458 | ||
2622 | 2459 | void ftdi_unthrottle(struct tty_struct *tty) | |
2623 | static void ftdi_unthrottle(struct tty_struct *tty) | ||
2624 | { | 2460 | { |
2625 | struct usb_serial_port *port = tty->driver_data; | 2461 | struct usb_serial_port *port = tty->driver_data; |
2626 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2462 | int was_throttled; |
2627 | int actually_throttled; | ||
2628 | unsigned long flags; | 2463 | unsigned long flags; |
2629 | 2464 | ||
2630 | dbg("%s - port %d", __func__, port->number); | 2465 | dbg("%s - port %d", __func__, port->number); |
2631 | 2466 | ||
2632 | spin_lock_irqsave(&priv->rx_lock, flags); | 2467 | spin_lock_irqsave(&port->lock, flags); |
2633 | actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; | 2468 | was_throttled = port->throttled; |
2634 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); | 2469 | port->throttled = port->throttle_req = 0; |
2635 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 2470 | spin_unlock_irqrestore(&port->lock, flags); |
2636 | 2471 | ||
2637 | if (actually_throttled) | 2472 | /* Resubmit urb if throttled and open. */ |
2638 | schedule_delayed_work(&priv->rx_work, 0); | 2473 | if (was_throttled && test_bit(ASYNCB_INITIALIZED, &port->port.flags)) |
2474 | ftdi_submit_read_urb(port, GFP_KERNEL); | ||
2639 | } | 2475 | } |
2640 | 2476 | ||
2641 | static int __init ftdi_init(void) | 2477 | static int __init ftdi_init(void) |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 20432d345529..5ac900e5a50e 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -1390,14 +1390,13 @@ static void garmin_throttle(struct tty_struct *tty) | |||
1390 | { | 1390 | { |
1391 | struct usb_serial_port *port = tty->driver_data; | 1391 | struct usb_serial_port *port = tty->driver_data; |
1392 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); | 1392 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); |
1393 | unsigned long flags; | ||
1394 | 1393 | ||
1395 | dbg("%s - port %d", __func__, port->number); | 1394 | dbg("%s - port %d", __func__, port->number); |
1396 | /* set flag, data received will be put into a queue | 1395 | /* set flag, data received will be put into a queue |
1397 | for later processing */ | 1396 | for later processing */ |
1398 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1397 | spin_lock_irq(&garmin_data_p->lock); |
1399 | garmin_data_p->flags |= FLAGS_QUEUING|FLAGS_THROTTLED; | 1398 | garmin_data_p->flags |= FLAGS_QUEUING|FLAGS_THROTTLED; |
1400 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 1399 | spin_unlock_irq(&garmin_data_p->lock); |
1401 | } | 1400 | } |
1402 | 1401 | ||
1403 | 1402 | ||
@@ -1405,13 +1404,12 @@ static void garmin_unthrottle(struct tty_struct *tty) | |||
1405 | { | 1404 | { |
1406 | struct usb_serial_port *port = tty->driver_data; | 1405 | struct usb_serial_port *port = tty->driver_data; |
1407 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); | 1406 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); |
1408 | unsigned long flags; | ||
1409 | int status; | 1407 | int status; |
1410 | 1408 | ||
1411 | dbg("%s - port %d", __func__, port->number); | 1409 | dbg("%s - port %d", __func__, port->number); |
1412 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1410 | spin_lock_irq(&garmin_data_p->lock); |
1413 | garmin_data_p->flags &= ~FLAGS_THROTTLED; | 1411 | garmin_data_p->flags &= ~FLAGS_THROTTLED; |
1414 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 1412 | spin_unlock_irq(&garmin_data_p->lock); |
1415 | 1413 | ||
1416 | /* in native mode send queued data to tty, in | 1414 | /* in native mode send queued data to tty, in |
1417 | serial mode nothing needs to be done here */ | 1415 | serial mode nothing needs to be done here */ |
@@ -1419,7 +1417,7 @@ static void garmin_unthrottle(struct tty_struct *tty) | |||
1419 | garmin_flush_queue(garmin_data_p); | 1417 | garmin_flush_queue(garmin_data_p); |
1420 | 1418 | ||
1421 | if (0 != (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) { | 1419 | if (0 != (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) { |
1422 | status = usb_submit_urb(port->read_urb, GFP_ATOMIC); | 1420 | status = usb_submit_urb(port->read_urb, GFP_KERNEL); |
1423 | if (status) | 1421 | if (status) |
1424 | dev_err(&port->dev, | 1422 | dev_err(&port->dev, |
1425 | "%s - failed resubmitting read urb, error %d\n", | 1423 | "%s - failed resubmitting read urb, error %d\n", |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index deba08c7a015..bbe005cefcfb 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -546,7 +546,7 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) | |||
546 | 546 | ||
547 | if (was_throttled) { | 547 | if (was_throttled) { |
548 | /* Resume reading from device */ | 548 | /* Resume reading from device */ |
549 | usb_serial_generic_resubmit_read_urb(port, GFP_KERNEL); | 549 | flush_and_resubmit_read_urb(port); |
550 | } | 550 | } |
551 | } | 551 | } |
552 | 552 | ||
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 24fcc64b837d..d6231c38813e 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -966,6 +966,15 @@ static int ipaq_calc_num_ports(struct usb_serial *serial) | |||
966 | static int ipaq_startup(struct usb_serial *serial) | 966 | static int ipaq_startup(struct usb_serial *serial) |
967 | { | 967 | { |
968 | dbg("%s", __func__); | 968 | dbg("%s", __func__); |
969 | |||
970 | /* Some of the devices in ipaq_id_table[] are composite, and we | ||
971 | * shouldn't bind to all the interfaces. This test will rule out | ||
972 | * some obviously invalid possibilities. | ||
973 | */ | ||
974 | if (serial->num_bulk_in < serial->num_ports || | ||
975 | serial->num_bulk_out < serial->num_ports) | ||
976 | return -ENODEV; | ||
977 | |||
969 | if (serial->dev->actconfig->desc.bConfigurationValue != 1) { | 978 | if (serial->dev->actconfig->desc.bConfigurationValue != 1) { |
970 | /* | 979 | /* |
971 | * FIXME: HP iPaq rx3715, possibly others, have 1 config that | 980 | * FIXME: HP iPaq rx3715, possibly others, have 1 config that |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 257c16cc6b2a..1296a097f5c3 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -290,7 +290,7 @@ static void keyspan_pda_rx_unthrottle(struct tty_struct *tty) | |||
290 | /* just restart the receive interrupt URB */ | 290 | /* just restart the receive interrupt URB */ |
291 | dbg("keyspan_pda_rx_unthrottle port %d", port->number); | 291 | dbg("keyspan_pda_rx_unthrottle port %d", port->number); |
292 | port->interrupt_in_urb->dev = port->serial->dev; | 292 | port->interrupt_in_urb->dev = port->serial->dev; |
293 | if (usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC)) | 293 | if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL)) |
294 | dbg(" usb_submit_urb(read urb) failed"); | 294 | dbg(" usb_submit_urb(read urb) failed"); |
295 | return; | 295 | return; |
296 | } | 296 | } |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index f7373371b137..3a7873806f46 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -951,7 +951,7 @@ static void klsi_105_unthrottle(struct tty_struct *tty) | |||
951 | dbg("%s - port %d", __func__, port->number); | 951 | dbg("%s - port %d", __func__, port->number); |
952 | 952 | ||
953 | port->read_urb->dev = port->serial->dev; | 953 | port->read_urb->dev = port->serial->dev; |
954 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | 954 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); |
955 | if (result) | 955 | if (result) |
956 | dev_err(&port->dev, | 956 | dev_err(&port->dev, |
957 | "%s - failed submitting read urb, error %d\n", | 957 | "%s - failed submitting read urb, error %d\n", |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index ad4998bbf16f..cd009cb280a5 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -777,20 +777,19 @@ static void mct_u232_throttle(struct tty_struct *tty) | |||
777 | { | 777 | { |
778 | struct usb_serial_port *port = tty->driver_data; | 778 | struct usb_serial_port *port = tty->driver_data; |
779 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 779 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
780 | unsigned long flags; | ||
781 | unsigned int control_state; | 780 | unsigned int control_state; |
782 | 781 | ||
783 | dbg("%s - port %d", __func__, port->number); | 782 | dbg("%s - port %d", __func__, port->number); |
784 | 783 | ||
785 | spin_lock_irqsave(&priv->lock, flags); | 784 | spin_lock_irq(&priv->lock); |
786 | priv->rx_flags |= THROTTLED; | 785 | priv->rx_flags |= THROTTLED; |
787 | if (C_CRTSCTS(tty)) { | 786 | if (C_CRTSCTS(tty)) { |
788 | priv->control_state &= ~TIOCM_RTS; | 787 | priv->control_state &= ~TIOCM_RTS; |
789 | control_state = priv->control_state; | 788 | control_state = priv->control_state; |
790 | spin_unlock_irqrestore(&priv->lock, flags); | 789 | spin_unlock_irq(&priv->lock); |
791 | (void) mct_u232_set_modem_ctrl(port->serial, control_state); | 790 | (void) mct_u232_set_modem_ctrl(port->serial, control_state); |
792 | } else { | 791 | } else { |
793 | spin_unlock_irqrestore(&priv->lock, flags); | 792 | spin_unlock_irq(&priv->lock); |
794 | } | 793 | } |
795 | } | 794 | } |
796 | 795 | ||
@@ -799,20 +798,19 @@ static void mct_u232_unthrottle(struct tty_struct *tty) | |||
799 | { | 798 | { |
800 | struct usb_serial_port *port = tty->driver_data; | 799 | struct usb_serial_port *port = tty->driver_data; |
801 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 800 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
802 | unsigned long flags; | ||
803 | unsigned int control_state; | 801 | unsigned int control_state; |
804 | 802 | ||
805 | dbg("%s - port %d", __func__, port->number); | 803 | dbg("%s - port %d", __func__, port->number); |
806 | 804 | ||
807 | spin_lock_irqsave(&priv->lock, flags); | 805 | spin_lock_irq(&priv->lock); |
808 | if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) { | 806 | if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) { |
809 | priv->rx_flags &= ~THROTTLED; | 807 | priv->rx_flags &= ~THROTTLED; |
810 | priv->control_state |= TIOCM_RTS; | 808 | priv->control_state |= TIOCM_RTS; |
811 | control_state = priv->control_state; | 809 | control_state = priv->control_state; |
812 | spin_unlock_irqrestore(&priv->lock, flags); | 810 | spin_unlock_irq(&priv->lock); |
813 | (void) mct_u232_set_modem_ctrl(port->serial, control_state); | 811 | (void) mct_u232_set_modem_ctrl(port->serial, control_state); |
814 | } else { | 812 | } else { |
815 | spin_unlock_irqrestore(&priv->lock, flags); | 813 | spin_unlock_irq(&priv->lock); |
816 | } | 814 | } |
817 | } | 815 | } |
818 | 816 | ||
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 1085a577c5c1..80f59b6350cb 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
@@ -314,21 +314,24 @@ static void opticon_unthrottle(struct tty_struct *tty) | |||
314 | struct usb_serial_port *port = tty->driver_data; | 314 | struct usb_serial_port *port = tty->driver_data; |
315 | struct opticon_private *priv = usb_get_serial_data(port->serial); | 315 | struct opticon_private *priv = usb_get_serial_data(port->serial); |
316 | unsigned long flags; | 316 | unsigned long flags; |
317 | int result; | 317 | int result, was_throttled; |
318 | 318 | ||
319 | dbg("%s - port %d", __func__, port->number); | 319 | dbg("%s - port %d", __func__, port->number); |
320 | 320 | ||
321 | spin_lock_irqsave(&priv->lock, flags); | 321 | spin_lock_irqsave(&priv->lock, flags); |
322 | priv->throttled = false; | 322 | priv->throttled = false; |
323 | was_throttled = priv->actually_throttled; | ||
323 | priv->actually_throttled = false; | 324 | priv->actually_throttled = false; |
324 | spin_unlock_irqrestore(&priv->lock, flags); | 325 | spin_unlock_irqrestore(&priv->lock, flags); |
325 | 326 | ||
326 | priv->bulk_read_urb->dev = port->serial->dev; | 327 | priv->bulk_read_urb->dev = port->serial->dev; |
327 | result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); | 328 | if (was_throttled) { |
328 | if (result) | 329 | result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); |
329 | dev_err(&port->dev, | 330 | if (result) |
330 | "%s - failed submitting read urb, error %d\n", | 331 | dev_err(&port->dev, |
332 | "%s - failed submitting read urb, error %d\n", | ||
331 | __func__, result); | 333 | __func__, result); |
334 | } | ||
332 | } | 335 | } |
333 | 336 | ||
334 | static int opticon_tiocmget(struct tty_struct *tty, struct file *file) | 337 | static int opticon_tiocmget(struct tty_struct *tty, struct file *file) |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f66e39883218..43c227027560 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -165,6 +165,7 @@ static int option_resume(struct usb_serial *serial); | |||
165 | #define HUAWEI_PRODUCT_E143D 0x143D | 165 | #define HUAWEI_PRODUCT_E143D 0x143D |
166 | #define HUAWEI_PRODUCT_E143E 0x143E | 166 | #define HUAWEI_PRODUCT_E143E 0x143E |
167 | #define HUAWEI_PRODUCT_E143F 0x143F | 167 | #define HUAWEI_PRODUCT_E143F 0x143F |
168 | #define HUAWEI_PRODUCT_E14AC 0x14AC | ||
168 | 169 | ||
169 | #define QUANTA_VENDOR_ID 0x0408 | 170 | #define QUANTA_VENDOR_ID 0x0408 |
170 | #define QUANTA_PRODUCT_Q101 0xEA02 | 171 | #define QUANTA_PRODUCT_Q101 0xEA02 |
@@ -318,6 +319,7 @@ static int option_resume(struct usb_serial *serial); | |||
318 | /* TOSHIBA PRODUCTS */ | 319 | /* TOSHIBA PRODUCTS */ |
319 | #define TOSHIBA_VENDOR_ID 0x0930 | 320 | #define TOSHIBA_VENDOR_ID 0x0930 |
320 | #define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 | 321 | #define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 |
322 | #define TOSHIBA_PRODUCT_G450 0x0d45 | ||
321 | 323 | ||
322 | #define ALINK_VENDOR_ID 0x1e0e | 324 | #define ALINK_VENDOR_ID 0x1e0e |
323 | #define ALINK_PRODUCT_3GU 0x9200 | 325 | #define ALINK_PRODUCT_3GU 0x9200 |
@@ -424,6 +426,7 @@ static struct usb_device_id option_ids[] = { | |||
424 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, | 426 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, |
425 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, | 427 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, |
426 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, | 428 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, |
429 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) }, | ||
427 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) }, | 430 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) }, |
428 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ | 431 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ |
429 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ | 432 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ |
@@ -581,6 +584,7 @@ static struct usb_device_id option_ids[] = { | |||
581 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, | 584 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, |
582 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, | 585 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, |
583 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) }, | 586 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) }, |
587 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, | ||
584 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ | 588 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ |
585 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, | 589 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, |
586 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, | 590 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 0f4a70ce3823..c644e26394b4 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -288,7 +288,7 @@ static void setup_line(struct work_struct *work) | |||
288 | 288 | ||
289 | dbg("%s(): submitting interrupt urb", __func__); | 289 | dbg("%s(): submitting interrupt urb", __func__); |
290 | port->interrupt_in_urb->dev = port->serial->dev; | 290 | port->interrupt_in_urb->dev = port->serial->dev; |
291 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 291 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
292 | if (result != 0) { | 292 | if (result != 0) { |
293 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" | 293 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" |
294 | " with error %d\n", __func__, result); | 294 | " with error %d\n", __func__, result); |
@@ -335,7 +335,7 @@ void send_data(struct work_struct *work) | |||
335 | 335 | ||
336 | dbg("%s(): submitting interrupt urb", __func__); | 336 | dbg("%s(): submitting interrupt urb", __func__); |
337 | port->interrupt_in_urb->dev = port->serial->dev; | 337 | port->interrupt_in_urb->dev = port->serial->dev; |
338 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 338 | result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); |
339 | if (result != 0) { | 339 | if (result != 0) { |
340 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" | 340 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" |
341 | " with error %d\n", __func__, result); | 341 | " with error %d\n", __func__, result); |
@@ -349,7 +349,7 @@ void send_data(struct work_struct *work) | |||
349 | 349 | ||
350 | port->write_urb->transfer_buffer_length = count; | 350 | port->write_urb->transfer_buffer_length = count; |
351 | port->write_urb->dev = port->serial->dev; | 351 | port->write_urb->dev = port->serial->dev; |
352 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | 352 | result = usb_submit_urb(port->write_urb, GFP_NOIO); |
353 | if (result != 0) { | 353 | if (result != 0) { |
354 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" | 354 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" |
355 | " with error %d\n", __func__, result); | 355 | " with error %d\n", __func__, result); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 1128e01525b1..9ec1a49e2362 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -1046,13 +1046,15 @@ static void pl2303_push_data(struct tty_struct *tty, | |||
1046 | /* overrun is special, not associated with a char */ | 1046 | /* overrun is special, not associated with a char */ |
1047 | if (line_status & UART_OVERRUN_ERROR) | 1047 | if (line_status & UART_OVERRUN_ERROR) |
1048 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 1048 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
1049 | if (port->console && port->sysrq) { | 1049 | |
1050 | if (tty_flag == TTY_NORMAL && !(port->console && port->sysrq)) | ||
1051 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
1052 | else { | ||
1050 | int i; | 1053 | int i; |
1051 | for (i = 0; i < urb->actual_length; ++i) | 1054 | for (i = 0; i < urb->actual_length; ++i) |
1052 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) | 1055 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) |
1053 | tty_insert_flip_char(tty, data[i], tty_flag); | 1056 | tty_insert_flip_char(tty, data[i], tty_flag); |
1054 | } else | 1057 | } |
1055 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
1056 | tty_flip_buffer_push(tty); | 1058 | tty_flip_buffer_push(tty); |
1057 | } | 1059 | } |
1058 | 1060 | ||
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 8c075b2416bb..45883988a005 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -17,7 +17,7 @@ | |||
17 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 17 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define DRIVER_VERSION "v.1.3.7" | 20 | #define DRIVER_VERSION "v.1.3.8" |
21 | #define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" | 21 | #define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" |
22 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" | 22 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" |
23 | 23 | ||
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index cb7e95f9fcbf..b282c0f2d8e5 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c | |||
@@ -165,34 +165,36 @@ static void symbol_throttle(struct tty_struct *tty) | |||
165 | { | 165 | { |
166 | struct usb_serial_port *port = tty->driver_data; | 166 | struct usb_serial_port *port = tty->driver_data; |
167 | struct symbol_private *priv = usb_get_serial_data(port->serial); | 167 | struct symbol_private *priv = usb_get_serial_data(port->serial); |
168 | unsigned long flags; | ||
169 | 168 | ||
170 | dbg("%s - port %d", __func__, port->number); | 169 | dbg("%s - port %d", __func__, port->number); |
171 | spin_lock_irqsave(&priv->lock, flags); | 170 | spin_lock_irq(&priv->lock); |
172 | priv->throttled = true; | 171 | priv->throttled = true; |
173 | spin_unlock_irqrestore(&priv->lock, flags); | 172 | spin_unlock_irq(&priv->lock); |
174 | } | 173 | } |
175 | 174 | ||
176 | static void symbol_unthrottle(struct tty_struct *tty) | 175 | static void symbol_unthrottle(struct tty_struct *tty) |
177 | { | 176 | { |
178 | struct usb_serial_port *port = tty->driver_data; | 177 | struct usb_serial_port *port = tty->driver_data; |
179 | struct symbol_private *priv = usb_get_serial_data(port->serial); | 178 | struct symbol_private *priv = usb_get_serial_data(port->serial); |
180 | unsigned long flags; | ||
181 | int result; | 179 | int result; |
180 | bool was_throttled; | ||
182 | 181 | ||
183 | dbg("%s - port %d", __func__, port->number); | 182 | dbg("%s - port %d", __func__, port->number); |
184 | 183 | ||
185 | spin_lock_irqsave(&priv->lock, flags); | 184 | spin_lock_irq(&priv->lock); |
186 | priv->throttled = false; | 185 | priv->throttled = false; |
186 | was_throttled = priv->actually_throttled; | ||
187 | priv->actually_throttled = false; | 187 | priv->actually_throttled = false; |
188 | spin_unlock_irqrestore(&priv->lock, flags); | 188 | spin_unlock_irq(&priv->lock); |
189 | 189 | ||
190 | priv->int_urb->dev = port->serial->dev; | 190 | priv->int_urb->dev = port->serial->dev; |
191 | result = usb_submit_urb(priv->int_urb, GFP_ATOMIC); | 191 | if (was_throttled) { |
192 | if (result) | 192 | result = usb_submit_urb(priv->int_urb, GFP_KERNEL); |
193 | dev_err(&port->dev, | 193 | if (result) |
194 | "%s - failed submitting read urb, error %d\n", | 194 | dev_err(&port->dev, |
195 | "%s - failed submitting read urb, error %d\n", | ||
195 | __func__, result); | 196 | __func__, result); |
197 | } | ||
196 | } | 198 | } |
197 | 199 | ||
198 | static int symbol_startup(struct usb_serial *serial) | 200 | static int symbol_startup(struct usb_serial *serial) |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index aa6b2ae951ae..bd3fa7ff15b1 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -156,7 +156,8 @@ static void destroy_serial(struct kref *kref) | |||
156 | if (serial->minor != SERIAL_TTY_NO_MINOR) | 156 | if (serial->minor != SERIAL_TTY_NO_MINOR) |
157 | return_serial(serial); | 157 | return_serial(serial); |
158 | 158 | ||
159 | serial->type->release(serial); | 159 | if (serial->attached) |
160 | serial->type->release(serial); | ||
160 | 161 | ||
161 | /* Now that nothing is using the ports, they can be freed */ | 162 | /* Now that nothing is using the ports, they can be freed */ |
162 | for (i = 0; i < serial->num_port_pointers; ++i) { | 163 | for (i = 0; i < serial->num_port_pointers; ++i) { |
@@ -1059,12 +1060,15 @@ int usb_serial_probe(struct usb_interface *interface, | |||
1059 | module_put(type->driver.owner); | 1060 | module_put(type->driver.owner); |
1060 | if (retval < 0) | 1061 | if (retval < 0) |
1061 | goto probe_error; | 1062 | goto probe_error; |
1063 | serial->attached = 1; | ||
1062 | if (retval > 0) { | 1064 | if (retval > 0) { |
1063 | /* quietly accept this device, but don't bind to a | 1065 | /* quietly accept this device, but don't bind to a |
1064 | serial port as it's about to disappear */ | 1066 | serial port as it's about to disappear */ |
1065 | serial->num_ports = 0; | 1067 | serial->num_ports = 0; |
1066 | goto exit; | 1068 | goto exit; |
1067 | } | 1069 | } |
1070 | } else { | ||
1071 | serial->attached = 1; | ||
1068 | } | 1072 | } |
1069 | 1073 | ||
1070 | if (get_free_serial(serial, num_ports, &minor) == NULL) { | 1074 | if (get_free_serial(serial, num_ports, &minor) == NULL) { |
@@ -1164,8 +1168,10 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) | |||
1164 | 1168 | ||
1165 | if (serial->type->suspend) { | 1169 | if (serial->type->suspend) { |
1166 | r = serial->type->suspend(serial, message); | 1170 | r = serial->type->suspend(serial, message); |
1167 | if (r < 0) | 1171 | if (r < 0) { |
1172 | serial->suspending = 0; | ||
1168 | goto err_out; | 1173 | goto err_out; |
1174 | } | ||
1169 | } | 1175 | } |
1170 | 1176 | ||
1171 | for (i = 0; i < serial->num_ports; ++i) { | 1177 | for (i = 0; i < serial->num_ports; ++i) { |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 1aa5d20a5d99..ad1f9232292d 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -513,7 +513,8 @@ static void visor_read_bulk_callback(struct urb *urb) | |||
513 | tty_kref_put(tty); | 513 | tty_kref_put(tty); |
514 | } | 514 | } |
515 | spin_lock(&priv->lock); | 515 | spin_lock(&priv->lock); |
516 | priv->bytes_in += available_room; | 516 | if (tty) |
517 | priv->bytes_in += available_room; | ||
517 | 518 | ||
518 | } else { | 519 | } else { |
519 | spin_lock(&priv->lock); | 520 | spin_lock(&priv->lock); |
@@ -582,12 +583,11 @@ static void visor_throttle(struct tty_struct *tty) | |||
582 | { | 583 | { |
583 | struct usb_serial_port *port = tty->driver_data; | 584 | struct usb_serial_port *port = tty->driver_data; |
584 | struct visor_private *priv = usb_get_serial_port_data(port); | 585 | struct visor_private *priv = usb_get_serial_port_data(port); |
585 | unsigned long flags; | ||
586 | 586 | ||
587 | dbg("%s - port %d", __func__, port->number); | 587 | dbg("%s - port %d", __func__, port->number); |
588 | spin_lock_irqsave(&priv->lock, flags); | 588 | spin_lock_irq(&priv->lock); |
589 | priv->throttled = 1; | 589 | priv->throttled = 1; |
590 | spin_unlock_irqrestore(&priv->lock, flags); | 590 | spin_unlock_irq(&priv->lock); |
591 | } | 591 | } |
592 | 592 | ||
593 | 593 | ||
@@ -595,21 +595,23 @@ static void visor_unthrottle(struct tty_struct *tty) | |||
595 | { | 595 | { |
596 | struct usb_serial_port *port = tty->driver_data; | 596 | struct usb_serial_port *port = tty->driver_data; |
597 | struct visor_private *priv = usb_get_serial_port_data(port); | 597 | struct visor_private *priv = usb_get_serial_port_data(port); |
598 | unsigned long flags; | 598 | int result, was_throttled; |
599 | int result; | ||
600 | 599 | ||
601 | dbg("%s - port %d", __func__, port->number); | 600 | dbg("%s - port %d", __func__, port->number); |
602 | spin_lock_irqsave(&priv->lock, flags); | 601 | spin_lock_irq(&priv->lock); |
603 | priv->throttled = 0; | 602 | priv->throttled = 0; |
603 | was_throttled = priv->actually_throttled; | ||
604 | priv->actually_throttled = 0; | 604 | priv->actually_throttled = 0; |
605 | spin_unlock_irqrestore(&priv->lock, flags); | 605 | spin_unlock_irq(&priv->lock); |
606 | 606 | ||
607 | port->read_urb->dev = port->serial->dev; | 607 | if (was_throttled) { |
608 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | 608 | port->read_urb->dev = port->serial->dev; |
609 | if (result) | 609 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); |
610 | dev_err(&port->dev, | 610 | if (result) |
611 | "%s - failed submitting read urb, error %d\n", | 611 | dev_err(&port->dev, |
612 | "%s - failed submitting read urb, error %d\n", | ||
612 | __func__, result); | 613 | __func__, result); |
614 | } | ||
613 | } | 615 | } |
614 | 616 | ||
615 | static int palm_os_3_probe(struct usb_serial *serial, | 617 | static int palm_os_3_probe(struct usb_serial *serial, |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 62424eec33ec..1093d2eb046a 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -949,13 +949,12 @@ static void whiteheat_throttle(struct tty_struct *tty) | |||
949 | { | 949 | { |
950 | struct usb_serial_port *port = tty->driver_data; | 950 | struct usb_serial_port *port = tty->driver_data; |
951 | struct whiteheat_private *info = usb_get_serial_port_data(port); | 951 | struct whiteheat_private *info = usb_get_serial_port_data(port); |
952 | unsigned long flags; | ||
953 | 952 | ||
954 | dbg("%s - port %d", __func__, port->number); | 953 | dbg("%s - port %d", __func__, port->number); |
955 | 954 | ||
956 | spin_lock_irqsave(&info->lock, flags); | 955 | spin_lock_irq(&info->lock); |
957 | info->flags |= THROTTLED; | 956 | info->flags |= THROTTLED; |
958 | spin_unlock_irqrestore(&info->lock, flags); | 957 | spin_unlock_irq(&info->lock); |
959 | 958 | ||
960 | return; | 959 | return; |
961 | } | 960 | } |
@@ -966,14 +965,13 @@ static void whiteheat_unthrottle(struct tty_struct *tty) | |||
966 | struct usb_serial_port *port = tty->driver_data; | 965 | struct usb_serial_port *port = tty->driver_data; |
967 | struct whiteheat_private *info = usb_get_serial_port_data(port); | 966 | struct whiteheat_private *info = usb_get_serial_port_data(port); |
968 | int actually_throttled; | 967 | int actually_throttled; |
969 | unsigned long flags; | ||
970 | 968 | ||
971 | dbg("%s - port %d", __func__, port->number); | 969 | dbg("%s - port %d", __func__, port->number); |
972 | 970 | ||
973 | spin_lock_irqsave(&info->lock, flags); | 971 | spin_lock_irq(&info->lock); |
974 | actually_throttled = info->flags & ACTUALLY_THROTTLED; | 972 | actually_throttled = info->flags & ACTUALLY_THROTTLED; |
975 | info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED); | 973 | info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED); |
976 | spin_unlock_irqrestore(&info->lock, flags); | 974 | spin_unlock_irq(&info->lock); |
977 | 975 | ||
978 | if (actually_throttled) | 976 | if (actually_throttled) |
979 | rx_data_softint(&info->rx_work); | 977 | rx_data_softint(&info->rx_work); |