Skip to content

Commit

Permalink
Merge tag 'sound-5.3-rc7' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "A collection of small fixes as usual:

   - More coverage of USB-audio descriptor sanity checks

   - A fix for mute LED regression on Conexant HD-audio codecs

   - A few device-specific fixes and quirks for USB-audio and HD-audio

   - A fix for (die-hard remaining) possible race in sequencer core

   - FireWire oxfw regression fix that was introduced in 5.3-rc1"

* tag 'sound-5.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: oxfw: fix to handle correct stream for PCM playback
  ALSA: seq: Fix potential concurrent access to the deleted pool
  ALSA: usb-audio: Check mixer unit bitmap yet more strictly
  ALSA: line6: Fix memory leak at line6_init_pcm() error path
  ALSA: usb-audio: Fix invalid NULL check in snd_emuusb_set_samplerate()
  ALSA: hda/ca0132 - Add new SBZ quirk
  ALSA: usb-audio: Add implicit fb quirk for Behringer UFX1604
  ALSA: hda - Fixes inverted Conexant GPIO mic mute led
  • Loading branch information
Linus Torvalds committed Aug 27, 2019
2 parents 452a044 + 2fd2329 commit 0004654
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 32 deletions.
3 changes: 1 addition & 2 deletions sound/core/seq/seq_clientmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1835,8 +1835,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
if (cptr->type == USER_CLIENT) {
info->input_pool = cptr->data.user.fifo_pool_size;
info->input_free = info->input_pool;
if (cptr->data.user.fifo)
info->input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool);
info->input_free = snd_seq_fifo_unused_cells(cptr->data.user.fifo);
} else {
info->input_pool = 0;
info->input_free = 0;
Expand Down
17 changes: 17 additions & 0 deletions sound/core/seq/seq_fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,20 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)

return 0;
}

/* get the number of unused cells safely */
int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f)
{
unsigned long flags;
int cells;

if (!f)
return 0;

snd_use_lock_use(&f->use_lock);
spin_lock_irqsave(&f->lock, flags);
cells = snd_seq_unused_cells(f->pool);
spin_unlock_irqrestore(&f->lock, flags);
snd_use_lock_free(&f->use_lock);
return cells;
}
2 changes: 2 additions & 0 deletions sound/core/seq/seq_fifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,7 @@ int snd_seq_fifo_poll_wait(struct snd_seq_fifo *f, struct file *file, poll_table
/* resize pool in fifo */
int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize);

/* get the number of unused cells safely */
int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f);

#endif
2 changes: 1 addition & 1 deletion sound/firewire/oxfw/oxfw-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
unsigned int channels = params_channels(hw_params);

mutex_lock(&oxfw->mutex);
err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream,
err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream,
rate, channels);
if (err >= 0)
++oxfw->substreams_count;
Expand Down
1 change: 1 addition & 0 deletions sound/pci/hda/patch_ca0132.c
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE),
SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ),
SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ),
SND_PCI_QUIRK(0x1102, 0x0027, "Sound Blaster Z", QUIRK_SBZ),
SND_PCI_QUIRK(0x1102, 0x0033, "Sound Blaster ZxR", QUIRK_SBZ),
SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI),
SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
Expand Down
17 changes: 9 additions & 8 deletions sound/pci/hda/patch_conexant.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,18 +611,20 @@ static void cxt_fixup_hp_gate_mic_jack(struct hda_codec *codec,

/* update LED status via GPIO */
static void cxt_update_gpio_led(struct hda_codec *codec, unsigned int mask,
bool enabled)
bool led_on)
{
struct conexant_spec *spec = codec->spec;
unsigned int oldval = spec->gpio_led;

if (spec->mute_led_polarity)
enabled = !enabled;
led_on = !led_on;

if (enabled)
spec->gpio_led &= ~mask;
else
if (led_on)
spec->gpio_led |= mask;
else
spec->gpio_led &= ~mask;
codec_dbg(codec, "mask:%d enabled:%d gpio_led:%d\n",
mask, led_on, spec->gpio_led);
if (spec->gpio_led != oldval)
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
spec->gpio_led);
Expand All @@ -633,8 +635,8 @@ static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled)
{
struct hda_codec *codec = private_data;
struct conexant_spec *spec = codec->spec;

cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
/* muted -> LED on */
cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, !enabled);
}

/* turn on/off mic-mute LED via GPIO per capture hook */
Expand All @@ -656,7 +658,6 @@ static void cxt_fixup_mute_led_gpio(struct hda_codec *codec,
{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 },
{}
};
codec_info(codec, "action: %d gpio_led: %d\n", action, spec->gpio_led);

if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook;
Expand Down
18 changes: 9 additions & 9 deletions sound/usb/line6/pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,15 @@ int line6_init_pcm(struct usb_line6 *line6,
line6pcm->volume_monitor = 255;
line6pcm->line6 = line6;

spin_lock_init(&line6pcm->out.lock);
spin_lock_init(&line6pcm->in.lock);
line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;

line6->line6pcm = line6pcm;

pcm->private_data = line6pcm;
pcm->private_free = line6_cleanup_pcm;

line6pcm->max_packet_size_in =
usb_maxpacket(line6->usbdev,
usb_rcvisocpipe(line6->usbdev, ep_read), 0);
Expand All @@ -562,15 +571,6 @@ int line6_init_pcm(struct usb_line6 *line6,
return -EINVAL;
}

spin_lock_init(&line6pcm->out.lock);
spin_lock_init(&line6pcm->in.lock);
line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;

line6->line6pcm = line6pcm;

pcm->private_data = line6pcm;
pcm->private_free = line6_cleanup_pcm;

err = line6_create_audio_out_urbs(line6pcm);
if (err < 0)
return err;
Expand Down
36 changes: 28 additions & 8 deletions sound/usb/mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
struct uac_mixer_unit_descriptor *desc)
{
int mu_channels;
void *c;

if (desc->bLength < sizeof(*desc))
return -EINVAL;
Expand All @@ -762,13 +761,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
break;
}

if (!mu_channels)
return 0;

c = uac_mixer_unit_bmControls(desc, state->mixer->protocol);
if (c - (void *)desc + (mu_channels - 1) / 8 >= desc->bLength)
return 0; /* no bmControls -> skip */

return mu_channels;
}

Expand Down Expand Up @@ -2009,6 +2001,31 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
* Mixer Unit
*/

/* check whether the given in/out overflows bmMixerControls matrix */
static bool mixer_bitmap_overflow(struct uac_mixer_unit_descriptor *desc,
int protocol, int num_ins, int num_outs)
{
u8 *hdr = (u8 *)desc;
u8 *c = uac_mixer_unit_bmControls(desc, protocol);
size_t rest; /* remaining bytes after bmMixerControls */

switch (protocol) {
case UAC_VERSION_1:
default:
rest = 1; /* iMixer */
break;
case UAC_VERSION_2:
rest = 2; /* bmControls + iMixer */
break;
case UAC_VERSION_3:
rest = 6; /* bmControls + wMixerDescrStr */
break;
}

/* overflow? */
return c + (num_ins * num_outs + 7) / 8 + rest > hdr + hdr[0];
}

/*
* build a mixer unit control
*
Expand Down Expand Up @@ -2137,6 +2154,9 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid,
if (err < 0)
return err;
num_ins += iterm.channels;
if (mixer_bitmap_overflow(desc, state->mixer->protocol,
num_ins, num_outs))
break;
for (; ich < num_ins; ich++) {
int och, ich_has_controls = 0;

Expand Down
8 changes: 4 additions & 4 deletions sound/usb/mixer_quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -1155,17 +1155,17 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
{
struct usb_mixer_interface *mixer;
struct usb_mixer_elem_info *cval;
int unitid = 12; /* SamleRate ExtensionUnit ID */
int unitid = 12; /* SampleRate ExtensionUnit ID */

list_for_each_entry(mixer, &chip->mixer_list, list) {
cval = mixer_elem_list_to_info(mixer->id_elems[unitid]);
if (cval) {
if (mixer->id_elems[unitid]) {
cval = mixer_elem_list_to_info(mixer->id_elems[unitid]);
snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
cval->control << 8,
samplerate_id);
snd_usb_mixer_notify_id(mixer, unitid);
break;
}
break;
}
}

Expand Down
1 change: 1 addition & 0 deletions sound/usb/pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs,
ep = 0x81;
ifnum = 2;
goto add_sync_ep_from_ifnum;
case USB_ID(0x1397, 0x0001): /* Behringer UFX1604 */
case USB_ID(0x1397, 0x0002): /* Behringer UFX1204 */
ep = 0x81;
ifnum = 1;
Expand Down

0 comments on commit 0004654

Please sign in to comment.