Skip to content

Commit b2345a8

Browse files
committed
ALSA: usb-audio: Fix the missing endpoints creations for quirks
The recent change in the endpoint management moved the endpoint object creation from the stream open time to the parser of the audio descriptor. It works fine for the standard audio, but it overlooked the other places that create audio streams via quirks (QUIRK_AUDIO_FIXED_ENDPOINT) like the reported a few Pioneer devices; those call snd_usb_add_audio_stream() manually, hence they miss the endpoints, eventually resulting in the error at opening streams. Moreover, now the sync EP setup was moved to the explicit call of snd_usb_audioformat_set_sync_ep(), and this needs to be added for those places, too. This patch addresses those regressions for quirks. It adds a local helper function add_audio_stream_from_fixed_fmt(), which does the all needed tasks, and replaces the calls of snd_usb_add_audio_stream() with this new function. Fixes: 54cb319 ("ALSA: usb-audio: Create endpoint objects at parsing phase") Reported-by: František Kučera <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 7b62275 commit b2345a8

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

sound/usb/quirks.c

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,40 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip,
120120
return 0;
121121
}
122122

123+
/* create the audio stream and the corresponding endpoints from the fixed
124+
* audioformat object; this is used for quirks with the fixed EPs
125+
*/
126+
static int add_audio_stream_from_fixed_fmt(struct snd_usb_audio *chip,
127+
struct audioformat *fp)
128+
{
129+
int stream, err;
130+
131+
stream = (fp->endpoint & USB_DIR_IN) ?
132+
SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
133+
134+
snd_usb_audioformat_set_sync_ep(chip, fp);
135+
136+
err = snd_usb_add_audio_stream(chip, stream, fp);
137+
if (err < 0)
138+
return err;
139+
140+
err = snd_usb_add_endpoint(chip, fp->endpoint,
141+
SND_USB_ENDPOINT_TYPE_DATA);
142+
if (err < 0)
143+
return err;
144+
145+
if (fp->sync_ep) {
146+
err = snd_usb_add_endpoint(chip, fp->sync_ep,
147+
fp->implicit_fb ?
148+
SND_USB_ENDPOINT_TYPE_DATA :
149+
SND_USB_ENDPOINT_TYPE_SYNC);
150+
if (err < 0)
151+
return err;
152+
}
153+
154+
return 0;
155+
}
156+
123157
/*
124158
* create a stream for an endpoint/altsetting without proper descriptors
125159
*/
@@ -131,8 +165,8 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
131165
struct audioformat *fp;
132166
struct usb_host_interface *alts;
133167
struct usb_interface_descriptor *altsd;
134-
int stream, err;
135168
unsigned *rate_table = NULL;
169+
int err;
136170

137171
fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
138172
if (!fp)
@@ -153,11 +187,6 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
153187
fp->rate_table = rate_table;
154188
}
155189

156-
stream = (fp->endpoint & USB_DIR_IN)
157-
? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
158-
err = snd_usb_add_audio_stream(chip, stream, fp);
159-
if (err < 0)
160-
goto error;
161190
if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
162191
fp->altset_idx >= iface->num_altsetting) {
163192
err = -EINVAL;
@@ -176,6 +205,13 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
176205
fp->datainterval = snd_usb_parse_datainterval(chip, alts);
177206
if (fp->maxpacksize == 0)
178207
fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
208+
if (!fp->fmt_type)
209+
fp->fmt_type = UAC_FORMAT_TYPE_I;
210+
211+
err = add_audio_stream_from_fixed_fmt(chip, fp);
212+
if (err < 0)
213+
goto error;
214+
179215
usb_set_interface(chip->dev, fp->iface, 0);
180216
snd_usb_init_pitch(chip, fp);
181217
snd_usb_init_sample_rate(chip, fp, fp->rate_max);
@@ -417,7 +453,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
417453
struct usb_host_interface *alts;
418454
struct usb_interface_descriptor *altsd;
419455
struct audioformat *fp;
420-
int stream, err;
456+
int err;
421457

422458
/* both PCM and MIDI interfaces have 2 or more altsettings */
423459
if (iface->num_altsetting < 2)
@@ -482,9 +518,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
482518
return -ENXIO;
483519
}
484520

485-
stream = (fp->endpoint & USB_DIR_IN)
486-
? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
487-
err = snd_usb_add_audio_stream(chip, stream, fp);
521+
err = add_audio_stream_from_fixed_fmt(chip, fp);
488522
if (err < 0) {
489523
list_del(&fp->list); /* unlink for avoiding double-free */
490524
kfree(fp);

0 commit comments

Comments
 (0)