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

5  * Copyright (C) 2012-2014  LSI Corporation
6 * Copyright (C) 2013-2014 Avago Technologies
7 * (mailto: MPT-FusionLinux.pdl@avagotech.com)
22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
64 * _transport_sas_node_find_by_sas_address - sas node search
67 * Context: Calling function should acquire ioc->sas_node_lock.
69 * Search for either hba phys or expander device based on handle, then returns
76 if (ioc->sas_hba.sas_address == sas_address) in _transport_sas_node_find_by_sas_address()
77 return &ioc->sas_hba; in _transport_sas_node_find_by_sas_address()
84 * _transport_convert_phy_link_rate -
130 * _transport_set_identify - set identify for phys and end devices
132 * @handle: device handle
137 * Return: 0 for success, non-zero for failure.
140 _transport_set_identify(struct MPT3SAS_ADAPTER *ioc, u16 handle, in _transport_set_identify() argument
148 if (ioc->shost_recovery || ioc->pci_error_recovery) { in _transport_set_identify()
150 return -EFAULT; in _transport_set_identify()
154 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { in _transport_set_identify()
157 return -ENXIO; in _transport_set_identify()
163 ioc_err(ioc, "handle(0x%04x), ioc_status(0x%04x) failure at %s:%d/%s()!\n", in _transport_set_identify()
164 handle, ioc_status, __FILE__, __LINE__, __func__); in _transport_set_identify()
165 return -EIO; in _transport_set_identify()
172 identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress); in _transport_set_identify()
174 /* phy number of the parent device this device is linked to */ in _transport_set_identify()
175 identify->phy_identifier = sas_device_pg0.PhyNum; in _transport_set_identify()
180 identify->device_type = SAS_PHY_UNUSED; in _transport_set_identify()
183 identify->device_type = SAS_END_DEVICE; in _transport_set_identify()
186 identify->device_type = SAS_EDGE_EXPANDER_DEVICE; in _transport_set_identify()
189 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE; in _transport_set_identify()
195 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP; in _transport_set_identify()
197 identify->initiator_port_protocols |= SAS_PROTOCOL_STP; in _transport_set_identify()
199 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP; in _transport_set_identify()
201 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA; in _transport_set_identify()
205 identify->target_port_protocols |= SAS_PROTOCOL_SSP; in _transport_set_identify()
207 identify->target_port_protocols |= SAS_PROTOCOL_STP; in _transport_set_identify()
209 identify->target_port_protocols |= SAS_PROTOCOL_SMP; in _transport_set_identify()
211 identify->target_port_protocols |= SAS_PROTOCOL_SATA; in _transport_set_identify()
217 * mpt3sas_transport_done - internal transport layer callback handler.
224 * The callback index passed is `ioc->transport_cb_idx`
236 if (ioc->transport_cmds.status == MPT3_CMD_NOT_USED) in mpt3sas_transport_done()
238 if (ioc->transport_cmds.smid != smid) in mpt3sas_transport_done()
240 ioc->transport_cmds.status |= MPT3_CMD_COMPLETE; in mpt3sas_transport_done()
242 memcpy(ioc->transport_cmds.reply, mpi_reply, in mpt3sas_transport_done()
243 mpi_reply->MsgLength*4); in mpt3sas_transport_done()
244 ioc->transport_cmds.status |= MPT3_CMD_REPLY_VALID; in mpt3sas_transport_done()
246 ioc->transport_cmds.status &= ~MPT3_CMD_PENDING; in mpt3sas_transport_done()
247 complete(&ioc->transport_cmds.done); in mpt3sas_transport_done()
280 * transport_expander_report_manufacture - obtain SMP report_manufacture
287 * Return: 0 for success, non-zero for failure.
307 if (ioc->shost_recovery || ioc->pci_error_recovery) { in _transport_expander_report_manufacture()
309 return -EFAULT; in _transport_expander_report_manufacture()
312 mutex_lock(&ioc->transport_cmds.mutex); in _transport_expander_report_manufacture()
314 if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { in _transport_expander_report_manufacture()
316 rc = -EAGAIN; in _transport_expander_report_manufacture()
319 ioc->transport_cmds.status = MPT3_CMD_PENDING; in _transport_expander_report_manufacture()
325 smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx); in _transport_expander_report_manufacture()
328 rc = -EAGAIN; in _transport_expander_report_manufacture()
334 ioc->transport_cmds.smid = smid; in _transport_expander_report_manufacture()
338 data_out = dma_alloc_coherent(&ioc->pdev->dev, data_out_sz + data_in_sz, in _transport_expander_report_manufacture()
343 rc = -ENOMEM; in _transport_expander_report_manufacture()
351 manufacture_request->smp_frame_type = 0x40; in _transport_expander_report_manufacture()
352 manufacture_request->function = 1; in _transport_expander_report_manufacture()
353 manufacture_request->reserved = 0; in _transport_expander_report_manufacture()
354 manufacture_request->request_length = 0; in _transport_expander_report_manufacture()
357 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; in _transport_expander_report_manufacture()
358 mpi_request->PhysicalPort = 0xFF; in _transport_expander_report_manufacture()
359 mpi_request->SASAddress = cpu_to_le64(sas_address); in _transport_expander_report_manufacture()
360 mpi_request->RequestDataLength = cpu_to_le16(data_out_sz); in _transport_expander_report_manufacture()
361 psge = &mpi_request->SGL; in _transport_expander_report_manufacture()
363 ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, in _transport_expander_report_manufacture()
367 ioc_info(ioc, "report_manufacture - send to sas_addr(0x%016llx)\n", in _transport_expander_report_manufacture()
369 init_completion(&ioc->transport_cmds.done); in _transport_expander_report_manufacture()
370 ioc->put_smid_default(ioc, smid); in _transport_expander_report_manufacture()
371 wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); in _transport_expander_report_manufacture()
373 if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { in _transport_expander_report_manufacture()
377 if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) in _transport_expander_report_manufacture()
382 dtransportprintk(ioc, ioc_info(ioc, "report_manufacture - complete\n")); in _transport_expander_report_manufacture()
384 if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { in _transport_expander_report_manufacture()
387 mpi_reply = ioc->transport_cmds.reply; in _transport_expander_report_manufacture()
390 ioc_info(ioc, "report_manufacture - reply data transfer size(%d)\n", in _transport_expander_report_manufacture()
391 le16_to_cpu(mpi_reply->ResponseDataLength))); in _transport_expander_report_manufacture()
393 if (le16_to_cpu(mpi_reply->ResponseDataLength) != in _transport_expander_report_manufacture()
398 strncpy(edev->vendor_id, manufacture_reply->vendor_id, in _transport_expander_report_manufacture()
400 strncpy(edev->product_id, manufacture_reply->product_id, in _transport_expander_report_manufacture()
402 strncpy(edev->product_rev, manufacture_reply->product_rev, in _transport_expander_report_manufacture()
404 edev->level = manufacture_reply->sas_format & 1; in _transport_expander_report_manufacture()
405 if (edev->level) { in _transport_expander_report_manufacture()
406 strncpy(edev->component_vendor_id, in _transport_expander_report_manufacture()
407 manufacture_reply->component_vendor_id, in _transport_expander_report_manufacture()
409 tmp = (u8 *)&manufacture_reply->component_id; in _transport_expander_report_manufacture()
410 edev->component_id = tmp[0] << 8 | tmp[1]; in _transport_expander_report_manufacture()
411 edev->component_revision_id = in _transport_expander_report_manufacture()
412 manufacture_reply->component_revision_id; in _transport_expander_report_manufacture()
416 ioc_info(ioc, "report_manufacture - no reply\n")); in _transport_expander_report_manufacture()
422 ioc->transport_cmds.status = MPT3_CMD_NOT_USED; in _transport_expander_report_manufacture()
424 dma_free_coherent(&ioc->pdev->dev, data_out_sz + data_in_sz, in _transport_expander_report_manufacture()
427 mutex_unlock(&ioc->transport_cmds.mutex); in _transport_expander_report_manufacture()
433 * _transport_delete_port - helper function to removing a port
441 u64 sas_address = mpt3sas_port->remote_identify.sas_address; in _transport_delete_port()
443 mpt3sas_port->remote_identify.device_type; in _transport_delete_port()
445 dev_printk(KERN_INFO, &mpt3sas_port->port->dev, in _transport_delete_port()
449 ioc->logging_level |= MPT_DEBUG_TRANSPORT; in _transport_delete_port()
455 ioc->logging_level &= ~MPT_DEBUG_TRANSPORT; in _transport_delete_port()
459 * _transport_delete_phy - helper function to removing single phy from port
462 * @mpt3sas_phy: mpt3sas per phy object
468 u64 sas_address = mpt3sas_port->remote_identify.sas_address; in _transport_delete_phy()
470 dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev, in _transport_delete_phy()
471 "remove: sas_addr(0x%016llx), phy(%d)\n", in _transport_delete_phy()
472 (unsigned long long) sas_address, mpt3sas_phy->phy_id); in _transport_delete_phy()
474 list_del(&mpt3sas_phy->port_siblings); in _transport_delete_phy()
475 mpt3sas_port->num_phys--; in _transport_delete_phy()
476 sas_port_delete_phy(mpt3sas_port->port, mpt3sas_phy->phy); in _transport_delete_phy()
477 mpt3sas_phy->phy_belongs_to_port = 0; in _transport_delete_phy()
481 * _transport_add_phy - helper function to adding single phy to port
484 * @mpt3sas_phy: mpt3sas per phy object
490 u64 sas_address = mpt3sas_port->remote_identify.sas_address; in _transport_add_phy()
492 dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev, in _transport_add_phy()
493 "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long) in _transport_add_phy()
494 sas_address, mpt3sas_phy->phy_id); in _transport_add_phy()
496 list_add_tail(&mpt3sas_phy->port_siblings, &mpt3sas_port->phy_list); in _transport_add_phy()
497 mpt3sas_port->num_phys++; in _transport_add_phy()
498 sas_port_add_phy(mpt3sas_port->port, mpt3sas_phy->phy); in _transport_add_phy()
499 mpt3sas_phy->phy_belongs_to_port = 1; in _transport_add_phy()
503 * _transport_add_phy_to_an_existing_port - adding new phy to existing port
506 * @mpt3sas_phy: mpt3sas per phy object
507 * @sas_address: sas address of device/expander were phy needs to be added to
517 if (mpt3sas_phy->phy_belongs_to_port == 1) in _transport_add_phy_to_an_existing_port()
520 list_for_each_entry(mpt3sas_port, &sas_node->sas_port_list, in _transport_add_phy_to_an_existing_port()
522 if (mpt3sas_port->remote_identify.sas_address != in _transport_add_phy_to_an_existing_port()
525 list_for_each_entry(phy_srch, &mpt3sas_port->phy_list, in _transport_add_phy_to_an_existing_port()
537 * _transport_del_phy_from_an_existing_port - delete phy from existing port
540 * @mpt3sas_phy: mpt3sas per phy object
549 if (mpt3sas_phy->phy_belongs_to_port == 0) in _transport_del_phy_from_an_existing_port()
552 list_for_each_entry_safe(mpt3sas_port, next, &sas_node->sas_port_list, in _transport_del_phy_from_an_existing_port()
554 list_for_each_entry(phy_srch, &mpt3sas_port->phy_list, in _transport_del_phy_from_an_existing_port()
559 if (mpt3sas_port->num_phys == 1) in _transport_del_phy_from_an_existing_port()
570 * _transport_sanity_check - sanity check when adding a new port
583 for (i = 0; i < sas_node->num_phys; i++) { in _transport_sanity_check()
584 if (sas_node->phy[i].remote_identify.sas_address != sas_address) in _transport_sanity_check()
586 if (sas_node->phy[i].phy_belongs_to_port == 1) in _transport_sanity_check()
588 &sas_node->phy[i]); in _transport_sanity_check()
593 * mpt3sas_transport_port_add - insert port to the list
595 * @handle: handle of attached device
597 * Context: This function will acquire ioc->sas_node_lock.
599 * Adding new port object to the sas_node->sas_port_list.
604 mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, in mpt3sas_transport_port_add() argument
624 INIT_LIST_HEAD(&mpt3sas_port->port_list); in mpt3sas_transport_port_add()
625 INIT_LIST_HEAD(&mpt3sas_port->phy_list); in mpt3sas_transport_port_add()
626 spin_lock_irqsave(&ioc->sas_node_lock, flags); in mpt3sas_transport_port_add()
628 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in mpt3sas_transport_port_add()
636 if ((_transport_set_identify(ioc, handle, in mpt3sas_transport_port_add()
637 &mpt3sas_port->remote_identify))) { in mpt3sas_transport_port_add()
643 if (mpt3sas_port->remote_identify.device_type == SAS_PHY_UNUSED) { in mpt3sas_transport_port_add()
650 mpt3sas_port->remote_identify.sas_address); in mpt3sas_transport_port_add()
652 for (i = 0; i < sas_node->num_phys; i++) { in mpt3sas_transport_port_add()
653 if (sas_node->phy[i].remote_identify.sas_address != in mpt3sas_transport_port_add()
654 mpt3sas_port->remote_identify.sas_address) in mpt3sas_transport_port_add()
656 list_add_tail(&sas_node->phy[i].port_siblings, in mpt3sas_transport_port_add()
657 &mpt3sas_port->phy_list); in mpt3sas_transport_port_add()
658 mpt3sas_port->num_phys++; in mpt3sas_transport_port_add()
661 if (!mpt3sas_port->num_phys) { in mpt3sas_transport_port_add()
667 if (!sas_node->parent_dev) { in mpt3sas_transport_port_add()
672 port = sas_port_alloc_num(sas_node->parent_dev); in mpt3sas_transport_port_add()
679 list_for_each_entry(mpt3sas_phy, &mpt3sas_port->phy_list, in mpt3sas_transport_port_add()
681 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) in mpt3sas_transport_port_add()
682 dev_printk(KERN_INFO, &port->dev, in mpt3sas_transport_port_add()
683 "add: handle(0x%04x), sas_addr(0x%016llx), phy(%d)\n", in mpt3sas_transport_port_add()
684 handle, (unsigned long long) in mpt3sas_transport_port_add()
685 mpt3sas_port->remote_identify.sas_address, in mpt3sas_transport_port_add()
686 mpt3sas_phy->phy_id); in mpt3sas_transport_port_add()
687 sas_port_add_phy(port, mpt3sas_phy->phy); in mpt3sas_transport_port_add()
688 mpt3sas_phy->phy_belongs_to_port = 1; in mpt3sas_transport_port_add()
691 mpt3sas_port->port = port; in mpt3sas_transport_port_add()
692 if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) in mpt3sas_transport_port_add()
696 mpt3sas_port->remote_identify.device_type); in mpt3sas_transport_port_add()
698 rphy->identify = mpt3sas_port->remote_identify; in mpt3sas_transport_port_add()
700 if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpt3sas_transport_port_add()
702 mpt3sas_port->remote_identify.sas_address); in mpt3sas_transport_port_add()
709 sas_device->pend_sas_rphy_add = 1; in mpt3sas_transport_port_add()
717 if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { in mpt3sas_transport_port_add()
718 sas_device->pend_sas_rphy_add = 0; in mpt3sas_transport_port_add()
722 dev_info(&rphy->dev, in mpt3sas_transport_port_add()
723 "add: handle(0x%04x), sas_addr(0x%016llx)\n", handle, in mpt3sas_transport_port_add()
724 (unsigned long long)mpt3sas_port->remote_identify.sas_address); in mpt3sas_transport_port_add()
726 mpt3sas_port->rphy = rphy; in mpt3sas_transport_port_add()
727 spin_lock_irqsave(&ioc->sas_node_lock, flags); in mpt3sas_transport_port_add()
728 list_add_tail(&mpt3sas_port->port_list, &sas_node->sas_port_list); in mpt3sas_transport_port_add()
729 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in mpt3sas_transport_port_add()
732 if (mpt3sas_port->remote_identify.device_type == in mpt3sas_transport_port_add()
734 mpt3sas_port->remote_identify.device_type == in mpt3sas_transport_port_add()
737 mpt3sas_port->remote_identify.sas_address, in mpt3sas_transport_port_add()
742 list_for_each_entry_safe(mpt3sas_phy, next, &mpt3sas_port->phy_list, in mpt3sas_transport_port_add()
744 list_del(&mpt3sas_phy->port_siblings); in mpt3sas_transport_port_add()
750 * mpt3sas_transport_port_remove - remove port from the list
754 * Context: This function will acquire ioc->sas_node_lock.
757 * ioc->sas_port_list.
770 spin_lock_irqsave(&ioc->sas_node_lock, flags); in mpt3sas_transport_port_remove()
774 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in mpt3sas_transport_port_remove()
777 list_for_each_entry_safe(mpt3sas_port, next, &sas_node->sas_port_list, in mpt3sas_transport_port_remove()
779 if (mpt3sas_port->remote_identify.sas_address != sas_address) in mpt3sas_transport_port_remove()
782 list_del(&mpt3sas_port->port_list); in mpt3sas_transport_port_remove()
787 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in mpt3sas_transport_port_remove()
791 for (i = 0; i < sas_node->num_phys; i++) { in mpt3sas_transport_port_remove()
792 if (sas_node->phy[i].remote_identify.sas_address == sas_address) in mpt3sas_transport_port_remove()
793 memset(&sas_node->phy[i].remote_identify, 0 , in mpt3sas_transport_port_remove()
797 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in mpt3sas_transport_port_remove()
800 &mpt3sas_port->phy_list, port_siblings) { in mpt3sas_transport_port_remove()
801 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) in mpt3sas_transport_port_remove()
802 dev_printk(KERN_INFO, &mpt3sas_port->port->dev, in mpt3sas_transport_port_remove()
803 "remove: sas_addr(0x%016llx), phy(%d)\n", in mpt3sas_transport_port_remove()
805 mpt3sas_port->remote_identify.sas_address, in mpt3sas_transport_port_remove()
806 mpt3sas_phy->phy_id); in mpt3sas_transport_port_remove()
807 mpt3sas_phy->phy_belongs_to_port = 0; in mpt3sas_transport_port_remove()
808 if (!ioc->remove_host) in mpt3sas_transport_port_remove()
809 sas_port_delete_phy(mpt3sas_port->port, in mpt3sas_transport_port_remove()
810 mpt3sas_phy->phy); in mpt3sas_transport_port_remove()
811 list_del(&mpt3sas_phy->port_siblings); in mpt3sas_transport_port_remove()
813 if (!ioc->remove_host) in mpt3sas_transport_port_remove()
814 sas_port_delete(mpt3sas_port->port); in mpt3sas_transport_port_remove()
821 * mpt3sas_transport_add_host_phy - report sas_host phy to transport
823 * @mpt3sas_phy: mpt3sas per phy object
824 * @phy_pg0: sas phy page 0
827 * Return: 0 for success, non-zero for failure.
833 struct sas_phy *phy; in mpt3sas_transport_add_host_phy() local
834 int phy_index = mpt3sas_phy->phy_id; in mpt3sas_transport_add_host_phy()
837 INIT_LIST_HEAD(&mpt3sas_phy->port_siblings); in mpt3sas_transport_add_host_phy()
838 phy = sas_phy_alloc(parent_dev, phy_index); in mpt3sas_transport_add_host_phy()
839 if (!phy) { in mpt3sas_transport_add_host_phy()
842 return -1; in mpt3sas_transport_add_host_phy()
844 if ((_transport_set_identify(ioc, mpt3sas_phy->handle, in mpt3sas_transport_add_host_phy()
845 &mpt3sas_phy->identify))) { in mpt3sas_transport_add_host_phy()
848 sas_phy_free(phy); in mpt3sas_transport_add_host_phy()
849 return -1; in mpt3sas_transport_add_host_phy()
851 phy->identify = mpt3sas_phy->identify; in mpt3sas_transport_add_host_phy()
852 mpt3sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle); in mpt3sas_transport_add_host_phy()
853 if (mpt3sas_phy->attached_handle) in mpt3sas_transport_add_host_phy()
854 _transport_set_identify(ioc, mpt3sas_phy->attached_handle, in mpt3sas_transport_add_host_phy()
855 &mpt3sas_phy->remote_identify); in mpt3sas_transport_add_host_phy()
856 phy->identify.phy_identifier = mpt3sas_phy->phy_id; in mpt3sas_transport_add_host_phy()
857 phy->negotiated_linkrate = _transport_convert_phy_link_rate( in mpt3sas_transport_add_host_phy()
859 phy->minimum_linkrate_hw = _transport_convert_phy_link_rate( in mpt3sas_transport_add_host_phy()
861 phy->maximum_linkrate_hw = _transport_convert_phy_link_rate( in mpt3sas_transport_add_host_phy()
863 phy->minimum_linkrate = _transport_convert_phy_link_rate( in mpt3sas_transport_add_host_phy()
865 phy->maximum_linkrate = _transport_convert_phy_link_rate( in mpt3sas_transport_add_host_phy()
868 if ((sas_phy_add(phy))) { in mpt3sas_transport_add_host_phy()
871 sas_phy_free(phy); in mpt3sas_transport_add_host_phy()
872 return -1; in mpt3sas_transport_add_host_phy()
874 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) in mpt3sas_transport_add_host_phy()
875 dev_printk(KERN_INFO, &phy->dev, in mpt3sas_transport_add_host_phy()
876 "add: handle(0x%04x), sas_addr(0x%016llx)\n" in mpt3sas_transport_add_host_phy()
878 mpt3sas_phy->handle, (unsigned long long) in mpt3sas_transport_add_host_phy()
879 mpt3sas_phy->identify.sas_address, in mpt3sas_transport_add_host_phy()
880 mpt3sas_phy->attached_handle, in mpt3sas_transport_add_host_phy()
882 mpt3sas_phy->remote_identify.sas_address); in mpt3sas_transport_add_host_phy()
883 mpt3sas_phy->phy = phy; in mpt3sas_transport_add_host_phy()
889 * mpt3sas_transport_add_expander_phy - report expander phy to transport
891 * @mpt3sas_phy: mpt3sas per phy object
895 * Return: 0 for success, non-zero for failure.
902 struct sas_phy *phy; in mpt3sas_transport_add_expander_phy() local
903 int phy_index = mpt3sas_phy->phy_id; in mpt3sas_transport_add_expander_phy()
905 INIT_LIST_HEAD(&mpt3sas_phy->port_siblings); in mpt3sas_transport_add_expander_phy()
906 phy = sas_phy_alloc(parent_dev, phy_index); in mpt3sas_transport_add_expander_phy()
907 if (!phy) { in mpt3sas_transport_add_expander_phy()
910 return -1; in mpt3sas_transport_add_expander_phy()
912 if ((_transport_set_identify(ioc, mpt3sas_phy->handle, in mpt3sas_transport_add_expander_phy()
913 &mpt3sas_phy->identify))) { in mpt3sas_transport_add_expander_phy()
916 sas_phy_free(phy); in mpt3sas_transport_add_expander_phy()
917 return -1; in mpt3sas_transport_add_expander_phy()
919 phy->identify = mpt3sas_phy->identify; in mpt3sas_transport_add_expander_phy()
920 mpt3sas_phy->attached_handle = in mpt3sas_transport_add_expander_phy()
922 if (mpt3sas_phy->attached_handle) in mpt3sas_transport_add_expander_phy()
923 _transport_set_identify(ioc, mpt3sas_phy->attached_handle, in mpt3sas_transport_add_expander_phy()
924 &mpt3sas_phy->remote_identify); in mpt3sas_transport_add_expander_phy()
925 phy->identify.phy_identifier = mpt3sas_phy->phy_id; in mpt3sas_transport_add_expander_phy()
926 phy->negotiated_linkrate = _transport_convert_phy_link_rate( in mpt3sas_transport_add_expander_phy()
929 phy->minimum_linkrate_hw = _transport_convert_phy_link_rate( in mpt3sas_transport_add_expander_phy()
931 phy->maximum_linkrate_hw = _transport_convert_phy_link_rate( in mpt3sas_transport_add_expander_phy()
933 phy->minimum_linkrate = _transport_convert_phy_link_rate( in mpt3sas_transport_add_expander_phy()
935 phy->maximum_linkrate = _transport_convert_phy_link_rate( in mpt3sas_transport_add_expander_phy()
938 if ((sas_phy_add(phy))) { in mpt3sas_transport_add_expander_phy()
941 sas_phy_free(phy); in mpt3sas_transport_add_expander_phy()
942 return -1; in mpt3sas_transport_add_expander_phy()
944 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) in mpt3sas_transport_add_expander_phy()
945 dev_printk(KERN_INFO, &phy->dev, in mpt3sas_transport_add_expander_phy()
946 "add: handle(0x%04x), sas_addr(0x%016llx)\n" in mpt3sas_transport_add_expander_phy()
948 mpt3sas_phy->handle, (unsigned long long) in mpt3sas_transport_add_expander_phy()
949 mpt3sas_phy->identify.sas_address, in mpt3sas_transport_add_expander_phy()
950 mpt3sas_phy->attached_handle, in mpt3sas_transport_add_expander_phy()
952 mpt3sas_phy->remote_identify.sas_address); in mpt3sas_transport_add_expander_phy()
953 mpt3sas_phy->phy = phy; in mpt3sas_transport_add_expander_phy()
958 * mpt3sas_transport_update_links - refreshing phy link changes
961 * @handle: attached device handle
962 * @phy_number: phy number
967 u64 sas_address, u16 handle, u8 phy_number, u8 link_rate) in mpt3sas_transport_update_links() argument
973 if (ioc->shost_recovery || ioc->pci_error_recovery) in mpt3sas_transport_update_links()
976 spin_lock_irqsave(&ioc->sas_node_lock, flags); in mpt3sas_transport_update_links()
979 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in mpt3sas_transport_update_links()
983 mpt3sas_phy = &sas_node->phy[phy_number]; in mpt3sas_transport_update_links()
984 mpt3sas_phy->attached_handle = handle; in mpt3sas_transport_update_links()
985 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in mpt3sas_transport_update_links()
986 if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { in mpt3sas_transport_update_links()
987 _transport_set_identify(ioc, handle, in mpt3sas_transport_update_links()
988 &mpt3sas_phy->remote_identify); in mpt3sas_transport_update_links()
990 mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address); in mpt3sas_transport_update_links()
992 memset(&mpt3sas_phy->remote_identify, 0 , sizeof(struct in mpt3sas_transport_update_links()
995 if (mpt3sas_phy->phy) in mpt3sas_transport_update_links()
996 mpt3sas_phy->phy->negotiated_linkrate = in mpt3sas_transport_update_links()
999 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) in mpt3sas_transport_update_links()
1000 dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev, in mpt3sas_transport_update_links()
1002 "\tlink_rate(0x%02x), phy(%d)\n" in mpt3sas_transport_update_links()
1005 link_rate, phy_number, handle, (unsigned long long) in mpt3sas_transport_update_links()
1006 mpt3sas_phy->remote_identify.sas_address); in mpt3sas_transport_update_links()
1010 phy_to_ioc(struct sas_phy *phy) in phy_to_ioc() argument
1012 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); in phy_to_ioc()
1019 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); in rphy_to_ioc()
1023 /* report phy error log structure */
1034 /* report phy error log reply structure */
1051 * _transport_get_expander_phy_error_log - return expander counters
1053 * @phy: The sas phy object
1055 * Return: 0 for success, non-zero for failure.
1060 struct sas_phy *phy) in _transport_get_expander_phy_error_log() argument
1074 if (ioc->shost_recovery || ioc->pci_error_recovery) { in _transport_get_expander_phy_error_log()
1076 return -EFAULT; in _transport_get_expander_phy_error_log()
1079 mutex_lock(&ioc->transport_cmds.mutex); in _transport_get_expander_phy_error_log()
1081 if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { in _transport_get_expander_phy_error_log()
1083 rc = -EAGAIN; in _transport_get_expander_phy_error_log()
1086 ioc->transport_cmds.status = MPT3_CMD_PENDING; in _transport_get_expander_phy_error_log()
1092 smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx); in _transport_get_expander_phy_error_log()
1095 rc = -EAGAIN; in _transport_get_expander_phy_error_log()
1100 ioc->transport_cmds.smid = smid; in _transport_get_expander_phy_error_log()
1104 data_out = dma_alloc_coherent(&ioc->pdev->dev, sz, &data_out_dma, in _transport_get_expander_phy_error_log()
1109 rc = -ENOMEM; in _transport_get_expander_phy_error_log()
1114 rc = -EINVAL; in _transport_get_expander_phy_error_log()
1117 phy_error_log_request->smp_frame_type = 0x40; in _transport_get_expander_phy_error_log()
1118 phy_error_log_request->function = 0x11; in _transport_get_expander_phy_error_log()
1119 phy_error_log_request->request_length = 2; in _transport_get_expander_phy_error_log()
1120 phy_error_log_request->allocated_response_length = 0; in _transport_get_expander_phy_error_log()
1121 phy_error_log_request->phy_identifier = phy->number; in _transport_get_expander_phy_error_log()
1124 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; in _transport_get_expander_phy_error_log()
1125 mpi_request->PhysicalPort = 0xFF; in _transport_get_expander_phy_error_log()
1126 mpi_request->VF_ID = 0; /* TODO */ in _transport_get_expander_phy_error_log()
1127 mpi_request->VP_ID = 0; in _transport_get_expander_phy_error_log()
1128 mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); in _transport_get_expander_phy_error_log()
1129 mpi_request->RequestDataLength = in _transport_get_expander_phy_error_log()
1131 psge = &mpi_request->SGL; in _transport_get_expander_phy_error_log()
1133 ioc->build_sg(ioc, psge, data_out_dma, in _transport_get_expander_phy_error_log()
1139 ioc_info(ioc, "phy_error_log - send to sas_addr(0x%016llx), phy(%d)\n", in _transport_get_expander_phy_error_log()
1140 (u64)phy->identify.sas_address, in _transport_get_expander_phy_error_log()
1141 phy->number)); in _transport_get_expander_phy_error_log()
1142 init_completion(&ioc->transport_cmds.done); in _transport_get_expander_phy_error_log()
1143 ioc->put_smid_default(ioc, smid); in _transport_get_expander_phy_error_log()
1144 wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); in _transport_get_expander_phy_error_log()
1146 if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { in _transport_get_expander_phy_error_log()
1150 if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) in _transport_get_expander_phy_error_log()
1155 dtransportprintk(ioc, ioc_info(ioc, "phy_error_log - complete\n")); in _transport_get_expander_phy_error_log()
1157 if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { in _transport_get_expander_phy_error_log()
1159 mpi_reply = ioc->transport_cmds.reply; in _transport_get_expander_phy_error_log()
1162 ioc_info(ioc, "phy_error_log - reply data transfer size(%d)\n", in _transport_get_expander_phy_error_log()
1163 le16_to_cpu(mpi_reply->ResponseDataLength))); in _transport_get_expander_phy_error_log()
1165 if (le16_to_cpu(mpi_reply->ResponseDataLength) != in _transport_get_expander_phy_error_log()
1173 ioc_info(ioc, "phy_error_log - function_result(%d)\n", in _transport_get_expander_phy_error_log()
1174 phy_error_log_reply->function_result)); in _transport_get_expander_phy_error_log()
1176 phy->invalid_dword_count = in _transport_get_expander_phy_error_log()
1177 be32_to_cpu(phy_error_log_reply->invalid_dword); in _transport_get_expander_phy_error_log()
1178 phy->running_disparity_error_count = in _transport_get_expander_phy_error_log()
1179 be32_to_cpu(phy_error_log_reply->running_disparity_error); in _transport_get_expander_phy_error_log()
1180 phy->loss_of_dword_sync_count = in _transport_get_expander_phy_error_log()
1181 be32_to_cpu(phy_error_log_reply->loss_of_dword_sync); in _transport_get_expander_phy_error_log()
1182 phy->phy_reset_problem_count = in _transport_get_expander_phy_error_log()
1183 be32_to_cpu(phy_error_log_reply->phy_reset_problem); in _transport_get_expander_phy_error_log()
1187 ioc_info(ioc, "phy_error_log - no reply\n")); in _transport_get_expander_phy_error_log()
1193 ioc->transport_cmds.status = MPT3_CMD_NOT_USED; in _transport_get_expander_phy_error_log()
1195 dma_free_coherent(&ioc->pdev->dev, sz, data_out, data_out_dma); in _transport_get_expander_phy_error_log()
1197 mutex_unlock(&ioc->transport_cmds.mutex); in _transport_get_expander_phy_error_log()
1202 * _transport_get_linkerrors - return phy counters for both hba and expanders
1203 * @phy: The sas phy object
1205 * Return: 0 for success, non-zero for failure.
1209 _transport_get_linkerrors(struct sas_phy *phy) in _transport_get_linkerrors() argument
1211 struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); in _transport_get_linkerrors()
1216 spin_lock_irqsave(&ioc->sas_node_lock, flags); in _transport_get_linkerrors()
1218 phy->identify.sas_address) == NULL) { in _transport_get_linkerrors()
1219 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in _transport_get_linkerrors()
1220 return -EINVAL; in _transport_get_linkerrors()
1222 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in _transport_get_linkerrors()
1224 if (phy->identify.sas_address != ioc->sas_hba.sas_address) in _transport_get_linkerrors()
1225 return _transport_get_expander_phy_error_log(ioc, phy); in _transport_get_linkerrors()
1227 /* get hba phy error logs */ in _transport_get_linkerrors()
1229 phy->number))) { in _transport_get_linkerrors()
1232 return -ENXIO; in _transport_get_linkerrors()
1236 ioc_info(ioc, "phy(%d), ioc_status (0x%04x), loginfo(0x%08x)\n", in _transport_get_linkerrors()
1237 phy->number, in _transport_get_linkerrors()
1241 phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount); in _transport_get_linkerrors()
1242 phy->running_disparity_error_count = in _transport_get_linkerrors()
1244 phy->loss_of_dword_sync_count = in _transport_get_linkerrors()
1246 phy->phy_reset_problem_count = in _transport_get_linkerrors()
1252 * _transport_get_enclosure_identifier -
1253 * @rphy: The sas phy object
1257 * Return: 0 for success, non-zero for failure.
1267 spin_lock_irqsave(&ioc->sas_device_lock, flags); in _transport_get_enclosure_identifier()
1269 rphy->identify.sas_address); in _transport_get_enclosure_identifier()
1271 *identifier = sas_device->enclosure_logical_id; in _transport_get_enclosure_identifier()
1276 rc = -ENXIO; in _transport_get_enclosure_identifier()
1279 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); in _transport_get_enclosure_identifier()
1284 * _transport_get_bay_identifier -
1285 * @rphy: The sas phy object
1297 spin_lock_irqsave(&ioc->sas_device_lock, flags); in _transport_get_bay_identifier()
1299 rphy->identify.sas_address); in _transport_get_bay_identifier()
1301 rc = sas_device->slot; in _transport_get_bay_identifier()
1304 rc = -ENXIO; in _transport_get_bay_identifier()
1306 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); in _transport_get_bay_identifier()
1310 /* phy control request structure */
1327 /* phy control reply structure */
1340 * _transport_expander_phy_control - expander phy control
1342 * @phy: The sas phy object
1345 * Return: 0 for success, non-zero for failure.
1350 struct sas_phy *phy, u8 phy_operation) in _transport_expander_phy_control() argument
1364 if (ioc->shost_recovery || ioc->pci_error_recovery) { in _transport_expander_phy_control()
1366 return -EFAULT; in _transport_expander_phy_control()
1369 mutex_lock(&ioc->transport_cmds.mutex); in _transport_expander_phy_control()
1371 if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { in _transport_expander_phy_control()
1373 rc = -EAGAIN; in _transport_expander_phy_control()
1376 ioc->transport_cmds.status = MPT3_CMD_PENDING; in _transport_expander_phy_control()
1382 smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx); in _transport_expander_phy_control()
1385 rc = -EAGAIN; in _transport_expander_phy_control()
1390 ioc->transport_cmds.smid = smid; in _transport_expander_phy_control()
1394 data_out = dma_alloc_coherent(&ioc->pdev->dev, sz, &data_out_dma, in _transport_expander_phy_control()
1399 rc = -ENOMEM; in _transport_expander_phy_control()
1404 rc = -EINVAL; in _transport_expander_phy_control()
1407 phy_control_request->smp_frame_type = 0x40; in _transport_expander_phy_control()
1408 phy_control_request->function = 0x91; in _transport_expander_phy_control()
1409 phy_control_request->request_length = 9; in _transport_expander_phy_control()
1410 phy_control_request->allocated_response_length = 0; in _transport_expander_phy_control()
1411 phy_control_request->phy_identifier = phy->number; in _transport_expander_phy_control()
1412 phy_control_request->phy_operation = phy_operation; in _transport_expander_phy_control()
1413 phy_control_request->programmed_min_physical_link_rate = in _transport_expander_phy_control()
1414 phy->minimum_linkrate << 4; in _transport_expander_phy_control()
1415 phy_control_request->programmed_max_physical_link_rate = in _transport_expander_phy_control()
1416 phy->maximum_linkrate << 4; in _transport_expander_phy_control()
1419 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; in _transport_expander_phy_control()
1420 mpi_request->PhysicalPort = 0xFF; in _transport_expander_phy_control()
1421 mpi_request->VF_ID = 0; /* TODO */ in _transport_expander_phy_control()
1422 mpi_request->VP_ID = 0; in _transport_expander_phy_control()
1423 mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); in _transport_expander_phy_control()
1424 mpi_request->RequestDataLength = in _transport_expander_phy_control()
1426 psge = &mpi_request->SGL; in _transport_expander_phy_control()
1428 ioc->build_sg(ioc, psge, data_out_dma, in _transport_expander_phy_control()
1434 ioc_info(ioc, "phy_control - send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n", in _transport_expander_phy_control()
1435 (u64)phy->identify.sas_address, in _transport_expander_phy_control()
1436 phy->number, phy_operation)); in _transport_expander_phy_control()
1437 init_completion(&ioc->transport_cmds.done); in _transport_expander_phy_control()
1438 ioc->put_smid_default(ioc, smid); in _transport_expander_phy_control()
1439 wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); in _transport_expander_phy_control()
1441 if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { in _transport_expander_phy_control()
1445 if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) in _transport_expander_phy_control()
1450 dtransportprintk(ioc, ioc_info(ioc, "phy_control - complete\n")); in _transport_expander_phy_control()
1452 if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { in _transport_expander_phy_control()
1454 mpi_reply = ioc->transport_cmds.reply; in _transport_expander_phy_control()
1457 ioc_info(ioc, "phy_control - reply data transfer size(%d)\n", in _transport_expander_phy_control()
1458 le16_to_cpu(mpi_reply->ResponseDataLength))); in _transport_expander_phy_control()
1460 if (le16_to_cpu(mpi_reply->ResponseDataLength) != in _transport_expander_phy_control()
1468 ioc_info(ioc, "phy_control - function_result(%d)\n", in _transport_expander_phy_control()
1469 phy_control_reply->function_result)); in _transport_expander_phy_control()
1474 ioc_info(ioc, "phy_control - no reply\n")); in _transport_expander_phy_control()
1480 ioc->transport_cmds.status = MPT3_CMD_NOT_USED; in _transport_expander_phy_control()
1482 dma_free_coherent(&ioc->pdev->dev, sz, data_out, in _transport_expander_phy_control()
1485 mutex_unlock(&ioc->transport_cmds.mutex); in _transport_expander_phy_control()
1490 * _transport_phy_reset -
1491 * @phy: The sas phy object
1494 * Return: 0 for success, non-zero for failure.
1497 _transport_phy_reset(struct sas_phy *phy, int hard_reset) in _transport_phy_reset() argument
1499 struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); in _transport_phy_reset()
1504 spin_lock_irqsave(&ioc->sas_node_lock, flags); in _transport_phy_reset()
1506 phy->identify.sas_address) == NULL) { in _transport_phy_reset()
1507 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in _transport_phy_reset()
1508 return -EINVAL; in _transport_phy_reset()
1510 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in _transport_phy_reset()
1512 /* handle expander phys */ in _transport_phy_reset()
1513 if (phy->identify.sas_address != ioc->sas_hba.sas_address) in _transport_phy_reset()
1514 return _transport_expander_phy_control(ioc, phy, in _transport_phy_reset()
1518 /* handle hba phys */ in _transport_phy_reset()
1523 mpi_request.PhyNum = phy->number; in _transport_phy_reset()
1528 return -ENXIO; in _transport_phy_reset()
1532 ioc_info(ioc, "phy(%d), ioc_status(0x%04x), loginfo(0x%08x)\n", in _transport_phy_reset()
1533 phy->number, le16_to_cpu(mpi_reply.IOCStatus), in _transport_phy_reset()
1540 * _transport_phy_enable - enable/disable phys
1541 * @phy: The sas phy object
1542 * @enable: enable phy when true
1545 * Return: 0 for success, non-zero for failure.
1548 _transport_phy_enable(struct sas_phy *phy, int enable) in _transport_phy_enable() argument
1550 struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); in _transport_phy_enable()
1560 spin_lock_irqsave(&ioc->sas_node_lock, flags); in _transport_phy_enable()
1562 phy->identify.sas_address) == NULL) { in _transport_phy_enable()
1563 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in _transport_phy_enable()
1564 return -EINVAL; in _transport_phy_enable()
1566 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in _transport_phy_enable()
1568 /* handle expander phys */ in _transport_phy_enable()
1569 if (phy->identify.sas_address != ioc->sas_hba.sas_address) in _transport_phy_enable()
1570 return _transport_expander_phy_control(ioc, phy, in _transport_phy_enable()
1574 /* handle hba phys */ in _transport_phy_enable()
1577 sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys * in _transport_phy_enable()
1583 rc = -ENOMEM; in _transport_phy_enable()
1590 rc = -ENXIO; in _transport_phy_enable()
1598 rc = -EIO; in _transport_phy_enable()
1603 for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) { in _transport_phy_enable()
1604 if (sas_iounit_pg0->PhyData[i].PortFlags & in _transport_phy_enable()
1606 …ioc_err(ioc, "discovery is active on port = %d, phy = %d: unable to enable/disable phys, try again… in _transport_phy_enable()
1607 sas_iounit_pg0->PhyData[i].Port, i); in _transport_phy_enable()
1613 rc = -EAGAIN; in _transport_phy_enable()
1618 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * in _transport_phy_enable()
1624 rc = -ENOMEM; in _transport_phy_enable()
1631 rc = -ENXIO; in _transport_phy_enable()
1639 rc = -EIO; in _transport_phy_enable()
1644 for (i = 0; i < ioc->sas_hba.num_phys ; i++) { in _transport_phy_enable()
1645 sas_iounit_pg1->PhyData[i].Port = in _transport_phy_enable()
1646 sas_iounit_pg0->PhyData[i].Port; in _transport_phy_enable()
1647 sas_iounit_pg1->PhyData[i].PortFlags = in _transport_phy_enable()
1648 (sas_iounit_pg0->PhyData[i].PortFlags & in _transport_phy_enable()
1650 sas_iounit_pg1->PhyData[i].PhyFlags = in _transport_phy_enable()
1651 (sas_iounit_pg0->PhyData[i].PhyFlags & in _transport_phy_enable()
1657 sas_iounit_pg1->PhyData[phy->number].PhyFlags in _transport_phy_enable()
1660 sas_iounit_pg1->PhyData[phy->number].PhyFlags in _transport_phy_enable()
1667 _transport_phy_reset(phy, 0); in _transport_phy_enable()
1676 * _transport_phy_speed - set phy min/max link rates
1677 * @phy: The sas phy object
1682 * Return: 0 for success, non-zero for failure.
1685 _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) in _transport_phy_speed() argument
1687 struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); in _transport_phy_speed()
1697 spin_lock_irqsave(&ioc->sas_node_lock, flags); in _transport_phy_speed()
1699 phy->identify.sas_address) == NULL) { in _transport_phy_speed()
1700 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in _transport_phy_speed()
1701 return -EINVAL; in _transport_phy_speed()
1703 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); in _transport_phy_speed()
1705 if (!rates->minimum_linkrate) in _transport_phy_speed()
1706 rates->minimum_linkrate = phy->minimum_linkrate; in _transport_phy_speed()
1707 else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) in _transport_phy_speed()
1708 rates->minimum_linkrate = phy->minimum_linkrate_hw; in _transport_phy_speed()
1710 if (!rates->maximum_linkrate) in _transport_phy_speed()
1711 rates->maximum_linkrate = phy->maximum_linkrate; in _transport_phy_speed()
1712 else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) in _transport_phy_speed()
1713 rates->maximum_linkrate = phy->maximum_linkrate_hw; in _transport_phy_speed()
1715 /* handle expander phys */ in _transport_phy_speed()
1716 if (phy->identify.sas_address != ioc->sas_hba.sas_address) { in _transport_phy_speed()
1717 phy->minimum_linkrate = rates->minimum_linkrate; in _transport_phy_speed()
1718 phy->maximum_linkrate = rates->maximum_linkrate; in _transport_phy_speed()
1719 return _transport_expander_phy_control(ioc, phy, in _transport_phy_speed()
1723 /* handle hba phys */ in _transport_phy_speed()
1726 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * in _transport_phy_speed()
1732 rc = -ENOMEM; in _transport_phy_speed()
1739 rc = -ENXIO; in _transport_phy_speed()
1747 rc = -EIO; in _transport_phy_speed()
1751 for (i = 0; i < ioc->sas_hba.num_phys; i++) { in _transport_phy_speed()
1752 if (phy->number != i) { in _transport_phy_speed()
1753 sas_iounit_pg1->PhyData[i].MaxMinLinkRate = in _transport_phy_speed()
1754 (ioc->sas_hba.phy[i].phy->minimum_linkrate + in _transport_phy_speed()
1755 (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4)); in _transport_phy_speed()
1757 sas_iounit_pg1->PhyData[i].MaxMinLinkRate = in _transport_phy_speed()
1758 (rates->minimum_linkrate + in _transport_phy_speed()
1759 (rates->maximum_linkrate << 4)); in _transport_phy_speed()
1767 rc = -ENXIO; in _transport_phy_speed()
1772 _transport_phy_reset(phy, 0); in _transport_phy_speed()
1774 /* read phy page 0, then update the rates in the sas transport phy */ in _transport_phy_speed()
1776 phy->number)) { in _transport_phy_speed()
1777 phy->minimum_linkrate = _transport_convert_phy_link_rate( in _transport_phy_speed()
1779 phy->maximum_linkrate = _transport_convert_phy_link_rate( in _transport_phy_speed()
1781 phy->negotiated_linkrate = _transport_convert_phy_link_rate( in _transport_phy_speed()
1796 if (buf->sg_cnt > 1) { in _transport_map_smp_buffer()
1797 *p = dma_alloc_coherent(dev, buf->payload_len, dma_addr, in _transport_map_smp_buffer()
1800 return -ENOMEM; in _transport_map_smp_buffer()
1801 *dma_len = buf->payload_len; in _transport_map_smp_buffer()
1803 if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL)) in _transport_map_smp_buffer()
1804 return -ENOMEM; in _transport_map_smp_buffer()
1805 *dma_addr = sg_dma_address(buf->sg_list); in _transport_map_smp_buffer()
1806 *dma_len = sg_dma_len(buf->sg_list); in _transport_map_smp_buffer()
1818 dma_free_coherent(dev, buf->payload_len, p, dma_addr); in _transport_unmap_smp_buffer()
1820 dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL); in _transport_unmap_smp_buffer()
1824 * _transport_smp_handler - transport portal for smp passthru
1831 * smp_rep_general /sys/class/bsg/expander-5:0
1851 if (ioc->shost_recovery || ioc->pci_error_recovery) { in _transport_smp_handler()
1853 rc = -EFAULT; in _transport_smp_handler()
1857 rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex); in _transport_smp_handler()
1861 if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { in _transport_smp_handler()
1864 rc = -EAGAIN; in _transport_smp_handler()
1867 ioc->transport_cmds.status = MPT3_CMD_PENDING; in _transport_smp_handler()
1869 rc = _transport_map_smp_buffer(&ioc->pdev->dev, &job->request_payload, in _transport_smp_handler()
1874 sg_copy_to_buffer(job->request_payload.sg_list, in _transport_smp_handler()
1875 job->request_payload.sg_cnt, addr_out, in _transport_smp_handler()
1876 job->request_payload.payload_len); in _transport_smp_handler()
1879 rc = _transport_map_smp_buffer(&ioc->pdev->dev, &job->reply_payload, in _transport_smp_handler()
1888 smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx); in _transport_smp_handler()
1891 rc = -EAGAIN; in _transport_smp_handler()
1897 ioc->transport_cmds.smid = smid; in _transport_smp_handler()
1900 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; in _transport_smp_handler()
1901 mpi_request->PhysicalPort = 0xFF; in _transport_smp_handler()
1902 mpi_request->SASAddress = (rphy) ? in _transport_smp_handler()
1903 cpu_to_le64(rphy->identify.sas_address) : in _transport_smp_handler()
1904 cpu_to_le64(ioc->sas_hba.sas_address); in _transport_smp_handler()
1905 mpi_request->RequestDataLength = cpu_to_le16(dma_len_out - 4); in _transport_smp_handler()
1906 psge = &mpi_request->SGL; in _transport_smp_handler()
1908 ioc->build_sg(ioc, psge, dma_addr_out, dma_len_out - 4, dma_addr_in, in _transport_smp_handler()
1909 dma_len_in - 4); in _transport_smp_handler()
1914 init_completion(&ioc->transport_cmds.done); in _transport_smp_handler()
1915 ioc->put_smid_default(ioc, smid); in _transport_smp_handler()
1916 wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); in _transport_smp_handler()
1918 if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { in _transport_smp_handler()
1922 if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) { in _transport_smp_handler()
1924 rc = -ETIMEDOUT; in _transport_smp_handler()
1929 dtransportprintk(ioc, ioc_info(ioc, "%s - complete\n", __func__)); in _transport_smp_handler()
1931 if (!(ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID)) { in _transport_smp_handler()
1934 rc = -ENXIO; in _transport_smp_handler()
1938 mpi_reply = ioc->transport_cmds.reply; in _transport_smp_handler()
1943 le16_to_cpu(mpi_reply->ResponseDataLength))); in _transport_smp_handler()
1945 memcpy(job->reply, mpi_reply, sizeof(*mpi_reply)); in _transport_smp_handler()
1946 job->reply_len = sizeof(*mpi_reply); in _transport_smp_handler()
1947 reslen = le16_to_cpu(mpi_reply->ResponseDataLength); in _transport_smp_handler()
1950 sg_copy_to_buffer(job->reply_payload.sg_list, in _transport_smp_handler()
1951 job->reply_payload.sg_cnt, addr_in, in _transport_smp_handler()
1952 job->reply_payload.payload_len); in _transport_smp_handler()
1957 _transport_unmap_smp_buffer(&ioc->pdev->dev, &job->reply_payload, in _transport_smp_handler()
1960 _transport_unmap_smp_buffer(&ioc->pdev->dev, &job->request_payload, in _transport_smp_handler()
1963 ioc->transport_cmds.status = MPT3_CMD_NOT_USED; in _transport_smp_handler()
1964 mutex_unlock(&ioc->transport_cmds.mutex); in _transport_smp_handler()