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 16:03:04 -0500 |
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 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, | |||
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | static struct fw_iso_context * | 1339 | static struct fw_iso_context * |
1340 | ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size) | 1340 | ohci_allocate_iso_context(struct fw_card *card, int type, |
1341 | int sync, int tags, size_t header_size) | ||
1341 | { | 1342 | { |
1342 | struct fw_ohci *ohci = fw_ohci(card); | 1343 | struct fw_ohci *ohci = fw_ohci(card); |
1343 | struct iso_context *ctx, *list; | 1344 | struct iso_context *ctx, *list; |
@@ -1427,7 +1428,8 @@ static int ohci_start_iso(struct fw_iso_context *base, s32 cycle) | |||
1427 | reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 1 << index); | 1428 | reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 1 << index); |
1428 | reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index); | 1429 | reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index); |
1429 | reg_write(ohci, context_match(ctx->context.regs), | 1430 | reg_write(ohci, context_match(ctx->context.regs), |
1430 | 0xf0000000 | ctx->base.channel); | 1431 | (ctx->base.tags << 28) | |
1432 | (ctx->base.sync << 8) | ctx->base.channel); | ||
1431 | context_run(&ctx->context, mode); | 1433 | context_run(&ctx->context, mode); |
1432 | } | 1434 | } |
1433 | 1435 | ||
@@ -1573,6 +1575,26 @@ ohci_queue_iso_transmit(struct fw_iso_context *base, | |||
1573 | 1575 | ||
1574 | return 0; | 1576 | return 0; |
1575 | } | 1577 | } |
1578 | |||
1579 | static int | ||
1580 | setup_wait_descriptor(struct context *ctx) | ||
1581 | { | ||
1582 | struct descriptor *d; | ||
1583 | dma_addr_t d_bus; | ||
1584 | |||
1585 | d = context_get_descriptors(ctx, 1, &d_bus); | ||
1586 | if (d == NULL) | ||
1587 | return -ENOMEM; | ||
1588 | |||
1589 | d->control = cpu_to_le16(descriptor_input_more | | ||
1590 | descriptor_status | | ||
1591 | descriptor_branch_always | | ||
1592 | descriptor_wait); | ||
1593 | |||
1594 | context_append(ctx, d, 1, 0); | ||
1595 | |||
1596 | return 0; | ||
1597 | } | ||
1576 | 1598 | ||
1577 | static int | 1599 | static int |
1578 | ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base, | 1600 | ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base, |
@@ -1591,6 +1613,9 @@ ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base, | |||
1591 | /* FIXME: Cycle lost behavior should be configurable: lose | 1613 | /* FIXME: Cycle lost behavior should be configurable: lose |
1592 | * packet, retransmit or terminate.. */ | 1614 | * packet, retransmit or terminate.. */ |
1593 | 1615 | ||
1616 | if (packet->skip && setup_wait_descriptor(&ctx->context) < 0) | ||
1617 | return -ENOMEM; | ||
1618 | |||
1594 | p = packet; | 1619 | p = packet; |
1595 | z = 2; | 1620 | z = 2; |
1596 | 1621 | ||
@@ -1655,6 +1680,9 @@ ohci_queue_iso_receive_bufferfill(struct fw_iso_context *base, | |||
1655 | offset = payload & ~PAGE_MASK; | 1680 | offset = payload & ~PAGE_MASK; |
1656 | rest = packet->payload_length; | 1681 | rest = packet->payload_length; |
1657 | 1682 | ||
1683 | if (packet->skip && setup_wait_descriptor(&ctx->context) < 0) | ||
1684 | return -ENOMEM; | ||
1685 | |||
1658 | while (rest > 0) { | 1686 | while (rest > 0) { |
1659 | d = context_get_descriptors(&ctx->context, 1, &d_bus); | 1687 | d = context_get_descriptors(&ctx->context, 1, &d_bus); |
1660 | if (d == NULL) | 1688 | if (d == NULL) |