Lines Matching +full:phy +full:- +full:device
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
119 * @sas_address: SAS address of the expander device
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
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
267 * @device_info: Bitfield providing information about the device
269 * Return: 1 if the device is expander device, else 0.
281 * mpi3mr_get_sas_address - retrieve sas_address for handle
283 * @handle: Firmware device handle
286 * This function issues device page0 read for a given device
289 * Return: 0 for success, non-zero for failure
303 ioc_err(mrioc, "%s: device page0 read failed\n", __func__); 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()
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
330 * @sas_address: SAS address of the device
333 * This searches for target device from sas address and hba port
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
359 * @sas_address: SAS address of the device
362 * This searches for target device from sas address and hba port
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
390 * @sas_address: SAS address of the device
393 * This searches for target device using sas address and hba
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
429 * @sas_address: SAS address of the device
432 * This searches for target device from sas address and rphy
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.
491 * If the SAS address indicates the device is direct attached to
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
746 * @sas_address: SAS address of device/expander
749 * Verifies whether the Phys attached to a device with the given
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
777 * Populates sas identify info for a specific device.
779 * Return: 0 for success, non-zero for failure.
790 if (mrioc->reset_in_progress) { in mpi3mr_set_identify()
792 return -EFAULT; in mpi3mr_set_identify()
797 ioc_err(mrioc, "%s: device page0 read failed\n", __func__); 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()
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
857 * @parent_dev: Prent device class object
859 * Return: 0 for success, non-zero for failure.
863 struct device *parent_dev) in mpi3mr_add_host_phy()
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()
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
927 * @parent_dev: Parent device class object
929 * Return: 0 for success, non-zero for failure.
934 struct device *parent_dev) in mpi3mr_add_expander_phy()
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()
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
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()
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()
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
1104 * this is executed for each device addition or device info
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
1169 * this is executed for first device addition or device info
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()
1258 ioc_err(mrioc, "%s: device page0 read failed\n", __func__); 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()
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
1300 * device matching sas address and hba_port and adds it to the
1301 * sas_node's sas_port_list and expose the attached sas device
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()
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 if (mr_sas_node->num_phys > sizeof(mr_sas_port->phy_mask) * 8) in mpi3mr_sas_port_add()
1360 mr_sas_node->num_phys); in mpi3mr_sas_port_add()
1362 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_add()
1363 if ((mr_sas_node->phy[i].remote_identify.sas_address != in mpi3mr_sas_port_add()
1364 mr_sas_port->remote_identify.sas_address) || in mpi3mr_sas_port_add()
1365 (mr_sas_node->phy[i].hba_port != hba_port)) in mpi3mr_sas_port_add()
1368 if (i > sizeof(mr_sas_port->phy_mask) * 8) { in mpi3mr_sas_port_add()
1370 i, sizeof(mr_sas_port->phy_mask) * 8); in mpi3mr_sas_port_add()
1373 list_add_tail(&mr_sas_node->phy[i].port_siblings, in mpi3mr_sas_port_add()
1374 &mr_sas_port->phy_list); in mpi3mr_sas_port_add()
1375 mr_sas_port->num_phys++; in mpi3mr_sas_port_add()
1376 mr_sas_port->phy_mask |= (1 << i); in mpi3mr_sas_port_add()
1379 if (!mr_sas_port->num_phys) { in mpi3mr_sas_port_add()
1385 mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; in mpi3mr_sas_port_add()
1387 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1389 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1390 mr_sas_port->hba_port); in mpi3mr_sas_port_add()
1397 tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 1; in mpi3mr_sas_port_add()
1400 if (!mr_sas_node->parent_dev) { in mpi3mr_sas_port_add()
1406 port = sas_port_alloc_num(mr_sas_node->parent_dev); in mpi3mr_sas_port_add()
1413 list_for_each_entry(mr_sas_phy, &mr_sas_port->phy_list, in mpi3mr_sas_port_add()
1415 if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_sas_port_add()
1416 dev_info(&port->dev, in mpi3mr_sas_port_add()
1417 "add: handle(0x%04x), sas_address(0x%016llx), phy(%d)\n", in mpi3mr_sas_port_add()
1419 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1420 mr_sas_phy->phy_id); in mpi3mr_sas_port_add()
1421 sas_port_add_phy(port, mr_sas_phy->phy); in mpi3mr_sas_port_add()
1422 mr_sas_phy->phy_belongs_to_port = 1; in mpi3mr_sas_port_add()
1423 mr_sas_phy->hba_port = hba_port; in mpi3mr_sas_port_add()
1426 mr_sas_port->port = port; in mpi3mr_sas_port_add()
1427 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1429 tgtdev->dev_spec.sas_sata_inf.rphy = rphy; in mpi3mr_sas_port_add()
1432 mr_sas_port->remote_identify.device_type); in mpi3mr_sas_port_add()
1434 rphy->identify = mr_sas_port->remote_identify; in mpi3mr_sas_port_add()
1436 if (mrioc->current_event) in mpi3mr_sas_port_add()
1437 mrioc->current_event->pending_at_sml = 1; in mpi3mr_sas_port_add()
1443 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpi3mr_sas_port_add()
1444 tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 0; in mpi3mr_sas_port_add()
1445 tgtdev->dev_spec.sas_sata_inf.sas_transport_attached = 1; in mpi3mr_sas_port_add()
1449 dev_info(&rphy->dev, in mpi3mr_sas_port_add()
1452 mr_sas_port->remote_identify.sas_address); in mpi3mr_sas_port_add()
1454 mr_sas_port->rphy = rphy; in mpi3mr_sas_port_add()
1455 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1456 list_add_tail(&mr_sas_port->port_list, &mr_sas_node->sas_port_list); in mpi3mr_sas_port_add()
1457 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_add()
1459 if (mrioc->current_event) { in mpi3mr_sas_port_add()
1460 mrioc->current_event->pending_at_sml = 0; in mpi3mr_sas_port_add()
1461 if (mrioc->current_event->discard) in mpi3mr_sas_port_add()
1466 if (mr_sas_port->remote_identify.device_type == in mpi3mr_sas_port_add()
1468 mr_sas_port->remote_identify.device_type == in mpi3mr_sas_port_add()
1471 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_add()
1472 rphy_to_expander_device(rphy), hba_port->port_id); in mpi3mr_sas_port_add()
1477 list_for_each_entry_safe(mr_sas_phy, next, &mr_sas_port->phy_list, in mpi3mr_sas_port_add()
1479 list_del(&mr_sas_phy->port_siblings); in mpi3mr_sas_port_add()
1485 * mpi3mr_sas_port_remove - remove port from the list
1487 * @sas_address: SAS address of attached device
1510 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1514 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1517 list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list, in mpi3mr_sas_port_remove()
1519 if (mr_sas_port->remote_identify.sas_address != sas_address) in mpi3mr_sas_port_remove()
1521 if (mr_sas_port->hba_port != hba_port) in mpi3mr_sas_port_remove()
1524 list_del(&mr_sas_port->port_list); in mpi3mr_sas_port_remove()
1530 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1534 if (mr_sas_node->host_node) { in mpi3mr_sas_port_remove()
1536 &mrioc->hba_port_table_list, list) { in mpi3mr_sas_port_remove()
1541 srch_port, srch_port->port_id); in mpi3mr_sas_port_remove()
1542 list_del(&hba_port->list); in mpi3mr_sas_port_remove()
1548 for (i = 0; i < mr_sas_node->num_phys; i++) { in mpi3mr_sas_port_remove()
1549 if (mr_sas_node->phy[i].remote_identify.sas_address == in mpi3mr_sas_port_remove()
1551 memset(&mr_sas_node->phy[i].remote_identify, 0, in mpi3mr_sas_port_remove()
1555 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_sas_port_remove()
1557 if (mrioc->current_event) in mpi3mr_sas_port_remove()
1558 mrioc->current_event->pending_at_sml = 1; in mpi3mr_sas_port_remove()
1561 &mr_sas_port->phy_list, port_siblings) { in mpi3mr_sas_port_remove()
1562 if ((!mrioc->stop_drv_processing) && in mpi3mr_sas_port_remove()
1563 (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) in mpi3mr_sas_port_remove()
1564 dev_info(&mr_sas_port->port->dev, in mpi3mr_sas_port_remove()
1565 "remove: sas_address(0x%016llx), phy(%d)\n", in mpi3mr_sas_port_remove()
1567 mr_sas_port->remote_identify.sas_address, in mpi3mr_sas_port_remove()
1568 mr_sas_phy->phy_id); in mpi3mr_sas_port_remove()
1569 mr_sas_phy->phy_belongs_to_port = 0; in mpi3mr_sas_port_remove()
1570 if (!mrioc->stop_drv_processing) in mpi3mr_sas_port_remove()
1571 sas_port_delete_phy(mr_sas_port->port, in mpi3mr_sas_port_remove()
1572 mr_sas_phy->phy); in mpi3mr_sas_port_remove()
1573 list_del(&mr_sas_phy->port_siblings); in mpi3mr_sas_port_remove()
1575 if (!mrioc->stop_drv_processing) in mpi3mr_sas_port_remove()
1576 sas_port_delete(mr_sas_port->port); in mpi3mr_sas_port_remove()
1580 if (mrioc->current_event) { in mpi3mr_sas_port_remove()
1581 mrioc->current_event->pending_at_sml = 0; in mpi3mr_sas_port_remove()
1582 if (mrioc->current_event->discard) in mpi3mr_sas_port_remove()
1590 * struct host_port - host port details
1591 * @sas_address: SAS Address of the attached device
1592 * @phy_mask: phy mask of host port
1593 * @handle: Device Handle of attached device
1596 * @lowest_phy: lowest phy ID of host port
1608 * mpi3mr_update_mr_sas_port - update sas port objects during reset
1628 h_port->used = 1; in mpi3mr_update_mr_sas_port()
1629 mr_sas_port->marked_responding = 1; in mpi3mr_update_mr_sas_port()
1631 dev_info(&mr_sas_port->port->dev, in mpi3mr_update_mr_sas_port()
1633 mr_sas_port->remote_identify.sas_address, in mpi3mr_update_mr_sas_port()
1634 mr_sas_port->hba_port->port_id, mr_sas_port->phy_mask, in mpi3mr_update_mr_sas_port()
1635 h_port->iounit_port_id, h_port->phy_mask); in mpi3mr_update_mr_sas_port()
1637 mr_sas_port->hba_port->port_id = h_port->iounit_port_id; in mpi3mr_update_mr_sas_port()
1638 mr_sas_port->hba_port->flags &= ~MPI3MR_HBA_PORT_FLAG_DIRTY; in mpi3mr_update_mr_sas_port()
1641 phy_mask_xor = mr_sas_port->phy_mask ^ h_port->phy_mask; in mpi3mr_update_mr_sas_port()
1642 phys_to_be_added = h_port->phy_mask & phy_mask_xor; in mpi3mr_update_mr_sas_port()
1643 phys_to_be_removed = mr_sas_port->phy_mask & phy_mask_xor; in mpi3mr_update_mr_sas_port()
1651 mr_sas_phy = &mrioc->sas_hba.phy[i]; in mpi3mr_update_mr_sas_port()
1652 if (mr_sas_phy->phy_belongs_to_port) in mpi3mr_update_mr_sas_port()
1654 &mrioc->sas_hba, mr_sas_phy); in mpi3mr_update_mr_sas_port()
1656 &mrioc->sas_hba, mr_sas_phy, in mpi3mr_update_mr_sas_port()
1657 mr_sas_port->remote_identify.sas_address, in mpi3mr_update_mr_sas_port()
1658 mr_sas_port->hba_port); in mpi3mr_update_mr_sas_port()
1663 mr_sas_phy = &mrioc->sas_hba.phy[i]; in mpi3mr_update_mr_sas_port()
1664 if (mr_sas_phy->phy_belongs_to_port) in mpi3mr_update_mr_sas_port()
1666 &mrioc->sas_hba, mr_sas_phy); in mpi3mr_update_mr_sas_port()
1671 * mpi3mr_refresh_sas_ports - update host's sas ports during reset
1693 (mrioc->sas_hba.num_phys * in mpi3mr_refresh_sas_ports()
1705 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_refresh_sas_ports()
1707 sas_io_unit_pg0->phy_data[i].attached_dev_handle); in mpi3mr_refresh_sas_ports()
1738 h_port[port_idx].sas_address = le64_to_cpu(sasinf->sas_address); in mpi3mr_refresh_sas_ports()
1741 h_port[port_idx].iounit_port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_refresh_sas_ports()
1742 h_port[port_idx].lowest_phy = sasinf->phy_num; in mpi3mr_refresh_sas_ports()
1750 if (mrioc->logging_level & MPI3_DEBUG_RESET) { in mpi3mr_refresh_sas_ports()
1752 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1755 "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", in mpi3mr_refresh_sas_ports()
1756 mr_sas_port->hba_port->port_id, in mpi3mr_refresh_sas_ports()
1757 mr_sas_port->remote_identify.sas_address, in mpi3mr_refresh_sas_ports()
1758 mr_sas_port->phy_mask, mr_sas_port->lowest_phy); in mpi3mr_refresh_sas_ports()
1764 "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", in mpi3mr_refresh_sas_ports()
1771 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1773 mr_sas_port->marked_responding = 0; in mpi3mr_refresh_sas_ports()
1774 mr_sas_port->hba_port->flags |= MPI3MR_HBA_PORT_FLAG_DIRTY; in mpi3mr_refresh_sas_ports()
1777 /* First check for matching lowest phy */ in mpi3mr_refresh_sas_ports()
1780 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1782 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1784 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1786 if (h_port[i].lowest_phy == mr_sas_port->lowest_phy) { in mpi3mr_refresh_sas_ports()
1793 /* In case if lowest phy is got enabled or disabled during reset */ in mpi3mr_refresh_sas_ports()
1798 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1800 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1802 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1804 if (h_port[i].phy_mask & mr_sas_port->phy_mask) { in mpi3mr_refresh_sas_ports()
1816 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1818 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1820 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1831 * mpi3mr_refresh_expanders - Refresh expander device exposure
1836 * or expose any newly detected expander device to the upper layers.
1851 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1852 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { in mpi3mr_refresh_expanders()
1853 sas_expander->non_responding = 1; in mpi3mr_refresh_expanders()
1855 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1889 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1893 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1901 sas_expander->non_responding = 0; in mpi3mr_refresh_expanders()
1902 if (sas_expander->handle == handle) in mpi3mr_refresh_expanders()
1905 sas_expander->handle = handle; in mpi3mr_refresh_expanders()
1906 for (i = 0 ; i < sas_expander->num_phys ; i++) in mpi3mr_refresh_expanders()
1907 sas_expander->phy[i].handle = handle; in mpi3mr_refresh_expanders()
1912 * hba_port if the non responding expander device's parent device in mpi3mr_refresh_expanders()
1916 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1918 &mrioc->sas_expander_list, list) { in mpi3mr_refresh_expanders()
1919 if (sas_expander->non_responding) { in mpi3mr_refresh_expanders()
1920 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1922 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1925 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1929 * mpi3mr_expander_node_add - insert an expander to the list.
1934 * Adding new object to the ioc->sas_expander_list.
1943 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_add()
1944 list_add_tail(&sas_expander->list, &mrioc->sas_expander_list); in mpi3mr_expander_node_add()
1945 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_add()
1949 * mpi3mr_expander_add - Create expander object
1951 * @handle: Expander firmware device handle
1957 * Return: 0 for success, non-zero for failure.
1976 return -1; in mpi3mr_expander_add()
1978 if (mrioc->reset_in_progress) in mpi3mr_expander_add()
1979 return -1; in mpi3mr_expander_add()
1985 return -1; in mpi3mr_expander_add()
1991 return -1; in mpi3mr_expander_add()
1999 return -1; in mpi3mr_expander_add()
2007 return -1; in mpi3mr_expander_add()
2010 if (sas_address_parent != mrioc->sas_hba.sas_address) { in mpi3mr_expander_add()
2011 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2015 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2026 for (i = 0 ; i < sas_expander->num_phys ; i++) { in mpi3mr_expander_add()
2037 rc = -1; in mpi3mr_expander_add()
2043 rc = -1; in mpi3mr_expander_add()
2059 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2063 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2071 return -ENOMEM; in mpi3mr_expander_add()
2073 sas_expander->handle = handle; in mpi3mr_expander_add()
2074 sas_expander->num_phys = expander_pg0.num_phys; in mpi3mr_expander_add()
2075 sas_expander->sas_address_parent = sas_address_parent; in mpi3mr_expander_add()
2076 sas_expander->sas_address = sas_address; in mpi3mr_expander_add()
2077 sas_expander->hba_port = hba_port; in mpi3mr_expander_add()
2082 sas_expander->sas_address, sas_expander->num_phys); in mpi3mr_expander_add()
2084 if (!sas_expander->num_phys) { in mpi3mr_expander_add()
2085 rc = -1; in mpi3mr_expander_add()
2088 sas_expander->phy = kcalloc(sas_expander->num_phys, in mpi3mr_expander_add()
2090 if (!sas_expander->phy) { in mpi3mr_expander_add()
2091 rc = -1; in mpi3mr_expander_add()
2095 INIT_LIST_HEAD(&sas_expander->sas_port_list); in mpi3mr_expander_add()
2097 sas_expander->hba_port); in mpi3mr_expander_add()
2101 rc = -1; in mpi3mr_expander_add()
2104 sas_expander->parent_dev = &mr_sas_port->rphy->dev; in mpi3mr_expander_add()
2105 sas_expander->rphy = mr_sas_port->rphy; in mpi3mr_expander_add()
2107 for (i = 0 ; i < sas_expander->num_phys ; i++) { in mpi3mr_expander_add()
2116 rc = -1; in mpi3mr_expander_add()
2122 rc = -1; in mpi3mr_expander_add()
2126 sas_expander->phy[i].handle = handle; in mpi3mr_expander_add()
2127 sas_expander->phy[i].phy_id = i; in mpi3mr_expander_add()
2128 sas_expander->phy[i].hba_port = hba_port; in mpi3mr_expander_add()
2130 if ((mpi3mr_add_expander_phy(mrioc, &sas_expander->phy[i], in mpi3mr_expander_add()
2131 expander_pg1, sas_expander->parent_dev))) { in mpi3mr_expander_add()
2134 rc = -1; in mpi3mr_expander_add()
2139 if (sas_expander->enclosure_handle) { in mpi3mr_expander_add()
2142 sas_expander->enclosure_handle); in mpi3mr_expander_add()
2144 sas_expander->enclosure_logical_id = le64_to_cpu( in mpi3mr_expander_add()
2145 enclosure_dev->pg0.enclosure_logical_id); in mpi3mr_expander_add()
2155 sas_expander->sas_address, in mpi3mr_expander_add()
2156 sas_address_parent, sas_expander->hba_port); in mpi3mr_expander_add()
2157 kfree(sas_expander->phy); in mpi3mr_expander_add()
2163 * mpi3mr_expander_node_remove - recursive removal of expander.
2165 * @sas_expander: Expander device object
2169 * one of the attached device is an expander then it recursively
2170 * removes the expander device too.
2183 &sas_expander->sas_port_list, port_list) { in mpi3mr_expander_node_remove()
2184 if (mrioc->reset_in_progress) in mpi3mr_expander_node_remove()
2186 if (mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2189 mr_sas_port->remote_identify.sas_address, in mpi3mr_expander_node_remove()
2190 mr_sas_port->hba_port); in mpi3mr_expander_node_remove()
2191 else if (mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2193 mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2196 mr_sas_port->remote_identify.sas_address, in mpi3mr_expander_node_remove()
2197 mr_sas_port->hba_port); in mpi3mr_expander_node_remove()
2200 port_id = sas_expander->hba_port->port_id; in mpi3mr_expander_node_remove()
2201 mpi3mr_sas_port_remove(mrioc, sas_expander->sas_address, in mpi3mr_expander_node_remove()
2202 sas_expander->sas_address_parent, sas_expander->hba_port); in mpi3mr_expander_node_remove()
2205 sas_expander->handle, (unsigned long long) in mpi3mr_expander_node_remove()
2206 sas_expander->sas_address, port_id); in mpi3mr_expander_node_remove()
2208 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_remove()
2209 list_del(&sas_expander->list); in mpi3mr_expander_node_remove()
2210 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_remove()
2212 kfree(sas_expander->phy); in mpi3mr_expander_node_remove()
2217 * mpi3mr_expander_remove - Remove expander object
2223 * mrioc->sas_expander_list and removes it from the SAS TL by
2234 if (mrioc->reset_in_progress) in mpi3mr_expander_remove()
2240 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_remove()
2243 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_remove()
2250 * mpi3mr_get_sas_negotiated_logical_linkrate - get linkrate
2252 * @tgtdev: Target device
2254 * This function identifies whether the target device is
2255 * attached directly or through expander and issues sas phy
2256 * page0 or expander phy page1 and gets the link rate, if there
2271 phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; in mpi3mr_get_sas_negotiated_logical_linkrate()
2272 if (!(tgtdev->devpg0_flag & MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)) { in mpi3mr_get_sas_negotiated_logical_linkrate()
2274 | tgtdev->parent_handle); in mpi3mr_get_sas_negotiated_logical_linkrate()
2313 * mpi3mr_report_tgtdev_to_sas_transport - expose dev to SAS TL
2315 * @tgtdev: Target device
2317 * This function exposes the target device after
2320 * Return: 0 on success, non-zero for failure.
2331 if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || in mpi3mr_report_tgtdev_to_sas_transport()
2332 !mrioc->sas_transport_enabled) in mpi3mr_report_tgtdev_to_sas_transport()
2333 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2335 sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; in mpi3mr_report_tgtdev_to_sas_transport()
2336 if (!mrioc->sas_hba.num_phys) in mpi3mr_report_tgtdev_to_sas_transport()
2341 if (mpi3mr_get_sas_address(mrioc, tgtdev->parent_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2345 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2347 tgtdev->dev_spec.sas_sata_inf.sas_address_parent = sas_address_parent; in mpi3mr_report_tgtdev_to_sas_transport()
2349 parent_phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; in mpi3mr_report_tgtdev_to_sas_transport()
2350 port_id = tgtdev->io_unit_port; in mpi3mr_report_tgtdev_to_sas_transport()
2356 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2358 tgtdev->dev_spec.sas_sata_inf.hba_port = hba_port; in mpi3mr_report_tgtdev_to_sas_transport()
2362 mpi3mr_update_links(mrioc, sas_address_parent, tgtdev->dev_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2365 tgtdev->host_exposed = 1; in mpi3mr_report_tgtdev_to_sas_transport()
2366 if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2368 retval = -1; in mpi3mr_report_tgtdev_to_sas_transport()
2369 } else if ((!tgtdev->starget) && (!mrioc->is_driver_loading)) { in mpi3mr_report_tgtdev_to_sas_transport()
2372 retval = -1; in mpi3mr_report_tgtdev_to_sas_transport()
2375 tgtdev->dev_spec.sas_sata_inf.hba_port = NULL; in mpi3mr_report_tgtdev_to_sas_transport()
2376 tgtdev->host_exposed = 0; in mpi3mr_report_tgtdev_to_sas_transport()
2382 * mpi3mr_remove_tgtdev_from_sas_transport - remove from SAS TL
2384 * @tgtdev: Target device
2386 * This function removes the target device
2396 if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || in mpi3mr_remove_tgtdev_from_sas_transport()
2397 !mrioc->sas_transport_enabled) in mpi3mr_remove_tgtdev_from_sas_transport()
2400 hba_port = tgtdev->dev_spec.sas_sata_inf.hba_port; in mpi3mr_remove_tgtdev_from_sas_transport()
2401 sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; in mpi3mr_remove_tgtdev_from_sas_transport()
2402 sas_address_parent = tgtdev->dev_spec.sas_sata_inf.sas_address_parent; in mpi3mr_remove_tgtdev_from_sas_transport()
2405 tgtdev->host_exposed = 0; in mpi3mr_remove_tgtdev_from_sas_transport()
2406 tgtdev->dev_spec.sas_sata_inf.hba_port = NULL; in mpi3mr_remove_tgtdev_from_sas_transport()
2410 * mpi3mr_get_port_id_by_sas_phy - Get port ID of the given phy
2411 * @phy: SAS transport layer phy object
2415 static inline u8 mpi3mr_get_port_id_by_sas_phy(struct sas_phy *phy) in mpi3mr_get_port_id_by_sas_phy() argument
2418 struct mpi3mr_hba_port *hba_port = phy->hostdata; in mpi3mr_get_port_id_by_sas_phy()
2421 port_id = hba_port->port_id; in mpi3mr_get_port_id_by_sas_phy()
2427 * mpi3mr_get_port_id_by_rphy - Get Port number from SAS rphy
2430 * @rphy: SAS transport layer remote phy object
2432 * Retrieves HBA port number in which the device pointed by the
2447 if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE || in mpi3mr_get_port_id_by_rphy()
2448 rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) { in mpi3mr_get_port_id_by_rphy()
2449 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_get_port_id_by_rphy()
2450 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, in mpi3mr_get_port_id_by_rphy()
2452 if (sas_expander->rphy == rphy) { in mpi3mr_get_port_id_by_rphy()
2453 port_id = sas_expander->hba_port->port_id; in mpi3mr_get_port_id_by_rphy()
2457 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_get_port_id_by_rphy()
2458 } else if (rphy->identify.device_type == SAS_END_DEVICE) { in mpi3mr_get_port_id_by_rphy()
2459 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_get_port_id_by_rphy()
2462 rphy->identify.sas_address, rphy); in mpi3mr_get_port_id_by_rphy()
2463 if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) { in mpi3mr_get_port_id_by_rphy()
2465 tgtdev->dev_spec.sas_sata_inf.hba_port->port_id; in mpi3mr_get_port_id_by_rphy()
2468 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_get_port_id_by_rphy()
2473 static inline struct mpi3mr_ioc *phy_to_mrioc(struct sas_phy *phy) in phy_to_mrioc() argument
2475 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in phy_to_mrioc()
2482 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); in rphy_to_mrioc()
2487 /* report phy error log structure */
2498 /* report phy error log reply structure */
2516 * mpi3mr_get_expander_phy_error_log - return expander counters:
2518 * @phy: The SAS transport layer phy object
2520 * Return: 0 for success, non-zero for failure.
2524 struct sas_phy *phy) in mpi3mr_get_expander_phy_error_log() argument
2540 if (mrioc->reset_in_progress) { in mpi3mr_get_expander_phy_error_log()
2542 return -EFAULT; in mpi3mr_get_expander_phy_error_log()
2548 data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma, in mpi3mr_get_expander_phy_error_log()
2551 rc = -ENOMEM; in mpi3mr_get_expander_phy_error_log()
2558 rc = -EINVAL; in mpi3mr_get_expander_phy_error_log()
2561 phy_error_log_request->smp_frame_type = 0x40; in mpi3mr_get_expander_phy_error_log()
2562 phy_error_log_request->function = 0x11; in mpi3mr_get_expander_phy_error_log()
2563 phy_error_log_request->request_length = 2; in mpi3mr_get_expander_phy_error_log()
2564 phy_error_log_request->allocated_response_length = 0; in mpi3mr_get_expander_phy_error_log()
2565 phy_error_log_request->phy_identifier = phy->number; in mpi3mr_get_expander_phy_error_log()
2571 mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_sas_phy(phy); in mpi3mr_get_expander_phy_error_log()
2572 mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address); in mpi3mr_get_expander_phy_error_log()
2581 "sending phy error log SMP request to sas_address(0x%016llx), phy_id(%d)\n", in mpi3mr_get_expander_phy_error_log()
2582 (unsigned long long)phy->identify.sas_address, phy->number); in mpi3mr_get_expander_phy_error_log()
2589 "phy error log SMP request completed with ioc_status(0x%04x)\n", in mpi3mr_get_expander_phy_error_log()
2594 "phy error log - reply data transfer size(%d)\n", in mpi3mr_get_expander_phy_error_log()
2602 "phy error log - function_result(%d)\n", in mpi3mr_get_expander_phy_error_log()
2603 phy_error_log_reply->function_result); in mpi3mr_get_expander_phy_error_log()
2605 phy->invalid_dword_count = in mpi3mr_get_expander_phy_error_log()
2606 be32_to_cpu(phy_error_log_reply->invalid_dword); in mpi3mr_get_expander_phy_error_log()
2607 phy->running_disparity_error_count = in mpi3mr_get_expander_phy_error_log()
2608 be32_to_cpu(phy_error_log_reply->running_disparity_error); in mpi3mr_get_expander_phy_error_log()
2609 phy->loss_of_dword_sync_count = in mpi3mr_get_expander_phy_error_log()
2610 be32_to_cpu(phy_error_log_reply->loss_of_dword_sync); in mpi3mr_get_expander_phy_error_log()
2611 phy->phy_reset_problem_count = in mpi3mr_get_expander_phy_error_log()
2612 be32_to_cpu(phy_error_log_reply->phy_reset_problem); in mpi3mr_get_expander_phy_error_log()
2618 dma_free_coherent(&mrioc->pdev->dev, sz, data_out, in mpi3mr_get_expander_phy_error_log()
2625 * mpi3mr_transport_get_linkerrors - return phy error counters
2626 * @phy: The SAS transport layer phy object
2628 * This function retrieves the phy error log information of the
2629 * HBA or expander for which the phy belongs to
2631 * Return: 0 for success, non-zero for failure.
2633 static int mpi3mr_transport_get_linkerrors(struct sas_phy *phy) in mpi3mr_transport_get_linkerrors() argument
2635 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_get_linkerrors()
2640 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_get_linkerrors()
2644 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_get_linkerrors()
2645 return mpi3mr_get_expander_phy_error_log(mrioc, phy); in mpi3mr_transport_get_linkerrors()
2648 /* get hba phy error logs */ in mpi3mr_transport_get_linkerrors()
2651 MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number))) { in mpi3mr_transport_get_linkerrors()
2654 return -ENXIO; in mpi3mr_transport_get_linkerrors()
2660 return -ENXIO; in mpi3mr_transport_get_linkerrors()
2662 phy->invalid_dword_count = le32_to_cpu(phy_pg1.invalid_dword_count); in mpi3mr_transport_get_linkerrors()
2663 phy->running_disparity_error_count = in mpi3mr_transport_get_linkerrors()
2665 phy->loss_of_dword_sync_count = in mpi3mr_transport_get_linkerrors()
2667 phy->phy_reset_problem_count = in mpi3mr_transport_get_linkerrors()
2673 * mpi3mr_transport_get_enclosure_identifier - Get Enclosure ID
2674 * @rphy: The SAS transport layer remote phy object
2677 * Returns the enclosure id for the device pointed by the remote
2678 * phy object.
2680 * Return: 0 on success or -ENXIO
2691 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_enclosure_identifier()
2693 rphy->identify.sas_address, rphy); in mpi3mr_transport_get_enclosure_identifier()
2696 tgtdev->enclosure_logical_id; in mpi3mr_transport_get_enclosure_identifier()
2701 rc = -ENXIO; in mpi3mr_transport_get_enclosure_identifier()
2703 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_enclosure_identifier()
2709 * mpi3mr_transport_get_bay_identifier - Get bay ID
2710 * @rphy: The SAS transport layer remote phy object
2712 * Returns the slot id for the device pointed by the remote phy
2715 * Return: Valid slot ID on success or -ENXIO
2725 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_bay_identifier()
2727 rphy->identify.sas_address, rphy); in mpi3mr_transport_get_bay_identifier()
2729 rc = tgtdev->slot; in mpi3mr_transport_get_bay_identifier()
2732 rc = -ENXIO; in mpi3mr_transport_get_bay_identifier()
2733 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_bay_identifier()
2738 /* phy control request structure */
2755 /* phy control reply structure */
2768 * mpi3mr_expander_phy_control - expander phy control
2770 * @phy: The SAS transport layer phy object
2771 * @phy_operation: The phy operation to be executed
2773 * Issues SMP passthru phy control request to execute a specific
2774 * phy operation for a given expander device.
2776 * Return: 0 for success, non-zero for failure.
2780 struct sas_phy *phy, u8 phy_operation) in mpi3mr_expander_phy_control() argument
2799 if (mrioc->reset_in_progress) { in mpi3mr_expander_phy_control()
2801 return -EFAULT; in mpi3mr_expander_phy_control()
2807 data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma, in mpi3mr_expander_phy_control()
2810 rc = -ENOMEM; in mpi3mr_expander_phy_control()
2817 rc = -EINVAL; in mpi3mr_expander_phy_control()
2821 phy_control_request->smp_frame_type = 0x40; in mpi3mr_expander_phy_control()
2822 phy_control_request->function = 0x91; in mpi3mr_expander_phy_control()
2823 phy_control_request->request_length = 9; in mpi3mr_expander_phy_control()
2824 phy_control_request->allocated_response_length = 0; in mpi3mr_expander_phy_control()
2825 phy_control_request->phy_identifier = phy->number; in mpi3mr_expander_phy_control()
2826 phy_control_request->phy_operation = phy_operation; in mpi3mr_expander_phy_control()
2827 phy_control_request->programmed_min_physical_link_rate = in mpi3mr_expander_phy_control()
2828 phy->minimum_linkrate << 4; in mpi3mr_expander_phy_control()
2829 phy_control_request->programmed_max_physical_link_rate = in mpi3mr_expander_phy_control()
2830 phy->maximum_linkrate << 4; in mpi3mr_expander_phy_control()
2836 mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_sas_phy(phy); in mpi3mr_expander_phy_control()
2837 mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address); in mpi3mr_expander_phy_control()
2846 "sending phy control SMP request to sas_address(0x%016llx), phy_id(%d) opcode(%d)\n", in mpi3mr_expander_phy_control()
2847 (unsigned long long)phy->identify.sas_address, phy->number, in mpi3mr_expander_phy_control()
2855 "phy control SMP request completed with ioc_status(0x%04x)\n", in mpi3mr_expander_phy_control()
2860 "phy control - reply data transfer size(%d)\n", in mpi3mr_expander_phy_control()
2867 "phy control - function_result(%d)\n", in mpi3mr_expander_phy_control()
2868 phy_control_reply->function_result); in mpi3mr_expander_phy_control()
2873 dma_free_coherent(&mrioc->pdev->dev, sz, data_out, in mpi3mr_expander_phy_control()
2880 * mpi3mr_transport_phy_reset - Reset a given phy
2881 * @phy: The SAS transport layer phy object
2884 * Return: 0 for success, non-zero for failure.
2887 mpi3mr_transport_phy_reset(struct sas_phy *phy, int hard_reset) in mpi3mr_transport_phy_reset() argument
2889 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_phy_reset()
2897 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_phy_reset()
2902 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_phy_reset()
2903 return mpi3mr_expander_phy_control(mrioc, phy, in mpi3mr_transport_phy_reset()
2916 phy->number; in mpi3mr_transport_phy_reset()
2919 "sending phy reset request to sas_address(0x%016llx), phy_id(%d) hard_reset(%d)\n", in mpi3mr_transport_phy_reset()
2920 (unsigned long long)phy->identify.sas_address, phy->number, in mpi3mr_transport_phy_reset()
2925 rc = -EAGAIN; in mpi3mr_transport_phy_reset()
2930 "phy reset request completed with ioc_status(0x%04x)\n", in mpi3mr_transport_phy_reset()
2937 * mpi3mr_transport_phy_enable - enable/disable phys
2938 * @phy: The SAS transport layer phy object
2939 * @enable: flag to enable/disable, enable phy when true
2942 * configuration page changes or expander phy control command
2944 * Return: 0 for success, non-zero for failure.
2947 mpi3mr_transport_phy_enable(struct sas_phy *phy, int enable) in mpi3mr_transport_phy_enable() argument
2949 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_phy_enable()
2956 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_phy_enable()
2961 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_phy_enable()
2962 return mpi3mr_expander_phy_control(mrioc, phy, in mpi3mr_transport_phy_enable()
2968 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_enable()
2972 rc = -ENOMEM; in mpi3mr_transport_phy_enable()
2978 rc = -ENXIO; in mpi3mr_transport_phy_enable()
2983 for (i = 0, discovery_active = 0; i < mrioc->sas_hba.num_phys ; i++) { in mpi3mr_transport_phy_enable()
2984 if (sas_io_unit_pg0->phy_data[i].port_flags & in mpi3mr_transport_phy_enable()
2987 "discovery is active on port = %d, phy = %d\n" in mpi3mr_transport_phy_enable()
2989 sas_io_unit_pg0->phy_data[i].io_unit_port, i); in mpi3mr_transport_phy_enable()
2995 rc = -EAGAIN; in mpi3mr_transport_phy_enable()
2999 if ((sas_io_unit_pg0->phy_data[phy->number].phy_flags & in mpi3mr_transport_phy_enable()
3004 rc = -ENXIO; in mpi3mr_transport_phy_enable()
3010 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_enable()
3014 rc = -ENOMEM; in mpi3mr_transport_phy_enable()
3021 rc = -ENXIO; in mpi3mr_transport_phy_enable()
3026 sas_io_unit_pg1->phy_data[phy->number].phy_flags in mpi3mr_transport_phy_enable()
3029 sas_io_unit_pg1->phy_data[phy->number].phy_flags in mpi3mr_transport_phy_enable()
3036 mpi3mr_transport_phy_reset(phy, 0); in mpi3mr_transport_phy_enable()
3045 * mpi3mr_transport_phy_speed - set phy min/max speed
3046 * @phy: The SAS transport later phy object
3050 * argument to the given phy by executing required configuration
3051 * page changes or expander phy control command
3053 * Return: 0 for success, non-zero for failure.
3056 mpi3mr_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) in mpi3mr_transport_phy_speed() argument
3058 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_phy_speed()
3064 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_phy_speed()
3068 if (!rates->minimum_linkrate) in mpi3mr_transport_phy_speed()
3069 rates->minimum_linkrate = phy->minimum_linkrate; in mpi3mr_transport_phy_speed()
3070 else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) in mpi3mr_transport_phy_speed()
3071 rates->minimum_linkrate = phy->minimum_linkrate_hw; in mpi3mr_transport_phy_speed()
3073 if (!rates->maximum_linkrate) in mpi3mr_transport_phy_speed()
3074 rates->maximum_linkrate = phy->maximum_linkrate; in mpi3mr_transport_phy_speed()
3075 else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) in mpi3mr_transport_phy_speed()
3076 rates->maximum_linkrate = phy->maximum_linkrate_hw; in mpi3mr_transport_phy_speed()
3079 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) { in mpi3mr_transport_phy_speed()
3080 phy->minimum_linkrate = rates->minimum_linkrate; in mpi3mr_transport_phy_speed()
3081 phy->maximum_linkrate = rates->maximum_linkrate; in mpi3mr_transport_phy_speed()
3082 return mpi3mr_expander_phy_control(mrioc, phy, in mpi3mr_transport_phy_speed()
3088 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_speed()
3092 rc = -ENOMEM; in mpi3mr_transport_phy_speed()
3099 rc = -ENXIO; in mpi3mr_transport_phy_speed()
3103 sas_io_unit_pg1->phy_data[phy->number].max_min_link_rate = in mpi3mr_transport_phy_speed()
3104 (rates->minimum_linkrate + (rates->maximum_linkrate << 4)); in mpi3mr_transport_phy_speed()
3109 rc = -ENXIO; in mpi3mr_transport_phy_speed()
3114 mpi3mr_transport_phy_reset(phy, 0); in mpi3mr_transport_phy_speed()
3116 /* read phy page 0, then update the rates in the sas transport phy */ in mpi3mr_transport_phy_speed()
3119 MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number) && in mpi3mr_transport_phy_speed()
3121 phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_transport_phy_speed()
3124 phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_transport_phy_speed()
3126 phy->negotiated_linkrate = in mpi3mr_transport_phy_speed()
3139 * mpi3mr_map_smp_buffer - map BSG dma buffer
3140 * @dev: Generic device reference
3148 * Return: 0 on success, non-zero on failure
3151 mpi3mr_map_smp_buffer(struct device *dev, struct bsg_buffer *buf, in mpi3mr_map_smp_buffer()
3155 if (buf->sg_cnt > 1) { in mpi3mr_map_smp_buffer()
3156 *p = dma_alloc_coherent(dev, buf->payload_len, dma_addr, in mpi3mr_map_smp_buffer()
3159 return -ENOMEM; in mpi3mr_map_smp_buffer()
3160 *dma_len = buf->payload_len; in mpi3mr_map_smp_buffer()
3162 if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL)) in mpi3mr_map_smp_buffer()
3163 return -ENOMEM; in mpi3mr_map_smp_buffer()
3164 *dma_addr = sg_dma_address(buf->sg_list); in mpi3mr_map_smp_buffer()
3165 *dma_len = sg_dma_len(buf->sg_list); in mpi3mr_map_smp_buffer()
3173 * mpi3mr_unmap_smp_buffer - unmap BSG dma buffer
3174 * @dev: Generic device reference
3182 mpi3mr_unmap_smp_buffer(struct device *dev, struct bsg_buffer *buf, in mpi3mr_unmap_smp_buffer()
3186 dma_free_coherent(dev, buf->payload_len, p, dma_addr); in mpi3mr_unmap_smp_buffer()
3188 dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL); in mpi3mr_unmap_smp_buffer()
3192 * mpi3mr_transport_smp_handler - handler for smp passthru
3221 if (mrioc->reset_in_progress) { in mpi3mr_transport_smp_handler()
3223 rc = -EFAULT; in mpi3mr_transport_smp_handler()
3227 rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->request_payload, in mpi3mr_transport_smp_handler()
3233 sg_copy_to_buffer(job->request_payload.sg_list, in mpi3mr_transport_smp_handler()
3234 job->request_payload.sg_cnt, addr_out, in mpi3mr_transport_smp_handler()
3235 job->request_payload.payload_len); in mpi3mr_transport_smp_handler()
3237 rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->reply_payload, in mpi3mr_transport_smp_handler()
3248 cpu_to_le64(rphy->identify.sas_address) : in mpi3mr_transport_smp_handler()
3249 cpu_to_le64(mrioc->sas_hba.sas_address)); in mpi3mr_transport_smp_handler()
3251 mpi3mr_add_sg_single(psge, sgl_flags, dma_len_out - 4, dma_addr_out); in mpi3mr_transport_smp_handler()
3254 mpi3mr_add_sg_single(psge, sgl_flags, dma_len_in - 4, dma_addr_in); in mpi3mr_transport_smp_handler()
3268 "SMP request - reply data transfer size(%d)\n", in mpi3mr_transport_smp_handler()
3271 memcpy(job->reply, &mpi_reply, reply_sz); in mpi3mr_transport_smp_handler()
3272 job->reply_len = reply_sz; in mpi3mr_transport_smp_handler()
3276 sg_copy_from_buffer(job->reply_payload.sg_list, in mpi3mr_transport_smp_handler()
3277 job->reply_payload.sg_cnt, addr_in, in mpi3mr_transport_smp_handler()
3278 job->reply_payload.payload_len); in mpi3mr_transport_smp_handler()
3282 mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->reply_payload, in mpi3mr_transport_smp_handler()
3285 mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->request_payload, in mpi3mr_transport_smp_handler()