summaryrefslogtreecommitdiff
path: root/drivers/firewire/fw-ohci.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2007-02-16 17:34:51 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2007-03-09 22:03:04 +0100
commit98b6cbe83b6e8db54638746c9040c7962d96b322 (patch)
treead9d7587a5dde5510b402da8681e8c3d150d7ca5 /drivers/firewire/fw-ohci.c
parent21efb3cfc6ed49991638000f58bb23b838c76e25 (diff)
firewire: Implement sync and tag matching for isochronous receive.
Signed-off-by: Kristian Høgsberg <krh@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-ohci.c')
-rw-r--r--drivers/firewire/fw-ohci.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 0088acd7718..ea43a5ed18c 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -1337,7 +1337,8 @@ static int handle_it_packet(struct context *context,
}
static struct fw_iso_context *
-ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
+ohci_allocate_iso_context(struct fw_card *card, int type,
+ int sync, int tags, size_t header_size)
{
struct fw_ohci *ohci = fw_ohci(card);
struct iso_context *ctx, *list;
@@ -1427,7 +1428,8 @@ static int ohci_start_iso(struct fw_iso_context *base, s32 cycle)
reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 1 << index);
reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index);
reg_write(ohci, context_match(ctx->context.regs),
- 0xf0000000 | ctx->base.channel);
+ (ctx->base.tags << 28) |
+ (ctx->base.sync << 8) | ctx->base.channel);
context_run(&ctx->context, mode);
}
@@ -1573,6 +1575,26 @@ ohci_queue_iso_transmit(struct fw_iso_context *base,
return 0;
}
+
+static int
+setup_wait_descriptor(struct context *ctx)
+{
+ struct descriptor *d;
+ dma_addr_t d_bus;
+
+ d = context_get_descriptors(ctx, 1, &d_bus);
+ if (d == NULL)
+ return -ENOMEM;
+
+ d->control = cpu_to_le16(descriptor_input_more |
+ descriptor_status |
+ descriptor_branch_always |
+ descriptor_wait);
+
+ context_append(ctx, d, 1, 0);
+
+ return 0;
+}
static int
ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
@@ -1591,6 +1613,9 @@ ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
/* FIXME: Cycle lost behavior should be configurable: lose
* packet, retransmit or terminate.. */
+ if (packet->skip && setup_wait_descriptor(&ctx->context) < 0)
+ return -ENOMEM;
+
p = packet;
z = 2;
@@ -1655,6 +1680,9 @@ ohci_queue_iso_receive_bufferfill(struct fw_iso_context *base,
offset = payload & ~PAGE_MASK;
rest = packet->payload_length;
+ if (packet->skip && setup_wait_descriptor(&ctx->context) < 0)
+ return -ENOMEM;
+
while (rest > 0) {
d = context_get_descriptors(&ctx->context, 1, &d_bus);
if (d == NULL)