From d69397ae8f3519cf291ba2efc173ad257376cf0d Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 9 Dec 2008 00:08:35 -0500 Subject: [PATCH] Fix iso_shutdown with juju firewire stack Make iso start/stop/start sequences on the same handle, such as those used by apps such as MythTV behave as expected. I can finally watch video off my cable box over FireWire using MythTV w/the juju stack now. :) Initially, seemed a one-liner might be the ticket (setting handle->iso.fd = -1 at the end of fw_iso_shutdown()), but that led to memory corruption and a locked up system. What ultimately worked was essentially mimicking what the old stack did to track iso state, and call fw_iso_stop() from fw_iso_shutdown() as needed. Nb: Only lightly tested with iso receive via MythTV, but its all fairly straight-forward, I think. Signed-off-by: Jarod Wilson Signed-off-by: Dan Dennedy --- src/fw-iso.c | 24 +++++++++++++++++++++--- src/fw.h | 1 + 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/fw-iso.c b/src/fw-iso.c index a696ba1..6a84662 100644 --- a/src/fw-iso.c +++ b/src/fw-iso.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 8 -*- * - * raw1394-iso.c -- Emulation of the raw1394 rawiso API on the firewire stack + * fw-iso.c -- Emulation of the raw1394 rawiso API on the firewire stack * * Copyright (C) 2007 Kristian Hoegsberg * @@ -141,7 +141,14 @@ int fw_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, return retval; } - return queue_xmit_packets(handle, fwhandle->iso.buf_packets); + retval = queue_xmit_packets(handle, fwhandle->iso.buf_packets); + + if (retval) + return -1; + else + fwhandle->iso.state = ISO_ACTIVE; + + return 0; } static int @@ -224,7 +231,12 @@ int fw_iso_recv_start(fw_handle_t handle, int start_on_cycle, start_iso.sync = 0; start_iso.handle = 0; - return ioctl(handle->iso.fd, FW_CDEV_IOC_START_ISO, &start_iso); + if (ioctl(handle->iso.fd, FW_CDEV_IOC_START_ISO, &start_iso)) + return -1; + else + handle->iso.state = ISO_ACTIVE; + + return 0; } static int handle_iso_event(raw1394handle_t handle, @@ -445,6 +457,7 @@ iso_init(fw_handle_t handle, int type, handle->iso.head = handle->iso.buffer; handle->iso.tail = handle->iso.buffer; handle->iso.first_payload = handle->iso.buffer; + handle->iso.state = ISO_STOPPED; return 0; } @@ -521,15 +534,20 @@ void fw_iso_stop(fw_handle_t handle) handle->iso.first_payload = handle->iso.buffer; handle->iso.packet_phase = 0; handle->iso.packet_count = 0; + handle->iso.packet_index = 0; + handle->iso.state = ISO_STOPPED; } void fw_iso_shutdown(fw_handle_t handle) { munmap(handle->iso.buffer, handle->iso.buf_packets * handle->iso.max_packet_size); + if (handle->iso.state != ISO_STOPPED) + fw_iso_stop(handle); close(handle->iso.fd); free(handle->iso.packets); handle->iso.packets = NULL; + handle->iso.fd = -1; } int fw_read_cycle_timer(fw_handle_t handle, diff --git a/src/fw.h b/src/fw.h index 5b99245..56b59d9 100644 --- a/src/fw.h +++ b/src/fw.h @@ -129,6 +129,7 @@ struct fw_handle { int prebuffer; int start_on_cycle; enum raw1394_iso_dma_recv_mode recv_mode; + enum { ISO_STOPPED, ISO_ACTIVE } state; raw1394_iso_xmit_handler_t xmit_handler; raw1394_iso_recv_handler_t recv_handler; unsigned char *buffer, *buffer_end, *head;