drivers/thunderbolt/path.c
Source file repositories/reference/linux-study-clean/drivers/thunderbolt/path.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/thunderbolt/path.c- Extension
.c- Size
- 16124 bytes
- Lines
- 619
- Domain
- Driver Families
- Bucket
- drivers/thunderbolt
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hlinux/errno.hlinux/delay.hlinux/ktime.htb.h
Detected Declarations
function Copyrightfunction tb_path_find_src_hopidfunction tb_path_discoverfunction tb_path_allocfunction tb_path_freefunction __tb_path_deallocate_nfcfunction __tb_path_deactivate_hopfunction tb_path_deactivate_hopfunction __tb_path_deactivate_hopsfunction tb_path_deactivatefunction tb_path_activatefunction tb_path_is_invalidfunction tb_path_port_on_path
Annotated Snippet
if (ret) {
tb_port_warn(port, "failed to read path at %d\n", hopid);
return NULL;
}
if (!hop.enable)
return NULL;
out_port = &sw->ports[hop.out_port];
hopid = hop.next_hop;
port = out_port->remote;
}
return out_port && hopid == dst_hopid ? out_port : NULL;
}
static int tb_path_find_src_hopid(struct tb_port *src,
const struct tb_port *dst, int dst_hopid)
{
struct tb_port *out;
int i;
for (i = TB_PATH_MIN_HOPID; i <= src->config.max_in_hop_id; i++) {
out = tb_path_find_dst_port(src, i, dst_hopid);
if (out == dst)
return i;
}
return 0;
}
/**
* tb_path_discover() - Discover a path
* @src: First input port of a path
* @src_hopid: Starting HopID of a path (%-1 if don't care)
* @dst: Expected destination port of the path (%NULL if don't care)
* @dst_hopid: HopID to the @dst (%-1 if don't care)
* @last: Last port is filled here if not %NULL
* @name: Name of the path
* @alloc_hopid: Allocate HopIDs for the ports
*
* Follows a path starting from @src and @src_hopid to the last output
* port of the path. Allocates HopIDs for the visited ports (if
* @alloc_hopid is true). Call tb_path_free() to release the path and
* allocated HopIDs when the path is not needed anymore.
*
* Note function discovers also incomplete paths so caller should check
* that the @dst port is the expected one. If it is not, the path can be
* cleaned up by calling tb_path_deactivate() before tb_path_free().
*
* Return: Pointer to &struct tb_path, %NULL in case of failure.
*/
struct tb_path *tb_path_discover(struct tb_port *src, int src_hopid,
struct tb_port *dst, int dst_hopid,
struct tb_port **last, const char *name,
bool alloc_hopid)
{
struct tb_port *out_port;
struct tb_regs_hop hop;
struct tb_path *path;
struct tb_switch *sw;
struct tb_port *p;
size_t num_hops;
int ret, i, h;
if (src_hopid < 0 && dst) {
/*
* For incomplete paths the intermediate HopID can be
* different from the one used by the protocol adapter
* so in that case find a path that ends on @dst with
* matching @dst_hopid. That should give us the correct
* HopID for the @src.
*/
src_hopid = tb_path_find_src_hopid(src, dst, dst_hopid);
if (!src_hopid)
return NULL;
}
p = src;
h = src_hopid;
num_hops = 0;
for (i = 0; p && i < TB_PATH_MAX_HOPS; i++) {
sw = p->sw;
ret = tb_port_read(p, &hop, TB_CFG_HOPS, 2 * h, 2);
if (ret) {
tb_port_warn(p, "failed to read path at %d\n", h);
return NULL;
}
Annotation
- Immediate include surface: `linux/slab.h`, `linux/errno.h`, `linux/delay.h`, `linux/ktime.h`, `tb.h`.
- Detected declarations: `function Copyright`, `function tb_path_find_src_hopid`, `function tb_path_discover`, `function tb_path_alloc`, `function tb_path_free`, `function __tb_path_deallocate_nfc`, `function __tb_path_deactivate_hop`, `function tb_path_deactivate_hop`, `function __tb_path_deactivate_hops`, `function tb_path_deactivate`.
- Atlas domain: Driver Families / drivers/thunderbolt.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.