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

#include "mpi3mr.h"

static void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *sas_expander);

/**
 * 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(dev_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->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;
	u32	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;
	u32 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%x, new: port_id %d phy_mask:0x%x\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(u32)) {
		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(u32)) {
		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[32];
	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;
	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%x), 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%x), 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(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 -1;

	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.
 */
static 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)) {
		tgtdev->host_exposed = 0;
		retval = -1;
	} else if ((!tgtdev->starget)) {
		if (!mrioc->is_driver_loading)
			mpi3mr_sas_port_remove(mrioc, sas_address,
			    sas_address_parent, hba_port);
		tgtdev->host_exposed = 0;
		retval = -1;
	}
	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;
}

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