Commit d595ee7e authored by Johannes Berg's avatar Johannes Berg Committed by Jaroslav Kysela

[ALSA] aoa: fix up i2sbus_attach_codec

This patch changes i2sbus_attach_codec to implement a proper error handling
strategy using labels to jump to the right part. Since it has an elaborate
set-up sequence it also needs that tear-down, which I had hard-coded
inbetween all the checks. This increases readability and should reduce .text
size as well.
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent 73e85fe8
...@@ -812,7 +812,6 @@ static void i2sbus_private_free(struct snd_pcm *pcm) ...@@ -812,7 +812,6 @@ static void i2sbus_private_free(struct snd_pcm *pcm)
module_put(THIS_MODULE); module_put(THIS_MODULE);
} }
/* FIXME: this function needs an error handling strategy with labels */
int int
i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
struct codec_info *ci, void *data) struct codec_info *ci, void *data)
...@@ -880,24 +879,21 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, ...@@ -880,24 +879,21 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
if (!cii->sdev) { if (!cii->sdev) {
printk(KERN_DEBUG printk(KERN_DEBUG
"i2sbus: failed to get soundbus dev reference\n"); "i2sbus: failed to get soundbus dev reference\n");
kfree(cii); err = -ENODEV;
return -ENODEV; goto out_free_cii;
} }
if (!try_module_get(THIS_MODULE)) { if (!try_module_get(THIS_MODULE)) {
printk(KERN_DEBUG "i2sbus: failed to get module reference!\n"); printk(KERN_DEBUG "i2sbus: failed to get module reference!\n");
soundbus_dev_put(dev); err = -EBUSY;
kfree(cii); goto out_put_sdev;
return -EBUSY;
} }
if (!try_module_get(ci->owner)) { if (!try_module_get(ci->owner)) {
printk(KERN_DEBUG printk(KERN_DEBUG
"i2sbus: failed to get module reference to codec owner!\n"); "i2sbus: failed to get module reference to codec owner!\n");
module_put(THIS_MODULE); err = -EBUSY;
soundbus_dev_put(dev); goto out_put_this_module;
kfree(cii);
return -EBUSY;
} }
if (!dev->pcm) { if (!dev->pcm) {
...@@ -905,11 +901,7 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, ...@@ -905,11 +901,7 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
&dev->pcm); &dev->pcm);
if (err) { if (err) {
printk(KERN_DEBUG "i2sbus: failed to create pcm\n"); printk(KERN_DEBUG "i2sbus: failed to create pcm\n");
kfree(cii); goto out_put_ci_module;
module_put(ci->owner);
soundbus_dev_put(dev);
module_put(THIS_MODULE);
return err;
} }
dev->pcm->dev = &dev->ofdev.dev; dev->pcm->dev = &dev->ofdev.dev;
} }
...@@ -923,20 +915,12 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, ...@@ -923,20 +915,12 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
/* eh? */ /* eh? */
printk(KERN_ERR printk(KERN_ERR
"Can't attach same bus to different cards!\n"); "Can't attach same bus to different cards!\n");
module_put(ci->owner); err = -EINVAL;
kfree(cii); goto out_put_ci_module;
soundbus_dev_put(dev);
module_put(THIS_MODULE);
return -EINVAL;
}
if ((err =
snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1))) {
module_put(ci->owner);
kfree(cii);
soundbus_dev_put(dev);
module_put(THIS_MODULE);
return err;
} }
err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1);
if (err)
goto out_put_ci_module;
snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
&i2sbus_playback_ops); &i2sbus_playback_ops);
i2sdev->out.created = 1; i2sdev->out.created = 1;
...@@ -946,20 +930,11 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, ...@@ -946,20 +930,11 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
if (dev->pcm->card != card) { if (dev->pcm->card != card) {
printk(KERN_ERR printk(KERN_ERR
"Can't attach same bus to different cards!\n"); "Can't attach same bus to different cards!\n");
module_put(ci->owner); goto out_put_ci_module;
kfree(cii);
soundbus_dev_put(dev);
module_put(THIS_MODULE);
return -EINVAL;
}
if ((err =
snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1))) {
module_put(ci->owner);
kfree(cii);
soundbus_dev_put(dev);
module_put(THIS_MODULE);
return err;
} }
err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1);
if (err)
goto out_put_ci_module;
snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
&i2sbus_record_ops); &i2sbus_record_ops);
i2sdev->in.created = 1; i2sdev->in.created = 1;
...@@ -974,11 +949,7 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, ...@@ -974,11 +949,7 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
err = snd_device_register(card, dev->pcm); err = snd_device_register(card, dev->pcm);
if (err) { if (err) {
printk(KERN_ERR "i2sbus: error registering new pcm\n"); printk(KERN_ERR "i2sbus: error registering new pcm\n");
module_put(ci->owner); goto out_put_ci_module;
kfree(cii);
soundbus_dev_put(dev);
module_put(THIS_MODULE);
return err;
} }
/* no errors any more, so let's add this to our list */ /* no errors any more, so let's add this to our list */
list_add(&cii->list, &dev->codec_list); list_add(&cii->list, &dev->codec_list);
...@@ -993,6 +964,15 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, ...@@ -993,6 +964,15 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
64 * 1024, 64 * 1024); 64 * 1024, 64 * 1024);
return 0; return 0;
out_put_ci_module:
module_put(ci->owner);
out_put_this_module:
module_put(THIS_MODULE);
out_put_sdev:
soundbus_dev_put(dev);
out_free_cii:
kfree(cii);
return err;
} }
void i2sbus_detach_codec(struct soundbus_dev *dev, void *data) void i2sbus_detach_codec(struct soundbus_dev *dev, void *data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment