diff options
-rw-r--r-- | sound/firewire/amdtp-stream.c | 80 | ||||
-rw-r--r-- | sound/firewire/amdtp-stream.h | 3 | ||||
-rw-r--r-- | sound/firewire/bebob/bebob_stream.c | 21 |
3 files changed, 23 insertions, 81 deletions
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index 35925c9666fc..48ed9612407f 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c @@ -1199,12 +1199,16 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context, } if (stream_count == callbacked_count) { + unsigned int next_cycle; + list_for_each_entry(s, &d->streams, list) { if (s->direction != AMDTP_IN_STREAM) continue; - if (compare_ohci_cycle_count(s->next_cycle, cycle) > 0) - cycle = s->next_cycle; + next_cycle = increment_ohci_cycle_count(s->next_cycle, + d->processing_cycle.tx_init_skip); + if (compare_ohci_cycle_count(next_cycle, cycle) > 0) + cycle = next_cycle; s->context->callback.sc = process_tx_packets_intermediately; } @@ -1533,36 +1537,13 @@ int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s, } EXPORT_SYMBOL_GPL(amdtp_domain_add_stream); -static int get_current_cycle_time(struct fw_card *fw_card, int *cur_cycle) -{ - int generation; - int rcode; - __be32 reg; - u32 data; - - // This is a request to local 1394 OHCI controller and expected to - // complete without any event waiting. - generation = fw_card->generation; - smp_rmb(); // node_id vs. generation. - rcode = fw_run_transaction(fw_card, TCODE_READ_QUADLET_REQUEST, - fw_card->node_id, generation, SCODE_100, - CSR_REGISTER_BASE + CSR_CYCLE_TIME, - ®, sizeof(reg)); - if (rcode != RCODE_COMPLETE) - return -EIO; - - data = be32_to_cpu(reg); - *cur_cycle = data >> 12; - - return 0; -} - /** * amdtp_domain_start - start sending packets for isoc context in the domain. * @d: the AMDTP domain. - * @ir_delay_cycle: the cycle delay to start all IR contexts. + * @tx_init_skip_cycles: the number of cycles to skip processing packets at initial stage of IR + * contexts. */ -int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle) +int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles) { static const struct { unsigned int data_block; @@ -1581,7 +1562,6 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle) unsigned int idle_irq_interval; unsigned int queue_size; struct amdtp_stream *s; - int cycle; int err; // Select an IT context as IRQ target. @@ -1593,6 +1573,8 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle) return -ENXIO; d->irq_target = s; + d->processing_cycle.tx_init_skip = tx_init_skip_cycles; + // This is a case that AMDTP streams in domain run just for MIDI // substream. Use the number of events equivalent to 10 msec as // interval of hardware IRQ. @@ -1615,48 +1597,12 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle) d->syt_offset_state = entry->syt_offset; d->last_syt_offset = TICKS_PER_CYCLE; - if (ir_delay_cycle > 0) { - struct fw_card *fw_card = fw_parent_device(s->unit)->card; - - err = get_current_cycle_time(fw_card, &cycle); - if (err < 0) - goto error; - - // No need to care overflow in cycle field because of enough - // width. - cycle += ir_delay_cycle; - - // Round up to sec field. - if ((cycle & 0x00001fff) >= CYCLES_PER_SECOND) { - unsigned int sec; - - // The sec field can overflow. - sec = (cycle & 0xffffe000) >> 13; - cycle = (++sec << 13) | - ((cycle & 0x00001fff) / CYCLES_PER_SECOND); - } - - // In OHCI 1394 specification, lower 2 bits are available for - // sec field. - cycle &= 0x00007fff; - } else { - cycle = -1; - } - list_for_each_entry(s, &d->streams, list) { - int cycle_match; - - if (s->direction == AMDTP_IN_STREAM) { - cycle_match = cycle; - } else { - // IT context starts immediately. - cycle_match = -1; + if (s->direction == AMDTP_OUT_STREAM) s->ctx_data.rx.seq_index = 0; - } if (s != d->irq_target) { - err = amdtp_stream_start(s, s->channel, s->speed, - cycle_match, queue_size, 0); + err = amdtp_stream_start(s, s->channel, s->speed, -1, queue_size, 0); if (err < 0) goto error; } diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h index 6fad113188fe..ebd040560791 100644 --- a/sound/firewire/amdtp-stream.h +++ b/sound/firewire/amdtp-stream.h @@ -289,6 +289,7 @@ struct amdtp_domain { struct amdtp_stream *irq_target; struct { + unsigned int tx_init_skip; unsigned int tx_start; } processing_cycle; @@ -309,7 +310,7 @@ void amdtp_domain_destroy(struct amdtp_domain *d); int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s, int channel, int speed); -int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle); +int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles); void amdtp_domain_stop(struct amdtp_domain *d); static inline int amdtp_domain_set_events_per_period(struct amdtp_domain *d, diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c index b612ee3e33b6..8053d02b68f0 100644 --- a/sound/firewire/bebob/bebob_stream.c +++ b/sound/firewire/bebob/bebob_stream.c @@ -626,7 +626,7 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob) enum snd_bebob_clock_type src; struct amdtp_stream *master, *slave; unsigned int curr_rate; - unsigned int ir_delay_cycle; + unsigned int tx_init_skip_cycles; if (bebob->maudio_special_quirk) { err = bebob->spec->rate->get(bebob, &curr_rate); @@ -654,20 +654,13 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob) if (err < 0) goto error; - // The device postpones start of transmission mostly for 1 sec - // after receives packets firstly. For safe, IR context starts - // 0.4 sec (=3200 cycles) later to version 1 or 2 firmware, - // 2.0 sec (=16000 cycles) for version 3 firmware. This is - // within 2.5 sec (=CALLBACK_TIMEOUT). - // Furthermore, some devices transfer isoc packets with - // discontinuous counter in the beginning of packet streaming. - // The delay has an effect to avoid detection of this - // discontinuity. + // Some devices transfer isoc packets with discontinuous counter in the beginning + // of packet streaming. if (bebob->version < 2) - ir_delay_cycle = 3200; + tx_init_skip_cycles = 3200; else - ir_delay_cycle = 16000; - err = amdtp_domain_start(&bebob->domain, ir_delay_cycle); + tx_init_skip_cycles = 16000; + err = amdtp_domain_start(&bebob->domain, tx_init_skip_cycles); if (err < 0) goto error; @@ -684,6 +677,8 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob) } } + // Some devices postpone start of transmission mostly for 1 sec after receives + // packets firstly. if (!amdtp_stream_wait_callback(&bebob->rx_stream, CALLBACK_TIMEOUT) || !amdtp_stream_wait_callback(&bebob->tx_stream, |