Skip to content

Commit

Permalink
firewire: fix libdc1394/FlyCap2 iso event regression
Browse files Browse the repository at this point in the history
Commit 18d6271 (firewire: prevent dropping of completed iso packet
header data) was intended to be an obvious bug fix, but libdc1394 and
FlyCap2 depend on the old behaviour by ignoring all returned information
and thus not noticing that not all packets have been received yet.  The
result was that the video frame buffers would be saved before they
contained the correct data.

Reintroduce the old behaviour for old clients.

Tested-by: Stepan Salenikovich <stepan.salenikovich@gmail.com>
Tested-by: Josep Bosch <jep250@gmail.com>
Cc: <stable@vger.kernel.org> # 3.4+
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
  • Loading branch information
cladisch authored and Stefan Richter committed Jul 27, 2013
1 parent bcabcfd commit 0699a73
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 4 deletions.
3 changes: 3 additions & 0 deletions drivers/firewire/core-cdev.c
Expand Up @@ -54,6 +54,7 @@
#define FW_CDEV_KERNEL_VERSION 5
#define FW_CDEV_VERSION_EVENT_REQUEST2 4
#define FW_CDEV_VERSION_ALLOCATE_REGION_END 4
#define FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW 5

struct client {
u32 version;
Expand Down Expand Up @@ -1005,6 +1006,8 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
a->channel, a->speed, a->header_size, cb, client);
if (IS_ERR(context))
return PTR_ERR(context);
if (client->version < FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW)
context->drop_overflow_headers = true;

/* We only support one context at this time. */
spin_lock_irq(&client->lock);
Expand Down
10 changes: 8 additions & 2 deletions drivers/firewire/ohci.c
Expand Up @@ -2749,8 +2749,11 @@ static void copy_iso_headers(struct iso_context *ctx, const u32 *dma_hdr)
{
u32 *ctx_hdr;

if (ctx->header_length + ctx->base.header_size > PAGE_SIZE)
if (ctx->header_length + ctx->base.header_size > PAGE_SIZE) {
if (ctx->base.drop_overflow_headers)
return;
flush_iso_completions(ctx);
}

ctx_hdr = ctx->header + ctx->header_length;
ctx->last_timestamp = (u16)le32_to_cpu((__force __le32)dma_hdr[0]);
Expand Down Expand Up @@ -2910,8 +2913,11 @@ static int handle_it_packet(struct context *context,

sync_it_packet_for_cpu(context, d);

if (ctx->header_length + 4 > PAGE_SIZE)
if (ctx->header_length + 4 > PAGE_SIZE) {
if (ctx->base.drop_overflow_headers)
return 1;
flush_iso_completions(ctx);
}

ctx_hdr = ctx->header + ctx->header_length;
ctx->last_timestamp = le16_to_cpu(last->res_count);
Expand Down
1 change: 1 addition & 0 deletions include/linux/firewire.h
Expand Up @@ -436,6 +436,7 @@ struct fw_iso_context {
int type;
int channel;
int speed;
bool drop_overflow_headers;
size_t header_size;
union {
fw_iso_callback_t sc;
Expand Down
4 changes: 2 additions & 2 deletions include/uapi/linux/firewire-cdev.h
Expand Up @@ -215,8 +215,8 @@ struct fw_cdev_event_request2 {
* with the %FW_CDEV_ISO_INTERRUPT bit set, when explicitly requested with
* %FW_CDEV_IOC_FLUSH_ISO, or when there have been so many completed packets
* without the interrupt bit set that the kernel's internal buffer for @header
* is about to overflow. (In the last case, kernels with ABI version < 5 drop
* header data up to the next interrupt packet.)
* is about to overflow. (In the last case, ABI versions < 5 drop header data
* up to the next interrupt packet.)
*
* Isochronous transmit events (context type %FW_CDEV_ISO_CONTEXT_TRANSMIT):
*
Expand Down

0 comments on commit 0699a73

Please sign in to comment.