diff options
author | Kristian Høgsberg <krh@redhat.com> | 2007-02-16 17:34:51 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2007-03-09 22:03:04 +0100 |
commit | 98b6cbe83b6e8db54638746c9040c7962d96b322 (patch) | |
tree | ad9d7587a5dde5510b402da8681e8c3d150d7ca5 /drivers/firewire/fw-ohci.c | |
parent | 21efb3cfc6ed49991638000f58bb23b838c76e25 (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.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 0088acd7718e..ea43a5ed18cf 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) |