static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device)
{
- struct list_head *p;
struct snd_pcm *pcm;
- list_for_each(p, &snd_pcm_devices) {
- pcm = list_entry(p, struct snd_pcm, list);
+ list_for_each_entry(pcm, &snd_pcm_devices, list) {
if (pcm->card == card && pcm->device == device)
return pcm;
}
substream->number = idx;
substream->stream = stream;
sprintf(substream->name, "subdevice #%i", idx);
+ snprintf(substream->latency_id, sizeof(substream->latency_id),
+ "ALSA-PCM%d-%d%c%d", pcm->card->number, pcm->device,
+ (stream ? 'c' : 'p'), idx);
substream->buffer_bytes_max = UINT_MAX;
if (prev == NULL)
pstr->substream = substream;
err = snd_pcm_substream_proc_init(substream);
if (err < 0) {
snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
+ if (prev == NULL)
+ pstr->substream = NULL;
+ else
+ prev->next = NULL;
kfree(substream);
return err;
}
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;
card = pcm->card;
down_read(&card->controls_rwsem);
- list_for_each(list, &card->ctl_files) {
- kctl = snd_ctl_file(list);
+ list_for_each_entry(kctl, &card->ctl_files, list) {
if (kctl->pid == current->pid) {
prefer_subdevice = kctl->prefer_pcm_subdevice;
if (prefer_subdevice != -1)
substream->pstr->substream_opened--;
}
+static ssize_t show_pcm_class(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct snd_pcm *pcm;
+ const char *str;
+ static const char *strs[SNDRV_PCM_CLASS_LAST + 1] = {
+ [SNDRV_PCM_CLASS_GENERIC] = "generic",
+ [SNDRV_PCM_CLASS_MULTI] = "multi",
+ [SNDRV_PCM_CLASS_MODEM] = "modem",
+ [SNDRV_PCM_CLASS_DIGITIZER] = "digitizer",
+ };
+
+ if (! (pcm = dev_get_drvdata(dev)) ||
+ pcm->dev_class > SNDRV_PCM_CLASS_LAST)
+ str = "none";
+ else
+ str = strs[pcm->dev_class];
+ return snprintf(buf, PAGE_SIZE, "%s\n", str);
+}
+
+static struct device_attribute pcm_attrs =
+ __ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL);
+
static int snd_pcm_dev_register(struct snd_device *device)
{
int cidx, err;
struct snd_pcm_substream *substream;
- struct list_head *list;
+ struct snd_pcm_notify *notify;
char str[16];
struct snd_pcm *pcm = device->device_data;
+ struct device *dev;
snd_assert(pcm != NULL && device != NULL, return -ENXIO);
mutex_lock(®ister_mutex);
devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
break;
}
- if ((err = snd_register_device(devtype, pcm->card,
- pcm->device,
- &snd_pcm_f_ops[cidx],
- pcm, str)) < 0)
- {
+ /* device pointer to use, pcm->dev takes precedence if
+ * it is assigned, otherwise fall back to card's device
+ * if possible */
+ dev = pcm->dev;
+ if (!dev)
+ dev = pcm->card ? pcm->card->dev : NULL;
+ /* register pcm */
+ err = snd_register_device_for_dev(devtype, pcm->card,
+ pcm->device,
+ &snd_pcm_f_ops[cidx],
+ pcm, str, dev);
+ if (err < 0) {
list_del(&pcm->list);
mutex_unlock(®ister_mutex);
return err;
}
+ snd_add_device_sysfs_file(devtype, pcm->card, pcm->device,
+ &pcm_attrs);
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
snd_pcm_timer_init(substream);
}
- list_for_each(list, &snd_pcm_notify_list) {
- struct snd_pcm_notify *notify;
- notify = list_entry(list, struct snd_pcm_notify, list);
+
+ list_for_each_entry(notify, &snd_pcm_notify_list, list)
notify->n_register(pcm);
- }
+
mutex_unlock(®ister_mutex);
return 0;
}
int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
{
- struct list_head *p;
+ struct snd_pcm *pcm;
snd_assert(notify != NULL &&
notify->n_register != NULL &&
mutex_lock(®ister_mutex);
if (nfree) {
list_del(¬ify->list);
- list_for_each(p, &snd_pcm_devices)
- notify->n_unregister(list_entry(p,
- struct snd_pcm, list));
+ list_for_each_entry(pcm, &snd_pcm_devices, list)
+ notify->n_unregister(pcm);
} else {
list_add_tail(¬ify->list, &snd_pcm_notify_list);
- list_for_each(p, &snd_pcm_devices)
- notify->n_register(list_entry(p, struct snd_pcm, list));
+ list_for_each_entry(pcm, &snd_pcm_devices, list)
+ notify->n_register(pcm);
}
mutex_unlock(®ister_mutex);
return 0;
static void snd_pcm_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
- struct list_head *p;
struct snd_pcm *pcm;
mutex_lock(®ister_mutex);
- list_for_each(p, &snd_pcm_devices) {
- pcm = list_entry(p, struct snd_pcm, list);
+ list_for_each_entry(pcm, &snd_pcm_devices, 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)