diff options
Diffstat (limited to 'drivers/net/can/usb/kvaser_usb.c')
| -rw-r--r-- | drivers/net/can/usb/kvaser_usb.c | 57 |
1 files changed, 29 insertions, 28 deletions
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 541fb7a05625..7af379ca861b 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c | |||
| @@ -520,10 +520,10 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, | |||
| 520 | skb = alloc_can_err_skb(priv->netdev, &cf); | 520 | skb = alloc_can_err_skb(priv->netdev, &cf); |
| 521 | if (skb) { | 521 | if (skb) { |
| 522 | cf->can_id |= CAN_ERR_RESTARTED; | 522 | cf->can_id |= CAN_ERR_RESTARTED; |
| 523 | netif_rx(skb); | ||
| 524 | 523 | ||
| 525 | stats->rx_packets++; | 524 | stats->rx_packets++; |
| 526 | stats->rx_bytes += cf->can_dlc; | 525 | stats->rx_bytes += cf->can_dlc; |
| 526 | netif_rx(skb); | ||
| 527 | } else { | 527 | } else { |
| 528 | netdev_err(priv->netdev, | 528 | netdev_err(priv->netdev, |
| 529 | "No memory left for err_skb\n"); | 529 | "No memory left for err_skb\n"); |
| @@ -587,7 +587,7 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv, | |||
| 587 | usb_sndbulkpipe(dev->udev, | 587 | usb_sndbulkpipe(dev->udev, |
| 588 | dev->bulk_out->bEndpointAddress), | 588 | dev->bulk_out->bEndpointAddress), |
| 589 | buf, msg->len, | 589 | buf, msg->len, |
| 590 | kvaser_usb_simple_msg_callback, priv); | 590 | kvaser_usb_simple_msg_callback, netdev); |
| 591 | usb_anchor_urb(urb, &priv->tx_submitted); | 591 | usb_anchor_urb(urb, &priv->tx_submitted); |
| 592 | 592 | ||
| 593 | err = usb_submit_urb(urb, GFP_ATOMIC); | 593 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| @@ -662,11 +662,6 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
| 662 | priv = dev->nets[channel]; | 662 | priv = dev->nets[channel]; |
| 663 | stats = &priv->netdev->stats; | 663 | stats = &priv->netdev->stats; |
| 664 | 664 | ||
| 665 | if (status & M16C_STATE_BUS_RESET) { | ||
| 666 | kvaser_usb_unlink_tx_urbs(priv); | ||
| 667 | return; | ||
| 668 | } | ||
| 669 | |||
| 670 | skb = alloc_can_err_skb(priv->netdev, &cf); | 665 | skb = alloc_can_err_skb(priv->netdev, &cf); |
| 671 | if (!skb) { | 666 | if (!skb) { |
| 672 | stats->rx_dropped++; | 667 | stats->rx_dropped++; |
| @@ -677,7 +672,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
| 677 | 672 | ||
| 678 | netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status); | 673 | netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status); |
| 679 | 674 | ||
| 680 | if (status & M16C_STATE_BUS_OFF) { | 675 | if (status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) { |
| 681 | cf->can_id |= CAN_ERR_BUSOFF; | 676 | cf->can_id |= CAN_ERR_BUSOFF; |
| 682 | 677 | ||
| 683 | priv->can.can_stats.bus_off++; | 678 | priv->can.can_stats.bus_off++; |
| @@ -703,9 +698,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
| 703 | } | 698 | } |
| 704 | 699 | ||
| 705 | new_state = CAN_STATE_ERROR_PASSIVE; | 700 | new_state = CAN_STATE_ERROR_PASSIVE; |
| 706 | } | 701 | } else if (status & M16C_STATE_BUS_ERROR) { |
| 707 | |||
| 708 | if (status == M16C_STATE_BUS_ERROR) { | ||
| 709 | if ((priv->can.state < CAN_STATE_ERROR_WARNING) && | 702 | if ((priv->can.state < CAN_STATE_ERROR_WARNING) && |
| 710 | ((txerr >= 96) || (rxerr >= 96))) { | 703 | ((txerr >= 96) || (rxerr >= 96))) { |
| 711 | cf->can_id |= CAN_ERR_CRTL; | 704 | cf->can_id |= CAN_ERR_CRTL; |
| @@ -715,7 +708,8 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
| 715 | 708 | ||
| 716 | priv->can.can_stats.error_warning++; | 709 | priv->can.can_stats.error_warning++; |
| 717 | new_state = CAN_STATE_ERROR_WARNING; | 710 | new_state = CAN_STATE_ERROR_WARNING; |
| 718 | } else if (priv->can.state > CAN_STATE_ERROR_ACTIVE) { | 711 | } else if ((priv->can.state > CAN_STATE_ERROR_ACTIVE) && |
| 712 | ((txerr < 96) && (rxerr < 96))) { | ||
| 719 | cf->can_id |= CAN_ERR_PROT; | 713 | cf->can_id |= CAN_ERR_PROT; |
| 720 | cf->data[2] = CAN_ERR_PROT_ACTIVE; | 714 | cf->data[2] = CAN_ERR_PROT_ACTIVE; |
| 721 | 715 | ||
| @@ -770,10 +764,9 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
| 770 | 764 | ||
| 771 | priv->can.state = new_state; | 765 | priv->can.state = new_state; |
| 772 | 766 | ||
| 773 | netif_rx(skb); | ||
| 774 | |||
| 775 | stats->rx_packets++; | 767 | stats->rx_packets++; |
| 776 | stats->rx_bytes += cf->can_dlc; | 768 | stats->rx_bytes += cf->can_dlc; |
| 769 | netif_rx(skb); | ||
| 777 | } | 770 | } |
| 778 | 771 | ||
| 779 | static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, | 772 | static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, |
| @@ -805,10 +798,9 @@ static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, | |||
| 805 | stats->rx_over_errors++; | 798 | stats->rx_over_errors++; |
| 806 | stats->rx_errors++; | 799 | stats->rx_errors++; |
| 807 | 800 | ||
| 808 | netif_rx(skb); | ||
| 809 | |||
| 810 | stats->rx_packets++; | 801 | stats->rx_packets++; |
| 811 | stats->rx_bytes += cf->can_dlc; | 802 | stats->rx_bytes += cf->can_dlc; |
| 803 | netif_rx(skb); | ||
| 812 | } | 804 | } |
| 813 | } | 805 | } |
| 814 | 806 | ||
| @@ -887,10 +879,9 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, | |||
| 887 | cf->can_dlc); | 879 | cf->can_dlc); |
| 888 | } | 880 | } |
| 889 | 881 | ||
| 890 | netif_rx(skb); | ||
| 891 | |||
| 892 | stats->rx_packets++; | 882 | stats->rx_packets++; |
| 893 | stats->rx_bytes += cf->can_dlc; | 883 | stats->rx_bytes += cf->can_dlc; |
| 884 | netif_rx(skb); | ||
| 894 | } | 885 | } |
| 895 | 886 | ||
| 896 | static void kvaser_usb_start_chip_reply(const struct kvaser_usb *dev, | 887 | static void kvaser_usb_start_chip_reply(const struct kvaser_usb *dev, |
| @@ -1246,6 +1237,9 @@ static int kvaser_usb_close(struct net_device *netdev) | |||
| 1246 | if (err) | 1237 | if (err) |
| 1247 | netdev_warn(netdev, "Cannot stop device, error %d\n", err); | 1238 | netdev_warn(netdev, "Cannot stop device, error %d\n", err); |
| 1248 | 1239 | ||
| 1240 | /* reset tx contexts */ | ||
| 1241 | kvaser_usb_unlink_tx_urbs(priv); | ||
| 1242 | |||
| 1249 | priv->can.state = CAN_STATE_STOPPED; | 1243 | priv->can.state = CAN_STATE_STOPPED; |
| 1250 | close_candev(priv->netdev); | 1244 | close_candev(priv->netdev); |
| 1251 | 1245 | ||
| @@ -1294,12 +1288,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
| 1294 | if (!urb) { | 1288 | if (!urb) { |
| 1295 | netdev_err(netdev, "No memory left for URBs\n"); | 1289 | netdev_err(netdev, "No memory left for URBs\n"); |
| 1296 | stats->tx_dropped++; | 1290 | stats->tx_dropped++; |
| 1297 | goto nourbmem; | 1291 | dev_kfree_skb(skb); |
| 1292 | return NETDEV_TX_OK; | ||
| 1298 | } | 1293 | } |
| 1299 | 1294 | ||
| 1300 | buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC); | 1295 | buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC); |
| 1301 | if (!buf) { | 1296 | if (!buf) { |
| 1302 | stats->tx_dropped++; | 1297 | stats->tx_dropped++; |
| 1298 | dev_kfree_skb(skb); | ||
| 1303 | goto nobufmem; | 1299 | goto nobufmem; |
| 1304 | } | 1300 | } |
| 1305 | 1301 | ||
| @@ -1334,6 +1330,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
| 1334 | } | 1330 | } |
| 1335 | } | 1331 | } |
| 1336 | 1332 | ||
| 1333 | /* This should never happen; it implies a flow control bug */ | ||
| 1337 | if (!context) { | 1334 | if (!context) { |
| 1338 | netdev_warn(netdev, "cannot find free context\n"); | 1335 | netdev_warn(netdev, "cannot find free context\n"); |
| 1339 | ret = NETDEV_TX_BUSY; | 1336 | ret = NETDEV_TX_BUSY; |
| @@ -1364,9 +1361,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
| 1364 | if (unlikely(err)) { | 1361 | if (unlikely(err)) { |
| 1365 | can_free_echo_skb(netdev, context->echo_index); | 1362 | can_free_echo_skb(netdev, context->echo_index); |
| 1366 | 1363 | ||
| 1367 | skb = NULL; /* set to NULL to avoid double free in | ||
| 1368 | * dev_kfree_skb(skb) */ | ||
| 1369 | |||
| 1370 | atomic_dec(&priv->active_tx_urbs); | 1364 | atomic_dec(&priv->active_tx_urbs); |
| 1371 | usb_unanchor_urb(urb); | 1365 | usb_unanchor_urb(urb); |
| 1372 | 1366 | ||
| @@ -1388,8 +1382,6 @@ releasebuf: | |||
| 1388 | kfree(buf); | 1382 | kfree(buf); |
| 1389 | nobufmem: | 1383 | nobufmem: |
| 1390 | usb_free_urb(urb); | 1384 | usb_free_urb(urb); |
| 1391 | nourbmem: | ||
| 1392 | dev_kfree_skb(skb); | ||
| 1393 | return ret; | 1385 | return ret; |
| 1394 | } | 1386 | } |
| 1395 | 1387 | ||
| @@ -1502,6 +1494,10 @@ static int kvaser_usb_init_one(struct usb_interface *intf, | |||
| 1502 | struct kvaser_usb_net_priv *priv; | 1494 | struct kvaser_usb_net_priv *priv; |
| 1503 | int i, err; | 1495 | int i, err; |
| 1504 | 1496 | ||
| 1497 | err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, channel); | ||
| 1498 | if (err) | ||
| 1499 | return err; | ||
| 1500 | |||
| 1505 | netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); | 1501 | netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); |
| 1506 | if (!netdev) { | 1502 | if (!netdev) { |
| 1507 | dev_err(&intf->dev, "Cannot alloc candev\n"); | 1503 | dev_err(&intf->dev, "Cannot alloc candev\n"); |
| @@ -1588,7 +1584,7 @@ static int kvaser_usb_probe(struct usb_interface *intf, | |||
| 1588 | { | 1584 | { |
| 1589 | struct kvaser_usb *dev; | 1585 | struct kvaser_usb *dev; |
| 1590 | int err = -ENOMEM; | 1586 | int err = -ENOMEM; |
| 1591 | int i; | 1587 | int i, retry = 3; |
| 1592 | 1588 | ||
| 1593 | dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); | 1589 | dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); |
| 1594 | if (!dev) | 1590 | if (!dev) |
| @@ -1606,10 +1602,15 @@ static int kvaser_usb_probe(struct usb_interface *intf, | |||
| 1606 | 1602 | ||
| 1607 | usb_set_intfdata(intf, dev); | 1603 | usb_set_intfdata(intf, dev); |
| 1608 | 1604 | ||
| 1609 | for (i = 0; i < MAX_NET_DEVICES; i++) | 1605 | /* On some x86 laptops, plugging a Kvaser device again after |
| 1610 | kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, i); | 1606 | * an unplug makes the firmware always ignore the very first |
| 1607 | * command. For such a case, provide some room for retries | ||
| 1608 | * instead of completely exiting the driver. | ||
| 1609 | */ | ||
| 1610 | do { | ||
| 1611 | err = kvaser_usb_get_software_info(dev); | ||
| 1612 | } while (--retry && err == -ETIMEDOUT); | ||
| 1611 | 1613 | ||
| 1612 | err = kvaser_usb_get_software_info(dev); | ||
| 1613 | if (err) { | 1614 | if (err) { |
| 1614 | dev_err(&intf->dev, | 1615 | dev_err(&intf->dev, |
| 1615 | "Cannot get software infos, error %d\n", err); | 1616 | "Cannot get software infos, error %d\n", err); |
