Commit d5cf9911 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Distinguish each substream for better sticky assignment

The commit ef18bede introduced a
mechanism to assign the previously used slot for the next reopen of a
PCM stream.  But the PCM device number isn't always unique (it may
have multiple substreams), and also the code doesn't check the stream
direction, thus both playback and capture streams share the same
device number.

For avoiding this conflict, make a unique key for each substream and
store/check this value at reopening.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 97999e28
...@@ -381,7 +381,7 @@ struct azx_dev { ...@@ -381,7 +381,7 @@ struct azx_dev {
*/ */
unsigned char stream_tag; /* assigned stream */ unsigned char stream_tag; /* assigned stream */
unsigned char index; /* stream index */ unsigned char index; /* stream index */
int device; /* last device number assigned to */ int assigned_key; /* last device# key assigned to */
unsigned int opened :1; unsigned int opened :1;
unsigned int running :1; unsigned int running :1;
...@@ -1613,6 +1613,9 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream) ...@@ -1613,6 +1613,9 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
{ {
int dev, i, nums; int dev, i, nums;
struct azx_dev *res = NULL; struct azx_dev *res = NULL;
/* make a non-zero unique key for the substream */
int key = (substream->pcm->device << 16) | (substream->number << 2) |
(substream->stream + 1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
dev = chip->playback_index_offset; dev = chip->playback_index_offset;
...@@ -1624,12 +1627,12 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream) ...@@ -1624,12 +1627,12 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
for (i = 0; i < nums; i++, dev++) for (i = 0; i < nums; i++, dev++)
if (!chip->azx_dev[dev].opened) { if (!chip->azx_dev[dev].opened) {
res = &chip->azx_dev[dev]; res = &chip->azx_dev[dev];
if (res->device == substream->pcm->device) if (res->assigned_key == key)
break; break;
} }
if (res) { if (res) {
res->opened = 1; res->opened = 1;
res->device = substream->pcm->device; res->assigned_key = key;
} }
return res; return res;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment