summaryrefslogtreecommitdiffstats
path: root/src/fw-iso.c
diff options
context:
space:
mode:
authorGravatar Jay Fenlason 2009-11-19 15:00:02 -0500
committerGravatar Stefan Richter 2009-11-22 22:42:16 +0100
commitce82d255efa4d748e4ade922f71796a502a19c27 (patch)
tree5788f308ef82578fa84db013c61530dca90b8d25 /src/fw-iso.c
parentFix default isochronous IRQ interval on firewire-core (diff)
Fix reporting of isochronous transmit cycles on firewire-core
While firewire-core's iso reception ABI was fixed in its version 2 to report the cycle of each received packet to userspace like rawiso does, this same enhancement was forgotten to add to the iso transmission ABI, causing FFADO to fail to set up and maintain streaming. Since kernel commit 31769cef2e973544164aa7d0db2e2024660d5e21, we also get iso xmit cycles in fw_cdev_event_iso_interrupt.header. Pass these to the iso receive handler. In case of older kernels, calculate cycles based on the cycle of the iso interrupt event. These are inaccurate but better than nothing. Signed-off-by: Jay Fenlason <fenlason@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (changelog, whitespace)
Diffstat (limited to 'src/fw-iso.c')
-rw-r--r--src/fw-iso.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/src/fw-iso.c b/src/fw-iso.c
index edf2fd7..235040b 100644
--- a/src/fw-iso.c
+++ b/src/fw-iso.c
@@ -70,13 +70,12 @@ queue_packet(fw_handle_t handle,
}
static int
-queue_xmit_packets(raw1394handle_t handle, int limit)
+queue_xmit_packets(raw1394handle_t handle, int limit, int cycle)
{
fw_handle_t fwhandle = handle->mode.fw;
enum raw1394_iso_disposition d;
unsigned char tag, sy;
unsigned int len;
- int cycle = -1;
unsigned int dropped = 0;
if (fwhandle->iso.xmit_handler == NULL)
@@ -90,6 +89,11 @@ queue_xmit_packets(raw1394handle_t handle, int limit)
switch (d) {
case RAW1394_ISO_OK:
queue_packet(fwhandle, len, 0, tag, sy);
+ if (cycle >= 0) {
+ cycle++;
+ if (cycle >= 8000)
+ cycle %= 8000;
+ }
break;
case RAW1394_ISO_DEFER:
case RAW1394_ISO_AGAIN:
@@ -119,7 +123,21 @@ int fw_iso_xmit_start(raw1394handle_t handle, int start_on_cycle,
fwhandle->iso.prebuffer = prebuffer_packets;
fwhandle->iso.start_on_cycle = start_on_cycle;
- queue_xmit_packets(handle, prebuffer_packets);
+ retval = queue_xmit_packets(handle, prebuffer_packets, start_on_cycle);
+ if (retval)
+ return -1;
+
+ if (start_on_cycle >= 0) {
+ int tmp;
+
+ tmp = start_on_cycle + prebuffer_packets;
+ tmp %= 8000;
+ retval = queue_xmit_packets(handle, fwhandle->iso.buf_packets, tmp);
+ } else {
+ retval = queue_xmit_packets(handle, fwhandle->iso.buf_packets, -1);
+ }
+ if (retval)
+ return -1;
if (fwhandle->iso.prebuffer <= fwhandle->iso.packet_count) {
start_iso.cycle = start_on_cycle;
@@ -131,12 +149,7 @@ int fw_iso_xmit_start(raw1394handle_t handle, int start_on_cycle,
return retval;
}
- retval = queue_xmit_packets(handle, fwhandle->iso.buf_packets);
-
- if (retval)
- return -1;
- else
- fwhandle->iso.state = ISO_ACTIVE;
+ fwhandle->iso.state = ISO_ACTIVE;
return 0;
}
@@ -256,8 +269,31 @@ static int handle_iso_event(raw1394handle_t handle,
switch (fwhandle->iso.type) {
case FW_CDEV_ISO_CONTEXT_TRANSMIT:
+ {
+ int cycle;
+
fwhandle->iso.packet_count -= fwhandle->iso.irq_interval;
- return queue_xmit_packets(handle, fwhandle->iso.buf_packets);
+ if (interrupt->header_length) {
+ /*
+ * Take the cycle of the last packet transmitted, add
+ * the number of packets currently queued, plus one, and
+ * that's the cycle number of the next packet to ask
+ * for.
+ */
+ cycle = be32_to_cpu(interrupt->header[interrupt->header_length/4 - 1]);
+ cycle &= 0x1fff;
+ } else {
+ /*
+ * Bogusly faking it again. Assume that the last packet
+ * transmitted was transmitted on interrupt->cycle.
+ */
+ cycle = interrupt->cycle;
+ }
+ cycle += fwhandle->iso.packet_count;
+ cycle++;
+ cycle %= 8000;
+ return queue_xmit_packets(handle, fwhandle->iso.buf_packets, cycle);
+ }
case FW_CDEV_ISO_CONTEXT_RECEIVE:
return flush_recv_packets(handle, interrupt);
default:
rary version info in configure.in, use in src/Makefile.am.Gravatar aeb 4-2/+16 2000-06-15Update libtool version number.Gravatar aeb 2-2/+2 2000-06-14Added copyright headers.Gravatar aeb 6-0/+54 2000-06-11Added explicit AC_PROG_INSTALL call.Gravatar aeb 1-0/+1 2000-06-09Fix size of error field.Gravatar aeb 1-2/+2 2000-06-02Modified support for 32/64 bit environments, control struct fields have fixed...Gravatar aeb 7-43/+28 2000-05-28Added support for environments with 64 bit kernel and 32 bit userland.Gravatar aeb 8-7/+45 2000-04-27Fixed missing setting of ext code in raw1394_start_lock()Gravatar aeb 1-0/+1 2000-04-15Fixed lock transaction to actually return response value.Gravatar aeb 3-5/+11 2000-04-12Add userdata functions as news.Gravatar aeb 1-0/+4 2000-04-05Add userdata functions.Gravatar aeb 3-0/+18 2000-03-18Bump version number to 0.6.Gravatar aeb 3-5/+6 2000-03-18Mention byte order change.Gravatar aeb 1-0/+2 2000-03-18Mention SourceForge home.Gravatar aeb 1-1/+5