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.c329
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
204struct 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
213struct 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
225struct hso_serial { 185struct 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);
351static void async_put_intf(struct work_struct *data); 310static void async_put_intf(struct work_struct *data);
352static int hso_put_activity(struct hso_device *hso_dev); 311static int hso_put_activity(struct hso_device *hso_dev);
353static int hso_get_activity(struct hso_device *hso_dev); 312static int hso_get_activity(struct hso_device *hso_dev);
354static 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}
1504int 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
1529static 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 */
1608static int
1609hso_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 */
1657static 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
1686static int hso_serial_tiocmget(struct tty_struct *tty, struct file *file) 1464static 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
1717static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, 1484static 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
1756static 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 */
1783static void hso_kick_transmit(struct hso_serial *serial) 1524static 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
2639static 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 ) */
2654static void hso_free_serial_device(struct hso_device *hso_dev) 2372static 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(
2749exit2: 2446exit2:
2750 hso_serial_common_free(serial); 2447 hso_serial_common_free(serial);
2751exit: 2448exit:
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,