/** * tb_init_port() - initialize a port * * This is a helper method for tb_switch_alloc. Does not check or initialize * any downstream switches. * * Return: Returns 0 on success or an error code on failure. */ static int tb_init_port(struct tb_port *port) { int res; int cap; res = tb_port_read(port, &port->config, TB_CFG_PORT, 0, 8); if (res) return res; /* Port 0 is the switch itself and has no PHY. */ if (port->config.type == TB_TYPE_PORT && port->port != 0) { cap = tb_find_cap(port, TB_CFG_PORT, TB_CAP_PHY); if (cap > 0) port->cap_phy = cap; else tb_port_WARN(port, "non switch port without a PHY\n"); } tb_dump_port(port->sw->tb, &port->config); /* TODO: Read dual link port, DP port and more from EEPROM. */ return 0; }
static int tb_drom_parse_entry(struct tb_switch *sw, struct tb_drom_entry_header *header) { struct tb_port *port; int res; enum tb_port_type type; if (header->type != TB_DROM_ENTRY_PORT) return 0; port = &sw->ports[header->index]; port->disabled = header->port_disabled; if (port->disabled) return 0; res = tb_port_read(port, &type, TB_CFG_PORT, 2, 1); if (res) return res; type &= 0xffffff; if (type == TB_TYPE_PORT) { struct tb_drom_entry_port *entry = (void *) header; if (header->len != sizeof(*entry)) { tb_sw_warn(sw, "port entry has size %#x (expected %#zx)\n", header->len, sizeof(struct tb_drom_entry_port)); return -EIO; } tb_drom_parse_port_entry(port, entry); } return 0; }
/** * tb_port_state() - get connectedness state of a port * * The port must have a TB_CAP_PHY (i.e. it should be a real port). * * Return: Returns an enum tb_port_state on success or an error code on failure. */ static int tb_port_state(struct tb_port *port) { struct tb_cap_phy phy; int res; if (port->cap_phy == 0) { tb_port_WARN(port, "does not have a PHY\n"); return -EINVAL; } res = tb_port_read(port, &phy, TB_CFG_PORT, port->cap_phy, 2); if (res) return res; return phy.state; }