/* *Sanitycheckthemaxrangesforallthephysthemaxindex
* is always equal to the port range index */ if (port_agent->phy_valid_port_range[0].max_index != 0 ||
port_agent->phy_valid_port_range[1].max_index != 1 ||
port_agent->phy_valid_port_range[2].max_index != 2 ||
port_agent->phy_valid_port_range[3].max_index != 3) return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
/* *Thisisarequesttoconfigureasinglex4portoratleastattempt
* to make all the phys into a single port */ if (port_agent->phy_valid_port_range[0].min_index == 0 &&
port_agent->phy_valid_port_range[1].min_index == 0 &&
port_agent->phy_valid_port_range[2].min_index == 0 &&
port_agent->phy_valid_port_range[3].min_index == 0) return SCI_SUCCESS;
/* *PE0andPE3canneverhavethesameSASAddressunlessthey *arepartofthesamex4wideportandwehavealreadychecked
* for this condition. */
sci_phy_get_sas_address(&ihost->phys[0], &first_address);
sci_phy_get_sas_address(&ihost->phys[3], &second_address);
if (sci_sas_address_compare(first_address, second_address) == 0) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
}
/* *PE0andPE1areconfiguredintoa2x1portsmakesurethatthe *SASAddressforPE0andPE2aredifferentsincetheycannotbe
* part of the same port. */ if (port_agent->phy_valid_port_range[0].min_index == 0 &&
port_agent->phy_valid_port_range[1].min_index == 1) {
sci_phy_get_sas_address(&ihost->phys[0], &first_address);
sci_phy_get_sas_address(&ihost->phys[2], &second_address);
if (sci_sas_address_compare(first_address, second_address) == 0) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
}
}
/* *PE2andPE3areconfiguredintoa2x1portsmakesurethatthe *SASAddressforPE1andPE3aredifferentsincetheycannotbe
* part of the same port. */ if (port_agent->phy_valid_port_range[2].min_index == 2 &&
port_agent->phy_valid_port_range[3].min_index == 3) {
sci_phy_get_sas_address(&ihost->phys[1], &first_address);
sci_phy_get_sas_address(&ihost->phys[3], &second_address);
if (sci_sas_address_compare(first_address, second_address) == 0) { return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
}
}
/* verify all of the phys in the same port are using the same SAS address */ staticenum 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;
if (!phy_mask) continue; /* *Makesurethatoneormoreofthephyswerenotalreadyassingedto
* 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);
/* *Thephy_indexcanbeusedasthestartingpointforthe *portrangesincethehardwarestartsalllogicalports
* 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;
}
/* *Seehowmanyadditionalphysarebeingaddedtothislogicalport. *Note:Wehavenotmovedthecurrentphy_indexsowewillactually *comparethestarttingphywithitself.
* This is expected and required to add the phy to the port. */ for (; phy_index < SCI_MAX_PHYS; phy_index++) { 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) { /* *Thephymaskspecifiedthatthisphyispartofthesameport
* as the starting phy and it is not so fail this configuration */ return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
}
/* Find the mask of phys that are reported read but as yet unconfigured into a port */
configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
for (index = 0; index < SCI_MAX_PHYS; index++) { struct isci_phy *iphy = &ihost->phys[index];
staticvoid sci_mpc_agent_link_up(struct isci_host *ihost, struct sci_port_configuration_agent *port_agent, struct isci_port *iport, struct isci_phy *iphy)
{ /* If the port is NULL then the phy was not assigned to a port. *ThisisbecausethephywasnotgiventhesameSASAddressas *theotherPHYsintheport.
*/ if (!iport) return;
/* verify phys are assigned a valid SAS address for automatic port *configurationmode.
*/ staticenum 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;
}
}
}
if (iport) { if (sci_port_is_valid_phy_assignment(iport, iphy->phy_index))
apc_activity = SCIC_SDS_APC_ADD_PHY; else
apc_activity = SCIC_SDS_APC_SKIP_PHY;
} else { /* *ThereisnomatchingPortforthisPHYsoletssearchthroughthe *PortsandseeifwecanaddthePHYtoitsownportormaybestart *thetimerandwaittoseeifawiderportcanbemade. *
* Note the break when we reach the condition of the port id == phy id */ for (port_index = port_agent->phy_valid_port_range[iphy->phy_index].min_index;
port_index <= port_agent->phy_valid_port_range[iphy->phy_index].max_index;
port_index++) {
iport = &ihost->ports[port_index];
/* First we must make sure that this PHY can be added to this Port. */ if (sci_port_is_valid_phy_assignment(iport, iphy->phy_index)) { /* *PortcontainsaPHYwithagreaterPHYIDthanthecurrent *PHYthathasgonelinkup.Thisphycannotbepartofany
* port so skip it and move on. */ if (iport->active_phy_mask > (1 << iphy->phy_index)) {
apc_activity = SCIC_SDS_APC_SKIP_PHY; break;
}
/* *WehavereachedtheendofourPortlistandhavenotfound *anyreasonwhyweshouldnoteitheraddthePHYtotheport
* or wait for more phys to become active. */ if (iport->physical_port_index == iphy->phy_index) { /* *ThePorteitherhasnoactivePHYs. *ConsiderthatiftheporthadanyactivePHYswewouldhave *oractivePHYswith
* a lower PHY Id than this PHY. */ if (apc_activity != SCIC_SDS_APC_START_TIMER) {
apc_activity = SCIC_SDS_APC_ADD_PHY;
}
break;
}
/* *ThecurrentPorthasnoactivePHYsandthisPHYcouldbepart *ofthisPort.Sincewedontknowasyetsetuptostartthe
* timer and see if there is a better configuration. */ if (iport->active_phy_mask == 0) {
apc_activity = SCIC_SDS_APC_START_TIMER;
}
} elseif (iport->active_phy_mask != 0) { /* *ThePorthasanactivephyandthecurrentPhycannot *participateinthisportsoskipthePHYandseeif
* there is a better configuration. */
apc_activity = SCIC_SDS_APC_SKIP_PHY;
}
}
}
/* *Checktoseeifthestarttimeroperationsshouldinsteadmaptoan *addphyoperation.Thisiscausedbecausewehavebeenwaitingto *addaphytoaportbutcouldnotbecuasetheautomaticport *configurationenginehadachoiceofpossibleportsforthephy. *Sincewehavegonethroughatimeoutwearegoingtorestrictthe
* choice to the smallest possible port. */ if (
(start_timer == false)
&& (apc_activity == SCIC_SDS_APC_START_TIMER)
) {
apc_activity = SCIC_SDS_APC_ADD_PHY;
}
switch (apc_activity) { case SCIC_SDS_APC_ADD_PHY:
status = sci_port_add_phy(iport, iphy);
if (!iport) { /* the phy is not the part of this port */
port_agent->phy_ready_mask |= 1 << phy_index;
sci_apc_agent_start_timer(port_agent,
SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION);
} else { /* the phy is already the part of the port */
port_agent->phy_ready_mask |= 1 << phy_index;
sci_port_link_up(iport, iphy);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.