2 * miscellaneous helper functions
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
8 #include <linux/delay.h>
9 #include <linux/device.h>
10 #include <linux/firewire.h>
11 #include <linux/module.h>
14 #define ERROR_RETRY_DELAY_MS 20
17 * snd_fw_transaction - send a request and wait for its completion
18 * @unit: the driver's unit on the target device
19 * @tcode: the transaction code
20 * @offset: the address in the target's address space
21 * @buffer: input/output data
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
27 * Submits an asynchronous request to the target device, and waits for the
28 * response. The node ID and the current generation are derived from @unit.
29 * On a bus reset or an error, the transaction is retried a few times.
30 * Returns zero on success, or a negative error code.
32 int snd_fw_transaction(struct fw_unit
*unit
, int tcode
,
33 u64 offset
, void *buffer
, size_t length
,
36 struct fw_device
*device
= fw_parent_device(unit
);
37 int generation
, rcode
, tries
= 0;
39 generation
= flags
& FW_GENERATION_MASK
;
41 if (!(flags
& FW_FIXED_GENERATION
)) {
42 generation
= device
->generation
;
43 smp_rmb(); /* node_id vs. generation */
45 rcode
= fw_run_transaction(device
->card
, tcode
,
46 device
->node_id
, generation
,
47 device
->max_speed
, offset
,
50 if (rcode
== RCODE_COMPLETE
)
53 if (rcode
== RCODE_GENERATION
&& (flags
& FW_FIXED_GENERATION
))
56 if (rcode_is_permanent_error(rcode
) || ++tries
>= 3) {
57 if (!(flags
& FW_QUIET
))
58 dev_err(&unit
->device
,
59 "transaction failed: %s\n",
60 fw_rcode_string(rcode
));
64 msleep(ERROR_RETRY_DELAY_MS
);
67 EXPORT_SYMBOL(snd_fw_transaction
);
69 MODULE_DESCRIPTION("FireWire audio helper functions");
70 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
71 MODULE_LICENSE("GPL v2");