pcan: usb_submit_urb() hangs in peak_usb_ndo_start_xmit()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi folks!

I think we spotted a problem in the pcan_usb_fd device driver. I
tracked it down but I have no idea if this is actually a device or a
driver problem. First things first. Wo do stuff with can(-fd) and iso-
tp using the pcan pro fd interface and we discovered a weird cornercase
which can be reproduced with the attached python script.

For the reproducer setup take a pcan pro fd, connect channel 1 to
channel 2 and set the device up (for both channels) like the following:

# ip link set can0 type can bitrate 500000 dbitrate 2000000 fd on
# ip link set can1 type can bitrate 500000 dbitrate 2000000 fd on

Then run isotprecv:

# isotprecv -l -d 0x650 -s 0x6f0 -L 72:64:1 can1

And start the attached poc.py script.

The very can frame which poc.py should send is:

  25 ff

But this can frame is always missing on the bus. It is missing in the
output of candump or wireshark as well. This behaviour seems to be
dependent on how many consecutive iso-tp frames are generated. In other
words, large iso-tp packets are truncated. This can not be reproduced
via the virtual vcan interface.

This cornercase unfortunately breaks our testing setups. Let's track it
down. I did a few rounds of pr_debug() debugging.

-----------------------------------------------------------------------
af_can.c

I checked if this problem originates from the isotp module by checking
the input of can_send() in af_can.c. Everything looks fine there:

[snip]
Dez 15 21:33:12 kronos kernel: 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  $...............
Dez 15 21:33:12 kronos kernel: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Dez 15 21:33:12 kronos kernel: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Dez 15 21:33:12 kronos kernel: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Dez 15 21:33:12 kronos kernel: can_send: calling queue xmit
Dez 15 21:33:12 kronos kernel: 25 ff                                            %.
Dez 15 21:33:12 kronos kernel: can_send: calling queue xmit

------------------------------------------------------------------------
pcan_usb_core.c

I went one layer deeper and took a look at peak_usb_ndo_start_xmit(),
especially the usb_submit_urb() call. The problem seems to be that the
very last call to usb_submit_urb() call blocks for over a minute.

Dez 15 21:33:12 kronos kernel: peak_usb_ndo_start_xmit: submitting urb
Dez 15 21:33:12 kronos kernel: peak_usb_ndo_start_xmit: urb success
Dez 15 21:33:12 kronos kernel: peak_usb_ndo_start_xmit: submitting urb
Dez 15 21:41:59 kronos kernel: peak_usb_ndo_start_xmit: urb success         <---- ??


Anybody out there who can help me tracking this down further?

Stefan
#!/usr/bin/env python3

import socket
import struct
import time


# Socket Constants not available in the socket module
# https://github.com/hartkopp/can-isotp/blob/master/include/uapi/linux/can/isotp.h
SOL_CAN_ISOTP = socket.SOL_CAN_BASE + socket.CAN_ISOTP

# Valuetypes for SOL_CAN_ISOTP
CAN_ISOTP_OPTS = 1
CAN_ISOTP_RECV_FC = 2
CAN_ISOTP_TX_STMIN = 3
CAN_ISOTP_RX_STMIN = 4
CAN_ISOTP_LL_OPTS = 5

# Flags for setsockopt CAN_ISOTP_OPTS
CAN_ISOTP_LISTEN_MODE = 0x001
CAN_ISOTP_EXTEND_ADDR = 0x002
CAN_ISOTP_TX_PADDING = 0x004
CAN_ISOTP_RX_PADDING = 0x008
CAN_ISOTP_CHK_PAD_LEN = 0x010
CAN_ISOTP_CHK_PAD_DATA = 0x020
CAN_ISOTP_HALF_DUPLEX = 0x040
CAN_ISOTP_FORCE_TXSTMIN = 0x080
CAN_ISOTP_FORCE_RXSTMIN = 0x100
CAN_ISOTP_RX_EXT_ADDR = 0x200


sock = socket.socket(socket.PF_CAN, socket.SOCK_DGRAM, socket.CAN_ISOTP)
sock.bind(("can0", 0x6f0, 0x650))
# data = struct.pack("@IIBBBB", flags, frame_txtime, ext_addr,
#                    txpad_content, rxpad_content, rx_ext_address)
# sock.setsockopt(self.SOL_CAN_ISOTP, self.CAN_ISOTP_OPTS, data)
canmtu = 72
data = struct.pack("@BBB", canmtu, 64, 0)
sock.setsockopt(SOL_CAN_ISOTP, CAN_ISOTP_LL_OPTS, data)


# for i in range(0x40):
sock.send(b"\x00"*(0x529)+b"\xff")
time.sleep(0.05)
sock.send(b"\x00"*(0x52a)+b"\xff")
# time.sleep(0.05)
# sock.send(b"\xCA\xCA\xCA\xCA")
# time.sleep(0.05)

[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux