staging: greybus: audio: Ensure proper byte order
authorVaibhav Agarwal <vaibhav.agarwal@linaro.org>
Wed, 18 Jan 2017 17:21:53 +0000 (22:51 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Jan 2017 10:08:00 +0000 (11:08 +0100)
Proper byte order was completely disregarded for multi byte data shared
between AP and module (and APB1). Fix this.

Signed-off-by: Vaibhav Agarwal <vaibhav.agarwal@linaro.org>
Signed-off-by: Vaibhav Agarwal <vaibhav.sr@gmail.com>
Acked-by: Mark Greer <mgreer@animalcreek.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/greybus/audio_module.c
drivers/staging/greybus/audio_topology.c

index 17a9948b1ba1e2c26007f922242019fb63f6567c..094c3be79b3373f55b9071d42790c11a48348322 100644 (file)
@@ -134,7 +134,7 @@ static int gbaudio_request_stream(struct gbaudio_module_info *module,
                                  struct gb_audio_streaming_event_request *req)
 {
        dev_warn(module->dev, "Audio Event received: cport: %u, event: %u\n",
-                req->data_cport, req->event);
+                le16_to_cpu(req->data_cport), req->event);
 
        return 0;
 }
index ee2113eb899e2f8e17f5f2bafb2695c0b9d3e96b..07fac3948f3a60c70b8e3a2cf7f823d1cc0e76d9 100644 (file)
@@ -141,13 +141,14 @@ static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb,
 {
        const char **strings;
        int i;
+       unsigned int items;
        __u8 *data;
 
-       strings = devm_kzalloc(gb->dev, sizeof(char *) * gbenum->items,
-                              GFP_KERNEL);
+       items = le32_to_cpu(gbenum->items);
+       strings = devm_kzalloc(gb->dev, sizeof(char *) * items, GFP_KERNEL);
        data = gbenum->names;
 
-       for (i = 0; i < gbenum->items; i++) {
+       for (i = 0; i < items; i++) {
                strings[i] = (const char *)data;
                while (*data != '\0')
                        data++;
@@ -185,11 +186,11 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol,
        switch (info->type) {
        case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
        case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
-               uinfo->value.integer.min = info->value.integer.min;
-               uinfo->value.integer.max = info->value.integer.max;
+               uinfo->value.integer.min = le32_to_cpu(info->value.integer.min);
+               uinfo->value.integer.max = le32_to_cpu(info->value.integer.max);
                break;
        case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
-               max = info->value.enumerated.items;
+               max = le32_to_cpu(info->value.enumerated.items);
                uinfo->value.enumerated.items = max;
                if (uinfo->value.enumerated.item > max - 1)
                        uinfo->value.enumerated.item = max - 1;
@@ -249,17 +250,17 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol,
        case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
        case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
                ucontrol->value.integer.value[0] =
-                       gbvalue.value.integer_value[0];
+                       le32_to_cpu(gbvalue.value.integer_value[0]);
                if (data->vcount == 2)
                        ucontrol->value.integer.value[1] =
-                               gbvalue.value.integer_value[1];
+                               le32_to_cpu(gbvalue.value.integer_value[1]);
                break;
        case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
                ucontrol->value.enumerated.item[0] =
-                       gbvalue.value.enumerated_item[0];
+                       le32_to_cpu(gbvalue.value.enumerated_item[0]);
                if (data->vcount == 2)
                        ucontrol->value.enumerated.item[1] =
-                               gbvalue.value.enumerated_item[1];
+                               le32_to_cpu(gbvalue.value.enumerated_item[1]);
                break;
        default:
                dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
@@ -296,17 +297,17 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol,
        case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
        case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
                gbvalue.value.integer_value[0] =
-                       ucontrol->value.integer.value[0];
+                       cpu_to_le32(ucontrol->value.integer.value[0]);
                if (data->vcount == 2)
                        gbvalue.value.integer_value[1] =
-                               ucontrol->value.integer.value[1];
+                               cpu_to_le32(ucontrol->value.integer.value[1]);
                break;
        case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
                gbvalue.value.enumerated_item[0] =
-                       ucontrol->value.enumerated.item[0];
+                       cpu_to_le32(ucontrol->value.enumerated.item[0]);
                if (data->vcount == 2)
                        gbvalue.value.enumerated_item[1] =
-                               ucontrol->value.enumerated.item[1];
+                               cpu_to_le32(ucontrol->value.enumerated.item[1]);
                break;
        default:
                dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
@@ -361,8 +362,8 @@ static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol,
        info = (struct gb_audio_ctl_elem_info *)data->info;
 
        /* update uinfo */
-       platform_max = info->value.integer.max;
-       platform_min = info->value.integer.min;
+       platform_max = le32_to_cpu(info->value.integer.max);
+       platform_min = le32_to_cpu(info->value.integer.min);
 
        if (platform_max == 1 &&
            !strnstr(kcontrol->id.name, " Volume", NAME_SIZE))
@@ -420,7 +421,8 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol,
                return ret;
        }
        /* update ucontrol */
-       ucontrol->value.integer.value[0] = gbvalue.value.integer_value[0];
+       ucontrol->value.integer.value[0] =
+               le32_to_cpu(gbvalue.value.integer_value[0]);
 
        return ret;
 }
@@ -454,7 +456,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
                         "GB: Control '%s' is stereo, which is not supported\n",
                         kcontrol->id.name);
 
-       max = info->value.integer.max;
+       max = le32_to_cpu(info->value.integer.max);
        mask = (1 << fls(max)) - 1;
        val = ucontrol->value.integer.value[0] & mask;
        connect = !!val;
@@ -470,7 +472,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
                                                        connect);
                }
                gbvalue.value.integer_value[0] =
-                       ucontrol->value.integer.value[0];
+                       cpu_to_le32(ucontrol->value.integer.value[0]);
 
                ret = gb_pm_runtime_get_sync(bundle);
                if (ret)
@@ -584,10 +586,11 @@ static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol,
                return ret;
        }
 
-       ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0];
+       ucontrol->value.enumerated.item[0] =
+               le32_to_cpu(gbvalue.value.enumerated_item[0]);
        if (e->shift_l != e->shift_r)
                ucontrol->value.enumerated.item[1] =
-                       gbvalue.value.enumerated_item[1];
+                       le32_to_cpu(gbvalue.value.enumerated_item[1]);
 
        return 0;
 }
@@ -613,13 +616,14 @@ static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol,
 
        if (ucontrol->value.enumerated.item[0] > e->max - 1)
                return -EINVAL;
-       gbvalue.value.enumerated_item[0] = ucontrol->value.enumerated.item[0];
+       gbvalue.value.enumerated_item[0] =
+               cpu_to_le32(ucontrol->value.enumerated.item[0]);
 
        if (e->shift_l != e->shift_r) {
                if (ucontrol->value.enumerated.item[1] > e->max - 1)
                        return -EINVAL;
                gbvalue.value.enumerated_item[1] =
-                       ucontrol->value.enumerated.item[1];
+                       cpu_to_le32(ucontrol->value.enumerated.item[1]);
        }
 
        bundle = to_gb_bundle(module->dev);
@@ -656,13 +660,13 @@ static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb,
        gb_enum = &ctl->info.value.enumerated;
 
        /* since count=1, and reg is dummy */
-       gbe->max = gb_enum->items;
+       gbe->max = le32_to_cpu(gb_enum->items);
        gbe->texts = gb_generate_enum_strings(gb, gb_enum);
 
        /* debug enum info */
-       dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items,
-                gb_enum->names_length);
-       for (i = 0; i < gb_enum->items; i++)
+       dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max,
+                le16_to_cpu(gb_enum->names_length));
+       for (i = 0; i < gbe->max; i++)
                dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
 
        *kctl = (struct snd_kcontrol_new)
@@ -691,7 +695,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb,
                        if (!ctldata)
                                return -ENOMEM;
                        ctldata->ctl_id = ctl->id;
-                       ctldata->data_cport = ctl->data_cport;
+                       ctldata->data_cport = le16_to_cpu(ctl->data_cport);
                        ctldata->access = ctl->access;
                        ctldata->vcount = ctl->count_values;
                        ctldata->info = &ctl->info;
@@ -865,13 +869,13 @@ static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb,
        gb_enum = &ctl->info.value.enumerated;
 
        /* since count=1, and reg is dummy */
-       gbe->max = gb_enum->items;
+       gbe->max = le32_to_cpu(gb_enum->items);
        gbe->texts = gb_generate_enum_strings(gb, gb_enum);
 
        /* debug enum info */
-       dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items,
-                gb_enum->names_length);
-       for (i = 0; i < gb_enum->items; i++)
+       dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max,
+                le16_to_cpu(gb_enum->names_length));
+       for (i = 0; i < gbe->max; i++)
                dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
 
        *kctl = (struct snd_kcontrol_new)
@@ -891,7 +895,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb,
        if (!ctldata)
                return -ENOMEM;
        ctldata->ctl_id = ctl->id;
-       ctldata->data_cport = ctl->data_cport;
+       ctldata->data_cport = le16_to_cpu(ctl->data_cport);
        ctldata->access = ctl->access;
        ctldata->vcount = ctl->count_values;
        ctldata->info = &ctl->info;
@@ -1037,10 +1041,10 @@ static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module,
                        csize = offsetof(struct gb_audio_control, info);
                        csize += offsetof(struct gb_audio_ctl_elem_info, value);
                        csize += offsetof(struct gb_audio_enumerated, names);
-                       csize += gbenum->names_length;
+                       csize += le16_to_cpu(gbenum->names_length);
                        control->texts = (const char * const *)
                                gb_generate_enum_strings(module, gbenum);
-                       control->items = gbenum->items;
+                       control->items = le32_to_cpu(gbenum->items);
                } else {
                        csize = sizeof(struct gb_audio_control);
                }
@@ -1185,10 +1189,10 @@ static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module,
                        csize = offsetof(struct gb_audio_control, info);
                        csize += offsetof(struct gb_audio_ctl_elem_info, value);
                        csize += offsetof(struct gb_audio_enumerated, names);
-                       csize += gbenum->names_length;
+                       csize += le16_to_cpu(gbenum->names_length);
                        control->texts = (const char * const *)
                                gb_generate_enum_strings(module, gbenum);
-                       control->items = gbenum->items;
+                       control->items = le32_to_cpu(gbenum->items);
                } else {
                        csize = sizeof(struct gb_audio_control);
                }
@@ -1331,11 +1335,12 @@ static int gbaudio_tplg_process_header(struct gbaudio_module_info *module,
 
        /* update block offset */
        module->dai_offset = (unsigned long)&tplg_data->data;
-       module->control_offset = module->dai_offset + tplg_data->size_dais;
+       module->control_offset = module->dai_offset +
+                                       le32_to_cpu(tplg_data->size_dais);
        module->widget_offset = module->control_offset +
-               tplg_data->size_controls;
+                                       le32_to_cpu(tplg_data->size_controls);
        module->route_offset = module->widget_offset +
-               tplg_data->size_widgets;
+                                       le32_to_cpu(tplg_data->size_widgets);
 
        dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset);
        dev_dbg(module->dev, "control offset is %lx\n",
@@ -1353,6 +1358,7 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
        struct gb_audio_control *controls;
        struct gb_audio_widget *widgets;
        struct gb_audio_route *routes;
+       unsigned int jack_type;
 
        if (!tplg_data)
                return -EINVAL;
@@ -1395,10 +1401,10 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
        dev_dbg(module->dev, "Route parsing finished\n");
 
        /* parse jack capabilities */
-       if (tplg_data->jack_type) {
-               module->jack_mask = tplg_data->jack_type & GBCODEC_JACK_MASK;
-               module->button_mask = tplg_data->jack_type &
-                       GBCODEC_JACK_BUTTON_MASK;
+       jack_type = le32_to_cpu(tplg_data->jack_type);
+       if (jack_type) {
+               module->jack_mask = jack_type & GBCODEC_JACK_MASK;
+               module->button_mask = jack_type & GBCODEC_JACK_BUTTON_MASK;
        }
 
        return ret;