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 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()
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()
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
1477 * @sas_address: SAS address of attached device
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
1581 * @sas_address: SAS Address of the attached device
1582 * @phy_mask: phy mask of host port
1583 * @handle: Device Handle of attached device
1586 * @lowest_phy: lowest phy ID of host port
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()
1699 for (i = 0; i < mrioc->sas_hba.num_phys; i++) { in mpi3mr_refresh_sas_ports()
1701 sas_io_unit_pg0->phy_data[i].attached_dev_handle); in mpi3mr_refresh_sas_ports()
1732 h_port[port_idx].sas_address = le64_to_cpu(sasinf->sas_address); in mpi3mr_refresh_sas_ports()
1735 h_port[port_idx].iounit_port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; in mpi3mr_refresh_sas_ports()
1736 h_port[port_idx].lowest_phy = sasinf->phy_num; in mpi3mr_refresh_sas_ports()
1744 if (mrioc->logging_level & MPI3_DEBUG_RESET) { in mpi3mr_refresh_sas_ports()
1746 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1749 "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%llx), lowest phy id:%d\n", in mpi3mr_refresh_sas_ports()
1750 mr_sas_port->hba_port->port_id, in mpi3mr_refresh_sas_ports()
1751 mr_sas_port->remote_identify.sas_address, in mpi3mr_refresh_sas_ports()
1752 mr_sas_port->phy_mask, mr_sas_port->lowest_phy); in mpi3mr_refresh_sas_ports()
1758 "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%llx), lowest phy id:%d\n", in mpi3mr_refresh_sas_ports()
1765 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1767 mr_sas_port->marked_responding = 0; in mpi3mr_refresh_sas_ports()
1768 mr_sas_port->hba_port->flags |= MPI3MR_HBA_PORT_FLAG_DIRTY; in mpi3mr_refresh_sas_ports()
1771 /* First check for matching lowest phy */ in mpi3mr_refresh_sas_ports()
1774 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1776 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1778 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1780 if (h_port[i].lowest_phy == mr_sas_port->lowest_phy) { in mpi3mr_refresh_sas_ports()
1787 /* In case if lowest phy is got enabled or disabled during reset */ in mpi3mr_refresh_sas_ports()
1792 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1794 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1796 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1798 if (h_port[i].phy_mask & mr_sas_port->phy_mask) { in mpi3mr_refresh_sas_ports()
1810 list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, in mpi3mr_refresh_sas_ports()
1812 if (mr_sas_port->marked_responding) in mpi3mr_refresh_sas_ports()
1814 if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) in mpi3mr_refresh_sas_ports()
1826 * mpi3mr_refresh_expanders - Refresh expander device exposure
1831 * or expose any newly detected expander device to the upper layers.
1846 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1847 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { in mpi3mr_refresh_expanders()
1848 sas_expander->non_responding = 1; in mpi3mr_refresh_expanders()
1850 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1884 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1888 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1896 sas_expander->non_responding = 0; in mpi3mr_refresh_expanders()
1897 if (sas_expander->handle == handle) in mpi3mr_refresh_expanders()
1900 sas_expander->handle = handle; in mpi3mr_refresh_expanders()
1901 for (i = 0 ; i < sas_expander->num_phys ; i++) in mpi3mr_refresh_expanders()
1902 sas_expander->phy[i].handle = handle; in mpi3mr_refresh_expanders()
1907 * hba_port if the non responding expander device's parent device in mpi3mr_refresh_expanders()
1911 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1913 &mrioc->sas_expander_list, list) { in mpi3mr_refresh_expanders()
1914 if (sas_expander->non_responding) { in mpi3mr_refresh_expanders()
1915 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1917 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1920 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_refresh_expanders()
1924 * mpi3mr_expander_node_add - insert an expander to the list.
1929 * Adding new object to the ioc->sas_expander_list.
1938 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_add()
1939 list_add_tail(&sas_expander->list, &mrioc->sas_expander_list); in mpi3mr_expander_node_add()
1940 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_add()
1944 * mpi3mr_expander_add - Create expander object
1946 * @handle: Expander firmware device handle
1952 * Return: 0 for success, non-zero for failure.
1971 return -1; in mpi3mr_expander_add()
1973 if (mrioc->reset_in_progress) in mpi3mr_expander_add()
1974 return -1; in mpi3mr_expander_add()
1980 return -1; in mpi3mr_expander_add()
1986 return -1; in mpi3mr_expander_add()
1994 return -1; in mpi3mr_expander_add()
2002 return -1; in mpi3mr_expander_add()
2005 if (sas_address_parent != mrioc->sas_hba.sas_address) { in mpi3mr_expander_add()
2006 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2010 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2021 for (i = 0 ; i < sas_expander->num_phys ; i++) { in mpi3mr_expander_add()
2032 rc = -1; in mpi3mr_expander_add()
2038 rc = -1; in mpi3mr_expander_add()
2054 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2058 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_add()
2066 return -ENOMEM; in mpi3mr_expander_add()
2068 sas_expander->handle = handle; in mpi3mr_expander_add()
2069 sas_expander->num_phys = expander_pg0.num_phys; in mpi3mr_expander_add()
2070 sas_expander->sas_address_parent = sas_address_parent; in mpi3mr_expander_add()
2071 sas_expander->sas_address = sas_address; in mpi3mr_expander_add()
2072 sas_expander->hba_port = hba_port; in mpi3mr_expander_add()
2077 sas_expander->sas_address, sas_expander->num_phys); in mpi3mr_expander_add()
2079 if (!sas_expander->num_phys) { in mpi3mr_expander_add()
2080 rc = -1; in mpi3mr_expander_add()
2083 sas_expander->phy = kcalloc(sas_expander->num_phys, in mpi3mr_expander_add()
2085 if (!sas_expander->phy) { in mpi3mr_expander_add()
2086 rc = -1; in mpi3mr_expander_add()
2090 INIT_LIST_HEAD(&sas_expander->sas_port_list); in mpi3mr_expander_add()
2092 sas_expander->hba_port); in mpi3mr_expander_add()
2096 rc = -1; in mpi3mr_expander_add()
2099 sas_expander->parent_dev = &mr_sas_port->rphy->dev; in mpi3mr_expander_add()
2100 sas_expander->rphy = mr_sas_port->rphy; in mpi3mr_expander_add()
2102 for (i = 0 ; i < sas_expander->num_phys ; i++) { in mpi3mr_expander_add()
2111 rc = -1; in mpi3mr_expander_add()
2117 rc = -1; in mpi3mr_expander_add()
2121 sas_expander->phy[i].handle = handle; in mpi3mr_expander_add()
2122 sas_expander->phy[i].phy_id = i; in mpi3mr_expander_add()
2123 sas_expander->phy[i].hba_port = hba_port; in mpi3mr_expander_add()
2125 if ((mpi3mr_add_expander_phy(mrioc, &sas_expander->phy[i], in mpi3mr_expander_add()
2126 expander_pg1, sas_expander->parent_dev))) { in mpi3mr_expander_add()
2129 rc = -1; in mpi3mr_expander_add()
2134 if (sas_expander->enclosure_handle) { in mpi3mr_expander_add()
2137 sas_expander->enclosure_handle); in mpi3mr_expander_add()
2139 sas_expander->enclosure_logical_id = le64_to_cpu( in mpi3mr_expander_add()
2140 enclosure_dev->pg0.enclosure_logical_id); in mpi3mr_expander_add()
2150 sas_expander->sas_address, in mpi3mr_expander_add()
2151 sas_address_parent, sas_expander->hba_port); in mpi3mr_expander_add()
2152 kfree(sas_expander->phy); in mpi3mr_expander_add()
2158 * mpi3mr_expander_node_remove - recursive removal of expander.
2160 * @sas_expander: Expander device object
2164 * one of the attached device is an expander then it recursively
2165 * removes the expander device too.
2178 &sas_expander->sas_port_list, port_list) { in mpi3mr_expander_node_remove()
2179 if (mrioc->reset_in_progress) in mpi3mr_expander_node_remove()
2181 if (mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2184 mr_sas_port->remote_identify.sas_address, in mpi3mr_expander_node_remove()
2185 mr_sas_port->hba_port); in mpi3mr_expander_node_remove()
2186 else if (mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2188 mr_sas_port->remote_identify.device_type == in mpi3mr_expander_node_remove()
2191 mr_sas_port->remote_identify.sas_address, in mpi3mr_expander_node_remove()
2192 mr_sas_port->hba_port); in mpi3mr_expander_node_remove()
2195 port_id = sas_expander->hba_port->port_id; in mpi3mr_expander_node_remove()
2196 mpi3mr_sas_port_remove(mrioc, sas_expander->sas_address, in mpi3mr_expander_node_remove()
2197 sas_expander->sas_address_parent, sas_expander->hba_port); in mpi3mr_expander_node_remove()
2200 sas_expander->handle, (unsigned long long) in mpi3mr_expander_node_remove()
2201 sas_expander->sas_address, port_id); in mpi3mr_expander_node_remove()
2203 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_remove()
2204 list_del(&sas_expander->list); in mpi3mr_expander_node_remove()
2205 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_node_remove()
2207 kfree(sas_expander->phy); in mpi3mr_expander_node_remove()
2212 * mpi3mr_expander_remove - Remove expander object
2218 * mrioc->sas_expander_list and removes it from the SAS TL by
2229 if (mrioc->reset_in_progress) in mpi3mr_expander_remove()
2235 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_expander_remove()
2238 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_expander_remove()
2245 * mpi3mr_get_sas_negotiated_logical_linkrate - get linkrate
2247 * @tgtdev: Target device
2249 * This function identifies whether the target device is
2250 * attached directly or through expander and issues sas phy
2251 * page0 or expander phy page1 and gets the link rate, if there
2266 phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; in mpi3mr_get_sas_negotiated_logical_linkrate()
2267 if (!(tgtdev->devpg0_flag & MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)) { in mpi3mr_get_sas_negotiated_logical_linkrate()
2269 | tgtdev->parent_handle); in mpi3mr_get_sas_negotiated_logical_linkrate()
2308 * mpi3mr_report_tgtdev_to_sas_transport - expose dev to SAS TL
2310 * @tgtdev: Target device
2312 * This function exposes the target device after
2315 * Return: 0 on success, non-zero for failure.
2326 if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || in mpi3mr_report_tgtdev_to_sas_transport()
2327 !mrioc->sas_transport_enabled) in mpi3mr_report_tgtdev_to_sas_transport()
2328 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2330 sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; in mpi3mr_report_tgtdev_to_sas_transport()
2331 if (!mrioc->sas_hba.num_phys) in mpi3mr_report_tgtdev_to_sas_transport()
2336 if (mpi3mr_get_sas_address(mrioc, tgtdev->parent_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2340 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2342 tgtdev->dev_spec.sas_sata_inf.sas_address_parent = sas_address_parent; in mpi3mr_report_tgtdev_to_sas_transport()
2344 parent_phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; in mpi3mr_report_tgtdev_to_sas_transport()
2345 port_id = tgtdev->io_unit_port; in mpi3mr_report_tgtdev_to_sas_transport()
2351 return -1; in mpi3mr_report_tgtdev_to_sas_transport()
2353 tgtdev->dev_spec.sas_sata_inf.hba_port = hba_port; in mpi3mr_report_tgtdev_to_sas_transport()
2357 mpi3mr_update_links(mrioc, sas_address_parent, tgtdev->dev_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2360 tgtdev->host_exposed = 1; in mpi3mr_report_tgtdev_to_sas_transport()
2361 if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle, in mpi3mr_report_tgtdev_to_sas_transport()
2363 retval = -1; in mpi3mr_report_tgtdev_to_sas_transport()
2364 } else if ((!tgtdev->starget) && (!mrioc->is_driver_loading)) { in mpi3mr_report_tgtdev_to_sas_transport()
2367 retval = -1; in mpi3mr_report_tgtdev_to_sas_transport()
2370 tgtdev->dev_spec.sas_sata_inf.hba_port = NULL; in mpi3mr_report_tgtdev_to_sas_transport()
2371 tgtdev->host_exposed = 0; in mpi3mr_report_tgtdev_to_sas_transport()
2377 * mpi3mr_remove_tgtdev_from_sas_transport - remove from SAS TL
2379 * @tgtdev: Target device
2381 * This function removes the target device
2391 if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || in mpi3mr_remove_tgtdev_from_sas_transport()
2392 !mrioc->sas_transport_enabled) in mpi3mr_remove_tgtdev_from_sas_transport()
2395 hba_port = tgtdev->dev_spec.sas_sata_inf.hba_port; in mpi3mr_remove_tgtdev_from_sas_transport()
2396 sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; in mpi3mr_remove_tgtdev_from_sas_transport()
2397 sas_address_parent = tgtdev->dev_spec.sas_sata_inf.sas_address_parent; in mpi3mr_remove_tgtdev_from_sas_transport()
2400 tgtdev->host_exposed = 0; in mpi3mr_remove_tgtdev_from_sas_transport()
2401 tgtdev->dev_spec.sas_sata_inf.hba_port = NULL; in mpi3mr_remove_tgtdev_from_sas_transport()
2405 * mpi3mr_get_port_id_by_sas_phy - Get port ID of the given phy
2406 * @phy: SAS transport layer phy object
2410 static inline u8 mpi3mr_get_port_id_by_sas_phy(struct sas_phy *phy) in mpi3mr_get_port_id_by_sas_phy() argument
2413 struct mpi3mr_hba_port *hba_port = phy->hostdata; in mpi3mr_get_port_id_by_sas_phy()
2416 port_id = hba_port->port_id; in mpi3mr_get_port_id_by_sas_phy()
2422 * mpi3mr_get_port_id_by_rphy - Get Port number from SAS rphy
2425 * @rphy: SAS transport layer remote phy object
2427 * Retrieves HBA port number in which the device pointed by the
2442 if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE || in mpi3mr_get_port_id_by_rphy()
2443 rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) { in mpi3mr_get_port_id_by_rphy()
2444 spin_lock_irqsave(&mrioc->sas_node_lock, flags); in mpi3mr_get_port_id_by_rphy()
2445 list_for_each_entry(sas_expander, &mrioc->sas_expander_list, in mpi3mr_get_port_id_by_rphy()
2447 if (sas_expander->rphy == rphy) { in mpi3mr_get_port_id_by_rphy()
2448 port_id = sas_expander->hba_port->port_id; in mpi3mr_get_port_id_by_rphy()
2452 spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); in mpi3mr_get_port_id_by_rphy()
2453 } else if (rphy->identify.device_type == SAS_END_DEVICE) { in mpi3mr_get_port_id_by_rphy()
2454 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_get_port_id_by_rphy()
2457 rphy->identify.sas_address, rphy); in mpi3mr_get_port_id_by_rphy()
2458 if (tgtdev && tgtdev->dev_spec.sas_sata_inf.hba_port) { in mpi3mr_get_port_id_by_rphy()
2460 tgtdev->dev_spec.sas_sata_inf.hba_port->port_id; in mpi3mr_get_port_id_by_rphy()
2463 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_get_port_id_by_rphy()
2468 static inline struct mpi3mr_ioc *phy_to_mrioc(struct sas_phy *phy) in phy_to_mrioc() argument
2470 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in phy_to_mrioc()
2477 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); in rphy_to_mrioc()
2482 /* report phy error log structure */
2493 /* report phy error log reply structure */
2511 * mpi3mr_get_expander_phy_error_log - return expander counters:
2513 * @phy: The SAS transport layer phy object
2515 * Return: 0 for success, non-zero for failure.
2519 struct sas_phy *phy) in mpi3mr_get_expander_phy_error_log() argument
2535 if (mrioc->reset_in_progress) { in mpi3mr_get_expander_phy_error_log()
2537 return -EFAULT; in mpi3mr_get_expander_phy_error_log()
2543 data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma, in mpi3mr_get_expander_phy_error_log()
2546 rc = -ENOMEM; in mpi3mr_get_expander_phy_error_log()
2553 rc = -EINVAL; in mpi3mr_get_expander_phy_error_log()
2556 phy_error_log_request->smp_frame_type = 0x40; in mpi3mr_get_expander_phy_error_log()
2557 phy_error_log_request->function = 0x11; in mpi3mr_get_expander_phy_error_log()
2558 phy_error_log_request->request_length = 2; in mpi3mr_get_expander_phy_error_log()
2559 phy_error_log_request->allocated_response_length = 0; in mpi3mr_get_expander_phy_error_log()
2560 phy_error_log_request->phy_identifier = phy->number; in mpi3mr_get_expander_phy_error_log()
2566 mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_sas_phy(phy); in mpi3mr_get_expander_phy_error_log()
2567 mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address); in mpi3mr_get_expander_phy_error_log()
2576 "sending phy error log SMP request to sas_address(0x%016llx), phy_id(%d)\n", in mpi3mr_get_expander_phy_error_log()
2577 (unsigned long long)phy->identify.sas_address, phy->number); in mpi3mr_get_expander_phy_error_log()
2584 "phy error log SMP request completed with ioc_status(0x%04x)\n", in mpi3mr_get_expander_phy_error_log()
2589 "phy error log - reply data transfer size(%d)\n", in mpi3mr_get_expander_phy_error_log()
2597 "phy error log - function_result(%d)\n", in mpi3mr_get_expander_phy_error_log()
2598 phy_error_log_reply->function_result); in mpi3mr_get_expander_phy_error_log()
2600 phy->invalid_dword_count = in mpi3mr_get_expander_phy_error_log()
2601 be32_to_cpu(phy_error_log_reply->invalid_dword); in mpi3mr_get_expander_phy_error_log()
2602 phy->running_disparity_error_count = in mpi3mr_get_expander_phy_error_log()
2603 be32_to_cpu(phy_error_log_reply->running_disparity_error); in mpi3mr_get_expander_phy_error_log()
2604 phy->loss_of_dword_sync_count = in mpi3mr_get_expander_phy_error_log()
2605 be32_to_cpu(phy_error_log_reply->loss_of_dword_sync); in mpi3mr_get_expander_phy_error_log()
2606 phy->phy_reset_problem_count = in mpi3mr_get_expander_phy_error_log()
2607 be32_to_cpu(phy_error_log_reply->phy_reset_problem); in mpi3mr_get_expander_phy_error_log()
2613 dma_free_coherent(&mrioc->pdev->dev, sz, data_out, in mpi3mr_get_expander_phy_error_log()
2620 * mpi3mr_transport_get_linkerrors - return phy error counters
2621 * @phy: The SAS transport layer phy object
2623 * This function retrieves the phy error log information of the
2624 * HBA or expander for which the phy belongs to
2626 * Return: 0 for success, non-zero for failure.
2628 static int mpi3mr_transport_get_linkerrors(struct sas_phy *phy) in mpi3mr_transport_get_linkerrors() argument
2630 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_get_linkerrors()
2635 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_get_linkerrors()
2639 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_get_linkerrors()
2640 return mpi3mr_get_expander_phy_error_log(mrioc, phy); in mpi3mr_transport_get_linkerrors()
2643 /* get hba phy error logs */ in mpi3mr_transport_get_linkerrors()
2646 MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number))) { in mpi3mr_transport_get_linkerrors()
2649 return -ENXIO; in mpi3mr_transport_get_linkerrors()
2655 return -ENXIO; in mpi3mr_transport_get_linkerrors()
2657 phy->invalid_dword_count = le32_to_cpu(phy_pg1.invalid_dword_count); in mpi3mr_transport_get_linkerrors()
2658 phy->running_disparity_error_count = in mpi3mr_transport_get_linkerrors()
2660 phy->loss_of_dword_sync_count = in mpi3mr_transport_get_linkerrors()
2662 phy->phy_reset_problem_count = in mpi3mr_transport_get_linkerrors()
2668 * mpi3mr_transport_get_enclosure_identifier - Get Enclosure ID
2669 * @rphy: The SAS transport layer remote phy object
2672 * Returns the enclosure id for the device pointed by the remote
2673 * phy object.
2675 * Return: 0 on success or -ENXIO
2686 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_enclosure_identifier()
2688 rphy->identify.sas_address, rphy); in mpi3mr_transport_get_enclosure_identifier()
2691 tgtdev->enclosure_logical_id; in mpi3mr_transport_get_enclosure_identifier()
2696 rc = -ENXIO; in mpi3mr_transport_get_enclosure_identifier()
2698 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_enclosure_identifier()
2704 * mpi3mr_transport_get_bay_identifier - Get bay ID
2705 * @rphy: The SAS transport layer remote phy object
2707 * Returns the slot id for the device pointed by the remote phy
2710 * Return: Valid slot ID on success or -ENXIO
2720 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_bay_identifier()
2722 rphy->identify.sas_address, rphy); in mpi3mr_transport_get_bay_identifier()
2724 rc = tgtdev->slot; in mpi3mr_transport_get_bay_identifier()
2727 rc = -ENXIO; in mpi3mr_transport_get_bay_identifier()
2728 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); in mpi3mr_transport_get_bay_identifier()
2733 /* phy control request structure */
2750 /* phy control reply structure */
2763 * mpi3mr_expander_phy_control - expander phy control
2765 * @phy: The SAS transport layer phy object
2766 * @phy_operation: The phy operation to be executed
2768 * Issues SMP passthru phy control request to execute a specific
2769 * phy operation for a given expander device.
2771 * Return: 0 for success, non-zero for failure.
2775 struct sas_phy *phy, u8 phy_operation) in mpi3mr_expander_phy_control() argument
2794 if (mrioc->reset_in_progress) { in mpi3mr_expander_phy_control()
2796 return -EFAULT; in mpi3mr_expander_phy_control()
2802 data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma, in mpi3mr_expander_phy_control()
2805 rc = -ENOMEM; in mpi3mr_expander_phy_control()
2812 rc = -EINVAL; in mpi3mr_expander_phy_control()
2816 phy_control_request->smp_frame_type = 0x40; in mpi3mr_expander_phy_control()
2817 phy_control_request->function = 0x91; in mpi3mr_expander_phy_control()
2818 phy_control_request->request_length = 9; in mpi3mr_expander_phy_control()
2819 phy_control_request->allocated_response_length = 0; in mpi3mr_expander_phy_control()
2820 phy_control_request->phy_identifier = phy->number; in mpi3mr_expander_phy_control()
2821 phy_control_request->phy_operation = phy_operation; in mpi3mr_expander_phy_control()
2822 phy_control_request->programmed_min_physical_link_rate = in mpi3mr_expander_phy_control()
2823 phy->minimum_linkrate << 4; in mpi3mr_expander_phy_control()
2824 phy_control_request->programmed_max_physical_link_rate = in mpi3mr_expander_phy_control()
2825 phy->maximum_linkrate << 4; in mpi3mr_expander_phy_control()
2831 mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_sas_phy(phy); in mpi3mr_expander_phy_control()
2832 mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address); in mpi3mr_expander_phy_control()
2841 "sending phy control SMP request to sas_address(0x%016llx), phy_id(%d) opcode(%d)\n", in mpi3mr_expander_phy_control()
2842 (unsigned long long)phy->identify.sas_address, phy->number, in mpi3mr_expander_phy_control()
2850 "phy control SMP request completed with ioc_status(0x%04x)\n", in mpi3mr_expander_phy_control()
2855 "phy control - reply data transfer size(%d)\n", in mpi3mr_expander_phy_control()
2862 "phy control - function_result(%d)\n", in mpi3mr_expander_phy_control()
2863 phy_control_reply->function_result); in mpi3mr_expander_phy_control()
2868 dma_free_coherent(&mrioc->pdev->dev, sz, data_out, in mpi3mr_expander_phy_control()
2875 * mpi3mr_transport_phy_reset - Reset a given phy
2876 * @phy: The SAS transport layer phy object
2879 * Return: 0 for success, non-zero for failure.
2882 mpi3mr_transport_phy_reset(struct sas_phy *phy, int hard_reset) in mpi3mr_transport_phy_reset() argument
2884 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_phy_reset()
2892 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_phy_reset()
2897 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_phy_reset()
2898 return mpi3mr_expander_phy_control(mrioc, phy, in mpi3mr_transport_phy_reset()
2911 phy->number; in mpi3mr_transport_phy_reset()
2914 "sending phy reset request to sas_address(0x%016llx), phy_id(%d) hard_reset(%d)\n", in mpi3mr_transport_phy_reset()
2915 (unsigned long long)phy->identify.sas_address, phy->number, in mpi3mr_transport_phy_reset()
2920 rc = -EAGAIN; in mpi3mr_transport_phy_reset()
2925 "phy reset request completed with ioc_status(0x%04x)\n", in mpi3mr_transport_phy_reset()
2932 * mpi3mr_transport_phy_enable - enable/disable phys
2933 * @phy: The SAS transport layer phy object
2934 * @enable: flag to enable/disable, enable phy when true
2937 * configuration page changes or expander phy control command
2939 * Return: 0 for success, non-zero for failure.
2942 mpi3mr_transport_phy_enable(struct sas_phy *phy, int enable) in mpi3mr_transport_phy_enable() argument
2944 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_phy_enable()
2951 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_phy_enable()
2956 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) in mpi3mr_transport_phy_enable()
2957 return mpi3mr_expander_phy_control(mrioc, phy, in mpi3mr_transport_phy_enable()
2963 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_enable()
2967 rc = -ENOMEM; in mpi3mr_transport_phy_enable()
2973 rc = -ENXIO; in mpi3mr_transport_phy_enable()
2978 for (i = 0, discovery_active = 0; i < mrioc->sas_hba.num_phys ; i++) { in mpi3mr_transport_phy_enable()
2979 if (sas_io_unit_pg0->phy_data[i].port_flags & in mpi3mr_transport_phy_enable()
2982 "discovery is active on port = %d, phy = %d\n" in mpi3mr_transport_phy_enable()
2984 sas_io_unit_pg0->phy_data[i].io_unit_port, i); in mpi3mr_transport_phy_enable()
2990 rc = -EAGAIN; in mpi3mr_transport_phy_enable()
2994 if ((sas_io_unit_pg0->phy_data[phy->number].phy_flags & in mpi3mr_transport_phy_enable()
2999 rc = -ENXIO; in mpi3mr_transport_phy_enable()
3005 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_enable()
3009 rc = -ENOMEM; in mpi3mr_transport_phy_enable()
3016 rc = -ENXIO; in mpi3mr_transport_phy_enable()
3021 sas_io_unit_pg1->phy_data[phy->number].phy_flags in mpi3mr_transport_phy_enable()
3024 sas_io_unit_pg1->phy_data[phy->number].phy_flags in mpi3mr_transport_phy_enable()
3031 mpi3mr_transport_phy_reset(phy, 0); in mpi3mr_transport_phy_enable()
3040 * mpi3mr_transport_phy_speed - set phy min/max speed
3041 * @phy: The SAS transport later phy object
3045 * argument to the given phy by executing required configuration
3046 * page changes or expander phy control command
3048 * Return: 0 for success, non-zero for failure.
3051 mpi3mr_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) in mpi3mr_transport_phy_speed() argument
3053 struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); in mpi3mr_transport_phy_speed()
3059 rc = mpi3mr_parent_present(mrioc, phy); in mpi3mr_transport_phy_speed()
3063 if (!rates->minimum_linkrate) in mpi3mr_transport_phy_speed()
3064 rates->minimum_linkrate = phy->minimum_linkrate; in mpi3mr_transport_phy_speed()
3065 else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) in mpi3mr_transport_phy_speed()
3066 rates->minimum_linkrate = phy->minimum_linkrate_hw; in mpi3mr_transport_phy_speed()
3068 if (!rates->maximum_linkrate) in mpi3mr_transport_phy_speed()
3069 rates->maximum_linkrate = phy->maximum_linkrate; in mpi3mr_transport_phy_speed()
3070 else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) in mpi3mr_transport_phy_speed()
3071 rates->maximum_linkrate = phy->maximum_linkrate_hw; in mpi3mr_transport_phy_speed()
3074 if (phy->identify.sas_address != mrioc->sas_hba.sas_address) { in mpi3mr_transport_phy_speed()
3075 phy->minimum_linkrate = rates->minimum_linkrate; in mpi3mr_transport_phy_speed()
3076 phy->maximum_linkrate = rates->maximum_linkrate; in mpi3mr_transport_phy_speed()
3077 return mpi3mr_expander_phy_control(mrioc, phy, in mpi3mr_transport_phy_speed()
3083 (mrioc->sas_hba.num_phys * in mpi3mr_transport_phy_speed()
3087 rc = -ENOMEM; in mpi3mr_transport_phy_speed()
3094 rc = -ENXIO; in mpi3mr_transport_phy_speed()
3098 sas_io_unit_pg1->phy_data[phy->number].max_min_link_rate = in mpi3mr_transport_phy_speed()
3099 (rates->minimum_linkrate + (rates->maximum_linkrate << 4)); in mpi3mr_transport_phy_speed()
3104 rc = -ENXIO; in mpi3mr_transport_phy_speed()
3109 mpi3mr_transport_phy_reset(phy, 0); in mpi3mr_transport_phy_speed()
3111 /* read phy page 0, then update the rates in the sas transport phy */ in mpi3mr_transport_phy_speed()
3114 MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number) && in mpi3mr_transport_phy_speed()
3116 phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_transport_phy_speed()
3119 phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( in mpi3mr_transport_phy_speed()
3121 phy->negotiated_linkrate = in mpi3mr_transport_phy_speed()
3134 * mpi3mr_map_smp_buffer - map BSG dma buffer
3135 * @dev: Generic device reference
3143 * Return: 0 on success, non-zero on failure
3146 mpi3mr_map_smp_buffer(struct device *dev, struct bsg_buffer *buf, in mpi3mr_map_smp_buffer()
3150 if (buf->sg_cnt > 1) { in mpi3mr_map_smp_buffer()
3151 *p = dma_alloc_coherent(dev, buf->payload_len, dma_addr, in mpi3mr_map_smp_buffer()
3154 return -ENOMEM; in mpi3mr_map_smp_buffer()
3155 *dma_len = buf->payload_len; in mpi3mr_map_smp_buffer()
3157 if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL)) in mpi3mr_map_smp_buffer()
3158 return -ENOMEM; in mpi3mr_map_smp_buffer()
3159 *dma_addr = sg_dma_address(buf->sg_list); in mpi3mr_map_smp_buffer()
3160 *dma_len = sg_dma_len(buf->sg_list); in mpi3mr_map_smp_buffer()
3168 * mpi3mr_unmap_smp_buffer - unmap BSG dma buffer
3169 * @dev: Generic device reference
3177 mpi3mr_unmap_smp_buffer(struct device *dev, struct bsg_buffer *buf, in mpi3mr_unmap_smp_buffer()
3181 dma_free_coherent(dev, buf->payload_len, p, dma_addr); in mpi3mr_unmap_smp_buffer()
3183 dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL); in mpi3mr_unmap_smp_buffer()
3187 * mpi3mr_transport_smp_handler - handler for smp passthru
3216 if (mrioc->reset_in_progress) { in mpi3mr_transport_smp_handler()
3218 rc = -EFAULT; in mpi3mr_transport_smp_handler()
3222 rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->request_payload, in mpi3mr_transport_smp_handler()
3228 sg_copy_to_buffer(job->request_payload.sg_list, in mpi3mr_transport_smp_handler()
3229 job->request_payload.sg_cnt, addr_out, in mpi3mr_transport_smp_handler()
3230 job->request_payload.payload_len); in mpi3mr_transport_smp_handler()
3232 rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->reply_payload, in mpi3mr_transport_smp_handler()
3243 cpu_to_le64(rphy->identify.sas_address) : in mpi3mr_transport_smp_handler()
3244 cpu_to_le64(mrioc->sas_hba.sas_address)); in mpi3mr_transport_smp_handler()
3246 mpi3mr_add_sg_single(psge, sgl_flags, dma_len_out - 4, dma_addr_out); in mpi3mr_transport_smp_handler()
3249 mpi3mr_add_sg_single(psge, sgl_flags, dma_len_in - 4, dma_addr_in); in mpi3mr_transport_smp_handler()
3263 "SMP request - reply data transfer size(%d)\n", in mpi3mr_transport_smp_handler()
3266 memcpy(job->reply, &mpi_reply, reply_sz); in mpi3mr_transport_smp_handler()
3267 job->reply_len = reply_sz; in mpi3mr_transport_smp_handler()
3271 sg_copy_from_buffer(job->reply_payload.sg_list, in mpi3mr_transport_smp_handler()
3272 job->reply_payload.sg_cnt, addr_in, in mpi3mr_transport_smp_handler()
3273 job->reply_payload.payload_len); in mpi3mr_transport_smp_handler()
3277 mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->reply_payload, in mpi3mr_transport_smp_handler()
3280 mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->request_payload, in mpi3mr_transport_smp_handler()