in switch.c [730:791]
static int tb_init_port(struct tb_port *port)
{
int res;
int cap;
INIT_LIST_HEAD(&port->list);
/* Control adapter does not have configuration space */
if (!port->port)
return 0;
res = tb_port_read(port, &port->config, TB_CFG_PORT, 0, 8);
if (res) {
if (res == -ENODEV) {
tb_dbg(port->sw->tb, " Port %d: not implemented\n",
port->port);
port->disabled = true;
return 0;
}
return res;
}
/* Port 0 is the switch itself and has no PHY. */
if (port->config.type == TB_TYPE_PORT) {
cap = tb_port_find_cap(port, TB_PORT_CAP_PHY);
if (cap > 0)
port->cap_phy = cap;
else
tb_port_WARN(port, "non switch port without a PHY\n");
cap = tb_port_find_cap(port, TB_PORT_CAP_USB4);
if (cap > 0)
port->cap_usb4 = cap;
/*
* USB4 ports the buffers allocated for the control path
* can be read from the path config space. Legacy
* devices we use hard-coded value.
*/
if (tb_switch_is_usb4(port->sw)) {
struct tb_regs_hop hop;
if (!tb_port_read(port, &hop, TB_CFG_HOPS, 0, 2))
port->ctl_credits = hop.initial_credits;
}
if (!port->ctl_credits)
port->ctl_credits = 2;
} else {
cap = tb_port_find_cap(port, TB_PORT_CAP_ADAP);
if (cap > 0)
port->cap_adap = cap;
}
port->total_credits =
(port->config.nfc_credits & ADP_CS_4_TOTAL_BUFFERS_MASK) >>
ADP_CS_4_TOTAL_BUFFERS_SHIFT;
tb_dump_port(port->sw->tb, port);
return 0;
}