Lines Matching +full:port +full:- +full:expander

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) 2017-2023 Broadcom Inc.
6 * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com)
15 * mpi3mr_post_transport_req - Issue transport requests and wait
33 * Return: 0 on success, non-zero on failure.
41 mutex_lock(&mrioc->transport_cmds.mutex); in mpi3mr_post_transport_req()
42 if (mrioc->transport_cmds.state & MPI3MR_CMD_PENDING) { in mpi3mr_post_transport_req()
43 retval = -1; in mpi3mr_post_transport_req()
45 mutex_unlock(&mrioc->transport_cmds.mutex); in mpi3mr_post_transport_req()
48 mrioc->transport_cmds.state = MPI3MR_CMD_PENDING; in mpi3mr_post_transport_req()
49 mrioc->transport_cmds.is_waiting = 1; in mpi3mr_post_transport_req()
50 mrioc->transport_cmds.callback = NULL; in mpi3mr_post_transport_req()
51 mrioc->transport_cmds.ioc_status = 0; in mpi3mr_post_transport_req()
52 mrioc->transport_cmds.ioc_loginfo = 0; in mpi3mr_post_transport_req()
54 init_completion(&mrioc->transport_cmds.done); in mpi3mr_post_transport_req()
56 if (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO) in mpi3mr_post_transport_req()
63 wait_for_completion_timeout(&mrioc->transport_cmds.done, in mpi3mr_post_transport_req()
65 if (!(mrioc->transport_cmds.state & MPI3MR_CMD_COMPLETE)) { in mpi3mr_post_transport_req()
69 retval = -1; in mpi3mr_post_transport_req()
72 *ioc_status = mrioc->transport_cmds.ioc_status & in mpi3mr_post_transport_req()
77 *ioc_status, mrioc->transport_cmds.ioc_loginfo); in mpi3mr_post_transport_req()
79 if ((reply) && (mrioc->transport_cmds.state & MPI3MR_CMD_REPLY_VALID)) in mpi3mr_post_transport_req()
80 memcpy((u8 *)reply, mrioc->transport_cmds.reply, reply_sz); in mpi3mr_post_transport_req()
83 mrioc->transport_cmds.state = MPI3MR_CMD_NOTUSED; in mpi3mr_post_transport_req()
84 mutex_unlock(&mrioc->transport_cmds.mutex); in mpi3mr_post_transport_req()
119 * mpi3mr_report_manufacture - obtain SMP report_manufacture
121 * @sas_address: SAS address of the expander device
123 * @port_id: ID of the HBA port
127 * Return: 0 for success, non-zero for failure.
149 if (mrioc->reset_in_progress) { in mpi3mr_report_manufacture()
151 return -EFAULT; in mpi3mr_report_manufacture()
154 if (mrioc->pci_err_recovery) { in mpi3mr_report_manufacture()
156 return -EFAULT; in mpi3mr_report_manufacture()
161 data_out = dma_alloc_coherent(&mrioc->pdev->dev, in mpi3mr_report_manufacture()
164 rc = -ENOMEM; in mpi3mr_report_manufacture()
172 manufacture_request->smp_frame_type = 0x40; in mpi3mr_report_manufacture()
173 manufacture_request->function = 1; in mpi3mr_report_manufacture()
174 manufacture_request->reserved = 0; in mpi3mr_report_manufacture()
175 manufacture_request->request_length = 0; in mpi3mr_report_manufacture()
191 "sending report manufacturer SMP request to sas_address(0x%016llx), port(%d)\n", in mpi3mr_report_manufacture()
205 rc = -EINVAL; in mpi3mr_report_manufacture()
210 "report manufacturer - reply data transfer size(%d)\n", in mpi3mr_report_manufacture()
215 rc = -EINVAL; in mpi3mr_report_manufacture()
219 memtostr(edev->vendor_id, manufacture_reply->vendor_id); in mpi3mr_report_manufacture()
220 memtostr(edev->product_id, manufacture_reply->product_id); in mpi3mr_report_manufacture()
221 memtostr(edev->product_rev, manufacture_reply->product_rev); in mpi3mr_report_manufacture()
222 edev->level = manufacture_reply->sas_format & 1; in mpi3mr_report_manufacture()
223 if (edev->level) { in mpi3mr_report_manufacture()
224 memtostr(edev->component_vendor_id, in mpi3mr_report_manufacture()
225 manufacture_reply->component_vendor_id); in mpi3mr_report_manufacture()
226 tmp = (u8 *)&manufacture_reply->component_id; in mpi3mr_report_manufacture()
227 edev->component_id = tmp[0] << 8 | tmp[1]; in mpi3mr_report_manufacture()
228 edev->component_revision_id = in mpi3mr_report_manufacture()
229 manufacture_reply->component_revision_id; in mpi3mr_report_manufacture()
234 dma_free_coherent(&mrioc->pdev->dev, data_out_sz + data_in_sz, in mpi3mr_report_manufacture()
241 * __mpi3mr_expander_find_by_handle - expander search by handle
243 * @handle: Firmware device handle of the expander
247 * This searches for expander device based on handle, then
250 * Return: Expander sas_node object reference or NULL
258 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { in __mpi3mr_expander_find_by_handle()
259 if (sas_expander->handle != handle) in __mpi3mr_expander_find_by_handle()
269 * mpi3mr_is_expander_device - if device is an expander
272 * Return: 1 if the device is expander device, else 0.
284 * mpi3mr_get_sas_address - retrieve sas_address for handle
292 * Return: 0 for success, non-zero for failure
307 return -ENXIO; in mpi3mr_get_sas_address()
313 return -ENXIO; in mpi3mr_get_sas_address()
318 *sas_address = mrioc->sas_hba.sas_address; in mpi3mr_get_sas_address()
321 *sas_address = le64_to_cpu(sasinf->sas_address); in mpi3mr_get_sas_address()
325 return -ENXIO; in mpi3mr_get_sas_address()
331 * __mpi3mr_get_tgtdev_by_addr - target device search
334 * @hba_port: HBA port entry
336 * This searches for target device from sas address and hba port
346 assert_spin_locked(&mrioc->tgtdev_lock); in __mpi3mr_get_tgtdev_by_addr()
348 list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) in __mpi3mr_get_tgtdev_by_addr()
349 if ((tgtdev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA) && in __mpi3mr_get_tgtdev_by_addr()
350 (tgtdev->dev_spec.sas_sata_inf.sas_address == sas_address) in __mpi3mr_get_tgtdev_by_addr()
351 && (tgtdev->dev_spec.sas_sata_inf.hba_port == hba_port)) in __mpi3mr_get_tgtdev_by_addr()
360 * mpi3mr_get_tgtdev_by_addr - target device search
363 * @hba_port: HBA port entry
365 * This searches for target device from sas address and hba port
382 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_get_tgtdev_by_addr()
384 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_get_tgtdev_by_addr()
391 * mpi3mr_remove_device_by_sas_address - remove the device
394 * @hba_port: HBA port entry
397 * port pointer then removes it from the OS.
411 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_remove_device_by_sas_address()
415 if (!list_empty(&tgtdev->list)) { in mpi3mr_remove_device_by_sas_address()
416 list_del_init(&tgtdev->list); in mpi3mr_remove_device_by_sas_address()
421 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_remove_device_by_sas_address()
423 if (tgtdev->host_exposed) in mpi3mr_remove_device_by_sas_address()
430 * __mpi3mr_get_tgtdev_by_addr_and_rphy - target device search
445 assert_spin_locked(&mrioc->tgtdev_lock); in __mpi3mr_get_tgtdev_by_addr_and_rphy()
447 list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) in __mpi3mr_get_tgtdev_by_addr_and_rphy()
448 if ((tgtdev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA) && in __mpi3mr_get_tgtdev_by_addr_and_rphy()
449 (tgtdev->dev_spec.sas_sata_inf.sas_address == sas_address) in __mpi3mr_get_tgtdev_by_addr_and_rphy()
450 && (tgtdev->dev_spec.sas_sata_inf.rphy == rphy)) in __mpi3mr_get_tgtdev_by_addr_and_rphy()
459 * mpi3mr_expander_find_by_sas_address - sas expander search
461 * @sas_address: SAS address of expander
462 * @hba_port: HBA port entry
464 * Return: A valid SAS expander node or NULL.
476 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { in mpi3mr_expander_find_by_sas_address()
477 if ((sas_expander->sas_address != sas_address) || in mpi3mr_expander_find_by_sas_address()
478 (sas_expander->hba_port != hba_port)) in mpi3mr_expander_find_by_sas_address()
488 * __mpi3mr_sas_node_find_by_sas_address - sas node search
490 * @sas_address: SAS address of expander or sas host
491 * @hba_port: HBA port entry
492 * Context: Caller should acquire mrioc->sas_node_lock.
497 * address and hba port are used to identify the exact expander
509 if (mrioc->sas_hba.sas_address == sas_address) in __mpi3mr_sas_node_find_by_sas_address()
510 return &mrioc->sas_hba; in __mpi3mr_sas_node_find_by_sas_address()
516 * mpi3mr_parent_present - Is parent present for a phy
520 * Return: 0 if parent is present else non-zero
525 struct mpi3mr_hba_port *hba_port = phy->hostdata; in mpi3mr_parent_present()
527 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_parent_present()
529 phy->identify.sas_address, in mpi3mr_parent_present()
531 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_parent_present()
532 return -1; in mpi3mr_parent_present()
534 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_parent_present()
539 * mpi3mr_convert_phy_link_rate -
589 * mpi3mr_delete_sas_phy - Remove a single phy from port
591 * @mr_sas_port: Internal Port object
601 u64 sas_address = mr_sas_port->remote_identify.sas_address; in mpi3mr_delete_sas_phy()
603 dev_info(&mr_sas_phy->phy->dev, in mpi3mr_delete_sas_phy()
605 (unsigned long long) sas_address, mr_sas_phy->phy_id); in mpi3mr_delete_sas_phy()
607 list_del(&mr_sas_phy->port_siblings); in mpi3mr_delete_sas_phy()
608 mr_sas_port->num_phys--; in mpi3mr_delete_sas_phy()
611 mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); in mpi3mr_delete_sas_phy()
613 if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) in mpi3mr_delete_sas_phy()
614 mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; in mpi3mr_delete_sas_phy()
616 sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); in mpi3mr_delete_sas_phy()
617 mr_sas_phy->phy_belongs_to_port = 0; in mpi3mr_delete_sas_phy()
621 * mpi3mr_add_sas_phy - Adding a single phy to a port
623 * @mr_sas_port: Internal Port object
633 u64 sas_address = mr_sas_port->remote_identify.sas_address; in mpi3mr_add_sas_phy()
635 dev_info(&mr_sas_phy->phy->dev, in mpi3mr_add_sas_phy()
637 sas_address, mr_sas_phy->phy_id); in mpi3mr_add_sas_phy()
639 list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); in mpi3mr_add_sas_phy()
640 mr_sas_port->num_phys++; in mpi3mr_add_sas_phy()
642 mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); in mpi3mr_add_sas_phy()
644 if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) in mpi3mr_add_sas_phy()
645 mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; in mpi3mr_add_sas_phy()
647 sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); in mpi3mr_add_sas_phy()
648 mr_sas_phy->phy_belongs_to_port = 1; in mpi3mr_add_sas_phy()
652 * mpi3mr_add_phy_to_an_existing_port - add phy to existing port
654 * @mr_sas_node: Internal sas node object (expander or host)
656 * @sas_address: SAS address of device/expander were phy needs
658 * @hba_port: HBA port entry
669 if (mr_sas_phy->phy_belongs_to_port == 1) in mpi3mr_add_phy_to_an_existing_port()
675 list_for_each_entry(mr_sas_port, &mr_sas_node->sas_port_list, in mpi3mr_add_phy_to_an_existing_port()
677 if (mr_sas_port->remote_identify.sas_address != in mpi3mr_add_phy_to_an_existing_port()
680 if (mr_sas_port->hba_port != hba_port) in mpi3mr_add_phy_to_an_existing_port()
682 list_for_each_entry(srch_phy, &mr_sas_port->phy_list, in mpi3mr_add_phy_to_an_existing_port()
687 mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy, mr_sas_node->host_node); in mpi3mr_add_phy_to_an_existing_port()
693 * mpi3mr_delete_sas_port - helper function to removing a port
695 * @mr_sas_port: Internal Port object
702 u64 sas_address = mr_sas_port->remote_identify.sas_address; in mpi3mr_delete_sas_port()
703 struct mpi3mr_hba_port *hba_port = mr_sas_port->hba_port; in mpi3mr_delete_sas_port()
705 mr_sas_port->remote_identify.device_type; in mpi3mr_delete_sas_port()
707 dev_info(&mr_sas_port->port->dev, in mpi3mr_delete_sas_port()
721 * mpi3mr_del_phy_from_an_existing_port - del phy from a port
723 * @mr_sas_node: Internal sas node object (expander or host)
734 if (mr_sas_phy->phy_belongs_to_port == 0) in mpi3mr_del_phy_from_an_existing_port()
737 list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list, in mpi3mr_del_phy_from_an_existing_port()
739 list_for_each_entry(srch_phy, &mr_sas_port->phy_list, in mpi3mr_del_phy_from_an_existing_port()
743 if ((mr_sas_port->num_phys == 1) && in mpi3mr_del_phy_from_an_existing_port()
744 !mrioc->reset_in_progress) in mpi3mr_del_phy_from_an_existing_port()
748 mr_sas_phy, mr_sas_node->host_node); in mpi3mr_del_phy_from_an_existing_port()
755 * mpi3mr_sas_port_sanity_check - sanity check while adding port
757 * @mr_sas_node: Internal sas node object (expander or host)
758 * @sas_address: SAS address of device/expander
759 * @hba_port: HBA port entry
762 * SAS address already belongs to an existing sas port if so
763 * will remove those phys from the sas port
773 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_sanity_check()
774 if ((mr_sas_node->phy[i].remote_identify.sas_address != in mpi3mr_sas_port_sanity_check()
775 sas_address) || (mr_sas_node->phy[i].hba_port != hba_port)) in mpi3mr_sas_port_sanity_check()
777 if (mr_sas_node->phy[i].phy_belongs_to_port == 1) in mpi3mr_sas_port_sanity_check()
779 mr_sas_node, &mr_sas_node->phy[i]); in mpi3mr_sas_port_sanity_check()
784 * mpi3mr_set_identify - set identify for phys and end devices
791 * Return: 0 for success, non-zero for failure.
802 if (mrioc->reset_in_progress) { in mpi3mr_set_identify()
804 return -EFAULT; in mpi3mr_set_identify()
807 if (mrioc->pci_err_recovery) { in mpi3mr_set_identify()
810 return -EFAULT; in mpi3mr_set_identify()
816 return -ENXIO; in mpi3mr_set_identify()
822 return -EIO; in mpi3mr_set_identify()
827 device_info = le16_to_cpu(sasinf->device_info); in mpi3mr_set_identify()
830 identify->sas_address = le64_to_cpu(sasinf->sas_address); in mpi3mr_set_identify()
833 identify->phy_identifier = sasinf->phy_num; in mpi3mr_set_identify()
838 identify->device_type = SAS_PHY_UNUSED; in mpi3mr_set_identify()
841 identify->device_type = SAS_END_DEVICE; in mpi3mr_set_identify()
844 identify->device_type = SAS_EDGE_EXPANDER_DEVICE; in mpi3mr_set_identify()
850 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP; in mpi3mr_set_identify()
853 identify->initiator_port_protocols |= (SAS_PROTOCOL_STP | in mpi3mr_set_identify()
856 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP; in mpi3mr_set_identify()
860 identify->target_port_protocols |= SAS_PROTOCOL_SSP; in mpi3mr_set_identify()
863 identify->target_port_protocols |= (SAS_PROTOCOL_STP | in mpi3mr_set_identify()
866 identify->target_port_protocols |= SAS_PROTOCOL_SMP; in mpi3mr_set_identify()
871 * mpi3mr_add_host_phy - report sas_host phy to SAS transport
877 * Return: 0 for success, non-zero for failure.
884 int phy_index = mr_sas_phy->phy_id; in mpi3mr_add_host_phy()
887 INIT_LIST_HEAD(&mr_sas_phy->port_siblings); in mpi3mr_add_host_phy()
892 return -1; in mpi3mr_add_host_phy()
894 if ((mpi3mr_set_identify(mrioc, mr_sas_phy->handle, in mpi3mr_add_host_phy()
895 &mr_sas_phy->identify))) { in mpi3mr_add_host_phy()
899 return -1; in mpi3mr_add_host_phy()
901 phy->identify = mr_sas_phy->identify; in mpi3mr_add_host_phy()
902 mr_sas_phy->attached_handle = le16_to_cpu(phy_pg0.attached_dev_handle); in mpi3mr_add_host_phy()
903 if (mr_sas_phy->attached_handle) in mpi3mr_add_host_phy()
904 mpi3mr_set_identify(mrioc, mr_sas_phy->attached_handle, in mpi3mr_add_host_phy()
905 &mr_sas_phy->remote_identify); in mpi3mr_add_host_phy()
906 phy->identify.phy_identifier = mr_sas_phy->phy_id; in mpi3mr_add_host_phy()
907 phy->negotiated_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
911 phy->minimum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
913 phy->maximum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
915 phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
917 phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
919 phy->hostdata = mr_sas_phy->hba_port; in mpi3mr_add_host_phy()
925 return -1; in mpi3mr_add_host_phy()
927 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_add_host_phy()
928 dev_info(&phy->dev, in mpi3mr_add_host_phy()
931 mr_sas_phy->handle, (unsigned long long) in mpi3mr_add_host_phy()
932 mr_sas_phy->identify.sas_address, in mpi3mr_add_host_phy()
933 mr_sas_phy->attached_handle, in mpi3mr_add_host_phy()
935 mr_sas_phy->remote_identify.sas_address); in mpi3mr_add_host_phy()
936 mr_sas_phy->phy = phy; in mpi3mr_add_host_phy()
941 * mpi3mr_add_expander_phy - report expander phy to transport
944 * @expander_pg1: SAS Expander page 1
947 * Return: 0 for success, non-zero for failure.
955 int phy_index = mr_sas_phy->phy_id; in mpi3mr_add_expander_phy()
957 INIT_LIST_HEAD(&mr_sas_phy->port_siblings); in mpi3mr_add_expander_phy()
962 return -1; in mpi3mr_add_expander_phy()
964 if ((mpi3mr_set_identify(mrioc, mr_sas_phy->handle, in mpi3mr_add_expander_phy()
965 &mr_sas_phy->identify))) { in mpi3mr_add_expander_phy()
969 return -1; in mpi3mr_add_expander_phy()
971 phy->identify = mr_sas_phy->identify; in mpi3mr_add_expander_phy()
972 mr_sas_phy->attached_handle = in mpi3mr_add_expander_phy()
974 if (mr_sas_phy->attached_handle) in mpi3mr_add_expander_phy()
975 mpi3mr_set_identify(mrioc, mr_sas_phy->attached_handle, in mpi3mr_add_expander_phy()
976 &mr_sas_phy->remote_identify); in mpi3mr_add_expander_phy()
977 phy->identify.phy_identifier = mr_sas_phy->phy_id; in mpi3mr_add_expander_phy()
978 phy->negotiated_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
982 phy->minimum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
984 phy->maximum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
986 phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
988 phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
990 phy->hostdata = mr_sas_phy->hba_port; in mpi3mr_add_expander_phy()
996 return -1; in mpi3mr_add_expander_phy()
998 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_add_expander_phy()
999 dev_info(&phy->dev, in mpi3mr_add_expander_phy()
1002 mr_sas_phy->handle, (unsigned long long) in mpi3mr_add_expander_phy()
1003 mr_sas_phy->identify.sas_address, in mpi3mr_add_expander_phy()
1004 mr_sas_phy->attached_handle, in mpi3mr_add_expander_phy()
1006 mr_sas_phy->remote_identify.sas_address); in mpi3mr_add_expander_phy()
1007 mr_sas_phy->phy = phy; in mpi3mr_add_expander_phy()
1012 * mpi3mr_alloc_hba_port - alloc hba port object
1014 * @port_id: Port number
1016 * Alloc memory for hba port object.
1027 hba_port->port_id = port_id; in mpi3mr_alloc_hba_port()
1028 ioc_info(mrioc, "hba_port entry: %p, port: %d is added to hba_port list\n", in mpi3mr_alloc_hba_port()
1029 hba_port, hba_port->port_id); in mpi3mr_alloc_hba_port()
1030 if (mrioc->reset_in_progress || in mpi3mr_alloc_hba_port()
1031 mrioc->pci_err_recovery) in mpi3mr_alloc_hba_port()
1032 hba_port->flags = MPI3MR_HBA_PORT_FLAG_NEW; in mpi3mr_alloc_hba_port()
1033 list_add_tail(&hba_port->list, &mrioc->hba_port_table_list); in mpi3mr_alloc_hba_port()
1038 * mpi3mr_get_hba_port_by_id - find hba port by id
1040 * @port_id: Port ID to search
1042 * Return: mpi3mr_hba_port reference for the matched port
1048 struct mpi3mr_hba_port *port, *port_next; in mpi3mr_get_hba_port_by_id() local
1050 list_for_each_entry_safe(port, port_next, in mpi3mr_get_hba_port_by_id()
1051 &mrioc->hba_port_table_list, list) { in mpi3mr_get_hba_port_by_id()
1052 if (port->port_id != port_id) in mpi3mr_get_hba_port_by_id()
1054 if (port->flags & MPI3MR_HBA_PORT_FLAG_DIRTY) in mpi3mr_get_hba_port_by_id()
1056 return port; in mpi3mr_get_hba_port_by_id()
1063 * mpi3mr_update_links - refreshing SAS phy link changes
1065 * @sas_address_parent: SAS address of parent expander or host
1069 * @hba_port: HBA port entry
1081 if (mrioc->reset_in_progress || mrioc->pci_err_recovery) in mpi3mr_update_links()
1084 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_update_links()
1088 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_update_links()
1092 mr_sas_phy = &mr_sas_node->phy[phy_number]; in mpi3mr_update_links()
1093 mr_sas_phy->attached_handle = handle; in mpi3mr_update_links()
1094 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_update_links()
1097 &mr_sas_phy->remote_identify); in mpi3mr_update_links()
1099 mr_sas_phy, mr_sas_phy->remote_identify.sas_address, in mpi3mr_update_links()
1102 memset(&mr_sas_phy->remote_identify, 0, sizeof(struct in mpi3mr_update_links()
1105 if (mr_sas_phy->phy) in mpi3mr_update_links()
1106 mr_sas_phy->phy->negotiated_linkrate = in mpi3mr_update_links()
1109 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_update_links()
1110 dev_info(&mr_sas_phy->phy->dev, in mpi3mr_update_links()
1116 mr_sas_phy->remote_identify.sas_address); in mpi3mr_update_links()
1120 * mpi3mr_sas_host_refresh - refreshing sas host object contents
1139 (unsigned long long)mrioc->sas_hba.sas_address); in mpi3mr_sas_host_refresh()
1142 (mrioc->sas_hba.num_phys * in mpi3mr_sas_host_refresh()
1153 mrioc->sas_hba.handle = 0; in mpi3mr_sas_host_refresh()
1154 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_sas_host_refresh()
1155 if (sas_io_unit_pg0->phy_data[i].phy_flags & in mpi3mr_sas_host_refresh()
1160 sas_io_unit_pg0->phy_data[i].negotiated_link_rate >> 4; in mpi3mr_sas_host_refresh()
1161 if (!mrioc->sas_hba.handle) in mpi3mr_sas_host_refresh()
1162 mrioc->sas_hba.handle = le16_to_cpu( in mpi3mr_sas_host_refresh()
1163 sas_io_unit_pg0->phy_data[i].controller_dev_handle); in mpi3mr_sas_host_refresh()
1164 port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_sas_host_refresh()
1169 mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle; in mpi3mr_sas_host_refresh()
1171 sas_io_unit_pg0->phy_data[i].attached_dev_handle); in mpi3mr_sas_host_refresh()
1174 mrioc->sas_hba.phy[i].hba_port = in mpi3mr_sas_host_refresh()
1176 mpi3mr_update_links(mrioc, mrioc->sas_hba.sas_address, in mpi3mr_sas_host_refresh()
1178 mrioc->sas_hba.phy[i].hba_port); in mpi3mr_sas_host_refresh()
1185 * mpi3mr_sas_host_add - create sas host object
1216 num_phys = sas_io_unit_pg0->num_phys; in mpi3mr_sas_host_add()
1219 mrioc->sas_hba.host_node = 1; in mpi3mr_sas_host_add()
1220 INIT_LIST_HEAD(&mrioc->sas_hba.sas_port_list); in mpi3mr_sas_host_add()
1221 mrioc->sas_hba.parent_dev = &mrioc->shost->shost_gendev; in mpi3mr_sas_host_add()
1222 mrioc->sas_hba.phy = kcalloc(num_phys, in mpi3mr_sas_host_add()
1224 if (!mrioc->sas_hba.phy) in mpi3mr_sas_host_add()
1227 mrioc->sas_hba.num_phys = num_phys; in mpi3mr_sas_host_add()
1241 mrioc->sas_hba.handle = 0; in mpi3mr_sas_host_add()
1242 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_sas_host_add()
1243 if (sas_io_unit_pg0->phy_data[i].phy_flags & in mpi3mr_sas_host_add()
1260 if (!mrioc->sas_hba.handle) in mpi3mr_sas_host_add()
1261 mrioc->sas_hba.handle = le16_to_cpu( in mpi3mr_sas_host_add()
1262 sas_io_unit_pg0->phy_data[i].controller_dev_handle); in mpi3mr_sas_host_add()
1263 port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_sas_host_add()
1269 mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle; in mpi3mr_sas_host_add()
1270 mrioc->sas_hba.phy[i].phy_id = i; in mpi3mr_sas_host_add()
1271 mrioc->sas_hba.phy[i].hba_port = in mpi3mr_sas_host_add()
1273 mpi3mr_add_host_phy(mrioc, &mrioc->sas_hba.phy[i], in mpi3mr_sas_host_add()
1274 phy_pg0, mrioc->sas_hba.parent_dev); in mpi3mr_sas_host_add()
1278 mrioc->sas_hba.handle))) { in mpi3mr_sas_host_add()
1284 mrioc->sas_hba.handle, ioc_status, __FILE__, __LINE__, in mpi3mr_sas_host_add()
1288 mrioc->sas_hba.enclosure_handle = in mpi3mr_sas_host_add()
1291 mrioc->sas_hba.sas_address = in mpi3mr_sas_host_add()
1292 le64_to_cpu(sasinf->sas_address); in mpi3mr_sas_host_add()
1295 mrioc->sas_hba.handle, in mpi3mr_sas_host_add()
1296 (unsigned long long) mrioc->sas_hba.sas_address, in mpi3mr_sas_host_add()
1297 mrioc->sas_hba.num_phys); in mpi3mr_sas_host_add()
1299 if (mrioc->sas_hba.enclosure_handle) { in mpi3mr_sas_host_add()
1303 mrioc->sas_hba.enclosure_handle)) && in mpi3mr_sas_host_add()
1305 mrioc->sas_hba.enclosure_logical_id = in mpi3mr_sas_host_add()
1314 * mpi3mr_sas_port_add - Expose the SAS device to the SAS TL
1317 * @sas_address_parent: sas address of parent expander or host
1318 * @hba_port: HBA port entry
1320 * This function creates a new sas port object for the given end
1337 struct sas_port *port; in mpi3mr_sas_port_add() local
1349 INIT_LIST_HEAD(&mr_sas_port->port_list); in mpi3mr_sas_port_add()
1350 INIT_LIST_HEAD(&mr_sas_port->phy_list); in mpi3mr_sas_port_add()
1351 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1354 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1363 &mr_sas_port->remote_identify))) { in mpi3mr_sas_port_add()
1369 if (mr_sas_port->remote_identify.device_type == SAS_PHY_UNUSED) { in mpi3mr_sas_port_add()
1375 mr_sas_port->hba_port = hba_port; in mpi3mr_sas_port_add()
1377 mr_sas_port->remote_identify.sas_address, hba_port); in mpi3mr_sas_port_add()
1379 if (mr_sas_node->host_node && mr_sas_node->num_phys >= in mpi3mr_sas_port_add()
1380 sizeof(mr_sas_port->phy_mask) * 8) in mpi3mr_sas_port_add()
1381 ioc_info(mrioc, "max port count %u could be too high\n", in mpi3mr_sas_port_add()
1382 mr_sas_node->num_phys); in mpi3mr_sas_port_add()
1384 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_add()
1385 if ((mr_sas_node->phy[i].remote_identify.sas_address != in mpi3mr_sas_port_add()
1386 mr_sas_port->remote_identify.sas_address) || in mpi3mr_sas_port_add()
1387 (mr_sas_node->phy[i].hba_port != hba_port)) in mpi3mr_sas_port_add()
1390 if (mr_sas_node->host_node && (i >= sizeof(mr_sas_port->phy_mask) * 8)) { in mpi3mr_sas_port_add()
1391 ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n", in mpi3mr_sas_port_add()
1392 i, sizeof(mr_sas_port->phy_mask) * 8); in mpi3mr_sas_port_add()
1395 list_add_tail(&mr_sas_node->phy[i].port_siblings, in mpi3mr_sas_port_add()
1396 &mr_sas_port->phy_list); in mpi3mr_sas_port_add()
1397 mr_sas_port->num_phys++; in mpi3mr_sas_port_add()
1398 if (mr_sas_node->host_node) in mpi3mr_sas_port_add()
1399 mr_sas_port->phy_mask |= (1 << i); in mpi3mr_sas_port_add()
1402 if (!mr_sas_port->num_phys) { in mpi3mr_sas_port_add()
1408 if (mr_sas_node->host_node) in mpi3mr_sas_port_add()
1409 mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; in mpi3mr_sas_port_add()
1411 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1413 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1414 mr_sas_port->hba_port); in mpi3mr_sas_port_add()
1421 tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 1; in mpi3mr_sas_port_add()
1424 if (!mr_sas_node->parent_dev) { in mpi3mr_sas_port_add()
1430 port = sas_port_alloc_num(mr_sas_node->parent_dev); in mpi3mr_sas_port_add()
1431 if ((sas_port_add(port))) { in mpi3mr_sas_port_add()
1437 list_for_each_entry(mr_sas_phy, &mr_sas_port->phy_list, in mpi3mr_sas_port_add()
1439 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_sas_port_add()
1440 dev_info(&port->dev, in mpi3mr_sas_port_add()
1443 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1444 mr_sas_phy->phy_id); in mpi3mr_sas_port_add()
1445 sas_port_add_phy(port, mr_sas_phy->phy); in mpi3mr_sas_port_add()
1446 mr_sas_phy->phy_belongs_to_port = 1; in mpi3mr_sas_port_add()
1447 mr_sas_phy->hba_port = hba_port; in mpi3mr_sas_port_add()
1450 mr_sas_port->port = port; in mpi3mr_sas_port_add()
1451 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1452 rphy = sas_end_device_alloc(port); in mpi3mr_sas_port_add()
1453 tgtdev->dev_spec.sas_sata_inf.rphy = rphy; in mpi3mr_sas_port_add()
1455 rphy = sas_expander_alloc(port, in mpi3mr_sas_port_add()
1456 mr_sas_port->remote_identify.device_type); in mpi3mr_sas_port_add()
1458 rphy->identify = mr_sas_port->remote_identify; in mpi3mr_sas_port_add()
1460 if (mrioc->current_event) in mpi3mr_sas_port_add()
1461 mrioc->current_event->pending_at_sml = 1; in mpi3mr_sas_port_add()
1467 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1468 tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 0; in mpi3mr_sas_port_add()
1469 tgtdev->dev_spec.sas_sata_inf.sas_transport_attached = 1; in mpi3mr_sas_port_add()
1473 dev_info(&rphy->dev, in mpi3mr_sas_port_add()
1476 mr_sas_port->remote_identify.sas_address); in mpi3mr_sas_port_add()
1478 mr_sas_port->rphy = rphy; in mpi3mr_sas_port_add()
1479 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1480 list_add_tail(&mr_sas_port->port_list, &mr_sas_node->sas_port_list); in mpi3mr_sas_port_add()
1481 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1483 if (mrioc->current_event) { in mpi3mr_sas_port_add()
1484 mrioc->current_event->pending_at_sml = 0; in mpi3mr_sas_port_add()
1485 if (mrioc->current_event->discard) in mpi3mr_sas_port_add()
1490 if (mr_sas_port->remote_identify.device_type == in mpi3mr_sas_port_add()
1492 mr_sas_port->remote_identify.device_type == in mpi3mr_sas_port_add()
1495 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1496 rphy_to_expander_device(rphy), hba_port->port_id); in mpi3mr_sas_port_add()
1501 list_for_each_entry_safe(mr_sas_phy, next, &mr_sas_port->phy_list, in mpi3mr_sas_port_add()
1503 list_del(&mr_sas_phy->port_siblings); in mpi3mr_sas_port_add()
1509 * mpi3mr_sas_port_remove - remove port from the list
1512 * @sas_address_parent: SAS address of parent expander or host
1513 * @hba_port: HBA port entry
1534 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1538 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1541 list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list, in mpi3mr_sas_port_remove()
1543 if (mr_sas_port->remote_identify.sas_address != sas_address) in mpi3mr_sas_port_remove()
1545 if (mr_sas_port->hba_port != hba_port) in mpi3mr_sas_port_remove()
1548 list_del(&mr_sas_port->port_list); in mpi3mr_sas_port_remove()
1554 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1558 if (mr_sas_node->host_node) { in mpi3mr_sas_port_remove()
1560 &mrioc->hba_port_table_list, list) { in mpi3mr_sas_port_remove()
1564 "removing hba_port entry: %p port: %d from hba_port list\n", in mpi3mr_sas_port_remove()
1565 srch_port, srch_port->port_id); in mpi3mr_sas_port_remove()
1566 list_del(&hba_port->list); in mpi3mr_sas_port_remove()
1572 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_remove()
1573 if (mr_sas_node->phy[i].remote_identify.sas_address == in mpi3mr_sas_port_remove()
1575 memset(&mr_sas_node->phy[i].remote_identify, 0, in mpi3mr_sas_port_remove()
1579 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1581 if (mrioc->current_event) in mpi3mr_sas_port_remove()
1582 mrioc->current_event->pending_at_sml = 1; in mpi3mr_sas_port_remove()
1585 &mr_sas_port->phy_list, port_siblings) { in mpi3mr_sas_port_remove()
1586 if ((!mrioc->stop_drv_processing) && in mpi3mr_sas_port_remove()
1587 (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_sas_port_remove()
1588 dev_info(&mr_sas_port->port->dev, in mpi3mr_sas_port_remove()
1591 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_remove()
1592 mr_sas_phy->phy_id); in mpi3mr_sas_port_remove()
1593 mr_sas_phy->phy_belongs_to_port = 0; in mpi3mr_sas_port_remove()
1594 if (!mrioc->stop_drv_processing) in mpi3mr_sas_port_remove()
1595 sas_port_delete_phy(mr_sas_port->port, in mpi3mr_sas_port_remove()
1596 mr_sas_phy->phy); in mpi3mr_sas_port_remove()
1597 list_del(&mr_sas_phy->port_siblings); in mpi3mr_sas_port_remove()
1599 if (!mrioc->stop_drv_processing) in mpi3mr_sas_port_remove()
1600 sas_port_delete(mr_sas_port->port); in mpi3mr_sas_port_remove()
1604 if (mrioc->current_event) { in mpi3mr_sas_port_remove()
1605 mrioc->current_event->pending_at_sml = 0; in mpi3mr_sas_port_remove()
1606 if (mrioc->current_event->discard) in mpi3mr_sas_port_remove()
1614 * struct host_port - host port details
1616 * @phy_mask: phy mask of host port
1618 * @iounit_port_id: port ID
1619 * @used: host port is already matched with sas port from sas_port_list
1620 * @lowest_phy: lowest phy ID of host port
1632 * mpi3mr_update_mr_sas_port - update sas port objects during reset
1637 * Update the port ID of sas port object. Also add the phys if new phys got
1638 * added to current sas port and remove the phys if some phys are moved
1639 * out of the current sas port.
1652 h_port->used = 1; in mpi3mr_update_mr_sas_port()
1653 mr_sas_port->marked_responding = 1; in mpi3mr_update_mr_sas_port()
1655 dev_info(&mr_sas_port->port->dev, in mpi3mr_update_mr_sas_port()
1657 mr_sas_port->remote_identify.sas_address, in mpi3mr_update_mr_sas_port()
1658 mr_sas_port->hba_port->port_id, mr_sas_port->phy_mask, in mpi3mr_update_mr_sas_port()
1659 h_port->iounit_port_id, h_port->phy_mask); in mpi3mr_update_mr_sas_port()
1661 mr_sas_port->hba_port->port_id = h_port->iounit_port_id; in mpi3mr_update_mr_sas_port()
1662 mr_sas_port->hba_port->flags &= ~MPI3MR_HBA_PORT_FLAG_DIRTY; in mpi3mr_update_mr_sas_port()
1665 phy_mask_xor = mr_sas_port->phy_mask ^ h_port->phy_mask; in mpi3mr_update_mr_sas_port()
1666 phys_to_be_added = h_port->phy_mask & phy_mask_xor; in mpi3mr_update_mr_sas_port()
1667 phys_to_be_removed = mr_sas_port->phy_mask & phy_mask_xor; in mpi3mr_update_mr_sas_port()
1670 * Register these new phys to current mr_sas_port's port. in mpi3mr_update_mr_sas_port()
1671 * if these phys are previously registered with another port in mpi3mr_update_mr_sas_port()
1672 * then delete these phys from that port first. in mpi3mr_update_mr_sas_port()
1675 mr_sas_phy = &mrioc->sas_hba.phy[i]; in mpi3mr_update_mr_sas_port()
1676 if (mr_sas_phy->phy_belongs_to_port) in mpi3mr_update_mr_sas_port()
1678 &mrioc->sas_hba, mr_sas_phy); in mpi3mr_update_mr_sas_port()
1680 &mrioc->sas_hba, mr_sas_phy, in mpi3mr_update_mr_sas_port()
1681 mr_sas_port->remote_identify.sas_address, in mpi3mr_update_mr_sas_port()
1682 mr_sas_port->hba_port); in mpi3mr_update_mr_sas_port()
1685 /* Delete the phys which are not part of current mr_sas_port's port. */ in mpi3mr_update_mr_sas_port()
1687 mr_sas_phy = &mrioc->sas_hba.phy[i]; in mpi3mr_update_mr_sas_port()
1688 if (mr_sas_phy->phy_belongs_to_port) in mpi3mr_update_mr_sas_port()
1690 &mrioc->sas_hba, mr_sas_phy); in mpi3mr_update_mr_sas_port()
1695 * mpi3mr_refresh_sas_ports - update host's sas ports during reset
1700 * phys are (moved in)/(moved out) of sas port. Also update
1717 (mrioc->sas_hba.num_phys * in mpi3mr_refresh_sas_ports()
1732 /* Create a new expander port table */ in mpi3mr_refresh_sas_ports()
1733 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_refresh_sas_ports()
1735 sas_io_unit_pg0->phy_data[i].attached_dev_handle); in mpi3mr_refresh_sas_ports()
1766 h_port[port_idx].sas_address = le64_to_cpu(sasinf->sas_address); in mpi3mr_refresh_sas_ports()
1769 h_port[port_idx].iounit_port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_refresh_sas_ports()
1770 h_port[port_idx].lowest_phy = sasinf->phy_num; in mpi3mr_refresh_sas_ports()
1778 if (mrioc->logging_level & MPI3_DEBUG_RESET) { in mpi3mr_refresh_sas_ports()
1779 ioc_info(mrioc, "Host port details before reset\n"); in mpi3mr_refresh_sas_ports()
1780 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1784 mr_sas_port->hba_port->port_id, in mpi3mr_refresh_sas_ports()
1785 mr_sas_port->remote_identify.sas_address, in mpi3mr_refresh_sas_ports()
1786 mr_sas_port->phy_mask, mr_sas_port->lowest_phy); in mpi3mr_refresh_sas_ports()
1789 ioc_info(mrioc, "Host port details after reset\n"); in mpi3mr_refresh_sas_ports()
1798 /* mark all host sas port entries as dirty */ in mpi3mr_refresh_sas_ports()
1799 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1801 mr_sas_port->marked_responding = 0; in mpi3mr_refresh_sas_ports()
1802 mr_sas_port->hba_port->flags |= MPI3MR_HBA_PORT_FLAG_DIRTY; in mpi3mr_refresh_sas_ports()
1808 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1810 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1812 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1814 if (h_port[i].lowest_phy == mr_sas_port->lowest_phy) { in mpi3mr_refresh_sas_ports()
1826 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1828 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1830 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1832 if (h_port[i].phy_mask & mr_sas_port->phy_mask) { in mpi3mr_refresh_sas_ports()
1839 /* In case if expander cable is removed & connected to another HBA port during reset */ in mpi3mr_refresh_sas_ports()
1844 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1846 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1848 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1860 * mpi3mr_refresh_expanders - Refresh expander device exposure
1864 * missing expander devices during reset and remove from the upper layers
1865 * or expose any newly detected expander device to the upper layers.
1880 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1881 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { in mpi3mr_refresh_expanders()
1882 sas_expander->non_responding = 1; in mpi3mr_refresh_expanders()
1884 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1890 /* Search for responding expander devices and add them if they are newly got added */ in mpi3mr_refresh_expanders()
1918 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1922 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1930 sas_expander->non_responding = 0; in mpi3mr_refresh_expanders()
1931 if (sas_expander->handle == handle) in mpi3mr_refresh_expanders()
1934 sas_expander->handle = handle; in mpi3mr_refresh_expanders()
1935 for (i = 0 ; i < sas_expander->num_phys ; i++) in mpi3mr_refresh_expanders()
1936 sas_expander->phy[i].handle = handle; in mpi3mr_refresh_expanders()
1940 * Delete non responding expander devices and the corresponding in mpi3mr_refresh_expanders()
1941 * hba_port if the non responding expander device's parent device in mpi3mr_refresh_expanders()
1945 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1947 &mrioc->sas_expander_list, list) { in mpi3mr_refresh_expanders()
1948 if (sas_expander->non_responding) { in mpi3mr_refresh_expanders()
1949 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1951 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1954 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1958 * mpi3mr_expander_node_add - insert an expander to the list.
1960 * @sas_expander: Expander sas node
1963 * Adding new object to the ioc->sas_expander_list.
1972 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_add()
1973 list_add_tail(&sas_expander->list, &mrioc->sas_expander_list); in mpi3mr_expander_node_add()
1974 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_add()
1978 * mpi3mr_expander_add - Create expander object
1980 * @handle: Expander firmware device handle
1982 * This function creating expander object, stored in
1986 * Return: 0 for success, non-zero for failure.
2005 return -1; in mpi3mr_expander_add()
2007 if (mrioc->reset_in_progress || mrioc->pci_err_recovery) in mpi3mr_expander_add()
2008 return -1; in mpi3mr_expander_add()
2014 return -1; in mpi3mr_expander_add()
2020 return -1; in mpi3mr_expander_add()
2028 return -1; in mpi3mr_expander_add()
2036 return -1; in mpi3mr_expander_add()
2039 if (sas_address_parent != mrioc->sas_hba.sas_address) { in mpi3mr_expander_add()
2040 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2044 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2051 * When there is a parent expander present, update it's in mpi3mr_expander_add()
2052 * phys where child expander is connected with the link in mpi3mr_expander_add()
2055 for (i = 0 ; i < sas_expander->num_phys ; i++) { in mpi3mr_expander_add()
2066 rc = -1; in mpi3mr_expander_add()
2072 rc = -1; in mpi3mr_expander_add()
2088 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2092 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2100 return -ENOMEM; in mpi3mr_expander_add()
2102 sas_expander->handle = handle; in mpi3mr_expander_add()
2103 sas_expander->num_phys = expander_pg0.num_phys; in mpi3mr_expander_add()
2104 sas_expander->sas_address_parent = sas_address_parent; in mpi3mr_expander_add()
2105 sas_expander->sas_address = sas_address; in mpi3mr_expander_add()
2106 sas_expander->hba_port = hba_port; in mpi3mr_expander_add()
2111 sas_expander->sas_address, sas_expander->num_phys); in mpi3mr_expander_add()
2113 if (!sas_expander->num_phys) { in mpi3mr_expander_add()
2114 rc = -1; in mpi3mr_expander_add()
2117 sas_expander->phy = kcalloc(sas_expander->num_phys, in mpi3mr_expander_add()
2119 if (!sas_expander->phy) { in mpi3mr_expander_add()
2120 rc = -1; in mpi3mr_expander_add()
2124 INIT_LIST_HEAD(&sas_expander->sas_port_list); in mpi3mr_expander_add()
2126 sas_expander->hba_port); in mpi3mr_expander_add()
2130 rc = -1; in mpi3mr_expander_add()
2133 sas_expander->parent_dev = &mr_sas_port->rphy->dev; in mpi3mr_expander_add()
2134 sas_expander->rphy = mr_sas_port->rphy; in mpi3mr_expander_add()
2136 for (i = 0 ; i < sas_expander->num_phys ; i++) { in mpi3mr_expander_add()
2145 rc = -1; in mpi3mr_expander_add()
2151 rc = -1; in mpi3mr_expander_add()
2155 sas_expander->phy[i].handle = handle; in mpi3mr_expander_add()
2156 sas_expander->phy[i].phy_id = i; in mpi3mr_expander_add()
2157 sas_expander->phy[i].hba_port = hba_port; in mpi3mr_expander_add()
2159 if ((mpi3mr_add_expander_phy(mrioc, &sas_expander->phy[i], in mpi3mr_expander_add()
2160 expander_pg1, sas_expander->parent_dev))) { in mpi3mr_expander_add()
2163 rc = -1; in mpi3mr_expander_add()
2168 if (sas_expander->enclosure_handle) { in mpi3mr_expander_add()
2171 sas_expander->enclosure_handle); in mpi3mr_expander_add()
2173 sas_expander->enclosure_logical_id = le64_to_cpu( in mpi3mr_expander_add()
2174 enclosure_dev->pg0.enclosure_logical_id); in mpi3mr_expander_add()
2184 sas_expander->sas_address, in mpi3mr_expander_add()
2185 sas_address_parent, sas_expander->hba_port); in mpi3mr_expander_add()
2186 kfree(sas_expander->phy); in mpi3mr_expander_add()
2192 * mpi3mr_expander_node_remove - recursive removal of expander.
2194 * @sas_expander: Expander device object
2196 * Removes expander object and freeing associated memory from
2198 * one of the attached device is an expander then it recursively
2199 * removes the expander device too.
2210 /* remove sibling ports attached to this expander */ in mpi3mr_expander_node_remove()
2212 &sas_expander->sas_port_list, port_list) { in mpi3mr_expander_node_remove()
2213 if (mrioc->reset_in_progress || mrioc->pci_err_recovery) in mpi3mr_expander_node_remove()
2215 if (mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2218 mr_sas_port->remote_identify.sas_address, in mpi3mr_expander_node_remove()
2219 mr_sas_port->hba_port); in mpi3mr_expander_node_remove()
2220 else if (mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2222 mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2225 mr_sas_port->remote_identify.sas_address, in mpi3mr_expander_node_remove()
2226 mr_sas_port->hba_port); in mpi3mr_expander_node_remove()
2229 port_id = sas_expander->hba_port->port_id; in mpi3mr_expander_node_remove()
2230 mpi3mr_sas_port_remove(mrioc, sas_expander->sas_address, in mpi3mr_expander_node_remove()
2231 sas_expander->sas_address_parent, sas_expander->hba_port); in mpi3mr_expander_node_remove()
2233 ioc_info(mrioc, "expander_remove: handle(0x%04x), sas_addr(0x%016llx), port:%d\n", in mpi3mr_expander_node_remove()
2234 sas_expander->handle, (unsigned long long) in mpi3mr_expander_node_remove()
2235 sas_expander->sas_address, port_id); in mpi3mr_expander_node_remove()
2237 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_remove()
2238 list_del(&sas_expander->list); in mpi3mr_expander_node_remove()
2239 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_remove()
2241 kfree(sas_expander->phy); in mpi3mr_expander_node_remove()
2246 * mpi3mr_expander_remove - Remove expander object
2248 * @sas_address: Remove expander sas_address
2249 * @hba_port: HBA port reference
2251 * This function remove expander object, stored in
2252 * mrioc->sas_expander_list and removes it from the SAS TL by
2263 if (mrioc->reset_in_progress || mrioc->pci_err_recovery) in mpi3mr_expander_remove()
2269 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_remove()
2272 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_remove()
2279 * mpi3mr_get_sas_negotiated_logical_linkrate - get linkrate
2284 * attached directly or through expander and issues sas phy
2285 * page0 or expander phy page1 and gets the link rate, if there
2300 phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; in mpi3mr_get_sas_negotiated_logical_linkrate()
2301 if (!(tgtdev->devpg0_flag & MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)) { in mpi3mr_get_sas_negotiated_logical_linkrate()
2303 | tgtdev->parent_handle); in mpi3mr_get_sas_negotiated_logical_linkrate()
2342 * mpi3mr_report_tgtdev_to_sas_transport - expose dev to SAS TL
2349 * Return: 0 on success, non-zero for failure.
2360 if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || in mpi3mr_report_tgtdev_to_sas_transport()
2361 !mrioc->sas_transport_enabled) in mpi3mr_report_tgtdev_to_sas_transport()
2362 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2364 sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; in mpi3mr_report_tgtdev_to_sas_transport()
2365 if (!mrioc->sas_hba.num_phys) in mpi3mr_report_tgtdev_to_sas_transport()
2370 if (mpi3mr_get_sas_address(mrioc, tgtdev->parent_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2374 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2376 tgtdev->dev_spec.sas_sata_inf.sas_address_parent = sas_address_parent; in mpi3mr_report_tgtdev_to_sas_transport()
2378 parent_phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; in mpi3mr_report_tgtdev_to_sas_transport()
2379 port_id = tgtdev->io_unit_port; in mpi3mr_report_tgtdev_to_sas_transport()
2385 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2387 tgtdev->dev_spec.sas_sata_inf.hba_port = hba_port; in mpi3mr_report_tgtdev_to_sas_transport()
2391 mpi3mr_update_links(mrioc, sas_address_parent, tgtdev->dev_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2394 tgtdev->host_exposed = 1; in mpi3mr_report_tgtdev_to_sas_transport()
2395 if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2397 retval = -1; in mpi3mr_report_tgtdev_to_sas_transport()
2398 } else if ((!tgtdev->starget) && (!mrioc->is_driver_loading)) { in mpi3mr_report_tgtdev_to_sas_transport()
2401 retval = -1; in mpi3mr_report_tgtdev_to_sas_transport()
2404 tgtdev->dev_spec.sas_sata_inf.hba_port = NULL; in mpi3mr_report_tgtdev_to_sas_transport()
2405 tgtdev->host_exposed = 0; in mpi3mr_report_tgtdev_to_sas_transport()
2411 * mpi3mr_remove_tgtdev_from_sas_transport - remove from SAS TL
2425 if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || in mpi3mr_remove_tgtdev_from_sas_transport()
2426 !mrioc->sas_transport_enabled) in mpi3mr_remove_tgtdev_from_sas_transport()
2429 hba_port = tgtdev->dev_spec.sas_sata_inf.hba_port; in mpi3mr_remove_tgtdev_from_sas_transport()
2430 sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; in mpi3mr_remove_tgtdev_from_sas_transport()
2431 sas_address_parent = tgtdev->dev_spec.sas_sata_inf.sas_address_parent; in mpi3mr_remove_tgtdev_from_sas_transport()
2434 tgtdev->host_exposed = 0; in mpi3mr_remove_tgtdev_from_sas_transport()
2435 tgtdev->dev_spec.sas_sata_inf.hba_port = NULL; in mpi3mr_remove_tgtdev_from_sas_transport()
2439 * mpi3mr_get_port_id_by_sas_phy - Get port ID of the given phy
2442 * Return: Port number for valid ID else 0xFFFF
2447 struct mpi3mr_hba_port *hba_port = phy->hostdata; in mpi3mr_get_port_id_by_sas_phy()
2450 port_id = hba_port->port_id; in mpi3mr_get_port_id_by_sas_phy()
2456 * mpi3mr_get_port_id_by_rphy - Get Port number from SAS rphy
2461 * Retrieves HBA port number in which the device pointed by the
2464 * Return: Valid port number on success else OxFFFF.
2476 if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE || in mpi3mr_get_port_id_by_rphy()
2477 rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) { in mpi3mr_get_port_id_by_rphy()
2478 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_get_port_id_by_rphy()
2479 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, in mpi3mr_get_port_id_by_rphy()
2481 if (sas_expander->rphy == rphy) { in mpi3mr_get_port_id_by_rphy()
2482 port_id = sas_expander->hba_port->port_id; in mpi3mr_get_port_id_by_rphy()
2486 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_get_port_id_by_rphy()
2487 } else if (rphy->identify.device_type == SAS_END_DEVICE) { in mpi3mr_get_port_id_by_rphy()
2488 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_get_port_id_by_rphy()
2491 rphy->identify.sas_address, rphy); in mpi3mr_get_port_id_by_rphy()
2492 if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) { in mpi3mr_get_port_id_by_rphy()
2494 tgtdev->dev_spec.sas_sata_inf.hba_port->port_id; in mpi3mr_get_port_id_by_rphy()
2497 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_get_port_id_by_rphy()
2504 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in phy_to_mrioc()
2511 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); in rphy_to_mrioc()
2545 * mpi3mr_get_expander_phy_error_log - return expander counters:
2549 * Return: 0 for success, non-zero for failure.
2569 if (mrioc->reset_in_progress) { in mpi3mr_get_expander_phy_error_log()
2571 return -EFAULT; in mpi3mr_get_expander_phy_error_log()
2574 if (mrioc->pci_err_recovery) { in mpi3mr_get_expander_phy_error_log()
2576 return -EFAULT; in mpi3mr_get_expander_phy_error_log()
2582 data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma, in mpi3mr_get_expander_phy_error_log()
2585 rc = -ENOMEM; in mpi3mr_get_expander_phy_error_log()
2592 rc = -EINVAL; in mpi3mr_get_expander_phy_error_log()
2595 phy_error_log_request->smp_frame_type = 0x40; in mpi3mr_get_expander_phy_error_log()
2596 phy_error_log_request->function = 0x11; in mpi3mr_get_expander_phy_error_log()
2597 phy_error_log_request->request_length = 2; in mpi3mr_get_expander_phy_error_log()
2598 phy_error_log_request->allocated_response_length = 0; in mpi3mr_get_expander_phy_error_log()
2599 phy_error_log_request->phy_identifier = phy->number; in mpi3mr_get_expander_phy_error_log()
2606 mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address); in mpi3mr_get_expander_phy_error_log()
2616 (unsigned long long)phy->identify.sas_address, phy->number); in mpi3mr_get_expander_phy_error_log()
2628 "phy error log - reply data transfer size(%d)\n", in mpi3mr_get_expander_phy_error_log()
2636 "phy error log - function_result(%d)\n", in mpi3mr_get_expander_phy_error_log()
2637 phy_error_log_reply->function_result); in mpi3mr_get_expander_phy_error_log()
2639 phy->invalid_dword_count = in mpi3mr_get_expander_phy_error_log()
2640 be32_to_cpu(phy_error_log_reply->invalid_dword); in mpi3mr_get_expander_phy_error_log()
2641 phy->running_disparity_error_count = in mpi3mr_get_expander_phy_error_log()
2642 be32_to_cpu(phy_error_log_reply->running_disparity_error); in mpi3mr_get_expander_phy_error_log()
2643 phy->loss_of_dword_sync_count = in mpi3mr_get_expander_phy_error_log()
2644 be32_to_cpu(phy_error_log_reply->loss_of_dword_sync); in mpi3mr_get_expander_phy_error_log()
2645 phy->phy_reset_problem_count = in mpi3mr_get_expander_phy_error_log()
2646 be32_to_cpu(phy_error_log_reply->phy_reset_problem); in mpi3mr_get_expander_phy_error_log()
2652 dma_free_coherent(&mrioc->pdev->dev, sz, data_out, in mpi3mr_get_expander_phy_error_log()
2659 * mpi3mr_transport_get_linkerrors - return phy error counters
2663 * HBA or expander for which the phy belongs to
2665 * Return: 0 for success, non-zero for failure.
2678 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_get_linkerrors()
2685 MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number))) { in mpi3mr_transport_get_linkerrors()
2688 return -ENXIO; in mpi3mr_transport_get_linkerrors()
2694 return -ENXIO; in mpi3mr_transport_get_linkerrors()
2696 phy->invalid_dword_count = le32_to_cpu(phy_pg1.invalid_dword_count); in mpi3mr_transport_get_linkerrors()
2697 phy->running_disparity_error_count = in mpi3mr_transport_get_linkerrors()
2699 phy->loss_of_dword_sync_count = in mpi3mr_transport_get_linkerrors()
2701 phy->phy_reset_problem_count = in mpi3mr_transport_get_linkerrors()
2707 * mpi3mr_transport_get_enclosure_identifier - Get Enclosure ID
2714 * Return: 0 on success or -ENXIO
2725 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_enclosure_identifier()
2727 rphy->identify.sas_address, rphy); in mpi3mr_transport_get_enclosure_identifier()
2730 tgtdev->enclosure_logical_id; in mpi3mr_transport_get_enclosure_identifier()
2735 rc = -ENXIO; in mpi3mr_transport_get_enclosure_identifier()
2737 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_enclosure_identifier()
2743 * mpi3mr_transport_get_bay_identifier - Get bay ID
2749 * Return: Valid slot ID on success or -ENXIO
2759 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_bay_identifier()
2761 rphy->identify.sas_address, rphy); in mpi3mr_transport_get_bay_identifier()
2763 rc = tgtdev->slot; in mpi3mr_transport_get_bay_identifier()
2766 rc = -ENXIO; in mpi3mr_transport_get_bay_identifier()
2767 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_bay_identifier()
2802 * mpi3mr_expander_phy_control - expander phy control
2808 * phy operation for a given expander device.
2810 * Return: 0 for success, non-zero for failure.
2833 if (mrioc->reset_in_progress) { in mpi3mr_expander_phy_control()
2835 return -EFAULT; in mpi3mr_expander_phy_control()
2838 if (mrioc->pci_err_recovery) { in mpi3mr_expander_phy_control()
2841 return -EFAULT; in mpi3mr_expander_phy_control()
2847 data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma, in mpi3mr_expander_phy_control()
2850 rc = -ENOMEM; in mpi3mr_expander_phy_control()
2857 rc = -EINVAL; in mpi3mr_expander_phy_control()
2861 phy_control_request->smp_frame_type = 0x40; in mpi3mr_expander_phy_control()
2862 phy_control_request->function = 0x91; in mpi3mr_expander_phy_control()
2863 phy_control_request->request_length = 9; in mpi3mr_expander_phy_control()
2864 phy_control_request->allocated_response_length = 0; in mpi3mr_expander_phy_control()
2865 phy_control_request->phy_identifier = phy->number; in mpi3mr_expander_phy_control()
2866 phy_control_request->phy_operation = phy_operation; in mpi3mr_expander_phy_control()
2867 phy_control_request->programmed_min_physical_link_rate = in mpi3mr_expander_phy_control()
2868 phy->minimum_linkrate << 4; in mpi3mr_expander_phy_control()
2869 phy_control_request->programmed_max_physical_link_rate = in mpi3mr_expander_phy_control()
2870 phy->maximum_linkrate << 4; in mpi3mr_expander_phy_control()
2877 mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address); in mpi3mr_expander_phy_control()
2887 (unsigned long long)phy->identify.sas_address, phy->number, in mpi3mr_expander_phy_control()
2900 "phy control - reply data transfer size(%d)\n", in mpi3mr_expander_phy_control()
2907 "phy control - function_result(%d)\n", in mpi3mr_expander_phy_control()
2908 phy_control_reply->function_result); in mpi3mr_expander_phy_control()
2913 dma_free_coherent(&mrioc->pdev->dev, sz, data_out, in mpi3mr_expander_phy_control()
2920 * mpi3mr_transport_phy_reset - Reset a given phy
2924 * Return: 0 for success, non-zero for failure.
2941 /* handle expander phys */ in mpi3mr_transport_phy_reset()
2942 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_phy_reset()
2956 phy->number; in mpi3mr_transport_phy_reset()
2960 (unsigned long long)phy->identify.sas_address, phy->number, in mpi3mr_transport_phy_reset()
2965 rc = -EAGAIN; in mpi3mr_transport_phy_reset()
2977 * mpi3mr_transport_phy_enable - enable/disable phys
2982 * configuration page changes or expander phy control command
2984 * Return: 0 for success, non-zero for failure.
3000 /* handle expander phys */ in mpi3mr_transport_phy_enable()
3001 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_phy_enable()
3008 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_enable()
3012 rc = -ENOMEM; in mpi3mr_transport_phy_enable()
3018 rc = -ENXIO; in mpi3mr_transport_phy_enable()
3023 for (i = 0, discovery_active = 0; i < mrioc->sas_hba.num_phys ; i++) { in mpi3mr_transport_phy_enable()
3024 if (sas_io_unit_pg0->phy_data[i].port_flags & in mpi3mr_transport_phy_enable()
3027 "discovery is active on port = %d, phy = %d\n" in mpi3mr_transport_phy_enable()
3029 sas_io_unit_pg0->phy_data[i].io_unit_port, i); in mpi3mr_transport_phy_enable()
3035 rc = -EAGAIN; in mpi3mr_transport_phy_enable()
3039 if ((sas_io_unit_pg0->phy_data[phy->number].phy_flags & in mpi3mr_transport_phy_enable()
3044 rc = -ENXIO; in mpi3mr_transport_phy_enable()
3050 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_enable()
3054 rc = -ENOMEM; in mpi3mr_transport_phy_enable()
3061 rc = -ENXIO; in mpi3mr_transport_phy_enable()
3066 sas_io_unit_pg1->phy_data[phy->number].phy_flags in mpi3mr_transport_phy_enable()
3069 sas_io_unit_pg1->phy_data[phy->number].phy_flags in mpi3mr_transport_phy_enable()
3085 * mpi3mr_transport_phy_speed - set phy min/max speed
3091 * page changes or expander phy control command
3093 * Return: 0 for success, non-zero for failure.
3108 if (!rates->minimum_linkrate) in mpi3mr_transport_phy_speed()
3109 rates->minimum_linkrate = phy->minimum_linkrate; in mpi3mr_transport_phy_speed()
3110 else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) in mpi3mr_transport_phy_speed()
3111 rates->minimum_linkrate = phy->minimum_linkrate_hw; in mpi3mr_transport_phy_speed()
3113 if (!rates->maximum_linkrate) in mpi3mr_transport_phy_speed()
3114 rates->maximum_linkrate = phy->maximum_linkrate; in mpi3mr_transport_phy_speed()
3115 else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) in mpi3mr_transport_phy_speed()
3116 rates->maximum_linkrate = phy->maximum_linkrate_hw; in mpi3mr_transport_phy_speed()
3118 /* handle expander phys */ in mpi3mr_transport_phy_speed()
3119 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) { in mpi3mr_transport_phy_speed()
3120 phy->minimum_linkrate = rates->minimum_linkrate; in mpi3mr_transport_phy_speed()
3121 phy->maximum_linkrate = rates->maximum_linkrate; in mpi3mr_transport_phy_speed()
3128 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_speed()
3132 rc = -ENOMEM; in mpi3mr_transport_phy_speed()
3139 rc = -ENXIO; in mpi3mr_transport_phy_speed()
3143 sas_io_unit_pg1->phy_data[phy->number].max_min_link_rate = in mpi3mr_transport_phy_speed()
3144 (rates->minimum_linkrate + (rates->maximum_linkrate << 4)); in mpi3mr_transport_phy_speed()
3149 rc = -ENXIO; in mpi3mr_transport_phy_speed()
3159 MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number) && in mpi3mr_transport_phy_speed()
3161 phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_transport_phy_speed()
3164 phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_transport_phy_speed()
3166 phy->negotiated_linkrate = in mpi3mr_transport_phy_speed()
3179 * mpi3mr_map_smp_buffer - map BSG dma buffer
3188 * Return: 0 on success, non-zero on failure
3195 if (buf->sg_cnt > 1) { in mpi3mr_map_smp_buffer()
3196 *p = dma_alloc_coherent(dev, buf->payload_len, dma_addr, in mpi3mr_map_smp_buffer()
3199 return -ENOMEM; in mpi3mr_map_smp_buffer()
3200 *dma_len = buf->payload_len; in mpi3mr_map_smp_buffer()
3202 if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL)) in mpi3mr_map_smp_buffer()
3203 return -ENOMEM; in mpi3mr_map_smp_buffer()
3204 *dma_addr = sg_dma_address(buf->sg_list); in mpi3mr_map_smp_buffer()
3205 *dma_len = sg_dma_len(buf->sg_list); in mpi3mr_map_smp_buffer()
3213 * mpi3mr_unmap_smp_buffer - unmap BSG dma buffer
3226 dma_free_coherent(dev, buf->payload_len, p, dma_addr); in mpi3mr_unmap_smp_buffer()
3228 dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL); in mpi3mr_unmap_smp_buffer()
3232 * mpi3mr_transport_smp_handler - handler for smp passthru
3235 * @rphy: SAS transport rphy object pointing the expander
3261 if (mrioc->reset_in_progress) { in mpi3mr_transport_smp_handler()
3263 rc = -EFAULT; in mpi3mr_transport_smp_handler()
3267 if (mrioc->pci_err_recovery) { in mpi3mr_transport_smp_handler()
3269 rc = -EFAULT; in mpi3mr_transport_smp_handler()
3273 rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->request_payload, in mpi3mr_transport_smp_handler()
3279 sg_copy_to_buffer(job->request_payload.sg_list, in mpi3mr_transport_smp_handler()
3280 job->request_payload.sg_cnt, addr_out, in mpi3mr_transport_smp_handler()
3281 job->request_payload.payload_len); in mpi3mr_transport_smp_handler()
3283 rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->reply_payload, in mpi3mr_transport_smp_handler()
3294 cpu_to_le64(rphy->identify.sas_address) : in mpi3mr_transport_smp_handler()
3295 cpu_to_le64(mrioc->sas_hba.sas_address)); in mpi3mr_transport_smp_handler()
3297 mpi3mr_add_sg_single(psge, sgl_flags, dma_len_out - 4, dma_addr_out); in mpi3mr_transport_smp_handler()
3300 mpi3mr_add_sg_single(psge, sgl_flags, dma_len_in - 4, dma_addr_in); in mpi3mr_transport_smp_handler()
3314 "SMP request - reply data transfer size(%d)\n", in mpi3mr_transport_smp_handler()
3317 memcpy(job->reply, &mpi_reply, reply_sz); in mpi3mr_transport_smp_handler()
3318 job->reply_len = reply_sz; in mpi3mr_transport_smp_handler()
3322 sg_copy_from_buffer(job->reply_payload.sg_list, in mpi3mr_transport_smp_handler()
3323 job->reply_payload.sg_cnt, addr_in, in mpi3mr_transport_smp_handler()
3324 job->reply_payload.payload_len); in mpi3mr_transport_smp_handler()
3328 mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->reply_payload, in mpi3mr_transport_smp_handler()
3331 mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->request_payload, in mpi3mr_transport_smp_handler()