aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-10-06 04:07:58 -0400
committerTakashi Iwai <tiwai@suse.de>2011-10-06 04:11:11 -0400
commitd5cf9911988287e819ce98ccd9f61ca82fbc90c6 (patch)
treef097738d1b72946aecf757d93e7b27847af6b15b /sound/pci/hda
parent97999e28c74c5908445735ac282e8b20deb67b81 (diff)
ALSA: hda - Distinguish each substream for better sticky assignment
The commit ef18beded8ddbaafdf4914bab209f77e60ae3a18 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: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_intel.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 8a5dc574b657..90713f0b526c 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -381,7 +381,7 @@ struct azx_dev {
381 */ 381 */
382 unsigned char stream_tag; /* assigned stream */ 382 unsigned char stream_tag; /* assigned stream */
383 unsigned char index; /* stream index */ 383 unsigned char index; /* stream index */
384 int device; /* last device number assigned to */ 384 int assigned_key; /* last device# key assigned to */
385 385
386 unsigned int opened :1; 386 unsigned int opened :1;
387 unsigned int running :1; 387 unsigned int running :1;
@@ -1613,6 +1613,9 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
1613{ 1613{
1614 int dev, i, nums; 1614 int dev, i, nums;
1615 struct azx_dev *res = NULL; 1615 struct azx_dev *res = NULL;
1616 /* make a non-zero unique key for the substream */
1617 int key = (substream->pcm->device << 16) | (substream->number << 2) |
1618 (substream->stream + 1);
1616 1619
1617 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 1620 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1618 dev = chip->playback_index_offset; 1621 dev = chip->playback_index_offset;
@@ -1624,12 +1627,12 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
1624 for (i = 0; i < nums; i++, dev++) 1627 for (i = 0; i < nums; i++, dev++)
1625 if (!chip->azx_dev[dev].opened) { 1628 if (!chip->azx_dev[dev].opened) {
1626 res = &chip->azx_dev[dev]; 1629 res = &chip->azx_dev[dev];
1627 if (res->device == substream->pcm->device) 1630 if (res->assigned_key == key)
1628 break; 1631 break;
1629 } 1632 }
1630 if (res) { 1633 if (res) {
1631 res->opened = 1; 1634 res->opened = 1;
1632 res->device = substream->pcm->device; 1635 res->assigned_key = key;
1633 } 1636 }
1634 return res; 1637 return res;
1635} 1638}