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