drivers/thunderbolt/tunnel.c
Source file repositories/reference/linux-study-clean/drivers/thunderbolt/tunnel.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/thunderbolt/tunnel.c- Extension
.c- Size
- 68697 bytes
- Lines
- 2649
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/delay.hlinux/slab.hlinux/list.hlinux/ktime.hlinux/string_helpers.htunnel.htb.h
Detected Declarations
function tb_usable_creditsfunction tb_available_creditsfunction tb_init_pm_supportfunction tb_tunnel_getfunction tb_tunnel_destroyfunction tb_tunnel_putfunction tb_tunnel_eventfunction tb_tunnel_set_activefunction tb_tunnel_changedfunction tb_pci_set_ext_encapsulationfunction tb_pci_activatefunction tb_pci_init_creditsfunction tb_pci_init_pathfunction tb_path_for_each_hopfunction tb_tunnel_discover_pcifunction tb_tunnel_alloc_pcifunction tb_tunnel_reserved_pcifunction tb_dp_is_usb4function tb_dp_cm_handshakefunction tb_dp_cap_get_ratefunction tb_dp_cap_get_rate_extfunction tb_dp_is_uhbr_ratefunction tb_dp_cap_set_ratefunction tb_dp_cap_get_lanesfunction tb_dp_cap_set_lanesfunction tb_dp_bandwidthfunction tb_dp_reduce_bandwidthfunction tb_dp_xchg_capsfunction tb_dp_bandwidth_alloc_mode_enablefunction tb_dp_pre_activatefunction tb_dp_post_deactivatefunction dprx_timeout_to_ktimefunction tb_dp_wait_dprxfunction tb_dp_dprx_workfunction tb_dp_dprx_startfunction tb_dp_dprx_stopfunction tb_dp_activatefunction tb_dp_bandwidth_mode_maximum_bandwidthfunction tb_dp_bandwidth_mode_consumed_bandwidthfunction tb_dp_allocated_bandwidthfunction tb_dp_alloc_bandwidthfunction tb_dp_read_capfunction tb_dp_maximum_bandwidthfunction tb_dp_consumed_bandwidthfunction tb_dp_init_aux_creditsfunction tb_dp_init_aux_pathfunction tb_path_for_each_hopfunction tb_dp_init_video_credits
Annotated Snippet
if (tb_dp_bandwidth(dp_bw[i][0], dp_bw[i][1]) <= max_bw) {
*new_rate = dp_bw[i][0];
*new_lanes = dp_bw[i][1];
return 0;
}
}
return -ENOSR;
}
static int tb_dp_xchg_caps(struct tb_tunnel *tunnel)
{
u32 out_dp_cap, out_rate, out_lanes, in_dp_cap, in_rate, in_lanes, bw;
struct tb_port *out = tunnel->dst_port;
struct tb_port *in = tunnel->src_port;
int ret, max_bw;
/*
* Copy DP_LOCAL_CAP register to DP_REMOTE_CAP register for
* newer generation hardware.
*/
if (in->sw->generation < 2 || out->sw->generation < 2)
return 0;
/*
* Perform connection manager handshake between IN and OUT ports
* before capabilities exchange can take place.
*/
ret = tb_dp_cm_handshake(in, out, 3000);
if (ret)
return ret;
/* Read both DP_LOCAL_CAP registers */
ret = tb_port_read(in, &in_dp_cap, TB_CFG_PORT,
in->cap_adap + DP_LOCAL_CAP, 1);
if (ret)
return ret;
ret = tb_port_read(out, &out_dp_cap, TB_CFG_PORT,
out->cap_adap + DP_LOCAL_CAP, 1);
if (ret)
return ret;
/* Write IN local caps to OUT remote caps */
ret = tb_port_write(out, &in_dp_cap, TB_CFG_PORT,
out->cap_adap + DP_REMOTE_CAP, 1);
if (ret)
return ret;
in_rate = tb_dp_cap_get_rate(in_dp_cap);
in_lanes = tb_dp_cap_get_lanes(in_dp_cap);
tb_tunnel_dbg(tunnel,
"DP IN maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n",
in_rate, in_lanes, tb_dp_bandwidth(in_rate, in_lanes));
/*
* If the tunnel bandwidth is limited (max_bw is set) then see
* if we need to reduce bandwidth to fit there.
*/
out_rate = tb_dp_cap_get_rate(out_dp_cap);
out_lanes = tb_dp_cap_get_lanes(out_dp_cap);
bw = tb_dp_bandwidth(out_rate, out_lanes);
tb_tunnel_dbg(tunnel,
"DP OUT maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n",
out_rate, out_lanes, bw);
if (tb_tunnel_direction_downstream(tunnel))
max_bw = tunnel->max_down;
else
max_bw = tunnel->max_up;
if (max_bw && bw > max_bw) {
u32 new_rate, new_lanes, new_bw;
ret = tb_dp_reduce_bandwidth(max_bw, in_rate, in_lanes,
out_rate, out_lanes, &new_rate,
&new_lanes);
if (ret) {
tb_tunnel_info(tunnel, "not enough bandwidth\n");
return ret;
}
new_bw = tb_dp_bandwidth(new_rate, new_lanes);
tb_tunnel_dbg(tunnel,
"bandwidth reduced to %u Mb/s x%u = %u Mb/s\n",
new_rate, new_lanes, new_bw);
/*
* Set new rate and number of lanes before writing it to
* the IN port remote caps.
Annotation
- Immediate include surface: `linux/delay.h`, `linux/slab.h`, `linux/list.h`, `linux/ktime.h`, `linux/string_helpers.h`, `tunnel.h`, `tb.h`.
- Detected declarations: `function tb_usable_credits`, `function tb_available_credits`, `function tb_init_pm_support`, `function tb_tunnel_get`, `function tb_tunnel_destroy`, `function tb_tunnel_put`, `function tb_tunnel_event`, `function tb_tunnel_set_active`, `function tb_tunnel_changed`, `function tb_pci_set_ext_encapsulation`.
- Atlas domain: Driver Families / drivers/thunderbolt.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.