Merge git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-sched
[sfrench/cifs-2.6.git] / sound / core / pcm.c
index fbbbcd20c4cc7d6001163631dbfa15b55900e56d..2743414fc8fa8ac7fbf14d9b49dc38be622eea0a 100644 (file)
@@ -45,11 +45,9 @@ static int snd_pcm_dev_disconnect(struct snd_device *device);
 
 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;
        }
@@ -640,6 +638,10 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
                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;
                }
@@ -778,7 +780,6 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
        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;
 
@@ -791,8 +792,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
 
        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)
@@ -910,7 +910,8 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
        substream->pstr->substream_opened--;
 }
 
-static ssize_t show_pcm_class(struct class_device *class_device, char *buf)
+static ssize_t show_pcm_class(struct device *dev,
+                             struct device_attribute *attr, char *buf)
 {
        struct snd_pcm *pcm;
        const char *str;
@@ -921,7 +922,7 @@ static ssize_t show_pcm_class(struct class_device *class_device, char *buf)
                [SNDRV_PCM_CLASS_DIGITIZER] = "digitizer",
        };
 
-       if (! (pcm = class_get_devdata(class_device)) ||
+       if (! (pcm = dev_get_drvdata(dev)) ||
            pcm->dev_class > SNDRV_PCM_CLASS_LAST)
                str = "none";
        else
@@ -929,16 +930,17 @@ static ssize_t show_pcm_class(struct class_device *class_device, char *buf)
         return snprintf(buf, PAGE_SIZE, "%s\n", str);
 }
 
-static struct class_device_attribute pcm_attrs =
+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(&register_mutex);
@@ -961,11 +963,18 @@ static int snd_pcm_dev_register(struct snd_device *device)
                        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 = snd_card_get_device_link(pcm->card);
+               /* 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(&register_mutex);
                        return err;
@@ -975,11 +984,10 @@ static int snd_pcm_dev_register(struct snd_device *device)
                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(&register_mutex);
        return 0;
 }
@@ -1022,7 +1030,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
 
 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 &&
@@ -1031,13 +1039,12 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
        mutex_lock(&register_mutex);
        if (nfree) {
                list_del(&notify->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(&notify->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(&register_mutex);
        return 0;
@@ -1053,12 +1060,10 @@ EXPORT_SYMBOL(snd_pcm_notify);
 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(&register_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)