linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re:  Kvazer USB CAN driver
       [not found] <a8d74bed340445f081325afedf044bb5@AMSPR06MB053.eurprd06.prod.outlook.com>
@ 2014-01-07 14:45 ` Oliver Hartkopp
  2014-01-07 15:15   ` GARNERO, PIERRE (P.)
       [not found] ` <1389107792.5708.9.camel@blackbox>
  1 sibling, 1 reply; 13+ messages in thread
From: Oliver Hartkopp @ 2014-01-07 14:45 UTC (permalink / raw)
  To: GARNERO, PIERRE (P.); +Cc: linux-can@vger.kernel.org

Hello Pierre,

I moved your question to the new linux-can mailing list you should use in future.

On 07.01.2014 15:17, GARNERO, PIERRE (P.) wrote:

> 
> I would like to use a KVAZER USBcan Rugged device with the socketcan library.
> 
> I use Raspbian OS and I have built a kernel with anything enabled regarding CAN.
> 
>  
> 
> I have loaded the following modules:
> 
> # modprobe can
> 
> # modprobe vcan
> 
> # modprobe can-raw
> 
> # modprobe can-dev
> 
> # modprobe kvazer-usb
> 
>  
> 
> But any ip link command (ex: ip link add dev can0 type can) failed with
> “RTNETLINK answer : operation not permitted” (excepted for vcan which works well).

When your modprobe succeeded (and the USB adapter is attached) a can0
interface should have been created by the kvaser-usb driver automatically.

The "ip link add dev can0 type can" is wrong.
You may add virtual CAN devices with this procedure, e.g.
ip link add dev vcan0 type vcan

But you can never create a real CAN interface with the ip tool.

> 
> Could someone provide me some hints regarding the steps to have a Kvaser
> USBcan device up and running using the net driver ?
> 

Once can0 showed up:

e.g. with dmesg | grep can0

or in 

cat /proc/net/dev

You can set the bitrate and set the interface to up afterwards:

http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/networking/can.txt?h=linux-3.12.y#n758

Regards,
Oliver


^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE:  Kvazer USB CAN driver
  2014-01-07 14:45 ` Kvazer USB CAN driver Oliver Hartkopp
@ 2014-01-07 15:15   ` GARNERO, PIERRE (P.)
  0 siblings, 0 replies; 13+ messages in thread
From: GARNERO, PIERRE (P.) @ 2014-01-07 15:15 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: linux-can@vger.kernel.org

Hello Oliver,

Thanks a lot for your answer. I will check if I get a can0 device when modules are loaded.

I will register to this new mailing list. I was a little bit reluctant initially to post on this mailing list because I thought it was reserved for development discussions.

Have a nice day,

Pierre

-----Message d'origine-----
De : Oliver Hartkopp [mailto:socketcan@hartkopp.net] 
Envoyé : mardi 7 janvier 2014 15:46
À : GARNERO, PIERRE (P.)
Cc : linux-can@vger.kernel.org
Objet : Re: Kvazer USB CAN driver

Hello Pierre,

I moved your question to the new linux-can mailing list you should use in future.

On 07.01.2014 15:17, GARNERO, PIERRE (P.) wrote:

> 
> I would like to use a KVAZER USBcan Rugged device with the socketcan library.
> 
> I use Raspbian OS and I have built a kernel with anything enabled regarding CAN.
> 
>  
> 
> I have loaded the following modules:
> 
> # modprobe can
> 
> # modprobe vcan
> 
> # modprobe can-raw
> 
> # modprobe can-dev
> 
> # modprobe kvazer-usb
> 
>  
> 
> But any ip link command (ex: ip link add dev can0 type can) failed 
> with "RTNETLINK answer : operation not permitted" (excepted for vcan which works well).

When your modprobe succeeded (and the USB adapter is attached) a can0 interface should have been created by the kvaser-usb driver automatically.

The "ip link add dev can0 type can" is wrong.
You may add virtual CAN devices with this procedure, e.g.
ip link add dev vcan0 type vcan

But you can never create a real CAN interface with the ip tool.

> 
> Could someone provide me some hints regarding the steps to have a 
> Kvaser USBcan device up and running using the net driver ?
> 

Once can0 showed up:

e.g. with dmesg | grep can0

or in 

cat /proc/net/dev

You can set the bitrate and set the interface to up afterwards:

http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/networking/can.txt?h=linux-3.12.y#n758

Regards,
Oliver


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Kvazer USB CAN driver
       [not found]   ` <85d7d20e09a64996a182e491c6d250e0@AMSPR06MB053.eurprd06.prod.outlook.com>
@ 2014-01-08 21:28     ` Oliver Hartkopp
  2014-01-09  7:12       ` GARNERO, PIERRE (P.)
                         ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Oliver Hartkopp @ 2014-01-08 21:28 UTC (permalink / raw)
  To: GARNERO, PIERRE (P.)
  Cc: linux-can@vger.kernel.org, Olivier Sobrie, Daniel Berglund

Hello Pierre,

what exact kernel version are you using there?

Do you use the Mainline driver that comes with Linux or did you use the Kvaser
driver from http://www.kvaser.com/en/downloads.html ??

Can you provide a crash dump?

I also added the Kvaser authors in CC

Regards,
Oliver

On 07.01.2014 17:46, GARNERO, PIERRE (P.) wrote:
> Hello,
> 
> Thanks for all this information. And, basically the issue is the fact that no can network interface shows up.
> 
> If I boot with the Kvaser device plugged, I could well see it using:
>  Lsusb
> 
> ...but 
>  sudo ip link list
> ...does not reveal any can interface while I have loaded these modules: can, can-raw, can-dev, kvaser-usb.
> ...while dmesg displays "usbcore: registered new interface driver kvaser_usb"...
> 
> In addition, if I hotplug Kvaser device, I get a kernel panic.
> 
> So, I have probably made a mistake when I have built the kernel.
> 
> Cheers,
> 
> Pierre 
> 
>  
> -----Message d'origine-----
> De : socketcan-users-bounces@lists.berlios.de [mailto:socketcan-users-bounces@lists.berlios.de] De la part de Max S.
> Envoyé : mardi 7 janvier 2014 16:17
> À : socketcan-users@lists.berlios.de
> Objet : Re: [Socketcan-users] Beginner question - Kvazer USB CAN driver
> 
> Hello,
> 
> I'm not sure about the kvaser in particular, but the driver should create the network interfaces when the USB device is attached.
> 
> so no need to add a new socketcan device.
> 
> Check to make sure you have kvaser connected:
> 	lsusb
> 
> Check to make sure kvaser driver has made network interfaces:
> 	sudo ip link list
> 
> Then bring the interface up:
> 	sudo ip link set can0 up type can bitrate 250000
> 
> Listen to some frames:
> 	candump can0
> 
> Depending on how you have permissions set up you will require sudo to use most of the ip commands.
> 
> Regards,
> Max Schneider
> 
> On Tue, 2014-01-07 at 14:17 +0000, GARNERO, PIERRE (P.) wrote:
>> Hello.
>>
>>  
>>
>> I would like to use a KVAZER USBcan Rugged device with the socketcan 
>> library.
>>
>> I use Raspbian OS and I have built a kernel with anything enabled 
>> regarding CAN.
>>
>>  
>>
>> I have loaded the following modules:
>>
>> # modprobe can
>>
>> # modprobe vcan
>>
>> # modprobe can-raw
>>
>> # modprobe can-dev
>>
>> # modprobe kvazer-usb
>>
>>  
>>
>> But any ip link command (ex: ip link add dev can0 type can) failed 
>> with “RTNETLINK answer : operation not permitted” (excepted for vcan 
>> which works well).
>>
>>  
>>
>> Could someone provide me some hints regarding the steps to have a 
>> Kvaser USBcan device up and running using the net driver ?
>>
>>  
>>
>> Many thanks in advance,
>>
>>  
>>
>> Pierre
>>
>>  
>>
>>  
>>
>>  
>>
>>  
>>
>>  
>>
>>
>> _______________________________________________
>> Socketcan-users mailing list
>> Socketcan-users@lists.berlios.de
>> https://lists.berlios.de/mailman/listinfo/socketcan-users
> 
> 
> _______________________________________________
> Socketcan-users mailing list
> Socketcan-users@lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/socketcan-users
> _______________________________________________
> Socketcan-users mailing list
> Socketcan-users@lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/socketcan-users
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Kvazer USB CAN driver
  2014-01-08 21:28     ` Oliver Hartkopp
@ 2014-01-09  7:12       ` GARNERO, PIERRE (P.)
  2014-01-09 13:14       ` GARNERO, PIERRE (P.)
  2014-01-13  9:31       ` GARNERO, PIERRE (P.)
  2 siblings, 0 replies; 13+ messages in thread
From: GARNERO, PIERRE (P.) @ 2014-01-09  7:12 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: linux-can@vger.kernel.org, Olivier Sobrie, Daniel Berglund

Hello Oliver,

Thanks for your mail.
I use kernel version 3.10.25+, downloaded from https://github.com/raspberrypi/linux. I have just activated anything regarding CAN support when I have built this kernel (compared to the "oldconfig" settings, where the "oldconfig" configuration comes from the last NOOBS delivery with 3.10.24+ kernel).
I use the driver coming from Linux. I haven't used the driver provided by Kvaser on my Rasperry platform (however, I use the Kvaser driver on a Fedora 17 distrib/classical PC, with Kvaser user space API  and everything works well).
My goal is to use the socket CAN API on Raspbian for my ("midnight") development project. 
I will try to provide a crash dump when I can get the HW again as it is used right now by an "official" Visteon project.

Again, thanks for your help!

Cheers,

Pierre


-----Message d'origine-----
De : Oliver Hartkopp [mailto:socketcan@hartkopp.net] 
Envoyé : mercredi 8 janvier 2014 22:29
À : GARNERO, PIERRE (P.)
Cc : linux-can@vger.kernel.org; Olivier Sobrie; Daniel Berglund
Objet : Re: Kvazer USB CAN driver

Hello Pierre,

what exact kernel version are you using there?

Do you use the Mainline driver that comes with Linux or did you use the Kvaser driver from http://www.kvaser.com/en/downloads.html ??

Can you provide a crash dump?

I also added the Kvaser authors in CC

Regards,
Oliver

On 07.01.2014 17:46, GARNERO, PIERRE (P.) wrote:
> Hello,
> 
> Thanks for all this information. And, basically the issue is the fact that no can network interface shows up.
> 
> If I boot with the Kvaser device plugged, I could well see it using:
>  Lsusb
> 
> ...but
>  sudo ip link list
> ...does not reveal any can interface while I have loaded these modules: can, can-raw, can-dev, kvaser-usb.
> ...while dmesg displays "usbcore: registered new interface driver kvaser_usb"...
> 
> In addition, if I hotplug Kvaser device, I get a kernel panic.
> 
> So, I have probably made a mistake when I have built the kernel.
> 
> Cheers,
> 
> Pierre
> 
>  
> -----Message d'origine-----
> De : socketcan-users-bounces@lists.berlios.de [mailto:socketcan-users-bounces@lists.berlios.de] De la part de Max S.
> Envoyé : mardi 7 janvier 2014 16:17
> À : socketcan-users@lists.berlios.de
> Objet : Re: [Socketcan-users] Beginner question - Kvazer USB CAN 
> driver
> 
> Hello,
> 
> I'm not sure about the kvaser in particular, but the driver should create the network interfaces when the USB device is attached.
> 
> so no need to add a new socketcan device.
> 
> Check to make sure you have kvaser connected:
> 	lsusb
> 
> Check to make sure kvaser driver has made network interfaces:
> 	sudo ip link list
> 
> Then bring the interface up:
> 	sudo ip link set can0 up type can bitrate 250000
> 
> Listen to some frames:
> 	candump can0
> 
> Depending on how you have permissions set up you will require sudo to use most of the ip commands.
> 
> Regards,
> Max Schneider
> 
> On Tue, 2014-01-07 at 14:17 +0000, GARNERO, PIERRE (P.) wrote:
>> Hello.
>>
>>  
>>
>> I would like to use a KVAZER USBcan Rugged device with the socketcan 
>> library.
>>
>> I use Raspbian OS and I have built a kernel with anything enabled 
>> regarding CAN.
>>
>>  
>>
>> I have loaded the following modules:
>>
>> # modprobe can
>>
>> # modprobe vcan
>>
>> # modprobe can-raw
>>
>> # modprobe can-dev
>>
>> # modprobe kvazer-usb
>>
>>  
>>
>> But any ip link command (ex: ip link add dev can0 type can) failed 
>> with “RTNETLINK answer : operation not permitted” (excepted for vcan 
>> which works well).
>>
>>  
>>
>> Could someone provide me some hints regarding the steps to have a 
>> Kvaser USBcan device up and running using the net driver ?
>>
>>  
>>
>> Many thanks in advance,
>>
>>  
>>
>> Pierre
>>
>>  
>>
>>  
>>
>>  
>>
>>  
>>
>>  
>>
>>
>> _______________________________________________
>> Socketcan-users mailing list
>> Socketcan-users@lists.berlios.de
>> https://lists.berlios.de/mailman/listinfo/socketcan-users
> 
> 
> _______________________________________________
> Socketcan-users mailing list
> Socketcan-users@lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/socketcan-users
> _______________________________________________
> Socketcan-users mailing list
> Socketcan-users@lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/socketcan-users
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Kvazer USB CAN driver
  2014-01-08 21:28     ` Oliver Hartkopp
  2014-01-09  7:12       ` GARNERO, PIERRE (P.)
@ 2014-01-09 13:14       ` GARNERO, PIERRE (P.)
  2014-01-13  9:31       ` GARNERO, PIERRE (P.)
  2 siblings, 0 replies; 13+ messages in thread
From: GARNERO, PIERRE (P.) @ 2014-01-09 13:14 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: linux-can@vger.kernel.org, Olivier Sobrie, Daniel Berglund

Hello Olivier,

I finally managed to get a powered USB hub and the kernel panic does not show up anymore.

I could see the Kvaser device using lsusb.
 
However, even with this configuration, I cannot see any can0 interface (after having loaded all the necessary modules).

Cheers,

Pierre

-----Message d'origine-----
De : Oliver Hartkopp [mailto:socketcan@hartkopp.net] 
Envoyé : mercredi 8 janvier 2014 22:29
À : GARNERO, PIERRE (P.)
Cc : linux-can@vger.kernel.org; Olivier Sobrie; Daniel Berglund
Objet : Re: Kvazer USB CAN driver

Hello Pierre,

what exact kernel version are you using there?

Do you use the Mainline driver that comes with Linux or did you use the Kvaser driver from http://www.kvaser.com/en/downloads.html ??

Can you provide a crash dump?

I also added the Kvaser authors in CC

Regards,
Oliver

On 07.01.2014 17:46, GARNERO, PIERRE (P.) wrote:
> Hello,
> 
> Thanks for all this information. And, basically the issue is the fact that no can network interface shows up.
> 
> If I boot with the Kvaser device plugged, I could well see it using:
>  Lsusb
> 
> ...but
>  sudo ip link list
> ...does not reveal any can interface while I have loaded these modules: can, can-raw, can-dev, kvaser-usb.
> ...while dmesg displays "usbcore: registered new interface driver kvaser_usb"...
> 
> In addition, if I hotplug Kvaser device, I get a kernel panic.
> 
> So, I have probably made a mistake when I have built the kernel.
> 
> Cheers,
> 
> Pierre
> 
>  
> -----Message d'origine-----
> De : socketcan-users-bounces@lists.berlios.de [mailto:socketcan-users-bounces@lists.berlios.de] De la part de Max S.
> Envoyé : mardi 7 janvier 2014 16:17
> À : socketcan-users@lists.berlios.de
> Objet : Re: [Socketcan-users] Beginner question - Kvazer USB CAN 
> driver
> 
> Hello,
> 
> I'm not sure about the kvaser in particular, but the driver should create the network interfaces when the USB device is attached.
> 
> so no need to add a new socketcan device.
> 
> Check to make sure you have kvaser connected:
> 	lsusb
> 
> Check to make sure kvaser driver has made network interfaces:
> 	sudo ip link list
> 
> Then bring the interface up:
> 	sudo ip link set can0 up type can bitrate 250000
> 
> Listen to some frames:
> 	candump can0
> 
> Depending on how you have permissions set up you will require sudo to use most of the ip commands.
> 
> Regards,
> Max Schneider
> 
> On Tue, 2014-01-07 at 14:17 +0000, GARNERO, PIERRE (P.) wrote:
>> Hello.
>>
>>  
>>
>> I would like to use a KVAZER USBcan Rugged device with the socketcan 
>> library.
>>
>> I use Raspbian OS and I have built a kernel with anything enabled 
>> regarding CAN.
>>
>>  
>>
>> I have loaded the following modules:
>>
>> # modprobe can
>>
>> # modprobe vcan
>>
>> # modprobe can-raw
>>
>> # modprobe can-dev
>>
>> # modprobe kvazer-usb
>>
>>  
>>
>> But any ip link command (ex: ip link add dev can0 type can) failed 
>> with “RTNETLINK answer : operation not permitted” (excepted for vcan 
>> which works well).
>>
>>  
>>
>> Could someone provide me some hints regarding the steps to have a 
>> Kvaser USBcan device up and running using the net driver ?
>>
>>  
>>
>> Many thanks in advance,
>>
>>  
>>
>> Pierre
>>
>>  
>>
>>  
>>
>>  
>>
>>  
>>
>>  
>>
>>
>> _______________________________________________
>> Socketcan-users mailing list
>> Socketcan-users@lists.berlios.de
>> https://lists.berlios.de/mailman/listinfo/socketcan-users
> 
> 
> _______________________________________________
> Socketcan-users mailing list
> Socketcan-users@lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/socketcan-users
> _______________________________________________
> Socketcan-users mailing list
> Socketcan-users@lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/socketcan-users
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Kvazer USB CAN driver
  2014-01-08 21:28     ` Oliver Hartkopp
  2014-01-09  7:12       ` GARNERO, PIERRE (P.)
  2014-01-09 13:14       ` GARNERO, PIERRE (P.)
@ 2014-01-13  9:31       ` GARNERO, PIERRE (P.)
  2014-01-16 11:02         ` Olivier Sobrie
  2 siblings, 1 reply; 13+ messages in thread
From: GARNERO, PIERRE (P.) @ 2014-01-13  9:31 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: linux-can@vger.kernel.org, Olivier Sobrie, Daniel Berglund

Hello Olivier,

I think I understand why this is not working.

I have looked at the Kvaser drivers on USB and, basically, there are 2 big families:
•	Leaf
•	USBII

As far as I understand the current netdriver implements the Leaf family only.

I could see that all USB “product ids” are well identical than the one defined in Kvaser leaf driver. However usbII devices with product ids 2,3,4,5 are not present.
Effectivelly, le product id tied to my kvaser usbcan Rugged device is "2".

I have tried to look at the differences (from kvaser driver sources) and there a lot of discrepencies between the leaf usb commands and the usbcan2 (helios?)  usb commands. So, supporting this device should not be an easy task....


Cheers,

Pierre

-----Message d'origine-----
De : Oliver Hartkopp [mailto:socketcan@hartkopp.net] 
Envoyé : mercredi 8 janvier 2014 22:29
À : GARNERO, PIERRE (P.)
Cc : linux-can@vger.kernel.org; Olivier Sobrie; Daniel Berglund
Objet : Re: Kvazer USB CAN driver

Hello Pierre,

what exact kernel version are you using there?

Do you use the Mainline driver that comes with Linux or did you use the Kvaser driver from http://www.kvaser.com/en/downloads.html ??

Can you provide a crash dump?

I also added the Kvaser authors in CC

Regards,
Oliver

On 07.01.2014 17:46, GARNERO, PIERRE (P.) wrote:
> Hello,
> 
> Thanks for all this information. And, basically the issue is the fact that no can network interface shows up.
> 
> If I boot with the Kvaser device plugged, I could well see it using:
>  Lsusb
> 
> ...but
>  sudo ip link list
> ...does not reveal any can interface while I have loaded these modules: can, can-raw, can-dev, kvaser-usb.
> ...while dmesg displays "usbcore: registered new interface driver kvaser_usb"...
> 
> In addition, if I hotplug Kvaser device, I get a kernel panic.
> 
> So, I have probably made a mistake when I have built the kernel.
> 
> Cheers,
> 
> Pierre
> 
>  
> -----Message d'origine-----
> De : socketcan-users-bounces@lists.berlios.de [mailto:socketcan-users-bounces@lists.berlios.de] De la part de Max S.
> Envoyé : mardi 7 janvier 2014 16:17
> À : socketcan-users@lists.berlios.de
> Objet : Re: [Socketcan-users] Beginner question - Kvazer USB CAN 
> driver
> 
> Hello,
> 
> I'm not sure about the kvaser in particular, but the driver should create the network interfaces when the USB device is attached.
> 
> so no need to add a new socketcan device.
> 
> Check to make sure you have kvaser connected:
> 	lsusb
> 
> Check to make sure kvaser driver has made network interfaces:
> 	sudo ip link list
> 
> Then bring the interface up:
> 	sudo ip link set can0 up type can bitrate 250000
> 
> Listen to some frames:
> 	candump can0
> 
> Depending on how you have permissions set up you will require sudo to use most of the ip commands.
> 
> Regards,
> Max Schneider
> 
> On Tue, 2014-01-07 at 14:17 +0000, GARNERO, PIERRE (P.) wrote:
>> Hello.
>>
>>  
>>
>> I would like to use a KVAZER USBcan Rugged device with the socketcan 
>> library.
>>
>> I use Raspbian OS and I have built a kernel with anything enabled 
>> regarding CAN.
>>
>>  
>>
>> I have loaded the following modules:
>>
>> # modprobe can
>>
>> # modprobe vcan
>>
>> # modprobe can-raw
>>
>> # modprobe can-dev
>>
>> # modprobe kvazer-usb
>>
>>  
>>
>> But any ip link command (ex: ip link add dev can0 type can) failed 
>> with “RTNETLINK answer : operation not permitted” (excepted for vcan 
>> which works well).
>>
>>  
>>
>> Could someone provide me some hints regarding the steps to have a 
>> Kvaser USBcan device up and running using the net driver ?
>>
>>  
>>
>> Many thanks in advance,
>>
>>  
>>
>> Pierre
>>
>>  
>>
>>  
>>
>>  
>>
>>  
>>
>>  
>>
>>
>> _______________________________________________
>> Socketcan-users mailing list
>> Socketcan-users@lists.berlios.de
>> https://lists.berlios.de/mailman/listinfo/socketcan-users
> 
> 
> _______________________________________________
> Socketcan-users mailing list
> Socketcan-users@lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/socketcan-users
> _______________________________________________
> Socketcan-users mailing list
> Socketcan-users@lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/socketcan-users
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Kvazer USB CAN driver
  2014-01-13  9:31       ` GARNERO, PIERRE (P.)
@ 2014-01-16 11:02         ` Olivier Sobrie
  2014-01-16 12:55           ` GARNERO, PIERRE (P.)
  2014-01-17  9:36           ` GARNERO, PIERRE (P.)
  0 siblings, 2 replies; 13+ messages in thread
From: Olivier Sobrie @ 2014-01-16 11:02 UTC (permalink / raw)
  To: GARNERO, PIERRE (P.)
  Cc: Oliver Hartkopp, linux-can@vger.kernel.org, Daniel Berglund

Hello Pierre,

Sorry I didn't see your previous mails...

On Mon, Jan 13, 2014 at 09:31:55AM +0000, GARNERO, PIERRE (P.) wrote:
> Hello Olivier,
> 
> I think I understand why this is not working.
> 
> I have looked at the Kvaser drivers on USB and, basically, there are 2 big families:
> •	Leaf
> •	USBII
> 
> As far as I understand the current netdriver implements the Leaf family only.

Indeed.

> 
> I could see that all USB “product ids” are well identical than the one defined in Kvaser leaf driver. However usbII devices with product ids 2,3,4,5 are not present.
> Effectivelly, le product id tied to my kvaser usbcan Rugged device is "2".

If so, I wonder how you get the kernel panic you mentionned in a previous
mail? I would be interrested in seeing where it crashes.

> 
> I have tried to look at the differences (from kvaser driver sources) and there a lot of discrepencies between the leaf usb commands and the usbcan2 (helios?)  usb commands. So, supporting this device should not be an easy task....

Indeed the commands sent to hardware looks to be different.
I'll have a look once I found some time...

Kr,

Olivier

> 
> 
> Cheers,
> 
> Pierre
> 
> -----Message d'origine-----
> De : Oliver Hartkopp [mailto:socketcan@hartkopp.net] 
> Envoyé : mercredi 8 janvier 2014 22:29
> À : GARNERO, PIERRE (P.)
> Cc : linux-can@vger.kernel.org; Olivier Sobrie; Daniel Berglund
> Objet : Re: Kvazer USB CAN driver
> 
> Hello Pierre,
> 
> what exact kernel version are you using there?
> 
> Do you use the Mainline driver that comes with Linux or did you use the Kvaser driver from http://www.kvaser.com/en/downloads.html ??
> 
> Can you provide a crash dump?
> 
> I also added the Kvaser authors in CC
> 
> Regards,
> Oliver
> 
> On 07.01.2014 17:46, GARNERO, PIERRE (P.) wrote:
> > Hello,
> > 
> > Thanks for all this information. And, basically the issue is the fact that no can network interface shows up.
> > 
> > If I boot with the Kvaser device plugged, I could well see it using:
> >  Lsusb
> > 
> > ...but
> >  sudo ip link list
> > ...does not reveal any can interface while I have loaded these modules: can, can-raw, can-dev, kvaser-usb.
> > ...while dmesg displays "usbcore: registered new interface driver kvaser_usb"...
> > 
> > In addition, if I hotplug Kvaser device, I get a kernel panic.
> > 
> > So, I have probably made a mistake when I have built the kernel.
> > 
> > Cheers,
> > 
> > Pierre
> > 
> >  
> > -----Message d'origine-----
> > De : socketcan-users-bounces@lists.berlios.de [mailto:socketcan-users-bounces@lists.berlios.de] De la part de Max S.
> > Envoyé : mardi 7 janvier 2014 16:17
> > À : socketcan-users@lists.berlios.de
> > Objet : Re: [Socketcan-users] Beginner question - Kvazer USB CAN 
> > driver
> > 
> > Hello,
> > 
> > I'm not sure about the kvaser in particular, but the driver should create the network interfaces when the USB device is attached.
> > 
> > so no need to add a new socketcan device.
> > 
> > Check to make sure you have kvaser connected:
> > 	lsusb
> > 
> > Check to make sure kvaser driver has made network interfaces:
> > 	sudo ip link list
> > 
> > Then bring the interface up:
> > 	sudo ip link set can0 up type can bitrate 250000
> > 
> > Listen to some frames:
> > 	candump can0
> > 
> > Depending on how you have permissions set up you will require sudo to use most of the ip commands.
> > 
> > Regards,
> > Max Schneider
> > 
> > On Tue, 2014-01-07 at 14:17 +0000, GARNERO, PIERRE (P.) wrote:
> >> Hello.
> >>
> >>  
> >>
> >> I would like to use a KVAZER USBcan Rugged device with the socketcan 
> >> library.
> >>
> >> I use Raspbian OS and I have built a kernel with anything enabled 
> >> regarding CAN.
> >>
> >>  
> >>
> >> I have loaded the following modules:
> >>
> >> # modprobe can
> >>
> >> # modprobe vcan
> >>
> >> # modprobe can-raw
> >>
> >> # modprobe can-dev
> >>
> >> # modprobe kvazer-usb
> >>
> >>  
> >>
> >> But any ip link command (ex: ip link add dev can0 type can) failed 
> >> with “RTNETLINK answer : operation not permitted” (excepted for vcan 
> >> which works well).
> >>
> >>  
> >>
> >> Could someone provide me some hints regarding the steps to have a 
> >> Kvaser USBcan device up and running using the net driver ?
> >>
> >>  
> >>
> >> Many thanks in advance,
> >>
> >>  
> >>
> >> Pierre
> >>
> >>  
> >>
> >>  
> >>
> >>  
> >>
> >>  
> >>
> >>  
> >>
> >>
> >> _______________________________________________
> >> Socketcan-users mailing list
> >> Socketcan-users@lists.berlios.de
> >> https://lists.berlios.de/mailman/listinfo/socketcan-users
> > 
> > 
> > _______________________________________________
> > Socketcan-users mailing list
> > Socketcan-users@lists.berlios.de
> > https://lists.berlios.de/mailman/listinfo/socketcan-users
> > _______________________________________________
> > Socketcan-users mailing list
> > Socketcan-users@lists.berlios.de
> > https://lists.berlios.de/mailman/listinfo/socketcan-users
> > 

-- 
Olivier

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Kvazer USB CAN driver
  2014-01-16 11:02         ` Olivier Sobrie
@ 2014-01-16 12:55           ` GARNERO, PIERRE (P.)
  2014-01-17  9:36           ` GARNERO, PIERRE (P.)
  1 sibling, 0 replies; 13+ messages in thread
From: GARNERO, PIERRE (P.) @ 2014-01-16 12:55 UTC (permalink / raw)
  To: Olivier Sobrie
  Cc: Oliver Hartkopp, linux-can@vger.kernel.org, Daniel Berglund

Hello Olivier,

I don't have access the Raspberry hw so I cannot get the kernel panic dump soon. But of course I will provide it when possible.
I have modified a little bit the kvaser_usb.c source to be able to detect the canUSB HW, so I have seen a can0 device on Raspberry.
So again, due to the fact that I do not have the Raspberry HW, I am going to make some tests on a x86 platform with Fedora. It will be easier to troubleshoot it.
I will let you know the result.

Cheers,

Pierre

-----Message d'origine-----
De : Olivier Sobrie [mailto:olivier.sobrie@gmail.com] De la part de Olivier Sobrie
Envoyé : jeudi 16 janvier 2014 12:02
À : GARNERO, PIERRE (P.)
Cc : Oliver Hartkopp; linux-can@vger.kernel.org; Daniel Berglund
Objet : Re: Kvazer USB CAN driver

Hello Pierre,

Sorry I didn't see your previous mails...

On Mon, Jan 13, 2014 at 09:31:55AM +0000, GARNERO, PIERRE (P.) wrote:
> Hello Olivier,
> 
> I think I understand why this is not working.
> 
> I have looked at the Kvaser drivers on USB and, basically, there are 2 big families:
> •	Leaf
> •	USBII
> 
> As far as I understand the current netdriver implements the Leaf family only.

Indeed.

> 
> I could see that all USB “product ids” are well identical than the one defined in Kvaser leaf driver. However usbII devices with product ids 2,3,4,5 are not present.
> Effectivelly, le product id tied to my kvaser usbcan Rugged device is "2".

If so, I wonder how you get the kernel panic you mentionned in a previous mail? I would be interrested in seeing where it crashes.

> 
> I have tried to look at the differences (from kvaser driver sources) and there a lot of discrepencies between the leaf usb commands and the usbcan2 (helios?)  usb commands. So, supporting this device should not be an easy task....

Indeed the commands sent to hardware looks to be different.
I'll have a look once I found some time...

Kr,

Olivier

> 
> 
> Cheers,
> 
> Pierre
> 
> -----Message d'origine-----
> De : Oliver Hartkopp [mailto:socketcan@hartkopp.net] Envoyé : mercredi 
> 8 janvier 2014 22:29 À : GARNERO, PIERRE (P.) Cc : 
> linux-can@vger.kernel.org; Olivier Sobrie; Daniel Berglund Objet : Re: 
> Kvazer USB CAN driver
> 
> Hello Pierre,
> 
> what exact kernel version are you using there?
> 
> Do you use the Mainline driver that comes with Linux or did you use the Kvaser driver from http://www.kvaser.com/en/downloads.html ??
> 
> Can you provide a crash dump?
> 
> I also added the Kvaser authors in CC
> 
> Regards,
> Oliver
> 
> On 07.01.2014 17:46, GARNERO, PIERRE (P.) wrote:
> > Hello,
> > 
> > Thanks for all this information. And, basically the issue is the fact that no can network interface shows up.
> > 
> > If I boot with the Kvaser device plugged, I could well see it using:
> >  Lsusb
> > 
> > ...but
> >  sudo ip link list
> > ...does not reveal any can interface while I have loaded these modules: can, can-raw, can-dev, kvaser-usb.
> > ...while dmesg displays "usbcore: registered new interface driver kvaser_usb"...
> > 
> > In addition, if I hotplug Kvaser device, I get a kernel panic.
> > 
> > So, I have probably made a mistake when I have built the kernel.
> > 
> > Cheers,
> > 
> > Pierre
> > 
> >  
> > -----Message d'origine-----
> > De : socketcan-users-bounces@lists.berlios.de [mailto:socketcan-users-bounces@lists.berlios.de] De la part de Max S.
> > Envoyé : mardi 7 janvier 2014 16:17
> > À : socketcan-users@lists.berlios.de Objet : Re: [Socketcan-users] 
> > Beginner question - Kvazer USB CAN driver
> > 
> > Hello,
> > 
> > I'm not sure about the kvaser in particular, but the driver should create the network interfaces when the USB device is attached.
> > 
> > so no need to add a new socketcan device.
> > 
> > Check to make sure you have kvaser connected:
> > 	lsusb
> > 
> > Check to make sure kvaser driver has made network interfaces:
> > 	sudo ip link list
> > 
> > Then bring the interface up:
> > 	sudo ip link set can0 up type can bitrate 250000
> > 
> > Listen to some frames:
> > 	candump can0
> > 
> > Depending on how you have permissions set up you will require sudo to use most of the ip commands.
> > 
> > Regards,
> > Max Schneider
> > 
> > On Tue, 2014-01-07 at 14:17 +0000, GARNERO, PIERRE (P.) wrote:
> >> Hello.
> >>
> >>  
> >>
> >> I would like to use a KVAZER USBcan Rugged device with the 
> >> socketcan library.
> >>
> >> I use Raspbian OS and I have built a kernel with anything enabled 
> >> regarding CAN.
> >>
> >>  
> >>
> >> I have loaded the following modules:
> >>
> >> # modprobe can
> >>
> >> # modprobe vcan
> >>
> >> # modprobe can-raw
> >>
> >> # modprobe can-dev
> >>
> >> # modprobe kvazer-usb
> >>
> >>  
> >>
> >> But any ip link command (ex: ip link add dev can0 type can) failed 
> >> with “RTNETLINK answer : operation not permitted” (excepted for 
> >> vcan which works well).
> >>
> >>  
> >>
> >> Could someone provide me some hints regarding the steps to have a 
> >> Kvaser USBcan device up and running using the net driver ?
> >>
> >>  
> >>
> >> Many thanks in advance,
> >>
> >>  
> >>
> >> Pierre
> >>
> >>  
> >>
> >>  
> >>
> >>  
> >>
> >>  
> >>
> >>  
> >>
> >>
> >> _______________________________________________
> >> Socketcan-users mailing list
> >> Socketcan-users@lists.berlios.de
> >> https://lists.berlios.de/mailman/listinfo/socketcan-users
> > 
> > 
> > _______________________________________________
> > Socketcan-users mailing list
> > Socketcan-users@lists.berlios.de
> > https://lists.berlios.de/mailman/listinfo/socketcan-users
> > _______________________________________________
> > Socketcan-users mailing list
> > Socketcan-users@lists.berlios.de
> > https://lists.berlios.de/mailman/listinfo/socketcan-users
> > 

--
Olivier

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Kvazer USB CAN driver
  2014-01-16 11:02         ` Olivier Sobrie
  2014-01-16 12:55           ` GARNERO, PIERRE (P.)
@ 2014-01-17  9:36           ` GARNERO, PIERRE (P.)
  2014-01-17  9:50             ` Marc Kleine-Budde
  1 sibling, 1 reply; 13+ messages in thread
From: GARNERO, PIERRE (P.) @ 2014-01-17  9:36 UTC (permalink / raw)
  To: Olivier Sobrie
  Cc: Oliver Hartkopp, linux-can@vger.kernel.org, Daniel Berglund

[-- Attachment #1: Type: text/plain, Size: 6416 bytes --]

Hello Olivier,

I have been able to test my modification of kvaser_usb.c file on Fedora 17/x86 (see attachment).
This module is able to read CAN messages coming from a Kvaser canUSB Rugged device (which is enough for my goal). 

Cheers,

Pierre

-----Message d'origine-----
De : GARNERO, PIERRE (P.) 
Envoyé : jeudi 16 janvier 2014 13:56
À : 'Olivier Sobrie'
Cc : Oliver Hartkopp; linux-can@vger.kernel.org; Daniel Berglund
Objet : RE: Kvazer USB CAN driver

Hello Olivier,

I don't have access the Raspberry hw so I cannot get the kernel panic dump soon. But of course I will provide it when possible.
I have modified a little bit the kvaser_usb.c source to be able to detect the canUSB HW, so I have seen a can0 device on Raspberry.
So again, due to the fact that I do not have the Raspberry HW, I am going to make some tests on a x86 platform with Fedora. It will be easier to troubleshoot it.
I will let you know the result.

Cheers,

Pierre

-----Message d'origine-----
De : Olivier Sobrie [mailto:olivier.sobrie@gmail.com] De la part de Olivier Sobrie Envoyé : jeudi 16 janvier 2014 12:02 À : GARNERO, PIERRE (P.) Cc : Oliver Hartkopp; linux-can@vger.kernel.org; Daniel Berglund Objet : Re: Kvazer USB CAN driver

Hello Pierre,

Sorry I didn't see your previous mails...

On Mon, Jan 13, 2014 at 09:31:55AM +0000, GARNERO, PIERRE (P.) wrote:
> Hello Olivier,
> 
> I think I understand why this is not working.
> 
> I have looked at the Kvaser drivers on USB and, basically, there are 2 big families:
> •	Leaf
> •	USBII
> 
> As far as I understand the current netdriver implements the Leaf family only.

Indeed.

> 
> I could see that all USB “product ids” are well identical than the one defined in Kvaser leaf driver. However usbII devices with product ids 2,3,4,5 are not present.
> Effectivelly, le product id tied to my kvaser usbcan Rugged device is "2".

If so, I wonder how you get the kernel panic you mentionned in a previous mail? I would be interrested in seeing where it crashes.

> 
> I have tried to look at the differences (from kvaser driver sources) and there a lot of discrepencies between the leaf usb commands and the usbcan2 (helios?)  usb commands. So, supporting this device should not be an easy task....

Indeed the commands sent to hardware looks to be different.
I'll have a look once I found some time...

Kr,

Olivier

> 
> 
> Cheers,
> 
> Pierre
> 
> -----Message d'origine-----
> De : Oliver Hartkopp [mailto:socketcan@hartkopp.net] Envoyé : mercredi
> 8 janvier 2014 22:29 À : GARNERO, PIERRE (P.) Cc : 
> linux-can@vger.kernel.org; Olivier Sobrie; Daniel Berglund Objet : Re: 
> Kvazer USB CAN driver
> 
> Hello Pierre,
> 
> what exact kernel version are you using there?
> 
> Do you use the Mainline driver that comes with Linux or did you use the Kvaser driver from http://www.kvaser.com/en/downloads.html ??
> 
> Can you provide a crash dump?
> 
> I also added the Kvaser authors in CC
> 
> Regards,
> Oliver
> 
> On 07.01.2014 17:46, GARNERO, PIERRE (P.) wrote:
> > Hello,
> > 
> > Thanks for all this information. And, basically the issue is the fact that no can network interface shows up.
> > 
> > If I boot with the Kvaser device plugged, I could well see it using:
> >  Lsusb
> > 
> > ...but
> >  sudo ip link list
> > ...does not reveal any can interface while I have loaded these modules: can, can-raw, can-dev, kvaser-usb.
> > ...while dmesg displays "usbcore: registered new interface driver kvaser_usb"...
> > 
> > In addition, if I hotplug Kvaser device, I get a kernel panic.
> > 
> > So, I have probably made a mistake when I have built the kernel.
> > 
> > Cheers,
> > 
> > Pierre
> > 
> >  
> > -----Message d'origine-----
> > De : socketcan-users-bounces@lists.berlios.de [mailto:socketcan-users-bounces@lists.berlios.de] De la part de Max S.
> > Envoyé : mardi 7 janvier 2014 16:17
> > À : socketcan-users@lists.berlios.de Objet : Re: [Socketcan-users] 
> > Beginner question - Kvazer USB CAN driver
> > 
> > Hello,
> > 
> > I'm not sure about the kvaser in particular, but the driver should create the network interfaces when the USB device is attached.
> > 
> > so no need to add a new socketcan device.
> > 
> > Check to make sure you have kvaser connected:
> > 	lsusb
> > 
> > Check to make sure kvaser driver has made network interfaces:
> > 	sudo ip link list
> > 
> > Then bring the interface up:
> > 	sudo ip link set can0 up type can bitrate 250000
> > 
> > Listen to some frames:
> > 	candump can0
> > 
> > Depending on how you have permissions set up you will require sudo to use most of the ip commands.
> > 
> > Regards,
> > Max Schneider
> > 
> > On Tue, 2014-01-07 at 14:17 +0000, GARNERO, PIERRE (P.) wrote:
> >> Hello.
> >>
> >>  
> >>
> >> I would like to use a KVAZER USBcan Rugged device with the 
> >> socketcan library.
> >>
> >> I use Raspbian OS and I have built a kernel with anything enabled 
> >> regarding CAN.
> >>
> >>  
> >>
> >> I have loaded the following modules:
> >>
> >> # modprobe can
> >>
> >> # modprobe vcan
> >>
> >> # modprobe can-raw
> >>
> >> # modprobe can-dev
> >>
> >> # modprobe kvazer-usb
> >>
> >>  
> >>
> >> But any ip link command (ex: ip link add dev can0 type can) failed 
> >> with “RTNETLINK answer : operation not permitted” (excepted for 
> >> vcan which works well).
> >>
> >>  
> >>
> >> Could someone provide me some hints regarding the steps to have a 
> >> Kvaser USBcan device up and running using the net driver ?
> >>
> >>  
> >>
> >> Many thanks in advance,
> >>
> >>  
> >>
> >> Pierre
> >>
> >>  
> >>
> >>  
> >>
> >>  
> >>
> >>  
> >>
> >>  
> >>
> >>
> >> _______________________________________________
> >> Socketcan-users mailing list
> >> Socketcan-users@lists.berlios.de
> >> https://lists.berlios.de/mailman/listinfo/socketcan-users
> > 
> > 
> > _______________________________________________
> > Socketcan-users mailing list
> > Socketcan-users@lists.berlios.de
> > https://lists.berlios.de/mailman/listinfo/socketcan-users
> > _______________________________________________
> > Socketcan-users mailing list
> > Socketcan-users@lists.berlios.de
> > https://lists.berlios.de/mailman/listinfo/socketcan-users
> > 

--
Olivier

[-- Attachment #2: kvaser_usb2.c --]
[-- Type: text/plain, Size: 39659 bytes --]

/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * Parts of this driver are based on the following:
 *  - Kvaser linux leaf driver (version 4.78)
 *  - Kvaser linux USBcanII driver (version 5.2.0)
 *  - CAN driver for esd CAN-USB/2
 *
 * Copyright (C) 2002-2006 KVASER AB, Sweden. All rights reserved.
 * Copyright (C) 2010 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh
 * Copyright (C) 2012 Olivier Sobrie <olivier@sobrie.be>
 * Copyright (C) 2013 Pierre Garnero <pierre.garnero@villamicro.fr>
 */

#include <linux/init.h>
#include <linux/completion.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/usb.h>

#include <linux/can.h>
#include <linux/can/dev.h>
#include <linux/can/error.h>

#define MAX_TX_URBS			16
#define MAX_RX_URBS			4
#define START_TIMEOUT			1000 /* msecs */
#define STOP_TIMEOUT			1000 /* msecs */
#define USB_SEND_TIMEOUT		1000 /* msecs */
#define USB_RECV_TIMEOUT		1000 /* msecs */
#define RX_BUFFER_SIZE			3072
#define CAN_USB_CLOCK			8000000
#define MAX_NET_DEVICES			3

/* Kvaser USB devices */
#define KVASER_VENDOR_ID		0x0bfd
#define USB_USBCAN2_PRODUCT_ID		0x0004	
#define USB_USBCAN_REVB_PRODUCT_ID 	0x0002	
#define USB_MEMORATOR_PRODUCT_ID	0x0005	
#define USB_VCI2_PRODUCT_ID	 	0x0003	

/* USB devices features */
#define KVASER_HAS_SILENT_MODE		BIT(0)
#define KVASER_HAS_TXRX_ERRORS		BIT(1)

/* Message header size */
#define MSG_HEADER_LEN			2

/* Can message flags */
#define MSG_FLAG_ERROR_FRAME		BIT(0)
#define MSG_FLAG_OVERRUN		BIT(1)
#define MSG_FLAG_NERR			BIT(2)
#define MSG_FLAG_WAKEUP			BIT(3)
#define MSG_FLAG_REMOTE_FRAME		BIT(4)
#define MSG_FLAG_RESERVED		BIT(5)
#define MSG_FLAG_TX_ACK			BIT(6)
#define MSG_FLAG_TX_REQUEST		BIT(7)

/* Can states */
#define M16C_STATE_BUS_RESET		BIT(0)
#define M16C_STATE_BUS_ERROR		BIT(4)
#define M16C_STATE_BUS_PASSIVE		BIT(5)
#define M16C_STATE_BUS_OFF		BIT(6)

/* Can msg ids */
#define CMD_RX_STD_MESSAGE		12
#define CMD_TX_STD_MESSAGE		13
#define CMD_RX_EXT_MESSAGE		14
#define CMD_TX_EXT_MESSAGE		15
#define CMD_SET_BUS_PARAMS		16
#define CMD_GET_BUS_PARAMS		17
#define CMD_GET_BUS_PARAMS_REPLY	18
#define CMD_GET_CHIP_STATE		19
#define CMD_CHIP_STATE_EVENT		20
#define CMD_SET_CTRL_MODE		21
#define CMD_GET_CTRL_MODE		22
#define CMD_GET_CTRL_MODE_REPLY		23
#define CMD_RESET_CHIP			24
#define CMD_RESET_CARD			25
#define CMD_START_CHIP			26
#define CMD_START_CHIP_REPLY		27
#define CMD_STOP_CHIP			28
#define CMD_STOP_CHIP_REPLY		29
#define CMD_RESET_CLOCK			32
#define CMD_CLOCK_OVERFLOW_EVENT	33
#define CMD_GET_CARD_INFO		34
#define CMD_GET_CARD_INFO_REPLY		35
#define CMD_GET_SOFTWARE_INFO		38
#define CMD_GET_SOFTWARE_INFO_REPLY	39
#define CMD_ERROR_EVENT			45
#define CMD_FLUSH_QUEUE			48
#define CMD_RESET_ERROR_COUNTER		49
#define CMD_TX_ACKNOWLEDGE		50
#define CMD_CAN_ERROR_EVENT		51
#define CMD_MEMO_WRITE_SECTOR_REQ                    52
#define CMD_MEMO_WRITE_SECTOR_RESP                   53
#define CMD_MEMO_ERASE_SECTOR_REQ                    54
#define CMD_MEMO_WRITE_CONFIG_REQ                    55
#define CMD_MEMO_WRITE_CONFIG_RESP                   56
#define CMD_MEMO_READ_CONFIG_REQ                     57
#define CMD_MEMO_READ_CONFIG_RESP                    58
#define CMD_MEMO_ERASE_SECTOR_RESP                   59
#define CMD_TX_REQUEST                               60
#define CMD_SET_HEARTBEAT_RATE_REQ                   61
#define CMD_HEARTBEAT_RESP                           62
#define CMD_SET_AUTO_TX_BUFFER                       63
#define CMD_MEMO_GET_FILESYSTEM_INFO_STRUCT_REQ      64
#define CMD_MEMO_GET_FILESYSTEM_INFO_STRUCT_RESP     65
#define CMD_MEMO_GET_DISK_INFO_STRUCT_REQ            66
#define CMD_MEMO_GET_DISK_INFO_STRUCT_RESP           67
#define CMD_MEMO_GET_DISK_HW_INFO_STRUCT_REQ         68
#define CMD_MEMO_GET_DISK_HW_INFO_STRUCT_RESP        69
#define CMD_MEMO_FORMAT_DISK_REQ                     70
#define CMD_MEMO_FORMAT_DISK_RESP                    71
#define CMD_AUTO_TX_BUFFER_REQ                       72
#define CMD_AUTO_TX_BUFFER_RESP                      73
#define CMD_SET_TRANSCEIVER_MODE_REQ                 74
#define CMD_MEMO_GET_RTC_REQ                         82
#define CMD_MEMO_GET_RTC_RESP                        83
#define CMD_MEMO_SET_RTC_REQ                         84
#define CMD_MEMO_SET_RTC_RESP                        85
#define CMD_SET_IO_PORTS_REQ                         86
#define CMD_GET_IO_PORTS_REQ                         87
#define CMD_GET_IO_PORTS_RESP                        88
#define CMD_MEMO_READ_SECTOR_REQ                     89
#define CMD_MEMO_READ_SECTOR_RESP                    90
#define CMD_READ_UFILE_REQ                           91
#define CMD_READ_UFILE_RESP                          92
#define CMD_WRITE_UFILE_REQ                          93
#define CMD_WRITE_UFILE_RESP                         94
#define CMD_FORMAT_UFILES_REQ                        95
#define CMD_FORMAT_UFILES_RESP                       96
#define CMD_GET_TRANSCEIVER_INFO_REQ                 97
#define CMD_GET_TRANSCEIVER_INFO_RESP                98
#define CMD_MEMO_CONFIG_MODE_REQ                     99
#define CMD_MEMO_CONFIG_MODE_RESP                   100
#define CMD_LED_ACTION_REQ                          101
#define CMD_LED_ACTION_RESP                         102

/* error factors */
#define M16C_EF_ACKE			BIT(0)
#define M16C_EF_CRCE			BIT(1)
#define M16C_EF_FORME			BIT(2)
#define M16C_EF_STFE			BIT(3)
#define M16C_EF_BITE0			BIT(4)
#define M16C_EF_BITE1			BIT(5)
#define M16C_EF_RCVE			BIT(6)
#define M16C_EF_TRE			BIT(7)

/* bittiming parameters */
#define KVASER_USB_TSEG1_MIN		1
#define KVASER_USB_TSEG1_MAX		16
#define KVASER_USB_TSEG2_MIN		1
#define KVASER_USB_TSEG2_MAX		8
#define KVASER_USB_SJW_MAX		4
#define KVASER_USB_BRP_MIN		1
#define KVASER_USB_BRP_MAX		64
#define KVASER_USB_BRP_INC		1

/* ctrl modes */
#define KVASER_CTRL_MODE_NORMAL		1
#define KVASER_CTRL_MODE_SILENT		2
#define KVASER_CTRL_MODE_SELFRECEPTION	3
#define KVASER_CTRL_MODE_OFF		4

/* log message */
#define KVASER_EXTENDED_FRAME		BIT(31)

struct kvaser_msg_simple {
	u8 tid;
	u8 channel;
} __packed;

struct kvaser_msg_cardinfo {
	u8 tid;
	u8 nchannels;
	__le32 serial_number_low;
	__le32 serial_number_high;
	__le32 clock_resolution;
	__le32 mfgdate;
	u8 ean[8];
	u8 hw_revision;
	u8 padding[3];
} __packed;

struct kvaser_msg_softinfo {
	u8 tid;
	u8 application_name[5];
	__le16 max_outstanding_tx;
	__le16 padding[3];
	__le32 application_version;
	__le16 checksum;
	__le16 sw_options;
} __packed;

struct kvaser_msg_busparams {
	u8 tid;
	u8 channel;
	__le32 bitrate;
	u8 tseg1;
	u8 tseg2;
	u8 sjw;
	u8 no_samp;
} __packed;

struct kvaser_msg_tx_can {
	u8 channel;
	u8 tid;
	u8 msg[14];
	u8 flags;
	u8 padding;
} __packed;

struct kvaser_msg_rx_can {
	u8 channel;
	u8 flag;
	u8 msg[14];
	__le16 time;
} __packed;

struct kvaser_msg_chip_state_event {
	u8 tid;
	u8 channel;
	u8 tx_errors_count;
	u8 rx_errors_count;
	__le16 time;
	u8 status;
	u8 padding[3];
} __packed;

struct kvaser_msg_tx_acknowledge {
	u8 channel;
	u8 tid;
	__le16 time;
	__le16 padding;
} __packed;

struct kvaser_msg_error_event {
	u8 tid;
	u8 padding;
	u8 tx_errors_count_ch0;
	u8 rx_errors_count_ch0;
	u8 tx_errors_count_ch1;
	u8 rx_errors_count_ch1;
	u8 status_ch0;
	u8 status_ch1;
	__le16 time;
} __packed;

struct kvaser_msg_ctrl_mode {
	u8 tid;
	u8 channel;
	u8 ctrl_mode;
	u8 padding[3];
} __packed;

struct kvaser_msg_flush_queue {
	u8 tid;
	u8 channel;
	u8 flags;
	u8 padding[3];
} __packed;

struct kvaser_msg_log_message {
	u8 channel;
	u8 flags;
	__le16 time[3];
	u8 dlc;
	u8 time_offset;
	__le32 id;
	u8 data[8];
} __packed;

struct kvaser_msg {
	u8 len;
	u8 id;
	union	{
		struct kvaser_msg_simple simple;
		struct kvaser_msg_cardinfo cardinfo;
		struct kvaser_msg_softinfo softinfo;
		struct kvaser_msg_busparams busparams;
		struct kvaser_msg_tx_can tx_can;
		struct kvaser_msg_rx_can rx_can;
		struct kvaser_msg_chip_state_event chip_state_event;
		struct kvaser_msg_tx_acknowledge tx_acknowledge;
		struct kvaser_msg_error_event error_event;
		struct kvaser_msg_ctrl_mode ctrl_mode;
		struct kvaser_msg_flush_queue flush_queue;
		struct kvaser_msg_log_message log_message;
	} u;
} __packed;

struct kvaser_usb_tx_urb_context {
	struct kvaser_usb_net_priv *priv;
	u32 echo_index;
	int dlc;
};

struct kvaser_usb {
	struct usb_device *udev;
	struct kvaser_usb_net_priv *nets[MAX_NET_DEVICES];

	struct usb_endpoint_descriptor *bulk_in, *bulk_out;
	struct usb_anchor rx_submitted;

	u32 fw_version;
	unsigned int nchannels;

	bool rxinitdone;
	void *rxbuf[MAX_RX_URBS];
	dma_addr_t rxbuf_dma[MAX_RX_URBS];
};

struct kvaser_usb_net_priv {
	struct can_priv can;

	atomic_t active_tx_urbs;
	struct usb_anchor tx_submitted;
	struct kvaser_usb_tx_urb_context tx_contexts[MAX_TX_URBS];

	struct completion start_comp, stop_comp;

	struct kvaser_usb *dev;
	struct net_device *netdev;
	int channel;

	struct can_berr_counter bec;
};

static const struct usb_device_id kvaser_usb_table[] = {
	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID),
		.driver_info = KVASER_HAS_TXRX_ERRORS |
			       KVASER_HAS_SILENT_MODE },
	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_REVB_PRODUCT_ID),
		.driver_info = KVASER_HAS_TXRX_ERRORS |
			       KVASER_HAS_SILENT_MODE },
	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMORATOR_PRODUCT_ID),
		.driver_info = KVASER_HAS_TXRX_ERRORS |
			       KVASER_HAS_SILENT_MODE },
	{ USB_DEVICE(KVASER_VENDOR_ID, USB_VCI2_PRODUCT_ID),
		.driver_info = KVASER_HAS_TXRX_ERRORS |
			       KVASER_HAS_SILENT_MODE },
	{ }
};
MODULE_DEVICE_TABLE(usb, kvaser_usb_table);

static inline int kvaser_usb_send_msg(const struct kvaser_usb *dev,
				      struct kvaser_msg *msg)
{
	int actual_len;

	return usb_bulk_msg(dev->udev,
			    usb_sndbulkpipe(dev->udev,
					dev->bulk_out->bEndpointAddress),
			    msg, msg->len, &actual_len,
			    USB_SEND_TIMEOUT);
}

static int kvaser_usb_wait_msg(const struct kvaser_usb *dev, u8 id,
			       struct kvaser_msg *msg)
{
	struct kvaser_msg *tmp;
	void *buf;
	int actual_len;
	int err;
	int pos = 0;

	buf = kzalloc(RX_BUFFER_SIZE, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	err = usb_bulk_msg(dev->udev,
			   usb_rcvbulkpipe(dev->udev,
					   dev->bulk_in->bEndpointAddress),
			   buf, RX_BUFFER_SIZE, &actual_len,
			   USB_RECV_TIMEOUT);
	if (err < 0)
		goto end;

	while (pos <= actual_len - MSG_HEADER_LEN) {
		tmp = buf + pos;

		if (!tmp->len)
			break;

		if (pos + tmp->len > actual_len) {
			dev_err(dev->udev->dev.parent, "Format error\n");
			break;
		}

		if (tmp->id == id) {
			memcpy(msg, tmp, tmp->len);
			goto end;
		}

		pos += tmp->len;
	}

	err = -EINVAL;

end:
	kfree(buf);

	return err;
}

static int kvaser_usb_send_simple_msg(const struct kvaser_usb *dev,
				      u8 msg_id, int channel)
{
	struct kvaser_msg *msg;
	int rc;

	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	msg->id = msg_id;
	msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_simple);
	msg->u.simple.channel = channel;
	msg->u.simple.tid = 0xff;

	rc = kvaser_usb_send_msg(dev, msg);

	kfree(msg);
	return rc;
}

static int kvaser_usb_get_software_info(struct kvaser_usb *dev)
{
	struct kvaser_msg msg;
	int err;

	err = kvaser_usb_send_simple_msg(dev, CMD_GET_SOFTWARE_INFO, 0);
	if (err)
		return err;

	err = kvaser_usb_wait_msg(dev, CMD_GET_SOFTWARE_INFO_REPLY, &msg);
	if (err)
		return err;

	dev->fw_version = le32_to_cpu(msg.u.softinfo.application_version);

	return 0;
}

static int kvaser_usb_get_card_info(struct kvaser_usb *dev)
{
	struct kvaser_msg msg;
	int err;

	err = kvaser_usb_send_simple_msg(dev, CMD_GET_CARD_INFO, 0);
	if (err)
		return err;

	err = kvaser_usb_wait_msg(dev, CMD_GET_CARD_INFO_REPLY, &msg);
	if (err)
		return err;

	dev->nchannels = msg.u.cardinfo.nchannels;

	return 0;
}

static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev,
				      const struct kvaser_msg *msg)
{
	struct net_device_stats *stats;
	struct kvaser_usb_tx_urb_context *context;
	struct kvaser_usb_net_priv *priv;
	struct sk_buff *skb;
	struct can_frame *cf;
	u8 channel = msg->u.tx_acknowledge.channel;
	u8 tid = msg->u.tx_acknowledge.tid;

	if (channel >= dev->nchannels) {
		dev_err(dev->udev->dev.parent,
			"Invalid channel number (%d)\n", channel);
		return;
	}

	priv = dev->nets[channel];

	if (!netif_device_present(priv->netdev))
		return;

	stats = &priv->netdev->stats;

	context = &priv->tx_contexts[tid % MAX_TX_URBS];

	/* Sometimes the state change doesn't come after a bus-off event */
	if (priv->can.restart_ms &&
	    (priv->can.state >= CAN_STATE_BUS_OFF)) {
		skb = alloc_can_err_skb(priv->netdev, &cf);
		if (skb) {
			cf->can_id |= CAN_ERR_RESTARTED;
			netif_rx(skb);

			stats->rx_packets++;
			stats->rx_bytes += cf->can_dlc;
		} else {
			netdev_err(priv->netdev,
				   "No memory left for err_skb\n");
		}

		priv->can.can_stats.restarts++;
		netif_carrier_on(priv->netdev);

		priv->can.state = CAN_STATE_ERROR_ACTIVE;
	}

	stats->tx_packets++;
	stats->tx_bytes += context->dlc;
	can_get_echo_skb(priv->netdev, context->echo_index);

	context->echo_index = MAX_TX_URBS;
	atomic_dec(&priv->active_tx_urbs);

	netif_wake_queue(priv->netdev);
}

static void kvaser_usb_simple_msg_callback(struct urb *urb)
{
	struct net_device *netdev = urb->context;

	kfree(urb->transfer_buffer);

	if (urb->status)
		netdev_warn(netdev, "urb status received: %d\n",
			    urb->status);
}

static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv,
				       u8 msg_id)
{
	struct kvaser_usb *dev = priv->dev;
	struct net_device *netdev = priv->netdev;
	struct kvaser_msg *msg;
	struct urb *urb;
	void *buf;
	int err;

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb) {
		netdev_err(netdev, "No memory left for URBs\n");
		return -ENOMEM;
	}

	buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC);
	if (!buf) {
		usb_free_urb(urb);
		return -ENOMEM;
	}

	msg = (struct kvaser_msg *)buf;
	msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_simple);
	msg->id = msg_id;
	msg->u.simple.channel = priv->channel;

	usb_fill_bulk_urb(urb, dev->udev,
			  usb_sndbulkpipe(dev->udev,
					  dev->bulk_out->bEndpointAddress),
			  buf, msg->len,
			  kvaser_usb_simple_msg_callback, priv);
	usb_anchor_urb(urb, &priv->tx_submitted);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err) {
		netdev_err(netdev, "Error transmitting URB\n");
		usb_unanchor_urb(urb);
		usb_free_urb(urb);
		kfree(buf);
		return err;
	}

	usb_free_urb(urb);

	return 0;
}

static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)
{
	int i;

	usb_kill_anchored_urbs(&priv->tx_submitted);
	atomic_set(&priv->active_tx_urbs, 0);

	for (i = 0; i < MAX_TX_URBS; i++)
		priv->tx_contexts[i].echo_index = MAX_TX_URBS;
}

static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
				const struct kvaser_msg *msg)
{
	struct can_frame *cf;
	struct sk_buff *skb;
	struct net_device_stats *stats;
	struct kvaser_usb_net_priv *priv;
	unsigned int new_state;
	u8 channel, status, txerr, rxerr, error_factor;

	switch (msg->id) {
	case CMD_CAN_ERROR_EVENT:
		/*BUG: for the moment we are dealing with a single channel only.... */
		channel = 0;
		status =  msg->u.error_event.status_ch0;
		txerr = msg->u.error_event.tx_errors_count_ch0;
		rxerr = msg->u.error_event.rx_errors_count_ch0;
		error_factor = 0;
		break;
	case CMD_CHIP_STATE_EVENT:
		channel = msg->u.chip_state_event.channel;
		status =  msg->u.chip_state_event.status;
		txerr = msg->u.chip_state_event.tx_errors_count;
		rxerr = msg->u.chip_state_event.rx_errors_count;
		error_factor = 0;
		break;
	default:
		dev_err(dev->udev->dev.parent, "Invalid msg id (%d)\n",
			msg->id);
		return;
	}

	if (channel >= dev->nchannels) {
		dev_err(dev->udev->dev.parent,
			"Invalid channel number (%d)\n", channel);
		return;
	}

	priv = dev->nets[channel];
	stats = &priv->netdev->stats;

	if (status & M16C_STATE_BUS_RESET) {
		kvaser_usb_unlink_tx_urbs(priv);
		return;
	}

	skb = alloc_can_err_skb(priv->netdev, &cf);
	if (!skb) {
		stats->rx_dropped++;
		return;
	}

	new_state = priv->can.state;

	netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status);

	if (status & M16C_STATE_BUS_OFF) {
		cf->can_id |= CAN_ERR_BUSOFF;

		priv->can.can_stats.bus_off++;
		if (!priv->can.restart_ms)
			kvaser_usb_simple_msg_async(priv, CMD_STOP_CHIP);

		netif_carrier_off(priv->netdev);

		new_state = CAN_STATE_BUS_OFF;
	} else if (status & M16C_STATE_BUS_PASSIVE) {
		if (priv->can.state != CAN_STATE_ERROR_PASSIVE) {
			cf->can_id |= CAN_ERR_CRTL;

			if (txerr || rxerr)
				cf->data[1] = (txerr > rxerr)
						? CAN_ERR_CRTL_TX_PASSIVE
						: CAN_ERR_CRTL_RX_PASSIVE;
			else
				cf->data[1] = CAN_ERR_CRTL_TX_PASSIVE |
					      CAN_ERR_CRTL_RX_PASSIVE;

			priv->can.can_stats.error_passive++;
		}

		new_state = CAN_STATE_ERROR_PASSIVE;
	}

	if (status == M16C_STATE_BUS_ERROR) {
		if ((priv->can.state < CAN_STATE_ERROR_WARNING) &&
		    ((txerr >= 96) || (rxerr >= 96))) {
			cf->can_id |= CAN_ERR_CRTL;
			cf->data[1] = (txerr > rxerr)
					? CAN_ERR_CRTL_TX_WARNING
					: CAN_ERR_CRTL_RX_WARNING;

			priv->can.can_stats.error_warning++;
			new_state = CAN_STATE_ERROR_WARNING;
		} else if (priv->can.state > CAN_STATE_ERROR_ACTIVE) {
			cf->can_id |= CAN_ERR_PROT;
			cf->data[2] = CAN_ERR_PROT_ACTIVE;

			new_state = CAN_STATE_ERROR_ACTIVE;
		}
	}

	if (!status) {
		cf->can_id |= CAN_ERR_PROT;
		cf->data[2] = CAN_ERR_PROT_ACTIVE;

		new_state = CAN_STATE_ERROR_ACTIVE;
	}

	if (priv->can.restart_ms &&
	    (priv->can.state >= CAN_STATE_BUS_OFF) &&
	    (new_state < CAN_STATE_BUS_OFF)) {
		cf->can_id |= CAN_ERR_RESTARTED;
		netif_carrier_on(priv->netdev);

		priv->can.can_stats.restarts++;
	}

	if (error_factor) {
		priv->can.can_stats.bus_error++;
		stats->rx_errors++;

		cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;

		if (error_factor & M16C_EF_ACKE)
			cf->data[3] |= (CAN_ERR_PROT_LOC_ACK);
		if (error_factor & M16C_EF_CRCE)
			cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
					CAN_ERR_PROT_LOC_CRC_DEL);
		if (error_factor & M16C_EF_FORME)
			cf->data[2] |= CAN_ERR_PROT_FORM;
		if (error_factor & M16C_EF_STFE)
			cf->data[2] |= CAN_ERR_PROT_STUFF;
		if (error_factor & M16C_EF_BITE0)
			cf->data[2] |= CAN_ERR_PROT_BIT0;
		if (error_factor & M16C_EF_BITE1)
			cf->data[2] |= CAN_ERR_PROT_BIT1;
		if (error_factor & M16C_EF_TRE)
			cf->data[2] |= CAN_ERR_PROT_TX;
	}

	cf->data[6] = txerr;
	cf->data[7] = rxerr;

	priv->bec.txerr = txerr;
	priv->bec.rxerr = rxerr;

	priv->can.state = new_state;

	netif_rx(skb);

	stats->rx_packets++;
	stats->rx_bytes += cf->can_dlc;
}

static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv,
				  const struct kvaser_msg *msg)
{
	struct can_frame *cf;
	struct sk_buff *skb;
	struct net_device_stats *stats = &priv->netdev->stats;

	if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME |
					 MSG_FLAG_NERR)) {
		netdev_err(priv->netdev, "Unknow error (flags: 0x%02x)\n",
			   msg->u.rx_can.flag);

		stats->rx_errors++;
		return;
	}

	if (msg->u.rx_can.flag & MSG_FLAG_OVERRUN) {
		skb = alloc_can_err_skb(priv->netdev, &cf);
		if (!skb) {
			stats->rx_dropped++;
			return;
		}

		cf->can_id |= CAN_ERR_CRTL;
		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;

		stats->rx_over_errors++;
		stats->rx_errors++;

		netif_rx(skb);

		stats->rx_packets++;
		stats->rx_bytes += cf->can_dlc;
	}
}

static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
				  const struct kvaser_msg *msg)
{
	struct kvaser_usb_net_priv *priv;
	struct can_frame *cf;
	struct sk_buff *skb;
	struct net_device_stats *stats;
	u8 channel = msg->u.rx_can.channel;

	if (channel >= dev->nchannels) {
		dev_err(dev->udev->dev.parent,
			"Invalid channel number (%d)\n", channel);
		return;
	}

	priv = dev->nets[channel];
	stats = &priv->netdev->stats;

	if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME |
				  MSG_FLAG_NERR |
				  MSG_FLAG_OVERRUN)) {
		kvaser_usb_rx_can_err(priv, msg);
		return;
	} else if (msg->u.rx_can.flag & ~MSG_FLAG_REMOTE_FRAME) {
		netdev_warn(priv->netdev,
			    "Unhandled frame (flags: 0x%02x)",
			    msg->u.rx_can.flag);
		return;
	}

	skb = alloc_can_skb(priv->netdev, &cf);
	if (!skb) {
		stats->tx_dropped++;
		return;
	}

	cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) |
		     (msg->u.rx_can.msg[1] & 0x3f);

	if (msg->id == CMD_RX_EXT_MESSAGE) {
		cf->can_id <<= 18;
		cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) |
			      ((msg->u.rx_can.msg[3] & 0xff) << 6) |
			      (msg->u.rx_can.msg[4] & 0x3f);
		cf->can_id |= CAN_EFF_FLAG;
	}

	cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]);

	if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME)
		cf->can_id |= CAN_RTR_FLAG;
	else
		memcpy(cf->data, &msg->u.rx_can.msg[6],
		       cf->can_dlc);

	netif_rx(skb);

	stats->rx_packets++;
	stats->rx_bytes += cf->can_dlc;
}

static void kvaser_usb_start_chip_reply(const struct kvaser_usb *dev,
					const struct kvaser_msg *msg)
{
	struct kvaser_usb_net_priv *priv;
	u8 channel = msg->u.simple.channel;

	if (channel >= dev->nchannels) {
		dev_err(dev->udev->dev.parent,
			"Invalid channel number (%d)\n", channel);
		return;
	}

	priv = dev->nets[channel];

	if (completion_done(&priv->start_comp) &&
	    netif_queue_stopped(priv->netdev)) {
		netif_wake_queue(priv->netdev);
	} else {
		netif_start_queue(priv->netdev);
		complete(&priv->start_comp);
	}
}

static void kvaser_usb_stop_chip_reply(const struct kvaser_usb *dev,
				       const struct kvaser_msg *msg)
{
	struct kvaser_usb_net_priv *priv;
	u8 channel = msg->u.simple.channel;

	if (channel >= dev->nchannels) {
		dev_err(dev->udev->dev.parent,
			"Invalid channel number (%d)\n", channel);
		return;
	}

	priv = dev->nets[channel];

	complete(&priv->stop_comp);
}

static void kvaser_usb_handle_message(const struct kvaser_usb *dev,
				      const struct kvaser_msg *msg)
{
	switch (msg->id) {
	case CMD_START_CHIP_REPLY:
		kvaser_usb_start_chip_reply(dev, msg);
		break;

	case CMD_STOP_CHIP_REPLY:
		kvaser_usb_stop_chip_reply(dev, msg);
		break;

	case CMD_RX_STD_MESSAGE:
	case CMD_RX_EXT_MESSAGE:
		kvaser_usb_rx_can_msg(dev, msg);
		break;

	case CMD_CHIP_STATE_EVENT:
	case CMD_CAN_ERROR_EVENT:
		kvaser_usb_rx_error(dev, msg);
		break;

	case CMD_TX_ACKNOWLEDGE:
		kvaser_usb_tx_acknowledge(dev, msg);
		break;

	default:
		dev_warn(dev->udev->dev.parent,
			 "Unhandled message (%d)\n", msg->id);
		break;
	}
}

static void kvaser_usb_read_bulk_callback(struct urb *urb)
{
	struct kvaser_usb *dev = urb->context;
	struct kvaser_msg *msg;
	int pos = 0;
	int err, i;

	switch (urb->status) {
	case 0:
		break;
	case -ENOENT:
	case -ESHUTDOWN:
		return;
	default:
		dev_info(dev->udev->dev.parent, "Rx URB aborted (%d)\n",
			 urb->status);
		goto resubmit_urb;
	}

	while (pos <= urb->actual_length - MSG_HEADER_LEN) {
		msg = urb->transfer_buffer + pos;

		if (!msg->len)
			break;

		if (pos + msg->len > urb->actual_length) {
			dev_err(dev->udev->dev.parent, "Format error\n");
			break;
		}

		kvaser_usb_handle_message(dev, msg);

		pos += msg->len;
	}

resubmit_urb:
	usb_fill_bulk_urb(urb, dev->udev,
			  usb_rcvbulkpipe(dev->udev,
					  dev->bulk_in->bEndpointAddress),
			  urb->transfer_buffer, RX_BUFFER_SIZE,
			  kvaser_usb_read_bulk_callback, dev);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err == -ENODEV) {
		for (i = 0; i < dev->nchannels; i++) {
			if (!dev->nets[i])
				continue;

			netif_device_detach(dev->nets[i]->netdev);
		}
	} else if (err) {
		dev_err(dev->udev->dev.parent,
			"Failed resubmitting read bulk urb: %d\n", err);
	}

	return;
}

static int kvaser_usb_setup_rx_urbs(struct kvaser_usb *dev)
{
	int i, err = 0;

	if (dev->rxinitdone)
		return 0;

	for (i = 0; i < MAX_RX_URBS; i++) {
		struct urb *urb = NULL;
		u8 *buf = NULL;
		dma_addr_t buf_dma;

		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!urb) {
			dev_warn(dev->udev->dev.parent,
				 "No memory left for URBs\n");
			err = -ENOMEM;
			break;
		}

		buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE,
					 GFP_KERNEL, &buf_dma);
		if (!buf) {
			dev_warn(dev->udev->dev.parent,
				 "No memory left for USB buffer\n");
			usb_free_urb(urb);
			err = -ENOMEM;
			break;
		}

		usb_fill_bulk_urb(urb, dev->udev,
				  usb_rcvbulkpipe(dev->udev,
					  dev->bulk_in->bEndpointAddress),
				  buf, RX_BUFFER_SIZE,
				  kvaser_usb_read_bulk_callback,
				  dev);
		urb->transfer_dma = buf_dma;
		urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
		usb_anchor_urb(urb, &dev->rx_submitted);

		err = usb_submit_urb(urb, GFP_KERNEL);
		if (err) {
			usb_unanchor_urb(urb);
			usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
					  buf_dma);
			usb_free_urb(urb);
			break;
		}

		dev->rxbuf[i] = buf;
		dev->rxbuf_dma[i] = buf_dma;

		usb_free_urb(urb);
	}

	if (i == 0) {
		dev_warn(dev->udev->dev.parent,
			 "Cannot setup read URBs, error %d\n", err);
		return err;
	} else if (i < MAX_RX_URBS) {
		dev_warn(dev->udev->dev.parent,
			 "RX performances may be slow\n");
	}

	dev->rxinitdone = true;

	return 0;
}

static int kvaser_usb_set_opt_mode(const struct kvaser_usb_net_priv *priv)
{
	struct kvaser_msg *msg;
	int rc;

	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	msg->id = CMD_SET_CTRL_MODE;
	msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_ctrl_mode);
	msg->u.ctrl_mode.tid = 0xff;
	msg->u.ctrl_mode.channel = priv->channel;

	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
		msg->u.ctrl_mode.ctrl_mode = KVASER_CTRL_MODE_SILENT;
	else
		msg->u.ctrl_mode.ctrl_mode = KVASER_CTRL_MODE_NORMAL;

	rc = kvaser_usb_send_msg(priv->dev, msg);

	kfree(msg);
	return rc;
}

static int kvaser_usb_start_chip(struct kvaser_usb_net_priv *priv)
{
	int err;

	init_completion(&priv->start_comp);

	err = kvaser_usb_send_simple_msg(priv->dev, CMD_START_CHIP,
					 priv->channel);
	if (err)
		return err;

	if (!wait_for_completion_timeout(&priv->start_comp,
					 msecs_to_jiffies(START_TIMEOUT)))
		return -ETIMEDOUT;

	return 0;
}

static int kvaser_usb_open(struct net_device *netdev)
{
	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
	struct kvaser_usb *dev = priv->dev;
	int err;

	err = open_candev(netdev);
	if (err)
		return err;

	err = kvaser_usb_setup_rx_urbs(dev);
	if (err)
		goto error;

	err = kvaser_usb_set_opt_mode(priv);
	if (err)
		goto error;

	err = kvaser_usb_start_chip(priv);
	if (err) {
		netdev_warn(netdev, "Cannot start device, error %d\n", err);
		goto error;
	}

	priv->can.state = CAN_STATE_ERROR_ACTIVE;

	return 0;

error:
	close_candev(netdev);
	return err;
}

static void kvaser_usb_unlink_all_urbs(struct kvaser_usb *dev)
{
	int i;

	usb_kill_anchored_urbs(&dev->rx_submitted);

	for (i = 0; i < MAX_RX_URBS; i++)
		usb_free_coherent(dev->udev, RX_BUFFER_SIZE,
				  dev->rxbuf[i],
				  dev->rxbuf_dma[i]);

	for (i = 0; i < MAX_NET_DEVICES; i++) {
		struct kvaser_usb_net_priv *priv = dev->nets[i];

		if (priv)
			kvaser_usb_unlink_tx_urbs(priv);
	}
}

static int kvaser_usb_stop_chip(struct kvaser_usb_net_priv *priv)
{
	int err;

	init_completion(&priv->stop_comp);

	err = kvaser_usb_send_simple_msg(priv->dev, CMD_STOP_CHIP,
					 priv->channel);
	if (err)
		return err;

	if (!wait_for_completion_timeout(&priv->stop_comp,
					 msecs_to_jiffies(STOP_TIMEOUT)))
		return -ETIMEDOUT;

	return 0;
}

static int kvaser_usb_flush_queue(struct kvaser_usb_net_priv *priv)
{
	struct kvaser_msg *msg;
	int rc;

	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	msg->id = CMD_FLUSH_QUEUE;
	msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_flush_queue);
	msg->u.flush_queue.channel = priv->channel;
	msg->u.flush_queue.flags = 0x00;

	rc = kvaser_usb_send_msg(priv->dev, msg);

	kfree(msg);
	return rc;
}

static int kvaser_usb_close(struct net_device *netdev)
{
	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
	struct kvaser_usb *dev = priv->dev;
	int err;

	netif_stop_queue(netdev);

	err = kvaser_usb_flush_queue(priv);
	if (err)
		netdev_warn(netdev, "Cannot flush queue, error %d\n", err);

	if (kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel))
		netdev_warn(netdev, "Cannot reset card, error %d\n", err);

	err = kvaser_usb_stop_chip(priv);
	if (err)
		netdev_warn(netdev, "Cannot stop device, error %d\n", err);

	priv->can.state = CAN_STATE_STOPPED;
	close_candev(priv->netdev);

	return 0;
}

static void kvaser_usb_write_bulk_callback(struct urb *urb)
{
	struct kvaser_usb_tx_urb_context *context = urb->context;
	struct kvaser_usb_net_priv *priv;
	struct net_device *netdev;

	if (WARN_ON(!context))
		return;

	priv = context->priv;
	netdev = priv->netdev;

	kfree(urb->transfer_buffer);

	if (!netif_device_present(netdev))
		return;

	if (urb->status)
		netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status);
}

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++;
		goto nourbmem;
	}

	buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC);
	if (!buf) {
		stats->tx_dropped++;
		goto nobufmem;
	}

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

		skb = NULL; /* set to NULL to avoid double free in
			     * dev_kfree_skb(skb) */

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

	usb_free_urb(urb);

	return NETDEV_TX_OK;

releasebuf:
	kfree(buf);
nobufmem:
	usb_free_urb(urb);
nourbmem:
	dev_kfree_skb(skb);
	return ret;
}

static const struct net_device_ops kvaser_usb_netdev_ops = {
	.ndo_open = kvaser_usb_open,
	.ndo_stop = kvaser_usb_close,
	.ndo_start_xmit = kvaser_usb_start_xmit,
};

static const struct can_bittiming_const kvaser_usb_bittiming_const = {
	.name = "kvaser_usb2",
	.tseg1_min = KVASER_USB_TSEG1_MIN,
	.tseg1_max = KVASER_USB_TSEG1_MAX,
	.tseg2_min = KVASER_USB_TSEG2_MIN,
	.tseg2_max = KVASER_USB_TSEG2_MAX,
	.sjw_max = KVASER_USB_SJW_MAX,
	.brp_min = KVASER_USB_BRP_MIN,
	.brp_max = KVASER_USB_BRP_MAX,
	.brp_inc = KVASER_USB_BRP_INC,
};

static int kvaser_usb_set_bittiming(struct net_device *netdev)
{
	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
	struct can_bittiming *bt = &priv->can.bittiming;
	struct kvaser_usb *dev = priv->dev;
	struct kvaser_msg *msg;
	int rc;

	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	msg->id = CMD_SET_BUS_PARAMS;
	msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_busparams);
	msg->u.busparams.channel = priv->channel;
	msg->u.busparams.tid = 0xff;
	msg->u.busparams.bitrate = cpu_to_le32(bt->bitrate);
	msg->u.busparams.sjw = bt->sjw;
	msg->u.busparams.tseg1 = bt->prop_seg + bt->phase_seg1;
	msg->u.busparams.tseg2 = bt->phase_seg2;

	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
		msg->u.busparams.no_samp = 3;
	else
		msg->u.busparams.no_samp = 1;

	rc = kvaser_usb_send_msg(dev, msg);

	kfree(msg);
	return rc;
}

static int kvaser_usb_set_mode(struct net_device *netdev,
			       enum can_mode mode)
{
	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
	int err;

	switch (mode) {
	case CAN_MODE_START:
		err = kvaser_usb_simple_msg_async(priv, CMD_START_CHIP);
		if (err)
			return err;
		break;
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static int kvaser_usb_get_berr_counter(const struct net_device *netdev,
				       struct can_berr_counter *bec)
{
	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);

	*bec = priv->bec;

	return 0;
}

static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
{
	int i;

	for (i = 0; i < dev->nchannels; i++) {
		if (!dev->nets[i])
			continue;

		unregister_netdev(dev->nets[i]->netdev);
	}

	kvaser_usb_unlink_all_urbs(dev);

	for (i = 0; i < dev->nchannels; i++) {
		if (!dev->nets[i])
			continue;

		free_candev(dev->nets[i]->netdev);
	}
}

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 -ENOMEM;
	}

	priv = netdev_priv(netdev);

	init_completion(&priv->start_comp);
	init_completion(&priv->stop_comp);

	init_usb_anchor(&priv->tx_submitted);
	atomic_set(&priv->active_tx_urbs, 0);

	for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++)
		priv->tx_contexts[i].echo_index = MAX_TX_URBS;

	priv->dev = dev;
	priv->netdev = netdev;
	priv->channel = channel;

	priv->can.state = CAN_STATE_STOPPED;
	priv->can.clock.freq = CAN_USB_CLOCK;
	priv->can.bittiming_const = &kvaser_usb_bittiming_const;
	priv->can.do_set_bittiming = kvaser_usb_set_bittiming;
	priv->can.do_set_mode = kvaser_usb_set_mode;
	if (id->driver_info & KVASER_HAS_TXRX_ERRORS)
		priv->can.do_get_berr_counter = kvaser_usb_get_berr_counter;
	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
	if (id->driver_info & KVASER_HAS_SILENT_MODE)
		priv->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY;

	netdev->flags |= IFF_ECHO;

	netdev->netdev_ops = &kvaser_usb_netdev_ops;

	SET_NETDEV_DEV(netdev, &intf->dev);

	dev->nets[channel] = priv;

	err = register_candev(netdev);
	if (err) {
		dev_err(&intf->dev, "Failed to register can device\n");
		free_candev(netdev);
		dev->nets[channel] = NULL;
		return err;
	}

	netdev_dbg(netdev, "device registered\n");

	return 0;
}

static int kvaser_usb_get_endpoints(const struct usb_interface *intf,
				    struct usb_endpoint_descriptor **in,
				    struct usb_endpoint_descriptor **out)
{
	const struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	int i;

	iface_desc = &intf->altsetting[0];

	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (!*in && usb_endpoint_is_bulk_in(endpoint))
			*in = endpoint;

		if (!*out && usb_endpoint_is_bulk_out(endpoint))
			*out = endpoint;

		/* use first bulk endpoint for in and out */
		if (*in && *out)
			return 0;
	}

	return -ENODEV;
}

static int kvaser_usb_probe(struct usb_interface *intf,
		 	     const struct usb_device_id *id)
{
	struct kvaser_usb *dev;
	int err = -ENOMEM;
	int i;

	dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	err = kvaser_usb_get_endpoints(intf, &dev->bulk_in, &dev->bulk_out);
	if (err) {
		dev_err(&intf->dev, "Cannot get usb endpoint(s)");
		return err;
	}

	dev->udev = interface_to_usbdev(intf);

	init_usb_anchor(&dev->rx_submitted);

	usb_set_intfdata(intf, dev);

	for (i = 0; i < MAX_NET_DEVICES; i++)
		kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, i);

	err = kvaser_usb_get_software_info(dev);
	if (err) {
		dev_err(&intf->dev,
			"Cannot get software infos, error %d\n", err);
		return err;
	}

	err = kvaser_usb_get_card_info(dev);
	if (err) {
		dev_err(&intf->dev,
			"Cannot get card infos, error %d\n", err);
		return err;
	}

	dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n",
		((dev->fw_version >> 24) & 0xff),
		((dev->fw_version >> 16) & 0xff),
		(dev->fw_version & 0xffff));

	for (i = 0; i < dev->nchannels; i++) {
		err = kvaser_usb_init_one(intf, id, i);
		if (err) {
			kvaser_usb_remove_interfaces(dev);
			return err;
		}
	}

	return 0;
}

static void kvaser_usb_disconnect(struct usb_interface *intf)
{
	struct kvaser_usb *dev = usb_get_intfdata(intf);

	usb_set_intfdata(intf, NULL);

	if (!dev)
		return;

	kvaser_usb_remove_interfaces(dev);
}

static struct usb_driver kvaser_usb_driver = {
	.name = "kvaser_usb2",
	.probe = kvaser_usb_probe,
	.disconnect = kvaser_usb_disconnect,
	.id_table = kvaser_usb_table,
};

module_usb_driver(kvaser_usb_driver);

MODULE_AUTHOR("Olivier Sobrie <olivier@sobrie.be>");
MODULE_DESCRIPTION("CAN driver for Kvaser CAN/USB devices");
MODULE_LICENSE("GPL v2");

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Kvazer USB CAN driver
  2014-01-17  9:36           ` GARNERO, PIERRE (P.)
@ 2014-01-17  9:50             ` Marc Kleine-Budde
  2014-01-17 13:50               ` GARNERO, PIERRE (P.)
  0 siblings, 1 reply; 13+ messages in thread
From: Marc Kleine-Budde @ 2014-01-17  9:50 UTC (permalink / raw)
  To: GARNERO, PIERRE (P.), Olivier Sobrie
  Cc: Oliver Hartkopp, linux-can@vger.kernel.org, Daniel Berglund

[-- Attachment #1: Type: text/plain, Size: 713 bytes --]

Hello,

On 01/17/2014 10:36 AM, GARNERO, PIERRE (P.) wrote:
> I have been able to test my modification of kvaser_usb.c file on
> Fedora 17/x86 (see attachment). This module is able to read CAN
> messages coming from a Kvaser canUSB Rugged device (which is enough
> for my goal).

The diff to the original driver isn't that big, if you want to get it
mainlined you should work on integrating it into the original driver.

Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Kvazer USB CAN driver
  2014-01-17  9:50             ` Marc Kleine-Budde
@ 2014-01-17 13:50               ` GARNERO, PIERRE (P.)
  2014-01-17 14:00                 ` Marc Kleine-Budde
  0 siblings, 1 reply; 13+ messages in thread
From: GARNERO, PIERRE (P.) @ 2014-01-17 13:50 UTC (permalink / raw)
  To: Marc Kleine-Budde, Olivier Sobrie
  Cc: Oliver Hartkopp, linux-can@vger.kernel.org, Daniel Berglund

Hello Marc,

Yes. I will try to do so. However, I am a newbie in this area, so a pointer on how to proceed will be more than welcome (maybe in a private mail in order not to pollute the mailing list ?).

Cheers,

Pierre

-----Message d'origine-----
De : Marc Kleine-Budde [mailto:mkl@pengutronix.de] 
Envoyé : vendredi 17 janvier 2014 10:50
À : GARNERO, PIERRE (P.); Olivier Sobrie
Cc : Oliver Hartkopp; linux-can@vger.kernel.org; Daniel Berglund
Objet : Re: Kvazer USB CAN driver

Hello,

On 01/17/2014 10:36 AM, GARNERO, PIERRE (P.) wrote:
> I have been able to test my modification of kvaser_usb.c file on 
> Fedora 17/x86 (see attachment). This module is able to read CAN 
> messages coming from a Kvaser canUSB Rugged device (which is enough 
> for my goal).

The diff to the original driver isn't that big, if you want to get it mainlined you should work on integrating it into the original driver.

Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Kvazer USB CAN driver
  2014-01-17 13:50               ` GARNERO, PIERRE (P.)
@ 2014-01-17 14:00                 ` Marc Kleine-Budde
  2014-01-18 14:26                   ` GARNERO, PIERRE (P.)
  0 siblings, 1 reply; 13+ messages in thread
From: Marc Kleine-Budde @ 2014-01-17 14:00 UTC (permalink / raw)
  To: GARNERO, PIERRE (P.), Olivier Sobrie
  Cc: Oliver Hartkopp, linux-can@vger.kernel.org, Daniel Berglund

[-- Attachment #1: Type: text/plain, Size: 808 bytes --]

On 01/17/2014 02:50 PM, GARNERO, PIERRE (P.) wrote:
> Yes. I will try to do so. However, I am a newbie in this area, so a
> pointer on how to proceed will be more than welcome (maybe in a
> private mail in order not to pollute the mailing list ?).

No :) This discussion should take place on the mailinglist, as there
might be more people here, who want to learn something. And this
mailinglist is really low traffic.

I think the first step should be to make the structs describing the USB
messages compatible.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Kvazer USB CAN driver
  2014-01-17 14:00                 ` Marc Kleine-Budde
@ 2014-01-18 14:26                   ` GARNERO, PIERRE (P.)
  0 siblings, 0 replies; 13+ messages in thread
From: GARNERO, PIERRE (P.) @ 2014-01-18 14:26 UTC (permalink / raw)
  To: Marc Kleine-Budde, Olivier Sobrie
  Cc: Oliver Hartkopp, linux-can@vger.kernel.org, Daniel Berglund

Hi Marc,

I would suggest to handle the different kvaser USB device families in dedicated modules.

My points are:
* while, currently, the USB commands used in the netdriver seems to be quite similar,  they represent a small subset of all filo and helios kvaser USB commands. In opposition, the full list of filo and helios USB commands shows a large number of discrepencies. If,  in the future, the netdriver should be improved to support more functionalities, then having a single module will make this task more complex. For instance, Kvaser provides a full implementation for both families in different files. And a large number of difference shows up between them. Supporting both families in a single module will be easier at the beginning but will become more and more painfull when features will be added.
* in a single module, we will have to dynamically select one USB command set depending on the device id. I do not think that we could design a single "abstract" command set that could fit all purposes. This will make a "common" driver (a little bit) less efficient (in term of CPU usage). And, as my initial goal is to have such a driver on an entry level CPU, it matters (for me).

What do you think ?

Another question: supposing that I come with a perfect source code :-), what is the process to have it mainlined ? Should I use git and push something somewhere ?  Or ...?  

Cheers,

Pierre

-----Message d'origine-----
De : Marc Kleine-Budde [mailto:mkl@pengutronix.de] 
Envoyé : vendredi 17 janvier 2014 15:01
À : GARNERO, PIERRE (P.); Olivier Sobrie
Cc : Oliver Hartkopp; linux-can@vger.kernel.org; Daniel Berglund
Objet : Re: Kvazer USB CAN driver

On 01/17/2014 02:50 PM, GARNERO, PIERRE (P.) wrote:
> Yes. I will try to do so. However, I am a newbie in this area, so a 
> pointer on how to proceed will be more than welcome (maybe in a 
> private mail in order not to pollute the mailing list ?).

No :) This discussion should take place on the mailinglist, as there might be more people here, who want to learn something. And this mailinglist is really low traffic.

I think the first step should be to make the structs describing the USB messages compatible.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2014-01-18 14:26 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <a8d74bed340445f081325afedf044bb5@AMSPR06MB053.eurprd06.prod.outlook.com>
2014-01-07 14:45 ` Kvazer USB CAN driver Oliver Hartkopp
2014-01-07 15:15   ` GARNERO, PIERRE (P.)
     [not found] ` <1389107792.5708.9.camel@blackbox>
     [not found]   ` <85d7d20e09a64996a182e491c6d250e0@AMSPR06MB053.eurprd06.prod.outlook.com>
2014-01-08 21:28     ` Oliver Hartkopp
2014-01-09  7:12       ` GARNERO, PIERRE (P.)
2014-01-09 13:14       ` GARNERO, PIERRE (P.)
2014-01-13  9:31       ` GARNERO, PIERRE (P.)
2014-01-16 11:02         ` Olivier Sobrie
2014-01-16 12:55           ` GARNERO, PIERRE (P.)
2014-01-17  9:36           ` GARNERO, PIERRE (P.)
2014-01-17  9:50             ` Marc Kleine-Budde
2014-01-17 13:50               ` GARNERO, PIERRE (P.)
2014-01-17 14:00                 ` Marc Kleine-Budde
2014-01-18 14:26                   ` GARNERO, PIERRE (P.)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).