summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Sawicki <piotr.sawicki@intel.com>2011-02-23 00:09:14 -0800
committerDan Williams <dan.j.williams@intel.com>2011-07-03 03:55:28 -0700
commitb3824292cb93d4e45b87fe76d8774cbde9e43200 (patch)
tree5a77449b770e2a5fb35164298ea4dc702e456852
parent52b957c80c3be9bab2748b0ac59ed3c3e8ffe196 (diff)
downloadop-kernel-dev-b3824292cb93d4e45b87fe76d8774cbde9e43200.zip
op-kernel-dev-b3824292cb93d4e45b87fe76d8774cbde9e43200.tar.gz
isci: fix for asserts during aborts/resets to SAS/SATA in APC mode
Sending aborts/resets to SAS/SATA targets in APC mode eventually causes an assert in scic_sds_apc_agent_link_up(). We need to handle the hard reset case for apc mode ports. Signed-off-by: Piotr Sawicki <piotr.sawicki@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/isci/core/scic_sds_port_configuration_agent.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c
index dd2cdd4..001472e 100644
--- a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c
+++ b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c
@@ -676,28 +676,40 @@ static void scic_sds_apc_agent_configure_ports(
}
/**
- *
- * @controller: This is the controller object that receives the link up
+ * scic_sds_apc_agent_link_up - handle apc link up events
+ * @scic: This is the controller object that receives the link up
* notification.
- * @port: This is the port object associated with the phy. If the is no
+ * @sci_port: This is the port object associated with the phy. If the is no
* associated port this is an NULL.
- * @phy: This is the phy object which has gone link up.
+ * @sci_phy: This is the phy object which has gone link up.
*
* This method handles the automatic port configuration for link up
* notifications. Is it possible to get a link down notification from a phy
* that has no assocoated port?
*/
-static void scic_sds_apc_agent_link_up(
- struct scic_sds_controller *controller,
- struct scic_sds_port_configuration_agent *port_agent,
- struct scic_sds_port *port,
- struct scic_sds_phy *phy)
+static void scic_sds_apc_agent_link_up(struct scic_sds_controller *scic,
+ struct scic_sds_port_configuration_agent *port_agent,
+ struct scic_sds_port *sci_port,
+ struct scic_sds_phy *sci_phy)
{
- BUG_ON(port != NULL);
-
- port_agent->phy_ready_mask |= (1 << scic_sds_phy_get_index(phy));
+ u8 phy_index = sci_phy->phy_index;
- scic_sds_apc_agent_configure_ports(controller, port_agent, phy, true);
+ if (!sci_port) {
+ /* the phy is not the part of this port */
+ port_agent->phy_ready_mask |= 1 << phy_index;
+ scic_sds_apc_agent_configure_ports(scic, port_agent, sci_phy, true);
+ } else {
+ /* the phy is already the part of the port */
+ u32 port_state = sci_port->parent.state_machine.current_state_id;
+
+ /* if the PORT'S state is resetting then the link up is from
+ * port hard reset in this case, we need to tell the port
+ * that link up is recieved
+ */
+ BUG_ON(port_state != SCI_BASE_PORT_STATE_RESETTING);
+ port_agent->phy_ready_mask |= 1 << phy_index;
+ scic_sds_port_link_up(sci_port, sci_phy);
+ }
}
/**
OpenPOWER on IntegriCloud