ALSA: usb-audio: Fix races at disconnection in mixer_quirks.c
Similar like the previous commit, cover with chip->shutdown_rwsem and chip->shutdown checks. Reported-by: Matthieu CASTET <matthieu.castet@parrot.com> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Родитель
34f3c89fda
Коммит
888ea7d5ac
|
@ -283,6 +283,11 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
|
||||||
if (value > 1)
|
if (value > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
changed = value != mixer->audigy2nx_leds[index];
|
changed = value != mixer->audigy2nx_leds[index];
|
||||||
|
down_read(&mixer->chip->shutdown_rwsem);
|
||||||
|
if (mixer->chip->shutdown) {
|
||||||
|
err = -ENODEV;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
|
if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
|
||||||
err = snd_usb_ctl_msg(mixer->chip->dev,
|
err = snd_usb_ctl_msg(mixer->chip->dev,
|
||||||
usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
|
usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
|
||||||
|
@ -299,6 +304,8 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
|
||||||
usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
|
usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
|
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
|
||||||
value, index + 2, NULL, 0);
|
value, index + 2, NULL, 0);
|
||||||
|
out:
|
||||||
|
up_read(&mixer->chip->shutdown_rwsem);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
mixer->audigy2nx_leds[index] = value;
|
mixer->audigy2nx_leds[index] = value;
|
||||||
|
@ -392,11 +399,16 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
|
||||||
|
|
||||||
for (i = 0; jacks[i].name; ++i) {
|
for (i = 0; jacks[i].name; ++i) {
|
||||||
snd_iprintf(buffer, "%s: ", jacks[i].name);
|
snd_iprintf(buffer, "%s: ", jacks[i].name);
|
||||||
err = snd_usb_ctl_msg(mixer->chip->dev,
|
down_read(&mixer->chip->shutdown_rwsem);
|
||||||
|
if (mixer->chip->shutdown)
|
||||||
|
err = 0;
|
||||||
|
else
|
||||||
|
err = snd_usb_ctl_msg(mixer->chip->dev,
|
||||||
usb_rcvctrlpipe(mixer->chip->dev, 0),
|
usb_rcvctrlpipe(mixer->chip->dev, 0),
|
||||||
UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
|
UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
|
||||||
USB_RECIP_INTERFACE, 0,
|
USB_RECIP_INTERFACE, 0,
|
||||||
jacks[i].unitid << 8, buf, 3);
|
jacks[i].unitid << 8, buf, 3);
|
||||||
|
up_read(&mixer->chip->shutdown_rwsem);
|
||||||
if (err == 3 && (buf[0] == 3 || buf[0] == 6))
|
if (err == 3 && (buf[0] == 3 || buf[0] == 6))
|
||||||
snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
|
snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
|
||||||
else
|
else
|
||||||
|
@ -426,10 +438,15 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
|
||||||
else
|
else
|
||||||
new_status = old_status & ~0x02;
|
new_status = old_status & ~0x02;
|
||||||
changed = new_status != old_status;
|
changed = new_status != old_status;
|
||||||
err = snd_usb_ctl_msg(mixer->chip->dev,
|
down_read(&mixer->chip->shutdown_rwsem);
|
||||||
|
if (mixer->chip->shutdown)
|
||||||
|
err = -ENODEV;
|
||||||
|
else
|
||||||
|
err = snd_usb_ctl_msg(mixer->chip->dev,
|
||||||
usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
|
usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
|
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
|
||||||
50, 0, &new_status, 1);
|
50, 0, &new_status, 1);
|
||||||
|
up_read(&mixer->chip->shutdown_rwsem);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
mixer->xonar_u1_status = new_status;
|
mixer->xonar_u1_status = new_status;
|
||||||
|
@ -468,11 +485,17 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
|
||||||
u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
|
u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
|
||||||
u16 wIndex = kcontrol->private_value & 0xffff;
|
u16 wIndex = kcontrol->private_value & 0xffff;
|
||||||
u8 tmp;
|
u8 tmp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
|
down_read(&mixer->chip->shutdown_rwsem);
|
||||||
|
if (mixer->chip->shutdown)
|
||||||
|
ret = -ENODEV;
|
||||||
|
else
|
||||||
|
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||||
0, cpu_to_le16(wIndex),
|
0, cpu_to_le16(wIndex),
|
||||||
&tmp, sizeof(tmp), 1000);
|
&tmp, sizeof(tmp), 1000);
|
||||||
|
up_read(&mixer->chip->shutdown_rwsem);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
snd_printk(KERN_ERR
|
snd_printk(KERN_ERR
|
||||||
|
@ -493,11 +516,17 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
|
||||||
u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
|
u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
|
||||||
u16 wIndex = kcontrol->private_value & 0xffff;
|
u16 wIndex = kcontrol->private_value & 0xffff;
|
||||||
u16 wValue = ucontrol->value.integer.value[0];
|
u16 wValue = ucontrol->value.integer.value[0];
|
||||||
|
int ret;
|
||||||
|
|
||||||
int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
|
down_read(&mixer->chip->shutdown_rwsem);
|
||||||
|
if (mixer->chip->shutdown)
|
||||||
|
ret = -ENODEV;
|
||||||
|
else
|
||||||
|
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
|
||||||
cpu_to_le16(wValue), cpu_to_le16(wIndex),
|
cpu_to_le16(wValue), cpu_to_le16(wIndex),
|
||||||
NULL, 0, 1000);
|
NULL, 0, 1000);
|
||||||
|
up_read(&mixer->chip->shutdown_rwsem);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
snd_printk(KERN_ERR
|
snd_printk(KERN_ERR
|
||||||
|
@ -656,11 +685,16 @@ static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|
||||||
err = snd_usb_ctl_msg(chip->dev,
|
down_read(&mixer->chip->shutdown_rwsem);
|
||||||
|
if (mixer->chip->shutdown)
|
||||||
|
err = -ENODEV;
|
||||||
|
else
|
||||||
|
err = snd_usb_ctl_msg(chip->dev,
|
||||||
usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
|
usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
|
||||||
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
|
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
|
||||||
validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
|
validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
|
||||||
value, val_len);
|
value, val_len);
|
||||||
|
up_read(&mixer->chip->shutdown_rwsem);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -703,11 +737,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
|
||||||
|
|
||||||
if (!pval->is_cached) {
|
if (!pval->is_cached) {
|
||||||
/* Read current value */
|
/* Read current value */
|
||||||
err = snd_usb_ctl_msg(chip->dev,
|
down_read(&mixer->chip->shutdown_rwsem);
|
||||||
|
if (mixer->chip->shutdown)
|
||||||
|
err = -ENODEV;
|
||||||
|
else
|
||||||
|
err = snd_usb_ctl_msg(chip->dev,
|
||||||
usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
|
usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
|
||||||
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
|
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
|
||||||
validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
|
validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
|
||||||
value, val_len);
|
value, val_len);
|
||||||
|
up_read(&mixer->chip->shutdown_rwsem);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -719,11 +758,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
|
||||||
if (cur_val != new_val) {
|
if (cur_val != new_val) {
|
||||||
value[0] = new_val;
|
value[0] = new_val;
|
||||||
value[1] = 0;
|
value[1] = 0;
|
||||||
err = snd_usb_ctl_msg(chip->dev,
|
down_read(&mixer->chip->shutdown_rwsem);
|
||||||
|
if (mixer->chip->shutdown)
|
||||||
|
err = -ENODEV;
|
||||||
|
else
|
||||||
|
err = snd_usb_ctl_msg(chip->dev,
|
||||||
usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
|
usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
|
||||||
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
|
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
|
||||||
validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
|
validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
|
||||||
value, val_len);
|
value, val_len);
|
||||||
|
up_read(&mixer->chip->shutdown_rwsem);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче