1*f091ec76SIvan Orlov.. SPDX-License-Identifier: GPL-2.0 2*f091ec76SIvan Orlov 3*f091ec76SIvan OrlovThe Virtual PCM Test Driver 4*f091ec76SIvan Orlov=========================== 5*f091ec76SIvan Orlov 6*f091ec76SIvan OrlovThe Virtual PCM Test Driver emulates a generic PCM device, and can be used for 7*f091ec76SIvan Orlovtesting/fuzzing of the userspace ALSA applications, as well as for testing/fuzzing of 8*f091ec76SIvan Orlovthe PCM middle layer. Additionally, it can be used for simulating hard to reproduce 9*f091ec76SIvan Orlovproblems with PCM devices. 10*f091ec76SIvan Orlov 11*f091ec76SIvan OrlovWhat can this driver do? 12*f091ec76SIvan Orlov~~~~~~~~~~~~~~~~~~~~~~~~ 13*f091ec76SIvan Orlov 14*f091ec76SIvan OrlovAt this moment the driver can do the following things: 15*f091ec76SIvan Orlov * Simulate both capture and playback processes 16*f091ec76SIvan Orlov * Generate random or pattern-based capturing data 17*f091ec76SIvan Orlov * Inject delays into the playback and capturing processes 18*f091ec76SIvan Orlov * Inject errors during the PCM callbacks 19*f091ec76SIvan Orlov 20*f091ec76SIvan OrlovIt supports up to 8 substreams and 4 channels. Also it supports both interleaved and 21*f091ec76SIvan Orlovnon-interleaved access modes. 22*f091ec76SIvan Orlov 23*f091ec76SIvan OrlovAlso, this driver can check the playback stream for containing the predefined pattern, 24*f091ec76SIvan Orlovwhich is used in the corresponding selftest (alsa/pcmtest-test.sh) to check the PCM middle 25*f091ec76SIvan Orlovlayer data transferring functionality. Additionally, this driver redefines the default 26*f091ec76SIvan OrlovRESET ioctl, and the selftest covers this PCM API functionality as well. 27*f091ec76SIvan Orlov 28*f091ec76SIvan OrlovConfiguration 29*f091ec76SIvan Orlov------------- 30*f091ec76SIvan Orlov 31*f091ec76SIvan OrlovThe driver has several parameters besides the common ALSA module parameters: 32*f091ec76SIvan Orlov 33*f091ec76SIvan Orlov * fill_mode (bool) - Buffer fill mode (see below) 34*f091ec76SIvan Orlov * inject_delay (int) 35*f091ec76SIvan Orlov * inject_hwpars_err (bool) 36*f091ec76SIvan Orlov * inject_prepare_err (bool) 37*f091ec76SIvan Orlov * inject_trigger_err (bool) 38*f091ec76SIvan Orlov 39*f091ec76SIvan Orlov 40*f091ec76SIvan OrlovCapture Data Generation 41*f091ec76SIvan Orlov----------------------- 42*f091ec76SIvan Orlov 43*f091ec76SIvan OrlovThe driver has two modes of data generation: the first (0 in the fill_mode parameter) 44*f091ec76SIvan Orlovmeans random data generation, the second (1 in the fill_mode) - pattern-based 45*f091ec76SIvan Orlovdata generation. Let's look at the second mode. 46*f091ec76SIvan Orlov 47*f091ec76SIvan OrlovFirst of all, you may want to specify the pattern for data generation. You can do it 48*f091ec76SIvan Orlovby writing the pattern to the debugfs file. There are pattern buffer debugfs entries 49*f091ec76SIvan Orlovfor each channel, as well as entries which contain the pattern buffer length. 50*f091ec76SIvan Orlov 51*f091ec76SIvan Orlov * /sys/kernel/debug/pcmtest/fill_pattern[0-3] 52*f091ec76SIvan Orlov * /sys/kernel/debug/pcmtest/fill_pattern[0-3]_len 53*f091ec76SIvan Orlov 54*f091ec76SIvan OrlovTo set the pattern for the channel 0 you can execute the following command: 55*f091ec76SIvan Orlov 56*f091ec76SIvan Orlov.. code-block:: bash 57*f091ec76SIvan Orlov 58*f091ec76SIvan Orlov echo -n mycoolpattern > /sys/kernel/debug/pcmtest/fill_pattern0 59*f091ec76SIvan Orlov 60*f091ec76SIvan OrlovThen, after every capture action performed on the 'pcmtest' device the buffer for the 61*f091ec76SIvan Orlovchannel 0 will contain 'mycoolpatternmycoolpatternmycoolpatternmy...'. 62*f091ec76SIvan Orlov 63*f091ec76SIvan OrlovThe pattern itself can be up to 4096 bytes long. 64*f091ec76SIvan Orlov 65*f091ec76SIvan OrlovDelay injection 66*f091ec76SIvan Orlov--------------- 67*f091ec76SIvan Orlov 68*f091ec76SIvan OrlovThe driver has 'inject_delay' parameter, which has very self-descriptive name and 69*f091ec76SIvan Orlovcan be used for time delay/speedup simulations. The parameter has integer type, and 70*f091ec76SIvan Orlovit means the delay added between module's internal timer ticks. 71*f091ec76SIvan Orlov 72*f091ec76SIvan OrlovIf the 'inject_delay' value is positive, the buffer will be filled slower, if it is 73*f091ec76SIvan Orlovnegative - faster. You can try it yourself by starting a recording in any 74*f091ec76SIvan Orlovaudiorecording application (like Audacity) and selecting the 'pcmtest' device as a 75*f091ec76SIvan Orlovsource. 76*f091ec76SIvan Orlov 77*f091ec76SIvan OrlovThis parameter can be also used for generating a huge amount of sound data in a very 78*f091ec76SIvan Orlovshort period of time (with the negative 'inject_delay' value). 79*f091ec76SIvan Orlov 80*f091ec76SIvan OrlovErrors injection 81*f091ec76SIvan Orlov---------------- 82*f091ec76SIvan Orlov 83*f091ec76SIvan OrlovThis module can be used for injecting errors into the PCM communication process. This 84*f091ec76SIvan Orlovaction can help you to figure out how the userspace ALSA program behaves under unusual 85*f091ec76SIvan Orlovcircumstances. 86*f091ec76SIvan Orlov 87*f091ec76SIvan OrlovFor example, you can make all 'hw_params' PCM callback calls return EBUSY error by 88*f091ec76SIvan Orlovwriting '1' to the 'inject_hwpars_err' module parameter: 89*f091ec76SIvan Orlov 90*f091ec76SIvan Orlov.. code-block:: bash 91*f091ec76SIvan Orlov 92*f091ec76SIvan Orlov echo 1 > /sys/module/snd_pcmtest/parameters/inject_hwpars_err 93*f091ec76SIvan Orlov 94*f091ec76SIvan OrlovErrors can be injected into the following PCM callbacks: 95*f091ec76SIvan Orlov 96*f091ec76SIvan Orlov * hw_params (EBUSY) 97*f091ec76SIvan Orlov * prepare (EINVAL) 98*f091ec76SIvan Orlov * trigger (EINVAL) 99*f091ec76SIvan Orlov 100*f091ec76SIvan OrlovPlayback test 101*f091ec76SIvan Orlov------------- 102*f091ec76SIvan Orlov 103*f091ec76SIvan OrlovThis driver can be also used for the playback functionality testing - every time you 104*f091ec76SIvan Orlovwrite the playback data to the 'pcmtest' PCM device and close it, the driver checks the 105*f091ec76SIvan Orlovbuffer for containing the looped pattern (which is specified in the fill_pattern 106*f091ec76SIvan Orlovdebugfs file for each channel). If the playback buffer content represents the looped 107*f091ec76SIvan Orlovpattern, 'pc_test' debugfs entry is set into '1'. Otherwise, the driver sets it to '0'. 108*f091ec76SIvan Orlov 109*f091ec76SIvan Orlovioctl redefinition test 110*f091ec76SIvan Orlov----------------------- 111*f091ec76SIvan Orlov 112*f091ec76SIvan OrlovThe driver redefines the 'reset' ioctl, which is default for all PCM devices. To test 113*f091ec76SIvan Orlovthis functionality, we can trigger the reset ioctl and check the 'ioctl_test' debugfs 114*f091ec76SIvan Orloventry: 115*f091ec76SIvan Orlov 116*f091ec76SIvan Orlov.. code-block:: bash 117*f091ec76SIvan Orlov 118*f091ec76SIvan Orlov cat /sys/kernel/debug/pcmtest/ioctl_test 119*f091ec76SIvan Orlov 120*f091ec76SIvan OrlovIf the ioctl is triggered successfully, this file will contain '1', and '0' otherwise. 121