static enum sci_status sci_apc_agent_validate_phy_configuration(struct isci_host *ihost, struct sci_port_configuration_agent *port_agent) { u8 phy_index; u8 port_index; struct sci_sas_address sas_address; struct sci_sas_address phy_assigned_address; phy_index = 0; while (phy_index < SCI_MAX_PHYS) { port_index = phy_index; sci_phy_get_sas_address(&ihost->phys[phy_index], &sas_address); while (++phy_index < SCI_MAX_PHYS) { sci_phy_get_sas_address(&ihost->phys[phy_index], &phy_assigned_address); if (sci_sas_address_compare(sas_address, phy_assigned_address) == 0) { port_agent->phy_valid_port_range[phy_index].min_index = port_index; port_agent->phy_valid_port_range[phy_index].max_index = phy_index; } else { port_agent->phy_valid_port_range[phy_index].min_index = phy_index; port_agent->phy_valid_port_range[phy_index].max_index = phy_index; break; } } } return sci_port_configuration_agent_validate_ports(ihost, port_agent); }
/* verify phys are assigned a valid SAS address for automatic port * configuration mode. */ static enum sci_status sci_apc_agent_validate_phy_configuration(struct isci_host *ihost, struct sci_port_configuration_agent *port_agent) { u8 phy_index; u8 port_index; struct sci_sas_address sas_address; struct sci_sas_address phy_assigned_address; phy_index = 0; while (phy_index < SCI_MAX_PHYS) { port_index = phy_index; /* Get the assigned SAS Address for the first PHY on the controller. */ sci_phy_get_sas_address(&ihost->phys[phy_index], &sas_address); while (++phy_index < SCI_MAX_PHYS) { sci_phy_get_sas_address(&ihost->phys[phy_index], &phy_assigned_address); /* Verify each of the SAS address are all the same for every PHY */ if (sci_sas_address_compare(sas_address, phy_assigned_address) == 0) { port_agent->phy_valid_port_range[phy_index].min_index = port_index; port_agent->phy_valid_port_range[phy_index].max_index = phy_index; } else { port_agent->phy_valid_port_range[phy_index].min_index = phy_index; port_agent->phy_valid_port_range[phy_index].max_index = phy_index; break; } } } return sci_port_configuration_agent_validate_ports(ihost, port_agent); }
static enum sci_status sci_mpc_agent_validate_phy_configuration(struct isci_host *ihost, struct sci_port_configuration_agent *port_agent) { u32 phy_mask; u32 assigned_phy_mask; struct sci_sas_address sas_address; struct sci_sas_address phy_assigned_address; u8 port_index; u8 phy_index; assigned_phy_mask = 0; sas_address.high = 0; sas_address.low = 0; for (port_index = 0; port_index < SCI_MAX_PORTS; port_index++) { phy_mask = ihost->oem_parameters.ports[port_index].phy_mask; if (!phy_mask) continue; if ((phy_mask & ~assigned_phy_mask) == 0) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; } for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) { if ((phy_mask & (1 << phy_index)) == 0) continue; sci_phy_get_sas_address(&ihost->phys[phy_index], &sas_address); port_agent->phy_valid_port_range[phy_index].min_index = port_index; port_agent->phy_valid_port_range[phy_index].max_index = phy_index; if (phy_index != port_index) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; } break; } while (phy_index < SCI_MAX_PHYS) { if ((phy_mask & (1 << phy_index)) == 0) continue; sci_phy_get_sas_address(&ihost->phys[phy_index], &phy_assigned_address); if (sci_sas_address_compare(sas_address, phy_assigned_address) != 0) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; } port_agent->phy_valid_port_range[phy_index].min_index = port_index; port_agent->phy_valid_port_range[phy_index].max_index = phy_index; sci_port_add_phy(&ihost->ports[port_index], &ihost->phys[phy_index]); assigned_phy_mask |= (1 << phy_index); } phy_index++; } return sci_port_configuration_agent_validate_ports(ihost, port_agent); }
/* verify all of the phys in the same port are using the same SAS address */ static enum sci_status sci_mpc_agent_validate_phy_configuration(struct isci_host *ihost, struct sci_port_configuration_agent *port_agent) { u32 phy_mask; u32 assigned_phy_mask; struct sci_sas_address sas_address; struct sci_sas_address phy_assigned_address; u8 port_index; u8 phy_index; assigned_phy_mask = 0; sas_address.high = 0; sas_address.low = 0; for (port_index = 0; port_index < SCI_MAX_PORTS; port_index++) { phy_mask = ihost->oem_parameters.ports[port_index].phy_mask; if (!phy_mask) continue; /* * Make sure that one or more of the phys were not already assinged to * a different port. */ if ((phy_mask & ~assigned_phy_mask) == 0) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; } /* Find the starting phy index for this round through the loop */ for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) { if ((phy_mask & (1 << phy_index)) == 0) continue; sci_phy_get_sas_address(&ihost->phys[phy_index], &sas_address); /* * The phy_index can be used as the starting point for the * port range since the hardware starts all logical ports * the same as the PE index. */ port_agent->phy_valid_port_range[phy_index].min_index = port_index; port_agent->phy_valid_port_range[phy_index].max_index = phy_index; if (phy_index != port_index) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; } break; } /* * See how many additional phys are being added to this logical port. * Note: We have not moved the current phy_index so we will actually * compare the startting phy with itself. * This is expected and required to add the phy to the port. */ while (phy_index < SCI_MAX_PHYS) { if ((phy_mask & (1 << phy_index)) == 0) continue; sci_phy_get_sas_address(&ihost->phys[phy_index], &phy_assigned_address); if (sci_sas_address_compare(sas_address, phy_assigned_address) != 0) { /* * The phy mask specified that this phy is part of the same port * as the starting phy and it is not so fail this configuration */ return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; } port_agent->phy_valid_port_range[phy_index].min_index = port_index; port_agent->phy_valid_port_range[phy_index].max_index = phy_index; sci_port_add_phy(&ihost->ports[port_index], &ihost->phys[phy_index]); assigned_phy_mask |= (1 << phy_index); } phy_index++; } return sci_port_configuration_agent_validate_ports(ihost, port_agent); }