STRUCT FW_CDEV_EVENT_ISO_INTERRUPT(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… NAME πŸ’…

struct fw_cdev_event_iso_interrupt β€” the little event that slides into your life when an iso packet finishes, bestie ✨

So this is the Kernel API Manual page for it, and yes we are going to read the whole thing together, no skimming 🫢


πŸ¦‹ SYNOPSIS πŸ¦‹

struct fw_cdev_event_iso_interrupt {
    __u64 closure;
    __u32 type;
    __u32 cycle;
    __u32 header_length;
    __u32 header[];
 };

That's the whole vibe, look at it, it's giving "small struct, big responsibilities" 😭


πŸŽ€ Members πŸŽ€

  • closure β€” ok so this one you don't set yourself; it's the common-event closure situation (peep fw_cdev_event_common), and it gets set by the FW_CDEV_CREATE_ISO_CONTEXT ioctl. Not your job, it's the kernel's job πŸ’…
  • type β€” again, common-event territory (fw_cdev_event_common), and it's always FW_CDEV_EVENT_ISO_INTERRUPT. Always. Periodt.
  • cycle β€” the cycle counter of the last completed packet ⭐
  • header_length β€” total length of the headers that follow, counted in bytes, no cap πŸ“
  • header β€” the stripped headers, if there are any. "if any" is doing a lot of heavy lifting there, iykyk πŸ™ˆ

✨ Description ✨

So when does this event actually show up? Three situations, bestie, and they're all valid:

  1. when the controller has completed an fw_cdev_iso_packet that had the FW_CDEV_ISO_INTERRUPT bit set πŸ”₯
  2. when it's explicitly requested with FW_CDEV_IOC_FLUSH_ISO 🌸
  3. 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 πŸ’€
And in that third case, heads up: ABI versions < 5 drop header data up to the next interrupt packet. Not a drill, that data is gone.

🌈 Isochronous transmit events (context type FW_CDEV_ISO_CONTEXT_TRANSMIT)

In version 3 and some implementations of version 2 of the ABI, header_length is a multiple of 4, and header contains timestamps of all packets up until the interrupt packet. The format of those timestamps is exactly as described below for isochronous reception πŸ‘‘ In version 1 of the ABI, header_length was 0. Iconic behaviour, honestly.

🧚 Isochronous receive events (context type FW_CDEV_ISO_CONTEXT_RECEIVE)

The headers stripped of all packets up until and including the interrupt packet are returned in the header field. The amount of header data per packet is as specified at iso context creation by fw_cdev_create_iso_context.header_size.

Hence, _interrupt.header_length / _context.header_size is the number of packets received in this interrupt event πŸŽ€ The client can now iterate through the mmap'ed DMA buffer according to this number of packets and to the buffer sizes as the client specified in fw_cdev_queue_iso. Go off, client.

Since version 2 of this ABI, the portion for each packet in _interrupt.header consists of the 1394 isochronous packet header, followed by a timestamp quadlet if fw_cdev_create_iso_context.header_size > 4, followed by quadlets from the packet payload if fw_cdev_create_iso_context.header_size > 8. Layered. Structured. We love a consistent format πŸ¦‹

Format of 1394 iso packet header: 16 bits data_length, 2 bits tag, 6 bits channel, 4 bits tcode, 4 bits sy, in big endian byte order. And data_length is the actual received size of the packet without the four 1394 iso packet header bytes. Don't forget that subtraction, bestie, it's a whole thing 😭

Format of timestamp: 16 bits invalid, 3 bits cycleSeconds, 13 bits cycleCount, in big endian byte order. Big endian supremacy, I guess 🌸

Ok and one historical note for the lore girlies: in version 1 of the ABI, no timestamp quadlet was inserted; instead, payload data followed directly after the 1394 is header if header_size > 4. But behaviour of ver. 1 of this ABI is no longer available since ABI ver. 2. RIP to a real one πŸ•―οΈ

πŸ’œ SEE ALSO πŸ’œ

Kernel file ./include/uapi/linux/firewire-cdev.h, plus the whole friend group:

  • struct fw_cdev_event_common(9)
  • struct fw_cdev_event_bus_reset(9)
  • struct fw_cdev_event_response(9)
  • struct fw_cdev_event_response2(9)
  • struct fw_cdev_event_request(9)
  • struct fw_cdev_event_request2(9)
  • struct fw_cdev_event_request3(9)
  • struct fw_cdev_event_iso_interrupt_mc(9)
  • struct fw_cdev_event_iso_resource(9)
  • struct fw_cdev_event_phy_packet(9)
  • struct fw_cdev_event_phy_packet2(9)
  • union fw_cdev_event(9)
  • struct fw_cdev_get_info(9)
  • struct fw_cdev_send_request(9)
  • struct fw_cdev_send_response(9)
  • struct fw_cdev_allocate(9)
  • struct fw_cdev_deallocate(9)
  • struct fw_cdev_initiate_bus_reset(9)
  • struct fw_cdev_add_descriptor(9)
  • struct fw_cdev_remove_descriptor(9)
  • struct fw_cdev_create_iso_context(9)
  • struct fw_cdev_set_iso_channels(9)
  • struct fw_cdev_iso_packet(9)
  • struct fw_cdev_queue_iso(9)
  • struct fw_cdev_start_iso(9)
  • struct fw_cdev_stop_iso(9)
  • struct fw_cdev_flush_iso(9)
  • struct fw_cdev_get_cycle_timer(9)
  • struct fw_cdev_get_cycle_timer2(9)
  • struct fw_cdev_allocate_iso_resource(9)
  • struct fw_cdev_send_stream_packet(9)
  • struct fw_cdev_send_phy_packet(9)
  • struct fw_cdev_receive_phy_packets(9)

And that's the page, bestie!! πŸ’– This one lives in ./include/uapi/linux, dated October 2026, section 9 of the manual β€” go forth and interrupt responsibly 🌟 slay βœ¨πŸŽ€

πŸ“¦ where this page comes from