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