summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/firewire/amdtp.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c
index c69c3ab90acc..c26dda7f41e6 100644
--- a/sound/firewire/amdtp.c
+++ b/sound/firewire/amdtp.c
@@ -647,16 +647,13 @@ static inline int queue_in_packet(struct amdtp_stream *s)
amdtp_stream_get_max_payload(s), false);
}
-static void handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
- unsigned int syt)
+static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
+ unsigned int syt)
{
__be32 *buffer;
unsigned int payload_length;
struct snd_pcm_substream *pcm;
- if (s->packet_index < 0)
- return;
-
buffer = s->buffer.packets[s->packet_index].buffer;
buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
(s->data_block_quadlets << AMDTP_DBS_SHIFT) |
@@ -676,14 +673,14 @@ static void handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
payload_length = 8 + data_blocks * 4 * s->data_block_quadlets;
- if (queue_out_packet(s, payload_length, false) < 0) {
- s->packet_index = -1;
- amdtp_stream_pcm_abort(s);
- return;
- }
+ if (queue_out_packet(s, payload_length, false) < 0)
+ return -EIO;
if (pcm)
update_pcm_pointers(s, pcm, data_blocks);
+
+ /* No need to return the number of handled data blocks. */
+ return 0;
}
static int handle_in_packet(struct amdtp_stream *s,
@@ -795,6 +792,9 @@ static void out_stream_callback(struct fw_iso_context *context, u32 cycle,
unsigned int i, syt, packets = header_length / 4;
unsigned int data_blocks;
+ if (s->packet_index < 0)
+ return;
+
/*
* Compute the cycle of the last queued packet.
* (We need only the four lowest bits for the SYT, so we can ignore
@@ -806,8 +806,13 @@ static void out_stream_callback(struct fw_iso_context *context, u32 cycle,
syt = calculate_syt(s, ++cycle);
data_blocks = calculate_data_blocks(s, syt);
- handle_out_packet(s, data_blocks, syt);
+ if (handle_out_packet(s, data_blocks, syt) < 0) {
+ s->packet_index = -1;
+ amdtp_stream_pcm_abort(s);
+ return;
+ }
}
+
fw_iso_context_queue_flush(s->context);
}
@@ -821,6 +826,9 @@ static void in_stream_callback(struct fw_iso_context *context, u32 cycle,
unsigned int data_blocks;
__be32 *buffer, *headers = header;
+ if (s->packet_index < 0)
+ return;
+
/* The number of packets in buffer */
packets = header_length / IN_PACKET_HEADER_SIZE;
@@ -828,9 +836,6 @@ static void in_stream_callback(struct fw_iso_context *context, u32 cycle,
max_payload_quadlets = amdtp_stream_get_max_payload(s) / 4;
for (p = 0; p < packets; p++) {
- if (s->packet_index < 0)
- break;
-
buffer = s->buffer.packets[s->packet_index].buffer;
/* The number of quadlets in this packet */
@@ -853,7 +858,11 @@ static void in_stream_callback(struct fw_iso_context *context, u32 cycle,
/* Process sync slave stream */
if (s->sync_slave && s->sync_slave->callbacked) {
syt = be32_to_cpu(buffer[1]) & CIP_SYT_MASK;
- handle_out_packet(s->sync_slave, data_blocks, syt);
+ if (handle_out_packet(s->sync_slave,
+ data_blocks, syt) < 0) {
+ s->packet_index = -1;
+ break;
+ }
}
}