Commit 6f3c07d0 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

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: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 07ea238c
......@@ -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 @@ static int handle_in_packet(struct amdtp_stream *s,
}
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);
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment