diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 19:12:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 19:12:24 -0400 |
commit | 94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9 (patch) | |
tree | 39197121b6ef8cddaa0f4057fe24b4ced58e8982 /drivers/net/usb/hso.c | |
parent | 5d4e2d08e7fdf7339f84a1c670d296a77e02f881 (diff) | |
parent | 59bd234b72fc29887839d792b7d6c7e8d2a577a6 (diff) |
Merge tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY updates from Greg Kroah-Hartman:
"Here's the big TTY/serial driver pull request for the 3.5-rc1 merge
window.
Nothing major in here, just lots of incremental changes from Alan and
Jiri reworking some tty core things to behave better and to get a more
solid grasp on some of the nasty tty locking issues.
There are a few tty and serial driver updates in here as well.
All of this has been in the linux-next releases for a while with no
problems.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
* tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (115 commits)
serial: bfin_uart: Make MMR access compatible with 32 bits bf609 style controller.
serial: bfin_uart: RTS and CTS MMRs can be either 16-bit width or 32-bit width.
serial: bfin_uart: narrow the reboot condition in DMA tx interrupt
serial: bfin_uart: Adapt bf5xx serial driver to bf60x serial4 controller.
Revert "serial_core: Update buffer overrun statistics."
tty: hvc_xen: NULL dereference on allocation failure
tty: Fix LED error return
tty: Allow uart_register/unregister/register
tty: move global ldisc idle waitqueue to the individual ldisc
serial8250-em: Add DT support
serial8250-em: clk_get() IS_ERR() error handling fix
serial_core: Update buffer overrun statistics.
tty: drop the pty lock during hangup
cris: fix missing tty arg in wait_event_interruptible_tty call
tty/amiserial: Add missing argument for tty_unlock()
tty_lock: Localise the lock
pty: Lock the devpts bits privately
tty_lock: undo the old tty_lock use on the ctty
serial8250-em: Emma Mobile UART driver V2
Add missing call to uart_update_timeout()
...
Diffstat (limited to 'drivers/net/usb/hso.c')
-rw-r--r-- | drivers/net/usb/hso.c | 105 |
1 files changed, 44 insertions, 61 deletions
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 042c1a99520f..62f30b46fa42 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -106,13 +106,6 @@ | |||
106 | 106 | ||
107 | #define MAX_RX_URBS 2 | 107 | #define MAX_RX_URBS 2 |
108 | 108 | ||
109 | static inline struct hso_serial *get_serial_by_tty(struct tty_struct *tty) | ||
110 | { | ||
111 | if (tty) | ||
112 | return tty->driver_data; | ||
113 | return NULL; | ||
114 | } | ||
115 | |||
116 | /*****************************************************************************/ | 109 | /*****************************************************************************/ |
117 | /* Debugging functions */ | 110 | /* Debugging functions */ |
118 | /*****************************************************************************/ | 111 | /*****************************************************************************/ |
@@ -255,9 +248,8 @@ struct hso_serial { | |||
255 | u8 dtr_state; | 248 | u8 dtr_state; |
256 | unsigned tx_urb_used:1; | 249 | unsigned tx_urb_used:1; |
257 | 250 | ||
251 | struct tty_port port; | ||
258 | /* from usb_serial_port */ | 252 | /* from usb_serial_port */ |
259 | struct tty_struct *tty; | ||
260 | int open_count; | ||
261 | spinlock_t serial_lock; | 253 | spinlock_t serial_lock; |
262 | 254 | ||
263 | int (*write_data) (struct hso_serial *serial); | 255 | int (*write_data) (struct hso_serial *serial); |
@@ -1114,7 +1106,7 @@ static void hso_init_termios(struct ktermios *termios) | |||
1114 | static void _hso_serial_set_termios(struct tty_struct *tty, | 1106 | static void _hso_serial_set_termios(struct tty_struct *tty, |
1115 | struct ktermios *old) | 1107 | struct ktermios *old) |
1116 | { | 1108 | { |
1117 | struct hso_serial *serial = get_serial_by_tty(tty); | 1109 | struct hso_serial *serial = tty->driver_data; |
1118 | struct ktermios *termios; | 1110 | struct ktermios *termios; |
1119 | 1111 | ||
1120 | if (!serial) { | 1112 | if (!serial) { |
@@ -1190,7 +1182,7 @@ static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial) | |||
1190 | struct urb *urb; | 1182 | struct urb *urb; |
1191 | 1183 | ||
1192 | urb = serial->rx_urb[0]; | 1184 | urb = serial->rx_urb[0]; |
1193 | if (serial->open_count > 0) { | 1185 | if (serial->port.count > 0) { |
1194 | count = put_rxbuf_data(urb, serial); | 1186 | count = put_rxbuf_data(urb, serial); |
1195 | if (count == -1) | 1187 | if (count == -1) |
1196 | return; | 1188 | return; |
@@ -1226,7 +1218,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1226 | DUMP1(urb->transfer_buffer, urb->actual_length); | 1218 | DUMP1(urb->transfer_buffer, urb->actual_length); |
1227 | 1219 | ||
1228 | /* Anyone listening? */ | 1220 | /* Anyone listening? */ |
1229 | if (serial->open_count == 0) | 1221 | if (serial->port.count == 0) |
1230 | return; | 1222 | return; |
1231 | 1223 | ||
1232 | if (status == 0) { | 1224 | if (status == 0) { |
@@ -1268,7 +1260,7 @@ static void hso_unthrottle_tasklet(struct hso_serial *serial) | |||
1268 | 1260 | ||
1269 | static void hso_unthrottle(struct tty_struct *tty) | 1261 | static void hso_unthrottle(struct tty_struct *tty) |
1270 | { | 1262 | { |
1271 | struct hso_serial *serial = get_serial_by_tty(tty); | 1263 | struct hso_serial *serial = tty->driver_data; |
1272 | 1264 | ||
1273 | tasklet_hi_schedule(&serial->unthrottle_tasklet); | 1265 | tasklet_hi_schedule(&serial->unthrottle_tasklet); |
1274 | } | 1266 | } |
@@ -1304,15 +1296,12 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) | |||
1304 | kref_get(&serial->parent->ref); | 1296 | kref_get(&serial->parent->ref); |
1305 | 1297 | ||
1306 | /* setup */ | 1298 | /* setup */ |
1307 | spin_lock_irq(&serial->serial_lock); | ||
1308 | tty->driver_data = serial; | 1299 | tty->driver_data = serial; |
1309 | tty_kref_put(serial->tty); | 1300 | tty_port_tty_set(&serial->port, tty); |
1310 | serial->tty = tty_kref_get(tty); | ||
1311 | spin_unlock_irq(&serial->serial_lock); | ||
1312 | 1301 | ||
1313 | /* check for port already opened, if not set the termios */ | 1302 | /* check for port already opened, if not set the termios */ |
1314 | serial->open_count++; | 1303 | serial->port.count++; |
1315 | if (serial->open_count == 1) { | 1304 | if (serial->port.count == 1) { |
1316 | serial->rx_state = RX_IDLE; | 1305 | serial->rx_state = RX_IDLE; |
1317 | /* Force default termio settings */ | 1306 | /* Force default termio settings */ |
1318 | _hso_serial_set_termios(tty, NULL); | 1307 | _hso_serial_set_termios(tty, NULL); |
@@ -1324,7 +1313,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) | |||
1324 | result = hso_start_serial_device(serial->parent, GFP_KERNEL); | 1313 | result = hso_start_serial_device(serial->parent, GFP_KERNEL); |
1325 | if (result) { | 1314 | if (result) { |
1326 | hso_stop_serial_device(serial->parent); | 1315 | hso_stop_serial_device(serial->parent); |
1327 | serial->open_count--; | 1316 | serial->port.count--; |
1328 | kref_put(&serial->parent->ref, hso_serial_ref_free); | 1317 | kref_put(&serial->parent->ref, hso_serial_ref_free); |
1329 | } | 1318 | } |
1330 | } else { | 1319 | } else { |
@@ -1361,17 +1350,11 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) | |||
1361 | 1350 | ||
1362 | /* reset the rts and dtr */ | 1351 | /* reset the rts and dtr */ |
1363 | /* do the actual close */ | 1352 | /* do the actual close */ |
1364 | serial->open_count--; | 1353 | serial->port.count--; |
1365 | 1354 | ||
1366 | if (serial->open_count <= 0) { | 1355 | if (serial->port.count <= 0) { |
1367 | serial->open_count = 0; | 1356 | serial->port.count = 0; |
1368 | spin_lock_irq(&serial->serial_lock); | 1357 | tty_port_tty_set(&serial->port, NULL); |
1369 | if (serial->tty == tty) { | ||
1370 | serial->tty->driver_data = NULL; | ||
1371 | serial->tty = NULL; | ||
1372 | tty_kref_put(tty); | ||
1373 | } | ||
1374 | spin_unlock_irq(&serial->serial_lock); | ||
1375 | if (!usb_gone) | 1358 | if (!usb_gone) |
1376 | hso_stop_serial_device(serial->parent); | 1359 | hso_stop_serial_device(serial->parent); |
1377 | tasklet_kill(&serial->unthrottle_tasklet); | 1360 | tasklet_kill(&serial->unthrottle_tasklet); |
@@ -1390,7 +1373,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) | |||
1390 | static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf, | 1373 | static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf, |
1391 | int count) | 1374 | int count) |
1392 | { | 1375 | { |
1393 | struct hso_serial *serial = get_serial_by_tty(tty); | 1376 | struct hso_serial *serial = tty->driver_data; |
1394 | int space, tx_bytes; | 1377 | int space, tx_bytes; |
1395 | unsigned long flags; | 1378 | unsigned long flags; |
1396 | 1379 | ||
@@ -1422,7 +1405,7 @@ out: | |||
1422 | /* how much room is there for writing */ | 1405 | /* how much room is there for writing */ |
1423 | static int hso_serial_write_room(struct tty_struct *tty) | 1406 | static int hso_serial_write_room(struct tty_struct *tty) |
1424 | { | 1407 | { |
1425 | struct hso_serial *serial = get_serial_by_tty(tty); | 1408 | struct hso_serial *serial = tty->driver_data; |
1426 | int room; | 1409 | int room; |
1427 | unsigned long flags; | 1410 | unsigned long flags; |
1428 | 1411 | ||
@@ -1437,7 +1420,7 @@ static int hso_serial_write_room(struct tty_struct *tty) | |||
1437 | /* setup the term */ | 1420 | /* setup the term */ |
1438 | static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) | 1421 | static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) |
1439 | { | 1422 | { |
1440 | struct hso_serial *serial = get_serial_by_tty(tty); | 1423 | struct hso_serial *serial = tty->driver_data; |
1441 | unsigned long flags; | 1424 | unsigned long flags; |
1442 | 1425 | ||
1443 | if (old) | 1426 | if (old) |
@@ -1446,7 +1429,7 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1446 | 1429 | ||
1447 | /* the actual setup */ | 1430 | /* the actual setup */ |
1448 | spin_lock_irqsave(&serial->serial_lock, flags); | 1431 | spin_lock_irqsave(&serial->serial_lock, flags); |
1449 | if (serial->open_count) | 1432 | if (serial->port.count) |
1450 | _hso_serial_set_termios(tty, old); | 1433 | _hso_serial_set_termios(tty, old); |
1451 | else | 1434 | else |
1452 | tty->termios = old; | 1435 | tty->termios = old; |
@@ -1458,7 +1441,7 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1458 | /* how many characters in the buffer */ | 1441 | /* how many characters in the buffer */ |
1459 | static int hso_serial_chars_in_buffer(struct tty_struct *tty) | 1442 | static int hso_serial_chars_in_buffer(struct tty_struct *tty) |
1460 | { | 1443 | { |
1461 | struct hso_serial *serial = get_serial_by_tty(tty); | 1444 | struct hso_serial *serial = tty->driver_data; |
1462 | int chars; | 1445 | int chars; |
1463 | unsigned long flags; | 1446 | unsigned long flags; |
1464 | 1447 | ||
@@ -1629,7 +1612,7 @@ static int hso_get_count(struct tty_struct *tty, | |||
1629 | struct serial_icounter_struct *icount) | 1612 | struct serial_icounter_struct *icount) |
1630 | { | 1613 | { |
1631 | struct uart_icount cnow; | 1614 | struct uart_icount cnow; |
1632 | struct hso_serial *serial = get_serial_by_tty(tty); | 1615 | struct hso_serial *serial = tty->driver_data; |
1633 | struct hso_tiocmget *tiocmget = serial->tiocmget; | 1616 | struct hso_tiocmget *tiocmget = serial->tiocmget; |
1634 | 1617 | ||
1635 | memset(icount, 0, sizeof(struct serial_icounter_struct)); | 1618 | memset(icount, 0, sizeof(struct serial_icounter_struct)); |
@@ -1659,7 +1642,7 @@ static int hso_get_count(struct tty_struct *tty, | |||
1659 | static int hso_serial_tiocmget(struct tty_struct *tty) | 1642 | static int hso_serial_tiocmget(struct tty_struct *tty) |
1660 | { | 1643 | { |
1661 | int retval; | 1644 | int retval; |
1662 | struct hso_serial *serial = get_serial_by_tty(tty); | 1645 | struct hso_serial *serial = tty->driver_data; |
1663 | struct hso_tiocmget *tiocmget; | 1646 | struct hso_tiocmget *tiocmget; |
1664 | u16 UART_state_bitmap; | 1647 | u16 UART_state_bitmap; |
1665 | 1648 | ||
@@ -1693,7 +1676,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty, | |||
1693 | int val = 0; | 1676 | int val = 0; |
1694 | unsigned long flags; | 1677 | unsigned long flags; |
1695 | int if_num; | 1678 | int if_num; |
1696 | struct hso_serial *serial = get_serial_by_tty(tty); | 1679 | struct hso_serial *serial = tty->driver_data; |
1697 | 1680 | ||
1698 | /* sanity check */ | 1681 | /* sanity check */ |
1699 | if (!serial) { | 1682 | if (!serial) { |
@@ -1733,7 +1716,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty, | |||
1733 | static int hso_serial_ioctl(struct tty_struct *tty, | 1716 | static int hso_serial_ioctl(struct tty_struct *tty, |
1734 | unsigned int cmd, unsigned long arg) | 1717 | unsigned int cmd, unsigned long arg) |
1735 | { | 1718 | { |
1736 | struct hso_serial *serial = get_serial_by_tty(tty); | 1719 | struct hso_serial *serial = tty->driver_data; |
1737 | int ret = 0; | 1720 | int ret = 0; |
1738 | D4("IOCTL cmd: %d, arg: %ld", cmd, arg); | 1721 | D4("IOCTL cmd: %d, arg: %ld", cmd, arg); |
1739 | 1722 | ||
@@ -1905,7 +1888,7 @@ static void intr_callback(struct urb *urb) | |||
1905 | D1("Pending read interrupt on port %d\n", i); | 1888 | D1("Pending read interrupt on port %d\n", i); |
1906 | spin_lock(&serial->serial_lock); | 1889 | spin_lock(&serial->serial_lock); |
1907 | if (serial->rx_state == RX_IDLE && | 1890 | if (serial->rx_state == RX_IDLE && |
1908 | serial->open_count > 0) { | 1891 | serial->port.count > 0) { |
1909 | /* Setup and send a ctrl req read on | 1892 | /* Setup and send a ctrl req read on |
1910 | * port i */ | 1893 | * port i */ |
1911 | if (!serial->rx_urb_filled[0]) { | 1894 | if (!serial->rx_urb_filled[0]) { |
@@ -1954,14 +1937,13 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) | |||
1954 | 1937 | ||
1955 | spin_lock(&serial->serial_lock); | 1938 | spin_lock(&serial->serial_lock); |
1956 | serial->tx_urb_used = 0; | 1939 | serial->tx_urb_used = 0; |
1957 | tty = tty_kref_get(serial->tty); | ||
1958 | spin_unlock(&serial->serial_lock); | 1940 | spin_unlock(&serial->serial_lock); |
1959 | if (status) { | 1941 | if (status) { |
1960 | handle_usb_error(status, __func__, serial->parent); | 1942 | handle_usb_error(status, __func__, serial->parent); |
1961 | tty_kref_put(tty); | ||
1962 | return; | 1943 | return; |
1963 | } | 1944 | } |
1964 | hso_put_activity(serial->parent); | 1945 | hso_put_activity(serial->parent); |
1946 | tty = tty_port_tty_get(&serial->port); | ||
1965 | if (tty) { | 1947 | if (tty) { |
1966 | tty_wakeup(tty); | 1948 | tty_wakeup(tty); |
1967 | tty_kref_put(tty); | 1949 | tty_kref_put(tty); |
@@ -2001,7 +1983,6 @@ static void ctrl_callback(struct urb *urb) | |||
2001 | struct hso_serial *serial = urb->context; | 1983 | struct hso_serial *serial = urb->context; |
2002 | struct usb_ctrlrequest *req; | 1984 | struct usb_ctrlrequest *req; |
2003 | int status = urb->status; | 1985 | int status = urb->status; |
2004 | struct tty_struct *tty; | ||
2005 | 1986 | ||
2006 | /* sanity check */ | 1987 | /* sanity check */ |
2007 | if (!serial) | 1988 | if (!serial) |
@@ -2009,11 +1990,9 @@ static void ctrl_callback(struct urb *urb) | |||
2009 | 1990 | ||
2010 | spin_lock(&serial->serial_lock); | 1991 | spin_lock(&serial->serial_lock); |
2011 | serial->tx_urb_used = 0; | 1992 | serial->tx_urb_used = 0; |
2012 | tty = tty_kref_get(serial->tty); | ||
2013 | spin_unlock(&serial->serial_lock); | 1993 | spin_unlock(&serial->serial_lock); |
2014 | if (status) { | 1994 | if (status) { |
2015 | handle_usb_error(status, __func__, serial->parent); | 1995 | handle_usb_error(status, __func__, serial->parent); |
2016 | tty_kref_put(tty); | ||
2017 | return; | 1996 | return; |
2018 | } | 1997 | } |
2019 | 1998 | ||
@@ -2031,13 +2010,15 @@ static void ctrl_callback(struct urb *urb) | |||
2031 | put_rxbuf_data_and_resubmit_ctrl_urb(serial); | 2010 | put_rxbuf_data_and_resubmit_ctrl_urb(serial); |
2032 | spin_unlock(&serial->serial_lock); | 2011 | spin_unlock(&serial->serial_lock); |
2033 | } else { | 2012 | } else { |
2013 | struct tty_struct *tty = tty_port_tty_get(&serial->port); | ||
2034 | hso_put_activity(serial->parent); | 2014 | hso_put_activity(serial->parent); |
2035 | if (tty) | 2015 | if (tty) { |
2036 | tty_wakeup(tty); | 2016 | tty_wakeup(tty); |
2017 | tty_kref_put(tty); | ||
2018 | } | ||
2037 | /* response to a write command */ | 2019 | /* response to a write command */ |
2038 | hso_kick_transmit(serial); | 2020 | hso_kick_transmit(serial); |
2039 | } | 2021 | } |
2040 | tty_kref_put(tty); | ||
2041 | } | 2022 | } |
2042 | 2023 | ||
2043 | /* handle RX data for serial port */ | 2024 | /* handle RX data for serial port */ |
@@ -2053,8 +2034,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) | |||
2053 | return -2; | 2034 | return -2; |
2054 | } | 2035 | } |
2055 | 2036 | ||
2056 | /* All callers to put_rxbuf_data hold serial_lock */ | 2037 | tty = tty_port_tty_get(&serial->port); |
2057 | tty = tty_kref_get(serial->tty); | ||
2058 | 2038 | ||
2059 | /* Push data to tty */ | 2039 | /* Push data to tty */ |
2060 | if (tty) { | 2040 | if (tty) { |
@@ -2074,12 +2054,12 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) | |||
2074 | write_length_remaining -= curr_write_len; | 2054 | write_length_remaining -= curr_write_len; |
2075 | tty_flip_buffer_push(tty); | 2055 | tty_flip_buffer_push(tty); |
2076 | } | 2056 | } |
2057 | tty_kref_put(tty); | ||
2077 | } | 2058 | } |
2078 | if (write_length_remaining == 0) { | 2059 | if (write_length_remaining == 0) { |
2079 | serial->curr_rx_urb_offset = 0; | 2060 | serial->curr_rx_urb_offset = 0; |
2080 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; | 2061 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; |
2081 | } | 2062 | } |
2082 | tty_kref_put(tty); | ||
2083 | return write_length_remaining; | 2063 | return write_length_remaining; |
2084 | } | 2064 | } |
2085 | 2065 | ||
@@ -2320,6 +2300,7 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, | |||
2320 | serial->minor = minor; | 2300 | serial->minor = minor; |
2321 | serial->magic = HSO_SERIAL_MAGIC; | 2301 | serial->magic = HSO_SERIAL_MAGIC; |
2322 | spin_lock_init(&serial->serial_lock); | 2302 | spin_lock_init(&serial->serial_lock); |
2303 | tty_port_init(&serial->port); | ||
2323 | serial->num_rx_urbs = num_urbs; | 2304 | serial->num_rx_urbs = num_urbs; |
2324 | 2305 | ||
2325 | /* RX, allocate urb and initialize */ | 2306 | /* RX, allocate urb and initialize */ |
@@ -3098,7 +3079,7 @@ static int hso_resume(struct usb_interface *iface) | |||
3098 | /* Start all serial ports */ | 3079 | /* Start all serial ports */ |
3099 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { | 3080 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { |
3100 | if (serial_table[i] && (serial_table[i]->interface == iface)) { | 3081 | if (serial_table[i] && (serial_table[i]->interface == iface)) { |
3101 | if (dev2ser(serial_table[i])->open_count) { | 3082 | if (dev2ser(serial_table[i])->port.count) { |
3102 | result = | 3083 | result = |
3103 | hso_start_serial_device(serial_table[i], GFP_NOIO); | 3084 | hso_start_serial_device(serial_table[i], GFP_NOIO); |
3104 | hso_kick_transmit(dev2ser(serial_table[i])); | 3085 | hso_kick_transmit(dev2ser(serial_table[i])); |
@@ -3172,13 +3153,12 @@ static void hso_free_interface(struct usb_interface *interface) | |||
3172 | if (serial_table[i] && | 3153 | if (serial_table[i] && |
3173 | (serial_table[i]->interface == interface)) { | 3154 | (serial_table[i]->interface == interface)) { |
3174 | hso_dev = dev2ser(serial_table[i]); | 3155 | hso_dev = dev2ser(serial_table[i]); |
3175 | spin_lock_irq(&hso_dev->serial_lock); | 3156 | tty = tty_port_tty_get(&hso_dev->port); |
3176 | tty = tty_kref_get(hso_dev->tty); | 3157 | if (tty) { |
3177 | spin_unlock_irq(&hso_dev->serial_lock); | ||
3178 | if (tty) | ||
3179 | tty_hangup(tty); | 3158 | tty_hangup(tty); |
3159 | tty_kref_put(tty); | ||
3160 | } | ||
3180 | mutex_lock(&hso_dev->parent->mutex); | 3161 | mutex_lock(&hso_dev->parent->mutex); |
3181 | tty_kref_put(tty); | ||
3182 | hso_dev->parent->usb_gone = 1; | 3162 | hso_dev->parent->usb_gone = 1; |
3183 | mutex_unlock(&hso_dev->parent->mutex); | 3163 | mutex_unlock(&hso_dev->parent->mutex); |
3184 | kref_put(&serial_table[i]->ref, hso_serial_ref_free); | 3164 | kref_put(&serial_table[i]->ref, hso_serial_ref_free); |
@@ -3313,7 +3293,6 @@ static int __init hso_init(void) | |||
3313 | return -ENOMEM; | 3293 | return -ENOMEM; |
3314 | 3294 | ||
3315 | /* fill in all needed values */ | 3295 | /* fill in all needed values */ |
3316 | tty_drv->magic = TTY_DRIVER_MAGIC; | ||
3317 | tty_drv->driver_name = driver_name; | 3296 | tty_drv->driver_name = driver_name; |
3318 | tty_drv->name = tty_filename; | 3297 | tty_drv->name = tty_filename; |
3319 | 3298 | ||
@@ -3334,7 +3313,7 @@ static int __init hso_init(void) | |||
3334 | if (result) { | 3313 | if (result) { |
3335 | printk(KERN_ERR "%s - tty_register_driver failed(%d)\n", | 3314 | printk(KERN_ERR "%s - tty_register_driver failed(%d)\n", |
3336 | __func__, result); | 3315 | __func__, result); |
3337 | return result; | 3316 | goto err_free_tty; |
3338 | } | 3317 | } |
3339 | 3318 | ||
3340 | /* register this module as an usb driver */ | 3319 | /* register this module as an usb driver */ |
@@ -3342,13 +3321,16 @@ static int __init hso_init(void) | |||
3342 | if (result) { | 3321 | if (result) { |
3343 | printk(KERN_ERR "Could not register hso driver? error: %d\n", | 3322 | printk(KERN_ERR "Could not register hso driver? error: %d\n", |
3344 | result); | 3323 | result); |
3345 | /* cleanup serial interface */ | 3324 | goto err_unreg_tty; |
3346 | tty_unregister_driver(tty_drv); | ||
3347 | return result; | ||
3348 | } | 3325 | } |
3349 | 3326 | ||
3350 | /* done */ | 3327 | /* done */ |
3351 | return 0; | 3328 | return 0; |
3329 | err_unreg_tty: | ||
3330 | tty_unregister_driver(tty_drv); | ||
3331 | err_free_tty: | ||
3332 | put_tty_driver(tty_drv); | ||
3333 | return result; | ||
3352 | } | 3334 | } |
3353 | 3335 | ||
3354 | static void __exit hso_exit(void) | 3336 | static void __exit hso_exit(void) |
@@ -3356,6 +3338,7 @@ static void __exit hso_exit(void) | |||
3356 | printk(KERN_INFO "hso: unloaded\n"); | 3338 | printk(KERN_INFO "hso: unloaded\n"); |
3357 | 3339 | ||
3358 | tty_unregister_driver(tty_drv); | 3340 | tty_unregister_driver(tty_drv); |
3341 | put_tty_driver(tty_drv); | ||
3359 | /* deregister the usb driver */ | 3342 | /* deregister the usb driver */ |
3360 | usb_deregister(&hso_driver); | 3343 | usb_deregister(&hso_driver); |
3361 | } | 3344 | } |