diff options
Diffstat (limited to 'sound/firewire/lib.c')
-rw-r--r-- | sound/firewire/lib.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c index 14eb41498372..7409edba9f06 100644 --- a/sound/firewire/lib.c +++ b/sound/firewire/lib.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include "lib.h" | 12 | #include "lib.h" |
13 | 13 | ||
14 | #define ERROR_RETRY_DELAY_MS 5 | 14 | #define ERROR_RETRY_DELAY_MS 20 |
15 | 15 | ||
16 | /** | 16 | /** |
17 | * snd_fw_transaction - send a request and wait for its completion | 17 | * snd_fw_transaction - send a request and wait for its completion |
@@ -20,6 +20,9 @@ | |||
20 | * @offset: the address in the target's address space | 20 | * @offset: the address in the target's address space |
21 | * @buffer: input/output data | 21 | * @buffer: input/output data |
22 | * @length: length of @buffer | 22 | * @length: length of @buffer |
23 | * @flags: use %FW_FIXED_GENERATION and add the generation value to attempt the | ||
24 | * request only in that generation; use %FW_QUIET to suppress error | ||
25 | * messages | ||
23 | * | 26 | * |
24 | * Submits an asynchronous request to the target device, and waits for the | 27 | * Submits an asynchronous request to the target device, and waits for the |
25 | * response. The node ID and the current generation are derived from @unit. | 28 | * response. The node ID and the current generation are derived from @unit. |
@@ -27,14 +30,18 @@ | |||
27 | * Returns zero on success, or a negative error code. | 30 | * Returns zero on success, or a negative error code. |
28 | */ | 31 | */ |
29 | int snd_fw_transaction(struct fw_unit *unit, int tcode, | 32 | int snd_fw_transaction(struct fw_unit *unit, int tcode, |
30 | u64 offset, void *buffer, size_t length) | 33 | u64 offset, void *buffer, size_t length, |
34 | unsigned int flags) | ||
31 | { | 35 | { |
32 | struct fw_device *device = fw_parent_device(unit); | 36 | struct fw_device *device = fw_parent_device(unit); |
33 | int generation, rcode, tries = 0; | 37 | int generation, rcode, tries = 0; |
34 | 38 | ||
39 | generation = flags & FW_GENERATION_MASK; | ||
35 | for (;;) { | 40 | for (;;) { |
36 | generation = device->generation; | 41 | if (!(flags & FW_FIXED_GENERATION)) { |
37 | smp_rmb(); /* node_id vs. generation */ | 42 | generation = device->generation; |
43 | smp_rmb(); /* node_id vs. generation */ | ||
44 | } | ||
38 | rcode = fw_run_transaction(device->card, tcode, | 45 | rcode = fw_run_transaction(device->card, tcode, |
39 | device->node_id, generation, | 46 | device->node_id, generation, |
40 | device->max_speed, offset, | 47 | device->max_speed, offset, |
@@ -43,9 +50,14 @@ int snd_fw_transaction(struct fw_unit *unit, int tcode, | |||
43 | if (rcode == RCODE_COMPLETE) | 50 | if (rcode == RCODE_COMPLETE) |
44 | return 0; | 51 | return 0; |
45 | 52 | ||
53 | if (rcode == RCODE_GENERATION && (flags & FW_FIXED_GENERATION)) | ||
54 | return -EAGAIN; | ||
55 | |||
46 | if (rcode_is_permanent_error(rcode) || ++tries >= 3) { | 56 | if (rcode_is_permanent_error(rcode) || ++tries >= 3) { |
47 | dev_err(&unit->device, "transaction failed: %s\n", | 57 | if (!(flags & FW_QUIET)) |
48 | fw_rcode_string(rcode)); | 58 | dev_err(&unit->device, |
59 | "transaction failed: %s\n", | ||
60 | fw_rcode_string(rcode)); | ||
49 | return -EIO; | 61 | return -EIO; |
50 | } | 62 | } |
51 | 63 | ||