0001
0002
0003
0004
0005
0006
0007
0008 #include "ff.h"
0009
0010 static void finish_transmit_midi_msg(struct snd_ff *ff, unsigned int port,
0011 int rcode)
0012 {
0013 struct snd_rawmidi_substream *substream =
0014 READ_ONCE(ff->rx_midi_substreams[port]);
0015
0016 if (rcode_is_permanent_error(rcode)) {
0017 ff->rx_midi_error[port] = true;
0018 return;
0019 }
0020
0021 if (rcode != RCODE_COMPLETE) {
0022
0023 ff->next_ktime[port] = 0;
0024 schedule_work(&ff->rx_midi_work[port]);
0025 return;
0026 }
0027
0028 snd_rawmidi_transmit_ack(substream, ff->rx_bytes[port]);
0029 ff->rx_bytes[port] = 0;
0030
0031 if (!snd_rawmidi_transmit_empty(substream))
0032 schedule_work(&ff->rx_midi_work[port]);
0033 }
0034
0035 static void finish_transmit_midi0_msg(struct fw_card *card, int rcode,
0036 void *data, size_t length,
0037 void *callback_data)
0038 {
0039 struct snd_ff *ff =
0040 container_of(callback_data, struct snd_ff, transactions[0]);
0041 finish_transmit_midi_msg(ff, 0, rcode);
0042 }
0043
0044 static void finish_transmit_midi1_msg(struct fw_card *card, int rcode,
0045 void *data, size_t length,
0046 void *callback_data)
0047 {
0048 struct snd_ff *ff =
0049 container_of(callback_data, struct snd_ff, transactions[1]);
0050 finish_transmit_midi_msg(ff, 1, rcode);
0051 }
0052
0053 static void transmit_midi_msg(struct snd_ff *ff, unsigned int port)
0054 {
0055 struct snd_rawmidi_substream *substream =
0056 READ_ONCE(ff->rx_midi_substreams[port]);
0057 int quad_count;
0058
0059 struct fw_device *fw_dev = fw_parent_device(ff->unit);
0060 unsigned long long addr;
0061 int generation;
0062 fw_transaction_callback_t callback;
0063 int tcode;
0064
0065 if (substream == NULL || snd_rawmidi_transmit_empty(substream))
0066 return;
0067
0068 if (ff->rx_bytes[port] > 0 || ff->rx_midi_error[port])
0069 return;
0070
0071
0072 if (ktime_after(ff->next_ktime[port], ktime_get())) {
0073 schedule_work(&ff->rx_midi_work[port]);
0074 return;
0075 }
0076
0077 quad_count = ff->spec->protocol->fill_midi_msg(ff, substream, port);
0078 if (quad_count <= 0)
0079 return;
0080
0081 if (port == 0) {
0082 addr = ff->spec->midi_rx_addrs[0];
0083 callback = finish_transmit_midi0_msg;
0084 } else {
0085 addr = ff->spec->midi_rx_addrs[1];
0086 callback = finish_transmit_midi1_msg;
0087 }
0088
0089
0090 ff->next_ktime[port] = ktime_add_ns(ktime_get(),
0091 ff->rx_bytes[port] * 8 * (NSEC_PER_SEC / 31250));
0092
0093 if (quad_count == 1)
0094 tcode = TCODE_WRITE_QUADLET_REQUEST;
0095 else
0096 tcode = TCODE_WRITE_BLOCK_REQUEST;
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 generation = fw_dev->generation;
0107 smp_rmb();
0108 fw_send_request(fw_dev->card, &ff->transactions[port], tcode,
0109 fw_dev->node_id, generation, fw_dev->max_speed,
0110 addr, &ff->msg_buf[port], quad_count * 4,
0111 callback, &ff->transactions[port]);
0112 }
0113
0114 static void transmit_midi0_msg(struct work_struct *work)
0115 {
0116 struct snd_ff *ff = container_of(work, struct snd_ff, rx_midi_work[0]);
0117
0118 transmit_midi_msg(ff, 0);
0119 }
0120
0121 static void transmit_midi1_msg(struct work_struct *work)
0122 {
0123 struct snd_ff *ff = container_of(work, struct snd_ff, rx_midi_work[1]);
0124
0125 transmit_midi_msg(ff, 1);
0126 }
0127
0128 static void handle_midi_msg(struct fw_card *card, struct fw_request *request,
0129 int tcode, int destination, int source,
0130 int generation, unsigned long long offset,
0131 void *data, size_t length, void *callback_data)
0132 {
0133 struct snd_ff *ff = callback_data;
0134 __le32 *buf = data;
0135
0136 fw_send_response(card, request, RCODE_COMPLETE);
0137
0138 offset -= ff->async_handler.offset;
0139 ff->spec->protocol->handle_midi_msg(ff, (unsigned int)offset, buf,
0140 length);
0141 }
0142
0143 static int allocate_own_address(struct snd_ff *ff, int i)
0144 {
0145 struct fw_address_region midi_msg_region;
0146 int err;
0147
0148 ff->async_handler.length = ff->spec->midi_addr_range;
0149 ff->async_handler.address_callback = handle_midi_msg;
0150 ff->async_handler.callback_data = ff;
0151
0152 midi_msg_region.start = 0x000100000000ull * i;
0153 midi_msg_region.end = midi_msg_region.start + ff->async_handler.length;
0154
0155 err = fw_core_add_address_handler(&ff->async_handler, &midi_msg_region);
0156 if (err >= 0) {
0157
0158 if (ff->async_handler.offset & 0x0000ffffffff) {
0159 fw_core_remove_address_handler(&ff->async_handler);
0160 err = -EAGAIN;
0161 }
0162 }
0163
0164 return err;
0165 }
0166
0167
0168
0169
0170
0171
0172
0173
0174 int snd_ff_transaction_reregister(struct snd_ff *ff)
0175 {
0176 struct fw_card *fw_card = fw_parent_device(ff->unit)->card;
0177 u32 addr;
0178 __le32 reg;
0179
0180
0181
0182
0183
0184 addr = (fw_card->node_id << 16) | (ff->async_handler.offset >> 32);
0185 reg = cpu_to_le32(addr);
0186 return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
0187 ff->spec->midi_high_addr,
0188 ®, sizeof(reg), 0);
0189 }
0190
0191 int snd_ff_transaction_register(struct snd_ff *ff)
0192 {
0193 int i, err;
0194
0195
0196
0197
0198
0199 for (i = 0; i < 0xffff; i++) {
0200 err = allocate_own_address(ff, i);
0201 if (err != -EBUSY && err != -EAGAIN)
0202 break;
0203 }
0204 if (err < 0)
0205 return err;
0206
0207 err = snd_ff_transaction_reregister(ff);
0208 if (err < 0)
0209 return err;
0210
0211 INIT_WORK(&ff->rx_midi_work[0], transmit_midi0_msg);
0212 INIT_WORK(&ff->rx_midi_work[1], transmit_midi1_msg);
0213
0214 return 0;
0215 }
0216
0217 void snd_ff_transaction_unregister(struct snd_ff *ff)
0218 {
0219 __le32 reg;
0220
0221 if (ff->async_handler.callback_data == NULL)
0222 return;
0223 ff->async_handler.callback_data = NULL;
0224
0225
0226 reg = cpu_to_le32(0x00000000);
0227 snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
0228 ff->spec->midi_high_addr,
0229 ®, sizeof(reg), 0);
0230
0231 fw_core_remove_address_handler(&ff->async_handler);
0232 }