cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mpt3sas_transport.c (65103B)


      1/*
      2 * SAS Transport Layer for MPT (Message Passing Technology) based controllers
      3 *
      4 * This code is based on drivers/scsi/mpt3sas/mpt3sas_transport.c
      5 * Copyright (C) 2012-2014  LSI Corporation
      6 * Copyright (C) 2013-2014 Avago Technologies
      7 *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
      8 *
      9 * This program is free software; you can redistribute it and/or
     10 * modify it under the terms of the GNU General Public License
     11 * as published by the Free Software Foundation; either version 2
     12 * of the License, or (at your option) any later version.
     13 *
     14 * This program is distributed in the hope that it will be useful,
     15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 * GNU General Public License for more details.
     18 *
     19 * NO WARRANTY
     20 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
     21 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
     22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
     23 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
     24 * solely responsible for determining the appropriateness of using and
     25 * distributing the Program and assumes all risks associated with its
     26 * exercise of rights under this Agreement, including but not limited to
     27 * the risks and costs of program errors, damage to or loss of data,
     28 * programs or equipment, and unavailability or interruption of operations.
     29
     30 * DISCLAIMER OF LIABILITY
     31 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
     32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     33 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
     34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
     36 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
     37 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
     38
     39 * You should have received a copy of the GNU General Public License
     40 * along with this program; if not, write to the Free Software
     41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
     42 * USA.
     43 */
     44
     45#include <linux/module.h>
     46#include <linux/kernel.h>
     47#include <linux/init.h>
     48#include <linux/errno.h>
     49#include <linux/sched.h>
     50#include <linux/workqueue.h>
     51#include <linux/delay.h>
     52#include <linux/pci.h>
     53
     54#include <scsi/scsi.h>
     55#include <scsi/scsi_cmnd.h>
     56#include <scsi/scsi_device.h>
     57#include <scsi/scsi_host.h>
     58#include <scsi/scsi_transport_sas.h>
     59#include <scsi/scsi_dbg.h>
     60
     61#include "mpt3sas_base.h"
     62
     63/**
     64 * _transport_get_port_id_by_sas_phy - get zone's port id that Phy belong to
     65 * @phy: sas_phy object
     66 *
     67 * Return Port number
     68 */
     69static inline u8
     70_transport_get_port_id_by_sas_phy(struct sas_phy *phy)
     71{
     72	u8 port_id = 0xFF;
     73	struct hba_port *port = phy->hostdata;
     74
     75	if (port)
     76		port_id = port->port_id;
     77
     78	return port_id;
     79}
     80
     81/**
     82 * _transport_sas_node_find_by_sas_address - sas node search
     83 * @ioc: per adapter object
     84 * @sas_address: sas address of expander or sas host
     85 * @port: hba port entry
     86 * Context: Calling function should acquire ioc->sas_node_lock.
     87 *
     88 * Search for either hba phys or expander device based on handle, then returns
     89 * the sas_node object.
     90 */
     91static struct _sas_node *
     92_transport_sas_node_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
     93	u64 sas_address, struct hba_port *port)
     94{
     95	if (ioc->sas_hba.sas_address == sas_address)
     96		return &ioc->sas_hba;
     97	else
     98		return mpt3sas_scsih_expander_find_by_sas_address(ioc,
     99		    sas_address, port);
    100}
    101
    102/**
    103 * _transport_get_port_id_by_rphy - Get Port number from rphy object
    104 * @ioc: per adapter object
    105 * @rphy: sas_rphy object
    106 *
    107 * Returns Port number.
    108 */
    109static u8
    110_transport_get_port_id_by_rphy(struct MPT3SAS_ADAPTER *ioc,
    111	struct sas_rphy *rphy)
    112{
    113	struct _sas_node *sas_expander;
    114	struct _sas_device *sas_device;
    115	unsigned long flags;
    116	u8 port_id = 0xFF;
    117
    118	if (!rphy)
    119		return port_id;
    120
    121	if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
    122	    rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) {
    123		spin_lock_irqsave(&ioc->sas_node_lock, flags);
    124		list_for_each_entry(sas_expander,
    125		    &ioc->sas_expander_list, list) {
    126			if (sas_expander->rphy == rphy) {
    127				port_id = sas_expander->port->port_id;
    128				break;
    129			}
    130		}
    131		spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
    132	} else if (rphy->identify.device_type == SAS_END_DEVICE) {
    133		spin_lock_irqsave(&ioc->sas_device_lock, flags);
    134		sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy);
    135		if (sas_device) {
    136			port_id = sas_device->port->port_id;
    137			sas_device_put(sas_device);
    138		}
    139		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
    140	}
    141
    142	return port_id;
    143}
    144
    145/**
    146 * _transport_convert_phy_link_rate -
    147 * @link_rate: link rate returned from mpt firmware
    148 *
    149 * Convert link_rate from mpi fusion into sas_transport form.
    150 */
    151static enum sas_linkrate
    152_transport_convert_phy_link_rate(u8 link_rate)
    153{
    154	enum sas_linkrate rc;
    155
    156	switch (link_rate) {
    157	case MPI2_SAS_NEG_LINK_RATE_1_5:
    158		rc = SAS_LINK_RATE_1_5_GBPS;
    159		break;
    160	case MPI2_SAS_NEG_LINK_RATE_3_0:
    161		rc = SAS_LINK_RATE_3_0_GBPS;
    162		break;
    163	case MPI2_SAS_NEG_LINK_RATE_6_0:
    164		rc = SAS_LINK_RATE_6_0_GBPS;
    165		break;
    166	case MPI25_SAS_NEG_LINK_RATE_12_0:
    167		rc = SAS_LINK_RATE_12_0_GBPS;
    168		break;
    169	case MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED:
    170		rc = SAS_PHY_DISABLED;
    171		break;
    172	case MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED:
    173		rc = SAS_LINK_RATE_FAILED;
    174		break;
    175	case MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR:
    176		rc = SAS_SATA_PORT_SELECTOR;
    177		break;
    178	case MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS:
    179		rc = SAS_PHY_RESET_IN_PROGRESS;
    180		break;
    181
    182	default:
    183	case MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE:
    184	case MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE:
    185		rc = SAS_LINK_RATE_UNKNOWN;
    186		break;
    187	}
    188	return rc;
    189}
    190
    191/**
    192 * _transport_set_identify - set identify for phys and end devices
    193 * @ioc: per adapter object
    194 * @handle: device handle
    195 * @identify: sas identify info
    196 *
    197 * Populates sas identify info.
    198 *
    199 * Return: 0 for success, non-zero for failure.
    200 */
    201static int
    202_transport_set_identify(struct MPT3SAS_ADAPTER *ioc, u16 handle,
    203	struct sas_identify *identify)
    204{
    205	Mpi2SasDevicePage0_t sas_device_pg0;
    206	Mpi2ConfigReply_t mpi_reply;
    207	u32 device_info;
    208	u32 ioc_status;
    209
    210	if (ioc->shost_recovery || ioc->pci_error_recovery) {
    211		ioc_info(ioc, "%s: host reset in progress!\n", __func__);
    212		return -EFAULT;
    213	}
    214
    215	if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
    216	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
    217		ioc_err(ioc, "failure at %s:%d/%s()!\n",
    218			__FILE__, __LINE__, __func__);
    219		return -ENXIO;
    220	}
    221
    222	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
    223	    MPI2_IOCSTATUS_MASK;
    224	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
    225		ioc_err(ioc, "handle(0x%04x), ioc_status(0x%04x) failure at %s:%d/%s()!\n",
    226			handle, ioc_status, __FILE__, __LINE__, __func__);
    227		return -EIO;
    228	}
    229
    230	memset(identify, 0, sizeof(struct sas_identify));
    231	device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
    232
    233	/* sas_address */
    234	identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
    235
    236	/* phy number of the parent device this device is linked to */
    237	identify->phy_identifier = sas_device_pg0.PhyNum;
    238
    239	/* device_type */
    240	switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
    241	case MPI2_SAS_DEVICE_INFO_NO_DEVICE:
    242		identify->device_type = SAS_PHY_UNUSED;
    243		break;
    244	case MPI2_SAS_DEVICE_INFO_END_DEVICE:
    245		identify->device_type = SAS_END_DEVICE;
    246		break;
    247	case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER:
    248		identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
    249		break;
    250	case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER:
    251		identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
    252		break;
    253	}
    254
    255	/* initiator_port_protocols */
    256	if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR)
    257		identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
    258	if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR)
    259		identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
    260	if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR)
    261		identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
    262	if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST)
    263		identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
    264
    265	/* target_port_protocols */
    266	if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET)
    267		identify->target_port_protocols |= SAS_PROTOCOL_SSP;
    268	if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
    269		identify->target_port_protocols |= SAS_PROTOCOL_STP;
    270	if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET)
    271		identify->target_port_protocols |= SAS_PROTOCOL_SMP;
    272	if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
    273		identify->target_port_protocols |= SAS_PROTOCOL_SATA;
    274
    275	return 0;
    276}
    277
    278/**
    279 * mpt3sas_transport_done -  internal transport layer callback handler.
    280 * @ioc: per adapter object
    281 * @smid: system request message index
    282 * @msix_index: MSIX table index supplied by the OS
    283 * @reply: reply message frame(lower 32bit addr)
    284 *
    285 * Callback handler when sending internal generated transport cmds.
    286 * The callback index passed is `ioc->transport_cb_idx`
    287 *
    288 * Return: 1 meaning mf should be freed from _base_interrupt
    289 *         0 means the mf is freed from this function.
    290 */
    291u8
    292mpt3sas_transport_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
    293	u32 reply)
    294{
    295	MPI2DefaultReply_t *mpi_reply;
    296
    297	mpi_reply =  mpt3sas_base_get_reply_virt_addr(ioc, reply);
    298	if (ioc->transport_cmds.status == MPT3_CMD_NOT_USED)
    299		return 1;
    300	if (ioc->transport_cmds.smid != smid)
    301		return 1;
    302	ioc->transport_cmds.status |= MPT3_CMD_COMPLETE;
    303	if (mpi_reply) {
    304		memcpy(ioc->transport_cmds.reply, mpi_reply,
    305		    mpi_reply->MsgLength*4);
    306		ioc->transport_cmds.status |= MPT3_CMD_REPLY_VALID;
    307	}
    308	ioc->transport_cmds.status &= ~MPT3_CMD_PENDING;
    309	complete(&ioc->transport_cmds.done);
    310	return 1;
    311}
    312
    313/* report manufacture request structure */
    314struct rep_manu_request {
    315	u8 smp_frame_type;
    316	u8 function;
    317	u8 reserved;
    318	u8 request_length;
    319};
    320
    321/* report manufacture reply structure */
    322struct rep_manu_reply {
    323	u8 smp_frame_type; /* 0x41 */
    324	u8 function; /* 0x01 */
    325	u8 function_result;
    326	u8 response_length;
    327	u16 expander_change_count;
    328	u8 reserved0[2];
    329	u8 sas_format;
    330	u8 reserved2[3];
    331	u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
    332	u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
    333	u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
    334	u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
    335	u16 component_id;
    336	u8 component_revision_id;
    337	u8 reserved3;
    338	u8 vendor_specific[8];
    339};
    340
    341/**
    342 * _transport_expander_report_manufacture - obtain SMP report_manufacture
    343 * @ioc: per adapter object
    344 * @sas_address: expander sas address
    345 * @edev: the sas_expander_device object
    346 * @port_id: Port ID number
    347 *
    348 * Fills in the sas_expander_device object when SMP port is created.
    349 *
    350 * Return: 0 for success, non-zero for failure.
    351 */
    352static int
    353_transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc,
    354	u64 sas_address, struct sas_expander_device *edev, u8 port_id)
    355{
    356	Mpi2SmpPassthroughRequest_t *mpi_request;
    357	Mpi2SmpPassthroughReply_t *mpi_reply;
    358	struct rep_manu_reply *manufacture_reply;
    359	struct rep_manu_request *manufacture_request;
    360	int rc;
    361	u16 smid;
    362	void *psge;
    363	u8 issue_reset = 0;
    364	void *data_out = NULL;
    365	dma_addr_t data_out_dma;
    366	dma_addr_t data_in_dma;
    367	size_t data_in_sz;
    368	size_t data_out_sz;
    369
    370	if (ioc->shost_recovery || ioc->pci_error_recovery) {
    371		ioc_info(ioc, "%s: host reset in progress!\n", __func__);
    372		return -EFAULT;
    373	}
    374
    375	mutex_lock(&ioc->transport_cmds.mutex);
    376
    377	if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
    378		ioc_err(ioc, "%s: transport_cmds in use\n", __func__);
    379		rc = -EAGAIN;
    380		goto out;
    381	}
    382	ioc->transport_cmds.status = MPT3_CMD_PENDING;
    383
    384	rc = mpt3sas_wait_for_ioc(ioc, IOC_OPERATIONAL_WAIT_COUNT);
    385	if (rc)
    386		goto out;
    387
    388	smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
    389	if (!smid) {
    390		ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
    391		rc = -EAGAIN;
    392		goto out;
    393	}
    394
    395	rc = 0;
    396	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
    397	ioc->transport_cmds.smid = smid;
    398
    399	data_out_sz = sizeof(struct rep_manu_request);
    400	data_in_sz = sizeof(struct rep_manu_reply);
    401	data_out = dma_alloc_coherent(&ioc->pdev->dev, data_out_sz + data_in_sz,
    402			&data_out_dma, GFP_KERNEL);
    403	if (!data_out) {
    404		pr_err("failure at %s:%d/%s()!\n", __FILE__,
    405		    __LINE__, __func__);
    406		rc = -ENOMEM;
    407		mpt3sas_base_free_smid(ioc, smid);
    408		goto out;
    409	}
    410
    411	data_in_dma = data_out_dma + sizeof(struct rep_manu_request);
    412
    413	manufacture_request = data_out;
    414	manufacture_request->smp_frame_type = 0x40;
    415	manufacture_request->function = 1;
    416	manufacture_request->reserved = 0;
    417	manufacture_request->request_length = 0;
    418
    419	memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
    420	mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
    421	mpi_request->PhysicalPort = port_id;
    422	mpi_request->SASAddress = cpu_to_le64(sas_address);
    423	mpi_request->RequestDataLength = cpu_to_le16(data_out_sz);
    424	psge = &mpi_request->SGL;
    425
    426	ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma,
    427	    data_in_sz);
    428
    429	dtransportprintk(ioc,
    430			 ioc_info(ioc, "report_manufacture - send to sas_addr(0x%016llx)\n",
    431				  (u64)sas_address));
    432	init_completion(&ioc->transport_cmds.done);
    433	ioc->put_smid_default(ioc, smid);
    434	wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
    435
    436	if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
    437		ioc_err(ioc, "%s: timeout\n", __func__);
    438		_debug_dump_mf(mpi_request,
    439		    sizeof(Mpi2SmpPassthroughRequest_t)/4);
    440		if (!(ioc->transport_cmds.status & MPT3_CMD_RESET))
    441			issue_reset = 1;
    442		goto issue_host_reset;
    443	}
    444
    445	dtransportprintk(ioc, ioc_info(ioc, "report_manufacture - complete\n"));
    446
    447	if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) {
    448		u8 *tmp;
    449
    450		mpi_reply = ioc->transport_cmds.reply;
    451
    452		dtransportprintk(ioc,
    453				 ioc_info(ioc, "report_manufacture - reply data transfer size(%d)\n",
    454					  le16_to_cpu(mpi_reply->ResponseDataLength)));
    455
    456		if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
    457		    sizeof(struct rep_manu_reply))
    458			goto out;
    459
    460		manufacture_reply = data_out + sizeof(struct rep_manu_request);
    461		strncpy(edev->vendor_id, manufacture_reply->vendor_id,
    462		     SAS_EXPANDER_VENDOR_ID_LEN);
    463		strncpy(edev->product_id, manufacture_reply->product_id,
    464		     SAS_EXPANDER_PRODUCT_ID_LEN);
    465		strncpy(edev->product_rev, manufacture_reply->product_rev,
    466		     SAS_EXPANDER_PRODUCT_REV_LEN);
    467		edev->level = manufacture_reply->sas_format & 1;
    468		if (edev->level) {
    469			strncpy(edev->component_vendor_id,
    470			    manufacture_reply->component_vendor_id,
    471			     SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
    472			tmp = (u8 *)&manufacture_reply->component_id;
    473			edev->component_id = tmp[0] << 8 | tmp[1];
    474			edev->component_revision_id =
    475			    manufacture_reply->component_revision_id;
    476		}
    477	} else
    478		dtransportprintk(ioc,
    479				 ioc_info(ioc, "report_manufacture - no reply\n"));
    480
    481 issue_host_reset:
    482	if (issue_reset)
    483		mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
    484 out:
    485	ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
    486	if (data_out)
    487		dma_free_coherent(&ioc->pdev->dev, data_out_sz + data_in_sz,
    488		    data_out, data_out_dma);
    489
    490	mutex_unlock(&ioc->transport_cmds.mutex);
    491	return rc;
    492}
    493
    494
    495/**
    496 * _transport_delete_port - helper function to removing a port
    497 * @ioc: per adapter object
    498 * @mpt3sas_port: mpt3sas per port object
    499 */
    500static void
    501_transport_delete_port(struct MPT3SAS_ADAPTER *ioc,
    502	struct _sas_port *mpt3sas_port)
    503{
    504	u64 sas_address = mpt3sas_port->remote_identify.sas_address;
    505	struct hba_port *port = mpt3sas_port->hba_port;
    506	enum sas_device_type device_type =
    507	    mpt3sas_port->remote_identify.device_type;
    508
    509	dev_printk(KERN_INFO, &mpt3sas_port->port->dev,
    510	    "remove: sas_addr(0x%016llx)\n",
    511	    (unsigned long long) sas_address);
    512
    513	ioc->logging_level |= MPT_DEBUG_TRANSPORT;
    514	if (device_type == SAS_END_DEVICE)
    515		mpt3sas_device_remove_by_sas_address(ioc,
    516		    sas_address, port);
    517	else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
    518	    device_type == SAS_FANOUT_EXPANDER_DEVICE)
    519		mpt3sas_expander_remove(ioc, sas_address, port);
    520	ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
    521}
    522
    523/**
    524 * _transport_delete_phy - helper function to removing single phy from port
    525 * @ioc: per adapter object
    526 * @mpt3sas_port: mpt3sas per port object
    527 * @mpt3sas_phy: mpt3sas per phy object
    528 */
    529static void
    530_transport_delete_phy(struct MPT3SAS_ADAPTER *ioc,
    531	struct _sas_port *mpt3sas_port, struct _sas_phy *mpt3sas_phy)
    532{
    533	u64 sas_address = mpt3sas_port->remote_identify.sas_address;
    534
    535	dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev,
    536	    "remove: sas_addr(0x%016llx), phy(%d)\n",
    537	    (unsigned long long) sas_address, mpt3sas_phy->phy_id);
    538
    539	list_del(&mpt3sas_phy->port_siblings);
    540	mpt3sas_port->num_phys--;
    541	sas_port_delete_phy(mpt3sas_port->port, mpt3sas_phy->phy);
    542	mpt3sas_phy->phy_belongs_to_port = 0;
    543}
    544
    545/**
    546 * _transport_add_phy - helper function to adding single phy to port
    547 * @ioc: per adapter object
    548 * @mpt3sas_port: mpt3sas per port object
    549 * @mpt3sas_phy: mpt3sas per phy object
    550 */
    551static void
    552_transport_add_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_port *mpt3sas_port,
    553	struct _sas_phy *mpt3sas_phy)
    554{
    555	u64 sas_address = mpt3sas_port->remote_identify.sas_address;
    556
    557	dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev,
    558	    "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long)
    559	    sas_address, mpt3sas_phy->phy_id);
    560
    561	list_add_tail(&mpt3sas_phy->port_siblings, &mpt3sas_port->phy_list);
    562	mpt3sas_port->num_phys++;
    563	sas_port_add_phy(mpt3sas_port->port, mpt3sas_phy->phy);
    564	mpt3sas_phy->phy_belongs_to_port = 1;
    565}
    566
    567/**
    568 * mpt3sas_transport_add_phy_to_an_existing_port - adding new phy to existing port
    569 * @ioc: per adapter object
    570 * @sas_node: sas node object (either expander or sas host)
    571 * @mpt3sas_phy: mpt3sas per phy object
    572 * @sas_address: sas address of device/expander were phy needs to be added to
    573 * @port: hba port entry
    574 */
    575void
    576mpt3sas_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc,
    577	struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy,
    578	u64 sas_address, struct hba_port *port)
    579{
    580	struct _sas_port *mpt3sas_port;
    581	struct _sas_phy *phy_srch;
    582
    583	if (mpt3sas_phy->phy_belongs_to_port == 1)
    584		return;
    585
    586	if (!port)
    587		return;
    588
    589	list_for_each_entry(mpt3sas_port, &sas_node->sas_port_list,
    590	    port_list) {
    591		if (mpt3sas_port->remote_identify.sas_address !=
    592		    sas_address)
    593			continue;
    594		if (mpt3sas_port->hba_port != port)
    595			continue;
    596		list_for_each_entry(phy_srch, &mpt3sas_port->phy_list,
    597		    port_siblings) {
    598			if (phy_srch == mpt3sas_phy)
    599				return;
    600		}
    601		_transport_add_phy(ioc, mpt3sas_port, mpt3sas_phy);
    602		return;
    603	}
    604
    605}
    606
    607/**
    608 * mpt3sas_transport_del_phy_from_an_existing_port - delete phy from existing port
    609 * @ioc: per adapter object
    610 * @sas_node: sas node object (either expander or sas host)
    611 * @mpt3sas_phy: mpt3sas per phy object
    612 */
    613void
    614mpt3sas_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc,
    615	struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy)
    616{
    617	struct _sas_port *mpt3sas_port, *next;
    618	struct _sas_phy *phy_srch;
    619
    620	if (mpt3sas_phy->phy_belongs_to_port == 0)
    621		return;
    622
    623	list_for_each_entry_safe(mpt3sas_port, next, &sas_node->sas_port_list,
    624	    port_list) {
    625		list_for_each_entry(phy_srch, &mpt3sas_port->phy_list,
    626		    port_siblings) {
    627			if (phy_srch != mpt3sas_phy)
    628				continue;
    629
    630			/*
    631			 * Don't delete port during host reset,
    632			 * just delete phy.
    633			 */
    634			if (mpt3sas_port->num_phys == 1 && !ioc->shost_recovery)
    635				_transport_delete_port(ioc, mpt3sas_port);
    636			else
    637				_transport_delete_phy(ioc, mpt3sas_port,
    638				    mpt3sas_phy);
    639			return;
    640		}
    641	}
    642}
    643
    644/**
    645 * _transport_sanity_check - sanity check when adding a new port
    646 * @ioc: per adapter object
    647 * @sas_node: sas node object (either expander or sas host)
    648 * @sas_address: sas address of device being added
    649 * @port: hba port entry
    650 *
    651 * See the explanation above from _transport_delete_duplicate_port
    652 */
    653static void
    654_transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node,
    655	u64 sas_address, struct hba_port *port)
    656{
    657	int i;
    658
    659	for (i = 0; i < sas_node->num_phys; i++) {
    660		if (sas_node->phy[i].remote_identify.sas_address != sas_address)
    661			continue;
    662		if (sas_node->phy[i].port != port)
    663			continue;
    664		if (sas_node->phy[i].phy_belongs_to_port == 1)
    665			mpt3sas_transport_del_phy_from_an_existing_port(ioc,
    666			    sas_node, &sas_node->phy[i]);
    667	}
    668}
    669
    670/**
    671 * mpt3sas_transport_port_add - insert port to the list
    672 * @ioc: per adapter object
    673 * @handle: handle of attached device
    674 * @sas_address: sas address of parent expander or sas host
    675 * @hba_port: hba port entry
    676 * Context: This function will acquire ioc->sas_node_lock.
    677 *
    678 * Adding new port object to the sas_node->sas_port_list.
    679 *
    680 * Return: mpt3sas_port.
    681 */
    682struct _sas_port *
    683mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
    684	u64 sas_address, struct hba_port *hba_port)
    685{
    686	struct _sas_phy *mpt3sas_phy, *next;
    687	struct _sas_port *mpt3sas_port;
    688	unsigned long flags;
    689	struct _sas_node *sas_node;
    690	struct sas_rphy *rphy;
    691	struct _sas_device *sas_device = NULL;
    692	int i;
    693	struct sas_port *port;
    694	struct virtual_phy *vphy = NULL;
    695
    696	if (!hba_port) {
    697		ioc_err(ioc, "failure at %s:%d/%s()!\n",
    698		    __FILE__, __LINE__, __func__);
    699		return NULL;
    700	}
    701
    702	mpt3sas_port = kzalloc(sizeof(struct _sas_port),
    703	    GFP_KERNEL);
    704	if (!mpt3sas_port) {
    705		ioc_err(ioc, "failure at %s:%d/%s()!\n",
    706			__FILE__, __LINE__, __func__);
    707		return NULL;
    708	}
    709
    710	INIT_LIST_HEAD(&mpt3sas_port->port_list);
    711	INIT_LIST_HEAD(&mpt3sas_port->phy_list);
    712	spin_lock_irqsave(&ioc->sas_node_lock, flags);
    713	sas_node = _transport_sas_node_find_by_sas_address(ioc,
    714	    sas_address, hba_port);
    715	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
    716
    717	if (!sas_node) {
    718		ioc_err(ioc, "%s: Could not find parent sas_address(0x%016llx)!\n",
    719			__func__, (u64)sas_address);
    720		goto out_fail;
    721	}
    722
    723	if ((_transport_set_identify(ioc, handle,
    724	    &mpt3sas_port->remote_identify))) {
    725		ioc_err(ioc, "failure at %s:%d/%s()!\n",
    726			__FILE__, __LINE__, __func__);
    727		goto out_fail;
    728	}
    729
    730	if (mpt3sas_port->remote_identify.device_type == SAS_PHY_UNUSED) {
    731		ioc_err(ioc, "failure at %s:%d/%s()!\n",
    732			__FILE__, __LINE__, __func__);
    733		goto out_fail;
    734	}
    735
    736	mpt3sas_port->hba_port = hba_port;
    737	_transport_sanity_check(ioc, sas_node,
    738	    mpt3sas_port->remote_identify.sas_address, hba_port);
    739
    740	for (i = 0; i < sas_node->num_phys; i++) {
    741		if (sas_node->phy[i].remote_identify.sas_address !=
    742		    mpt3sas_port->remote_identify.sas_address)
    743			continue;
    744		if (sas_node->phy[i].port != hba_port)
    745			continue;
    746		list_add_tail(&sas_node->phy[i].port_siblings,
    747		    &mpt3sas_port->phy_list);
    748		mpt3sas_port->num_phys++;
    749		if (sas_node->handle <= ioc->sas_hba.num_phys) {
    750			if (!sas_node->phy[i].hba_vphy) {
    751				hba_port->phy_mask |= (1 << i);
    752				continue;
    753			}
    754
    755			vphy = mpt3sas_get_vphy_by_phy(ioc, hba_port, i);
    756			if (!vphy) {
    757				ioc_err(ioc, "failure at %s:%d/%s()!\n",
    758				    __FILE__, __LINE__, __func__);
    759				goto out_fail;
    760			}
    761		}
    762	}
    763
    764	if (!mpt3sas_port->num_phys) {
    765		ioc_err(ioc, "failure at %s:%d/%s()!\n",
    766			__FILE__, __LINE__, __func__);
    767		goto out_fail;
    768	}
    769
    770	if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
    771		sas_device = mpt3sas_get_sdev_by_addr(ioc,
    772		    mpt3sas_port->remote_identify.sas_address,
    773		    mpt3sas_port->hba_port);
    774		if (!sas_device) {
    775			ioc_err(ioc, "failure at %s:%d/%s()!\n",
    776			    __FILE__, __LINE__, __func__);
    777			goto out_fail;
    778		}
    779		sas_device->pend_sas_rphy_add = 1;
    780	}
    781
    782	if (!sas_node->parent_dev) {
    783		ioc_err(ioc, "failure at %s:%d/%s()!\n",
    784			__FILE__, __LINE__, __func__);
    785		goto out_fail;
    786	}
    787	port = sas_port_alloc_num(sas_node->parent_dev);
    788	if ((sas_port_add(port))) {
    789		ioc_err(ioc, "failure at %s:%d/%s()!\n",
    790			__FILE__, __LINE__, __func__);
    791		goto out_fail;
    792	}
    793
    794	list_for_each_entry(mpt3sas_phy, &mpt3sas_port->phy_list,
    795	    port_siblings) {
    796		if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
    797			dev_printk(KERN_INFO, &port->dev,
    798				"add: handle(0x%04x), sas_addr(0x%016llx), phy(%d)\n",
    799				handle, (unsigned long long)
    800			    mpt3sas_port->remote_identify.sas_address,
    801			    mpt3sas_phy->phy_id);
    802		sas_port_add_phy(port, mpt3sas_phy->phy);
    803		mpt3sas_phy->phy_belongs_to_port = 1;
    804		mpt3sas_phy->port = hba_port;
    805	}
    806
    807	mpt3sas_port->port = port;
    808	if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
    809		rphy = sas_end_device_alloc(port);
    810		sas_device->rphy = rphy;
    811		if (sas_node->handle <= ioc->sas_hba.num_phys) {
    812			if (!vphy)
    813				hba_port->sas_address =
    814				    sas_device->sas_address;
    815			else
    816				vphy->sas_address =
    817				    sas_device->sas_address;
    818		}
    819	} else {
    820		rphy = sas_expander_alloc(port,
    821		    mpt3sas_port->remote_identify.device_type);
    822		if (sas_node->handle <= ioc->sas_hba.num_phys)
    823			hba_port->sas_address =
    824			    mpt3sas_port->remote_identify.sas_address;
    825	}
    826
    827	rphy->identify = mpt3sas_port->remote_identify;
    828
    829	if ((sas_rphy_add(rphy))) {
    830		ioc_err(ioc, "failure at %s:%d/%s()!\n",
    831			__FILE__, __LINE__, __func__);
    832	}
    833
    834	if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
    835		sas_device->pend_sas_rphy_add = 0;
    836		sas_device_put(sas_device);
    837	}
    838
    839	dev_info(&rphy->dev,
    840	    "add: handle(0x%04x), sas_addr(0x%016llx)\n", handle,
    841	    (unsigned long long)mpt3sas_port->remote_identify.sas_address);
    842
    843	mpt3sas_port->rphy = rphy;
    844	spin_lock_irqsave(&ioc->sas_node_lock, flags);
    845	list_add_tail(&mpt3sas_port->port_list, &sas_node->sas_port_list);
    846	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
    847
    848	/* fill in report manufacture */
    849	if (mpt3sas_port->remote_identify.device_type ==
    850	    MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
    851	    mpt3sas_port->remote_identify.device_type ==
    852	    MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
    853		_transport_expander_report_manufacture(ioc,
    854		    mpt3sas_port->remote_identify.sas_address,
    855		    rphy_to_expander_device(rphy), hba_port->port_id);
    856	return mpt3sas_port;
    857
    858 out_fail:
    859	list_for_each_entry_safe(mpt3sas_phy, next, &mpt3sas_port->phy_list,
    860	    port_siblings)
    861		list_del(&mpt3sas_phy->port_siblings);
    862	kfree(mpt3sas_port);
    863	return NULL;
    864}
    865
    866/**
    867 * mpt3sas_transport_port_remove - remove port from the list
    868 * @ioc: per adapter object
    869 * @sas_address: sas address of attached device
    870 * @sas_address_parent: sas address of parent expander or sas host
    871 * @port: hba port entry
    872 * Context: This function will acquire ioc->sas_node_lock.
    873 *
    874 * Removing object and freeing associated memory from the
    875 * ioc->sas_port_list.
    876 */
    877void
    878mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
    879	u64 sas_address_parent, struct hba_port *port)
    880{
    881	int i;
    882	unsigned long flags;
    883	struct _sas_port *mpt3sas_port, *next;
    884	struct _sas_node *sas_node;
    885	u8 found = 0;
    886	struct _sas_phy *mpt3sas_phy, *next_phy;
    887	struct hba_port *hba_port_next, *hba_port = NULL;
    888	struct virtual_phy *vphy, *vphy_next = NULL;
    889
    890	if (!port)
    891		return;
    892
    893	spin_lock_irqsave(&ioc->sas_node_lock, flags);
    894	sas_node = _transport_sas_node_find_by_sas_address(ioc,
    895	    sas_address_parent, port);
    896	if (!sas_node) {
    897		spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
    898		return;
    899	}
    900	list_for_each_entry_safe(mpt3sas_port, next, &sas_node->sas_port_list,
    901	    port_list) {
    902		if (mpt3sas_port->remote_identify.sas_address != sas_address)
    903			continue;
    904		if (mpt3sas_port->hba_port != port)
    905			continue;
    906		found = 1;
    907		list_del(&mpt3sas_port->port_list);
    908		goto out;
    909	}
    910 out:
    911	if (!found) {
    912		spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
    913		return;
    914	}
    915
    916	if (sas_node->handle <= ioc->sas_hba.num_phys &&
    917	    (ioc->multipath_on_hba)) {
    918		if (port->vphys_mask) {
    919			list_for_each_entry_safe(vphy, vphy_next,
    920			    &port->vphys_list, list) {
    921				if (vphy->sas_address != sas_address)
    922					continue;
    923				ioc_info(ioc,
    924				    "remove vphy entry: %p of port:%p,from %d port's vphys list\n",
    925				    vphy, port, port->port_id);
    926				port->vphys_mask &= ~vphy->phy_mask;
    927				list_del(&vphy->list);
    928				kfree(vphy);
    929			}
    930		}
    931
    932		list_for_each_entry_safe(hba_port, hba_port_next,
    933		    &ioc->port_table_list, list) {
    934			if (hba_port != port)
    935				continue;
    936			/*
    937			 * Delete hba_port object if
    938			 *  - hba_port object's sas address matches with current
    939			 *    removed device's sas address and no vphy's
    940			 *    associated with it.
    941			 *  - Current removed device is a vSES device and
    942			 *    none of the other direct attached device have
    943			 *    this vSES device's port number (hence hba_port
    944			 *    object sas_address field will be zero).
    945			 */
    946			if ((hba_port->sas_address == sas_address ||
    947			    !hba_port->sas_address) && !hba_port->vphys_mask) {
    948				ioc_info(ioc,
    949				    "remove hba_port entry: %p port: %d from hba_port list\n",
    950				    hba_port, hba_port->port_id);
    951				list_del(&hba_port->list);
    952				kfree(hba_port);
    953			} else if (hba_port->sas_address == sas_address &&
    954			    hba_port->vphys_mask) {
    955				/*
    956				 * Current removed device is a non vSES device
    957				 * and a vSES device has the same port number
    958				 * as of current device's port number. Hence
    959				 * only clear the sas_address filed, don't
    960				 * delete the hba_port object.
    961				 */
    962				ioc_info(ioc,
    963				    "clearing sas_address from hba_port entry: %p port: %d from hba_port list\n",
    964				    hba_port, hba_port->port_id);
    965				port->sas_address = 0;
    966			}
    967			break;
    968		}
    969	}
    970
    971	for (i = 0; i < sas_node->num_phys; i++) {
    972		if (sas_node->phy[i].remote_identify.sas_address == sas_address)
    973			memset(&sas_node->phy[i].remote_identify, 0 ,
    974			    sizeof(struct sas_identify));
    975	}
    976
    977	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
    978
    979	list_for_each_entry_safe(mpt3sas_phy, next_phy,
    980	    &mpt3sas_port->phy_list, port_siblings) {
    981		if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
    982			dev_printk(KERN_INFO, &mpt3sas_port->port->dev,
    983			    "remove: sas_addr(0x%016llx), phy(%d)\n",
    984			    (unsigned long long)
    985			    mpt3sas_port->remote_identify.sas_address,
    986			    mpt3sas_phy->phy_id);
    987		mpt3sas_phy->phy_belongs_to_port = 0;
    988		if (!ioc->remove_host)
    989			sas_port_delete_phy(mpt3sas_port->port,
    990						mpt3sas_phy->phy);
    991		list_del(&mpt3sas_phy->port_siblings);
    992	}
    993	if (!ioc->remove_host)
    994		sas_port_delete(mpt3sas_port->port);
    995	ioc_info(ioc, "%s: removed: sas_addr(0x%016llx)\n",
    996	    __func__, (unsigned long long)sas_address);
    997	kfree(mpt3sas_port);
    998}
    999
   1000/**
   1001 * mpt3sas_transport_add_host_phy - report sas_host phy to transport
   1002 * @ioc: per adapter object
   1003 * @mpt3sas_phy: mpt3sas per phy object
   1004 * @phy_pg0: sas phy page 0
   1005 * @parent_dev: parent device class object
   1006 *
   1007 * Return: 0 for success, non-zero for failure.
   1008 */
   1009int
   1010mpt3sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy
   1011	*mpt3sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev)
   1012{
   1013	struct sas_phy *phy;
   1014	int phy_index = mpt3sas_phy->phy_id;
   1015
   1016
   1017	INIT_LIST_HEAD(&mpt3sas_phy->port_siblings);
   1018	phy = sas_phy_alloc(parent_dev, phy_index);
   1019	if (!phy) {
   1020		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1021			__FILE__, __LINE__, __func__);
   1022		return -1;
   1023	}
   1024	if ((_transport_set_identify(ioc, mpt3sas_phy->handle,
   1025	    &mpt3sas_phy->identify))) {
   1026		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1027			__FILE__, __LINE__, __func__);
   1028		sas_phy_free(phy);
   1029		return -1;
   1030	}
   1031	phy->identify = mpt3sas_phy->identify;
   1032	mpt3sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle);
   1033	if (mpt3sas_phy->attached_handle)
   1034		_transport_set_identify(ioc, mpt3sas_phy->attached_handle,
   1035		    &mpt3sas_phy->remote_identify);
   1036	phy->identify.phy_identifier = mpt3sas_phy->phy_id;
   1037	phy->negotiated_linkrate = _transport_convert_phy_link_rate(
   1038	    phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
   1039	phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
   1040	    phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
   1041	phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
   1042	    phy_pg0.HwLinkRate >> 4);
   1043	phy->minimum_linkrate = _transport_convert_phy_link_rate(
   1044	    phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
   1045	phy->maximum_linkrate = _transport_convert_phy_link_rate(
   1046	    phy_pg0.ProgrammedLinkRate >> 4);
   1047	phy->hostdata = mpt3sas_phy->port;
   1048
   1049	if ((sas_phy_add(phy))) {
   1050		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1051			__FILE__, __LINE__, __func__);
   1052		sas_phy_free(phy);
   1053		return -1;
   1054	}
   1055	if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
   1056		dev_printk(KERN_INFO, &phy->dev,
   1057		    "add: handle(0x%04x), sas_addr(0x%016llx)\n"
   1058		    "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
   1059		    mpt3sas_phy->handle, (unsigned long long)
   1060		    mpt3sas_phy->identify.sas_address,
   1061		    mpt3sas_phy->attached_handle,
   1062		    (unsigned long long)
   1063		    mpt3sas_phy->remote_identify.sas_address);
   1064	mpt3sas_phy->phy = phy;
   1065	return 0;
   1066}
   1067
   1068
   1069/**
   1070 * mpt3sas_transport_add_expander_phy - report expander phy to transport
   1071 * @ioc: per adapter object
   1072 * @mpt3sas_phy: mpt3sas per phy object
   1073 * @expander_pg1: expander page 1
   1074 * @parent_dev: parent device class object
   1075 *
   1076 * Return: 0 for success, non-zero for failure.
   1077 */
   1078int
   1079mpt3sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy
   1080	*mpt3sas_phy, Mpi2ExpanderPage1_t expander_pg1,
   1081	struct device *parent_dev)
   1082{
   1083	struct sas_phy *phy;
   1084	int phy_index = mpt3sas_phy->phy_id;
   1085
   1086	INIT_LIST_HEAD(&mpt3sas_phy->port_siblings);
   1087	phy = sas_phy_alloc(parent_dev, phy_index);
   1088	if (!phy) {
   1089		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1090			__FILE__, __LINE__, __func__);
   1091		return -1;
   1092	}
   1093	if ((_transport_set_identify(ioc, mpt3sas_phy->handle,
   1094	    &mpt3sas_phy->identify))) {
   1095		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1096			__FILE__, __LINE__, __func__);
   1097		sas_phy_free(phy);
   1098		return -1;
   1099	}
   1100	phy->identify = mpt3sas_phy->identify;
   1101	mpt3sas_phy->attached_handle =
   1102	    le16_to_cpu(expander_pg1.AttachedDevHandle);
   1103	if (mpt3sas_phy->attached_handle)
   1104		_transport_set_identify(ioc, mpt3sas_phy->attached_handle,
   1105		    &mpt3sas_phy->remote_identify);
   1106	phy->identify.phy_identifier = mpt3sas_phy->phy_id;
   1107	phy->negotiated_linkrate = _transport_convert_phy_link_rate(
   1108	    expander_pg1.NegotiatedLinkRate &
   1109	    MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
   1110	phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
   1111	    expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
   1112	phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
   1113	    expander_pg1.HwLinkRate >> 4);
   1114	phy->minimum_linkrate = _transport_convert_phy_link_rate(
   1115	    expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
   1116	phy->maximum_linkrate = _transport_convert_phy_link_rate(
   1117	    expander_pg1.ProgrammedLinkRate >> 4);
   1118	phy->hostdata = mpt3sas_phy->port;
   1119
   1120	if ((sas_phy_add(phy))) {
   1121		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1122			__FILE__, __LINE__, __func__);
   1123		sas_phy_free(phy);
   1124		return -1;
   1125	}
   1126	if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
   1127		dev_printk(KERN_INFO, &phy->dev,
   1128		    "add: handle(0x%04x), sas_addr(0x%016llx)\n"
   1129		    "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
   1130		    mpt3sas_phy->handle, (unsigned long long)
   1131		    mpt3sas_phy->identify.sas_address,
   1132		    mpt3sas_phy->attached_handle,
   1133		    (unsigned long long)
   1134		    mpt3sas_phy->remote_identify.sas_address);
   1135	mpt3sas_phy->phy = phy;
   1136	return 0;
   1137}
   1138
   1139/**
   1140 * mpt3sas_transport_update_links - refreshing phy link changes
   1141 * @ioc: per adapter object
   1142 * @sas_address: sas address of parent expander or sas host
   1143 * @handle: attached device handle
   1144 * @phy_number: phy number
   1145 * @link_rate: new link rate
   1146 * @port: hba port entry
   1147 *
   1148 * Return nothing.
   1149 */
   1150void
   1151mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc,
   1152	u64 sas_address, u16 handle, u8 phy_number, u8 link_rate,
   1153	struct hba_port *port)
   1154{
   1155	unsigned long flags;
   1156	struct _sas_node *sas_node;
   1157	struct _sas_phy *mpt3sas_phy;
   1158	struct hba_port *hba_port = NULL;
   1159
   1160	if (ioc->shost_recovery || ioc->pci_error_recovery)
   1161		return;
   1162
   1163	spin_lock_irqsave(&ioc->sas_node_lock, flags);
   1164	sas_node = _transport_sas_node_find_by_sas_address(ioc,
   1165	    sas_address, port);
   1166	if (!sas_node) {
   1167		spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
   1168		return;
   1169	}
   1170
   1171	mpt3sas_phy = &sas_node->phy[phy_number];
   1172	mpt3sas_phy->attached_handle = handle;
   1173	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
   1174	if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
   1175		_transport_set_identify(ioc, handle,
   1176		    &mpt3sas_phy->remote_identify);
   1177		if ((sas_node->handle <= ioc->sas_hba.num_phys) &&
   1178		    (ioc->multipath_on_hba)) {
   1179			list_for_each_entry(hba_port,
   1180			    &ioc->port_table_list, list) {
   1181				if (hba_port->sas_address == sas_address &&
   1182				    hba_port == port)
   1183					hba_port->phy_mask |=
   1184					    (1 << mpt3sas_phy->phy_id);
   1185			}
   1186		}
   1187		mpt3sas_transport_add_phy_to_an_existing_port(ioc, sas_node,
   1188		    mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address,
   1189		    port);
   1190	} else
   1191		memset(&mpt3sas_phy->remote_identify, 0 , sizeof(struct
   1192		    sas_identify));
   1193
   1194	if (mpt3sas_phy->phy)
   1195		mpt3sas_phy->phy->negotiated_linkrate =
   1196		    _transport_convert_phy_link_rate(link_rate);
   1197
   1198	if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
   1199		dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev,
   1200		    "refresh: parent sas_addr(0x%016llx),\n"
   1201		    "\tlink_rate(0x%02x), phy(%d)\n"
   1202		    "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
   1203		    (unsigned long long)sas_address,
   1204		    link_rate, phy_number, handle, (unsigned long long)
   1205		    mpt3sas_phy->remote_identify.sas_address);
   1206}
   1207
   1208static inline void *
   1209phy_to_ioc(struct sas_phy *phy)
   1210{
   1211	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
   1212	return shost_priv(shost);
   1213}
   1214
   1215static inline void *
   1216rphy_to_ioc(struct sas_rphy *rphy)
   1217{
   1218	struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
   1219	return shost_priv(shost);
   1220}
   1221
   1222/* report phy error log structure */
   1223struct phy_error_log_request {
   1224	u8 smp_frame_type; /* 0x40 */
   1225	u8 function; /* 0x11 */
   1226	u8 allocated_response_length;
   1227	u8 request_length; /* 02 */
   1228	u8 reserved_1[5];
   1229	u8 phy_identifier;
   1230	u8 reserved_2[2];
   1231};
   1232
   1233/* report phy error log reply structure */
   1234struct phy_error_log_reply {
   1235	u8 smp_frame_type; /* 0x41 */
   1236	u8 function; /* 0x11 */
   1237	u8 function_result;
   1238	u8 response_length;
   1239	__be16 expander_change_count;
   1240	u8 reserved_1[3];
   1241	u8 phy_identifier;
   1242	u8 reserved_2[2];
   1243	__be32 invalid_dword;
   1244	__be32 running_disparity_error;
   1245	__be32 loss_of_dword_sync;
   1246	__be32 phy_reset_problem;
   1247};
   1248
   1249/**
   1250 * _transport_get_expander_phy_error_log - return expander counters
   1251 * @ioc: per adapter object
   1252 * @phy: The sas phy object
   1253 *
   1254 * Return: 0 for success, non-zero for failure.
   1255 *
   1256 */
   1257static int
   1258_transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc,
   1259	struct sas_phy *phy)
   1260{
   1261	Mpi2SmpPassthroughRequest_t *mpi_request;
   1262	Mpi2SmpPassthroughReply_t *mpi_reply;
   1263	struct phy_error_log_request *phy_error_log_request;
   1264	struct phy_error_log_reply *phy_error_log_reply;
   1265	int rc;
   1266	u16 smid;
   1267	void *psge;
   1268	u8 issue_reset = 0;
   1269	void *data_out = NULL;
   1270	dma_addr_t data_out_dma;
   1271	u32 sz;
   1272
   1273	if (ioc->shost_recovery || ioc->pci_error_recovery) {
   1274		ioc_info(ioc, "%s: host reset in progress!\n", __func__);
   1275		return -EFAULT;
   1276	}
   1277
   1278	mutex_lock(&ioc->transport_cmds.mutex);
   1279
   1280	if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
   1281		ioc_err(ioc, "%s: transport_cmds in use\n", __func__);
   1282		rc = -EAGAIN;
   1283		goto out;
   1284	}
   1285	ioc->transport_cmds.status = MPT3_CMD_PENDING;
   1286
   1287	rc = mpt3sas_wait_for_ioc(ioc, IOC_OPERATIONAL_WAIT_COUNT);
   1288	if (rc)
   1289		goto out;
   1290
   1291	smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
   1292	if (!smid) {
   1293		ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
   1294		rc = -EAGAIN;
   1295		goto out;
   1296	}
   1297
   1298	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
   1299	ioc->transport_cmds.smid = smid;
   1300
   1301	sz = sizeof(struct phy_error_log_request) +
   1302	    sizeof(struct phy_error_log_reply);
   1303	data_out = dma_alloc_coherent(&ioc->pdev->dev, sz, &data_out_dma,
   1304			GFP_KERNEL);
   1305	if (!data_out) {
   1306		pr_err("failure at %s:%d/%s()!\n", __FILE__,
   1307		    __LINE__, __func__);
   1308		rc = -ENOMEM;
   1309		mpt3sas_base_free_smid(ioc, smid);
   1310		goto out;
   1311	}
   1312
   1313	rc = -EINVAL;
   1314	memset(data_out, 0, sz);
   1315	phy_error_log_request = data_out;
   1316	phy_error_log_request->smp_frame_type = 0x40;
   1317	phy_error_log_request->function = 0x11;
   1318	phy_error_log_request->request_length = 2;
   1319	phy_error_log_request->allocated_response_length = 0;
   1320	phy_error_log_request->phy_identifier = phy->number;
   1321
   1322	memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
   1323	mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
   1324	mpi_request->PhysicalPort = _transport_get_port_id_by_sas_phy(phy);
   1325	mpi_request->VF_ID = 0; /* TODO */
   1326	mpi_request->VP_ID = 0;
   1327	mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
   1328	mpi_request->RequestDataLength =
   1329	    cpu_to_le16(sizeof(struct phy_error_log_request));
   1330	psge = &mpi_request->SGL;
   1331
   1332	ioc->build_sg(ioc, psge, data_out_dma,
   1333		sizeof(struct phy_error_log_request),
   1334	    data_out_dma + sizeof(struct phy_error_log_request),
   1335	    sizeof(struct phy_error_log_reply));
   1336
   1337	dtransportprintk(ioc,
   1338			 ioc_info(ioc, "phy_error_log - send to sas_addr(0x%016llx), phy(%d)\n",
   1339				  (u64)phy->identify.sas_address,
   1340				  phy->number));
   1341	init_completion(&ioc->transport_cmds.done);
   1342	ioc->put_smid_default(ioc, smid);
   1343	wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
   1344
   1345	if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
   1346		ioc_err(ioc, "%s: timeout\n", __func__);
   1347		_debug_dump_mf(mpi_request,
   1348		    sizeof(Mpi2SmpPassthroughRequest_t)/4);
   1349		if (!(ioc->transport_cmds.status & MPT3_CMD_RESET))
   1350			issue_reset = 1;
   1351		goto issue_host_reset;
   1352	}
   1353
   1354	dtransportprintk(ioc, ioc_info(ioc, "phy_error_log - complete\n"));
   1355
   1356	if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) {
   1357
   1358		mpi_reply = ioc->transport_cmds.reply;
   1359
   1360		dtransportprintk(ioc,
   1361				 ioc_info(ioc, "phy_error_log - reply data transfer size(%d)\n",
   1362					  le16_to_cpu(mpi_reply->ResponseDataLength)));
   1363
   1364		if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
   1365		    sizeof(struct phy_error_log_reply))
   1366			goto out;
   1367
   1368		phy_error_log_reply = data_out +
   1369		    sizeof(struct phy_error_log_request);
   1370
   1371		dtransportprintk(ioc,
   1372				 ioc_info(ioc, "phy_error_log - function_result(%d)\n",
   1373					  phy_error_log_reply->function_result));
   1374
   1375		phy->invalid_dword_count =
   1376		    be32_to_cpu(phy_error_log_reply->invalid_dword);
   1377		phy->running_disparity_error_count =
   1378		    be32_to_cpu(phy_error_log_reply->running_disparity_error);
   1379		phy->loss_of_dword_sync_count =
   1380		    be32_to_cpu(phy_error_log_reply->loss_of_dword_sync);
   1381		phy->phy_reset_problem_count =
   1382		    be32_to_cpu(phy_error_log_reply->phy_reset_problem);
   1383		rc = 0;
   1384	} else
   1385		dtransportprintk(ioc,
   1386				 ioc_info(ioc, "phy_error_log - no reply\n"));
   1387
   1388 issue_host_reset:
   1389	if (issue_reset)
   1390		mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
   1391 out:
   1392	ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
   1393	if (data_out)
   1394		dma_free_coherent(&ioc->pdev->dev, sz, data_out, data_out_dma);
   1395
   1396	mutex_unlock(&ioc->transport_cmds.mutex);
   1397	return rc;
   1398}
   1399
   1400/**
   1401 * _transport_get_linkerrors - return phy counters for both hba and expanders
   1402 * @phy: The sas phy object
   1403 *
   1404 * Return: 0 for success, non-zero for failure.
   1405 *
   1406 */
   1407static int
   1408_transport_get_linkerrors(struct sas_phy *phy)
   1409{
   1410	struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
   1411	unsigned long flags;
   1412	Mpi2ConfigReply_t mpi_reply;
   1413	Mpi2SasPhyPage1_t phy_pg1;
   1414	struct hba_port *port = phy->hostdata;
   1415	int port_id = port->port_id;
   1416
   1417	spin_lock_irqsave(&ioc->sas_node_lock, flags);
   1418	if (_transport_sas_node_find_by_sas_address(ioc,
   1419	    phy->identify.sas_address,
   1420	    mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) {
   1421		spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
   1422		return -EINVAL;
   1423	}
   1424	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
   1425
   1426	if (phy->identify.sas_address != ioc->sas_hba.sas_address)
   1427		return _transport_get_expander_phy_error_log(ioc, phy);
   1428
   1429	/* get hba phy error logs */
   1430	if ((mpt3sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1,
   1431		    phy->number))) {
   1432		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1433			__FILE__, __LINE__, __func__);
   1434		return -ENXIO;
   1435	}
   1436
   1437	if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
   1438		ioc_info(ioc, "phy(%d), ioc_status (0x%04x), loginfo(0x%08x)\n",
   1439			 phy->number,
   1440			 le16_to_cpu(mpi_reply.IOCStatus),
   1441			 le32_to_cpu(mpi_reply.IOCLogInfo));
   1442
   1443	phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount);
   1444	phy->running_disparity_error_count =
   1445	    le32_to_cpu(phy_pg1.RunningDisparityErrorCount);
   1446	phy->loss_of_dword_sync_count =
   1447	    le32_to_cpu(phy_pg1.LossDwordSynchCount);
   1448	phy->phy_reset_problem_count =
   1449	    le32_to_cpu(phy_pg1.PhyResetProblemCount);
   1450	return 0;
   1451}
   1452
   1453/**
   1454 * _transport_get_enclosure_identifier -
   1455 * @rphy: The sas phy object
   1456 * @identifier: ?
   1457 *
   1458 * Obtain the enclosure logical id for an expander.
   1459 * Return: 0 for success, non-zero for failure.
   1460 */
   1461static int
   1462_transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
   1463{
   1464	struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
   1465	struct _sas_device *sas_device;
   1466	unsigned long flags;
   1467	int rc;
   1468
   1469	spin_lock_irqsave(&ioc->sas_device_lock, flags);
   1470	sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy);
   1471	if (sas_device) {
   1472		*identifier = sas_device->enclosure_logical_id;
   1473		rc = 0;
   1474		sas_device_put(sas_device);
   1475	} else {
   1476		*identifier = 0;
   1477		rc = -ENXIO;
   1478	}
   1479
   1480	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
   1481	return rc;
   1482}
   1483
   1484/**
   1485 * _transport_get_bay_identifier -
   1486 * @rphy: The sas phy object
   1487 *
   1488 * Return: the slot id for a device that resides inside an enclosure.
   1489 */
   1490static int
   1491_transport_get_bay_identifier(struct sas_rphy *rphy)
   1492{
   1493	struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
   1494	struct _sas_device *sas_device;
   1495	unsigned long flags;
   1496	int rc;
   1497
   1498	spin_lock_irqsave(&ioc->sas_device_lock, flags);
   1499	sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy);
   1500	if (sas_device) {
   1501		rc = sas_device->slot;
   1502		sas_device_put(sas_device);
   1503	} else {
   1504		rc = -ENXIO;
   1505	}
   1506	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
   1507	return rc;
   1508}
   1509
   1510/* phy control request structure */
   1511struct phy_control_request {
   1512	u8 smp_frame_type; /* 0x40 */
   1513	u8 function; /* 0x91 */
   1514	u8 allocated_response_length;
   1515	u8 request_length; /* 0x09 */
   1516	u16 expander_change_count;
   1517	u8 reserved_1[3];
   1518	u8 phy_identifier;
   1519	u8 phy_operation;
   1520	u8 reserved_2[13];
   1521	u64 attached_device_name;
   1522	u8 programmed_min_physical_link_rate;
   1523	u8 programmed_max_physical_link_rate;
   1524	u8 reserved_3[6];
   1525};
   1526
   1527/* phy control reply structure */
   1528struct phy_control_reply {
   1529	u8 smp_frame_type; /* 0x41 */
   1530	u8 function; /* 0x11 */
   1531	u8 function_result;
   1532	u8 response_length;
   1533};
   1534
   1535#define SMP_PHY_CONTROL_LINK_RESET	(0x01)
   1536#define SMP_PHY_CONTROL_HARD_RESET	(0x02)
   1537#define SMP_PHY_CONTROL_DISABLE		(0x03)
   1538
   1539/**
   1540 * _transport_expander_phy_control - expander phy control
   1541 * @ioc: per adapter object
   1542 * @phy: The sas phy object
   1543 * @phy_operation: ?
   1544 *
   1545 * Return: 0 for success, non-zero for failure.
   1546 *
   1547 */
   1548static int
   1549_transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc,
   1550	struct sas_phy *phy, u8 phy_operation)
   1551{
   1552	Mpi2SmpPassthroughRequest_t *mpi_request;
   1553	Mpi2SmpPassthroughReply_t *mpi_reply;
   1554	struct phy_control_request *phy_control_request;
   1555	struct phy_control_reply *phy_control_reply;
   1556	int rc;
   1557	u16 smid;
   1558	void *psge;
   1559	u8 issue_reset = 0;
   1560	void *data_out = NULL;
   1561	dma_addr_t data_out_dma;
   1562	u32 sz;
   1563
   1564	if (ioc->shost_recovery || ioc->pci_error_recovery) {
   1565		ioc_info(ioc, "%s: host reset in progress!\n", __func__);
   1566		return -EFAULT;
   1567	}
   1568
   1569	mutex_lock(&ioc->transport_cmds.mutex);
   1570
   1571	if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
   1572		ioc_err(ioc, "%s: transport_cmds in use\n", __func__);
   1573		rc = -EAGAIN;
   1574		goto out;
   1575	}
   1576	ioc->transport_cmds.status = MPT3_CMD_PENDING;
   1577
   1578	rc = mpt3sas_wait_for_ioc(ioc, IOC_OPERATIONAL_WAIT_COUNT);
   1579	if (rc)
   1580		goto out;
   1581
   1582	smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
   1583	if (!smid) {
   1584		ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
   1585		rc = -EAGAIN;
   1586		goto out;
   1587	}
   1588
   1589	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
   1590	ioc->transport_cmds.smid = smid;
   1591
   1592	sz = sizeof(struct phy_control_request) +
   1593	    sizeof(struct phy_control_reply);
   1594	data_out = dma_alloc_coherent(&ioc->pdev->dev, sz, &data_out_dma,
   1595			GFP_KERNEL);
   1596	if (!data_out) {
   1597		pr_err("failure at %s:%d/%s()!\n", __FILE__,
   1598		    __LINE__, __func__);
   1599		rc = -ENOMEM;
   1600		mpt3sas_base_free_smid(ioc, smid);
   1601		goto out;
   1602	}
   1603
   1604	rc = -EINVAL;
   1605	memset(data_out, 0, sz);
   1606	phy_control_request = data_out;
   1607	phy_control_request->smp_frame_type = 0x40;
   1608	phy_control_request->function = 0x91;
   1609	phy_control_request->request_length = 9;
   1610	phy_control_request->allocated_response_length = 0;
   1611	phy_control_request->phy_identifier = phy->number;
   1612	phy_control_request->phy_operation = phy_operation;
   1613	phy_control_request->programmed_min_physical_link_rate =
   1614	    phy->minimum_linkrate << 4;
   1615	phy_control_request->programmed_max_physical_link_rate =
   1616	    phy->maximum_linkrate << 4;
   1617
   1618	memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
   1619	mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
   1620	mpi_request->PhysicalPort = _transport_get_port_id_by_sas_phy(phy);
   1621	mpi_request->VF_ID = 0; /* TODO */
   1622	mpi_request->VP_ID = 0;
   1623	mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
   1624	mpi_request->RequestDataLength =
   1625	    cpu_to_le16(sizeof(struct phy_error_log_request));
   1626	psge = &mpi_request->SGL;
   1627
   1628	ioc->build_sg(ioc, psge, data_out_dma,
   1629			    sizeof(struct phy_control_request),
   1630	    data_out_dma + sizeof(struct phy_control_request),
   1631	    sizeof(struct phy_control_reply));
   1632
   1633	dtransportprintk(ioc,
   1634			 ioc_info(ioc, "phy_control - send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n",
   1635				  (u64)phy->identify.sas_address,
   1636				  phy->number, phy_operation));
   1637	init_completion(&ioc->transport_cmds.done);
   1638	ioc->put_smid_default(ioc, smid);
   1639	wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
   1640
   1641	if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
   1642		ioc_err(ioc, "%s: timeout\n", __func__);
   1643		_debug_dump_mf(mpi_request,
   1644		    sizeof(Mpi2SmpPassthroughRequest_t)/4);
   1645		if (!(ioc->transport_cmds.status & MPT3_CMD_RESET))
   1646			issue_reset = 1;
   1647		goto issue_host_reset;
   1648	}
   1649
   1650	dtransportprintk(ioc, ioc_info(ioc, "phy_control - complete\n"));
   1651
   1652	if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) {
   1653
   1654		mpi_reply = ioc->transport_cmds.reply;
   1655
   1656		dtransportprintk(ioc,
   1657				 ioc_info(ioc, "phy_control - reply data transfer size(%d)\n",
   1658					  le16_to_cpu(mpi_reply->ResponseDataLength)));
   1659
   1660		if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
   1661		    sizeof(struct phy_control_reply))
   1662			goto out;
   1663
   1664		phy_control_reply = data_out +
   1665		    sizeof(struct phy_control_request);
   1666
   1667		dtransportprintk(ioc,
   1668				 ioc_info(ioc, "phy_control - function_result(%d)\n",
   1669					  phy_control_reply->function_result));
   1670
   1671		rc = 0;
   1672	} else
   1673		dtransportprintk(ioc,
   1674				 ioc_info(ioc, "phy_control - no reply\n"));
   1675
   1676 issue_host_reset:
   1677	if (issue_reset)
   1678		mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
   1679 out:
   1680	ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
   1681	if (data_out)
   1682		dma_free_coherent(&ioc->pdev->dev, sz, data_out,
   1683				data_out_dma);
   1684
   1685	mutex_unlock(&ioc->transport_cmds.mutex);
   1686	return rc;
   1687}
   1688
   1689/**
   1690 * _transport_phy_reset -
   1691 * @phy: The sas phy object
   1692 * @hard_reset:
   1693 *
   1694 * Return: 0 for success, non-zero for failure.
   1695 */
   1696static int
   1697_transport_phy_reset(struct sas_phy *phy, int hard_reset)
   1698{
   1699	struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
   1700	Mpi2SasIoUnitControlReply_t mpi_reply;
   1701	Mpi2SasIoUnitControlRequest_t mpi_request;
   1702	struct hba_port *port = phy->hostdata;
   1703	int port_id = port->port_id;
   1704	unsigned long flags;
   1705
   1706	spin_lock_irqsave(&ioc->sas_node_lock, flags);
   1707	if (_transport_sas_node_find_by_sas_address(ioc,
   1708	    phy->identify.sas_address,
   1709	    mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) {
   1710		spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
   1711		return -EINVAL;
   1712	}
   1713	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
   1714
   1715	/* handle expander phys */
   1716	if (phy->identify.sas_address != ioc->sas_hba.sas_address)
   1717		return _transport_expander_phy_control(ioc, phy,
   1718		    (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET :
   1719		    SMP_PHY_CONTROL_LINK_RESET);
   1720
   1721	/* handle hba phys */
   1722	memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
   1723	mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
   1724	mpi_request.Operation = hard_reset ?
   1725	    MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
   1726	mpi_request.PhyNum = phy->number;
   1727
   1728	if ((mpt3sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
   1729		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1730			__FILE__, __LINE__, __func__);
   1731		return -ENXIO;
   1732	}
   1733
   1734	if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
   1735		ioc_info(ioc, "phy(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
   1736			 phy->number, le16_to_cpu(mpi_reply.IOCStatus),
   1737			 le32_to_cpu(mpi_reply.IOCLogInfo));
   1738
   1739	return 0;
   1740}
   1741
   1742/**
   1743 * _transport_phy_enable - enable/disable phys
   1744 * @phy: The sas phy object
   1745 * @enable: enable phy when true
   1746 *
   1747 * Only support sas_host direct attached phys.
   1748 * Return: 0 for success, non-zero for failure.
   1749 */
   1750static int
   1751_transport_phy_enable(struct sas_phy *phy, int enable)
   1752{
   1753	struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
   1754	Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
   1755	Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
   1756	Mpi2ConfigReply_t mpi_reply;
   1757	u16 ioc_status;
   1758	u16 sz;
   1759	int rc = 0;
   1760	unsigned long flags;
   1761	int i, discovery_active;
   1762	struct hba_port *port = phy->hostdata;
   1763	int port_id = port->port_id;
   1764
   1765	spin_lock_irqsave(&ioc->sas_node_lock, flags);
   1766	if (_transport_sas_node_find_by_sas_address(ioc,
   1767	    phy->identify.sas_address,
   1768	    mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) {
   1769		spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
   1770		return -EINVAL;
   1771	}
   1772	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
   1773
   1774	/* handle expander phys */
   1775	if (phy->identify.sas_address != ioc->sas_hba.sas_address)
   1776		return _transport_expander_phy_control(ioc, phy,
   1777		    (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET :
   1778		    SMP_PHY_CONTROL_DISABLE);
   1779
   1780	/* handle hba phys */
   1781
   1782	/* read sas_iounit page 0 */
   1783	sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
   1784	    sizeof(Mpi2SasIOUnit0PhyData_t));
   1785	sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
   1786	if (!sas_iounit_pg0) {
   1787		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1788			__FILE__, __LINE__, __func__);
   1789		rc = -ENOMEM;
   1790		goto out;
   1791	}
   1792	if ((mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
   1793	    sas_iounit_pg0, sz))) {
   1794		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1795			__FILE__, __LINE__, __func__);
   1796		rc = -ENXIO;
   1797		goto out;
   1798	}
   1799	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
   1800	    MPI2_IOCSTATUS_MASK;
   1801	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
   1802		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1803			__FILE__, __LINE__, __func__);
   1804		rc = -EIO;
   1805		goto out;
   1806	}
   1807
   1808	/* unable to enable/disable phys when when discovery is active */
   1809	for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) {
   1810		if (sas_iounit_pg0->PhyData[i].PortFlags &
   1811		    MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) {
   1812			ioc_err(ioc, "discovery is active on port = %d, phy = %d: unable to enable/disable phys, try again later!\n",
   1813				sas_iounit_pg0->PhyData[i].Port, i);
   1814			discovery_active = 1;
   1815		}
   1816	}
   1817
   1818	if (discovery_active) {
   1819		rc = -EAGAIN;
   1820		goto out;
   1821	}
   1822
   1823	/* read sas_iounit page 1 */
   1824	sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
   1825	    sizeof(Mpi2SasIOUnit1PhyData_t));
   1826	sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
   1827	if (!sas_iounit_pg1) {
   1828		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1829			__FILE__, __LINE__, __func__);
   1830		rc = -ENOMEM;
   1831		goto out;
   1832	}
   1833	if ((mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
   1834	    sas_iounit_pg1, sz))) {
   1835		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1836			__FILE__, __LINE__, __func__);
   1837		rc = -ENXIO;
   1838		goto out;
   1839	}
   1840	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
   1841	    MPI2_IOCSTATUS_MASK;
   1842	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
   1843		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1844			__FILE__, __LINE__, __func__);
   1845		rc = -EIO;
   1846		goto out;
   1847	}
   1848
   1849	/* copy Port/PortFlags/PhyFlags from page 0 */
   1850	for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
   1851		sas_iounit_pg1->PhyData[i].Port =
   1852		    sas_iounit_pg0->PhyData[i].Port;
   1853		sas_iounit_pg1->PhyData[i].PortFlags =
   1854		    (sas_iounit_pg0->PhyData[i].PortFlags &
   1855		    MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG);
   1856		sas_iounit_pg1->PhyData[i].PhyFlags =
   1857		    (sas_iounit_pg0->PhyData[i].PhyFlags &
   1858		    (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED +
   1859		    MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED));
   1860	}
   1861
   1862	if (enable)
   1863		sas_iounit_pg1->PhyData[phy->number].PhyFlags
   1864		    &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
   1865	else
   1866		sas_iounit_pg1->PhyData[phy->number].PhyFlags
   1867		    |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
   1868
   1869	mpt3sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
   1870
   1871	/* link reset */
   1872	if (enable)
   1873		_transport_phy_reset(phy, 0);
   1874
   1875 out:
   1876	kfree(sas_iounit_pg1);
   1877	kfree(sas_iounit_pg0);
   1878	return rc;
   1879}
   1880
   1881/**
   1882 * _transport_phy_speed - set phy min/max link rates
   1883 * @phy: The sas phy object
   1884 * @rates: rates defined in sas_phy_linkrates
   1885 *
   1886 * Only support sas_host direct attached phys.
   1887 *
   1888 * Return: 0 for success, non-zero for failure.
   1889 */
   1890static int
   1891_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
   1892{
   1893	struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
   1894	Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
   1895	Mpi2SasPhyPage0_t phy_pg0;
   1896	Mpi2ConfigReply_t mpi_reply;
   1897	u16 ioc_status;
   1898	u16 sz;
   1899	int i;
   1900	int rc = 0;
   1901	unsigned long flags;
   1902	struct hba_port *port = phy->hostdata;
   1903	int port_id = port->port_id;
   1904
   1905	spin_lock_irqsave(&ioc->sas_node_lock, flags);
   1906	if (_transport_sas_node_find_by_sas_address(ioc,
   1907	    phy->identify.sas_address,
   1908	    mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) {
   1909		spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
   1910		return -EINVAL;
   1911	}
   1912	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
   1913
   1914	if (!rates->minimum_linkrate)
   1915		rates->minimum_linkrate = phy->minimum_linkrate;
   1916	else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
   1917		rates->minimum_linkrate = phy->minimum_linkrate_hw;
   1918
   1919	if (!rates->maximum_linkrate)
   1920		rates->maximum_linkrate = phy->maximum_linkrate;
   1921	else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
   1922		rates->maximum_linkrate = phy->maximum_linkrate_hw;
   1923
   1924	/* handle expander phys */
   1925	if (phy->identify.sas_address != ioc->sas_hba.sas_address) {
   1926		phy->minimum_linkrate = rates->minimum_linkrate;
   1927		phy->maximum_linkrate = rates->maximum_linkrate;
   1928		return _transport_expander_phy_control(ioc, phy,
   1929		    SMP_PHY_CONTROL_LINK_RESET);
   1930	}
   1931
   1932	/* handle hba phys */
   1933
   1934	/* sas_iounit page 1 */
   1935	sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
   1936	    sizeof(Mpi2SasIOUnit1PhyData_t));
   1937	sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
   1938	if (!sas_iounit_pg1) {
   1939		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1940			__FILE__, __LINE__, __func__);
   1941		rc = -ENOMEM;
   1942		goto out;
   1943	}
   1944	if ((mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
   1945	    sas_iounit_pg1, sz))) {
   1946		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1947			__FILE__, __LINE__, __func__);
   1948		rc = -ENXIO;
   1949		goto out;
   1950	}
   1951	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
   1952	    MPI2_IOCSTATUS_MASK;
   1953	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
   1954		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1955			__FILE__, __LINE__, __func__);
   1956		rc = -EIO;
   1957		goto out;
   1958	}
   1959
   1960	for (i = 0; i < ioc->sas_hba.num_phys; i++) {
   1961		if (phy->number != i) {
   1962			sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
   1963			    (ioc->sas_hba.phy[i].phy->minimum_linkrate +
   1964			    (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
   1965		} else {
   1966			sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
   1967			    (rates->minimum_linkrate +
   1968			    (rates->maximum_linkrate << 4));
   1969		}
   1970	}
   1971
   1972	if (mpt3sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
   1973	    sz)) {
   1974		ioc_err(ioc, "failure at %s:%d/%s()!\n",
   1975			__FILE__, __LINE__, __func__);
   1976		rc = -ENXIO;
   1977		goto out;
   1978	}
   1979
   1980	/* link reset */
   1981	_transport_phy_reset(phy, 0);
   1982
   1983	/* read phy page 0, then update the rates in the sas transport phy */
   1984	if (!mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
   1985	    phy->number)) {
   1986		phy->minimum_linkrate = _transport_convert_phy_link_rate(
   1987		    phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
   1988		phy->maximum_linkrate = _transport_convert_phy_link_rate(
   1989		    phy_pg0.ProgrammedLinkRate >> 4);
   1990		phy->negotiated_linkrate = _transport_convert_phy_link_rate(
   1991		    phy_pg0.NegotiatedLinkRate &
   1992		    MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
   1993	}
   1994
   1995 out:
   1996	kfree(sas_iounit_pg1);
   1997	return rc;
   1998}
   1999
   2000static int
   2001_transport_map_smp_buffer(struct device *dev, struct bsg_buffer *buf,
   2002		dma_addr_t *dma_addr, size_t *dma_len, void **p)
   2003{
   2004	/* Check if the request is split across multiple segments */
   2005	if (buf->sg_cnt > 1) {
   2006		*p = dma_alloc_coherent(dev, buf->payload_len, dma_addr,
   2007				GFP_KERNEL);
   2008		if (!*p)
   2009			return -ENOMEM;
   2010		*dma_len = buf->payload_len;
   2011	} else {
   2012		if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL))
   2013			return -ENOMEM;
   2014		*dma_addr = sg_dma_address(buf->sg_list);
   2015		*dma_len = sg_dma_len(buf->sg_list);
   2016		*p = NULL;
   2017	}
   2018
   2019	return 0;
   2020}
   2021
   2022static void
   2023_transport_unmap_smp_buffer(struct device *dev, struct bsg_buffer *buf,
   2024		dma_addr_t dma_addr, void *p)
   2025{
   2026	if (p)
   2027		dma_free_coherent(dev, buf->payload_len, p, dma_addr);
   2028	else
   2029		dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL);
   2030}
   2031
   2032/**
   2033 * _transport_smp_handler - transport portal for smp passthru
   2034 * @job: ?
   2035 * @shost: shost object
   2036 * @rphy: sas transport rphy object
   2037 *
   2038 * This used primarily for smp_utils.
   2039 * Example:
   2040 *           smp_rep_general /sys/class/bsg/expander-5:0
   2041 */
   2042static void
   2043_transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
   2044		struct sas_rphy *rphy)
   2045{
   2046	struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
   2047	Mpi2SmpPassthroughRequest_t *mpi_request;
   2048	Mpi2SmpPassthroughReply_t *mpi_reply;
   2049	int rc;
   2050	u16 smid;
   2051	void *psge;
   2052	dma_addr_t dma_addr_in;
   2053	dma_addr_t dma_addr_out;
   2054	void *addr_in = NULL;
   2055	void *addr_out = NULL;
   2056	size_t dma_len_in;
   2057	size_t dma_len_out;
   2058	unsigned int reslen = 0;
   2059
   2060	if (ioc->shost_recovery || ioc->pci_error_recovery) {
   2061		ioc_info(ioc, "%s: host reset in progress!\n", __func__);
   2062		rc = -EFAULT;
   2063		goto job_done;
   2064	}
   2065
   2066	rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
   2067	if (rc)
   2068		goto job_done;
   2069
   2070	if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
   2071		ioc_err(ioc, "%s: transport_cmds in use\n",
   2072			__func__);
   2073		rc = -EAGAIN;
   2074		goto out;
   2075	}
   2076	ioc->transport_cmds.status = MPT3_CMD_PENDING;
   2077
   2078	rc = _transport_map_smp_buffer(&ioc->pdev->dev, &job->request_payload,
   2079			&dma_addr_out, &dma_len_out, &addr_out);
   2080	if (rc)
   2081		goto out;
   2082	if (addr_out) {
   2083		sg_copy_to_buffer(job->request_payload.sg_list,
   2084				job->request_payload.sg_cnt, addr_out,
   2085				job->request_payload.payload_len);
   2086	}
   2087
   2088	rc = _transport_map_smp_buffer(&ioc->pdev->dev, &job->reply_payload,
   2089			&dma_addr_in, &dma_len_in, &addr_in);
   2090	if (rc)
   2091		goto unmap_out;
   2092
   2093	rc = mpt3sas_wait_for_ioc(ioc, IOC_OPERATIONAL_WAIT_COUNT);
   2094	if (rc)
   2095		goto unmap_in;
   2096
   2097	smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
   2098	if (!smid) {
   2099		ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
   2100		rc = -EAGAIN;
   2101		goto unmap_in;
   2102	}
   2103
   2104	rc = 0;
   2105	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
   2106	ioc->transport_cmds.smid = smid;
   2107
   2108	memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
   2109	mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
   2110	mpi_request->PhysicalPort = _transport_get_port_id_by_rphy(ioc, rphy);
   2111	mpi_request->SASAddress = (rphy) ?
   2112	    cpu_to_le64(rphy->identify.sas_address) :
   2113	    cpu_to_le64(ioc->sas_hba.sas_address);
   2114	mpi_request->RequestDataLength = cpu_to_le16(dma_len_out - 4);
   2115	psge = &mpi_request->SGL;
   2116
   2117	ioc->build_sg(ioc, psge, dma_addr_out, dma_len_out - 4, dma_addr_in,
   2118			dma_len_in - 4);
   2119
   2120	dtransportprintk(ioc,
   2121			 ioc_info(ioc, "%s: sending smp request\n", __func__));
   2122
   2123	init_completion(&ioc->transport_cmds.done);
   2124	ioc->put_smid_default(ioc, smid);
   2125	wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
   2126
   2127	if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
   2128		ioc_err(ioc, "%s: timeout\n", __func__);
   2129		_debug_dump_mf(mpi_request,
   2130		    sizeof(Mpi2SmpPassthroughRequest_t)/4);
   2131		if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) {
   2132			mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
   2133			rc = -ETIMEDOUT;
   2134			goto unmap_in;
   2135		}
   2136	}
   2137
   2138	dtransportprintk(ioc, ioc_info(ioc, "%s - complete\n", __func__));
   2139
   2140	if (!(ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID)) {
   2141		dtransportprintk(ioc,
   2142				 ioc_info(ioc, "%s: no reply\n", __func__));
   2143		rc = -ENXIO;
   2144		goto unmap_in;
   2145	}
   2146
   2147	mpi_reply = ioc->transport_cmds.reply;
   2148
   2149	dtransportprintk(ioc,
   2150			 ioc_info(ioc, "%s: reply data transfer size(%d)\n",
   2151				  __func__,
   2152				  le16_to_cpu(mpi_reply->ResponseDataLength)));
   2153
   2154	memcpy(job->reply, mpi_reply, sizeof(*mpi_reply));
   2155	job->reply_len = sizeof(*mpi_reply);
   2156	reslen = le16_to_cpu(mpi_reply->ResponseDataLength);
   2157
   2158	if (addr_in) {
   2159		sg_copy_to_buffer(job->reply_payload.sg_list,
   2160				job->reply_payload.sg_cnt, addr_in,
   2161				job->reply_payload.payload_len);
   2162	}
   2163
   2164	rc = 0;
   2165 unmap_in:
   2166	_transport_unmap_smp_buffer(&ioc->pdev->dev, &job->reply_payload,
   2167			dma_addr_in, addr_in);
   2168 unmap_out:
   2169	_transport_unmap_smp_buffer(&ioc->pdev->dev, &job->request_payload,
   2170			dma_addr_out, addr_out);
   2171 out:
   2172	ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
   2173	mutex_unlock(&ioc->transport_cmds.mutex);
   2174job_done:
   2175	bsg_job_done(job, rc, reslen);
   2176}
   2177
   2178struct sas_function_template mpt3sas_transport_functions = {
   2179	.get_linkerrors		= _transport_get_linkerrors,
   2180	.get_enclosure_identifier = _transport_get_enclosure_identifier,
   2181	.get_bay_identifier	= _transport_get_bay_identifier,
   2182	.phy_reset		= _transport_phy_reset,
   2183	.phy_enable		= _transport_phy_enable,
   2184	.set_phy_speed		= _transport_phy_speed,
   2185	.smp_handler		= _transport_smp_handler,
   2186};
   2187
   2188struct scsi_transport_template *mpt3sas_transport_template;