summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Fenlason <fenlason@redhat.com>2009-11-21 00:05:56 +0100
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-11-21 00:56:47 +0100
commit31769cef2e973544164aa7d0db2e2024660d5e21 (patch)
tree6f3c2ce2e742fa197ac1460012a14eaf09bf3afa
parent5ed1f321a71b8549cc2eea26c94fe7943ed01d31 (diff)
firewire: ohci: pass correct iso xmit timestamps to core
Here is the final set of patches I used to get ffado to work with the new firewire stack. With these patches, I was able to start ardour and record from and playback to my PreSonus Inspire1394 from a (mostly) Fedora 12 system. Signed-off-by: Jay Fenlason <fenlason@redhat.com> Until now, firewire-ohci exposed only the transmit cycle of the last transmitted packet at each isochronous transmit complete event. This made it impossible for FFADO (FireWire audio drivers in userspace) to synchronize audio-out streams. The fix is to store the timestamp of each packet in the iso xmit event. As a bonus, the transfer status is stored too. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
-rw-r--r--drivers/firewire/ohci.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index c07cfada190..94260aa76aa 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1904,15 +1904,30 @@ static int handle_it_packet(struct context *context,
{
struct iso_context *ctx =
container_of(context, struct iso_context, context);
+ int i;
+ struct descriptor *pd;
- if (last->transfer_status == 0)
- /* This descriptor isn't done yet, stop iteration. */
+ for (pd = d; pd <= last; pd++)
+ if (pd->transfer_status)
+ break;
+ if (pd > last)
+ /* Descriptor(s) not done yet, stop iteration */
return 0;
- if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS)
+ i = ctx->header_length;
+ if (i + 4 < PAGE_SIZE) {
+ /* Present this value as big-endian to match the receive code */
+ *(__be32 *)(ctx->header + i) = cpu_to_be32(
+ ((u32)le16_to_cpu(pd->transfer_status) << 16) |
+ le16_to_cpu(pd->res_count));
+ ctx->header_length += 4;
+ }
+ if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) {
ctx->base.callback(&ctx->base, le16_to_cpu(last->res_count),
- 0, NULL, ctx->base.callback_data);
-
+ ctx->header_length, ctx->header,
+ ctx->base.callback_data);
+ ctx->header_length = 0;
+ }
return 1;
}