Lines Matching +full:phy +full:- +full:handle

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) 2017-2023 Broadcom Inc.
6 * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com)
13 * mpi3mr_post_transport_req - Issue transport requests and wait
31 * Return: 0 on success, non-zero on failure.
39 mutex_lock(&mrioc->transport_cmds.mutex); in mpi3mr_post_transport_req()
40 if (mrioc->transport_cmds.state & MPI3MR_CMD_PENDING) { in mpi3mr_post_transport_req()
41 retval = -1; in mpi3mr_post_transport_req()
43 mutex_unlock(&mrioc->transport_cmds.mutex); in mpi3mr_post_transport_req()
46 mrioc->transport_cmds.state = MPI3MR_CMD_PENDING; in mpi3mr_post_transport_req()
47 mrioc->transport_cmds.is_waiting = 1; in mpi3mr_post_transport_req()
48 mrioc->transport_cmds.callback = NULL; in mpi3mr_post_transport_req()
49 mrioc->transport_cmds.ioc_status = 0; in mpi3mr_post_transport_req()
50 mrioc->transport_cmds.ioc_loginfo = 0; in mpi3mr_post_transport_req()
52 init_completion(&mrioc->transport_cmds.done); in mpi3mr_post_transport_req()
54 if (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO) in mpi3mr_post_transport_req()
61 wait_for_completion_timeout(&mrioc->transport_cmds.done, in mpi3mr_post_transport_req()
63 if (!(mrioc->transport_cmds.state & MPI3MR_CMD_COMPLETE)) { in mpi3mr_post_transport_req()
67 retval = -1; in mpi3mr_post_transport_req()
70 *ioc_status = mrioc->transport_cmds.ioc_status & in mpi3mr_post_transport_req()
75 *ioc_status, mrioc->transport_cmds.ioc_loginfo); in mpi3mr_post_transport_req()
77 if ((reply) && (mrioc->transport_cmds.state & MPI3MR_CMD_REPLY_VALID)) in mpi3mr_post_transport_req()
78 memcpy((u8 *)reply, mrioc->transport_cmds.reply, reply_sz); in mpi3mr_post_transport_req()
81 mrioc->transport_cmds.state = MPI3MR_CMD_NOTUSED; in mpi3mr_post_transport_req()
82 mutex_unlock(&mrioc->transport_cmds.mutex); in mpi3mr_post_transport_req()
117 * mpi3mr_report_manufacture - obtain SMP report_manufacture
125 * Return: 0 for success, non-zero for failure.
147 if (mrioc->reset_in_progress) { in mpi3mr_report_manufacture()
149 return -EFAULT; in mpi3mr_report_manufacture()
154 data_out = dma_alloc_coherent(&mrioc->pdev->dev, in mpi3mr_report_manufacture()
157 rc = -ENOMEM; in mpi3mr_report_manufacture()
165 manufacture_request->smp_frame_type = 0x40; in mpi3mr_report_manufacture()
166 manufacture_request->function = 1; in mpi3mr_report_manufacture()
167 manufacture_request->reserved = 0; in mpi3mr_report_manufacture()
168 manufacture_request->request_length = 0; in mpi3mr_report_manufacture()
198 rc = -EINVAL; in mpi3mr_report_manufacture()
203 "report manufacturer - reply data transfer size(%d)\n", in mpi3mr_report_manufacture()
208 rc = -EINVAL; in mpi3mr_report_manufacture()
212 strscpy(edev->vendor_id, manufacture_reply->vendor_id, in mpi3mr_report_manufacture()
214 strscpy(edev->product_id, manufacture_reply->product_id, in mpi3mr_report_manufacture()
216 strscpy(edev->product_rev, manufacture_reply->product_rev, in mpi3mr_report_manufacture()
218 edev->level = manufacture_reply->sas_format & 1; in mpi3mr_report_manufacture()
219 if (edev->level) { in mpi3mr_report_manufacture()
220 strscpy(edev->component_vendor_id, in mpi3mr_report_manufacture()
221 manufacture_reply->component_vendor_id, in mpi3mr_report_manufacture()
223 tmp = (u8 *)&manufacture_reply->component_id; in mpi3mr_report_manufacture()
224 edev->component_id = tmp[0] << 8 | tmp[1]; in mpi3mr_report_manufacture()
225 edev->component_revision_id = in mpi3mr_report_manufacture()
226 manufacture_reply->component_revision_id; in mpi3mr_report_manufacture()
231 dma_free_coherent(&mrioc->pdev->dev, data_out_sz + data_in_sz, in mpi3mr_report_manufacture()
238 * __mpi3mr_expander_find_by_handle - expander search by handle
240 * @handle: Firmware device handle of the expander
244 * This searches for expander device based on handle, then
250 *mrioc, u16 handle) in __mpi3mr_expander_find_by_handle() argument
255 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { in __mpi3mr_expander_find_by_handle()
256 if (sas_expander->handle != handle) in __mpi3mr_expander_find_by_handle()
266 * mpi3mr_is_expander_device - if device is an expander
281 * mpi3mr_get_sas_address - retrieve sas_address for handle
283 * @handle: Firmware device handle
287 * handle and gets the SAS address and return it back
289 * Return: 0 for success, non-zero for failure
291 static int mpi3mr_get_sas_address(struct mpi3mr_ioc *mrioc, u16 handle, in mpi3mr_get_sas_address() argument
302 handle))) { in mpi3mr_get_sas_address()
304 return -ENXIO; in mpi3mr_get_sas_address()
308 …ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:… in mpi3mr_get_sas_address()
309 handle, ioc_status, __FILE__, __LINE__, __func__); in mpi3mr_get_sas_address()
310 return -ENXIO; in mpi3mr_get_sas_address()
315 *sas_address = mrioc->sas_hba.sas_address; in mpi3mr_get_sas_address()
318 *sas_address = le64_to_cpu(sasinf->sas_address); in mpi3mr_get_sas_address()
322 return -ENXIO; in mpi3mr_get_sas_address()
328 * __mpi3mr_get_tgtdev_by_addr - target device search
343 assert_spin_locked(&mrioc->tgtdev_lock); in __mpi3mr_get_tgtdev_by_addr()
345 list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) in __mpi3mr_get_tgtdev_by_addr()
346 if ((tgtdev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA) && in __mpi3mr_get_tgtdev_by_addr()
347 (tgtdev->dev_spec.sas_sata_inf.sas_address == sas_address) in __mpi3mr_get_tgtdev_by_addr()
348 && (tgtdev->dev_spec.sas_sata_inf.hba_port == hba_port)) in __mpi3mr_get_tgtdev_by_addr()
357 * mpi3mr_get_tgtdev_by_addr - target device search
379 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_get_tgtdev_by_addr()
381 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_get_tgtdev_by_addr()
388 * mpi3mr_remove_device_by_sas_address - remove the device
408 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_remove_device_by_sas_address()
412 if (!list_empty(&tgtdev->list)) { in mpi3mr_remove_device_by_sas_address()
413 list_del_init(&tgtdev->list); in mpi3mr_remove_device_by_sas_address()
418 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_remove_device_by_sas_address()
420 if (tgtdev->host_exposed) in mpi3mr_remove_device_by_sas_address()
427 * __mpi3mr_get_tgtdev_by_addr_and_rphy - target device search
442 assert_spin_locked(&mrioc->tgtdev_lock); in __mpi3mr_get_tgtdev_by_addr_and_rphy()
444 list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) in __mpi3mr_get_tgtdev_by_addr_and_rphy()
445 if ((tgtdev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA) && in __mpi3mr_get_tgtdev_by_addr_and_rphy()
446 (tgtdev->dev_spec.sas_sata_inf.sas_address == sas_address) in __mpi3mr_get_tgtdev_by_addr_and_rphy()
447 && (tgtdev->dev_spec.sas_sata_inf.rphy == rphy)) in __mpi3mr_get_tgtdev_by_addr_and_rphy()
456 * mpi3mr_expander_find_by_sas_address - sas expander search
473 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { in mpi3mr_expander_find_by_sas_address()
474 if ((sas_expander->sas_address != sas_address) || in mpi3mr_expander_find_by_sas_address()
475 (sas_expander->hba_port != hba_port)) in mpi3mr_expander_find_by_sas_address()
485 * __mpi3mr_sas_node_find_by_sas_address - sas node search
489 * Context: Caller should acquire mrioc->sas_node_lock.
506 if (mrioc->sas_hba.sas_address == sas_address) in __mpi3mr_sas_node_find_by_sas_address()
507 return &mrioc->sas_hba; in __mpi3mr_sas_node_find_by_sas_address()
513 * mpi3mr_parent_present - Is parent present for a phy
515 * @phy: SAS transport layer phy object
517 * Return: 0 if parent is present else non-zero
519 static int mpi3mr_parent_present(struct mpi3mr_ioc *mrioc, struct sas_phy *phy) in mpi3mr_parent_present() argument
522 struct mpi3mr_hba_port *hba_port = phy->hostdata; in mpi3mr_parent_present()
524 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_parent_present()
526 phy->identify.sas_address, in mpi3mr_parent_present()
528 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_parent_present()
529 return -1; in mpi3mr_parent_present()
531 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_parent_present()
536 * mpi3mr_convert_phy_link_rate -
586 * mpi3mr_delete_sas_phy - Remove a single phy from port
589 * @mr_sas_phy: Internal Phy object
597 u64 sas_address = mr_sas_port->remote_identify.sas_address; in mpi3mr_delete_sas_phy()
599 dev_info(&mr_sas_phy->phy->dev, in mpi3mr_delete_sas_phy()
600 "remove: sas_address(0x%016llx), phy(%d)\n", in mpi3mr_delete_sas_phy()
601 (unsigned long long) sas_address, mr_sas_phy->phy_id); in mpi3mr_delete_sas_phy()
603 list_del(&mr_sas_phy->port_siblings); in mpi3mr_delete_sas_phy()
604 mr_sas_port->num_phys--; in mpi3mr_delete_sas_phy()
605 mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); in mpi3mr_delete_sas_phy()
606 if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) in mpi3mr_delete_sas_phy()
607 mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; in mpi3mr_delete_sas_phy()
608 sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); in mpi3mr_delete_sas_phy()
609 mr_sas_phy->phy_belongs_to_port = 0; in mpi3mr_delete_sas_phy()
613 * mpi3mr_add_sas_phy - Adding a single phy to a port
616 * @mr_sas_phy: Internal Phy object
624 u64 sas_address = mr_sas_port->remote_identify.sas_address; in mpi3mr_add_sas_phy()
626 dev_info(&mr_sas_phy->phy->dev, in mpi3mr_add_sas_phy()
627 "add: sas_address(0x%016llx), phy(%d)\n", (unsigned long long) in mpi3mr_add_sas_phy()
628 sas_address, mr_sas_phy->phy_id); in mpi3mr_add_sas_phy()
630 list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); in mpi3mr_add_sas_phy()
631 mr_sas_port->num_phys++; in mpi3mr_add_sas_phy()
632 mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); in mpi3mr_add_sas_phy()
633 if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) in mpi3mr_add_sas_phy()
634 mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; in mpi3mr_add_sas_phy()
635 sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); in mpi3mr_add_sas_phy()
636 mr_sas_phy->phy_belongs_to_port = 1; in mpi3mr_add_sas_phy()
640 * mpi3mr_add_phy_to_an_existing_port - add phy to existing port
643 * @mr_sas_phy: Internal Phy object *
644 * @sas_address: SAS address of device/expander were phy needs
657 if (mr_sas_phy->phy_belongs_to_port == 1) in mpi3mr_add_phy_to_an_existing_port()
663 list_for_each_entry(mr_sas_port, &mr_sas_node->sas_port_list, in mpi3mr_add_phy_to_an_existing_port()
665 if (mr_sas_port->remote_identify.sas_address != in mpi3mr_add_phy_to_an_existing_port()
668 if (mr_sas_port->hba_port != hba_port) in mpi3mr_add_phy_to_an_existing_port()
670 list_for_each_entry(srch_phy, &mr_sas_port->phy_list, in mpi3mr_add_phy_to_an_existing_port()
681 * mpi3mr_delete_sas_port - helper function to removing a port
690 u64 sas_address = mr_sas_port->remote_identify.sas_address; in mpi3mr_delete_sas_port()
691 struct mpi3mr_hba_port *hba_port = mr_sas_port->hba_port; in mpi3mr_delete_sas_port()
693 mr_sas_port->remote_identify.device_type; in mpi3mr_delete_sas_port()
695 dev_info(&mr_sas_port->port->dev, in mpi3mr_delete_sas_port()
709 * mpi3mr_del_phy_from_an_existing_port - del phy from a port
712 * @mr_sas_phy: Internal Phy object
722 if (mr_sas_phy->phy_belongs_to_port == 0) in mpi3mr_del_phy_from_an_existing_port()
725 list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list, in mpi3mr_del_phy_from_an_existing_port()
727 list_for_each_entry(srch_phy, &mr_sas_port->phy_list, in mpi3mr_del_phy_from_an_existing_port()
731 if ((mr_sas_port->num_phys == 1) && in mpi3mr_del_phy_from_an_existing_port()
732 !mrioc->reset_in_progress) in mpi3mr_del_phy_from_an_existing_port()
743 * mpi3mr_sas_port_sanity_check - sanity check while adding port
761 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_sanity_check()
762 if ((mr_sas_node->phy[i].remote_identify.sas_address != in mpi3mr_sas_port_sanity_check()
763 sas_address) || (mr_sas_node->phy[i].hba_port != hba_port)) in mpi3mr_sas_port_sanity_check()
765 if (mr_sas_node->phy[i].phy_belongs_to_port == 1) in mpi3mr_sas_port_sanity_check()
767 mr_sas_node, &mr_sas_node->phy[i]); in mpi3mr_sas_port_sanity_check()
772 * mpi3mr_set_identify - set identify for phys and end devices
774 * @handle: Firmware device handle
779 * Return: 0 for success, non-zero for failure.
781 static int mpi3mr_set_identify(struct mpi3mr_ioc *mrioc, u16 handle, in mpi3mr_set_identify() argument
790 if (mrioc->reset_in_progress) { in mpi3mr_set_identify()
792 return -EFAULT; in mpi3mr_set_identify()
796 sizeof(device_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE, handle))) { in mpi3mr_set_identify()
798 return -ENXIO; in mpi3mr_set_identify()
802 …ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:… in mpi3mr_set_identify()
803 handle, ioc_status, __FILE__, __LINE__, __func__); in mpi3mr_set_identify()
804 return -EIO; in mpi3mr_set_identify()
809 device_info = le16_to_cpu(sasinf->device_info); in mpi3mr_set_identify()
812 identify->sas_address = le64_to_cpu(sasinf->sas_address); in mpi3mr_set_identify()
814 /* phy number of the parent device this device is linked to */ in mpi3mr_set_identify()
815 identify->phy_identifier = sasinf->phy_num; in mpi3mr_set_identify()
820 identify->device_type = SAS_PHY_UNUSED; in mpi3mr_set_identify()
823 identify->device_type = SAS_END_DEVICE; in mpi3mr_set_identify()
826 identify->device_type = SAS_EDGE_EXPANDER_DEVICE; in mpi3mr_set_identify()
832 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP; in mpi3mr_set_identify()
835 identify->initiator_port_protocols |= (SAS_PROTOCOL_STP | in mpi3mr_set_identify()
838 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP; in mpi3mr_set_identify()
842 identify->target_port_protocols |= SAS_PROTOCOL_SSP; in mpi3mr_set_identify()
845 identify->target_port_protocols |= (SAS_PROTOCOL_STP | in mpi3mr_set_identify()
848 identify->target_port_protocols |= SAS_PROTOCOL_SMP; in mpi3mr_set_identify()
853 * mpi3mr_add_host_phy - report sas_host phy to SAS transport
855 * @mr_sas_phy: Internal Phy object
856 * @phy_pg0: SAS phy page 0
859 * Return: 0 for success, non-zero for failure.
865 struct sas_phy *phy; in mpi3mr_add_host_phy() local
866 int phy_index = mr_sas_phy->phy_id; in mpi3mr_add_host_phy()
869 INIT_LIST_HEAD(&mr_sas_phy->port_siblings); in mpi3mr_add_host_phy()
870 phy = sas_phy_alloc(parent_dev, phy_index); in mpi3mr_add_host_phy()
871 if (!phy) { in mpi3mr_add_host_phy()
874 return -1; in mpi3mr_add_host_phy()
876 if ((mpi3mr_set_identify(mrioc, mr_sas_phy->handle, in mpi3mr_add_host_phy()
877 &mr_sas_phy->identify))) { in mpi3mr_add_host_phy()
880 sas_phy_free(phy); in mpi3mr_add_host_phy()
881 return -1; in mpi3mr_add_host_phy()
883 phy->identify = mr_sas_phy->identify; in mpi3mr_add_host_phy()
884 mr_sas_phy->attached_handle = le16_to_cpu(phy_pg0.attached_dev_handle); in mpi3mr_add_host_phy()
885 if (mr_sas_phy->attached_handle) in mpi3mr_add_host_phy()
886 mpi3mr_set_identify(mrioc, mr_sas_phy->attached_handle, in mpi3mr_add_host_phy()
887 &mr_sas_phy->remote_identify); in mpi3mr_add_host_phy()
888 phy->identify.phy_identifier = mr_sas_phy->phy_id; in mpi3mr_add_host_phy()
889 phy->negotiated_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
893 phy->minimum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
895 phy->maximum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
897 phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
899 phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_host_phy()
901 phy->hostdata = mr_sas_phy->hba_port; in mpi3mr_add_host_phy()
903 if ((sas_phy_add(phy))) { in mpi3mr_add_host_phy()
906 sas_phy_free(phy); in mpi3mr_add_host_phy()
907 return -1; in mpi3mr_add_host_phy()
909 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_add_host_phy()
910 dev_info(&phy->dev, in mpi3mr_add_host_phy()
911 "add: handle(0x%04x), sas_address(0x%016llx)\n" in mpi3mr_add_host_phy()
913 mr_sas_phy->handle, (unsigned long long) in mpi3mr_add_host_phy()
914 mr_sas_phy->identify.sas_address, in mpi3mr_add_host_phy()
915 mr_sas_phy->attached_handle, in mpi3mr_add_host_phy()
917 mr_sas_phy->remote_identify.sas_address); in mpi3mr_add_host_phy()
918 mr_sas_phy->phy = phy; in mpi3mr_add_host_phy()
923 * mpi3mr_add_expander_phy - report expander phy to transport
925 * @mr_sas_phy: Internal Phy object
929 * Return: 0 for success, non-zero for failure.
936 struct sas_phy *phy; in mpi3mr_add_expander_phy() local
937 int phy_index = mr_sas_phy->phy_id; in mpi3mr_add_expander_phy()
939 INIT_LIST_HEAD(&mr_sas_phy->port_siblings); in mpi3mr_add_expander_phy()
940 phy = sas_phy_alloc(parent_dev, phy_index); in mpi3mr_add_expander_phy()
941 if (!phy) { in mpi3mr_add_expander_phy()
944 return -1; in mpi3mr_add_expander_phy()
946 if ((mpi3mr_set_identify(mrioc, mr_sas_phy->handle, in mpi3mr_add_expander_phy()
947 &mr_sas_phy->identify))) { in mpi3mr_add_expander_phy()
950 sas_phy_free(phy); in mpi3mr_add_expander_phy()
951 return -1; in mpi3mr_add_expander_phy()
953 phy->identify = mr_sas_phy->identify; in mpi3mr_add_expander_phy()
954 mr_sas_phy->attached_handle = in mpi3mr_add_expander_phy()
956 if (mr_sas_phy->attached_handle) in mpi3mr_add_expander_phy()
957 mpi3mr_set_identify(mrioc, mr_sas_phy->attached_handle, in mpi3mr_add_expander_phy()
958 &mr_sas_phy->remote_identify); in mpi3mr_add_expander_phy()
959 phy->identify.phy_identifier = mr_sas_phy->phy_id; in mpi3mr_add_expander_phy()
960 phy->negotiated_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
964 phy->minimum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
966 phy->maximum_linkrate_hw = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
968 phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
970 phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_add_expander_phy()
972 phy->hostdata = mr_sas_phy->hba_port; in mpi3mr_add_expander_phy()
974 if ((sas_phy_add(phy))) { in mpi3mr_add_expander_phy()
977 sas_phy_free(phy); in mpi3mr_add_expander_phy()
978 return -1; in mpi3mr_add_expander_phy()
980 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_add_expander_phy()
981 dev_info(&phy->dev, in mpi3mr_add_expander_phy()
982 "add: handle(0x%04x), sas_address(0x%016llx)\n" in mpi3mr_add_expander_phy()
984 mr_sas_phy->handle, (unsigned long long) in mpi3mr_add_expander_phy()
985 mr_sas_phy->identify.sas_address, in mpi3mr_add_expander_phy()
986 mr_sas_phy->attached_handle, in mpi3mr_add_expander_phy()
988 mr_sas_phy->remote_identify.sas_address); in mpi3mr_add_expander_phy()
989 mr_sas_phy->phy = phy; in mpi3mr_add_expander_phy()
994 * mpi3mr_alloc_hba_port - alloc hba port object
1009 hba_port->port_id = port_id; in mpi3mr_alloc_hba_port()
1011 hba_port, hba_port->port_id); in mpi3mr_alloc_hba_port()
1012 list_add_tail(&hba_port->list, &mrioc->hba_port_table_list); in mpi3mr_alloc_hba_port()
1017 * mpi3mr_get_hba_port_by_id - find hba port by id
1019 * @port_id - Port ID to search
1030 &mrioc->hba_port_table_list, list) { in mpi3mr_get_hba_port_by_id()
1031 if (port->port_id != port_id) in mpi3mr_get_hba_port_by_id()
1033 if (port->flags & MPI3MR_HBA_PORT_FLAG_DIRTY) in mpi3mr_get_hba_port_by_id()
1042 * mpi3mr_update_links - refreshing SAS phy link changes
1045 * @handle: Firmware device handle of attached device
1046 * @phy_number: Phy number
1053 u64 sas_address_parent, u16 handle, u8 phy_number, u8 link_rate, in mpi3mr_update_links() argument
1060 if (mrioc->reset_in_progress) in mpi3mr_update_links()
1063 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_update_links()
1067 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_update_links()
1071 mr_sas_phy = &mr_sas_node->phy[phy_number]; in mpi3mr_update_links()
1072 mr_sas_phy->attached_handle = handle; in mpi3mr_update_links()
1073 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_update_links()
1074 if (handle && (link_rate >= MPI3_SAS_NEG_LINK_RATE_1_5)) { in mpi3mr_update_links()
1075 mpi3mr_set_identify(mrioc, handle, in mpi3mr_update_links()
1076 &mr_sas_phy->remote_identify); in mpi3mr_update_links()
1078 mr_sas_phy, mr_sas_phy->remote_identify.sas_address, in mpi3mr_update_links()
1081 memset(&mr_sas_phy->remote_identify, 0, sizeof(struct in mpi3mr_update_links()
1084 if (mr_sas_phy->phy) in mpi3mr_update_links()
1085 mr_sas_phy->phy->negotiated_linkrate = in mpi3mr_update_links()
1088 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_update_links()
1089 dev_info(&mr_sas_phy->phy->dev, in mpi3mr_update_links()
1091 "\tlink_rate(0x%02x), phy(%d)\n" in mpi3mr_update_links()
1094 link_rate, phy_number, handle, (unsigned long long) in mpi3mr_update_links()
1095 mr_sas_phy->remote_identify.sas_address); in mpi3mr_update_links()
1099 * mpi3mr_sas_host_refresh - refreshing sas host object contents
1102 * This function refreshes the controllers phy information and
1118 (unsigned long long)mrioc->sas_hba.sas_address); in mpi3mr_sas_host_refresh()
1121 (mrioc->sas_hba.num_phys * in mpi3mr_sas_host_refresh()
1132 mrioc->sas_hba.handle = 0; in mpi3mr_sas_host_refresh()
1133 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_sas_host_refresh()
1134 if (sas_io_unit_pg0->phy_data[i].phy_flags & in mpi3mr_sas_host_refresh()
1139 sas_io_unit_pg0->phy_data[i].negotiated_link_rate >> 4; in mpi3mr_sas_host_refresh()
1140 if (!mrioc->sas_hba.handle) in mpi3mr_sas_host_refresh()
1141 mrioc->sas_hba.handle = le16_to_cpu( in mpi3mr_sas_host_refresh()
1142 sas_io_unit_pg0->phy_data[i].controller_dev_handle); in mpi3mr_sas_host_refresh()
1143 port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_sas_host_refresh()
1148 mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle; in mpi3mr_sas_host_refresh()
1150 sas_io_unit_pg0->phy_data[i].attached_dev_handle); in mpi3mr_sas_host_refresh()
1153 mrioc->sas_hba.phy[i].hba_port = in mpi3mr_sas_host_refresh()
1155 mpi3mr_update_links(mrioc, mrioc->sas_hba.sas_address, in mpi3mr_sas_host_refresh()
1157 mrioc->sas_hba.phy[i].hba_port); in mpi3mr_sas_host_refresh()
1164 * mpi3mr_sas_host_add - create sas host object
1167 * This function creates the controllers phy information and
1195 num_phys = sas_io_unit_pg0->num_phys; in mpi3mr_sas_host_add()
1198 mrioc->sas_hba.host_node = 1; in mpi3mr_sas_host_add()
1199 INIT_LIST_HEAD(&mrioc->sas_hba.sas_port_list); in mpi3mr_sas_host_add()
1200 mrioc->sas_hba.parent_dev = &mrioc->shost->shost_gendev; in mpi3mr_sas_host_add()
1201 mrioc->sas_hba.phy = kcalloc(num_phys, in mpi3mr_sas_host_add()
1203 if (!mrioc->sas_hba.phy) in mpi3mr_sas_host_add()
1206 mrioc->sas_hba.num_phys = num_phys; in mpi3mr_sas_host_add()
1220 mrioc->sas_hba.handle = 0; in mpi3mr_sas_host_add()
1221 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_sas_host_add()
1222 if (sas_io_unit_pg0->phy_data[i].phy_flags & in mpi3mr_sas_host_add()
1239 if (!mrioc->sas_hba.handle) in mpi3mr_sas_host_add()
1240 mrioc->sas_hba.handle = le16_to_cpu( in mpi3mr_sas_host_add()
1241 sas_io_unit_pg0->phy_data[i].controller_dev_handle); in mpi3mr_sas_host_add()
1242 port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_sas_host_add()
1248 mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle; in mpi3mr_sas_host_add()
1249 mrioc->sas_hba.phy[i].phy_id = i; in mpi3mr_sas_host_add()
1250 mrioc->sas_hba.phy[i].hba_port = in mpi3mr_sas_host_add()
1252 mpi3mr_add_host_phy(mrioc, &mrioc->sas_hba.phy[i], in mpi3mr_sas_host_add()
1253 phy_pg0, mrioc->sas_hba.parent_dev); in mpi3mr_sas_host_add()
1257 mrioc->sas_hba.handle))) { in mpi3mr_sas_host_add()
1262 …ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:… in mpi3mr_sas_host_add()
1263 mrioc->sas_hba.handle, ioc_status, __FILE__, __LINE__, in mpi3mr_sas_host_add()
1267 mrioc->sas_hba.enclosure_handle = in mpi3mr_sas_host_add()
1270 mrioc->sas_hba.sas_address = in mpi3mr_sas_host_add()
1271 le64_to_cpu(sasinf->sas_address); in mpi3mr_sas_host_add()
1273 "host_add: handle(0x%04x), sas_addr(0x%016llx), phys(%d)\n", in mpi3mr_sas_host_add()
1274 mrioc->sas_hba.handle, in mpi3mr_sas_host_add()
1275 (unsigned long long) mrioc->sas_hba.sas_address, in mpi3mr_sas_host_add()
1276 mrioc->sas_hba.num_phys); in mpi3mr_sas_host_add()
1278 if (mrioc->sas_hba.enclosure_handle) { in mpi3mr_sas_host_add()
1282 mrioc->sas_hba.enclosure_handle)) && in mpi3mr_sas_host_add()
1284 mrioc->sas_hba.enclosure_logical_id = in mpi3mr_sas_host_add()
1293 * mpi3mr_sas_port_add - Expose the SAS device to the SAS TL
1295 * @handle: Firmware device handle of the attached device
1307 u16 handle, u64 sas_address_parent, struct mpi3mr_hba_port *hba_port) in mpi3mr_sas_port_add() argument
1328 INIT_LIST_HEAD(&mr_sas_port->port_list); in mpi3mr_sas_port_add()
1329 INIT_LIST_HEAD(&mr_sas_port->phy_list); in mpi3mr_sas_port_add()
1330 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1333 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1341 if ((mpi3mr_set_identify(mrioc, handle, in mpi3mr_sas_port_add()
1342 &mr_sas_port->remote_identify))) { in mpi3mr_sas_port_add()
1348 if (mr_sas_port->remote_identify.device_type == SAS_PHY_UNUSED) { in mpi3mr_sas_port_add()
1354 mr_sas_port->hba_port = hba_port; in mpi3mr_sas_port_add()
1356 mr_sas_port->remote_identify.sas_address, hba_port); in mpi3mr_sas_port_add()
1358 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_add()
1359 if ((mr_sas_node->phy[i].remote_identify.sas_address != in mpi3mr_sas_port_add()
1360 mr_sas_port->remote_identify.sas_address) || in mpi3mr_sas_port_add()
1361 (mr_sas_node->phy[i].hba_port != hba_port)) in mpi3mr_sas_port_add()
1363 list_add_tail(&mr_sas_node->phy[i].port_siblings, in mpi3mr_sas_port_add()
1364 &mr_sas_port->phy_list); in mpi3mr_sas_port_add()
1365 mr_sas_port->num_phys++; in mpi3mr_sas_port_add()
1366 mr_sas_port->phy_mask |= (1 << i); in mpi3mr_sas_port_add()
1369 if (!mr_sas_port->num_phys) { in mpi3mr_sas_port_add()
1375 mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; in mpi3mr_sas_port_add()
1377 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1379 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1380 mr_sas_port->hba_port); in mpi3mr_sas_port_add()
1387 tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 1; in mpi3mr_sas_port_add()
1390 if (!mr_sas_node->parent_dev) { in mpi3mr_sas_port_add()
1396 port = sas_port_alloc_num(mr_sas_node->parent_dev); in mpi3mr_sas_port_add()
1403 list_for_each_entry(mr_sas_phy, &mr_sas_port->phy_list, in mpi3mr_sas_port_add()
1405 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_sas_port_add()
1406 dev_info(&port->dev, in mpi3mr_sas_port_add()
1407 "add: handle(0x%04x), sas_address(0x%016llx), phy(%d)\n", in mpi3mr_sas_port_add()
1408 handle, (unsigned long long) in mpi3mr_sas_port_add()
1409 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1410 mr_sas_phy->phy_id); in mpi3mr_sas_port_add()
1411 sas_port_add_phy(port, mr_sas_phy->phy); in mpi3mr_sas_port_add()
1412 mr_sas_phy->phy_belongs_to_port = 1; in mpi3mr_sas_port_add()
1413 mr_sas_phy->hba_port = hba_port; in mpi3mr_sas_port_add()
1416 mr_sas_port->port = port; in mpi3mr_sas_port_add()
1417 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1419 tgtdev->dev_spec.sas_sata_inf.rphy = rphy; in mpi3mr_sas_port_add()
1422 mr_sas_port->remote_identify.device_type); in mpi3mr_sas_port_add()
1424 rphy->identify = mr_sas_port->remote_identify; in mpi3mr_sas_port_add()
1426 if (mrioc->current_event) in mpi3mr_sas_port_add()
1427 mrioc->current_event->pending_at_sml = 1; in mpi3mr_sas_port_add()
1433 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1434 tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 0; in mpi3mr_sas_port_add()
1435 tgtdev->dev_spec.sas_sata_inf.sas_transport_attached = 1; in mpi3mr_sas_port_add()
1439 dev_info(&rphy->dev, in mpi3mr_sas_port_add()
1440 "%s: added: handle(0x%04x), sas_address(0x%016llx)\n", in mpi3mr_sas_port_add()
1441 __func__, handle, (unsigned long long) in mpi3mr_sas_port_add()
1442 mr_sas_port->remote_identify.sas_address); in mpi3mr_sas_port_add()
1444 mr_sas_port->rphy = rphy; in mpi3mr_sas_port_add()
1445 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1446 list_add_tail(&mr_sas_port->port_list, &mr_sas_node->sas_port_list); in mpi3mr_sas_port_add()
1447 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1449 if (mrioc->current_event) { in mpi3mr_sas_port_add()
1450 mrioc->current_event->pending_at_sml = 0; in mpi3mr_sas_port_add()
1451 if (mrioc->current_event->discard) in mpi3mr_sas_port_add()
1456 if (mr_sas_port->remote_identify.device_type == in mpi3mr_sas_port_add()
1458 mr_sas_port->remote_identify.device_type == in mpi3mr_sas_port_add()
1461 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1462 rphy_to_expander_device(rphy), hba_port->port_id); in mpi3mr_sas_port_add()
1467 list_for_each_entry_safe(mr_sas_phy, next, &mr_sas_port->phy_list, in mpi3mr_sas_port_add()
1469 list_del(&mr_sas_phy->port_siblings); in mpi3mr_sas_port_add()
1475 * mpi3mr_sas_port_remove - remove port from the list
1500 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1504 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1507 list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list, in mpi3mr_sas_port_remove()
1509 if (mr_sas_port->remote_identify.sas_address != sas_address) in mpi3mr_sas_port_remove()
1511 if (mr_sas_port->hba_port != hba_port) in mpi3mr_sas_port_remove()
1514 list_del(&mr_sas_port->port_list); in mpi3mr_sas_port_remove()
1520 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1524 if (mr_sas_node->host_node) { in mpi3mr_sas_port_remove()
1526 &mrioc->hba_port_table_list, list) { in mpi3mr_sas_port_remove()
1531 srch_port, srch_port->port_id); in mpi3mr_sas_port_remove()
1532 list_del(&hba_port->list); in mpi3mr_sas_port_remove()
1538 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_remove()
1539 if (mr_sas_node->phy[i].remote_identify.sas_address == in mpi3mr_sas_port_remove()
1541 memset(&mr_sas_node->phy[i].remote_identify, 0, in mpi3mr_sas_port_remove()
1545 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1547 if (mrioc->current_event) in mpi3mr_sas_port_remove()
1548 mrioc->current_event->pending_at_sml = 1; in mpi3mr_sas_port_remove()
1551 &mr_sas_port->phy_list, port_siblings) { in mpi3mr_sas_port_remove()
1552 if ((!mrioc->stop_drv_processing) && in mpi3mr_sas_port_remove()
1553 (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_sas_port_remove()
1554 dev_info(&mr_sas_port->port->dev, in mpi3mr_sas_port_remove()
1555 "remove: sas_address(0x%016llx), phy(%d)\n", in mpi3mr_sas_port_remove()
1557 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_remove()
1558 mr_sas_phy->phy_id); in mpi3mr_sas_port_remove()
1559 mr_sas_phy->phy_belongs_to_port = 0; in mpi3mr_sas_port_remove()
1560 if (!mrioc->stop_drv_processing) in mpi3mr_sas_port_remove()
1561 sas_port_delete_phy(mr_sas_port->port, in mpi3mr_sas_port_remove()
1562 mr_sas_phy->phy); in mpi3mr_sas_port_remove()
1563 list_del(&mr_sas_phy->port_siblings); in mpi3mr_sas_port_remove()
1565 if (!mrioc->stop_drv_processing) in mpi3mr_sas_port_remove()
1566 sas_port_delete(mr_sas_port->port); in mpi3mr_sas_port_remove()
1570 if (mrioc->current_event) { in mpi3mr_sas_port_remove()
1571 mrioc->current_event->pending_at_sml = 0; in mpi3mr_sas_port_remove()
1572 if (mrioc->current_event->discard) in mpi3mr_sas_port_remove()
1580 * struct host_port - host port details
1582 * @phy_mask: phy mask of host port
1583 * @handle: Device Handle of attached device
1586 * @lowest_phy: lowest phy ID of host port
1591 u16 handle; member
1598 * mpi3mr_update_mr_sas_port - update sas port objects during reset
1618 h_port->used = 1; in mpi3mr_update_mr_sas_port()
1619 mr_sas_port->marked_responding = 1; in mpi3mr_update_mr_sas_port()
1621 dev_info(&mr_sas_port->port->dev, in mpi3mr_update_mr_sas_port()
1623 mr_sas_port->remote_identify.sas_address, in mpi3mr_update_mr_sas_port()
1624 mr_sas_port->hba_port->port_id, mr_sas_port->phy_mask, in mpi3mr_update_mr_sas_port()
1625 h_port->iounit_port_id, h_port->phy_mask); in mpi3mr_update_mr_sas_port()
1627 mr_sas_port->hba_port->port_id = h_port->iounit_port_id; in mpi3mr_update_mr_sas_port()
1628 mr_sas_port->hba_port->flags &= ~MPI3MR_HBA_PORT_FLAG_DIRTY; in mpi3mr_update_mr_sas_port()
1631 phy_mask_xor = mr_sas_port->phy_mask ^ h_port->phy_mask; in mpi3mr_update_mr_sas_port()
1632 phys_to_be_added = h_port->phy_mask & phy_mask_xor; in mpi3mr_update_mr_sas_port()
1633 phys_to_be_removed = mr_sas_port->phy_mask & phy_mask_xor; in mpi3mr_update_mr_sas_port()
1641 mr_sas_phy = &mrioc->sas_hba.phy[i]; in mpi3mr_update_mr_sas_port()
1642 if (mr_sas_phy->phy_belongs_to_port) in mpi3mr_update_mr_sas_port()
1644 &mrioc->sas_hba, mr_sas_phy); in mpi3mr_update_mr_sas_port()
1646 &mrioc->sas_hba, mr_sas_phy, in mpi3mr_update_mr_sas_port()
1647 mr_sas_port->remote_identify.sas_address, in mpi3mr_update_mr_sas_port()
1648 mr_sas_port->hba_port); in mpi3mr_update_mr_sas_port()
1653 mr_sas_phy = &mrioc->sas_hba.phy[i]; in mpi3mr_update_mr_sas_port()
1654 if (mr_sas_phy->phy_belongs_to_port) in mpi3mr_update_mr_sas_port()
1656 &mrioc->sas_hba, mr_sas_phy); in mpi3mr_update_mr_sas_port()
1661 * mpi3mr_refresh_sas_ports - update host's sas ports during reset
1683 (mrioc->sas_hba.num_phys * in mpi3mr_refresh_sas_ports()
1695 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_refresh_sas_ports()
1697 sas_io_unit_pg0->phy_data[i].attached_dev_handle); in mpi3mr_refresh_sas_ports()
1702 if (h_port[j].handle == attached_handle) { in mpi3mr_refresh_sas_ports()
1714 "failed to read dev_pg0 for handle(0x%04x) at %s:%d/%s()!\n", in mpi3mr_refresh_sas_ports()
1720 "ioc_status(0x%x) while reading dev_pg0 for handle(0x%04x) at %s:%d/%s()!\n", in mpi3mr_refresh_sas_ports()
1728 h_port[port_idx].sas_address = le64_to_cpu(sasinf->sas_address); in mpi3mr_refresh_sas_ports()
1729 h_port[port_idx].handle = attached_handle; in mpi3mr_refresh_sas_ports()
1731 h_port[port_idx].iounit_port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_refresh_sas_ports()
1732 h_port[port_idx].lowest_phy = sasinf->phy_num; in mpi3mr_refresh_sas_ports()
1740 if (mrioc->logging_level & MPI3_DEBUG_RESET) { in mpi3mr_refresh_sas_ports()
1742 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1745 "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", in mpi3mr_refresh_sas_ports()
1746 mr_sas_port->hba_port->port_id, in mpi3mr_refresh_sas_ports()
1747 mr_sas_port->remote_identify.sas_address, in mpi3mr_refresh_sas_ports()
1748 mr_sas_port->phy_mask, mr_sas_port->lowest_phy); in mpi3mr_refresh_sas_ports()
1754 "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", in mpi3mr_refresh_sas_ports()
1761 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1763 mr_sas_port->marked_responding = 0; in mpi3mr_refresh_sas_ports()
1764 mr_sas_port->hba_port->flags |= MPI3MR_HBA_PORT_FLAG_DIRTY; in mpi3mr_refresh_sas_ports()
1767 /* First check for matching lowest phy */ in mpi3mr_refresh_sas_ports()
1770 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1772 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1774 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1776 if (h_port[i].lowest_phy == mr_sas_port->lowest_phy) { in mpi3mr_refresh_sas_ports()
1783 /* In case if lowest phy is got enabled or disabled during reset */ in mpi3mr_refresh_sas_ports()
1788 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1790 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1792 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1794 if (h_port[i].phy_mask & mr_sas_port->phy_mask) { in mpi3mr_refresh_sas_ports()
1806 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1808 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1810 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1821 * mpi3mr_refresh_expanders - Refresh expander device exposure
1835 u16 ioc_status, handle; in mpi3mr_refresh_expanders() local
1841 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1842 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { in mpi3mr_refresh_expanders()
1843 sas_expander->non_responding = 1; in mpi3mr_refresh_expanders()
1845 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1849 handle = 0xffff; in mpi3mr_refresh_expanders()
1855 MPI3_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE, handle))) { in mpi3mr_refresh_expanders()
1857 "failed to read exp pg0 for handle(0x%04x) at %s:%d/%s()!\n", in mpi3mr_refresh_expanders()
1858 handle, __FILE__, __LINE__, __func__); in mpi3mr_refresh_expanders()
1864 "ioc_status(0x%x) while reading exp pg0 for handle:(0x%04x), %s:%d/%s()!\n", in mpi3mr_refresh_expanders()
1865 ioc_status, handle, __FILE__, __LINE__, __func__); in mpi3mr_refresh_expanders()
1869 handle = le16_to_cpu(expander_pg0.dev_handle); in mpi3mr_refresh_expanders()
1875 mpi3mr_expander_add(mrioc, handle); in mpi3mr_refresh_expanders()
1879 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1883 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1887 mpi3mr_expander_add(mrioc, handle); in mpi3mr_refresh_expanders()
1891 sas_expander->non_responding = 0; in mpi3mr_refresh_expanders()
1892 if (sas_expander->handle == handle) in mpi3mr_refresh_expanders()
1895 sas_expander->handle = handle; in mpi3mr_refresh_expanders()
1896 for (i = 0 ; i < sas_expander->num_phys ; i++) in mpi3mr_refresh_expanders()
1897 sas_expander->phy[i].handle = handle; in mpi3mr_refresh_expanders()
1906 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1908 &mrioc->sas_expander_list, list) { in mpi3mr_refresh_expanders()
1909 if (sas_expander->non_responding) { in mpi3mr_refresh_expanders()
1910 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1912 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1915 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1919 * mpi3mr_expander_node_add - insert an expander to the list.
1924 * Adding new object to the ioc->sas_expander_list.
1933 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_add()
1934 list_add_tail(&sas_expander->list, &mrioc->sas_expander_list); in mpi3mr_expander_node_add()
1935 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_add()
1939 * mpi3mr_expander_add - Create expander object
1941 * @handle: Expander firmware device handle
1947 * Return: 0 for success, non-zero for failure.
1949 int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle) in mpi3mr_expander_add() argument
1965 if (!handle) in mpi3mr_expander_add()
1966 return -1; in mpi3mr_expander_add()
1968 if (mrioc->reset_in_progress) in mpi3mr_expander_add()
1969 return -1; in mpi3mr_expander_add()
1972 sizeof(expander_pg0), MPI3_SAS_EXPAND_PGAD_FORM_HANDLE, handle))) { in mpi3mr_expander_add()
1975 return -1; in mpi3mr_expander_add()
1981 return -1; in mpi3mr_expander_add()
1989 return -1; in mpi3mr_expander_add()
1997 return -1; in mpi3mr_expander_add()
2000 if (sas_address_parent != mrioc->sas_hba.sas_address) { in mpi3mr_expander_add()
2001 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2005 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2014 * speed, attached dev handle and sas address. in mpi3mr_expander_add()
2016 for (i = 0 ; i < sas_expander->num_phys ; i++) { in mpi3mr_expander_add()
2027 rc = -1; in mpi3mr_expander_add()
2033 rc = -1; in mpi3mr_expander_add()
2038 if (temp_handle != handle) in mpi3mr_expander_add()
2044 handle, i, link_rate, hba_port); in mpi3mr_expander_add()
2049 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2053 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2061 return -ENOMEM; in mpi3mr_expander_add()
2063 sas_expander->handle = handle; in mpi3mr_expander_add()
2064 sas_expander->num_phys = expander_pg0.num_phys; in mpi3mr_expander_add()
2065 sas_expander->sas_address_parent = sas_address_parent; in mpi3mr_expander_add()
2066 sas_expander->sas_address = sas_address; in mpi3mr_expander_add()
2067 sas_expander->hba_port = hba_port; in mpi3mr_expander_add()
2070 "expander_add: handle(0x%04x), parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", in mpi3mr_expander_add()
2071 handle, parent_handle, (unsigned long long) in mpi3mr_expander_add()
2072 sas_expander->sas_address, sas_expander->num_phys); in mpi3mr_expander_add()
2074 if (!sas_expander->num_phys) { in mpi3mr_expander_add()
2075 rc = -1; in mpi3mr_expander_add()
2078 sas_expander->phy = kcalloc(sas_expander->num_phys, in mpi3mr_expander_add()
2080 if (!sas_expander->phy) { in mpi3mr_expander_add()
2081 rc = -1; in mpi3mr_expander_add()
2085 INIT_LIST_HEAD(&sas_expander->sas_port_list); in mpi3mr_expander_add()
2086 mr_sas_port = mpi3mr_sas_port_add(mrioc, handle, sas_address_parent, in mpi3mr_expander_add()
2087 sas_expander->hba_port); in mpi3mr_expander_add()
2091 rc = -1; in mpi3mr_expander_add()
2094 sas_expander->parent_dev = &mr_sas_port->rphy->dev; in mpi3mr_expander_add()
2095 sas_expander->rphy = mr_sas_port->rphy; in mpi3mr_expander_add()
2097 for (i = 0 ; i < sas_expander->num_phys ; i++) { in mpi3mr_expander_add()
2099 handle; in mpi3mr_expander_add()
2106 rc = -1; in mpi3mr_expander_add()
2112 rc = -1; in mpi3mr_expander_add()
2116 sas_expander->phy[i].handle = handle; in mpi3mr_expander_add()
2117 sas_expander->phy[i].phy_id = i; in mpi3mr_expander_add()
2118 sas_expander->phy[i].hba_port = hba_port; in mpi3mr_expander_add()
2120 if ((mpi3mr_add_expander_phy(mrioc, &sas_expander->phy[i], in mpi3mr_expander_add()
2121 expander_pg1, sas_expander->parent_dev))) { in mpi3mr_expander_add()
2124 rc = -1; in mpi3mr_expander_add()
2129 if (sas_expander->enclosure_handle) { in mpi3mr_expander_add()
2132 sas_expander->enclosure_handle); in mpi3mr_expander_add()
2134 sas_expander->enclosure_logical_id = le64_to_cpu( in mpi3mr_expander_add()
2135 enclosure_dev->pg0.enclosure_logical_id); in mpi3mr_expander_add()
2145 sas_expander->sas_address, in mpi3mr_expander_add()
2146 sas_address_parent, sas_expander->hba_port); in mpi3mr_expander_add()
2147 kfree(sas_expander->phy); in mpi3mr_expander_add()
2153 * mpi3mr_expander_node_remove - recursive removal of expander.
2173 &sas_expander->sas_port_list, port_list) { in mpi3mr_expander_node_remove()
2174 if (mrioc->reset_in_progress) in mpi3mr_expander_node_remove()
2176 if (mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2179 mr_sas_port->remote_identify.sas_address, in mpi3mr_expander_node_remove()
2180 mr_sas_port->hba_port); in mpi3mr_expander_node_remove()
2181 else if (mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2183 mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2186 mr_sas_port->remote_identify.sas_address, in mpi3mr_expander_node_remove()
2187 mr_sas_port->hba_port); in mpi3mr_expander_node_remove()
2190 port_id = sas_expander->hba_port->port_id; in mpi3mr_expander_node_remove()
2191 mpi3mr_sas_port_remove(mrioc, sas_expander->sas_address, in mpi3mr_expander_node_remove()
2192 sas_expander->sas_address_parent, sas_expander->hba_port); in mpi3mr_expander_node_remove()
2194 ioc_info(mrioc, "expander_remove: handle(0x%04x), sas_addr(0x%016llx), port:%d\n", in mpi3mr_expander_node_remove()
2195 sas_expander->handle, (unsigned long long) in mpi3mr_expander_node_remove()
2196 sas_expander->sas_address, port_id); in mpi3mr_expander_node_remove()
2198 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_remove()
2199 list_del(&sas_expander->list); in mpi3mr_expander_node_remove()
2200 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_remove()
2202 kfree(sas_expander->phy); in mpi3mr_expander_node_remove()
2207 * mpi3mr_expander_remove - Remove expander object
2213 * mrioc->sas_expander_list and removes it from the SAS TL by
2224 if (mrioc->reset_in_progress) in mpi3mr_expander_remove()
2230 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_remove()
2233 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_remove()
2240 * mpi3mr_get_sas_negotiated_logical_linkrate - get linkrate
2245 * attached directly or through expander and issues sas phy
2246 * page0 or expander phy page1 and gets the link rate, if there
2261 phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; in mpi3mr_get_sas_negotiated_logical_linkrate()
2262 if (!(tgtdev->devpg0_flag & MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)) { in mpi3mr_get_sas_negotiated_logical_linkrate()
2264 | tgtdev->parent_handle); in mpi3mr_get_sas_negotiated_logical_linkrate()
2303 * mpi3mr_report_tgtdev_to_sas_transport - expose dev to SAS TL
2310 * Return: 0 on success, non-zero for failure.
2321 if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || in mpi3mr_report_tgtdev_to_sas_transport()
2322 !mrioc->sas_transport_enabled) in mpi3mr_report_tgtdev_to_sas_transport()
2323 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2325 sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; in mpi3mr_report_tgtdev_to_sas_transport()
2326 if (!mrioc->sas_hba.num_phys) in mpi3mr_report_tgtdev_to_sas_transport()
2331 if (mpi3mr_get_sas_address(mrioc, tgtdev->parent_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2335 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2337 tgtdev->dev_spec.sas_sata_inf.sas_address_parent = sas_address_parent; in mpi3mr_report_tgtdev_to_sas_transport()
2339 parent_phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; in mpi3mr_report_tgtdev_to_sas_transport()
2340 port_id = tgtdev->io_unit_port; in mpi3mr_report_tgtdev_to_sas_transport()
2346 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2348 tgtdev->dev_spec.sas_sata_inf.hba_port = hba_port; in mpi3mr_report_tgtdev_to_sas_transport()
2352 mpi3mr_update_links(mrioc, sas_address_parent, tgtdev->dev_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2355 tgtdev->host_exposed = 1; in mpi3mr_report_tgtdev_to_sas_transport()
2356 if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2358 retval = -1; in mpi3mr_report_tgtdev_to_sas_transport()
2359 } else if ((!tgtdev->starget) && (!mrioc->is_driver_loading)) { in mpi3mr_report_tgtdev_to_sas_transport()
2362 retval = -1; in mpi3mr_report_tgtdev_to_sas_transport()
2365 tgtdev->dev_spec.sas_sata_inf.hba_port = NULL; in mpi3mr_report_tgtdev_to_sas_transport()
2366 tgtdev->host_exposed = 0; in mpi3mr_report_tgtdev_to_sas_transport()
2372 * mpi3mr_remove_tgtdev_from_sas_transport - remove from SAS TL
2386 if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || in mpi3mr_remove_tgtdev_from_sas_transport()
2387 !mrioc->sas_transport_enabled) in mpi3mr_remove_tgtdev_from_sas_transport()
2390 hba_port = tgtdev->dev_spec.sas_sata_inf.hba_port; in mpi3mr_remove_tgtdev_from_sas_transport()
2391 sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; in mpi3mr_remove_tgtdev_from_sas_transport()
2392 sas_address_parent = tgtdev->dev_spec.sas_sata_inf.sas_address_parent; in mpi3mr_remove_tgtdev_from_sas_transport()
2395 tgtdev->host_exposed = 0; in mpi3mr_remove_tgtdev_from_sas_transport()
2396 tgtdev->dev_spec.sas_sata_inf.hba_port = NULL; 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
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()
2453 if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) { 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
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()
2891 /* handle expander phys */ 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()
2897 /* handle hba phys */ 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()
2950 /* handle expander phys */ 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()
2956 /* handle hba phys */ 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()
3068 /* handle expander phys */ 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()
3076 /* handle hba phys */ 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
3138 * Return: 0 on success, non-zero on failure
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
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()