[alsa-devel] [PATCH 0/8] ALSA: Another sparse warning fix round
Hi,
this is another pile of patches to fix sparse warnings, at this time, about the strong-types like snd_pcm_format_t. The patch 2 introduces a new macro for the iteration loop and some other tasks so that the driver doesn't need to use ugly __force cast.
Takashi
===
Takashi Iwai (8): ALSA: aloop: Fix PCM format assignment ALSA: pcm: More helper macros for reducing snd_pcm_format_t cast ALSA: usb-audio: Use pcm_for_each_format() macro for PCM format iterations ALSA: dummy: Use standard macros for fixing PCM format cast ALSA: pcm: Use standard macros for fixing PCM format cast ALSA: pcm: Use a macro for parameter masks to reduce the needed cast ALSA: pcm_dmaengine: Use pcm_for_each_format() macro for PCM format iteration ALSA: pcm: Minor refactoring
include/sound/pcm.h | 9 +++++++++ include/sound/pcm_params.h | 7 +++++++ sound/core/oss/pcm_oss.c | 19 ++++++++----------- sound/core/pcm_dmaengine.c | 2 +- sound/core/pcm_misc.c | 17 +++++++++++------ sound/core/pcm_native.c | 47 +++++++++++++++++++++++++--------------------- sound/drivers/aloop.c | 6 +++--- sound/drivers/dummy.c | 6 +++--- sound/usb/proc.c | 2 +- 9 files changed, 69 insertions(+), 46 deletions(-)
Fix sparse warnings about PCM format assignment regarding the strong typed snd_pcm_format_t: sound/drivers/aloop.c:352:45: warning: restricted snd_pcm_format_t degrades to integer sound/drivers/aloop.c:355:39: warning: incorrect type in assignment (different base types) sound/drivers/aloop.c:355:39: expected unsigned int format sound/drivers/aloop.c:355:39: got restricted snd_pcm_format_t [usertype] format sound/drivers/aloop.c:1435:34: warning: incorrect type in assignment (different base types) sound/drivers/aloop.c:1435:34: expected long max sound/drivers/aloop.c:1435:34: got restricted snd_pcm_format_t [usertype] sound/drivers/aloop.c:1565:39: warning: incorrect type in assignment (different base types) sound/drivers/aloop.c:1565:39: expected unsigned int format sound/drivers/aloop.c:1565:39: got restricted snd_pcm_format_t [usertype]
Some code in this driver assigns an integer value to snd_pcm_format_t via control API, and they need to be with the explicit cast.
No functional changes, just sparse warning fixes.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/drivers/aloop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index d78a27271d6d..251eaf1152e2 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -118,7 +118,7 @@ struct loopback_cable { struct loopback_setup { unsigned int notify: 1; unsigned int rate_shift; - unsigned int format; + snd_pcm_format_t format; unsigned int rate; unsigned int channels; struct snd_ctl_elem_id active_id; @@ -1432,7 +1432,7 @@ static int loopback_format_info(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; uinfo->value.integer.min = 0; - uinfo->value.integer.max = SNDRV_PCM_FORMAT_LAST; + uinfo->value.integer.max = (__force int)SNDRV_PCM_FORMAT_LAST; uinfo->value.integer.step = 1; return 0; } @@ -1443,7 +1443,7 @@ static int loopback_format_get(struct snd_kcontrol *kcontrol, struct loopback *loopback = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = - loopback->setup[kcontrol->id.subdevice] + (__force int)loopback->setup[kcontrol->id.subdevice] [kcontrol->id.device].format; return 0; }
snd_pcm_format_t is a strong-typed integer and requires the explicit cast with __force if converted or compared with a normal integer value. Since most of use cases do iterate over all formats and test / set the mask, provide a couple of new helper macros that do the explicit cast.
Signed-off-by: Takashi Iwai tiwai@suse.de --- include/sound/pcm.h | 9 +++++++++ include/sound/pcm_params.h | 7 +++++++ 2 files changed, 16 insertions(+)
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index f657ff08f317..31a4b300e4c9 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -1415,6 +1415,15 @@ static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format) return 1ULL << (__force int) pcm_format; }
+/** + * pcm_for_each_format - helper to iterate for each format type + * @f: the iterator variable in snd_pcm_format_t type + */ +#define pcm_for_each_format(f) \ + for ((f) = SNDRV_PCM_FORMAT_FIRST; \ + (__force int)(f) <= (__force int)SNDRV_PCM_FORMAT_LAST; \ + (f) = (__force snd_pcm_format_t)((__force int)(f) + 1)) + /* printk helpers */ #define pcm_err(pcm, fmt, args...) \ dev_err((pcm)->card->dev, fmt, ##args) diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h index 661450a2095b..36f94735d23d 100644 --- a/include/sound/pcm_params.h +++ b/include/sound/pcm_params.h @@ -133,6 +133,13 @@ static inline int snd_mask_test(const struct snd_mask *mask, unsigned int val) return mask->bits[MASK_OFS(val)] & MASK_BIT(val); }
+/* Most of drivers need only this one */ +static inline int snd_mask_test_format(const struct snd_mask *mask, + snd_pcm_format_t format) +{ + return snd_mask_test(mask, (__force unsigned int)format); +} + static inline int snd_mask_single(const struct snd_mask *mask) { int i, c = 0;
The new macro can fix the sparse warnings gracefully: sound/usb/proc.c:73:31: warning: restricted snd_pcm_format_t degrades to integer sound/usb/proc.c:73:38: warning: restricted snd_pcm_format_t degrades to integer sound/usb/proc.c:73:61: warning: restricted snd_pcm_format_t degrades to integer
No functional changes, just sparse warning fixes.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/usb/proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/usb/proc.c b/sound/usb/proc.c index ffbf4bd9208c..4174ad11fca6 100644 --- a/sound/usb/proc.c +++ b/sound/usb/proc.c @@ -70,7 +70,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s snd_iprintf(buffer, " Interface %d\n", fp->iface); snd_iprintf(buffer, " Altset %d\n", fp->altsetting); snd_iprintf(buffer, " Format:"); - for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt) + pcm_for_each_format(fmt) if (fp->formats & pcm_format_to_bits(fmt)) snd_iprintf(buffer, " %s", snd_pcm_format_name(fmt));
Simplify the code with the new macros for PCM format type iterations. This fixes the sparse warnings nicely: sound/drivers/dummy.c:906:25: warning: restricted snd_pcm_format_t degrades to integer sound/drivers/dummy.c:908:25: warning: incorrect type in argument 1 (different base types) sound/drivers/dummy.c:908:25: expected restricted snd_pcm_format_t [usertype] format sound/drivers/dummy.c:908:25: got int [assigned] i
No functional changes, just sparse warning fixes.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/drivers/dummy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 02ac3f4e0c02..b5486de08b97 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c @@ -901,10 +901,10 @@ static int snd_card_dummy_new_mixer(struct snd_dummy *dummy) static void print_formats(struct snd_dummy *dummy, struct snd_info_buffer *buffer) { - int i; + snd_pcm_format_t i;
- for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { - if (dummy->pcm_hw.formats & (1ULL << i)) + pcm_for_each_format(i) { + if (dummy->pcm_hw.formats & pcm_format_to_bits(i)) snd_iprintf(buffer, " %s", snd_pcm_format_name(i)); } }
Simplify the code with the new macros for PCM format type iterations. This fixes the sparse warnings nicely: sound/core/pcm_native.c:2302:26: warning: restricted snd_pcm_format_t degrades to integer sound/core/pcm_native.c:2306:54: warning: incorrect type in argument 1 (different base types) sound/core/pcm_native.c:2306:54: expected restricted snd_pcm_format_t [usertype] format sound/core/pcm_native.c:2306:54: got unsigned int [assigned] k ....
No functional changes, just sparse warning fixes.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/core/oss/pcm_oss.c | 19 ++++++++----------- sound/core/pcm_native.c | 15 ++++++++------- 2 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 13db77771f0f..707eb2a9d50c 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -884,20 +884,17 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) sformat = snd_pcm_plug_slave_format(format, sformat_mask);
if ((__force int)sformat < 0 || - !snd_mask_test(sformat_mask, (__force int)sformat)) { - for (sformat = (__force snd_pcm_format_t)0; - (__force int)sformat <= (__force int)SNDRV_PCM_FORMAT_LAST; - sformat = (__force snd_pcm_format_t)((__force int)sformat + 1)) { - if (snd_mask_test(sformat_mask, (__force int)sformat) && + !snd_mask_test_format(sformat_mask, sformat)) { + pcm_for_each_format(sformat) { + if (snd_mask_test_format(sformat_mask, sformat) && snd_pcm_oss_format_to(sformat) >= 0) - break; - } - if ((__force int)sformat > (__force int)SNDRV_PCM_FORMAT_LAST) { - pcm_dbg(substream->pcm, "Cannot find a format!!!\n"); - err = -EINVAL; - goto failure; + goto format_found; } + pcm_dbg(substream->pcm, "Cannot find a format!!!\n"); + err = -EINVAL; + goto failure; } + format_found: err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, (__force int)sformat, 0); if (err < 0) goto failure; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 336406bcb59e..900f9cfd4646 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -2293,21 +2293,21 @@ static int snd_pcm_hw_rule_mulkdiv(struct snd_pcm_hw_params *params, static int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { - unsigned int k; + snd_pcm_format_t k; const struct snd_interval *i = hw_param_interval_c(params, rule->deps[0]); struct snd_mask m; struct snd_mask *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); snd_mask_any(&m); - for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) { + pcm_for_each_format(k) { int bits; - if (! snd_mask_test(mask, k)) + if (!snd_mask_test_format(mask, k)) continue; bits = snd_pcm_format_physical_width(k); if (bits <= 0) continue; /* ignore invalid formats */ if ((unsigned)bits < i->min || (unsigned)bits > i->max) - snd_mask_reset(&m, k); + snd_mask_reset(&m, (__force unsigned)k); } return snd_mask_refine(mask, &m); } @@ -2316,14 +2316,15 @@ static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { struct snd_interval t; - unsigned int k; + snd_pcm_format_t k; + t.min = UINT_MAX; t.max = 0; t.openmin = 0; t.openmax = 0; - for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) { + pcm_for_each_format(k) { int bits; - if (! snd_mask_test(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k)) + if (!snd_mask_test_format(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k)) continue; bits = snd_pcm_format_physical_width(k); if (bits <= 0)
The parameter bit mask needs often explicit cast with __force, e.g. for the PCM subformat type. Instead of adding __force at each place, which is error prone, this patch introduces a new macro and replaces the all bit shift with it. This fixes the sparse warnings like the following: sound/core/pcm_native.c:2508:30: warning: restricted snd_pcm_access_t degrades to integer
No functional changes, just sparse warning fixes.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/core/pcm_native.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 900f9cfd4646..559633d4702d 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -228,6 +228,9 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream, return err; }
+/* macro for simplified cast */ +#define PARAM_MASK_BIT(b) (1U << (__force int)(b)) + static bool hw_support_mmap(struct snd_pcm_substream *substream) { if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP)) @@ -257,7 +260,7 @@ static int constrain_mask_params(struct snd_pcm_substream *substream, return -EINVAL;
/* This parameter is not requested to change by a caller. */ - if (!(params->rmask & (1 << k))) + if (!(params->rmask & PARAM_MASK_BIT(k))) continue;
if (trace_hw_mask_param_enabled()) @@ -271,7 +274,7 @@ static int constrain_mask_params(struct snd_pcm_substream *substream,
/* Set corresponding flag so that the caller gets it. */ trace_hw_mask_param(substream, k, 0, &old_mask, m); - params->cmask |= 1 << k; + params->cmask |= PARAM_MASK_BIT(k); }
return 0; @@ -293,7 +296,7 @@ static int constrain_interval_params(struct snd_pcm_substream *substream, return -EINVAL;
/* This parameter is not requested to change by a caller. */ - if (!(params->rmask & (1 << k))) + if (!(params->rmask & PARAM_MASK_BIT(k))) continue;
if (trace_hw_interval_param_enabled()) @@ -307,7 +310,7 @@ static int constrain_interval_params(struct snd_pcm_substream *substream,
/* Set corresponding flag so that the caller gets it. */ trace_hw_interval_param(substream, k, 0, &old_interval, i); - params->cmask |= 1 << k; + params->cmask |= PARAM_MASK_BIT(k); }
return 0; @@ -349,7 +352,7 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream, * have 0 so that the parameters are never changed anymore. */ for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) - vstamps[k] = (params->rmask & (1 << k)) ? 1 : 0; + vstamps[k] = (params->rmask & PARAM_MASK_BIT(k)) ? 1 : 0;
/* Due to the above design, actual sequence number starts at 2. */ stamp = 2; @@ -417,7 +420,7 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream, hw_param_interval(params, r->var)); }
- params->cmask |= (1 << r->var); + params->cmask |= PARAM_MASK_BIT(r->var); vstamps[r->var] = stamp; again = true; } @@ -486,9 +489,9 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
params->info = 0; params->fifo_size = 0; - if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS)) + if (params->rmask & PARAM_MASK_BIT(SNDRV_PCM_HW_PARAM_SAMPLE_BITS)) params->msbits = 0; - if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) { + if (params->rmask & PARAM_MASK_BIT(SNDRV_PCM_HW_PARAM_RATE)) { params->rate_num = 0; params->rate_den = 0; } @@ -2506,16 +2509,16 @@ static int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) unsigned int mask = 0;
if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) - mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED; + mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_RW_INTERLEAVED); if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) - mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED; + mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_RW_NONINTERLEAVED); if (hw_support_mmap(substream)) { if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) - mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED; + mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_INTERLEAVED); if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) - mask |= 1 << SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED; + mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED); if (hw->info & SNDRV_PCM_INFO_COMPLEX) - mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX; + mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_COMPLEX); } err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask); if (err < 0) @@ -2525,7 +2528,8 @@ static int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) if (err < 0) return err;
- err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD); + err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, + PARAM_MASK_BIT(SNDRV_PCM_SUBFORMAT_STD)); if (err < 0) return err;
The new macro can fix the sparse warnings gracefully: sound/core/pcm_dmaengine.c:429:50: warning: restricted snd_pcm_format_t degrades to integer sound/core/pcm_dmaengine.c:429:55: warning: restricted snd_pcm_format_t degrades to integer sound/core/pcm_dmaengine.c:429:79: warning: restricted snd_pcm_format_t degrades to integer
No functional changes, just sparse warning fixes.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/core/pcm_dmaengine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index 5749a8a49784..b37c70864b57 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -426,7 +426,7 @@ int snd_dmaengine_pcm_refine_runtime_hwparams( * default assumption is that it supports 1, 2 and 4 bytes * widths. */ - for (i = SNDRV_PCM_FORMAT_FIRST; i <= SNDRV_PCM_FORMAT_LAST; i++) { + pcm_for_each_format(i) { int bits = snd_pcm_format_physical_width(i);
/*
Make a common helper for validating the format type. This reduces the number of cast in the code that are needed for suppressing sparse warnings.
No functional changes, just minor refactoring.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/core/pcm_misc.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index a6a541511534..cf3e8c26e00a 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c @@ -42,6 +42,11 @@ struct pcm_format_data { /* we do lots of calculations on snd_pcm_format_t; shut up sparse */ #define INT __force int
+static bool valid_format(snd_pcm_format_t format) +{ + return (INT)format >= 0 && (INT)format <= (INT)SNDRV_PCM_FORMAT_LAST; +} + static const struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = { [SNDRV_PCM_FORMAT_S8] = { .width = 8, .phys = 8, .le = -1, .signd = 1, @@ -259,7 +264,7 @@ static const struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = int snd_pcm_format_signed(snd_pcm_format_t format) { int val; - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) + if (!valid_format(format)) return -EINVAL; if ((val = pcm_formats[(INT)format].signd) < 0) return -EINVAL; @@ -307,7 +312,7 @@ EXPORT_SYMBOL(snd_pcm_format_linear); int snd_pcm_format_little_endian(snd_pcm_format_t format) { int val; - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) + if (!valid_format(format)) return -EINVAL; if ((val = pcm_formats[(INT)format].le) < 0) return -EINVAL; @@ -343,7 +348,7 @@ EXPORT_SYMBOL(snd_pcm_format_big_endian); int snd_pcm_format_width(snd_pcm_format_t format) { int val; - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) + if (!valid_format(format)) return -EINVAL; if ((val = pcm_formats[(INT)format].width) == 0) return -EINVAL; @@ -361,7 +366,7 @@ EXPORT_SYMBOL(snd_pcm_format_width); int snd_pcm_format_physical_width(snd_pcm_format_t format) { int val; - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) + if (!valid_format(format)) return -EINVAL; if ((val = pcm_formats[(INT)format].phys) == 0) return -EINVAL; @@ -394,7 +399,7 @@ EXPORT_SYMBOL(snd_pcm_format_size); */ const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format) { - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) + if (!valid_format(format)) return NULL; if (! pcm_formats[(INT)format].phys) return NULL; @@ -418,7 +423,7 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int unsigned char *dst; const unsigned char *pat;
- if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) + if (!valid_format(format)) return -EINVAL; if (samples == 0) return 0;
participants (1)
-
Takashi Iwai