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