aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/hso.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/hso.c')
-rw-r--r--drivers/net/usb/hso.c54
1 files changed, 42 insertions, 12 deletions
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 9f7896a25f1b..d345a6eec4ca 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -1015,7 +1015,7 @@ static void _hso_serial_set_termios(struct tty_struct *tty,
1015 struct hso_serial *serial = get_serial_by_tty(tty); 1015 struct hso_serial *serial = get_serial_by_tty(tty);
1016 struct ktermios *termios; 1016 struct ktermios *termios;
1017 1017
1018 if ((!tty) || (!tty->termios) || (!serial)) { 1018 if (!serial) {
1019 printk(KERN_ERR "%s: no tty structures", __func__); 1019 printk(KERN_ERR "%s: no tty structures", __func__);
1020 return; 1020 return;
1021 } 1021 }
@@ -1057,14 +1057,14 @@ static void _hso_serial_set_termios(struct tty_struct *tty,
1057 termios->c_cflag |= CS8; /* character size 8 bits */ 1057 termios->c_cflag |= CS8; /* character size 8 bits */
1058 1058
1059 /* baud rate 115200 */ 1059 /* baud rate 115200 */
1060 tty_encode_baud_rate(serial->tty, 115200, 115200); 1060 tty_encode_baud_rate(tty, 115200, 115200);
1061 1061
1062 /* 1062 /*
1063 * Force low_latency on; otherwise the pushes are scheduled; 1063 * Force low_latency on; otherwise the pushes are scheduled;
1064 * this is bad as it opens up the possibility of dropping bytes 1064 * this is bad as it opens up the possibility of dropping bytes
1065 * on the floor. We don't want to drop bytes on the floor. :) 1065 * on the floor. We don't want to drop bytes on the floor. :)
1066 */ 1066 */
1067 serial->tty->low_latency = 1; 1067 tty->low_latency = 1;
1068 return; 1068 return;
1069} 1069}
1070 1070
@@ -1228,6 +1228,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
1228 1228
1229 /* sanity check */ 1229 /* sanity check */
1230 if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) { 1230 if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) {
1231 WARN_ON(1);
1231 tty->driver_data = NULL; 1232 tty->driver_data = NULL;
1232 D1("Failed to open port"); 1233 D1("Failed to open port");
1233 return -ENODEV; 1234 return -ENODEV;
@@ -1242,8 +1243,10 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
1242 kref_get(&serial->parent->ref); 1243 kref_get(&serial->parent->ref);
1243 1244
1244 /* setup */ 1245 /* setup */
1246 spin_lock_irq(&serial->serial_lock);
1245 tty->driver_data = serial; 1247 tty->driver_data = serial;
1246 serial->tty = tty; 1248 serial->tty = tty_kref_get(tty);
1249 spin_unlock_irq(&serial->serial_lock);
1247 1250
1248 /* check for port already opened, if not set the termios */ 1251 /* check for port already opened, if not set the termios */
1249 serial->open_count++; 1252 serial->open_count++;
@@ -1285,6 +1288,10 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
1285 1288
1286 D1("Closing serial port"); 1289 D1("Closing serial port");
1287 1290
1291 /* Open failed, no close cleanup required */
1292 if (serial == NULL)
1293 return;
1294
1288 mutex_lock(&serial->parent->mutex); 1295 mutex_lock(&serial->parent->mutex);
1289 usb_gone = serial->parent->usb_gone; 1296 usb_gone = serial->parent->usb_gone;
1290 1297
@@ -1297,10 +1304,13 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
1297 kref_put(&serial->parent->ref, hso_serial_ref_free); 1304 kref_put(&serial->parent->ref, hso_serial_ref_free);
1298 if (serial->open_count <= 0) { 1305 if (serial->open_count <= 0) {
1299 serial->open_count = 0; 1306 serial->open_count = 0;
1300 if (serial->tty) { 1307 spin_lock_irq(&serial->serial_lock);
1308 if (serial->tty == tty) {
1301 serial->tty->driver_data = NULL; 1309 serial->tty->driver_data = NULL;
1302 serial->tty = NULL; 1310 serial->tty = NULL;
1311 tty_kref_put(tty);
1303 } 1312 }
1313 spin_unlock_irq(&serial->serial_lock);
1304 if (!usb_gone) 1314 if (!usb_gone)
1305 hso_stop_serial_device(serial->parent); 1315 hso_stop_serial_device(serial->parent);
1306 tasklet_kill(&serial->unthrottle_tasklet); 1316 tasklet_kill(&serial->unthrottle_tasklet);
@@ -1653,6 +1663,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
1653{ 1663{
1654 struct hso_serial *serial = urb->context; 1664 struct hso_serial *serial = urb->context;
1655 int status = urb->status; 1665 int status = urb->status;
1666 struct tty_struct *tty;
1656 1667
1657 /* sanity check */ 1668 /* sanity check */
1658 if (!serial) { 1669 if (!serial) {
@@ -1662,14 +1673,18 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
1662 1673
1663 spin_lock(&serial->serial_lock); 1674 spin_lock(&serial->serial_lock);
1664 serial->tx_urb_used = 0; 1675 serial->tx_urb_used = 0;
1676 tty = tty_kref_get(serial->tty);
1665 spin_unlock(&serial->serial_lock); 1677 spin_unlock(&serial->serial_lock);
1666 if (status) { 1678 if (status) {
1667 log_usb_status(status, __func__); 1679 log_usb_status(status, __func__);
1680 tty_kref_put(tty);
1668 return; 1681 return;
1669 } 1682 }
1670 hso_put_activity(serial->parent); 1683 hso_put_activity(serial->parent);
1671 if (serial->tty) 1684 if (tty) {
1672 tty_wakeup(serial->tty); 1685 tty_wakeup(tty);
1686 tty_kref_put(tty);
1687 }
1673 hso_kick_transmit(serial); 1688 hso_kick_transmit(serial);
1674 1689
1675 D1(" "); 1690 D1(" ");
@@ -1706,6 +1721,7 @@ static void ctrl_callback(struct urb *urb)
1706 struct hso_serial *serial = urb->context; 1721 struct hso_serial *serial = urb->context;
1707 struct usb_ctrlrequest *req; 1722 struct usb_ctrlrequest *req;
1708 int status = urb->status; 1723 int status = urb->status;
1724 struct tty_struct *tty;
1709 1725
1710 /* sanity check */ 1726 /* sanity check */
1711 if (!serial) 1727 if (!serial)
@@ -1713,9 +1729,11 @@ static void ctrl_callback(struct urb *urb)
1713 1729
1714 spin_lock(&serial->serial_lock); 1730 spin_lock(&serial->serial_lock);
1715 serial->tx_urb_used = 0; 1731 serial->tx_urb_used = 0;
1732 tty = tty_kref_get(serial->tty);
1716 spin_unlock(&serial->serial_lock); 1733 spin_unlock(&serial->serial_lock);
1717 if (status) { 1734 if (status) {
1718 log_usb_status(status, __func__); 1735 log_usb_status(status, __func__);
1736 tty_kref_put(tty);
1719 return; 1737 return;
1720 } 1738 }
1721 1739
@@ -1734,25 +1752,31 @@ static void ctrl_callback(struct urb *urb)
1734 spin_unlock(&serial->serial_lock); 1752 spin_unlock(&serial->serial_lock);
1735 } else { 1753 } else {
1736 hso_put_activity(serial->parent); 1754 hso_put_activity(serial->parent);
1737 if (serial->tty) 1755 if (tty)
1738 tty_wakeup(serial->tty); 1756 tty_wakeup(tty);
1739 /* response to a write command */ 1757 /* response to a write command */
1740 hso_kick_transmit(serial); 1758 hso_kick_transmit(serial);
1741 } 1759 }
1760 tty_kref_put(tty);
1742} 1761}
1743 1762
1744/* handle RX data for serial port */ 1763/* handle RX data for serial port */
1745static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) 1764static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
1746{ 1765{
1747 struct tty_struct *tty = serial->tty; 1766 struct tty_struct *tty;
1748 int write_length_remaining = 0; 1767 int write_length_remaining = 0;
1749 int curr_write_len; 1768 int curr_write_len;
1769
1750 /* Sanity check */ 1770 /* Sanity check */
1751 if (urb == NULL || serial == NULL) { 1771 if (urb == NULL || serial == NULL) {
1752 D1("serial = NULL"); 1772 D1("serial = NULL");
1753 return -2; 1773 return -2;
1754 } 1774 }
1755 1775
1776 spin_lock(&serial->serial_lock);
1777 tty = tty_kref_get(serial->tty);
1778 spin_unlock(&serial->serial_lock);
1779
1756 /* Push data to tty */ 1780 /* Push data to tty */
1757 if (tty) { 1781 if (tty) {
1758 write_length_remaining = urb->actual_length - 1782 write_length_remaining = urb->actual_length -
@@ -1774,6 +1798,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
1774 serial->curr_rx_urb_offset = 0; 1798 serial->curr_rx_urb_offset = 0;
1775 serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; 1799 serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
1776 } 1800 }
1801 tty_kref_put(tty);
1777 return write_length_remaining; 1802 return write_length_remaining;
1778} 1803}
1779 1804
@@ -2786,15 +2811,20 @@ static void hso_serial_ref_free(struct kref *ref)
2786static void hso_free_interface(struct usb_interface *interface) 2811static void hso_free_interface(struct usb_interface *interface)
2787{ 2812{
2788 struct hso_serial *hso_dev; 2813 struct hso_serial *hso_dev;
2814 struct tty_struct *tty;
2789 int i; 2815 int i;
2790 2816
2791 for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { 2817 for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
2792 if (serial_table[i] 2818 if (serial_table[i]
2793 && (serial_table[i]->interface == interface)) { 2819 && (serial_table[i]->interface == interface)) {
2794 hso_dev = dev2ser(serial_table[i]); 2820 hso_dev = dev2ser(serial_table[i]);
2795 if (hso_dev->tty) 2821 spin_lock_irq(&hso_dev->serial_lock);
2796 tty_hangup(hso_dev->tty); 2822 tty = tty_kref_get(hso_dev->tty);
2823 spin_unlock_irq(&hso_dev->serial_lock);
2824 if (tty)
2825 tty_hangup(tty);
2797 mutex_lock(&hso_dev->parent->mutex); 2826 mutex_lock(&hso_dev->parent->mutex);
2827 tty_kref_put(tty);
2798 hso_dev->parent->usb_gone = 1; 2828 hso_dev->parent->usb_gone = 1;
2799 mutex_unlock(&hso_dev->parent->mutex); 2829 mutex_unlock(&hso_dev->parent->mutex);
2800 kref_put(&serial_table[i]->ref, hso_serial_ref_free); 2830 kref_put(&serial_table[i]->ref, hso_serial_ref_free);