0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/delay.h>
0009 #include <linux/device.h>
0010 #include <linux/firewire.h>
0011 #include <linux/module.h>
0012 #include <linux/slab.h>
0013 #include "lib.h"
0014
0015 #define ERROR_RETRY_DELAY_MS 20
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 int snd_fw_transaction(struct fw_unit *unit, int tcode,
0034 u64 offset, void *buffer, size_t length,
0035 unsigned int flags)
0036 {
0037 struct fw_device *device = fw_parent_device(unit);
0038 int generation, rcode, tries = 0;
0039
0040 generation = flags & FW_GENERATION_MASK;
0041 for (;;) {
0042 if (!(flags & FW_FIXED_GENERATION)) {
0043 generation = device->generation;
0044 smp_rmb();
0045 }
0046 rcode = fw_run_transaction(device->card, tcode,
0047 device->node_id, generation,
0048 device->max_speed, offset,
0049 buffer, length);
0050
0051 if (rcode == RCODE_COMPLETE)
0052 return 0;
0053
0054 if (rcode == RCODE_GENERATION && (flags & FW_FIXED_GENERATION))
0055 return -EAGAIN;
0056
0057 if (rcode_is_permanent_error(rcode) || ++tries >= 3) {
0058 if (!(flags & FW_QUIET))
0059 dev_err(&unit->device,
0060 "transaction failed: %s\n",
0061 fw_rcode_string(rcode));
0062 return -EIO;
0063 }
0064
0065 msleep(ERROR_RETRY_DELAY_MS);
0066 }
0067 }
0068 EXPORT_SYMBOL(snd_fw_transaction);
0069
0070 MODULE_DESCRIPTION("FireWire audio helper functions");
0071 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
0072 MODULE_LICENSE("GPL v2");