Commit a5f89a50 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "All stable fixes here:

   - a regression fix of USB-audio for the previous hardening patch

   - a potential UAF fix in rawmidi

   - HD-audio and USB-audio quirks, the missing new ID"

* tag 'sound-4.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: usb-audio: Fix the missing ctl name suffix at parsing SU
  ALSA: hda/realtek - Fix Dell AIO LineOut issue
  ALSA: rawmidi: Avoid racy info ioctl via ctl device
  ALSA: hda - Add vendor id for Cannonlake HDMI codec
  ALSA: usb-audio: Add native DSD support for Esoteric D-05X
parents 10a7e9d8 5a15f289
Loading
Loading
Loading
Loading
+12 −3
Original line number Original line Diff line number Diff line
@@ -579,15 +579,14 @@ static int snd_rawmidi_info_user(struct snd_rawmidi_substream *substream,
	return 0;
	return 0;
}
}


int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info)
static int __snd_rawmidi_info_select(struct snd_card *card,
				     struct snd_rawmidi_info *info)
{
{
	struct snd_rawmidi *rmidi;
	struct snd_rawmidi *rmidi;
	struct snd_rawmidi_str *pstr;
	struct snd_rawmidi_str *pstr;
	struct snd_rawmidi_substream *substream;
	struct snd_rawmidi_substream *substream;


	mutex_lock(&register_mutex);
	rmidi = snd_rawmidi_search(card, info->device);
	rmidi = snd_rawmidi_search(card, info->device);
	mutex_unlock(&register_mutex);
	if (!rmidi)
	if (!rmidi)
		return -ENXIO;
		return -ENXIO;
	if (info->stream < 0 || info->stream > 1)
	if (info->stream < 0 || info->stream > 1)
@@ -603,6 +602,16 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info
	}
	}
	return -ENXIO;
	return -ENXIO;
}
}

int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info)
{
	int ret;

	mutex_lock(&register_mutex);
	ret = __snd_rawmidi_info_select(card, info);
	mutex_unlock(&register_mutex);
	return ret;
}
EXPORT_SYMBOL(snd_rawmidi_info_select);
EXPORT_SYMBOL(snd_rawmidi_info_select);


static int snd_rawmidi_info_select_user(struct snd_card *card,
static int snd_rawmidi_info_select_user(struct snd_card *card,
+4 −2
Original line number Original line Diff line number Diff line
@@ -55,10 +55,11 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
#define is_kabylake(codec) ((codec)->core.vendor_id == 0x8086280b)
#define is_kabylake(codec) ((codec)->core.vendor_id == 0x8086280b)
#define is_geminilake(codec) (((codec)->core.vendor_id == 0x8086280d) || \
#define is_geminilake(codec) (((codec)->core.vendor_id == 0x8086280d) || \
				((codec)->core.vendor_id == 0x80862800))
				((codec)->core.vendor_id == 0x80862800))
#define is_cannonlake(codec) ((codec)->core.vendor_id == 0x8086280c)
#define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \
#define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \
				|| is_skylake(codec) || is_broxton(codec) \
				|| is_skylake(codec) || is_broxton(codec) \
				|| is_kabylake(codec)) || is_geminilake(codec)
				|| is_kabylake(codec)) || is_geminilake(codec) \

				|| is_cannonlake(codec)
#define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882)
#define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882)
#define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883)
#define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883)
#define is_valleyview_plus(codec) (is_valleyview(codec) || is_cherryview(codec))
#define is_valleyview_plus(codec) (is_valleyview(codec) || is_cherryview(codec))
@@ -3841,6 +3842,7 @@ HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_i915_hsw_hdmi),
HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI",	patch_i915_hsw_hdmi),
HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI",	patch_i915_hsw_hdmi),
HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI",	patch_i915_hsw_hdmi),
HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI",	patch_i915_hsw_hdmi),
HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI",	patch_i915_hsw_hdmi),
HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI",	patch_i915_hsw_hdmi),
HDA_CODEC_ENTRY(0x8086280c, "Cannonlake HDMI",	patch_i915_glk_hdmi),
HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI",	patch_i915_glk_hdmi),
HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI",	patch_i915_glk_hdmi),
HDA_CODEC_ENTRY(0x80862800, "Geminilake HDMI",	patch_i915_glk_hdmi),
HDA_CODEC_ENTRY(0x80862800, "Geminilake HDMI",	patch_i915_glk_hdmi),
HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI",	patch_generic_hdmi),
HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI",	patch_generic_hdmi),
+34 −1
Original line number Original line Diff line number Diff line
@@ -5185,6 +5185,22 @@ static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
	}
	}
}
}


/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
static void alc274_fixup_bind_dacs(struct hda_codec *codec,
				    const struct hda_fixup *fix, int action)
{
	struct alc_spec *spec = codec->spec;
	static hda_nid_t preferred_pairs[] = {
		0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
		0
	};

	if (action != HDA_FIXUP_ACT_PRE_PROBE)
		return;

	spec->gen.preferred_dacs = preferred_pairs;
}

/* for hda_fixup_thinkpad_acpi() */
/* for hda_fixup_thinkpad_acpi() */
#include "thinkpad_helper.c"
#include "thinkpad_helper.c"


@@ -5302,6 +5318,8 @@ enum {
	ALC233_FIXUP_LENOVO_MULTI_CODECS,
	ALC233_FIXUP_LENOVO_MULTI_CODECS,
	ALC294_FIXUP_LENOVO_MIC_LOCATION,
	ALC294_FIXUP_LENOVO_MIC_LOCATION,
	ALC700_FIXUP_INTEL_REFERENCE,
	ALC700_FIXUP_INTEL_REFERENCE,
	ALC274_FIXUP_DELL_BIND_DACS,
	ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
};
};


static const struct hda_fixup alc269_fixups[] = {
static const struct hda_fixup alc269_fixups[] = {
@@ -6112,6 +6130,21 @@ static const struct hda_fixup alc269_fixups[] = {
			{}
			{}
		}
		}
	},
	},
	[ALC274_FIXUP_DELL_BIND_DACS] = {
		.type = HDA_FIXUP_FUNC,
		.v.func = alc274_fixup_bind_dacs,
		.chained = true,
		.chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
	},
	[ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
		.type = HDA_FIXUP_PINS,
		.v.pins = (const struct hda_pintbl[]) {
			{ 0x1b, 0x0401102f },
			{ }
		},
		.chained = true,
		.chain_id = ALC274_FIXUP_DELL_BIND_DACS
	},
};
};


static const struct snd_pci_quirk alc269_fixup_tbl[] = {
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -6578,7 +6611,7 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
		{0x14, 0x90170110},
		{0x14, 0x90170110},
		{0x1b, 0x90a70130},
		{0x1b, 0x90a70130},
		{0x21, 0x03211020}),
		{0x21, 0x03211020}),
	SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
	SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
		{0x12, 0xb7a60130},
		{0x12, 0xb7a60130},
		{0x13, 0xb8a61140},
		{0x13, 0xb8a61140},
		{0x16, 0x90170110},
		{0x16, 0x90170110},
+16 −11
Original line number Original line Diff line number Diff line
@@ -2173,20 +2173,25 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
	kctl->private_value = (unsigned long)namelist;
	kctl->private_value = (unsigned long)namelist;
	kctl->private_free = usb_mixer_selector_elem_free;
	kctl->private_free = usb_mixer_selector_elem_free;


	nameid = uac_selector_unit_iSelector(desc);
	/* check the static mapping table at first */
	len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
	len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
	if (len)
	if (!len) {
		;
		/* no mapping ? */
	else if (nameid)
		/* if iSelector is given, use it */
		len = snd_usb_copy_string_desc(state, nameid, kctl->id.name,
		nameid = uac_selector_unit_iSelector(desc);
		if (nameid)
			len = snd_usb_copy_string_desc(state, nameid,
						       kctl->id.name,
						       sizeof(kctl->id.name));
						       sizeof(kctl->id.name));
	else
		/* ... or pick up the terminal name at next */
		if (!len)
			len = get_term_name(state, &state->oterm,
			len = get_term_name(state, &state->oterm,
				    kctl->id.name, sizeof(kctl->id.name), 0);
				    kctl->id.name, sizeof(kctl->id.name), 0);

		/* ... or use the fixed string "USB" as the last resort */
	if (!len) {
		if (!len)
			strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
			strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));


		/* and add the proper suffix */
		if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
		if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
			append_ctl_name(kctl, " Clock Source");
			append_ctl_name(kctl, " Clock Source");
		else if ((state->oterm.type & 0xff00) == 0x0100)
		else if ((state->oterm.type & 0xff00) == 0x0100)
+4 −3
Original line number Original line Diff line number Diff line
@@ -1166,10 +1166,11 @@ static bool is_marantz_denon_dac(unsigned int id)
/* TEAC UD-501/UD-503/NT-503 USB DACs need a vendor cmd to switch
/* TEAC UD-501/UD-503/NT-503 USB DACs need a vendor cmd to switch
 * between PCM/DOP and native DSD mode
 * between PCM/DOP and native DSD mode
 */
 */
static bool is_teac_50X_dac(unsigned int id)
static bool is_teac_dsd_dac(unsigned int id)
{
{
	switch (id) {
	switch (id) {
	case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */
	case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */
	case USB_ID(0x0644, 0x8044): /* Esoteric D-05X */
		return true;
		return true;
	}
	}
	return false;
	return false;
@@ -1202,7 +1203,7 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs,
			break;
			break;
		}
		}
		mdelay(20);
		mdelay(20);
	} else if (is_teac_50X_dac(subs->stream->chip->usb_id)) {
	} else if (is_teac_dsd_dac(subs->stream->chip->usb_id)) {
		/* Vendor mode switch cmd is required. */
		/* Vendor mode switch cmd is required. */
		switch (fmt->altsetting) {
		switch (fmt->altsetting) {
		case 3: /* DSD mode (DSD_U32) requested */
		case 3: /* DSD mode (DSD_U32) requested */
@@ -1392,7 +1393,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
	}
	}


	/* TEAC devices with USB DAC functionality */
	/* TEAC devices with USB DAC functionality */
	if (is_teac_50X_dac(chip->usb_id)) {
	if (is_teac_dsd_dac(chip->usb_id)) {
		if (fp->altsetting == 3)
		if (fp->altsetting == 3)
			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
	}
	}