aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/raw1394.c
diff options
context:
space:
mode:
authorPieter Palmers <pieterp@joow.be>2008-03-19 17:10:59 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-04-25 12:15:45 -0400
commitcc9429bcb6e36e9f2c51e4e47b95740e472c4c2d (patch)
treefecf2d6e8fdbe6f0dd5ee74e4b3cbe945d473c3d /drivers/ieee1394/raw1394.c
parentdb8be076cad4b843aa743ef462c75022cddd9c63 (diff)
ieee1394: rawiso: requeue packet for transmission after skipped cycle
As it seems, some host controllers have issues that can cause them to skip cycles now and then when using large packets. I suspect that this is due to DMA not succeeding in time. If the transmit fifo can't contain more than one packet (big packets), the DMA should provide a new packet each cycle (125us). I am under the impression that my current PCI express test system can't guarantee this. In any case, the patch tries to provide a workaround as follows: The DMA program descriptors are modified such that when an error occurs, the DMA engine retries the descriptor the next cycle instead of stalling. This way no data is lost. The side effect of this is that packets are sent with one cycle delay. This however might not be that much of a problem for certain protocols (e.g. AM824). If they use padding packets for e.g. rate matching they can drop one of those to resync the streams. The amount of skips between two userspace wakeups is counted. This number is then propagated to userspace through the upper 16 bits of the 'dropped' parameter. This allows unmodified userspace applications due to the following: 1) libraw simply passes this dropped parameter to the user application 2) the meaning of the dropped parameter is: if it's nonzero, something bad has happened. The actual value of the parameter at this moment does not have a specific meaning. A libraw client can then retrieve the number of skipped cycles and account for them if needed. Signed-off-by: Pieter Palmers <pieterp@joow.be> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/ieee1394/raw1394.c')
-rw-r--r--drivers/ieee1394/raw1394.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 04e96ba56e09..567dafc2369d 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -2356,13 +2356,16 @@ static void rawiso_activity_cb(struct hpsb_iso *iso)
2356static void raw1394_iso_fill_status(struct hpsb_iso *iso, 2356static void raw1394_iso_fill_status(struct hpsb_iso *iso,
2357 struct raw1394_iso_status *stat) 2357 struct raw1394_iso_status *stat)
2358{ 2358{
2359 int overflows = atomic_read(&iso->overflows);
2360 int skips = atomic_read(&iso->skips);
2361
2359 stat->config.data_buf_size = iso->buf_size; 2362 stat->config.data_buf_size = iso->buf_size;
2360 stat->config.buf_packets = iso->buf_packets; 2363 stat->config.buf_packets = iso->buf_packets;
2361 stat->config.channel = iso->channel; 2364 stat->config.channel = iso->channel;
2362 stat->config.speed = iso->speed; 2365 stat->config.speed = iso->speed;
2363 stat->config.irq_interval = iso->irq_interval; 2366 stat->config.irq_interval = iso->irq_interval;
2364 stat->n_packets = hpsb_iso_n_ready(iso); 2367 stat->n_packets = hpsb_iso_n_ready(iso);
2365 stat->overflows = atomic_read(&iso->overflows); 2368 stat->overflows = ((skips & 0xFFFF) << 16) | ((overflows & 0xFFFF));
2366 stat->xmit_cycle = iso->xmit_cycle; 2369 stat->xmit_cycle = iso->xmit_cycle;
2367} 2370}
2368 2371
@@ -2437,6 +2440,8 @@ static int raw1394_iso_get_status(struct file_info *fi, void __user * uaddr)
2437 2440
2438 /* reset overflow counter */ 2441 /* reset overflow counter */
2439 atomic_set(&iso->overflows, 0); 2442 atomic_set(&iso->overflows, 0);
2443 /* reset skip counter */
2444 atomic_set(&iso->skips, 0);
2440 2445
2441 return 0; 2446 return 0;
2442} 2447}