| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* CAN driver for Geschwister Schneider USB/CAN devices |
|---|
| 2 | 3 | * and bytewerk.org candleLight USB CAN interfaces. |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * Copyright (C) 2016 Hubert Denkmair |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * Many thanks to all socketcan devs! |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 11 | | - * under the terms of the GNU General Public License as published |
|---|
| 12 | | - * by the Free Software Foundation; version 2 of the License. |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 15 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 16 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 17 | | - * General Public License for more details. |
|---|
| 18 | 10 | */ |
|---|
| 19 | 11 | |
|---|
| 20 | 12 | #include <linux/init.h> |
|---|
| .. | .. |
|---|
| 192 | 184 | |
|---|
| 193 | 185 | struct usb_anchor tx_submitted; |
|---|
| 194 | 186 | atomic_t active_tx_urbs; |
|---|
| 187 | + void *rxbuf[GS_MAX_RX_URBS]; |
|---|
| 188 | + dma_addr_t rxbuf_dma[GS_MAX_RX_URBS]; |
|---|
| 195 | 189 | }; |
|---|
| 196 | 190 | |
|---|
| 197 | 191 | /* usb interface struct */ |
|---|
| 198 | 192 | struct gs_usb { |
|---|
| 199 | 193 | struct gs_can *canch[GS_MAX_INTF]; |
|---|
| 200 | 194 | struct usb_anchor rx_submitted; |
|---|
| 201 | | - atomic_t active_channels; |
|---|
| 202 | 195 | struct usb_device *udev; |
|---|
| 196 | + u8 active_channels; |
|---|
| 203 | 197 | }; |
|---|
| 204 | 198 | |
|---|
| 205 | 199 | /* 'allocate' a tx context. |
|---|
| .. | .. |
|---|
| 596 | 590 | if (rc) |
|---|
| 597 | 591 | return rc; |
|---|
| 598 | 592 | |
|---|
| 599 | | - if (atomic_add_return(1, &parent->active_channels) == 1) { |
|---|
| 593 | + if (!parent->active_channels) { |
|---|
| 600 | 594 | for (i = 0; i < GS_MAX_RX_URBS; i++) { |
|---|
| 601 | 595 | struct urb *urb; |
|---|
| 602 | 596 | u8 *buf; |
|---|
| 597 | + dma_addr_t buf_dma; |
|---|
| 603 | 598 | |
|---|
| 604 | 599 | /* alloc rx urb */ |
|---|
| 605 | 600 | urb = usb_alloc_urb(0, GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 610 | 605 | buf = usb_alloc_coherent(dev->udev, |
|---|
| 611 | 606 | sizeof(struct gs_host_frame), |
|---|
| 612 | 607 | GFP_KERNEL, |
|---|
| 613 | | - &urb->transfer_dma); |
|---|
| 608 | + &buf_dma); |
|---|
| 614 | 609 | if (!buf) { |
|---|
| 615 | 610 | netdev_err(netdev, |
|---|
| 616 | 611 | "No memory left for USB buffer\n"); |
|---|
| 617 | 612 | usb_free_urb(urb); |
|---|
| 618 | 613 | return -ENOMEM; |
|---|
| 619 | 614 | } |
|---|
| 615 | + |
|---|
| 616 | + urb->transfer_dma = buf_dma; |
|---|
| 620 | 617 | |
|---|
| 621 | 618 | /* fill, anchor, and submit rx urb */ |
|---|
| 622 | 619 | usb_fill_bulk_urb(urb, |
|---|
| .. | .. |
|---|
| 641 | 638 | rc); |
|---|
| 642 | 639 | |
|---|
| 643 | 640 | usb_unanchor_urb(urb); |
|---|
| 641 | + usb_free_coherent(dev->udev, |
|---|
| 642 | + sizeof(struct gs_host_frame), |
|---|
| 643 | + buf, |
|---|
| 644 | + buf_dma); |
|---|
| 644 | 645 | usb_free_urb(urb); |
|---|
| 645 | 646 | break; |
|---|
| 646 | 647 | } |
|---|
| 648 | + |
|---|
| 649 | + dev->rxbuf[i] = buf; |
|---|
| 650 | + dev->rxbuf_dma[i] = buf_dma; |
|---|
| 647 | 651 | |
|---|
| 648 | 652 | /* Drop reference, |
|---|
| 649 | 653 | * USB core will take care of freeing it |
|---|
| .. | .. |
|---|
| 674 | 678 | flags |= GS_CAN_MODE_TRIPLE_SAMPLE; |
|---|
| 675 | 679 | |
|---|
| 676 | 680 | /* finally start device */ |
|---|
| 681 | + dev->can.state = CAN_STATE_ERROR_ACTIVE; |
|---|
| 677 | 682 | dm->mode = cpu_to_le32(GS_CAN_MODE_START); |
|---|
| 678 | 683 | dm->flags = cpu_to_le32(flags); |
|---|
| 679 | 684 | rc = usb_control_msg(interface_to_usbdev(dev->iface), |
|---|
| .. | .. |
|---|
| 690 | 695 | if (rc < 0) { |
|---|
| 691 | 696 | netdev_err(netdev, "Couldn't start device (err=%d)\n", rc); |
|---|
| 692 | 697 | kfree(dm); |
|---|
| 698 | + dev->can.state = CAN_STATE_STOPPED; |
|---|
| 693 | 699 | return rc; |
|---|
| 694 | 700 | } |
|---|
| 695 | 701 | |
|---|
| 696 | 702 | kfree(dm); |
|---|
| 697 | 703 | |
|---|
| 698 | | - dev->can.state = CAN_STATE_ERROR_ACTIVE; |
|---|
| 699 | | - |
|---|
| 704 | + parent->active_channels++; |
|---|
| 700 | 705 | if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) |
|---|
| 701 | 706 | netif_start_queue(netdev); |
|---|
| 702 | 707 | |
|---|
| .. | .. |
|---|
| 708 | 713 | int rc; |
|---|
| 709 | 714 | struct gs_can *dev = netdev_priv(netdev); |
|---|
| 710 | 715 | struct gs_usb *parent = dev->parent; |
|---|
| 716 | + unsigned int i; |
|---|
| 711 | 717 | |
|---|
| 712 | 718 | netif_stop_queue(netdev); |
|---|
| 713 | 719 | |
|---|
| 714 | 720 | /* Stop polling */ |
|---|
| 715 | | - if (atomic_dec_and_test(&parent->active_channels)) |
|---|
| 721 | + parent->active_channels--; |
|---|
| 722 | + if (!parent->active_channels) { |
|---|
| 716 | 723 | usb_kill_anchored_urbs(&parent->rx_submitted); |
|---|
| 724 | + for (i = 0; i < GS_MAX_RX_URBS; i++) |
|---|
| 725 | + usb_free_coherent(dev->udev, |
|---|
| 726 | + sizeof(struct gs_host_frame), |
|---|
| 727 | + dev->rxbuf[i], |
|---|
| 728 | + dev->rxbuf_dma[i]); |
|---|
| 729 | + } |
|---|
| 717 | 730 | |
|---|
| 718 | 731 | /* Stop sending URBs */ |
|---|
| 719 | 732 | usb_kill_anchored_urbs(&dev->tx_submitted); |
|---|
| .. | .. |
|---|
| 847 | 860 | |
|---|
| 848 | 861 | netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */ |
|---|
| 849 | 862 | |
|---|
| 850 | | - /* dev settup */ |
|---|
| 863 | + /* dev setup */ |
|---|
| 851 | 864 | strcpy(dev->bt_const.name, "gs_usb"); |
|---|
| 852 | 865 | dev->bt_const.tseg1_min = le32_to_cpu(bt_const->tseg1_min); |
|---|
| 853 | 866 | dev->bt_const.tseg1_max = le32_to_cpu(bt_const->tseg1_max); |
|---|
| .. | .. |
|---|
| 871 | 884 | dev->tx_context[rc].echo_id = GS_MAX_TX_URBS; |
|---|
| 872 | 885 | } |
|---|
| 873 | 886 | |
|---|
| 874 | | - /* can settup */ |
|---|
| 887 | + /* can setup */ |
|---|
| 875 | 888 | dev->can.state = CAN_STATE_STOPPED; |
|---|
| 876 | 889 | dev->can.clock.freq = le32_to_cpu(bt_const->fclk_can); |
|---|
| 877 | 890 | dev->can.bittiming_const = &dev->bt_const; |
|---|
| .. | .. |
|---|
| 990 | 1003 | } |
|---|
| 991 | 1004 | |
|---|
| 992 | 1005 | init_usb_anchor(&dev->rx_submitted); |
|---|
| 993 | | - |
|---|
| 994 | | - atomic_set(&dev->active_channels, 0); |
|---|
| 995 | 1006 | |
|---|
| 996 | 1007 | usb_set_intfdata(intf, dev); |
|---|
| 997 | 1008 | dev->udev = interface_to_usbdev(intf); |
|---|