Lines Matching +full:phy +full:- +full:device

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) 2017-2022 Broadcom Inc.
6 * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com)
16 * mpi3mr_post_transport_req - Issue transport requests and wait
34 * Return: 0 on success, non-zero on failure.
42 mutex_lock(&mrioc->transport_cmds.mutex); in mpi3mr_post_transport_req()
43 if (mrioc->transport_cmds.state & MPI3MR_CMD_PENDING) { in mpi3mr_post_transport_req()
44 retval = -1; in mpi3mr_post_transport_req()
46 mutex_unlock(&mrioc->transport_cmds.mutex); in mpi3mr_post_transport_req()
49 mrioc->transport_cmds.state = MPI3MR_CMD_PENDING; in mpi3mr_post_transport_req()
50 mrioc->transport_cmds.is_waiting = 1; in mpi3mr_post_transport_req()
51 mrioc->transport_cmds.callback = NULL; in mpi3mr_post_transport_req()
52 mrioc->transport_cmds.ioc_status = 0; in mpi3mr_post_transport_req()
53 mrioc->transport_cmds.ioc_loginfo = 0; in mpi3mr_post_transport_req()
55 init_completion(&mrioc->transport_cmds.done); in mpi3mr_post_transport_req()
57 if (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO) in mpi3mr_post_transport_req()
64 wait_for_completion_timeout(&mrioc->transport_cmds.done, in mpi3mr_post_transport_req()
66 if (!(mrioc->transport_cmds.state & MPI3MR_CMD_COMPLETE)) { in mpi3mr_post_transport_req()
70 retval = -1; in mpi3mr_post_transport_req()
73 *ioc_status = mrioc->transport_cmds.ioc_status & in mpi3mr_post_transport_req()
78 *ioc_status, mrioc->transport_cmds.ioc_loginfo); in mpi3mr_post_transport_req()
80 if ((reply) && (mrioc->transport_cmds.state & MPI3MR_CMD_REPLY_VALID)) in mpi3mr_post_transport_req()
81 memcpy((u8 *)reply, mrioc->transport_cmds.reply, reply_sz); in mpi3mr_post_transport_req()
84 mrioc->transport_cmds.state = MPI3MR_CMD_NOTUSED; in mpi3mr_post_transport_req()
85 mutex_unlock(&mrioc->transport_cmds.mutex); in mpi3mr_post_transport_req()
120 * mpi3mr_report_manufacture - obtain SMP report_manufacture
122 * @sas_address: SAS address of the expander device
128 * Return: 0 for success, non-zero for failure.
150 if (mrioc->reset_in_progress) { in mpi3mr_report_manufacture()
152 return -EFAULT; in mpi3mr_report_manufacture()
157 data_out = dma_alloc_coherent(&mrioc->pdev->dev, in mpi3mr_report_manufacture()
160 rc = -ENOMEM; in mpi3mr_report_manufacture()
168 manufacture_request->smp_frame_type = 0x40; in mpi3mr_report_manufacture()
169 manufacture_request->function = 1; in mpi3mr_report_manufacture()
170 manufacture_request->reserved = 0; in mpi3mr_report_manufacture()
171 manufacture_request->request_length = 0; in mpi3mr_report_manufacture()
201 rc = -EINVAL; in mpi3mr_report_manufacture()
206 "report manufacturer - reply data transfer size(%d)\n", in mpi3mr_report_manufacture()
211 rc = -EINVAL; in mpi3mr_report_manufacture()
215 strscpy(edev->vendor_id, manufacture_reply->vendor_id, in mpi3mr_report_manufacture()
217 strscpy(edev->product_id, manufacture_reply->product_id, in mpi3mr_report_manufacture()
219 strscpy(edev->product_rev, manufacture_reply->product_rev, in mpi3mr_report_manufacture()
221 edev->level = manufacture_reply->sas_format & 1; in mpi3mr_report_manufacture()
222 if (edev->level) { in mpi3mr_report_manufacture()
223 strscpy(edev->component_vendor_id, in mpi3mr_report_manufacture()
224 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
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
270 * @device_info: Bitfield providing information about the device
272 * Return: 1 if the device is expander device, else 0.
284 * mpi3mr_get_sas_address - retrieve sas_address for handle
286 * @handle: Firmware device handle
289 * This function issues device page0 read for a given device
292 * Return: 0 for success, non-zero for failure
306 ioc_err(mrioc, "%s: device page0 read failed\n", __func__); in mpi3mr_get_sas_address()
307 return -ENXIO; in mpi3mr_get_sas_address()
311 …ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:… 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
333 * @sas_address: SAS address of the device
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
362 * @sas_address: SAS address of the device
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
393 * @sas_address: SAS address of the device
396 * This searches for target device using sas address and hba
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
432 * @sas_address: SAS address of the device
435 * This searches for target device from sas address and rphy
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
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
492 * Context: Caller should acquire mrioc->sas_node_lock.
494 * If the SAS address indicates the device is direct attached to
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
518 * @phy: SAS transport layer phy object
520 * Return: 0 if parent is present else non-zero
522 static int mpi3mr_parent_present(struct mpi3mr_ioc *mrioc, struct sas_phy *phy) in mpi3mr_parent_present() argument
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
592 * @mr_sas_phy: Internal Phy object
600 u64 sas_address = mr_sas_port->remote_identify.sas_address; in mpi3mr_delete_sas_phy()
602 dev_info(&mr_sas_phy->phy->dev, in mpi3mr_delete_sas_phy()
603 "remove: sas_address(0x%016llx), phy(%d)\n", in mpi3mr_delete_sas_phy()
604 (unsigned long long) sas_address, mr_sas_phy->phy_id); in mpi3mr_delete_sas_phy()
606 list_del(&mr_sas_phy->port_siblings); in mpi3mr_delete_sas_phy()
607 mr_sas_port->num_phys--; in mpi3mr_delete_sas_phy()
608 mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); in mpi3mr_delete_sas_phy()
609 if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) in mpi3mr_delete_sas_phy()
610 mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; in mpi3mr_delete_sas_phy()
611 sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); in mpi3mr_delete_sas_phy()
612 mr_sas_phy->phy_belongs_to_port = 0; in mpi3mr_delete_sas_phy()
616 * mpi3mr_add_sas_phy - Adding a single phy to a port
619 * @mr_sas_phy: Internal Phy object
627 u64 sas_address = mr_sas_port->remote_identify.sas_address; in mpi3mr_add_sas_phy()
629 dev_info(&mr_sas_phy->phy->dev, in mpi3mr_add_sas_phy()
630 "add: sas_address(0x%016llx), phy(%d)\n", (unsigned long long) in mpi3mr_add_sas_phy()
631 sas_address, mr_sas_phy->phy_id); in mpi3mr_add_sas_phy()
633 list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); in mpi3mr_add_sas_phy()
634 mr_sas_port->num_phys++; in mpi3mr_add_sas_phy()
635 mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); in mpi3mr_add_sas_phy()
636 if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) in mpi3mr_add_sas_phy()
637 mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; in mpi3mr_add_sas_phy()
638 sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); in mpi3mr_add_sas_phy()
639 mr_sas_phy->phy_belongs_to_port = 1; in mpi3mr_add_sas_phy()
643 * mpi3mr_add_phy_to_an_existing_port - add phy to existing port
646 * @mr_sas_phy: Internal Phy object *
647 * @sas_address: SAS address of device/expander were phy needs
660 if (mr_sas_phy->phy_belongs_to_port == 1) in mpi3mr_add_phy_to_an_existing_port()
666 list_for_each_entry(mr_sas_port, &mr_sas_node->sas_port_list, in mpi3mr_add_phy_to_an_existing_port()
668 if (mr_sas_port->remote_identify.sas_address != in mpi3mr_add_phy_to_an_existing_port()
671 if (mr_sas_port->hba_port != hba_port) in mpi3mr_add_phy_to_an_existing_port()
673 list_for_each_entry(srch_phy, &mr_sas_port->phy_list, in mpi3mr_add_phy_to_an_existing_port()
684 * mpi3mr_delete_sas_port - helper function to removing a port
693 u64 sas_address = mr_sas_port->remote_identify.sas_address; in mpi3mr_delete_sas_port()
694 struct mpi3mr_hba_port *hba_port = mr_sas_port->hba_port; in mpi3mr_delete_sas_port()
696 mr_sas_port->remote_identify.device_type; in mpi3mr_delete_sas_port()
698 dev_info(&mr_sas_port->port->dev, in mpi3mr_delete_sas_port()
712 * mpi3mr_del_phy_from_an_existing_port - del phy from a port
715 * @mr_sas_phy: Internal Phy object
725 if (mr_sas_phy->phy_belongs_to_port == 0) in mpi3mr_del_phy_from_an_existing_port()
728 list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list, in mpi3mr_del_phy_from_an_existing_port()
730 list_for_each_entry(srch_phy, &mr_sas_port->phy_list, in mpi3mr_del_phy_from_an_existing_port()
734 if ((mr_sas_port->num_phys == 1) && in mpi3mr_del_phy_from_an_existing_port()
735 !mrioc->reset_in_progress) in mpi3mr_del_phy_from_an_existing_port()
746 * mpi3mr_sas_port_sanity_check - sanity check while adding port
749 * @sas_address: SAS address of device/expander
752 * Verifies whether the Phys attached to a device with the given
764 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_sanity_check()
765 if ((mr_sas_node->phy[i].remote_identify.sas_address != in mpi3mr_sas_port_sanity_check()
766 sas_address) || (mr_sas_node->phy[i].hba_port != hba_port)) in mpi3mr_sas_port_sanity_check()
768 if (mr_sas_node->phy[i].phy_belongs_to_port == 1) in mpi3mr_sas_port_sanity_check()
770 mr_sas_node, &mr_sas_node->phy[i]); in mpi3mr_sas_port_sanity_check()
775 * mpi3mr_set_identify - set identify for phys and end devices
777 * @handle: Firmware device handle
780 * Populates sas identify info for a specific device.
782 * Return: 0 for success, non-zero for failure.
793 if (mrioc->reset_in_progress) { in mpi3mr_set_identify()
795 return -EFAULT; in mpi3mr_set_identify()
800 ioc_err(mrioc, "%s: device page0 read failed\n", __func__); in mpi3mr_set_identify()
801 return -ENXIO; in mpi3mr_set_identify()
805 …ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:… in mpi3mr_set_identify()
807 return -EIO; in mpi3mr_set_identify()
812 device_info = le16_to_cpu(sasinf->device_info); in mpi3mr_set_identify()
815 identify->sas_address = le64_to_cpu(sasinf->sas_address); in mpi3mr_set_identify()
817 /* phy number of the parent device this device is linked to */ in mpi3mr_set_identify()
818 identify->phy_identifier = sasinf->phy_num; in mpi3mr_set_identify()
823 identify->device_type = SAS_PHY_UNUSED; in mpi3mr_set_identify()
826 identify->device_type = SAS_END_DEVICE; in mpi3mr_set_identify()
829 identify->device_type = SAS_EDGE_EXPANDER_DEVICE; in mpi3mr_set_identify()
835 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP; in mpi3mr_set_identify()
838 identify->initiator_port_protocols |= (SAS_PROTOCOL_STP | in mpi3mr_set_identify()
841 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP; in mpi3mr_set_identify()
845 identify->target_port_protocols |= SAS_PROTOCOL_SSP; in mpi3mr_set_identify()
848 identify->target_port_protocols |= (SAS_PROTOCOL_STP | in mpi3mr_set_identify()
851 identify->target_port_protocols |= SAS_PROTOCOL_SMP; in mpi3mr_set_identify()
856 * mpi3mr_add_host_phy - report sas_host phy to SAS transport
858 * @mr_sas_phy: Internal Phy object
859 * @phy_pg0: SAS phy page 0
860 * @parent_dev: Prent device class object
862 * Return: 0 for success, non-zero for failure.
866 struct device *parent_dev) in mpi3mr_add_host_phy()
868 struct sas_phy *phy; in mpi3mr_add_host_phy() local
869 int phy_index = mr_sas_phy->phy_id; in mpi3mr_add_host_phy()
872 INIT_LIST_HEAD(&mr_sas_phy->port_siblings); in mpi3mr_add_host_phy()
873 phy = sas_phy_alloc(parent_dev, phy_index); in mpi3mr_add_host_phy()
874 if (!phy) { in mpi3mr_add_host_phy()
877 return -1; in mpi3mr_add_host_phy()
879 if ((mpi3mr_set_identify(mrioc, mr_sas_phy->handle, in mpi3mr_add_host_phy()
880 &mr_sas_phy->identify))) { in mpi3mr_add_host_phy()
883 sas_phy_free(phy); in mpi3mr_add_host_phy()
884 return -1; in mpi3mr_add_host_phy()
886 phy->identify = mr_sas_phy->identify; in mpi3mr_add_host_phy()
887 mr_sas_phy->attached_handle = le16_to_cpu(phy_pg0.attached_dev_handle); in mpi3mr_add_host_phy()
888 if (mr_sas_phy->attached_handle) in mpi3mr_add_host_phy()
889 mpi3mr_set_identify(mrioc, mr_sas_phy->attached_handle, in mpi3mr_add_host_phy()
890 &mr_sas_phy->remote_identify); in mpi3mr_add_host_phy()
891 phy->identify.phy_identifier = mr_sas_phy->phy_id; in mpi3mr_add_host_phy()
892 phy->negotiated_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
896 phy->minimum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
898 phy->maximum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
900 phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
902 phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
904 phy->hostdata = mr_sas_phy->hba_port; in mpi3mr_add_host_phy()
906 if ((sas_phy_add(phy))) { in mpi3mr_add_host_phy()
909 sas_phy_free(phy); in mpi3mr_add_host_phy()
910 return -1; in mpi3mr_add_host_phy()
912 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_add_host_phy()
913 dev_info(&phy->dev, in mpi3mr_add_host_phy()
916 mr_sas_phy->handle, (unsigned long long) in mpi3mr_add_host_phy()
917 mr_sas_phy->identify.sas_address, in mpi3mr_add_host_phy()
918 mr_sas_phy->attached_handle, in mpi3mr_add_host_phy()
920 mr_sas_phy->remote_identify.sas_address); in mpi3mr_add_host_phy()
921 mr_sas_phy->phy = phy; in mpi3mr_add_host_phy()
926 * mpi3mr_add_expander_phy - report expander phy to transport
928 * @mr_sas_phy: Internal Phy object
930 * @parent_dev: Parent device class object
932 * Return: 0 for success, non-zero for failure.
937 struct device *parent_dev) in mpi3mr_add_expander_phy()
939 struct sas_phy *phy; in mpi3mr_add_expander_phy() local
940 int phy_index = mr_sas_phy->phy_id; in mpi3mr_add_expander_phy()
942 INIT_LIST_HEAD(&mr_sas_phy->port_siblings); in mpi3mr_add_expander_phy()
943 phy = sas_phy_alloc(parent_dev, phy_index); in mpi3mr_add_expander_phy()
944 if (!phy) { in mpi3mr_add_expander_phy()
947 return -1; in mpi3mr_add_expander_phy()
949 if ((mpi3mr_set_identify(mrioc, mr_sas_phy->handle, in mpi3mr_add_expander_phy()
950 &mr_sas_phy->identify))) { in mpi3mr_add_expander_phy()
953 sas_phy_free(phy); in mpi3mr_add_expander_phy()
954 return -1; in mpi3mr_add_expander_phy()
956 phy->identify = mr_sas_phy->identify; in mpi3mr_add_expander_phy()
957 mr_sas_phy->attached_handle = in mpi3mr_add_expander_phy()
959 if (mr_sas_phy->attached_handle) in mpi3mr_add_expander_phy()
960 mpi3mr_set_identify(mrioc, mr_sas_phy->attached_handle, in mpi3mr_add_expander_phy()
961 &mr_sas_phy->remote_identify); in mpi3mr_add_expander_phy()
962 phy->identify.phy_identifier = mr_sas_phy->phy_id; in mpi3mr_add_expander_phy()
963 phy->negotiated_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
967 phy->minimum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
969 phy->maximum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
971 phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
973 phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
975 phy->hostdata = mr_sas_phy->hba_port; in mpi3mr_add_expander_phy()
977 if ((sas_phy_add(phy))) { in mpi3mr_add_expander_phy()
980 sas_phy_free(phy); in mpi3mr_add_expander_phy()
981 return -1; in mpi3mr_add_expander_phy()
983 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_add_expander_phy()
984 dev_info(&phy->dev, in mpi3mr_add_expander_phy()
987 mr_sas_phy->handle, (unsigned long long) in mpi3mr_add_expander_phy()
988 mr_sas_phy->identify.sas_address, in mpi3mr_add_expander_phy()
989 mr_sas_phy->attached_handle, in mpi3mr_add_expander_phy()
991 mr_sas_phy->remote_identify.sas_address); in mpi3mr_add_expander_phy()
992 mr_sas_phy->phy = phy; in mpi3mr_add_expander_phy()
997 * mpi3mr_alloc_hba_port - alloc hba port object
1012 hba_port->port_id = port_id; in mpi3mr_alloc_hba_port()
1014 hba_port, hba_port->port_id); in mpi3mr_alloc_hba_port()
1015 list_add_tail(&hba_port->list, &mrioc->hba_port_table_list); in mpi3mr_alloc_hba_port()
1020 * mpi3mr_get_hba_port_by_id - find hba port by id
1022 * @port_id - Port ID to search
1033 &mrioc->hba_port_table_list, list) { in mpi3mr_get_hba_port_by_id()
1034 if (port->port_id != port_id) in mpi3mr_get_hba_port_by_id()
1036 if (port->flags & MPI3MR_HBA_PORT_FLAG_DIRTY) in mpi3mr_get_hba_port_by_id()
1045 * mpi3mr_update_links - refreshing SAS phy link changes
1048 * @handle: Firmware device handle of attached device
1049 * @phy_number: Phy number
1063 if (mrioc->reset_in_progress) in mpi3mr_update_links()
1066 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_update_links()
1070 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_update_links()
1074 mr_sas_phy = &mr_sas_node->phy[phy_number]; in mpi3mr_update_links()
1075 mr_sas_phy->attached_handle = handle; in mpi3mr_update_links()
1076 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_update_links()
1079 &mr_sas_phy->remote_identify); in mpi3mr_update_links()
1081 mr_sas_phy, mr_sas_phy->remote_identify.sas_address, in mpi3mr_update_links()
1084 memset(&mr_sas_phy->remote_identify, 0, sizeof(struct in mpi3mr_update_links()
1087 if (mr_sas_phy->phy) in mpi3mr_update_links()
1088 mr_sas_phy->phy->negotiated_linkrate = in mpi3mr_update_links()
1091 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_update_links()
1092 dev_info(&mr_sas_phy->phy->dev, in mpi3mr_update_links()
1094 "\tlink_rate(0x%02x), phy(%d)\n" in mpi3mr_update_links()
1098 mr_sas_phy->remote_identify.sas_address); in mpi3mr_update_links()
1102 * mpi3mr_sas_host_refresh - refreshing sas host object contents
1105 * This function refreshes the controllers phy information and
1107 * this is executed for each device addition or device info
1121 (unsigned long long)mrioc->sas_hba.sas_address); in mpi3mr_sas_host_refresh()
1124 (mrioc->sas_hba.num_phys * in mpi3mr_sas_host_refresh()
1135 mrioc->sas_hba.handle = 0; in mpi3mr_sas_host_refresh()
1136 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_sas_host_refresh()
1137 if (sas_io_unit_pg0->phy_data[i].phy_flags & in mpi3mr_sas_host_refresh()
1142 sas_io_unit_pg0->phy_data[i].negotiated_link_rate >> 4; in mpi3mr_sas_host_refresh()
1143 if (!mrioc->sas_hba.handle) in mpi3mr_sas_host_refresh()
1144 mrioc->sas_hba.handle = le16_to_cpu( in mpi3mr_sas_host_refresh()
1145 sas_io_unit_pg0->phy_data[i].controller_dev_handle); in mpi3mr_sas_host_refresh()
1146 port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_sas_host_refresh()
1151 mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle; in mpi3mr_sas_host_refresh()
1153 sas_io_unit_pg0->phy_data[i].attached_dev_handle); in mpi3mr_sas_host_refresh()
1156 mrioc->sas_hba.phy[i].hba_port = in mpi3mr_sas_host_refresh()
1158 mpi3mr_update_links(mrioc, mrioc->sas_hba.sas_address, in mpi3mr_sas_host_refresh()
1160 mrioc->sas_hba.phy[i].hba_port); in mpi3mr_sas_host_refresh()
1167 * mpi3mr_sas_host_add - create sas host object
1170 * This function creates the controllers phy information and
1172 * this is executed for first device addition or device info
1198 num_phys = sas_io_unit_pg0->num_phys; in mpi3mr_sas_host_add()
1201 mrioc->sas_hba.host_node = 1; in mpi3mr_sas_host_add()
1202 INIT_LIST_HEAD(&mrioc->sas_hba.sas_port_list); in mpi3mr_sas_host_add()
1203 mrioc->sas_hba.parent_dev = &mrioc->shost->shost_gendev; in mpi3mr_sas_host_add()
1204 mrioc->sas_hba.phy = kcalloc(num_phys, in mpi3mr_sas_host_add()
1206 if (!mrioc->sas_hba.phy) in mpi3mr_sas_host_add()
1209 mrioc->sas_hba.num_phys = num_phys; in mpi3mr_sas_host_add()
1223 mrioc->sas_hba.handle = 0; in mpi3mr_sas_host_add()
1224 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_sas_host_add()
1225 if (sas_io_unit_pg0->phy_data[i].phy_flags & in mpi3mr_sas_host_add()
1242 if (!mrioc->sas_hba.handle) in mpi3mr_sas_host_add()
1243 mrioc->sas_hba.handle = le16_to_cpu( in mpi3mr_sas_host_add()
1244 sas_io_unit_pg0->phy_data[i].controller_dev_handle); in mpi3mr_sas_host_add()
1245 port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_sas_host_add()
1251 mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle; in mpi3mr_sas_host_add()
1252 mrioc->sas_hba.phy[i].phy_id = i; in mpi3mr_sas_host_add()
1253 mrioc->sas_hba.phy[i].hba_port = in mpi3mr_sas_host_add()
1255 mpi3mr_add_host_phy(mrioc, &mrioc->sas_hba.phy[i], in mpi3mr_sas_host_add()
1256 phy_pg0, mrioc->sas_hba.parent_dev); in mpi3mr_sas_host_add()
1260 mrioc->sas_hba.handle))) { in mpi3mr_sas_host_add()
1261 ioc_err(mrioc, "%s: device page0 read failed\n", __func__); in mpi3mr_sas_host_add()
1265 …ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:… in mpi3mr_sas_host_add()
1266 mrioc->sas_hba.handle, ioc_status, __FILE__, __LINE__, in mpi3mr_sas_host_add()
1270 mrioc->sas_hba.enclosure_handle = in mpi3mr_sas_host_add()
1273 mrioc->sas_hba.sas_address = in mpi3mr_sas_host_add()
1274 le64_to_cpu(sasinf->sas_address); in mpi3mr_sas_host_add()
1277 mrioc->sas_hba.handle, in mpi3mr_sas_host_add()
1278 (unsigned long long) mrioc->sas_hba.sas_address, in mpi3mr_sas_host_add()
1279 mrioc->sas_hba.num_phys); in mpi3mr_sas_host_add()
1281 if (mrioc->sas_hba.enclosure_handle) { in mpi3mr_sas_host_add()
1285 mrioc->sas_hba.enclosure_handle)) && in mpi3mr_sas_host_add()
1287 mrioc->sas_hba.enclosure_logical_id = in mpi3mr_sas_host_add()
1296 * mpi3mr_sas_port_add - Expose the SAS device to the SAS TL
1298 * @handle: Firmware device handle of the attached device
1303 * device matching sas address and hba_port and adds it to the
1304 * sas_node's sas_port_list and expose the attached sas device
1331 INIT_LIST_HEAD(&mr_sas_port->port_list); in mpi3mr_sas_port_add()
1332 INIT_LIST_HEAD(&mr_sas_port->phy_list); in mpi3mr_sas_port_add()
1333 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1336 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1345 &mr_sas_port->remote_identify))) { in mpi3mr_sas_port_add()
1351 if (mr_sas_port->remote_identify.device_type == SAS_PHY_UNUSED) { in mpi3mr_sas_port_add()
1357 mr_sas_port->hba_port = hba_port; in mpi3mr_sas_port_add()
1359 mr_sas_port->remote_identify.sas_address, hba_port); in mpi3mr_sas_port_add()
1361 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_add()
1362 if ((mr_sas_node->phy[i].remote_identify.sas_address != in mpi3mr_sas_port_add()
1363 mr_sas_port->remote_identify.sas_address) || in mpi3mr_sas_port_add()
1364 (mr_sas_node->phy[i].hba_port != hba_port)) in mpi3mr_sas_port_add()
1366 list_add_tail(&mr_sas_node->phy[i].port_siblings, in mpi3mr_sas_port_add()
1367 &mr_sas_port->phy_list); in mpi3mr_sas_port_add()
1368 mr_sas_port->num_phys++; in mpi3mr_sas_port_add()
1369 mr_sas_port->phy_mask |= (1 << i); in mpi3mr_sas_port_add()
1372 if (!mr_sas_port->num_phys) { in mpi3mr_sas_port_add()
1378 mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; in mpi3mr_sas_port_add()
1380 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1382 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1383 mr_sas_port->hba_port); in mpi3mr_sas_port_add()
1390 tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 1; in mpi3mr_sas_port_add()
1393 if (!mr_sas_node->parent_dev) { in mpi3mr_sas_port_add()
1399 port = sas_port_alloc_num(mr_sas_node->parent_dev); in mpi3mr_sas_port_add()
1406 list_for_each_entry(mr_sas_phy, &mr_sas_port->phy_list, in mpi3mr_sas_port_add()
1408 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_sas_port_add()
1409 dev_info(&port->dev, in mpi3mr_sas_port_add()
1410 "add: handle(0x%04x), sas_address(0x%016llx), phy(%d)\n", in mpi3mr_sas_port_add()
1412 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1413 mr_sas_phy->phy_id); in mpi3mr_sas_port_add()
1414 sas_port_add_phy(port, mr_sas_phy->phy); in mpi3mr_sas_port_add()
1415 mr_sas_phy->phy_belongs_to_port = 1; in mpi3mr_sas_port_add()
1416 mr_sas_phy->hba_port = hba_port; in mpi3mr_sas_port_add()
1419 mr_sas_port->port = port; in mpi3mr_sas_port_add()
1420 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1422 tgtdev->dev_spec.sas_sata_inf.rphy = rphy; in mpi3mr_sas_port_add()
1425 mr_sas_port->remote_identify.device_type); in mpi3mr_sas_port_add()
1427 rphy->identify = mr_sas_port->remote_identify; in mpi3mr_sas_port_add()
1429 if (mrioc->current_event) in mpi3mr_sas_port_add()
1430 mrioc->current_event->pending_at_sml = 1; in mpi3mr_sas_port_add()
1436 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1437 tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 0; in mpi3mr_sas_port_add()
1438 tgtdev->dev_spec.sas_sata_inf.sas_transport_attached = 1; in mpi3mr_sas_port_add()
1442 dev_info(&rphy->dev, in mpi3mr_sas_port_add()
1445 mr_sas_port->remote_identify.sas_address); in mpi3mr_sas_port_add()
1447 mr_sas_port->rphy = rphy; in mpi3mr_sas_port_add()
1448 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1449 list_add_tail(&mr_sas_port->port_list, &mr_sas_node->sas_port_list); in mpi3mr_sas_port_add()
1450 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1452 if (mrioc->current_event) { in mpi3mr_sas_port_add()
1453 mrioc->current_event->pending_at_sml = 0; in mpi3mr_sas_port_add()
1454 if (mrioc->current_event->discard) in mpi3mr_sas_port_add()
1459 if (mr_sas_port->remote_identify.device_type == in mpi3mr_sas_port_add()
1461 mr_sas_port->remote_identify.device_type == in mpi3mr_sas_port_add()
1464 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1465 rphy_to_expander_device(rphy), hba_port->port_id); in mpi3mr_sas_port_add()
1470 list_for_each_entry_safe(mr_sas_phy, next, &mr_sas_port->phy_list, in mpi3mr_sas_port_add()
1472 list_del(&mr_sas_phy->port_siblings); in mpi3mr_sas_port_add()
1478 * mpi3mr_sas_port_remove - remove port from the list
1480 * @sas_address: SAS address of attached device
1503 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1507 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1510 list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list, in mpi3mr_sas_port_remove()
1512 if (mr_sas_port->remote_identify.sas_address != sas_address) in mpi3mr_sas_port_remove()
1514 if (mr_sas_port->hba_port != hba_port) in mpi3mr_sas_port_remove()
1517 list_del(&mr_sas_port->port_list); in mpi3mr_sas_port_remove()
1523 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1527 if (mr_sas_node->host_node) { in mpi3mr_sas_port_remove()
1529 &mrioc->hba_port_table_list, list) { in mpi3mr_sas_port_remove()
1534 srch_port, srch_port->port_id); in mpi3mr_sas_port_remove()
1535 list_del(&hba_port->list); in mpi3mr_sas_port_remove()
1541 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_remove()
1542 if (mr_sas_node->phy[i].remote_identify.sas_address == in mpi3mr_sas_port_remove()
1544 memset(&mr_sas_node->phy[i].remote_identify, 0, in mpi3mr_sas_port_remove()
1548 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1550 if (mrioc->current_event) in mpi3mr_sas_port_remove()
1551 mrioc->current_event->pending_at_sml = 1; in mpi3mr_sas_port_remove()
1554 &mr_sas_port->phy_list, port_siblings) { in mpi3mr_sas_port_remove()
1555 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_sas_port_remove()
1556 dev_info(&mr_sas_port->port->dev, in mpi3mr_sas_port_remove()
1557 "remove: sas_address(0x%016llx), phy(%d)\n", in mpi3mr_sas_port_remove()
1559 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_remove()
1560 mr_sas_phy->phy_id); in mpi3mr_sas_port_remove()
1561 mr_sas_phy->phy_belongs_to_port = 0; in mpi3mr_sas_port_remove()
1562 if (!mrioc->stop_drv_processing) in mpi3mr_sas_port_remove()
1563 sas_port_delete_phy(mr_sas_port->port, in mpi3mr_sas_port_remove()
1564 mr_sas_phy->phy); in mpi3mr_sas_port_remove()
1565 list_del(&mr_sas_phy->port_siblings); in mpi3mr_sas_port_remove()
1567 if (!mrioc->stop_drv_processing) in mpi3mr_sas_port_remove()
1568 sas_port_delete(mr_sas_port->port); in mpi3mr_sas_port_remove()
1572 if (mrioc->current_event) { in mpi3mr_sas_port_remove()
1573 mrioc->current_event->pending_at_sml = 0; in mpi3mr_sas_port_remove()
1574 if (mrioc->current_event->discard) in mpi3mr_sas_port_remove()
1582 * struct host_port - host port details
1583 * @sas_address: SAS Address of the attached device
1584 * @phy_mask: phy mask of host port
1585 * @handle: Device Handle of attached device
1588 * @lowest_phy: lowest phy ID of host port
1600 * mpi3mr_update_mr_sas_port - update sas port objects during reset
1620 h_port->used = 1; in mpi3mr_update_mr_sas_port()
1621 mr_sas_port->marked_responding = 1; in mpi3mr_update_mr_sas_port()
1623 dev_info(&mr_sas_port->port->dev, in mpi3mr_update_mr_sas_port()
1625 mr_sas_port->remote_identify.sas_address, in mpi3mr_update_mr_sas_port()
1626 mr_sas_port->hba_port->port_id, mr_sas_port->phy_mask, in mpi3mr_update_mr_sas_port()
1627 h_port->iounit_port_id, h_port->phy_mask); in mpi3mr_update_mr_sas_port()
1629 mr_sas_port->hba_port->port_id = h_port->iounit_port_id; in mpi3mr_update_mr_sas_port()
1630 mr_sas_port->hba_port->flags &= ~MPI3MR_HBA_PORT_FLAG_DIRTY; in mpi3mr_update_mr_sas_port()
1633 phy_mask_xor = mr_sas_port->phy_mask ^ h_port->phy_mask; in mpi3mr_update_mr_sas_port()
1634 phys_to_be_added = h_port->phy_mask & phy_mask_xor; in mpi3mr_update_mr_sas_port()
1635 phys_to_be_removed = mr_sas_port->phy_mask & phy_mask_xor; in mpi3mr_update_mr_sas_port()
1643 mr_sas_phy = &mrioc->sas_hba.phy[i]; in mpi3mr_update_mr_sas_port()
1644 if (mr_sas_phy->phy_belongs_to_port) in mpi3mr_update_mr_sas_port()
1646 &mrioc->sas_hba, mr_sas_phy); in mpi3mr_update_mr_sas_port()
1648 &mrioc->sas_hba, mr_sas_phy, in mpi3mr_update_mr_sas_port()
1649 mr_sas_port->remote_identify.sas_address, in mpi3mr_update_mr_sas_port()
1650 mr_sas_port->hba_port); in mpi3mr_update_mr_sas_port()
1655 mr_sas_phy = &mrioc->sas_hba.phy[i]; in mpi3mr_update_mr_sas_port()
1656 if (mr_sas_phy->phy_belongs_to_port) in mpi3mr_update_mr_sas_port()
1658 &mrioc->sas_hba, mr_sas_phy); in mpi3mr_update_mr_sas_port()
1663 * mpi3mr_refresh_sas_ports - update host's sas ports during reset
1685 (mrioc->sas_hba.num_phys * in mpi3mr_refresh_sas_ports()
1697 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_refresh_sas_ports()
1699 sas_io_unit_pg0->phy_data[i].attached_dev_handle); in mpi3mr_refresh_sas_ports()
1730 h_port[port_idx].sas_address = le64_to_cpu(sasinf->sas_address); in mpi3mr_refresh_sas_ports()
1733 h_port[port_idx].iounit_port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_refresh_sas_ports()
1734 h_port[port_idx].lowest_phy = sasinf->phy_num; in mpi3mr_refresh_sas_ports()
1742 if (mrioc->logging_level & MPI3_DEBUG_RESET) { in mpi3mr_refresh_sas_ports()
1744 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1747 "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", in mpi3mr_refresh_sas_ports()
1748 mr_sas_port->hba_port->port_id, in mpi3mr_refresh_sas_ports()
1749 mr_sas_port->remote_identify.sas_address, in mpi3mr_refresh_sas_ports()
1750 mr_sas_port->phy_mask, mr_sas_port->lowest_phy); in mpi3mr_refresh_sas_ports()
1756 "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", in mpi3mr_refresh_sas_ports()
1763 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1765 mr_sas_port->marked_responding = 0; in mpi3mr_refresh_sas_ports()
1766 mr_sas_port->hba_port->flags |= MPI3MR_HBA_PORT_FLAG_DIRTY; in mpi3mr_refresh_sas_ports()
1769 /* First check for matching lowest phy */ in mpi3mr_refresh_sas_ports()
1772 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1774 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1776 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1778 if (h_port[i].lowest_phy == mr_sas_port->lowest_phy) { in mpi3mr_refresh_sas_ports()
1785 /* In case if lowest phy is got enabled or disabled during reset */ in mpi3mr_refresh_sas_ports()
1790 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1792 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1794 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1796 if (h_port[i].phy_mask & mr_sas_port->phy_mask) { 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()
1823 * mpi3mr_refresh_expanders - Refresh expander device exposure
1828 * or expose any newly detected expander device to the upper layers.
1843 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1844 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { in mpi3mr_refresh_expanders()
1845 sas_expander->non_responding = 1; in mpi3mr_refresh_expanders()
1847 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1881 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1885 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1893 sas_expander->non_responding = 0; in mpi3mr_refresh_expanders()
1894 if (sas_expander->handle == handle) in mpi3mr_refresh_expanders()
1897 sas_expander->handle = handle; in mpi3mr_refresh_expanders()
1898 for (i = 0 ; i < sas_expander->num_phys ; i++) in mpi3mr_refresh_expanders()
1899 sas_expander->phy[i].handle = handle; in mpi3mr_refresh_expanders()
1904 * hba_port if the non responding expander device's parent device in mpi3mr_refresh_expanders()
1908 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1910 &mrioc->sas_expander_list, list) { in mpi3mr_refresh_expanders()
1911 if (sas_expander->non_responding) { in mpi3mr_refresh_expanders()
1912 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1914 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1917 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1921 * mpi3mr_expander_node_add - insert an expander to the list.
1926 * Adding new object to the ioc->sas_expander_list.
1935 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_add()
1936 list_add_tail(&sas_expander->list, &mrioc->sas_expander_list); in mpi3mr_expander_node_add()
1937 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_add()
1941 * mpi3mr_expander_add - Create expander object
1943 * @handle: Expander firmware device handle
1949 * Return: 0 for success, non-zero for failure.
1968 return -1; in mpi3mr_expander_add()
1970 if (mrioc->reset_in_progress) in mpi3mr_expander_add()
1971 return -1; in mpi3mr_expander_add()
1977 return -1; in mpi3mr_expander_add()
1983 return -1; in mpi3mr_expander_add()
1991 return -1; in mpi3mr_expander_add()
1999 return -1; in mpi3mr_expander_add()
2002 if (sas_address_parent != mrioc->sas_hba.sas_address) { in mpi3mr_expander_add()
2003 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2007 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2018 for (i = 0 ; i < sas_expander->num_phys ; i++) { in mpi3mr_expander_add()
2029 rc = -1; in mpi3mr_expander_add()
2035 rc = -1; in mpi3mr_expander_add()
2051 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2055 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2063 return -1; in mpi3mr_expander_add()
2065 sas_expander->handle = handle; in mpi3mr_expander_add()
2066 sas_expander->num_phys = expander_pg0.num_phys; in mpi3mr_expander_add()
2067 sas_expander->sas_address_parent = sas_address_parent; in mpi3mr_expander_add()
2068 sas_expander->sas_address = sas_address; in mpi3mr_expander_add()
2069 sas_expander->hba_port = hba_port; in mpi3mr_expander_add()
2074 sas_expander->sas_address, sas_expander->num_phys); in mpi3mr_expander_add()
2076 if (!sas_expander->num_phys) { in mpi3mr_expander_add()
2077 rc = -1; in mpi3mr_expander_add()
2080 sas_expander->phy = kcalloc(sas_expander->num_phys, in mpi3mr_expander_add()
2082 if (!sas_expander->phy) { in mpi3mr_expander_add()
2083 rc = -1; in mpi3mr_expander_add()
2087 INIT_LIST_HEAD(&sas_expander->sas_port_list); in mpi3mr_expander_add()
2089 sas_expander->hba_port); in mpi3mr_expander_add()
2093 rc = -1; in mpi3mr_expander_add()
2096 sas_expander->parent_dev = &mr_sas_port->rphy->dev; in mpi3mr_expander_add()
2097 sas_expander->rphy = mr_sas_port->rphy; in mpi3mr_expander_add()
2099 for (i = 0 ; i < sas_expander->num_phys ; i++) { in mpi3mr_expander_add()
2108 rc = -1; in mpi3mr_expander_add()
2114 rc = -1; in mpi3mr_expander_add()
2118 sas_expander->phy[i].handle = handle; in mpi3mr_expander_add()
2119 sas_expander->phy[i].phy_id = i; in mpi3mr_expander_add()
2120 sas_expander->phy[i].hba_port = hba_port; in mpi3mr_expander_add()
2122 if ((mpi3mr_add_expander_phy(mrioc, &sas_expander->phy[i], in mpi3mr_expander_add()
2123 expander_pg1, sas_expander->parent_dev))) { in mpi3mr_expander_add()
2126 rc = -1; in mpi3mr_expander_add()
2131 if (sas_expander->enclosure_handle) { in mpi3mr_expander_add()
2134 sas_expander->enclosure_handle); in mpi3mr_expander_add()
2136 sas_expander->enclosure_logical_id = le64_to_cpu( in mpi3mr_expander_add()
2137 enclosure_dev->pg0.enclosure_logical_id); in mpi3mr_expander_add()
2147 sas_expander->sas_address, in mpi3mr_expander_add()
2148 sas_address_parent, sas_expander->hba_port); in mpi3mr_expander_add()
2149 kfree(sas_expander->phy); in mpi3mr_expander_add()
2155 * mpi3mr_expander_node_remove - recursive removal of expander.
2157 * @sas_expander: Expander device object
2161 * one of the attached device is an expander then it recursively
2162 * removes the expander device too.
2175 &sas_expander->sas_port_list, port_list) { in mpi3mr_expander_node_remove()
2176 if (mrioc->reset_in_progress) in mpi3mr_expander_node_remove()
2178 if (mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2181 mr_sas_port->remote_identify.sas_address, in mpi3mr_expander_node_remove()
2182 mr_sas_port->hba_port); in mpi3mr_expander_node_remove()
2183 else if (mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2185 mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2188 mr_sas_port->remote_identify.sas_address, in mpi3mr_expander_node_remove()
2189 mr_sas_port->hba_port); in mpi3mr_expander_node_remove()
2192 port_id = sas_expander->hba_port->port_id; in mpi3mr_expander_node_remove()
2193 mpi3mr_sas_port_remove(mrioc, sas_expander->sas_address, in mpi3mr_expander_node_remove()
2194 sas_expander->sas_address_parent, sas_expander->hba_port); in mpi3mr_expander_node_remove()
2197 sas_expander->handle, (unsigned long long) in mpi3mr_expander_node_remove()
2198 sas_expander->sas_address, port_id); in mpi3mr_expander_node_remove()
2200 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_remove()
2201 list_del(&sas_expander->list); in mpi3mr_expander_node_remove()
2202 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_remove()
2204 kfree(sas_expander->phy); in mpi3mr_expander_node_remove()
2209 * mpi3mr_expander_remove - Remove expander object
2215 * mrioc->sas_expander_list and removes it from the SAS TL by
2226 if (mrioc->reset_in_progress) in mpi3mr_expander_remove()
2232 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_remove()
2235 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_remove()
2242 * mpi3mr_get_sas_negotiated_logical_linkrate - get linkrate
2244 * @tgtdev: Target device
2246 * This function identifies whether the target device is
2247 * attached directly or through expander and issues sas phy
2248 * page0 or expander phy page1 and gets the link rate, if there
2263 phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; in mpi3mr_get_sas_negotiated_logical_linkrate()
2264 if (!(tgtdev->devpg0_flag & MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)) { in mpi3mr_get_sas_negotiated_logical_linkrate()
2266 | tgtdev->parent_handle); in mpi3mr_get_sas_negotiated_logical_linkrate()
2305 * mpi3mr_report_tgtdev_to_sas_transport - expose dev to SAS TL
2307 * @tgtdev: Target device
2309 * This function exposes the target device after
2312 * Return: 0 on success, non-zero for failure.
2323 if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || in mpi3mr_report_tgtdev_to_sas_transport()
2324 !mrioc->sas_transport_enabled) in mpi3mr_report_tgtdev_to_sas_transport()
2325 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2327 sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; in mpi3mr_report_tgtdev_to_sas_transport()
2328 if (!mrioc->sas_hba.num_phys) in mpi3mr_report_tgtdev_to_sas_transport()
2333 if (mpi3mr_get_sas_address(mrioc, tgtdev->parent_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2337 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2339 tgtdev->dev_spec.sas_sata_inf.sas_address_parent = sas_address_parent; in mpi3mr_report_tgtdev_to_sas_transport()
2341 parent_phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; in mpi3mr_report_tgtdev_to_sas_transport()
2342 port_id = tgtdev->io_unit_port; in mpi3mr_report_tgtdev_to_sas_transport()
2348 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2350 tgtdev->dev_spec.sas_sata_inf.hba_port = hba_port; in mpi3mr_report_tgtdev_to_sas_transport()
2354 mpi3mr_update_links(mrioc, sas_address_parent, tgtdev->dev_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2357 tgtdev->host_exposed = 1; in mpi3mr_report_tgtdev_to_sas_transport()
2358 if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2360 tgtdev->host_exposed = 0; in mpi3mr_report_tgtdev_to_sas_transport()
2361 retval = -1; in mpi3mr_report_tgtdev_to_sas_transport()
2362 } else if ((!tgtdev->starget)) { in mpi3mr_report_tgtdev_to_sas_transport()
2363 if (!mrioc->is_driver_loading) in mpi3mr_report_tgtdev_to_sas_transport()
2366 tgtdev->host_exposed = 0; in mpi3mr_report_tgtdev_to_sas_transport()
2367 retval = -1; in mpi3mr_report_tgtdev_to_sas_transport()
2373 * mpi3mr_remove_tgtdev_from_sas_transport - remove from SAS TL
2375 * @tgtdev: Target device
2377 * This function removes the target device
2387 if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || in mpi3mr_remove_tgtdev_from_sas_transport()
2388 !mrioc->sas_transport_enabled) in mpi3mr_remove_tgtdev_from_sas_transport()
2391 hba_port = tgtdev->dev_spec.sas_sata_inf.hba_port; in mpi3mr_remove_tgtdev_from_sas_transport()
2392 sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; in mpi3mr_remove_tgtdev_from_sas_transport()
2393 sas_address_parent = tgtdev->dev_spec.sas_sata_inf.sas_address_parent; in mpi3mr_remove_tgtdev_from_sas_transport()
2396 tgtdev->host_exposed = 0; in mpi3mr_remove_tgtdev_from_sas_transport()
2400 * mpi3mr_get_port_id_by_sas_phy - Get port ID of the given phy
2401 * @phy: SAS transport layer phy object
2405 static inline u8 mpi3mr_get_port_id_by_sas_phy(struct sas_phy *phy) in mpi3mr_get_port_id_by_sas_phy() argument
2408 struct mpi3mr_hba_port *hba_port = phy->hostdata; in mpi3mr_get_port_id_by_sas_phy()
2411 port_id = hba_port->port_id; in mpi3mr_get_port_id_by_sas_phy()
2417 * mpi3mr_get_port_id_by_rphy - Get Port number from SAS rphy
2420 * @rphy: SAS transport layer remote phy object
2422 * Retrieves HBA port number in which the device pointed by the
2437 if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE || in mpi3mr_get_port_id_by_rphy()
2438 rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) { in mpi3mr_get_port_id_by_rphy()
2439 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_get_port_id_by_rphy()
2440 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, in mpi3mr_get_port_id_by_rphy()
2442 if (sas_expander->rphy == rphy) { in mpi3mr_get_port_id_by_rphy()
2443 port_id = sas_expander->hba_port->port_id; in mpi3mr_get_port_id_by_rphy()
2447 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_get_port_id_by_rphy()
2448 } else if (rphy->identify.device_type == SAS_END_DEVICE) { in mpi3mr_get_port_id_by_rphy()
2449 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_get_port_id_by_rphy()
2452 rphy->identify.sas_address, rphy); in mpi3mr_get_port_id_by_rphy()
2455 tgtdev->dev_spec.sas_sata_inf.hba_port->port_id; in mpi3mr_get_port_id_by_rphy()
2458 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_get_port_id_by_rphy()
2463 static inline struct mpi3mr_ioc *phy_to_mrioc(struct sas_phy *phy) in phy_to_mrioc() argument
2465 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in phy_to_mrioc()
2472 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); in rphy_to_mrioc()
2477 /* report phy error log structure */
2488 /* report phy error log reply structure */
2506 * mpi3mr_get_expander_phy_error_log - return expander counters:
2508 * @phy: The SAS transport layer phy object
2510 * Return: 0 for success, non-zero for failure.
2514 struct sas_phy *phy) in mpi3mr_get_expander_phy_error_log() argument
2530 if (mrioc->reset_in_progress) { in mpi3mr_get_expander_phy_error_log()
2532 return -EFAULT; in mpi3mr_get_expander_phy_error_log()
2538 data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma, in mpi3mr_get_expander_phy_error_log()
2541 rc = -ENOMEM; in mpi3mr_get_expander_phy_error_log()
2548 rc = -EINVAL; in mpi3mr_get_expander_phy_error_log()
2551 phy_error_log_request->smp_frame_type = 0x40; in mpi3mr_get_expander_phy_error_log()
2552 phy_error_log_request->function = 0x11; in mpi3mr_get_expander_phy_error_log()
2553 phy_error_log_request->request_length = 2; in mpi3mr_get_expander_phy_error_log()
2554 phy_error_log_request->allocated_response_length = 0; in mpi3mr_get_expander_phy_error_log()
2555 phy_error_log_request->phy_identifier = phy->number; in mpi3mr_get_expander_phy_error_log()
2561 mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_sas_phy(phy); in mpi3mr_get_expander_phy_error_log()
2562 mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address); in mpi3mr_get_expander_phy_error_log()
2571 "sending phy error log SMP request to sas_address(0x%016llx), phy_id(%d)\n", in mpi3mr_get_expander_phy_error_log()
2572 (unsigned long long)phy->identify.sas_address, phy->number); in mpi3mr_get_expander_phy_error_log()
2579 "phy error log SMP request completed with ioc_status(0x%04x)\n", in mpi3mr_get_expander_phy_error_log()
2584 "phy error log - reply data transfer size(%d)\n", in mpi3mr_get_expander_phy_error_log()
2592 "phy error log - function_result(%d)\n", in mpi3mr_get_expander_phy_error_log()
2593 phy_error_log_reply->function_result); in mpi3mr_get_expander_phy_error_log()
2595 phy->invalid_dword_count = in mpi3mr_get_expander_phy_error_log()
2596 be32_to_cpu(phy_error_log_reply->invalid_dword); in mpi3mr_get_expander_phy_error_log()
2597 phy->running_disparity_error_count = in mpi3mr_get_expander_phy_error_log()
2598 be32_to_cpu(phy_error_log_reply->running_disparity_error); in mpi3mr_get_expander_phy_error_log()
2599 phy->loss_of_dword_sync_count = in mpi3mr_get_expander_phy_error_log()
2600 be32_to_cpu(phy_error_log_reply->loss_of_dword_sync); in mpi3mr_get_expander_phy_error_log()
2601 phy->phy_reset_problem_count = in mpi3mr_get_expander_phy_error_log()
2602 be32_to_cpu(phy_error_log_reply->phy_reset_problem); in mpi3mr_get_expander_phy_error_log()
2608 dma_free_coherent(&mrioc->pdev->dev, sz, data_out, in mpi3mr_get_expander_phy_error_log()
2615 * mpi3mr_transport_get_linkerrors - return phy error counters
2616 * @phy: The SAS transport layer phy object
2618 * This function retrieves the phy error log information of the
2619 * HBA or expander for which the phy belongs to
2621 * Return: 0 for success, non-zero for failure.
2623 static int mpi3mr_transport_get_linkerrors(struct sas_phy *phy) in mpi3mr_transport_get_linkerrors() argument
2625 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_get_linkerrors()
2630 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_get_linkerrors()
2634 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_get_linkerrors()
2635 return mpi3mr_get_expander_phy_error_log(mrioc, phy); in mpi3mr_transport_get_linkerrors()
2638 /* get hba phy error logs */ in mpi3mr_transport_get_linkerrors()
2641 MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number))) { in mpi3mr_transport_get_linkerrors()
2644 return -ENXIO; in mpi3mr_transport_get_linkerrors()
2650 return -ENXIO; in mpi3mr_transport_get_linkerrors()
2652 phy->invalid_dword_count = le32_to_cpu(phy_pg1.invalid_dword_count); in mpi3mr_transport_get_linkerrors()
2653 phy->running_disparity_error_count = in mpi3mr_transport_get_linkerrors()
2655 phy->loss_of_dword_sync_count = in mpi3mr_transport_get_linkerrors()
2657 phy->phy_reset_problem_count = in mpi3mr_transport_get_linkerrors()
2663 * mpi3mr_transport_get_enclosure_identifier - Get Enclosure ID
2664 * @rphy: The SAS transport layer remote phy object
2667 * Returns the enclosure id for the device pointed by the remote
2668 * phy object.
2670 * Return: 0 on success or -ENXIO
2681 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_enclosure_identifier()
2683 rphy->identify.sas_address, rphy); in mpi3mr_transport_get_enclosure_identifier()
2686 tgtdev->enclosure_logical_id; in mpi3mr_transport_get_enclosure_identifier()
2691 rc = -ENXIO; in mpi3mr_transport_get_enclosure_identifier()
2693 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_enclosure_identifier()
2699 * mpi3mr_transport_get_bay_identifier - Get bay ID
2700 * @rphy: The SAS transport layer remote phy object
2702 * Returns the slot id for the device pointed by the remote phy
2705 * Return: Valid slot ID on success or -ENXIO
2715 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_bay_identifier()
2717 rphy->identify.sas_address, rphy); in mpi3mr_transport_get_bay_identifier()
2719 rc = tgtdev->slot; in mpi3mr_transport_get_bay_identifier()
2722 rc = -ENXIO; in mpi3mr_transport_get_bay_identifier()
2723 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_bay_identifier()
2728 /* phy control request structure */
2745 /* phy control reply structure */
2758 * mpi3mr_expander_phy_control - expander phy control
2760 * @phy: The SAS transport layer phy object
2761 * @phy_operation: The phy operation to be executed
2763 * Issues SMP passthru phy control request to execute a specific
2764 * phy operation for a given expander device.
2766 * Return: 0 for success, non-zero for failure.
2770 struct sas_phy *phy, u8 phy_operation) in mpi3mr_expander_phy_control() argument
2789 if (mrioc->reset_in_progress) { in mpi3mr_expander_phy_control()
2791 return -EFAULT; in mpi3mr_expander_phy_control()
2797 data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma, in mpi3mr_expander_phy_control()
2800 rc = -ENOMEM; in mpi3mr_expander_phy_control()
2807 rc = -EINVAL; in mpi3mr_expander_phy_control()
2811 phy_control_request->smp_frame_type = 0x40; in mpi3mr_expander_phy_control()
2812 phy_control_request->function = 0x91; in mpi3mr_expander_phy_control()
2813 phy_control_request->request_length = 9; in mpi3mr_expander_phy_control()
2814 phy_control_request->allocated_response_length = 0; in mpi3mr_expander_phy_control()
2815 phy_control_request->phy_identifier = phy->number; in mpi3mr_expander_phy_control()
2816 phy_control_request->phy_operation = phy_operation; in mpi3mr_expander_phy_control()
2817 phy_control_request->programmed_min_physical_link_rate = in mpi3mr_expander_phy_control()
2818 phy->minimum_linkrate << 4; in mpi3mr_expander_phy_control()
2819 phy_control_request->programmed_max_physical_link_rate = in mpi3mr_expander_phy_control()
2820 phy->maximum_linkrate << 4; in mpi3mr_expander_phy_control()
2826 mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_sas_phy(phy); in mpi3mr_expander_phy_control()
2827 mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address); in mpi3mr_expander_phy_control()
2836 "sending phy control SMP request to sas_address(0x%016llx), phy_id(%d) opcode(%d)\n", in mpi3mr_expander_phy_control()
2837 (unsigned long long)phy->identify.sas_address, phy->number, in mpi3mr_expander_phy_control()
2845 "phy control SMP request completed with ioc_status(0x%04x)\n", in mpi3mr_expander_phy_control()
2850 "phy control - reply data transfer size(%d)\n", in mpi3mr_expander_phy_control()
2857 "phy control - function_result(%d)\n", in mpi3mr_expander_phy_control()
2858 phy_control_reply->function_result); in mpi3mr_expander_phy_control()
2863 dma_free_coherent(&mrioc->pdev->dev, sz, data_out, in mpi3mr_expander_phy_control()
2870 * mpi3mr_transport_phy_reset - Reset a given phy
2871 * @phy: The SAS transport layer phy object
2874 * Return: 0 for success, non-zero for failure.
2877 mpi3mr_transport_phy_reset(struct sas_phy *phy, int hard_reset) in mpi3mr_transport_phy_reset() argument
2879 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_phy_reset()
2887 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_phy_reset()
2892 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_phy_reset()
2893 return mpi3mr_expander_phy_control(mrioc, phy, in mpi3mr_transport_phy_reset()
2906 phy->number; in mpi3mr_transport_phy_reset()
2909 "sending phy reset request to sas_address(0x%016llx), phy_id(%d) hard_reset(%d)\n", in mpi3mr_transport_phy_reset()
2910 (unsigned long long)phy->identify.sas_address, phy->number, in mpi3mr_transport_phy_reset()
2915 rc = -EAGAIN; in mpi3mr_transport_phy_reset()
2920 "phy reset request completed with ioc_status(0x%04x)\n", in mpi3mr_transport_phy_reset()
2927 * mpi3mr_transport_phy_enable - enable/disable phys
2928 * @phy: The SAS transport layer phy object
2929 * @enable: flag to enable/disable, enable phy when true
2932 * configuration page changes or expander phy control command
2934 * Return: 0 for success, non-zero for failure.
2937 mpi3mr_transport_phy_enable(struct sas_phy *phy, int enable) in mpi3mr_transport_phy_enable() argument
2939 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_phy_enable()
2946 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_phy_enable()
2951 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_phy_enable()
2952 return mpi3mr_expander_phy_control(mrioc, phy, in mpi3mr_transport_phy_enable()
2958 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_enable()
2962 rc = -ENOMEM; in mpi3mr_transport_phy_enable()
2968 rc = -ENXIO; in mpi3mr_transport_phy_enable()
2973 for (i = 0, discovery_active = 0; i < mrioc->sas_hba.num_phys ; i++) { in mpi3mr_transport_phy_enable()
2974 if (sas_io_unit_pg0->phy_data[i].port_flags & in mpi3mr_transport_phy_enable()
2977 "discovery is active on port = %d, phy = %d\n" in mpi3mr_transport_phy_enable()
2979 sas_io_unit_pg0->phy_data[i].io_unit_port, i); in mpi3mr_transport_phy_enable()
2985 rc = -EAGAIN; in mpi3mr_transport_phy_enable()
2989 if ((sas_io_unit_pg0->phy_data[phy->number].phy_flags & in mpi3mr_transport_phy_enable()
2994 rc = -ENXIO; in mpi3mr_transport_phy_enable()
3000 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_enable()
3004 rc = -ENOMEM; in mpi3mr_transport_phy_enable()
3011 rc = -ENXIO; in mpi3mr_transport_phy_enable()
3016 sas_io_unit_pg1->phy_data[phy->number].phy_flags in mpi3mr_transport_phy_enable()
3019 sas_io_unit_pg1->phy_data[phy->number].phy_flags in mpi3mr_transport_phy_enable()
3026 mpi3mr_transport_phy_reset(phy, 0); in mpi3mr_transport_phy_enable()
3035 * mpi3mr_transport_phy_speed - set phy min/max speed
3036 * @phy: The SAS transport later phy object
3040 * argument to the given phy by executing required configuration
3041 * page changes or expander phy control command
3043 * Return: 0 for success, non-zero for failure.
3046 mpi3mr_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) in mpi3mr_transport_phy_speed() argument
3048 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_phy_speed()
3054 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_phy_speed()
3058 if (!rates->minimum_linkrate) in mpi3mr_transport_phy_speed()
3059 rates->minimum_linkrate = phy->minimum_linkrate; in mpi3mr_transport_phy_speed()
3060 else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) in mpi3mr_transport_phy_speed()
3061 rates->minimum_linkrate = phy->minimum_linkrate_hw; in mpi3mr_transport_phy_speed()
3063 if (!rates->maximum_linkrate) in mpi3mr_transport_phy_speed()
3064 rates->maximum_linkrate = phy->maximum_linkrate; in mpi3mr_transport_phy_speed()
3065 else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) in mpi3mr_transport_phy_speed()
3066 rates->maximum_linkrate = phy->maximum_linkrate_hw; in mpi3mr_transport_phy_speed()
3069 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) { in mpi3mr_transport_phy_speed()
3070 phy->minimum_linkrate = rates->minimum_linkrate; in mpi3mr_transport_phy_speed()
3071 phy->maximum_linkrate = rates->maximum_linkrate; in mpi3mr_transport_phy_speed()
3072 return mpi3mr_expander_phy_control(mrioc, phy, in mpi3mr_transport_phy_speed()
3078 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_speed()
3082 rc = -ENOMEM; in mpi3mr_transport_phy_speed()
3089 rc = -ENXIO; in mpi3mr_transport_phy_speed()
3093 sas_io_unit_pg1->phy_data[phy->number].max_min_link_rate = in mpi3mr_transport_phy_speed()
3094 (rates->minimum_linkrate + (rates->maximum_linkrate << 4)); in mpi3mr_transport_phy_speed()
3099 rc = -ENXIO; in mpi3mr_transport_phy_speed()
3104 mpi3mr_transport_phy_reset(phy, 0); in mpi3mr_transport_phy_speed()
3106 /* read phy page 0, then update the rates in the sas transport phy */ in mpi3mr_transport_phy_speed()
3109 MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number) && in mpi3mr_transport_phy_speed()
3111 phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_transport_phy_speed()
3114 phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_transport_phy_speed()
3116 phy->negotiated_linkrate = in mpi3mr_transport_phy_speed()
3129 * mpi3mr_map_smp_buffer - map BSG dma buffer
3130 * @dev: Generic device reference
3138 * Return: 0 on success, non-zero on failure
3141 mpi3mr_map_smp_buffer(struct device *dev, struct bsg_buffer *buf, in mpi3mr_map_smp_buffer()
3145 if (buf->sg_cnt > 1) { in mpi3mr_map_smp_buffer()
3146 *p = dma_alloc_coherent(dev, buf->payload_len, dma_addr, in mpi3mr_map_smp_buffer()
3149 return -ENOMEM; in mpi3mr_map_smp_buffer()
3150 *dma_len = buf->payload_len; in mpi3mr_map_smp_buffer()
3152 if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL)) in mpi3mr_map_smp_buffer()
3153 return -ENOMEM; in mpi3mr_map_smp_buffer()
3154 *dma_addr = sg_dma_address(buf->sg_list); in mpi3mr_map_smp_buffer()
3155 *dma_len = sg_dma_len(buf->sg_list); in mpi3mr_map_smp_buffer()
3163 * mpi3mr_unmap_smp_buffer - unmap BSG dma buffer
3164 * @dev: Generic device reference
3172 mpi3mr_unmap_smp_buffer(struct device *dev, struct bsg_buffer *buf, in mpi3mr_unmap_smp_buffer()
3176 dma_free_coherent(dev, buf->payload_len, p, dma_addr); in mpi3mr_unmap_smp_buffer()
3178 dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL); in mpi3mr_unmap_smp_buffer()
3182 * mpi3mr_transport_smp_handler - handler for smp passthru
3211 if (mrioc->reset_in_progress) { in mpi3mr_transport_smp_handler()
3213 rc = -EFAULT; in mpi3mr_transport_smp_handler()
3217 rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->request_payload, in mpi3mr_transport_smp_handler()
3223 sg_copy_to_buffer(job->request_payload.sg_list, in mpi3mr_transport_smp_handler()
3224 job->request_payload.sg_cnt, addr_out, in mpi3mr_transport_smp_handler()
3225 job->request_payload.payload_len); in mpi3mr_transport_smp_handler()
3227 rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->reply_payload, in mpi3mr_transport_smp_handler()
3238 cpu_to_le64(rphy->identify.sas_address) : in mpi3mr_transport_smp_handler()
3239 cpu_to_le64(mrioc->sas_hba.sas_address)); in mpi3mr_transport_smp_handler()
3241 mpi3mr_add_sg_single(psge, sgl_flags, dma_len_out - 4, dma_addr_out); in mpi3mr_transport_smp_handler()
3244 mpi3mr_add_sg_single(psge, sgl_flags, dma_len_in - 4, dma_addr_in); in mpi3mr_transport_smp_handler()
3258 "SMP request - reply data transfer size(%d)\n", in mpi3mr_transport_smp_handler()
3261 memcpy(job->reply, &mpi_reply, reply_sz); in mpi3mr_transport_smp_handler()
3262 job->reply_len = reply_sz; in mpi3mr_transport_smp_handler()
3266 sg_copy_from_buffer(job->reply_payload.sg_list, in mpi3mr_transport_smp_handler()
3267 job->reply_payload.sg_cnt, addr_in, in mpi3mr_transport_smp_handler()
3268 job->reply_payload.payload_len); in mpi3mr_transport_smp_handler()
3272 mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->reply_payload, in mpi3mr_transport_smp_handler()
3275 mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->request_payload, in mpi3mr_transport_smp_handler()