/*
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.GPL.
 *
 * BSD LICENSE
 *
 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "isci.h"
#include "port.h"
#include "request.h"

#define SCIC_SDS_PORT_HARD_RESET_TIMEOUT  (1000)
#define SCU_DUMMY_INDEX    (0xFFFF)

static void isci_port_change_state(struct isci_port *iport, enum isci_status status)
{
	unsigned long flags;

	dev_dbg(&iport->isci_host->pdev->dev,
		"%s: iport = %p, state = 0x%x\n",
		__func__, iport, status);

	/* XXX pointless lock */
	spin_lock_irqsave(&iport->state_lock, flags);
	iport->status = status;
	spin_unlock_irqrestore(&iport->state_lock, flags);
}

static void sci_port_get_protocols(struct isci_port *iport, struct sci_phy_proto *proto)
{
	u8 index;

	proto->all = 0;
	for (index = 0; index < SCI_MAX_PHYS; index++) {
		struct isci_phy *iphy = iport->phy_table[index];

		if (!iphy)
			continue;
		sci_phy_get_protocols(iphy, proto);
	}
}

static u32 sci_port_get_phys(struct isci_port *iport)
{
	u32 index;
	u32 mask;

	mask = 0;
	for (index = 0; index < SCI_MAX_PHYS; index++)
		if (iport->phy_table[index])
			mask |= (1 << index);

	return mask;
}

/**
 * sci_port_get_properties() - This method simply returns the properties
 *    regarding the port, such as: physical index, protocols, sas address, etc.
 * @port: this parameter specifies the port for which to retrieve the physical
 *    index.
 * @properties: This parameter specifies the properties structure into which to
 *    copy the requested information.
 *
 * Indicate if the user specified a valid port. SCI_SUCCESS This value is
 * returned if the specified port was valid. SCI_FAILURE_INVALID_PORT This
 * value is returned if the specified port is not valid.  When this value is
 * returned, no data is copied to the properties output parameter.
 */
enum sci_status sci_port_get_properties(struct isci_port *iport,
						struct sci_port_properties *prop)
{
	if (!iport || iport->logical_port_index == SCIC_SDS_DUMMY_PORT)
		return SCI_FAILURE_INVALID_PORT;

	prop->index = iport->logical_port_index;
	prop->phy_mask = sci_port_get_phys(iport);
	sci_port_get_sas_address(iport, &prop->local.sas_address);
	sci_port_get_protocols(iport, &prop->local.protocols);
	sci_port_get_attached_sas_address(iport, &prop->remote.sas_address);

	return SCI_SUCCESS;
}

static void sci_port_bcn_enable(struct isci_port *iport)
{
	struct isci_phy *iphy;
	u32 val;
	int i;

	for (i = 0; i < ARRAY_SIZE(iport->phy_table); i++) {
		iphy = iport->phy_table[i];
		if (!iphy)
			continue;
		val = readl(&iphy->link_layer_registers->link_layer_control);
		/* clear the bit by writing 1. */
		writel(val, &iphy->link_layer_registers->link_layer_control);
	}
}

static void isci_port_bc_change_received(struct isci_host *ihost,
					 struct isci_port *iport,
					 struct isci_phy *iphy)
{
	dev_dbg(&ihost->pdev->dev,
		"%s: isci_phy = %p, sas_phy = %p\n",
		__func__, iphy, &iphy->sas_phy);

	ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD);
	sci_port_bcn_enable(iport);
}

static void isci_port_link_up(struct isci_host *isci_host,
			      struct isci_port *iport,
			      struct isci_phy *iphy)
{
	unsigned long flags;
	struct sci_port_properties properties;
	unsigned long success = true;

	BUG_ON(iphy->isci_port != NULL);

	iphy->isci_port = iport;

	dev_dbg(&isci_host->pdev->dev,
		"%s: isci_port = %p\n",
		__func__, iport);

	spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);

	isci_port_change_state(iphy->isci_port, isci_starting);

	sci_port_get_properties(iport, &properties);

	if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
		u64 attached_sas_address;

		iphy->sas_phy.oob_mode = SATA_OOB_MODE;
		iphy->sas_phy.frame_rcvd_size = sizeof(struct dev_to_host_fis);

		/*
		 * For direct-attached SATA devices, the SCI core will
		 * automagically assign a SAS address to the end device
		 * for the purpose of creating a port. This SAS address
		 * will not be the same as assigned to the PHY and needs
		 * to be obtained from struct sci_port_properties properties.
		 */
		attached_sas_address = properties.remote.sas_address.high;
		attached_sas_address <<= 32;
		attached_sas_address |= properties.remote.sas_address.low;
		swab64s(&attached_sas_address);

		memcpy(&iphy->sas_phy.attached_sas_addr,
		       &attached_sas_address, sizeof(attached_sas_address));
	} else if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
		iphy->sas_phy.oob_mode = SAS_OOB_MODE;
		iphy->sas_phy.frame_rcvd_size = sizeof(struct sas_identify_frame);

		/* Copy the attached SAS address from the IAF */
		memcpy(iphy->sas_phy.attached_sas_addr,
		       iphy->frame_rcvd.iaf.sas_addr, SAS_ADDR_SIZE);
	} else {
		dev_err(&isci_host->pdev->dev, "%s: unkown target\n", __func__);
		success = false;
	}

	iphy->sas_phy.phy->negotiated_linkrate = sci_phy_linkrate(iphy);

	spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);

	/* Notify libsas that we have an address frame, if indeed
	 * we've found an SSP, SMP, or STP target */
	if (success)
		isci_host->sas_ha.notify_port_event(&iphy->sas_phy,
						    PORTE_BYTES_DMAED);
}


/**
 * isci_port_link_down() - This function is called by the sci core when a link
 *    becomes inactive.
 * @isci_host: This parameter specifies the isci host object.
 * @phy: This parameter specifies the isci phy with the active link.
 * @port: This parameter specifies the isci port with the active link.
 *
 */
static void isci_port_link_down(struct isci_host *isci_host,
				struct isci_phy *isci_phy,
				struct isci_port *isci_port)
{
	struct isci_remote_device *isci_device;

	dev_dbg(&isci_host->pdev->dev,
		"%s: isci_port = %p\n", __func__, isci_port);

	if (isci_port) {

		/* check to see if this is the last phy on this port. */
		if (isci_phy->sas_phy.port &&
		    isci_phy->sas_phy.port->num_phys == 1) {
			/* change the state for all devices on this port.  The
			 * next task sent to this device will be returned as
			 * SAS_TASK_UNDELIVERED, and the scsi mid layer will
			 * remove the target
			 */
			list_for_each_entry(isci_device,
					    &isci_port->remote_dev_list,
					    node) {
				dev_dbg(&isci_host->pdev->dev,
					"%s: isci_device = %p\n",
					__func__, isci_device);
				set_bit(IDEV_GONE, &isci_device->flags);
			}
			isci_port_change_state(isci_port, isci_stopping);
		}
	}

	/* Notify libsas of the borken link, this will trigger calls to our
	 * isci_port_deformed and isci_dev_gone functions.
	 */
	sas_phy_disconnected(&isci_phy->sas_phy);
	isci_host->sas_ha.notify_phy_event(&isci_phy->sas_phy,
					   PHYE_LOSS_OF_SIGNAL);

	isci_phy->isci_port = NULL;

	dev_dbg(&isci_host->pdev->dev,
		"%s: isci_port = %p - Done\n", __func__, isci_port);
}


/**
 * isci_port_ready() - This function is called by the sci core when a link
 *    becomes ready.
 * @isci_host: This parameter specifies the isci host object.
 * @port: This parameter specifies the sci port with the active link.
 *
 */
static void isci_port_ready(struct isci_host *isci_host, struct isci_port *isci_port)
{
	dev_dbg(&isci_host->pdev->dev,
		"%s: isci_port = %p\n", __func__, isci_port);

	complete_all(&isci_port->start_complete);
	isci_port_change_state(isci_port, isci_ready);
	return;
}

/**
 * isci_port_not_ready() - This function is called by the sci core when a link
 *    is not ready. All remote devices on this link will be removed if they are
 *    in the stopping state.
 * @isci_host: This parameter specifies the isci host object.
 * @port: This parameter specifies the sci port with the active link.
 *
 */
static void isci_port_not_ready(struct isci_host *isci_host, struct isci_port *isci_port)
{
	dev_dbg(&isci_host->pdev->dev,
		"%s: isci_port = %p\n", __func__, isci_port);
}

static void isci_port_stop_complete(struct isci_host *ihost,
				    struct isci_port *iport,
				    enum sci_status completion_status)
{
	dev_dbg(&ihost->pdev->dev, "Port stop complete\n");
}


static bool is_port_ready_state(enum sci_port_states state)
{
	switch (state) {
	case SCI_PORT_READY:
	case SCI_PORT_SUB_WAITING:
	case SCI_PORT_SUB_OPERATIONAL:
	case SCI_PORT_SUB_CONFIGURING:
		return true;
	default:
		return false;
	}
}

/* flag dummy rnc hanling when exiting a ready state */
static void port_state_machine_change(struct isci_port *iport,
				      enum sci_port_states state)
{
	struct sci_base_state_machine *sm = &iport->sm;
	enum sci_port_states old_state = sm->current_state_id;

	if (is_port_ready_state(old_state) && !is_port_ready_state(state))
		iport->ready_exit = true;

	sci_change_state(sm, state);
	iport->ready_exit = false;
}

/**
 * isci_port_hard_reset_complete() - This function is called by the sci core
 *    when the hard reset complete notification has been received.
 * @port: This parameter specifies the sci port with the active link.
 * @completion_status: This parameter specifies the core status for the reset
 *    process.
 *
 */
static void isci_port_hard_reset_complete(struct isci_port *isci_port,
					  enum sci_status completion_status)
{
	dev_dbg(&isci_port->isci_host->pdev->dev,
		"%s: isci_port = %p, completion_status=%x\n",
		     __func__, isci_port, completion_status);

	/* Save the status of the hard reset from the port. */
	isci_port->hard_reset_status = completion_status;

	if (completion_status != SCI_SUCCESS) {

		/* The reset failed.  The port state is now SCI_PORT_FAILED. */
		if (isci_port->active_phy_mask == 0) {

			/* Generate the link down now to the host, since it
			 * was intercepted by the hard reset state machine when
			 * it really happened.
			 */
			isci_port_link_down(isci_port->isci_host,
					    &isci_port->isci_host->phys[
						   isci_port->last_active_phy],
					    isci_port);
		}
		/* Advance the port state so that link state changes will be
		* noticed.
		*/
		port_state_machine_change(isci_port, SCI_PORT_SUB_WAITING);

	}
	complete_all(&isci_port->hard_reset_complete);
}

/* This method will return a true value if the specified phy can be assigned to
 * this port The following is a list of phys for each port that are allowed: -
 * Port 0 - 3 2 1 0 - Port 1 -     1 - Port 2 - 3 2 - Port 3 - 3 This method
 * doesn't preclude all configurations.  It merely ensures that a phy is part
 * of the allowable set of phy identifiers for that port.  For example, one
 * could assign phy 3 to port 0 and no other phys.  Please refer to
 * sci_port_is_phy_mask_valid() for information regarding whether the
 * phy_mask for a port can be supported. bool true if this is a valid phy
 * assignment for the port false if this is not a valid phy assignment for the
 * port
 */
bool sci_port_is_valid_phy_assignment(struct isci_port *iport, u32 phy_index)
{
	struct isci_host *ihost = iport->owning_controller;
	struct sci_user_parameters *user = &ihost->user_parameters;

	/* Initialize to invalid value. */
	u32 existing_phy_index = SCI_MAX_PHYS;
	u32 index;

	if ((iport->physical_port_index == 1) && (phy_index != 1))
		return false;

	if (iport->physical_port_index == 3 && phy_index != 3)
		return false;

	if (iport->physical_port_index == 2 &&
	    (phy_index == 0 || phy_index == 1))
		return false;

	for (index = 0; index < SCI_MAX_PHYS; index++)
		if (iport->phy_table[index] && index != phy_index)
			existing_phy_index = index;

	/* Ensure that all of the phys in the port are capable of
	 * operating at the same maximum link rate.
	 */
	if (existing_phy_index < SCI_MAX_PHYS &&
	    user->phys[phy_index].max_speed_generation !=
	    user->phys[existing_phy_index].max_speed_generation)
		return false;

	return true;
}

/**
 *
 * @sci_port: This is the port object for which to determine if the phy mask
 *    can be supported.
 *
 * This method will return a true value if the port's phy mask can be supported
 * by the SCU. The following is a list of valid PHY mask configurations for
 * each port: - Port 0 - [[3  2] 1] 0 - Port 1 -        [1] - Port 2 - [[3] 2]
 * - Port 3 -  [3] This method returns a boolean indication specifying if the
 * phy mask can be supported. true if this is a valid phy assignment for the
 * port false if this is not a valid phy assignment for the port
 */
static bool sci_port_is_phy_mask_valid(
	struct isci_port *iport,
	u32 phy_mask)
{
	if (iport->physical_port_index == 0) {
		if (((phy_mask & 0x0F) == 0x0F)
		    || ((phy_mask & 0x03) == 0x03)
		    || ((phy_mask & 0x01) == 0x01)
		    || (phy_mask == 0))
			return true;
	} else if (iport->physical_port_index == 1) {
		if (((phy_mask & 0x02) == 0x02)
		    || (phy_mask == 0))
			return true;
	} else if (iport->physical_port_index == 2) {
		if (((phy_mask & 0x0C) == 0x0C)
		    || ((phy_mask & 0x04) == 0x04)
		    || (phy_mask == 0))
			return true;
	} else if (iport->physical_port_index == 3) {
		if (((phy_mask & 0x08) == 0x08)
		    || (phy_mask == 0))
			return true;
	}

	return false;
}

/*
 * This method retrieves a currently active (i.e. connected) phy contained in
 * the port.  Currently, the lowest order phy that is connected is returned.
 * This method returns a pointer to a SCIS_SDS_PHY object. NULL This value is
 * returned if there are no currently active (i.e. connected to a remote end
 * point) phys contained in the port. All other values specify a struct sci_phy
 * object that is active in the port.
 */
static struct isci_phy *sci_port_get_a_connected_phy(struct isci_port *iport)
{
	u32 index;
	struct isci_phy *iphy;

	for (index = 0; index < SCI_MAX_PHYS; index++) {
		/* Ensure that the phy is both part of the port and currently
		 * connected to the remote end-point.
		 */
		iphy = iport->phy_table[index];
		if (iphy && sci_port_active_phy(iport, iphy))
			return iphy;
	}

	return NULL;
}

static enum sci_status sci_port_set_phy(struct isci_port *iport, struct isci_phy *iphy)
{
	/* Check to see if we can add this phy to a port
	 * that means that the phy is not part of a port and that the port does
	 * not already have a phy assinged to the phy index.
	 */
	if (!iport->phy_table[iphy->phy_index] &&
	    !phy_get_non_dummy_port(iphy) &&
	    sci_port_is_valid_phy_assignment(iport, iphy->phy_index)) {
		/* Phy is being added in the stopped state so we are in MPC mode
		 * make logical port index = physical port index
		 */
		iport->logical_port_index = iport->physical_port_index;
		iport->phy_table[iphy->phy_index] = iphy;
		sci_phy_set_port(iphy, iport);

		return SCI_SUCCESS;
	}

	return SCI_FAILURE;
}

static enum sci_status sci_port_clear_phy(struct isci_port *iport, struct isci_phy *iphy)
{
	/* Make sure that this phy is part of this port */
	if (iport->phy_table[iphy->phy_index] == iphy &&
	    phy_get_non_dummy_port(iphy) == iport) {
		struct isci_host *ihost = iport->owning_controller;

		/* Yep it is assigned to this port so remove it */
		sci_phy_set_port(iphy, &ihost->ports[SCI_MAX_PORTS]);
		iport->phy_table[iphy->phy_index] = NULL;
		return SCI_SUCCESS;
	}

	return SCI_FAILURE;
}

void sci_port_get_sas_address(struct isci_port *iport, struct sci_sas_address *sas)
{
	u32 index;

	sas->high = 0;
	sas->low  = 0;
	for (index = 0; index < SCI_MAX_PHYS; index++)
		if (iport->phy_table[index])
			sci_phy_get_sas_address(iport->phy_table[index], sas);
}

void sci_port_get_attached_sas_address(struct isci_port *iport, struct sci_sas_address *sas)
{
	struct isci_phy *iphy;

	/*
	 * Ensure that the phy is both part of the port and currently
	 * connected to the remote end-point.
	 */
	iphy = sci_port_get_a_connected_phy(iport);
	if (iphy) {
		if (iphy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA) {
			sci_phy_get_attached_sas_address(iphy, sas);
		} else {
			sci_phy_get_sas_address(iphy, sas);
			sas->low += iphy->phy_index;
		}
	} else {
		sas->high = 0;
		sas->low  = 0;
	}
}

/**
 * sci_port_construct_dummy_rnc() - create dummy rnc for si workaround
 *
 * @sci_port: logical port on which we need to create the remote node context
 * @rni: remote node index for this remote node context.
 *
 * This routine will construct a dummy remote node context data structure
 * This structure will be posted to the hardware to work around a scheduler
 * error in the hardware.
 */
static void sci_port_construct_dummy_rnc(struct isci_port *iport, u16 rni)
{
	union scu_remote_node_context *rnc;

	rnc = &iport->owning_controller->remote_node_context_table[rni];

	memset(rnc, 0, sizeof(union scu_remote_node_context));

	rnc->ssp.remote_sas_address_hi = 0;
	rnc->ssp.remote_sas_address_lo = 0;

	rnc->ssp.remote_node_index = rni;
	rnc->ssp.remote_node_port_width = 1;
	rnc->ssp.logical_port_index = iport->physical_port_index;

	rnc->ssp.nexus_loss_timer_enable = false;
	rnc->ssp.check_bit = false;
	rnc->ssp.is_valid = true;
	rnc->ssp.is_remote_node_context = true;
	rnc->ssp.function_number = 0;
	rnc->ssp.arbitration_wait_time = 0;
}

/*
 * construct a dummy task context data structure.  This
 * structure will be posted to the hardwre to work around a scheduler error
 * in the hardware.
 */
static void sci_port_construct_dummy_task(struct isci_port *iport, u16 tag)
{
	struct isci_host *ihost = iport->owning_controller;
	struct scu_task_context *task_context;

	task_context = &ihost->task_context_table[ISCI_TAG_TCI(tag)];
	memset(task_context, 0, sizeof(struct scu_task_context));

	task_context->initiator_request = 1;
	task_context->connection_rate = 1;
	task_context->logical_port_index = iport->physical_port_index;
	task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
	task_context->task_index = ISCI_TAG_TCI(tag);
	task_context->valid = SCU_TASK_CONTEXT_VALID;
	task_context->context_type = SCU_TASK_CONTEXT_TYPE;
	task_context->remote_node_index = iport->reserved_rni;
	task_context->do_not_dma_ssp_good_response = 1;
	task_context->task_phase = 0x01;
}

static void sci_port_destroy_dummy_resources(struct isci_port *iport)
{
	struct isci_host *ihost = iport->owning_controller;

	if (iport->reserved_tag != SCI_CONTROLLER_INVALID_IO_TAG)
		isci_free_tag(ihost, iport->reserved_tag);

	if (iport->reserved_rni != SCU_DUMMY_INDEX)
		sci_remote_node_table_release_remote_node_index(&ihost->available_remote_nodes,
								     1, iport->reserved_rni);

	iport->reserved_rni = SCU_DUMMY_INDEX;
	iport->reserved_tag = SCI_CONTROLLER_INVALID_IO_TAG;
}

void sci_port_setup_transports(struct isci_port *iport, u32 device_id)
{
	u8 index;

	for (index = 0; index < SCI_MAX_PHYS; index++) {
		if (iport->active_phy_mask & (1 << index))
			sci_phy_setup_transport(iport->phy_table[index], device_id);
	}
}

static void sci_port_resume_phy(struct isci_port *iport, struct isci_phy *iphy)
{
	sci_phy_resume(iphy);
	iport->enabled_phy_mask |= 1 << iphy->phy_index;
}

static void sci_port_activate_phy(struct isci_port *iport,
				  struct isci_phy *iphy,
				  u8 flags)
{
	struct isci_host *ihost = iport->owning_controller;

	if (iphy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA && (flags & PF_RESUME))
		sci_phy_resume(iphy);

	iport->active_phy_mask |= 1 << iphy->phy_index;

	sci_controller_clear_invalid_phy(ihost, iphy);

	if (flags & PF_NOTIFY)
		isci_port_link_up(ihost, iport, iphy);
}

void sci_port_deactivate_phy(struct isci_port *iport, struct isci_phy *iphy,
			     bool do_notify_user)
{
	struct isci_host *ihost = iport->owning_controller;

	iport->active_phy_mask &= ~(1 << iphy->phy_index);
	iport->enabled_phy_mask &= ~(1 << iphy->phy_index);
	if (!iport->active_phy_mask)
		iport->last_active_phy = iphy->phy_index;

	iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;

	/* Re-assign the phy back to the LP as if it were a narrow port for APC
	 * mode. For MPC mode, the phy will remain in the port.
	 */
	if (iport->owning_controller->oem_parameters.controller.mode_type ==
		SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE)
		writel(iphy->phy_index,
			&iport->port_pe_configuration_register[iphy->phy_index]);

	if (do_notify_user == true)
		isci_port_link_down(ihost, iphy, iport);
}

static void sci_port_invalid_link_up(struct isci_port *iport, struct isci_phy *iphy)
{
	struct isci_host *ihost = iport->owning_controller;

	/*
	 * Check to see if we have alreay reported this link as bad and if
	 * not go ahead and tell the SCI_USER that we have discovered an
	 * invalid link.
	 */
	if ((ihost->invalid_phy_mask & (1 << iphy->phy_index)) == 0) {
		ihost->invalid_phy_mask |= 1 << iphy->phy_index;
		dev_warn(&ihost->pdev->dev, "Invalid link up!\n");
	}
}

/**
 * sci_port_general_link_up_handler - phy can be assigned to port?
 * @sci_port: sci_port object for which has a phy that has gone link up.
 * @sci_phy: This is the struct isci_phy object that has gone link up.
 * @flags: PF_RESUME, PF_NOTIFY to sci_port_activate_phy
 *
 * Determine if this phy can be assigned to this port . If the phy is
 * not a valid PHY for this port then the function will notify the user.
 * A PHY can only be part of a port if it's attached SAS ADDRESS is the
 * same as all other PHYs in the same port.
 */
static void sci_port_general_link_up_handler(struct isci_port *iport,
					     struct isci_phy *iphy,
					     u8 flags)
{
	struct sci_sas_address port_sas_address;
	struct sci_sas_address phy_sas_address;

	sci_port_get_attached_sas_address(iport, &port_sas_address);
	sci_phy_get_attached_sas_address(iphy, &phy_sas_address);

	/* If the SAS address of the new phy matches the SAS address of
	 * other phys in the port OR this is the first phy in the port,
	 * then activate the phy and allow it to be used for operations
	 * in this port.
	 */
	if ((phy_sas_address.high == port_sas_address.high &&
	     phy_sas_address.low  == port_sas_address.low) ||
	    iport->active_phy_mask == 0) {
		struct sci_base_state_machine *sm = &iport->sm;

		sci_port_activate_phy(iport, iphy, flags);
		if (sm->current_state_id == SCI_PORT_RESETTING)
			port_state_machine_change(iport, SCI_PORT_READY);
	} else
		sci_port_invalid_link_up(iport, iphy);
}



/**
 * This method returns false if the port only has a single phy object assigned.
 *     If there are no phys or more than one phy then the method will return
 *    true.
 * @sci_port: The port for which the wide port condition is to be checked.
 *
 * bool true Is returned if this is a wide ported port. false Is returned if
 * this is a narrow port.
 */
static bool sci_port_is_wide(struct isci_port *iport)
{
	u32 index;
	u32 phy_count = 0;

	for (index = 0; index < SCI_MAX_PHYS; index++) {
		if (iport->phy_table[index] != NULL) {
			phy_count++;
		}
	}

	return phy_count != 1;
}

/**
 * This method is called by the PHY object when the link is detected. if the
 *    port wants the PHY to continue on to the link up state then the port
 *    layer must return true.  If the port object returns false the phy object
 *    must halt its attempt to go link up.
 * @sci_port: The port associated with the phy object.
 * @sci_phy: The phy object that is trying to go link up.
 *
 * true if the phy object can continue to the link up condition. true Is
 * returned if this phy can continue to the ready state. false Is returned if
 * can not continue on to the ready state. This notification is in place for
 * wide ports and direct attached phys.  Since there are no wide ported SATA
 * devices this could become an invalid port configuration.
 */
bool sci_port_link_detected(
	struct isci_port *iport,
	struct isci_phy *iphy)
{
	if ((iport->logical_port_index != SCIC_SDS_DUMMY_PORT) &&
	    (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA)) {
		if (sci_port_is_wide(iport)) {
			sci_port_invalid_link_up(iport, iphy);
			return false;
		} else {
			struct isci_host *ihost = iport->owning_controller;
			struct isci_port *dst_port = &(ihost->ports[iphy->phy_index]);
			writel(iphy->phy_index,
			       &dst_port->port_pe_configuration_register[iphy->phy_index]);
		}
	}

	return true;
}

static void port_timeout(unsigned long data)
{
	struct sci_timer *tmr = (struct sci_timer *)data;
	struct isci_port *iport = container_of(tmr, typeof(*iport), timer);
	struct isci_host *ihost = iport->owning_controller;
	unsigned long flags;
	u32 current_state;

	spin_lock_irqsave(&ihost->scic_lock, flags);

	if (tmr->cancel)
		goto done;

	current_state = iport->sm.current_state_id;

	if (current_state == SCI_PORT_RESETTING) {
		/* if the port is still in the resetting state then the timeout
		 * fired before the reset completed.
		 */
		port_state_machine_change(iport, SCI_PORT_FAILED);
	} else if (current_state == SCI_PORT_STOPPED) {
		/* if the port is stopped then the start request failed In this
		 * case stay in the stopped state.
		 */
		dev_err(sciport_to_dev(iport),
			"%s: SCIC Port 0x%p failed to stop before tiemout.\n",
			__func__,
			iport);
	} else if (current_state == SCI_PORT_STOPPING) {
		/* if the port is still stopping then the stop has not completed */
		isci_port_stop_complete(iport->owning_controller,
					iport,
					SCI_FAILURE_TIMEOUT);
	} else {
		/* The port is in the ready state and we have a timer
		 * reporting a timeout this should not happen.
		 */
		dev_err(sciport_to_dev(iport),
			"%s: SCIC Port 0x%p is processing a timeout operation "
			"in state %d.\n", __func__, iport, current_state);
	}

done:
	spin_unlock_irqrestore(&ihost->scic_lock, flags);
}

/* --------------------------------------------------------------------------- */

/**
 * This function updates the hardwares VIIT entry for this port.
 *
 *
 */
static void sci_port_update_viit_entry(struct isci_port *iport)
{
	struct sci_sas_address sas_address;

	sci_port_get_sas_address(iport, &sas_address);

	writel(sas_address.high,
		&iport->viit_registers->initiator_sas_address_hi);
	writel(sas_address.low,
		&iport->viit_registers->initiator_sas_address_lo);

	/* This value get cleared just in case its not already cleared */
	writel(0, &iport->viit_registers->reserved);

	/* We are required to update the status register last */
	writel(SCU_VIIT_ENTRY_ID_VIIT |
	       SCU_VIIT_IPPT_INITIATOR |
	       ((1 << iport->physical_port_index) << SCU_VIIT_ENTRY_LPVIE_SHIFT) |
	       SCU_VIIT_STATUS_ALL_VALID,
	       &iport->viit_registers->status);
}

enum sas_linkrate sci_port_get_max_allowed_speed(struct isci_port *iport)
{
	u16 index;
	struct isci_phy *iphy;
	enum sas_linkrate max_allowed_speed = SAS_LINK_RATE_6_0_GBPS;

	/*
	 * Loop through all of the phys in this port and find the phy with the
	 * lowest maximum link rate. */
	for (index = 0; index < SCI_MAX_PHYS; index++) {
		iphy = iport->phy_table[index];
		if (iphy && sci_port_active_phy(iport, iphy) &&
		    iphy->max_negotiated_speed < max_allowed_speed)
			max_allowed_speed = iphy->max_negotiated_speed;
	}

	return max_allowed_speed;
}

static void sci_port_suspend_port_task_scheduler(struct isci_port *iport)
{
	u32 pts_control_value;

	pts_control_value = readl(&iport->port_task_scheduler_registers->control);
	pts_control_value |= SCU_PTSxCR_GEN_BIT(SUSPEND);
	writel(pts_control_value, &iport->port_task_scheduler_registers->control);
}

/**
 * sci_port_post_dummy_request() - post dummy/workaround request
 * @sci_port: port to post task
 *
 * Prevent the hardware scheduler from posting new requests to the front
 * of the scheduler queue causing a starvation problem for currently
 * ongoing requests.
 *
 */
static void sci_port_post_dummy_request(struct isci_port *iport)
{
	struct isci_host *ihost = iport->owning_controller;
	u16 tag = iport->reserved_tag;
	struct scu_task_context *tc;
	u32 command;

	tc = &ihost->task_context_table[ISCI_TAG_TCI(tag)];
	tc->abort = 0;

	command = SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
		  iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
		  ISCI_TAG_TCI(tag);

	sci_controller_post_request(ihost, command);
}

/**
 * This routine will abort the dummy request.  This will alow the hardware to
 * power down parts of the silicon to save power.
 *
 * @sci_port: The port on which the task must be aborted.
 *
 */
static void sci_port_abort_dummy_request(struct isci_port *iport)
{
	struct isci_host *ihost = iport->owning_controller;
	u16 tag = iport->reserved_tag;
	struct scu_task_context *tc;
	u32 command;

	tc = &ihost->task_context_table[ISCI_TAG_TCI(tag)];
	tc->abort = 1;

	command = SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT |
		  iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
		  ISCI_TAG_TCI(tag);

	sci_controller_post_request(ihost, command);
}

/**
 *
 * @sci_port: This is the struct isci_port object to resume.
 *
 * This method will resume the port task scheduler for this port object. none
 */
static void
sci_port_resume_port_task_scheduler(struct isci_port *iport)
{
	u32 pts_control_value;

	pts_control_value = readl(&iport->port_task_scheduler_registers->control);
	pts_control_value &= ~SCU_PTSxCR_GEN_BIT(SUSPEND);
	writel(pts_control_value, &iport->port_task_scheduler_registers->control);
}

static void sci_port_ready_substate_waiting_enter(struct sci_base_state_machine *sm)
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);

	sci_port_suspend_port_task_scheduler(iport);

	iport->not_ready_reason = SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS;

	if (iport->active_phy_mask != 0) {
		/* At least one of the phys on the port is ready */
		port_state_machine_change(iport,
					  SCI_PORT_SUB_OPERATIONAL);
	}
}

static void scic_sds_port_ready_substate_waiting_exit(
					struct sci_base_state_machine *sm)
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	sci_port_resume_port_task_scheduler(iport);
}

static void sci_port_ready_substate_operational_enter(struct sci_base_state_machine *sm)
{
	u32 index;
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct isci_host *ihost = iport->owning_controller;

	isci_port_ready(ihost, iport);

	for (index = 0; index < SCI_MAX_PHYS; index++) {
		if (iport->phy_table[index]) {
			writel(iport->physical_port_index,
				&iport->port_pe_configuration_register[
					iport->phy_table[index]->phy_index]);
			if (((iport->active_phy_mask^iport->enabled_phy_mask) & (1 << index)) != 0)
				sci_port_resume_phy(iport, iport->phy_table[index]);
		}
	}

	sci_port_update_viit_entry(iport);

	/*
	 * Post the dummy task for the port so the hardware can schedule
	 * io correctly
	 */
	sci_port_post_dummy_request(iport);
}

static void sci_port_invalidate_dummy_remote_node(struct isci_port *iport)
{
	struct isci_host *ihost = iport->owning_controller;
	u8 phys_index = iport->physical_port_index;
	union scu_remote_node_context *rnc;
	u16 rni = iport->reserved_rni;
	u32 command;

	rnc = &ihost->remote_node_context_table[rni];

	rnc->ssp.is_valid = false;

	/* ensure the preceding tc abort request has reached the
	 * controller and give it ample time to act before posting the rnc
	 * invalidate
	 */
	readl(&ihost->smu_registers->interrupt_status); /* flush */
	udelay(10);

	command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE |
		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;

	sci_controller_post_request(ihost, command);
}

/**
 *
 * @object: This is the object which is cast to a struct isci_port object.
 *
 * This method will perform the actions required by the struct isci_port on
 * exiting the SCI_PORT_SUB_OPERATIONAL. This function reports
 * the port not ready and suspends the port task scheduler. none
 */
static void sci_port_ready_substate_operational_exit(struct sci_base_state_machine *sm)
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct isci_host *ihost = iport->owning_controller;

	/*
	 * Kill the dummy task for this port if it has not yet posted
	 * the hardware will treat this as a NOP and just return abort
	 * complete.
	 */
	sci_port_abort_dummy_request(iport);

	isci_port_not_ready(ihost, iport);

	if (iport->ready_exit)
		sci_port_invalidate_dummy_remote_node(iport);
}

static void sci_port_ready_substate_configuring_enter(struct sci_base_state_machine *sm)
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct isci_host *ihost = iport->owning_controller;

	if (iport->active_phy_mask == 0) {
		isci_port_not_ready(ihost, iport);

		port_state_machine_change(iport, SCI_PORT_SUB_WAITING);
	} else
		port_state_machine_change(iport, SCI_PORT_SUB_OPERATIONAL);
}

enum sci_status sci_port_start(struct isci_port *iport)
{
	struct isci_host *ihost = iport->owning_controller;
	enum sci_status status = SCI_SUCCESS;
	enum sci_port_states state;
	u32 phy_mask;

	state = iport->sm.current_state_id;
	if (state != SCI_PORT_STOPPED) {
		dev_warn(sciport_to_dev(iport),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}

	if (iport->assigned_device_count > 0) {
		/* TODO This is a start failure operation because
		 * there are still devices assigned to this port.
		 * There must be no devices assigned to a port on a
		 * start operation.
		 */
		return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
	}

	if (iport->reserved_rni == SCU_DUMMY_INDEX) {
		u16 rni = sci_remote_node_table_allocate_remote_node(
				&ihost->available_remote_nodes, 1);

		if (rni != SCU_DUMMY_INDEX)
			sci_port_construct_dummy_rnc(iport, rni);
		else
			status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
		iport->reserved_rni = rni;
	}

	if (iport->reserved_tag == SCI_CONTROLLER_INVALID_IO_TAG) {
		u16 tag;

		tag = isci_alloc_tag(ihost);
		if (tag == SCI_CONTROLLER_INVALID_IO_TAG)
			status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
		else
			sci_port_construct_dummy_task(iport, tag);
		iport->reserved_tag = tag;
	}

	if (status == SCI_SUCCESS) {
		phy_mask = sci_port_get_phys(iport);

		/*
		 * There are one or more phys assigned to this port.  Make sure
		 * the port's phy mask is in fact legal and supported by the
		 * silicon.
		 */
		if (sci_port_is_phy_mask_valid(iport, phy_mask) == true) {
			port_state_machine_change(iport,
						  SCI_PORT_READY);

			return SCI_SUCCESS;
		}
		status = SCI_FAILURE;
	}

	if (status != SCI_SUCCESS)
		sci_port_destroy_dummy_resources(iport);

	return status;
}

enum sci_status sci_port_stop(struct isci_port *iport)
{
	enum sci_port_states state;

	state = iport->sm.current_state_id;
	switch (state) {
	case SCI_PORT_STOPPED:
		return SCI_SUCCESS;
	case SCI_PORT_SUB_WAITING:
	case SCI_PORT_SUB_OPERATIONAL:
	case SCI_PORT_SUB_CONFIGURING:
	case SCI_PORT_RESETTING:
		port_state_machine_change(iport,
					  SCI_PORT_STOPPING);
		return SCI_SUCCESS;
	default:
		dev_warn(sciport_to_dev(iport),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

static enum sci_status sci_port_hard_reset(struct isci_port *iport, u32 timeout)
{
	enum sci_status status = SCI_FAILURE_INVALID_PHY;
	struct isci_phy *iphy = NULL;
	enum sci_port_states state;
	u32 phy_index;

	state = iport->sm.current_state_id;
	if (state != SCI_PORT_SUB_OPERATIONAL) {
		dev_warn(sciport_to_dev(iport),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}

	/* Select a phy on which we can send the hard reset request. */
	for (phy_index = 0; phy_index < SCI_MAX_PHYS && !iphy; phy_index++) {
		iphy = iport->phy_table[phy_index];
		if (iphy && !sci_port_active_phy(iport, iphy)) {
			/*
			 * We found a phy but it is not ready select
			 * different phy
			 */
			iphy = NULL;
		}
	}

	/* If we have a phy then go ahead and start the reset procedure */
	if (!iphy)
		return status;
	status = sci_phy_reset(iphy);

	if (status != SCI_SUCCESS)
		return status;

	sci_mod_timer(&iport->timer, timeout);
	iport->not_ready_reason = SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED;

	port_state_machine_change(iport, SCI_PORT_RESETTING);
	return SCI_SUCCESS;
}

/**
 * sci_port_add_phy() -
 * @sci_port: This parameter specifies the port in which the phy will be added.
 * @sci_phy: This parameter is the phy which is to be added to the port.
 *
 * This method will add a PHY to the selected port. This method returns an
 * enum sci_status. SCI_SUCCESS the phy has been added to the port. Any other
 * status is a failure to add the phy to the port.
 */
enum sci_status sci_port_add_phy(struct isci_port *iport,
				      struct isci_phy *iphy)
{
	enum sci_status status;
	enum sci_port_states state;

	state = iport->sm.current_state_id;
	switch (state) {
	case SCI_PORT_STOPPED: {
		struct sci_sas_address port_sas_address;

		/* Read the port assigned SAS Address if there is one */
		sci_port_get_sas_address(iport, &port_sas_address);

		if (port_sas_address.high != 0 && port_sas_address.low != 0) {
			struct sci_sas_address phy_sas_address;

			/* Make sure that the PHY SAS Address matches the SAS Address
			 * for this port
			 */
			sci_phy_get_sas_address(iphy, &phy_sas_address);

			if (port_sas_address.high != phy_sas_address.high ||
			    port_sas_address.low  != phy_sas_address.low)
				return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
		}
		return sci_port_set_phy(iport, iphy);
	}
	case SCI_PORT_SUB_WAITING:
	case SCI_PORT_SUB_OPERATIONAL:
		status = sci_port_set_phy(iport, iphy);

		if (status != SCI_SUCCESS)
			return status;

		sci_port_general_link_up_handler(iport, iphy, PF_NOTIFY|PF_RESUME);
		iport->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
		port_state_machine_change(iport, SCI_PORT_SUB_CONFIGURING);

		return status;
	case SCI_PORT_SUB_CONFIGURING:
		status = sci_port_set_phy(iport, iphy);

		if (status != SCI_SUCCESS)
			return status;
		sci_port_general_link_up_handler(iport, iphy, PF_NOTIFY);

		/* Re-enter the configuring state since this may be the last phy in
		 * the port.
		 */
		port_state_machine_change(iport,
					  SCI_PORT_SUB_CONFIGURING);
		return SCI_SUCCESS;
	default:
		dev_warn(sciport_to_dev(iport),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

/**
 * sci_port_remove_phy() -
 * @sci_port: This parameter specifies the port in which the phy will be added.
 * @sci_phy: This parameter is the phy which is to be added to the port.
 *
 * This method will remove the PHY from the selected PORT. This method returns
 * an enum sci_status. SCI_SUCCESS the phy has been removed from the port. Any
 * other status is a failure to add the phy to the port.
 */
enum sci_status sci_port_remove_phy(struct isci_port *iport,
					 struct isci_phy *iphy)
{
	enum sci_status status;
	enum sci_port_states state;

	state = iport->sm.current_state_id;

	switch (state) {
	case SCI_PORT_STOPPED:
		return sci_port_clear_phy(iport, iphy);
	case SCI_PORT_SUB_OPERATIONAL:
		status = sci_port_clear_phy(iport, iphy);
		if (status != SCI_SUCCESS)
			return status;

		sci_port_deactivate_phy(iport, iphy, true);
		iport->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
		port_state_machine_change(iport,
					  SCI_PORT_SUB_CONFIGURING);
		return SCI_SUCCESS;
	case SCI_PORT_SUB_CONFIGURING:
		status = sci_port_clear_phy(iport, iphy);

		if (status != SCI_SUCCESS)
			return status;
		sci_port_deactivate_phy(iport, iphy, true);

		/* Re-enter the configuring state since this may be the last phy in
		 * the port
		 */
		port_state_machine_change(iport,
					  SCI_PORT_SUB_CONFIGURING);
		return SCI_SUCCESS;
	default:
		dev_warn(sciport_to_dev(iport),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

enum sci_status sci_port_link_up(struct isci_port *iport,
				      struct isci_phy *iphy)
{
	enum sci_port_states state;

	state = iport->sm.current_state_id;
	switch (state) {
	case SCI_PORT_SUB_WAITING:
		/* Since this is the first phy going link up for the port we
		 * can just enable it and continue
		 */
		sci_port_activate_phy(iport, iphy, PF_NOTIFY|PF_RESUME);

		port_state_machine_change(iport,
					  SCI_PORT_SUB_OPERATIONAL);
		return SCI_SUCCESS;
	case SCI_PORT_SUB_OPERATIONAL:
		sci_port_general_link_up_handler(iport, iphy, PF_NOTIFY|PF_RESUME);
		return SCI_SUCCESS;
	case SCI_PORT_RESETTING:
		/* TODO We should  make  sure  that  the phy  that  has gone
		 * link up is the same one on which we sent the reset.  It is
		 * possible that the phy on which we sent  the reset is not the
		 * one that has  gone  link up  and we  want to make sure that
		 * phy being reset  comes  back.  Consider the case where a
		 * reset is sent but before the hardware processes the reset it
		 * get a link up on  the  port because of a hot plug event.
		 * because  of  the reset request this phy will go link down
		 * almost immediately.
		 */

		/* In the resetting state we don't notify the user regarding
		 * link up and link down notifications.
		 */
		sci_port_general_link_up_handler(iport, iphy, PF_RESUME);
		return SCI_SUCCESS;
	default:
		dev_warn(sciport_to_dev(iport),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

enum sci_status sci_port_link_down(struct isci_port *iport,
					struct isci_phy *iphy)
{
	enum sci_port_states state;

	state = iport->sm.current_state_id;
	switch (state) {
	case SCI_PORT_SUB_OPERATIONAL:
		sci_port_deactivate_phy(iport, iphy, true);

		/* If there are no active phys left in the port, then
		 * transition the port to the WAITING state until such time
		 * as a phy goes link up
		 */
		if (iport->active_phy_mask == 0)
			port_state_machine_change(iport,
						  SCI_PORT_SUB_WAITING);
		return SCI_SUCCESS;
	case SCI_PORT_RESETTING:
		/* In the resetting state we don't notify the user regarding
		 * link up and link down notifications. */
		sci_port_deactivate_phy(iport, iphy, false);
		return SCI_SUCCESS;
	default:
		dev_warn(sciport_to_dev(iport),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

enum sci_status sci_port_start_io(struct isci_port *iport,
				  struct isci_remote_device *idev,
				  struct isci_request *ireq)
{
	enum sci_port_states state;

	state = iport->sm.current_state_id;
	switch (state) {
	case SCI_PORT_SUB_WAITING:
		return SCI_FAILURE_INVALID_STATE;
	case SCI_PORT_SUB_OPERATIONAL:
		iport->started_request_count++;
		return SCI_SUCCESS;
	default:
		dev_warn(sciport_to_dev(iport),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

enum sci_status sci_port_complete_io(struct isci_port *iport,
				     struct isci_remote_device *idev,
				     struct isci_request *ireq)
{
	enum sci_port_states state;

	state = iport->sm.current_state_id;
	switch (state) {
	case SCI_PORT_STOPPED:
		dev_warn(sciport_to_dev(iport),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	case SCI_PORT_STOPPING:
		sci_port_decrement_request_count(iport);

		if (iport->started_request_count == 0)
			port_state_machine_change(iport,
						  SCI_PORT_STOPPED);
		break;
	case SCI_PORT_READY:
	case SCI_PORT_RESETTING:
	case SCI_PORT_FAILED:
	case SCI_PORT_SUB_WAITING:
	case SCI_PORT_SUB_OPERATIONAL:
		sci_port_decrement_request_count(iport);
		break;
	case SCI_PORT_SUB_CONFIGURING:
		sci_port_decrement_request_count(iport);
		if (iport->started_request_count == 0) {
			port_state_machine_change(iport,
						  SCI_PORT_SUB_OPERATIONAL);
		}
		break;
	}
	return SCI_SUCCESS;
}

static void sci_port_enable_port_task_scheduler(struct isci_port *iport)
{
	u32 pts_control_value;

	 /* enable the port task scheduler in a suspended state */
	pts_control_value = readl(&iport->port_task_scheduler_registers->control);
	pts_control_value |= SCU_PTSxCR_GEN_BIT(ENABLE) | SCU_PTSxCR_GEN_BIT(SUSPEND);
	writel(pts_control_value, &iport->port_task_scheduler_registers->control);
}

static void sci_port_disable_port_task_scheduler(struct isci_port *iport)
{
	u32 pts_control_value;

	pts_control_value = readl(&iport->port_task_scheduler_registers->control);
	pts_control_value &=
		~(SCU_PTSxCR_GEN_BIT(ENABLE) | SCU_PTSxCR_GEN_BIT(SUSPEND));
	writel(pts_control_value, &iport->port_task_scheduler_registers->control);
}

static void sci_port_post_dummy_remote_node(struct isci_port *iport)
{
	struct isci_host *ihost = iport->owning_controller;
	u8 phys_index = iport->physical_port_index;
	union scu_remote_node_context *rnc;
	u16 rni = iport->reserved_rni;
	u32 command;

	rnc = &ihost->remote_node_context_table[rni];
	rnc->ssp.is_valid = true;

	command = SCU_CONTEXT_COMMAND_POST_RNC_32 |
		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;

	sci_controller_post_request(ihost, command);

	/* ensure hardware has seen the post rnc command and give it
	 * ample time to act before sending the suspend
	 */
	readl(&ihost->smu_registers->interrupt_status); /* flush */
	udelay(10);

	command = SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX |
		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;

	sci_controller_post_request(ihost, command);
}

static void sci_port_stopped_state_enter(struct sci_base_state_machine *sm)
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);

	if (iport->sm.previous_state_id == SCI_PORT_STOPPING) {
		/*
		 * If we enter this state becasuse of a request to stop
		 * the port then we want to disable the hardwares port
		 * task scheduler. */
		sci_port_disable_port_task_scheduler(iport);
	}
}

static void sci_port_stopped_state_exit(struct sci_base_state_machine *sm)
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);

	/* Enable and suspend the port task scheduler */
	sci_port_enable_port_task_scheduler(iport);
}

static void sci_port_ready_state_enter(struct sci_base_state_machine *sm)
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct isci_host *ihost = iport->owning_controller;
	u32 prev_state;

	prev_state = iport->sm.previous_state_id;
	if (prev_state  == SCI_PORT_RESETTING)
		isci_port_hard_reset_complete(iport, SCI_SUCCESS);
	else
		isci_port_not_ready(ihost, iport);

	/* Post and suspend the dummy remote node context for this port. */
	sci_port_post_dummy_remote_node(iport);

	/* Start the ready substate machine */
	port_state_machine_change(iport,
				  SCI_PORT_SUB_WAITING);
}

static void sci_port_resetting_state_exit(struct sci_base_state_machine *sm)
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);

	sci_del_timer(&iport->timer);
}

static void sci_port_stopping_state_exit(struct sci_base_state_machine *sm)
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);

	sci_del_timer(&iport->timer);

	sci_port_destroy_dummy_resources(iport);
}

static void sci_port_failed_state_enter(struct sci_base_state_machine *sm)
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);

	isci_port_hard_reset_complete(iport, SCI_FAILURE_TIMEOUT);
}

/* --------------------------------------------------------------------------- */

static const struct sci_base_state sci_port_state_table[] = {
	[SCI_PORT_STOPPED] = {
		.enter_state = sci_port_stopped_state_enter,
		.exit_state  = sci_port_stopped_state_exit
	},
	[SCI_PORT_STOPPING] = {
		.exit_state  = sci_port_stopping_state_exit
	},
	[SCI_PORT_READY] = {
		.enter_state = sci_port_ready_state_enter,
	},
	[SCI_PORT_SUB_WAITING] = {
		.enter_state = sci_port_ready_substate_waiting_enter,
		.exit_state  = scic_sds_port_ready_substate_waiting_exit,
	},
	[SCI_PORT_SUB_OPERATIONAL] = {
		.enter_state = sci_port_ready_substate_operational_enter,
		.exit_state  = sci_port_ready_substate_operational_exit
	},
	[SCI_PORT_SUB_CONFIGURING] = {
		.enter_state = sci_port_ready_substate_configuring_enter
	},
	[SCI_PORT_RESETTING] = {
		.exit_state  = sci_port_resetting_state_exit
	},
	[SCI_PORT_FAILED] = {
		.enter_state = sci_port_failed_state_enter,
	}
};

void sci_port_construct(struct isci_port *iport, u8 index,
			     struct isci_host *ihost)
{
	sci_init_sm(&iport->sm, sci_port_state_table, SCI_PORT_STOPPED);

	iport->logical_port_index  = SCIC_SDS_DUMMY_PORT;
	iport->physical_port_index = index;
	iport->active_phy_mask     = 0;
	iport->enabled_phy_mask    = 0;
	iport->last_active_phy     = 0;
	iport->ready_exit	   = false;

	iport->owning_controller = ihost;

	iport->started_request_count = 0;
	iport->assigned_device_count = 0;

	iport->reserved_rni = SCU_DUMMY_INDEX;
	iport->reserved_tag = SCI_CONTROLLER_INVALID_IO_TAG;

	sci_init_timer(&iport->timer, port_timeout);

	iport->port_task_scheduler_registers = NULL;

	for (index = 0; index < SCI_MAX_PHYS; index++)
		iport->phy_table[index] = NULL;
}

void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index)
{
	INIT_LIST_HEAD(&iport->remote_dev_list);
	INIT_LIST_HEAD(&iport->domain_dev_list);
	spin_lock_init(&iport->state_lock);
	init_completion(&iport->start_complete);
	iport->isci_host = ihost;
	isci_port_change_state(iport, isci_freed);
}

/**
 * isci_port_get_state() - This function gets the status of the port object.
 * @isci_port: This parameter points to the isci_port object
 *
 * status of the object as a isci_status enum.
 */
enum isci_status isci_port_get_state(
	struct isci_port *isci_port)
{
	return isci_port->status;
}

void sci_port_broadcast_change_received(struct isci_port *iport, struct isci_phy *iphy)
{
	struct isci_host *ihost = iport->owning_controller;

	/* notify the user. */
	isci_port_bc_change_received(ihost, iport, iphy);
}

int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
				 struct isci_phy *iphy)
{
	unsigned long flags;
	enum sci_status status;
	int ret = TMF_RESP_FUNC_COMPLETE;

	dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n",
		__func__, iport);

	init_completion(&iport->hard_reset_complete);

	spin_lock_irqsave(&ihost->scic_lock, flags);

	#define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT
	status = sci_port_hard_reset(iport, ISCI_PORT_RESET_TIMEOUT);

	spin_unlock_irqrestore(&ihost->scic_lock, flags);

	if (status == SCI_SUCCESS) {
		wait_for_completion(&iport->hard_reset_complete);

		dev_dbg(&ihost->pdev->dev,
			"%s: iport = %p; hard reset completion\n",
			__func__, iport);

		if (iport->hard_reset_status != SCI_SUCCESS) {
			ret = TMF_RESP_FUNC_FAILED;

			dev_err(&ihost->pdev->dev,
				"%s: iport = %p; hard reset failed (0x%x)\n",
				__func__, iport, iport->hard_reset_status);
		}
	} else {
		ret = TMF_RESP_FUNC_FAILED;

		dev_err(&ihost->pdev->dev,
			"%s: iport = %p; sci_port_hard_reset call"
			" failed 0x%x\n",
			__func__, iport, status);

	}

	/* If the hard reset for the port has failed, consider this
	 * the same as link failures on all phys in the port.
	 */
	if (ret != TMF_RESP_FUNC_COMPLETE) {

		dev_err(&ihost->pdev->dev,
			"%s: iport = %p; hard reset failed "
			"(0x%x) - driving explicit link fail for all phys\n",
			__func__, iport, iport->hard_reset_status);
	}
	return ret;
}

/**
 * isci_port_deformed() - This function is called by libsas when a port becomes
 *    inactive.
 * @phy: This parameter specifies the libsas phy with the inactive port.
 *
 */
void isci_port_deformed(struct asd_sas_phy *phy)
{
	pr_debug("%s: sas_phy = %p\n", __func__, phy);
}

/**
 * isci_port_formed() - This function is called by libsas when a port becomes
 *    active.
 * @phy: This parameter specifies the libsas phy with the active port.
 *
 */
void isci_port_formed(struct asd_sas_phy *phy)
{
	pr_debug("%s: sas_phy = %p, sas_port = %p\n", __func__, phy, phy->port);
}
