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