Skip to contentSkip to conversation

can, tty: elmcan CAN/ldisc driver for ELM327 based OBD-II adapters

PATCH Superseded Max Staudt 3 participants 4 messages May 2, 2022 – May 3, 2022

Subsystems (4)

v4 of 9 Superseded Latest is v9 →

lore
Share & tools
lore

Max Staudt

author
#0 lore raw

PATCH v4 1/1 can, tty: elmcan CAN/ldisc driver for ELM327 based OBD-II adapters

This is the elmcan driver. It does a surprisingly good job at turning ELM327 based OBD-II interfaces into cheap CAN interfaces for simple homebrew projects.

Please see the included documentation for details and limitations:
Documentation/networking/device_drivers/can/elmcan.rst

---
Many thanks to Greg, Marc, Vincent for reviewing v3!

I've CC'd you hoping you'd check whether you are happy with the changes. Please do let me know.

Changes in v4:
- Rebased on top of v5.18-rc5
- Simplified TTY locking.
The ldisc layer already blocks our ldisc ops from running concurrently. No elm_get(), no RCU are needed, except locking against the TX worker.
- Removed .hangup() ldisc op which only called .close().
The ldisc layer calls .close() in a good place anyway.
- Restart on netdev down/up, even after UART failure.
This is in line with Marc's line of thinking, and there was no good reason not to implement it. It also cleaned up the code.
- hw_failure is now uart_side_failure and shutdown looks closer to es58x.
- Clarified memory/string comparisons.
One helper function remains, but it's hopefully clear now :)
- lockdep_assert_held() instead of comments.
- Cleaned up types in struct elmcan and used pahole to pack it. unsigned instead of int, u8 instead of char, ...
- The TX buffer is now a static part of struct elmcan. No more kmalloc().
- Removed dummy mailbox_read() for rx_offload.
by using can_rx_offload_add_manual() instead of can_rx_offload_add_fifo().
- netif_wake_queue() is moved to happen as late as possible.
Wake when the ELM327 is going into monitoring mode, not every time after flushing whatever UART buffer we were TX'ing.
- Use alloc_can_skb() and avoid late allocation and copy.
- elmcan_netdev_start_xmit(): Used can_dropped_invalid_skb().
- Replaced ->can_dlc with ->len.
- Clarified size of local TX buffer in elm327_handle_prompt().
- Renamed TODO_* to ELM327_TX_DO_* and ELM_* to ELM327_STATE_*.
- Minor string and other cleanups.
pr_fmt, MODULE_*, unnecessary checks, ...
- Clarified file header.

Changes in v3:
- Now depends on c2faf737abfb for new ldisc number 30.
- Eliminated hardcoded string lengths (GCC will work its magic).
- Emit generic error frames if an error message couldn't be parsed.
- Silence driver startup and init (but still announce ldattach).
- Cleaned up comments, strings, readme.
- Removed sole module option "accept_flaky_uart".
I likely had EMI in earlier testing, which is gone now. This means we can stay strict, unless anyone objects.

Changes in v2:
- Moved to SocketCAN's rx-offload wrapper for NAPI, thus avoiding packets being reordered.
- Updated TTY ldisc code for Linux v5.17-rc3. A lot of cleanup has happened there lately.
- netif_stop_queue() is called earlier in _netdev_close().
- Minor cleanup: More helpful strings and return values.

---
 .../networking/device_drivers/can/elmcan.rst  |  325 +++++
 .../networking/device_drivers/can/index.rst   |    1 +
 MAINTAINERS                                   |    7 +
 drivers/net/can/Kconfig                       |   17 +
 drivers/net/can/Makefile                      |    1 +
 drivers/net/can/elmcan.c                      | 1144 +++++++++++++++++
 include/uapi/linux/tty.h                      |    3 +-
 7 files changed, 1497 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/networking/device_drivers/can/elmcan.rst
 create mode 100644 drivers/net/can/elmcan.c
Documentation/networking/device_drivers/can/elmcan.rst new file +325 -0
new file mode 100644
index 000000000000..b33a4b7da772
@@ -0,0 +1,325 @@
+.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+
+ELM327 driver for Linux SocketCAN
+==================================
+
+Authors
+--------
+
+Max Staudt <[email protected]>
+
+
+
+Motivation
+-----------
+
+This driver aims to lower the initial cost for hackers interested in
+working with CAN buses.
+
+CAN adapters are expensive, few, and far between.
+ELM327 interfaces are cheap and plentiful.
+Let's use ELM327s as CAN adapters.
+
+
+
+Introduction
+-------------
+
+This driver is an effort to turn abundant ELM327 based OBD interfaces
+into full fledged (as far as possible) CAN interfaces.
+
+Since the ELM327 was never meant to be a stand alone CAN controller,
+the driver has to switch between its modes as quickly as possible in
+order to fake full-duplex operation.
+
+As such, elmcan is a best effort driver. However, this is more than
+enough to implement simple request-response protocols (such as OBD II),
+and to monitor broadcast messages on a bus (such as in a vehicle).
+
+Most ELM327s come as nondescript serial devices, attached via USB or
+Bluetooth. The driver cannot recognize them by itself, and as such it
+is up to the user to attach it in form of a TTY line discipline
+(similar to PPP, SLIP, slcan, ...).
+
+This driver is meant for ELM327 versions 1.4b and up, see below for
+known limitations in older controllers and clones.
+
+
+
+Data sheet
+-----------
+
+The official data sheets can be found at ELM electronics' home page:
+
+  https://www.elmelectronics.com/
+
+
+
+How to check the controller version
+------------------------------------
+
+Use a terminal program to attach to the controller.
+The default settings are 38400 baud/s, 8 data bits, no parity, 1 stopbit.
+
+After issuing the "``AT WS``" command, the controller will respond with
+its version::
+
+    >AT WS
+
+
+    ELM327 v1.4b
+
+    >
+
+Note that clones may claim to be any version they like.
+It is not indicative of their actual feature set.
+
+
+
+How to attach the line discipline
+----------------------------------
+
+Every ELM327 chip is factory programmed to operate at a serial setting
+of 38400 baud/s, 8 data bits, no parity, 1 stopbit.
+
+The line discipline can be attached on a command prompt as follows::
+
+    sudo ldattach \
+           --debug \
+           --speed 38400 \
+           --eightbits \
+           --noparity \
+           --onestopbit \
+           --iflag -ICRNL,INLCR,-IXOFF \
+           30 \
+           /dev/ttyUSB0
+
+To change the ELM327's serial settings, please refer to its data
+sheet. This needs to be done before attaching the line discipline.
+
+Once the ldisc is attached, the CAN interface starts out unconfigured.
+Set the speed before starting it:
+
+    # The interface needs to be down to change parameters
+    sudo ip link set can0 down
+    sudo ip link set can0 type can bitrate 500000
+    sudo ip link set can0 up
+
+500000 bit/s is a common rate for OBD-II diagnostics.
+If you're connecting straight to a car's OBD port, this is the speed
+that most cars (but not all!) expect.
+
+After this, you can set out as usual with candump, cansniffer, etc.
+
+
+
+Known limitations of the controller
+------------------------------------
+
+- Clone devices ("v1.5" and others)
+
+  Sending RTR frames is not supported and will be dropped silently.
+
+  Receiving RTR with DLC 8 will appear to be a regular frame with
+  the last received frame's DLC and payload.
+
+  "``AT CSM``" not supported, thus no ACK-ing frames while listening:
+  "``AT MA``" will always be silent. However, immediately after
+  sending a frame, the ELM327 will be in "receive reply" mode, in
+  which it *does* ACK any received frames. Once the bus goes silent
+  or an error occurs (such as BUFFER FULL), the ELM327 will end reply
+  reception mode on its own and elmcan will fall back to "``AT MA``"
+  in order to keep monitoring the bus.
+
+
+- All versions
+
+  No full duplex operation is supported. The driver will switch
+  between input/output mode as quickly as possible.
+
+  The length of outgoing RTR frames cannot be set. In fact, some
+  clones (tested with one identifying as "``v1.5``") are unable to
+  send RTR frames at all.
+
+  We don't have a way to get real-time notifications on CAN errors.
+  While there is a command (``AT CS``) to retrieve some basic stats,
+  we don't poll it as it would force us to interrupt reception mode.
+
+
+- Versions prior to 1.4b
+
+  These versions do not send CAN ACKs when in monitoring mode (AT MA).
+  However, they do send ACKs while waiting for a reply immediately
+  after sending a frame. The driver maximizes this time to make the
+  controller as useful as possible.
+
+  Starting with version 1.4b, the ELM327 supports the "``AT CSM``"
+  command, and the "listen-only" CAN option will take effect.
+
+
+- Versions prior to 1.4
+
+  These chips do not support the "``AT PB``" command, and thus cannot
+  change bitrate or SFF/EFF mode on-the-fly. This will have to be
+  programmed by the user before attaching the line discipline. See the
+  data sheet for details.
+
+
+- Versions prior to 1.3
+
+  These chips cannot be used at all with elmcan. They do not support
+  the "``AT D1``" command, which is necessary to avoid parsing conflicts
+  on incoming data, as well as distinction of RTR frame lengths.
+
+  Specifically, this allows for easy distinction of SFF and EFF
+  frames, and to check whether frames are complete. While it is possible
+  to deduce the type and length from the length of the line the ELM327
+  sends us, this method fails when the ELM327's UART output buffer
+  overruns. It may abort sending in the middle of the line, which will
+  then be mistaken for something else.
+
+
+
+Known limitations of the driver
+--------------------------------
+
+- No 8/7 timing.
+
+  ELM327 can only set CAN bitrates that are of the form 500000/n, where
+  n is an integer divisor.
+  However there is an exception: With a separate flag, it may set the
+  speed to be 8/7 of the speed indicated by the divisor.
+  This mode is not currently implemented.
+
+- No evaluation of command responses.
+
+  The ELM327 will reply with OK when a command is understood, and with ?
+  when it is not. The driver does not currently check this, and simply
+  assumes that the chip understands every command.
+  The driver is built such that functionality degrades gracefully
+  nevertheless. See the section on known limitations of the controller.
+
+- No use of hardware CAN ID filtering
+
+  An ELM327's UART sending buffer will easily overflow on heavy CAN bus
+  load, resulting in the "``BUFFER FULL``" message. Using the hardware
+  filters available through "``AT CF xxx``" and "``AT CM xxx``" would be
+  helpful here, however SocketCAN does not currently provide a facility
+  to make use of such hardware features.
+
+
+
+Communication example
+----------------------
+
+This is a short and incomplete introduction on how to talk to an ELM327.
+
+
+The ELM327 has two modes:
+
+- Command mode
+- Reception mode
+
+In command mode, it expects one command per line, terminated by CR.
+By default, the prompt is a "``>``", after which a command can be
+entered::
+
+    >ATE1
+    OK
+    >
+
+The init script in the driver switches off several configuration options
+that are only meaningful in the original OBD scenario the chip is meant
+for, and are actually a hindrance for elmcan.
+
+
+When a command is not recognized, such as by an older version of the
+ELM327, a question mark is printed as a response instead of OK::
+
+    >ATUNKNOWN
+    ?
+    >
+
+At present, elmcan does not evaluate this response and silently assumes
+that all commands are recognized. It is structured such that it will
+degrade gracefully when a command is unknown. See the sections above on
+known limitations for details.
+
+
+When a CAN frame is to be sent, the target address is configured, after
+which the frame is sent as a command that consists of the data's hex
+dump::
+
+    >ATSH123
+    OK
+    >DEADBEEF12345678
+    OK
+    >
+
+The above interaction sends the frame "``DE AD BE EF 12 34 56 78``" with
+the 11 bit CAN ID ``0x123``.
+For this to function, the controller must be configured for 11 bit CAN
+ID sending mode (using "``AT PB``", see code or datasheet).
+
+
+Once a frame has been sent and wait-for-reply mode is on (``ATR1``,
+configured on ``listen-only=off``), or when the reply timeout expires and
+the driver sets the controller into monitoring mode (``ATMA``), the ELM327
+will send one line for each received CAN frame, consisting of CAN ID,
+DLC, and data::
+
+    123 8 DEADBEEF12345678
+
+For 29 bit CAN frames, the address format is slightly different, which
+elmcan uses to tell the two apart::
+
+    12 34 56 78 8 DEADBEEF12345678
+
+The ELM327 will receive both 11 and 29 bit frames - the current CAN
+config (``ATPB``) does not matter.
+
+
+If the ELM327's internal UART sending buffer runs full, it will abort
+the monitoring mode, print "BUFFER FULL" and drop back into command
+mode. Note that in this case, unlike with other error messages, the
+error message may appear on the same line as the last (usually
+incomplete) data frame::
+
+    12 34 56 78 8 DEADBEEF123 BUFFER FULL
+
+
+
+Rationale behind the chosen configuration
+------------------------------------------
+
+``AT E1``
+  Echo on
+
+  We need this to be able to get a prompt reliably.
+
+``AT S1``
+  Spaces on
+
+  We need this to distinguish 11/29 bit CAN addresses received.
+
+  Note:
+  We can usually do this using the line length (odd/even),
+  but this fails if the line is not transmitted fully to
+  the host (BUFFER FULL).
+
+``AT D1``
+  DLC on
+
+  We need this to tell the "length" of RTR frames.
+
+
+
+A note on CAN bus termination
+------------------------------
+
+Your adapter may have resistors soldered in which are meant to terminate
+the bus. This is correct when it is plugged into a OBD-II socket, but
+not helpful when trying to tap into the middle of an existing CAN bus.
+
+If communications don't work with the adapter connected, check for the
+termination resistors on its PCB and try removing them.
Documentation/networking/device_drivers/can/index.rst +1 -0
index 58b6e0ad3030..e3f2be735aef 100644
@@ -10,6 +10,7 @@ Contents:
 .. toctree::
    :maxdepth: 2
 
+   elmcan
    freescale/flexcan
 
 .. only::  subproject and html
MAINTAINERS +7 -0
index edc96cdb85e8..8a1f2bf82407 100644
@@ -7218,6 +7218,13 @@ L:	[email protected]
 S:	Maintained
 F:	drivers/net/ethernet/ibm/ehea/
 
+ELM327 CAN NETWORK DRIVER
+M:	Max Staudt <[email protected]>
+L:	[email protected]
+S:	Maintained
+F:	Documentation/networking/device_drivers/can/elmcan.rst
+F:	drivers/net/can/elmcan.c
+
 EM28XX VIDEO4LINUX DRIVER
 M:	Mauro Carvalho Chehab <[email protected]>
 L:	[email protected]
drivers/net/can/Kconfig +17 -0
index fff259247d52..226bd00fc048 100644
@@ -180,6 +180,23 @@ source "drivers/net/can/softing/Kconfig"
 source "drivers/net/can/spi/Kconfig"
 source "drivers/net/can/usb/Kconfig"
 
+config CAN_ELMCAN
+	tristate "Serial / USB serial ELM327 based OBD-II Interfaces (elmcan)"
+	depends on TTY
+	help
+	  CAN driver for several 'low cost' OBD-II interfaces based on the
+	  ELM327 OBD-II interpreter chip.
+
+	  This is a best effort driver - the ELM327 interface was never
+	  designed to be used as a standalone CAN interface. However, it can
+	  still be used for simple request-response protocols (such as OBD II),
+	  and to monitor broadcast messages on a bus (such as in a vehicle).
+
+	  Please refer to the documentation for information on how to use it:
+	  Documentation/networking/device_drivers/can/elmcan.rst
+
+	  If this driver is built as a module, it will be called elmcan.
+
 endif
 
 config CAN_DEBUG_DEVICES
drivers/net/can/Makefile +1 -0
index 1e660afcb61b..c25a0f8a397b 100644
@@ -6,6 +6,7 @@
 obj-$(CONFIG_CAN_VCAN)		+= vcan.o
 obj-$(CONFIG_CAN_VXCAN)		+= vxcan.o
 obj-$(CONFIG_CAN_SLCAN)		+= slcan.o
+obj-$(CONFIG_CAN_ELMCAN)	+= elmcan.o
 
 obj-y				+= dev/
 obj-y				+= rcar/
drivers/net/can/elmcan.c new file +1144 -0

1,144 lines not on this page · raw message

include/uapi/linux/tty.h +2 -1
index 9d0f06bfbac3..bd034d0511f6 100644
@@ -38,8 +38,9 @@
 #define N_NULL		27	/* Null ldisc used for error handling */
 #define N_MCTP		28	/* MCTP-over-serial */
 #define N_DEVELOPMENT	29	/* Manual out-of-tree testing */
+#define N_ELMCAN	30	/* Serial / USB serial OBD-II Interfaces */
 
 /* Always the newest line discipline + 1 */
-#define NR_LDISCS	30
+#define NR_LDISCS	31
 
 #endif /* _UAPI_LINUX_TTY_H */
Signature · 1 line
2.30.2
#1 lore raw
I love your patch! Yet something to improve:

Hi Max,

I love your patch! Yet something to improve:

[auto build test ERROR on tty/tty-testing]
[also build test ERROR on linus/master v5.18-rc5 next-20220502] [cannot apply to mkl-can-next/testing linux/master]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Max-Staudt/can-tty-elmcan-CAN-ldisc-driver-for-ELM327-based-OBD-II-adapters/20220502-232340
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20220503/[email protected]/config)
compiler: arceb-elf-gcc (GCC) 11.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/abb85fc1dc50ffca72049df7c5714a83d081d6f6
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Max-Staudt/can-tty-elmcan-CAN-ldisc-driver-for-ELM327-based-OBD-II-adapters/20220502-232340 git checkout abb85fc1dc50ffca72049df7c5714a83d081d6f6
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

In file included from arch/arc/include/asm/bug.h:30,
from include/linux/bug.h:5, from include/linux/cpumask.h:14, from include/linux/mm_types_task.h:14, from include/linux/mm_types.h:5, from include/linux/buildid.h:5, from include/linux/module.h:14, from drivers/net/can/elmcan.c:16:
drivers/net/can/elmcan.c: In function 'elm327_send':

>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:130:9: note: in expansion of macro 'lockdep_assert_held'
     130 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_kick_into_cmd_mode':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:160:9: note: in expansion of macro 'lockdep_assert_held'
     160 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_send_frame':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:173:9: note: in expansion of macro 'lockdep_assert_held'
     173 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_init':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:235:9: note: in expansion of macro 'lockdep_assert_held'
     235 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_feed_frame_to_netdev':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:265:9: note: in expansion of macro 'lockdep_assert_held'
     265 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_uart_side_failure':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:286:9: note: in expansion of macro 'lockdep_assert_held'
     286 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_parse_error':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:327:9: note: in expansion of macro 'lockdep_assert_held'
     327 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_parse_frame':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:394:9: note: in expansion of macro 'lockdep_assert_held'
     394 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_parse_line':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:516:9: note: in expansion of macro 'lockdep_assert_held'
     516 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_handle_prompt':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:550:9: note: in expansion of macro 'lockdep_assert_held'
     550 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_drop_bytes':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:655:9: note: in expansion of macro 'lockdep_assert_held'
     655 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c: In function 'elm327_parse_rxbuf':
>> include/linux/lockdep.h:286:61: error: invalid type argument of '->' (have 'spinlock_t' {aka 'struct spinlock'})
     286 | #define lockdep_is_held(lock)           lock_is_held(&(lock)->dep_map)
         |                                                             ^~
   include/asm-generic/bug.h:122:32: note: in definition of macro 'WARN_ON'
     122 |         int __ret_warn_on = !!(condition);                              \
         |                                ^~~~~~~~~
   include/linux/lockdep.h:316:9: note: in expansion of macro 'lockdep_assert'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |         ^~~~~~~~~~~~~~
   include/linux/lockdep.h:316:24: note: in expansion of macro 'lockdep_is_held'
     316 |         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
         |                        ^~~~~~~~~~~~~~~
   drivers/net/can/elmcan.c:666:9: note: in expansion of macro 'lockdep_assert_held'
     666 |         lockdep_assert_held(elm->lock);
         |         ^~~~~~~~~~~~~~~~~~~

vim +286 include/linux/lockdep.h

f607c668577481 Peter Zijlstra 2009-07-20 285
f8319483f57f1c Peter Zijlstra 2016-11-30 @286 #define lockdep_is_held(lock) lock_is_held(&(lock)->dep_map)
f8319483f57f1c Peter Zijlstra 2016-11-30 287 #define lockdep_is_held_type(lock, r) lock_is_held_type(&(lock)->dep_map, (r))
f607c668577481 Peter Zijlstra 2009-07-20 288

Signature · 2 lines
0-DAY CI Kernel Test Service
https://01.org/lkp
author
#2 lore raw
Quoted 5 lines · On Tue, 3 May 2022 07:33:06 +0800 kernel test robot <[email protected]> wrote:

Hi Max,

I love your patch! Yet something to improve:

...

Thanks, kernel test robot!

I'll head off and fix stuff.

For any reviewers: I'll post a v5 soon.

Max

#3 lore raw
Quoted 1 line · Max Staudt

I'll head off and fix stuff.

Can you build and test the driver on an lockdep enabled kernel?

regards,
Marc

Signature · 4 lines
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |