pcmtest.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Virtual ALSA driver for PCM testing/fuzzing
  4. *
  5. * Copyright 2023 Ivan Orlov <ivan.orlov0322@gmail.com>
  6. *
  7. * This is a simple virtual ALSA driver, which can be used for audio applications/PCM middle layer
  8. * testing or fuzzing.
  9. * It can:
  10. * - Simulate 'playback' and 'capture' actions
  11. * - Generate random or pattern-based capture data
  12. * - Check playback buffer for containing looped template, and notify about the results
  13. * through the debugfs entry
  14. * - Inject delays into the playback and capturing processes. See 'inject_delay' parameter.
  15. * - Inject errors during the PCM callbacks.
  16. * - Register custom RESET ioctl and notify when it is called through the debugfs entry
  17. * - Work in interleaved and non-interleaved modes
  18. * - Support up to 8 substreams
  19. * - Support up to 4 channels
  20. * - Support framerates from 8 kHz to 48 kHz
  21. *
  22. * When driver works in the capture mode with multiple channels, it duplicates the looped
  23. * pattern to each separate channel. For example, if we have 2 channels, format = U8, interleaved
  24. * access mode and pattern 'abacaba', the DMA buffer will look like aabbccaabbaaaa..., so buffer for
  25. * each channel will contain abacabaabacaba... Same for the non-interleaved mode.
  26. *
  27. * However, it may break the capturing on the higher framerates with small period size, so it is
  28. * better to choose larger period sizes.
  29. *
  30. * You can find the corresponding selftest in the 'alsa' selftests folder.
  31. */
  32. #include <linux/module.h>
  33. #include <linux/init.h>
  34. #include <sound/pcm.h>
  35. #include <sound/core.h>
  36. #include <linux/dma-mapping.h>
  37. #include <linux/platform_device.h>
  38. #include <linux/string.h>
  39. #include <linux/timer.h>
  40. #include <linux/random.h>
  41. #include <linux/debugfs.h>
  42. #include <linux/delay.h>
  43. #define TIMER_PER_SEC 5
  44. #define TIMER_INTERVAL (HZ / TIMER_PER_SEC)
  45. #define DELAY_JIFFIES HZ
  46. #define PLAYBACK_SUBSTREAM_CNT 8
  47. #define CAPTURE_SUBSTREAM_CNT 8
  48. #define MAX_CHANNELS_NUM 4
  49. #define DEFAULT_PATTERN "abacaba"
  50. #define DEFAULT_PATTERN_LEN 7
  51. #define FILL_MODE_RAND 0
  52. #define FILL_MODE_PAT 1
  53. #define MAX_PATTERN_LEN 4096
  54. static int index = -1;
  55. static char *id = "pcmtest";
  56. static bool enable = true;
  57. static int inject_delay;
  58. static bool inject_hwpars_err;
  59. static bool inject_prepare_err;
  60. static bool inject_trigger_err;
  61. static bool inject_open_err;
  62. static short fill_mode = FILL_MODE_PAT;
  63. static u8 playback_capture_test;
  64. static u8 ioctl_reset_test;
  65. static struct dentry *driver_debug_dir;
  66. module_param(index, int, 0444);
  67. MODULE_PARM_DESC(index, "Index value for pcmtest soundcard");
  68. module_param(id, charp, 0444);
  69. MODULE_PARM_DESC(id, "ID string for pcmtest soundcard");
  70. module_param(enable, bool, 0444);
  71. MODULE_PARM_DESC(enable, "Enable pcmtest soundcard.");
  72. module_param(fill_mode, short, 0600);
  73. MODULE_PARM_DESC(fill_mode, "Buffer fill mode: rand(0) or pattern(1)");
  74. module_param(inject_delay, int, 0600);
  75. MODULE_PARM_DESC(inject_delay, "Inject delays during playback/capture (in jiffies)");
  76. module_param(inject_hwpars_err, bool, 0600);
  77. MODULE_PARM_DESC(inject_hwpars_err, "Inject EBUSY error in the 'hw_params' callback");
  78. module_param(inject_prepare_err, bool, 0600);
  79. MODULE_PARM_DESC(inject_prepare_err, "Inject EINVAL error in the 'prepare' callback");
  80. module_param(inject_trigger_err, bool, 0600);
  81. MODULE_PARM_DESC(inject_trigger_err, "Inject EINVAL error in the 'trigger' callback");
  82. module_param(inject_open_err, bool, 0600);
  83. MODULE_PARM_DESC(inject_open_err, "Inject EBUSY error in the 'open' callback");
  84. struct pcmtst {
  85. struct snd_pcm *pcm;
  86. struct snd_card *card;
  87. struct platform_device *pdev;
  88. };
  89. struct pcmtst_buf_iter {
  90. size_t buf_pos; // position in the DMA buffer
  91. size_t period_pos; // period-relative position
  92. size_t b_rw; // Bytes to write on every timer tick
  93. size_t s_rw_ch; // Samples to write to one channel on every tick
  94. unsigned int sample_bytes; // sample_bits / 8
  95. bool is_buf_corrupted; // playback test result indicator
  96. size_t period_bytes; // bytes in a one period
  97. bool interleaved; // Interleaved/Non-interleaved mode
  98. size_t total_bytes; // Total bytes read/written
  99. size_t chan_block; // Bytes in one channel buffer when non-interleaved
  100. struct snd_pcm_substream *substream;
  101. bool suspend; // We need to pause timer without shutting it down
  102. struct timer_list timer_instance;
  103. };
  104. static struct snd_pcm_hardware snd_pcmtst_hw = {
  105. .info = (SNDRV_PCM_INFO_INTERLEAVED |
  106. SNDRV_PCM_INFO_BLOCK_TRANSFER |
  107. SNDRV_PCM_INFO_NONINTERLEAVED |
  108. SNDRV_PCM_INFO_MMAP_VALID |
  109. SNDRV_PCM_INFO_PAUSE),
  110. .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
  111. .rates = SNDRV_PCM_RATE_8000_48000,
  112. .rate_min = 8000,
  113. .rate_max = 48000,
  114. .channels_min = 1,
  115. .channels_max = MAX_CHANNELS_NUM,
  116. .buffer_bytes_max = 128 * 1024,
  117. .period_bytes_min = 4096,
  118. .period_bytes_max = 32768,
  119. .periods_min = 1,
  120. .periods_max = 1024,
  121. };
  122. struct pattern_buf {
  123. char *buf;
  124. u32 len;
  125. };
  126. static int buf_allocated;
  127. static struct pattern_buf patt_bufs[MAX_CHANNELS_NUM];
  128. static inline void inc_buf_pos(struct pcmtst_buf_iter *v_iter, size_t by, size_t bytes)
  129. {
  130. v_iter->total_bytes += by;
  131. v_iter->buf_pos += by;
  132. if (v_iter->buf_pos >= bytes)
  133. v_iter->buf_pos %= bytes;
  134. }
  135. /*
  136. * Position in the DMA buffer when we are in the non-interleaved mode. We increment buf_pos
  137. * every time we write a byte to any channel, so the position in the current channel buffer is
  138. * (position in the DMA buffer) / count_of_channels + size_of_channel_buf * current_channel
  139. */
  140. static inline size_t buf_pos_n(struct pcmtst_buf_iter *v_iter, unsigned int channels,
  141. unsigned int chan_num)
  142. {
  143. return v_iter->buf_pos / channels + v_iter->chan_block * chan_num;
  144. }
  145. /*
  146. * Get the count of bytes written for the current channel in the interleaved mode.
  147. * This is (count of samples written for the current channel) * bytes_in_sample +
  148. * (relative position in the current sample)
  149. */
  150. static inline size_t ch_pos_i(size_t b_total, unsigned int channels, unsigned int b_sample)
  151. {
  152. return b_total / channels / b_sample * b_sample + (b_total % b_sample);
  153. }
  154. static void check_buf_block_i(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
  155. {
  156. size_t i;
  157. short ch_num;
  158. u8 current_byte;
  159. for (i = 0; i < v_iter->b_rw; i++) {
  160. current_byte = runtime->dma_area[v_iter->buf_pos];
  161. if (!current_byte)
  162. break;
  163. ch_num = (v_iter->total_bytes / v_iter->sample_bytes) % runtime->channels;
  164. if (current_byte != patt_bufs[ch_num].buf[ch_pos_i(v_iter->total_bytes,
  165. runtime->channels,
  166. v_iter->sample_bytes)
  167. % patt_bufs[ch_num].len]) {
  168. v_iter->is_buf_corrupted = true;
  169. break;
  170. }
  171. inc_buf_pos(v_iter, 1, runtime->dma_bytes);
  172. }
  173. // If we broke during the loop, add remaining bytes to the buffer position.
  174. inc_buf_pos(v_iter, v_iter->b_rw - i, runtime->dma_bytes);
  175. }
  176. static void check_buf_block_ni(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
  177. {
  178. unsigned int channels = runtime->channels;
  179. size_t i;
  180. short ch_num;
  181. u8 current_byte;
  182. for (i = 0; i < v_iter->b_rw; i++) {
  183. ch_num = i % channels;
  184. current_byte = runtime->dma_area[buf_pos_n(v_iter, channels, ch_num)];
  185. if (!current_byte)
  186. break;
  187. if (current_byte != patt_bufs[ch_num].buf[(v_iter->total_bytes / channels)
  188. % patt_bufs[ch_num].len]) {
  189. v_iter->is_buf_corrupted = true;
  190. break;
  191. }
  192. inc_buf_pos(v_iter, 1, runtime->dma_bytes);
  193. }
  194. inc_buf_pos(v_iter, v_iter->b_rw - i, runtime->dma_bytes);
  195. }
  196. /*
  197. * Check one block of the buffer. Here we iterate the buffer until we find '0'. This condition is
  198. * necessary because we need to detect when the reading/writing ends, so we assume that the pattern
  199. * doesn't contain zeros.
  200. */
  201. static void check_buf_block(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
  202. {
  203. if (v_iter->interleaved)
  204. check_buf_block_i(v_iter, runtime);
  205. else
  206. check_buf_block_ni(v_iter, runtime);
  207. }
  208. /*
  209. * Fill buffer in the non-interleaved mode. The order of samples is C0, ..., C0, C1, ..., C1, C2...
  210. * The channel buffers lay in the DMA buffer continuously (see default copy
  211. * handlers in the pcm_lib.c file).
  212. *
  213. * Here we increment the DMA buffer position every time we write a byte to any channel 'buffer'.
  214. * We need this to simulate the correct hardware pointer moving.
  215. */
  216. static void fill_block_pattern_n(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
  217. {
  218. size_t i;
  219. unsigned int channels = runtime->channels;
  220. short ch_num;
  221. for (i = 0; i < v_iter->b_rw; i++) {
  222. ch_num = i % channels;
  223. runtime->dma_area[buf_pos_n(v_iter, channels, ch_num)] =
  224. patt_bufs[ch_num].buf[(v_iter->total_bytes / channels)
  225. % patt_bufs[ch_num].len];
  226. inc_buf_pos(v_iter, 1, runtime->dma_bytes);
  227. }
  228. }
  229. // Fill buffer in the interleaved mode. The order of samples is C0, C1, C2, C0, C1, C2, ...
  230. static void fill_block_pattern_i(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
  231. {
  232. size_t sample;
  233. size_t pos_in_ch, pos_pattern;
  234. short ch, pos_sample;
  235. pos_in_ch = ch_pos_i(v_iter->total_bytes, runtime->channels, v_iter->sample_bytes);
  236. for (sample = 0; sample < v_iter->s_rw_ch; sample++) {
  237. for (ch = 0; ch < runtime->channels; ch++) {
  238. for (pos_sample = 0; pos_sample < v_iter->sample_bytes; pos_sample++) {
  239. pos_pattern = (pos_in_ch + sample * v_iter->sample_bytes
  240. + pos_sample) % patt_bufs[ch].len;
  241. runtime->dma_area[v_iter->buf_pos] = patt_bufs[ch].buf[pos_pattern];
  242. inc_buf_pos(v_iter, 1, runtime->dma_bytes);
  243. }
  244. }
  245. }
  246. }
  247. static void fill_block_pattern(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
  248. {
  249. if (v_iter->interleaved)
  250. fill_block_pattern_i(v_iter, runtime);
  251. else
  252. fill_block_pattern_n(v_iter, runtime);
  253. }
  254. static void fill_block_rand_n(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
  255. {
  256. unsigned int channels = runtime->channels;
  257. // Remaining space in all channel buffers
  258. size_t bytes_remain = runtime->dma_bytes - v_iter->buf_pos;
  259. unsigned int i;
  260. for (i = 0; i < channels; i++) {
  261. if (v_iter->b_rw <= bytes_remain) {
  262. //b_rw - count of bytes must be written for all channels at each timer tick
  263. get_random_bytes(runtime->dma_area + buf_pos_n(v_iter, channels, i),
  264. v_iter->b_rw / channels);
  265. } else {
  266. // Write to the end of buffer and start from the beginning of it
  267. get_random_bytes(runtime->dma_area + buf_pos_n(v_iter, channels, i),
  268. bytes_remain / channels);
  269. get_random_bytes(runtime->dma_area + v_iter->chan_block * i,
  270. (v_iter->b_rw - bytes_remain) / channels);
  271. }
  272. }
  273. inc_buf_pos(v_iter, v_iter->b_rw, runtime->dma_bytes);
  274. }
  275. static void fill_block_rand_i(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
  276. {
  277. size_t in_cur_block = runtime->dma_bytes - v_iter->buf_pos;
  278. if (v_iter->b_rw <= in_cur_block) {
  279. get_random_bytes(&runtime->dma_area[v_iter->buf_pos], v_iter->b_rw);
  280. } else {
  281. get_random_bytes(&runtime->dma_area[v_iter->buf_pos], in_cur_block);
  282. get_random_bytes(runtime->dma_area, v_iter->b_rw - in_cur_block);
  283. }
  284. inc_buf_pos(v_iter, v_iter->b_rw, runtime->dma_bytes);
  285. }
  286. static void fill_block_random(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
  287. {
  288. if (v_iter->interleaved)
  289. fill_block_rand_i(v_iter, runtime);
  290. else
  291. fill_block_rand_n(v_iter, runtime);
  292. }
  293. static void fill_block(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime)
  294. {
  295. switch (fill_mode) {
  296. case FILL_MODE_RAND:
  297. fill_block_random(v_iter, runtime);
  298. break;
  299. case FILL_MODE_PAT:
  300. fill_block_pattern(v_iter, runtime);
  301. break;
  302. }
  303. }
  304. /*
  305. * Here we iterate through the buffer by (buffer_size / iterates_per_second) bytes.
  306. * The driver uses timer to simulate the hardware pointer moving, and notify the PCM middle layer
  307. * about period elapsed.
  308. */
  309. static void timer_timeout(struct timer_list *data)
  310. {
  311. struct pcmtst_buf_iter *v_iter;
  312. struct snd_pcm_substream *substream;
  313. v_iter = timer_container_of(v_iter, data, timer_instance);
  314. substream = v_iter->substream;
  315. if (v_iter->suspend)
  316. return;
  317. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !v_iter->is_buf_corrupted)
  318. check_buf_block(v_iter, substream->runtime);
  319. else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  320. fill_block(v_iter, substream->runtime);
  321. else
  322. inc_buf_pos(v_iter, v_iter->b_rw, substream->runtime->dma_bytes);
  323. v_iter->period_pos += v_iter->b_rw;
  324. if (v_iter->period_pos >= v_iter->period_bytes) {
  325. v_iter->period_pos %= v_iter->period_bytes;
  326. snd_pcm_period_elapsed(substream);
  327. }
  328. if (!v_iter->suspend)
  329. mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL + inject_delay);
  330. }
  331. static int snd_pcmtst_pcm_open(struct snd_pcm_substream *substream)
  332. {
  333. struct snd_pcm_runtime *runtime = substream->runtime;
  334. struct pcmtst_buf_iter *v_iter;
  335. if (inject_open_err)
  336. return -EBUSY;
  337. v_iter = kzalloc_obj(*v_iter);
  338. if (!v_iter)
  339. return -ENOMEM;
  340. v_iter->substream = substream;
  341. runtime->hw = snd_pcmtst_hw;
  342. runtime->private_data = v_iter;
  343. playback_capture_test = 0;
  344. ioctl_reset_test = 0;
  345. timer_setup(&v_iter->timer_instance, timer_timeout, 0);
  346. return 0;
  347. }
  348. static int snd_pcmtst_pcm_close(struct snd_pcm_substream *substream)
  349. {
  350. struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
  351. timer_shutdown_sync(&v_iter->timer_instance);
  352. playback_capture_test = !v_iter->is_buf_corrupted;
  353. kfree(v_iter);
  354. return 0;
  355. }
  356. static inline void reset_buf_iterator(struct pcmtst_buf_iter *v_iter)
  357. {
  358. v_iter->buf_pos = 0;
  359. v_iter->is_buf_corrupted = false;
  360. v_iter->period_pos = 0;
  361. v_iter->total_bytes = 0;
  362. }
  363. static inline void start_pcmtest_timer(struct pcmtst_buf_iter *v_iter)
  364. {
  365. v_iter->suspend = false;
  366. mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL);
  367. }
  368. static int snd_pcmtst_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
  369. {
  370. struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
  371. if (inject_trigger_err)
  372. return -EINVAL;
  373. switch (cmd) {
  374. case SNDRV_PCM_TRIGGER_START:
  375. reset_buf_iterator(v_iter);
  376. start_pcmtest_timer(v_iter);
  377. break;
  378. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  379. start_pcmtest_timer(v_iter);
  380. break;
  381. case SNDRV_PCM_TRIGGER_STOP:
  382. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  383. // We can't call timer_shutdown_sync here, as it is forbidden to sleep here
  384. v_iter->suspend = true;
  385. timer_delete(&v_iter->timer_instance);
  386. break;
  387. }
  388. return 0;
  389. }
  390. static snd_pcm_uframes_t snd_pcmtst_pcm_pointer(struct snd_pcm_substream *substream)
  391. {
  392. struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
  393. return bytes_to_frames(substream->runtime, v_iter->buf_pos);
  394. }
  395. static int snd_pcmtst_free(struct pcmtst *pcmtst)
  396. {
  397. if (!pcmtst)
  398. return 0;
  399. kfree(pcmtst);
  400. return 0;
  401. }
  402. // These callbacks are required, but empty - all freeing occurs in pdev_remove
  403. static int snd_pcmtst_dev_free(struct snd_device *device)
  404. {
  405. return 0;
  406. }
  407. static void pcmtst_pdev_release(struct device *dev)
  408. {
  409. }
  410. static int snd_pcmtst_pcm_prepare(struct snd_pcm_substream *substream)
  411. {
  412. struct snd_pcm_runtime *runtime = substream->runtime;
  413. struct pcmtst_buf_iter *v_iter = runtime->private_data;
  414. if (inject_prepare_err)
  415. return -EINVAL;
  416. v_iter->sample_bytes = samples_to_bytes(runtime, 1);
  417. v_iter->period_bytes = snd_pcm_lib_period_bytes(substream);
  418. v_iter->interleaved = true;
  419. if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ||
  420. runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) {
  421. v_iter->chan_block = snd_pcm_lib_buffer_bytes(substream) / runtime->channels;
  422. v_iter->interleaved = false;
  423. }
  424. // We want to record RATE * ch_cnt samples per sec, it is rate * sample_bytes * ch_cnt bytes
  425. v_iter->s_rw_ch = runtime->rate / TIMER_PER_SEC;
  426. v_iter->b_rw = v_iter->s_rw_ch * v_iter->sample_bytes * runtime->channels;
  427. return 0;
  428. }
  429. static int snd_pcmtst_pcm_hw_params(struct snd_pcm_substream *substream,
  430. struct snd_pcm_hw_params *params)
  431. {
  432. if (inject_hwpars_err)
  433. return -EBUSY;
  434. return 0;
  435. }
  436. static int snd_pcmtst_pcm_hw_free(struct snd_pcm_substream *substream)
  437. {
  438. return 0;
  439. }
  440. static int snd_pcmtst_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg)
  441. {
  442. switch (cmd) {
  443. case SNDRV_PCM_IOCTL1_RESET:
  444. ioctl_reset_test = 1;
  445. break;
  446. }
  447. return snd_pcm_lib_ioctl(substream, cmd, arg);
  448. }
  449. static int snd_pcmtst_sync_stop(struct snd_pcm_substream *substream)
  450. {
  451. struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
  452. timer_delete_sync(&v_iter->timer_instance);
  453. return 0;
  454. }
  455. static const struct snd_pcm_ops snd_pcmtst_playback_ops = {
  456. .open = snd_pcmtst_pcm_open,
  457. .close = snd_pcmtst_pcm_close,
  458. .trigger = snd_pcmtst_pcm_trigger,
  459. .hw_params = snd_pcmtst_pcm_hw_params,
  460. .ioctl = snd_pcmtst_ioctl,
  461. .sync_stop = snd_pcmtst_sync_stop,
  462. .hw_free = snd_pcmtst_pcm_hw_free,
  463. .prepare = snd_pcmtst_pcm_prepare,
  464. .pointer = snd_pcmtst_pcm_pointer,
  465. };
  466. static const struct snd_pcm_ops snd_pcmtst_capture_ops = {
  467. .open = snd_pcmtst_pcm_open,
  468. .close = snd_pcmtst_pcm_close,
  469. .trigger = snd_pcmtst_pcm_trigger,
  470. .hw_params = snd_pcmtst_pcm_hw_params,
  471. .hw_free = snd_pcmtst_pcm_hw_free,
  472. .ioctl = snd_pcmtst_ioctl,
  473. .sync_stop = snd_pcmtst_sync_stop,
  474. .prepare = snd_pcmtst_pcm_prepare,
  475. .pointer = snd_pcmtst_pcm_pointer,
  476. };
  477. static int snd_pcmtst_new_pcm(struct pcmtst *pcmtst)
  478. {
  479. struct snd_pcm *pcm;
  480. int err;
  481. err = snd_pcm_new(pcmtst->card, "PCMTest", 0, PLAYBACK_SUBSTREAM_CNT,
  482. CAPTURE_SUBSTREAM_CNT, &pcm);
  483. if (err < 0)
  484. return err;
  485. pcm->private_data = pcmtst;
  486. strscpy(pcm->name, "PCMTest");
  487. pcmtst->pcm = pcm;
  488. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_pcmtst_playback_ops);
  489. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_pcmtst_capture_ops);
  490. err = snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &pcmtst->pdev->dev,
  491. 0, 128 * 1024);
  492. return err;
  493. }
  494. static int snd_pcmtst_create(struct snd_card *card, struct platform_device *pdev,
  495. struct pcmtst **r_pcmtst)
  496. {
  497. struct pcmtst *pcmtst;
  498. int err;
  499. static const struct snd_device_ops ops = {
  500. .dev_free = snd_pcmtst_dev_free,
  501. };
  502. pcmtst = kzalloc_obj(*pcmtst);
  503. if (!pcmtst)
  504. return -ENOMEM;
  505. pcmtst->card = card;
  506. pcmtst->pdev = pdev;
  507. err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pcmtst, &ops);
  508. if (err < 0)
  509. goto _err_free_chip;
  510. err = snd_pcmtst_new_pcm(pcmtst);
  511. if (err < 0)
  512. goto _err_free_chip;
  513. *r_pcmtst = pcmtst;
  514. return 0;
  515. _err_free_chip:
  516. snd_pcmtst_free(pcmtst);
  517. return err;
  518. }
  519. static int pcmtst_probe(struct platform_device *pdev)
  520. {
  521. struct snd_card *card;
  522. struct pcmtst *pcmtst;
  523. int err;
  524. err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
  525. if (err)
  526. return err;
  527. err = snd_devm_card_new(&pdev->dev, index, id, THIS_MODULE, 0, &card);
  528. if (err < 0)
  529. return err;
  530. err = snd_pcmtst_create(card, pdev, &pcmtst);
  531. if (err < 0)
  532. return err;
  533. strscpy(card->driver, "PCM-TEST Driver");
  534. strscpy(card->shortname, "PCM-Test");
  535. strscpy(card->longname, "PCM-Test virtual driver");
  536. err = snd_card_register(card);
  537. if (err < 0)
  538. return err;
  539. platform_set_drvdata(pdev, pcmtst);
  540. return 0;
  541. }
  542. static void pdev_remove(struct platform_device *pdev)
  543. {
  544. struct pcmtst *pcmtst = platform_get_drvdata(pdev);
  545. snd_pcmtst_free(pcmtst);
  546. }
  547. static struct platform_device pcmtst_pdev = {
  548. .name = "pcmtest",
  549. .dev.release = pcmtst_pdev_release,
  550. };
  551. static struct platform_driver pcmtst_pdrv = {
  552. .probe = pcmtst_probe,
  553. .remove = pdev_remove,
  554. .driver = {
  555. .name = "pcmtest",
  556. },
  557. };
  558. static ssize_t pattern_write(struct file *file, const char __user *u_buff, size_t len, loff_t *off)
  559. {
  560. struct pattern_buf *patt_buf = file->f_inode->i_private;
  561. ssize_t to_write = len;
  562. if (*off + to_write > MAX_PATTERN_LEN)
  563. to_write = MAX_PATTERN_LEN - *off;
  564. // Crop silently everything over the buffer
  565. if (to_write <= 0)
  566. return len;
  567. if (copy_from_user(patt_buf->buf + *off, u_buff, to_write))
  568. return -EFAULT;
  569. patt_buf->len = *off + to_write;
  570. *off += to_write;
  571. return to_write;
  572. }
  573. static ssize_t pattern_read(struct file *file, char __user *u_buff, size_t len, loff_t *off)
  574. {
  575. struct pattern_buf *patt_buf = file->f_inode->i_private;
  576. ssize_t to_read = len;
  577. if (*off + to_read >= MAX_PATTERN_LEN)
  578. to_read = MAX_PATTERN_LEN - *off;
  579. if (to_read <= 0)
  580. return 0;
  581. if (copy_to_user(u_buff, patt_buf->buf + *off, to_read))
  582. to_read = 0;
  583. else
  584. *off += to_read;
  585. return to_read;
  586. }
  587. static const struct file_operations fill_pattern_fops = {
  588. .read = pattern_read,
  589. .write = pattern_write,
  590. };
  591. static int setup_patt_bufs(void)
  592. {
  593. size_t i;
  594. for (i = 0; i < ARRAY_SIZE(patt_bufs); i++) {
  595. patt_bufs[i].buf = kmalloc(MAX_PATTERN_LEN, GFP_KERNEL);
  596. if (!patt_bufs[i].buf)
  597. break;
  598. strscpy_pad(patt_bufs[i].buf, DEFAULT_PATTERN, MAX_PATTERN_LEN);
  599. patt_bufs[i].len = DEFAULT_PATTERN_LEN;
  600. }
  601. return i;
  602. }
  603. static const char * const pattern_files[] = { "fill_pattern0", "fill_pattern1",
  604. "fill_pattern2", "fill_pattern3"};
  605. static int init_debug_files(int buf_count)
  606. {
  607. size_t i;
  608. char len_file_name[32];
  609. driver_debug_dir = debugfs_create_dir("pcmtest", NULL);
  610. if (IS_ERR(driver_debug_dir))
  611. return PTR_ERR(driver_debug_dir);
  612. debugfs_create_u8("pc_test", 0444, driver_debug_dir, &playback_capture_test);
  613. debugfs_create_u8("ioctl_test", 0444, driver_debug_dir, &ioctl_reset_test);
  614. for (i = 0; i < buf_count; i++) {
  615. debugfs_create_file(pattern_files[i], 0600, driver_debug_dir,
  616. &patt_bufs[i], &fill_pattern_fops);
  617. snprintf(len_file_name, sizeof(len_file_name), "%s_len", pattern_files[i]);
  618. debugfs_create_u32(len_file_name, 0444, driver_debug_dir, &patt_bufs[i].len);
  619. }
  620. return 0;
  621. }
  622. static void free_pattern_buffers(void)
  623. {
  624. int i;
  625. for (i = 0; i < buf_allocated; i++)
  626. kfree(patt_bufs[i].buf);
  627. }
  628. static void clear_debug_files(void)
  629. {
  630. debugfs_remove_recursive(driver_debug_dir);
  631. }
  632. static int __init mod_init(void)
  633. {
  634. int err = 0;
  635. buf_allocated = setup_patt_bufs();
  636. if (!buf_allocated)
  637. return -ENOMEM;
  638. snd_pcmtst_hw.channels_max = buf_allocated;
  639. err = init_debug_files(buf_allocated);
  640. if (err)
  641. return err;
  642. err = platform_device_register(&pcmtst_pdev);
  643. if (err)
  644. return err;
  645. err = platform_driver_register(&pcmtst_pdrv);
  646. if (err)
  647. platform_device_unregister(&pcmtst_pdev);
  648. return err;
  649. }
  650. static void __exit mod_exit(void)
  651. {
  652. clear_debug_files();
  653. free_pattern_buffers();
  654. platform_driver_unregister(&pcmtst_pdrv);
  655. platform_device_unregister(&pcmtst_pdev);
  656. }
  657. MODULE_DESCRIPTION("Virtual ALSA driver for PCM testing/fuzzing");
  658. MODULE_LICENSE("GPL");
  659. MODULE_AUTHOR("Ivan Orlov");
  660. module_init(mod_init);
  661. module_exit(mod_exit);