diff options
Diffstat (limited to 'drivers/net/usb/hso.c')
-rw-r--r-- | drivers/net/usb/hso.c | 127 |
1 files changed, 53 insertions, 74 deletions
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 1cd752f9a6e1..304fe78ff60e 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -324,7 +324,7 @@ struct hso_device { | |||
324 | /* Prototypes */ | 324 | /* Prototypes */ |
325 | /*****************************************************************************/ | 325 | /*****************************************************************************/ |
326 | /* Serial driver functions */ | 326 | /* Serial driver functions */ |
327 | static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, | 327 | static int hso_serial_tiocmset(struct tty_struct *tty, |
328 | unsigned int set, unsigned int clear); | 328 | unsigned int set, unsigned int clear); |
329 | static void ctrl_callback(struct urb *urb); | 329 | static void ctrl_callback(struct urb *urb); |
330 | static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial); | 330 | static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial); |
@@ -843,16 +843,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb, | |||
843 | return NETDEV_TX_OK; | 843 | return NETDEV_TX_OK; |
844 | } | 844 | } |
845 | 845 | ||
846 | static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) | ||
847 | { | ||
848 | struct hso_net *odev = netdev_priv(net); | ||
849 | |||
850 | strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN); | ||
851 | usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info); | ||
852 | } | ||
853 | |||
854 | static const struct ethtool_ops ops = { | 846 | static const struct ethtool_ops ops = { |
855 | .get_drvinfo = hso_get_drvinfo, | ||
856 | .get_link = ethtool_op_get_link | 847 | .get_link = ethtool_op_get_link |
857 | }; | 848 | }; |
858 | 849 | ||
@@ -967,10 +958,6 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, | |||
967 | /* Packet is complete. Inject into stack. */ | 958 | /* Packet is complete. Inject into stack. */ |
968 | /* We have IP packet here */ | 959 | /* We have IP packet here */ |
969 | odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); | 960 | odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); |
970 | /* don't check it */ | ||
971 | odev->skb_rx_buf->ip_summed = | ||
972 | CHECKSUM_UNNECESSARY; | ||
973 | |||
974 | skb_reset_mac_header(odev->skb_rx_buf); | 961 | skb_reset_mac_header(odev->skb_rx_buf); |
975 | 962 | ||
976 | /* Ship it off to the kernel */ | 963 | /* Ship it off to the kernel */ |
@@ -1010,6 +997,18 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, | |||
1010 | } | 997 | } |
1011 | } | 998 | } |
1012 | 999 | ||
1000 | static void fix_crc_bug(struct urb *urb, __le16 max_packet_size) | ||
1001 | { | ||
1002 | static const u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; | ||
1003 | u32 rest = urb->actual_length % le16_to_cpu(max_packet_size); | ||
1004 | |||
1005 | if (((rest == 5) || (rest == 6)) && | ||
1006 | !memcmp(((u8 *)urb->transfer_buffer) + urb->actual_length - 4, | ||
1007 | crc_check, 4)) { | ||
1008 | urb->actual_length -= 4; | ||
1009 | } | ||
1010 | } | ||
1011 | |||
1013 | /* Moving data from usb to kernel (in interrupt state) */ | 1012 | /* Moving data from usb to kernel (in interrupt state) */ |
1014 | static void read_bulk_callback(struct urb *urb) | 1013 | static void read_bulk_callback(struct urb *urb) |
1015 | { | 1014 | { |
@@ -1038,17 +1037,8 @@ static void read_bulk_callback(struct urb *urb) | |||
1038 | return; | 1037 | return; |
1039 | } | 1038 | } |
1040 | 1039 | ||
1041 | if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { | 1040 | if (odev->parent->port_spec & HSO_INFO_CRC_BUG) |
1042 | u32 rest; | 1041 | fix_crc_bug(urb, odev->in_endp->wMaxPacketSize); |
1043 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; | ||
1044 | rest = urb->actual_length % | ||
1045 | le16_to_cpu(odev->in_endp->wMaxPacketSize); | ||
1046 | if (((rest == 5) || (rest == 6)) && | ||
1047 | !memcmp(((u8 *) urb->transfer_buffer) + | ||
1048 | urb->actual_length - 4, crc_check, 4)) { | ||
1049 | urb->actual_length -= 4; | ||
1050 | } | ||
1051 | } | ||
1052 | 1042 | ||
1053 | /* do we even have a packet? */ | 1043 | /* do we even have a packet? */ |
1054 | if (urb->actual_length) { | 1044 | if (urb->actual_length) { |
@@ -1240,18 +1230,8 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1240 | return; | 1230 | return; |
1241 | 1231 | ||
1242 | if (status == 0) { | 1232 | if (status == 0) { |
1243 | if (serial->parent->port_spec & HSO_INFO_CRC_BUG) { | 1233 | if (serial->parent->port_spec & HSO_INFO_CRC_BUG) |
1244 | u32 rest; | 1234 | fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); |
1245 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; | ||
1246 | rest = | ||
1247 | urb->actual_length % | ||
1248 | le16_to_cpu(serial->in_endp->wMaxPacketSize); | ||
1249 | if (((rest == 5) || (rest == 6)) && | ||
1250 | !memcmp(((u8 *) urb->transfer_buffer) + | ||
1251 | urb->actual_length - 4, crc_check, 4)) { | ||
1252 | urb->actual_length -= 4; | ||
1253 | } | ||
1254 | } | ||
1255 | /* Valid data, handle RX data */ | 1235 | /* Valid data, handle RX data */ |
1256 | spin_lock(&serial->serial_lock); | 1236 | spin_lock(&serial->serial_lock); |
1257 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; | 1237 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; |
@@ -1355,7 +1335,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) | |||
1355 | 1335 | ||
1356 | /* done */ | 1336 | /* done */ |
1357 | if (result) | 1337 | if (result) |
1358 | hso_serial_tiocmset(tty, NULL, TIOCM_RTS | TIOCM_DTR, 0); | 1338 | hso_serial_tiocmset(tty, TIOCM_RTS | TIOCM_DTR, 0); |
1359 | err_out: | 1339 | err_out: |
1360 | mutex_unlock(&serial->parent->mutex); | 1340 | mutex_unlock(&serial->parent->mutex); |
1361 | return result; | 1341 | return result; |
@@ -1645,11 +1625,11 @@ hso_wait_modem_status(struct hso_serial *serial, unsigned long arg) | |||
1645 | * NB: both 1->0 and 0->1 transitions are counted except for | 1625 | * NB: both 1->0 and 0->1 transitions are counted except for |
1646 | * RI where only 0->1 is counted. | 1626 | * RI where only 0->1 is counted. |
1647 | */ | 1627 | */ |
1648 | static int hso_get_count(struct hso_serial *serial, | 1628 | static int hso_get_count(struct tty_struct *tty, |
1649 | struct serial_icounter_struct __user *icnt) | 1629 | struct serial_icounter_struct *icount) |
1650 | { | 1630 | { |
1651 | struct serial_icounter_struct icount; | ||
1652 | struct uart_icount cnow; | 1631 | struct uart_icount cnow; |
1632 | struct hso_serial *serial = get_serial_by_tty(tty); | ||
1653 | struct hso_tiocmget *tiocmget = serial->tiocmget; | 1633 | struct hso_tiocmget *tiocmget = serial->tiocmget; |
1654 | 1634 | ||
1655 | memset(&icount, 0, sizeof(struct serial_icounter_struct)); | 1635 | memset(&icount, 0, sizeof(struct serial_icounter_struct)); |
@@ -1660,23 +1640,23 @@ static int hso_get_count(struct hso_serial *serial, | |||
1660 | memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount)); | 1640 | memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount)); |
1661 | spin_unlock_irq(&serial->serial_lock); | 1641 | spin_unlock_irq(&serial->serial_lock); |
1662 | 1642 | ||
1663 | icount.cts = cnow.cts; | 1643 | icount->cts = cnow.cts; |
1664 | icount.dsr = cnow.dsr; | 1644 | icount->dsr = cnow.dsr; |
1665 | icount.rng = cnow.rng; | 1645 | icount->rng = cnow.rng; |
1666 | icount.dcd = cnow.dcd; | 1646 | icount->dcd = cnow.dcd; |
1667 | icount.rx = cnow.rx; | 1647 | icount->rx = cnow.rx; |
1668 | icount.tx = cnow.tx; | 1648 | icount->tx = cnow.tx; |
1669 | icount.frame = cnow.frame; | 1649 | icount->frame = cnow.frame; |
1670 | icount.overrun = cnow.overrun; | 1650 | icount->overrun = cnow.overrun; |
1671 | icount.parity = cnow.parity; | 1651 | icount->parity = cnow.parity; |
1672 | icount.brk = cnow.brk; | 1652 | icount->brk = cnow.brk; |
1673 | icount.buf_overrun = cnow.buf_overrun; | 1653 | icount->buf_overrun = cnow.buf_overrun; |
1674 | 1654 | ||
1675 | return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0; | 1655 | return 0; |
1676 | } | 1656 | } |
1677 | 1657 | ||
1678 | 1658 | ||
1679 | static int hso_serial_tiocmget(struct tty_struct *tty, struct file *file) | 1659 | static int hso_serial_tiocmget(struct tty_struct *tty) |
1680 | { | 1660 | { |
1681 | int retval; | 1661 | int retval; |
1682 | struct hso_serial *serial = get_serial_by_tty(tty); | 1662 | struct hso_serial *serial = get_serial_by_tty(tty); |
@@ -1707,7 +1687,7 @@ static int hso_serial_tiocmget(struct tty_struct *tty, struct file *file) | |||
1707 | return retval; | 1687 | return retval; |
1708 | } | 1688 | } |
1709 | 1689 | ||
1710 | static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, | 1690 | static int hso_serial_tiocmset(struct tty_struct *tty, |
1711 | unsigned int set, unsigned int clear) | 1691 | unsigned int set, unsigned int clear) |
1712 | { | 1692 | { |
1713 | int val = 0; | 1693 | int val = 0; |
@@ -1750,11 +1730,10 @@ static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, | |||
1750 | USB_CTRL_SET_TIMEOUT); | 1730 | USB_CTRL_SET_TIMEOUT); |
1751 | } | 1731 | } |
1752 | 1732 | ||
1753 | static int hso_serial_ioctl(struct tty_struct *tty, struct file *file, | 1733 | static int hso_serial_ioctl(struct tty_struct *tty, |
1754 | unsigned int cmd, unsigned long arg) | 1734 | unsigned int cmd, unsigned long arg) |
1755 | { | 1735 | { |
1756 | struct hso_serial *serial = get_serial_by_tty(tty); | 1736 | struct hso_serial *serial = get_serial_by_tty(tty); |
1757 | void __user *uarg = (void __user *)arg; | ||
1758 | int ret = 0; | 1737 | int ret = 0; |
1759 | D4("IOCTL cmd: %d, arg: %ld", cmd, arg); | 1738 | D4("IOCTL cmd: %d, arg: %ld", cmd, arg); |
1760 | 1739 | ||
@@ -1764,10 +1743,6 @@ static int hso_serial_ioctl(struct tty_struct *tty, struct file *file, | |||
1764 | case TIOCMIWAIT: | 1743 | case TIOCMIWAIT: |
1765 | ret = hso_wait_modem_status(serial, arg); | 1744 | ret = hso_wait_modem_status(serial, arg); |
1766 | break; | 1745 | break; |
1767 | |||
1768 | case TIOCGICOUNT: | ||
1769 | ret = hso_get_count(serial, uarg); | ||
1770 | break; | ||
1771 | default: | 1746 | default: |
1772 | ret = -ENOIOCTLCMD; | 1747 | ret = -ENOIOCTLCMD; |
1773 | break; | 1748 | break; |
@@ -2446,10 +2421,8 @@ static void hso_free_net_device(struct hso_device *hso_dev) | |||
2446 | 2421 | ||
2447 | remove_net_device(hso_net->parent); | 2422 | remove_net_device(hso_net->parent); |
2448 | 2423 | ||
2449 | if (hso_net->net) { | 2424 | if (hso_net->net) |
2450 | unregister_netdev(hso_net->net); | 2425 | unregister_netdev(hso_net->net); |
2451 | free_netdev(hso_net->net); | ||
2452 | } | ||
2453 | 2426 | ||
2454 | /* start freeing */ | 2427 | /* start freeing */ |
2455 | for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { | 2428 | for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { |
@@ -2461,6 +2434,9 @@ static void hso_free_net_device(struct hso_device *hso_dev) | |||
2461 | kfree(hso_net->mux_bulk_tx_buf); | 2434 | kfree(hso_net->mux_bulk_tx_buf); |
2462 | hso_net->mux_bulk_tx_buf = NULL; | 2435 | hso_net->mux_bulk_tx_buf = NULL; |
2463 | 2436 | ||
2437 | if (hso_net->net) | ||
2438 | free_netdev(hso_net->net); | ||
2439 | |||
2464 | kfree(hso_dev); | 2440 | kfree(hso_dev); |
2465 | } | 2441 | } |
2466 | 2442 | ||
@@ -2653,15 +2629,15 @@ exit: | |||
2653 | 2629 | ||
2654 | static void hso_free_tiomget(struct hso_serial *serial) | 2630 | static void hso_free_tiomget(struct hso_serial *serial) |
2655 | { | 2631 | { |
2656 | struct hso_tiocmget *tiocmget = serial->tiocmget; | 2632 | struct hso_tiocmget *tiocmget; |
2633 | if (!serial) | ||
2634 | return; | ||
2635 | tiocmget = serial->tiocmget; | ||
2657 | if (tiocmget) { | 2636 | if (tiocmget) { |
2658 | if (tiocmget->urb) { | 2637 | usb_free_urb(tiocmget->urb); |
2659 | usb_free_urb(tiocmget->urb); | 2638 | tiocmget->urb = NULL; |
2660 | tiocmget->urb = NULL; | ||
2661 | } | ||
2662 | serial->tiocmget = NULL; | 2639 | serial->tiocmget = NULL; |
2663 | kfree(tiocmget); | 2640 | kfree(tiocmget); |
2664 | |||
2665 | } | 2641 | } |
2666 | } | 2642 | } |
2667 | 2643 | ||
@@ -3007,12 +2983,14 @@ static int hso_probe(struct usb_interface *interface, | |||
3007 | 2983 | ||
3008 | case HSO_INTF_BULK: | 2984 | case HSO_INTF_BULK: |
3009 | /* It's a regular bulk interface */ | 2985 | /* It's a regular bulk interface */ |
3010 | if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) && | 2986 | if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) { |
3011 | !disable_net) | 2987 | if (!disable_net) |
3012 | hso_dev = hso_create_net_device(interface, port_spec); | 2988 | hso_dev = |
3013 | else | 2989 | hso_create_net_device(interface, port_spec); |
2990 | } else { | ||
3014 | hso_dev = | 2991 | hso_dev = |
3015 | hso_create_bulk_serial_device(interface, port_spec); | 2992 | hso_create_bulk_serial_device(interface, port_spec); |
2993 | } | ||
3016 | if (!hso_dev) | 2994 | if (!hso_dev) |
3017 | goto exit; | 2995 | goto exit; |
3018 | break; | 2996 | break; |
@@ -3300,6 +3278,7 @@ static const struct tty_operations hso_serial_ops = { | |||
3300 | .chars_in_buffer = hso_serial_chars_in_buffer, | 3278 | .chars_in_buffer = hso_serial_chars_in_buffer, |
3301 | .tiocmget = hso_serial_tiocmget, | 3279 | .tiocmget = hso_serial_tiocmget, |
3302 | .tiocmset = hso_serial_tiocmset, | 3280 | .tiocmset = hso_serial_tiocmset, |
3281 | .get_icount = hso_get_count, | ||
3303 | .unthrottle = hso_unthrottle | 3282 | .unthrottle = hso_unthrottle |
3304 | }; | 3283 | }; |
3305 | 3284 | ||