[alsa-devel] [PATCH 00/12] Fixes for sparse warnings and other misc bugs
Hi,
this is a series of patches to correct bugs spotted by sparse and manual lookups, applied in a wide range of drivers.
Takashi
===
Takashi Iwai (12): ALSA: usb-audio: Fix multiple definitions in AU0828_DEVICE() macro ALSA: msnd: Add missing __iomem annotations ALSA: msnd: Fix the default sample sizes ALSA: hda/ca0132 - Use NULL instead of 0 ALSA: msnd: Use NULL instead of 0 ALSA: hda - Fix a sparse warning about snd_ctl_elem_iface_t ALSA: opl3: Declare common variables properly ALSA: usb-audio: Declare the common variable in header file ALSA: pcm: Add __force to cast in snd_pcm_lib_read/write() ALSA: pcm: Use standard lower_32_bits() and upper_32_bits() ALSA: korg1212: Add __force annotation to cast in user-copy callbacks ALSA: emu10k1: Fix missing __force annotation for user/kernel pointer cast
include/sound/pcm.h | 4 ++-- sound/core/oss/pcm_plugin.c | 8 ++++---- sound/drivers/opl3/opl3_drums.c | 2 -- sound/drivers/opl3/opl3_lib.c | 3 +-- sound/drivers/opl3/opl3_midi.c | 4 ---- sound/drivers/opl3/opl3_oss.c | 2 -- sound/drivers/opl3/opl3_synth.c | 1 + sound/drivers/opl3/opl3_voice.h | 4 ++++ sound/isa/msnd/msnd.c | 18 +++++++++--------- sound/isa/msnd/msnd.h | 2 +- sound/isa/msnd/msnd_midi.c | 2 +- sound/isa/msnd/msnd_pinnacle.c | 8 ++++---- sound/pci/emu10k1/emufx.c | 24 ++++++++++++------------ sound/pci/hda/hda_codec.c | 4 ++-- sound/pci/hda/patch_ca0132.c | 3 +-- sound/pci/korg1212/korg1212.c | 4 ++-- sound/usb/mixer.h | 2 ++ sound/usb/mixer_quirks.c | 2 -- sound/usb/quirks-table.h | 3 ++- 19 files changed, 48 insertions(+), 52 deletions(-)
AU0828_DEVICE() macro in quirks-table.h uses USB_DEVICE_VENDOR_SPEC() for expanding idVendor and idProduct fields. However, the latter macro adds also match_flags and bInterfaceClass, which are different from the values AU0828_DEVICE() macro sets after that.
For fixing them, just expand idVendor and idProduct fields manually in AU0828_DEVICE().
This fixes sparse warnings like: sound/usb/quirks-table.h:2892:1: warning: Initializer entry defined twice
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/usb/quirks-table.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 8aac48f9c322..08aa78007020 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -2875,7 +2875,8 @@ YAMAHA_DEVICE(0x7010, "UB99"), */
#define AU0828_DEVICE(vid, pid, vname, pname) { \ - USB_DEVICE_VENDOR_SPEC(vid, pid), \ + .idVendor = vid, \ + .idProduct = pid, \ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ USB_DEVICE_ID_MATCH_INT_CLASS | \ USB_DEVICE_ID_MATCH_INT_SUBCLASS, \
The io-mapped buffers used in msnd drivers need __iomem annotations.
This fixes sparse warnings like: sound/isa/msnd/msnd_pinnacle.c:172:45: warning: incorrect type in initializer (different address spaces)
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/isa/msnd/msnd.c | 18 +++++++++--------- sound/isa/msnd/msnd.h | 2 +- sound/isa/msnd/msnd_midi.c | 2 +- sound/isa/msnd/msnd_pinnacle.c | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/sound/isa/msnd/msnd.c b/sound/isa/msnd/msnd.c index 569897f64fda..7c3203fe4869 100644 --- a/sound/isa/msnd/msnd.c +++ b/sound/isa/msnd/msnd.c @@ -54,7 +54,7 @@ #define LOGNAME "msnd"
-void snd_msnd_init_queue(void *base, int start, int size) +void snd_msnd_init_queue(void __iomem *base, int start, int size) { writew(PCTODSP_BASED(start), base + JQS_wStart); writew(PCTODSP_OFFSET(size) - 1, base + JQS_wSize); @@ -270,7 +270,7 @@ int snd_msnd_DARQ(struct snd_msnd *chip, int bank) udelay(1);
if (chip->capturePeriods == 2) { - void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF + + void __iomem *pDAQ = chip->mappedbase + DARQ_DATA_BUFF + bank * DAQDS__size + DAQDS_wStart; unsigned short offset = 0x3000 + chip->capturePeriodBytes;
@@ -309,7 +309,7 @@ int snd_msnd_DAPQ(struct snd_msnd *chip, int start) { u16 DAPQ_tail; int protect = start, nbanks = 0; - void *DAQD; + void __iomem *DAQD; static int play_banks_submitted; /* unsigned long flags; spin_lock_irqsave(&chip->lock, flags); not necessary */ @@ -370,7 +370,7 @@ static void snd_msnd_play_reset_queue(struct snd_msnd *chip, unsigned int pcm_count) { int n; - void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF; + void __iomem *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF;
chip->last_playbank = -1; chip->playLimit = pcm_count * (pcm_periods - 1); @@ -398,7 +398,7 @@ static void snd_msnd_capture_reset_queue(struct snd_msnd *chip, unsigned int pcm_count) { int n; - void *pDAQ; + void __iomem *pDAQ; /* unsigned long flags; */
/* snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE); */ @@ -485,7 +485,7 @@ static int snd_msnd_playback_open(struct snd_pcm_substream *substream) clear_bit(F_WRITING, &chip->flags); snd_msnd_enable_irq(chip);
- runtime->dma_area = chip->mappedbase; + runtime->dma_area = (__force void *)chip->mappedbase; runtime->dma_bytes = 0x3000;
chip->playback_substream = substream; @@ -508,7 +508,7 @@ static int snd_msnd_playback_hw_params(struct snd_pcm_substream *substream, { int i; struct snd_msnd *chip = snd_pcm_substream_chip(substream); - void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF; + void __iomem *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF;
chip->play_sample_size = snd_pcm_format_width(params_format(params)); chip->play_channels = params_channels(params); @@ -589,7 +589,7 @@ static int snd_msnd_capture_open(struct snd_pcm_substream *substream)
set_bit(F_AUDIO_READ_INUSE, &chip->flags); snd_msnd_enable_irq(chip); - runtime->dma_area = chip->mappedbase + 0x3000; + runtime->dma_area = (__force void *)chip->mappedbase + 0x3000; runtime->dma_bytes = 0x3000; memset(runtime->dma_area, 0, runtime->dma_bytes); chip->capture_substream = substream; @@ -654,7 +654,7 @@ static int snd_msnd_capture_hw_params(struct snd_pcm_substream *substream, { int i; struct snd_msnd *chip = snd_pcm_substream_chip(substream); - void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF; + void __iomem *pDAQ = chip->mappedbase + DARQ_DATA_BUFF;
chip->capture_sample_size = snd_pcm_format_width(params_format(params)); chip->capture_channels = params_channels(params); diff --git a/sound/isa/msnd/msnd.h b/sound/isa/msnd/msnd.h index 5f3c7dcd9f9d..80c718757eef 100644 --- a/sound/isa/msnd/msnd.h +++ b/sound/isa/msnd/msnd.h @@ -283,7 +283,7 @@ struct snd_msnd {
};
-void snd_msnd_init_queue(void *base, int start, int size); +void snd_msnd_init_queue(void __iomem *base, int start, int size);
int snd_msnd_send_dsp_cmd(struct snd_msnd *chip, u8 cmd); int snd_msnd_send_word(struct snd_msnd *chip, diff --git a/sound/isa/msnd/msnd_midi.c b/sound/isa/msnd/msnd_midi.c index 013d8d1170fe..42876b0cb68b 100644 --- a/sound/isa/msnd/msnd_midi.c +++ b/sound/isa/msnd/msnd_midi.c @@ -119,7 +119,7 @@ void snd_msndmidi_input_read(void *mpuv) { unsigned long flags; struct snd_msndmidi *mpu = mpuv; - void *pwMIDQData = mpu->dev->mappedbase + MIDQ_DATA_BUFF; + void __iomem *pwMIDQData = mpu->dev->mappedbase + MIDQ_DATA_BUFF; u16 head, tail, size;
spin_lock_irqsave(&mpu->input_lock, flags); diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c index 6c584d9b6c42..642609f7eda9 100644 --- a/sound/isa/msnd/msnd_pinnacle.c +++ b/sound/isa/msnd/msnd_pinnacle.c @@ -169,7 +169,7 @@ static void snd_msnd_eval_dsp_msg(struct snd_msnd *chip, u16 wMessage) static irqreturn_t snd_msnd_interrupt(int irq, void *dev_id) { struct snd_msnd *chip = dev_id; - void *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF; + void __iomem *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF; u16 head, tail, size;
/* Send ack to DSP */
The default sample sizes set by msnd driver are bogus; it sets ALSA PCM format, not the actual bit width.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/isa/msnd/msnd_pinnacle.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c index 642609f7eda9..7e3f52c8a6c6 100644 --- a/sound/isa/msnd/msnd_pinnacle.c +++ b/sound/isa/msnd/msnd_pinnacle.c @@ -82,10 +82,10 @@
static void set_default_audio_parameters(struct snd_msnd *chip) { - chip->play_sample_size = DEFSAMPLESIZE; + chip->play_sample_size = snd_pcm_format_width(DEFSAMPLESIZE); chip->play_sample_rate = DEFSAMPLERATE; chip->play_channels = DEFCHANNELS; - chip->capture_sample_size = DEFSAMPLESIZE; + chip->capture_sample_size = snd_pcm_format_width(DEFSAMPLESIZE); chip->capture_sample_rate = DEFSAMPLERATE; chip->capture_channels = DEFCHANNELS; }
Use NULL for initializing the snd_kcontrol_new.tlv field, instead of 0, as warned by sparse: sound/pci/hda/patch_ca0132.c:5519:22: warning: Using plain integer as NULL pointer
Also, the driver does the same initialization twice, once for knew.tlv.c and another for knew.tlv.p while both point to the same address (these are union). Drop the latter superfluous one.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/patch_ca0132.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 321e95c409c1..27d3388cd2a2 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -5516,8 +5516,7 @@ static int ca0132_alt_add_effect_slider(struct hda_codec *codec, hda_nid_t nid,
sprintf(namestr, "FX: %s %s Volume", pfx, dirstr[dir]);
- knew.tlv.c = 0; - knew.tlv.p = 0; + knew.tlv.c = NULL;
switch (nid) { case XBASS_XOVER:
Fix a sparse warning: sound/isa/msnd/msnd_pinnacle.c:813:1: warning: Using plain integer as NULL pointer
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/isa/msnd/msnd_pinnacle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c index 7e3f52c8a6c6..11af9c40bc05 100644 --- a/sound/isa/msnd/msnd_pinnacle.c +++ b/sound/isa/msnd/msnd_pinnacle.c @@ -810,7 +810,7 @@ module_param(calibrate_signal, int, 0444); #ifndef MSND_CLASSIC module_param_array(digital, int, NULL, 0444); module_param_hw_array(cfg, long, ioport, NULL, 0444); -module_param_array(reset, int, 0, 0444); +module_param_array(reset, int, NULL, 0444); module_param_hw_array(mpu_io, long, ioport, NULL, 0444); module_param_hw_array(mpu_irq, int, irq, NULL, 0444); module_param_hw_array(ide_io0, long, ioport, NULL, 0444);
The knew->iface field is in snd_ctl_elem_iface_t, which is with __bitwise, hence it can't be converted implicitly from integer. Give an explicit cast for the invalid type.
Spotted by sparse: sound/pci/hda/hda_codec.c:3280:25: warning: restricted snd_ctl_elem_iface_t degrades to integer
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 6d0c0b143270..0a5085537034 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3277,8 +3277,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, for (; knew->name; knew++) { struct snd_kcontrol *kctl; int addr = 0, idx = 0; - if (knew->iface == -1) /* skip this codec private value */ - continue; + if (knew->iface == (__force snd_ctl_elem_iface_t)-1) + continue; /* skip this codec private value */ for (;;) { kctl = snd_ctl_new1(knew, codec); if (!kctl)
Move the declarations of common variables into opl3_voice.h instead of declaring at each file multiple times, which was error-prone.
This fixes sparse warnings like: sound/drivers/opl3/opl3_synth.c:51:6: warning: symbol 'snd_opl3_regmap' was not declared. Should it be static?
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/drivers/opl3/opl3_drums.c | 2 -- sound/drivers/opl3/opl3_lib.c | 3 +-- sound/drivers/opl3/opl3_midi.c | 4 ---- sound/drivers/opl3/opl3_oss.c | 2 -- sound/drivers/opl3/opl3_synth.c | 1 + sound/drivers/opl3/opl3_voice.h | 4 ++++ 6 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/sound/drivers/opl3/opl3_drums.c b/sound/drivers/opl3/opl3_drums.c index 73694380734a..14929822956c 100644 --- a/sound/drivers/opl3/opl3_drums.c +++ b/sound/drivers/opl3/opl3_drums.c @@ -21,8 +21,6 @@
#include "opl3_voice.h"
-extern char snd_opl3_regmap[MAX_OPL2_VOICES][4]; - static char snd_opl3_drum_table[47] = { OPL3_BASSDRUM_ON, OPL3_BASSDRUM_ON, OPL3_HIHAT_ON, /* 35 - 37 */ diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c index 588963d6be28..1a5355b747ec 100644 --- a/sound/drivers/opl3/opl3_lib.c +++ b/sound/drivers/opl3/opl3_lib.c @@ -31,13 +31,12 @@ #include <linux/slab.h> #include <linux/ioport.h> #include <sound/minors.h> +#include "opl3_voice.h"
MODULE_AUTHOR("Jaroslav Kysela perex@perex.cz, Hannu Savolainen 1993-1996, Rob Hooft"); MODULE_DESCRIPTION("Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)"); MODULE_LICENSE("GPL");
-extern char snd_opl3_regmap[MAX_OPL2_VOICES][4]; - static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val) { unsigned long flags; diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c index 71cd5a2fbe82..471916ca0b6b 100644 --- a/sound/drivers/opl3/opl3_midi.c +++ b/sound/drivers/opl3/opl3_midi.c @@ -25,10 +25,6 @@ #include "opl3_voice.h" #include <sound/asoundef.h>
-extern char snd_opl3_regmap[MAX_OPL2_VOICES][4]; - -extern bool use_internal_drums; - static void snd_opl3_note_off_unsafe(void *p, int note, int vel, struct snd_midi_channel *chan); /* diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c index 8a0ce3f43f42..869220ced4ed 100644 --- a/sound/drivers/opl3/opl3_oss.c +++ b/sound/drivers/opl3/opl3_oss.c @@ -29,8 +29,6 @@ static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg);
/* operators */
-extern struct snd_midi_op opl3_ops; - static struct snd_seq_oss_callback oss_callback = { .owner = THIS_MODULE, .open = snd_opl3_open_seq_oss, diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c index 42920a243328..d522925fc5c0 100644 --- a/sound/drivers/opl3/opl3_synth.c +++ b/sound/drivers/opl3/opl3_synth.c @@ -24,6 +24,7 @@ #include <linux/nospec.h> #include <sound/opl3.h> #include <sound/asound_fm.h> +#include "opl3_voice.h"
#if IS_ENABLED(CONFIG_SND_SEQUENCER) #define OPL3_SUPPORT_SYNTH diff --git a/sound/drivers/opl3/opl3_voice.h b/sound/drivers/opl3/opl3_voice.h index a2445163008e..5b02bd49fde4 100644 --- a/sound/drivers/opl3/opl3_voice.h +++ b/sound/drivers/opl3/opl3_voice.h @@ -52,4 +52,8 @@ void snd_opl3_free_seq_oss(struct snd_opl3 *opl3); #define snd_opl3_free_seq_oss(opl3) /* NOP */ #endif
+extern char snd_opl3_regmap[MAX_OPL2_VOICES][4]; +extern bool use_internal_drums; +extern struct snd_midi_op opl3_ops; + #endif
Declare snd_usb_feature_unit_ctl properly in mixer.h. Otherwise it's error-prone.
This fixes the sparse warning: sound/usb/mixer.c:1464:25: warning: symbol 'snd_usb_feature_unit_ctl' was not declared. Should it be static?
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/usb/mixer.h | 2 ++ sound/usb/mixer_quirks.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index e02653465e29..3d12af8bf191 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h @@ -109,4 +109,6 @@ int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval,
extern void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl);
+extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; + #endif /* __USBMIXER_H */ diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index e82a72fea9a1..cbfb48bdea51 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -47,8 +47,6 @@ #include "mixer_us16x08.h" #include "helper.h"
-extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; - struct std_mono_table { unsigned int unitid, control, cmask; int val_type;
The snd_pcm_lib_read() and snd_pcm_lib_write() inline functions have the explicit cast from a user pointer to a kernel pointer, but they lacks of __force prefix.
This fixes sparse warnings like: ./include/sound/pcm.h:1093:47: warning: cast removes address space of expression
Fixes: 68541213720d ("ALSA: pcm: Direct in-kernel read/write support") Signed-off-by: Takashi Iwai tiwai@suse.de --- include/sound/pcm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 1206045ccf03..d6bd3caf6878 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -1090,14 +1090,14 @@ static inline snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t frames) { - return __snd_pcm_lib_xfer(substream, (void *)buf, true, frames, false); + return __snd_pcm_lib_xfer(substream, (void __force *)buf, true, frames, false); }
static inline snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __user *buf, snd_pcm_uframes_t frames) { - return __snd_pcm_lib_xfer(substream, (void *)buf, true, frames, false); + return __snd_pcm_lib_xfer(substream, (void __force *)buf, true, frames, false); }
static inline snd_pcm_sframes_t
Instead of open codes, use the standard macros for obtaining the lower and upper 32bit values.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/core/oss/pcm_plugin.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index 85a56af104bd..85bab922ce69 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c @@ -281,10 +281,10 @@ static int snd_pcm_plug_formats(const struct snd_mask *mask, SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE); snd_mask_set(&formats, (__force int)SNDRV_PCM_FORMAT_MU_LAW); - if (formats.bits[0] & (u32)linfmts) - formats.bits[0] |= (u32)linfmts; - if (formats.bits[1] & (u32)(linfmts >> 32)) - formats.bits[1] |= (u32)(linfmts >> 32); + if (formats.bits[0] & lower_32_bits(linfmts)) + formats.bits[0] |= lower_32_bits(linfmts); + if (formats.bits[1] & upper_32_bits(linfmts)) + formats.bits[1] |= upper_32_bits(linfmts); return snd_mask_test(&formats, (__force int)format); }
The user-copy callbacks in korg1212 driver contain the explicit cast from a user pointer to a kernel pointer, but they missed __force prefix. It's mandatory for converting between them.
Spotted by sparse, a warning like: sound/pci/korg1212/korg1212.c:1329:33: warning: cast removes address space of expression
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/korg1212/korg1212.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 4206ba44d8bb..4e189a93f475 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -1326,7 +1326,7 @@ static int snd_korg1212_copy_to(struct snd_pcm_substream *substream, } #endif if (in_kernel) - memcpy((void *)dst, src, size); + memcpy((__force void *)dst, src, size); else if (copy_to_user(dst, src, size)) return -EFAULT; src++; @@ -1365,7 +1365,7 @@ static int snd_korg1212_copy_from(struct snd_pcm_substream *substream, } #endif if (in_kernel) - memcpy((void *)dst, src, size); + memcpy(dst, (__force void *)src, size); else if (copy_from_user(dst, src, size)) return -EFAULT; dst++;
The cast between user-space and kernel-space needs an explicit __force prefix, but it's missing in many places in emu10k1 driver code.
Spotted by sparse as a warning like: sound/pci/emu10k1/emufx.c:529:33: warning: cast removes address space of expression
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/emu10k1/emufx.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index de2ecbe95d6c..90713741c2dc 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -526,7 +526,7 @@ static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu, if (!test_bit(gpr, icode->gpr_valid)) continue; if (in_kernel) - val = *(u32 *)&icode->gpr_map[gpr]; + val = *(__force u32 *)&icode->gpr_map[gpr]; else if (get_user(val, &icode->gpr_map[gpr])) return -EFAULT; snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val); @@ -560,8 +560,8 @@ static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu, if (!test_bit(tram, icode->tram_valid)) continue; if (in_kernel) { - val = *(u32 *)&icode->tram_data_map[tram]; - addr = *(u32 *)&icode->tram_addr_map[tram]; + val = *(__force u32 *)&icode->tram_data_map[tram]; + addr = *(__force u32 *)&icode->tram_addr_map[tram]; } else { if (get_user(val, &icode->tram_data_map[tram]) || get_user(addr, &icode->tram_addr_map[tram])) @@ -611,8 +611,8 @@ static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu, if (!test_bit(pc / 2, icode->code_valid)) continue; if (in_kernel) { - lo = *(u32 *)&icode->code[pc + 0]; - hi = *(u32 *)&icode->code[pc + 1]; + lo = *(__force u32 *)&icode->code[pc + 0]; + hi = *(__force u32 *)&icode->code[pc + 1]; } else { if (get_user(lo, &icode->code[pc + 0]) || get_user(hi, &icode->code[pc + 1])) @@ -666,7 +666,7 @@ static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel) if (!_tlv) return NULL; if (in_kernel) - memcpy(data, (void *)_tlv, sizeof(data)); + memcpy(data, (__force void *)_tlv, sizeof(data)); else if (copy_from_user(data, _tlv, sizeof(data))) return NULL; if (data[1] >= MAX_TLV_SIZE) @@ -676,7 +676,7 @@ static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel) return NULL; memcpy(tlv, data, sizeof(data)); if (in_kernel) { - memcpy(tlv + 2, (void *)(_tlv + 2), data[1]); + memcpy(tlv + 2, (__force void *)(_tlv + 2), data[1]); } else if (copy_from_user(tlv + 2, _tlv + 2, data[1])) { kfree(tlv); return NULL; @@ -693,7 +693,7 @@ static int copy_gctl(struct snd_emu10k1 *emu,
if (emu->support_tlv) { if (in_kernel) - memcpy(gctl, (void *)&_gctl[idx], sizeof(*gctl)); + memcpy(gctl, (__force void *)&_gctl[idx], sizeof(*gctl)); else if (copy_from_user(gctl, &_gctl[idx], sizeof(*gctl))) return -EFAULT; return 0; @@ -701,7 +701,7 @@ static int copy_gctl(struct snd_emu10k1 *emu,
octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl; if (in_kernel) - memcpy(gctl, (void *)&octl[idx], sizeof(*octl)); + memcpy(gctl, (__force void *)&octl[idx], sizeof(*octl)); else if (copy_from_user(gctl, &octl[idx], sizeof(*octl))) return -EFAULT; gctl->tlv = NULL; @@ -735,7 +735,7 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, for (i = 0, _id = icode->gpr_del_controls; i < icode->gpr_del_control_count; i++, _id++) { if (in_kernel) - id = *(struct snd_ctl_elem_id *)_id; + id = *(__force struct snd_ctl_elem_id *)_id; else if (copy_from_user(&id, _id, sizeof(id))) return -EFAULT; if (snd_emu10k1_look_for_ctl(emu, &id) == NULL) @@ -833,7 +833,7 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, knew.device = gctl->id.device; knew.subdevice = gctl->id.subdevice; knew.info = snd_emu10k1_gpr_ctl_info; - knew.tlv.p = copy_tlv(gctl->tlv, in_kernel); + knew.tlv.p = copy_tlv((__force const unsigned int __user *)gctl->tlv, in_kernel); if (knew.tlv.p) knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ; @@ -897,7 +897,7 @@ static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu, for (i = 0, _id = icode->gpr_del_controls; i < icode->gpr_del_control_count; i++, _id++) { if (in_kernel) - id = *(struct snd_ctl_elem_id *)_id; + id = *(__force struct snd_ctl_elem_id *)_id; else if (copy_from_user(&id, _id, sizeof(id))) return -EFAULT; down_write(&card->controls_rwsem);
participants (1)
-
Takashi Iwai