ALSA: asihpi - Fix format validity check.
authorEliot Blennerhassett <eblennerhassett@audioscience.com>
Thu, 22 Dec 2011 00:38:51 +0000 (13:38 +1300)
committerTakashi Iwai <tiwai@suse.de>
Thu, 22 Dec 2011 07:13:11 +0000 (08:13 +0100)
Sharing and not reinitialising static pcm_hardware struct resulted in
stream format validity flags being incorrectly shared between cards.
Fix and clarify by declaring locally and initialising in the open functions.

Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/asihpi/asihpi.c

index fdec4aa05c8a9785cdc03f78c934af89b1446954..fd3926fb0a082321a828581fec36b41ad89aba40 100644 (file)
@@ -938,15 +938,15 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
        return ptr;
 }
 
-static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
-                                               u32 h_stream,
-                                               struct snd_pcm_hardware *pcmhw)
+static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
+                                               u32 h_stream)
 {
        struct hpi_format hpi_format;
        u16 format;
        u16 err;
        u32 h_control;
        u32 sample_rate = 48000;
+       u64 formats = 0;
 
        /* on cards without SRC, must query at valid rate,
        * maybe set by external sync
@@ -966,32 +966,24 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
                if (!err)
                        err = hpi_outstream_query_format(h_stream, &hpi_format);
                if (!err && (hpi_to_alsa_formats[format] != -1))
-                       pcmhw->formats |= (1ULL << hpi_to_alsa_formats[format]);
+                       formats |= (1ULL << hpi_to_alsa_formats[format]);
        }
+       return formats;
 }
 
-static struct snd_pcm_hardware snd_card_asihpi_playback = {
-       .buffer_bytes_max = BUFFER_BYTES_MAX,
-       .period_bytes_min = PERIOD_BYTES_MIN,
-       .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
-       .periods_min = PERIODS_MIN,
-       .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
-       .fifo_size = 0,
-};
-
 static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_card_asihpi_pcm *dpcm;
        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
+       struct snd_pcm_hardware snd_card_asihpi_playback;
        int err;
 
        dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
        if (dpcm == NULL)
                return -ENOMEM;
 
-       err =
-           hpi_outstream_open(card->hpi->adapter->index,
+       err = hpi_outstream_open(card->hpi->adapter->index,
                              substream->number, &dpcm->h_stream);
        hpi_handle_error(err);
        if (err)
@@ -1013,13 +1005,19 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
        runtime->private_data = dpcm;
        runtime->private_free = snd_card_asihpi_runtime_free;
 
-       snd_card_asihpi_playback.channels_max = card->out_max_chans;
-       snd_card_asihpi_playback.channels_min = card->out_min_chans;
+       memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback));
+       snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX;
+       snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN;
        /*?snd_card_asihpi_playback.period_bytes_min =
        card->out_max_chans * 4096; */
-
-       snd_card_asihpi_playback_format(card, dpcm->h_stream,
-                                       &snd_card_asihpi_playback);
+       snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
+       snd_card_asihpi_playback.periods_min = PERIODS_MIN;
+       snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
+       /* snd_card_asihpi_playback.fifo_size = 0; */
+       snd_card_asihpi_playback.channels_max = card->out_max_chans;
+       snd_card_asihpi_playback.channels_min = card->out_min_chans;
+       snd_card_asihpi_playback.formats =
+                       snd_card_asihpi_playback_formats(card, dpcm->h_stream);
 
        snd_card_asihpi_pcm_samplerates(card,  &snd_card_asihpi_playback);
 
@@ -1116,15 +1114,15 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
 
 
 
-static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
-                                       u32 h_stream,
-                                        struct snd_pcm_hardware *pcmhw)
+static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
+                                       u32 h_stream)
 {
   struct hpi_format hpi_format;
        u16 format;
        u16 err;
        u32 h_control;
        u32 sample_rate = 48000;
+       u64 formats = 0;
 
        /* on cards without SRC, must query at valid rate,
                maybe set by external sync */
@@ -1144,25 +1142,17 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
                if (!err)
                        err = hpi_instream_query_format(h_stream, &hpi_format);
                if (!err)
-                       pcmhw->formats |= (1ULL << hpi_to_alsa_formats[format]);
+                       formats |= (1ULL << hpi_to_alsa_formats[format]);
        }
+       return formats;
 }
 
-
-static struct snd_pcm_hardware snd_card_asihpi_capture = {
-       .buffer_bytes_max = BUFFER_BYTES_MAX,
-       .period_bytes_min = PERIOD_BYTES_MIN,
-       .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
-       .periods_min = PERIODS_MIN,
-       .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
-       .fifo_size = 0,
-};
-
 static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
        struct snd_card_asihpi_pcm *dpcm;
+       struct snd_pcm_hardware snd_card_asihpi_capture;
        int err;
 
        dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
@@ -1189,10 +1179,17 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
        runtime->private_data = dpcm;
        runtime->private_free = snd_card_asihpi_runtime_free;
 
+       memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture));
+       snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX;
+       snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN;
+       snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
+       snd_card_asihpi_capture.periods_min = PERIODS_MIN;
+       snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
+       /* snd_card_asihpi_capture.fifo_size = 0; */
        snd_card_asihpi_capture.channels_max = card->in_max_chans;
        snd_card_asihpi_capture.channels_min = card->in_min_chans;
-       snd_card_asihpi_capture_format(card, dpcm->h_stream,
-                                      &snd_card_asihpi_capture);
+       snd_card_asihpi_capture.formats =
+               snd_card_asihpi_capture_formats(card, dpcm->h_stream);
        snd_card_asihpi_pcm_samplerates(card,  &snd_card_asihpi_capture);
        snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
                                        SNDRV_PCM_INFO_MMAP |