aboutsummaryrefslogtreecommitdiff
path: root/sound/core/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/pcm.c')
-rw-r--r--sound/core/pcm.c454
1 files changed, 254 insertions, 200 deletions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 184e74b75ba..28ca61eb0b0 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -33,23 +33,33 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Abramo Bagnara <abramo@alsa-proj
MODULE_DESCRIPTION("Midlevel PCM code for ALSA.");
MODULE_LICENSE("GPL");
-snd_pcm_t *snd_pcm_devices[SNDRV_CARDS * SNDRV_PCM_DEVICES];
+static LIST_HEAD(snd_pcm_devices);
static LIST_HEAD(snd_pcm_notify_list);
static DECLARE_MUTEX(register_mutex);
-static int snd_pcm_free(snd_pcm_t *pcm);
-static int snd_pcm_dev_free(snd_device_t *device);
-static int snd_pcm_dev_register(snd_device_t *device);
-static int snd_pcm_dev_disconnect(snd_device_t *device);
-static int snd_pcm_dev_unregister(snd_device_t *device);
+static int snd_pcm_free(struct snd_pcm *pcm);
+static int snd_pcm_dev_free(struct snd_device *device);
+static int snd_pcm_dev_register(struct snd_device *device);
+static int snd_pcm_dev_disconnect(struct snd_device *device);
+static int snd_pcm_dev_unregister(struct snd_device *device);
-static int snd_pcm_control_ioctl(snd_card_t * card,
- snd_ctl_file_t * control,
- unsigned int cmd, unsigned long arg)
+static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device)
{
- unsigned int tmp;
+ struct list_head *p;
+ struct snd_pcm *pcm;
+
+ list_for_each(p, &snd_pcm_devices) {
+ pcm = list_entry(p, struct snd_pcm, list);
+ if (pcm->card == card && pcm->device == device)
+ return pcm;
+ }
+ return NULL;
+}
- tmp = card->number * SNDRV_PCM_DEVICES;
+static int snd_pcm_control_ioctl(struct snd_card *card,
+ struct snd_ctl_file *control,
+ unsigned int cmd, unsigned long arg)
+{
switch (cmd) {
case SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE:
{
@@ -57,51 +67,66 @@ static int snd_pcm_control_ioctl(snd_card_t * card,
if (get_user(device, (int __user *)arg))
return -EFAULT;
+ down(&register_mutex);
device = device < 0 ? 0 : device + 1;
while (device < SNDRV_PCM_DEVICES) {
- if (snd_pcm_devices[tmp + device])
+ if (snd_pcm_search(card, device))
break;
device++;
}
if (device == SNDRV_PCM_DEVICES)
device = -1;
+ up(&register_mutex);
if (put_user(device, (int __user *)arg))
return -EFAULT;
return 0;
}
case SNDRV_CTL_IOCTL_PCM_INFO:
{
- snd_pcm_info_t __user *info;
+ struct snd_pcm_info __user *info;
unsigned int device, subdevice;
- snd_pcm_stream_t stream;
- snd_pcm_t *pcm;
- snd_pcm_str_t *pstr;
- snd_pcm_substream_t *substream;
- info = (snd_pcm_info_t __user *)arg;
+ int stream;
+ struct snd_pcm *pcm;
+ struct snd_pcm_str *pstr;
+ struct snd_pcm_substream *substream;
+ int err;
+
+ info = (struct snd_pcm_info __user *)arg;
if (get_user(device, &info->device))
return -EFAULT;
- if (device >= SNDRV_PCM_DEVICES)
- return -ENXIO;
- pcm = snd_pcm_devices[tmp + device];
- if (pcm == NULL)
- return -ENXIO;
if (get_user(stream, &info->stream))
return -EFAULT;
if (stream < 0 || stream > 1)
return -EINVAL;
- pstr = &pcm->streams[stream];
- if (pstr->substream_count == 0)
- return -ENOENT;
if (get_user(subdevice, &info->subdevice))
return -EFAULT;
- if (subdevice >= pstr->substream_count)
- return -ENXIO;
- for (substream = pstr->substream; substream; substream = substream->next)
+ down(&register_mutex);
+ pcm = snd_pcm_search(card, device);
+ if (pcm == NULL) {
+ err = -ENXIO;
+ goto _error;
+ }
+ pstr = &pcm->streams[stream];
+ if (pstr->substream_count == 0) {
+ err = -ENOENT;
+ goto _error;
+ }
+ if (subdevice >= pstr->substream_count) {
+ err = -ENXIO;
+ goto _error;
+ }
+ for (substream = pstr->substream; substream;
+ substream = substream->next)
if (substream->number == (int)subdevice)
break;
- if (substream == NULL)
- return -ENXIO;
- return snd_pcm_info_user(substream, info);
+ if (substream == NULL) {
+ err = -ENXIO;
+ goto _error;
+ }
+ err = snd_pcm_info_user(substream, info);
+ _error:
+ up(&register_mutex);
+ return err;
}
case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
{
@@ -126,30 +151,6 @@ static int snd_pcm_control_ioctl(snd_card_t * card,
#define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v
#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v
-static char *snd_pcm_stream_names[] = {
- STREAM(PLAYBACK),
- STREAM(CAPTURE),
-};
-
-static char *snd_pcm_state_names[] = {
- STATE(OPEN),
- STATE(SETUP),
- STATE(PREPARED),
- STATE(RUNNING),
- STATE(XRUN),
- STATE(DRAINING),
- STATE(PAUSED),
- STATE(SUSPENDED),
-};
-
-static char *snd_pcm_access_names[] = {
- ACCESS(MMAP_INTERLEAVED),
- ACCESS(MMAP_NONINTERLEAVED),
- ACCESS(MMAP_COMPLEX),
- ACCESS(RW_INTERLEAVED),
- ACCESS(RW_NONINTERLEAVED),
-};
-
static char *snd_pcm_format_names[] = {
FORMAT(S8),
FORMAT(U8),
@@ -191,6 +192,36 @@ static char *snd_pcm_format_names[] = {
FORMAT(U18_3BE),
};
+const char *snd_pcm_format_name(snd_pcm_format_t format)
+{
+ return snd_pcm_format_names[format];
+}
+
+#ifdef CONFIG_PROC_FS
+static char *snd_pcm_stream_names[] = {
+ STREAM(PLAYBACK),
+ STREAM(CAPTURE),
+};
+
+static char *snd_pcm_state_names[] = {
+ STATE(OPEN),
+ STATE(SETUP),
+ STATE(PREPARED),
+ STATE(RUNNING),
+ STATE(XRUN),
+ STATE(DRAINING),
+ STATE(PAUSED),
+ STATE(SUSPENDED),
+};
+
+static char *snd_pcm_access_names[] = {
+ ACCESS(MMAP_INTERLEAVED),
+ ACCESS(MMAP_NONINTERLEAVED),
+ ACCESS(MMAP_COMPLEX),
+ ACCESS(RW_INTERLEAVED),
+ ACCESS(RW_NONINTERLEAVED),
+};
+
static char *snd_pcm_subformat_names[] = {
SUBFORMAT(STD),
};
@@ -200,7 +231,7 @@ static char *snd_pcm_tstamp_mode_names[] = {
TSTAMP(MMAP),
};
-static const char *snd_pcm_stream_name(snd_pcm_stream_t stream)
+static const char *snd_pcm_stream_name(int stream)
{
snd_assert(stream <= SNDRV_PCM_STREAM_LAST, return NULL);
return snd_pcm_stream_names[stream];
@@ -208,23 +239,15 @@ static const char *snd_pcm_stream_name(snd_pcm_stream_t stream)
static const char *snd_pcm_access_name(snd_pcm_access_t access)
{
- snd_assert(access <= SNDRV_PCM_ACCESS_LAST, return NULL);
return snd_pcm_access_names[access];
}
-const char *snd_pcm_format_name(snd_pcm_format_t format)
-{
- snd_assert(format <= SNDRV_PCM_FORMAT_LAST, return NULL);
- return snd_pcm_format_names[format];
-}
-
static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
{
- snd_assert(subformat <= SNDRV_PCM_SUBFORMAT_LAST, return NULL);
return snd_pcm_subformat_names[subformat];
}
-static const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode)
+static const char *snd_pcm_tstamp_mode_name(int mode)
{
snd_assert(mode <= SNDRV_PCM_TSTAMP_LAST, return NULL);
return snd_pcm_tstamp_mode_names[mode];
@@ -232,7 +255,6 @@ static const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode)
static const char *snd_pcm_state_name(snd_pcm_state_t state)
{
- snd_assert(state <= SNDRV_PCM_STATE_LAST, return NULL);
return snd_pcm_state_names[state];
}
@@ -267,10 +289,10 @@ static const char *snd_pcm_oss_format_name(int format)
}
#endif
-#ifdef CONFIG_PROC_FS
-static void snd_pcm_proc_info_read(snd_pcm_substream_t *substream, snd_info_buffer_t *buffer)
+static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
+ struct snd_info_buffer *buffer)
{
- snd_pcm_info_t *info;
+ struct snd_pcm_info *info;
int err;
if (! substream)
@@ -302,20 +324,25 @@ static void snd_pcm_proc_info_read(snd_pcm_substream_t *substream, snd_info_buff
kfree(info);
}
-static void snd_pcm_stream_proc_info_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
- snd_pcm_proc_info_read(((snd_pcm_str_t *)entry->private_data)->substream, buffer);
+ snd_pcm_proc_info_read(((struct snd_pcm_str *)entry->private_data)->substream,
+ buffer);
}
-static void snd_pcm_substream_proc_info_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
- snd_pcm_proc_info_read((snd_pcm_substream_t *)entry->private_data, buffer);
+ snd_pcm_proc_info_read((struct snd_pcm_substream *)entry->private_data,
+ buffer);
}
-static void snd_pcm_substream_proc_hw_params_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
- snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_pcm_substream *substream = entry->private_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
if (!runtime) {
snd_iprintf(buffer, "closed\n");
return;
@@ -347,10 +374,11 @@ static void snd_pcm_substream_proc_hw_params_read(snd_info_entry_t *entry, snd_i
snd_pcm_stream_unlock_irq(substream);
}
-static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
- snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;
- snd_pcm_runtime_t *runtime = substream->runtime;
+ struct snd_pcm_substream *substream = entry->private_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
if (!runtime) {
snd_iprintf(buffer, "closed\n");
return;
@@ -374,11 +402,12 @@ static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_i
snd_pcm_stream_unlock_irq(substream);
}
-static void snd_pcm_substream_proc_status_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
- snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;
- snd_pcm_runtime_t *runtime = substream->runtime;
- snd_pcm_status_t status;
+ struct snd_pcm_substream *substream = entry->private_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_pcm_status status;
int err;
if (!runtime) {
snd_iprintf(buffer, "closed\n");
@@ -402,28 +431,29 @@ static void snd_pcm_substream_proc_status_read(snd_info_entry_t *entry, snd_info
snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr);
snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr);
}
-#endif
#ifdef CONFIG_SND_DEBUG
-static void snd_pcm_xrun_debug_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
- snd_pcm_str_t *pstr = (snd_pcm_str_t *)entry->private_data;
+ struct snd_pcm_str *pstr = entry->private_data;
snd_iprintf(buffer, "%d\n", pstr->xrun_debug);
}
-static void snd_pcm_xrun_debug_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_xrun_debug_write(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
- snd_pcm_str_t *pstr = (snd_pcm_str_t *)entry->private_data;
+ struct snd_pcm_str *pstr = entry->private_data;
char line[64];
if (!snd_info_get_line(buffer, line, sizeof(line)))
pstr->xrun_debug = simple_strtoul(line, NULL, 10);
}
#endif
-static int snd_pcm_stream_proc_init(snd_pcm_str_t *pstr)
+static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
{
- snd_pcm_t *pcm = pstr->pcm;
- snd_info_entry_t *entry;
+ struct snd_pcm *pcm = pstr->pcm;
+ struct snd_info_entry *entry;
char name[16];
sprintf(name, "pcm%i%c", pcm->device,
@@ -447,7 +477,8 @@ static int snd_pcm_stream_proc_init(snd_pcm_str_t *pstr)
pstr->proc_info_entry = entry;
#ifdef CONFIG_SND_DEBUG
- if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", pstr->proc_root)) != NULL) {
+ if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
+ pstr->proc_root)) != NULL) {
entry->c.text.read_size = 64;
entry->c.text.read = snd_pcm_xrun_debug_read;
entry->c.text.write_size = 64;
@@ -464,7 +495,7 @@ static int snd_pcm_stream_proc_init(snd_pcm_str_t *pstr)
return 0;
}
-static int snd_pcm_stream_proc_done(snd_pcm_str_t *pstr)
+static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr)
{
#ifdef CONFIG_SND_DEBUG
if (pstr->proc_xrun_debug_entry) {
@@ -483,10 +514,10 @@ static int snd_pcm_stream_proc_done(snd_pcm_str_t *pstr)
return 0;
}
-static int snd_pcm_substream_proc_init(snd_pcm_substream_t *substream)
+static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
{
- snd_info_entry_t *entry;
- snd_card_t *card;
+ struct snd_info_entry *entry;
+ struct snd_card *card;
char name[16];
card = substream->pcm->card;
@@ -540,7 +571,7 @@ static int snd_pcm_substream_proc_init(snd_pcm_substream_t *substream)
return 0;
}
-static int snd_pcm_substream_proc_done(snd_pcm_substream_t *substream)
+static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream)
{
if (substream->proc_info_entry) {
snd_info_unregister(substream->proc_info_entry);
@@ -564,6 +595,12 @@ static int snd_pcm_substream_proc_done(snd_pcm_substream_t *substream)
}
return 0;
}
+#else /* !CONFIG_PROC_FS */
+static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }
+static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }
+static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }
+static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; }
+#endif /* CONFIG_PROC_FS */
/**
* snd_pcm_new_stream - create a new PCM stream
@@ -578,11 +615,11 @@ static int snd_pcm_substream_proc_done(snd_pcm_substream_t *substream)
*
* Returns zero if successful, or a negative error code on failure.
*/
-int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
+int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
{
int idx, err;
- snd_pcm_str_t *pstr = &pcm->streams[stream];
- snd_pcm_substream_t *substream, *prev;
+ struct snd_pcm_str *pstr = &pcm->streams[stream];
+ struct snd_pcm_substream *substream, *prev;
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
init_MUTEX(&pstr->oss.setup_mutex);
@@ -590,17 +627,20 @@ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
pstr->stream = stream;
pstr->pcm = pcm;
pstr->substream_count = substream_count;
- pstr->reg = &snd_pcm_reg[stream];
if (substream_count > 0) {
err = snd_pcm_stream_proc_init(pstr);
- if (err < 0)
+ if (err < 0) {
+ snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
return err;
+ }
}
prev = NULL;
for (idx = 0, prev = NULL; idx < substream_count; idx++) {
substream = kzalloc(sizeof(*substream), GFP_KERNEL);
- if (substream == NULL)
+ if (substream == NULL) {
+ snd_printk(KERN_ERR "Cannot allocate PCM substream\n");
return -ENOMEM;
+ }
substream->pcm = pcm;
substream->pstr = pstr;
substream->number = idx;
@@ -613,6 +653,7 @@ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
prev->next = substream;
err = snd_pcm_substream_proc_init(substream);
if (err < 0) {
+ snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
kfree(substream);
return err;
}
@@ -642,13 +683,13 @@ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
*
* Returns zero if successful, or a negative error code on failure.
*/
-int snd_pcm_new(snd_card_t * card, char *id, int device,
+int snd_pcm_new(struct snd_card *card, char *id, int device,
int playback_count, int capture_count,
- snd_pcm_t ** rpcm)
+ struct snd_pcm ** rpcm)
{
- snd_pcm_t *pcm;
+ struct snd_pcm *pcm;
int err;
- static snd_device_ops_t ops = {
+ static struct snd_device_ops ops = {
.dev_free = snd_pcm_dev_free,
.dev_register = snd_pcm_dev_register,
.dev_disconnect = snd_pcm_dev_disconnect,
@@ -659,13 +700,14 @@ int snd_pcm_new(snd_card_t * card, char *id, int device,
*rpcm = NULL;
snd_assert(card != NULL, return -ENXIO);
pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
- if (pcm == NULL)
+ if (pcm == NULL) {
+ snd_printk(KERN_ERR "Cannot allocate PCM\n");
return -ENOMEM;
+ }
pcm->card = card;
pcm->device = device;
- if (id) {
+ if (id)
strlcpy(pcm->id, id, sizeof(pcm->id));
- }
if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
snd_pcm_free(pcm);
return err;
@@ -684,11 +726,11 @@ int snd_pcm_new(snd_card_t * card, char *id, int device,
return 0;
}
-static void snd_pcm_free_stream(snd_pcm_str_t * pstr)
+static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
{
- snd_pcm_substream_t *substream, *substream_next;
+ struct snd_pcm_substream *substream, *substream_next;
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
- snd_pcm_oss_setup_t *setup, *setupn;
+ struct snd_pcm_oss_setup *setup, *setupn;
#endif
substream = pstr->substream;
while (substream) {
@@ -707,7 +749,7 @@ static void snd_pcm_free_stream(snd_pcm_str_t * pstr)
#endif
}
-static int snd_pcm_free(snd_pcm_t *pcm)
+static int snd_pcm_free(struct snd_pcm *pcm)
{
snd_assert(pcm != NULL, return -ENXIO);
if (pcm->private_free)
@@ -719,26 +761,26 @@ static int snd_pcm_free(snd_pcm_t *pcm)
return 0;
}
-static int snd_pcm_dev_free(snd_device_t *device)
+static int snd_pcm_dev_free(struct snd_device *device)
{
- snd_pcm_t *pcm = device->device_data;
+ struct snd_pcm *pcm = device->device_data;
return snd_pcm_free(pcm);
}
static void snd_pcm_tick_timer_func(unsigned long data)
{
- snd_pcm_substream_t *substream = (snd_pcm_substream_t*) data;
+ struct snd_pcm_substream *substream = (struct snd_pcm_substream *) data;
snd_pcm_tick_elapsed(substream);
}
-int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
- snd_pcm_substream_t **rsubstream)
+int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
+ struct snd_pcm_substream **rsubstream)
{
- snd_pcm_str_t * pstr;
- snd_pcm_substream_t * substream;
- snd_pcm_runtime_t * runtime;
- snd_ctl_file_t *kctl;
- snd_card_t *card;
+ struct snd_pcm_str * pstr;
+ struct snd_pcm_substream *substream;
+ struct snd_pcm_runtime *runtime;
+ struct snd_ctl_file *kctl;
+ struct snd_card *card;
struct list_head *list;
int prefer_subdevice = -1;
size_t size;
@@ -800,7 +842,7 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
if (runtime == NULL)
return -ENOMEM;
- size = PAGE_ALIGN(sizeof(snd_pcm_mmap_status_t));
+ size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status));
runtime->status = snd_malloc_pages(size, GFP_KERNEL);
if (runtime->status == NULL) {
kfree(runtime);
@@ -808,10 +850,11 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
}
memset((void*)runtime->status, 0, size);
- size = PAGE_ALIGN(sizeof(snd_pcm_mmap_control_t));
+ size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control));
runtime->control = snd_malloc_pages(size, GFP_KERNEL);
if (runtime->control == NULL) {
- snd_free_pages((void*)runtime->status, PAGE_ALIGN(sizeof(snd_pcm_mmap_status_t)));
+ snd_free_pages((void*)runtime->status,
+ PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
kfree(runtime);
return -ENOMEM;
}
@@ -832,39 +875,39 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
return 0;
}
-void snd_pcm_release_substream(snd_pcm_substream_t *substream)
+void snd_pcm_release_substream(struct snd_pcm_substream *substream)
{
- snd_pcm_runtime_t * runtime;
+ struct snd_pcm_runtime *runtime;
substream->file = NULL;
runtime = substream->runtime;
snd_assert(runtime != NULL, return);
if (runtime->private_free != NULL)
runtime->private_free(runtime);
- snd_free_pages((void*)runtime->status, PAGE_ALIGN(sizeof(snd_pcm_mmap_status_t)));
- snd_free_pages((void*)runtime->control, PAGE_ALIGN(sizeof(snd_pcm_mmap_control_t)));
+ snd_free_pages((void*)runtime->status,
+ PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
+ snd_free_pages((void*)runtime->control,
+ PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
kfree(runtime->hw_constraints.rules);
kfree(runtime);
substream->runtime = NULL;
substream->pstr->substream_opened--;
}
-static int snd_pcm_dev_register(snd_device_t *device)
+static int snd_pcm_dev_register(struct snd_device *device)
{
- int idx, cidx, err;
- unsigned short minor;
- snd_pcm_substream_t *substream;
+ int cidx, err;
+ struct snd_pcm_substream *substream;
struct list_head *list;
char str[16];
- snd_pcm_t *pcm = device->device_data;
+ struct snd_pcm *pcm = device->device_data;
snd_assert(pcm != NULL && device != NULL, return -ENXIO);
down(&register_mutex);
- idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
- if (snd_pcm_devices[idx]) {
+ if (snd_pcm_search(pcm->card, pcm->device)) {
up(&register_mutex);
return -EBUSY;
}
- snd_pcm_devices[idx] = pcm;
+ list_add_tail(&pcm->list, &snd_pcm_devices);
for (cidx = 0; cidx < 2; cidx++) {
int devtype = -1;
if (pcm->streams[cidx].substream == NULL)
@@ -872,17 +915,19 @@ static int snd_pcm_dev_register(snd_device_t *device)
switch (cidx) {
case SNDRV_PCM_STREAM_PLAYBACK:
sprintf(str, "pcmC%iD%ip", pcm->card->number, pcm->device);
- minor = SNDRV_MINOR_PCM_PLAYBACK + idx;
devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
break;
case SNDRV_PCM_STREAM_CAPTURE:
sprintf(str, "pcmC%iD%ic", pcm->card->number, pcm->device);
- minor = SNDRV_MINOR_PCM_CAPTURE + idx;
devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
break;
}
- if ((err = snd_register_device(devtype, pcm->card, pcm->device, pcm->streams[cidx].reg, str)) < 0) {
- snd_pcm_devices[idx] = NULL;
+ if ((err = snd_register_device(devtype, pcm->card,
+ pcm->device,
+ &snd_pcm_f_ops[cidx],
+ pcm, str)) < 0)
+ {
+ list_del(&pcm->list);
up(&register_mutex);
return err;
}
@@ -890,48 +935,46 @@ static int snd_pcm_dev_register(snd_device_t *device)
snd_pcm_timer_init(substream);
}
list_for_each(list, &snd_pcm_notify_list) {
- snd_pcm_notify_t *notify;
- notify = list_entry(list, snd_pcm_notify_t, list);
+ struct snd_pcm_notify *notify;
+ notify = list_entry(list, struct snd_pcm_notify, list);
notify->n_register(pcm);
}
up(&register_mutex);
return 0;
}
-static int snd_pcm_dev_disconnect(snd_device_t *device)
+static int snd_pcm_dev_disconnect(struct snd_device *device)
{
- snd_pcm_t *pcm = device->device_data;
+ struct snd_pcm *pcm = device->device_data;
struct list_head *list;
- snd_pcm_substream_t *substream;
- int idx, cidx;
+ struct snd_pcm_substream *substream;
+ int cidx;
down(&register_mutex);
- idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
- snd_pcm_devices[idx] = NULL;
+ list_del_init(&pcm->list);
for (cidx = 0; cidx < 2; cidx++)
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
if (substream->runtime)
substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
list_for_each(list, &snd_pcm_notify_list) {
- snd_pcm_notify_t *notify;
- notify = list_entry(list, snd_pcm_notify_t, list);
+ struct snd_pcm_notify *notify;
+ notify = list_entry(list, struct snd_pcm_notify, list);
notify->n_disconnect(pcm);
}
up(&register_mutex);
return 0;
}
-static int snd_pcm_dev_unregister(snd_device_t *device)
+static int snd_pcm_dev_unregister(struct snd_device *device)
{
- int idx, cidx, devtype;
- snd_pcm_substream_t *substream;
+ int cidx, devtype;
+ struct snd_pcm_substream *substream;
struct list_head *list;
- snd_pcm_t *pcm = device->device_data;
+ struct snd_pcm *pcm = device->device_data;
snd_assert(pcm != NULL, return -ENXIO);
down(&register_mutex);
- idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
- snd_pcm_devices[idx] = NULL;
+ list_del(&pcm->list);
for (cidx = 0; cidx < 2; cidx++) {
devtype = -1;
switch (cidx) {
@@ -947,84 +990,99 @@ static int snd_pcm_dev_unregister(snd_device_t *device)
snd_pcm_timer_done(substream);
}
list_for_each(list, &snd_pcm_notify_list) {
- snd_pcm_notify_t *notify;
- notify = list_entry(list, snd_pcm_notify_t, list);
+ struct snd_pcm_notify *notify;
+ notify = list_entry(list, struct snd_pcm_notify, list);
notify->n_unregister(pcm);
}
up(&register_mutex);
return snd_pcm_free(pcm);
}
-int snd_pcm_notify(snd_pcm_notify_t *notify, int nfree)
+int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
{
- int idx;
+ struct list_head *p;
snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL);
down(&register_mutex);
if (nfree) {
list_del(&notify->list);
- for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
- if (snd_pcm_devices[idx] == NULL)
- continue;
- notify->n_unregister(snd_pcm_devices[idx]);
- }
+ list_for_each(p, &snd_pcm_devices)
+ notify->n_unregister(list_entry(p,
+ struct snd_pcm, list));
} else {
list_add_tail(&notify->list, &snd_pcm_notify_list);
- for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
- if (snd_pcm_devices[idx] == NULL)
- continue;
- notify->n_register(snd_pcm_devices[idx]);
- }
+ list_for_each(p, &snd_pcm_devices)
+ notify->n_register(list_entry(p, struct snd_pcm, list));
}
up(&register_mutex);
return 0;
}
+#ifdef CONFIG_PROC_FS
/*
* Info interface
*/
-static void snd_pcm_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void snd_pcm_proc_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
- int idx;
- snd_pcm_t *pcm;
+ struct list_head *p;
+ struct snd_pcm *pcm;
down(&register_mutex);
- for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
- pcm = snd_pcm_devices[idx];
- if (pcm == NULL)
- continue;
- snd_iprintf(buffer, "%02i-%02i: %s : %s", idx / SNDRV_PCM_DEVICES,
- idx % SNDRV_PCM_DEVICES, pcm->id, pcm->name);
+ list_for_each(p, &snd_pcm_devices) {
+ pcm = list_entry(p, struct snd_pcm, list);
+ snd_iprintf(buffer, "%02i-%02i: %s : %s",
+ pcm->card->number, pcm->device, pcm->id, pcm->name);
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
- snd_iprintf(buffer, " : playback %i", pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count);
+ snd_iprintf(buffer, " : playback %i",
+ pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count);
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
- snd_iprintf(buffer, " : capture %i", pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
+ snd_iprintf(buffer, " : capture %i",
+ pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
snd_iprintf(buffer, "\n");
}
up(&register_mutex);
}
-/*
- * ENTRY functions
- */
-
-static snd_info_entry_t *snd_pcm_proc_entry = NULL;
+static struct snd_info_entry *snd_pcm_proc_entry = NULL;
-static int __init alsa_pcm_init(void)
+static void snd_pcm_proc_init(void)
{
- snd_info_entry_t *entry;
+ struct snd_info_entry *entry;
- snd_ctl_register_ioctl(snd_pcm_control_ioctl);
- snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) {
- snd_info_set_text_ops(entry, NULL, SNDRV_CARDS * SNDRV_PCM_DEVICES * 128, snd_pcm_proc_read);
+ snd_info_set_text_ops(entry, NULL, SNDRV_CARDS * SNDRV_PCM_DEVICES * 128,
+ snd_pcm_proc_read);
if (snd_info_register(entry) < 0) {
snd_info_free_entry(entry);
entry = NULL;
}
}
snd_pcm_proc_entry = entry;
+}
+
+static void snd_pcm_proc_done(void)
+{
+ if (snd_pcm_proc_entry)
+ snd_info_unregister(snd_pcm_proc_entry);
+}
+
+#else /* !CONFIG_PROC_FS */
+#define snd_pcm_proc_init()
+#define snd_pcm_proc_done()
+#endif /* CONFIG_PROC_FS */
+
+
+/*
+ * ENTRY functions
+ */
+
+static int __init alsa_pcm_init(void)
+{
+ snd_ctl_register_ioctl(snd_pcm_control_ioctl);
+ snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
+ snd_pcm_proc_init();
return 0;
}
@@ -1032,16 +1090,12 @@ static void __exit alsa_pcm_exit(void)
{
snd_ctl_unregister_ioctl(snd_pcm_control_ioctl);
snd_ctl_unregister_ioctl_compat(snd_pcm_control_ioctl);
- if (snd_pcm_proc_entry) {
- snd_info_unregister(snd_pcm_proc_entry);
- snd_pcm_proc_entry = NULL;
- }
+ snd_pcm_proc_done();
}
module_init(alsa_pcm_init)
module_exit(alsa_pcm_exit)
-EXPORT_SYMBOL(snd_pcm_devices);
EXPORT_SYMBOL(snd_pcm_new);
EXPORT_SYMBOL(snd_pcm_new_stream);
EXPORT_SYMBOL(snd_pcm_notify);