diff options
author | Eliot Blennerhassett <eblennerhassett@audioscience.com> | 2011-12-21 19:38:51 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-12-22 02:13:11 -0500 |
commit | 68d533932217c6b3da4ab9abb15ab79d3a79474c (patch) | |
tree | c04309f2eb7165bf5e78a38c123c57c9fa69181a /sound/pci/asihpi | |
parent | c1d70dd9c44d7554b97f38b5ce8001d3cbe10f61 (diff) |
ALSA: asihpi - Fix format validity check.
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>
Diffstat (limited to 'sound/pci/asihpi')
-rw-r--r-- | sound/pci/asihpi/asihpi.c | 69 |
1 files changed, 33 insertions, 36 deletions
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index fdec4aa05c8a..fd3926fb0a08 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -938,15 +938,15 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) | |||
938 | return ptr; | 938 | return ptr; |
939 | } | 939 | } |
940 | 940 | ||
941 | static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, | 941 | static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi, |
942 | u32 h_stream, | 942 | u32 h_stream) |
943 | struct snd_pcm_hardware *pcmhw) | ||
944 | { | 943 | { |
945 | struct hpi_format hpi_format; | 944 | struct hpi_format hpi_format; |
946 | u16 format; | 945 | u16 format; |
947 | u16 err; | 946 | u16 err; |
948 | u32 h_control; | 947 | u32 h_control; |
949 | u32 sample_rate = 48000; | 948 | u32 sample_rate = 48000; |
949 | u64 formats = 0; | ||
950 | 950 | ||
951 | /* on cards without SRC, must query at valid rate, | 951 | /* on cards without SRC, must query at valid rate, |
952 | * maybe set by external sync | 952 | * maybe set by external sync |
@@ -966,32 +966,24 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, | |||
966 | if (!err) | 966 | if (!err) |
967 | err = hpi_outstream_query_format(h_stream, &hpi_format); | 967 | err = hpi_outstream_query_format(h_stream, &hpi_format); |
968 | if (!err && (hpi_to_alsa_formats[format] != -1)) | 968 | if (!err && (hpi_to_alsa_formats[format] != -1)) |
969 | pcmhw->formats |= (1ULL << hpi_to_alsa_formats[format]); | 969 | formats |= (1ULL << hpi_to_alsa_formats[format]); |
970 | } | 970 | } |
971 | return formats; | ||
971 | } | 972 | } |
972 | 973 | ||
973 | static struct snd_pcm_hardware snd_card_asihpi_playback = { | ||
974 | .buffer_bytes_max = BUFFER_BYTES_MAX, | ||
975 | .period_bytes_min = PERIOD_BYTES_MIN, | ||
976 | .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN, | ||
977 | .periods_min = PERIODS_MIN, | ||
978 | .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, | ||
979 | .fifo_size = 0, | ||
980 | }; | ||
981 | |||
982 | static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) | 974 | static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) |
983 | { | 975 | { |
984 | struct snd_pcm_runtime *runtime = substream->runtime; | 976 | struct snd_pcm_runtime *runtime = substream->runtime; |
985 | struct snd_card_asihpi_pcm *dpcm; | 977 | struct snd_card_asihpi_pcm *dpcm; |
986 | struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); | 978 | struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); |
979 | struct snd_pcm_hardware snd_card_asihpi_playback; | ||
987 | int err; | 980 | int err; |
988 | 981 | ||
989 | dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); | 982 | dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); |
990 | if (dpcm == NULL) | 983 | if (dpcm == NULL) |
991 | return -ENOMEM; | 984 | return -ENOMEM; |
992 | 985 | ||
993 | err = | 986 | err = hpi_outstream_open(card->hpi->adapter->index, |
994 | hpi_outstream_open(card->hpi->adapter->index, | ||
995 | substream->number, &dpcm->h_stream); | 987 | substream->number, &dpcm->h_stream); |
996 | hpi_handle_error(err); | 988 | hpi_handle_error(err); |
997 | if (err) | 989 | if (err) |
@@ -1013,13 +1005,19 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) | |||
1013 | runtime->private_data = dpcm; | 1005 | runtime->private_data = dpcm; |
1014 | runtime->private_free = snd_card_asihpi_runtime_free; | 1006 | runtime->private_free = snd_card_asihpi_runtime_free; |
1015 | 1007 | ||
1016 | snd_card_asihpi_playback.channels_max = card->out_max_chans; | 1008 | memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback)); |
1017 | snd_card_asihpi_playback.channels_min = card->out_min_chans; | 1009 | snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX; |
1010 | snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN; | ||
1018 | /*?snd_card_asihpi_playback.period_bytes_min = | 1011 | /*?snd_card_asihpi_playback.period_bytes_min = |
1019 | card->out_max_chans * 4096; */ | 1012 | card->out_max_chans * 4096; */ |
1020 | 1013 | snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; | |
1021 | snd_card_asihpi_playback_format(card, dpcm->h_stream, | 1014 | snd_card_asihpi_playback.periods_min = PERIODS_MIN; |
1022 | &snd_card_asihpi_playback); | 1015 | snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; |
1016 | /* snd_card_asihpi_playback.fifo_size = 0; */ | ||
1017 | snd_card_asihpi_playback.channels_max = card->out_max_chans; | ||
1018 | snd_card_asihpi_playback.channels_min = card->out_min_chans; | ||
1019 | snd_card_asihpi_playback.formats = | ||
1020 | snd_card_asihpi_playback_formats(card, dpcm->h_stream); | ||
1023 | 1021 | ||
1024 | snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback); | 1022 | snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback); |
1025 | 1023 | ||
@@ -1116,15 +1114,15 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) | |||
1116 | 1114 | ||
1117 | 1115 | ||
1118 | 1116 | ||
1119 | static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi, | 1117 | static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi, |
1120 | u32 h_stream, | 1118 | u32 h_stream) |
1121 | struct snd_pcm_hardware *pcmhw) | ||
1122 | { | 1119 | { |
1123 | struct hpi_format hpi_format; | 1120 | struct hpi_format hpi_format; |
1124 | u16 format; | 1121 | u16 format; |
1125 | u16 err; | 1122 | u16 err; |
1126 | u32 h_control; | 1123 | u32 h_control; |
1127 | u32 sample_rate = 48000; | 1124 | u32 sample_rate = 48000; |
1125 | u64 formats = 0; | ||
1128 | 1126 | ||
1129 | /* on cards without SRC, must query at valid rate, | 1127 | /* on cards without SRC, must query at valid rate, |
1130 | maybe set by external sync */ | 1128 | maybe set by external sync */ |
@@ -1144,25 +1142,17 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi, | |||
1144 | if (!err) | 1142 | if (!err) |
1145 | err = hpi_instream_query_format(h_stream, &hpi_format); | 1143 | err = hpi_instream_query_format(h_stream, &hpi_format); |
1146 | if (!err) | 1144 | if (!err) |
1147 | pcmhw->formats |= (1ULL << hpi_to_alsa_formats[format]); | 1145 | formats |= (1ULL << hpi_to_alsa_formats[format]); |
1148 | } | 1146 | } |
1147 | return formats; | ||
1149 | } | 1148 | } |
1150 | 1149 | ||
1151 | |||
1152 | static struct snd_pcm_hardware snd_card_asihpi_capture = { | ||
1153 | .buffer_bytes_max = BUFFER_BYTES_MAX, | ||
1154 | .period_bytes_min = PERIOD_BYTES_MIN, | ||
1155 | .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN, | ||
1156 | .periods_min = PERIODS_MIN, | ||
1157 | .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, | ||
1158 | .fifo_size = 0, | ||
1159 | }; | ||
1160 | |||
1161 | static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) | 1150 | static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) |
1162 | { | 1151 | { |
1163 | struct snd_pcm_runtime *runtime = substream->runtime; | 1152 | struct snd_pcm_runtime *runtime = substream->runtime; |
1164 | struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); | 1153 | struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); |
1165 | struct snd_card_asihpi_pcm *dpcm; | 1154 | struct snd_card_asihpi_pcm *dpcm; |
1155 | struct snd_pcm_hardware snd_card_asihpi_capture; | ||
1166 | int err; | 1156 | int err; |
1167 | 1157 | ||
1168 | dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); | 1158 | dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); |
@@ -1189,10 +1179,17 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) | |||
1189 | runtime->private_data = dpcm; | 1179 | runtime->private_data = dpcm; |
1190 | runtime->private_free = snd_card_asihpi_runtime_free; | 1180 | runtime->private_free = snd_card_asihpi_runtime_free; |
1191 | 1181 | ||
1182 | memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture)); | ||
1183 | snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX; | ||
1184 | snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN; | ||
1185 | snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; | ||
1186 | snd_card_asihpi_capture.periods_min = PERIODS_MIN; | ||
1187 | snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; | ||
1188 | /* snd_card_asihpi_capture.fifo_size = 0; */ | ||
1192 | snd_card_asihpi_capture.channels_max = card->in_max_chans; | 1189 | snd_card_asihpi_capture.channels_max = card->in_max_chans; |
1193 | snd_card_asihpi_capture.channels_min = card->in_min_chans; | 1190 | snd_card_asihpi_capture.channels_min = card->in_min_chans; |
1194 | snd_card_asihpi_capture_format(card, dpcm->h_stream, | 1191 | snd_card_asihpi_capture.formats = |
1195 | &snd_card_asihpi_capture); | 1192 | snd_card_asihpi_capture_formats(card, dpcm->h_stream); |
1196 | snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); | 1193 | snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); |
1197 | snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED | | 1194 | snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED | |
1198 | SNDRV_PCM_INFO_MMAP | | 1195 | SNDRV_PCM_INFO_MMAP | |