summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2019-05-22 23:17:04 +0900
committerTakashi Iwai <tiwai@suse.de>2019-05-23 12:19:39 +0200
commit6f3c07d03c6bc84d2da6ce0e24e9a1feece42c47 (patch)
tree06c0b294ef92c96ca78af620c4cfd063680ae80e /sound
parent07ea238ca139aef1820802409a6a7bdd45e38caa (diff)
ALSA: firewire-lib: calculate the length of packet payload in packet handler
In current packet handler, the length of payload is given as an argument of callback function, however this value is just required to process payload of transferred isoc packet, thus just for IR context. This commit replaces the argument for payload of packet with the argument of context header. As a result, the length of payload is computed in packet handler for IR context. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/firewire/amdtp-stream.c49
-rw-r--r--sound/firewire/amdtp-stream.h5
2 files changed, 25 insertions, 29 deletions
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index 020edf2b1726..4584525a7f30 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -474,14 +474,14 @@ static inline int queue_in_packet(struct amdtp_stream *s)
return queue_packet(s, s->ctx_data.tx.max_payload_length);
}
-static int handle_out_packet(struct amdtp_stream *s,
- unsigned int payload_length, unsigned int cycle,
- unsigned int index)
+static int handle_out_packet(struct amdtp_stream *s, unsigned int cycle,
+ const __be32 *ctx_header, unsigned int index)
{
__be32 *buffer;
unsigned int syt;
unsigned int data_blocks;
unsigned int pcm_frames;
+ unsigned int payload_length;
struct snd_pcm_substream *pcm;
buffer = s->buffer.packets[s->packet_index].buffer;
@@ -521,13 +521,14 @@ static int handle_out_packet(struct amdtp_stream *s,
}
static int handle_out_packet_without_header(struct amdtp_stream *s,
- unsigned int payload_length, unsigned int cycle,
- unsigned int index)
+ unsigned int cycle, const __be32 *ctx_header,
+ unsigned int index)
{
__be32 *buffer;
unsigned int syt;
unsigned int data_blocks;
unsigned int pcm_frames;
+ unsigned int payload_length;
struct snd_pcm_substream *pcm;
buffer = s->buffer.packets[s->packet_index].buffer;
@@ -551,11 +552,11 @@ static int handle_out_packet_without_header(struct amdtp_stream *s,
return 0;
}
-static int handle_in_packet(struct amdtp_stream *s,
- unsigned int payload_length, unsigned int cycle,
- unsigned int index)
+static int handle_in_packet(struct amdtp_stream *s, unsigned int cycle,
+ const __be32 *ctx_header, unsigned int index)
{
__be32 *buffer;
+ unsigned int payload_length;
u32 cip_header[2];
unsigned int sph, fmt, fdf, syt;
unsigned int data_block_quadlets, data_block_counter, dbc_interval;
@@ -564,6 +565,14 @@ static int handle_in_packet(struct amdtp_stream *s,
unsigned int pcm_frames;
bool lost;
+ payload_length = be32_to_cpu(ctx_header[0]) >> ISO_DATA_LENGTH_SHIFT;
+ if (payload_length > s->ctx_data.tx.max_payload_length) {
+ dev_err(&s->unit->device,
+ "Detect jumbo payload: %04x %04x\n",
+ payload_length, s->ctx_data.tx.max_payload_length);
+ return -EIO;
+ }
+
buffer = s->buffer.packets[s->packet_index].buffer;
cip_header[0] = be32_to_cpu(buffer[0]);
cip_header[1] = be32_to_cpu(buffer[1]);
@@ -668,14 +677,16 @@ end:
}
static int handle_in_packet_without_header(struct amdtp_stream *s,
- unsigned int payload_length, unsigned int cycle,
- unsigned int index)
+ unsigned int cycle, const __be32 *ctx_header,
+ unsigned int index)
{
__be32 *buffer;
+ unsigned int payload_length;
unsigned int data_blocks;
struct snd_pcm_substream *pcm;
unsigned int pcm_frames;
+ payload_length = be32_to_cpu(ctx_header[0]) >> ISO_DATA_LENGTH_SHIFT;
buffer = s->buffer.packets[s->packet_index].buffer;
data_blocks = payload_length / sizeof(__be32) / s->data_block_quadlets;
@@ -745,7 +756,7 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
cycle = compute_it_cycle(*ctx_header);
- if (s->handle_packet(s, 0, cycle, i) < 0) {
+ if (s->handle_packet(s, cycle, ctx_header, i) < 0) {
cancel_stream(s);
return;
}
@@ -762,7 +773,6 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
{
struct amdtp_stream *s = private_data;
unsigned int i, packets;
- unsigned int payload_length, max_payload_length;
__be32 *ctx_header = header;
if (s->packet_index < 0)
@@ -771,25 +781,12 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
// The number of packets in buffer.
packets = header_length / s->ctx_data.tx.ctx_header_size;
- /* For buffer-over-run prevention. */
- max_payload_length = s->ctx_data.tx.max_payload_length;
-
for (i = 0; i < packets; i++) {
- u32 iso_header = be32_to_cpu(ctx_header[0]);
u32 cycle;
cycle = compute_cycle_count(ctx_header[1]);
- /* The number of bytes in this packet */
- payload_length = iso_header >> ISO_DATA_LENGTH_SHIFT;
- if (payload_length > max_payload_length) {
- dev_err(&s->unit->device,
- "Detect jumbo payload: %04x %04x\n",
- payload_length, max_payload_length);
- break;
- }
-
- if (s->handle_packet(s, payload_length, cycle, i) < 0)
+ if (s->handle_packet(s, cycle, ctx_header, i) < 0)
break;
ctx_header += s->ctx_data.tx.ctx_header_size / sizeof(*ctx_header);
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index 1945ef59ab92..d317fdc6ab5f 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -108,9 +108,8 @@ struct amdtp_stream {
struct iso_packets_buffer buffer;
int packet_index;
int tag;
- int (*handle_packet)(struct amdtp_stream *s,
- unsigned int payload_quadlets, unsigned int cycle,
- unsigned int index);
+ int (*handle_packet)(struct amdtp_stream *s, unsigned int cycle,
+ const __be32 *ctx_header, unsigned int index);
union {
struct {
unsigned int ctx_header_size;