162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ciThe Virtual PCM Test Driver
462306a36Sopenharmony_ci===========================
562306a36Sopenharmony_ci
662306a36Sopenharmony_ciThe Virtual PCM Test Driver emulates a generic PCM device, and can be used for
762306a36Sopenharmony_citesting/fuzzing of the userspace ALSA applications, as well as for testing/fuzzing of
862306a36Sopenharmony_cithe PCM middle layer. Additionally, it can be used for simulating hard to reproduce
962306a36Sopenharmony_ciproblems with PCM devices.
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciWhat can this driver do?
1262306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ciAt this moment the driver can do the following things:
1562306a36Sopenharmony_ci	* Simulate both capture and playback processes
1662306a36Sopenharmony_ci	* Generate random or pattern-based capturing data
1762306a36Sopenharmony_ci	* Inject delays into the playback and capturing processes
1862306a36Sopenharmony_ci	* Inject errors during the PCM callbacks
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ciIt supports up to 8 substreams and 4 channels. Also it supports both interleaved and
2162306a36Sopenharmony_cinon-interleaved access modes.
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ciAlso, this driver can check the playback stream for containing the predefined pattern,
2462306a36Sopenharmony_ciwhich is used in the corresponding selftest (alsa/pcmtest-test.sh) to check the PCM middle
2562306a36Sopenharmony_cilayer data transferring functionality. Additionally, this driver redefines the default
2662306a36Sopenharmony_ciRESET ioctl, and the selftest covers this PCM API functionality as well.
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ciConfiguration
2962306a36Sopenharmony_ci-------------
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ciThe driver has several parameters besides the common ALSA module parameters:
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	* fill_mode (bool) - Buffer fill mode (see below)
3462306a36Sopenharmony_ci	* inject_delay (int)
3562306a36Sopenharmony_ci	* inject_hwpars_err (bool)
3662306a36Sopenharmony_ci	* inject_prepare_err (bool)
3762306a36Sopenharmony_ci	* inject_trigger_err (bool)
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ciCapture Data Generation
4162306a36Sopenharmony_ci-----------------------
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ciThe driver has two modes of data generation: the first (0 in the fill_mode parameter)
4462306a36Sopenharmony_cimeans random data generation, the second (1 in the fill_mode) - pattern-based
4562306a36Sopenharmony_cidata generation. Let's look at the second mode.
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ciFirst of all, you may want to specify the pattern for data generation. You can do it
4862306a36Sopenharmony_ciby writing the pattern to the debugfs file. There are pattern buffer debugfs entries
4962306a36Sopenharmony_cifor each channel, as well as entries which contain the pattern buffer length.
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	* /sys/kernel/debug/pcmtest/fill_pattern[0-3]
5262306a36Sopenharmony_ci	* /sys/kernel/debug/pcmtest/fill_pattern[0-3]_len
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ciTo set the pattern for the channel 0 you can execute the following command:
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci.. code-block:: bash
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	echo -n mycoolpattern > /sys/kernel/debug/pcmtest/fill_pattern0
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ciThen, after every capture action performed on the 'pcmtest' device the buffer for the
6162306a36Sopenharmony_cichannel 0 will contain 'mycoolpatternmycoolpatternmycoolpatternmy...'.
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ciThe pattern itself can be up to 4096 bytes long.
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ciDelay injection
6662306a36Sopenharmony_ci---------------
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ciThe driver has 'inject_delay' parameter, which has very self-descriptive name and
6962306a36Sopenharmony_cican be used for time delay/speedup simulations. The parameter has integer type, and
7062306a36Sopenharmony_ciit means the delay added between module's internal timer ticks.
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ciIf the 'inject_delay' value is positive, the buffer will be filled slower, if it is
7362306a36Sopenharmony_cinegative - faster. You can try it yourself by starting a recording in any
7462306a36Sopenharmony_ciaudiorecording application (like Audacity) and selecting the 'pcmtest' device as a
7562306a36Sopenharmony_cisource.
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ciThis parameter can be also used for generating a huge amount of sound data in a very
7862306a36Sopenharmony_cishort period of time (with the negative 'inject_delay' value).
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciErrors injection
8162306a36Sopenharmony_ci----------------
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ciThis module can be used for injecting errors into the PCM communication process. This
8462306a36Sopenharmony_ciaction can help you to figure out how the userspace ALSA program behaves under unusual
8562306a36Sopenharmony_cicircumstances.
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ciFor example, you can make all 'hw_params' PCM callback calls return EBUSY error by
8862306a36Sopenharmony_ciwriting '1' to the 'inject_hwpars_err' module parameter:
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci.. code-block:: bash
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	echo 1 > /sys/module/snd_pcmtest/parameters/inject_hwpars_err
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ciErrors can be injected into the following PCM callbacks:
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	* hw_params (EBUSY)
9762306a36Sopenharmony_ci	* prepare (EINVAL)
9862306a36Sopenharmony_ci	* trigger (EINVAL)
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ciPlayback test
10162306a36Sopenharmony_ci-------------
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ciThis driver can be also used for the playback functionality testing - every time you
10462306a36Sopenharmony_ciwrite the playback data to the 'pcmtest' PCM device and close it, the driver checks the
10562306a36Sopenharmony_cibuffer for containing the looped pattern (which is specified in the fill_pattern
10662306a36Sopenharmony_cidebugfs file for each channel). If the playback buffer content represents the looped
10762306a36Sopenharmony_cipattern, 'pc_test' debugfs entry is set into '1'. Otherwise, the driver sets it to '0'.
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ciioctl redefinition test
11062306a36Sopenharmony_ci-----------------------
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ciThe driver redefines the 'reset' ioctl, which is default for all PCM devices. To test
11362306a36Sopenharmony_cithis functionality, we can trigger the reset ioctl and check the 'ioctl_test' debugfs
11462306a36Sopenharmony_cientry:
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci.. code-block:: bash
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	cat /sys/kernel/debug/pcmtest/ioctl_test
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ciIf the ioctl is triggered successfully, this file will contain '1', and '0' otherwise.
121