STRUCT SPI_IOC_TRANSFER(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

✨ struct spi_ioc_transfer(9) β€” like, the whole entire vibe ✨

okay bestie, welcome to the Kernel API Manual πŸ’– this is the page for struct spi_ioc_transfer, and by the end you're gonna know it like the back of your hand. no cap.


🌸 NAME 🌸

struct spi_ioc_transfer β€” it describes a single SPI transfer. one. that's the whole job. icon behavior honestly πŸ‘‘


πŸ¦‹ SYNOPSIS πŸ¦‹

struct spi_ioc_transfer {
    __u64 tx_buf;
    __u64 rx_buf;
    __u32 len;
    __u32 speed_hz;
    __u16 delay_usecs;
    __u8 bits_per_word;
    __u8 cs_change;
    __u8 tx_nbits;
    __u8 rx_nbits;
    __u8 word_delay_usecs;
    __u8 pad;
 };

look at her. so structured. so demure. πŸŽ€ (yes the closing brace has a lil space before it in the original, we do not judge, we respect)


πŸŽ€ Members πŸŽ€

okay so each field, one by one, no skipping, i promised:

  • tx_buf β€” holds a pointer to the userspace buffer with your transmit data, or null. and if you give it no data at all? zeroes get shifted out. free real estate ✨
  • rx_buf β€” holds a pointer to the userspace buffer for receive data, or null. that's it. that's the field.
  • len β€” the length of the tx and rx buffers, in bytes. both of them. yes. same number. 🫢
  • speed_hz β€” a temporary override of the device's bitrate. temporary! like a weekend trip, not a move-in πŸ’…
  • delay_usecs β€” if nonzero, this is how long to delay after the last bit transfer, before optionally deselecting the device before the next transfer. key word: after. πŸ•
  • bits_per_word β€” temporary override of the device's wordsize. again with the temporary. she's just visiting 🌸
  • cs_change β€” true to deselect the device before starting the next transfer. bold move, love that for you πŸ’€
  • word_delay_usecs β€” if nonzero, how long to wait between words within one transfer. 🚨 but this one needs explicit support in the SPI controller β€” otherwise it is silently ignored. silently!! she will not tell you!! no warning, no text, nothing 😭
  • pad β€” it's padding. she's here for the vibes and the alignment. we zero her anyway (more on that in a sec) πŸ’œ
also, tx_nbits and rx_nbits are literally sitting right there in the struct, being listed in the SYNOPSIS like the main characters they are, and the Members list does not say a single word about them. love that for them. i'm not gonna invent lore. i'm just saying. πŸ‘€

πŸ’… Description πŸ’…

so this structure is mapped directly to the kernel spi_transfer structure. same fields, same meanings β€” the only ✨exception✨ is that, of course, the pointers live in a different address space (and ngl they may be different sizes in some cases, like 32-bit i386 userspace running over a 64-bit x86_64 kernel 🫠).

Zero-initialize the structure, including the currently unused fields. yes, all of them, even the ones you think are dead. this is so you accommodate potential future updates. future-proofing is self-care πŸ§–β€β™€οΈ

now, SPI_IOC_MESSAGE gives userspace the equivalent of kernel spi_sync. what you do is pass it an array of related transfers, and they'll execute together β€” besties who arrive as a group 🫢 each transfer may be half duplex (either direction) or full duplex. choose your fighter.

struct spi_ioc_transfer mesg[4];
...
status = ioctl(fd, SPI_IOC_MESSAGE(4), mesg);

so for example (and this is genuinely iconic, watch this): one transfer might send a nine bit command (right aligned in a 16-bit word), the next could read a block of 8-bit data before terminating that command by temporarily deselecting the chip; the next could send a different nine bit command (re-selecting the chip), and the last transfer might write some register values. four transfers. one group chat. one ioctl. ate. πŸ”₯


πŸ”₯ SEE ALSO πŸ”₯

  • Kernel file ./include/uapi/linux/spi/spidev.h β€” go read the source, bestie, it's giving primary source realness πŸ“–

⭐ reminder before you go: zero-initialize everything, and do not expect word_delay_usecs to work without explicit controller support, because she will ghost you without a single error message. consider yourself warned πŸŽ€

🌈 that's the page!! brought to you by ./include/uapi/linux/spi, dated October 2026, and honestly? the October 2026 of it all. she's from the future and she's slaying πŸ’œ mwah, go write some drivers 🫢✨

πŸ“¦ where this page comes from