Skip to content

Commit 0ca5ad7

Browse files
authored
socketcan: usb bulk mode for rx (commaai#584)
1 parent 5778c0a commit 0ca5ad7

File tree

3 files changed

+67
-74
lines changed

3 files changed

+67
-74
lines changed

drivers/linux/Makefile

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
VERSION=0.0.1
22
obj-m+=panda.o
33

4-
link:
5-
sudo dkms add `pwd`
4+
all: build install
65

76
build:
87
sudo dkms build panda/$(VERSION)
98

109
install:
1110
sudo dkms install panda/$(VERSION)
1211

13-
all: build install
12+
remove:
13+
sudo dkms remove panda/$(VERSION) --all
1414

1515
uninstall:
1616
sudo dkms uninstall panda/$(VERSION)
17-
sudo dkms remove panda/$(VERSION) --all
1817

18+
clean: remove
19+
20+
link:
21+
sudo dkms add `pwd`
22+
23+
unload:
24+
sudo rmmod panda

drivers/linux/README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ This will allow the panda to work with tools such as `can-utils`
77
- `apt-get install dkms gcc linux-headers-$(uname -r) make sudo`
88

99
## Installation
10-
- `make link` (only needed the first time. It will report an error on subsequent attempts to link)
1110
- `make all`
12-
- `make install`
11+
- `make link` (optional, setup to build/install when kernel is updated)
1312

1413
## Uninstall
15-
- `make uninstall`
14+
- `make clean`
1615

1716
## Usage
1817

drivers/linux/panda.c

+55-67
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ MODULE_DEVICE_TABLE(usb, panda_usb_table);
8686
const int can_numbering[] = {0,1,2};
8787

8888
struct panda_inf_priv *
89-
panda_get_inf_from_bus_id(struct panda_dev_priv *priv_dev, int bus_id){
89+
panda_get_inf_from_bus_id(struct panda_dev_priv *priv_dev, int bus_id) {
9090
int inf_num;
9191
for(inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++)
9292
if(can_numbering[inf_num] == bus_id)
@@ -107,8 +107,7 @@ static inline void panda_init_ctx(struct panda_inf_priv *priv)
107107
atomic_set(&priv->free_ctx_cnt, ARRAY_SIZE(priv->tx_context));
108108
}
109109

110-
static inline struct panda_usb_ctx *panda_usb_get_free_ctx(struct panda_inf_priv *priv,
111-
struct can_frame *cf)
110+
static inline struct panda_usb_ctx *panda_usb_get_free_ctx(struct panda_inf_priv *priv, struct can_frame *cf)
112111
{
113112
int i = 0;
114113
struct panda_usb_ctx *ctx = NULL;
@@ -124,8 +123,8 @@ static inline struct panda_usb_ctx *panda_usb_get_free_ctx(struct panda_inf_priv
124123
}
125124
}
126125

127-
printk("CTX num %d\n", atomic_read(&priv->free_ctx_cnt));
128-
if (!atomic_read(&priv->free_ctx_cnt)){
126+
//printk("CTX num %d\n", atomic_read(&priv->free_ctx_cnt));
127+
if (!atomic_read(&priv->free_ctx_cnt)) {
129128
/* That was the last free ctx. Slow down tx path */
130129
printk("SENDING TOO FAST\n");
131130
netif_stop_queue(priv->netdev);
@@ -148,19 +147,17 @@ static inline void panda_usb_free_ctx(struct panda_usb_ctx *ctx)
148147
netif_wake_queue(ctx->priv->netdev);
149148
}
150149

151-
152-
153150
static void panda_urb_unlink(struct panda_inf_priv *priv)
154151
{
155152
usb_kill_anchored_urbs(&priv->priv_dev->rx_submitted);
156153
usb_kill_anchored_urbs(&priv->tx_submitted);
157154
}
158155

159-
static int panda_set_output_enable(struct panda_inf_priv* priv, bool enable){
156+
static int panda_set_output_enable(struct panda_inf_priv* priv, bool enable) {
160157
return usb_control_msg(priv->priv_dev->udev,
161-
usb_sndctrlpipe(priv->priv_dev->udev, 0),
162-
0xDC, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
163-
enable ? SAFETY_ALLOUTPUT : SAFETY_SILENT, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
158+
usb_sndctrlpipe(priv->priv_dev->udev, 0),
159+
0xDC, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
160+
enable ? SAFETY_ALLOUTPUT : SAFETY_SILENT, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
164161
}
165162

166163
static void panda_usb_write_bulk_callback(struct urb *urb)
@@ -173,8 +170,7 @@ static void panda_usb_write_bulk_callback(struct urb *urb)
173170
netdev = ctx->priv->netdev;
174171

175172
/* free up our allocated buffer */
176-
usb_free_coherent(urb->dev, urb->transfer_buffer_length,
177-
urb->transfer_buffer, urb->transfer_dma);
173+
usb_free_coherent(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma);
178174

179175
if (!netif_device_present(netdev))
180176
return;
@@ -191,10 +187,7 @@ static void panda_usb_write_bulk_callback(struct urb *urb)
191187
panda_usb_free_ctx(ctx);
192188
}
193189

194-
195-
static netdev_tx_t panda_usb_xmit(struct panda_inf_priv *priv,
196-
struct panda_usb_can_msg *usb_msg,
197-
struct panda_usb_ctx *ctx)
190+
static netdev_tx_t panda_usb_xmit(struct panda_inf_priv *priv, struct panda_usb_can_msg *usb_msg, struct panda_usb_ctx *ctx)
198191
{
199192
struct urb *urb;
200193
u8 *buf;
@@ -205,9 +198,7 @@ static netdev_tx_t panda_usb_xmit(struct panda_inf_priv *priv,
205198
if (!urb)
206199
return -ENOMEM;
207200

208-
buf = usb_alloc_coherent(priv->priv_dev->udev,
209-
PANDA_USB_TX_BUFF_SIZE, GFP_ATOMIC,
210-
&urb->transfer_dma);
201+
buf = usb_alloc_coherent(priv->priv_dev->udev, PANDA_USB_TX_BUFF_SIZE, GFP_ATOMIC, &urb->transfer_dma);
211202
if (!buf) {
212203
err = -ENOMEM;
213204
goto nomembuf;
@@ -216,9 +207,9 @@ static netdev_tx_t panda_usb_xmit(struct panda_inf_priv *priv,
216207
memcpy(buf, usb_msg, PANDA_USB_TX_BUFF_SIZE);
217208

218209
usb_fill_bulk_urb(urb, priv->priv_dev->udev,
219-
usb_sndbulkpipe(priv->priv_dev->udev, 3), buf,
220-
PANDA_USB_TX_BUFF_SIZE, panda_usb_write_bulk_callback,
221-
ctx);
210+
usb_sndbulkpipe(priv->priv_dev->udev, 3), buf,
211+
PANDA_USB_TX_BUFF_SIZE, panda_usb_write_bulk_callback,
212+
ctx);
222213

223214
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
224215
usb_anchor_urb(urb, &priv->tx_submitted);
@@ -247,8 +238,7 @@ static netdev_tx_t panda_usb_xmit(struct panda_inf_priv *priv,
247238
return err;
248239
}
249240

250-
static void panda_usb_process_can_rx(struct panda_dev_priv *priv_dev,
251-
struct panda_usb_can_msg *msg)
241+
static void panda_usb_process_can_rx(struct panda_dev_priv *priv_dev, struct panda_usb_can_msg *msg)
252242
{
253243
struct can_frame *cf;
254244
struct sk_buff *skb;
@@ -258,11 +248,11 @@ static void panda_usb_process_can_rx(struct panda_dev_priv *priv_dev,
258248

259249
bus_num = (msg->bus_dat_len >> 4) & 0xf;
260250
priv_inf = panda_get_inf_from_bus_id(priv_dev, bus_num);
261-
if(!priv_inf){
251+
if (!priv_inf) {
262252
printk("Got something on an unused interface %d\n", bus_num);
263253
return;
264254
}
265-
printk("Recv bus %d\n", bus_num);
255+
//printk("Recv bus %d\n", bus_num);
266256

267257
stats = &priv_inf->netdev->stats;
268258
//u16 sid;
@@ -274,9 +264,9 @@ static void panda_usb_process_can_rx(struct panda_dev_priv *priv_dev,
274264
if (!skb)
275265
return;
276266

277-
if(msg->rir & PANDA_CAN_EXTENDED){
267+
if (msg->rir & PANDA_CAN_EXTENDED) {
278268
cf->can_id = (msg->rir >> 3) | CAN_EFF_FLAG;
279-
}else{
269+
} else {
280270
cf->can_id = (msg->rir >> 21);
281271
}
282272

@@ -298,7 +288,7 @@ static void panda_usb_process_can_rx(struct panda_dev_priv *priv_dev,
298288
netif_rx(skb);
299289
}
300290

301-
static void panda_usb_read_int_callback(struct urb *urb)
291+
static void panda_usb_read_bulk_callback(struct urb *urb)
302292
{
303293
struct panda_dev_priv *priv_dev = urb->context;
304294
int retval;
@@ -332,19 +322,20 @@ static void panda_usb_read_int_callback(struct urb *urb)
332322
}
333323

334324
resubmit_urb:
335-
usb_fill_int_urb(urb, priv_dev->udev,
336-
usb_rcvintpipe(priv_dev->udev, 1),
337-
urb->transfer_buffer, PANDA_USB_RX_BUFF_SIZE,
338-
panda_usb_read_int_callback, priv_dev, 5);
325+
usb_fill_bulk_urb(urb, priv_dev->udev,
326+
usb_rcvbulkpipe(priv_dev->udev, 1),
327+
urb->transfer_buffer, PANDA_USB_RX_BUFF_SIZE,
328+
panda_usb_read_bulk_callback, priv_dev);
339329

340330
retval = usb_submit_urb(urb, GFP_ATOMIC);
341331

342-
if (retval == -ENODEV){
343-
for(inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++)
344-
if(priv_dev->interfaces[inf_num])
345-
netif_device_detach(priv_dev->interfaces[inf_num]->netdev);
346-
}else if (retval)
332+
if (retval == -ENODEV) {
333+
for (inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++)
334+
if (priv_dev->interfaces[inf_num])
335+
netif_device_detach(priv_dev->interfaces[inf_num]->netdev);
336+
} else if (retval) {
347337
dev_err(priv_dev->dev, "failed resubmitting read bulk urb: %d\n", retval);
338+
}
348339
}
349340

350341

@@ -355,12 +346,12 @@ static int panda_usb_start(struct panda_dev_priv *priv_dev)
355346
u8 *buf;
356347
int inf_num;
357348

358-
for(inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++)
349+
for (inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++)
359350
panda_init_ctx(priv_dev->interfaces[inf_num]);
360351

361-
err = usb_set_interface(priv_dev->udev, 0, 1);
352+
err = usb_set_interface(priv_dev->udev, 0, 0);
362353
if (err) {
363-
dev_err(priv_dev->dev, "Can not set alternate setting to 1, error: %i", err);
354+
dev_err(priv_dev->dev, "Can not set alternate setting to 0, error: %i", err);
364355
return err;
365356
}
366357

@@ -370,27 +361,25 @@ static int panda_usb_start(struct panda_dev_priv *priv_dev)
370361
return -ENOMEM;
371362
}
372363

373-
buf = usb_alloc_coherent(priv_dev->udev, PANDA_USB_RX_BUFF_SIZE,
374-
GFP_KERNEL, &urb->transfer_dma);
364+
buf = usb_alloc_coherent(priv_dev->udev, PANDA_USB_RX_BUFF_SIZE, GFP_KERNEL, &urb->transfer_dma);
375365
if (!buf) {
376366
dev_err(priv_dev->dev, "No memory left for USB buffer\n");
377367
usb_free_urb(urb);
378368
return -ENOMEM;
379369
}
380370

381-
usb_fill_int_urb(urb, priv_dev->udev,
382-
usb_rcvintpipe(priv_dev->udev, 1),
383-
buf, PANDA_USB_RX_BUFF_SIZE,
384-
panda_usb_read_int_callback, priv_dev, 5);
371+
usb_fill_bulk_urb(urb, priv_dev->udev,
372+
usb_rcvbulkpipe(priv_dev->udev, 1),
373+
buf, PANDA_USB_RX_BUFF_SIZE,
374+
panda_usb_read_bulk_callback, priv_dev);
385375
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
386376

387377
usb_anchor_urb(urb, &priv_dev->rx_submitted);
388378

389379
err = usb_submit_urb(urb, GFP_KERNEL);
390380
if (err) {
391381
usb_unanchor_urb(urb);
392-
usb_free_coherent(priv_dev->udev, PANDA_USB_RX_BUFF_SIZE,
393-
buf, urb->transfer_dma);
382+
usb_free_coherent(priv_dev->udev, PANDA_USB_RX_BUFF_SIZE, buf, urb->transfer_dma);
394383
usb_free_urb(urb);
395384
dev_err(priv_dev->dev, "Failed in start, while submitting urb.\n");
396385
return err;
@@ -439,8 +428,7 @@ static int panda_usb_close(struct net_device *netdev)
439428
return 0;
440429
}
441430

442-
static netdev_tx_t panda_usb_start_xmit(struct sk_buff *skb,
443-
struct net_device *netdev)
431+
static netdev_tx_t panda_usb_start_xmit(struct sk_buff *skb, struct net_device *netdev)
444432
{
445433
struct panda_inf_priv *priv_inf = netdev_priv(netdev);
446434
struct can_frame *cf = (struct can_frame *)skb->data;
@@ -450,7 +438,7 @@ static netdev_tx_t panda_usb_start_xmit(struct sk_buff *skb,
450438
struct panda_usb_can_msg usb_msg = {};
451439
int bus = priv_inf->mcu_can_ifnum;
452440

453-
if (can_dropped_invalid_skb(netdev, skb)){
441+
if (can_dropped_invalid_skb(netdev, skb)) {
454442
printk("Invalid CAN packet");
455443
return NETDEV_TX_OK;
456444
}
@@ -461,10 +449,9 @@ static netdev_tx_t panda_usb_start_xmit(struct sk_buff *skb,
461449
//everywhere and encouraged in the documentation.
462450
can_put_echo_skb(skb, priv_inf->netdev, ctx->ndx, NULL);
463451

464-
if(cf->can_id & CAN_EFF_FLAG){
465-
usb_msg.rir = cpu_to_le32(((cf->can_id & 0x1FFFFFFF) << 3) |
466-
PANDA_CAN_TRANSMIT | PANDA_CAN_EXTENDED);
467-
}else{
452+
if (cf->can_id & CAN_EFF_FLAG) {
453+
usb_msg.rir = cpu_to_le32(((cf->can_id & 0x1FFFFFFF) << 3) | PANDA_CAN_TRANSMIT | PANDA_CAN_EXTENDED);
454+
} else {
468455
usb_msg.rir = cpu_to_le32(((cf->can_id & 0x7FF) << 21) | PANDA_CAN_TRANSMIT);
469456
}
470457
usb_msg.bus_dat_len = cpu_to_le32((cf->can_dlc & 0x0F) | (bus << 4));
@@ -475,7 +462,7 @@ static netdev_tx_t panda_usb_start_xmit(struct sk_buff *skb,
475462
//if (cf->can_id & CAN_RTR_FLAG)
476463
// usb_msg.dlc |= PANDA_DLC_RTR_MASK;
477464

478-
netdev_err(netdev, "Received data from socket. canid: %x; len: %d\n", cf->can_id, cf->can_dlc);
465+
// printk("Received data from socket. bus: %x; canid: %x; len: %d\n", priv_inf->mcu_can_ifnum, cf->can_id, cf->can_dlc);
479466

480467
err = panda_usb_xmit(priv_inf, &usb_msg, ctx);
481468
if (err)
@@ -498,8 +485,7 @@ static const struct net_device_ops panda_netdev_ops = {
498485
.ndo_start_xmit = panda_usb_start_xmit,
499486
};
500487

501-
static int panda_usb_probe(struct usb_interface *intf,
502-
const struct usb_device_id *id)
488+
static int panda_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
503489
{
504490
struct net_device *netdev;
505491
struct panda_inf_priv *priv_inf;
@@ -518,7 +504,7 @@ static int panda_usb_probe(struct usb_interface *intf,
518504
usb_set_intfdata(intf, priv_dev);
519505

520506
////// Interface privs
521-
for(inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++){
507+
for (inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++) {
522508
netdev = alloc_candev(sizeof(struct panda_inf_priv), PANDA_MAX_TX_URBS);
523509
if (!netdev) {
524510
dev_err(&intf->dev, "Couldn't alloc candev\n");
@@ -569,13 +555,14 @@ static int panda_usb_probe(struct usb_interface *intf,
569555
return 0;
570556

571557
cleanup_candev:
572-
for(inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++){
558+
for (inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++) {
573559
priv_inf = priv_dev->interfaces[inf_num];
574-
if(priv_inf){
560+
if (priv_inf) {
575561
unregister_candev(priv_inf->netdev);
576562
free_candev(priv_inf->netdev);
577-
}else
563+
} else {
578564
break;
565+
}
579566
}
580567

581568
kfree(priv_dev);
@@ -592,14 +579,15 @@ static void panda_usb_disconnect(struct usb_interface *intf)
592579

593580
usb_set_intfdata(intf, NULL);
594581

595-
for(inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++){
582+
for (inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++) {
596583
priv_inf = priv_dev->interfaces[inf_num];
597-
if(priv_inf){
584+
if (priv_inf) {
598585
netdev_info(priv_inf->netdev, "device disconnected\n");
599586
unregister_candev(priv_inf->netdev);
600587
free_candev(priv_inf->netdev);
601-
}else
588+
} else {
602589
break;
590+
}
603591
}
604592

605593
panda_urb_unlink(priv_inf);

0 commit comments

Comments
 (0)