diff options
author | Piotr Sawicki <piotr.sawicki@intel.com> | 2011-02-23 00:09:14 -0800 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 03:55:28 -0700 |
commit | b3824292cb93d4e45b87fe76d8774cbde9e43200 (patch) | |
tree | 5a77449b770e2a5fb35164298ea4dc702e456852 | |
parent | 52b957c80c3be9bab2748b0ac59ed3c3e8ffe196 (diff) | |
download | op-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.c | 38 |
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); + } } /** |