STRUCT FW_CDEV_ALLOCATE(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’– struct fw_cdev_allocate(9) πŸ’–

okay bestie, welcome to the Kernel API Manual ✨ β€” this is the page for struct fw_cdev_allocate, and it's genuinely iconic. it's basically how you claim a little slice of the 48-bit address space on your local node and go "this is MINE, requests please πŸ™". let's get into it πŸŽ€


🌸 SYNOPSIS 🌸

struct fw_cdev_allocate {
    __u64 offset;
    __u64 closure;
    __u32 length;
    __u32 handle;
    __u64 region_end;
 };

like, look at her. five fields. main character struct energy fr fr πŸ‘‘


πŸ” Members πŸ”

  • offset β€” the start offset of the address range. where your little kingdom begins ✨
  • closure β€” this lil guy gets passed right back to userspace in request events, so it's basically your personal note-to-self that comes home to you 🫢
  • length β€” how long the CSR is, in bytes. the size of the vibe πŸ’…
  • handle β€” the handle to the allocation, and heads up: this one is written by the kernel for you, not by you. it's an out param, slay πŸŽ€
  • region_end β€” the first address above the address range. (added in ABI v4, 2.6.36) πŸ¦‹

🌈 Description 🌈

so what does it actually DO. it allocates an address range in the 48-bit address space on the local node (the controller). this lets userspace listen for requests whose offset lands inside that address range β€” like having your very own doorman πŸ˜­πŸ’–

every single time the kernel receives a request within the range, an fw_cdev_event_request2 event gets emitted. (and if the kernel or the client is implementing ABI version <= 3, then an fw_cdev_event_request is generated instead β€” vintage behavior, we respect the elders πŸ™ˆ)

the closure field is passed back to userspace in these request events. the handle field is an out parameter, returning a handle to the allocated range β€” and you're gonna use that for later deallocation of the range, so don't lose it, bestie πŸ’€

the address range is allocated on all local nodes. the address allocation is exclusive β€” except for the FCP command and response registers, those get special treatment πŸ‘‘. and this is the important part: if an exclusive address region is already in use, the ioctl fails with errno set to EBUSY. no cap, it just says no.

⚠️ warning-adjacent but make it cute: EBUSY means somebody else already called dibs. it's not a bug, it's a boundary πŸ’…

if kernel and client implement ABI version >= 4, the kernel looks up a free spot of size length inside [offset..region_end) and, if found, writes the start address of the new CSR back in offset. i.e. offset is an in and out parameter β€” it goes in and comes back changed, little glow-up ✨. and if this automatic placement of a CSR in a bigger address range is not desired, you simply set region_end = offset + length. that's the whole trick, iykyk.

if the kernel or the client implements ABI version <= 3, then region_end is ignored and effectively assumed to be offset + length. she's not even in the room 😭

region_end is only present in a kernel header >= 2.6.36. if necessary, this can for example be tested by #ifdef FW_CDEV_EVENT_REQUEST2 β€” yes, the preprocessor is your friend here, we love conditional compilation 🧚


πŸ“š SEE ALSO πŸ“š

all the lore, in order β€” go read the whole friend group 🌸:

  • Kernel file ./include/uapi/linux/firewire-cdev.h 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(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_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)

aaand that's the page!! tysm for reading, you ate that πŸ“πŸ’œ

πŸŽ€ sign-off time: this lil masterpiece lives in ./include/uapi/linux, and it was dated October 2026. periodt. write that down. 🌟
πŸ“¦ where this page comes from