]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - sound/firewire/amdtp-am824.c
Merge tag 'for-5.4/post-2019-09-24' of git://git.kernel.dk/linux-block
[linux.git] / sound / firewire / amdtp-am824.c
index fd5d6b8ac557aa57035ddd66b0a83ba7dc7ea8bd..67d735e9a6a4c2564d12613b25c2078d66c446bd 100644 (file)
@@ -146,19 +146,24 @@ void amdtp_am824_set_midi_position(struct amdtp_stream *s,
 }
 EXPORT_SYMBOL_GPL(amdtp_am824_set_midi_position);
 
-static void write_pcm_s32(struct amdtp_stream *s,
-                         struct snd_pcm_substream *pcm,
-                         __be32 *buffer, unsigned int frames)
+static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
+                         __be32 *buffer, unsigned int frames,
+                         unsigned int pcm_frames)
 {
        struct amdtp_am824 *p = s->protocol;
+       unsigned int channels = p->pcm_channels;
        struct snd_pcm_runtime *runtime = pcm->runtime;
-       unsigned int channels, remaining_frames, i, c;
+       unsigned int pcm_buffer_pointer;
+       int remaining_frames;
        const u32 *src;
+       int i, c;
+
+       pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
+       pcm_buffer_pointer %= runtime->buffer_size;
 
-       channels = p->pcm_channels;
        src = (void *)runtime->dma_area +
-                       frames_to_bytes(runtime, s->pcm_buffer_pointer);
-       remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
+                               frames_to_bytes(runtime, pcm_buffer_pointer);
+       remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
 
        for (i = 0; i < frames; ++i) {
                for (c = 0; c < channels; ++c) {
@@ -172,19 +177,24 @@ static void write_pcm_s32(struct amdtp_stream *s,
        }
 }
 
-static void read_pcm_s32(struct amdtp_stream *s,
-                        struct snd_pcm_substream *pcm,
-                        __be32 *buffer, unsigned int frames)
+static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
+                        __be32 *buffer, unsigned int frames,
+                        unsigned int pcm_frames)
 {
        struct amdtp_am824 *p = s->protocol;
+       unsigned int channels = p->pcm_channels;
        struct snd_pcm_runtime *runtime = pcm->runtime;
-       unsigned int channels, remaining_frames, i, c;
+       unsigned int pcm_buffer_pointer;
+       int remaining_frames;
        u32 *dst;
+       int i, c;
+
+       pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
+       pcm_buffer_pointer %= runtime->buffer_size;
 
-       channels = p->pcm_channels;
        dst  = (void *)runtime->dma_area +
-                       frames_to_bytes(runtime, s->pcm_buffer_pointer);
-       remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
+                               frames_to_bytes(runtime, pcm_buffer_pointer);
+       remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
 
        for (i = 0; i < frames; ++i) {
                for (c = 0; c < channels; ++c) {
@@ -284,7 +294,7 @@ static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port)
 }
 
 static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
-                               unsigned int frames)
+                       unsigned int frames, unsigned int data_block_counter)
 {
        struct amdtp_am824 *p = s->protocol;
        unsigned int f, port;
@@ -293,7 +303,7 @@ static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
        for (f = 0; f < frames; f++) {
                b = (u8 *)&buffer[p->midi_position];
 
-               port = (s->data_block_counter + f) % 8;
+               port = (data_block_counter + f) % 8;
                if (f < MAX_MIDI_RX_BLOCKS &&
                    midi_ratelimit_per_packet(s, port) &&
                    p->midi[port] != NULL &&
@@ -311,16 +321,20 @@ static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
        }
 }
 
-static void read_midi_messages(struct amdtp_stream *s,
-                              __be32 *buffer, unsigned int frames)
+static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
+                       unsigned int frames, unsigned int data_block_counter)
 {
        struct amdtp_am824 *p = s->protocol;
-       unsigned int f, port;
        int len;
        u8 *b;
+       int f;
 
        for (f = 0; f < frames; f++) {
-               port = (8 - s->ctx_data.tx.first_dbc + s->data_block_counter + f) % 8;
+               unsigned int port = f;
+
+               if (!(s->flags & CIP_UNALIGHED_DBC))
+                       port += data_block_counter;
+               port %= 8;
                b = (u8 *)&buffer[p->midi_position];
 
                len = b[0] - 0x80;
@@ -331,43 +345,60 @@ static void read_midi_messages(struct amdtp_stream *s,
        }
 }
 
-static unsigned int process_rx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
-                                          unsigned int data_blocks, unsigned int *syt)
+static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
+                                           const struct pkt_desc *descs,
+                                           unsigned int packets,
+                                           struct snd_pcm_substream *pcm)
 {
        struct amdtp_am824 *p = s->protocol;
-       struct snd_pcm_substream *pcm = READ_ONCE(s->pcm);
-       unsigned int pcm_frames;
-
-       if (pcm) {
-               write_pcm_s32(s, pcm, buffer, data_blocks);
-               pcm_frames = data_blocks * p->frame_multiplier;
-       } else {
-               write_pcm_silence(s, buffer, data_blocks);
-               pcm_frames = 0;
-       }
+       unsigned int pcm_frames = 0;
+       int i;
 
-       if (p->midi_ports)
-               write_midi_messages(s, buffer, data_blocks);
+       for (i = 0; i < packets; ++i) {
+               const struct pkt_desc *desc = descs + i;
+               __be32 *buf = desc->ctx_payload;
+               unsigned int data_blocks = desc->data_blocks;
+
+               if (pcm) {
+                       write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
+                       pcm_frames += data_blocks * p->frame_multiplier;
+               } else {
+                       write_pcm_silence(s, buf, data_blocks);
+               }
+
+               if (p->midi_ports) {
+                       write_midi_messages(s, buf, data_blocks,
+                                           desc->data_block_counter);
+               }
+       }
 
        return pcm_frames;
 }
 
-static unsigned int process_tx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
-                                          unsigned int data_blocks, unsigned int *syt)
+static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
+                                           const struct pkt_desc *descs,
+                                           unsigned int packets,
+                                           struct snd_pcm_substream *pcm)
 {
        struct amdtp_am824 *p = s->protocol;
-       struct snd_pcm_substream *pcm = READ_ONCE(s->pcm);
-       unsigned int pcm_frames;
-
-       if (pcm) {
-               read_pcm_s32(s, pcm, buffer, data_blocks);
-               pcm_frames = data_blocks * p->frame_multiplier;
-       } else {
-               pcm_frames = 0;
-       }
+       unsigned int pcm_frames = 0;
+       int i;
+
+       for (i = 0; i < packets; ++i) {
+               const struct pkt_desc *desc = descs + i;
+               __be32 *buf = desc->ctx_payload;
+               unsigned int data_blocks = desc->data_blocks;
 
-       if (p->midi_ports)
-               read_midi_messages(s, buffer, data_blocks);
+               if (pcm) {
+                       read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
+                       pcm_frames += data_blocks * p->frame_multiplier;
+               }
+
+               if (p->midi_ports) {
+                       read_midi_messages(s, buf, data_blocks,
+                                          desc->data_block_counter);
+               }
+       }
 
        return pcm_frames;
 }
@@ -383,15 +414,14 @@ static unsigned int process_tx_data_blocks(struct amdtp_stream *s, __be32 *buffe
 int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
                     enum amdtp_stream_direction dir, enum cip_flags flags)
 {
-       amdtp_stream_process_data_blocks_t process_data_blocks;
+       amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
 
        if (dir == AMDTP_IN_STREAM)
-               process_data_blocks = process_tx_data_blocks;
+               process_ctx_payloads = process_ir_ctx_payloads;
        else
-               process_data_blocks = process_rx_data_blocks;
+               process_ctx_payloads = process_it_ctx_payloads;
 
        return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
-                                process_data_blocks,
-                                sizeof(struct amdtp_am824));
+                       process_ctx_payloads, sizeof(struct amdtp_am824));
 }
 EXPORT_SYMBOL_GPL(amdtp_am824_init);