diff options
Diffstat (limited to 'sound/firewire')
46 files changed, 1841 insertions, 2014 deletions
diff --git a/sound/firewire/amdtp-am824.c b/sound/firewire/amdtp-am824.c index 71168728940a..fd5d6b8ac557 100644 --- a/sound/firewire/amdtp-am824.c +++ b/sound/firewire/amdtp-am824.c @@ -82,7 +82,7 @@ int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate, if (err < 0) return err; - s->fdf = AMDTP_FDF_AM824 | s->sfc; + s->ctx_data.rx.fdf = AMDTP_FDF_AM824 | s->sfc; p->pcm_channels = pcm_channels; p->midi_ports = midi_ports; @@ -320,7 +320,7 @@ static void read_midi_messages(struct amdtp_stream *s, u8 *b; for (f = 0; f < frames; f++) { - port = (8 - s->tx_first_dbc + s->data_block_counter + f) % 8; + port = (8 - s->ctx_data.tx.first_dbc + s->data_block_counter + f) % 8; b = (u8 *)&buffer[p->midi_position]; len = b[0] - 0x80; diff --git a/sound/firewire/amdtp-stream-trace.h b/sound/firewire/amdtp-stream-trace.h index edb5c3afa6f8..4adbbf789cbe 100644 --- a/sound/firewire/amdtp-stream-trace.h +++ b/sound/firewire/amdtp-stream-trace.h @@ -13,147 +13,16 @@ #include <linux/tracepoint.h> -TRACE_EVENT(in_packet, - TP_PROTO(const struct amdtp_stream *s, u32 cycles, u32 *cip_header, unsigned int payload_length, unsigned int index), - TP_ARGS(s, cycles, cip_header, payload_length, index), - TP_STRUCT__entry( - __field(unsigned int, second) - __field(unsigned int, cycle) - __field(int, channel) - __field(int, src) - __field(int, dest) - __field(u32, cip_header0) - __field(u32, cip_header1) - __field(unsigned int, payload_quadlets) - __field(unsigned int, packet_index) - __field(unsigned int, irq) - __field(unsigned int, index) - ), - TP_fast_assign( - __entry->second = cycles / CYCLES_PER_SECOND; - __entry->cycle = cycles % CYCLES_PER_SECOND; - __entry->channel = s->context->channel; - __entry->src = fw_parent_device(s->unit)->node_id; - __entry->dest = fw_parent_device(s->unit)->card->node_id; - __entry->cip_header0 = cip_header[0]; - __entry->cip_header1 = cip_header[1]; - __entry->payload_quadlets = payload_length / 4; - __entry->packet_index = s->packet_index; - __entry->irq = !!in_interrupt(); - __entry->index = index; - ), - TP_printk( - "%02u %04u %04x %04x %02d %08x %08x %03u %02u %01u %02u", - __entry->second, - __entry->cycle, - __entry->src, - __entry->dest, - __entry->channel, - __entry->cip_header0, - __entry->cip_header1, - __entry->payload_quadlets, - __entry->packet_index, - __entry->irq, - __entry->index) -); - -TRACE_EVENT(out_packet, - TP_PROTO(const struct amdtp_stream *s, u32 cycles, __be32 *cip_header, unsigned int payload_length, unsigned int index), - TP_ARGS(s, cycles, cip_header, payload_length, index), - TP_STRUCT__entry( - __field(unsigned int, second) - __field(unsigned int, cycle) - __field(int, channel) - __field(int, src) - __field(int, dest) - __field(u32, cip_header0) - __field(u32, cip_header1) - __field(unsigned int, payload_quadlets) - __field(unsigned int, packet_index) - __field(unsigned int, irq) - __field(unsigned int, index) - ), - TP_fast_assign( - __entry->second = cycles / CYCLES_PER_SECOND; - __entry->cycle = cycles % CYCLES_PER_SECOND; - __entry->channel = s->context->channel; - __entry->src = fw_parent_device(s->unit)->card->node_id; - __entry->dest = fw_parent_device(s->unit)->node_id; - __entry->cip_header0 = be32_to_cpu(cip_header[0]); - __entry->cip_header1 = be32_to_cpu(cip_header[1]); - __entry->payload_quadlets = payload_length / 4; - __entry->packet_index = s->packet_index; - __entry->irq = !!in_interrupt(); - __entry->index = index; - ), - TP_printk( - "%02u %04u %04x %04x %02d %08x %08x %03u %02u %01u %02u", - __entry->second, - __entry->cycle, - __entry->src, - __entry->dest, - __entry->channel, - __entry->cip_header0, - __entry->cip_header1, - __entry->payload_quadlets, - __entry->packet_index, - __entry->irq, - __entry->index) -); - -TRACE_EVENT(in_packet_without_header, - TP_PROTO(const struct amdtp_stream *s, u32 cycles, unsigned int payload_quadlets, unsigned int data_blocks, unsigned int index), - TP_ARGS(s, cycles, payload_quadlets, data_blocks, index), - TP_STRUCT__entry( - __field(unsigned int, second) - __field(unsigned int, cycle) - __field(int, channel) - __field(int, src) - __field(int, dest) - __field(unsigned int, payload_quadlets) - __field(unsigned int, data_blocks) - __field(unsigned int, data_block_counter) - __field(unsigned int, packet_index) - __field(unsigned int, irq) - __field(unsigned int, index) - ), - TP_fast_assign( - __entry->second = cycles / CYCLES_PER_SECOND; - __entry->cycle = cycles % CYCLES_PER_SECOND; - __entry->channel = s->context->channel; - __entry->src = fw_parent_device(s->unit)->node_id; - __entry->dest = fw_parent_device(s->unit)->card->node_id; - __entry->payload_quadlets = payload_quadlets; - __entry->data_blocks = data_blocks, - __entry->data_block_counter = s->data_block_counter, - __entry->packet_index = s->packet_index; - __entry->irq = !!in_interrupt(); - __entry->index = index; - ), - TP_printk( - "%02u %04u %04x %04x %02d %03u %02u %03u %02u %01u %02u", - __entry->second, - __entry->cycle, - __entry->src, - __entry->dest, - __entry->channel, - __entry->payload_quadlets, - __entry->data_blocks, - __entry->data_block_counter, - __entry->packet_index, - __entry->irq, - __entry->index) -); - -TRACE_EVENT(out_packet_without_header, - TP_PROTO(const struct amdtp_stream *s, u32 cycles, unsigned int payload_length, unsigned int data_blocks, unsigned int index), - TP_ARGS(s, cycles, payload_length, data_blocks, index), +TRACE_EVENT(amdtp_packet, + TP_PROTO(const struct amdtp_stream *s, u32 cycles, const __be32 *cip_header, unsigned int payload_length, unsigned int data_blocks, unsigned int index), + TP_ARGS(s, cycles, cip_header, payload_length, data_blocks, index), TP_STRUCT__entry( __field(unsigned int, second) __field(unsigned int, cycle) __field(int, channel) __field(int, src) __field(int, dest) + __dynamic_array(u8, cip_header, cip_header ? 8 : 0) __field(unsigned int, payload_quadlets) __field(unsigned int, data_blocks) __field(unsigned int, data_block_counter) @@ -165,17 +34,26 @@ TRACE_EVENT(out_packet_without_header, __entry->second = cycles / CYCLES_PER_SECOND; __entry->cycle = cycles % CYCLES_PER_SECOND; __entry->channel = s->context->channel; - __entry->src = fw_parent_device(s->unit)->card->node_id; - __entry->dest = fw_parent_device(s->unit)->node_id; - __entry->payload_quadlets = payload_length / 4; - __entry->data_blocks = data_blocks, + if (s->direction == AMDTP_IN_STREAM) { + __entry->src = fw_parent_device(s->unit)->node_id; + __entry->dest = fw_parent_device(s->unit)->card->node_id; + } else { + __entry->src = fw_parent_device(s->unit)->card->node_id; + __entry->dest = fw_parent_device(s->unit)->node_id; + } + if (cip_header) { + memcpy(__get_dynamic_array(cip_header), cip_header, + __get_dynamic_array_len(cip_header)); + } + __entry->payload_quadlets = payload_length / sizeof(__be32); + __entry->data_blocks = data_blocks; __entry->data_block_counter = s->data_block_counter, __entry->packet_index = s->packet_index; __entry->irq = !!in_interrupt(); __entry->index = index; ), TP_printk( - "%02u %04u %04x %04x %02d %03u %02u %03u %02u %01u %02u", + "%02u %04u %04x %04x %02d %03u %02u %03u %02u %01u %02u %s", __entry->second, __entry->cycle, __entry->src, @@ -186,7 +64,10 @@ TRACE_EVENT(out_packet_without_header, __entry->data_block_counter, __entry->packet_index, __entry->irq, - __entry->index) + __entry->index, + __print_array(__get_dynamic_array(cip_header), + __get_dynamic_array_len(cip_header), + sizeof(u8))) ); #endif diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index 68f5fa4b183d..4d71d74707cf 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c @@ -56,10 +56,15 @@ #define INTERRUPT_INTERVAL 16 #define QUEUE_LENGTH 48 -#define IR_HEADER_SIZE 8 // For header and timestamp. -#define OUT_PACKET_HEADER_SIZE 0 +// For iso header, tstamp and 2 CIP header. +#define IR_CTX_HEADER_SIZE_CIP 16 +// For iso header and tstamp. +#define IR_CTX_HEADER_SIZE_NO_CIP 8 #define HEADER_TSTAMP_MASK 0x0000ffff +#define IT_PKT_HEADER_SIZE_CIP 8 // For 2 CIP header. +#define IT_PKT_HEADER_SIZE_NO_CIP 0 // Nothing. + static void pcm_period_tasklet(unsigned long data); /** @@ -260,11 +265,18 @@ int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate, s->data_block_quadlets = data_block_quadlets; s->syt_interval = amdtp_syt_intervals[sfc]; - /* default buffering in the device */ - s->transfer_delay = TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE; - if (s->flags & CIP_BLOCKING) - /* additional buffering needed to adjust for no-data packets */ - s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate; + // default buffering in the device. + if (s->direction == AMDTP_OUT_STREAM) { + s->ctx_data.rx.transfer_delay = + TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE; + + if (s->flags & CIP_BLOCKING) { + // additional buffering needed to adjust for no-data + // packets. + s->ctx_data.rx.transfer_delay += + TICKS_PER_SECOND * s->syt_interval / rate; + } + } return 0; } @@ -280,15 +292,15 @@ EXPORT_SYMBOL(amdtp_stream_set_parameters); unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s) { unsigned int multiplier = 1; - unsigned int header_size = 0; + unsigned int cip_header_size = 0; if (s->flags & CIP_JUMBO_PAYLOAD) multiplier = 5; if (!(s->flags & CIP_NO_HEADER)) - header_size = 8; + cip_header_size = sizeof(__be32) * 2; - return header_size + - s->syt_interval * s->data_block_quadlets * 4 * multiplier; + return cip_header_size + + s->syt_interval * s->data_block_quadlets * sizeof(__be32) * multiplier; } EXPORT_SYMBOL(amdtp_stream_get_max_payload); @@ -321,10 +333,10 @@ static unsigned int calculate_data_blocks(struct amdtp_stream *s, /* Non-blocking mode. */ } else { if (!cip_sfc_is_base_44100(s->sfc)) { - /* Sample_rate / 8000 is an integer, and precomputed. */ - data_blocks = s->data_block_state; + // Sample_rate / 8000 is an integer, and precomputed. + data_blocks = s->ctx_data.rx.data_block_state; } else { - phase = s->data_block_state; + phase = s->ctx_data.rx.data_block_state; /* * This calculates the number of data blocks per packet so that @@ -343,7 +355,7 @@ static unsigned int calculate_data_blocks(struct amdtp_stream *s, data_blocks = 11 * (s->sfc >> 1) + (phase == 0); if (++phase >= (80 >> (s->sfc >> 1))) phase = 0; - s->data_block_state = phase; + s->ctx_data.rx.data_block_state = phase; } } @@ -355,9 +367,10 @@ static unsigned int calculate_syt(struct amdtp_stream *s, { unsigned int syt_offset, phase, index, syt; - if (s->last_syt_offset < TICKS_PER_CYCLE) { + if (s->ctx_data.rx.last_syt_offset < TICKS_PER_CYCLE) { if (!cip_sfc_is_base_44100(s->sfc)) - syt_offset = s->last_syt_offset + s->syt_offset_state; + syt_offset = s->ctx_data.rx.last_syt_offset + + s->ctx_data.rx.syt_offset_state; else { /* * The time, in ticks, of the n'th SYT_INTERVAL sample is: @@ -369,21 +382,21 @@ static unsigned int calculate_syt(struct amdtp_stream *s, * 1386 1386 1387 1386 1386 1386 1387 1386 1386 1386 1387 ... * This code generates _exactly_ the same sequence. */ - phase = s->syt_offset_state; + phase = s->ctx_data.rx.syt_offset_state; index = phase % 13; - syt_offset = s->last_syt_offset; + syt_offset = s->ctx_data.rx.last_syt_offset; syt_offset += 1386 + ((index && !(index & 3)) || phase == 146); if (++phase >= 147) phase = 0; - s->syt_offset_state = phase; + s->ctx_data.rx.syt_offset_state = phase; } } else - syt_offset = s->last_syt_offset - TICKS_PER_CYCLE; - s->last_syt_offset = syt_offset; + syt_offset = s->ctx_data.rx.last_syt_offset - TICKS_PER_CYCLE; + s->ctx_data.rx.last_syt_offset = syt_offset; if (syt_offset < TICKS_PER_CYCLE) { - syt_offset += s->transfer_delay; + syt_offset += s->ctx_data.rx.transfer_delay; syt = (cycle + syt_offset / TICKS_PER_CYCLE) << 12; syt += syt_offset % TICKS_PER_CYCLE; @@ -420,23 +433,15 @@ static void pcm_period_tasklet(unsigned long data) snd_pcm_period_elapsed(pcm); } -static int queue_packet(struct amdtp_stream *s, unsigned int header_length, - unsigned int payload_length) +static int queue_packet(struct amdtp_stream *s, struct fw_iso_packet *params) { - struct fw_iso_packet p = {0}; - int err = 0; + int err; - if (IS_ERR(s->context)) - goto end; + params->interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL); + params->tag = s->tag; + params->sy = 0; - p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL); - p.tag = s->tag; - p.header_length = header_length; - if (payload_length > 0) - p.payload_length = payload_length; - else - p.skip = true; - err = fw_iso_context_queue(s->context, &p, &s->buffer.iso_buffer, + err = fw_iso_context_queue(s->context, params, &s->buffer.iso_buffer, s->buffer.packets[s->packet_index].offset); if (err < 0) { dev_err(&s->unit->device, "queueing error: %d\n", err); @@ -450,112 +455,83 @@ end: } static inline int queue_out_packet(struct amdtp_stream *s, - unsigned int payload_length) + struct fw_iso_packet *params) { - return queue_packet(s, OUT_PACKET_HEADER_SIZE, payload_length); + params->skip = + !!(params->header_length == 0 && params->payload_length == 0); + return queue_packet(s, params); } -static inline int queue_in_packet(struct amdtp_stream *s) +static inline int queue_in_packet(struct amdtp_stream *s, + struct fw_iso_packet *params) { - return queue_packet(s, IR_HEADER_SIZE, s->max_payload_length); + // Queue one packet for IR context. + params->header_length = s->ctx_data.tx.ctx_header_size; + params->payload_length = s->ctx_data.tx.max_ctx_payload_length; + params->skip = false; + return queue_packet(s, params); } -static int handle_out_packet(struct amdtp_stream *s, - unsigned int payload_length, unsigned int cycle, - unsigned int index) +static void generate_cip_header(struct amdtp_stream *s, __be32 cip_header[2], + unsigned int syt) { - __be32 *buffer; - unsigned int syt; - unsigned int data_blocks; - unsigned int pcm_frames; - struct snd_pcm_substream *pcm; - - buffer = s->buffer.packets[s->packet_index].buffer; - syt = calculate_syt(s, cycle); - data_blocks = calculate_data_blocks(s, syt); - pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt); - - if (s->flags & CIP_DBC_IS_END_EVENT) - s->data_block_counter = - (s->data_block_counter + data_blocks) & 0xff; - - buffer[0] = cpu_to_be32(READ_ONCE(s->source_node_id_field) | + cip_header[0] = cpu_to_be32(READ_ONCE(s->source_node_id_field) | (s->data_block_quadlets << CIP_DBS_SHIFT) | ((s->sph << CIP_SPH_SHIFT) & CIP_SPH_MASK) | s->data_block_counter); - buffer[1] = cpu_to_be32(CIP_EOH | - ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) | - ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) | - (syt & CIP_SYT_MASK)); - - if (!(s->flags & CIP_DBC_IS_END_EVENT)) - s->data_block_counter = - (s->data_block_counter + data_blocks) & 0xff; - payload_length = 8 + data_blocks * 4 * s->data_block_quadlets; - - trace_out_packet(s, cycle, buffer, payload_length, index); - - if (queue_out_packet(s, payload_length) < 0) - return -EIO; - - pcm = READ_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; + cip_header[1] = cpu_to_be32(CIP_EOH | + ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) | + ((s->ctx_data.rx.fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) | + (syt & CIP_SYT_MASK)); } -static int handle_out_packet_without_header(struct amdtp_stream *s, - unsigned int payload_length, unsigned int cycle, - unsigned int index) +static void build_it_pkt_header(struct amdtp_stream *s, unsigned int cycle, + struct fw_iso_packet *params, + unsigned int data_blocks, unsigned int syt, + unsigned int index) { - __be32 *buffer; - unsigned int syt; - unsigned int data_blocks; - unsigned int pcm_frames; - struct snd_pcm_substream *pcm; - - buffer = s->buffer.packets[s->packet_index].buffer; - syt = calculate_syt(s, cycle); - data_blocks = calculate_data_blocks(s, syt); - pcm_frames = s->process_data_blocks(s, buffer, data_blocks, &syt); - s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff; + unsigned int payload_length; + __be32 *cip_header; - payload_length = data_blocks * 4 * s->data_block_quadlets; + payload_length = data_blocks * sizeof(__be32) * s->data_block_quadlets; + params->payload_length = payload_length; - trace_out_packet_without_header(s, cycle, payload_length, data_blocks, - index); + if (s->flags & CIP_DBC_IS_END_EVENT) { + s->data_block_counter = + (s->data_block_counter + data_blocks) & 0xff; + } - if (queue_out_packet(s, payload_length) < 0) - return -EIO; + if (!(s->flags & CIP_NO_HEADER)) { + cip_header = (__be32 *)params->header; + generate_cip_header(s, cip_header, syt); + params->header_length = 2 * sizeof(__be32); + payload_length += params->header_length; + } else { + cip_header = NULL; + } - pcm = READ_ONCE(s->pcm); - if (pcm && pcm_frames > 0) - update_pcm_pointers(s, pcm, pcm_frames); + trace_amdtp_packet(s, cycle, cip_header, payload_length, data_blocks, + index); - /* No need to return the number of handled data blocks. */ - return 0; + if (!(s->flags & CIP_DBC_IS_END_EVENT)) { + s->data_block_counter = + (s->data_block_counter + data_blocks) & 0xff; + } } -static int handle_in_packet(struct amdtp_stream *s, - unsigned int payload_length, unsigned int cycle, - unsigned int index) +static int check_cip_header(struct amdtp_stream *s, const __be32 *buf, + unsigned int payload_length, + unsigned int *data_blocks, unsigned int *dbc, + unsigned int *syt) { - __be32 *buffer; u32 cip_header[2]; - unsigned int sph, fmt, fdf, syt; - unsigned int data_block_quadlets, data_block_counter, dbc_interval; - unsigned int data_blocks; - struct snd_pcm_substream *pcm; - unsigned int pcm_frames; + unsigned int sph; + unsigned int fmt; + unsigned int fdf; bool lost; - buffer = s->buffer.packets[s->packet_index].buffer; - cip_header[0] = be32_to_cpu(buffer[0]); - cip_header[1] = be32_to_cpu(buffer[1]); - - trace_in_packet(s, cycle, cip_header, payload_length, index); + cip_header[0] = be32_to_cpu(buf[0]); + cip_header[1] = be32_to_cpu(buf[1]); /* * This module supports 'Two-quadlet CIP header with SYT field'. @@ -567,9 +543,7 @@ static int handle_in_packet(struct amdtp_stream *s, dev_info_ratelimited(&s->unit->device, "Invalid CIP header for AMDTP: %08X:%08X\n", cip_header[0], cip_header[1]); - data_blocks = 0; - pcm_frames = 0; - goto end; + return -EAGAIN; } /* Check valid protocol or not. */ @@ -579,19 +553,17 @@ static int handle_in_packet(struct amdtp_stream *s, dev_info_ratelimited(&s->unit->device, "Detect unexpected protocol: %08x %08x\n", cip_header[0], cip_header[1]); - data_blocks = 0; - pcm_frames = 0; - goto end; + return -EAGAIN; } /* Calculate data blocks */ fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT; - if (payload_length < 12 || + if (payload_length < sizeof(__be32) * 2 || (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) { - data_blocks = 0; + *data_blocks = 0; } else { - data_block_quadlets = - (cip_header[0] & CIP_DBS_MASK) >> CIP_DBS_SHIFT; + unsigned int data_block_quadlets = + (cip_header[0] & CIP_DBS_MASK) >> CIP_DBS_SHIFT; /* avoid division by zero */ if (data_block_quadlets == 0) { dev_err(&s->unit->device, @@ -602,95 +574,97 @@ static int handle_in_packet(struct amdtp_stream *s, if (s->flags & CIP_WRONG_DBS) data_block_quadlets = s->data_block_quadlets; - data_blocks = (payload_length / 4 - 2) / + *data_blocks = (payload_length / sizeof(__be32) - 2) / data_block_quadlets; } /* Check data block counter continuity */ - data_block_counter = cip_header[0] & CIP_DBC_MASK; - if (data_blocks == 0 && (s->flags & CIP_EMPTY_HAS_WRONG_DBC) && + *dbc = cip_header[0] & CIP_DBC_MASK; + if (*data_blocks == 0 && (s->flags & CIP_EMPTY_HAS_WRONG_DBC) && s->data_block_counter != UINT_MAX) - data_block_counter = s->data_block_counter; + *dbc = s->data_block_counter; if (((s->flags & CIP_SKIP_DBC_ZERO_CHECK) && - data_block_counter == s->tx_first_dbc) || + *dbc == s->ctx_data.tx.first_dbc) || s->data_block_counter == UINT_MAX) { lost = false; } else if (!(s->flags & CIP_DBC_IS_END_EVENT)) { - lost = data_block_counter != s->data_block_counter; + lost = *dbc != s->data_block_counter; } else { - if (data_blocks > 0 && s->tx_dbc_interval > 0) - dbc_interval = s->tx_dbc_interval; + unsigned int dbc_interval; + + if (*data_blocks > 0 && s->ctx_data.tx.dbc_interval > 0) + dbc_interval = s->ctx_data.tx.dbc_interval; else - dbc_interval = data_blocks; + dbc_interval = *data_blocks; - lost = data_block_counter != - ((s->data_block_counter + dbc_interval) & 0xff); + lost = *dbc != ((s->data_block_counter + dbc_interval) & 0xff); } if (lost) { dev_err(&s->unit->device, "Detect discontinuity of CIP: %02X %02X\n", - s->data_block_counter, data_block_counter); + s->data_block_counter, *dbc); return -EIO; } - syt = be32_to_cpu(buffer[1]) & CIP_SYT_MASK; - pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt); - - if (s->flags & CIP_DBC_IS_END_EVENT) - s->data_block_counter = data_block_counter; - else - s->data_block_counter = - (data_block_counter + data_blocks) & 0xff; -end: - if (queue_in_packet(s) < 0) - return -EIO; - - pcm = READ_ONCE(s->pcm); - if (pcm && pcm_frames > 0) - update_pcm_pointers(s, pcm, pcm_frames); + *syt = cip_header[1] & CIP_SYT_MASK; return 0; } -static int handle_in_packet_without_header(struct amdtp_stream *s, - unsigned int payload_length, unsigned int cycle, - unsigned int index) +static int parse_ir_ctx_header(struct amdtp_stream *s, unsigned int cycle, + const __be32 *ctx_header, + unsigned int *payload_length, + unsigned int *data_blocks, unsigned int *syt, + unsigned int index) { - __be32 *buffer; - unsigned int payload_quadlets; - unsigned int data_blocks; - struct snd_pcm_substream *pcm; - unsigned int pcm_frames; - - buffer = s->buffer.packets[s->packet_index].buffer; - payload_quadlets = payload_length / 4; - data_blocks = payload_quadlets / s->data_block_quadlets; + unsigned int dbc; + const __be32 *cip_header; + int err; - trace_in_packet_without_header(s, cycle, payload_quadlets, data_blocks, - index); + *payload_length = be32_to_cpu(ctx_header[0]) >> ISO_DATA_LENGTH_SHIFT; + if (*payload_length > s->ctx_data.tx.ctx_header_size + + s->ctx_data.tx.max_ctx_payload_length) { + dev_err(& |
