linux/sound/core/pcm.c
<<
>>
Prefs
   1/*
   2 *  Digital Audio (PCM) abstract layer
   3 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   4 *
   5 *
   6 *   This program is free software; you can redistribute it and/or modify
   7 *   it under the terms of the GNU General Public License as published by
   8 *   the Free Software Foundation; either version 2 of the License, or
   9 *   (at your option) any later version.
  10 *
  11 *   This program is distributed in the hope that it will be useful,
  12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *   GNU General Public License for more details.
  15 *
  16 *   You should have received a copy of the GNU General Public License
  17 *   along with this program; if not, write to the Free Software
  18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  19 *
  20 */
  21
  22#include <linux/init.h>
  23#include <linux/slab.h>
  24#include <linux/module.h>
  25#include <linux/time.h>
  26#include <linux/mutex.h>
  27#include <linux/device.h>
  28#include <linux/nospec.h>
  29#include <sound/core.h>
  30#include <sound/minors.h>
  31#include <sound/pcm.h>
  32#include <sound/timer.h>
  33#include <sound/control.h>
  34#include <sound/info.h>
  35
  36#include "pcm_local.h"
  37
  38MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>");
  39MODULE_DESCRIPTION("Midlevel PCM code for ALSA.");
  40MODULE_LICENSE("GPL");
  41
  42static LIST_HEAD(snd_pcm_devices);
  43static DEFINE_MUTEX(register_mutex);
  44#if IS_ENABLED(CONFIG_SND_PCM_OSS)
  45static LIST_HEAD(snd_pcm_notify_list);
  46#endif
  47
  48static int snd_pcm_free(struct snd_pcm *pcm);
  49static int snd_pcm_dev_free(struct snd_device *device);
  50static int snd_pcm_dev_register(struct snd_device *device);
  51static int snd_pcm_dev_disconnect(struct snd_device *device);
  52
  53static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
  54{
  55        struct snd_pcm *pcm;
  56
  57        list_for_each_entry(pcm, &snd_pcm_devices, list) {
  58                if (pcm->card == card && pcm->device == device)
  59                        return pcm;
  60        }
  61        return NULL;
  62}
  63
  64static int snd_pcm_next(struct snd_card *card, int device)
  65{
  66        struct snd_pcm *pcm;
  67
  68        list_for_each_entry(pcm, &snd_pcm_devices, list) {
  69                if (pcm->card == card && pcm->device > device)
  70                        return pcm->device;
  71                else if (pcm->card->number > card->number)
  72                        return -1;
  73        }
  74        return -1;
  75}
  76
  77static int snd_pcm_add(struct snd_pcm *newpcm)
  78{
  79        struct snd_pcm *pcm;
  80
  81        if (newpcm->internal)
  82                return 0;
  83
  84        list_for_each_entry(pcm, &snd_pcm_devices, list) {
  85                if (pcm->card == newpcm->card && pcm->device == newpcm->device)
  86                        return -EBUSY;
  87                if (pcm->card->number > newpcm->card->number ||
  88                                (pcm->card == newpcm->card &&
  89                                pcm->device > newpcm->device)) {
  90                        list_add(&newpcm->list, pcm->list.prev);
  91                        return 0;
  92                }
  93        }
  94        list_add_tail(&newpcm->list, &snd_pcm_devices);
  95        return 0;
  96}
  97
  98static int snd_pcm_control_ioctl(struct snd_card *card,
  99                                 struct snd_ctl_file *control,
 100                                 unsigned int cmd, unsigned long arg)
 101{
 102        switch (cmd) {
 103        case SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE:
 104                {
 105                        int device;
 106
 107                        if (get_user(device, (int __user *)arg))
 108                                return -EFAULT;
 109                        mutex_lock(&register_mutex);
 110                        device = snd_pcm_next(card, device);
 111                        mutex_unlock(&register_mutex);
 112                        if (put_user(device, (int __user *)arg))
 113                                return -EFAULT;
 114                        return 0;
 115                }
 116        case SNDRV_CTL_IOCTL_PCM_INFO:
 117                {
 118                        struct snd_pcm_info __user *info;
 119                        unsigned int device, subdevice;
 120                        int stream;
 121                        struct snd_pcm *pcm;
 122                        struct snd_pcm_str *pstr;
 123                        struct snd_pcm_substream *substream;
 124                        int err;
 125
 126                        info = (struct snd_pcm_info __user *)arg;
 127                        if (get_user(device, &info->device))
 128                                return -EFAULT;
 129                        if (get_user(stream, &info->stream))
 130                                return -EFAULT;
 131                        if (stream < 0 || stream > 1)
 132                                return -EINVAL;
 133                        stream = array_index_nospec(stream, 2);
 134                        if (get_user(subdevice, &info->subdevice))
 135                                return -EFAULT;
 136                        mutex_lock(&register_mutex);
 137                        pcm = snd_pcm_get(card, device);
 138                        if (pcm == NULL) {
 139                                err = -ENXIO;
 140                                goto _error;
 141                        }
 142                        pstr = &pcm->streams[stream];
 143                        if (pstr->substream_count == 0) {
 144                                err = -ENOENT;
 145                                goto _error;
 146                        }
 147                        if (subdevice >= pstr->substream_count) {
 148                                err = -ENXIO;
 149                                goto _error;
 150                        }
 151                        for (substream = pstr->substream; substream;
 152                             substream = substream->next)
 153                                if (substream->number == (int)subdevice)
 154                                        break;
 155                        if (substream == NULL) {
 156                                err = -ENXIO;
 157                                goto _error;
 158                        }
 159                        mutex_lock(&pcm->open_mutex);
 160                        err = snd_pcm_info_user(substream, info);
 161                        mutex_unlock(&pcm->open_mutex);
 162                _error:
 163                        mutex_unlock(&register_mutex);
 164                        return err;
 165                }
 166        case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
 167                {
 168                        int val;
 169                        
 170                        if (get_user(val, (int __user *)arg))
 171                                return -EFAULT;
 172                        control->preferred_subdevice[SND_CTL_SUBDEV_PCM] = val;
 173                        return 0;
 174                }
 175        }
 176        return -ENOIOCTLCMD;
 177}
 178
 179#define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v
 180
 181static char *snd_pcm_format_names[] = {
 182        FORMAT(S8),
 183        FORMAT(U8),
 184        FORMAT(S16_LE),
 185        FORMAT(S16_BE),
 186        FORMAT(U16_LE),
 187        FORMAT(U16_BE),
 188        FORMAT(S24_LE),
 189        FORMAT(S24_BE),
 190        FORMAT(U24_LE),
 191        FORMAT(U24_BE),
 192        FORMAT(S32_LE),
 193        FORMAT(S32_BE),
 194        FORMAT(U32_LE),
 195        FORMAT(U32_BE),
 196        FORMAT(FLOAT_LE),
 197        FORMAT(FLOAT_BE),
 198        FORMAT(FLOAT64_LE),
 199        FORMAT(FLOAT64_BE),
 200        FORMAT(IEC958_SUBFRAME_LE),
 201        FORMAT(IEC958_SUBFRAME_BE),
 202        FORMAT(MU_LAW),
 203        FORMAT(A_LAW),
 204        FORMAT(IMA_ADPCM),
 205        FORMAT(MPEG),
 206        FORMAT(GSM),
 207        FORMAT(SPECIAL),
 208        FORMAT(S24_3LE),
 209        FORMAT(S24_3BE),
 210        FORMAT(U24_3LE),
 211        FORMAT(U24_3BE),
 212        FORMAT(S20_3LE),
 213        FORMAT(S20_3BE),
 214        FORMAT(U20_3LE),
 215        FORMAT(U20_3BE),
 216        FORMAT(S18_3LE),
 217        FORMAT(S18_3BE),
 218        FORMAT(U18_3LE),
 219        FORMAT(U18_3BE),
 220        FORMAT(G723_24),
 221        FORMAT(G723_24_1B),
 222        FORMAT(G723_40),
 223        FORMAT(G723_40_1B),
 224        FORMAT(DSD_U8),
 225        FORMAT(DSD_U16_LE),
 226        FORMAT(DSD_U32_LE),
 227        FORMAT(DSD_U16_BE),
 228        FORMAT(DSD_U32_BE),
 229};
 230
 231/**
 232 * snd_pcm_format_name - Return a name string for the given PCM format
 233 * @format: PCM format
 234 */
 235const char *snd_pcm_format_name(snd_pcm_format_t format)
 236{
 237        if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names))
 238                return "Unknown";
 239        return snd_pcm_format_names[(__force unsigned int)format];
 240}
 241EXPORT_SYMBOL_GPL(snd_pcm_format_name);
 242
 243#ifdef CONFIG_SND_VERBOSE_PROCFS
 244
 245#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
 246#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
 247#define READY(v) [SNDRV_PCM_READY_##v] = #v
 248#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v
 249#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v
 250#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v
 251#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v
 252#define START(v) [SNDRV_PCM_START_##v] = #v
 253#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v 
 254
 255static char *snd_pcm_stream_names[] = {
 256        STREAM(PLAYBACK),
 257        STREAM(CAPTURE),
 258};
 259
 260static char *snd_pcm_state_names[] = {
 261        STATE(OPEN),
 262        STATE(SETUP),
 263        STATE(PREPARED),
 264        STATE(RUNNING),
 265        STATE(XRUN),
 266        STATE(DRAINING),
 267        STATE(PAUSED),
 268        STATE(SUSPENDED),
 269};
 270
 271static char *snd_pcm_access_names[] = {
 272        ACCESS(MMAP_INTERLEAVED), 
 273        ACCESS(MMAP_NONINTERLEAVED),
 274        ACCESS(MMAP_COMPLEX),
 275        ACCESS(RW_INTERLEAVED),
 276        ACCESS(RW_NONINTERLEAVED),
 277};
 278
 279static char *snd_pcm_subformat_names[] = {
 280        SUBFORMAT(STD), 
 281};
 282
 283static char *snd_pcm_tstamp_mode_names[] = {
 284        TSTAMP(NONE),
 285        TSTAMP(ENABLE),
 286};
 287
 288static const char *snd_pcm_stream_name(int stream)
 289{
 290        return snd_pcm_stream_names[stream];
 291}
 292
 293static const char *snd_pcm_access_name(snd_pcm_access_t access)
 294{
 295        return snd_pcm_access_names[(__force int)access];
 296}
 297
 298static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
 299{
 300        return snd_pcm_subformat_names[(__force int)subformat];
 301}
 302
 303static const char *snd_pcm_tstamp_mode_name(int mode)
 304{
 305        return snd_pcm_tstamp_mode_names[mode];
 306}
 307
 308static const char *snd_pcm_state_name(snd_pcm_state_t state)
 309{
 310        return snd_pcm_state_names[(__force int)state];
 311}
 312
 313#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 314#include <linux/soundcard.h>
 315
 316static const char *snd_pcm_oss_format_name(int format)
 317{
 318        switch (format) {
 319        case AFMT_MU_LAW:
 320                return "MU_LAW";
 321        case AFMT_A_LAW:
 322                return "A_LAW";
 323        case AFMT_IMA_ADPCM:
 324                return "IMA_ADPCM";
 325        case AFMT_U8:
 326                return "U8";
 327        case AFMT_S16_LE:
 328                return "S16_LE";
 329        case AFMT_S16_BE:
 330                return "S16_BE";
 331        case AFMT_S8:
 332                return "S8";
 333        case AFMT_U16_LE:
 334                return "U16_LE";
 335        case AFMT_U16_BE:
 336                return "U16_BE";
 337        case AFMT_MPEG:
 338                return "MPEG";
 339        default:
 340                return "unknown";
 341        }
 342}
 343#endif
 344
 345static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
 346                                   struct snd_info_buffer *buffer)
 347{
 348        struct snd_pcm_info *info;
 349        int err;
 350
 351        if (! substream)
 352                return;
 353
 354        info = kmalloc(sizeof(*info), GFP_KERNEL);
 355        if (!info)
 356                return;
 357
 358        err = snd_pcm_info(substream, info);
 359        if (err < 0) {
 360                snd_iprintf(buffer, "error %d\n", err);
 361                kfree(info);
 362                return;
 363        }
 364        snd_iprintf(buffer, "card: %d\n", info->card);
 365        snd_iprintf(buffer, "device: %d\n", info->device);
 366        snd_iprintf(buffer, "subdevice: %d\n", info->subdevice);
 367        snd_iprintf(buffer, "stream: %s\n", snd_pcm_stream_name(info->stream));
 368        snd_iprintf(buffer, "id: %s\n", info->id);
 369        snd_iprintf(buffer, "name: %s\n", info->name);
 370        snd_iprintf(buffer, "subname: %s\n", info->subname);
 371        snd_iprintf(buffer, "class: %d\n", info->dev_class);
 372        snd_iprintf(buffer, "subclass: %d\n", info->dev_subclass);
 373        snd_iprintf(buffer, "subdevices_count: %d\n", info->subdevices_count);
 374        snd_iprintf(buffer, "subdevices_avail: %d\n", info->subdevices_avail);
 375        kfree(info);
 376}
 377
 378static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry,
 379                                          struct snd_info_buffer *buffer)
 380{
 381        snd_pcm_proc_info_read(((struct snd_pcm_str *)entry->private_data)->substream,
 382                               buffer);
 383}
 384
 385static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry,
 386                                             struct snd_info_buffer *buffer)
 387{
 388        snd_pcm_proc_info_read(entry->private_data, buffer);
 389}
 390
 391static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
 392                                                  struct snd_info_buffer *buffer)
 393{
 394        struct snd_pcm_substream *substream = entry->private_data;
 395        struct snd_pcm_runtime *runtime;
 396
 397        mutex_lock(&substream->pcm->open_mutex);
 398        runtime = substream->runtime;
 399        if (!runtime) {
 400                snd_iprintf(buffer, "closed\n");
 401                goto unlock;
 402        }
 403        if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
 404                snd_iprintf(buffer, "no setup\n");
 405                goto unlock;
 406        }
 407        snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
 408        snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format));
 409        snd_iprintf(buffer, "subformat: %s\n", snd_pcm_subformat_name(runtime->subformat));
 410        snd_iprintf(buffer, "channels: %u\n", runtime->channels);       
 411        snd_iprintf(buffer, "rate: %u (%u/%u)\n", runtime->rate, runtime->rate_num, runtime->rate_den); 
 412        snd_iprintf(buffer, "period_size: %lu\n", runtime->period_size);        
 413        snd_iprintf(buffer, "buffer_size: %lu\n", runtime->buffer_size);        
 414#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 415        if (substream->oss.oss) {
 416                snd_iprintf(buffer, "OSS format: %s\n", snd_pcm_oss_format_name(runtime->oss.format));
 417                snd_iprintf(buffer, "OSS channels: %u\n", runtime->oss.channels);       
 418                snd_iprintf(buffer, "OSS rate: %u\n", runtime->oss.rate);
 419                snd_iprintf(buffer, "OSS period bytes: %lu\n", (unsigned long)runtime->oss.period_bytes);
 420                snd_iprintf(buffer, "OSS periods: %u\n", runtime->oss.periods);
 421                snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);
 422        }
 423#endif
 424 unlock:
 425        mutex_unlock(&substream->pcm->open_mutex);
 426}
 427
 428static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
 429                                                  struct snd_info_buffer *buffer)
 430{
 431        struct snd_pcm_substream *substream = entry->private_data;
 432        struct snd_pcm_runtime *runtime;
 433
 434        mutex_lock(&substream->pcm->open_mutex);
 435        runtime = substream->runtime;
 436        if (!runtime) {
 437                snd_iprintf(buffer, "closed\n");
 438                goto unlock;
 439        }
 440        if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
 441                snd_iprintf(buffer, "no setup\n");
 442                goto unlock;
 443        }
 444        snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
 445        snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);
 446        snd_iprintf(buffer, "avail_min: %lu\n", runtime->control->avail_min);
 447        snd_iprintf(buffer, "start_threshold: %lu\n", runtime->start_threshold);
 448        snd_iprintf(buffer, "stop_threshold: %lu\n", runtime->stop_threshold);
 449        snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
 450        snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
 451        snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
 452 unlock:
 453        mutex_unlock(&substream->pcm->open_mutex);
 454}
 455
 456static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
 457                                               struct snd_info_buffer *buffer)
 458{
 459        struct snd_pcm_substream *substream = entry->private_data;
 460        struct snd_pcm_runtime *runtime;
 461        struct snd_pcm_status status;
 462        int err;
 463
 464        mutex_lock(&substream->pcm->open_mutex);
 465        runtime = substream->runtime;
 466        if (!runtime) {
 467                snd_iprintf(buffer, "closed\n");
 468                goto unlock;
 469        }
 470        memset(&status, 0, sizeof(status));
 471        err = snd_pcm_status(substream, &status);
 472        if (err < 0) {
 473                snd_iprintf(buffer, "error %d\n", err);
 474                goto unlock;
 475        }
 476        snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
 477        snd_iprintf(buffer, "owner_pid   : %d\n", pid_vnr(substream->pid));
 478        snd_iprintf(buffer, "trigger_time: %ld.%09ld\n",
 479                status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec);
 480        snd_iprintf(buffer, "tstamp      : %ld.%09ld\n",
 481                status.tstamp.tv_sec, status.tstamp.tv_nsec);
 482        snd_iprintf(buffer, "delay       : %ld\n", status.delay);
 483        snd_iprintf(buffer, "avail       : %ld\n", status.avail);
 484        snd_iprintf(buffer, "avail_max   : %ld\n", status.avail_max);
 485        snd_iprintf(buffer, "-----\n");
 486        snd_iprintf(buffer, "hw_ptr      : %ld\n", runtime->status->hw_ptr);
 487        snd_iprintf(buffer, "appl_ptr    : %ld\n", runtime->control->appl_ptr);
 488 unlock:
 489        mutex_unlock(&substream->pcm->open_mutex);
 490}
 491
 492#ifdef CONFIG_SND_PCM_XRUN_DEBUG
 493static void snd_pcm_xrun_injection_write(struct snd_info_entry *entry,
 494                                         struct snd_info_buffer *buffer)
 495{
 496        struct snd_pcm_substream *substream = entry->private_data;
 497
 498        snd_pcm_stop_xrun(substream);
 499}
 500
 501static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
 502                                    struct snd_info_buffer *buffer)
 503{
 504        struct snd_pcm_str *pstr = entry->private_data;
 505        snd_iprintf(buffer, "%d\n", pstr->xrun_debug);
 506}
 507
 508static void snd_pcm_xrun_debug_write(struct snd_info_entry *entry,
 509                                     struct snd_info_buffer *buffer)
 510{
 511        struct snd_pcm_str *pstr = entry->private_data;
 512        char line[64];
 513        if (!snd_info_get_line(buffer, line, sizeof(line)))
 514                pstr->xrun_debug = simple_strtoul(line, NULL, 10);
 515}
 516#endif
 517
 518static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
 519{
 520        struct snd_pcm *pcm = pstr->pcm;
 521        struct snd_info_entry *entry;
 522        char name[16];
 523
 524        sprintf(name, "pcm%i%c", pcm->device, 
 525                pstr->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
 526        entry = snd_info_create_card_entry(pcm->card, name,
 527                                           pcm->card->proc_root);
 528        if (!entry)
 529                return -ENOMEM;
 530        entry->mode = S_IFDIR | 0555;
 531        pstr->proc_root = entry;
 532        entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root);
 533        if (entry)
 534                snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read);
 535#ifdef CONFIG_SND_PCM_XRUN_DEBUG
 536        entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
 537                                           pstr->proc_root);
 538        if (entry) {
 539                snd_info_set_text_ops(entry, pstr, snd_pcm_xrun_debug_read);
 540                entry->c.text.write = snd_pcm_xrun_debug_write;
 541                entry->mode |= 0200;
 542        }
 543#endif
 544        return 0;
 545}
 546
 547static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr)
 548{
 549        snd_info_free_entry(pstr->proc_root);
 550        pstr->proc_root = NULL;
 551        return 0;
 552}
 553
 554static struct snd_info_entry *
 555create_substream_info_entry(struct snd_pcm_substream *substream,
 556                            const char *name,
 557                            void (*read)(struct snd_info_entry *,
 558                                         struct snd_info_buffer *))
 559{
 560        struct snd_info_entry *entry;
 561
 562        entry = snd_info_create_card_entry(substream->pcm->card, name,
 563                                           substream->proc_root);
 564        if (entry)
 565                snd_info_set_text_ops(entry, substream, read);
 566        return entry;
 567}
 568
 569static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
 570{
 571        struct snd_info_entry *entry;
 572        struct snd_card *card;
 573        char name[16];
 574
 575        card = substream->pcm->card;
 576
 577        sprintf(name, "sub%i", substream->number);
 578        entry = snd_info_create_card_entry(card, name,
 579                                           substream->pstr->proc_root);
 580        if (!entry)
 581                return -ENOMEM;
 582        entry->mode = S_IFDIR | 0555;
 583        substream->proc_root = entry;
 584
 585        create_substream_info_entry(substream, "info",
 586                                    snd_pcm_substream_proc_info_read);
 587        create_substream_info_entry(substream, "hw_params",
 588                                    snd_pcm_substream_proc_hw_params_read);
 589        create_substream_info_entry(substream, "sw_params",
 590                                    snd_pcm_substream_proc_sw_params_read);
 591        create_substream_info_entry(substream, "status",
 592                                    snd_pcm_substream_proc_status_read);
 593
 594#ifdef CONFIG_SND_PCM_XRUN_DEBUG
 595        entry = create_substream_info_entry(substream, "xrun_injection", NULL);
 596        if (entry) {
 597                entry->c.text.write = snd_pcm_xrun_injection_write;
 598                entry->mode = S_IFREG | 0200;
 599        }
 600#endif /* CONFIG_SND_PCM_XRUN_DEBUG */
 601
 602        return 0;
 603}
 604
 605#else /* !CONFIG_SND_VERBOSE_PROCFS */
 606static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }
 607static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }
 608static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }
 609#endif /* CONFIG_SND_VERBOSE_PROCFS */
 610
 611static const struct attribute_group *pcm_dev_attr_groups[];
 612
 613/*
 614 * PM callbacks: we need to deal only with suspend here, as the resume is
 615 * triggered either from user-space or the driver's resume callback
 616 */
 617#ifdef CONFIG_PM_SLEEP
 618static int do_pcm_suspend(struct device *dev)
 619{
 620        struct snd_pcm_str *pstr = container_of(dev, struct snd_pcm_str, dev);
 621
 622        if (!pstr->pcm->no_device_suspend)
 623                snd_pcm_suspend_all(pstr->pcm);
 624        return 0;
 625}
 626#endif
 627
 628static const struct dev_pm_ops pcm_dev_pm_ops = {
 629        SET_SYSTEM_SLEEP_PM_OPS(do_pcm_suspend, NULL)
 630};
 631
 632/* device type for PCM -- basically only for passing PM callbacks */
 633static const struct device_type pcm_dev_type = {
 634        .name = "pcm",
 635        .pm = &pcm_dev_pm_ops,
 636};
 637
 638/**
 639 * snd_pcm_new_stream - create a new PCM stream
 640 * @pcm: the pcm instance
 641 * @stream: the stream direction, SNDRV_PCM_STREAM_XXX
 642 * @substream_count: the number of substreams
 643 *
 644 * Creates a new stream for the pcm.
 645 * The corresponding stream on the pcm must have been empty before
 646 * calling this, i.e. zero must be given to the argument of
 647 * snd_pcm_new().
 648 *
 649 * Return: Zero if successful, or a negative error code on failure.
 650 */
 651int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
 652{
 653        int idx, err;
 654        struct snd_pcm_str *pstr = &pcm->streams[stream];
 655        struct snd_pcm_substream *substream, *prev;
 656
 657#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 658        mutex_init(&pstr->oss.setup_mutex);
 659#endif
 660        pstr->stream = stream;
 661        pstr->pcm = pcm;
 662        pstr->substream_count = substream_count;
 663        if (!substream_count)
 664                return 0;
 665
 666        snd_device_initialize(&pstr->dev, pcm->card);
 667        pstr->dev.groups = pcm_dev_attr_groups;
 668        pstr->dev.type = &pcm_dev_type;
 669        dev_set_name(&pstr->dev, "pcmC%iD%i%c", pcm->card->number, pcm->device,
 670                     stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
 671
 672        if (!pcm->internal) {
 673                err = snd_pcm_stream_proc_init(pstr);
 674                if (err < 0) {
 675                        pcm_err(pcm, "Error in snd_pcm_stream_proc_init\n");
 676                        return err;
 677                }
 678        }
 679        prev = NULL;
 680        for (idx = 0, prev = NULL; idx < substream_count; idx++) {
 681                substream = kzalloc(sizeof(*substream), GFP_KERNEL);
 682                if (!substream)
 683                        return -ENOMEM;
 684                substream->pcm = pcm;
 685                substream->pstr = pstr;
 686                substream->number = idx;
 687                substream->stream = stream;
 688                sprintf(substream->name, "subdevice #%i", idx);
 689                substream->buffer_bytes_max = UINT_MAX;
 690                if (prev == NULL)
 691                        pstr->substream = substream;
 692                else
 693                        prev->next = substream;
 694
 695                if (!pcm->internal) {
 696                        err = snd_pcm_substream_proc_init(substream);
 697                        if (err < 0) {
 698                                pcm_err(pcm,
 699                                        "Error in snd_pcm_stream_proc_init\n");
 700                                if (prev == NULL)
 701                                        pstr->substream = NULL;
 702                                else
 703                                        prev->next = NULL;
 704                                kfree(substream);
 705                                return err;
 706                        }
 707                }
 708                substream->group = &substream->self_group;
 709                snd_pcm_group_init(&substream->self_group);
 710                list_add_tail(&substream->link_list, &substream->self_group.substreams);
 711                atomic_set(&substream->mmap_count, 0);
 712                prev = substream;
 713        }
 714        return 0;
 715}                               
 716EXPORT_SYMBOL(snd_pcm_new_stream);
 717
 718static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
 719                int playback_count, int capture_count, bool internal,
 720                struct snd_pcm **rpcm)
 721{
 722        struct snd_pcm *pcm;
 723        int err;
 724        static struct snd_device_ops ops = {
 725                .dev_free = snd_pcm_dev_free,
 726                .dev_register = snd_pcm_dev_register,
 727                .dev_disconnect = snd_pcm_dev_disconnect,
 728        };
 729        static struct snd_device_ops internal_ops = {
 730                .dev_free = snd_pcm_dev_free,
 731        };
 732
 733        if (snd_BUG_ON(!card))
 734                return -ENXIO;
 735        if (rpcm)
 736                *rpcm = NULL;
 737        pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
 738        if (!pcm)
 739                return -ENOMEM;
 740        pcm->card = card;
 741        pcm->device = device;
 742        pcm->internal = internal;
 743        mutex_init(&pcm->open_mutex);
 744        init_waitqueue_head(&pcm->open_wait);
 745        INIT_LIST_HEAD(&pcm->list);
 746        if (id)
 747                strlcpy(pcm->id, id, sizeof(pcm->id));
 748
 749        err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK,
 750                                 playback_count);
 751        if (err < 0)
 752                goto free_pcm;
 753
 754        err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count);
 755        if (err < 0)
 756                goto free_pcm;
 757
 758        err = snd_device_new(card, SNDRV_DEV_PCM, pcm,
 759                             internal ? &internal_ops : &ops);
 760        if (err < 0)
 761                goto free_pcm;
 762
 763        if (rpcm)
 764                *rpcm = pcm;
 765        return 0;
 766
 767free_pcm:
 768        snd_pcm_free(pcm);
 769        return err;
 770}
 771
 772/**
 773 * snd_pcm_new - create a new PCM instance
 774 * @card: the card instance
 775 * @id: the id string
 776 * @device: the device index (zero based)
 777 * @playback_count: the number of substreams for playback
 778 * @capture_count: the number of substreams for capture
 779 * @rpcm: the pointer to store the new pcm instance
 780 *
 781 * Creates a new PCM instance.
 782 *
 783 * The pcm operators have to be set afterwards to the new instance
 784 * via snd_pcm_set_ops().
 785 *
 786 * Return: Zero if successful, or a negative error code on failure.
 787 */
 788int snd_pcm_new(struct snd_card *card, const char *id, int device,
 789                int playback_count, int capture_count, struct snd_pcm **rpcm)
 790{
 791        return _snd_pcm_new(card, id, device, playback_count, capture_count,
 792                        false, rpcm);
 793}
 794EXPORT_SYMBOL(snd_pcm_new);
 795
 796/**
 797 * snd_pcm_new_internal - create a new internal PCM instance
 798 * @card: the card instance
 799 * @id: the id string
 800 * @device: the device index (zero based - shared with normal PCMs)
 801 * @playback_count: the number of substreams for playback
 802 * @capture_count: the number of substreams for capture
 803 * @rpcm: the pointer to store the new pcm instance
 804 *
 805 * Creates a new internal PCM instance with no userspace device or procfs
 806 * entries. This is used by ASoC Back End PCMs in order to create a PCM that
 807 * will only be used internally by kernel drivers. i.e. it cannot be opened
 808 * by userspace. It provides existing ASoC components drivers with a substream
 809 * and access to any private data.
 810 *
 811 * The pcm operators have to be set afterwards to the new instance
 812 * via snd_pcm_set_ops().
 813 *
 814 * Return: Zero if successful, or a negative error code on failure.
 815 */
 816int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
 817        int playback_count, int capture_count,
 818        struct snd_pcm **rpcm)
 819{
 820        return _snd_pcm_new(card, id, device, playback_count, capture_count,
 821                        true, rpcm);
 822}
 823EXPORT_SYMBOL(snd_pcm_new_internal);
 824
 825static void free_chmap(struct snd_pcm_str *pstr)
 826{
 827        if (pstr->chmap_kctl) {
 828                snd_ctl_remove(pstr->pcm->card, pstr->chmap_kctl);
 829                pstr->chmap_kctl = NULL;
 830        }
 831}
 832
 833static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
 834{
 835        struct snd_pcm_substream *substream, *substream_next;
 836#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 837        struct snd_pcm_oss_setup *setup, *setupn;
 838#endif
 839
 840        /* free all proc files under the stream */
 841        snd_pcm_stream_proc_done(pstr);
 842
 843        substream = pstr->substream;
 844        while (substream) {
 845                substream_next = substream->next;
 846                snd_pcm_timer_done(substream);
 847                kfree(substream);
 848                substream = substream_next;
 849        }
 850#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 851        for (setup = pstr->oss.setup_list; setup; setup = setupn) {
 852                setupn = setup->next;
 853                kfree(setup->task_name);
 854                kfree(setup);
 855        }
 856#endif
 857        free_chmap(pstr);
 858        if (pstr->substream_count)
 859                put_device(&pstr->dev);
 860}
 861
 862#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 863#define pcm_call_notify(pcm, call)                                      \
 864        do {                                                            \
 865                struct snd_pcm_notify *_notify;                         \
 866                list_for_each_entry(_notify, &snd_pcm_notify_list, list) \
 867                        _notify->call(pcm);                             \
 868        } while (0)
 869#else
 870#define pcm_call_notify(pcm, call) do {} while (0)
 871#endif
 872
 873static int snd_pcm_free(struct snd_pcm *pcm)
 874{
 875        if (!pcm)
 876                return 0;
 877        if (!pcm->internal)
 878                pcm_call_notify(pcm, n_unregister);
 879        if (pcm->private_free)
 880                pcm->private_free(pcm);
 881        snd_pcm_lib_preallocate_free_for_all(pcm);
 882        snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]);
 883        snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_CAPTURE]);
 884        kfree(pcm);
 885        return 0;
 886}
 887
 888static int snd_pcm_dev_free(struct snd_device *device)
 889{
 890        struct snd_pcm *pcm = device->device_data;
 891        return snd_pcm_free(pcm);
 892}
 893
 894int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
 895                             struct file *file,
 896                             struct snd_pcm_substream **rsubstream)
 897{
 898        struct snd_pcm_str * pstr;
 899        struct snd_pcm_substream *substream;
 900        struct snd_pcm_runtime *runtime;
 901        struct snd_card *card;
 902        int prefer_subdevice;
 903        size_t size;
 904
 905        if (snd_BUG_ON(!pcm || !rsubstream))
 906                return -ENXIO;
 907        if (snd_BUG_ON(stream != SNDRV_PCM_STREAM_PLAYBACK &&
 908                       stream != SNDRV_PCM_STREAM_CAPTURE))
 909                return -EINVAL;
 910        *rsubstream = NULL;
 911        pstr = &pcm->streams[stream];
 912        if (pstr->substream == NULL || pstr->substream_count == 0)
 913                return -ENODEV;
 914
 915        card = pcm->card;
 916        prefer_subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_PCM);
 917
 918        if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
 919                int opposite = !stream;
 920
 921                for (substream = pcm->streams[opposite].substream; substream;
 922                     substream = substream->next) {
 923                        if (SUBSTREAM_BUSY(substream))
 924                                return -EAGAIN;
 925                }
 926        }
 927
 928        if (file->f_flags & O_APPEND) {
 929                if (prefer_subdevice < 0) {
 930                        if (pstr->substream_count > 1)
 931                                return -EINVAL; /* must be unique */
 932                        substream = pstr->substream;
 933                } else {
 934                        for (substream = pstr->substream; substream;
 935                             substream = substream->next)
 936                                if (substream->number == prefer_subdevice)
 937                                        break;
 938                }
 939                if (! substream)
 940                        return -ENODEV;
 941                if (! SUBSTREAM_BUSY(substream))
 942                        return -EBADFD;
 943                substream->ref_count++;
 944                *rsubstream = substream;
 945                return 0;
 946        }
 947
 948        for (substream = pstr->substream; substream; substream = substream->next) {
 949                if (!SUBSTREAM_BUSY(substream) &&
 950                    (prefer_subdevice == -1 ||
 951                     substream->number == prefer_subdevice))
 952                        break;
 953        }
 954        if (substream == NULL)
 955                return -EAGAIN;
 956
 957        runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
 958        if (runtime == NULL)
 959                return -ENOMEM;
 960
 961        size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status));
 962        runtime->status = snd_malloc_pages(size, GFP_KERNEL);
 963        if (runtime->status == NULL) {
 964                kfree(runtime);
 965                return -ENOMEM;
 966        }
 967        memset((void*)runtime->status, 0, size);
 968
 969        size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control));
 970        runtime->control = snd_malloc_pages(size, GFP_KERNEL);
 971        if (runtime->control == NULL) {
 972                snd_free_pages((void*)runtime->status,
 973                               PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
 974                kfree(runtime);
 975                return -ENOMEM;
 976        }
 977        memset((void*)runtime->control, 0, size);
 978
 979        init_waitqueue_head(&runtime->sleep);
 980        init_waitqueue_head(&runtime->tsleep);
 981
 982        runtime->status->state = SNDRV_PCM_STATE_OPEN;
 983
 984        substream->runtime = runtime;
 985        substream->private_data = pcm->private_data;
 986        substream->ref_count = 1;
 987        substream->f_flags = file->f_flags;
 988        substream->pid = get_pid(task_pid(current));
 989        pstr->substream_opened++;
 990        *rsubstream = substream;
 991        return 0;
 992}
 993
 994void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
 995{
 996        struct snd_pcm_runtime *runtime;
 997
 998        if (PCM_RUNTIME_CHECK(substream))
 999                return;
1000        runtime = substream->runtime;
1001        if (runtime->private_free != NULL)
1002                runtime->private_free(runtime);
1003        snd_free_pages((void*)runtime->status,
1004                       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
1005        snd_free_pages((void*)runtime->control,
1006                       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
1007        kfree(runtime->hw_constraints.rules);
1008        /* Avoid concurrent access to runtime via PCM timer interface */
1009        if (substream->timer)
1010                spin_lock_irq(&substream->timer->lock);
1011        substream->runtime = NULL;
1012        if (substream->timer)
1013                spin_unlock_irq(&substream->timer->lock);
1014        kfree(runtime);
1015        put_pid(substream->pid);
1016        substream->pid = NULL;
1017        substream->pstr->substream_opened--;
1018}
1019
1020static ssize_t show_pcm_class(struct device *dev,
1021                              struct device_attribute *attr, char *buf)
1022{
1023        struct snd_pcm_str *pstr = container_of(dev, struct snd_pcm_str, dev);
1024        struct snd_pcm *pcm = pstr->pcm;
1025        const char *str;
1026        static const char *strs[SNDRV_PCM_CLASS_LAST + 1] = {
1027                [SNDRV_PCM_CLASS_GENERIC] = "generic",
1028                [SNDRV_PCM_CLASS_MULTI] = "multi",
1029                [SNDRV_PCM_CLASS_MODEM] = "modem",
1030                [SNDRV_PCM_CLASS_DIGITIZER] = "digitizer",
1031        };
1032
1033        if (pcm->dev_class > SNDRV_PCM_CLASS_LAST)
1034                str = "none";
1035        else
1036                str = strs[pcm->dev_class];
1037        return snprintf(buf, PAGE_SIZE, "%s\n", str);
1038}
1039
1040static DEVICE_ATTR(pcm_class, 0444, show_pcm_class, NULL);
1041static struct attribute *pcm_dev_attrs[] = {
1042        &dev_attr_pcm_class.attr,
1043        NULL
1044};
1045
1046static const struct attribute_group pcm_dev_attr_group = {
1047        .attrs  = pcm_dev_attrs,
1048};
1049
1050static const struct attribute_group *pcm_dev_attr_groups[] = {
1051        &pcm_dev_attr_group,
1052        NULL
1053};
1054
1055static int snd_pcm_dev_register(struct snd_device *device)
1056{
1057        int cidx, err;
1058        struct snd_pcm_substream *substream;
1059        struct snd_pcm *pcm;
1060
1061        if (snd_BUG_ON(!device || !device->device_data))
1062                return -ENXIO;
1063        pcm = device->device_data;
1064
1065        mutex_lock(&register_mutex);
1066        err = snd_pcm_add(pcm);
1067        if (err)
1068                goto unlock;
1069        for (cidx = 0; cidx < 2; cidx++) {
1070                int devtype = -1;
1071                if (pcm->streams[cidx].substream == NULL)
1072                        continue;
1073                switch (cidx) {
1074                case SNDRV_PCM_STREAM_PLAYBACK:
1075                        devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
1076                        break;
1077                case SNDRV_PCM_STREAM_CAPTURE:
1078                        devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
1079                        break;
1080                }
1081                /* register pcm */
1082                err = snd_register_device(devtype, pcm->card, pcm->device,
1083                                          &snd_pcm_f_ops[cidx], pcm,
1084                                          &pcm->streams[cidx].dev);
1085                if (err < 0) {
1086                        list_del_init(&pcm->list);
1087                        goto unlock;
1088                }
1089
1090                for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
1091                        snd_pcm_timer_init(substream);
1092        }
1093
1094        pcm_call_notify(pcm, n_register);
1095
1096 unlock:
1097        mutex_unlock(&register_mutex);
1098        return err;
1099}
1100
1101static int snd_pcm_dev_disconnect(struct snd_device *device)
1102{
1103        struct snd_pcm *pcm = device->device_data;
1104        struct snd_pcm_substream *substream;
1105        int cidx;
1106
1107        mutex_lock(&register_mutex);
1108        mutex_lock(&pcm->open_mutex);
1109        wake_up(&pcm->open_wait);
1110        list_del_init(&pcm->list);
1111        for (cidx = 0; cidx < 2; cidx++) {
1112                for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
1113                        snd_pcm_stream_lock_irq(substream);
1114                        if (substream->runtime) {
1115                                if (snd_pcm_running(substream))
1116                                        snd_pcm_stop(substream,
1117                                                     SNDRV_PCM_STATE_DISCONNECTED);
1118                                /* to be sure, set the state unconditionally */
1119                                substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
1120                                wake_up(&substream->runtime->sleep);
1121                                wake_up(&substream->runtime->tsleep);
1122                        }
1123                        snd_pcm_stream_unlock_irq(substream);
1124                }
1125        }
1126
1127        pcm_call_notify(pcm, n_disconnect);
1128        for (cidx = 0; cidx < 2; cidx++) {
1129                snd_unregister_device(&pcm->streams[cidx].dev);
1130                free_chmap(&pcm->streams[cidx]);
1131        }
1132        mutex_unlock(&pcm->open_mutex);
1133        mutex_unlock(&register_mutex);
1134        return 0;
1135}
1136
1137#if IS_ENABLED(CONFIG_SND_PCM_OSS)
1138/**
1139 * snd_pcm_notify - Add/remove the notify list
1140 * @notify: PCM notify list
1141 * @nfree: 0 = register, 1 = unregister
1142 *
1143 * This adds the given notifier to the global list so that the callback is
1144 * called for each registered PCM devices.  This exists only for PCM OSS
1145 * emulation, so far.
1146 */
1147int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
1148{
1149        struct snd_pcm *pcm;
1150
1151        if (snd_BUG_ON(!notify ||
1152                       !notify->n_register ||
1153                       !notify->n_unregister ||
1154                       !notify->n_disconnect))
1155                return -EINVAL;
1156        mutex_lock(&register_mutex);
1157        if (nfree) {
1158                list_del(&notify->list);
1159                list_for_each_entry(pcm, &snd_pcm_devices, list)
1160                        notify->n_unregister(pcm);
1161        } else {
1162                list_add_tail(&notify->list, &snd_pcm_notify_list);
1163                list_for_each_entry(pcm, &snd_pcm_devices, list)
1164                        notify->n_register(pcm);
1165        }
1166        mutex_unlock(&register_mutex);
1167        return 0;
1168}
1169EXPORT_SYMBOL(snd_pcm_notify);
1170#endif /* CONFIG_SND_PCM_OSS */
1171
1172#ifdef CONFIG_SND_PROC_FS
1173/*
1174 *  Info interface
1175 */
1176
1177static void snd_pcm_proc_read(struct snd_info_entry *entry,
1178                              struct snd_info_buffer *buffer)
1179{
1180        struct snd_pcm *pcm;
1181
1182        mutex_lock(&register_mutex);
1183        list_for_each_entry(pcm, &snd_pcm_devices, list) {
1184                snd_iprintf(buffer, "%02i-%02i: %s : %s",
1185                            pcm->card->number, pcm->device, pcm->id, pcm->name);
1186                if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
1187                        snd_iprintf(buffer, " : playback %i",
1188                                    pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count);
1189                if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
1190                        snd_iprintf(buffer, " : capture %i",
1191                                    pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
1192                snd_iprintf(buffer, "\n");
1193        }
1194        mutex_unlock(&register_mutex);
1195}
1196
1197static struct snd_info_entry *snd_pcm_proc_entry;
1198
1199static void snd_pcm_proc_init(void)
1200{
1201        struct snd_info_entry *entry;
1202
1203        entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL);
1204        if (entry) {
1205                snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read);
1206                if (snd_info_register(entry) < 0) {
1207                        snd_info_free_entry(entry);
1208                        entry = NULL;
1209                }
1210        }
1211        snd_pcm_proc_entry = entry;
1212}
1213
1214static void snd_pcm_proc_done(void)
1215{
1216        snd_info_free_entry(snd_pcm_proc_entry);
1217}
1218
1219#else /* !CONFIG_SND_PROC_FS */
1220#define snd_pcm_proc_init()
1221#define snd_pcm_proc_done()
1222#endif /* CONFIG_SND_PROC_FS */
1223
1224
1225/*
1226 *  ENTRY functions
1227 */
1228
1229static int __init alsa_pcm_init(void)
1230{
1231        snd_ctl_register_ioctl(snd_pcm_control_ioctl);
1232        snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
1233        snd_pcm_proc_init();
1234        return 0;
1235}
1236
1237static void __exit alsa_pcm_exit(void)
1238{
1239        snd_ctl_unregister_ioctl(snd_pcm_control_ioctl);
1240        snd_ctl_unregister_ioctl_compat(snd_pcm_control_ioctl);
1241        snd_pcm_proc_done();
1242}
1243
1244module_init(alsa_pcm_init)
1245module_exit(alsa_pcm_exit)
1246