firewire: allow explicit flushing of iso packet completions

Extend the kernel and userspace APIs to allow reporting all currently
completed isochronous packets, even if the next interrupt packet has not
yet been reached.  This is required to determine the status of the
packets at the end of a paused or stopped stream, and useful for more
precise synchronization of audio streams.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h
index b9bd349..d500369 100644
--- a/include/linux/firewire-cdev.h
+++ b/include/linux/firewire-cdev.h
@@ -212,10 +212,11 @@
  * @header:	Stripped headers, if any
  *
  * This event is sent when the controller has completed an &fw_cdev_iso_packet
- * with the %FW_CDEV_ISO_INTERRUPT bit set, 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 latter case, kernels with
- * ABI version < 5 drop header data up to the next interrupt packet.)
+ * 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.)
  *
  * Isochronous transmit events (context type %FW_CDEV_ISO_CONTEXT_TRANSMIT):
  *
@@ -271,7 +272,8 @@
  * This event is sent in multichannel contexts (context type
  * %FW_CDEV_ISO_CONTEXT_RECEIVE_MULTICHANNEL) for &fw_cdev_iso_packet buffer
  * chunks that have been completely filled and that have the
- * %FW_CDEV_ISO_INTERRUPT bit set.
+ * %FW_CDEV_ISO_INTERRUPT bit set, or when explicitly requested with
+ * %FW_CDEV_IOC_FLUSH_ISO.
  *
  * The buffer is continuously filled with the following data, per packet:
  *  - the 1394 iso packet header as described at &fw_cdev_event_iso_interrupt,
@@ -421,6 +423,9 @@
 #define FW_CDEV_IOC_RECEIVE_PHY_PACKETS _IOW('#', 0x16, struct fw_cdev_receive_phy_packets)
 #define FW_CDEV_IOC_SET_ISO_CHANNELS    _IOW('#', 0x17, struct fw_cdev_set_iso_channels)
 
+/* available since kernel version 3.4 */
+#define FW_CDEV_IOC_FLUSH_ISO           _IOW('#', 0x18, struct fw_cdev_flush_iso)
+
 /*
  * ABI version history
  *  1  (2.6.22)  - initial version
@@ -445,6 +450,7 @@
  *                 %FW_CDEV_IOC_SET_ISO_CHANNELS
  *  5  (3.4)     - send %FW_CDEV_EVENT_ISO_INTERRUPT events when needed to
  *                 avoid dropping data
+ *               - added %FW_CDEV_IOC_FLUSH_ISO
  */
 
 /**
@@ -855,6 +861,25 @@
 };
 
 /**
+ * struct fw_cdev_flush_iso - flush completed iso packets
+ * @handle:	handle of isochronous context to flush
+ *
+ * For %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE contexts,
+ * report any completed packets.
+ *
+ * For %FW_CDEV_ISO_CONTEXT_RECEIVE_MULTICHANNEL contexts, report the current
+ * offset in the receive buffer, if it has changed; this is typically in the
+ * middle of some buffer chunk.
+ *
+ * Any %FW_CDEV_EVENT_ISO_INTERRUPT or %FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL
+ * events generated by this ioctl are sent synchronously, i.e., are available
+ * for reading from the file descriptor when this ioctl returns.
+ */
+struct fw_cdev_flush_iso {
+	__u32 handle;
+};
+
+/**
  * struct fw_cdev_get_cycle_timer - read cycle timer register
  * @local_time:   system time, in microseconds since the Epoch
  * @cycle_timer:  Cycle Time register contents