aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire/isight.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2011-09-04 16:17:38 -0400
committerClemens Ladisch <clemens@ladisch.de>2013-10-20 16:07:57 -0400
commit1b70485f135a39d5f2d8c392a16817456fa3a5cd (patch)
treecf1b9b833619374c3169c368890652d53594b43d /sound/firewire/isight.c
parenta644a9473f7f9519e2fe519136959dd0e671572a (diff)
ALSA: firewire: extend snd_fw_transaction()
Add a flag to snd_fw_transaction() to allow it to abort when a bus reset happens. This removes most of the duplicated error handling loops that were required around calls to the low-level fw_run_transaction(). Also add a flag to suppress error messages; errors are expected when we attempt to clean up after the device was unplugged. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'sound/firewire/isight.c')
-rw-r--r--sound/firewire/isight.c43
1 files changed, 20 insertions, 23 deletions
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
index 58a5afefdc69..fd42e6b315e6 100644
--- a/sound/firewire/isight.c
+++ b/sound/firewire/isight.c
@@ -217,7 +217,7 @@ static void isight_packet(struct fw_iso_context *context, u32 cycle,
217 217
218static int isight_connect(struct isight *isight) 218static int isight_connect(struct isight *isight)
219{ 219{
220 int ch, err, rcode, errors = 0; 220 int ch, err;
221 __be32 value; 221 __be32 value;
222 222
223retry_after_bus_reset: 223retry_after_bus_reset:
@@ -230,27 +230,19 @@ retry_after_bus_reset:
230 } 230 }
231 231
232 value = cpu_to_be32(ch | (isight->device->max_speed << SPEED_SHIFT)); 232 value = cpu_to_be32(ch | (isight->device->max_speed << SPEED_SHIFT));
233 for (;;) { 233 err = snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST,
234 rcode = fw_run_transaction( 234 isight->audio_base + REG_ISO_TX_CONFIG,
235 isight->device->card, 235 &value, 4, FW_FIXED_GENERATION |
236 TCODE_WRITE_QUADLET_REQUEST, 236 isight->resources.generation);
237 isight->device->node_id, 237 if (err == -EAGAIN) {
238 isight->resources.generation, 238 fw_iso_resources_free(&isight->resources);
239 isight->device->max_speed, 239 goto retry_after_bus_reset;
240 isight->audio_base + REG_ISO_TX_CONFIG, 240 } else if (err < 0) {
241 &value, 4); 241 goto err_resources;
242 if (rcode == RCODE_COMPLETE) {
243 return 0;
244 } else if (rcode == RCODE_GENERATION) {
245 fw_iso_resources_free(&isight->resources);
246 goto retry_after_bus_reset;
247 } else if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
248 err = -EIO;
249 goto err_resources;
250 }
251 msleep(5);
252 } 242 }
253 243
244 return 0;
245
254err_resources: 246err_resources:
255 fw_iso_resources_free(&isight->resources); 247 fw_iso_resources_free(&isight->resources);
256error: 248error:
@@ -315,17 +307,19 @@ static int isight_hw_params(struct snd_pcm_substream *substream,
315static int reg_read(struct isight *isight, int offset, __be32 *value) 307static int reg_read(struct isight *isight, int offset, __be32 *value)
316{ 308{
317 return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST, 309 return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST,
318 isight->audio_base + offset, value, 4); 310 isight->audio_base + offset, value, 4, 0);
319} 311}
320 312
321static int reg_write(struct isight *isight, int offset, __be32 value) 313static int reg_write(struct isight *isight, int offset, __be32 value)
322{ 314{
323 return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST, 315 return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST,
324 isight->audio_base + offset, &value, 4); 316 isight->audio_base + offset, &value, 4, 0);
325} 317}
326 318
327static void isight_stop_streaming(struct isight *isight) 319static void isight_stop_streaming(struct isight *isight)
328{ 320{
321 __be32 value;
322
329 if (!isight->context) 323 if (!isight->context)
330 return; 324 return;
331 325
@@ -333,7 +327,10 @@ static void isight_stop_streaming(struct isight *isight)
333 fw_iso_context_destroy(isight->context); 327 fw_iso_context_destroy(isight->context);
334 isight->context = NULL; 328 isight->context = NULL;
335 fw_iso_resources_free(&isight->resources); 329 fw_iso_resources_free(&isight->resources);
336 reg_write(isight, REG_AUDIO_ENABLE, 0); 330 value = 0;
331 snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST,
332 isight->audio_base + REG_AUDIO_ENABLE,
333 &value, 4, FW_QUIET);
337} 334}
338 335
339static int isight_hw_free(struct snd_pcm_substream *substream) 336static int isight_hw_free(struct snd_pcm_substream *substream)