diff options
Diffstat (limited to 'drivers/net/can/usb/ems_usb.c')
| -rw-r--r-- | drivers/net/can/usb/ems_usb.c | 195 |
1 files changed, 65 insertions, 130 deletions
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 9012e0abc62..00f2534dde7 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -16,7 +16,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include <linux/init.h> #include <linux/signal.h> #include <linux/slab.h> #include <linux/module.h> @@ -197,7 +196,7 @@ struct cpc_can_err_counter { }; /* Main message type used between library and application */ -struct __attribute__ ((packed)) ems_cpc_msg { +struct __packed ems_cpc_msg { u8 type; /* type of message */ u8 length; /* length of data within union 'msg' */ u8 msgid; /* confirmation handle */ @@ -232,7 +231,7 @@ MODULE_DEVICE_TABLE(usb, ems_usb_table); #define INTR_IN_BUFFER_SIZE 4 #define MAX_RX_URBS 10 -#define MAX_TX_URBS CAN_ECHO_SKB_MAX +#define MAX_TX_URBS 10 struct ems_usb; @@ -245,7 +244,6 @@ struct ems_tx_urb_context { struct ems_usb { struct can_priv can; /* must be the first member */ - int open_time; struct sk_buff *echo_skb[MAX_TX_URBS]; @@ -288,8 +286,7 @@ static void ems_usb_read_interrupt_callback(struct urb *urb) return; default: - dev_info(netdev->dev.parent, "Rx interrupt aborted %d\n", - urb->status); + netdev_info(netdev, "Rx interrupt aborted %d\n", urb->status); break; } @@ -298,10 +295,7 @@ static void ems_usb_read_interrupt_callback(struct urb *urb) if (err == -ENODEV) netif_device_detach(netdev); else if (err) - dev_err(netdev->dev.parent, - "failed resubmitting intr urb: %d\n", err); - - return; + netdev_err(netdev, "failed resubmitting intr urb: %d\n", err); } static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) @@ -311,23 +305,19 @@ static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) int i; struct net_device_stats *stats = &dev->netdev->stats; - skb = netdev_alloc_skb(dev->netdev, sizeof(struct can_frame)); + skb = alloc_can_skb(dev->netdev, &cf); if (skb == NULL) return; - skb->protocol = htons(ETH_P_CAN); - - cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); - - cf->can_id = msg->msg.can_msg.id; - cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8); + cf->can_id = le32_to_cpu(msg->msg.can_msg.id); + cf->can_dlc = get_can_dlc(msg->msg.can_msg.length & 0xF); - if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME - || msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) + if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME || + msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) cf->can_id |= CAN_EFF_FLAG; - if (msg->type == CPC_MSG_TYPE_RTR_FRAME - || msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) { + if (msg->type == CPC_MSG_TYPE_RTR_FRAME || + msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) { cf->can_id |= CAN_RTR_FLAG; } else { for (i = 0; i < cf->can_dlc; i++) @@ -346,18 +336,10 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) struct sk_buff *skb; struct net_device_stats *stats = &dev->netdev->stats; - skb = netdev_alloc_skb(dev->netdev, sizeof(struct can_frame)); + skb = alloc_can_err_skb(dev->netdev, &cf); if (skb == NULL) return; - skb->protocol = htons(ETH_P_CAN); - - cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); - memset(cf, 0, sizeof(struct can_frame)); - - cf->can_id = CAN_ERR_FLAG; - cf->can_dlc = CAN_ERR_DLC; - if (msg->type == CPC_MSG_TYPE_CAN_STATE) { u8 state = msg->msg.can_state; @@ -400,7 +382,7 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) break; } - /* Error occured during transmission? */ + /* Error occurred during transmission? */ if ((ecc & SJA1000_ECC_DIR) == 0) cf->data[2] |= CAN_ERR_PROT_TX; @@ -445,8 +427,7 @@ static void ems_usb_read_bulk_callback(struct urb *urb) return; default: - dev_info(netdev->dev.parent, "Rx URB aborted (%d)\n", - urb->status); + netdev_info(netdev, "Rx URB aborted (%d)\n", urb->status); goto resubmit_urb; } @@ -491,7 +472,7 @@ static void ems_usb_read_bulk_callback(struct urb *urb) msg_count--; if (start > urb->transfer_buffer_length) { - dev_err(netdev->dev.parent, "format error\n"); + netdev_err(netdev, "format error\n"); break; } } @@ -507,10 +488,8 @@ resubmit_urb: if (retval == -ENODEV) netif_device_detach(netdev); else if (retval) - dev_err(netdev->dev.parent, - "failed resubmitting read bulk urb: %d\n", retval); - - return; + netdev_err(netdev, + "failed resubmitting read bulk urb: %d\n", retval); } /* @@ -528,8 +507,8 @@ static void ems_usb_write_bulk_callback(struct urb *urb) netdev = dev->netdev; /* free up our allocated buffer */ - usb_buffer_free(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); + usb_free_coherent(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); atomic_dec(&dev->active_tx_urbs); @@ -537,8 +516,7 @@ static void ems_usb_write_bulk_callback(struct urb *urb) return; if (urb->status) - dev_info(netdev->dev.parent, "Tx URB aborted (%d)\n", - urb->status); + netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status); netdev->trans_start = jiffies; @@ -621,18 +599,18 @@ static int ems_usb_start(struct ems_usb *dev) /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - dev_err(netdev->dev.parent, - "No memory left for URBs\n"); - return -ENOMEM; + netdev_err(netdev, "No memory left for URBs\n"); + err = -ENOMEM; + break; } - buf = usb_buffer_alloc(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, - &urb->transfer_dma); + buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, + &urb->transfer_dma); if (!buf) { - dev_err(netdev->dev.parent, - "No memory left for USB buffer\n"); + netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); - return -ENOMEM; + err = -ENOMEM; + break; } usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), @@ -643,12 +621,10 @@ static int ems_usb_start(struct ems_usb *dev) err = usb_submit_urb(urb, GFP_KERNEL); if (err) { - if (err == -ENODEV) - netif_device_detach(dev->netdev); - usb_unanchor_urb(urb); - usb_buffer_free(dev->udev, RX_BUFFER_SIZE, buf, - urb->transfer_dma); + usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, + urb->transfer_dma); + usb_free_urb(urb); break; } @@ -658,13 +634,13 @@ static int ems_usb_start(struct ems_usb *dev) /* Did we submit any URBs */ if (i == 0) { - dev_warn(netdev->dev.parent, "couldn't setup read URBs\n"); + netdev_warn(netdev, "couldn't setup read URBs\n"); return err; } /* Warn if we've couldn't transmit all the URBs */ if (i < MAX_RX_URBS) - dev_warn(netdev->dev.parent, "rx performance may be slow\n"); + netdev_warn(netdev, "rx performance may be slow\n"); /* Setup and start interrupt URB */ usb_fill_int_urb(dev->intr_urb, dev->udev, @@ -675,11 +651,7 @@ static int ems_usb_start(struct ems_usb *dev) err = usb_submit_urb(dev->intr_urb, GFP_KERNEL); if (err) { - if (err == -ENODEV) - netif_device_detach(dev->netdev); - - dev_warn(netdev->dev.parent, "intr URB submit failed: %d\n", - err); + netdev_warn(netdev, "intr URB submit failed: %d\n", err); return err; } @@ -708,10 +680,7 @@ static int ems_usb_start(struct ems_usb *dev) return 0; failed: - if (err == -ENODEV) - netif_device_detach(dev->netdev); - - dev_warn(netdev->dev.parent, "couldn't submit control: %d\n", err); + netdev_warn(netdev, "couldn't submit control: %d\n", err); return err; } @@ -751,15 +720,13 @@ static int ems_usb_open(struct net_device *netdev) if (err == -ENODEV) netif_device_detach(dev->netdev); - dev_warn(netdev->dev.parent, "couldn't start device: %d\n", - err); + netdev_warn(netdev, "couldn't start device: %d\n", err); close_candev(netdev); return err; } - dev->open_time = jiffies; netif_start_queue(netdev); @@ -779,16 +746,19 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN + sizeof(struct cpc_can_msg); + if (can_dropped_invalid_skb(netdev, skb)) + return NETDEV_TX_OK; + /* create a URB, and a buffer for it, and copy the data to the URB */ urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { - dev_err(netdev->dev.parent, "No memory left for URBs\n"); + netdev_err(netdev, "No memory left for URBs\n"); goto nomem; } - buf = usb_buffer_alloc(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); + buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { - dev_err(netdev->dev.parent, "No memory left for USB buffer\n"); + netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); goto nomem; } @@ -813,6 +783,9 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc; } + /* Respect byte order */ + msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id); + for (i = 0; i < MAX_TX_URBS; i++) { if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) { context = &dev->tx_contexts[i]; @@ -825,10 +798,10 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne * allowed (MAX_TX_URBS). */ if (!context) { - usb_unanchor_urb(urb); - usb_buffer_free(dev->udev, size, buf, urb->transfer_dma); + usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); + usb_free_urb(urb); - dev_warn(netdev->dev.parent, "couldn't find free context\n"); + netdev_warn(netdev, "couldn't find free context\n"); return NETDEV_TX_BUSY; } @@ -851,7 +824,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne can_free_echo_skb(netdev, context->echo_index); usb_unanchor_urb(urb); - usb_buffer_free(dev->udev, size, buf, urb->transfer_dma); + usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); dev_kfree_skb(skb); atomic_dec(&dev->active_tx_urbs); @@ -859,7 +832,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne if (err == -ENODEV) { netif_device_detach(netdev); } else { - dev_warn(netdev->dev.parent, "failed tx_urb %d\n", err); + netdev_warn(netdev, "failed tx_urb %d\n", err); stats->tx_dropped++; } @@ -882,9 +855,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne return NETDEV_TX_OK; nomem: - if (skb) - dev_kfree_skb(skb); - + dev_kfree_skb(skb); stats->tx_dropped++; return NETDEV_TX_OK; @@ -901,12 +872,10 @@ static int ems_usb_close(struct net_device *netdev) /* Set CAN controller to reset mode */ if (ems_usb_write_mode(dev, SJA1000_MOD_RM)) - dev_warn(netdev->dev.parent, "couldn't stop device"); + netdev_warn(netdev, "couldn't stop device"); close_candev(netdev); - dev->open_time = 0; - return 0; } @@ -914,9 +883,10 @@ static const struct net_device_ops ems_usb_netdev_ops = { .ndo_open = ems_usb_open, .ndo_stop = ems_usb_close, .ndo_start_xmit = ems_usb_start_xmit, + .ndo_change_mtu = can_change_mtu, }; -static struct can_bittiming_const ems_usb_bittiming_const = { +static const struct can_bittiming_const ems_usb_bittiming_const = { .name = "ems_usb", .tseg1_min = 1, .tseg1_max = 16, @@ -932,13 +902,10 @@ static int ems_usb_set_mode(struct net_device *netdev, enum can_mode mode) { struct ems_usb *dev = netdev_priv(netdev); - if (!dev->open_time) - return -EINVAL; - switch (mode) { case CAN_MODE_START: if (ems_usb_write_mode(dev, SJA1000_MOD_NORMAL)) - dev_warn(netdev->dev.parent, "couldn't start device"); + netdev_warn(netdev, "couldn't start device"); if (netif_queue_stopped(netdev)) netif_wake_queue(netdev); @@ -963,8 +930,7 @@ static int ems_usb_set_bittiming(struct net_device *netdev) if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) btr1 |= 0x80; - dev_info(netdev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n", - btr0, btr1); + netdev_info(netdev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); dev->active_params.msg.can_params.cc_params.sja1000.btr0 = btr0; dev->active_params.msg.can_params.cc_params.sja1000.btr1 = btr1; @@ -1012,9 +978,9 @@ static int ems_usb_probe(struct usb_interface *intf, struct ems_usb *dev; int i, err = -ENOMEM; - netdev = alloc_candev(sizeof(struct ems_usb)); + netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS); if (!netdev) { - dev_err(netdev->dev.parent, "Couldn't alloc candev\n"); + dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n"); return -ENOMEM; } @@ -1028,8 +994,7 @@ static int ems_usb_probe(struct usb_interface *intf, dev->can.bittiming_const = &ems_usb_bittiming_const; dev->can.do_set_bittiming = ems_usb_set_bittiming; dev->can.do_set_mode = ems_usb_set_mode; - - netdev->flags |= IFF_ECHO; /* we support local echo */ + dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; netdev->netdev_ops = &ems_usb_netdev_ops; @@ -1045,22 +1010,18 @@ static int ems_usb_probe(struct usb_interface *intf, dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->intr_urb) { - dev_err(netdev->dev.parent, "Couldn't alloc intr URB\n"); + dev_err(&intf->dev, "Couldn't alloc intr URB\n"); goto cleanup_candev; } dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL); - if (!dev->intr_in_buffer) { - dev_err(netdev->dev.parent, "Couldn't alloc Intr buffer\n"); + if (!dev->intr_in_buffer) goto cleanup_intr_urb; - } dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE + sizeof(struct ems_cpc_msg), GFP_KERNEL); - if (!dev->tx_msg_buffer) { - dev_err(netdev->dev.parent, "Couldn't alloc Tx buffer\n"); + if (!dev->tx_msg_buffer) goto cleanup_intr_in_buffer; - } usb_set_intfdata(intf, dev); @@ -1070,15 +1031,13 @@ static int ems_usb_probe(struct usb_interface *intf, err = ems_usb_command_msg(dev, &dev->active_params); if (err) { - dev_err(netdev->dev.parent, - "couldn't initialize controller: %d\n", err); + netdev_err(netdev, "couldn't initialize controller: %d\n", err); goto cleanup_tx_msg_buffer; } err = register_candev(netdev); if (err) { - dev_err(netdev->dev.parent, - "couldn't register CAN device: %d\n", err); + netdev_err(netdev, "couldn't register CAN device: %d\n", err); goto cleanup_tx_msg_buffer; } @@ -1128,28 +1087,4 @@ static struct usb_driver ems_usb_driver = { .id_table = ems_usb_table, }; -static int __init ems_usb_init(void) -{ - int err; - - printk(KERN_INFO "CPC-USB kernel driver loaded\n"); - - /* register this driver with the USB subsystem */ - err = usb_register(&ems_usb_driver); - - if (err) { - err("usb_register failed. Error number %d\n", err); - return err; - } - - return 0; -} - -static void __exit ems_usb_exit(void) -{ - /* deregister this driver with the USB subsystem */ - usb_deregister(&ems_usb_driver); -} - -module_init(ems_usb_init); -module_exit(ems_usb_exit); +module_usb_driver(ems_usb_driver); |
