/*
 * 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);
}

/*
 * This function will indicate which protocols are supported by this port.
 * @sci_port: a handle corresponding to the SAS port for which to return the
 *    supported protocols.
 * @protocols: This parameter specifies a pointer to a data structure
 *    which the core will copy the protocol values for the port from the
 *    transmit_identification register.
 */
static void
scic_sds_port_get_protocols(struct scic_sds_port *sci_port,
			    struct scic_phy_proto *protocols)
{
	u8 index;

	protocols->all = 0;

	for (index = 0; index < SCI_MAX_PHYS; index++) {
		if (sci_port->phy_table[index] != NULL) {
			scic_sds_phy_get_protocols(sci_port->phy_table[index],
						   protocols);
		}
	}
}

/**
 * This method requests a list (mask) of the phys contained in the supplied SAS
 *    port.
 * @sci_port: a handle corresponding to the SAS port for which to return the
 *    phy mask.
 *
 * Return a bit mask indicating which phys are a part of this port. Each bit
 * corresponds to a phy identifier (e.g. bit 0 = phy id 0).
 */
static u32 scic_sds_port_get_phys(struct scic_sds_port *sci_port)
{
	u32 index;
	u32 mask;

	mask = 0;

	for (index = 0; index < SCI_MAX_PHYS; index++) {
		if (sci_port->phy_table[index] != NULL) {
			mask |= (1 << index);
		}
	}

	return mask;
}

/**
 * scic_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.
 */
static enum sci_status scic_port_get_properties(struct scic_sds_port *port,
						struct scic_port_properties *prop)
{
	if ((port == NULL) ||
	    (port->logical_port_index == SCIC_SDS_DUMMY_PORT))
		return SCI_FAILURE_INVALID_PORT;

	prop->index    = port->logical_port_index;
	prop->phy_mask = scic_sds_port_get_phys(port);
	scic_sds_port_get_sas_address(port, &prop->local.sas_address);
	scic_sds_port_get_protocols(port, &prop->local.protocols);
	scic_sds_port_get_attached_sas_address(port, &prop->remote.sas_address);

	return SCI_SUCCESS;
}

static void isci_port_link_up(struct isci_host *isci_host,
			      struct scic_sds_port *port,
			      struct scic_sds_phy *phy)
{
	unsigned long flags;
	struct scic_port_properties properties;
	struct isci_phy *isci_phy = sci_phy_to_iphy(phy);
	struct isci_port *isci_port = sci_port_to_iport(port);
	unsigned long success = true;

	BUG_ON(isci_phy->isci_port != NULL);

	isci_phy->isci_port = isci_port;

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

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

	isci_port_change_state(isci_phy->isci_port, isci_starting);

	scic_port_get_properties(port, &properties);

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

		isci_phy->sas_phy.oob_mode = SATA_OOB_MODE;
		isci_phy->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 scic_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(&isci_phy->sas_phy.attached_sas_addr,
		       &attached_sas_address, sizeof(attached_sas_address));
	} else if (phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
		isci_phy->sas_phy.oob_mode = SAS_OOB_MODE;
		isci_phy->sas_phy.frame_rcvd_size = sizeof(struct sas_identify_frame);

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

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

	spin_unlock_irqrestore(&isci_phy->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(&isci_phy->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);
				isci_remote_device_change_state(isci_device,
								isci_stopping);
			}
		}
		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 scic_sds_controller *scic,
				    struct scic_sds_port *sci_port,
				    enum sci_status completion_status)
{
	dev_dbg(&scic_to_ihost(scic)->pdev->dev, "Port stop complete\n");
}

/**
 * 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;

	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
 * scic_sds_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 scic_sds_port_is_valid_phy_assignment(struct scic_sds_port *sci_port,
					   u32 phy_index)
{
	/* Initialize to invalid value. */
	u32 existing_phy_index = SCI_MAX_PHYS;
	u32 index;

	if ((sci_port->physical_port_index == 1) && (phy_index != 1)) {
		return false;
	}

	if (sci_port->physical_port_index == 3 && phy_index != 3) {
		return false;
	}

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

	for (index = 0; index < SCI_MAX_PHYS; index++) {
		if ((sci_port->phy_table[index] != NULL)
		    && (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)
		&& (sci_port->owning_controller->user_parameters.sds1.phys[
			    phy_index].max_speed_generation !=
		    sci_port->owning_controller->user_parameters.sds1.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 scic_sds_port_is_phy_mask_valid(
	struct scic_sds_port *sci_port,
	u32 phy_mask)
{
	if (sci_port->physical_port_index == 0) {
		if (((phy_mask & 0x0F) == 0x0F)
		    || ((phy_mask & 0x03) == 0x03)
		    || ((phy_mask & 0x01) == 0x01)
		    || (phy_mask == 0))
			return true;
	} else if (sci_port->physical_port_index == 1) {
		if (((phy_mask & 0x02) == 0x02)
		    || (phy_mask == 0))
			return true;
	} else if (sci_port->physical_port_index == 2) {
		if (((phy_mask & 0x0C) == 0x0C)
		    || ((phy_mask & 0x04) == 0x04)
		    || (phy_mask == 0))
			return true;
	} else if (sci_port->physical_port_index == 3) {
		if (((phy_mask & 0x08) == 0x08)
		    || (phy_mask == 0))
			return true;
	}

	return false;
}

/**
 *
 * @sci_port: This parameter specifies the port from which to return a
 *    connected phy.
 *
 * 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 scic_sds_phy
 * object that is active in the port.
 */
static struct scic_sds_phy *scic_sds_port_get_a_connected_phy(
	struct scic_sds_port *sci_port
	) {
	u32 index;
	struct scic_sds_phy *phy;

	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. */
		phy = sci_port->phy_table[index];
		if (
			(phy != NULL)
			&& scic_sds_port_active_phy(sci_port, phy)
			) {
			return phy;
		}
	}

	return NULL;
}

/**
 * scic_sds_port_set_phy() -
 * @out]: port The port object to which the phy assignement is being made.
 * @out]: phy The phy which is being assigned to the port.
 *
 * This method attempts to make the assignment of the phy to the port. If
 * successful the phy is assigned to the ports phy table. bool true if the phy
 * assignment can be made. false if the phy assignement can not be made. This
 * is a functional test that only fails if the phy is currently assigned to a
 * different port.
 */
static enum sci_status scic_sds_port_set_phy(
	struct scic_sds_port *port,
	struct scic_sds_phy *phy)
{
	/*
	 * 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 (
		(port->phy_table[phy->phy_index] == NULL)
		&& (phy_get_non_dummy_port(phy) == NULL)
		&& scic_sds_port_is_valid_phy_assignment(port, phy->phy_index)
		) {
		/*
		 * Phy is being added in the stopped state so we are in MPC mode
		 * make logical port index = physical port index */
		port->logical_port_index = port->physical_port_index;
		port->phy_table[phy->phy_index] = phy;
		scic_sds_phy_set_port(phy, port);

		return SCI_SUCCESS;
	}

	return SCI_FAILURE;
}

/**
 * scic_sds_port_clear_phy() -
 * @out]: port The port from which the phy is being cleared.
 * @out]: phy The phy being cleared from the port.
 *
 * This method will clear the phy assigned to this port.  This method fails if
 * this phy is not currently assinged to this port. bool true if the phy is
 * removed from the port. false if this phy is not assined to this port.
 */
static enum sci_status scic_sds_port_clear_phy(
	struct scic_sds_port *port,
	struct scic_sds_phy *phy)
{
	/* Make sure that this phy is part of this port */
	if (port->phy_table[phy->phy_index] == phy &&
	    phy_get_non_dummy_port(phy) == port) {
		struct scic_sds_controller *scic = port->owning_controller;
		struct isci_host *ihost = scic_to_ihost(scic);

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

	return SCI_FAILURE;
}


/**
 * This method requests the SAS address for the supplied SAS port from the SCI
 *    implementation.
 * @sci_port: a handle corresponding to the SAS port for which to return the
 *    SAS address.
 * @sas_address: This parameter specifies a pointer to a SAS address structure
 *    into which the core will copy the SAS address for the port.
 *
 */
void scic_sds_port_get_sas_address(
	struct scic_sds_port *sci_port,
	struct sci_sas_address *sas_address)
{
	u32 index;

	sas_address->high = 0;
	sas_address->low  = 0;

	for (index = 0; index < SCI_MAX_PHYS; index++) {
		if (sci_port->phy_table[index] != NULL) {
			scic_sds_phy_get_sas_address(sci_port->phy_table[index], sas_address);
		}
	}
}

/*
 * This function requests the SAS address for the device directly attached to
 *    this SAS port.
 * @sci_port: a handle corresponding to the SAS port for which to return the
 *    SAS address.
 * @sas_address: This parameter specifies a pointer to a SAS address structure
 *    into which the core will copy the SAS address for the device directly
 *    attached to the port.
 *
 */
void scic_sds_port_get_attached_sas_address(
	struct scic_sds_port *sci_port,
	struct sci_sas_address *sas_address)
{
	struct scic_sds_phy *sci_phy;

	/*
	 * Ensure that the phy is both part of the port and currently
	 * connected to the remote end-point.
	 */
	sci_phy = scic_sds_port_get_a_connected_phy(sci_port);
	if (sci_phy) {
		if (sci_phy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA) {
			scic_sds_phy_get_attached_sas_address(sci_phy,
							      sas_address);
		} else {
			scic_sds_phy_get_sas_address(sci_phy, sas_address);
			sas_address->low += sci_phy->phy_index;
		}
	} else {
		sas_address->high = 0;
		sas_address->low  = 0;
	}
}

/**
 * scic_sds_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 scic_sds_port_construct_dummy_rnc(struct scic_sds_port *sci_port, u16 rni)
{
	union scu_remote_node_context *rnc;

	rnc = &sci_port->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 = sci_port->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;
}

/**
 * scic_sds_port_construct_dummy_task() - create dummy task for si workaround
 * @sci_port The logical port on which we need to create the
 *            remote node context.
 *            context.
 * @tci The remote node index for this remote node context.
 *
 * This routine will 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 scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tci)
{
	struct scu_task_context *task_context;

	task_context = scic_sds_controller_get_task_context_buffer(sci_port->owning_controller, tci);

	memset(task_context, 0, sizeof(struct scu_task_context));

	task_context->abort = 0;
	task_context->priority = 0;
	task_context->initiator_request = 1;
	task_context->connection_rate = 1;
	task_context->protocol_engine_index = 0;
	task_context->logical_port_index = sci_port->physical_port_index;
	task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
	task_context->task_index = scic_sds_io_tag_get_index(tci);
	task_context->valid = SCU_TASK_CONTEXT_VALID;
	task_context->context_type = SCU_TASK_CONTEXT_TYPE;

	task_context->remote_node_index = sci_port->reserved_rni;
	task_context->command_code = 0;

	task_context->link_layer_control = 0;
	task_context->do_not_dma_ssp_good_response = 1;
	task_context->strict_ordering = 0;
	task_context->control_frame = 0;
	task_context->timeout_enable = 0;
	task_context->block_guard_enable = 0;

	task_context->address_modifier = 0;

	task_context->task_phase = 0x01;
}

static void scic_sds_port_destroy_dummy_resources(struct scic_sds_port *sci_port)
{
	struct scic_sds_controller *scic = sci_port->owning_controller;

	if (sci_port->reserved_tci != SCU_DUMMY_INDEX)
		scic_controller_free_io_tag(scic, sci_port->reserved_tci);

	if (sci_port->reserved_rni != SCU_DUMMY_INDEX)
		scic_sds_remote_node_table_release_remote_node_index(&scic->available_remote_nodes,
								     1, sci_port->reserved_rni);

	sci_port->reserved_rni = SCU_DUMMY_INDEX;
	sci_port->reserved_tci = SCU_DUMMY_INDEX;
}

/**
 * This method performs initialization of the supplied port. Initialization
 *    includes: - state machine initialization - member variable initialization
 *    - configuring the phy_mask
 * @sci_port:
 * @transport_layer_registers:
 * @port_task_scheduler_registers:
 * @port_configuration_regsiter:
 *
 * enum sci_status SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION This value is returned
 * if the phy being added to the port
 */
enum sci_status scic_sds_port_initialize(
	struct scic_sds_port *sci_port,
	void __iomem *port_task_scheduler_registers,
	void __iomem *port_configuration_regsiter,
	void __iomem *viit_registers)
{
	sci_port->port_task_scheduler_registers  = port_task_scheduler_registers;
	sci_port->port_pe_configuration_register = port_configuration_regsiter;
	sci_port->viit_registers                 = viit_registers;

	return SCI_SUCCESS;
}


/**
 * This method assigns the direct attached device ID for this port.
 *
 * @param[in] sci_port The port for which the direct attached device id is to
 *       be assigned.
 * @param[in] device_id The direct attached device ID to assign to the port.
 *       This will be the RNi for the device
 */
void scic_sds_port_setup_transports(
	struct scic_sds_port *sci_port,
	u32 device_id)
{
	u8 index;

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

/**
 *
 * @sci_port: This is the port on which the phy should be enabled.
 * @sci_phy: This is the specific phy which to enable.
 * @do_notify_user: This parameter specifies whether to inform the user (via
 *    scic_cb_port_link_up()) as to the fact that a new phy as become ready.
 *
 * This function will activate the phy in the port.
 * Activation includes: - adding
 * the phy to the port - enabling the Protocol Engine in the silicon. -
 * notifying the user that the link is up. none
 */
static void scic_sds_port_activate_phy(struct scic_sds_port *sci_port,
				       struct scic_sds_phy *sci_phy,
				       bool do_notify_user)
{
	struct scic_sds_controller *scic = sci_port->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);

	if (sci_phy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA)
		scic_sds_phy_resume(sci_phy);

	sci_port->active_phy_mask |= 1 << sci_phy->phy_index;

	scic_sds_controller_clear_invalid_phy(scic, sci_phy);

	if (do_notify_user == true)
		isci_port_link_up(ihost, sci_port, sci_phy);
}

void scic_sds_port_deactivate_phy(struct scic_sds_port *sci_port,
				  struct scic_sds_phy *sci_phy,
				  bool do_notify_user)
{
	struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port);
	struct isci_port *iport = sci_port_to_iport(sci_port);
	struct isci_host *ihost = scic_to_ihost(scic);
	struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);

	sci_port->active_phy_mask &= ~(1 << sci_phy->phy_index);

	sci_phy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;

	/* Re-assign the phy back to the LP as if it were a narrow port */
	writel(sci_phy->phy_index,
		&sci_port->port_pe_configuration_register[sci_phy->phy_index]);

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

/**
 *
 * @sci_port: This is the port on which the phy should be disabled.
 * @sci_phy: This is the specific phy which to disabled.
 *
 * This function will disable the phy and report that the phy is not valid for
 * this port object. None
 */
static void scic_sds_port_invalid_link_up(struct scic_sds_port *sci_port,
					  struct scic_sds_phy *sci_phy)
{
	struct scic_sds_controller *scic = sci_port->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 ((scic->invalid_phy_mask & (1 << sci_phy->phy_index)) == 0) {
		scic_sds_controller_set_invalid_phy(scic, sci_phy);
		dev_warn(&scic_to_ihost(scic)->pdev->dev, "Invalid link up!\n");
	}
}

static bool is_port_ready_state(enum scic_sds_port_states state)
{
	switch (state) {
	case SCI_BASE_PORT_STATE_READY:
	case SCIC_SDS_PORT_READY_SUBSTATE_WAITING:
	case SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL:
	case SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING:
		return true;
	default:
		return false;
	}
}

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

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

	sci_base_state_machine_change_state(sm, state);
	sci_port->ready_exit = false;
}

/**
 * scic_sds_port_general_link_up_handler - phy can be assigned to port?
 * @sci_port: scic_sds_port object for which has a phy that has gone link up.
 * @sci_phy: This is the struct scic_sds_phy object that has gone link up.
 * @do_notify_user: This parameter specifies whether to inform the user (via
 *    scic_cb_port_link_up()) as to the fact that a new phy as become ready.
 *
 * 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. none
 */
static void scic_sds_port_general_link_up_handler(struct scic_sds_port *sci_port,
						  struct scic_sds_phy *sci_phy,
						  bool do_notify_user)
{
	struct sci_sas_address port_sas_address;
	struct sci_sas_address phy_sas_address;

	scic_sds_port_get_attached_sas_address(sci_port, &port_sas_address);
	scic_sds_phy_get_attached_sas_address(sci_phy, &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) ||
	    sci_port->active_phy_mask == 0) {
		struct sci_base_state_machine *sm = &sci_port->state_machine;

		scic_sds_port_activate_phy(sci_port, sci_phy, do_notify_user);
		if (sm->current_state_id == SCI_BASE_PORT_STATE_RESETTING)
			port_state_machine_change(sci_port, SCI_BASE_PORT_STATE_READY);
	} else
		scic_sds_port_invalid_link_up(sci_port, sci_phy);
}



/**
 * 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 scic_sds_port_is_wide(struct scic_sds_port *sci_port)
{
	u32 index;
	u32 phy_count = 0;

	for (index = 0; index < SCI_MAX_PHYS; index++) {
		if (sci_port->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 scic_sds_port_link_detected(
	struct scic_sds_port *sci_port,
	struct scic_sds_phy *sci_phy)
{
	if ((sci_port->logical_port_index != SCIC_SDS_DUMMY_PORT) &&
	    (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) &&
	    scic_sds_port_is_wide(sci_port)) {
		scic_sds_port_invalid_link_up(sci_port, sci_phy);

		return false;
	}

	return true;
}

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

	spin_lock_irqsave(&ihost->scic_lock, flags);

	if (tmr->cancel)
		goto done;

	current_state = sci_base_state_machine_get_state(&sci_port->state_machine);

	if (current_state == SCI_BASE_PORT_STATE_RESETTING) {
		/* if the port is still in the resetting state then the timeout
		 * fired before the reset completed.
		 */
		port_state_machine_change(sci_port, SCI_BASE_PORT_STATE_FAILED);
	} else if (current_state == SCI_BASE_PORT_STATE_STOPPED) {
		/* if the port is stopped then the start request failed In this
		 * case stay in the stopped state.
		 */
		dev_err(sciport_to_dev(sci_port),
			"%s: SCIC Port 0x%p failed to stop before tiemout.\n",
			__func__,
			sci_port);
	} else if (current_state == SCI_BASE_PORT_STATE_STOPPING) {
		/* if the port is still stopping then the stop has not completed */
		isci_port_stop_complete(sci_port->owning_controller,
					sci_port,
					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(sci_port),
			"%s: SCIC Port 0x%p is processing a timeout operation "
			"in state %d.\n", __func__, sci_port, current_state);
	}

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

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

/**
 * This function updates the hardwares VIIT entry for this port.
 *
 *
 */
static void scic_sds_port_update_viit_entry(struct scic_sds_port *sci_port)
{
	struct sci_sas_address sas_address;

	scic_sds_port_get_sas_address(sci_port, &sas_address);

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

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

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

/**
 * This method returns the maximum allowed speed for data transfers on this
 *    port.  This maximum allowed speed evaluates to the maximum speed of the
 *    slowest phy in the port.
 * @sci_port: This parameter specifies the port for which to retrieve the
 *    maximum allowed speed.
 *
 * This method returns the maximum negotiated speed of the slowest phy in the
 * port.
 */
enum sas_linkrate scic_sds_port_get_max_allowed_speed(
	struct scic_sds_port *sci_port)
{
	u16 index;
	enum sas_linkrate max_allowed_speed = SAS_LINK_RATE_6_0_GBPS;
	struct scic_sds_phy *phy = NULL;

	/*
	 * 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++) {
		phy = sci_port->phy_table[index];
		if (
			(phy != NULL)
			&& (scic_sds_port_active_phy(sci_port, phy) == true)
			&& (phy->max_negotiated_speed < max_allowed_speed)
			)
			max_allowed_speed = phy->max_negotiated_speed;
	}

	return max_allowed_speed;
}

static void scic_port_enable_broadcast_change_notification(struct scic_sds_port *port)
{
	struct scic_sds_phy *phy;
	u32 register_value;
	u8 index;

	/* Loop through all of the phys to enable BCN. */
	for (index = 0; index < SCI_MAX_PHYS; index++) {
		phy = port->phy_table[index];
		if (phy != NULL) {
			register_value =
				readl(&phy->link_layer_registers->link_layer_control);

			/* clear the bit by writing 1. */
			writel(register_value,
				&phy->link_layer_registers->link_layer_control);
		}
	}
}

/**
 *
 * @sci_port: This is the struct scic_sds_port object to suspend.
 *
 * This method will susped the port task scheduler for this port object. none
 */
static void
scic_sds_port_suspend_port_task_scheduler(struct scic_sds_port *port)
{
	u32 pts_control_value;

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

/**
 * scic_sds_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 scic_sds_port_post_dummy_request(struct scic_sds_port *sci_port)
{
	u32 command;
	struct scu_task_context *task_context;
	struct scic_sds_controller *scic = sci_port->owning_controller;
	u16 tci = sci_port->reserved_tci;

	task_context = scic_sds_controller_get_task_context_buffer(scic, tci);

	task_context->abort = 0;

	command = SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
		  sci_port->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
		  tci;

	scic_sds_controller_post_request(scic, 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 scic_sds_port_abort_dummy_request(struct scic_sds_port *sci_port)
{
	struct scic_sds_controller *scic = sci_port->owning_controller;
	u16 tci = sci_port->reserved_tci;
	struct scu_task_context *tc;
	u32 command;

	tc = scic_sds_controller_get_task_context_buffer(scic, tci);

	tc->abort = 1;

	command = SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT |
		  sci_port->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
		  tci;

	scic_sds_controller_post_request(scic, command);
}

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

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

static void scic_sds_port_ready_substate_waiting_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_port *sci_port = container_of(sm, typeof(*sci_port), state_machine);

	scic_sds_port_suspend_port_task_scheduler(sci_port);

	sci_port->not_ready_reason = SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS;

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

static void scic_sds_port_ready_substate_operational_enter(struct sci_base_state_machine *sm)
{
	u32 index;
	struct scic_sds_port *sci_port = container_of(sm, typeof(*sci_port), state_machine);
	struct scic_sds_controller *scic = sci_port->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);
	struct isci_port *iport = sci_port_to_iport(sci_port);

	isci_port_ready(ihost, iport);

	for (index = 0; index < SCI_MAX_PHYS; index++) {
		if (sci_port->phy_table[index]) {
			writel(sci_port->physical_port_index,
				&sci_port->port_pe_configuration_register[
					sci_port->phy_table[index]->phy_index]);
		}
	}

	scic_sds_port_update_viit_entry(sci_port);

	scic_sds_port_resume_port_task_scheduler(sci_port);

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

static void scic_sds_port_invalidate_dummy_remote_node(struct scic_sds_port *sci_port)
{
	struct scic_sds_controller *scic = sci_port->owning_controller;
	u8 phys_index = sci_port->physical_port_index;
	union scu_remote_node_context *rnc;
	u16 rni = sci_port->reserved_rni;
	u32 command;

	rnc = &scic->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(&scic->smu_registers->interrupt_status); /* flush */
	udelay(10);

	command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE |
		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;

	scic_sds_controller_post_request(scic, command);
}

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

	/*
	 * 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.
	 */
	scic_sds_port_abort_dummy_request(sci_port);

	isci_port_not_ready(ihost, iport);

	if (sci_port->ready_exit)
		scic_sds_port_invalidate_dummy_remote_node(sci_port);
}

static void scic_sds_port_ready_substate_configuring_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_port *sci_port = container_of(sm, typeof(*sci_port), state_machine);
	struct scic_sds_controller *scic = sci_port->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);
	struct isci_port *iport = sci_port_to_iport(sci_port);

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

		port_state_machine_change(sci_port,
					  SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
	} else if (sci_port->started_request_count == 0)
		port_state_machine_change(sci_port,
					  SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
}

static void scic_sds_port_ready_substate_configuring_exit(struct sci_base_state_machine *sm)
{
	struct scic_sds_port *sci_port = container_of(sm, typeof(*sci_port), state_machine);

	scic_sds_port_suspend_port_task_scheduler(sci_port);
	if (sci_port->ready_exit)
		scic_sds_port_invalidate_dummy_remote_node(sci_port);
}

enum sci_status scic_sds_port_start(struct scic_sds_port *sci_port)
{
	struct scic_sds_controller *scic = sci_port->owning_controller;
	enum sci_status status = SCI_SUCCESS;
	enum scic_sds_port_states state;
	u32 phy_mask;

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

	if (sci_port->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 (sci_port->reserved_rni == SCU_DUMMY_INDEX) {
		u16 rni = scic_sds_remote_node_table_allocate_remote_node(
				&scic->available_remote_nodes, 1);

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

	if (sci_port->reserved_tci == SCU_DUMMY_INDEX) {
		/* Allocate a TCI and remove the sequence nibble */
		u16 tci = scic_controller_allocate_io_tag(scic);

		if (tci != SCU_DUMMY_INDEX)
			scic_sds_port_construct_dummy_task(sci_port, tci);
		else
			status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
		sci_port->reserved_tci = tci;
	}

	if (status == SCI_SUCCESS) {
		phy_mask = scic_sds_port_get_phys(sci_port);

		/*
		 * 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 (scic_sds_port_is_phy_mask_valid(sci_port, phy_mask) == true) {
			port_state_machine_change(sci_port,
						  SCI_BASE_PORT_STATE_READY);

			return SCI_SUCCESS;
		}
		status = SCI_FAILURE;
	}

	if (status != SCI_SUCCESS)
		scic_sds_port_destroy_dummy_resources(sci_port);

	return status;
}

enum sci_status scic_sds_port_stop(struct scic_sds_port *sci_port)
{
	enum scic_sds_port_states state;

	state = sci_port->state_machine.current_state_id;
	switch (state) {
	case SCI_BASE_PORT_STATE_STOPPED:
		return SCI_SUCCESS;
	case SCIC_SDS_PORT_READY_SUBSTATE_WAITING:
	case SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL:
	case SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING:
	case SCI_BASE_PORT_STATE_RESETTING:
		port_state_machine_change(sci_port,
					  SCI_BASE_PORT_STATE_STOPPING);
		return SCI_SUCCESS;
	default:
		dev_warn(sciport_to_dev(sci_port),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

static enum sci_status scic_port_hard_reset(struct scic_sds_port *sci_port, u32 timeout)
{
	enum sci_status status = SCI_FAILURE_INVALID_PHY;
	struct scic_sds_phy *selected_phy = NULL;
	enum scic_sds_port_states state;
	u32 phy_index;

	state = sci_port->state_machine.current_state_id;
	if (state != SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL) {
		dev_warn(sciport_to_dev(sci_port),
			 "%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 && !selected_phy; phy_index++) {
		selected_phy = sci_port->phy_table[phy_index];
		if (selected_phy &&
		    !scic_sds_port_active_phy(sci_port, selected_phy)) {
			/*
			 * We found a phy but it is not ready select
			 * different phy
			 */
			selected_phy = NULL;
		}
	}

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

	if (status != SCI_SUCCESS)
		return status;

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

	port_state_machine_change(sci_port,
				  SCI_BASE_PORT_STATE_RESETTING);
	return SCI_SUCCESS;
}

/**
 * scic_sds_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 scic_sds_port_add_phy(struct scic_sds_port *sci_port,
				      struct scic_sds_phy *sci_phy)
{
	enum sci_status status;
	enum scic_sds_port_states state;

	state = sci_port->state_machine.current_state_id;
	switch (state) {
	case SCI_BASE_PORT_STATE_STOPPED: {
		struct sci_sas_address port_sas_address;

		/* Read the port assigned SAS Address if there is one */
		scic_sds_port_get_sas_address(sci_port, &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
			 */
			scic_sds_phy_get_sas_address(sci_phy, &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 scic_sds_port_set_phy(sci_port, sci_phy);
	}
	case SCIC_SDS_PORT_READY_SUBSTATE_WAITING:
	case SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL:
		status = scic_sds_port_set_phy(sci_port, sci_phy);

		if (status != SCI_SUCCESS)
			return status;

		scic_sds_port_general_link_up_handler(sci_port, sci_phy, true);
		sci_port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
		port_state_machine_change(sci_port, SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING);

		return status;
	case SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING:
		status = scic_sds_port_set_phy(sci_port, sci_phy);

		if (status != SCI_SUCCESS)
			return status;
		scic_sds_port_general_link_up_handler(sci_port, sci_phy, true);

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

/**
 * scic_sds_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 scic_sds_port_remove_phy(struct scic_sds_port *sci_port,
					 struct scic_sds_phy *sci_phy)
{
	enum sci_status status;
	enum scic_sds_port_states state;

	state = sci_port->state_machine.current_state_id;

	switch (state) {
	case SCI_BASE_PORT_STATE_STOPPED:
		return scic_sds_port_clear_phy(sci_port, sci_phy);
	case SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL:
		status = scic_sds_port_clear_phy(sci_port, sci_phy);
		if (status != SCI_SUCCESS)
			return status;

		scic_sds_port_deactivate_phy(sci_port, sci_phy, true);
		sci_port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
		port_state_machine_change(sci_port,
					  SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING);
		return SCI_SUCCESS;
	case SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING:
		status = scic_sds_port_clear_phy(sci_port, sci_phy);

		if (status != SCI_SUCCESS)
			return status;
		scic_sds_port_deactivate_phy(sci_port, sci_phy, true);

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

enum sci_status scic_sds_port_link_up(struct scic_sds_port *sci_port,
				      struct scic_sds_phy *sci_phy)
{
	enum scic_sds_port_states state;

	state = sci_port->state_machine.current_state_id;
	switch (state) {
	case SCIC_SDS_PORT_READY_SUBSTATE_WAITING:
		/* Since this is the first phy going link up for the port we
		 * can just enable it and continue
		 */
		scic_sds_port_activate_phy(sci_port, sci_phy, true);

		port_state_machine_change(sci_port,
					  SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
		return SCI_SUCCESS;
	case SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL:
		scic_sds_port_general_link_up_handler(sci_port, sci_phy, true);
		return SCI_SUCCESS;
	case SCI_BASE_PORT_STATE_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.
		 */
		scic_sds_port_general_link_up_handler(sci_port, sci_phy, false);
		return SCI_SUCCESS;
	default:
		dev_warn(sciport_to_dev(sci_port),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

enum sci_status scic_sds_port_link_down(struct scic_sds_port *sci_port,
					struct scic_sds_phy *sci_phy)
{
	enum scic_sds_port_states state;

	state = sci_port->state_machine.current_state_id;
	switch (state) {
	case SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL:
		scic_sds_port_deactivate_phy(sci_port, sci_phy, 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 (sci_port->active_phy_mask == 0)
			port_state_machine_change(sci_port,
						  SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
		return SCI_SUCCESS;
	case SCI_BASE_PORT_STATE_RESETTING:
		/* In the resetting state we don't notify the user regarding
		 * link up and link down notifications. */
		scic_sds_port_deactivate_phy(sci_port, sci_phy, false);
		return SCI_SUCCESS;
	default:
		dev_warn(sciport_to_dev(sci_port),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

enum sci_status scic_sds_port_start_io(struct scic_sds_port *sci_port,
				       struct scic_sds_remote_device *sci_dev,
				       struct scic_sds_request *sci_req)
{
	enum scic_sds_port_states state;

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

enum sci_status scic_sds_port_complete_io(struct scic_sds_port *sci_port,
					  struct scic_sds_remote_device *sci_dev,
					  struct scic_sds_request *sci_req)
{
	enum scic_sds_port_states state;

	state = sci_port->state_machine.current_state_id;
	switch (state) {
	case SCI_BASE_PORT_STATE_STOPPED:
		dev_warn(sciport_to_dev(sci_port),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	case SCI_BASE_PORT_STATE_STOPPING:
		scic_sds_port_decrement_request_count(sci_port);

		if (sci_port->started_request_count == 0)
			port_state_machine_change(sci_port,
						  SCI_BASE_PORT_STATE_STOPPED);
		break;
	case SCI_BASE_PORT_STATE_READY:
	case SCI_BASE_PORT_STATE_RESETTING:
	case SCI_BASE_PORT_STATE_FAILED:
	case SCIC_SDS_PORT_READY_SUBSTATE_WAITING:
	case SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL:
		scic_sds_port_decrement_request_count(sci_port);
		break;
	case SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING:
		scic_sds_port_decrement_request_count(sci_port);
		if (sci_port->started_request_count == 0) {
			port_state_machine_change(sci_port,
						  SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
		}
		break;
	}
	return SCI_SUCCESS;
}

/**
 *
 * @sci_port: This is the port object which to suspend.
 *
 * This method will enable the SCU Port Task Scheduler for this port object but
 * will leave the port task scheduler in a suspended state. none
 */
static void
scic_sds_port_enable_port_task_scheduler(struct scic_sds_port *port)
{
	u32 pts_control_value;

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

/**
 *
 * @sci_port: This is the port object which to resume.
 *
 * This method will disable the SCU port task scheduler for this port object.
 * none
 */
static void
scic_sds_port_disable_port_task_scheduler(struct scic_sds_port *port)
{
	u32 pts_control_value;

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

static void scic_sds_port_post_dummy_remote_node(struct scic_sds_port *sci_port)
{
	struct scic_sds_controller *scic = sci_port->owning_controller;
	u8 phys_index = sci_port->physical_port_index;
	union scu_remote_node_context *rnc;
	u16 rni = sci_port->reserved_rni;
	u32 command;

	rnc = &scic->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;

	scic_sds_controller_post_request(scic, command);

	/* ensure hardware has seen the post rnc command and give it
	 * ample time to act before sending the suspend
	 */
	readl(&scic->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;

	scic_sds_controller_post_request(scic, command);
}

static void scic_sds_port_stopped_state_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_port *sci_port = container_of(sm, typeof(*sci_port), state_machine);

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

static void scic_sds_port_stopped_state_exit(struct sci_base_state_machine *sm)
{
	struct scic_sds_port *sci_port = container_of(sm, typeof(*sci_port), state_machine);

	/* Enable and suspend the port task scheduler */
	scic_sds_port_enable_port_task_scheduler(sci_port);
}

static void scic_sds_port_ready_state_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_port *sci_port = container_of(sm, typeof(*sci_port), state_machine);
	struct scic_sds_controller *scic = sci_port->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);
	struct isci_port *iport = sci_port_to_iport(sci_port);
	u32 prev_state;

	prev_state = sci_port->state_machine.previous_state_id;
	if (prev_state  == SCI_BASE_PORT_STATE_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. */
	scic_sds_port_post_dummy_remote_node(sci_port);

	/* Start the ready substate machine */
	port_state_machine_change(sci_port,
				  SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
}

static void scic_sds_port_resetting_state_exit(struct sci_base_state_machine *sm)
{
	struct scic_sds_port *sci_port = container_of(sm, typeof(*sci_port), state_machine);

	sci_del_timer(&sci_port->timer);
}

static void scic_sds_port_stopping_state_exit(struct sci_base_state_machine *sm)
{
	struct scic_sds_port *sci_port = container_of(sm, typeof(*sci_port), state_machine);

	sci_del_timer(&sci_port->timer);

	scic_sds_port_destroy_dummy_resources(sci_port);
}

static void scic_sds_port_failed_state_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_port *sci_port = container_of(sm, typeof(*sci_port), state_machine);
	struct isci_port *iport = sci_port_to_iport(sci_port);

	isci_port_hard_reset_complete(iport, SCI_FAILURE_TIMEOUT);
}

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

static const struct sci_base_state scic_sds_port_state_table[] = {
	[SCI_BASE_PORT_STATE_STOPPED] = {
		.enter_state = scic_sds_port_stopped_state_enter,
		.exit_state  = scic_sds_port_stopped_state_exit
	},
	[SCI_BASE_PORT_STATE_STOPPING] = {
		.exit_state  = scic_sds_port_stopping_state_exit
	},
	[SCI_BASE_PORT_STATE_READY] = {
		.enter_state = scic_sds_port_ready_state_enter,
	},
	[SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = {
		.enter_state = scic_sds_port_ready_substate_waiting_enter,
	},
	[SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = {
		.enter_state = scic_sds_port_ready_substate_operational_enter,
		.exit_state  = scic_sds_port_ready_substate_operational_exit
	},
	[SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = {
		.enter_state = scic_sds_port_ready_substate_configuring_enter,
		.exit_state  = scic_sds_port_ready_substate_configuring_exit
	},
	[SCI_BASE_PORT_STATE_RESETTING] = {
		.exit_state  = scic_sds_port_resetting_state_exit
	},
	[SCI_BASE_PORT_STATE_FAILED] = {
		.enter_state = scic_sds_port_failed_state_enter,
	}
};

void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 index,
			     struct scic_sds_controller *scic)
{
	sci_base_state_machine_construct(&sci_port->state_machine,
					 scic_sds_port_state_table,
					 SCI_BASE_PORT_STATE_STOPPED);

	sci_base_state_machine_start(&sci_port->state_machine);

	sci_port->logical_port_index  = SCIC_SDS_DUMMY_PORT;
	sci_port->physical_port_index = index;
	sci_port->active_phy_mask     = 0;
	sci_port->ready_exit	      = false;

	sci_port->owning_controller = scic;

	sci_port->started_request_count = 0;
	sci_port->assigned_device_count = 0;

	sci_port->reserved_rni = SCU_DUMMY_INDEX;
	sci_port->reserved_tci = SCU_DUMMY_INDEX;

	sci_init_timer(&sci_port->timer, port_timeout);

	sci_port->port_task_scheduler_registers = NULL;

	for (index = 0; index < SCI_MAX_PHYS; index++)
		sci_port->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;
}

static void isci_port_bc_change_received(struct isci_host *ihost,
					 struct scic_sds_port *sci_port,
					 struct scic_sds_phy *sci_phy)
{
	struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);

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

	ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD);
	scic_port_enable_broadcast_change_notification(sci_port);
}

void scic_sds_port_broadcast_change_received(
	struct scic_sds_port *sci_port,
	struct scic_sds_phy *sci_phy)
{
	struct scic_sds_controller *scic = sci_port->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);

	/* notify the user. */
	isci_port_bc_change_received(ihost, sci_port, sci_phy);
}

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 = scic_port_hard_reset(&iport->sci, 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;
	} else {
		ret = TMF_RESP_FUNC_FAILED;

		dev_err(&ihost->pdev->dev,
			"%s: iport = %p; scic_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) - sending link down to libsas for phy %p\n",
			__func__, iport, iport->hard_reset_status, iphy);

		isci_port_link_down(ihost, iphy, iport);
	}

	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);
}
