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); |