summaryrefslogtreecommitdiffstats
path: root/Documentation/i2c/slave-testunit-backend.rst
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-30 09:22:00 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-30 09:22:00 -0700
commit034dd340b08be1f2f0477ad16131d609f9dbd53c (patch)
tree2536f4b2d7893ccd916b5abdf3c454ad6edc03c2 /Documentation/i2c/slave-testunit-backend.rst
downloadlinux-stable-034dd340b08be1f2f0477ad16131d609f9dbd53c.tar.gz
linux-stable-034dd340b08be1f2f0477ad16131d609f9dbd53c.zip
Merge tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-tracegrafted
Pull tracing fixes from Steven Rostedt: - Fix error output of boot instance creation failure Currently if a boot instance creation fails, instead of printing out the name of the instance that failed, it prints "(null)". That is because it prints "cur_str" that had already been processed by strsep(). Print the saved name instead. While at it, print the error code of the failure. - Fix use-after-free for same named historgrams Histograms can be named so that they can be used in multiple events. But if the named histogram has a variable attached, the second event that uses the named histogram which duplicates it and needs to free the original after duplication leaves the old variable in place and still visible. If another histogram uses than variable, it will use the stale one which will try to reference the freed duplicate histogram and crash the kernel. Free the duplicate variables along with the duplicated histogram data. - Check return value of kthread_run() in event self test The events self tests uses a kthread for testing but does not check if it succeeded in creating a kthread. If the kthread creation were to fail, the code will still try to call kthread_stop() on the error returned. - Fix race between reading trace_pipe and updating subbuffer size If a user is reading the trace_pipe file at the same time they update the ring buffer sub-buffer size, can cause the trace_pipe read to read stale data. Add trace_access_lock() around updating the ring buffer sub-buffer size. - Fix eventfs_inode on failure path in creation of the events directory In the creation of the "events" directory, if after allocating the eventfs_inode a failure is detected, it calls cleanup_ei() which calls free_ei(). The free_ei() will test if eventfs_inode being freed has no children. It is a bug if it does. But on the failure case of the creation of the "events" directory, the children lists have not yet been initialized and the free will trigger a warning because list_empty() on an uninitialized list returns false. Move the initialization into init_ei() where it makes more sense and makes sure that a created eventfs_inode has its lists initialized upon creation. - Check return value of kthread_run() in ftrace direct sample code The sample code that shows how to use the ftrace direct calls does not test the return of kthread_run() to see if it succeeds. Return a failure if the kthread_run() doesn't succeed. - Clear user events state on fork in case of alloc failure On fork, the child gets a pointer to the parent's user events state. It makes a copy of it then updates the child's pointer to it. But if the allocation fails, the duplication function leaves the child with a pointer to its parent's descriptor. When the child cleans up its data, it will free the parent's descriptor while the parent is still using it. In the duplication function, set the child's user_event_mm to NULL before testing if the allocation succeeded, and when it exits it will not free the parent's descriptor. - Fix retry exhaustion in simple ring buffer reader swap simple_ring_buffer_swap_reader_page() starts with retry set to 8 and post-decrements it only after a failed link replacement. On the final attempt, a successful replacement leaves retry at zero, while a failed replacement leaves it at -1. But the check for success expects the retry value to be non-zero and exits with an error on zero. This is the opposite result. Fix it. - Fail nicely when the remote swap_reader_page() returns an error Currently, if the swap_reader_page() of a remote buffer fails, it triggers a WARN_ON_ONCE() and continues normally. Instead, have it exit with an error and a pr_warn() print instead of a full WARNING. * tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: ring-buffer: Stop remote reader update when page swap fails tracing: Fix retry exhaustion in simple ring buffer reader swap tracing/user_events: Clear copied tracing state before fork duplication samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-multi-modify samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-modify eventfs: Initialize ei->children and ei->list in init_ei() tracing: Fix use-after-free in trace_pipe read on sub-buffer order change tracing: Fix crash passing ERR_PTR to kthread_stop() tracing: Fix use-after-free with same-name named triggers tracing: Fix logged instance name on creation failure
Diffstat (limited to 'Documentation/i2c/slave-testunit-backend.rst')
-rw-r--r--Documentation/i2c/slave-testunit-backend.rst235
1 files changed, 235 insertions, 0 deletions
diff --git a/Documentation/i2c/slave-testunit-backend.rst b/Documentation/i2c/slave-testunit-backend.rst
new file mode 100644
index 000000000..d752f433b
--- /dev/null
+++ b/Documentation/i2c/slave-testunit-backend.rst
@@ -0,0 +1,235 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+================================
+Linux I2C slave testunit backend
+================================
+
+by Wolfram Sang <wsa@sang-engineering.com> in 2020
+
+This backend can be used to trigger test cases for I2C bus masters which
+require a remote device with certain capabilities (and which are usually not so
+easy to obtain). Examples include multi-master testing, and SMBus Host Notify
+testing. For some tests, the I2C slave controller must be able to switch
+between master and slave mode because it needs to send data, too.
+
+Note that this is a device for testing and debugging. It should not be enabled
+in a production build. And while there is some versioning and we try hard to
+keep backward compatibility, there is no stable ABI guaranteed!
+
+Instantiating the device is regular. Example for bus 0, address 0x30::
+
+ # echo "slave-testunit 0x1030" > /sys/bus/i2c/devices/i2c-0/new_device
+
+Or using firmware nodes. Here is a devicetree example (note this is only a
+debug device, so there are no official DT bindings)::
+
+ &i2c0 {
+ ...
+
+ testunit@30 {
+ compatible = "slave-testunit";
+ reg = <(0x30 | I2C_OWN_SLAVE_ADDRESS)>;
+ };
+ };
+
+After that, you will have the device listening. Reading will return a single
+byte. Its value is 0 if the testunit is idle, otherwise the command number of
+the currently running command.
+
+When writing, the device consists of 4 8-bit registers and, except for some
+"partial" commands, all registers must be written to start a testcase, i.e. you
+usually write 4 bytes to the device. The registers are:
+
+.. csv-table::
+ :header: "Offset", "Name", "Description"
+
+ 0x00, CMD, which test to trigger
+ 0x01, DATAL, configuration byte 1 for the test
+ 0x02, DATAH, configuration byte 2 for the test
+ 0x03, DELAY, delay in n * 10ms until test is started
+
+Using 'i2cset' from the i2c-tools package, the generic command looks like::
+
+ # i2cset -y <bus_num> <testunit_address> <CMD> <DATAL> <DATAH> <DELAY> i
+
+DELAY is a generic parameter which will delay the execution of the test in CMD.
+While a command is running (including the delay), new commands will not be
+acknowledged. You need to wait until the old one is completed.
+
+The commands are described in the following section. An invalid command will
+result in the transfer not being acknowledged.
+
+Commands
+--------
+
+0x00 NOOP
+~~~~~~~~~
+
+Reserved for future use.
+
+0x01 READ_BYTES
+~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+
+ * - CMD
+ - DATAL
+ - DATAH
+ - DELAY
+
+ * - 0x01
+ - address to read data from (lower 7 bits, highest bit currently unused)
+ - number of bytes to read
+ - n * 10ms
+
+Also needs master mode. This is useful to test if your bus master driver is
+handling multi-master correctly. You can trigger the testunit to read bytes
+from another device on the bus. If the bus master under test also wants to
+access the bus at the same time, the bus will be busy. Example to read 128
+bytes from device 0x50 after 50ms of delay::
+
+ # i2cset -y 0 0x30 1 0x50 0x80 5 i
+
+0x02 SMBUS_HOST_NOTIFY
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+
+ * - CMD
+ - DATAL
+ - DATAH
+ - DELAY
+
+ * - 0x02
+ - low byte of the status word to send
+ - high byte of the status word to send
+ - n * 10ms
+
+Also needs master mode. This test will send an SMBUS_HOST_NOTIFY message to the
+host. Note that the status word is currently ignored in the Linux Kernel.
+Example to send a notification with status word 0x6442 after 10ms::
+
+ # i2cset -y 0 0x30 2 0x42 0x64 1 i
+
+If the host controller supports HostNotify, this message with debug level
+should appear (Linux 6.11 and later)::
+
+ Detected HostNotify from address 0x30
+
+0x03 SMBUS_BLOCK_PROC_CALL
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+
+ * - CMD
+ - DATAL
+ - DATAH
+ - DELAY
+
+ * - 0x03
+ - 0x01 (i.e. one further byte will be written)
+ - number of bytes to be sent back
+ - leave out, partial command!
+
+Partial command. This test will respond to a block process call as defined by
+the SMBus specification. The one data byte written specifies how many bytes
+will be sent back in the following read transfer. Note that in this read
+transfer, the testunit will prefix the length of the bytes to follow. So, if
+your host bus driver emulates SMBus calls like the majority does, it needs to
+support the I2C_M_RECV_LEN flag of an i2c_msg. This is a good testcase for it.
+The returned data consists of the length first, and then of an array of bytes
+from length-1 to 0. Here is an example which emulates
+i2c_smbus_block_process_call() using i2ctransfer (you need i2c-tools v4.2 or
+later)::
+
+ # i2ctransfer -y 0 w3@0x30 3 1 0x10 r?
+ 0x10 0x0f 0x0e 0x0d 0x0c 0x0b 0x0a 0x09 0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01 0x00
+
+0x04 GET_VERSION_WITH_REP_START
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+
+ * - CMD
+ - DATAL
+ - DATAH
+ - DELAY
+
+ * - 0x04
+ - currently unused
+ - currently unused
+ - leave out, partial command!
+
+Partial command. After sending this command, the testunit will reply to a read
+message with a NUL terminated version string based on UTS_RELEASE. The first
+character is always a 'v' and the length of the version string is at maximum
+128 bytes. However, it will only respond if the read message is connected to
+the write message via repeated start. If your controller driver handles
+repeated start correctly, this will work::
+
+ # i2ctransfer -y 0 w3@0x30 4 0 0 r128
+ 0x76 0x36 0x2e 0x31 0x31 0x2e 0x30 0x2d 0x72 0x63 0x31 0x2d 0x30 0x30 0x30 0x30 ...
+
+If you have i2c-tools 4.4 or later, you can print out the data right away::
+
+ # i2ctransfer -y -b 0 w3@0x30 4 0 0 r128
+ v6.11.0-rc1-00009-gd37a1b4d3fd0
+
+STOP/START combinations between the two messages will *not* work because they
+are not equivalent to a REPEATED START. As an example, this returns just the
+default response::
+
+ # i2cset -y 0 0x30 4 0 0 i; i2cget -y 0 0x30
+ 0x00
+
+0x05 SMBUS_ALERT_REQUEST
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+
+ * - CMD
+ - DATAL
+ - DATAH
+ - DELAY
+
+ * - 0x05
+ - response value (7 MSBs interpreted as I2C address)
+ - currently unused
+ - n * 10ms
+
+This test raises an interrupt via the SMBAlert pin which the host controller
+must handle. The pin must be connected to the testunit as a GPIO. GPIO access
+is not allowed to sleep. Currently, this can only be described using firmware
+nodes. So, for devicetree, you would add something like this to the testunit
+node::
+
+ gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
+
+The following command will trigger the alert with a response of 0xc9 after 1
+second of delay::
+
+ # i2cset -y 0 0x30 5 0xc9 0x00 100 i
+
+If the host controller supports SMBusAlert, this message with debug level
+should appear::
+
+ smbus_alert 0-000c: SMBALERT# from dev 0x64, flag 1
+
+This message may appear more than once because the testunit is software not
+hardware and, thus, may not be able to react to the response of the host fast
+enough. The interrupt count should increase only by one, though::
+
+ # cat /proc/interrupts | grep smbus_alert
+ 93: 1 gpio-rcar 26 Edge smbus_alert
+
+If the host does not respond to the alert within 1 second, the test will be
+aborted and the testunit will report an error.
+
+For this test, the testunit will shortly drop its assigned address and listen
+on the SMBus Alert Response Address (0x0c). It will reassign its original
+address afterwards.