Re: [PATCH v2] can: kvaser_usb: Add support for Kvaser CAN/USB devices
Hi Oliver, On 08/08/2012 08:14 AM, Olivier Sobrie wrote: Hi Wolfgang, On Tue, Aug 07, 2012 at 08:26:38AM +0200, Wolfgang Grandegger wrote: On 08/06/2012 07:21 AM, Olivier Sobrie wrote: This driver provides support for several Kvaser CAN/USB devices. Such kind of devices supports up to three can network interfaces. s/can/CAN/ It has been tested with a Kvaser USB Leaf Light (one network interface) connected to a pch_can interface. The firmware version of the Kvaser device was 2.5.205. List of Kvaser devices supported by the driver: - Kvaser Leaf prototype (P010v2 and v3) - Kvaser Leaf Light (P010v3) - Kvaser Leaf Professional HS - Kvaser Leaf SemiPro HS - Kvaser Leaf Professional LS - Kvaser Leaf Professional SWC - Kvaser Leaf Professional LIN - Kvaser Leaf SemiPro LS - Kvaser Leaf SemiPro SWC - Kvaser Memorator II, Prototype - Kvaser Memorator II HS/HS - Kvaser USBcan Professional HS/HS - Kvaser Leaf Light GI - Kvaser Leaf Professional HS (OBD-II connector) - Kvaser Memorator Professional HS/LS - Kvaser Leaf Light China - Kvaser BlackBird SemiPro - Kvaser OEM Mercury - Kvaser OEM Leaf - Kvaser USBcan R Impressive list! What CAN controllers are used inside the devices? SJA1000? I took this list from the Kvaser driver. However I only have a Kvaser Leaf Light device thus I'm not sure it will work with other ones. If you prefer I can only let Kvaser Leaf Light instead of the full list. In my device it looks to be a Renesas M16C controller. OK. Checking the manual, if available, could help to understand how the firmware handles bus errors and state changes. Signed-off-by: Olivier Sobrie oliv...@sobrie.be --- Changes since v1: - added copyrights - kvaser_usb.h merged into kvaser.c - added kvaser_usb_get_endpoints to find eindpoints instead of hardcoding their address - some cleanup and comestic changes - fixed issues with errors handling - fixed restart-ms == 0 case - removed do_get_berr_counter method since the hardware doens't return good values for txerr and rxerr. If someone in the linux-usb mailing can review it, it would be nice. Concerning the errors, it behaves like that now: 1) Short-circuit CAN-H and CAN-L and restart-ms = 0 t0: short-circuit + 'cansend can1 123#112233' can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 20C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-off bus-error t1: remove short-circuit + 'ip link set can1 type can restart' can1 2100 [8] 00 00 00 00 00 00 00 00 ERRORFRAME restarted-after-bus-off can1 2004 [8] 00 0C 00 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} Why do we get the last error message? Maybe the firmware does it that way (going down passive-warning-active). It goes in that order: warning - passive - bus off - warning - passive - ... Just for curiosity? You don't see back to error active? 2) Short-circuit CAN-H and CAN-L and restart-ms = 100 t0: short-circuit + cansend can1 123#112233 can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 20C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-off bus-error can1 218C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error restarted-after-bus-off can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 20C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-off bus-error ... can1 218C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning}
Re: [PATCH v2] can: kvaser_usb: Add support for Kvaser CAN/USB devices
On Wed, Aug 08, 2012 at 10:25:35AM +0200, Wolfgang Grandegger wrote: Hi Oliver, On 08/08/2012 08:14 AM, Olivier Sobrie wrote: Hi Wolfgang, On Tue, Aug 07, 2012 at 08:26:38AM +0200, Wolfgang Grandegger wrote: On 08/06/2012 07:21 AM, Olivier Sobrie wrote: This driver provides support for several Kvaser CAN/USB devices. Such kind of devices supports up to three can network interfaces. s/can/CAN/ It has been tested with a Kvaser USB Leaf Light (one network interface) connected to a pch_can interface. The firmware version of the Kvaser device was 2.5.205. List of Kvaser devices supported by the driver: - Kvaser Leaf prototype (P010v2 and v3) - Kvaser Leaf Light (P010v3) - Kvaser Leaf Professional HS - Kvaser Leaf SemiPro HS - Kvaser Leaf Professional LS - Kvaser Leaf Professional SWC - Kvaser Leaf Professional LIN - Kvaser Leaf SemiPro LS - Kvaser Leaf SemiPro SWC - Kvaser Memorator II, Prototype - Kvaser Memorator II HS/HS - Kvaser USBcan Professional HS/HS - Kvaser Leaf Light GI - Kvaser Leaf Professional HS (OBD-II connector) - Kvaser Memorator Professional HS/LS - Kvaser Leaf Light China - Kvaser BlackBird SemiPro - Kvaser OEM Mercury - Kvaser OEM Leaf - Kvaser USBcan R Impressive list! What CAN controllers are used inside the devices? SJA1000? I took this list from the Kvaser driver. However I only have a Kvaser Leaf Light device thus I'm not sure it will work with other ones. If you prefer I can only let Kvaser Leaf Light instead of the full list. In my device it looks to be a Renesas M16C controller. OK. Checking the manual, if available, could help to understand how the firmware handles bus errors and state changes. Ok I'll try to find it. Signed-off-by: Olivier Sobrie oliv...@sobrie.be --- Changes since v1: - added copyrights - kvaser_usb.h merged into kvaser.c - added kvaser_usb_get_endpoints to find eindpoints instead of hardcoding their address - some cleanup and comestic changes - fixed issues with errors handling - fixed restart-ms == 0 case - removed do_get_berr_counter method since the hardware doens't return good values for txerr and rxerr. If someone in the linux-usb mailing can review it, it would be nice. Concerning the errors, it behaves like that now: 1) Short-circuit CAN-H and CAN-L and restart-ms = 0 t0: short-circuit + 'cansend can1 123#112233' can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 20C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-off bus-error t1: remove short-circuit + 'ip link set can1 type can restart' can1 2100 [8] 00 00 00 00 00 00 00 00 ERRORFRAME restarted-after-bus-off can1 2004 [8] 00 0C 00 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} Why do we get the last error message? Maybe the firmware does it that way (going down passive-warning-active). It goes in that order: warning - passive - bus off - warning - passive - ... Just for curiosity? You don't see back to error active? No but that's maybe because of my misunderstanding of the M16C_STATE_BUS_ERROR flag. What I see is: t1: M16C_STATE_BUS_ERROR t2: M16C_STATE_BUS_ERROR | M16C_STATE_BUS_PASSIVE t3: M16C_STATE_BUS_ERROR | M16C_STATE_BUS_OFF and then again t4: M16C_STATE_BUS_ERROR t2: M16C_STATE_BUS_ERROR | M16C_STATE_BUS_PASSIVE t3: M16C_STATE_BUS_ERROR | M16C_STATE_BUS_OFF Thus as you suggested below, the flag M16C_STATE_BUS_ERROR might not mean CAN_STATE_ERROR_WARNING... 2) Short-circuit CAN-H and CAN-L and restart-ms = 100 t0: short-circuit + cansend can1 123#112233 can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 20C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-off bus-error can1 218C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error restarted-after-bus-off can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME
Re: [PATCH v2] can: kvaser_usb: Add support for Kvaser CAN/USB devices
On 08/08/2012 03:30 PM, Olivier Sobrie wrote: On Wed, Aug 08, 2012 at 10:25:35AM +0200, Wolfgang Grandegger wrote: Hi Oliver, On 08/08/2012 08:14 AM, Olivier Sobrie wrote: Hi Wolfgang, On Tue, Aug 07, 2012 at 08:26:38AM +0200, Wolfgang Grandegger wrote: On 08/06/2012 07:21 AM, Olivier Sobrie wrote: This driver provides support for several Kvaser CAN/USB devices. Such kind of devices supports up to three can network interfaces. s/can/CAN/ It has been tested with a Kvaser USB Leaf Light (one network interface) connected to a pch_can interface. The firmware version of the Kvaser device was 2.5.205. List of Kvaser devices supported by the driver: - Kvaser Leaf prototype (P010v2 and v3) - Kvaser Leaf Light (P010v3) - Kvaser Leaf Professional HS - Kvaser Leaf SemiPro HS - Kvaser Leaf Professional LS - Kvaser Leaf Professional SWC - Kvaser Leaf Professional LIN - Kvaser Leaf SemiPro LS - Kvaser Leaf SemiPro SWC - Kvaser Memorator II, Prototype - Kvaser Memorator II HS/HS - Kvaser USBcan Professional HS/HS - Kvaser Leaf Light GI - Kvaser Leaf Professional HS (OBD-II connector) - Kvaser Memorator Professional HS/LS - Kvaser Leaf Light China - Kvaser BlackBird SemiPro - Kvaser OEM Mercury - Kvaser OEM Leaf - Kvaser USBcan R Impressive list! What CAN controllers are used inside the devices? SJA1000? I took this list from the Kvaser driver. However I only have a Kvaser Leaf Light device thus I'm not sure it will work with other ones. If you prefer I can only let Kvaser Leaf Light instead of the full list. In my device it looks to be a Renesas M16C controller. OK. Checking the manual, if available, could help to understand how the firmware handles bus errors and state changes. Ok I'll try to find it. Signed-off-by: Olivier Sobrie oliv...@sobrie.be --- Changes since v1: - added copyrights - kvaser_usb.h merged into kvaser.c - added kvaser_usb_get_endpoints to find eindpoints instead of hardcoding their address - some cleanup and comestic changes - fixed issues with errors handling - fixed restart-ms == 0 case - removed do_get_berr_counter method since the hardware doens't return good values for txerr and rxerr. If someone in the linux-usb mailing can review it, it would be nice. Concerning the errors, it behaves like that now: 1) Short-circuit CAN-H and CAN-L and restart-ms = 0 t0: short-circuit + 'cansend can1 123#112233' can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 20C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-off bus-error t1: remove short-circuit + 'ip link set can1 type can restart' can1 2100 [8] 00 00 00 00 00 00 00 00 ERRORFRAME restarted-after-bus-off can1 2004 [8] 00 0C 00 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} Why do we get the last error message? Maybe the firmware does it that way (going down passive-warning-active). It goes in that order: warning - passive - bus off - warning - passive - ... Just for curiosity? You don't see back to error active? No but that's maybe because of my misunderstanding of the M16C_STATE_BUS_ERROR flag. What I see is: t1: M16C_STATE_BUS_ERROR t2: M16C_STATE_BUS_ERROR | M16C_STATE_BUS_PASSIVE t3: M16C_STATE_BUS_ERROR | M16C_STATE_BUS_OFF and then again t4: M16C_STATE_BUS_ERROR t2: M16C_STATE_BUS_ERROR | M16C_STATE_BUS_PASSIVE t3: M16C_STATE_BUS_ERROR | M16C_STATE_BUS_OFF Thus as you suggested below, the flag M16C_STATE_BUS_ERROR might not mean CAN_STATE_ERROR_WARNING... Do you see bus error bits set? If not, I could mean error active, otherwise error warning. Meaning the device sends such messages containing bus error information plus the current state. 2) Short-circuit CAN-H and CAN-L and restart-ms = 100 t0: short-circuit + cansend can1 123#112233 can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 20C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-off bus-error can1 218C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning}
Re: [PATCH v2] can: kvaser_usb: Add support for Kvaser CAN/USB devices
On 08/06/2012 07:21 AM, Olivier Sobrie wrote: This driver provides support for several Kvaser CAN/USB devices. Such kind of devices supports up to three can network interfaces. s/can/CAN/ It has been tested with a Kvaser USB Leaf Light (one network interface) connected to a pch_can interface. The firmware version of the Kvaser device was 2.5.205. List of Kvaser devices supported by the driver: - Kvaser Leaf prototype (P010v2 and v3) - Kvaser Leaf Light (P010v3) - Kvaser Leaf Professional HS - Kvaser Leaf SemiPro HS - Kvaser Leaf Professional LS - Kvaser Leaf Professional SWC - Kvaser Leaf Professional LIN - Kvaser Leaf SemiPro LS - Kvaser Leaf SemiPro SWC - Kvaser Memorator II, Prototype - Kvaser Memorator II HS/HS - Kvaser USBcan Professional HS/HS - Kvaser Leaf Light GI - Kvaser Leaf Professional HS (OBD-II connector) - Kvaser Memorator Professional HS/LS - Kvaser Leaf Light China - Kvaser BlackBird SemiPro - Kvaser OEM Mercury - Kvaser OEM Leaf - Kvaser USBcan R Impressive list! What CAN controllers are used inside the devices? SJA1000? Signed-off-by: Olivier Sobrie oliv...@sobrie.be --- Changes since v1: - added copyrights - kvaser_usb.h merged into kvaser.c - added kvaser_usb_get_endpoints to find eindpoints instead of hardcoding their address - some cleanup and comestic changes - fixed issues with errors handling - fixed restart-ms == 0 case - removed do_get_berr_counter method since the hardware doens't return good values for txerr and rxerr. If someone in the linux-usb mailing can review it, it would be nice. Concerning the errors, it behaves like that now: 1) Short-circuit CAN-H and CAN-L and restart-ms = 0 t0: short-circuit + 'cansend can1 123#112233' can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 20C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-off bus-error t1: remove short-circuit + 'ip link set can1 type can restart' can1 2100 [8] 00 00 00 00 00 00 00 00 ERRORFRAME restarted-after-bus-off can1 2004 [8] 00 0C 00 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} Why do we get the last error message? Maybe the firmware does it that way (going down passive-warning-active). 2) Short-circuit CAN-H and CAN-L and restart-ms = 100 t0: short-circuit + cansend can1 123#112233 can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 20C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-off bus-error can1 218C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error restarted-after-bus-off can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 20C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-off bus-error ... can1 218C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error restarted-after-bus-off can1 208C [8] 00 0C 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-warning,tx-error-warning} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error can1 208C [8] 00 30 90 00 00 00 00 00 ERRORFRAME controller-problem{rx-error-passive,tx-error-passive} protocol-violation{{tx-recessive-bit-error,error-on-tx}{}} bus-error t1: remove short-circuit can1 123 [3] 11 22 33 can1 2008 [8] 00 00 40 00 00 00 00 00
Re: [PATCH v2] can: kvaser_usb: Add support for Kvaser CAN/USB devices
Hi Oliver, On Mon, Aug 06, 2012 at 10:10:43AM +0200, Oliver Neukum wrote: On Monday 06 August 2012 07:21:29 Olivier Sobrie wrote: This driver provides support for several Kvaser CAN/USB devices. Such kind of devices supports up to three can network interfaces. It has been tested with a Kvaser USB Leaf Light (one network interface) connected to a pch_can interface. The firmware version of the Kvaser device was 2.5.205. +static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, +struct net_device *netdev) +{ + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); + struct kvaser_usb *dev = priv-dev; + struct net_device_stats *stats = netdev-stats; + struct can_frame *cf = (struct can_frame *)skb-data; + struct kvaser_usb_tx_urb_context *context = NULL; + struct urb *urb; + void *buf; + struct kvaser_msg *msg; + int i, err; + int ret = NETDEV_TX_OK; + + if (can_dropped_invalid_skb(netdev, skb)) + return NETDEV_TX_OK; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + netdev_err(netdev, No memory left for URBs\n); + stats-tx_dropped++; + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + buf = usb_alloc_coherent(dev-udev, sizeof(struct kvaser_msg), +GFP_ATOMIC, urb-transfer_dma); usb_alloc_coherent() as a rule only makes sense if you reuse the buffer and in some cases not even then. Please use a simple kmalloc() Ok thanks. I'll change it. + if (!buf) { + netdev_err(netdev, No memory left for USB buffer\n); + stats-tx_dropped++; + dev_kfree_skb(skb); + goto nobufmem; + } + + msg = (struct kvaser_msg *)buf; + msg-len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_tx_can); + msg-u.tx_can.flags = 0; + msg-u.tx_can.channel = priv-channel; + + if (cf-can_id CAN_EFF_FLAG) { + msg-id = CMD_TX_EXT_MESSAGE; + msg-u.tx_can.msg[0] = (cf-can_id 24) 0x1f; + msg-u.tx_can.msg[1] = (cf-can_id 18) 0x3f; + msg-u.tx_can.msg[2] = (cf-can_id 14) 0x0f; + msg-u.tx_can.msg[3] = (cf-can_id 6) 0xff; + msg-u.tx_can.msg[4] = cf-can_id 0x3f; + } else { + msg-id = CMD_TX_STD_MESSAGE; + msg-u.tx_can.msg[0] = (cf-can_id 6) 0x1f; + msg-u.tx_can.msg[1] = cf-can_id 0x3f; + } + + msg-u.tx_can.msg[5] = cf-can_dlc; + memcpy(msg-u.tx_can.msg[6], cf-data, cf-can_dlc); + + if (cf-can_id CAN_RTR_FLAG) + msg-u.tx_can.flags |= MSG_FLAG_REMOTE_FRAME; + + for (i = 0; i ARRAY_SIZE(priv-tx_contexts); i++) { + if (priv-tx_contexts[i].echo_index == MAX_TX_URBS) { + context = priv-tx_contexts[i]; + break; + } + } + + if (!context) { + netdev_warn(netdev, cannot find free context\n); + ret = NETDEV_TX_BUSY; + goto releasebuf; + } + + context-priv = priv; + context-echo_index = i; + context-dlc = cf-can_dlc; + + msg-u.tx_can.tid = context-echo_index; + + usb_fill_bulk_urb(urb, dev-udev, + usb_sndbulkpipe(dev-udev, + dev-bulk_out-bEndpointAddress), + buf, msg-len, + kvaser_usb_write_bulk_callback, context); + urb-transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + usb_anchor_urb(urb, priv-tx_submitted); + + can_put_echo_skb(skb, netdev, context-echo_index); + + atomic_inc(priv-active_tx_urbs); + + if (atomic_read(priv-active_tx_urbs) = MAX_TX_URBS) + netif_stop_queue(netdev); + + err = usb_submit_urb(urb, GFP_ATOMIC); + if (unlikely(err)) { + can_free_echo_skb(netdev, context-echo_index); + + atomic_dec(priv-active_tx_urbs); + usb_unanchor_urb(urb); + + stats-tx_dropped++; + + if (err == -ENODEV) + netif_device_detach(netdev); + else + netdev_warn(netdev, Failed tx_urb %d\n, err); + + goto releasebuf; + } + + netdev-trans_start = jiffies; + + usb_free_urb(urb); + + return NETDEV_TX_OK; + +releasebuf: + usb_free_coherent(dev-udev, sizeof(struct kvaser_msg), + buf, urb-transfer_dma); +nobufmem: + usb_free_urb(urb); + return ret; +} +static int kvaser_usb_init_one(struct usb_interface *intf, + const struct usb_device_id *id, int channel) +{ + struct kvaser_usb *dev = usb_get_intfdata(intf); + struct net_device *netdev; + struct kvaser_usb_net_priv *priv; + int i, err; + + netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); + if (!netdev) { +
Re: [PATCH v2] can: kvaser_usb: Add support for Kvaser CAN/USB devices
On Monday 06 August 2012 07:21:29 Olivier Sobrie wrote: This driver provides support for several Kvaser CAN/USB devices. Such kind of devices supports up to three can network interfaces. It has been tested with a Kvaser USB Leaf Light (one network interface) connected to a pch_can interface. The firmware version of the Kvaser device was 2.5.205. +static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, + struct net_device *netdev) +{ + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); + struct kvaser_usb *dev = priv-dev; + struct net_device_stats *stats = netdev-stats; + struct can_frame *cf = (struct can_frame *)skb-data; + struct kvaser_usb_tx_urb_context *context = NULL; + struct urb *urb; + void *buf; + struct kvaser_msg *msg; + int i, err; + int ret = NETDEV_TX_OK; + + if (can_dropped_invalid_skb(netdev, skb)) + return NETDEV_TX_OK; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + netdev_err(netdev, No memory left for URBs\n); + stats-tx_dropped++; + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + buf = usb_alloc_coherent(dev-udev, sizeof(struct kvaser_msg), + GFP_ATOMIC, urb-transfer_dma); usb_alloc_coherent() as a rule only makes sense if you reuse the buffer and in some cases not even then. Please use a simple kmalloc() + if (!buf) { + netdev_err(netdev, No memory left for USB buffer\n); + stats-tx_dropped++; + dev_kfree_skb(skb); + goto nobufmem; + } + + msg = (struct kvaser_msg *)buf; + msg-len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_tx_can); + msg-u.tx_can.flags = 0; + msg-u.tx_can.channel = priv-channel; + + if (cf-can_id CAN_EFF_FLAG) { + msg-id = CMD_TX_EXT_MESSAGE; + msg-u.tx_can.msg[0] = (cf-can_id 24) 0x1f; + msg-u.tx_can.msg[1] = (cf-can_id 18) 0x3f; + msg-u.tx_can.msg[2] = (cf-can_id 14) 0x0f; + msg-u.tx_can.msg[3] = (cf-can_id 6) 0xff; + msg-u.tx_can.msg[4] = cf-can_id 0x3f; + } else { + msg-id = CMD_TX_STD_MESSAGE; + msg-u.tx_can.msg[0] = (cf-can_id 6) 0x1f; + msg-u.tx_can.msg[1] = cf-can_id 0x3f; + } + + msg-u.tx_can.msg[5] = cf-can_dlc; + memcpy(msg-u.tx_can.msg[6], cf-data, cf-can_dlc); + + if (cf-can_id CAN_RTR_FLAG) + msg-u.tx_can.flags |= MSG_FLAG_REMOTE_FRAME; + + for (i = 0; i ARRAY_SIZE(priv-tx_contexts); i++) { + if (priv-tx_contexts[i].echo_index == MAX_TX_URBS) { + context = priv-tx_contexts[i]; + break; + } + } + + if (!context) { + netdev_warn(netdev, cannot find free context\n); + ret = NETDEV_TX_BUSY; + goto releasebuf; + } + + context-priv = priv; + context-echo_index = i; + context-dlc = cf-can_dlc; + + msg-u.tx_can.tid = context-echo_index; + + usb_fill_bulk_urb(urb, dev-udev, + usb_sndbulkpipe(dev-udev, + dev-bulk_out-bEndpointAddress), + buf, msg-len, + kvaser_usb_write_bulk_callback, context); + urb-transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + usb_anchor_urb(urb, priv-tx_submitted); + + can_put_echo_skb(skb, netdev, context-echo_index); + + atomic_inc(priv-active_tx_urbs); + + if (atomic_read(priv-active_tx_urbs) = MAX_TX_URBS) + netif_stop_queue(netdev); + + err = usb_submit_urb(urb, GFP_ATOMIC); + if (unlikely(err)) { + can_free_echo_skb(netdev, context-echo_index); + + atomic_dec(priv-active_tx_urbs); + usb_unanchor_urb(urb); + + stats-tx_dropped++; + + if (err == -ENODEV) + netif_device_detach(netdev); + else + netdev_warn(netdev, Failed tx_urb %d\n, err); + + goto releasebuf; + } + + netdev-trans_start = jiffies; + + usb_free_urb(urb); + + return NETDEV_TX_OK; + +releasebuf: + usb_free_coherent(dev-udev, sizeof(struct kvaser_msg), + buf, urb-transfer_dma); +nobufmem: + usb_free_urb(urb); + return ret; +} +static int kvaser_usb_init_one(struct usb_interface *intf, +const struct usb_device_id *id, int channel) +{ + struct kvaser_usb *dev = usb_get_intfdata(intf); + struct net_device *netdev; + struct kvaser_usb_net_priv *priv; + int i, err; + + netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); + if (!netdev) { + dev_err(intf-dev, Cannot alloc candev\n); + return