diff options
Diffstat (limited to 'drivers/net/usb/hso.c')
-rw-r--r-- | drivers/net/usb/hso.c | 329 |
1 files changed, 12 insertions, 317 deletions
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 7fde27eef440..af62f58ffcbf 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -39,11 +39,8 @@ | |||
39 | * port is opened, as this have a huge impact on the network port | 39 | * port is opened, as this have a huge impact on the network port |
40 | * throughput. | 40 | * throughput. |
41 | * | 41 | * |
42 | * Interface 2: Standard modem interface - circuit switched interface, this | 42 | * Interface 2: Standard modem interface - circuit switched interface, should |
43 | * can be used to make a standard ppp connection however it | 43 | * not be used. |
44 | * should not be used in conjunction with the IP network interface | ||
45 | * enabled for USB performance reasons i.e. if using this set | ||
46 | * ideally disable_net=1. | ||
47 | * | 44 | * |
48 | *****************************************************************************/ | 45 | *****************************************************************************/ |
49 | 46 | ||
@@ -66,8 +63,6 @@ | |||
66 | #include <linux/usb/cdc.h> | 63 | #include <linux/usb/cdc.h> |
67 | #include <net/arp.h> | 64 | #include <net/arp.h> |
68 | #include <asm/byteorder.h> | 65 | #include <asm/byteorder.h> |
69 | #include <linux/serial_core.h> | ||
70 | #include <linux/serial.h> | ||
71 | 66 | ||
72 | 67 | ||
73 | #define DRIVER_VERSION "1.2" | 68 | #define DRIVER_VERSION "1.2" |
@@ -187,41 +182,6 @@ enum rx_ctrl_state{ | |||
187 | RX_PENDING | 182 | RX_PENDING |
188 | }; | 183 | }; |
189 | 184 | ||
190 | #define BM_REQUEST_TYPE (0xa1) | ||
191 | #define B_NOTIFICATION (0x20) | ||
192 | #define W_VALUE (0x0) | ||
193 | #define W_INDEX (0x2) | ||
194 | #define W_LENGTH (0x2) | ||
195 | |||
196 | #define B_OVERRUN (0x1<<6) | ||
197 | #define B_PARITY (0x1<<5) | ||
198 | #define B_FRAMING (0x1<<4) | ||
199 | #define B_RING_SIGNAL (0x1<<3) | ||
200 | #define B_BREAK (0x1<<2) | ||
201 | #define B_TX_CARRIER (0x1<<1) | ||
202 | #define B_RX_CARRIER (0x1<<0) | ||
203 | |||
204 | struct hso_serial_state_notification { | ||
205 | u8 bmRequestType; | ||
206 | u8 bNotification; | ||
207 | u16 wValue; | ||
208 | u16 wIndex; | ||
209 | u16 wLength; | ||
210 | u16 UART_state_bitmap; | ||
211 | } __attribute__((packed)); | ||
212 | |||
213 | struct hso_tiocmget { | ||
214 | struct mutex mutex; | ||
215 | wait_queue_head_t waitq; | ||
216 | int intr_completed; | ||
217 | struct usb_endpoint_descriptor *endp; | ||
218 | struct urb *urb; | ||
219 | struct hso_serial_state_notification serial_state_notification; | ||
220 | u16 prev_UART_state_bitmap; | ||
221 | struct uart_icount icount; | ||
222 | }; | ||
223 | |||
224 | |||
225 | struct hso_serial { | 185 | struct hso_serial { |
226 | struct hso_device *parent; | 186 | struct hso_device *parent; |
227 | int magic; | 187 | int magic; |
@@ -259,7 +219,6 @@ struct hso_serial { | |||
259 | spinlock_t serial_lock; | 219 | spinlock_t serial_lock; |
260 | 220 | ||
261 | int (*write_data) (struct hso_serial *serial); | 221 | int (*write_data) (struct hso_serial *serial); |
262 | struct hso_tiocmget *tiocmget; | ||
263 | /* Hacks required to get flow control | 222 | /* Hacks required to get flow control |
264 | * working on the serial receive buffers | 223 | * working on the serial receive buffers |
265 | * so as not to drop characters on the floor. | 224 | * so as not to drop characters on the floor. |
@@ -351,7 +310,7 @@ static void async_get_intf(struct work_struct *data); | |||
351 | static void async_put_intf(struct work_struct *data); | 310 | static void async_put_intf(struct work_struct *data); |
352 | static int hso_put_activity(struct hso_device *hso_dev); | 311 | static int hso_put_activity(struct hso_device *hso_dev); |
353 | static int hso_get_activity(struct hso_device *hso_dev); | 312 | static int hso_get_activity(struct hso_device *hso_dev); |
354 | static void tiocmget_intr_callback(struct urb *urb); | 313 | |
355 | /*****************************************************************************/ | 314 | /*****************************************************************************/ |
356 | /* Helping functions */ | 315 | /* Helping functions */ |
357 | /*****************************************************************************/ | 316 | /*****************************************************************************/ |
@@ -1501,217 +1460,25 @@ static int hso_serial_chars_in_buffer(struct tty_struct *tty) | |||
1501 | 1460 | ||
1502 | return chars; | 1461 | return chars; |
1503 | } | 1462 | } |
1504 | int tiocmget_submit_urb(struct hso_serial *serial, | ||
1505 | struct hso_tiocmget *tiocmget, | ||
1506 | struct usb_device *usb) | ||
1507 | { | ||
1508 | int result; | ||
1509 | |||
1510 | if (serial->parent->usb_gone) | ||
1511 | return -ENODEV; | ||
1512 | usb_fill_int_urb(tiocmget->urb, usb, | ||
1513 | usb_rcvintpipe(usb, | ||
1514 | tiocmget->endp-> | ||
1515 | bEndpointAddress & 0x7F), | ||
1516 | &tiocmget->serial_state_notification, | ||
1517 | sizeof(struct hso_serial_state_notification), | ||
1518 | tiocmget_intr_callback, serial, | ||
1519 | tiocmget->endp->bInterval); | ||
1520 | result = usb_submit_urb(tiocmget->urb, GFP_ATOMIC); | ||
1521 | if (result) { | ||
1522 | dev_warn(&usb->dev, "%s usb_submit_urb failed %d\n", __func__, | ||
1523 | result); | ||
1524 | } | ||
1525 | return result; | ||
1526 | |||
1527 | } | ||
1528 | |||
1529 | static void tiocmget_intr_callback(struct urb *urb) | ||
1530 | { | ||
1531 | struct hso_serial *serial = urb->context; | ||
1532 | struct hso_tiocmget *tiocmget; | ||
1533 | int status = urb->status; | ||
1534 | u16 UART_state_bitmap, prev_UART_state_bitmap; | ||
1535 | struct uart_icount *icount; | ||
1536 | struct hso_serial_state_notification *serial_state_notification; | ||
1537 | struct usb_device *usb; | ||
1538 | |||
1539 | /* Sanity checks */ | ||
1540 | if (!serial) | ||
1541 | return; | ||
1542 | if (status) { | ||
1543 | log_usb_status(status, __func__); | ||
1544 | return; | ||
1545 | } | ||
1546 | tiocmget = serial->tiocmget; | ||
1547 | if (!tiocmget) | ||
1548 | return; | ||
1549 | usb = serial->parent->usb; | ||
1550 | serial_state_notification = &tiocmget->serial_state_notification; | ||
1551 | if (serial_state_notification->bmRequestType != BM_REQUEST_TYPE || | ||
1552 | serial_state_notification->bNotification != B_NOTIFICATION || | ||
1553 | le16_to_cpu(serial_state_notification->wValue) != W_VALUE || | ||
1554 | le16_to_cpu(serial_state_notification->wIndex) != W_INDEX || | ||
1555 | le16_to_cpu(serial_state_notification->wLength) != W_LENGTH) { | ||
1556 | dev_warn(&usb->dev, | ||
1557 | "hso received invalid serial state notification\n"); | ||
1558 | DUMP(serial_state_notification, | ||
1559 | sizeof(hso_serial_state_notifation)) | ||
1560 | } else { | ||
1561 | |||
1562 | UART_state_bitmap = le16_to_cpu(serial_state_notification-> | ||
1563 | UART_state_bitmap); | ||
1564 | prev_UART_state_bitmap = tiocmget->prev_UART_state_bitmap; | ||
1565 | icount = &tiocmget->icount; | ||
1566 | spin_lock(&serial->serial_lock); | ||
1567 | if ((UART_state_bitmap & B_OVERRUN) != | ||
1568 | (prev_UART_state_bitmap & B_OVERRUN)) | ||
1569 | icount->parity++; | ||
1570 | if ((UART_state_bitmap & B_PARITY) != | ||
1571 | (prev_UART_state_bitmap & B_PARITY)) | ||
1572 | icount->parity++; | ||
1573 | if ((UART_state_bitmap & B_FRAMING) != | ||
1574 | (prev_UART_state_bitmap & B_FRAMING)) | ||
1575 | icount->frame++; | ||
1576 | if ((UART_state_bitmap & B_RING_SIGNAL) && | ||
1577 | !(prev_UART_state_bitmap & B_RING_SIGNAL)) | ||
1578 | icount->rng++; | ||
1579 | if ((UART_state_bitmap & B_BREAK) != | ||
1580 | (prev_UART_state_bitmap & B_BREAK)) | ||
1581 | icount->brk++; | ||
1582 | if ((UART_state_bitmap & B_TX_CARRIER) != | ||
1583 | (prev_UART_state_bitmap & B_TX_CARRIER)) | ||
1584 | icount->dsr++; | ||
1585 | if ((UART_state_bitmap & B_RX_CARRIER) != | ||
1586 | (prev_UART_state_bitmap & B_RX_CARRIER)) | ||
1587 | icount->dcd++; | ||
1588 | tiocmget->prev_UART_state_bitmap = UART_state_bitmap; | ||
1589 | spin_unlock(&serial->serial_lock); | ||
1590 | tiocmget->intr_completed = 1; | ||
1591 | wake_up_interruptible(&tiocmget->waitq); | ||
1592 | } | ||
1593 | memset(serial_state_notification, 0, | ||
1594 | sizeof(struct hso_serial_state_notification)); | ||
1595 | tiocmget_submit_urb(serial, | ||
1596 | tiocmget, | ||
1597 | serial->parent->usb); | ||
1598 | } | ||
1599 | |||
1600 | /* | ||
1601 | * next few functions largely stolen from drivers/serial/serial_core.c | ||
1602 | */ | ||
1603 | /* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change | ||
1604 | * - mask passed in arg for lines of interest | ||
1605 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) | ||
1606 | * Caller should use TIOCGICOUNT to see which one it was | ||
1607 | */ | ||
1608 | static int | ||
1609 | hso_wait_modem_status(struct hso_serial *serial, unsigned long arg) | ||
1610 | { | ||
1611 | DECLARE_WAITQUEUE(wait, current); | ||
1612 | struct uart_icount cprev, cnow; | ||
1613 | struct hso_tiocmget *tiocmget; | ||
1614 | int ret; | ||
1615 | |||
1616 | tiocmget = serial->tiocmget; | ||
1617 | if (!tiocmget) | ||
1618 | return -ENOENT; | ||
1619 | /* | ||
1620 | * note the counters on entry | ||
1621 | */ | ||
1622 | spin_lock_irq(&serial->serial_lock); | ||
1623 | memcpy(&cprev, &tiocmget->icount, sizeof(struct uart_icount)); | ||
1624 | spin_unlock_irq(&serial->serial_lock); | ||
1625 | add_wait_queue(&tiocmget->waitq, &wait); | ||
1626 | for (;;) { | ||
1627 | spin_lock_irq(&serial->serial_lock); | ||
1628 | memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount)); | ||
1629 | spin_unlock_irq(&serial->serial_lock); | ||
1630 | set_current_state(TASK_INTERRUPTIBLE); | ||
1631 | if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || | ||
1632 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || | ||
1633 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd))) { | ||
1634 | ret = 0; | ||
1635 | break; | ||
1636 | } | ||
1637 | schedule(); | ||
1638 | /* see if a signal did it */ | ||
1639 | if (signal_pending(current)) { | ||
1640 | ret = -ERESTARTSYS; | ||
1641 | break; | ||
1642 | } | ||
1643 | cprev = cnow; | ||
1644 | } | ||
1645 | current->state = TASK_RUNNING; | ||
1646 | remove_wait_queue(&tiocmget->waitq, &wait); | ||
1647 | |||
1648 | return ret; | ||
1649 | } | ||
1650 | |||
1651 | /* | ||
1652 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1653 | * Return: write counters to the user passed counter struct | ||
1654 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1655 | * RI where only 0->1 is counted. | ||
1656 | */ | ||
1657 | static int hso_get_count(struct hso_serial *serial, | ||
1658 | struct serial_icounter_struct __user *icnt) | ||
1659 | { | ||
1660 | struct serial_icounter_struct icount; | ||
1661 | struct uart_icount cnow; | ||
1662 | struct hso_tiocmget *tiocmget = serial->tiocmget; | ||
1663 | |||
1664 | if (!tiocmget) | ||
1665 | return -ENOENT; | ||
1666 | spin_lock_irq(&serial->serial_lock); | ||
1667 | memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount)); | ||
1668 | spin_unlock_irq(&serial->serial_lock); | ||
1669 | |||
1670 | icount.cts = cnow.cts; | ||
1671 | icount.dsr = cnow.dsr; | ||
1672 | icount.rng = cnow.rng; | ||
1673 | icount.dcd = cnow.dcd; | ||
1674 | icount.rx = cnow.rx; | ||
1675 | icount.tx = cnow.tx; | ||
1676 | icount.frame = cnow.frame; | ||
1677 | icount.overrun = cnow.overrun; | ||
1678 | icount.parity = cnow.parity; | ||
1679 | icount.brk = cnow.brk; | ||
1680 | icount.buf_overrun = cnow.buf_overrun; | ||
1681 | |||
1682 | return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0; | ||
1683 | } | ||
1684 | |||
1685 | 1463 | ||
1686 | static int hso_serial_tiocmget(struct tty_struct *tty, struct file *file) | 1464 | static int hso_serial_tiocmget(struct tty_struct *tty, struct file *file) |
1687 | { | 1465 | { |
1688 | int retval; | 1466 | unsigned int value; |
1689 | struct hso_serial *serial = get_serial_by_tty(tty); | 1467 | struct hso_serial *serial = get_serial_by_tty(tty); |
1690 | struct hso_tiocmget *tiocmget; | 1468 | unsigned long flags; |
1691 | u16 UART_state_bitmap; | ||
1692 | 1469 | ||
1693 | /* sanity check */ | 1470 | /* sanity check */ |
1694 | if (!serial) { | 1471 | if (!serial) { |
1695 | D1("no tty structures"); | 1472 | D1("no tty structures"); |
1696 | return -EINVAL; | 1473 | return -EINVAL; |
1697 | } | 1474 | } |
1698 | spin_lock_irq(&serial->serial_lock); | 1475 | |
1699 | retval = ((serial->rts_state) ? TIOCM_RTS : 0) | | 1476 | spin_lock_irqsave(&serial->serial_lock, flags); |
1477 | value = ((serial->rts_state) ? TIOCM_RTS : 0) | | ||
1700 | ((serial->dtr_state) ? TIOCM_DTR : 0); | 1478 | ((serial->dtr_state) ? TIOCM_DTR : 0); |
1701 | tiocmget = serial->tiocmget; | 1479 | spin_unlock_irqrestore(&serial->serial_lock, flags); |
1702 | if (tiocmget) { | ||
1703 | 1480 | ||
1704 | UART_state_bitmap = le16_to_cpu( | 1481 | return value; |
1705 | tiocmget->prev_UART_state_bitmap); | ||
1706 | if (UART_state_bitmap & B_RING_SIGNAL) | ||
1707 | retval |= TIOCM_RNG; | ||
1708 | if (UART_state_bitmap & B_RX_CARRIER) | ||
1709 | retval |= TIOCM_CD; | ||
1710 | if (UART_state_bitmap & B_TX_CARRIER) | ||
1711 | retval |= TIOCM_DSR; | ||
1712 | } | ||
1713 | spin_unlock_irq(&serial->serial_lock); | ||
1714 | return retval; | ||
1715 | } | 1482 | } |
1716 | 1483 | ||
1717 | static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, | 1484 | static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, |
@@ -1753,32 +1520,6 @@ static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, | |||
1753 | USB_CTRL_SET_TIMEOUT); | 1520 | USB_CTRL_SET_TIMEOUT); |
1754 | } | 1521 | } |
1755 | 1522 | ||
1756 | static int hso_serial_ioctl(struct tty_struct *tty, struct file *file, | ||
1757 | unsigned int cmd, unsigned long arg) | ||
1758 | { | ||
1759 | struct hso_serial *serial = get_serial_by_tty(tty); | ||
1760 | void __user *uarg = (void __user *)arg; | ||
1761 | int ret = 0; | ||
1762 | D4("IOCTL cmd: %d, arg: %ld", cmd, arg); | ||
1763 | |||
1764 | if (!serial) | ||
1765 | return -ENODEV; | ||
1766 | switch (cmd) { | ||
1767 | case TIOCMIWAIT: | ||
1768 | ret = hso_wait_modem_status(serial, arg); | ||
1769 | break; | ||
1770 | |||
1771 | case TIOCGICOUNT: | ||
1772 | ret = hso_get_count(serial, uarg); | ||
1773 | break; | ||
1774 | default: | ||
1775 | ret = -ENOIOCTLCMD; | ||
1776 | break; | ||
1777 | } | ||
1778 | return ret; | ||
1779 | } | ||
1780 | |||
1781 | |||
1782 | /* starts a transmit */ | 1523 | /* starts a transmit */ |
1783 | static void hso_kick_transmit(struct hso_serial *serial) | 1524 | static void hso_kick_transmit(struct hso_serial *serial) |
1784 | { | 1525 | { |
@@ -2241,10 +1982,7 @@ static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags) | |||
2241 | serial->shared_int->use_count++; | 1982 | serial->shared_int->use_count++; |
2242 | mutex_unlock(&serial->shared_int->shared_int_lock); | 1983 | mutex_unlock(&serial->shared_int->shared_int_lock); |
2243 | } | 1984 | } |
2244 | if (serial->tiocmget) | 1985 | |
2245 | tiocmget_submit_urb(serial, | ||
2246 | serial->tiocmget, | ||
2247 | serial->parent->usb); | ||
2248 | return result; | 1986 | return result; |
2249 | } | 1987 | } |
2250 | 1988 | ||
@@ -2252,7 +1990,6 @@ static int hso_stop_serial_device(struct hso_device *hso_dev) | |||
2252 | { | 1990 | { |
2253 | int i; | 1991 | int i; |
2254 | struct hso_serial *serial = dev2ser(hso_dev); | 1992 | struct hso_serial *serial = dev2ser(hso_dev); |
2255 | struct hso_tiocmget *tiocmget; | ||
2256 | 1993 | ||
2257 | if (!serial) | 1994 | if (!serial) |
2258 | return -ENODEV; | 1995 | return -ENODEV; |
@@ -2281,11 +2018,6 @@ static int hso_stop_serial_device(struct hso_device *hso_dev) | |||
2281 | } | 2018 | } |
2282 | mutex_unlock(&serial->shared_int->shared_int_lock); | 2019 | mutex_unlock(&serial->shared_int->shared_int_lock); |
2283 | } | 2020 | } |
2284 | tiocmget = serial->tiocmget; | ||
2285 | if (tiocmget) { | ||
2286 | wake_up_interruptible(&tiocmget->waitq); | ||
2287 | usb_kill_urb(tiocmget->urb); | ||
2288 | } | ||
2289 | 2021 | ||
2290 | return 0; | 2022 | return 0; |
2291 | } | 2023 | } |
@@ -2636,20 +2368,6 @@ exit: | |||
2636 | return NULL; | 2368 | return NULL; |
2637 | } | 2369 | } |
2638 | 2370 | ||
2639 | static void hso_free_tiomget(struct hso_serial *serial) | ||
2640 | { | ||
2641 | struct hso_tiocmget *tiocmget = serial->tiocmget; | ||
2642 | if (tiocmget) { | ||
2643 | kfree(tiocmget); | ||
2644 | if (tiocmget->urb) { | ||
2645 | usb_free_urb(tiocmget->urb); | ||
2646 | tiocmget->urb = NULL; | ||
2647 | } | ||
2648 | serial->tiocmget = NULL; | ||
2649 | |||
2650 | } | ||
2651 | } | ||
2652 | |||
2653 | /* Frees an AT channel ( goes for both mux and non-mux ) */ | 2371 | /* Frees an AT channel ( goes for both mux and non-mux ) */ |
2654 | static void hso_free_serial_device(struct hso_device *hso_dev) | 2372 | static void hso_free_serial_device(struct hso_device *hso_dev) |
2655 | { | 2373 | { |
@@ -2668,7 +2386,6 @@ static void hso_free_serial_device(struct hso_device *hso_dev) | |||
2668 | else | 2386 | else |
2669 | mutex_unlock(&serial->shared_int->shared_int_lock); | 2387 | mutex_unlock(&serial->shared_int->shared_int_lock); |
2670 | } | 2388 | } |
2671 | hso_free_tiomget(serial); | ||
2672 | kfree(serial); | 2389 | kfree(serial); |
2673 | hso_free_device(hso_dev); | 2390 | hso_free_device(hso_dev); |
2674 | } | 2391 | } |
@@ -2680,7 +2397,6 @@ static struct hso_device *hso_create_bulk_serial_device( | |||
2680 | struct hso_device *hso_dev; | 2397 | struct hso_device *hso_dev; |
2681 | struct hso_serial *serial; | 2398 | struct hso_serial *serial; |
2682 | int num_urbs; | 2399 | int num_urbs; |
2683 | struct hso_tiocmget *tiocmget; | ||
2684 | 2400 | ||
2685 | hso_dev = hso_create_device(interface, port); | 2401 | hso_dev = hso_create_device(interface, port); |
2686 | if (!hso_dev) | 2402 | if (!hso_dev) |
@@ -2693,27 +2409,8 @@ static struct hso_device *hso_create_bulk_serial_device( | |||
2693 | serial->parent = hso_dev; | 2409 | serial->parent = hso_dev; |
2694 | hso_dev->port_data.dev_serial = serial; | 2410 | hso_dev->port_data.dev_serial = serial; |
2695 | 2411 | ||
2696 | if (port & HSO_PORT_MODEM) { | 2412 | if (port & HSO_PORT_MODEM) |
2697 | num_urbs = 2; | 2413 | num_urbs = 2; |
2698 | serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget), | ||
2699 | GFP_KERNEL); | ||
2700 | /* it isn't going to break our heart if serial->tiocmget | ||
2701 | * allocation fails don't bother checking this. | ||
2702 | */ | ||
2703 | if (serial->tiocmget) { | ||
2704 | tiocmget = serial->tiocmget; | ||
2705 | tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2706 | if (tiocmget->urb) { | ||
2707 | mutex_init(&tiocmget->mutex); | ||
2708 | init_waitqueue_head(&tiocmget->waitq); | ||
2709 | tiocmget->endp = hso_get_ep( | ||
2710 | interface, | ||
2711 | USB_ENDPOINT_XFER_INT, | ||
2712 | USB_DIR_IN); | ||
2713 | } else | ||
2714 | hso_free_tiomget(serial); | ||
2715 | } | ||
2716 | } | ||
2717 | else | 2414 | else |
2718 | num_urbs = 1; | 2415 | num_urbs = 1; |
2719 | 2416 | ||
@@ -2749,7 +2446,6 @@ static struct hso_device *hso_create_bulk_serial_device( | |||
2749 | exit2: | 2446 | exit2: |
2750 | hso_serial_common_free(serial); | 2447 | hso_serial_common_free(serial); |
2751 | exit: | 2448 | exit: |
2752 | hso_free_tiomget(serial); | ||
2753 | kfree(serial); | 2449 | kfree(serial); |
2754 | hso_free_device(hso_dev); | 2450 | hso_free_device(hso_dev); |
2755 | return NULL; | 2451 | return NULL; |
@@ -3262,7 +2958,6 @@ static const struct tty_operations hso_serial_ops = { | |||
3262 | .close = hso_serial_close, | 2958 | .close = hso_serial_close, |
3263 | .write = hso_serial_write, | 2959 | .write = hso_serial_write, |
3264 | .write_room = hso_serial_write_room, | 2960 | .write_room = hso_serial_write_room, |
3265 | .ioctl = hso_serial_ioctl, | ||
3266 | .set_termios = hso_serial_set_termios, | 2961 | .set_termios = hso_serial_set_termios, |
3267 | .chars_in_buffer = hso_serial_chars_in_buffer, | 2962 | .chars_in_buffer = hso_serial_chars_in_buffer, |
3268 | .tiocmget = hso_serial_tiocmget, | 2963 | .tiocmget = hso_serial_tiocmget, |