Re: [PATCH v2] can: kvaser_usb: Add support for Kvaser CAN/USB devices

2012-08-08 Thread Wolfgang Grandegger
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

2012-08-08 Thread Olivier Sobrie
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

2012-08-08 Thread Wolfgang Grandegger
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

2012-08-07 Thread Wolfgang Grandegger
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

2012-08-07 Thread Olivier Sobrie
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

2012-08-06 Thread Oliver Neukum
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