summaryrefslogtreecommitdiff
path: root/sound/virtio
diff options
context:
space:
mode:
Diffstat (limited to 'sound/virtio')
-rw-r--r--sound/virtio/virtio_kctl.c8
-rw-r--r--sound/virtio/virtio_pcm.c21
2 files changed, 19 insertions, 10 deletions
diff --git a/sound/virtio/virtio_kctl.c b/sound/virtio/virtio_kctl.c
index 7aa79c05b464..ffb903d56297 100644
--- a/sound/virtio/virtio_kctl.c
+++ b/sound/virtio/virtio_kctl.c
@@ -47,7 +47,7 @@ static const unsigned int g_v2a_mask_map[] = {
static int virtsnd_kctl_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
- struct virtio_snd *snd = kcontrol->private_data;
+ struct virtio_snd *snd = snd_kcontrol_chip(kcontrol);
struct virtio_kctl *kctl = &snd->kctls[kcontrol->private_value];
struct virtio_snd_ctl_info *kinfo =
&snd->kctl_infos[kcontrol->private_value];
@@ -102,7 +102,7 @@ static int virtsnd_kctl_info(struct snd_kcontrol *kcontrol,
static int virtsnd_kctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uvalue)
{
- struct virtio_snd *snd = kcontrol->private_data;
+ struct virtio_snd *snd = snd_kcontrol_chip(kcontrol);
struct virtio_snd_ctl_info *kinfo =
&snd->kctl_infos[kcontrol->private_value];
unsigned int type = le32_to_cpu(kinfo->type);
@@ -175,7 +175,7 @@ on_failure:
static int virtsnd_kctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uvalue)
{
- struct virtio_snd *snd = kcontrol->private_data;
+ struct virtio_snd *snd = snd_kcontrol_chip(kcontrol);
struct virtio_snd_ctl_info *kinfo =
&snd->kctl_infos[kcontrol->private_value];
unsigned int type = le32_to_cpu(kinfo->type);
@@ -239,7 +239,7 @@ static int virtsnd_kctl_put(struct snd_kcontrol *kcontrol,
static int virtsnd_kctl_tlv_op(struct snd_kcontrol *kcontrol, int op_flag,
unsigned int size, unsigned int __user *utlv)
{
- struct virtio_snd *snd = kcontrol->private_data;
+ struct virtio_snd *snd = snd_kcontrol_chip(kcontrol);
struct virtio_snd_msg *msg;
struct virtio_snd_ctl_hdr *hdr;
unsigned int *tlv;
diff --git a/sound/virtio/virtio_pcm.c b/sound/virtio/virtio_pcm.c
index 967e4c45be9b..2f7c5e709f07 100644
--- a/sound/virtio/virtio_pcm.c
+++ b/sound/virtio/virtio_pcm.c
@@ -339,6 +339,21 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd)
if (!snd->substreams)
return -ENOMEM;
+ /*
+ * Initialize critical substream fields early in case we hit an
+ * error path and end up trying to clean up uninitialized structures
+ * elsewhere.
+ */
+ for (i = 0; i < snd->nsubstreams; ++i) {
+ struct virtio_pcm_substream *vss = &snd->substreams[i];
+
+ vss->snd = snd;
+ vss->sid = i;
+ INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed);
+ init_waitqueue_head(&vss->msg_empty);
+ spin_lock_init(&vss->lock);
+ }
+
info = kcalloc(snd->nsubstreams, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
@@ -352,12 +367,6 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd)
struct virtio_pcm_substream *vss = &snd->substreams[i];
struct virtio_pcm *vpcm;
- vss->snd = snd;
- vss->sid = i;
- INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed);
- init_waitqueue_head(&vss->msg_empty);
- spin_lock_init(&vss->lock);
-
rc = virtsnd_pcm_build_hw(vss, &info[i]);
if (rc)
goto on_exit;