// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for Broadcom MPI3 Storage Controllers
 *
 * Copyright (C) 2017-2023 Broadcom Inc.
 *  (mailto: mpi3mr-linuxdrv.pdl@broadcom.com)
 *
 */

#include <linux/vmalloc.h>

#include "mpi3mr.h"

/**
 * mpi3mr_post_transport_req - Issue transport requests and wait
 * @mrioc: Adapter instance reference
 * @request: Properly populated MPI3 request
 * @request_sz: Size of the MPI3 request
 * @reply: Pointer to return MPI3 reply
 * @reply_sz: Size of the MPI3 reply buffer
 * @timeout: Timeout in seconds
 * @ioc_status: Pointer to return ioc status
 *
 * A generic function for posting MPI3 requests from the SAS
 * transport layer that uses transport command infrastructure.
 * This blocks for the completion of request for timeout seconds
 * and if the request times out this function faults the
 * controller with proper reason code.
 *
 * On successful completion of the request this function returns
 * appropriate ioc status from the firmware back to the caller.
 *
 * Return: 0 on success, non-zero on failure.
 */
static int mpi3mr_post_transport_req(struct mpi3mr_ioc *mrioc, void *request,
	u16 request_sz, void *reply, u16 reply_sz, int timeout,
	u16 *ioc_status)
{
	int retval = 0;

	mutex_lock(&mrioc->transport_cmds.mutex);
	if (mrioc->transport_cmds.state & MPI3MR_CMD_PENDING) {
		retval = -1;
		ioc_err(mrioc, "sending transport request failed due to command in use\n");
		mutex_unlock(&mrioc->transport_cmds.mutex);
		goto out;
	}
	mrioc->transport_cmds.state = MPI3MR_CMD_PENDING;
	mrioc->transport_cmds.is_waiting = 1;
	mrioc->transport_cmds.callback = NULL;
	mrioc->transport_cmds.ioc_status = 0;
	mrioc->transport_cmds.ioc_loginfo = 0;

	init_completion(&mrioc->transport_cmds.done);
	dprint_cfg_info(mrioc, "posting transport request\n");
	if (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)
		dprint_dump(request, request_sz, "transport_req");
	retval = mpi3mr_admin_request_post(mrioc, request, request_sz, 1);
	if (retval) {
		ioc_err(mrioc, "posting transport request failed\n");
		goto out_unlock;
	}
	wait_for_completion_timeout(&mrioc->transport_cmds.done,
	    (timeout * HZ));
	if (!(mrioc->transport_cmds.state & MPI3MR_CMD_COMPLETE)) {
		mpi3mr_check_rh_fault_ioc(mrioc,
		    MPI3MR_RESET_FROM_SAS_TRANSPORT_TIMEOUT);
		ioc_err(mrioc, "transport request timed out\n");
		retval = -1;
		goto out_unlock;
	}
	*ioc_status = mrioc->transport_cmds.ioc_status &
		MPI3_IOCSTATUS_STATUS_MASK;
	if ((*ioc_status) != MPI3_IOCSTATUS_SUCCESS)
		dprint_transport_err(mrioc,
		    "transport request returned with ioc_status(0x%04x), log_info(0x%08x)\n",
		    *ioc_status, mrioc->transport_cmds.ioc_loginfo);

	if ((reply) && (mrioc->transport_cmds.state & MPI3MR_CMD_REPLY_VALID))
		memcpy((u8 *)reply, mrioc->transport_cmds.reply, reply_sz);

out_unlock:
	mrioc->transport_cmds.state = MPI3MR_CMD_NOTUSED;
	mutex_unlock(&mrioc->transport_cmds.mutex);

out:
	return retval;
}

/* report manufacture request structure */
struct rep_manu_request {
	u8 smp_frame_type;
	u8 function;
	u8 reserved;
	u8 request_length;
};

/* report manufacture reply structure */
struct rep_manu_reply {
	u8 smp_frame_type; /* 0x41 */
	u8 function; /* 0x01 */
	u8 function_result;
	u8 response_length;
	u16 expander_change_count;
	u8 reserved0[2];
	u8 sas_format;
	u8 reserved2[3];
	u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
	u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
	u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
	u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
	u16 component_id;
	u8 component_revision_id;
	u8 reserved3;
	u8 vendor_specific[8];
};

/**
 * mpi3mr_report_manufacture - obtain SMP report_manufacture
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of the expander device
 * @edev: SAS transport layer sas_expander_device object
 * @port_id: ID of the HBA port
 *
 * Fills in the sas_expander_device with manufacturing info.
 *
 * Return: 0 for success, non-zero for failure.
 */
static int mpi3mr_report_manufacture(struct mpi3mr_ioc *mrioc,
	u64 sas_address, struct sas_expander_device *edev, u8 port_id)
{
	struct mpi3_smp_passthrough_request mpi_request;
	struct mpi3_smp_passthrough_reply mpi_reply;
	struct rep_manu_reply *manufacture_reply;
	struct rep_manu_request *manufacture_request;
	int rc = 0;
	void *psge;
	void *data_out = NULL;
	dma_addr_t data_out_dma;
	dma_addr_t data_in_dma;
	size_t data_in_sz;
	size_t data_out_sz;
	u8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST;
	u16 request_sz = sizeof(struct mpi3_smp_passthrough_request);
	u16 reply_sz = sizeof(struct mpi3_smp_passthrough_reply);
	u16 ioc_status;
	u8 *tmp;

	if (mrioc->reset_in_progress) {
		ioc_err(mrioc, "%s: host reset in progress!\n", __func__);
		return -EFAULT;
	}

	if (mrioc->pci_err_recovery) {
		ioc_err(mrioc, "%s: pci error recovery in progress!\n", __func__);
		return -EFAULT;
	}

	data_out_sz = sizeof(struct rep_manu_request);
	data_in_sz = sizeof(struct rep_manu_reply);
	data_out = dma_alloc_coherent(&mrioc->pdev->dev,
	    data_out_sz + data_in_sz, &data_out_dma, GFP_KERNEL);
	if (!data_out) {
		rc = -ENOMEM;
		goto out;
	}

	data_in_dma = data_out_dma + data_out_sz;
	manufacture_reply = data_out + data_out_sz;

	manufacture_request = data_out;
	manufacture_request->smp_frame_type = 0x40;
	manufacture_request->function = 1;
	manufacture_request->reserved = 0;
	manufacture_request->request_length = 0;

	memset(&mpi_request, 0, request_sz);
	memset(&mpi_reply, 0, reply_sz);
	mpi_request.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_TRANSPORT_CMDS);
	mpi_request.function = MPI3_FUNCTION_SMP_PASSTHROUGH;
	mpi_request.io_unit_port = (u8) port_id;
	mpi_request.sas_address = cpu_to_le64(sas_address);

	psge = &mpi_request.request_sge;
	mpi3mr_add_sg_single(psge, sgl_flags, data_out_sz, data_out_dma);

	psge = &mpi_request.response_sge;
	mpi3mr_add_sg_single(psge, sgl_flags, data_in_sz, data_in_dma);

	dprint_transport_info(mrioc,
	    "sending report manufacturer SMP request to sas_address(0x%016llx), port(%d)\n",
	    (unsigned long long)sas_address, port_id);

	rc = mpi3mr_post_transport_req(mrioc, &mpi_request, request_sz,
				       &mpi_reply, reply_sz,
				       MPI3MR_INTADMCMD_TIMEOUT, &ioc_status);
	if (rc)
		goto out;

	dprint_transport_info(mrioc,
	    "report manufacturer SMP request completed with ioc_status(0x%04x)\n",
	    ioc_status);

	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
		rc = -EINVAL;
		goto out;
	}

	dprint_transport_info(mrioc,
	    "report manufacturer - reply data transfer size(%d)\n",
	    le16_to_cpu(mpi_reply.response_data_length));

	if (le16_to_cpu(mpi_reply.response_data_length) !=
	    sizeof(struct rep_manu_reply)) {
		rc = -EINVAL;
		goto out;
	}

	memtostr(edev->vendor_id, manufacture_reply->vendor_id);
	memtostr(edev->product_id, manufacture_reply->product_id);
	memtostr(edev->product_rev, manufacture_reply->product_rev);
	edev->level = manufacture_reply->sas_format & 1;
	if (edev->level) {
		memtostr(edev->component_vendor_id,
			 manufacture_reply->component_vendor_id);
		tmp = (u8 *)&manufacture_reply->component_id;
		edev->component_id = tmp[0] << 8 | tmp[1];
		edev->component_revision_id =
		    manufacture_reply->component_revision_id;
	}

out:
	if (data_out)
		dma_free_coherent(&mrioc->pdev->dev, data_out_sz + data_in_sz,
		    data_out, data_out_dma);

	return rc;
}

/**
 * __mpi3mr_expander_find_by_handle - expander search by handle
 * @mrioc: Adapter instance reference
 * @handle: Firmware device handle of the expander
 *
 * Context: The caller should acquire sas_node_lock
 *
 * This searches for expander device based on handle, then
 * returns the sas_node object.
 *
 * Return: Expander sas_node object reference or NULL
 */
struct mpi3mr_sas_node *__mpi3mr_expander_find_by_handle(struct mpi3mr_ioc
	*mrioc, u16 handle)
{
	struct mpi3mr_sas_node *sas_expander, *r;

	r = NULL;
	list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) {
		if (sas_expander->handle != handle)
			continue;
		r = sas_expander;
		goto out;
	}
 out:
	return r;
}

/**
 * mpi3mr_is_expander_device - if device is an expander
 * @device_info: Bitfield providing information about the device
 *
 * Return: 1 if the device is expander device, else 0.
 */
u8 mpi3mr_is_expander_device(u16 device_info)
{
	if ((device_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) ==
	     MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_EXPANDER)
		return 1;
	else
		return 0;
}

/**
 * mpi3mr_get_sas_address - retrieve sas_address for handle
 * @mrioc: Adapter instance reference
 * @handle: Firmware device handle
 * @sas_address: Address to hold sas address
 *
 * This function issues device page0 read for a given device
 * handle and gets the SAS address and return it back
 *
 * Return: 0 for success, non-zero for failure
 */
static int mpi3mr_get_sas_address(struct mpi3mr_ioc *mrioc, u16 handle,
	u64 *sas_address)
{
	struct mpi3_device_page0 dev_pg0;
	u16 ioc_status;
	struct mpi3_device0_sas_sata_format *sasinf;

	*sas_address = 0;

	if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &dev_pg0,
	    sizeof(dev_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE,
	    handle))) {
		ioc_err(mrioc, "%s: device page0 read failed\n", __func__);
		return -ENXIO;
	}

	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
		ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:%d/%s()!\n",
		    handle, ioc_status, __FILE__, __LINE__, __func__);
		return -ENXIO;
	}

	if (le16_to_cpu(dev_pg0.flags) &
	    MPI3_DEVICE0_FLAGS_CONTROLLER_DEV_HANDLE)
		*sas_address = mrioc->sas_hba.sas_address;
	else if (dev_pg0.device_form == MPI3_DEVICE_DEVFORM_SAS_SATA) {
		sasinf = &dev_pg0.device_specific.sas_sata_format;
		*sas_address = le64_to_cpu(sasinf->sas_address);
	} else {
		ioc_err(mrioc, "%s: device_form(%d) is not SAS_SATA\n",
		    __func__, dev_pg0.device_form);
		return -ENXIO;
	}
	return 0;
}

/**
 * __mpi3mr_get_tgtdev_by_addr - target device search
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of the device
 * @hba_port: HBA port entry
 *
 * This searches for target device from sas address and hba port
 * pointer then return mpi3mr_tgt_dev object.
 *
 * Return: Valid tget_dev or NULL
 */
static struct mpi3mr_tgt_dev *__mpi3mr_get_tgtdev_by_addr(struct mpi3mr_ioc *mrioc,
	u64 sas_address, struct mpi3mr_hba_port *hba_port)
{
	struct mpi3mr_tgt_dev *tgtdev;

	assert_spin_locked(&mrioc->tgtdev_lock);

	list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list)
		if ((tgtdev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA) &&
		    (tgtdev->dev_spec.sas_sata_inf.sas_address == sas_address)
		    && (tgtdev->dev_spec.sas_sata_inf.hba_port == hba_port))
			goto found_device;
	return NULL;
found_device:
	mpi3mr_tgtdev_get(tgtdev);
	return tgtdev;
}

/**
 * mpi3mr_get_tgtdev_by_addr - target device search
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of the device
 * @hba_port: HBA port entry
 *
 * This searches for target device from sas address and hba port
 * pointer then return mpi3mr_tgt_dev object.
 *
 * Context: This function will acquire tgtdev_lock and will
 * release before returning the mpi3mr_tgt_dev object.
 *
 * Return: Valid tget_dev or NULL
 */
static struct mpi3mr_tgt_dev *mpi3mr_get_tgtdev_by_addr(struct mpi3mr_ioc *mrioc,
	u64 sas_address, struct mpi3mr_hba_port *hba_port)
{
	struct mpi3mr_tgt_dev *tgtdev = NULL;
	unsigned long flags;

	if (!hba_port)
		goto out;

	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
	tgtdev = __mpi3mr_get_tgtdev_by_addr(mrioc, sas_address, hba_port);
	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);

out:
	return tgtdev;
}

/**
 * mpi3mr_remove_device_by_sas_address - remove the device
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of the device
 * @hba_port: HBA port entry
 *
 * This searches for target device using sas address and hba
 * port pointer then removes it from the OS.
 *
 * Return: None
 */
static void mpi3mr_remove_device_by_sas_address(struct mpi3mr_ioc *mrioc,
	u64 sas_address, struct mpi3mr_hba_port *hba_port)
{
	struct mpi3mr_tgt_dev *tgtdev = NULL;
	unsigned long flags;
	u8 was_on_tgtdev_list = 0;

	if (!hba_port)
		return;

	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
	tgtdev = __mpi3mr_get_tgtdev_by_addr(mrioc,
			 sas_address, hba_port);
	if (tgtdev) {
		if (!list_empty(&tgtdev->list)) {
			list_del_init(&tgtdev->list);
			was_on_tgtdev_list = 1;
			mpi3mr_tgtdev_put(tgtdev);
		}
	}
	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
	if (was_on_tgtdev_list) {
		if (tgtdev->host_exposed)
			mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev);
		mpi3mr_tgtdev_put(tgtdev);
	}
}

/**
 * __mpi3mr_get_tgtdev_by_addr_and_rphy - target device search
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of the device
 * @rphy: SAS transport layer rphy object
 *
 * This searches for target device from sas address and rphy
 * pointer then return mpi3mr_tgt_dev object.
 *
 * Return: Valid tget_dev or NULL
 */
struct mpi3mr_tgt_dev *__mpi3mr_get_tgtdev_by_addr_and_rphy(
	struct mpi3mr_ioc *mrioc, u64 sas_address, struct sas_rphy *rphy)
{
	struct mpi3mr_tgt_dev *tgtdev;

	assert_spin_locked(&mrioc->tgtdev_lock);

	list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list)
		if ((tgtdev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA) &&
		    (tgtdev->dev_spec.sas_sata_inf.sas_address == sas_address)
		    && (tgtdev->dev_spec.sas_sata_inf.rphy == rphy))
			goto found_device;
	return NULL;
found_device:
	mpi3mr_tgtdev_get(tgtdev);
	return tgtdev;
}

/**
 * mpi3mr_expander_find_by_sas_address - sas expander search
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of expander
 * @hba_port: HBA port entry
 *
 * Return: A valid SAS expander node or NULL.
 *
 */
static struct mpi3mr_sas_node *mpi3mr_expander_find_by_sas_address(
	struct mpi3mr_ioc *mrioc, u64 sas_address,
	struct mpi3mr_hba_port *hba_port)
{
	struct mpi3mr_sas_node *sas_expander, *r = NULL;

	if (!hba_port)
		goto out;

	list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) {
		if ((sas_expander->sas_address != sas_address) ||
					 (sas_expander->hba_port != hba_port))
			continue;
		r = sas_expander;
		goto out;
	}
out:
	return r;
}

/**
 * __mpi3mr_sas_node_find_by_sas_address - sas node search
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of expander or sas host
 * @hba_port: HBA port entry
 * Context: Caller should acquire mrioc->sas_node_lock.
 *
 * If the SAS address indicates the device is direct attached to
 * the controller (controller's SAS address) then the SAS node
 * associated with the controller is returned back else the SAS
 * address and hba port are used to identify the exact expander
 * and the associated sas_node object is returned. If there is
 * no match NULL is returned.
 *
 * Return: A valid SAS node or NULL.
 *
 */
static struct mpi3mr_sas_node *__mpi3mr_sas_node_find_by_sas_address(
	struct mpi3mr_ioc *mrioc, u64 sas_address,
	struct mpi3mr_hba_port *hba_port)
{

	if (mrioc->sas_hba.sas_address == sas_address)
		return &mrioc->sas_hba;
	return mpi3mr_expander_find_by_sas_address(mrioc, sas_address,
	    hba_port);
}

/**
 * mpi3mr_parent_present - Is parent present for a phy
 * @mrioc: Adapter instance reference
 * @phy: SAS transport layer phy object
 *
 * Return: 0 if parent is present else non-zero
 */
static int mpi3mr_parent_present(struct mpi3mr_ioc *mrioc, struct sas_phy *phy)
{
	unsigned long flags;
	struct mpi3mr_hba_port *hba_port = phy->hostdata;

	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	if (__mpi3mr_sas_node_find_by_sas_address(mrioc,
	    phy->identify.sas_address,
	    hba_port) == NULL) {
		spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
		return -1;
	}
	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
	return 0;
}

/**
 * mpi3mr_convert_phy_link_rate -
 * @link_rate: link rate as defined in the MPI header
 *
 * Convert link_rate from mpi format into sas_transport layer
 * form.
 *
 * Return: A valid SAS transport layer defined link rate
 */
static enum sas_linkrate mpi3mr_convert_phy_link_rate(u8 link_rate)
{
	enum sas_linkrate rc;

	switch (link_rate) {
	case MPI3_SAS_NEG_LINK_RATE_1_5:
		rc = SAS_LINK_RATE_1_5_GBPS;
		break;
	case MPI3_SAS_NEG_LINK_RATE_3_0:
		rc = SAS_LINK_RATE_3_0_GBPS;
		break;
	case MPI3_SAS_NEG_LINK_RATE_6_0:
		rc = SAS_LINK_RATE_6_0_GBPS;
		break;
	case MPI3_SAS_NEG_LINK_RATE_12_0:
		rc = SAS_LINK_RATE_12_0_GBPS;
		break;
	case MPI3_SAS_NEG_LINK_RATE_22_5:
		rc = SAS_LINK_RATE_22_5_GBPS;
		break;
	case MPI3_SAS_NEG_LINK_RATE_PHY_DISABLED:
		rc = SAS_PHY_DISABLED;
		break;
	case MPI3_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED:
		rc = SAS_LINK_RATE_FAILED;
		break;
	case MPI3_SAS_NEG_LINK_RATE_PORT_SELECTOR:
		rc = SAS_SATA_PORT_SELECTOR;
		break;
	case MPI3_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS:
		rc = SAS_PHY_RESET_IN_PROGRESS;
		break;
	case MPI3_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE:
	case MPI3_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE:
	default:
		rc = SAS_LINK_RATE_UNKNOWN;
		break;
	}
	return rc;
}

/**
 * mpi3mr_delete_sas_phy - Remove a single phy from port
 * @mrioc: Adapter instance reference
 * @mr_sas_port: Internal Port object
 * @mr_sas_phy: Internal Phy object
 * @host_node: Flag to indicate this is a host_node
 *
 * Return: None.
 */
static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_port *mr_sas_port,
	struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node)
{
	u64 sas_address = mr_sas_port->remote_identify.sas_address;

	dev_info(&mr_sas_phy->phy->dev,
	    "remove: sas_address(0x%016llx), phy(%d)\n",
	    (unsigned long long) sas_address, mr_sas_phy->phy_id);

	list_del(&mr_sas_phy->port_siblings);
	mr_sas_port->num_phys--;

	if (host_node) {
		mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id);

		if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id)
			mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
	}
	sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy);
	mr_sas_phy->phy_belongs_to_port = 0;
}

/**
 * mpi3mr_add_sas_phy - Adding a single phy to a port
 * @mrioc: Adapter instance reference
 * @mr_sas_port: Internal Port object
 * @mr_sas_phy: Internal Phy object
 * @host_node: Flag to indicate this is a host_node
 *
 * Return: None.
 */
static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_port *mr_sas_port,
	struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node)
{
	u64 sas_address = mr_sas_port->remote_identify.sas_address;

	dev_info(&mr_sas_phy->phy->dev,
	    "add: sas_address(0x%016llx), phy(%d)\n", (unsigned long long)
	    sas_address, mr_sas_phy->phy_id);

	list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list);
	mr_sas_port->num_phys++;
	if (host_node) {
		mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id);

		if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy)
			mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
	}
	sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy);
	mr_sas_phy->phy_belongs_to_port = 1;
}

/**
 * mpi3mr_add_phy_to_an_existing_port - add phy to existing port
 * @mrioc: Adapter instance reference
 * @mr_sas_node: Internal sas node object (expander or host)
 * @mr_sas_phy: Internal Phy object *
 * @sas_address: SAS address of device/expander were phy needs
 *             to be added to
 * @hba_port: HBA port entry
 *
 * Return: None.
 */
static void mpi3mr_add_phy_to_an_existing_port(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *mr_sas_node, struct mpi3mr_sas_phy *mr_sas_phy,
	u64 sas_address, struct mpi3mr_hba_port *hba_port)
{
	struct mpi3mr_sas_port *mr_sas_port;
	struct mpi3mr_sas_phy *srch_phy;

	if (mr_sas_phy->phy_belongs_to_port == 1)
		return;

	if (!hba_port)
		return;

	list_for_each_entry(mr_sas_port, &mr_sas_node->sas_port_list,
	    port_list) {
		if (mr_sas_port->remote_identify.sas_address !=
		    sas_address)
			continue;
		if (mr_sas_port->hba_port != hba_port)
			continue;
		list_for_each_entry(srch_phy, &mr_sas_port->phy_list,
		    port_siblings) {
			if (srch_phy == mr_sas_phy)
				return;
		}
		mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy, mr_sas_node->host_node);
		return;
	}
}

/**
 * mpi3mr_delete_sas_port - helper function to removing a port
 * @mrioc: Adapter instance reference
 * @mr_sas_port: Internal Port object
 *
 * Return: None.
 */
static void  mpi3mr_delete_sas_port(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_port *mr_sas_port)
{
	u64 sas_address = mr_sas_port->remote_identify.sas_address;
	struct mpi3mr_hba_port *hba_port = mr_sas_port->hba_port;
	enum sas_device_type device_type =
	    mr_sas_port->remote_identify.device_type;

	dev_info(&mr_sas_port->port->dev,
	    "remove: sas_address(0x%016llx)\n",
	    (unsigned long long) sas_address);

	if (device_type == SAS_END_DEVICE)
		mpi3mr_remove_device_by_sas_address(mrioc, sas_address,
		    hba_port);

	else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
	    device_type == SAS_FANOUT_EXPANDER_DEVICE)
		mpi3mr_expander_remove(mrioc, sas_address, hba_port);
}

/**
 * mpi3mr_del_phy_from_an_existing_port - del phy from a port
 * @mrioc: Adapter instance reference
 * @mr_sas_node: Internal sas node object (expander or host)
 * @mr_sas_phy: Internal Phy object
 *
 * Return: None.
 */
static void mpi3mr_del_phy_from_an_existing_port(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *mr_sas_node, struct mpi3mr_sas_phy *mr_sas_phy)
{
	struct mpi3mr_sas_port *mr_sas_port, *next;
	struct mpi3mr_sas_phy *srch_phy;

	if (mr_sas_phy->phy_belongs_to_port == 0)
		return;

	list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list,
	    port_list) {
		list_for_each_entry(srch_phy, &mr_sas_port->phy_list,
		    port_siblings) {
			if (srch_phy != mr_sas_phy)
				continue;
			if ((mr_sas_port->num_phys == 1) &&
			    !mrioc->reset_in_progress)
				mpi3mr_delete_sas_port(mrioc, mr_sas_port);
			else
				mpi3mr_delete_sas_phy(mrioc, mr_sas_port,
				    mr_sas_phy, mr_sas_node->host_node);
			return;
		}
	}
}

/**
 * mpi3mr_sas_port_sanity_check - sanity check while adding port
 * @mrioc: Adapter instance reference
 * @mr_sas_node: Internal sas node object (expander or host)
 * @sas_address: SAS address of device/expander
 * @hba_port: HBA port entry
 *
 * Verifies whether the Phys attached to a device with the given
 * SAS address already belongs to an existing sas port if so
 * will remove those phys from the sas port
 *
 * Return: None.
 */
static void mpi3mr_sas_port_sanity_check(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *mr_sas_node, u64 sas_address,
	struct mpi3mr_hba_port *hba_port)
{
	int i;

	for (i = 0; i < mr_sas_node->num_phys; i++) {
		if ((mr_sas_node->phy[i].remote_identify.sas_address !=
		    sas_address) || (mr_sas_node->phy[i].hba_port != hba_port))
			continue;
		if (mr_sas_node->phy[i].phy_belongs_to_port == 1)
			mpi3mr_del_phy_from_an_existing_port(mrioc,
			    mr_sas_node, &mr_sas_node->phy[i]);
	}
}

/**
 * mpi3mr_set_identify - set identify for phys and end devices
 * @mrioc: Adapter instance reference
 * @handle: Firmware device handle
 * @identify: SAS transport layer's identify info
 *
 * Populates sas identify info for a specific device.
 *
 * Return: 0 for success, non-zero for failure.
 */
static int mpi3mr_set_identify(struct mpi3mr_ioc *mrioc, u16 handle,
	struct sas_identify *identify)
{

	struct mpi3_device_page0 device_pg0;
	struct mpi3_device0_sas_sata_format *sasinf;
	u16 device_info;
	u16 ioc_status;

	if (mrioc->reset_in_progress) {
		ioc_err(mrioc, "%s: host reset in progress!\n", __func__);
		return -EFAULT;
	}

	if (mrioc->pci_err_recovery) {
		ioc_err(mrioc, "%s: pci error recovery in progress!\n",
		    __func__);
		return -EFAULT;
	}

	if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &device_pg0,
	    sizeof(device_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE, handle))) {
		ioc_err(mrioc, "%s: device page0 read failed\n", __func__);
		return -ENXIO;
	}

	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
		ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:%d/%s()!\n",
		    handle, ioc_status, __FILE__, __LINE__, __func__);
		return -EIO;
	}

	memset(identify, 0, sizeof(struct sas_identify));
	sasinf = &device_pg0.device_specific.sas_sata_format;
	device_info = le16_to_cpu(sasinf->device_info);

	/* sas_address */
	identify->sas_address = le64_to_cpu(sasinf->sas_address);

	/* phy number of the parent device this device is linked to */
	identify->phy_identifier = sasinf->phy_num;

	/* device_type */
	switch (device_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) {
	case MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_NO_DEVICE:
		identify->device_type = SAS_PHY_UNUSED;
		break;
	case MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_END_DEVICE:
		identify->device_type = SAS_END_DEVICE;
		break;
	case MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_EXPANDER:
		identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
		break;
	}

	/* initiator_port_protocols */
	if (device_info & MPI3_SAS_DEVICE_INFO_SSP_INITIATOR)
		identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
	/* MPI3.0 doesn't have define for SATA INIT so setting both here*/
	if (device_info & MPI3_SAS_DEVICE_INFO_STP_INITIATOR)
		identify->initiator_port_protocols |= (SAS_PROTOCOL_STP |
		    SAS_PROTOCOL_SATA);
	if (device_info & MPI3_SAS_DEVICE_INFO_SMP_INITIATOR)
		identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;

	/* target_port_protocols */
	if (device_info & MPI3_SAS_DEVICE_INFO_SSP_TARGET)
		identify->target_port_protocols |= SAS_PROTOCOL_SSP;
	/* MPI3.0 doesn't have define for STP Target so setting both here*/
	if (device_info & MPI3_SAS_DEVICE_INFO_STP_SATA_TARGET)
		identify->target_port_protocols |= (SAS_PROTOCOL_STP |
		    SAS_PROTOCOL_SATA);
	if (device_info & MPI3_SAS_DEVICE_INFO_SMP_TARGET)
		identify->target_port_protocols |= SAS_PROTOCOL_SMP;
	return 0;
}

/**
 * mpi3mr_add_host_phy - report sas_host phy to SAS transport
 * @mrioc: Adapter instance reference
 * @mr_sas_phy: Internal Phy object
 * @phy_pg0: SAS phy page 0
 * @parent_dev: Prent device class object
 *
 * Return: 0 for success, non-zero for failure.
 */
static int mpi3mr_add_host_phy(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_phy *mr_sas_phy, struct mpi3_sas_phy_page0 phy_pg0,
	struct device *parent_dev)
{
	struct sas_phy *phy;
	int phy_index = mr_sas_phy->phy_id;


	INIT_LIST_HEAD(&mr_sas_phy->port_siblings);
	phy = sas_phy_alloc(parent_dev, phy_index);
	if (!phy) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return -1;
	}
	if ((mpi3mr_set_identify(mrioc, mr_sas_phy->handle,
	    &mr_sas_phy->identify))) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		sas_phy_free(phy);
		return -1;
	}
	phy->identify = mr_sas_phy->identify;
	mr_sas_phy->attached_handle = le16_to_cpu(phy_pg0.attached_dev_handle);
	if (mr_sas_phy->attached_handle)
		mpi3mr_set_identify(mrioc, mr_sas_phy->attached_handle,
		    &mr_sas_phy->remote_identify);
	phy->identify.phy_identifier = mr_sas_phy->phy_id;
	phy->negotiated_linkrate = mpi3mr_convert_phy_link_rate(
	    (phy_pg0.negotiated_link_rate &
	    MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
	    MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT);
	phy->minimum_linkrate_hw = mpi3mr_convert_phy_link_rate(
	    phy_pg0.hw_link_rate & MPI3_SAS_HWRATE_MIN_RATE_MASK);
	phy->maximum_linkrate_hw = mpi3mr_convert_phy_link_rate(
	    phy_pg0.hw_link_rate >> 4);
	phy->minimum_linkrate = mpi3mr_convert_phy_link_rate(
	    phy_pg0.programmed_link_rate & MPI3_SAS_PRATE_MIN_RATE_MASK);
	phy->maximum_linkrate = mpi3mr_convert_phy_link_rate(
	    phy_pg0.programmed_link_rate >> 4);
	phy->hostdata = mr_sas_phy->hba_port;

	if ((sas_phy_add(phy))) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		sas_phy_free(phy);
		return -1;
	}
	if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
		dev_info(&phy->dev,
		    "add: handle(0x%04x), sas_address(0x%016llx)\n"
		    "\tattached_handle(0x%04x), sas_address(0x%016llx)\n",
		    mr_sas_phy->handle, (unsigned long long)
		    mr_sas_phy->identify.sas_address,
		    mr_sas_phy->attached_handle,
		    (unsigned long long)
		    mr_sas_phy->remote_identify.sas_address);
	mr_sas_phy->phy = phy;
	return 0;
}

/**
 * mpi3mr_add_expander_phy - report expander phy to transport
 * @mrioc: Adapter instance reference
 * @mr_sas_phy: Internal Phy object
 * @expander_pg1: SAS Expander page 1
 * @parent_dev: Parent device class object
 *
 * Return: 0 for success, non-zero for failure.
 */
static int mpi3mr_add_expander_phy(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_phy *mr_sas_phy,
	struct mpi3_sas_expander_page1 expander_pg1,
	struct device *parent_dev)
{
	struct sas_phy *phy;
	int phy_index = mr_sas_phy->phy_id;

	INIT_LIST_HEAD(&mr_sas_phy->port_siblings);
	phy = sas_phy_alloc(parent_dev, phy_index);
	if (!phy) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return -1;
	}
	if ((mpi3mr_set_identify(mrioc, mr_sas_phy->handle,
	    &mr_sas_phy->identify))) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		sas_phy_free(phy);
		return -1;
	}
	phy->identify = mr_sas_phy->identify;
	mr_sas_phy->attached_handle =
	    le16_to_cpu(expander_pg1.attached_dev_handle);
	if (mr_sas_phy->attached_handle)
		mpi3mr_set_identify(mrioc, mr_sas_phy->attached_handle,
		    &mr_sas_phy->remote_identify);
	phy->identify.phy_identifier = mr_sas_phy->phy_id;
	phy->negotiated_linkrate = mpi3mr_convert_phy_link_rate(
	    (expander_pg1.negotiated_link_rate &
	    MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
	    MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT);
	phy->minimum_linkrate_hw = mpi3mr_convert_phy_link_rate(
	    expander_pg1.hw_link_rate & MPI3_SAS_HWRATE_MIN_RATE_MASK);
	phy->maximum_linkrate_hw = mpi3mr_convert_phy_link_rate(
	    expander_pg1.hw_link_rate >> 4);
	phy->minimum_linkrate = mpi3mr_convert_phy_link_rate(
	    expander_pg1.programmed_link_rate & MPI3_SAS_PRATE_MIN_RATE_MASK);
	phy->maximum_linkrate = mpi3mr_convert_phy_link_rate(
	    expander_pg1.programmed_link_rate >> 4);
	phy->hostdata = mr_sas_phy->hba_port;

	if ((sas_phy_add(phy))) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		sas_phy_free(phy);
		return -1;
	}
	if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
		dev_info(&phy->dev,
		    "add: handle(0x%04x), sas_address(0x%016llx)\n"
		    "\tattached_handle(0x%04x), sas_address(0x%016llx)\n",
		    mr_sas_phy->handle, (unsigned long long)
		    mr_sas_phy->identify.sas_address,
		    mr_sas_phy->attached_handle,
		    (unsigned long long)
		    mr_sas_phy->remote_identify.sas_address);
	mr_sas_phy->phy = phy;
	return 0;
}

/**
 * mpi3mr_alloc_hba_port - alloc hba port object
 * @mrioc: Adapter instance reference
 * @port_id: Port number
 *
 * Alloc memory for hba port object.
 */
static struct mpi3mr_hba_port *
mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id)
{
	struct mpi3mr_hba_port *hba_port;

	hba_port = kzalloc(sizeof(struct mpi3mr_hba_port),
	    GFP_KERNEL);
	if (!hba_port)
		return NULL;
	hba_port->port_id = port_id;
	ioc_info(mrioc, "hba_port entry: %p, port: %d is added to hba_port list\n",
	    hba_port, hba_port->port_id);
	if (mrioc->reset_in_progress ||
		mrioc->pci_err_recovery)
		hba_port->flags = MPI3MR_HBA_PORT_FLAG_NEW;
	list_add_tail(&hba_port->list, &mrioc->hba_port_table_list);
	return hba_port;
}

/**
 * mpi3mr_get_hba_port_by_id - find hba port by id
 * @mrioc: Adapter instance reference
 * @port_id: Port ID to search
 *
 * Return: mpi3mr_hba_port reference for the matched port
 */

struct mpi3mr_hba_port *mpi3mr_get_hba_port_by_id(struct mpi3mr_ioc *mrioc,
	u8 port_id)
{
	struct mpi3mr_hba_port *port, *port_next;

	list_for_each_entry_safe(port, port_next,
	    &mrioc->hba_port_table_list, list) {
		if (port->port_id != port_id)
			continue;
		if (port->flags & MPI3MR_HBA_PORT_FLAG_DIRTY)
			continue;
		return port;
	}

	return NULL;
}

/**
 * mpi3mr_update_links - refreshing SAS phy link changes
 * @mrioc: Adapter instance reference
 * @sas_address_parent: SAS address of parent expander or host
 * @handle: Firmware device handle of attached device
 * @phy_number: Phy number
 * @link_rate: New link rate
 * @hba_port: HBA port entry
 *
 * Return: None.
 */
void mpi3mr_update_links(struct mpi3mr_ioc *mrioc,
	u64 sas_address_parent, u16 handle, u8 phy_number, u8 link_rate,
	struct mpi3mr_hba_port *hba_port)
{
	unsigned long flags;
	struct mpi3mr_sas_node *mr_sas_node;
	struct mpi3mr_sas_phy *mr_sas_phy;

	if (mrioc->reset_in_progress || mrioc->pci_err_recovery)
		return;

	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	mr_sas_node = __mpi3mr_sas_node_find_by_sas_address(mrioc,
	    sas_address_parent, hba_port);
	if (!mr_sas_node) {
		spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
		return;
	}

	mr_sas_phy = &mr_sas_node->phy[phy_number];
	mr_sas_phy->attached_handle = handle;
	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
	if (handle && (link_rate >= MPI3_SAS_NEG_LINK_RATE_1_5)) {
		mpi3mr_set_identify(mrioc, handle,
		    &mr_sas_phy->remote_identify);
		mpi3mr_add_phy_to_an_existing_port(mrioc, mr_sas_node,
		    mr_sas_phy, mr_sas_phy->remote_identify.sas_address,
		    hba_port);
	} else
		memset(&mr_sas_phy->remote_identify, 0, sizeof(struct
		    sas_identify));

	if (mr_sas_phy->phy)
		mr_sas_phy->phy->negotiated_linkrate =
		    mpi3mr_convert_phy_link_rate(link_rate);

	if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
		dev_info(&mr_sas_phy->phy->dev,
		    "refresh: parent sas_address(0x%016llx),\n"
		    "\tlink_rate(0x%02x), phy(%d)\n"
		    "\tattached_handle(0x%04x), sas_address(0x%016llx)\n",
		    (unsigned long long)sas_address_parent,
		    link_rate, phy_number, handle, (unsigned long long)
		    mr_sas_phy->remote_identify.sas_address);
}

/**
 * mpi3mr_sas_host_refresh - refreshing sas host object contents
 * @mrioc: Adapter instance reference
 *
 * This function refreshes the controllers phy information and
 * updates the SAS transport layer with updated information,
 * this is executed for each device addition or device info
 * change events
 *
 * Return: None.
 */
void mpi3mr_sas_host_refresh(struct mpi3mr_ioc *mrioc)
{
	int i;
	u8 link_rate;
	u16 sz, port_id, attached_handle;
	struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL;

	dprint_transport_info(mrioc,
	    "updating handles for sas_host(0x%016llx)\n",
	    (unsigned long long)mrioc->sas_hba.sas_address);

	sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) +
	    (mrioc->sas_hba.num_phys *
	     sizeof(struct mpi3_sas_io_unit0_phy_data));
	sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL);
	if (!sas_io_unit_pg0)
		return;
	if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out;
	}

	mrioc->sas_hba.handle = 0;
	for (i = 0; i < mrioc->sas_hba.num_phys; i++) {
		if (sas_io_unit_pg0->phy_data[i].phy_flags &
		    (MPI3_SASIOUNIT0_PHYFLAGS_HOST_PHY |
		     MPI3_SASIOUNIT0_PHYFLAGS_VIRTUAL_PHY))
			continue;
		link_rate =
		    sas_io_unit_pg0->phy_data[i].negotiated_link_rate >> 4;
		if (!mrioc->sas_hba.handle)
			mrioc->sas_hba.handle = le16_to_cpu(
			    sas_io_unit_pg0->phy_data[i].controller_dev_handle);
		port_id = sas_io_unit_pg0->phy_data[i].io_unit_port;
		if (!(mpi3mr_get_hba_port_by_id(mrioc, port_id)))
			if (!mpi3mr_alloc_hba_port(mrioc, port_id))
				goto out;

		mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle;
		attached_handle = le16_to_cpu(
		    sas_io_unit_pg0->phy_data[i].attached_dev_handle);
		if (attached_handle && link_rate < MPI3_SAS_NEG_LINK_RATE_1_5)
			link_rate = MPI3_SAS_NEG_LINK_RATE_1_5;
		mrioc->sas_hba.phy[i].hba_port =
			mpi3mr_get_hba_port_by_id(mrioc, port_id);
		mpi3mr_update_links(mrioc, mrioc->sas_hba.sas_address,
		    attached_handle, i, link_rate,
		    mrioc->sas_hba.phy[i].hba_port);
	}
 out:
	kfree(sas_io_unit_pg0);
}

/**
 * mpi3mr_sas_host_add - create sas host object
 * @mrioc: Adapter instance reference
 *
 * This function creates the controllers phy information and
 * updates the SAS transport layer with updated information,
 * this is executed for first device addition or device info
 * change event.
 *
 * Return: None.
 */
void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc)
{
	int i;
	u16 sz, num_phys = 1, port_id, ioc_status;
	struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL;
	struct mpi3_sas_phy_page0 phy_pg0;
	struct mpi3_device_page0 dev_pg0;
	struct mpi3_enclosure_page0 encl_pg0;
	struct mpi3_device0_sas_sata_format *sasinf;

	sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) +
	    (num_phys * sizeof(struct mpi3_sas_io_unit0_phy_data));
	sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL);
	if (!sas_io_unit_pg0)
		return;

	if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out;
	}
	num_phys = sas_io_unit_pg0->num_phys;
	kfree(sas_io_unit_pg0);

	mrioc->sas_hba.host_node = 1;
	INIT_LIST_HEAD(&mrioc->sas_hba.sas_port_list);
	mrioc->sas_hba.parent_dev = &mrioc->shost->shost_gendev;
	mrioc->sas_hba.phy = kcalloc(num_phys,
	    sizeof(struct mpi3mr_sas_phy), GFP_KERNEL);
	if (!mrioc->sas_hba.phy)
		return;

	mrioc->sas_hba.num_phys = num_phys;

	sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) +
	    (num_phys * sizeof(struct mpi3_sas_io_unit0_phy_data));
	sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL);
	if (!sas_io_unit_pg0)
		return;

	if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out;
	}

	mrioc->sas_hba.handle = 0;
	for (i = 0; i < mrioc->sas_hba.num_phys; i++) {
		if (sas_io_unit_pg0->phy_data[i].phy_flags &
		    (MPI3_SASIOUNIT0_PHYFLAGS_HOST_PHY |
		    MPI3_SASIOUNIT0_PHYFLAGS_VIRTUAL_PHY))
			continue;
		if (mpi3mr_cfg_get_sas_phy_pg0(mrioc, &ioc_status, &phy_pg0,
		    sizeof(struct mpi3_sas_phy_page0),
		    MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, i)) {
			ioc_err(mrioc, "failure at %s:%d/%s()!\n",
			    __FILE__, __LINE__, __func__);
			goto out;
		}
		if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
			ioc_err(mrioc, "failure at %s:%d/%s()!\n",
			    __FILE__, __LINE__, __func__);
			goto out;
		}

		if (!mrioc->sas_hba.handle)
			mrioc->sas_hba.handle = le16_to_cpu(
			    sas_io_unit_pg0->phy_data[i].controller_dev_handle);
		port_id = sas_io_unit_pg0->phy_data[i].io_unit_port;

		if (!(mpi3mr_get_hba_port_by_id(mrioc, port_id)))
			if (!mpi3mr_alloc_hba_port(mrioc, port_id))
				goto out;

		mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle;
		mrioc->sas_hba.phy[i].phy_id = i;
		mrioc->sas_hba.phy[i].hba_port =
		    mpi3mr_get_hba_port_by_id(mrioc, port_id);
		mpi3mr_add_host_phy(mrioc, &mrioc->sas_hba.phy[i],
		    phy_pg0, mrioc->sas_hba.parent_dev);
	}
	if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &dev_pg0,
	    sizeof(dev_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE,
	    mrioc->sas_hba.handle))) {
		ioc_err(mrioc, "%s: device page0 read failed\n", __func__);
		goto out;
	}
	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
		ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:%d/%s()!\n",
		    mrioc->sas_hba.handle, ioc_status, __FILE__, __LINE__,
		    __func__);
		goto out;
	}
	mrioc->sas_hba.enclosure_handle =
	    le16_to_cpu(dev_pg0.enclosure_handle);
	sasinf = &dev_pg0.device_specific.sas_sata_format;
	mrioc->sas_hba.sas_address =
	    le64_to_cpu(sasinf->sas_address);
	ioc_info(mrioc,
	    "host_add: handle(0x%04x), sas_addr(0x%016llx), phys(%d)\n",
	    mrioc->sas_hba.handle,
	    (unsigned long long) mrioc->sas_hba.sas_address,
	    mrioc->sas_hba.num_phys);

	if (mrioc->sas_hba.enclosure_handle) {
		if (!(mpi3mr_cfg_get_enclosure_pg0(mrioc, &ioc_status,
		    &encl_pg0, sizeof(encl_pg0),
		    MPI3_ENCLOS_PGAD_FORM_HANDLE,
		    mrioc->sas_hba.enclosure_handle)) &&
		    (ioc_status == MPI3_IOCSTATUS_SUCCESS))
			mrioc->sas_hba.enclosure_logical_id =
				le64_to_cpu(encl_pg0.enclosure_logical_id);
	}

out:
	kfree(sas_io_unit_pg0);
}

/**
 * mpi3mr_sas_port_add - Expose the SAS device to the SAS TL
 * @mrioc: Adapter instance reference
 * @handle: Firmware device handle of the attached device
 * @sas_address_parent: sas address of parent expander or host
 * @hba_port: HBA port entry
 *
 * This function creates a new sas port object for the given end
 * device matching sas address and hba_port and adds it to the
 * sas_node's sas_port_list and expose the attached sas device
 * to the SAS transport layer through sas_rphy_add.
 *
 * Returns a valid mpi3mr_sas_port reference or NULL.
 */
static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
	u16 handle, u64 sas_address_parent, struct mpi3mr_hba_port *hba_port)
{
	struct mpi3mr_sas_phy *mr_sas_phy, *next;
	struct mpi3mr_sas_port *mr_sas_port;
	unsigned long flags;
	struct mpi3mr_sas_node *mr_sas_node;
	struct sas_rphy *rphy;
	struct mpi3mr_tgt_dev *tgtdev = NULL;
	int i;
	struct sas_port *port;

	if (!hba_port) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return NULL;
	}

	mr_sas_port = kzalloc(sizeof(struct mpi3mr_sas_port), GFP_KERNEL);
	if (!mr_sas_port)
		return NULL;

	INIT_LIST_HEAD(&mr_sas_port->port_list);
	INIT_LIST_HEAD(&mr_sas_port->phy_list);
	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	mr_sas_node = __mpi3mr_sas_node_find_by_sas_address(mrioc,
	    sas_address_parent, hba_port);
	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);

	if (!mr_sas_node) {
		ioc_err(mrioc, "%s:could not find parent sas_address(0x%016llx)!\n",
		    __func__, (unsigned long long)sas_address_parent);
		goto out_fail;
	}

	if ((mpi3mr_set_identify(mrioc, handle,
	    &mr_sas_port->remote_identify))) {
		ioc_err(mrioc,  "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out_fail;
	}

	if (mr_sas_port->remote_identify.device_type == SAS_PHY_UNUSED) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out_fail;
	}

	mr_sas_port->hba_port = hba_port;
	mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node,
	    mr_sas_port->remote_identify.sas_address, hba_port);

	if (mr_sas_node->host_node && mr_sas_node->num_phys >=
			sizeof(mr_sas_port->phy_mask) * 8)
		ioc_info(mrioc, "max port count %u could be too high\n",
		    mr_sas_node->num_phys);

	for (i = 0; i < mr_sas_node->num_phys; i++) {
		if ((mr_sas_node->phy[i].remote_identify.sas_address !=
		    mr_sas_port->remote_identify.sas_address) ||
		    (mr_sas_node->phy[i].hba_port != hba_port))
			continue;

		if (mr_sas_node->host_node && (i >= sizeof(mr_sas_port->phy_mask) * 8)) {
			ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n",
			    i, sizeof(mr_sas_port->phy_mask) * 8);
			goto out_fail;
		}
		list_add_tail(&mr_sas_node->phy[i].port_siblings,
		    &mr_sas_port->phy_list);
		mr_sas_port->num_phys++;
		if (mr_sas_node->host_node)
			mr_sas_port->phy_mask |= (1 << i);
	}

	if (!mr_sas_port->num_phys) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out_fail;
	}

	if (mr_sas_node->host_node)
		mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;

	if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) {
		tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc,
		    mr_sas_port->remote_identify.sas_address,
		    mr_sas_port->hba_port);

		if (!tgtdev) {
			ioc_err(mrioc, "failure at %s:%d/%s()!\n",
			    __FILE__, __LINE__, __func__);
			goto out_fail;
		}
		tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 1;
	}

	if (!mr_sas_node->parent_dev) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out_fail;
	}

	port = sas_port_alloc_num(mr_sas_node->parent_dev);
	if ((sas_port_add(port))) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out_fail;
	}

	list_for_each_entry(mr_sas_phy, &mr_sas_port->phy_list,
	    port_siblings) {
		if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
			dev_info(&port->dev,
			    "add: handle(0x%04x), sas_address(0x%016llx), phy(%d)\n",
			    handle, (unsigned long long)
			    mr_sas_port->remote_identify.sas_address,
			    mr_sas_phy->phy_id);
		sas_port_add_phy(port, mr_sas_phy->phy);
		mr_sas_phy->phy_belongs_to_port = 1;
		mr_sas_phy->hba_port = hba_port;
	}

	mr_sas_port->port = port;
	if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) {
		rphy = sas_end_device_alloc(port);
		tgtdev->dev_spec.sas_sata_inf.rphy = rphy;
	} else {
		rphy = sas_expander_alloc(port,
		    mr_sas_port->remote_identify.device_type);
	}
	rphy->identify = mr_sas_port->remote_identify;

	if (mrioc->current_event)
		mrioc->current_event->pending_at_sml = 1;

	if ((sas_rphy_add(rphy))) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
	}
	if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) {
		tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 0;
		tgtdev->dev_spec.sas_sata_inf.sas_transport_attached = 1;
		mpi3mr_tgtdev_put(tgtdev);
	}

	dev_info(&rphy->dev,
	    "%s: added: handle(0x%04x), sas_address(0x%016llx)\n",
	    __func__, handle, (unsigned long long)
	    mr_sas_port->remote_identify.sas_address);

	mr_sas_port->rphy = rphy;
	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	list_add_tail(&mr_sas_port->port_list, &mr_sas_node->sas_port_list);
	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);

	if (mrioc->current_event) {
		mrioc->current_event->pending_at_sml = 0;
		if (mrioc->current_event->discard)
			mpi3mr_print_device_event_notice(mrioc, true);
	}

	/* fill in report manufacture */
	if (mr_sas_port->remote_identify.device_type ==
	    SAS_EDGE_EXPANDER_DEVICE ||
	    mr_sas_port->remote_identify.device_type ==
	    SAS_FANOUT_EXPANDER_DEVICE)
		mpi3mr_report_manufacture(mrioc,
		    mr_sas_port->remote_identify.sas_address,
		    rphy_to_expander_device(rphy), hba_port->port_id);

	return mr_sas_port;

 out_fail:
	list_for_each_entry_safe(mr_sas_phy, next, &mr_sas_port->phy_list,
	    port_siblings)
		list_del(&mr_sas_phy->port_siblings);
	kfree(mr_sas_port);
	return NULL;
}

/**
 * mpi3mr_sas_port_remove - remove port from the list
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of attached device
 * @sas_address_parent: SAS address of parent expander or host
 * @hba_port: HBA port entry
 *
 * Removing object and freeing associated memory from the
 * sas_port_list.
 *
 * Return: None
 */
static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
	u64 sas_address_parent, struct mpi3mr_hba_port *hba_port)
{
	int i;
	unsigned long flags;
	struct mpi3mr_sas_port *mr_sas_port, *next;
	struct mpi3mr_sas_node *mr_sas_node;
	u8 found = 0;
	struct mpi3mr_sas_phy *mr_sas_phy, *next_phy;
	struct mpi3mr_hba_port *srch_port, *hba_port_next = NULL;

	if (!hba_port)
		return;

	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	mr_sas_node = __mpi3mr_sas_node_find_by_sas_address(mrioc,
	    sas_address_parent, hba_port);
	if (!mr_sas_node) {
		spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
		return;
	}
	list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list,
	    port_list) {
		if (mr_sas_port->remote_identify.sas_address != sas_address)
			continue;
		if (mr_sas_port->hba_port != hba_port)
			continue;
		found = 1;
		list_del(&mr_sas_port->port_list);
		goto out;
	}

 out:
	if (!found) {
		spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
		return;
	}

	if (mr_sas_node->host_node) {
		list_for_each_entry_safe(srch_port, hba_port_next,
		    &mrioc->hba_port_table_list, list) {
			if (srch_port != hba_port)
				continue;
			ioc_info(mrioc,
			    "removing hba_port entry: %p port: %d from hba_port list\n",
			    srch_port, srch_port->port_id);
			list_del(&hba_port->list);
			kfree(hba_port);
			break;
		}
	}

	for (i = 0; i < mr_sas_node->num_phys; i++) {
		if (mr_sas_node->phy[i].remote_identify.sas_address ==
		    sas_address)
			memset(&mr_sas_node->phy[i].remote_identify, 0,
			    sizeof(struct sas_identify));
	}

	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);

	if (mrioc->current_event)
		mrioc->current_event->pending_at_sml = 1;

	list_for_each_entry_safe(mr_sas_phy, next_phy,
	    &mr_sas_port->phy_list, port_siblings) {
		if ((!mrioc->stop_drv_processing) &&
		    (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO))
			dev_info(&mr_sas_port->port->dev,
			    "remove: sas_address(0x%016llx), phy(%d)\n",
			    (unsigned long long)
			    mr_sas_port->remote_identify.sas_address,
			    mr_sas_phy->phy_id);
		mr_sas_phy->phy_belongs_to_port = 0;
		if (!mrioc->stop_drv_processing)
			sas_port_delete_phy(mr_sas_port->port,
			    mr_sas_phy->phy);
		list_del(&mr_sas_phy->port_siblings);
	}
	if (!mrioc->stop_drv_processing)
		sas_port_delete(mr_sas_port->port);
	ioc_info(mrioc, "%s: removed sas_address(0x%016llx)\n",
	    __func__, (unsigned long long)sas_address);

	if (mrioc->current_event) {
		mrioc->current_event->pending_at_sml = 0;
		if (mrioc->current_event->discard)
			mpi3mr_print_device_event_notice(mrioc, false);
	}

	kfree(mr_sas_port);
}

/**
 * struct host_port - host port details
 * @sas_address: SAS Address of the attached device
 * @phy_mask: phy mask of host port
 * @handle: Device Handle of attached device
 * @iounit_port_id: port ID
 * @used: host port is already matched with sas port from sas_port_list
 * @lowest_phy: lowest phy ID of host port
 */
struct host_port {
	u64	sas_address;
	u64	phy_mask;
	u16	handle;
	u8	iounit_port_id;
	u8	used;
	u8	lowest_phy;
};

/**
 * mpi3mr_update_mr_sas_port - update sas port objects during reset
 * @mrioc: Adapter instance reference
 * @h_port: host_port object
 * @mr_sas_port: sas_port objects which needs to be updated
 *
 * Update the port ID of sas port object. Also add the phys if new phys got
 * added to current sas port and remove the phys if some phys are moved
 * out of the current sas port.
 *
 * Return: Nothing.
 */
static void
mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port,
	struct mpi3mr_sas_port *mr_sas_port)
{
	struct mpi3mr_sas_phy *mr_sas_phy;
	u64 phy_mask_xor;
	u64 phys_to_be_added, phys_to_be_removed;
	int i;

	h_port->used = 1;
	mr_sas_port->marked_responding = 1;

	dev_info(&mr_sas_port->port->dev,
	    "sas_address(0x%016llx), old: port_id %d phy_mask 0x%llx, new: port_id %d phy_mask:0x%llx\n",
	    mr_sas_port->remote_identify.sas_address,
	    mr_sas_port->hba_port->port_id, mr_sas_port->phy_mask,
	    h_port->iounit_port_id, h_port->phy_mask);

	mr_sas_port->hba_port->port_id = h_port->iounit_port_id;
	mr_sas_port->hba_port->flags &= ~MPI3MR_HBA_PORT_FLAG_DIRTY;

	/* Get the newly added phys bit map & removed phys bit map */
	phy_mask_xor = mr_sas_port->phy_mask ^ h_port->phy_mask;
	phys_to_be_added = h_port->phy_mask & phy_mask_xor;
	phys_to_be_removed = mr_sas_port->phy_mask & phy_mask_xor;

	/*
	 * Register these new phys to current mr_sas_port's port.
	 * if these phys are previously registered with another port
	 * then delete these phys from that port first.
	 */
	for_each_set_bit(i, (ulong *) &phys_to_be_added, BITS_PER_TYPE(u64)) {
		mr_sas_phy = &mrioc->sas_hba.phy[i];
		if (mr_sas_phy->phy_belongs_to_port)
			mpi3mr_del_phy_from_an_existing_port(mrioc,
			    &mrioc->sas_hba, mr_sas_phy);
		mpi3mr_add_phy_to_an_existing_port(mrioc,
		    &mrioc->sas_hba, mr_sas_phy,
		    mr_sas_port->remote_identify.sas_address,
		    mr_sas_port->hba_port);
	}

	/* Delete the phys which are not part of current mr_sas_port's port. */
	for_each_set_bit(i, (ulong *) &phys_to_be_removed, BITS_PER_TYPE(u64)) {
		mr_sas_phy = &mrioc->sas_hba.phy[i];
		if (mr_sas_phy->phy_belongs_to_port)
			mpi3mr_del_phy_from_an_existing_port(mrioc,
			    &mrioc->sas_hba, mr_sas_phy);
	}
}

/**
 * mpi3mr_refresh_sas_ports - update host's sas ports during reset
 * @mrioc: Adapter instance reference
 *
 * Update the host's sas ports during reset by checking whether
 * sas ports are still intact or not. Add/remove phys if any hba
 * phys are (moved in)/(moved out) of sas port. Also update
 * io_unit_port if it got changed during reset.
 *
 * Return: Nothing.
 */
void
mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc)
{
	struct host_port *h_port = NULL;
	int i, j, found, host_port_count = 0, port_idx;
	u16 sz, attached_handle, ioc_status;
	struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL;
	struct mpi3_device_page0 dev_pg0;
	struct mpi3_device0_sas_sata_format *sasinf;
	struct mpi3mr_sas_port *mr_sas_port;

	sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) +
		(mrioc->sas_hba.num_phys *
		 sizeof(struct mpi3_sas_io_unit0_phy_data));
	sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL);
	if (!sas_io_unit_pg0)
		return;
	h_port = kcalloc(64, sizeof(struct host_port), GFP_KERNEL);
	if (!h_port)
		goto out;

	if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out;
	}

	/* Create a new expander port table */
	for (i = 0; i < mrioc->sas_hba.num_phys; i++) {
		attached_handle = le16_to_cpu(
		    sas_io_unit_pg0->phy_data[i].attached_dev_handle);
		if (!attached_handle)
			continue;
		found = 0;
		for (j = 0; j < host_port_count; j++) {
			if (h_port[j].handle == attached_handle) {
				h_port[j].phy_mask |= (1 << i);
				found = 1;
				break;
			}
		}
		if (found)
			continue;
		if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &dev_pg0,
		    sizeof(dev_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE,
		    attached_handle))) {
			dprint_reset(mrioc,
			    "failed to read dev_pg0 for handle(0x%04x) at %s:%d/%s()!\n",
			    attached_handle, __FILE__, __LINE__, __func__);
			continue;
		}
		if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
			dprint_reset(mrioc,
			    "ioc_status(0x%x) while reading dev_pg0 for handle(0x%04x) at %s:%d/%s()!\n",
			    ioc_status, attached_handle,
			    __FILE__, __LINE__, __func__);
			continue;
		}
		sasinf = &dev_pg0.device_specific.sas_sata_format;

		port_idx = host_port_count;
		h_port[port_idx].sas_address = le64_to_cpu(sasinf->sas_address);
		h_port[port_idx].handle = attached_handle;
		h_port[port_idx].phy_mask = (1 << i);
		h_port[port_idx].iounit_port_id = sas_io_unit_pg0->phy_data[i].io_unit_port;
		h_port[port_idx].lowest_phy = sasinf->phy_num;
		h_port[port_idx].used = 0;
		host_port_count++;
	}

	if (!host_port_count)
		goto out;

	if (mrioc->logging_level & MPI3_DEBUG_RESET) {
		ioc_info(mrioc, "Host port details before reset\n");
		list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list,
		    port_list) {
			ioc_info(mrioc,
			    "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%llx), lowest phy id:%d\n",
			    mr_sas_port->hba_port->port_id,
			    mr_sas_port->remote_identify.sas_address,
			    mr_sas_port->phy_mask, mr_sas_port->lowest_phy);
		}
		mr_sas_port = NULL;
		ioc_info(mrioc, "Host port details after reset\n");
		for (i = 0; i < host_port_count; i++) {
			ioc_info(mrioc,
			    "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%llx), lowest phy id:%d\n",
			    h_port[i].iounit_port_id, h_port[i].sas_address,
			    h_port[i].phy_mask, h_port[i].lowest_phy);
		}
	}

	/* mark all host sas port entries as dirty */
	list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list,
	    port_list) {
		mr_sas_port->marked_responding = 0;
		mr_sas_port->hba_port->flags |= MPI3MR_HBA_PORT_FLAG_DIRTY;
	}

	/* First check for matching lowest phy */
	for (i = 0; i < host_port_count; i++) {
		mr_sas_port = NULL;
		list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list,
		    port_list) {
			if (mr_sas_port->marked_responding)
				continue;
			if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address)
				continue;
			if (h_port[i].lowest_phy == mr_sas_port->lowest_phy) {
				mpi3mr_update_mr_sas_port(mrioc, &h_port[i], mr_sas_port);
				break;
			}
		}
	}

	/* In case if lowest phy is got enabled or disabled during reset */
	for (i = 0; i < host_port_count; i++) {
		if (h_port[i].used)
			continue;
		mr_sas_port = NULL;
		list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list,
		    port_list) {
			if (mr_sas_port->marked_responding)
				continue;
			if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address)
				continue;
			if (h_port[i].phy_mask & mr_sas_port->phy_mask) {
				mpi3mr_update_mr_sas_port(mrioc, &h_port[i], mr_sas_port);
				break;
			}
		}
	}

	/* In case if expander cable is removed & connected to another HBA port during reset */
	for (i = 0; i < host_port_count; i++) {
		if (h_port[i].used)
			continue;
		mr_sas_port = NULL;
		list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list,
		    port_list) {
			if (mr_sas_port->marked_responding)
				continue;
			if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address)
				continue;
			mpi3mr_update_mr_sas_port(mrioc, &h_port[i], mr_sas_port);
			break;
		}
	}
out:
	kfree(h_port);
	kfree(sas_io_unit_pg0);
}

/**
 * mpi3mr_refresh_expanders - Refresh expander device exposure
 * @mrioc: Adapter instance reference
 *
 * This is executed post controller reset to identify any
 * missing expander devices during reset and remove from the upper layers
 * or expose any newly detected expander device to the upper layers.
 *
 * Return: Nothing.
 */
void
mpi3mr_refresh_expanders(struct mpi3mr_ioc *mrioc)
{
	struct mpi3mr_sas_node *sas_expander, *sas_expander_next;
	struct mpi3_sas_expander_page0 expander_pg0;
	u16 ioc_status, handle;
	u64 sas_address;
	int i;
	unsigned long flags;
	struct mpi3mr_hba_port *hba_port;

	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) {
		sas_expander->non_responding = 1;
	}
	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);

	sas_expander = NULL;

	handle = 0xffff;

	/* Search for responding expander devices and add them if they are newly got added */
	while (true) {
		if ((mpi3mr_cfg_get_sas_exp_pg0(mrioc, &ioc_status, &expander_pg0,
		    sizeof(struct mpi3_sas_expander_page0),
		    MPI3_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
			dprint_reset(mrioc,
			    "failed to read exp pg0 for handle(0x%04x) at %s:%d/%s()!\n",
			    handle, __FILE__, __LINE__, __func__);
			break;
		}

		if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
			dprint_reset(mrioc,
			   "ioc_status(0x%x) while reading exp pg0 for handle:(0x%04x), %s:%d/%s()!\n",
			   ioc_status, handle, __FILE__, __LINE__, __func__);
			break;
		}

		handle = le16_to_cpu(expander_pg0.dev_handle);
		sas_address = le64_to_cpu(expander_pg0.sas_address);
		hba_port = mpi3mr_get_hba_port_by_id(mrioc, expander_pg0.io_unit_port);

		if (!hba_port) {
			mpi3mr_sas_host_refresh(mrioc);
			mpi3mr_expander_add(mrioc, handle);
			continue;
		}

		spin_lock_irqsave(&mrioc->sas_node_lock, flags);
		sas_expander =
		    mpi3mr_expander_find_by_sas_address(mrioc,
		    sas_address, hba_port);
		spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);

		if (!sas_expander) {
			mpi3mr_sas_host_refresh(mrioc);
			mpi3mr_expander_add(mrioc, handle);
			continue;
		}

		sas_expander->non_responding = 0;
		if (sas_expander->handle == handle)
			continue;

		sas_expander->handle = handle;
		for (i = 0 ; i < sas_expander->num_phys ; i++)
			sas_expander->phy[i].handle = handle;
	}

	/*
	 * Delete non responding expander devices and the corresponding
	 * hba_port if the non responding expander device's parent device
	 * is a host node.
	 */
	sas_expander = NULL;
	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	list_for_each_entry_safe_reverse(sas_expander, sas_expander_next,
	    &mrioc->sas_expander_list, list) {
		if (sas_expander->non_responding) {
			spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
			mpi3mr_expander_node_remove(mrioc, sas_expander);
			spin_lock_irqsave(&mrioc->sas_node_lock, flags);
		}
	}
	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
}

/**
 * mpi3mr_expander_node_add - insert an expander to the list.
 * @mrioc: Adapter instance reference
 * @sas_expander: Expander sas node
 * Context: This function will acquire sas_node_lock.
 *
 * Adding new object to the ioc->sas_expander_list.
 *
 * Return: None.
 */
static void mpi3mr_expander_node_add(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *sas_expander)
{
	unsigned long flags;

	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	list_add_tail(&sas_expander->list, &mrioc->sas_expander_list);
	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
}

/**
 * mpi3mr_expander_add -  Create expander object
 * @mrioc: Adapter instance reference
 * @handle: Expander firmware device handle
 *
 * This function creating expander object, stored in
 * sas_expander_list and expose it to the SAS transport
 * layer.
 *
 * Return: 0 for success, non-zero for failure.
 */
int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle)
{
	struct mpi3mr_sas_node *sas_expander;
	struct mpi3mr_enclosure_node *enclosure_dev;
	struct mpi3_sas_expander_page0 expander_pg0;
	struct mpi3_sas_expander_page1 expander_pg1;
	u16 ioc_status, parent_handle, temp_handle;
	u64 sas_address, sas_address_parent = 0;
	int i;
	unsigned long flags;
	u8 port_id, link_rate;
	struct mpi3mr_sas_port *mr_sas_port = NULL;
	struct mpi3mr_hba_port *hba_port;
	u32 phynum_handle;
	int rc = 0;

	if (!handle)
		return -1;

	if (mrioc->reset_in_progress || mrioc->pci_err_recovery)
		return -1;

	if ((mpi3mr_cfg_get_sas_exp_pg0(mrioc, &ioc_status, &expander_pg0,
	    sizeof(expander_pg0), MPI3_SAS_EXPAND_PGAD_FORM_HANDLE, handle))) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return -1;
	}

	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return -1;
	}

	parent_handle = le16_to_cpu(expander_pg0.parent_dev_handle);
	if (mpi3mr_get_sas_address(mrioc, parent_handle, &sas_address_parent)
	    != 0) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return -1;
	}

	port_id = expander_pg0.io_unit_port;
	hba_port = mpi3mr_get_hba_port_by_id(mrioc, port_id);
	if (!hba_port) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return -1;
	}

	if (sas_address_parent != mrioc->sas_hba.sas_address) {
		spin_lock_irqsave(&mrioc->sas_node_lock, flags);
		sas_expander =
		   mpi3mr_expander_find_by_sas_address(mrioc,
		    sas_address_parent, hba_port);
		spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
		if (!sas_expander) {
			rc = mpi3mr_expander_add(mrioc, parent_handle);
			if (rc != 0)
				return rc;
		} else {
			/*
			 * When there is a parent expander present, update it's
			 * phys where child expander is connected with the link
			 * speed, attached dev handle and sas address.
			 */
			for (i = 0 ; i < sas_expander->num_phys ; i++) {
				phynum_handle =
				    (i << MPI3_SAS_EXPAND_PGAD_PHYNUM_SHIFT) |
				    parent_handle;
				if (mpi3mr_cfg_get_sas_exp_pg1(mrioc,
				    &ioc_status, &expander_pg1,
				    sizeof(expander_pg1),
				    MPI3_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM,
				    phynum_handle)) {
					ioc_err(mrioc, "failure at %s:%d/%s()!\n",
					    __FILE__, __LINE__, __func__);
					rc = -1;
					return rc;
				}
				if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
					ioc_err(mrioc, "failure at %s:%d/%s()!\n",
					    __FILE__, __LINE__, __func__);
					rc = -1;
					return rc;
				}
				temp_handle = le16_to_cpu(
				    expander_pg1.attached_dev_handle);
				if (temp_handle != handle)
					continue;
				link_rate = (expander_pg1.negotiated_link_rate &
				    MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
				    MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
				mpi3mr_update_links(mrioc, sas_address_parent,
				    handle, i, link_rate, hba_port);
			}
		}
	}

	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	sas_address = le64_to_cpu(expander_pg0.sas_address);
	sas_expander = mpi3mr_expander_find_by_sas_address(mrioc,
	    sas_address, hba_port);
	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);

	if (sas_expander)
		return 0;

	sas_expander = kzalloc(sizeof(struct mpi3mr_sas_node),
	    GFP_KERNEL);
	if (!sas_expander)
		return -ENOMEM;

	sas_expander->handle = handle;
	sas_expander->num_phys = expander_pg0.num_phys;
	sas_expander->sas_address_parent = sas_address_parent;
	sas_expander->sas_address = sas_address;
	sas_expander->hba_port = hba_port;

	ioc_info(mrioc,
	    "expander_add: handle(0x%04x), parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n",
	    handle, parent_handle, (unsigned long long)
	    sas_expander->sas_address, sas_expander->num_phys);

	if (!sas_expander->num_phys) {
		rc = -1;
		goto out_fail;
	}
	sas_expander->phy = kcalloc(sas_expander->num_phys,
	    sizeof(struct mpi3mr_sas_phy), GFP_KERNEL);
	if (!sas_expander->phy) {
		rc = -1;
		goto out_fail;
	}

	INIT_LIST_HEAD(&sas_expander->sas_port_list);
	mr_sas_port = mpi3mr_sas_port_add(mrioc, handle, sas_address_parent,
	    sas_expander->hba_port);
	if (!mr_sas_port) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		rc = -1;
		goto out_fail;
	}
	sas_expander->parent_dev = &mr_sas_port->rphy->dev;
	sas_expander->rphy = mr_sas_port->rphy;

	for (i = 0 ; i < sas_expander->num_phys ; i++) {
		phynum_handle = (i << MPI3_SAS_EXPAND_PGAD_PHYNUM_SHIFT) |
		    handle;
		if (mpi3mr_cfg_get_sas_exp_pg1(mrioc, &ioc_status,
		    &expander_pg1, sizeof(expander_pg1),
		    MPI3_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM,
		    phynum_handle)) {
			ioc_err(mrioc, "failure at %s:%d/%s()!\n",
			    __FILE__, __LINE__, __func__);
			rc = -1;
			goto out_fail;
		}
		if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
			ioc_err(mrioc, "failure at %s:%d/%s()!\n",
			    __FILE__, __LINE__, __func__);
			rc = -1;
			goto out_fail;
		}

		sas_expander->phy[i].handle = handle;
		sas_expander->phy[i].phy_id = i;
		sas_expander->phy[i].hba_port = hba_port;

		if ((mpi3mr_add_expander_phy(mrioc, &sas_expander->phy[i],
		    expander_pg1, sas_expander->parent_dev))) {
			ioc_err(mrioc, "failure at %s:%d/%s()!\n",
			    __FILE__, __LINE__, __func__);
			rc = -1;
			goto out_fail;
		}
	}

	if (sas_expander->enclosure_handle) {
		enclosure_dev =
			mpi3mr_enclosure_find_by_handle(mrioc,
						sas_expander->enclosure_handle);
		if (enclosure_dev)
			sas_expander->enclosure_logical_id = le64_to_cpu(
			    enclosure_dev->pg0.enclosure_logical_id);
	}

	mpi3mr_expander_node_add(mrioc, sas_expander);
	return 0;

out_fail:

	if (mr_sas_port)
		mpi3mr_sas_port_remove(mrioc,
		    sas_expander->sas_address,
		    sas_address_parent, sas_expander->hba_port);
	kfree(sas_expander->phy);
	kfree(sas_expander);
	return rc;
}

/**
 * mpi3mr_expander_node_remove - recursive removal of expander.
 * @mrioc: Adapter instance reference
 * @sas_expander: Expander device object
 *
 * Removes expander object and freeing associated memory from
 * the sas_expander_list and removes the same from SAS TL, if
 * one of the attached device is an expander then it recursively
 * removes the expander device too.
 *
 * Return nothing.
 */
void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *sas_expander)
{
	struct mpi3mr_sas_port *mr_sas_port, *next;
	unsigned long flags;
	u8 port_id;

	/* remove sibling ports attached to this expander */
	list_for_each_entry_safe(mr_sas_port, next,
	   &sas_expander->sas_port_list, port_list) {
		if (mrioc->reset_in_progress || mrioc->pci_err_recovery)
			return;
		if (mr_sas_port->remote_identify.device_type ==
		    SAS_END_DEVICE)
			mpi3mr_remove_device_by_sas_address(mrioc,
			    mr_sas_port->remote_identify.sas_address,
			    mr_sas_port->hba_port);
		else if (mr_sas_port->remote_identify.device_type ==
		    SAS_EDGE_EXPANDER_DEVICE ||
		    mr_sas_port->remote_identify.device_type ==
		    SAS_FANOUT_EXPANDER_DEVICE)
			mpi3mr_expander_remove(mrioc,
			    mr_sas_port->remote_identify.sas_address,
			    mr_sas_port->hba_port);
	}

	port_id = sas_expander->hba_port->port_id;
	mpi3mr_sas_port_remove(mrioc, sas_expander->sas_address,
	    sas_expander->sas_address_parent, sas_expander->hba_port);

	ioc_info(mrioc, "expander_remove: handle(0x%04x), sas_addr(0x%016llx), port:%d\n",
	    sas_expander->handle, (unsigned long long)
	    sas_expander->sas_address, port_id);

	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	list_del(&sas_expander->list);
	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);

	kfree(sas_expander->phy);
	kfree(sas_expander);
}

/**
 * mpi3mr_expander_remove - Remove expander object
 * @mrioc: Adapter instance reference
 * @sas_address: Remove expander sas_address
 * @hba_port: HBA port reference
 *
 * This function remove expander object, stored in
 * mrioc->sas_expander_list and removes it from the SAS TL by
 * calling mpi3mr_expander_node_remove().
 *
 * Return: None
 */
void mpi3mr_expander_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
	struct mpi3mr_hba_port *hba_port)
{
	struct mpi3mr_sas_node *sas_expander;
	unsigned long flags;

	if (mrioc->reset_in_progress || mrioc->pci_err_recovery)
		return;

	if (!hba_port)
		return;

	spin_lock_irqsave(&mrioc->sas_node_lock, flags);
	sas_expander = mpi3mr_expander_find_by_sas_address(mrioc, sas_address,
	    hba_port);
	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
	if (sas_expander)
		mpi3mr_expander_node_remove(mrioc, sas_expander);

}

/**
 * mpi3mr_get_sas_negotiated_logical_linkrate - get linkrate
 * @mrioc: Adapter instance reference
 * @tgtdev: Target device
 *
 * This function identifies whether the target device is
 * attached directly or through expander and issues sas phy
 * page0 or expander phy page1 and gets the link rate, if there
 * is any failure in reading the pages then this returns link
 * rate of 1.5.
 *
 * Return: logical link rate.
 */
static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_tgt_dev *tgtdev)
{
	u8 link_rate = MPI3_SAS_NEG_LINK_RATE_1_5, phy_number;
	struct mpi3_sas_expander_page1 expander_pg1;
	struct mpi3_sas_phy_page0 phy_pg0;
	u32 phynum_handle;
	u16 ioc_status;

	phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id;
	if (!(tgtdev->devpg0_flag & MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)) {
		phynum_handle = ((phy_number<<MPI3_SAS_EXPAND_PGAD_PHYNUM_SHIFT)
				 | tgtdev->parent_handle);
		if (mpi3mr_cfg_get_sas_exp_pg1(mrioc, &ioc_status,
		    &expander_pg1, sizeof(expander_pg1),
		    MPI3_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM,
		    phynum_handle)) {
			ioc_err(mrioc, "failure at %s:%d/%s()!\n",
			    __FILE__, __LINE__, __func__);
			goto out;
		}
		if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
			ioc_err(mrioc, "failure at %s:%d/%s()!\n",
			    __FILE__, __LINE__, __func__);
			goto out;
		}
		link_rate = (expander_pg1.negotiated_link_rate &
			     MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
			MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
		goto out;
	}
	if (mpi3mr_cfg_get_sas_phy_pg0(mrioc, &ioc_status, &phy_pg0,
	    sizeof(struct mpi3_sas_phy_page0),
	    MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy_number)) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out;
	}
	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		goto out;
	}
	link_rate = (phy_pg0.negotiated_link_rate &
		     MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
		MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
out:
	return link_rate;
}

/**
 * mpi3mr_report_tgtdev_to_sas_transport - expose dev to SAS TL
 * @mrioc: Adapter instance reference
 * @tgtdev: Target device
 *
 * This function exposes the target device after
 * preparing host_phy, setting up link rate etc.
 *
 * Return: 0 on success, non-zero for failure.
 */
int mpi3mr_report_tgtdev_to_sas_transport(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_tgt_dev *tgtdev)
{
	int retval = 0;
	u8 link_rate, parent_phy_number;
	u64 sas_address_parent, sas_address;
	struct mpi3mr_hba_port *hba_port;
	u8 port_id;

	if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) ||
	    !mrioc->sas_transport_enabled)
		return -1;

	sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address;
	if (!mrioc->sas_hba.num_phys)
		mpi3mr_sas_host_add(mrioc);
	else
		mpi3mr_sas_host_refresh(mrioc);

	if (mpi3mr_get_sas_address(mrioc, tgtdev->parent_handle,
	    &sas_address_parent) != 0) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return -1;
	}
	tgtdev->dev_spec.sas_sata_inf.sas_address_parent = sas_address_parent;

	parent_phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id;
	port_id = tgtdev->io_unit_port;

	hba_port = mpi3mr_get_hba_port_by_id(mrioc, port_id);
	if (!hba_port) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return -1;
	}
	tgtdev->dev_spec.sas_sata_inf.hba_port = hba_port;

	link_rate = mpi3mr_get_sas_negotiated_logical_linkrate(mrioc, tgtdev);

	mpi3mr_update_links(mrioc, sas_address_parent, tgtdev->dev_handle,
	    parent_phy_number, link_rate, hba_port);

	tgtdev->host_exposed = 1;
	if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle,
	    sas_address_parent, hba_port)) {
		retval = -1;
		} else if ((!tgtdev->starget) && (!mrioc->is_driver_loading)) {
			mpi3mr_sas_port_remove(mrioc, sas_address,
			    sas_address_parent, hba_port);
		retval = -1;
	}
	if (retval) {
		tgtdev->dev_spec.sas_sata_inf.hba_port = NULL;
		tgtdev->host_exposed = 0;
	}
	return retval;
}

/**
 * mpi3mr_remove_tgtdev_from_sas_transport - remove from SAS TL
 * @mrioc: Adapter instance reference
 * @tgtdev: Target device
 *
 * This function removes the target device
 *
 * Return: None.
 */
void mpi3mr_remove_tgtdev_from_sas_transport(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_tgt_dev *tgtdev)
{
	u64 sas_address_parent, sas_address;
	struct mpi3mr_hba_port *hba_port;

	if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) ||
	    !mrioc->sas_transport_enabled)
		return;

	hba_port = tgtdev->dev_spec.sas_sata_inf.hba_port;
	sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address;
	sas_address_parent = tgtdev->dev_spec.sas_sata_inf.sas_address_parent;
	mpi3mr_sas_port_remove(mrioc, sas_address, sas_address_parent,
	    hba_port);
	tgtdev->host_exposed = 0;
	tgtdev->dev_spec.sas_sata_inf.hba_port = NULL;
}

/**
 * mpi3mr_get_port_id_by_sas_phy -  Get port ID of the given phy
 * @phy: SAS transport layer phy object
 *
 * Return: Port number for valid ID else 0xFFFF
 */
static inline u8 mpi3mr_get_port_id_by_sas_phy(struct sas_phy *phy)
{
	u8 port_id = 0xFF;
	struct mpi3mr_hba_port *hba_port = phy->hostdata;

	if (hba_port)
		port_id = hba_port->port_id;

	return port_id;
}

/**
 * mpi3mr_get_port_id_by_rphy - Get Port number from SAS rphy
 *
 * @mrioc: Adapter instance reference
 * @rphy: SAS transport layer remote phy object
 *
 * Retrieves HBA port number in which the device pointed by the
 * rphy object is attached with.
 *
 * Return: Valid port number on success else OxFFFF.
 */
static u8 mpi3mr_get_port_id_by_rphy(struct mpi3mr_ioc *mrioc, struct sas_rphy *rphy)
{
	struct mpi3mr_sas_node *sas_expander;
	struct mpi3mr_tgt_dev *tgtdev;
	unsigned long flags;
	u8 port_id = 0xFF;

	if (!rphy)
		return port_id;

	if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
	    rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) {
		spin_lock_irqsave(&mrioc->sas_node_lock, flags);
		list_for_each_entry(sas_expander, &mrioc->sas_expander_list,
		    list) {
			if (sas_expander->rphy == rphy) {
				port_id = sas_expander->hba_port->port_id;
				break;
			}
		}
		spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);
	} else if (rphy->identify.device_type == SAS_END_DEVICE) {
		spin_lock_irqsave(&mrioc->tgtdev_lock, flags);

		tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,
			    rphy->identify.sas_address, rphy);
		if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) {
			port_id =
				tgtdev->dev_spec.sas_sata_inf.hba_port->port_id;
			mpi3mr_tgtdev_put(tgtdev);
		}
		spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
	}
	return port_id;
}

static inline struct mpi3mr_ioc *phy_to_mrioc(struct sas_phy *phy)
{
	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);

	return shost_priv(shost);
}

static inline struct mpi3mr_ioc *rphy_to_mrioc(struct sas_rphy *rphy)
{
	struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);

	return shost_priv(shost);
}

/* report phy error log structure */
struct phy_error_log_request {
	u8 smp_frame_type; /* 0x40 */
	u8 function; /* 0x11 */
	u8 allocated_response_length;
	u8 request_length; /* 02 */
	u8 reserved_1[5];
	u8 phy_identifier;
	u8 reserved_2[2];
};

/* report phy error log reply structure */
struct phy_error_log_reply {
	u8 smp_frame_type; /* 0x41 */
	u8 function; /* 0x11 */
	u8 function_result;
	u8 response_length;
	__be16 expander_change_count;
	u8 reserved_1[3];
	u8 phy_identifier;
	u8 reserved_2[2];
	__be32 invalid_dword;
	__be32 running_disparity_error;
	__be32 loss_of_dword_sync;
	__be32 phy_reset_problem;
};


/**
 * mpi3mr_get_expander_phy_error_log - return expander counters:
 * @mrioc: Adapter instance reference
 * @phy: The SAS transport layer phy object
 *
 * Return: 0 for success, non-zero for failure.
 *
 */
static int mpi3mr_get_expander_phy_error_log(struct mpi3mr_ioc *mrioc,
	struct sas_phy *phy)
{
	struct mpi3_smp_passthrough_request mpi_request;
	struct mpi3_smp_passthrough_reply mpi_reply;
	struct phy_error_log_request *phy_error_log_request;
	struct phy_error_log_reply *phy_error_log_reply;
	int rc;
	void *psge;
	void *data_out = NULL;
	dma_addr_t data_out_dma, data_in_dma;
	u32 data_out_sz, data_in_sz, sz;
	u8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST;
	u16 request_sz = sizeof(struct mpi3_smp_passthrough_request);
	u16 reply_sz = sizeof(struct mpi3_smp_passthrough_reply);
	u16 ioc_status;

	if (mrioc->reset_in_progress) {
		ioc_err(mrioc, "%s: host reset in progress!\n", __func__);
		return -EFAULT;
	}

	if (mrioc->pci_err_recovery) {
		ioc_err(mrioc, "%s: pci error recovery in progress!\n", __func__);
		return -EFAULT;
	}

	data_out_sz = sizeof(struct phy_error_log_request);
	data_in_sz = sizeof(struct phy_error_log_reply);
	sz = data_out_sz + data_in_sz;
	data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma,
	    GFP_KERNEL);
	if (!data_out) {
		rc = -ENOMEM;
		goto out;
	}

	data_in_dma = data_out_dma + data_out_sz;
	phy_error_log_reply = data_out + data_out_sz;

	rc = -EINVAL;
	memset(data_out, 0, sz);
	phy_error_log_request = data_out;
	phy_error_log_request->smp_frame_type = 0x40;
	phy_error_log_request->function = 0x11;
	phy_error_log_request->request_length = 2;
	phy_error_log_request->allocated_response_length = 0;
	phy_error_log_request->phy_identifier = phy->number;

	memset(&mpi_request, 0, request_sz);
	memset(&mpi_reply, 0, reply_sz);
	mpi_request.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_TRANSPORT_CMDS);
	mpi_request.function = MPI3_FUNCTION_SMP_PASSTHROUGH;
	mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_sas_phy(phy);
	mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address);

	psge = &mpi_request.request_sge;
	mpi3mr_add_sg_single(psge, sgl_flags, data_out_sz, data_out_dma);

	psge = &mpi_request.response_sge;
	mpi3mr_add_sg_single(psge, sgl_flags, data_in_sz, data_in_dma);

	dprint_transport_info(mrioc,
	    "sending phy error log SMP request to sas_address(0x%016llx), phy_id(%d)\n",
	    (unsigned long long)phy->identify.sas_address, phy->number);

	if (mpi3mr_post_transport_req(mrioc, &mpi_request, request_sz,
	    &mpi_reply, reply_sz, MPI3MR_INTADMCMD_TIMEOUT, &ioc_status))
		goto out;

	dprint_transport_info(mrioc,
	    "phy error log SMP request completed with ioc_status(0x%04x)\n",
	    ioc_status);

	if (ioc_status == MPI3_IOCSTATUS_SUCCESS) {
		dprint_transport_info(mrioc,
		    "phy error log - reply data transfer size(%d)\n",
		    le16_to_cpu(mpi_reply.response_data_length));

		if (le16_to_cpu(mpi_reply.response_data_length) !=
		    sizeof(struct phy_error_log_reply))
			goto out;

		dprint_transport_info(mrioc,
		    "phy error log - function_result(%d)\n",
		    phy_error_log_reply->function_result);

		phy->invalid_dword_count =
		    be32_to_cpu(phy_error_log_reply->invalid_dword);
		phy->running_disparity_error_count =
		    be32_to_cpu(phy_error_log_reply->running_disparity_error);
		phy->loss_of_dword_sync_count =
		    be32_to_cpu(phy_error_log_reply->loss_of_dword_sync);
		phy->phy_reset_problem_count =
		    be32_to_cpu(phy_error_log_reply->phy_reset_problem);
		rc = 0;
	}

out:
	if (data_out)
		dma_free_coherent(&mrioc->pdev->dev, sz, data_out,
		    data_out_dma);

	return rc;
}

/**
 * mpi3mr_transport_get_linkerrors - return phy error counters
 * @phy: The SAS transport layer phy object
 *
 * This function retrieves the phy error log information of the
 * HBA or expander for which the phy belongs to
 *
 * Return: 0 for success, non-zero for failure.
 */
static int mpi3mr_transport_get_linkerrors(struct sas_phy *phy)
{
	struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy);
	struct mpi3_sas_phy_page1 phy_pg1;
	int rc = 0;
	u16 ioc_status;

	rc = mpi3mr_parent_present(mrioc, phy);
	if (rc)
		return rc;

	if (phy->identify.sas_address != mrioc->sas_hba.sas_address)
		return mpi3mr_get_expander_phy_error_log(mrioc, phy);

	memset(&phy_pg1, 0, sizeof(struct mpi3_sas_phy_page1));
	/* get hba phy error logs */
	if ((mpi3mr_cfg_get_sas_phy_pg1(mrioc, &ioc_status, &phy_pg1,
	    sizeof(struct mpi3_sas_phy_page1),
	    MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number))) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return -ENXIO;
	}

	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		return -ENXIO;
	}
	phy->invalid_dword_count = le32_to_cpu(phy_pg1.invalid_dword_count);
	phy->running_disparity_error_count =
		le32_to_cpu(phy_pg1.running_disparity_error_count);
	phy->loss_of_dword_sync_count =
		le32_to_cpu(phy_pg1.loss_dword_synch_count);
	phy->phy_reset_problem_count =
		le32_to_cpu(phy_pg1.phy_reset_problem_count);
	return 0;
}

/**
 * mpi3mr_transport_get_enclosure_identifier - Get Enclosure ID
 * @rphy: The SAS transport layer remote phy object
 * @identifier: Enclosure identifier to be returned
 *
 * Returns the enclosure id for the device pointed by the remote
 * phy object.
 *
 * Return: 0 on success or -ENXIO
 */
static int
mpi3mr_transport_get_enclosure_identifier(struct sas_rphy *rphy,
	u64 *identifier)
{
	struct mpi3mr_ioc *mrioc = rphy_to_mrioc(rphy);
	struct mpi3mr_tgt_dev *tgtdev = NULL;
	unsigned long flags;
	int rc;

	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
	tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,
	    rphy->identify.sas_address, rphy);
	if (tgtdev) {
		*identifier =
			tgtdev->enclosure_logical_id;
		rc = 0;
		mpi3mr_tgtdev_put(tgtdev);
	} else {
		*identifier = 0;
		rc = -ENXIO;
	}
	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);

	return rc;
}

/**
 * mpi3mr_transport_get_bay_identifier - Get bay ID
 * @rphy: The SAS transport layer remote phy object
 *
 * Returns the slot id for the device pointed by the remote phy
 * object.
 *
 * Return: Valid slot ID on success or -ENXIO
 */
static int
mpi3mr_transport_get_bay_identifier(struct sas_rphy *rphy)
{
	struct mpi3mr_ioc *mrioc = rphy_to_mrioc(rphy);
	struct mpi3mr_tgt_dev *tgtdev = NULL;
	unsigned long flags;
	int rc;

	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
	tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,
	    rphy->identify.sas_address, rphy);
	if (tgtdev) {
		rc = tgtdev->slot;
		mpi3mr_tgtdev_put(tgtdev);
	} else
		rc = -ENXIO;
	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);

	return rc;
}

/* phy control request structure */
struct phy_control_request {
	u8 smp_frame_type; /* 0x40 */
	u8 function; /* 0x91 */
	u8 allocated_response_length;
	u8 request_length; /* 0x09 */
	u16 expander_change_count;
	u8 reserved_1[3];
	u8 phy_identifier;
	u8 phy_operation;
	u8 reserved_2[13];
	u64 attached_device_name;
	u8 programmed_min_physical_link_rate;
	u8 programmed_max_physical_link_rate;
	u8 reserved_3[6];
};

/* phy control reply structure */
struct phy_control_reply {
	u8 smp_frame_type; /* 0x41 */
	u8 function; /* 0x11 */
	u8 function_result;
	u8 response_length;
};

#define SMP_PHY_CONTROL_LINK_RESET	(0x01)
#define SMP_PHY_CONTROL_HARD_RESET	(0x02)
#define SMP_PHY_CONTROL_DISABLE		(0x03)

/**
 * mpi3mr_expander_phy_control - expander phy control
 * @mrioc: Adapter instance reference
 * @phy: The SAS transport layer phy object
 * @phy_operation: The phy operation to be executed
 *
 * Issues SMP passthru phy control request to execute a specific
 * phy operation for a given expander device.
 *
 * Return: 0 for success, non-zero for failure.
 */
static int
mpi3mr_expander_phy_control(struct mpi3mr_ioc *mrioc,
	struct sas_phy *phy, u8 phy_operation)
{
	struct mpi3_smp_passthrough_request mpi_request;
	struct mpi3_smp_passthrough_reply mpi_reply;
	struct phy_control_request *phy_control_request;
	struct phy_control_reply *phy_control_reply;
	int rc;
	void *psge;
	void *data_out = NULL;
	dma_addr_t data_out_dma;
	dma_addr_t data_in_dma;
	size_t data_in_sz;
	size_t data_out_sz;
	u8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST;
	u16 request_sz = sizeof(struct mpi3_smp_passthrough_request);
	u16 reply_sz = sizeof(struct mpi3_smp_passthrough_reply);
	u16 ioc_status;
	u16 sz;

	if (mrioc->reset_in_progress) {
		ioc_err(mrioc, "%s: host reset in progress!\n", __func__);
		return -EFAULT;
	}

	if (mrioc->pci_err_recovery) {
		ioc_err(mrioc, "%s: pci error recovery in progress!\n",
		    __func__);
		return -EFAULT;
	}

	data_out_sz = sizeof(struct phy_control_request);
	data_in_sz = sizeof(struct phy_control_reply);
	sz = data_out_sz + data_in_sz;
	data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma,
	    GFP_KERNEL);
	if (!data_out) {
		rc = -ENOMEM;
		goto out;
	}

	data_in_dma = data_out_dma + data_out_sz;
	phy_control_reply = data_out + data_out_sz;

	rc = -EINVAL;
	memset(data_out, 0, sz);

	phy_control_request = data_out;
	phy_control_request->smp_frame_type = 0x40;
	phy_control_request->function = 0x91;
	phy_control_request->request_length = 9;
	phy_control_request->allocated_response_length = 0;
	phy_control_request->phy_identifier = phy->number;
	phy_control_request->phy_operation = phy_operation;
	phy_control_request->programmed_min_physical_link_rate =
	    phy->minimum_linkrate << 4;
	phy_control_request->programmed_max_physical_link_rate =
	    phy->maximum_linkrate << 4;

	memset(&mpi_request, 0, request_sz);
	memset(&mpi_reply, 0, reply_sz);
	mpi_request.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_TRANSPORT_CMDS);
	mpi_request.function = MPI3_FUNCTION_SMP_PASSTHROUGH;
	mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_sas_phy(phy);
	mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address);

	psge = &mpi_request.request_sge;
	mpi3mr_add_sg_single(psge, sgl_flags, data_out_sz, data_out_dma);

	psge = &mpi_request.response_sge;
	mpi3mr_add_sg_single(psge, sgl_flags, data_in_sz, data_in_dma);

	dprint_transport_info(mrioc,
	    "sending phy control SMP request to sas_address(0x%016llx), phy_id(%d) opcode(%d)\n",
	    (unsigned long long)phy->identify.sas_address, phy->number,
	    phy_operation);

	if (mpi3mr_post_transport_req(mrioc, &mpi_request, request_sz,
	    &mpi_reply, reply_sz, MPI3MR_INTADMCMD_TIMEOUT, &ioc_status))
		goto out;

	dprint_transport_info(mrioc,
	    "phy control SMP request completed with ioc_status(0x%04x)\n",
	    ioc_status);

	if (ioc_status == MPI3_IOCSTATUS_SUCCESS) {
		dprint_transport_info(mrioc,
		    "phy control - reply data transfer size(%d)\n",
		    le16_to_cpu(mpi_reply.response_data_length));

		if (le16_to_cpu(mpi_reply.response_data_length) !=
		    sizeof(struct phy_control_reply))
			goto out;
		dprint_transport_info(mrioc,
		    "phy control - function_result(%d)\n",
		    phy_control_reply->function_result);
		rc = 0;
	}
 out:
	if (data_out)
		dma_free_coherent(&mrioc->pdev->dev, sz, data_out,
		    data_out_dma);

	return rc;
}

/**
 * mpi3mr_transport_phy_reset - Reset a given phy
 * @phy: The SAS transport layer phy object
 * @hard_reset: Flag to indicate the type of reset
 *
 * Return: 0 for success, non-zero for failure.
 */
static int
mpi3mr_transport_phy_reset(struct sas_phy *phy, int hard_reset)
{
	struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy);
	struct mpi3_iounit_control_request mpi_request;
	struct mpi3_iounit_control_reply mpi_reply;
	u16 request_sz = sizeof(struct mpi3_iounit_control_request);
	u16 reply_sz = sizeof(struct mpi3_iounit_control_reply);
	int rc = 0;
	u16 ioc_status;

	rc = mpi3mr_parent_present(mrioc, phy);
	if (rc)
		return rc;

	/* handle expander phys */
	if (phy->identify.sas_address != mrioc->sas_hba.sas_address)
		return mpi3mr_expander_phy_control(mrioc, phy,
		    (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET :
		    SMP_PHY_CONTROL_LINK_RESET);

	/* handle hba phys */
	memset(&mpi_request, 0, request_sz);
	mpi_request.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_TRANSPORT_CMDS);
	mpi_request.function = MPI3_FUNCTION_IO_UNIT_CONTROL;
	mpi_request.operation = MPI3_CTRL_OP_SAS_PHY_CONTROL;
	mpi_request.param8[MPI3_CTRL_OP_SAS_PHY_CONTROL_PARAM8_ACTION_INDEX] =
		(hard_reset ? MPI3_CTRL_ACTION_HARD_RESET :
		 MPI3_CTRL_ACTION_LINK_RESET);
	mpi_request.param8[MPI3_CTRL_OP_SAS_PHY_CONTROL_PARAM8_PHY_INDEX] =
		phy->number;

	dprint_transport_info(mrioc,
	    "sending phy reset request to sas_address(0x%016llx), phy_id(%d) hard_reset(%d)\n",
	    (unsigned long long)phy->identify.sas_address, phy->number,
	    hard_reset);

	if (mpi3mr_post_transport_req(mrioc, &mpi_request, request_sz,
	    &mpi_reply, reply_sz, MPI3MR_INTADMCMD_TIMEOUT, &ioc_status)) {
		rc = -EAGAIN;
		goto out;
	}

	dprint_transport_info(mrioc,
	    "phy reset request completed with ioc_status(0x%04x)\n",
	    ioc_status);
out:
	return rc;
}

/**
 * mpi3mr_transport_phy_enable - enable/disable phys
 * @phy: The SAS transport layer phy object
 * @enable: flag to enable/disable, enable phy when true
 *
 * This function enables/disables a given by executing required
 * configuration page changes or expander phy control command
 *
 * Return: 0 for success, non-zero for failure.
 */
static int
mpi3mr_transport_phy_enable(struct sas_phy *phy, int enable)
{
	struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy);
	struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL;
	struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1 = NULL;
	u16 sz;
	int rc = 0;
	int i, discovery_active;

	rc = mpi3mr_parent_present(mrioc, phy);
	if (rc)
		return rc;

	/* handle expander phys */
	if (phy->identify.sas_address != mrioc->sas_hba.sas_address)
		return mpi3mr_expander_phy_control(mrioc, phy,
		    (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET :
		    SMP_PHY_CONTROL_DISABLE);

	/* handle hba phys */
	sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) +
		(mrioc->sas_hba.num_phys *
		 sizeof(struct mpi3_sas_io_unit0_phy_data));
	sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL);
	if (!sas_io_unit_pg0) {
		rc = -ENOMEM;
		goto out;
	}
	if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		rc = -ENXIO;
		goto out;
	}

	/* unable to enable/disable phys when discovery is active */
	for (i = 0, discovery_active = 0; i < mrioc->sas_hba.num_phys ; i++) {
		if (sas_io_unit_pg0->phy_data[i].port_flags &
		    MPI3_SASIOUNIT0_PORTFLAGS_DISC_IN_PROGRESS) {
			ioc_err(mrioc,
			    "discovery is active on port = %d, phy = %d\n"
			    "\tunable to enable/disable phys, try again later!\n",
			    sas_io_unit_pg0->phy_data[i].io_unit_port, i);
			discovery_active = 1;
		}
	}

	if (discovery_active) {
		rc = -EAGAIN;
		goto out;
	}

	if ((sas_io_unit_pg0->phy_data[phy->number].phy_flags &
	     (MPI3_SASIOUNIT0_PHYFLAGS_HOST_PHY |
	      MPI3_SASIOUNIT0_PHYFLAGS_VIRTUAL_PHY))) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		rc = -ENXIO;
		goto out;
	}

	/* read sas_iounit page 1 */
	sz = offsetof(struct mpi3_sas_io_unit_page1, phy_data) +
		(mrioc->sas_hba.num_phys *
		 sizeof(struct mpi3_sas_io_unit1_phy_data));
	sas_io_unit_pg1 = kzalloc(sz, GFP_KERNEL);
	if (!sas_io_unit_pg1) {
		rc = -ENOMEM;
		goto out;
	}

	if (mpi3mr_cfg_get_sas_io_unit_pg1(mrioc, sas_io_unit_pg1, sz)) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		rc = -ENXIO;
		goto out;
	}

	if (enable)
		sas_io_unit_pg1->phy_data[phy->number].phy_flags
		    &= ~MPI3_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
	else
		sas_io_unit_pg1->phy_data[phy->number].phy_flags
		    |= MPI3_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;

	mpi3mr_cfg_set_sas_io_unit_pg1(mrioc, sas_io_unit_pg1, sz);

	/* link reset */
	if (enable)
		mpi3mr_transport_phy_reset(phy, 0);

 out:
	kfree(sas_io_unit_pg1);
	kfree(sas_io_unit_pg0);
	return rc;
}

/**
 * mpi3mr_transport_phy_speed - set phy min/max speed
 * @phy: The SAS transport later phy object
 * @rates: Rates defined as in sas_phy_linkrates
 *
 * This function sets the link rates given in the rates
 * argument to the given phy by executing required configuration
 * page changes or expander phy control command
 *
 * Return: 0 for success, non-zero for failure.
 */
static int
mpi3mr_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
{
	struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy);
	struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1 = NULL;
	struct mpi3_sas_phy_page0 phy_pg0;
	u16 sz, ioc_status;
	int rc = 0;

	rc = mpi3mr_parent_present(mrioc, phy);
	if (rc)
		return rc;

	if (!rates->minimum_linkrate)
		rates->minimum_linkrate = phy->minimum_linkrate;
	else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
		rates->minimum_linkrate = phy->minimum_linkrate_hw;

	if (!rates->maximum_linkrate)
		rates->maximum_linkrate = phy->maximum_linkrate;
	else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
		rates->maximum_linkrate = phy->maximum_linkrate_hw;

	/* handle expander phys */
	if (phy->identify.sas_address != mrioc->sas_hba.sas_address) {
		phy->minimum_linkrate = rates->minimum_linkrate;
		phy->maximum_linkrate = rates->maximum_linkrate;
		return mpi3mr_expander_phy_control(mrioc, phy,
		    SMP_PHY_CONTROL_LINK_RESET);
	}

	/* handle hba phys */
	sz = offsetof(struct mpi3_sas_io_unit_page1, phy_data) +
		(mrioc->sas_hba.num_phys *
		 sizeof(struct mpi3_sas_io_unit1_phy_data));
	sas_io_unit_pg1 = kzalloc(sz, GFP_KERNEL);
	if (!sas_io_unit_pg1) {
		rc = -ENOMEM;
		goto out;
	}

	if (mpi3mr_cfg_get_sas_io_unit_pg1(mrioc, sas_io_unit_pg1, sz)) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		rc = -ENXIO;
		goto out;
	}

	sas_io_unit_pg1->phy_data[phy->number].max_min_link_rate =
		(rates->minimum_linkrate + (rates->maximum_linkrate << 4));

	if (mpi3mr_cfg_set_sas_io_unit_pg1(mrioc, sas_io_unit_pg1, sz)) {
		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
		    __FILE__, __LINE__, __func__);
		rc = -ENXIO;
		goto out;
	}

	/* link reset */
	mpi3mr_transport_phy_reset(phy, 0);

	/* read phy page 0, then update the rates in the sas transport phy */
	if (!mpi3mr_cfg_get_sas_phy_pg0(mrioc, &ioc_status, &phy_pg0,
	    sizeof(struct mpi3_sas_phy_page0),
	    MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number) &&
	    (ioc_status == MPI3_IOCSTATUS_SUCCESS)) {
		phy->minimum_linkrate = mpi3mr_convert_phy_link_rate(
		    phy_pg0.programmed_link_rate &
		    MPI3_SAS_PRATE_MIN_RATE_MASK);
		phy->maximum_linkrate = mpi3mr_convert_phy_link_rate(
		    phy_pg0.programmed_link_rate >> 4);
		phy->negotiated_linkrate =
			mpi3mr_convert_phy_link_rate(
			    (phy_pg0.negotiated_link_rate &
			    MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK)
			    >> MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT);
	}

out:
	kfree(sas_io_unit_pg1);
	return rc;
}

/**
 * mpi3mr_map_smp_buffer - map BSG dma buffer
 * @dev: Generic device reference
 * @buf: BSG buffer pointer
 * @dma_addr: Physical address holder
 * @dma_len: Mapped DMA buffer length.
 * @p: Virtual address holder
 *
 * This function maps the DMAable buffer
 *
 * Return: 0 on success, non-zero on failure
 */
static int
mpi3mr_map_smp_buffer(struct device *dev, struct bsg_buffer *buf,
		dma_addr_t *dma_addr, size_t *dma_len, void **p)
{
	/* Check if the request is split across multiple segments */
	if (buf->sg_cnt > 1) {
		*p = dma_alloc_coherent(dev, buf->payload_len, dma_addr,
				GFP_KERNEL);
		if (!*p)
			return -ENOMEM;
		*dma_len = buf->payload_len;
	} else {
		if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL))
			return -ENOMEM;
		*dma_addr = sg_dma_address(buf->sg_list);
		*dma_len = sg_dma_len(buf->sg_list);
		*p = NULL;
	}

	return 0;
}

/**
 * mpi3mr_unmap_smp_buffer - unmap BSG dma buffer
 * @dev: Generic device reference
 * @buf: BSG buffer pointer
 * @dma_addr: Physical address to be unmapped
 * @p: Virtual address
 *
 * This function unmaps the DMAable buffer
 */
static void
mpi3mr_unmap_smp_buffer(struct device *dev, struct bsg_buffer *buf,
		dma_addr_t dma_addr, void *p)
{
	if (p)
		dma_free_coherent(dev, buf->payload_len, p, dma_addr);
	else
		dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL);
}

/**
 * mpi3mr_transport_smp_handler - handler for smp passthru
 * @job: BSG job reference
 * @shost: SCSI host object reference
 * @rphy: SAS transport rphy object pointing the expander
 *
 * This is used primarily by smp utils for sending the SMP
 * commands to the expanders attached to the controller
 */
static void
mpi3mr_transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
	struct sas_rphy *rphy)
{
	struct mpi3mr_ioc *mrioc = shost_priv(shost);
	struct mpi3_smp_passthrough_request mpi_request;
	struct mpi3_smp_passthrough_reply mpi_reply;
	int rc;
	void *psge;
	dma_addr_t dma_addr_in;
	dma_addr_t dma_addr_out;
	void *addr_in = NULL;
	void *addr_out = NULL;
	size_t dma_len_in;
	size_t dma_len_out;
	unsigned int reslen = 0;
	u16 request_sz = sizeof(struct mpi3_smp_passthrough_request);
	u16 reply_sz = sizeof(struct mpi3_smp_passthrough_reply);
	u8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST;
	u16 ioc_status;

	if (mrioc->reset_in_progress) {
		ioc_err(mrioc, "%s: host reset in progress!\n", __func__);
		rc = -EFAULT;
		goto out;
	}

	if (mrioc->pci_err_recovery) {
		ioc_err(mrioc, "%s: pci error recovery in progress!\n", __func__);
		rc = -EFAULT;
		goto out;
	}

	rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->request_payload,
	    &dma_addr_out, &dma_len_out, &addr_out);
	if (rc)
		goto out;

	if (addr_out)
		sg_copy_to_buffer(job->request_payload.sg_list,
		    job->request_payload.sg_cnt, addr_out,
		    job->request_payload.payload_len);

	rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->reply_payload,
			&dma_addr_in, &dma_len_in, &addr_in);
	if (rc)
		goto unmap_out;

	memset(&mpi_request, 0, request_sz);
	memset(&mpi_reply, 0, reply_sz);
	mpi_request.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_TRANSPORT_CMDS);
	mpi_request.function = MPI3_FUNCTION_SMP_PASSTHROUGH;
	mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_rphy(mrioc, rphy);
	mpi_request.sas_address = ((rphy) ?
	    cpu_to_le64(rphy->identify.sas_address) :
	    cpu_to_le64(mrioc->sas_hba.sas_address));
	psge = &mpi_request.request_sge;
	mpi3mr_add_sg_single(psge, sgl_flags, dma_len_out - 4, dma_addr_out);

	psge = &mpi_request.response_sge;
	mpi3mr_add_sg_single(psge, sgl_flags, dma_len_in - 4, dma_addr_in);

	dprint_transport_info(mrioc, "sending SMP request\n");

	rc = mpi3mr_post_transport_req(mrioc, &mpi_request, request_sz,
				       &mpi_reply, reply_sz,
				       MPI3MR_INTADMCMD_TIMEOUT, &ioc_status);
	if (rc)
		goto unmap_in;

	dprint_transport_info(mrioc,
	    "SMP request completed with ioc_status(0x%04x)\n", ioc_status);

	dprint_transport_info(mrioc,
		    "SMP request - reply data transfer size(%d)\n",
		    le16_to_cpu(mpi_reply.response_data_length));

	memcpy(job->reply, &mpi_reply, reply_sz);
	job->reply_len = reply_sz;
	reslen = le16_to_cpu(mpi_reply.response_data_length);

	if (addr_in)
		sg_copy_from_buffer(job->reply_payload.sg_list,
				job->reply_payload.sg_cnt, addr_in,
				job->reply_payload.payload_len);

	rc = 0;
unmap_in:
	mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->reply_payload,
			dma_addr_in, addr_in);
unmap_out:
	mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->request_payload,
			dma_addr_out, addr_out);
out:
	bsg_job_done(job, rc, reslen);
}

struct sas_function_template mpi3mr_transport_functions = {
	.get_linkerrors		= mpi3mr_transport_get_linkerrors,
	.get_enclosure_identifier = mpi3mr_transport_get_enclosure_identifier,
	.get_bay_identifier	= mpi3mr_transport_get_bay_identifier,
	.phy_reset		= mpi3mr_transport_phy_reset,
	.phy_enable		= mpi3mr_transport_phy_enable,
	.set_phy_speed		= mpi3mr_transport_phy_speed,
	.smp_handler		= mpi3mr_transport_smp_handler,
};

struct scsi_transport_template *mpi3mr_transport_template;
