xref: /linux/drivers/scsi/mpt3sas/mpt3sas_transport.c (revision 3932b9ca55b0be314a36d3e84faff3e823c081f5)
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-2013  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  */
71 static 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  */
88 static 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  */
138 static 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  */
231 u8
232 mpt3sas_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 */
254 struct 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 */
262 struct 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  */
291 static 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  */
468 static 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  */
497 static 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  */
521 static 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  */
546 static 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  */
581 static 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  */
616 static 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  */
642 struct _sas_port *
643 mpt3sas_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  */
777 void
778 mpt3sas_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  */
842 int
843 mpt3sas_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  */
910 int
911 mpt3sas_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  */
980 void
981 mpt3sas_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 
1027 static inline void *
1028 phy_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 
1034 static inline void *
1035 rphy_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 */
1042 struct 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 */
1053 struct 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  */
1076 static 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  */
1251 static 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  */
1302 static 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  */
1330 static 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 */
1350 struct 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 */
1367 struct 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  */
1386 static 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  */
1573 static 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  */
1625 static 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  */
1763 static 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  */
1880 static 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 
2122 struct 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 
2132 struct scsi_transport_template *mpt3sas_transport_template;
2133