[go: nahoru, domu]

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