Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 286357
b: refs/heads/master
c: be77834
h: refs/heads/master
i:
  286355: 7944a60
v: v3
  • Loading branch information
Marcin Tomczak authored and James Bottomley committed Jan 16, 2012
1 parent 549ea67 commit 2964d9b
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 472d4d2cfbc169f3868a5f63ce727a482a2fd487
refs/heads/master: be778341812dc75b1c515fab6ebd39c0daf1e2bc
59 changes: 55 additions & 4 deletions trunk/drivers/scsi/isci/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,8 @@ static enum sci_status sci_controller_start_next_phy(struct isci_host *ihost)
*/
if ((iphy->is_in_link_training == false && state == SCI_PHY_INITIAL) ||
(iphy->is_in_link_training == false && state == SCI_PHY_STOPPED) ||
(iphy->is_in_link_training == true && is_phy_starting(iphy))) {
(iphy->is_in_link_training == true && is_phy_starting(iphy)) ||
(ihost->port_agent.phy_ready_mask != ihost->port_agent.phy_configured_mask)) {
is_controller_start_complete = false;
break;
}
Expand Down Expand Up @@ -1904,6 +1905,31 @@ static void power_control_timeout(unsigned long data)
ihost->power_control.phys_waiting--;
ihost->power_control.phys_granted_power++;
sci_phy_consume_power_handler(iphy);

if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
u8 j;

for (j = 0; j < SCI_MAX_PHYS; j++) {
struct isci_phy *requester = ihost->power_control.requesters[j];

/*
* Search the power_control queue to see if there are other phys
* attached to the same remote device. If found, take all of
* them out of await_sas_power state.
*/
if (requester != NULL && requester != iphy) {
u8 other = memcmp(requester->frame_rcvd.iaf.sas_addr,
iphy->frame_rcvd.iaf.sas_addr,
sizeof(requester->frame_rcvd.iaf.sas_addr));

if (other == 0) {
ihost->power_control.requesters[j] = NULL;
ihost->power_control.phys_waiting--;
sci_phy_consume_power_handler(requester);
}
}
}
}
}

/*
Expand Down Expand Up @@ -1938,9 +1964,34 @@ void sci_controller_power_control_queue_insert(struct isci_host *ihost,
ihost->power_control.timer_started = true;

} else {
/* Add the phy in the waiting list */
ihost->power_control.requesters[iphy->phy_index] = iphy;
ihost->power_control.phys_waiting++;
/*
* There are phys, attached to the same sas address as this phy, are
* already in READY state, this phy don't need wait.
*/
u8 i;
struct isci_phy *current_phy;

for (i = 0; i < SCI_MAX_PHYS; i++) {
u8 other;
current_phy = &ihost->phys[i];

other = memcmp(current_phy->frame_rcvd.iaf.sas_addr,
iphy->frame_rcvd.iaf.sas_addr,
sizeof(current_phy->frame_rcvd.iaf.sas_addr));

if (current_phy->sm.current_state_id == SCI_PHY_READY &&
current_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS &&
other == 0) {
sci_phy_consume_power_handler(iphy);
break;
}
}

if (i == SCI_MAX_PHYS) {
/* Add the phy in the waiting list */
ihost->power_control.requesters[iphy->phy_index] = iphy;
ihost->power_control.phys_waiting++;
}
}
}

Expand Down
33 changes: 21 additions & 12 deletions trunk/drivers/scsi/isci/port_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,23 @@ sci_apc_agent_validate_phy_configuration(struct isci_host *ihost,
return sci_port_configuration_agent_validate_ports(ihost, port_agent);
}

/*
* This routine will restart the automatic port configuration timeout
* timer for the next time period. This could be caused by either a link
* down event or a link up event where we can not yet tell to which a phy
* belongs.
*/
static void sci_apc_agent_start_timer(
struct sci_port_configuration_agent *port_agent,
u32 timeout)
{
if (port_agent->timer_pending)
sci_del_timer(&port_agent->timer);

port_agent->timer_pending = true;
sci_mod_timer(&port_agent->timer, timeout);
}

static void sci_apc_agent_configure_ports(struct isci_host *ihost,
struct sci_port_configuration_agent *port_agent,
struct isci_phy *iphy,
Expand Down Expand Up @@ -565,17 +582,8 @@ static void sci_apc_agent_configure_ports(struct isci_host *ihost,
break;

case SCIC_SDS_APC_START_TIMER:
/*
* This can occur for either a link down event, or a link
* up event where we cannot yet tell the port to which a
* phy belongs.
*/
if (port_agent->timer_pending)
sci_del_timer(&port_agent->timer);

port_agent->timer_pending = true;
sci_mod_timer(&port_agent->timer,
SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION);
sci_apc_agent_start_timer(port_agent,
SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION);
break;

case SCIC_SDS_APC_SKIP_PHY:
Expand Down Expand Up @@ -607,7 +615,8 @@ static void sci_apc_agent_link_up(struct isci_host *ihost,
if (!iport) {
/* the phy is not the part of this port */
port_agent->phy_ready_mask |= 1 << phy_index;
sci_apc_agent_configure_ports(ihost, port_agent, iphy, true);
sci_apc_agent_start_timer(port_agent,
SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION);
} else {
/* the phy is already the part of the port */
u32 port_state = iport->sm.current_state_id;
Expand Down

0 comments on commit 2964d9b

Please sign in to comment.