STRUCT STM_DATA(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸŽ€ NAME πŸŽ€

hiii bestie, welcome to the Kernel API Manual πŸ’– β€” this page is literally all about struct stm_data, aka the STM device description and callbacks. Yeah, both. It's giving dual-threat main character energy ✨


🌸 SYNOPSIS 🌸

okay so here's the whole struct, no cap, every single field:

struct stm_data {
    const char              *name;
    struct stm_device       *stm;
    unsigned int            sw_start;
    unsigned int            sw_end;
    unsigned int            sw_nchannels;
    unsigned int            sw_mmiosz;
    unsigned int            hw_override;
    ssize_t (*packet)(struct stm_data *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, const unsigned char *);
    phys_addr_t (*mmio_addr)(struct stm_data *, unsigned int, unsigned int, unsigned int);
    int (*link)(struct stm_data *, unsigned int, unsigned int);
    void (*unlink)(struct stm_data *, unsigned int, unsigned int);
    long (*set_options)(struct stm_data *, unsigned int, unsigned int, unsigned int, unsigned long);
 };

πŸ¦‹ Members πŸ¦‹

okay so let's go field by field, i'm obsessed with how tidy this is 🫢

  • name β€” the device name 🏷️
  • stm β€” the internal structure, and it's only used by stm class code β€” so like, don't touch it, that's not your lane 😌
  • sw_start β€” the first STP master available to software
  • sw_end β€” the last STP master available to software
  • sw_nchannels β€” number of STP channels per master
  • sw_mmiosz β€” size of one channel's IO space, for mmap, and it's optional πŸ’…
  • hw_override β€” when this is set, the masters in the STP stream will not match the ones assigned by software β€” nope, they're up to the STM hardware 😳
  • packet β€” callback that sends an STP packet
  • mmio_addr β€” the mmap callback, optional
  • link β€” called when a new stm_source gets linked to us, optional
  • unlink β€” likewise for unlinking, again optional
  • set_options β€” set device-specific options on a channel

πŸ’œ Description πŸ’œ

so here's the vibe: you fill out this structure before calling stm_register_device to create an STM device, and stm_unregister_device to destroy it 🌈. And lowkey it also gets passed back to the packet, mmio_addr, link, unlink and set_options callbacks. so it's like, everywhere. iconic.

Normally an STM device will have a range of masters available to software, and the rest are statically assigned to various hardware trace sources ✨. That former bit is defined by the range [sw_start..sw_end] of the device description. So like β€” the lowest master that can be allocated to software writers is sw_start, and data from this writer will appear in the sw_start master in the STP stream πŸ‘‘

The packet callback should adhere to the following rules, fr fr, no vibing your way around these:

  1. it must return the number of bytes it consumed from the payload
  2. therefore, if it sent a packet that does not have payload (like FLAG), it must return zero
  3. if it does not support the requested packet type/flag combination, it must return -ENOTSUPP
⚠️ bestie please internalise rule 3, -ENOTSUPP is the whole point β€” don't just return whatever 😭

The unlink callback is called when there are no more active writers, so that the master/channel can be quiesced πŸ’€


⭐ SEE ALSO ⭐

Kernel file ./include/linux/stm.h β€” and while you're there, go say hi to enum stp_packet_type(9), enum stp_packet_flags(9), enum stm_source_type(9), and struct stm_source_data(9) πŸ¦‹


and that's the page!! πŸŽ€ this came out of ./include/linux, dated October 2026, from the Kernel API Manual β€” slay, go build something iconic, mwah πŸ’–βœ¨

πŸ“¦ where this page comes from