summaryrefslogtreecommitdiffstats
path: root/sound/firewire/amdtp.c
diff options
context:
space:
mode:
authorTakashi Sakamoto2014-04-25 15:45:16 +0200
committerTakashi Iwai2014-05-26 14:29:44 +0200
commitb6bc812327aa6961d783e81961273ebf2a304964 (patch)
treef200e026bd6383613d4a9e98e7234cc1e44dea90 /sound/firewire/amdtp.c
parentALSA: bebob: Add commands and connections/streams management (diff)
downloadkernel-qcow2-linux-b6bc812327aa6961d783e81961273ebf2a304964.tar.gz
kernel-qcow2-linux-b6bc812327aa6961d783e81961273ebf2a304964.tar.xz
kernel-qcow2-linux-b6bc812327aa6961d783e81961273ebf2a304964.zip
ALSA: bebob/firewire-lib: Add a quirk for discontinuity at bus reset
Normal BeBoB firmware has a quirk. When receiving bus reset, it transmits packets with discontinuous value in dbc field. This causes two situation, one is to abort streaming by firewire-lib as a result of detecting the discontinuity. Another is to call driver's .update() because of bus reset. These two is generated independently. (The former depends on isochronous stream and the latter depends on IEEE1394 bus driver.) When BeBoB driver works with XRUN-recoverable applications, this situation looks like stream_start_duplex() call followed by stream_update_duplex() call because applications will call snd_pcm_prepare() immediately at XRUN. To update connections and streams at first, this commit use completion. When queueing error occurs, stream_start_duplex() is forced to wait maximum 1000msec. During this, when .update() is called, the completion is waken and stream_start_duplex() is processed without breaking connections. At bus reset, stream_start_duplex() shouldn't break/establish connections and stream_update_duplex() should update connections because a caller of fw_iso_resources_allocate() is responsible for calling fw_iso_resources_update() on bus reset. This commit also adds a flag, which has an effect to skip checking continuity for first packet. This flag is useful for BeBoB quirk to start handling packets during streaming. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/amdtp.c')
-rw-r--r--sound/firewire/amdtp.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c
index 28ee3d86164d..690c60828872 100644
--- a/sound/firewire/amdtp.c
+++ b/sound/firewire/amdtp.c
@@ -665,7 +665,8 @@ static void handle_in_packet(struct amdtp_stream *s,
/* Check data block counter continuity */
data_block_counter = cip_header[0] & AMDTP_DBC_MASK;
- if ((s->flags & CIP_SKIP_DBC_ZERO_CHECK) && data_block_counter == 0) {
+ if (((s->flags & CIP_SKIP_DBC_ZERO_CHECK) && data_block_counter == 0) ||
+ (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;
@@ -850,7 +851,11 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
goto err_unlock;
}
- s->data_block_counter = 0;
+ if (s->direction == AMDTP_IN_STREAM &&
+ s->flags & CIP_SKIP_INIT_DBC_CHECK)
+ s->data_block_counter = UINT_MAX;
+ else
+ s->data_block_counter = 0;
s->data_block_state = initial_state[s->sfc].data_block;
s->syt_offset_state = initial_state[s->sfc].syt_offset;
s->last_syt_offset = TICKS_PER_CYCLE;