STRUCT TB_SWITCH(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

✨ NAME ✨

struct tb_switch β€” a thunderbolt switch, bestie πŸ’… (and yeah, this is that tb_switch(9) page you were looking for)

Okay so real quick β€” this is a page from the Kernel API Manual, and it's lowkey all about one struct. Buckle up, she's a big one πŸŽ€


🌸 SYNOPSIS 🌸

struct tb_switch {
    struct device dev;
    struct tb_regs_switch_header config;
    struct tb_port *ports;
    struct tb_dma_port *dma_port;
    struct tb_switch_tmu tmu;
    struct tb *tb;
    u64 uid;
    uuid_t *uuid;
    u16 vendor;
    u16 device;
    const char *vendor_name;
    const char *device_name;
    unsigned int link_speed;
    enum tb_link_width link_width;
    enum tb_link_width preferred_link_width;
    bool link_usb4;
    unsigned int generation;
    int cap_plug_events;
    int cap_vsec_tmu;
    int cap_lc;
    int cap_lp;
    bool is_unplugged;
    u8 *drom;
    struct tb_nvm *nvm;
    bool no_nvm_upgrade;
    bool safe_mode;
    bool boot;
    bool rpm;
    unsigned int authorized;
    enum tb_security_level security_level;
    struct dentry *debugfs_dir;
    u8 *key;
    u8 connection_id;
    u8 connection_key;
    u8 link;
    u8 depth;
    struct completion rpm_complete;
    unsigned long quirks;
    bool credit_allocation;
    unsigned int max_usb3_credits;
    unsigned int min_dp_aux_credits;
    unsigned int min_dp_main_credits;
    unsigned int max_pcie_credits;
    unsigned int max_dma_credits;
    unsigned int clx;
  #ifdef CONFIG_DEBUG_FS;
    struct debugfs_blob_wrapper drom_blob;
  #endif;
};

No cap, that's the whole thing verbatim πŸ’€ copy it exactly, don't be cute with it.


πŸ¦‹ MEMBERS πŸ¦‹

Okay so every single field, one by one, no skipping, we're getting through this together 🫢

  • dev β€” The device for the switch. Her actual device struct, the whole reason she shows up in sysfs and all that.
  • config β€” The switch configuration. It's a struct tb_regs_switch_header, iykyk.
  • ports β€” The ports in this switch. Plural, she has many ✨
  • dma_port β€” So if the switch has a port that supports the DMA-configuration-based mailbox, this bad boy holds a pointer to it (NULL otherwise). And it's giving multipurpose, because if it's set, that also means the switch has upgradeable NVM πŸ‘‘
  • tmu β€” The switch TMU configuration.
  • tb β€” Pointer to the domain the switch belongs to.
  • uid β€” The unique ID of the switch. Very main character, very one-of-one πŸ’…
  • uuid β€” The UUID of the switch, or NULL if that's not supported.
  • vendor β€” Vendor ID of the switch.
  • device β€” Device ID of the switch.
  • vendor_name β€” Name of the vendor, or NULL if it's not known. Not us guessing, that's literally what the field says πŸ™ˆ
  • device_name β€” Name of the device, or NULL if it's not known.
  • link_speed β€” Speed of the link, in Gb/s.
  • link_width β€” Width of the upstream facing link.
  • preferred_link_width β€” The router's preferred link width, and heads up: this is only set for Gen 4 links πŸ‘€
  • link_usb4 β€” Whether the upstream link is USB4.
  • generation β€” The switch's Thunderbolt generation.
  • cap_plug_events β€” Offset to the plug events capability (0 if it's not found).
  • cap_vsec_tmu β€” Offset to the TMU vendor specific capability (0 if it's not found).
  • cap_lc β€” Offset to the link controller capability (0 if it's not found).
  • cap_lp β€” Offset to the low power (CLx for TBT) capability (0 if it's not found).
  • is_unplugged β€” The switch is going away 😭 yeah, she's leaving.
  • drom β€” The DROM of the switch (NULL if it's not found).
  • nvm β€” Pointer to the NVM if the switch has one (NULL otherwise).
  • no_nvm_upgrade β€” Prevents NVM upgrade of this switch. Respect the boundary 🚫
  • safe_mode β€” The switch is in safe-mode.
  • boot β€” Whether the switch was already authorized on boot or not.
  • rpm β€” The switch supports runtime PM.
  • authorized β€” Whether the switch is authorized by user or policy.
  • security_level β€” The switch's supported security level. It's an enum tb_security_level, look it up bestie πŸ”
  • debugfs_dir β€” Pointer to the debugfs structure.
  • key β€” Contains the key used to challenge the device, or NULL if it's not supported. Size of the key is TB_SWITCH_KEY_SIZE β€” write that down ✍️
  • connection_id β€” Connection ID used with ICM messaging.
  • connection_key β€” Connection key used with ICM messaging.
  • link β€” Root switch link this switch is connected to (ICM only).
  • depth β€” Depth in the chain this switch is connected at (ICM only).
  • rpm_complete β€” Completion used to wait for runtime resume to complete (ICM only).
  • quirks β€” Quirks used for this Thunderbolt switch. Everybody's got their little quirks fr fr πŸ’€
  • credit_allocation β€” Are the below buffer allocation parameters valid. She's the vibe check for the next five fields 🌈
  • max_usb3_credits β€” Router preferred number of buffers for USB 3.x.
  • min_dp_aux_credits β€” Router preferred minimum number of buffers for DP AUX. Note the minimum, don't get it twisted πŸŽ€
  • min_dp_main_credits β€” Router preferred minimum number of buffers for DP MAIN.
  • max_pcie_credits β€” Router preferred number of buffers for PCIe.
  • max_dma_credits β€” Router preferred number of buffers for DMA/P2P.
  • clx β€” CLx states on the upstream link of the router.
  • drom_blob β€” DROM debugfs blob wrapper. And psst β€” this one lives inside #ifdef CONFIG_DEBUG_FS;, so she only exists when debugfs is configured 🧚

πŸ’œ DESCRIPTION πŸ’œ

So here's the important bit, don't skip it:

When the switch is being added or removed to the domain (other switches), you need to have the domain lock held. πŸ”’ Like, non-negotiable. Hold the lock. That's the rule.

And in USB4 terminology, this structure represents a router. Same girl, different name, periodt πŸ’…


⭐ SEE ALSO ⭐

Kernel file ./drivers/thunderbolt/tb.h β€” and like, all of these, in one big group-chat of related pages:

struct tb_nvm(9), enum tb_switch_tmu_mode(9), struct tb_switch_tmu(9), struct tb_bandwidth_group(9), struct tb_port(9), struct usb4_port(9), struct tb_retimer(9), struct tb_path_hop(9), enum tb_path_port(9), struct tb_path(9), struct tb_cm_ops(9), tb_upstream_port(9), tb_is_upstream_port(9), tb_port_has_remote(9), tb_domain_event(9), tb_switch_for_each_port(9), tb_switch_downstream_port(9), tb_switch_depth(9), tb_switch_is_icm(9), tb_switch_tmu_is_configured(9), tb_switch_tmu_is_enabled(9), tb_switch_clx_is_enabled(9), tb_port_path_direction_downstream(9), tb_for_each_port_on_path(9), tb_for_each_upstream_port_on_path(9), tb_path_for_each_hop(9), tb_downstream_route(9), tb_xdomain_downstream_port(9), usb4_switch_version(9), tb_switch_is_usb4(9), enum usb4_sb_target(9), enum usb4_margin_sw_error_counter(9), struct usb4_port_margining_params(9)


That's the whole page, bestie β€” go read some kernel source, you ate this πŸ’–βœ¨

Signed off from ./drivers/thunderbolt, dated October 2026, page struct tb_switch(9) β€” mwah πŸŽ€πŸ«Ά

πŸ“¦ where this page comes from