// 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 "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;
	}

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

	strscpy(edev->vendor_id, manufacture_reply->vendor_id,
	     SAS_EXPANDER_VENDOR_ID_LEN);
	strscpy(edev->product_id, manufacture_reply->product_id,
	     SAS_EXPANDER_PRODUCT_ID_LEN);
	strscpy(edev->product_rev, manufacture_reply->product_rev,
	     SAS_EXPANDER_PRODUCT_REV_LEN);
	edev->level = manufacture_reply->sas_format & 1;
	if (edev->level) {
		strscpy(edev->component_vendor_id,
		    manufacture_reply->component_vendor_id,
		     SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
		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
 *
 * 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)
{
	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--;
	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
 *
 * 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)
{
	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++;
	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);
		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);
			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 ((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);
	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)
		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);

	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;
		list_add_tail(&mr_sas_node->phy[i].port_siblings,
		    &mr_sas_port->phy_list);
		mr_sas_port->num_phys++;
		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;
	}

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

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

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

	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;
