summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/urb.c30
-rw-r--r--include/linux/usb.h2
-rw-r--r--sound/core/hrtimer.c2
-rw-r--r--sound/core/hwdep.c2
-rw-r--r--sound/core/pcm_native.c2
-rw-r--r--sound/core/seq/seq_clientmgr.c4
-rw-r--r--sound/core/timer.c11
-rw-r--r--sound/pci/asihpi/asihpi.c15
-rw-r--r--sound/pci/ens1370.c3
-rw-r--r--sound/pci/hda/hda_generic.c2
-rw-r--r--sound/pci/hda/patch_ca0132.c8
-rw-r--r--sound/pci/oxygen/xonar_dg.h2
-rw-r--r--sound/pci/oxygen/xonar_dg_mixer.c2
-rw-r--r--sound/sh/aica.c20
-rw-r--r--sound/synth/emux/emux_oss.c2
-rw-r--r--sound/usb/6fire/chip.c2
-rw-r--r--sound/usb/bcd2000/bcd2000.c7
-rw-r--r--sound/usb/caiaq/device.c7
-rw-r--r--sound/usb/caiaq/input.c9
-rw-r--r--sound/usb/hiface/pcm.c9
-rw-r--r--sound/usb/line6/capture.c2
-rw-r--r--sound/usb/line6/capture.h2
-rw-r--r--sound/usb/line6/driver.c30
-rw-r--r--sound/usb/line6/midi.c17
-rw-r--r--sound/usb/line6/playback.c2
-rw-r--r--sound/usb/line6/playback.h2
-rw-r--r--sound/usb/line6/podhd.c16
-rw-r--r--sound/usb/midi.c38
-rw-r--r--sound/usb/quirks.c24
-rw-r--r--sound/usb/usx2y/usbusx2y.c5
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c3
31 files changed, 193 insertions, 89 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 47903d510955..8b800e34407b 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -187,6 +187,31 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
/*-------------------------------------------------------------------*/
+static const int pipetypes[4] = {
+ PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
+};
+
+/**
+ * usb_urb_ep_type_check - sanity check of endpoint in the given urb
+ * @urb: urb to be checked
+ *
+ * This performs a light-weight sanity check for the endpoint in the
+ * given urb. It returns 0 if the urb contains a valid endpoint, otherwise
+ * a negative error code.
+ */
+int usb_urb_ep_type_check(const struct urb *urb)
+{
+ const struct usb_host_endpoint *ep;
+
+ ep = usb_pipe_endpoint(urb->dev, urb->pipe);
+ if (!ep)
+ return -EINVAL;
+ if (usb_pipetype(urb->pipe) != pipetypes[usb_endpoint_type(&ep->desc)])
+ return -EINVAL;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(usb_urb_ep_type_check);
+
/**
* usb_submit_urb - issue an asynchronous transfer request for an endpoint
* @urb: pointer to the urb describing the request
@@ -326,9 +351,6 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
*/
int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
{
- static int pipetypes[4] = {
- PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
- };
int xfertype, max;
struct usb_device *dev;
struct usb_host_endpoint *ep;
@@ -444,7 +466,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
*/
/* Check that the pipe's type matches the endpoint's type */
- if (usb_pipetype(urb->pipe) != pipetypes[xfertype])
+ if (usb_urb_ep_type_check(urb))
dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",
usb_pipetype(urb->pipe), pipetypes[xfertype]);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index cb9fbd54386e..2b861804fffa 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1728,6 +1728,8 @@ static inline int usb_urb_dir_out(struct urb *urb)
return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT;
}
+int usb_urb_ep_type_check(const struct urb *urb);
+
void *usb_alloc_coherent(struct usb_device *dev, size_t size,
gfp_t mem_flags, dma_addr_t *dma);
void usb_free_coherent(struct usb_device *dev, size_t size,
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index 1ac0c423903e..5603e49f7bf7 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -127,7 +127,7 @@ static int snd_hrtimer_stop(struct snd_timer *t)
return 0;
}
-static struct snd_timer_hardware hrtimer_hw = {
+static const struct snd_timer_hardware hrtimer_hw __initconst = {
.flags = SNDRV_TIMER_HW_AUTO | SNDRV_TIMER_HW_TASKLET,
.open = snd_hrtimer_open,
.close = snd_hrtimer_close,
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index a73baa1242be..8faae3d1455d 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -228,6 +228,8 @@ static int snd_hwdep_dsp_load(struct snd_hwdep *hw,
memset(&info, 0, sizeof(info));
if (copy_from_user(&info, _info, sizeof(info)))
return -EFAULT;
+ if (info.index >= 32)
+ return -EINVAL;
/* check whether the dsp was already loaded */
if (hw->dsp_loaded & (1 << info.index))
return -EBUSY;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 2fec2feac387..a4d92e46c459 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -195,7 +195,6 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore);
int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
{
- struct snd_pcm_runtime *runtime;
struct snd_pcm *pcm = substream->pcm;
struct snd_pcm_str *pstr = substream->pstr;
@@ -211,7 +210,6 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
info->subdevices_count = pstr->substream_count;
info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
strlcpy(info->subname, substream->name, sizeof(info->subname));
- runtime = substream->runtime;
return 0;
}
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 6c9cba2166d9..84759d9c54bf 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -802,6 +802,10 @@ static int snd_seq_deliver_event(struct snd_seq_client *client, struct snd_seq_e
return -EMLINK;
}
+ if (snd_seq_ev_is_variable(event) &&
+ snd_BUG_ON(atomic && (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR)))
+ return -EINVAL;
+
if (event->queue == SNDRV_SEQ_ADDRESS_SUBSCRIBERS ||
event->dest.client == SNDRV_SEQ_ADDRESS_SUBSCRIBERS)
result = deliver_to_subscribers(client, event, atomic, hop);
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 6cdd04a45962..09acaf2b2e57 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1028,15 +1028,17 @@ EXPORT_SYMBOL(snd_timer_global_register);
struct snd_timer_system_private {
struct timer_list tlist;
+ struct snd_timer *snd_timer;
unsigned long last_expires;
unsigned long last_jiffies;
unsigned long correction;
};
-static void snd_timer_s_function(unsigned long data)
+static void snd_timer_s_function(struct timer_list *t)
{
- struct snd_timer *timer = (struct snd_timer *)data;
- struct snd_timer_system_private *priv = timer->private_data;
+ struct snd_timer_system_private *priv = from_timer(priv, t,
+ tlist);
+ struct snd_timer *timer = priv->snd_timer;
unsigned long jiff = jiffies;
if (time_after(jiff, priv->last_expires))
priv->correction += (long)jiff - (long)priv->last_expires;
@@ -1118,7 +1120,8 @@ static int snd_timer_register_system(void)
snd_timer_free(timer);
return -ENOMEM;
}
- setup_timer(&priv->tlist, snd_timer_s_function, (unsigned long) timer);
+ priv->snd_timer = timer;
+ timer_setup(&priv->tlist, snd_timer_s_function, 0);
timer->private_data = priv;
timer->private_free = snd_timer_free_system;
return snd_timer_global_register(timer);
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index 70d023a85bf5..720361455c60 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -573,10 +573,8 @@ static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream)
static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream)
{
- struct snd_card_asihpi_pcm *dpcm;
struct snd_card_asihpi *card;
- dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data;
card = snd_pcm_substream_chip(substream);
hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
@@ -749,9 +747,9 @@ static inline unsigned int modulo_min(unsigned int a, unsigned int b,
/** Timer function, equivalent to interrupt service routine for cards
*/
-static void snd_card_asihpi_timer_function(unsigned long data)
+static void snd_card_asihpi_timer_function(struct timer_list *t)
{
- struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
+ struct snd_card_asihpi_pcm *dpcm = from_timer(dpcm, t, timer);
struct snd_pcm_substream *substream = dpcm->substream;
struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime;
@@ -863,7 +861,6 @@ static void snd_card_asihpi_timer_function(unsigned long data)
snd_pcm_group_for_each_entry(s, substream) {
struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
- runtime = s->runtime;
/* don't link Cap and Play */
if (substream->stream != s->stream)
@@ -948,7 +945,7 @@ static void snd_card_asihpi_int_task(unsigned long data)
asihpi = (struct snd_card_asihpi *)a->snd_card->private_data;
if (asihpi->llmode_streampriv)
snd_card_asihpi_timer_function(
- (unsigned long)asihpi->llmode_streampriv);
+ &asihpi->llmode_streampriv->timer);
}
static void snd_card_asihpi_isr(struct hpi_adapter *a)
@@ -1059,8 +1056,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
If internal and other stream playing, can't switch
*/
- setup_timer(&dpcm->timer, snd_card_asihpi_timer_function,
- (unsigned long) dpcm);
+ timer_setup(&dpcm->timer, snd_card_asihpi_timer_function, 0);
dpcm->substream = substream;
runtime->private_data = dpcm;
runtime->private_free = snd_card_asihpi_runtime_free;
@@ -1240,8 +1236,7 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
if (err)
return -EIO;
- setup_timer(&dpcm->timer, snd_card_asihpi_timer_function,
- (unsigned long) dpcm);
+ timer_setup(&dpcm->timer, snd_card_asihpi_timer_function, 0);
dpcm->substream = substream;
runtime->private_data = dpcm;
runtime->private_free = snd_card_asihpi_runtime_free;
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index d4cd6451fdca..39f79a6b5283 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -732,7 +732,7 @@ static void snd_es1371_codec_wait(struct snd_ac97 *ac97)
static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate)
{
- unsigned int n, truncm, freq, result;
+ unsigned int n, truncm, freq;
mutex_lock(&ensoniq->src_mutex);
n = rate / 3000;
@@ -740,7 +740,6 @@ static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate)
n--;
truncm = (21 * n - 1) | 1;
freq = ((48000UL << 15) / rate) * n;
- result = (48000UL << 15) / (freq / n);
if (rate >= 24000) {
if (truncm > 239)
truncm = 239;
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 28e265a88383..5cc65093d941 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -795,6 +795,8 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path,
hda_nid_t nid = path->path[i];
nums = snd_hda_get_conn_list(codec, nid, &conn);
+ if (nums < 0)
+ return;
type = get_wcaps_type(get_wcaps(codec, nid));
if (type == AC_WID_PIN ||
(type == AC_WID_AUD_IN && codec->single_adc_amp)) {
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 3e73d5c6ccfc..768ea8651993 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -27,6 +27,7 @@
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/firmware.h>
+#include <linux/kernel.h>
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_local.h"
@@ -3605,8 +3606,7 @@ static int ca0132_vnode_switch_set(struct snd_kcontrol *kcontrol,
static int ca0132_voicefx_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
- unsigned int items = sizeof(ca0132_voicefx_presets)
- / sizeof(struct ct_voicefx_preset);
+ unsigned int items = ARRAY_SIZE(ca0132_voicefx_presets);
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
@@ -3635,10 +3635,8 @@ static int ca0132_voicefx_put(struct snd_kcontrol *kcontrol,
struct ca0132_spec *spec = codec->spec;
int i, err = 0;
int sel = ucontrol->value.enumerated.item[0];
- unsigned int items = sizeof(ca0132_voicefx_presets)
- / sizeof(struct ct_voicefx_preset);
- if (sel >= items)
+ if (sel >= ARRAY_SIZE(ca0132_voicefx_presets))
return 0;
codec_dbg(codec, "ca0132_voicefx_put: sel=%d, preset=%s\n",
diff --git a/sound/pci/oxygen/xonar_dg.h b/sound/pci/oxygen/xonar_dg.h
index d461df357aa1..5a07cda011b3 100644
--- a/sound/pci/oxygen/xonar_dg.h
+++ b/sound/pci/oxygen/xonar_dg.h
@@ -51,6 +51,6 @@ void dg_suspend(struct oxygen *chip);
void dg_resume(struct oxygen *chip);
void dg_cleanup(struct oxygen *chip);
-extern struct oxygen_model model_xonar_dg;
+extern const struct oxygen_model model_xonar_dg;
#endif
diff --git a/sound/pci/oxygen/xonar_dg_mixer.c b/sound/pci/oxygen/xonar_dg_mixer.c
index b885dac28a09..d22fbe8aebd0 100644
--- a/sound/pci/oxygen/xonar_dg_mixer.c
+++ b/sound/pci/oxygen/xonar_dg_mixer.c
@@ -449,7 +449,7 @@ static int dg_mixer_init(struct oxygen *chip)
return 0;
}
-struct oxygen_model model_xonar_dg = {
+const struct oxygen_model model_xonar_dg = {
.longname = "C-Media Oxygen HD Audio",
.chip = "CMI8786",
.init = dg_init,
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index fdc680ae8aa0..2b26311405a4 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -299,14 +299,14 @@ static void run_spu_dma(struct work_struct *work)
}
}
-static void aica_period_elapsed(unsigned long timer_var)
+static void aica_period_elapsed(struct timer_list *t)
{
+ struct snd_card_aica *dreamcastcard = from_timer(dreamcastcard,
+ t, timer);
+ struct snd_pcm_substream *substream = dreamcastcard->timer_substream;
/*timer function - so cannot sleep */
int play_period;
struct snd_pcm_runtime *runtime;
- struct snd_pcm_substream *substream;
- struct snd_card_aica *dreamcastcard;
- substream = (struct snd_pcm_substream *) timer_var;
runtime = substream->runtime;
dreamcastcard = substream->pcm->private_data;
/* Have we played out an additional period? */
@@ -336,12 +336,12 @@ static void spu_begin_dma(struct snd_pcm_substream *substream)
/*get the queue to do the work */
schedule_work(&(dreamcastcard->spu_dma_work));
/* Timer may already be running */
- if (unlikely(dreamcastcard->timer.data)) {
+ if (unlikely(dreamcastcard->timer_substream)) {
mod_timer(&dreamcastcard->timer, jiffies + 4);
return;
}
- setup_timer(&dreamcastcard->timer, aica_period_elapsed,
- (unsigned long) substream);
+ timer_setup(&dreamcastcard->timer, aica_period_elapsed, 0);
+ dreamcastcard->timer_substream = substream;
mod_timer(&dreamcastcard->timer, jiffies + 4);
}
@@ -379,7 +379,7 @@ static int snd_aicapcm_pcm_close(struct snd_pcm_substream
{
struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
flush_work(&(dreamcastcard->spu_dma_work));
- if (dreamcastcard->timer.data)
+ if (dreamcastcard->timer_substream)
del_timer(&dreamcastcard->timer);
kfree(dreamcastcard->channel);
spu_disable();
@@ -600,7 +600,7 @@ static int snd_aica_probe(struct platform_device *devptr)
{
int err;
struct snd_card_aica *dreamcastcard;
- dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL);
+ dreamcastcard = kzalloc(sizeof(struct snd_card_aica), GFP_KERNEL);
if (unlikely(!dreamcastcard))
return -ENOMEM;
err = snd_card_new(&devptr->dev, index, SND_AICA_DRIVER,
@@ -619,8 +619,6 @@ static int snd_aica_probe(struct platform_device *devptr)
err = snd_aicapcmchip(dreamcastcard, 0);
if (unlikely(err < 0))
goto freedreamcast;
- dreamcastcard->timer.data = 0;
- dreamcastcard->channel = NULL;
/* Add basic controls */
err = add_aicamixer_controls(dreamcastcard);
if (unlikely(err < 0))
diff --git a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c
index de19e108974a..764ff4bc2089 100644
--- a/sound/synth/emux/emux_oss.c
+++ b/sound/synth/emux/emux_oss.c
@@ -430,7 +430,6 @@ gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd,
{
int voice;
unsigned short p1;
- short p2;
int plong;
struct snd_midi_channel *chan;
@@ -445,7 +444,6 @@ gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd,
chan = &port->chset.channels[voice];
p1 = *(unsigned short *) &event[4];
- p2 = *(short *) &event[6];
plong = *(int*) &event[4];
switch (cmd) {
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index c7641cb50616..17d5e3ee6d73 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -174,11 +174,9 @@ destroy_chip:
static void usb6fire_chip_disconnect(struct usb_interface *intf)
{
struct sfire_chip *chip;
- struct snd_card *card;
chip = usb_get_intfdata(intf);
if (chip) { /* if !chip, fw upload has been performed */
- card = chip->card;
chip->intf_count--;
if (!chip->intf_count) {
mutex_lock(&register_mutex);
diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c
index 7371e5b06035..a6408209d7f1 100644
--- a/sound/usb/bcd2000/bcd2000.c
+++ b/sound/usb/bcd2000/bcd2000.c
@@ -342,6 +342,13 @@ static int bcd2000_init_midi(struct bcd2000 *bcd2k)
bcd2k->midi_out_buf, BUFSIZE,
bcd2000_output_complete, bcd2k, 1);
+ /* sanity checks of EPs before actually submitting */
+ if (usb_urb_ep_type_check(bcd2k->midi_in_urb) ||
+ usb_urb_ep_type_check(bcd2k->midi_out_urb)) {
+ dev_err(&bcd2k->dev->dev, "invalid MIDI EP\n");
+ return -EINVAL;
+ }
+
bcd2000_init_device(bcd2k);
return 0;
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index d8409d9ae55b..d55ca48de3ea 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -461,6 +461,13 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
cdev->midi_out_buf, EP1_BUFSIZE,
snd_usb_caiaq_midi_output_done, cdev);
+ /* sanity checks of EPs before actually submitting */
+ if (usb_urb_ep_type_check(&cdev->ep1_in_urb) ||
+ usb_urb_ep_type_check(&cdev->midi_out_urb)) {
+ dev_err(dev, "invalid EPs\n");
+ return -EINVAL;
+ }
+
init_waitqueue_head(&cdev->ep1_wait_queue);
init_waitqueue_head(&cdev->prepare_wait_queue);
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index 4b3fb91deecd..e883659ea6e7 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -718,6 +718,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
usb_rcvbulkpipe(usb_dev, 0x4),
cdev->ep4_in_buf, EP4_BUFSIZE,
snd_usb_caiaq_ep4_reply_dispatch, cdev);
+ ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
+ if (ret < 0)
+ goto exit_free_idev;
snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);
@@ -757,6 +760,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
usb_rcvbulkpipe(usb_dev, 0x4),
cdev->ep4_in_buf, EP4_BUFSIZE,
snd_usb_caiaq_ep4_reply_dispatch, cdev);
+ ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
+ if (ret < 0)
+ goto exit_free_idev;
snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);
@@ -802,6 +808,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
usb_rcvbulkpipe(usb_dev, 0x4),
cdev->ep4_in_buf, EP4_BUFSIZE,
snd_usb_caiaq_ep4_reply_dispatch, cdev);
+ ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
+ if (ret < 0)
+ goto exit_free_idev;
snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);
break;
diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c
index 175d8d6b7f59..396c317115b1 100644
--- a/sound/usb/hiface/pcm.c
+++ b/sound/usb/hiface/pcm.c
@@ -541,6 +541,8 @@ static int hiface_pcm_init_urb(struct pcm_urb *urb,
usb_fill_bulk_urb(&urb->instance, chip->dev,
usb_sndbulkpipe(chip->dev, ep), (void *)urb->buffer,
PCM_PACKET_SIZE, handler, urb);
+ if (usb_urb_ep_type_check(&urb->instance))
+ return -EINVAL;
init_usb_anchor(&urb->submitted);
return 0;
@@ -599,9 +601,12 @@ int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq)
mutex_init(&rt->stream_mutex);
spin_lock_init(&rt->playback.lock);
- for (i = 0; i < PCM_N_URBS; i++)
- hiface_pcm_init_urb(&rt->out_urbs[i], chip, OUT_EP,
+ for (i = 0; i < PCM_N_URBS; i++) {
+ ret = hiface_pcm_init_urb(&rt->out_urbs[i], chip, OUT_EP,
hiface_pcm_out_urb_handler);
+ if (ret < 0)
+ return ret;
+ }
ret = snd_pcm_new(chip->card, "USB-SPDIF Audio", 0, 1, 0, &pcm);
if (ret < 0) {
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
index 7c812565f90d..947d6168f24a 100644
--- a/sound/usb/line6/capture.c
+++ b/sound/usb/line6/capture.c
@@ -248,7 +248,7 @@ static int snd_line6_capture_close(struct snd_pcm_substream *substream)
}
/* capture operators */
-struct snd_pcm_ops snd_line6_capture_ops = {
+const struct snd_pcm_ops snd_line6_capture_ops = {
.open = snd_line6_capture_open,
.close = snd_line6_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/usb/line6/capture.h b/sound/usb/line6/capture.h
index 890b21bff18c..b67ccc39fd25 100644
--- a/sound/usb/line6/capture.h
+++ b/sound/usb/line6/capture.h
@@ -17,7 +17,7 @@
#include "driver.h"
#include "pcm.h"
-extern struct snd_pcm_ops snd_line6_capture_ops;
+extern const struct snd_pcm_ops snd_line6_capture_ops;
extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf,
int fsize);
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index c8f723c3a033..8d5a454842f4 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -78,6 +78,13 @@ static int line6_start_listen(struct usb_line6 *line6)
line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
line6_data_received, line6);
}
+
+ /* sanity checks of EP before actually submitting */
+ if (usb_urb_ep_type_check(line6->urb_listen)) {
+ dev_err(line6->ifcdev, "invalid control EP\n");
+ return -EINVAL;
+ }
+
line6->urb_listen->actual_length = 0;
err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC);
return err;
@@ -168,17 +175,24 @@ static int line6_send_raw_message_async_part(struct message *msg,
}
msg->done += bytes;
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval < 0) {
- dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
- __func__, retval);
- usb_free_urb(urb);
- kfree(msg);
- return retval;
- }
+ /* sanity checks of EP before actually submitting */
+ retval = usb_urb_ep_type_check(urb);
+ if (retval < 0)
+ goto error;
+
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval < 0)
+ goto error;
return 0;
+
+ error:
+ dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
+ __func__, retval);
+ usb_free_urb(urb);
+ kfree(msg);
+ return retval;
}
/*
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
index 1d3a23b02d68..6d7cde56a355 100644
--- a/sound/usb/line6/midi.c
+++ b/sound/usb/line6/midi.c
@@ -130,16 +130,21 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
transfer_buffer, length, midi_sent, line6,
line6->interval);
urb->actual_length = 0;
- retval = usb_submit_urb(urb, GFP_ATOMIC);
+ retval = usb_urb_ep_type_check(urb);
+ if (retval < 0)
+ goto error;
- if (retval < 0) {
- dev_err(line6->ifcdev, "usb_submit_urb failed\n");
- usb_free_urb(urb);
- return retval;
- }
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval < 0)
+ goto error;
++line6->line6midi->num_active_send_urbs;
return 0;
+
+ error:
+ dev_err(line6->ifcdev, "usb_submit_urb failed\n");
+ usb_free_urb(urb);
+ return retval;
}
static int line6_midi_output_open(struct snd_rawmidi_substream *substream)
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c
index 812d18191e01..819e9b2d1d6e 100644
--- a/sound/usb/line6/playback.c
+++ b/sound/usb/line6/playback.c
@@ -393,7 +393,7 @@ static int snd_line6_playback_close(struct snd_pcm_substream *substream)
}
/* playback operators */
-struct snd_pcm_ops snd_line6_playback_ops = {
+const struct snd_pcm_ops snd_line6_playback_ops = {
.open = snd_line6_playback_open,
.close = snd_line6_playback_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/usb/line6/playback.h b/sound/usb/line6/playback.h
index 51fce29e8726..d8d3b8a07a72 100644
--- a/sound/usb/line6/playback.h
+++ b/sound/usb/line6/playback.h
@@ -27,7 +27,7 @@
*/
#define USE_CLEAR_BUFFER_WORKAROUND 1
-extern struct snd_pcm_ops snd_line6_playback_ops;
+extern const struct snd_pcm_ops snd_line6_playback_ops;
extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm);
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c
index 451007c27743..46fa8c046cb5 100644
--- a/sound/usb/line6/podhd.c
+++ b/sound/usb/line6/podhd.c
@@ -39,7 +39,8 @@ enum {
LINE6_PODHD500_1,
LINE6_PODX3,
LINE6_PODX3LIVE,
- LINE6_PODHD500X
+ LINE6_PODHD500X,
+ LINE6_PODHDDESKTOP
};
struct usb_line6_podhd {
@@ -379,6 +380,7 @@ static const struct usb_device_id podhd_id_table[] = {
{ LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 },
{ LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE },
{ LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X },
+ { LINE6_IF_NUM(0x4156, 0), .driver_info = LINE6_PODHDDESKTOP },
{}
};
@@ -465,6 +467,18 @@ static const struct line6_properties podhd_properties_table[] = {
.ep_audio_r = 0x86,
.ep_audio_w = 0x02,
},
+ [LINE6_PODHDDESKTOP] = {
+ .id = "PODHDDESKTOP",
+ .name = "POD HDDESKTOP",
+ .capabilities = LINE6_CAP_CONTROL
+ | LINE6_CAP_PCM | LINE6_CAP_HWMON,
+ .altsetting = 1,
+ .ep_ctrl_r = 0x81,
+ .ep_ctrl_w = 0x01,
+ .ctrl_if = 1,
+ .ep_audio_r = 0x86,
+ .ep_audio_w = 0x02,
+ },
};
/*
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index a92e2b2a91ec..7ab25de5ca0a 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1282,6 +1282,7 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi,
unsigned int pipe;
int length;
unsigned int i;
+ int err;
rep->in = NULL;
ep = kzalloc(sizeof(*ep), GFP_KERNEL);
@@ -1292,8 +1293,8 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi,
for (i = 0; i < INPUT_URBS; ++i) {
ep->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
if (!ep->urbs[i]) {
- snd_usbmidi_in_endpoint_delete(ep);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto error;
}
}
if (ep_info->in_interval)
@@ -1305,8 +1306,8 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi,
buffer = usb_alloc_coherent(umidi->dev, length, GFP_KERNEL,
&ep->urbs[i]->transfer_dma);
if (!buffer) {
- snd_usbmidi_in_endpoint_delete(ep);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto error;
}
if (ep_info->in_interval)
usb_fill_int_urb(ep->urbs[i], umidi->dev,
@@ -1318,10 +1319,20 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi,
pipe, buffer, length,
snd_usbmidi_in_urb_complete, ep);
ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+ err = usb_urb_ep_type_check(ep->urbs[i]);
+ if (err < 0) {
+ dev_err(&umidi->dev->dev, "invalid MIDI in EP %x\n",
+ ep_info->in_ep);
+ goto error;
+ }
}
rep->in = ep;
return 0;
+
+ error:
+ snd_usbmidi_in_endpoint_delete(ep);
+ return -ENOMEM;
}
/*
@@ -1357,6 +1368,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
unsigned int i;
unsigned int pipe;
void *buffer;
+ int err;
rep->out = NULL;
ep = kzalloc(sizeof(*ep), GFP_KERNEL);
@@ -1367,8 +1379,8 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
for (i = 0; i < OUTPUT_URBS; ++i) {
ep->urbs[i].urb = usb_alloc_urb(0, GFP_KERNEL);
if (!ep->urbs[i].urb) {
- snd_usbmidi_out_endpoint_delete(ep);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto error;
}
ep->urbs[i].ep = ep;
}
@@ -1406,8 +1418,8 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
ep->max_transfer, GFP_KERNEL,
&ep->urbs[i].urb->transfer_dma);
if (!buffer) {
- snd_usbmidi_out_endpoint_delete(ep);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto error;
}
if (ep_info->out_interval)
usb_fill_int_urb(ep->urbs[i].urb, umidi->dev,
@@ -1419,6 +1431,12 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
pipe, buffer, ep->max_transfer,
snd_usbmidi_out_urb_complete,
&ep->urbs[i]);
+ err = usb_urb_ep_type_check(ep->urbs[i].urb);
+ if (err < 0) {
+ dev_err(&umidi->dev->dev, "invalid MIDI out EP %x\n",
+ ep_info->out_ep);
+ goto error;
+ }
ep->urbs[i].urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
}
@@ -1437,6 +1455,10 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
rep->out = ep;
return 0;
+
+ error:
+ snd_usbmidi_out_endpoint_delete(ep);
+ return err;
}
/*
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 9ddaae3784f5..9aeb05f61f78 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1128,30 +1128,24 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
/* devices which do not support reading the sample rate. */
switch (chip->usb_id) {
case USB_ID(0x041E, 0x4080): /* Creative Live Cam VF0610 */
- case USB_ID(0x045E, 0x075D): /* MS Lifecam Cinema */
- case USB_ID(0x045E, 0x076D): /* MS Lifecam HD-5000 */
- case USB_ID(0x045E, 0x076E): /* MS Lifecam HD-5001 */
- case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */
- case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */
- case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
- case USB_ID(0x047F, 0x02F7): /* Plantronics BT-600 */
- case USB_ID(0x047F, 0x0415): /* Plantronics BT-300 */
- case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */
- case USB_ID(0x047F, 0xC022): /* Plantronics C310 */
- case USB_ID(0x047F, 0xC02F): /* Plantronics P610 */
- case USB_ID(0x047F, 0xC036): /* Plantronics C520-M */
case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */
case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
- case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */
- case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */
- case USB_ID(0x1de7, 0x0114): /* Phoenix Audio MT202pcs */
case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */
return true;
}
+
+ /* devices of these vendors don't support reading rate, either */
+ switch (USB_ID_VENDOR(chip->usb_id)) {
+ case 0x045E: /* MS Lifecam */
+ case 0x047F: /* Plantronics */
+ case 0x1de7: /* Phoenix Audio */
+ return true;
+ }
+
return false;
}
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 4569c0efac0a..0ddf29267d70 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -279,6 +279,9 @@ int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y)
usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0,
i_usX2Y_Out04Int, usX2Y
);
+ err = usb_urb_ep_type_check(usX2Y->AS04.urb[i]);
+ if (err < 0)
+ break;
}
return err;
}
@@ -298,6 +301,8 @@ int usX2Y_In04_init(struct usX2Ydev *usX2Y)
usX2Y->In04Buf, 21,
i_usX2Y_In04Int, usX2Y,
10);
+ if (usb_urb_ep_type_check(usX2Y->In04urb))
+ return -EINVAL;
return usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
}
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index f93b355756e6..345e439aa95b 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -677,6 +677,9 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
usb_fill_bulk_urb(us->urb[i], usX2Y->dev, usb_sndbulkpipe(usX2Y->dev, 4),
usbdata + i, 2, i_usX2Y_04Int, usX2Y);
}
+ err = usb_urb_ep_type_check(us->urb[0]);
+ if (err < 0)
+ goto cleanup;
us->submitted = 0;
us->len = NOOF_SETRATE_URBS;
usX2Y->US04 = us;