amdtp_stream_get_max_payload(s), false);
 }
 
+unsigned int process_rx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
+                                   unsigned int data_blocks, unsigned int *syt)
+{
+       struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
+       unsigned int pcm_frames;
+
+       if (pcm) {
+               s->transfer_samples(s, pcm, buffer, data_blocks);
+               pcm_frames = data_blocks * s->frame_multiplier;
+       } else {
+               write_pcm_silence(s, buffer, data_blocks);
+               pcm_frames = 0;
+       }
+
+       if (s->midi_ports)
+               write_midi_messages(s, buffer, data_blocks);
+
+       return pcm_frames;
+}
+
 static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
                             unsigned int syt)
 {
        __be32 *buffer;
        unsigned int payload_length;
+       unsigned int pcm_frames;
        struct snd_pcm_substream *pcm;
 
        buffer = s->buffer.packets[s->packet_index].buffer;
+       pcm_frames = process_rx_data_blocks(s, buffer + 2, data_blocks, &syt);
+
        buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
                                (s->data_block_quadlets << CIP_DBS_SHIFT) |
                                s->data_block_counter);
        buffer[1] = cpu_to_be32(CIP_EOH | CIP_FMT_AM | AMDTP_FDF_AM824 |
                                (s->sfc << CIP_FDF_SHIFT) | syt);
-       buffer += 2;
-
-       pcm = ACCESS_ONCE(s->pcm);
-       if (pcm)
-               s->transfer_samples(s, pcm, buffer, data_blocks);
-       else
-               write_pcm_silence(s, buffer, data_blocks);
-       if (s->midi_ports)
-               write_midi_messages(s, buffer, data_blocks);
 
        s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
 
        if (queue_out_packet(s, payload_length, false) < 0)
                return -EIO;
 
-       if (pcm)
-               update_pcm_pointers(s, pcm, data_blocks * s->frame_multiplier);
+       pcm = ACCESS_ONCE(s->pcm);
+       if (pcm && pcm_frames > 0)
+               update_pcm_pointers(s, pcm, pcm_frames);
 
        /* No need to return the number of handled data blocks. */
        return 0;
 }
 
+unsigned int process_tx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
+                                   unsigned int data_blocks, unsigned int *syt)
+{
+       struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
+       unsigned int pcm_frames;
+
+       if (pcm) {
+               s->transfer_samples(s, pcm, buffer, data_blocks);
+               pcm_frames = data_blocks * s->frame_multiplier;
+       } else {
+               pcm_frames = 0;
+       }
+
+       if (s->midi_ports)
+               read_midi_messages(s, buffer, data_blocks);
+
+       return pcm_frames;
+}
+
 static int handle_in_packet(struct amdtp_stream *s,
                            unsigned int payload_quadlets, __be32 *buffer,
-                           unsigned int *data_blocks)
+                           unsigned int *data_blocks, unsigned int syt)
 {
        u32 cip_header[2];
        unsigned int data_block_quadlets, data_block_counter, dbc_interval;
-       struct snd_pcm_substream *pcm = NULL;
+       struct snd_pcm_substream *pcm;
+       unsigned int pcm_frames;
        bool lost;
 
        cip_header[0] = be32_to_cpu(buffer[0]);
                                "Invalid CIP header for AMDTP: %08X:%08X\n",
                                cip_header[0], cip_header[1]);
                *data_blocks = 0;
+               pcm_frames = 0;
                goto end;
        }
 
                return -EIO;
        }
 
-       if (*data_blocks > 0) {
-               buffer += 2;
-
-               pcm = ACCESS_ONCE(s->pcm);
-               if (pcm)
-                       s->transfer_samples(s, pcm, buffer, *data_blocks);
-
-               if (s->midi_ports)
-                       read_midi_messages(s, buffer, *data_blocks);
-       }
+       pcm_frames = process_tx_data_blocks(s, buffer + 2, *data_blocks, &syt);
 
        if (s->flags & CIP_DBC_IS_END_EVENT)
                s->data_block_counter = data_block_counter;
        if (queue_in_packet(s) < 0)
                return -EIO;
 
-       if (pcm)
-               update_pcm_pointers(s, pcm, *data_blocks * s->frame_multiplier);
+       pcm = ACCESS_ONCE(s->pcm);
+       if (pcm && pcm_frames > 0)
+               update_pcm_pointers(s, pcm, pcm_frames);
 
        return 0;
 }
                        break;
                }
 
+               syt = be32_to_cpu(buffer[1]) & CIP_SYT_MASK;
                if (handle_in_packet(s, payload_quadlets, buffer,
-                                                       &data_blocks) < 0) {
+                                               &data_blocks, syt) < 0) {
                        s->packet_index = -1;
                        break;
                }
 
                /* Process sync slave stream */
                if (s->sync_slave && s->sync_slave->callbacked) {
-                       syt = be32_to_cpu(buffer[1]) & CIP_SYT_MASK;
                        if (handle_out_packet(s->sync_slave,
                                              data_blocks, syt) < 0) {
                                s->packet_index = -1;