2 * SAS Transport Layer for MPT (Message Passing Technology) based controllers
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)
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.
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.
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.
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
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,
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>
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>
61 #include "mpt3sas_base.h"
64 * _transport_get_port_id_by_sas_phy - get zone's port id that Phy belong to
65 * @phy: sas_phy object
70 _transport_get_port_id_by_sas_phy(struct sas_phy
*phy
)
73 struct hba_port
*port
= phy
->hostdata
;
76 port_id
= port
->port_id
;
82 * _transport_sas_node_find_by_sas_address - sas node search
83 * @ioc: per adapter object
84 * @sas_address: sas address of expander or sas host
85 * @port: hba port entry
86 * Context: Calling function should acquire ioc->sas_node_lock.
88 * Search for either hba phys or expander device based on handle, then returns
89 * the sas_node object.
91 static struct _sas_node
*
92 _transport_sas_node_find_by_sas_address(struct MPT3SAS_ADAPTER
*ioc
,
93 u64 sas_address
, struct hba_port
*port
)
95 if (ioc
->sas_hba
.sas_address
== sas_address
)
98 return mpt3sas_scsih_expander_find_by_sas_address(ioc
,
103 * _transport_get_port_id_by_rphy - Get Port number from rphy object
104 * @ioc: per adapter object
105 * @rphy: sas_rphy object
107 * Returns Port number.
110 _transport_get_port_id_by_rphy(struct MPT3SAS_ADAPTER
*ioc
,
111 struct sas_rphy
*rphy
)
113 struct _sas_node
*sas_expander
;
114 struct _sas_device
*sas_device
;
121 if (rphy
->identify
.device_type
== SAS_EDGE_EXPANDER_DEVICE
||
122 rphy
->identify
.device_type
== SAS_FANOUT_EXPANDER_DEVICE
) {
123 spin_lock_irqsave(&ioc
->sas_node_lock
, flags
);
124 list_for_each_entry(sas_expander
,
125 &ioc
->sas_expander_list
, list
) {
126 if (sas_expander
->rphy
== rphy
) {
127 port_id
= sas_expander
->port
->port_id
;
131 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
132 } else if (rphy
->identify
.device_type
== SAS_END_DEVICE
) {
133 spin_lock_irqsave(&ioc
->sas_device_lock
, flags
);
134 sas_device
= __mpt3sas_get_sdev_by_rphy(ioc
, rphy
);
136 port_id
= sas_device
->port
->port_id
;
137 sas_device_put(sas_device
);
139 spin_unlock_irqrestore(&ioc
->sas_device_lock
, flags
);
146 * _transport_convert_phy_link_rate -
147 * @link_rate: link rate returned from mpt firmware
149 * Convert link_rate from mpi fusion into sas_transport form.
151 static enum sas_linkrate
152 _transport_convert_phy_link_rate(u8 link_rate
)
154 enum sas_linkrate rc
;
157 case MPI2_SAS_NEG_LINK_RATE_1_5
:
158 rc
= SAS_LINK_RATE_1_5_GBPS
;
160 case MPI2_SAS_NEG_LINK_RATE_3_0
:
161 rc
= SAS_LINK_RATE_3_0_GBPS
;
163 case MPI2_SAS_NEG_LINK_RATE_6_0
:
164 rc
= SAS_LINK_RATE_6_0_GBPS
;
166 case MPI25_SAS_NEG_LINK_RATE_12_0
:
167 rc
= SAS_LINK_RATE_12_0_GBPS
;
169 case MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED
:
170 rc
= SAS_PHY_DISABLED
;
172 case MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED
:
173 rc
= SAS_LINK_RATE_FAILED
;
175 case MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR
:
176 rc
= SAS_SATA_PORT_SELECTOR
;
178 case MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS
:
179 rc
= SAS_PHY_RESET_IN_PROGRESS
;
183 case MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE
:
184 case MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE
:
185 rc
= SAS_LINK_RATE_UNKNOWN
;
192 * _transport_set_identify - set identify for phys and end devices
193 * @ioc: per adapter object
194 * @handle: device handle
195 * @identify: sas identify info
197 * Populates sas identify info.
199 * Return: 0 for success, non-zero for failure.
202 _transport_set_identify(struct MPT3SAS_ADAPTER
*ioc
, u16 handle
,
203 struct sas_identify
*identify
)
205 Mpi2SasDevicePage0_t sas_device_pg0
;
206 Mpi2ConfigReply_t mpi_reply
;
210 if (ioc
->shost_recovery
|| ioc
->pci_error_recovery
) {
211 ioc_info(ioc
, "%s: host reset in progress!\n", __func__
);
215 if ((mpt3sas_config_get_sas_device_pg0(ioc
, &mpi_reply
, &sas_device_pg0
,
216 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE
, handle
))) {
217 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
218 __FILE__
, __LINE__
, __func__
);
222 ioc_status
= le16_to_cpu(mpi_reply
.IOCStatus
) &
224 if (ioc_status
!= MPI2_IOCSTATUS_SUCCESS
) {
225 ioc_err(ioc
, "handle(0x%04x), ioc_status(0x%04x) failure at %s:%d/%s()!\n",
226 handle
, ioc_status
, __FILE__
, __LINE__
, __func__
);
230 memset(identify
, 0, sizeof(struct sas_identify
));
231 device_info
= le32_to_cpu(sas_device_pg0
.DeviceInfo
);
234 identify
->sas_address
= le64_to_cpu(sas_device_pg0
.SASAddress
);
236 /* phy number of the parent device this device is linked to */
237 identify
->phy_identifier
= sas_device_pg0
.PhyNum
;
240 switch (device_info
& MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE
) {
241 case MPI2_SAS_DEVICE_INFO_NO_DEVICE
:
242 identify
->device_type
= SAS_PHY_UNUSED
;
244 case MPI2_SAS_DEVICE_INFO_END_DEVICE
:
245 identify
->device_type
= SAS_END_DEVICE
;
247 case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER
:
248 identify
->device_type
= SAS_EDGE_EXPANDER_DEVICE
;
250 case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER
:
251 identify
->device_type
= SAS_FANOUT_EXPANDER_DEVICE
;
255 /* initiator_port_protocols */
256 if (device_info
& MPI2_SAS_DEVICE_INFO_SSP_INITIATOR
)
257 identify
->initiator_port_protocols
|= SAS_PROTOCOL_SSP
;
258 if (device_info
& MPI2_SAS_DEVICE_INFO_STP_INITIATOR
)
259 identify
->initiator_port_protocols
|= SAS_PROTOCOL_STP
;
260 if (device_info
& MPI2_SAS_DEVICE_INFO_SMP_INITIATOR
)
261 identify
->initiator_port_protocols
|= SAS_PROTOCOL_SMP
;
262 if (device_info
& MPI2_SAS_DEVICE_INFO_SATA_HOST
)
263 identify
->initiator_port_protocols
|= SAS_PROTOCOL_SATA
;
265 /* target_port_protocols */
266 if (device_info
& MPI2_SAS_DEVICE_INFO_SSP_TARGET
)
267 identify
->target_port_protocols
|= SAS_PROTOCOL_SSP
;
268 if (device_info
& MPI2_SAS_DEVICE_INFO_STP_TARGET
)
269 identify
->target_port_protocols
|= SAS_PROTOCOL_STP
;
270 if (device_info
& MPI2_SAS_DEVICE_INFO_SMP_TARGET
)
271 identify
->target_port_protocols
|= SAS_PROTOCOL_SMP
;
272 if (device_info
& MPI2_SAS_DEVICE_INFO_SATA_DEVICE
)
273 identify
->target_port_protocols
|= SAS_PROTOCOL_SATA
;
279 * mpt3sas_transport_done - internal transport layer callback handler.
280 * @ioc: per adapter object
281 * @smid: system request message index
282 * @msix_index: MSIX table index supplied by the OS
283 * @reply: reply message frame(lower 32bit addr)
285 * Callback handler when sending internal generated transport cmds.
286 * The callback index passed is `ioc->transport_cb_idx`
288 * Return: 1 meaning mf should be freed from _base_interrupt
289 * 0 means the mf is freed from this function.
292 mpt3sas_transport_done(struct MPT3SAS_ADAPTER
*ioc
, u16 smid
, u8 msix_index
,
295 MPI2DefaultReply_t
*mpi_reply
;
297 mpi_reply
= mpt3sas_base_get_reply_virt_addr(ioc
, reply
);
298 if (ioc
->transport_cmds
.status
== MPT3_CMD_NOT_USED
)
300 if (ioc
->transport_cmds
.smid
!= smid
)
302 ioc
->transport_cmds
.status
|= MPT3_CMD_COMPLETE
;
304 memcpy(ioc
->transport_cmds
.reply
, mpi_reply
,
305 mpi_reply
->MsgLength
*4);
306 ioc
->transport_cmds
.status
|= MPT3_CMD_REPLY_VALID
;
308 ioc
->transport_cmds
.status
&= ~MPT3_CMD_PENDING
;
309 complete(&ioc
->transport_cmds
.done
);
313 /* report manufacture request structure */
314 struct rep_manu_request
{
321 /* report manufacture reply structure */
322 struct rep_manu_reply
{
323 u8 smp_frame_type
; /* 0x41 */
324 u8 function
; /* 0x01 */
327 u16 expander_change_count
;
331 u8 vendor_id
[SAS_EXPANDER_VENDOR_ID_LEN
];
332 u8 product_id
[SAS_EXPANDER_PRODUCT_ID_LEN
];
333 u8 product_rev
[SAS_EXPANDER_PRODUCT_REV_LEN
];
334 u8 component_vendor_id
[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN
];
336 u8 component_revision_id
;
338 u8 vendor_specific
[8];
342 * _transport_expander_report_manufacture - obtain SMP report_manufacture
343 * @ioc: per adapter object
344 * @sas_address: expander sas address
345 * @edev: the sas_expander_device object
346 * @port_id: Port ID number
348 * Fills in the sas_expander_device object when SMP port is created.
350 * Return: 0 for success, non-zero for failure.
353 _transport_expander_report_manufacture(struct MPT3SAS_ADAPTER
*ioc
,
354 u64 sas_address
, struct sas_expander_device
*edev
, u8 port_id
)
356 Mpi2SmpPassthroughRequest_t
*mpi_request
;
357 Mpi2SmpPassthroughReply_t
*mpi_reply
;
358 struct rep_manu_reply
*manufacture_reply
;
359 struct rep_manu_request
*manufacture_request
;
364 void *data_out
= NULL
;
365 dma_addr_t data_out_dma
;
366 dma_addr_t data_in_dma
;
370 if (ioc
->shost_recovery
|| ioc
->pci_error_recovery
) {
371 ioc_info(ioc
, "%s: host reset in progress!\n", __func__
);
375 mutex_lock(&ioc
->transport_cmds
.mutex
);
377 if (ioc
->transport_cmds
.status
!= MPT3_CMD_NOT_USED
) {
378 ioc_err(ioc
, "%s: transport_cmds in use\n", __func__
);
382 ioc
->transport_cmds
.status
= MPT3_CMD_PENDING
;
384 rc
= mpt3sas_wait_for_ioc(ioc
, IOC_OPERATIONAL_WAIT_COUNT
);
388 smid
= mpt3sas_base_get_smid(ioc
, ioc
->transport_cb_idx
);
390 ioc_err(ioc
, "%s: failed obtaining a smid\n", __func__
);
396 mpi_request
= mpt3sas_base_get_msg_frame(ioc
, smid
);
397 ioc
->transport_cmds
.smid
= smid
;
399 data_out_sz
= sizeof(struct rep_manu_request
);
400 data_in_sz
= sizeof(struct rep_manu_reply
);
401 data_out
= dma_alloc_coherent(&ioc
->pdev
->dev
, data_out_sz
+ data_in_sz
,
402 &data_out_dma
, GFP_KERNEL
);
404 pr_err("failure at %s:%d/%s()!\n", __FILE__
,
407 mpt3sas_base_free_smid(ioc
, smid
);
411 data_in_dma
= data_out_dma
+ sizeof(struct rep_manu_request
);
413 manufacture_request
= data_out
;
414 manufacture_request
->smp_frame_type
= 0x40;
415 manufacture_request
->function
= 1;
416 manufacture_request
->reserved
= 0;
417 manufacture_request
->request_length
= 0;
419 memset(mpi_request
, 0, sizeof(Mpi2SmpPassthroughRequest_t
));
420 mpi_request
->Function
= MPI2_FUNCTION_SMP_PASSTHROUGH
;
421 mpi_request
->PhysicalPort
= port_id
;
422 mpi_request
->SASAddress
= cpu_to_le64(sas_address
);
423 mpi_request
->RequestDataLength
= cpu_to_le16(data_out_sz
);
424 psge
= &mpi_request
->SGL
;
426 ioc
->build_sg(ioc
, psge
, data_out_dma
, data_out_sz
, data_in_dma
,
429 dtransportprintk(ioc
,
430 ioc_info(ioc
, "report_manufacture - send to sas_addr(0x%016llx)\n",
432 init_completion(&ioc
->transport_cmds
.done
);
433 ioc
->put_smid_default(ioc
, smid
);
434 wait_for_completion_timeout(&ioc
->transport_cmds
.done
, 10*HZ
);
436 if (!(ioc
->transport_cmds
.status
& MPT3_CMD_COMPLETE
)) {
437 ioc_err(ioc
, "%s: timeout\n", __func__
);
438 _debug_dump_mf(mpi_request
,
439 sizeof(Mpi2SmpPassthroughRequest_t
)/4);
440 if (!(ioc
->transport_cmds
.status
& MPT3_CMD_RESET
))
442 goto issue_host_reset
;
445 dtransportprintk(ioc
, ioc_info(ioc
, "report_manufacture - complete\n"));
447 if (ioc
->transport_cmds
.status
& MPT3_CMD_REPLY_VALID
) {
450 mpi_reply
= ioc
->transport_cmds
.reply
;
452 dtransportprintk(ioc
,
453 ioc_info(ioc
, "report_manufacture - reply data transfer size(%d)\n",
454 le16_to_cpu(mpi_reply
->ResponseDataLength
)));
456 if (le16_to_cpu(mpi_reply
->ResponseDataLength
) !=
457 sizeof(struct rep_manu_reply
))
460 manufacture_reply
= data_out
+ sizeof(struct rep_manu_request
);
461 memtostr(edev
->vendor_id
, manufacture_reply
->vendor_id
);
462 memtostr(edev
->product_id
, manufacture_reply
->product_id
);
463 memtostr(edev
->product_rev
, manufacture_reply
->product_rev
);
464 edev
->level
= manufacture_reply
->sas_format
& 1;
466 memtostr(edev
->component_vendor_id
,
467 manufacture_reply
->component_vendor_id
);
468 tmp
= (u8
*)&manufacture_reply
->component_id
;
469 edev
->component_id
= tmp
[0] << 8 | tmp
[1];
470 edev
->component_revision_id
=
471 manufacture_reply
->component_revision_id
;
474 dtransportprintk(ioc
,
475 ioc_info(ioc
, "report_manufacture - no reply\n"));
479 mpt3sas_base_hard_reset_handler(ioc
, FORCE_BIG_HAMMER
);
481 ioc
->transport_cmds
.status
= MPT3_CMD_NOT_USED
;
483 dma_free_coherent(&ioc
->pdev
->dev
, data_out_sz
+ data_in_sz
,
484 data_out
, data_out_dma
);
486 mutex_unlock(&ioc
->transport_cmds
.mutex
);
492 * _transport_delete_port - helper function to removing a port
493 * @ioc: per adapter object
494 * @mpt3sas_port: mpt3sas per port object
497 _transport_delete_port(struct MPT3SAS_ADAPTER
*ioc
,
498 struct _sas_port
*mpt3sas_port
)
500 u64 sas_address
= mpt3sas_port
->remote_identify
.sas_address
;
501 struct hba_port
*port
= mpt3sas_port
->hba_port
;
502 enum sas_device_type device_type
=
503 mpt3sas_port
->remote_identify
.device_type
;
505 dev_printk(KERN_INFO
, &mpt3sas_port
->port
->dev
,
506 "remove: sas_addr(0x%016llx)\n",
507 (unsigned long long) sas_address
);
509 ioc
->logging_level
|= MPT_DEBUG_TRANSPORT
;
510 if (device_type
== SAS_END_DEVICE
)
511 mpt3sas_device_remove_by_sas_address(ioc
,
513 else if (device_type
== SAS_EDGE_EXPANDER_DEVICE
||
514 device_type
== SAS_FANOUT_EXPANDER_DEVICE
)
515 mpt3sas_expander_remove(ioc
, sas_address
, port
);
516 ioc
->logging_level
&= ~MPT_DEBUG_TRANSPORT
;
520 * _transport_delete_phy - helper function to removing single phy from port
521 * @ioc: per adapter object
522 * @mpt3sas_port: mpt3sas per port object
523 * @mpt3sas_phy: mpt3sas per phy object
526 _transport_delete_phy(struct MPT3SAS_ADAPTER
*ioc
,
527 struct _sas_port
*mpt3sas_port
, struct _sas_phy
*mpt3sas_phy
)
529 u64 sas_address
= mpt3sas_port
->remote_identify
.sas_address
;
531 dev_printk(KERN_INFO
, &mpt3sas_phy
->phy
->dev
,
532 "remove: sas_addr(0x%016llx), phy(%d)\n",
533 (unsigned long long) sas_address
, mpt3sas_phy
->phy_id
);
535 list_del(&mpt3sas_phy
->port_siblings
);
536 mpt3sas_port
->num_phys
--;
537 sas_port_delete_phy(mpt3sas_port
->port
, mpt3sas_phy
->phy
);
538 mpt3sas_phy
->phy_belongs_to_port
= 0;
542 * _transport_add_phy - helper function to adding single phy to port
543 * @ioc: per adapter object
544 * @mpt3sas_port: mpt3sas per port object
545 * @mpt3sas_phy: mpt3sas per phy object
548 _transport_add_phy(struct MPT3SAS_ADAPTER
*ioc
, struct _sas_port
*mpt3sas_port
,
549 struct _sas_phy
*mpt3sas_phy
)
551 u64 sas_address
= mpt3sas_port
->remote_identify
.sas_address
;
553 dev_printk(KERN_INFO
, &mpt3sas_phy
->phy
->dev
,
554 "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long)
555 sas_address
, mpt3sas_phy
->phy_id
);
557 list_add_tail(&mpt3sas_phy
->port_siblings
, &mpt3sas_port
->phy_list
);
558 mpt3sas_port
->num_phys
++;
559 sas_port_add_phy(mpt3sas_port
->port
, mpt3sas_phy
->phy
);
560 mpt3sas_phy
->phy_belongs_to_port
= 1;
564 * mpt3sas_transport_add_phy_to_an_existing_port - adding new phy to 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 * @sas_address: sas address of device/expander were phy needs to be added to
569 * @port: hba port entry
572 mpt3sas_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER
*ioc
,
573 struct _sas_node
*sas_node
, struct _sas_phy
*mpt3sas_phy
,
574 u64 sas_address
, struct hba_port
*port
)
576 struct _sas_port
*mpt3sas_port
;
577 struct _sas_phy
*phy_srch
;
579 if (mpt3sas_phy
->phy_belongs_to_port
== 1)
585 list_for_each_entry(mpt3sas_port
, &sas_node
->sas_port_list
,
587 if (mpt3sas_port
->remote_identify
.sas_address
!=
590 if (mpt3sas_port
->hba_port
!= port
)
592 list_for_each_entry(phy_srch
, &mpt3sas_port
->phy_list
,
594 if (phy_srch
== mpt3sas_phy
)
597 _transport_add_phy(ioc
, mpt3sas_port
, mpt3sas_phy
);
604 * mpt3sas_transport_del_phy_from_an_existing_port - delete phy from existing port
605 * @ioc: per adapter object
606 * @sas_node: sas node object (either expander or sas host)
607 * @mpt3sas_phy: mpt3sas per phy object
610 mpt3sas_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER
*ioc
,
611 struct _sas_node
*sas_node
, struct _sas_phy
*mpt3sas_phy
)
613 struct _sas_port
*mpt3sas_port
, *next
;
614 struct _sas_phy
*phy_srch
;
616 if (mpt3sas_phy
->phy_belongs_to_port
== 0)
619 list_for_each_entry_safe(mpt3sas_port
, next
, &sas_node
->sas_port_list
,
621 list_for_each_entry(phy_srch
, &mpt3sas_port
->phy_list
,
623 if (phy_srch
!= mpt3sas_phy
)
627 * Don't delete port during host reset,
630 if (mpt3sas_port
->num_phys
== 1 && !ioc
->shost_recovery
)
631 _transport_delete_port(ioc
, mpt3sas_port
);
633 _transport_delete_phy(ioc
, mpt3sas_port
,
641 * _transport_sanity_check - sanity check when adding a new port
642 * @ioc: per adapter object
643 * @sas_node: sas node object (either expander or sas host)
644 * @sas_address: sas address of device being added
645 * @port: hba port entry
647 * See the explanation above from _transport_delete_duplicate_port
650 _transport_sanity_check(struct MPT3SAS_ADAPTER
*ioc
, struct _sas_node
*sas_node
,
651 u64 sas_address
, struct hba_port
*port
)
655 for (i
= 0; i
< sas_node
->num_phys
; i
++) {
656 if (sas_node
->phy
[i
].remote_identify
.sas_address
!= sas_address
)
658 if (sas_node
->phy
[i
].port
!= port
)
660 if (sas_node
->phy
[i
].phy_belongs_to_port
== 1)
661 mpt3sas_transport_del_phy_from_an_existing_port(ioc
,
662 sas_node
, &sas_node
->phy
[i
]);
667 * mpt3sas_transport_port_add - insert port to the list
668 * @ioc: per adapter object
669 * @handle: handle of attached device
670 * @sas_address: sas address of parent expander or sas host
671 * @hba_port: hba port entry
672 * Context: This function will acquire ioc->sas_node_lock.
674 * Adding new port object to the sas_node->sas_port_list.
676 * Return: mpt3sas_port.
679 mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER
*ioc
, u16 handle
,
680 u64 sas_address
, struct hba_port
*hba_port
)
682 struct _sas_phy
*mpt3sas_phy
, *next
;
683 struct _sas_port
*mpt3sas_port
;
685 struct _sas_node
*sas_node
;
686 struct sas_rphy
*rphy
;
687 struct _sas_device
*sas_device
= NULL
;
689 struct sas_port
*port
;
690 struct virtual_phy
*vphy
= NULL
;
693 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
694 __FILE__
, __LINE__
, __func__
);
698 mpt3sas_port
= kzalloc(sizeof(struct _sas_port
),
701 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
702 __FILE__
, __LINE__
, __func__
);
706 INIT_LIST_HEAD(&mpt3sas_port
->port_list
);
707 INIT_LIST_HEAD(&mpt3sas_port
->phy_list
);
708 spin_lock_irqsave(&ioc
->sas_node_lock
, flags
);
709 sas_node
= _transport_sas_node_find_by_sas_address(ioc
,
710 sas_address
, hba_port
);
711 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
714 ioc_err(ioc
, "%s: Could not find parent sas_address(0x%016llx)!\n",
715 __func__
, (u64
)sas_address
);
719 if ((_transport_set_identify(ioc
, handle
,
720 &mpt3sas_port
->remote_identify
))) {
721 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
722 __FILE__
, __LINE__
, __func__
);
726 if (mpt3sas_port
->remote_identify
.device_type
== SAS_PHY_UNUSED
) {
727 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
728 __FILE__
, __LINE__
, __func__
);
732 mpt3sas_port
->hba_port
= hba_port
;
733 _transport_sanity_check(ioc
, sas_node
,
734 mpt3sas_port
->remote_identify
.sas_address
, hba_port
);
736 for (i
= 0; i
< sas_node
->num_phys
; i
++) {
737 if (sas_node
->phy
[i
].remote_identify
.sas_address
!=
738 mpt3sas_port
->remote_identify
.sas_address
)
740 if (sas_node
->phy
[i
].port
!= hba_port
)
742 list_add_tail(&sas_node
->phy
[i
].port_siblings
,
743 &mpt3sas_port
->phy_list
);
744 mpt3sas_port
->num_phys
++;
745 if (sas_node
->handle
<= ioc
->sas_hba
.num_phys
) {
746 if (!sas_node
->phy
[i
].hba_vphy
) {
747 hba_port
->phy_mask
|= (1 << i
);
751 vphy
= mpt3sas_get_vphy_by_phy(ioc
, hba_port
, i
);
753 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
754 __FILE__
, __LINE__
, __func__
);
760 if (!mpt3sas_port
->num_phys
) {
761 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
762 __FILE__
, __LINE__
, __func__
);
766 if (mpt3sas_port
->remote_identify
.device_type
== SAS_END_DEVICE
) {
767 sas_device
= mpt3sas_get_sdev_by_addr(ioc
,
768 mpt3sas_port
->remote_identify
.sas_address
,
769 mpt3sas_port
->hba_port
);
771 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
772 __FILE__
, __LINE__
, __func__
);
775 sas_device
->pend_sas_rphy_add
= 1;
778 if (!sas_node
->parent_dev
) {
779 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
780 __FILE__
, __LINE__
, __func__
);
783 port
= sas_port_alloc_num(sas_node
->parent_dev
);
784 if (!port
|| (sas_port_add(port
))) {
785 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
786 __FILE__
, __LINE__
, __func__
);
790 list_for_each_entry(mpt3sas_phy
, &mpt3sas_port
->phy_list
,
792 if ((ioc
->logging_level
& MPT_DEBUG_TRANSPORT
))
793 dev_printk(KERN_INFO
, &port
->dev
,
794 "add: handle(0x%04x), sas_addr(0x%016llx), phy(%d)\n",
795 handle
, (unsigned long long)
796 mpt3sas_port
->remote_identify
.sas_address
,
797 mpt3sas_phy
->phy_id
);
798 sas_port_add_phy(port
, mpt3sas_phy
->phy
);
799 mpt3sas_phy
->phy_belongs_to_port
= 1;
800 mpt3sas_phy
->port
= hba_port
;
803 mpt3sas_port
->port
= port
;
804 if (mpt3sas_port
->remote_identify
.device_type
== SAS_END_DEVICE
) {
805 rphy
= sas_end_device_alloc(port
);
806 sas_device
->rphy
= rphy
;
807 if (sas_node
->handle
<= ioc
->sas_hba
.num_phys
) {
809 hba_port
->sas_address
=
810 sas_device
->sas_address
;
813 sas_device
->sas_address
;
816 rphy
= sas_expander_alloc(port
,
817 mpt3sas_port
->remote_identify
.device_type
);
818 if (sas_node
->handle
<= ioc
->sas_hba
.num_phys
)
819 hba_port
->sas_address
=
820 mpt3sas_port
->remote_identify
.sas_address
;
824 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
825 __FILE__
, __LINE__
, __func__
);
826 goto out_delete_port
;
829 rphy
->identify
= mpt3sas_port
->remote_identify
;
831 if ((sas_rphy_add(rphy
))) {
832 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
833 __FILE__
, __LINE__
, __func__
);
836 goto out_delete_port
;
839 if (mpt3sas_port
->remote_identify
.device_type
== SAS_END_DEVICE
) {
840 sas_device
->pend_sas_rphy_add
= 0;
841 sas_device_put(sas_device
);
845 "add: handle(0x%04x), sas_addr(0x%016llx)\n", handle
,
846 (unsigned long long)mpt3sas_port
->remote_identify
.sas_address
);
848 mpt3sas_port
->rphy
= rphy
;
849 spin_lock_irqsave(&ioc
->sas_node_lock
, flags
);
850 list_add_tail(&mpt3sas_port
->port_list
, &sas_node
->sas_port_list
);
851 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
853 /* fill in report manufacture */
854 if (mpt3sas_port
->remote_identify
.device_type
==
855 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER
||
856 mpt3sas_port
->remote_identify
.device_type
==
857 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER
)
858 _transport_expander_report_manufacture(ioc
,
859 mpt3sas_port
->remote_identify
.sas_address
,
860 rphy_to_expander_device(rphy
), hba_port
->port_id
);
864 sas_port_delete(port
);
867 list_for_each_entry_safe(mpt3sas_phy
, next
, &mpt3sas_port
->phy_list
,
869 list_del(&mpt3sas_phy
->port_siblings
);
875 * mpt3sas_transport_port_remove - remove port from the list
876 * @ioc: per adapter object
877 * @sas_address: sas address of attached device
878 * @sas_address_parent: sas address of parent expander or sas host
879 * @port: hba port entry
880 * Context: This function will acquire ioc->sas_node_lock.
882 * Removing object and freeing associated memory from the
883 * ioc->sas_port_list.
886 mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER
*ioc
, u64 sas_address
,
887 u64 sas_address_parent
, struct hba_port
*port
)
891 struct _sas_port
*mpt3sas_port
, *next
;
892 struct _sas_node
*sas_node
;
894 struct _sas_phy
*mpt3sas_phy
, *next_phy
;
895 struct hba_port
*hba_port_next
, *hba_port
= NULL
;
896 struct virtual_phy
*vphy
, *vphy_next
= NULL
;
901 spin_lock_irqsave(&ioc
->sas_node_lock
, flags
);
902 sas_node
= _transport_sas_node_find_by_sas_address(ioc
,
903 sas_address_parent
, port
);
905 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
908 list_for_each_entry_safe(mpt3sas_port
, next
, &sas_node
->sas_port_list
,
910 if (mpt3sas_port
->remote_identify
.sas_address
!= sas_address
)
912 if (mpt3sas_port
->hba_port
!= port
)
915 list_del(&mpt3sas_port
->port_list
);
920 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
924 if (sas_node
->handle
<= ioc
->sas_hba
.num_phys
&&
925 (ioc
->multipath_on_hba
)) {
926 if (port
->vphys_mask
) {
927 list_for_each_entry_safe(vphy
, vphy_next
,
928 &port
->vphys_list
, list
) {
929 if (vphy
->sas_address
!= sas_address
)
932 "remove vphy entry: %p of port:%p,from %d port's vphys list\n",
933 vphy
, port
, port
->port_id
);
934 port
->vphys_mask
&= ~vphy
->phy_mask
;
935 list_del(&vphy
->list
);
940 list_for_each_entry_safe(hba_port
, hba_port_next
,
941 &ioc
->port_table_list
, list
) {
942 if (hba_port
!= port
)
945 * Delete hba_port object if
946 * - hba_port object's sas address matches with current
947 * removed device's sas address and no vphy's
948 * associated with it.
949 * - Current removed device is a vSES device and
950 * none of the other direct attached device have
951 * this vSES device's port number (hence hba_port
952 * object sas_address field will be zero).
954 if ((hba_port
->sas_address
== sas_address
||
955 !hba_port
->sas_address
) && !hba_port
->vphys_mask
) {
957 "remove hba_port entry: %p port: %d from hba_port list\n",
958 hba_port
, hba_port
->port_id
);
959 list_del(&hba_port
->list
);
961 } else if (hba_port
->sas_address
== sas_address
&&
962 hba_port
->vphys_mask
) {
964 * Current removed device is a non vSES device
965 * and a vSES device has the same port number
966 * as of current device's port number. Hence
967 * only clear the sas_address filed, don't
968 * delete the hba_port object.
971 "clearing sas_address from hba_port entry: %p port: %d from hba_port list\n",
972 hba_port
, hba_port
->port_id
);
973 port
->sas_address
= 0;
979 for (i
= 0; i
< sas_node
->num_phys
; i
++) {
980 if (sas_node
->phy
[i
].remote_identify
.sas_address
== sas_address
)
981 memset(&sas_node
->phy
[i
].remote_identify
, 0 ,
982 sizeof(struct sas_identify
));
985 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
987 list_for_each_entry_safe(mpt3sas_phy
, next_phy
,
988 &mpt3sas_port
->phy_list
, port_siblings
) {
989 if ((ioc
->logging_level
& MPT_DEBUG_TRANSPORT
))
990 dev_printk(KERN_INFO
, &mpt3sas_port
->port
->dev
,
991 "remove: sas_addr(0x%016llx), phy(%d)\n",
993 mpt3sas_port
->remote_identify
.sas_address
,
994 mpt3sas_phy
->phy_id
);
995 mpt3sas_phy
->phy_belongs_to_port
= 0;
996 if (!ioc
->remove_host
)
997 sas_port_delete_phy(mpt3sas_port
->port
,
999 list_del(&mpt3sas_phy
->port_siblings
);
1001 if (!ioc
->remove_host
)
1002 sas_port_delete(mpt3sas_port
->port
);
1003 ioc_info(ioc
, "%s: removed: sas_addr(0x%016llx)\n",
1004 __func__
, (unsigned long long)sas_address
);
1005 kfree(mpt3sas_port
);
1009 * mpt3sas_transport_add_host_phy - report sas_host phy to transport
1010 * @ioc: per adapter object
1011 * @mpt3sas_phy: mpt3sas per phy object
1012 * @phy_pg0: sas phy page 0
1013 * @parent_dev: parent device class object
1015 * Return: 0 for success, non-zero for failure.
1018 mpt3sas_transport_add_host_phy(struct MPT3SAS_ADAPTER
*ioc
, struct _sas_phy
1019 *mpt3sas_phy
, Mpi2SasPhyPage0_t phy_pg0
, struct device
*parent_dev
)
1021 struct sas_phy
*phy
;
1022 int phy_index
= mpt3sas_phy
->phy_id
;
1025 INIT_LIST_HEAD(&mpt3sas_phy
->port_siblings
);
1026 phy
= sas_phy_alloc(parent_dev
, phy_index
);
1028 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1029 __FILE__
, __LINE__
, __func__
);
1032 if ((_transport_set_identify(ioc
, mpt3sas_phy
->handle
,
1033 &mpt3sas_phy
->identify
))) {
1034 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1035 __FILE__
, __LINE__
, __func__
);
1039 phy
->identify
= mpt3sas_phy
->identify
;
1040 mpt3sas_phy
->attached_handle
= le16_to_cpu(phy_pg0
.AttachedDevHandle
);
1041 if (mpt3sas_phy
->attached_handle
)
1042 _transport_set_identify(ioc
, mpt3sas_phy
->attached_handle
,
1043 &mpt3sas_phy
->remote_identify
);
1044 phy
->identify
.phy_identifier
= mpt3sas_phy
->phy_id
;
1045 phy
->negotiated_linkrate
= _transport_convert_phy_link_rate(
1046 phy_pg0
.NegotiatedLinkRate
& MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL
);
1047 phy
->minimum_linkrate_hw
= _transport_convert_phy_link_rate(
1048 phy_pg0
.HwLinkRate
& MPI2_SAS_HWRATE_MIN_RATE_MASK
);
1049 phy
->maximum_linkrate_hw
= _transport_convert_phy_link_rate(
1050 phy_pg0
.HwLinkRate
>> 4);
1051 phy
->minimum_linkrate
= _transport_convert_phy_link_rate(
1052 phy_pg0
.ProgrammedLinkRate
& MPI2_SAS_PRATE_MIN_RATE_MASK
);
1053 phy
->maximum_linkrate
= _transport_convert_phy_link_rate(
1054 phy_pg0
.ProgrammedLinkRate
>> 4);
1055 phy
->hostdata
= mpt3sas_phy
->port
;
1057 if ((sas_phy_add(phy
))) {
1058 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1059 __FILE__
, __LINE__
, __func__
);
1063 if ((ioc
->logging_level
& MPT_DEBUG_TRANSPORT
))
1064 dev_printk(KERN_INFO
, &phy
->dev
,
1065 "add: handle(0x%04x), sas_addr(0x%016llx)\n"
1066 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
1067 mpt3sas_phy
->handle
, (unsigned long long)
1068 mpt3sas_phy
->identify
.sas_address
,
1069 mpt3sas_phy
->attached_handle
,
1070 (unsigned long long)
1071 mpt3sas_phy
->remote_identify
.sas_address
);
1072 mpt3sas_phy
->phy
= phy
;
1078 * mpt3sas_transport_add_expander_phy - report expander phy to transport
1079 * @ioc: per adapter object
1080 * @mpt3sas_phy: mpt3sas per phy object
1081 * @expander_pg1: expander page 1
1082 * @parent_dev: parent device class object
1084 * Return: 0 for success, non-zero for failure.
1087 mpt3sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER
*ioc
, struct _sas_phy
1088 *mpt3sas_phy
, Mpi2ExpanderPage1_t expander_pg1
,
1089 struct device
*parent_dev
)
1091 struct sas_phy
*phy
;
1092 int phy_index
= mpt3sas_phy
->phy_id
;
1094 INIT_LIST_HEAD(&mpt3sas_phy
->port_siblings
);
1095 phy
= sas_phy_alloc(parent_dev
, phy_index
);
1097 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1098 __FILE__
, __LINE__
, __func__
);
1101 if ((_transport_set_identify(ioc
, mpt3sas_phy
->handle
,
1102 &mpt3sas_phy
->identify
))) {
1103 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1104 __FILE__
, __LINE__
, __func__
);
1108 phy
->identify
= mpt3sas_phy
->identify
;
1109 mpt3sas_phy
->attached_handle
=
1110 le16_to_cpu(expander_pg1
.AttachedDevHandle
);
1111 if (mpt3sas_phy
->attached_handle
)
1112 _transport_set_identify(ioc
, mpt3sas_phy
->attached_handle
,
1113 &mpt3sas_phy
->remote_identify
);
1114 phy
->identify
.phy_identifier
= mpt3sas_phy
->phy_id
;
1115 phy
->negotiated_linkrate
= _transport_convert_phy_link_rate(
1116 expander_pg1
.NegotiatedLinkRate
&
1117 MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL
);
1118 phy
->minimum_linkrate_hw
= _transport_convert_phy_link_rate(
1119 expander_pg1
.HwLinkRate
& MPI2_SAS_HWRATE_MIN_RATE_MASK
);
1120 phy
->maximum_linkrate_hw
= _transport_convert_phy_link_rate(
1121 expander_pg1
.HwLinkRate
>> 4);
1122 phy
->minimum_linkrate
= _transport_convert_phy_link_rate(
1123 expander_pg1
.ProgrammedLinkRate
& MPI2_SAS_PRATE_MIN_RATE_MASK
);
1124 phy
->maximum_linkrate
= _transport_convert_phy_link_rate(
1125 expander_pg1
.ProgrammedLinkRate
>> 4);
1126 phy
->hostdata
= mpt3sas_phy
->port
;
1128 if ((sas_phy_add(phy
))) {
1129 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1130 __FILE__
, __LINE__
, __func__
);
1134 if ((ioc
->logging_level
& MPT_DEBUG_TRANSPORT
))
1135 dev_printk(KERN_INFO
, &phy
->dev
,
1136 "add: handle(0x%04x), sas_addr(0x%016llx)\n"
1137 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
1138 mpt3sas_phy
->handle
, (unsigned long long)
1139 mpt3sas_phy
->identify
.sas_address
,
1140 mpt3sas_phy
->attached_handle
,
1141 (unsigned long long)
1142 mpt3sas_phy
->remote_identify
.sas_address
);
1143 mpt3sas_phy
->phy
= phy
;
1148 * mpt3sas_transport_update_links - refreshing phy link changes
1149 * @ioc: per adapter object
1150 * @sas_address: sas address of parent expander or sas host
1151 * @handle: attached device handle
1152 * @phy_number: phy number
1153 * @link_rate: new link rate
1154 * @port: hba port entry
1159 mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER
*ioc
,
1160 u64 sas_address
, u16 handle
, u8 phy_number
, u8 link_rate
,
1161 struct hba_port
*port
)
1163 unsigned long flags
;
1164 struct _sas_node
*sas_node
;
1165 struct _sas_phy
*mpt3sas_phy
;
1166 struct hba_port
*hba_port
= NULL
;
1168 if (ioc
->shost_recovery
|| ioc
->pci_error_recovery
)
1171 spin_lock_irqsave(&ioc
->sas_node_lock
, flags
);
1172 sas_node
= _transport_sas_node_find_by_sas_address(ioc
,
1175 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
1179 mpt3sas_phy
= &sas_node
->phy
[phy_number
];
1180 mpt3sas_phy
->attached_handle
= handle
;
1181 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
1182 if (handle
&& (link_rate
>= MPI2_SAS_NEG_LINK_RATE_1_5
)) {
1183 _transport_set_identify(ioc
, handle
,
1184 &mpt3sas_phy
->remote_identify
);
1185 if ((sas_node
->handle
<= ioc
->sas_hba
.num_phys
) &&
1186 (ioc
->multipath_on_hba
)) {
1187 list_for_each_entry(hba_port
,
1188 &ioc
->port_table_list
, list
) {
1189 if (hba_port
->sas_address
== sas_address
&&
1191 hba_port
->phy_mask
|=
1192 (1 << mpt3sas_phy
->phy_id
);
1195 mpt3sas_transport_add_phy_to_an_existing_port(ioc
, sas_node
,
1196 mpt3sas_phy
, mpt3sas_phy
->remote_identify
.sas_address
,
1199 memset(&mpt3sas_phy
->remote_identify
, 0 , sizeof(struct
1202 if (mpt3sas_phy
->phy
)
1203 mpt3sas_phy
->phy
->negotiated_linkrate
=
1204 _transport_convert_phy_link_rate(link_rate
);
1206 if ((ioc
->logging_level
& MPT_DEBUG_TRANSPORT
))
1207 dev_printk(KERN_INFO
, &mpt3sas_phy
->phy
->dev
,
1208 "refresh: parent sas_addr(0x%016llx),\n"
1209 "\tlink_rate(0x%02x), phy(%d)\n"
1210 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
1211 (unsigned long long)sas_address
,
1212 link_rate
, phy_number
, handle
, (unsigned long long)
1213 mpt3sas_phy
->remote_identify
.sas_address
);
1216 static inline void *
1217 phy_to_ioc(struct sas_phy
*phy
)
1219 struct Scsi_Host
*shost
= dev_to_shost(phy
->dev
.parent
);
1220 return shost_priv(shost
);
1223 static inline void *
1224 rphy_to_ioc(struct sas_rphy
*rphy
)
1226 struct Scsi_Host
*shost
= dev_to_shost(rphy
->dev
.parent
->parent
);
1227 return shost_priv(shost
);
1230 /* report phy error log structure */
1231 struct phy_error_log_request
{
1232 u8 smp_frame_type
; /* 0x40 */
1233 u8 function
; /* 0x11 */
1234 u8 allocated_response_length
;
1235 u8 request_length
; /* 02 */
1241 /* report phy error log reply structure */
1242 struct phy_error_log_reply
{
1243 u8 smp_frame_type
; /* 0x41 */
1244 u8 function
; /* 0x11 */
1247 __be16 expander_change_count
;
1251 __be32 invalid_dword
;
1252 __be32 running_disparity_error
;
1253 __be32 loss_of_dword_sync
;
1254 __be32 phy_reset_problem
;
1258 * _transport_get_expander_phy_error_log - return expander counters
1259 * @ioc: per adapter object
1260 * @phy: The sas phy object
1262 * Return: 0 for success, non-zero for failure.
1266 _transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER
*ioc
,
1267 struct sas_phy
*phy
)
1269 Mpi2SmpPassthroughRequest_t
*mpi_request
;
1270 Mpi2SmpPassthroughReply_t
*mpi_reply
;
1271 struct phy_error_log_request
*phy_error_log_request
;
1272 struct phy_error_log_reply
*phy_error_log_reply
;
1277 void *data_out
= NULL
;
1278 dma_addr_t data_out_dma
;
1281 if (ioc
->shost_recovery
|| ioc
->pci_error_recovery
) {
1282 ioc_info(ioc
, "%s: host reset in progress!\n", __func__
);
1286 mutex_lock(&ioc
->transport_cmds
.mutex
);
1288 if (ioc
->transport_cmds
.status
!= MPT3_CMD_NOT_USED
) {
1289 ioc_err(ioc
, "%s: transport_cmds in use\n", __func__
);
1293 ioc
->transport_cmds
.status
= MPT3_CMD_PENDING
;
1295 rc
= mpt3sas_wait_for_ioc(ioc
, IOC_OPERATIONAL_WAIT_COUNT
);
1299 smid
= mpt3sas_base_get_smid(ioc
, ioc
->transport_cb_idx
);
1301 ioc_err(ioc
, "%s: failed obtaining a smid\n", __func__
);
1306 mpi_request
= mpt3sas_base_get_msg_frame(ioc
, smid
);
1307 ioc
->transport_cmds
.smid
= smid
;
1309 sz
= sizeof(struct phy_error_log_request
) +
1310 sizeof(struct phy_error_log_reply
);
1311 data_out
= dma_alloc_coherent(&ioc
->pdev
->dev
, sz
, &data_out_dma
,
1314 pr_err("failure at %s:%d/%s()!\n", __FILE__
,
1315 __LINE__
, __func__
);
1317 mpt3sas_base_free_smid(ioc
, smid
);
1322 memset(data_out
, 0, sz
);
1323 phy_error_log_request
= data_out
;
1324 phy_error_log_request
->smp_frame_type
= 0x40;
1325 phy_error_log_request
->function
= 0x11;
1326 phy_error_log_request
->request_length
= 2;
1327 phy_error_log_request
->allocated_response_length
= 0;
1328 phy_error_log_request
->phy_identifier
= phy
->number
;
1330 memset(mpi_request
, 0, sizeof(Mpi2SmpPassthroughRequest_t
));
1331 mpi_request
->Function
= MPI2_FUNCTION_SMP_PASSTHROUGH
;
1332 mpi_request
->PhysicalPort
= _transport_get_port_id_by_sas_phy(phy
);
1333 mpi_request
->VF_ID
= 0; /* TODO */
1334 mpi_request
->VP_ID
= 0;
1335 mpi_request
->SASAddress
= cpu_to_le64(phy
->identify
.sas_address
);
1336 mpi_request
->RequestDataLength
=
1337 cpu_to_le16(sizeof(struct phy_error_log_request
));
1338 psge
= &mpi_request
->SGL
;
1340 ioc
->build_sg(ioc
, psge
, data_out_dma
,
1341 sizeof(struct phy_error_log_request
),
1342 data_out_dma
+ sizeof(struct phy_error_log_request
),
1343 sizeof(struct phy_error_log_reply
));
1345 dtransportprintk(ioc
,
1346 ioc_info(ioc
, "phy_error_log - send to sas_addr(0x%016llx), phy(%d)\n",
1347 (u64
)phy
->identify
.sas_address
,
1349 init_completion(&ioc
->transport_cmds
.done
);
1350 ioc
->put_smid_default(ioc
, smid
);
1351 wait_for_completion_timeout(&ioc
->transport_cmds
.done
, 10*HZ
);
1353 if (!(ioc
->transport_cmds
.status
& MPT3_CMD_COMPLETE
)) {
1354 ioc_err(ioc
, "%s: timeout\n", __func__
);
1355 _debug_dump_mf(mpi_request
,
1356 sizeof(Mpi2SmpPassthroughRequest_t
)/4);
1357 if (!(ioc
->transport_cmds
.status
& MPT3_CMD_RESET
))
1359 goto issue_host_reset
;
1362 dtransportprintk(ioc
, ioc_info(ioc
, "phy_error_log - complete\n"));
1364 if (ioc
->transport_cmds
.status
& MPT3_CMD_REPLY_VALID
) {
1366 mpi_reply
= ioc
->transport_cmds
.reply
;
1368 dtransportprintk(ioc
,
1369 ioc_info(ioc
, "phy_error_log - reply data transfer size(%d)\n",
1370 le16_to_cpu(mpi_reply
->ResponseDataLength
)));
1372 if (le16_to_cpu(mpi_reply
->ResponseDataLength
) !=
1373 sizeof(struct phy_error_log_reply
))
1376 phy_error_log_reply
= data_out
+
1377 sizeof(struct phy_error_log_request
);
1379 dtransportprintk(ioc
,
1380 ioc_info(ioc
, "phy_error_log - function_result(%d)\n",
1381 phy_error_log_reply
->function_result
));
1383 phy
->invalid_dword_count
=
1384 be32_to_cpu(phy_error_log_reply
->invalid_dword
);
1385 phy
->running_disparity_error_count
=
1386 be32_to_cpu(phy_error_log_reply
->running_disparity_error
);
1387 phy
->loss_of_dword_sync_count
=
1388 be32_to_cpu(phy_error_log_reply
->loss_of_dword_sync
);
1389 phy
->phy_reset_problem_count
=
1390 be32_to_cpu(phy_error_log_reply
->phy_reset_problem
);
1393 dtransportprintk(ioc
,
1394 ioc_info(ioc
, "phy_error_log - no reply\n"));
1398 mpt3sas_base_hard_reset_handler(ioc
, FORCE_BIG_HAMMER
);
1400 ioc
->transport_cmds
.status
= MPT3_CMD_NOT_USED
;
1402 dma_free_coherent(&ioc
->pdev
->dev
, sz
, data_out
, data_out_dma
);
1404 mutex_unlock(&ioc
->transport_cmds
.mutex
);
1409 * _transport_get_linkerrors - return phy counters for both hba and expanders
1410 * @phy: The sas phy object
1412 * Return: 0 for success, non-zero for failure.
1416 _transport_get_linkerrors(struct sas_phy
*phy
)
1418 struct MPT3SAS_ADAPTER
*ioc
= phy_to_ioc(phy
);
1419 unsigned long flags
;
1420 Mpi2ConfigReply_t mpi_reply
;
1421 Mpi2SasPhyPage1_t phy_pg1
;
1422 struct hba_port
*port
= phy
->hostdata
;
1423 int port_id
= port
->port_id
;
1425 spin_lock_irqsave(&ioc
->sas_node_lock
, flags
);
1426 if (_transport_sas_node_find_by_sas_address(ioc
,
1427 phy
->identify
.sas_address
,
1428 mpt3sas_get_port_by_id(ioc
, port_id
, 0)) == NULL
) {
1429 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
1432 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
1434 if (phy
->identify
.sas_address
!= ioc
->sas_hba
.sas_address
)
1435 return _transport_get_expander_phy_error_log(ioc
, phy
);
1437 /* get hba phy error logs */
1438 if ((mpt3sas_config_get_phy_pg1(ioc
, &mpi_reply
, &phy_pg1
,
1440 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1441 __FILE__
, __LINE__
, __func__
);
1445 if (mpi_reply
.IOCStatus
|| mpi_reply
.IOCLogInfo
)
1446 ioc_info(ioc
, "phy(%d), ioc_status (0x%04x), loginfo(0x%08x)\n",
1448 le16_to_cpu(mpi_reply
.IOCStatus
),
1449 le32_to_cpu(mpi_reply
.IOCLogInfo
));
1451 phy
->invalid_dword_count
= le32_to_cpu(phy_pg1
.InvalidDwordCount
);
1452 phy
->running_disparity_error_count
=
1453 le32_to_cpu(phy_pg1
.RunningDisparityErrorCount
);
1454 phy
->loss_of_dword_sync_count
=
1455 le32_to_cpu(phy_pg1
.LossDwordSynchCount
);
1456 phy
->phy_reset_problem_count
=
1457 le32_to_cpu(phy_pg1
.PhyResetProblemCount
);
1462 * _transport_get_enclosure_identifier -
1463 * @rphy: The sas phy object
1466 * Obtain the enclosure logical id for an expander.
1467 * Return: 0 for success, non-zero for failure.
1470 _transport_get_enclosure_identifier(struct sas_rphy
*rphy
, u64
*identifier
)
1472 struct MPT3SAS_ADAPTER
*ioc
= rphy_to_ioc(rphy
);
1473 struct _sas_device
*sas_device
;
1474 unsigned long flags
;
1477 spin_lock_irqsave(&ioc
->sas_device_lock
, flags
);
1478 sas_device
= __mpt3sas_get_sdev_by_rphy(ioc
, rphy
);
1480 *identifier
= sas_device
->enclosure_logical_id
;
1482 sas_device_put(sas_device
);
1488 spin_unlock_irqrestore(&ioc
->sas_device_lock
, flags
);
1493 * _transport_get_bay_identifier -
1494 * @rphy: The sas phy object
1496 * Return: the slot id for a device that resides inside an enclosure.
1499 _transport_get_bay_identifier(struct sas_rphy
*rphy
)
1501 struct MPT3SAS_ADAPTER
*ioc
= rphy_to_ioc(rphy
);
1502 struct _sas_device
*sas_device
;
1503 unsigned long flags
;
1506 spin_lock_irqsave(&ioc
->sas_device_lock
, flags
);
1507 sas_device
= __mpt3sas_get_sdev_by_rphy(ioc
, rphy
);
1509 rc
= sas_device
->slot
;
1510 sas_device_put(sas_device
);
1514 spin_unlock_irqrestore(&ioc
->sas_device_lock
, flags
);
1518 /* phy control request structure */
1519 struct phy_control_request
{
1520 u8 smp_frame_type
; /* 0x40 */
1521 u8 function
; /* 0x91 */
1522 u8 allocated_response_length
;
1523 u8 request_length
; /* 0x09 */
1524 u16 expander_change_count
;
1529 u64 attached_device_name
;
1530 u8 programmed_min_physical_link_rate
;
1531 u8 programmed_max_physical_link_rate
;
1535 /* phy control reply structure */
1536 struct phy_control_reply
{
1537 u8 smp_frame_type
; /* 0x41 */
1538 u8 function
; /* 0x11 */
1543 #define SMP_PHY_CONTROL_LINK_RESET (0x01)
1544 #define SMP_PHY_CONTROL_HARD_RESET (0x02)
1545 #define SMP_PHY_CONTROL_DISABLE (0x03)
1548 * _transport_expander_phy_control - expander phy control
1549 * @ioc: per adapter object
1550 * @phy: The sas phy object
1553 * Return: 0 for success, non-zero for failure.
1557 _transport_expander_phy_control(struct MPT3SAS_ADAPTER
*ioc
,
1558 struct sas_phy
*phy
, u8 phy_operation
)
1560 Mpi2SmpPassthroughRequest_t
*mpi_request
;
1561 Mpi2SmpPassthroughReply_t
*mpi_reply
;
1562 struct phy_control_request
*phy_control_request
;
1563 struct phy_control_reply
*phy_control_reply
;
1568 void *data_out
= NULL
;
1569 dma_addr_t data_out_dma
;
1572 if (ioc
->shost_recovery
|| ioc
->pci_error_recovery
) {
1573 ioc_info(ioc
, "%s: host reset in progress!\n", __func__
);
1577 mutex_lock(&ioc
->transport_cmds
.mutex
);
1579 if (ioc
->transport_cmds
.status
!= MPT3_CMD_NOT_USED
) {
1580 ioc_err(ioc
, "%s: transport_cmds in use\n", __func__
);
1584 ioc
->transport_cmds
.status
= MPT3_CMD_PENDING
;
1586 rc
= mpt3sas_wait_for_ioc(ioc
, IOC_OPERATIONAL_WAIT_COUNT
);
1590 smid
= mpt3sas_base_get_smid(ioc
, ioc
->transport_cb_idx
);
1592 ioc_err(ioc
, "%s: failed obtaining a smid\n", __func__
);
1597 mpi_request
= mpt3sas_base_get_msg_frame(ioc
, smid
);
1598 ioc
->transport_cmds
.smid
= smid
;
1600 sz
= sizeof(struct phy_control_request
) +
1601 sizeof(struct phy_control_reply
);
1602 data_out
= dma_alloc_coherent(&ioc
->pdev
->dev
, sz
, &data_out_dma
,
1605 pr_err("failure at %s:%d/%s()!\n", __FILE__
,
1606 __LINE__
, __func__
);
1608 mpt3sas_base_free_smid(ioc
, smid
);
1613 memset(data_out
, 0, sz
);
1614 phy_control_request
= data_out
;
1615 phy_control_request
->smp_frame_type
= 0x40;
1616 phy_control_request
->function
= 0x91;
1617 phy_control_request
->request_length
= 9;
1618 phy_control_request
->allocated_response_length
= 0;
1619 phy_control_request
->phy_identifier
= phy
->number
;
1620 phy_control_request
->phy_operation
= phy_operation
;
1621 phy_control_request
->programmed_min_physical_link_rate
=
1622 phy
->minimum_linkrate
<< 4;
1623 phy_control_request
->programmed_max_physical_link_rate
=
1624 phy
->maximum_linkrate
<< 4;
1626 memset(mpi_request
, 0, sizeof(Mpi2SmpPassthroughRequest_t
));
1627 mpi_request
->Function
= MPI2_FUNCTION_SMP_PASSTHROUGH
;
1628 mpi_request
->PhysicalPort
= _transport_get_port_id_by_sas_phy(phy
);
1629 mpi_request
->VF_ID
= 0; /* TODO */
1630 mpi_request
->VP_ID
= 0;
1631 mpi_request
->SASAddress
= cpu_to_le64(phy
->identify
.sas_address
);
1632 mpi_request
->RequestDataLength
=
1633 cpu_to_le16(sizeof(struct phy_error_log_request
));
1634 psge
= &mpi_request
->SGL
;
1636 ioc
->build_sg(ioc
, psge
, data_out_dma
,
1637 sizeof(struct phy_control_request
),
1638 data_out_dma
+ sizeof(struct phy_control_request
),
1639 sizeof(struct phy_control_reply
));
1641 dtransportprintk(ioc
,
1642 ioc_info(ioc
, "phy_control - send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n",
1643 (u64
)phy
->identify
.sas_address
,
1644 phy
->number
, phy_operation
));
1645 init_completion(&ioc
->transport_cmds
.done
);
1646 ioc
->put_smid_default(ioc
, smid
);
1647 wait_for_completion_timeout(&ioc
->transport_cmds
.done
, 10*HZ
);
1649 if (!(ioc
->transport_cmds
.status
& MPT3_CMD_COMPLETE
)) {
1650 ioc_err(ioc
, "%s: timeout\n", __func__
);
1651 _debug_dump_mf(mpi_request
,
1652 sizeof(Mpi2SmpPassthroughRequest_t
)/4);
1653 if (!(ioc
->transport_cmds
.status
& MPT3_CMD_RESET
))
1655 goto issue_host_reset
;
1658 dtransportprintk(ioc
, ioc_info(ioc
, "phy_control - complete\n"));
1660 if (ioc
->transport_cmds
.status
& MPT3_CMD_REPLY_VALID
) {
1662 mpi_reply
= ioc
->transport_cmds
.reply
;
1664 dtransportprintk(ioc
,
1665 ioc_info(ioc
, "phy_control - reply data transfer size(%d)\n",
1666 le16_to_cpu(mpi_reply
->ResponseDataLength
)));
1668 if (le16_to_cpu(mpi_reply
->ResponseDataLength
) !=
1669 sizeof(struct phy_control_reply
))
1672 phy_control_reply
= data_out
+
1673 sizeof(struct phy_control_request
);
1675 dtransportprintk(ioc
,
1676 ioc_info(ioc
, "phy_control - function_result(%d)\n",
1677 phy_control_reply
->function_result
));
1681 dtransportprintk(ioc
,
1682 ioc_info(ioc
, "phy_control - no reply\n"));
1686 mpt3sas_base_hard_reset_handler(ioc
, FORCE_BIG_HAMMER
);
1688 ioc
->transport_cmds
.status
= MPT3_CMD_NOT_USED
;
1690 dma_free_coherent(&ioc
->pdev
->dev
, sz
, data_out
,
1693 mutex_unlock(&ioc
->transport_cmds
.mutex
);
1698 * _transport_phy_reset -
1699 * @phy: The sas phy object
1702 * Return: 0 for success, non-zero for failure.
1705 _transport_phy_reset(struct sas_phy
*phy
, int hard_reset
)
1707 struct MPT3SAS_ADAPTER
*ioc
= phy_to_ioc(phy
);
1708 Mpi2SasIoUnitControlReply_t mpi_reply
;
1709 Mpi2SasIoUnitControlRequest_t mpi_request
;
1710 struct hba_port
*port
= phy
->hostdata
;
1711 int port_id
= port
->port_id
;
1712 unsigned long flags
;
1714 spin_lock_irqsave(&ioc
->sas_node_lock
, flags
);
1715 if (_transport_sas_node_find_by_sas_address(ioc
,
1716 phy
->identify
.sas_address
,
1717 mpt3sas_get_port_by_id(ioc
, port_id
, 0)) == NULL
) {
1718 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
1721 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
1723 /* handle expander phys */
1724 if (phy
->identify
.sas_address
!= ioc
->sas_hba
.sas_address
)
1725 return _transport_expander_phy_control(ioc
, phy
,
1726 (hard_reset
== 1) ? SMP_PHY_CONTROL_HARD_RESET
:
1727 SMP_PHY_CONTROL_LINK_RESET
);
1729 /* handle hba phys */
1730 memset(&mpi_request
, 0, sizeof(Mpi2SasIoUnitControlRequest_t
));
1731 mpi_request
.Function
= MPI2_FUNCTION_SAS_IO_UNIT_CONTROL
;
1732 mpi_request
.Operation
= hard_reset
?
1733 MPI2_SAS_OP_PHY_HARD_RESET
: MPI2_SAS_OP_PHY_LINK_RESET
;
1734 mpi_request
.PhyNum
= phy
->number
;
1736 if ((mpt3sas_base_sas_iounit_control(ioc
, &mpi_reply
, &mpi_request
))) {
1737 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1738 __FILE__
, __LINE__
, __func__
);
1742 if (mpi_reply
.IOCStatus
|| mpi_reply
.IOCLogInfo
)
1743 ioc_info(ioc
, "phy(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
1744 phy
->number
, le16_to_cpu(mpi_reply
.IOCStatus
),
1745 le32_to_cpu(mpi_reply
.IOCLogInfo
));
1751 * _transport_phy_enable - enable/disable phys
1752 * @phy: The sas phy object
1753 * @enable: enable phy when true
1755 * Only support sas_host direct attached phys.
1756 * Return: 0 for success, non-zero for failure.
1759 _transport_phy_enable(struct sas_phy
*phy
, int enable
)
1761 struct MPT3SAS_ADAPTER
*ioc
= phy_to_ioc(phy
);
1762 Mpi2SasIOUnitPage1_t
*sas_iounit_pg1
= NULL
;
1763 Mpi2SasIOUnitPage0_t
*sas_iounit_pg0
= NULL
;
1764 Mpi2ConfigReply_t mpi_reply
;
1768 unsigned long flags
;
1769 int i
, discovery_active
;
1770 struct hba_port
*port
= phy
->hostdata
;
1771 int port_id
= port
->port_id
;
1773 spin_lock_irqsave(&ioc
->sas_node_lock
, flags
);
1774 if (_transport_sas_node_find_by_sas_address(ioc
,
1775 phy
->identify
.sas_address
,
1776 mpt3sas_get_port_by_id(ioc
, port_id
, 0)) == NULL
) {
1777 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
1780 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
1782 /* handle expander phys */
1783 if (phy
->identify
.sas_address
!= ioc
->sas_hba
.sas_address
)
1784 return _transport_expander_phy_control(ioc
, phy
,
1785 (enable
== 1) ? SMP_PHY_CONTROL_LINK_RESET
:
1786 SMP_PHY_CONTROL_DISABLE
);
1788 /* handle hba phys */
1790 /* read sas_iounit page 0 */
1791 sz
= struct_size(sas_iounit_pg0
, PhyData
, ioc
->sas_hba
.num_phys
);
1792 sas_iounit_pg0
= kzalloc(sz
, GFP_KERNEL
);
1793 if (!sas_iounit_pg0
) {
1794 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1795 __FILE__
, __LINE__
, __func__
);
1799 if ((mpt3sas_config_get_sas_iounit_pg0(ioc
, &mpi_reply
,
1800 sas_iounit_pg0
, sz
))) {
1801 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1802 __FILE__
, __LINE__
, __func__
);
1806 ioc_status
= le16_to_cpu(mpi_reply
.IOCStatus
) &
1807 MPI2_IOCSTATUS_MASK
;
1808 if (ioc_status
!= MPI2_IOCSTATUS_SUCCESS
) {
1809 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1810 __FILE__
, __LINE__
, __func__
);
1815 /* unable to enable/disable phys when when discovery is active */
1816 for (i
= 0, discovery_active
= 0; i
< ioc
->sas_hba
.num_phys
; i
++) {
1817 if (sas_iounit_pg0
->PhyData
[i
].PortFlags
&
1818 MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS
) {
1819 ioc_err(ioc
, "discovery is active on port = %d, phy = %d: unable to enable/disable phys, try again later!\n",
1820 sas_iounit_pg0
->PhyData
[i
].Port
, i
);
1821 discovery_active
= 1;
1825 if (discovery_active
) {
1830 /* read sas_iounit page 1 */
1831 sz
= struct_size(sas_iounit_pg1
, PhyData
, ioc
->sas_hba
.num_phys
);
1832 sas_iounit_pg1
= kzalloc(sz
, GFP_KERNEL
);
1833 if (!sas_iounit_pg1
) {
1834 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1835 __FILE__
, __LINE__
, __func__
);
1839 if ((mpt3sas_config_get_sas_iounit_pg1(ioc
, &mpi_reply
,
1840 sas_iounit_pg1
, sz
))) {
1841 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1842 __FILE__
, __LINE__
, __func__
);
1846 ioc_status
= le16_to_cpu(mpi_reply
.IOCStatus
) &
1847 MPI2_IOCSTATUS_MASK
;
1848 if (ioc_status
!= MPI2_IOCSTATUS_SUCCESS
) {
1849 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1850 __FILE__
, __LINE__
, __func__
);
1855 /* copy Port/PortFlags/PhyFlags from page 0 */
1856 for (i
= 0; i
< ioc
->sas_hba
.num_phys
; i
++) {
1857 sas_iounit_pg1
->PhyData
[i
].Port
=
1858 sas_iounit_pg0
->PhyData
[i
].Port
;
1859 sas_iounit_pg1
->PhyData
[i
].PortFlags
=
1860 (sas_iounit_pg0
->PhyData
[i
].PortFlags
&
1861 MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG
);
1862 sas_iounit_pg1
->PhyData
[i
].PhyFlags
=
1863 (sas_iounit_pg0
->PhyData
[i
].PhyFlags
&
1864 (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED
+
1865 MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED
));
1869 sas_iounit_pg1
->PhyData
[phy
->number
].PhyFlags
1870 &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE
;
1872 sas_iounit_pg1
->PhyData
[phy
->number
].PhyFlags
1873 |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE
;
1875 mpt3sas_config_set_sas_iounit_pg1(ioc
, &mpi_reply
, sas_iounit_pg1
, sz
);
1879 _transport_phy_reset(phy
, 0);
1882 kfree(sas_iounit_pg1
);
1883 kfree(sas_iounit_pg0
);
1888 * _transport_phy_speed - set phy min/max link rates
1889 * @phy: The sas phy object
1890 * @rates: rates defined in sas_phy_linkrates
1892 * Only support sas_host direct attached phys.
1894 * Return: 0 for success, non-zero for failure.
1897 _transport_phy_speed(struct sas_phy
*phy
, struct sas_phy_linkrates
*rates
)
1899 struct MPT3SAS_ADAPTER
*ioc
= phy_to_ioc(phy
);
1900 Mpi2SasIOUnitPage1_t
*sas_iounit_pg1
= NULL
;
1901 Mpi2SasPhyPage0_t phy_pg0
;
1902 Mpi2ConfigReply_t mpi_reply
;
1907 unsigned long flags
;
1908 struct hba_port
*port
= phy
->hostdata
;
1909 int port_id
= port
->port_id
;
1911 spin_lock_irqsave(&ioc
->sas_node_lock
, flags
);
1912 if (_transport_sas_node_find_by_sas_address(ioc
,
1913 phy
->identify
.sas_address
,
1914 mpt3sas_get_port_by_id(ioc
, port_id
, 0)) == NULL
) {
1915 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
1918 spin_unlock_irqrestore(&ioc
->sas_node_lock
, flags
);
1920 if (!rates
->minimum_linkrate
)
1921 rates
->minimum_linkrate
= phy
->minimum_linkrate
;
1922 else if (rates
->minimum_linkrate
< phy
->minimum_linkrate_hw
)
1923 rates
->minimum_linkrate
= phy
->minimum_linkrate_hw
;
1925 if (!rates
->maximum_linkrate
)
1926 rates
->maximum_linkrate
= phy
->maximum_linkrate
;
1927 else if (rates
->maximum_linkrate
> phy
->maximum_linkrate_hw
)
1928 rates
->maximum_linkrate
= phy
->maximum_linkrate_hw
;
1930 /* handle expander phys */
1931 if (phy
->identify
.sas_address
!= ioc
->sas_hba
.sas_address
) {
1932 phy
->minimum_linkrate
= rates
->minimum_linkrate
;
1933 phy
->maximum_linkrate
= rates
->maximum_linkrate
;
1934 return _transport_expander_phy_control(ioc
, phy
,
1935 SMP_PHY_CONTROL_LINK_RESET
);
1938 /* handle hba phys */
1940 /* sas_iounit page 1 */
1941 sz
= struct_size(sas_iounit_pg1
, PhyData
, ioc
->sas_hba
.num_phys
);
1942 sas_iounit_pg1
= kzalloc(sz
, GFP_KERNEL
);
1943 if (!sas_iounit_pg1
) {
1944 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1945 __FILE__
, __LINE__
, __func__
);
1949 if ((mpt3sas_config_get_sas_iounit_pg1(ioc
, &mpi_reply
,
1950 sas_iounit_pg1
, sz
))) {
1951 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1952 __FILE__
, __LINE__
, __func__
);
1956 ioc_status
= le16_to_cpu(mpi_reply
.IOCStatus
) &
1957 MPI2_IOCSTATUS_MASK
;
1958 if (ioc_status
!= MPI2_IOCSTATUS_SUCCESS
) {
1959 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1960 __FILE__
, __LINE__
, __func__
);
1965 for (i
= 0; i
< ioc
->sas_hba
.num_phys
; i
++) {
1966 if (phy
->number
!= i
) {
1967 sas_iounit_pg1
->PhyData
[i
].MaxMinLinkRate
=
1968 (ioc
->sas_hba
.phy
[i
].phy
->minimum_linkrate
+
1969 (ioc
->sas_hba
.phy
[i
].phy
->maximum_linkrate
<< 4));
1971 sas_iounit_pg1
->PhyData
[i
].MaxMinLinkRate
=
1972 (rates
->minimum_linkrate
+
1973 (rates
->maximum_linkrate
<< 4));
1977 if (mpt3sas_config_set_sas_iounit_pg1(ioc
, &mpi_reply
, sas_iounit_pg1
,
1979 ioc_err(ioc
, "failure at %s:%d/%s()!\n",
1980 __FILE__
, __LINE__
, __func__
);
1986 _transport_phy_reset(phy
, 0);
1988 /* read phy page 0, then update the rates in the sas transport phy */
1989 if (!mpt3sas_config_get_phy_pg0(ioc
, &mpi_reply
, &phy_pg0
,
1991 phy
->minimum_linkrate
= _transport_convert_phy_link_rate(
1992 phy_pg0
.ProgrammedLinkRate
& MPI2_SAS_PRATE_MIN_RATE_MASK
);
1993 phy
->maximum_linkrate
= _transport_convert_phy_link_rate(
1994 phy_pg0
.ProgrammedLinkRate
>> 4);
1995 phy
->negotiated_linkrate
= _transport_convert_phy_link_rate(
1996 phy_pg0
.NegotiatedLinkRate
&
1997 MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL
);
2001 kfree(sas_iounit_pg1
);
2006 _transport_map_smp_buffer(struct device
*dev
, struct bsg_buffer
*buf
,
2007 dma_addr_t
*dma_addr
, size_t *dma_len
, void **p
)
2009 /* Check if the request is split across multiple segments */
2010 if (buf
->sg_cnt
> 1) {
2011 *p
= dma_alloc_coherent(dev
, buf
->payload_len
, dma_addr
,
2015 *dma_len
= buf
->payload_len
;
2017 if (!dma_map_sg(dev
, buf
->sg_list
, 1, DMA_BIDIRECTIONAL
))
2019 *dma_addr
= sg_dma_address(buf
->sg_list
);
2020 *dma_len
= sg_dma_len(buf
->sg_list
);
2028 _transport_unmap_smp_buffer(struct device
*dev
, struct bsg_buffer
*buf
,
2029 dma_addr_t dma_addr
, void *p
)
2032 dma_free_coherent(dev
, buf
->payload_len
, p
, dma_addr
);
2034 dma_unmap_sg(dev
, buf
->sg_list
, 1, DMA_BIDIRECTIONAL
);
2038 * _transport_smp_handler - transport portal for smp passthru
2040 * @shost: shost object
2041 * @rphy: sas transport rphy object
2043 * This used primarily for smp_utils.
2045 * smp_rep_general /sys/class/bsg/expander-5:0
2048 _transport_smp_handler(struct bsg_job
*job
, struct Scsi_Host
*shost
,
2049 struct sas_rphy
*rphy
)
2051 struct MPT3SAS_ADAPTER
*ioc
= shost_priv(shost
);
2052 Mpi2SmpPassthroughRequest_t
*mpi_request
;
2053 Mpi2SmpPassthroughReply_t
*mpi_reply
;
2057 dma_addr_t dma_addr_in
;
2058 dma_addr_t dma_addr_out
;
2059 void *addr_in
= NULL
;
2060 void *addr_out
= NULL
;
2063 unsigned int reslen
= 0;
2065 if (ioc
->shost_recovery
|| ioc
->pci_error_recovery
) {
2066 ioc_info(ioc
, "%s: host reset in progress!\n", __func__
);
2071 rc
= mutex_lock_interruptible(&ioc
->transport_cmds
.mutex
);
2075 if (ioc
->transport_cmds
.status
!= MPT3_CMD_NOT_USED
) {
2076 ioc_err(ioc
, "%s: transport_cmds in use\n",
2081 ioc
->transport_cmds
.status
= MPT3_CMD_PENDING
;
2083 rc
= _transport_map_smp_buffer(&ioc
->pdev
->dev
, &job
->request_payload
,
2084 &dma_addr_out
, &dma_len_out
, &addr_out
);
2088 sg_copy_to_buffer(job
->request_payload
.sg_list
,
2089 job
->request_payload
.sg_cnt
, addr_out
,
2090 job
->request_payload
.payload_len
);
2093 rc
= _transport_map_smp_buffer(&ioc
->pdev
->dev
, &job
->reply_payload
,
2094 &dma_addr_in
, &dma_len_in
, &addr_in
);
2098 rc
= mpt3sas_wait_for_ioc(ioc
, IOC_OPERATIONAL_WAIT_COUNT
);
2102 smid
= mpt3sas_base_get_smid(ioc
, ioc
->transport_cb_idx
);
2104 ioc_err(ioc
, "%s: failed obtaining a smid\n", __func__
);
2110 mpi_request
= mpt3sas_base_get_msg_frame(ioc
, smid
);
2111 ioc
->transport_cmds
.smid
= smid
;
2113 memset(mpi_request
, 0, sizeof(Mpi2SmpPassthroughRequest_t
));
2114 mpi_request
->Function
= MPI2_FUNCTION_SMP_PASSTHROUGH
;
2115 mpi_request
->PhysicalPort
= _transport_get_port_id_by_rphy(ioc
, rphy
);
2116 mpi_request
->SASAddress
= (rphy
) ?
2117 cpu_to_le64(rphy
->identify
.sas_address
) :
2118 cpu_to_le64(ioc
->sas_hba
.sas_address
);
2119 mpi_request
->RequestDataLength
= cpu_to_le16(dma_len_out
- 4);
2120 psge
= &mpi_request
->SGL
;
2122 ioc
->build_sg(ioc
, psge
, dma_addr_out
, dma_len_out
- 4, dma_addr_in
,
2125 dtransportprintk(ioc
,
2126 ioc_info(ioc
, "%s: sending smp request\n", __func__
));
2128 init_completion(&ioc
->transport_cmds
.done
);
2129 ioc
->put_smid_default(ioc
, smid
);
2130 wait_for_completion_timeout(&ioc
->transport_cmds
.done
, 10*HZ
);
2132 if (!(ioc
->transport_cmds
.status
& MPT3_CMD_COMPLETE
)) {
2133 ioc_err(ioc
, "%s: timeout\n", __func__
);
2134 _debug_dump_mf(mpi_request
,
2135 sizeof(Mpi2SmpPassthroughRequest_t
)/4);
2136 if (!(ioc
->transport_cmds
.status
& MPT3_CMD_RESET
)) {
2137 mpt3sas_base_hard_reset_handler(ioc
, FORCE_BIG_HAMMER
);
2143 dtransportprintk(ioc
, ioc_info(ioc
, "%s - complete\n", __func__
));
2145 if (!(ioc
->transport_cmds
.status
& MPT3_CMD_REPLY_VALID
)) {
2146 dtransportprintk(ioc
,
2147 ioc_info(ioc
, "%s: no reply\n", __func__
));
2152 mpi_reply
= ioc
->transport_cmds
.reply
;
2154 dtransportprintk(ioc
,
2155 ioc_info(ioc
, "%s: reply data transfer size(%d)\n",
2157 le16_to_cpu(mpi_reply
->ResponseDataLength
)));
2159 memcpy(job
->reply
, mpi_reply
, sizeof(*mpi_reply
));
2160 job
->reply_len
= sizeof(*mpi_reply
);
2161 reslen
= le16_to_cpu(mpi_reply
->ResponseDataLength
);
2164 sg_copy_to_buffer(job
->reply_payload
.sg_list
,
2165 job
->reply_payload
.sg_cnt
, addr_in
,
2166 job
->reply_payload
.payload_len
);
2171 _transport_unmap_smp_buffer(&ioc
->pdev
->dev
, &job
->reply_payload
,
2172 dma_addr_in
, addr_in
);
2174 _transport_unmap_smp_buffer(&ioc
->pdev
->dev
, &job
->request_payload
,
2175 dma_addr_out
, addr_out
);
2177 ioc
->transport_cmds
.status
= MPT3_CMD_NOT_USED
;
2178 mutex_unlock(&ioc
->transport_cmds
.mutex
);
2180 bsg_job_done(job
, rc
, reslen
);
2183 struct sas_function_template mpt3sas_transport_functions
= {
2184 .get_linkerrors
= _transport_get_linkerrors
,
2185 .get_enclosure_identifier
= _transport_get_enclosure_identifier
,
2186 .get_bay_identifier
= _transport_get_bay_identifier
,
2187 .phy_reset
= _transport_phy_reset
,
2188 .phy_enable
= _transport_phy_enable
,
2189 .set_phy_speed
= _transport_phy_speed
,
2190 .smp_handler
= _transport_smp_handler
,
2193 struct scsi_transport_template
*mpt3sas_transport_template
;