summaryrefslogtreecommitdiff
path: root/drivers/scsi/isci/port_config.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2012-02-29 01:07:56 -0800
committerDan Williams <dan.j.williams@intel.com>2012-05-17 12:27:12 -0700
commit50a92d93148ec073efd2456b007e04ecae452086 (patch)
tree1a81ac87e301bdb7bd809daea52bd7be0b3b21b4 /drivers/scsi/isci/port_config.c
parenteb608c3cb3f0a6b99252ea6a69fc0d2bbecf1f4f (diff)
isci: fix 'link-up' events occur after 'start-complete'
The call to wait_for_start() is meant to ensure that all links have been given a chance to come up before letting the kernel proceed with probing. However, the implementation is not correctly syncing with the port configuration agent. In the MPC case the ports are hard-coded, in the APC case we need to wait for the port-configuration to form ports from the started phys. Towards that end increase the timeout for the APC agent to form ports, and delay start complete until all phys are out of link-training. Cc: <stable@vger.kernel.org> Cc: Richard Boyd <richard.g.boyd@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/port_config.c')
-rw-r--r--drivers/scsi/isci/port_config.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c
index 6d1e9544cbe5..cd962da4a57a 100644
--- a/drivers/scsi/isci/port_config.c
+++ b/drivers/scsi/isci/port_config.c
@@ -57,7 +57,7 @@
#define SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT (10)
#define SCIC_SDS_APC_RECONFIGURATION_TIMEOUT (10)
-#define SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION (250)
+#define SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION (1000)
enum SCIC_SDS_APC_ACTIVITY {
SCIC_SDS_APC_SKIP_PHY,
@@ -472,13 +472,9 @@ sci_apc_agent_validate_phy_configuration(struct isci_host *ihost,
* 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)
+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);
}
@@ -697,6 +693,9 @@ static void apc_agent_timeout(unsigned long data)
&ihost->phys[index], false);
}
+ if (is_controller_start_complete(ihost))
+ sci_controller_transition_to_ready(ihost, SCI_SUCCESS);
+
done:
spin_unlock_irqrestore(&ihost->scic_lock, flags);
}
@@ -732,6 +731,11 @@ void sci_port_configuration_agent_construct(
}
}
+bool is_port_config_apc(struct isci_host *ihost)
+{
+ return ihost->port_agent.link_up_handler == sci_apc_agent_link_up;
+}
+
enum sci_status sci_port_configuration_agent_initialize(
struct isci_host *ihost,
struct sci_port_configuration_agent *port_agent)