diff options
| author | Meizu OpenSource <patchwork@meizu.com> | 2016-08-15 10:19:42 +0800 |
|---|---|---|
| committer | Meizu OpenSource <patchwork@meizu.com> | 2016-08-15 10:19:42 +0800 |
| commit | d2e1446d81725c351dc73a03b397ce043fb18452 (patch) | |
| tree | 4dbc616b7f92aea39cd697a9084205ddb805e344 /sound/firewire/lib.c | |
first commit
Diffstat (limited to 'sound/firewire/lib.c')
| -rw-r--r-- | sound/firewire/lib.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c new file mode 100644 index 000000000..14eb41498 --- /dev/null +++ b/sound/firewire/lib.c @@ -0,0 +1,59 @@ +/* + * miscellaneous helper functions + * + * Copyright (c) Clemens Ladisch <clemens@ladisch.de> + * Licensed under the terms of the GNU General Public License, version 2. + */ + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/firewire.h> +#include <linux/module.h> +#include "lib.h" + +#define ERROR_RETRY_DELAY_MS 5 + +/** + * snd_fw_transaction - send a request and wait for its completion + * @unit: the driver's unit on the target device + * @tcode: the transaction code + * @offset: the address in the target's address space + * @buffer: input/output data + * @length: length of @buffer + * + * Submits an asynchronous request to the target device, and waits for the + * response. The node ID and the current generation are derived from @unit. + * On a bus reset or an error, the transaction is retried a few times. + * Returns zero on success, or a negative error code. + */ +int snd_fw_transaction(struct fw_unit *unit, int tcode, + u64 offset, void *buffer, size_t length) +{ + struct fw_device *device = fw_parent_device(unit); + int generation, rcode, tries = 0; + + for (;;) { + generation = device->generation; + smp_rmb(); /* node_id vs. generation */ + rcode = fw_run_transaction(device->card, tcode, + device->node_id, generation, + device->max_speed, offset, + buffer, length); + + if (rcode == RCODE_COMPLETE) + return 0; + + if (rcode_is_permanent_error(rcode) || ++tries >= 3) { + dev_err(&unit->device, "transaction failed: %s\n", + fw_rcode_string(rcode)); + return -EIO; + } + + msleep(ERROR_RETRY_DELAY_MS); + } +} +EXPORT_SYMBOL(snd_fw_transaction); + +MODULE_DESCRIPTION("FireWire audio helper functions"); +MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); +MODULE_LICENSE("GPL v2"); |
