From a1cca3e54ffe5921b4f81ead5a4db2d6b7bd0d20 Mon Sep 17 00:00:00 2001 From: YunYi Yang Date: Mon, 20 Nov 2023 14:50:42 +0800 Subject: [PATCH] Add features and bugfixes of the Hisi SAS driver --- kernel.spec | 111 +- ...-need-to-check-return-value-of-debug.patch | 165 + ...x-type-casting-and-missing-static-qu.patch | 134 + ...x-losing-directly-attached-disk-when.patch | 193 ++ ...e-pci_irq_get_affinity-for-v3-hw-as-.patch | 230 ++ ...0653-scsi-hisi_sas-Some-misc-tidy-up.patch | 315 ++ ...ke-max-IPTT-count-equal-for-all-hw-r.patch | 222 ++ ...x-pointer-usage-error-in-show-debugf.patch | 58 + ...apshot-HW-cache-of-IOST-and-ITCT-at-.patch | 335 ++ ...apshot-AXI-and-RAS-register-at-debug.patch | 345 ++ ...op-kmap_atomic-in-SMP-command-comple.patch | 105 + ..._sas-Drop-SMP-resp-frame-DMA-mapping.patch | 190 ++ ...op-free_irq-when-devm_request_irq-fa.patch | 175 ++ ...dify-return-type-of-debugfs-function.patch | 168 + ...isi_sas-Remove-some-unnecessary-code.patch | 55 + ...move-set-but-not-used-variable-irq_v.patch | 50 + ...e-devm_platform_ioremap_resource-to-.patch | 46 + ...d-debugfs-auto-trigger-for-internal-.patch | 44 + ...sas-Remove-hisi_sas_hw.slot_complete.patch | 84 + ...as-Remove-redundant-work-declaration.patch | 41 + ...emove-some-unused-function-arguments.patch | 153 + ...d-hisi_sas_debugfs_alloc-to-centrali.patch | 257 ++ ...-fix-spelling-mistake-digial-digital.patch | 45 + ...hisi_sas-Make-three-functions-static.patch | 59 + ...n-t-create-debugfs-dump-folder-twice.patch | 55 + ...sas-Add-timestamp-for-a-debugfs-dump.patch | 93 + ...as-Add-debugfs-file-structure-for-CQ.patch | 141 + ...as-Add-debugfs-file-structure-for-DQ.patch | 121 + ...d-debugfs-file-structure-for-registe.patch | 224 ++ ...-Add-debugfs-file-structure-for-port.patch | 126 + ...-Add-debugfs-file-structure-for-IOST.patch | 119 + ...-Add-debugfs-file-structure-for-ITCT.patch | 132 + ...d-debugfs-file-structure-for-IOST-ca.patch | 113 + ...d-debugfs-file-structure-for-ITCT-ca.patch | 112 + ...locate-memory-for-multiple-dumps-of-.patch | 403 +++ ...d-module-parameter-for-debugfs-dump-.patch | 91 + ...d-ability-to-have-multiple-debugfs-d.patch | 283 ++ ...lete-the-debugfs-folder-of-hisi_sas-.patch | 63 + ...Record-the-phy-down-event-in-debugfs.patch | 153 + ...turn-directly-if-init-hardware-faile.patch | 43 + ...s-Stop-converting-a-bool-into-a-bool.patch | 42 + ...place-magic-number-when-handle-chann.patch | 81 + ...dify-the-file-permissions-of-trigger.patch | 45 + ...d-prints-for-v3-hw-interrupt-converg.patch | 56 + ...e-dev_err-in-read_iost_itct_cache_v3.patch | 55 + ...as-Fix-build-error-without-SATA_HOST.patch | 50 + ...-hisi_sas-Display-proc_name-in-sysfs.patch | 78 + ...dify-the-commit-information-for-DSM-.patch | 54 + ...d-SAS_RAS_INTR0-to-debugfs-register-.patch | 44 + ...op-returning-error-code-from-slot_co.patch | 233 ++ ...-not-reset-phy-timer-to-wait-for-str.patch | 54 + ...isi_sas-Remove-one-kerneldoc-comment.patch | 42 + ...dify-macro-name-for-OOB-phy-linkrate.patch | 74 + ...-not-modify-upper-fields-of-PROG_PHY.patch | 96 + ...ke-phy-index-variable-name-consisten.patch | 162 + ...isi_sas-Add-BIST-support-for-phy-FFE.patch | 75 + ...d-BIST-support-for-fixed-code-patter.patch | 332 ++ ...5-scsi-hisi_sas-Add-missing-newlines.patch | 155 + ...706-scsi-hisi_sas-Code-style-cleanup.patch | 85 + ...itch-to-new-framework-to-support-sus.patch | 87 + ...d-controller-runtime-PM-support-for-.patch | 155 + ...-Add-check-for-methods-_PS0-and-_PR0.patch | 69 + ...d-device-link-between-SCSI-devices-a.patch | 86 + ...cover-PHY-state-according-to-the-sta.patch | 55 + ...ix-up-probe-error-handling-for-v3-hw.patch | 111 + ...duce-some-indirection-in-v3-hw-drive.patch | 67 + ...as-Move-debugfs-code-to-v3-hw-driver.patch | 2796 +++++++++++++++++ ...715-scsi-hisi_sas-Remove-preemptible.patch | 72 + ...e-threaded-irq-to-process-CQ-interru.patch | 325 ++ ...move-deferred-probe-check-in-hisi_sa.patch | 60 + ...as-Enable-debugfs-support-by-default.patch | 81 + ...i_sas-Add-trace-FIFO-debugfs-support.patch | 385 +++ ...int-SAS-address-for-v3-hw-erroneous-.patch | 57 + ...ll-sas_unregister_ha-to-roll-back-if.patch | 78 + ...rectly-snapshot-registers-when-execu.patch | 175 ++ ...rn-in-v3-hw-channel-interrupt-handle.patch | 66 + ...int-SATA-device-SAS-address-for-soft.patch | 53 + ...as-Put-a-limit-of-link-reset-retries.patch | 90 + ...n-I_T-nexus-resets-in-parallel-for-c.patch | 98 + ...-hisi_sas-Include-HZ-in-timer-macros.patch | 140 + ...set-controller-for-internal-abort-ti.patch | 194 ++ ...eed-up-error-handling-when-internal-.patch | 90 + ...itialise-devices-in-.slave_alloc-cal.patch | 127 + ...it-for-phyup-in-hisi_sas_control_phy.patch | 265 ++ ...d-more-logs-for-runtime-suspend-resu.patch | 68 + ...ep-controller-active-between-ISR-of-.patch | 121 + ...e-autosuspend-for-the-host-controlle.patch | 50 + ...mit-users-changing-debugfs-BIST-coun.patch | 109 + ...event-parallel-controller-reset-and-.patch | 62 + ...i-hisi_sas-Fix-phyup-timeout-on-FPGA.patch | 114 + ...dify-v3-HW-SSP-underflow-error-proce.patch | 197 ++ ...sas-Fix-rescan-after-deleting-a-disk.patch | 154 + ...do-RPM-resume-for-failed-notify-phy-.patch | 59 + ...e-abort-task-set-to-reset-SAS-disks-.patch | 47 + ...sable-SATA-disk-phy-for-severe-I_T-n.patch | 90 + ..._sas-Disable-SATA-disk-phy-for-sever.patch | 87 + ...t-a-port-invalid-only-if-there-are-n.patch | 50 + ...it-suspending-state-when-usage-count.patch | 291 ++ ...sure-all-enabled-PHYs-up-during-cont.patch | 113 + ...crease-debugfs_dump_index-after-dump.patch | 55 + ...nfigure-the-initialization-registers.patch | 103 + ...dd-slave_destroy-interface-for-v3-hw.patch | 87 + ...ock-requests-before-take-debugfs-sna.patch | 68 + ...rk-around-build-failure-in-suspend-f.patch | 81 + ...eck-usage-count-only-when-the-runtim.patch | 62 + ...v3_hw-Don-t-use-PCI-helper-functions.patch | 91 + ..._hw-Remove-extra-function-calls-for-.patch | 89 + ...64-Enable-dubugfs-config-of-hisi-sas.patch | 34 + series.conf | 107 + 109 files changed, 15835 insertions(+), 1 deletion(-) create mode 100644 patches/0649-scsi-hisi_sas-No-need-to-check-return-value-of-debug.patch create mode 100644 patches/0650-scsi-hisi_sas-Fix-type-casting-and-missing-static-qu.patch create mode 100644 patches/0651-scsi-hisi_sas-Fix-losing-directly-attached-disk-when.patch create mode 100644 patches/0652-scsi-hisi_sas-Use-pci_irq_get_affinity-for-v3-hw-as-.patch create mode 100644 patches/0653-scsi-hisi_sas-Some-misc-tidy-up.patch create mode 100644 patches/0654-scsi-hisi_sas-Make-max-IPTT-count-equal-for-all-hw-r.patch create mode 100644 patches/0655-scsi-hisi_sas-Fix-pointer-usage-error-in-show-debugf.patch create mode 100644 patches/0656-scsi-hisi_sas-Snapshot-HW-cache-of-IOST-and-ITCT-at-.patch create mode 100644 patches/0657-scsi-hisi_sas-Snapshot-AXI-and-RAS-register-at-debug.patch create mode 100644 patches/0658-scsi-hisi_sas-Drop-kmap_atomic-in-SMP-command-comple.patch create mode 100644 patches/0659-scsi-hisi_sas-Drop-SMP-resp-frame-DMA-mapping.patch create mode 100644 patches/0660-scsi-hisi_sas-Drop-free_irq-when-devm_request_irq-fa.patch create mode 100644 patches/0661-scsi-hisi_sas-Modify-return-type-of-debugfs-function.patch create mode 100644 patches/0662-scsi-hisi_sas-Remove-some-unnecessary-code.patch create mode 100644 patches/0663-scsi-hisi_sas-remove-set-but-not-used-variable-irq_v.patch create mode 100644 patches/0664-scsi-hisi_sas-use-devm_platform_ioremap_resource-to-.patch create mode 100644 patches/0665-scsi-hisi_sas-add-debugfs-auto-trigger-for-internal-.patch create mode 100644 patches/0666-scsi-hisi_sas-Remove-hisi_sas_hw.slot_complete.patch create mode 100644 patches/0667-scsi-hisi_sas-Remove-redundant-work-declaration.patch create mode 100644 patches/0668-scsi-hisi_sas-Remove-some-unused-function-arguments.patch create mode 100644 patches/0669-scsi-hisi_sas-Add-hisi_sas_debugfs_alloc-to-centrali.patch create mode 100644 patches/0670-scsi-hisi_sas-fix-spelling-mistake-digial-digital.patch create mode 100644 patches/0671-scsi-hisi_sas-Make-three-functions-static.patch create mode 100644 patches/0672-scsi-hisi_sas-Don-t-create-debugfs-dump-folder-twice.patch create mode 100644 patches/0673-scsi-hisi_sas-Add-timestamp-for-a-debugfs-dump.patch create mode 100644 patches/0674-scsi-hisi_sas-Add-debugfs-file-structure-for-CQ.patch create mode 100644 patches/0675-scsi-hisi_sas-Add-debugfs-file-structure-for-DQ.patch create mode 100644 patches/0676-scsi-hisi_sas-Add-debugfs-file-structure-for-registe.patch create mode 100644 patches/0677-scsi-hisi_sas-Add-debugfs-file-structure-for-port.patch create mode 100644 patches/0678-scsi-hisi_sas-Add-debugfs-file-structure-for-IOST.patch create mode 100644 patches/0679-scsi-hisi_sas-Add-debugfs-file-structure-for-ITCT.patch create mode 100644 patches/0680-scsi-hisi_sas-Add-debugfs-file-structure-for-IOST-ca.patch create mode 100644 patches/0681-scsi-hisi_sas-Add-debugfs-file-structure-for-ITCT-ca.patch create mode 100644 patches/0682-scsi-hisi_sas-Allocate-memory-for-multiple-dumps-of-.patch create mode 100644 patches/0683-scsi-hisi_sas-Add-module-parameter-for-debugfs-dump-.patch create mode 100644 patches/0684-scsi-hisi_sas-Add-ability-to-have-multiple-debugfs-d.patch create mode 100644 patches/0685-scsi-hisi_sas-Delete-the-debugfs-folder-of-hisi_sas-.patch create mode 100644 patches/0686-scsi-hisi_sas-Record-the-phy-down-event-in-debugfs.patch create mode 100644 patches/0687-scsi-hisi_sas-Return-directly-if-init-hardware-faile.patch create mode 100644 patches/0688-scsi-hisi_sas-Stop-converting-a-bool-into-a-bool.patch create mode 100644 patches/0689-scsi-hisi_sas-Replace-magic-number-when-handle-chann.patch create mode 100644 patches/0690-scsi-hisi_sas-Modify-the-file-permissions-of-trigger.patch create mode 100644 patches/0691-scsi-hisi_sas-Add-prints-for-v3-hw-interrupt-converg.patch create mode 100644 patches/0692-scsi-hisi_sas-Use-dev_err-in-read_iost_itct_cache_v3.patch create mode 100644 patches/0693-scsi-hisi_sas-Fix-build-error-without-SATA_HOST.patch create mode 100644 patches/0694-scsi-hisi_sas-Display-proc_name-in-sysfs.patch create mode 100644 patches/0695-scsi-hisi_sas-Modify-the-commit-information-for-DSM-.patch create mode 100644 patches/0696-scsi-hisi_sas-Add-SAS_RAS_INTR0-to-debugfs-register-.patch create mode 100644 patches/0697-scsi-hisi_sas-Stop-returning-error-code-from-slot_co.patch create mode 100644 patches/0698-scsi-hisi_sas-Do-not-reset-phy-timer-to-wait-for-str.patch create mode 100644 patches/0699-scsi-hisi_sas-Remove-one-kerneldoc-comment.patch create mode 100644 patches/0700-scsi-hisi_sas-Modify-macro-name-for-OOB-phy-linkrate.patch create mode 100644 patches/0701-scsi-hisi_sas-Do-not-modify-upper-fields-of-PROG_PHY.patch create mode 100644 patches/0702-scsi-hisi_sas-Make-phy-index-variable-name-consisten.patch create mode 100644 patches/0703-scsi-hisi_sas-Add-BIST-support-for-phy-FFE.patch create mode 100644 patches/0704-scsi-hisi_sas-Add-BIST-support-for-fixed-code-patter.patch create mode 100644 patches/0705-scsi-hisi_sas-Add-missing-newlines.patch create mode 100644 patches/0706-scsi-hisi_sas-Code-style-cleanup.patch create mode 100644 patches/0707-scsi-hisi_sas-Switch-to-new-framework-to-support-sus.patch create mode 100644 patches/0708-scsi-hisi_sas-Add-controller-runtime-PM-support-for-.patch create mode 100644 patches/0709-scsi-hisi_sas-Add-check-for-methods-_PS0-and-_PR0.patch create mode 100644 patches/0710-scsi-hisi_sas-Add-device-link-between-SCSI-devices-a.patch create mode 100644 patches/0711-scsi-hisi_sas-Recover-PHY-state-according-to-the-sta.patch create mode 100644 patches/0712-scsi-hisi_sas-Fix-up-probe-error-handling-for-v3-hw.patch create mode 100644 patches/0713-scsi-hisi_sas-Reduce-some-indirection-in-v3-hw-drive.patch create mode 100644 patches/0714-scsi-hisi_sas-Move-debugfs-code-to-v3-hw-driver.patch create mode 100644 patches/0715-scsi-hisi_sas-Remove-preemptible.patch create mode 100644 patches/0716-scsi-hisi_sas-use-threaded-irq-to-process-CQ-interru.patch create mode 100644 patches/0717-scsi-hisi_sas-Remove-deferred-probe-check-in-hisi_sa.patch create mode 100644 patches/0718-scsi-hisi_sas-Enable-debugfs-support-by-default.patch create mode 100644 patches/0719-scsi-hisi_sas-Add-trace-FIFO-debugfs-support.patch create mode 100644 patches/0720-scsi-hisi_sas-Print-SAS-address-for-v3-hw-erroneous-.patch create mode 100644 patches/0721-scsi-hisi_sas-Call-sas_unregister_ha-to-roll-back-if.patch create mode 100644 patches/0722-scsi-hisi_sas-Directly-snapshot-registers-when-execu.patch create mode 100644 patches/0723-scsi-hisi_sas-Warn-in-v3-hw-channel-interrupt-handle.patch create mode 100644 patches/0724-scsi-hisi_sas-Print-SATA-device-SAS-address-for-soft.patch create mode 100644 patches/0725-scsi-hisi_sas-Put-a-limit-of-link-reset-retries.patch create mode 100644 patches/0726-scsi-hisi_sas-Run-I_T-nexus-resets-in-parallel-for-c.patch create mode 100644 patches/0727-scsi-hisi_sas-Include-HZ-in-timer-macros.patch create mode 100644 patches/0728-scsi-hisi_sas-Reset-controller-for-internal-abort-ti.patch create mode 100644 patches/0729-scsi-hisi_sas-Speed-up-error-handling-when-internal-.patch create mode 100644 patches/0730-scsi-hisi_sas-Initialise-devices-in-.slave_alloc-cal.patch create mode 100644 patches/0731-scsi-hisi_sas-Wait-for-phyup-in-hisi_sas_control_phy.patch create mode 100644 patches/0732-scsi-hisi_sas-Add-more-logs-for-runtime-suspend-resu.patch create mode 100644 patches/0733-scsi-hisi_sas-Keep-controller-active-between-ISR-of-.patch create mode 100644 patches/0734-scsi-hisi_sas-Use-autosuspend-for-the-host-controlle.patch create mode 100644 patches/0735-scsi-hisi_sas-Limit-users-changing-debugfs-BIST-coun.patch create mode 100644 patches/0736-scsi-hisi_sas-Prevent-parallel-controller-reset-and-.patch create mode 100644 patches/0737-scsi-hisi_sas-Fix-phyup-timeout-on-FPGA.patch create mode 100644 patches/0738-scsi-hisi_sas-Modify-v3-HW-SSP-underflow-error-proce.patch create mode 100644 patches/0739-scsi-hisi_sas-Fix-rescan-after-deleting-a-disk.patch create mode 100644 patches/0740-scsi-hisi_sas-Undo-RPM-resume-for-failed-notify-phy-.patch create mode 100644 patches/0741-scsi-hisi_sas-Use-abort-task-set-to-reset-SAS-disks-.patch create mode 100644 patches/0742-scsi-hisi_sas-Disable-SATA-disk-phy-for-severe-I_T-n.patch create mode 100644 patches/0743-Revert-scsi-hisi_sas-Disable-SATA-disk-phy-for-sever.patch create mode 100644 patches/0744-scsi-hisi_sas-Set-a-port-invalid-only-if-there-are-n.patch create mode 100644 patches/0745-scsi-hisi_sas-Exit-suspending-state-when-usage-count.patch create mode 100644 patches/0746-scsi-hisi_sas-Ensure-all-enabled-PHYs-up-during-cont.patch create mode 100644 patches/0747-scsi-hisi_sas-Increase-debugfs_dump_index-after-dump.patch create mode 100644 patches/0748-scsi-hisi_sas-Configure-the-initialization-registers.patch create mode 100644 patches/0749-scsi-hisi_sas-Add-slave_destroy-interface-for-v3-hw.patch create mode 100644 patches/0750-scsi-hisi_sas-Block-requests-before-take-debugfs-sna.patch create mode 100644 patches/0751-scsi-hisi_sas-Work-around-build-failure-in-suspend-f.patch create mode 100644 patches/0752-scsi-hisi_sas-Check-usage-count-only-when-the-runtim.patch create mode 100644 patches/0753-scsi-hisi_sas_v3_hw-Don-t-use-PCI-helper-functions.patch create mode 100644 patches/0754-scsi-hisi_sas_v3_hw-Remove-extra-function-calls-for-.patch create mode 100644 patches/0755-config-arm64-Enable-dubugfs-config-of-hisi-sas.patch diff --git a/kernel.spec b/kernel.spec index c6ac5b3..d0784e7 100644 --- a/kernel.spec +++ b/kernel.spec @@ -32,7 +32,7 @@ Name: kernel Version: 4.19.90 -Release: %{hulkrelease}.0247 +Release: %{hulkrelease}.0248 Summary: Linux Kernel License: GPLv2 URL: http://www.kernel.org/ @@ -850,6 +850,115 @@ fi %changelog +* Mon Nov 20 2023 YunYi Yang - 4.19.90-2311.3.0.0248 +- config: arm64: Enable dubugfs config of hisi sas +- scsi: hisi_sas_v3_hw: Remove extra function calls for runtime pm +- scsi: hisi_sas_v3_hw: Don't use PCI helper functions +- scsi: hisi_sas: Check usage count only when the runtime PM status is RPM_SUSPENDING +- scsi: hisi_sas: Work around build failure in suspend function +- scsi: hisi_sas: Block requests before take debugfs snapshot +- scsi: hisi_sas: Add slave_destroy interface for v3 hw +- scsi: hisi_sas: Configure the initialization registers according to HBA model +- scsi: hisi_sas: Increase debugfs_dump_index after dump is completed +- scsi: hisi_sas: Ensure all enabled PHYs up during controller reset +- scsi: hisi_sas: Exit suspending state when usage count is greater than 0 +- scsi: hisi_sas: Set a port invalid only if there are no devices attached when refreshing port id +- Revert "scsi: hisi_sas: Disable SATA disk phy for severe I_T nexus reset failure" +- scsi: hisi_sas: Disable-SATA-disk-phy-for-severe-I_T-nexus reset failure +- scsi: hisi_sas: Use abort task set to reset SAS disks when discovered +- scsi: hisi_sas: Undo RPM resume for failed notify phy event for v3 HW +- scsi: hisi_sas: Fix rescan after deleting a disk +- scsi: hisi_sas: Modify v3 HW SSP underflow error processing +- scsi: hisi_sas: Fix phyup timeout on FPGA +- scsi: hisi_sas: Prevent parallel controller reset and control phy command +- scsi: hisi_sas: Limit users changing debugfs BIST count value +- scsi: hisi_sas: Use autosuspend for the host controller +- scsi: hisi_sas: Keep controller active between ISR of phyup and the event being processed +- scsi: hisi_sas: Add more logs for runtime suspend/resume +- scsi: hisi_sas: Wait for phyup in hisi_sas_control_phy() +- scsi: hisi_sas: Initialise devices in .slave_alloc callback +- scsi: hisi_sas: Speed up error handling when internal abort timeout occurs +- scsi: hisi_sas: Reset controller for internal abort timeout +- scsi: hisi_sas: Include HZ in timer macros +- scsi: hisi_sas: Run I_T nexus resets in parallel for clear nexus reset +- scsi: hisi_sas: Put a limit of link reset retries +- scsi: hisi_sas: Print SATA device SAS address for soft reset failure +- scsi: hisi_sas: Warn in v3 hw channel interrupt handler when status reg cleared +- scsi: hisi_sas: Directly snapshot registers when executing a reset +- scsi: hisi_sas: Call sas_unregister_ha() to roll back if .hw_init() fails +- scsi: hisi_sas: Print SAS address for v3 hw erroneous completion print +- scsi: hisi_sas: Add trace FIFO debugfs support +- scsi: hisi_sas: Enable debugfs support by default +- scsi: hisi_sas: Remove deferred probe check in hisi_sas_v2_probe() +- scsi: hisi_sas: use threaded irq to process CQ interrupts +- scsi: hisi_sas: Remove preemptible() +- scsi: hisi_sas: Move debugfs code to v3 hw driver +- scsi: hisi_sas: Reduce some indirection in v3 hw driver +- scsi: hisi_sas: Fix up probe error handling for v3 hw +- scsi: hisi_sas: Recover PHY state according to the status before reset +- scsi: hisi_sas: Add device link between SCSI devices and hisi_hba +- scsi: hisi_sas: Add check for methods _PS0 and _PR0 +- scsi: hisi_sas: Add controller runtime PM support for v3 hw +- scsi: hisi_sas: Switch to new framework to support suspend and resume +- scsi: hisi_sas: Code style cleanup +- scsi: hisi_sas: Add missing newlines +- scsi: hisi_sas: Add BIST support for fixed code pattern +- scsi: hisi_sas: Add BIST support for phy FFE +- scsi: hisi_sas: Make phy index variable name consistent +- scsi: hisi_sas: Do not modify upper fields of PROG_PHY_LINK_RATE reg +- scsi: hisi_sas: Modify macro name for OOB phy linkrate +- scsi: hisi_sas: Remove one kerneldoc comment +- scsi: hisi_sas: Do not reset phy timer to wait for stray phy up +- scsi: hisi_sas: Stop returning error code from slot_complete_vX_hw() +- scsi: hisi_sas: Add SAS_RAS_INTR0 to debugfs register name list +- scsi: hisi_sas: Modify the commit information for DSM method +- scsi: hisi_sas: Display proc_name in sysfs +- scsi: hisi_sas: Fix build error without SATA_HOST +- scsi: hisi_sas: Use dev_err() in read_iost_itct_cache_v3_hw() +- scsi: hisi_sas: Add prints for v3 hw interrupt converge and automatic affinity +- scsi: hisi_sas: Modify the file permissions of trigger_dump to write only +- scsi: hisi_sas: Replace magic number when handle channel interrupt +- scsi: hisi_sas: Stop converting a bool into a bool +- scsi: hisi_sas: Return directly if init hardware failed +- scsi: hisi_sas: Record the phy down event in debugfs +- scsi: hisi_sas: Delete the debugfs folder of hisi_sas when the probe fails +- scsi: hisi_sas: Add ability to have multiple debugfs dumps +- scsi: hisi_sas: Add module parameter for debugfs dump count +- scsi: hisi_sas: Allocate memory for multiple dumps of debugfs +- scsi: hisi_sas: Add debugfs file structure for ITCT cache +- scsi: hisi_sas: Add debugfs file structure for IOST cache +- scsi: hisi_sas: Add debugfs file structure for ITCT +- scsi: hisi_sas: Add debugfs file structure for IOST +- scsi: hisi_sas: Add debugfs file structure for port +- scsi: hisi_sas: Add debugfs file structure for registers +- scsi: hisi_sas: Add debugfs file structure for DQ +- scsi: hisi_sas: Add debugfs file structure for CQ +- scsi: hisi_sas: Add timestamp for a debugfs dump +- scsi: hisi_sas: Don't create debugfs dump folder twice +- scsi: hisi_sas: Make three functions static +- scsi: hisi_sas: fix spelling mistake "digial" -> "digital" +- scsi: hisi_sas: Add hisi_sas_debugfs_alloc() to centralise allocation +- scsi: hisi_sas: Remove some unused function arguments +- scsi: hisi_sas: Remove redundant work declaration +- scsi: hisi_sas: Remove hisi_sas_hw.slot_complete +- scsi: hisi_sas: add debugfs auto-trigger for internal abort time out +- scsi: hisi_sas: use devm_platform_ioremap_resource() to simplify code +- scsi: hisi_sas: remove set but not used variable 'irq_value' +- scsi: hisi_sas: Remove some unnecessary code +- scsi: hisi_sas: Modify return type of debugfs functions +- scsi: hisi_sas: Drop free_irq() when devm_request_irq() failed +- scsi: hisi_sas: Drop SMP resp frame DMA mapping +- scsi: hisi_sas: Drop kmap_atomic() in SMP command completion +- scsi: hisi_sas: Snapshot AXI and RAS register at debugfs +- scsi: hisi_sas: Snapshot HW cache of IOST and ITCT at debugfs +- scsi: hisi_sas: Fix pointer usage error in show debugfs IOST/ITCT +- scsi: hisi_sas: Make max IPTT count equal for all hw revisions +- scsi: hisi_sas: Some misc tidy-up +- scsi: hisi_sas: Use pci_irq_get_affinity() for v3 hw as experimental +- scsi: hisi_sas: Fix losing directly attached disk when hot-plug +- scsi: hisi_sas: Fix type casting and missing static qualifier in debugfs code +- scsi: hisi_sas: No need to check return value of debugfs_create functions + * Mon Nov 20 2023 Yu Liao - 4.19.90-2311.3.0.0247 - Backport cpu turbo patches diff --git a/patches/0649-scsi-hisi_sas-No-need-to-check-return-value-of-debug.patch b/patches/0649-scsi-hisi_sas-No-need-to-check-return-value-of-debug.patch new file mode 100644 index 0000000..aee44ec --- /dev/null +++ b/patches/0649-scsi-hisi_sas-No-need-to-check-return-value-of-debug.patch @@ -0,0 +1,165 @@ +From 9bdaf9ddf72f897d1e8f302025e7da0b62f4a405 Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Fri, 25 Jan 2019 22:22:27 +0800 +Subject: [PATCH 001/108] scsi: hisi_sas: No need to check return value of + debugfs_create functions + +mainline inclusion +from mainline-v5.1-rc1 +commit c2c7e740577154e755ec373712e32e5864e88315 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c2c7e740577154e755ec373712e32e5864e88315 + +---------------------------------------------------------------------- + +When calling debugfs functions, there is no need to ever check the return +value. The function can work or not, but the code logic should never do +something different based on this. + +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 + + drivers/scsi/hisi_sas/hisi_sas_main.c | 56 ++++++++++----------------- + 2 files changed, 21 insertions(+), 36 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 2880e4e22a73..d04d784c45b9 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -437,6 +437,7 @@ struct hisi_hba { + unsigned int dq_idx[NR_CPUS]; + int nvecs; + unsigned int dq_num_per_node; ++ bool debugfs_snapshot; + }; + + /* Generic HW DMA host memory structures */ +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 6bccd36556f2..6d8f9e9e0120 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1621,8 +1621,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) + if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + return -EPERM; + +- if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct && +- !hisi_hba->debugfs_dump_dentry) ++ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct) + hisi_hba->hw->debugfs_work_handler(&hisi_hba->debugfs_work); + + dev_info(dev, "controller resetting...\n"); +@@ -3499,67 +3498,51 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + + /* Create dump dir inside device dir */ + dump_dentry = debugfs_create_dir("dump", hisi_hba->debugfs_dir); +- if (!dump_dentry) +- goto fail; + + hisi_hba->debugfs_dump_dentry = dump_dentry; + +- if (!debugfs_create_file("global", 0400, dump_dentry, hisi_hba, +- &hisi_sas_debugfs_global_fops)) +- goto fail; ++ debugfs_create_file("global", 0400, dump_dentry, hisi_hba, ++ &hisi_sas_debugfs_global_fops); + + /* Create port dir and files */ + dentry = debugfs_create_dir("port", dump_dentry); +- if (!dentry) +- goto fail; + + for (p = 0; p < hisi_hba->n_phy; p++) { + snprintf(name, sizeof(name), "%d", p); +- if (!debugfs_create_file(name, 0400, dentry, +- &hisi_hba->phy[p], +- &hisi_sas_debugfs_port_fops)) +- goto fail; ++ debugfs_create_file(name, 0400, dentry, ++ &hisi_hba->phy[p], ++ &hisi_sas_debugfs_port_fops); + } + + /* Create CQ dir and files */ + dentry = debugfs_create_dir("cq", dump_dentry); +- if (!dentry) +- goto fail; + + for (c = 0; c < hisi_hba->queue_count; c++) { + snprintf(name, sizeof(name), "%d", c); + +- if (!debugfs_create_file(name, 0400, dentry, +- &hisi_hba->cq[c], +- &hisi_sas_debugfs_cq_fops)) +- goto fail; ++ debugfs_create_file(name, 0400, dentry, ++ &hisi_hba->cq[c], ++ &hisi_sas_debugfs_cq_fops); + } + + /* Create DQ dir and files */ + dentry = debugfs_create_dir("dq", dump_dentry); +- if (!dentry) +- goto fail; + + for (d = 0; d < hisi_hba->queue_count; d++) { + snprintf(name, sizeof(name), "%d", d); + +- if (!debugfs_create_file(name, 0400, dentry, +- &hisi_hba->dq[d], +- &hisi_sas_debugfs_dq_fops)) +- goto fail; ++ debugfs_create_file(name, 0400, dentry, ++ &hisi_hba->dq[d], ++ &hisi_sas_debugfs_dq_fops); + } + +- if (!debugfs_create_file("iost", 0400, dump_dentry, hisi_hba, +- &hisi_sas_debugfs_iost_fops)) +- goto fail; ++ debugfs_create_file("iost", 0400, dump_dentry, hisi_hba, ++ &hisi_sas_debugfs_iost_fops); + +- if (!debugfs_create_file("itct", 0400, dump_dentry, hisi_hba, +- &hisi_sas_debugfs_itct_fops)) +- goto fail; ++ debugfs_create_file("itct", 0400, dump_dentry, hisi_hba, ++ &hisi_sas_debugfs_itct_fops); + + return; +-fail: +- hisi_sas_debugfs_exit(hisi_hba); + } + + static void hisi_sas_debugfs_snapshot_regs(struct hisi_hba *hisi_hba) +@@ -3620,6 +3603,10 @@ void hisi_sas_debugfs_work_handler(struct work_struct *work) + struct hisi_hba *hisi_hba = + container_of(work, struct hisi_hba, debugfs_work); + ++ if (hisi_hba->debugfs_snapshot) ++ return; ++ hisi_hba->debugfs_snapshot = true; ++ + hisi_sas_debugfs_snapshot_regs(hisi_hba); + } + EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler); +@@ -3634,9 +3621,6 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), + hisi_sas_debugfs_dir); + +- if (!hisi_hba->debugfs_dir) +- return; +- + debugfs_create_file("trigger_dump", 0600, + hisi_hba->debugfs_dir, + hisi_hba, +-- +2.27.0 + diff --git a/patches/0650-scsi-hisi_sas-Fix-type-casting-and-missing-static-qu.patch b/patches/0650-scsi-hisi_sas-Fix-type-casting-and-missing-static-qu.patch new file mode 100644 index 0000000..c5ebdcd --- /dev/null +++ b/patches/0650-scsi-hisi_sas-Fix-type-casting-and-missing-static-qu.patch @@ -0,0 +1,134 @@ +From 97d8404c4e751475f0b428fee3dfda80dc936163 Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Fri, 25 Jan 2019 22:22:28 +0800 +Subject: [PATCH 002/108] scsi: hisi_sas: Fix type casting and missing static + qualifier in debugfs code + +mainline inclusion +from mainline-v5.1-rc1 +commit 5b0eeac4bed4b1a261acf3cd893f929e68814a0d +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5b0eeac4bed4b1a261acf3cd893f929e68814a0d + +---------------------------------------------------------------------- + +Sparse can detect some type casting issues in the debugfs code, so fix it +up. + +Also a missing static qualifier is added to hisi_sas_debugfs_to_reg_name(). + +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 4 ++-- + drivers/scsi/hisi_sas/hisi_sas_main.c | 19 ++++++++++--------- + 2 files changed, 12 insertions(+), 11 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index d04d784c45b9..cd64ac88b684 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -422,8 +422,8 @@ struct hisi_hba { + int enable_dix_dif; + + /* debugfs memories */ +- void *debugfs_global_reg; +- void *debugfs_port_reg[HISI_SAS_MAX_PHYS]; ++ u32 *debugfs_global_reg; ++ u32 *debugfs_port_reg[HISI_SAS_MAX_PHYS]; + void *debugfs_complete_hdr[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_cmd_hdr *debugfs_cmd_hdr[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_iost *debugfs_iost; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 6d8f9e9e0120..e7ffc5eaabe6 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2847,7 +2847,7 @@ static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba) + } + } + +-const char * ++static const char * + hisi_sas_debugfs_to_reg_name(int off, int base_off, + const struct hisi_sas_debugfs_reg_lu *lu) + { +@@ -2874,10 +2874,10 @@ static void hisi_sas_debugfs_print_reg(u32 *regs_val, const void *ptr, + + if (name) + seq_printf(s, "0x%08x 0x%08x %s\n", off, +- le32_to_cpu(regs_val[i]), name); ++ regs_val[i], name); + else + seq_printf(s, "0x%08x 0x%08x\n", off, +- le32_to_cpu(regs_val[i])); ++ regs_val[i]); + } + } + +@@ -2887,7 +2887,7 @@ static int hisi_sas_debugfs_global_show(struct seq_file *s, void *p) + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *reg_global = hw->debugfs_reg_global; + +- hisi_sas_debugfs_print_reg((u32 *)hisi_hba->debugfs_global_reg, ++ hisi_sas_debugfs_print_reg(hisi_hba->debugfs_global_reg, + reg_global, s); + + return 0; +@@ -3317,7 +3317,7 @@ static const struct file_operations hisi_sas_debugfs_port_fops = { + }; + + static int hisi_sas_show_row_64(struct seq_file *s, int index, +- int sz, u64 *ptr) ++ int sz, __le64 *ptr) + { + int i; + +@@ -3336,7 +3336,7 @@ static int hisi_sas_show_row_64(struct seq_file *s, int index, + } + + static int hisi_sas_show_row_32(struct seq_file *s, int index, +- int sz, u32 *ptr) ++ int sz, __le32 *ptr) + { + int i; + +@@ -3359,7 +3359,7 @@ static int hisi_sas_cq_show_slot(struct seq_file *s, int slot, void *cq_ptr) + struct hisi_hba *hisi_hba = cq->hisi_hba; + void *complete_queue = hisi_hba->debugfs_complete_hdr[cq->id]; + u64 offset = hisi_hba->hw->complete_hdr_size * slot; +- void *complete_hdr = complete_queue + offset; ++ __le32 *complete_hdr = complete_queue + offset; + + return hisi_sas_show_row_32(s, slot, + hisi_hba->hw->complete_hdr_size, +@@ -3398,7 +3398,7 @@ static int hisi_sas_dq_show_slot(struct seq_file *s, int slot, void *dq_ptr) + struct hisi_hba *hisi_hba = dq->hisi_hba; + void *cmd_queue = hisi_hba->debugfs_cmd_hdr[dq->id]; + u64 offset = sizeof(struct hisi_sas_cmd_hdr) * slot; +- void *cmd_hdr = cmd_queue + offset; ++ __le32 *cmd_hdr = cmd_queue + offset; + + return hisi_sas_show_row_32(s, slot, sizeof(struct hisi_sas_cmd_hdr), + cmd_hdr); +@@ -3434,10 +3434,11 @@ static int hisi_sas_debugfs_iost_show(struct seq_file *s, void *p) + struct hisi_hba *hisi_hba = s->private; + struct hisi_sas_iost *debugfs_iost = hisi_hba->debugfs_iost; + int i, ret, max_command_entries = hisi_hba->hw->max_command_entries; ++ __le64 *iost = &debugfs_iost->qw0; + + for (i = 0; i < max_command_entries; i++, debugfs_iost++) { + ret = hisi_sas_show_row_64(s, i, sizeof(*debugfs_iost), +- (u64 *)debugfs_iost); ++ iost); + if (ret) + return ret; + } +-- +2.27.0 + diff --git a/patches/0651-scsi-hisi_sas-Fix-losing-directly-attached-disk-when.patch b/patches/0651-scsi-hisi_sas-Fix-losing-directly-attached-disk-when.patch new file mode 100644 index 0000000..97dd0a6 --- /dev/null +++ b/patches/0651-scsi-hisi_sas-Fix-losing-directly-attached-disk-when.patch @@ -0,0 +1,193 @@ +From 0d1bdb32b173ca4a13619c592d53addb2061674f Mon Sep 17 00:00:00 2001 +From: Xiaofei Tan +Date: Fri, 25 Jan 2019 22:22:35 +0800 +Subject: [PATCH 003/108] scsi: hisi_sas: Fix losing directly attached disk + when hot-plug + +mainline inclusion +from mainline-v5.1-rc1 +commit b6c9b15e44090aee2a7fba646b06ff166f595b16 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b6c9b15e44090aee2a7fba646b06ff166f595b16 + +---------------------------------------------------------------------- + +Hot-plugging SAS wire of direct hard disk backplane may cause disk lost. We +have done this test with several types of SATA disk from different venders, +and only two models from Seagate has this problem, ST4000NM0035-1V4107 and +ST3000VM002-1ET166. + +The root cause is that the disk doesn't send D2H frame after OOB finished. +SAS controller will issue phyup interrupt only when D2H frame is received, +otherwise, will be waiting there all the time. + +When this issue happen, we can find the disk again with link reset. To fix +this issue, we setup an timer after OOB finished. If the PHY is not up in +20s, do link reset. Notes: the 20s is an experience value. + +Signed-off-by: Xiaofei Tan +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 + + drivers/scsi/hisi_sas/hisi_sas_main.c | 26 ++++++++++++++++++++++- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 26 +---------------------- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 29 ++------------------------ + 4 files changed, 29 insertions(+), 53 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index cd64ac88b684..daa64e5aff3e 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -608,6 +608,7 @@ extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba); + extern void hisi_sas_rst_work_handler(struct work_struct *work); + extern void hisi_sas_sync_rst_work_handler(struct work_struct *work); + extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba); ++extern void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no); + extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy, + enum hisi_sas_phy_event event); + extern void hisi_sas_release_tasks(struct hisi_hba *hisi_hba); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index e7ffc5eaabe6..852ece4af0f4 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -915,6 +915,30 @@ bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy, + } + EXPORT_SYMBOL_GPL(hisi_sas_notify_phy_event); + ++static void hisi_sas_wait_phyup_timedout(struct timer_list *t) ++{ ++ struct hisi_sas_phy *phy = from_timer(phy, t, timer); ++ struct hisi_hba *hisi_hba = phy->hisi_hba; ++ struct device *dev = hisi_hba->dev; ++ int phy_no = phy->sas_phy.id; ++ ++ dev_warn(dev, "phy%d wait phyup timeout, issuing link reset\n", phy_no); ++ hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); ++} ++ ++void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no) ++{ ++ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; ++ struct device *dev = hisi_hba->dev; ++ ++ if (!timer_pending(&phy->timer)) { ++ dev_dbg(dev, "phy%d OOB ready\n", phy_no); ++ phy->timer.expires = jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT * HZ; ++ add_timer(&phy->timer); ++ } ++} ++EXPORT_SYMBOL_GPL(hisi_sas_phy_oob_ready); ++ + static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) + { + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; +@@ -944,7 +968,7 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) + + spin_lock_init(&phy->lock); + +- timer_setup(&phy->timer, NULL, 0); ++ timer_setup(&phy->timer, hisi_sas_wait_phyup_timedout, 0); + } + + /* Wrapper to ensure we track hisi_sas_phy.enable properly */ +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index f9867176fa14..1b701ec807e8 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -2889,30 +2889,6 @@ static const struct hisi_sas_hw_error port_ecc_axi_error[] = { + }, + }; + +-static void wait_phyup_timedout_v2_hw(struct timer_list *t) +-{ +- struct hisi_sas_phy *phy = from_timer(phy, t, timer); +- struct hisi_hba *hisi_hba = phy->hisi_hba; +- struct device *dev = hisi_hba->dev; +- int phy_no = phy->sas_phy.id; +- +- dev_warn(dev, "phy%d wait phyup timeout, issuing link reset\n", phy_no); +- hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); +-} +- +-static void phy_oob_ready_v2_hw(struct hisi_hba *hisi_hba, int phy_no) +-{ +- struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; +- struct device *dev = hisi_hba->dev; +- +- if (!timer_pending(&phy->timer)) { +- dev_dbg(dev, "phy%d OOB ready\n", phy_no); +- phy->timer.function = wait_phyup_timedout_v2_hw; +- phy->timer.expires = jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT; +- add_timer(&phy->timer); +- } +-} +- + static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p) + { + struct hisi_hba *hisi_hba = p; +@@ -2974,7 +2950,7 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p) + phy_bcast_v2_hw(phy_no, hisi_hba); + + if (irq_value0 & CHL_INT0_PHY_RDY_MSK) +- phy_oob_ready_v2_hw(hisi_hba, phy_no); ++ hisi_sas_phy_oob_ready(hisi_hba, phy_no); + + hisi_sas_phy_write32(hisi_hba, phy_no, + CHL_INT0, irq_value0 +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 79010d02ad24..cfa9756fb995 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1916,38 +1916,13 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, irq_value); + } + +-static void wait_phyup_timedout_v3_hw(struct timer_list *t) +-{ +- struct hisi_sas_phy *phy = from_timer(phy, t, timer); +- struct hisi_hba *hisi_hba = phy->hisi_hba; +- struct device *dev = hisi_hba->dev; +- int phy_no = phy->sas_phy.id; +- +- dev_warn(dev, "phy%d wait phyup timeout, issuing link reset\n", phy_no); +- hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); +-} +- + static void handle_chl_int0_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + { + u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT0); +- struct device *dev = hisi_hba->dev; + +- if (irq_value0 & CHL_INT0_PHY_RDY_MSK) { +- struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; ++ if (irq_value0 & CHL_INT0_PHY_RDY_MSK) ++ hisi_sas_phy_oob_ready(hisi_hba, phy_no); + +- dev_dbg(dev, "phy%d OOB ready\n", phy_no); +- if (phy->phy_attached) +- goto out; +- +- if (!timer_pending(&phy->timer)) { +- phy->timer.function = wait_phyup_timedout_v3_hw; +- phy->timer.expires = jiffies + +- HISI_SAS_WAIT_PHYUP_TIMEOUT; +- add_timer(&phy->timer); +- } +- } +- +-out: + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, + irq_value0 & (~CHL_INT0_SL_RX_BCST_ACK_MSK) + & (~CHL_INT0_SL_PHY_ENABLE_MSK) +-- +2.27.0 + diff --git a/patches/0652-scsi-hisi_sas-Use-pci_irq_get_affinity-for-v3-hw-as-.patch b/patches/0652-scsi-hisi_sas-Use-pci_irq_get_affinity-for-v3-hw-as-.patch new file mode 100644 index 0000000..ea1b7fd --- /dev/null +++ b/patches/0652-scsi-hisi_sas-Use-pci_irq_get_affinity-for-v3-hw-as-.patch @@ -0,0 +1,230 @@ +From 99990c92d47d2a9485906a9bef7125269344a2b9 Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Wed, 6 Feb 2019 18:52:55 +0800 +Subject: [PATCH 004/108] scsi: hisi_sas: Use pci_irq_get_affinity() for v3 hw + as experimental + +mainline inclusion +from mainline-v5.1-rc1 +commit 4fefe5bbf599d6c6bee6b2ee376be789b33ca571 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4fefe5bbf599d6c6bee6b2ee376be789b33ca571 + +---------------------------------------------------------------------- + +For auto-control irq affinity mode, choose the dq to deliver IO according +to the current CPU. + +Then it decreases the performance regression that fio and CQ interrupts are +processed on different node. + +For user control irq affinity mode, keep it as before. + +To realize it, also need to distinguish the usage of dq lock and sas_dev +lock. + +We mark as experimental due to ongoing discussion on managed MSI IRQ +during hotplug: +https://marc.info/?l=linux-scsi&m=154876335707751&w=2 + +We're almost at the point where we can expose multiple queues to the upper +layer for SCSI MQ, but we need to sort out the per-HBA tags performance +issue. + +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h + drivers/scsi/hisi_sas/hisi_sas_main.c + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 4 +- + drivers/scsi/hisi_sas/hisi_sas_main.c | 20 ++++--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 74 +++++++++++++++++++------- + 3 files changed, 68 insertions(+), 30 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index daa64e5aff3e..06a8bf9f0f73 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -192,6 +192,7 @@ struct hisi_sas_port { + + struct hisi_sas_cq { + struct hisi_hba *hisi_hba; ++ const struct cpumask *pci_irq_mask; + struct tasklet_struct tasklet; + int rd_point; + int id; +@@ -214,8 +215,8 @@ struct hisi_sas_device { + enum sas_device_type dev_type; + unsigned int device_id; + int sata_idx; +- spinlock_t lock; + enum dev_status dev_status; ++ spinlock_t lock; /* For protecting slots */ + }; + + struct hisi_sas_tmf_task { +@@ -420,6 +421,7 @@ struct hisi_hba { + int bist_loopback_enable; + + int enable_dix_dif; ++ unsigned int *reply_map; + + /* debugfs memories */ + u32 *debugfs_global_reg; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 852ece4af0f4..7ccdaaba311c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -456,9 +456,6 @@ static int hisi_sas_task_prep(struct sas_task *task, + unsigned long flags; + int wr_q_index; + unsigned int curr_node_id = numa_node_id(); +- unsigned int dq_index = +- (hisi_hba->dq_idx[curr_node_id] % hisi_hba->dq_num_per_node) + +- (hisi_hba->dq_num_per_node * curr_node_id); + + if (DEV_IS_GONE(sas_dev)) { + if (sas_dev) +@@ -471,10 +468,14 @@ static int hisi_sas_task_prep(struct sas_task *task, + return -ECOMM; + } + +- if (hisi_hba->user_ctl_irq) +- *dq_pointer = dq = sas_dev->dq; +- else ++ if (hisi_hba->reply_map) { ++ int cpu = raw_smp_processor_id(); ++ unsigned int dq_index = hisi_hba->reply_map[cpu]; ++ + *dq_pointer = dq = &hisi_hba->dq[dq_index]; ++ } else { ++ *dq_pointer = dq = sas_dev->dq; ++ } + + port = to_hisi_sas_port(sas_port); + if (port && !port->port_attached) { +@@ -2207,11 +2208,8 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + abort_flag, tag, dq); + case HISI_SAS_INT_ABT_DEV: + for (i = 0; i < hisi_hba->nvecs; i++) { +- const struct cpumask *mask = NULL; +- +- if (hisi_hba->hw->get_managed_irq_aff) +- mask = hisi_hba->hw->get_managed_irq_aff( +- hisi_hba, i); ++ struct hisi_sas_cq *cq = &hisi_hba->cq[i]; ++ const struct cpumask *mask = cq->pci_irq_mask; + /* + * The kernel will not permit unmanaged (MSI are + * managed) IRQ affinity to offline CPUs, so +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index cfa9756fb995..4635c3b161db 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -556,6 +556,11 @@ module_param(user_ctl_irq, bool, 0444); + MODULE_PARM_DESC(user_ctl_irq, "Enable user control irq affinity:\n" + "default is auto-control irq affinity"); + ++static bool auto_affine_msi_experimental; ++module_param(auto_affine_msi_experimental, bool, 0444); ++MODULE_PARM_DESC(auto_affine_msi_experimental, "Enable auto-affinity of MSI IRQs as experimental:\n" ++ "default is off"); ++ + static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) + { + void __iomem *regs = hisi_hba->regs + off; +@@ -2677,33 +2682,66 @@ static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p) + return IRQ_HANDLED; + } + ++static void setup_reply_map_v3_hw(struct hisi_hba *hisi_hba, int nvecs) ++{ ++ const struct cpumask *mask; ++ int queue, cpu; ++ ++ for (queue = 0; queue < nvecs; queue++) { ++ struct hisi_sas_cq *cq = &hisi_hba->cq[queue]; ++ ++ mask = pci_irq_get_affinity(hisi_hba->pci_dev, queue + ++ HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW); ++ if (!mask) ++ goto fallback; ++ cq->pci_irq_mask = mask; ++ for_each_cpu(cpu, mask) ++ hisi_hba->reply_map[cpu] = queue; ++ } ++ return; ++ ++fallback: ++ for_each_possible_cpu(cpu) ++ hisi_hba->reply_map[cpu] = cpu % hisi_hba->queue_count; ++ /* Don't clean all CQ masks */ ++} ++ + static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; + struct pci_dev *pdev = hisi_hba->pci_dev; + int vectors, rc; + int i, k; +- int max_msi = HISI_SAS_MSI_COUNT_V3_HW; + int max_dq_num, online_numa_num; +- struct irq_affinity desc = { +- .pre_vectors = HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW, +- }; ++ int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi; + +- if (user_ctl_irq) { +- vectors = pci_alloc_irq_vectors(hisi_hba->pci_dev, 1, +- max_msi, PCI_IRQ_MSI); +- } else { +- vectors = pci_alloc_irq_vectors_affinity(hisi_hba->pci_dev, +- HISI_SAS_MIN_VECTORS_V3_HW, +- max_msi, +- PCI_IRQ_MSI | +- PCI_IRQ_AFFINITY, +- &desc); +- } ++ if (auto_affine_msi_experimental) { ++ struct irq_affinity desc = { ++ .pre_vectors = HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW, ++ }; + +- if (vectors < HISI_SAS_MIN_VECTORS_V3_HW) { +- dev_err(dev, "allocate msi (%d) not enough\n", vectors); +- return -ENOENT; ++ min_msi = HISI_SAS_MIN_VECTORS_V3_HW; ++ ++ hisi_hba->reply_map = devm_kcalloc(dev, nr_cpu_ids, ++ sizeof(unsigned int), ++ GFP_KERNEL); ++ if (!hisi_hba->reply_map) ++ return -ENOMEM; ++ vectors = pci_alloc_irq_vectors_affinity(hisi_hba->pci_dev, ++ min_msi, max_msi, ++ PCI_IRQ_MSI | ++ PCI_IRQ_AFFINITY, ++ &desc); ++ if (vectors < 0) ++ return -ENOENT; ++ setup_reply_map_v3_hw(hisi_hba, ++ vectors - HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW); ++ } else { ++ min_msi = max_msi; ++ vectors = pci_alloc_irq_vectors(hisi_hba->pci_dev, min_msi, ++ max_msi, PCI_IRQ_MSI); ++ if (vectors < 0) ++ return vectors; + } + + hisi_hba->nvecs = vectors - HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW; +-- +2.27.0 + diff --git a/patches/0653-scsi-hisi_sas-Some-misc-tidy-up.patch b/patches/0653-scsi-hisi_sas-Some-misc-tidy-up.patch new file mode 100644 index 0000000..32db754 --- /dev/null +++ b/patches/0653-scsi-hisi_sas-Some-misc-tidy-up.patch @@ -0,0 +1,315 @@ +From 3575b0415a53cfa189121b8feeefe8da388d83b8 Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Thu, 11 Apr 2019 20:46:44 +0800 +Subject: [PATCH 005/108] scsi: hisi_sas: Some misc tidy-up + +mainline inclusion +from mainline-v5.2-rc1 +commit 01d4e3a2fc07b269eedeefa1f7c5c7090c442900 +category: cleanup +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=01d4e3a2fc07b269eedeefa1f7c5c7090c442900 + +---------------------------------------------------------------------- + +Do some minor tidy-up. + +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 9 ++---- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 9 ++---- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 42 +++++++++++--------------- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 29 ++++++++---------- + 4 files changed, 37 insertions(+), 52 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 7ccdaaba311c..b280cc109efb 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2600,22 +2600,19 @@ int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba) + + if (device_property_read_u32(dev, "ctrl-reset-reg", + &hisi_hba->ctrl_reset_reg)) { +- dev_err(dev, +- "could not get property ctrl-reset-reg\n"); ++ dev_err(dev, "could not get property ctrl-reset-reg\n"); + return -ENOENT; + } + + if (device_property_read_u32(dev, "ctrl-reset-sts-reg", + &hisi_hba->ctrl_reset_sts_reg)) { +- dev_err(dev, +- "could not get property ctrl-reset-sts-reg\n"); ++ dev_err(dev, "could not get property ctrl-reset-sts-reg\n"); + return -ENOENT; + } + + if (device_property_read_u32(dev, "ctrl-clock-ena-reg", + &hisi_hba->ctrl_clock_ena_reg)) { +- dev_err(dev, +- "could not get property ctrl-clock-ena-reg\n"); ++ dev_err(dev, "could not get property ctrl-clock-ena-reg\n"); + return -ENOENT; + } + } +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index 6485e2b6456c..1c51cbd94925 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1662,8 +1662,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) + for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { + irq = platform_get_irq(pdev, idx); + if (!irq) { +- dev_err(dev, +- "irq init: fail map phy interrupt %d\n", ++ dev_err(dev, "irq init: fail map phy interrupt %d\n", + idx); + return -ENOENT; + } +@@ -1671,8 +1670,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) + rc = devm_request_irq(dev, irq, phy_interrupts[j], 0, + DRV_NAME " phy", phy); + if (rc) { +- dev_err(dev, "irq init: could not request " +- "phy interrupt %d, rc=%d\n", ++ dev_err(dev, "irq init: could not request phy interrupt %d, rc=%d\n", + irq, rc); + return -ENOENT; + } +@@ -1709,8 +1707,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) + rc = devm_request_irq(dev, irq, fatal_interrupts[i], 0, + DRV_NAME " fatal", hisi_hba); + if (rc) { +- dev_err(dev, +- "irq init: could not request fatal interrupt %d, rc=%d\n", ++ dev_err(dev, "irq init: could not request fatal interrupt %d, rc=%d\n", + irq, rc); + return -ENOENT; + } +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index 1b701ec807e8..72fb4fa69668 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -2413,14 +2413,12 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + slot_err_v2_hw(hisi_hba, task, slot, 2); + + if (ts->stat != SAS_DATA_UNDERRUN) +- dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d " +- "CQ hdr: 0x%x 0x%x 0x%x 0x%x " +- "Error info: 0x%x 0x%x 0x%x 0x%x\n", +- slot->idx, task, sas_dev->device_id, +- dw0, complete_hdr->dw1, +- complete_hdr->act, complete_hdr->dw3, +- error_info[0], error_info[1], +- error_info[2], error_info[3]); ++ dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", ++ slot->idx, task, sas_dev->device_id, ++ dw0, complete_hdr->dw1, ++ complete_hdr->act, complete_hdr->dw3, ++ error_info[0], error_info[1], ++ error_info[2], error_info[3]); + + if (unlikely(slot->abort)) { + sas_task_abort(task); +@@ -2495,7 +2493,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + spin_lock_irqsave(&device->done_lock, flags); + if (test_bit(SAS_HA_FROZEN, &ha->state)) { + spin_unlock_irqrestore(&device->done_lock, flags); +- dev_info(dev, "slot complete: task(%pK) ignored\n ", ++ dev_info(dev, "slot complete: task(%pK) ignored\n", + task); + return sts; + } +@@ -2936,7 +2934,7 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p) + + if (irq_value2 & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) { + dev_warn(dev, "phy%d identify timeout\n", +- phy_no); ++ phy_no); + hisi_sas_notify_phy_event(phy, + HISI_PHYE_LINK_RESET); + } +@@ -3039,7 +3037,7 @@ static const struct hisi_sas_hw_error axi_error[] = { + { .msk = BIT(5), .msg = "SATA_AXI_R_ERR" }, + { .msk = BIT(6), .msg = "DQE_AXI_R_ERR" }, + { .msk = BIT(7), .msg = "CQE_AXI_W_ERR" }, +- {}, ++ {} + }; + + static const struct hisi_sas_hw_error fifo_error[] = { +@@ -3048,7 +3046,7 @@ static const struct hisi_sas_hw_error fifo_error[] = { + { .msk = BIT(10), .msg = "GETDQE_FIFO" }, + { .msk = BIT(11), .msg = "CMDP_FIFO" }, + { .msk = BIT(12), .msg = "AWTCTRL_FIFO" }, +- {}, ++ {} + }; + + static const struct hisi_sas_hw_error fatal_axi_errors[] = { +@@ -3112,12 +3110,12 @@ static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p) + if (!(err_value & sub->msk)) + continue; + dev_err(dev, "%s (0x%x) found!\n", +- sub->msg, irq_value); ++ sub->msg, irq_value); + queue_work(hisi_hba->wq, &hisi_hba->rst_work); + } + } else { + dev_err(dev, "%s (0x%x) found!\n", +- axi_error->msg, irq_value); ++ axi_error->msg, irq_value); + queue_work(hisi_hba->wq, &hisi_hba->rst_work); + } + } +@@ -3255,7 +3253,7 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p) + /* check ERR bit of Status Register */ + if (fis->status & ATA_ERR) { + dev_warn(dev, "sata int: phy%d FIS status: 0x%x\n", phy_no, +- fis->status); ++ fis->status); + hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); + res = IRQ_NONE; + goto end; +@@ -3346,8 +3344,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) + rc = devm_request_irq(dev, irq, phy_interrupts[i], 0, + DRV_NAME " phy", hisi_hba); + if (rc) { +- dev_err(dev, "irq init: could not request " +- "phy interrupt %d, rc=%d\n", ++ dev_err(dev, "irq init: could not request phy interrupt %d, rc=%d\n", + irq, rc); + rc = -ENOENT; + goto free_phy_int_irqs; +@@ -3361,8 +3358,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) + rc = devm_request_irq(dev, irq, sata_int_v2_hw, 0, + DRV_NAME " sata", phy); + if (rc) { +- dev_err(dev, "irq init: could not request " +- "sata interrupt %d, rc=%d\n", ++ dev_err(dev, "irq init: could not request sata interrupt %d, rc=%d\n", + irq, rc); + rc = -ENOENT; + goto free_sata_int_irqs; +@@ -3374,8 +3370,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) + rc = devm_request_irq(dev, irq, fatal_interrupts[fatal_no], 0, + DRV_NAME " fatal", hisi_hba); + if (rc) { +- dev_err(dev, +- "irq init: could not request fatal interrupt %d, rc=%d\n", ++ dev_err(dev, "irq init: could not request fatal interrupt %d, rc=%d\n", + irq, rc); + rc = -ENOENT; + goto free_fatal_int_irqs; +@@ -3390,8 +3385,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) + rc = devm_request_irq(dev, irq, cq_interrupt_v2_hw, 0, + DRV_NAME " cq", cq); + if (rc) { +- dev_err(dev, +- "irq init: could not request cq interrupt %d, rc=%d\n", ++ dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", + irq, rc); + rc = -ENOENT; + goto free_cq_int_irqs; +@@ -3543,7 +3537,7 @@ static int write_gpio_v2_hw(struct hisi_hba *hisi_hba, u8 reg_type, + break; + default: + dev_err(dev, "write gpio: unsupported or bad reg type %d\n", +- reg_type); ++ reg_type); + return -EINVAL; + } + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 4635c3b161db..1285d61b29b4 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2088,7 +2088,7 @@ static const struct hisi_sas_hw_error axi_error[] = { + { .msk = BIT(5), .msg = "SATA_AXI_R_ERR" }, + { .msk = BIT(6), .msg = "DQE_AXI_R_ERR" }, + { .msk = BIT(7), .msg = "CQE_AXI_W_ERR" }, +- {}, ++ {} + }; + + static const struct hisi_sas_hw_error fifo_error[] = { +@@ -2097,7 +2097,7 @@ static const struct hisi_sas_hw_error fifo_error[] = { + { .msk = BIT(10), .msg = "GETDQE_FIFO" }, + { .msk = BIT(11), .msg = "CMDP_FIFO" }, + { .msk = BIT(12), .msg = "AWTCTRL_FIFO" }, +- {}, ++ {} + }; + + static const struct hisi_sas_hw_error fatal_axi_error[] = { +@@ -2453,15 +2453,13 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + + set_aborted_iptt(hisi_hba, slot); + slot_err_v3_hw(hisi_hba, task, slot); +- dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d sas_addr=0x%llx " +- "CQ hdr: 0x%x 0x%x 0x%x 0x%x " +- "Error info: 0x%x 0x%x 0x%x 0x%x\n", +- slot->idx, task, sas_dev->device_id, +- itct->sas_addr, +- dw0, dw1, +- complete_hdr->act, dw3, +- error_info[0], error_info[1], +- error_info[2], error_info[3]); ++ dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d sas_addr=0x%llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", ++ slot->idx, task, sas_dev->device_id, ++ itct->sas_addr, ++ dw0, dw1, ++ complete_hdr->act, dw3, ++ error_info[0], error_info[1], ++ error_info[2], error_info[3]); + + if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) && + (task->task_proto & SAS_PROTOCOL_SATA || +@@ -2793,8 +2791,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + cq_interrupt_v3_hw, irqflags, + DRV_NAME " cq", cq); + if (rc) { +- dev_err(dev, +- "could not request cq%d interrupt, rc=%d\n", ++ dev_err(dev, "could not request cq%d interrupt, rc=%d\n", + i, rc); + rc = -ENOENT; + goto free_cq_irqs; +@@ -2990,7 +2987,7 @@ static int write_gpio_v3_hw(struct hisi_hba *hisi_hba, u8 reg_type, + break; + default: + dev_err(dev, "write gpio: unsupported or bad reg type %d\n", +- reg_type); ++ reg_type); + return -EINVAL; + } + +@@ -3558,7 +3555,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + hisi_hba->regs = pcim_iomap(pdev, HISI_SAS_BAR_TO_IOMAP, 0); + if (!hisi_hba->regs) { +- dev_err(dev, "cannot map register.\n"); ++ dev_err(dev, "cannot map register\n"); + rc = -ENOMEM; + goto err_out_ha; + } +@@ -3775,7 +3772,7 @@ static int hisi_sas_v3_resume(struct pci_dev *pdev) + u32 device_state = pdev->current_state; + + dev_warn(dev, "resuming from operating state [D%d]\n", +- device_state); ++ device_state); + pci_set_power_state(pdev, PCI_D0); + pci_enable_wake(pdev, PCI_D0, 0); + pci_restore_state(pdev); +-- +2.27.0 + diff --git a/patches/0654-scsi-hisi_sas-Make-max-IPTT-count-equal-for-all-hw-r.patch b/patches/0654-scsi-hisi_sas-Make-max-IPTT-count-equal-for-all-hw-r.patch new file mode 100644 index 0000000..86cd136 --- /dev/null +++ b/patches/0654-scsi-hisi_sas-Make-max-IPTT-count-equal-for-all-hw-r.patch @@ -0,0 +1,222 @@ +From 41a669b572098e569f76c4bffcabee63413f31a0 Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Mon, 5 Aug 2019 21:47:58 +0800 +Subject: [PATCH 006/108] scsi: hisi_sas: Make max IPTT count equal for all hw + revisions + +mainline inclusion +from mainline-v5.4-rc1 +commit 93352abc81a90314bf032038200ce96989a32c62 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=93352abc81a90314bf032038200ce96989a32c62 + +---------------------------------------------------------------------- + +There is a small optimisation to be had by making the max IPTT the same for +all hw revisions, that being we can drop the check for read and write +pointer being the same in the get free slot function. + +Change v1 hw to have max IPTT of 4096 - same as v2 and v3 hw - and +drop hisi_sas_hw.max_command_entries. + +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h + drivers/scsi/hisi_sas/hisi_sas_main.c + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 6 ++++-- + drivers/scsi/hisi_sas/hisi_sas_main.c | 30 +++++++++++--------------- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 3 --- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 1 - + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 7 ++---- + 5 files changed, 19 insertions(+), 28 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 06a8bf9f0f73..94aeb3bb6329 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -37,7 +37,10 @@ + #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES + #define HISI_SAS_RESET_BIT 0 + #define HISI_SAS_REJECT_CMD_BIT 1 +-#define HISI_SAS_RESERVED_IPTT_CNT 96 ++#define HISI_SAS_MAX_COMMANDS (HISI_SAS_QUEUE_SLOTS) ++#define HISI_SAS_RESERVED_IPTT 96 ++#define HISI_SAS_UNRESERVED_IPTT \ ++ (HISI_SAS_MAX_COMMANDS - HISI_SAS_RESERVED_IPTT) + + #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer)) + #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table)) +@@ -337,7 +340,6 @@ struct hisi_sas_hw { + const struct cpumask *(*get_managed_irq_aff)(struct hisi_hba + *hisi_hba, int queue); + void (*debugfs_work_handler)(struct work_struct *work); +- int max_command_entries; + int complete_hdr_size; + struct scsi_host_template *sht; + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index b280cc109efb..7784b6c1b1d8 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -174,8 +174,8 @@ static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx) + { + unsigned long flags; + +- if (hisi_hba->hw->slot_index_alloc || (slot_idx >= +- hisi_hba->hw->max_command_entries - HISI_SAS_RESERVED_IPTT_CNT)) { ++ if (hisi_hba->hw->slot_index_alloc || ++ slot_idx >= HISI_SAS_UNRESERVED_IPTT) { + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_slot_index_clear(hisi_hba, slot_idx); + spin_unlock_irqrestore(&hisi_hba->lock, flags); +@@ -206,8 +206,7 @@ static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, + if (index >= hisi_hba->slot_index_count) { + index = find_next_zero_bit(bitmap, + hisi_hba->slot_index_count, +- hisi_hba->hw->max_command_entries - +- HISI_SAS_RESERVED_IPTT_CNT); ++ HISI_SAS_UNRESERVED_IPTT); + if (index >= hisi_hba->slot_index_count) { + spin_unlock_irqrestore(&hisi_hba->lock, flags); + return -SAS_QUEUE_FULL; +@@ -2356,7 +2355,7 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { + + void hisi_sas_init_mem(struct hisi_hba *hisi_hba) + { +- int i, s, max_command_entries = hisi_hba->hw->max_command_entries; ++ int i, s, max_command_entries = HISI_SAS_MAX_COMMANDS; + + for (i = 0; i < hisi_hba->queue_count; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; +@@ -2388,7 +2387,7 @@ EXPORT_SYMBOL_GPL(hisi_sas_init_mem); + int hisi_sas_alloc(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; +- int i, j, s, max_command_entries = hisi_hba->hw->max_command_entries; ++ int i, j, s, max_command_entries = HISI_SAS_MAX_COMMANDS; + int max_command_entries_ru, sz_slot_buf_ru; + int blk_cnt, slots_per_blk; + +@@ -2523,8 +2522,7 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba) + goto err_out; + + hisi_sas_slot_index_init(hisi_hba); +- hisi_hba->last_slot_index = hisi_hba->hw->max_command_entries - +- HISI_SAS_RESERVED_IPTT_CNT; ++ hisi_hba->last_slot_index = HISI_SAS_UNRESERVED_IPTT; + + hisi_hba->wq = create_singlethread_workqueue(dev_name(dev)); + if (!hisi_hba->wq) { +@@ -2738,13 +2736,11 @@ int hisi_sas_probe(struct platform_device *pdev, + /* shost support 16 bytes cmd len base on hw */ + shost->max_cmd_len = 16; + if (hisi_hba->hw->slot_index_alloc) { +- shost->can_queue = hisi_hba->hw->max_command_entries; +- shost->cmd_per_lun = hisi_hba->hw->max_command_entries; ++ shost->can_queue = HISI_SAS_MAX_COMMANDS; ++ shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS; + } else { +- shost->can_queue = hisi_hba->hw->max_command_entries - +- HISI_SAS_RESERVED_IPTT_CNT; +- shost->cmd_per_lun = hisi_hba->hw->max_command_entries - +- HISI_SAS_RESERVED_IPTT_CNT; ++ shost->can_queue = HISI_SAS_UNRESERVED_IPTT; ++ shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; + } + + sha->sas_ha_name = DRV_NAME; +@@ -2853,7 +2849,7 @@ static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba) + { +- int max_command_entries = hisi_hba->hw->max_command_entries; ++ int max_command_entries = HISI_SAS_MAX_COMMANDS; + void *databuf = hisi_hba->debugfs_iost; + struct hisi_sas_iost *iost; + int i; +@@ -3452,7 +3448,7 @@ static int hisi_sas_debugfs_iost_show(struct seq_file *s, void *p) + { + struct hisi_hba *hisi_hba = s->private; + struct hisi_sas_iost *debugfs_iost = hisi_hba->debugfs_iost; +- int i, ret, max_command_entries = hisi_hba->hw->max_command_entries; ++ int i, ret, max_command_entries = HISI_SAS_MAX_COMMANDS; + __le64 *iost = &debugfs_iost->qw0; + + for (i = 0; i < max_command_entries; i++, debugfs_iost++) { +@@ -3633,7 +3629,7 @@ EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler); + + void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + { +- int max_command_entries = hisi_hba->hw->max_command_entries; ++ int max_command_entries = HISI_SAS_MAX_COMMANDS; + struct device *dev = hisi_hba->dev; + int p, i, c, d; + size_t sz; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index 1c51cbd94925..1e03e673ceb5 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -406,8 +406,6 @@ enum { + TRANS_RX_SMP_RESP_TIMEOUT_ERR, /* 0x31a */ + }; + +-#define HISI_SAS_COMMAND_ENTRIES_V1_HW 4096 +- + #define HISI_SAS_PHY_MAX_INT_NR (HISI_SAS_PHY_INT_NR * HISI_SAS_MAX_PHYS) + #define HISI_SAS_CQ_MAX_INT_NR (HISI_SAS_MAX_QUEUES) + #define HISI_SAS_FATAL_INT_NR (2) +@@ -1806,7 +1804,6 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = { + .phy_set_linkrate = phy_set_linkrate_v1_hw, + .phy_get_max_linkrate = phy_get_max_linkrate_v1_hw, + .get_wideport_bitmap = get_wideport_bitmap_v1_hw, +- .max_command_entries = HISI_SAS_COMMAND_ENTRIES_V1_HW, + .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr), + .sht = &sht_v1_hw, + }; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index 72fb4fa69668..ff197bc06453 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3617,7 +3617,6 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = { + .get_events = phy_get_events_v2_hw, + .phy_set_linkrate = phy_set_linkrate_v2_hw, + .phy_get_max_linkrate = phy_get_max_linkrate_v2_hw, +- .max_command_entries = HISI_SAS_COMMAND_ENTRIES_V2_HW, + .complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr), + .soft_reset = soft_reset_v2_hw, + .get_phys_state = get_phys_state_v2_hw, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 1285d61b29b4..12fc3b370265 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3434,7 +3434,6 @@ static struct scsi_host_template sht_v3_hw = { + static const struct hisi_sas_hw hisi_sas_v3_hw = { + .hw_init = hisi_sas_v3_init, + .setup_itct = setup_itct_v3_hw, +- .max_command_entries = HISI_SAS_COMMAND_ENTRIES_V3_HW, + .get_wideport_bitmap = get_wideport_bitmap_v3_hw, + .complete_hdr_size = sizeof(struct hisi_sas_complete_v3_hdr), + .clear_itct = clear_itct_v3_hw, +@@ -3581,10 +3580,8 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + shost->max_channel = 1; + /* shost support 16 bytes cmd len base on hw */ + shost->max_cmd_len = 16; +- shost->can_queue = hisi_hba->hw->max_command_entries - +- HISI_SAS_RESERVED_IPTT_CNT; +- shost->cmd_per_lun = hisi_hba->hw->max_command_entries - +- HISI_SAS_RESERVED_IPTT_CNT; ++ shost->can_queue = HISI_SAS_UNRESERVED_IPTT; ++ shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; + + sha->sas_ha_name = DRV_NAME; + sha->dev = dev; +-- +2.27.0 + diff --git a/patches/0655-scsi-hisi_sas-Fix-pointer-usage-error-in-show-debugf.patch b/patches/0655-scsi-hisi_sas-Fix-pointer-usage-error-in-show-debugf.patch new file mode 100644 index 0000000..8576661 --- /dev/null +++ b/patches/0655-scsi-hisi_sas-Fix-pointer-usage-error-in-show-debugf.patch @@ -0,0 +1,58 @@ +From 86c4ef20704b03b85de06dfaaa982c5a182b3ebd Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Mon, 5 Aug 2019 21:48:00 +0800 +Subject: [PATCH 007/108] scsi: hisi_sas: Fix pointer usage error in show + debugfs IOST/ITCT + +mainline inclusion +from mainline-v5.4-rc1 +commit bee0cf25c030776a8ecfc3c951d3b73259dc6839 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bee0cf25c030776a8ecfc3c951d3b73259dc6839 + +---------------------------------------------------------------------- + +Fix how the pointer is set in hisi_sas_debugfs_iost_show() and +hisi_sas_debugfs_itct_show(). + +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 7784b6c1b1d8..8733e34b624d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -3449,9 +3449,10 @@ static int hisi_sas_debugfs_iost_show(struct seq_file *s, void *p) + struct hisi_hba *hisi_hba = s->private; + struct hisi_sas_iost *debugfs_iost = hisi_hba->debugfs_iost; + int i, ret, max_command_entries = HISI_SAS_MAX_COMMANDS; +- __le64 *iost = &debugfs_iost->qw0; + + for (i = 0; i < max_command_entries; i++, debugfs_iost++) { ++ __le64 *iost = &debugfs_iost->qw0; ++ + ret = hisi_sas_show_row_64(s, i, sizeof(*debugfs_iost), + iost); + if (ret) +@@ -3481,8 +3482,10 @@ static int hisi_sas_debugfs_itct_show(struct seq_file *s, void *p) + struct hisi_sas_itct *debugfs_itct = hisi_hba->debugfs_itct; + + for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, debugfs_itct++) { ++ __le64 *itct = &debugfs_itct->qw0; ++ + ret = hisi_sas_show_row_64(s, i, sizeof(*debugfs_itct), +- (u64 *)debugfs_itct); ++ itct); + if (ret) + return ret; + } +-- +2.27.0 + diff --git a/patches/0656-scsi-hisi_sas-Snapshot-HW-cache-of-IOST-and-ITCT-at-.patch b/patches/0656-scsi-hisi_sas-Snapshot-HW-cache-of-IOST-and-ITCT-at-.patch new file mode 100644 index 0000000..903fdb5 --- /dev/null +++ b/patches/0656-scsi-hisi_sas-Snapshot-HW-cache-of-IOST-and-ITCT-at-.patch @@ -0,0 +1,335 @@ +From 846a6ad62232595239572185fdc141894504b6d3 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Mon, 5 Aug 2019 21:48:01 +0800 +Subject: [PATCH 008/108] scsi: hisi_sas: Snapshot HW cache of IOST and ITCT at + debugfs + +mainline inclusion +from mainline-v5.4-rc1 +commit bbe0a7b348b336625292092c74fc7817aeb8d30b +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F808 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bbe0a7b348b336625292092c74fc7817aeb8d30b + +---------------------------------------------------------------------- + +The value of IOST/ITCT is updated to cache first, and then synchronize to +DDR periodically. So the value in IOST/ITCT cache is the latest data and +it's important for debugging. + +So, the HW cache of IOST and ITCT should be snapshot at debugfs. + +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 16 ++++ + drivers/scsi/hisi_sas/hisi_sas_main.c | 114 ++++++++++++++++++++++++- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 32 +++++++ + 3 files changed, 160 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 94aeb3bb6329..bc2b6995dca1 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -42,6 +42,9 @@ + #define HISI_SAS_UNRESERVED_IPTT \ + (HISI_SAS_MAX_COMMANDS - HISI_SAS_RESERVED_IPTT) + ++#define HISI_SAS_IOST_ITCT_CACHE_NUM 64 ++#define HISI_SAS_IOST_ITCT_CACHE_DW_SZ 10 ++ + #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer)) + #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table)) + +@@ -293,6 +296,14 @@ enum { + HISI_SAS_BIST_CODE_MODE_FIXED_DATA, + }; + ++struct hisi_sas_iost_itct_cache { ++ u32 data[HISI_SAS_IOST_ITCT_CACHE_DW_SZ]; ++}; ++ ++enum hisi_sas_debugfs_cache_type { ++ HISI_SAS_ITCT_CACHE, ++ HISI_SAS_IOST_CACHE, ++}; + + struct hisi_sas_hw { + int (*hw_init)(struct hisi_hba *hisi_hba); +@@ -340,6 +351,9 @@ struct hisi_sas_hw { + const struct cpumask *(*get_managed_irq_aff)(struct hisi_hba + *hisi_hba, int queue); + void (*debugfs_work_handler)(struct work_struct *work); ++ void (*read_iost_itct_cache)(struct hisi_hba *hisi_hba, ++ enum hisi_sas_debugfs_cache_type type, ++ u32 *cache); + int complete_hdr_size; + struct scsi_host_template *sht; + +@@ -432,6 +446,8 @@ struct hisi_hba { + struct hisi_sas_cmd_hdr *debugfs_cmd_hdr[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_iost *debugfs_iost; + struct hisi_sas_itct *debugfs_itct; ++ u64 *debugfs_iost_cache; ++ u64 *debugfs_itct_cache; + + struct dentry *debugfs_dir; + struct dentry *debugfs_dump_dentry; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 8733e34b624d..2d2373b11b20 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2835,10 +2835,14 @@ static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + { ++ void *cachebuf = hisi_hba->debugfs_itct_cache; + void *databuf = hisi_hba->debugfs_itct; + struct hisi_sas_itct *itct; + int i; + ++ hisi_hba->hw->read_iost_itct_cache(hisi_hba, HISI_SAS_ITCT_CACHE, ++ cachebuf); ++ + itct = hisi_hba->itct; + + for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) { +@@ -2850,10 +2854,14 @@ static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba) + { + int max_command_entries = HISI_SAS_MAX_COMMANDS; ++ void *cachebuf = hisi_hba->debugfs_iost_cache; + void *databuf = hisi_hba->debugfs_iost; + struct hisi_sas_iost *iost; + int i; + ++ hisi_hba->hw->read_iost_itct_cache(hisi_hba, HISI_SAS_IOST_CACHE, ++ cachebuf); ++ + iost = hisi_hba->iost; + + for (i = 0; i < max_command_entries; i++, iost++) { +@@ -3475,6 +3483,46 @@ static const struct file_operations hisi_sas_debugfs_iost_fops = { + .owner = THIS_MODULE, + }; + ++static int hisi_sas_debugfs_iost_cache_show(struct seq_file *s, void *p) ++{ ++ struct hisi_hba *hisi_hba = s->private; ++ struct hisi_sas_iost_itct_cache *iost_cache = ++ (struct hisi_sas_iost_itct_cache *)hisi_hba->debugfs_iost_cache; ++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; ++ int i, tab_idx; ++ __le64 *iost; ++ ++ for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) { ++ /* ++ * Data struct of IOST cache: ++ * Data[1]: BIT0~15: Table index ++ * Bit16: Valid mask ++ * Data[2]~[9]: IOST table ++ */ ++ tab_idx = (iost_cache->data[1] & 0xffff); ++ iost = (__le64 *)iost_cache; ++ ++ hisi_sas_show_row_64(s, tab_idx, cache_size, iost); ++ } ++ ++ return 0; ++} ++ ++static int hisi_sas_debugfs_iost_cache_open(struct inode *inode, ++ struct file *filp) ++{ ++ return single_open(filp, hisi_sas_debugfs_iost_cache_show, ++ inode->i_private); ++} ++ ++static const struct file_operations hisi_sas_debugfs_iost_cache_fops = { ++ .open = hisi_sas_debugfs_iost_cache_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ + static int hisi_sas_debugfs_itct_show(struct seq_file *s, void *p) + { + int i, ret; +@@ -3506,6 +3554,46 @@ static const struct file_operations hisi_sas_debugfs_itct_fops = { + .owner = THIS_MODULE, + }; + ++static int hisi_sas_debugfs_itct_cache_show(struct seq_file *s, void *p) ++{ ++ struct hisi_hba *hisi_hba = s->private; ++ struct hisi_sas_iost_itct_cache *itct_cache = ++ (struct hisi_sas_iost_itct_cache *)hisi_hba->debugfs_itct_cache; ++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; ++ int i, tab_idx; ++ __le64 *itct; ++ ++ for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) { ++ /* ++ * Data struct of ITCT cache: ++ * Data[1]: BIT0~15: Table index ++ * Bit16: Valid mask ++ * Data[2]~[9]: ITCT table ++ */ ++ tab_idx = itct_cache->data[1] & 0xffff; ++ itct = (__le64 *)itct_cache; ++ ++ hisi_sas_show_row_64(s, tab_idx, cache_size, itct); ++ } ++ ++ return 0; ++} ++ ++static int hisi_sas_debugfs_itct_cache_open(struct inode *inode, ++ struct file *filp) ++{ ++ return single_open(filp, hisi_sas_debugfs_itct_cache_show, ++ inode->i_private); ++} ++ ++static const struct file_operations hisi_sas_debugfs_itct_cache_fops = { ++ .open = hisi_sas_debugfs_itct_cache_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ + static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + { + struct dentry *dump_dentry; +@@ -3558,9 +3646,15 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + debugfs_create_file("iost", 0400, dump_dentry, hisi_hba, + &hisi_sas_debugfs_iost_fops); + ++ debugfs_create_file("iost_cache", 0400, dump_dentry, hisi_hba, ++ &hisi_sas_debugfs_iost_cache_fops); ++ + debugfs_create_file("itct", 0400, dump_dentry, hisi_hba, + &hisi_sas_debugfs_itct_fops); + ++ debugfs_create_file("itct_cache", 0400, dump_dentry, hisi_hba, ++ &hisi_sas_debugfs_itct_cache_fops); ++ + return; + } + +@@ -3715,14 +3809,26 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + goto fail_iost_dq; + } + +- /* Alloc buffer for iost */ + sz = max_command_entries * sizeof(struct hisi_sas_iost); + + hisi_hba->debugfs_iost = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->debugfs_iost) + goto fail_iost_dq; + +- /* Alloc buffer for itct */ ++ sz = HISI_SAS_IOST_ITCT_CACHE_NUM * ++ sizeof(struct hisi_sas_iost_itct_cache); ++ ++ hisi_hba->debugfs_iost_cache = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_iost_cache) ++ goto fail_iost_cache; ++ ++ sz = HISI_SAS_IOST_ITCT_CACHE_NUM * ++ sizeof(struct hisi_sas_iost_itct_cache); ++ ++ hisi_hba->debugfs_itct_cache = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_itct_cache) ++ goto fail_itct_cache; ++ + /* New memory allocation must be locate before itct */ + sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); + +@@ -3732,6 +3838,10 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + + return; + fail_itct: ++ devm_kfree(dev, hisi_hba->debugfs_iost_cache); ++fail_itct_cache: ++ devm_kfree(dev, hisi_hba->debugfs_iost_cache); ++fail_iost_cache: + devm_kfree(dev, hisi_hba->debugfs_iost); + fail_iost_dq: + for (i = 0; i < d; i++) +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 12fc3b370265..974a72d164c5 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -79,6 +79,7 @@ + #define HGC_DQE_ECC_MB_ADDR_OFF 16 + #define HGC_DQE_ECC_MB_ADDR_MSK (0xfff << HGC_DQE_ECC_MB_ADDR_OFF) + #define CHNL_INT_STATUS 0x148 ++#define TAB_DFX 0x14c + #define HGC_ITCT_ECC_ADDR 0x150 + #define HGC_ITCT_ECC_1B_ADDR_OFF 0 + #define HGC_ITCT_ECC_1B_ADDR_MSK (0x3ff << \ +@@ -91,6 +92,7 @@ + #define AXI_ERR_INFO_MSK (0xff << AXI_ERR_INFO_OFF) + #define FIFO_ERR_INFO_OFF 8 + #define FIFO_ERR_INFO_MSK (0xff << FIFO_ERR_INFO_OFF) ++#define TAB_RD_TYPE 0x15c + #define INT_COAL_EN 0x19c + #define OQ_INT_COAL_TIME 0x1a0 + #define OQ_INT_COAL_CNT 0x1a4 +@@ -3406,6 +3408,35 @@ struct device_attribute *host_attrs_v3_hw[] = { + NULL + }; + ++static void read_iost_itct_cache_v3_hw(struct hisi_hba *hisi_hba, ++ enum hisi_sas_debugfs_cache_type type, ++ u32 *cache) ++{ ++ u32 cache_dw_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * ++ HISI_SAS_IOST_ITCT_CACHE_NUM; ++ u32 *buf = cache; ++ u32 i, val; ++ ++ hisi_sas_write32(hisi_hba, TAB_RD_TYPE, type); ++ ++ for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_DW_SZ; i++) { ++ val = hisi_sas_read32(hisi_hba, TAB_DFX); ++ if (val == 0xffffffff) ++ break; ++ } ++ ++ if (val != 0xffffffff) { ++ pr_err("Issue occur when reading IOST/ITCT cache!\n"); ++ return; ++ } ++ ++ memset(buf, 0, cache_dw_size * 4); ++ buf[0] = val; ++ ++ for (i = 1; i < cache_dw_size; i++) ++ buf[i] = hisi_sas_read32(hisi_hba, TAB_DFX); ++} ++ + static struct scsi_host_template sht_v3_hw = { + .name = DRV_NAME, + .module = THIS_MODULE, +@@ -3463,6 +3494,7 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = { + .set_bist = debugfs_set_bist_v3_hw, + .get_managed_irq_aff = get_managed_irq_aff_v3_hw, + .debugfs_work_handler = hisi_sas_debugfs_work_handler, ++ .read_iost_itct_cache = read_iost_itct_cache_v3_hw, + }; + + static struct Scsi_Host * +-- +2.27.0 + diff --git a/patches/0657-scsi-hisi_sas-Snapshot-AXI-and-RAS-register-at-debug.patch b/patches/0657-scsi-hisi_sas-Snapshot-AXI-and-RAS-register-at-debug.patch new file mode 100644 index 0000000..c45f18d --- /dev/null +++ b/patches/0657-scsi-hisi_sas-Snapshot-AXI-and-RAS-register-at-debug.patch @@ -0,0 +1,345 @@ +From 0ca561926ef832d2acfef9a2dd906ff2f90105ee Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Mon, 5 Aug 2019 21:48:02 +0800 +Subject: [PATCH 009/108] scsi: hisi_sas: Snapshot AXI and RAS register at + debugfs + +mainline inclusion +from mainline-v5.4-rc1 +commit b0b3e4290e288bb633c4ff6331b2c0b9530aa9b8 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F808 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b0b3e4290e288bb633c4ff6331b2c0b9530aa9b8 + +---------------------------------------------------------------------- + +The AXI and RAS register values should also should be snapshot at debugfs. + +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 12 ++- + drivers/scsi/hisi_sas/hisi_sas_main.c | 132 ++++++++++++++++++++++--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 36 ++++++- + 3 files changed, 162 insertions(+), 18 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index bc2b6995dca1..de5752f07987 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -300,6 +300,13 @@ struct hisi_sas_iost_itct_cache { + u32 data[HISI_SAS_IOST_ITCT_CACHE_DW_SZ]; + }; + ++enum hisi_sas_debugfs_reg_array_member { ++ DEBUGFS_GLOBAL = 0, ++ DEBUGFS_AXI, ++ DEBUGFS_RAS, ++ DEBUGFS_REGS_NUM ++}; ++ + enum hisi_sas_debugfs_cache_type { + HISI_SAS_ITCT_CACHE, + HISI_SAS_IOST_CACHE, +@@ -357,7 +364,7 @@ struct hisi_sas_hw { + int complete_hdr_size; + struct scsi_host_template *sht; + +- const struct hisi_sas_debugfs_reg *debugfs_reg_global; ++ const struct hisi_sas_debugfs_reg *debugfs_reg_array[DEBUGFS_REGS_NUM]; + const struct hisi_sas_debugfs_reg *debugfs_reg_port; + int (*set_bist)(struct hisi_hba *hisi_hba, bool enable); + }; +@@ -440,7 +447,8 @@ struct hisi_hba { + unsigned int *reply_map; + + /* debugfs memories */ +- u32 *debugfs_global_reg; ++ /* Put Global AXI and RAS Register into register array */ ++ u32 *debugfs_regs[DEBUGFS_REGS_NUM]; + u32 *debugfs_port_reg[HISI_SAS_MAX_PHYS]; + void *debugfs_complete_hdr[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_cmd_hdr *debugfs_cmd_hdr[HISI_SAS_MAX_QUEUES]; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 2d2373b11b20..11c27ae7c0a2 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2824,15 +2824,42 @@ static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) + { +- u32 *databuf = (u32 *)hisi_hba->debugfs_global_reg; ++ u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_GLOBAL]; ++ const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *global = +- hisi_hba->hw->debugfs_reg_global; ++ hw->debugfs_reg_array[DEBUGFS_GLOBAL]; + int i; + + for (i = 0; i < global->count; i++, databuf++) + *databuf = global->read_global_reg(hisi_hba, 4 * i); + } + ++static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) ++{ ++ u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_AXI]; ++ const struct hisi_sas_hw *hw = hisi_hba->hw; ++ const struct hisi_sas_debugfs_reg *axi = ++ hw->debugfs_reg_array[DEBUGFS_AXI]; ++ int i; ++ ++ for (i = 0; i < axi->count; i++, databuf++) ++ *databuf = axi->read_global_reg(hisi_hba, ++ 4 * i + axi->base_off); ++} ++ ++static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) ++{ ++ u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_RAS]; ++ const struct hisi_sas_hw *hw = hisi_hba->hw; ++ const struct hisi_sas_debugfs_reg *ras = ++ hw->debugfs_reg_array[DEBUGFS_RAS]; ++ int i; ++ ++ for (i = 0; i < ras->count; i++, databuf++) ++ *databuf = ras->read_global_reg(hisi_hba, ++ 4 * i + ras->base_off); ++} ++ + static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + { + void *cachebuf = hisi_hba->debugfs_itct_cache; +@@ -2908,9 +2935,9 @@ static int hisi_sas_debugfs_global_show(struct seq_file *s, void *p) + { + struct hisi_hba *hisi_hba = s->private; + const struct hisi_sas_hw *hw = hisi_hba->hw; +- const struct hisi_sas_debugfs_reg *reg_global = hw->debugfs_reg_global; ++ const void *reg_global = hw->debugfs_reg_array[DEBUGFS_GLOBAL]; + +- hisi_sas_debugfs_print_reg(hisi_hba->debugfs_global_reg, ++ hisi_sas_debugfs_print_reg(hisi_hba->debugfs_regs[DEBUGFS_GLOBAL], + reg_global, s); + + return 0; +@@ -3312,6 +3339,58 @@ static const struct file_operations hisi_sas_debugfs_bist_enable_ops = { + .owner = THIS_MODULE, + }; + ++static int hisi_sas_debugfs_axi_show(struct seq_file *s, void *p) ++{ ++ struct hisi_hba *hisi_hba = s->private; ++ const struct hisi_sas_hw *hw = hisi_hba->hw; ++ const void *reg_axi = hw->debugfs_reg_array[DEBUGFS_AXI]; ++ ++ hisi_sas_debugfs_print_reg(hisi_hba->debugfs_regs[DEBUGFS_AXI], ++ reg_axi, s); ++ ++ return 0; ++} ++ ++static int hisi_sas_debugfs_axi_open(struct inode *inode, struct file *filp) ++{ ++ return single_open(filp, hisi_sas_debugfs_axi_show, ++ inode->i_private); ++} ++ ++static const struct file_operations hisi_sas_debugfs_axi_fops = { ++ .open = hisi_sas_debugfs_axi_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ ++static int hisi_sas_debugfs_ras_show(struct seq_file *s, void *p) ++{ ++ struct hisi_hba *hisi_hba = s->private; ++ const struct hisi_sas_hw *hw = hisi_hba->hw; ++ const void *reg_ras = hw->debugfs_reg_array[DEBUGFS_RAS]; ++ ++ hisi_sas_debugfs_print_reg(hisi_hba->debugfs_regs[DEBUGFS_RAS], ++ reg_ras, s); ++ ++ return 0; ++} ++ ++static int hisi_sas_debugfs_ras_open(struct inode *inode, struct file *filp) ++{ ++ return single_open(filp, hisi_sas_debugfs_ras_show, ++ inode->i_private); ++} ++ ++static const struct file_operations hisi_sas_debugfs_ras_fops = { ++ .open = hisi_sas_debugfs_ras_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ + + static int hisi_sas_debugfs_port_show(struct seq_file *s, void *p) + { +@@ -3655,6 +3734,12 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + debugfs_create_file("itct_cache", 0400, dump_dentry, hisi_hba, + &hisi_sas_debugfs_itct_cache_fops); + ++ debugfs_create_file("axi", 0400, dump_dentry, hisi_hba, ++ &hisi_sas_debugfs_axi_fops); ++ ++ debugfs_create_file("ras", 0400, dump_dentry, hisi_hba, ++ &hisi_sas_debugfs_ras_fops); ++ + return; + } + +@@ -3664,6 +3749,8 @@ static void hisi_sas_debugfs_snapshot_regs(struct hisi_hba *hisi_hba) + + hisi_sas_debugfs_snapshot_global_reg(hisi_hba); + hisi_sas_debugfs_snapshot_port_reg(hisi_hba); ++ hisi_sas_debugfs_snapshot_axi_reg(hisi_hba); ++ hisi_sas_debugfs_snapshot_ras_reg(hisi_hba); + hisi_sas_debugfs_snapshot_cq_reg(hisi_hba); + hisi_sas_debugfs_snapshot_dq_reg(hisi_hba); + hisi_sas_debugfs_snapshot_itct_reg(hisi_hba); +@@ -3727,6 +3814,7 @@ EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler); + void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + { + int max_command_entries = HISI_SAS_MAX_COMMANDS; ++ const struct hisi_sas_hw *hw = hisi_hba->hw; + struct device *dev = hisi_hba->dev; + int p, i, c, d; + size_t sz; +@@ -3771,16 +3859,14 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + hisi_hba, &hisi_sas_debugfs_bist_enable_ops)) + goto fail_global; + +- /* Alloc buffer for global */ +- sz = hisi_hba->hw->debugfs_reg_global->count * 4; +- hisi_hba->debugfs_global_reg = +- devm_kmalloc(dev, sz, GFP_KERNEL); ++ sz = hw->debugfs_reg_array[DEBUGFS_GLOBAL]->count * 4; ++ hisi_hba->debugfs_regs[DEBUGFS_GLOBAL] = ++ devm_kmalloc(dev, sz, GFP_KERNEL); + +- if (!hisi_hba->debugfs_global_reg) ++ if (!hisi_hba->debugfs_regs[DEBUGFS_GLOBAL]) + goto fail_global; + +- /* Alloc buffer for port */ +- sz = hisi_hba->hw->debugfs_reg_port->count * 4; ++ sz = hw->debugfs_reg_port->count * 4; + for (p = 0; p < hisi_hba->n_phy; p++) { + hisi_hba->debugfs_port_reg[p] = + devm_kmalloc(dev, sz, GFP_KERNEL); +@@ -3789,8 +3875,21 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + goto fail_port; + } + +- /* Alloc buffer for cq */ +- sz = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; ++ sz = hw->debugfs_reg_array[DEBUGFS_AXI]->count * 4; ++ hisi_hba->debugfs_regs[DEBUGFS_AXI] = ++ devm_kmalloc(dev, sz, GFP_KERNEL); ++ ++ if (!hisi_hba->debugfs_regs[DEBUGFS_AXI]) ++ goto fail_axi; ++ ++ sz = hw->debugfs_reg_array[DEBUGFS_RAS]->count * 4; ++ hisi_hba->debugfs_regs[DEBUGFS_RAS] = ++ devm_kmalloc(dev, sz, GFP_KERNEL); ++ ++ if (!hisi_hba->debugfs_regs[DEBUGFS_RAS]) ++ goto fail_ras; ++ ++ sz = hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + for (c = 0; c < hisi_hba->queue_count; c++) { + hisi_hba->debugfs_complete_hdr[c] = + devm_kmalloc(dev, sz, GFP_KERNEL); +@@ -3799,7 +3898,6 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + goto fail_cq; + } + +- /* Alloc buffer for dq */ + sz = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; + for (d = 0; d < hisi_hba->queue_count; d++) { + hisi_hba->debugfs_cmd_hdr[d] = +@@ -3849,10 +3947,14 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + fail_cq: + for (i = 0; i < c; i++) + devm_kfree(dev, hisi_hba->debugfs_complete_hdr[i]); ++ devm_kfree(dev, hisi_hba->debugfs_regs[DEBUGFS_RAS]); ++fail_ras: ++ devm_kfree(dev, hisi_hba->debugfs_regs[DEBUGFS_AXI]); ++fail_axi: + fail_port: + for (i = 0; i < p; i++) + devm_kfree(dev, hisi_hba->debugfs_port_reg[i]); +- devm_kfree(dev, hisi_hba->debugfs_global_reg); ++ devm_kfree(dev, hisi_hba->debugfs_regs[DEBUGFS_GLOBAL]); + fail_global: + hisi_sas_debugfs_exit(hisi_hba); + dev_info(dev, "failed to init debugfs!\n"); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 974a72d164c5..9500a02ae9c2 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3264,6 +3264,38 @@ static const struct hisi_sas_debugfs_reg debugfs_global_reg = { + .read_global_reg = hisi_sas_read32, + }; + ++static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = { ++ HISI_SAS_DEBUGFS_REG(AM_CFG_MAX_TRANS), ++ HISI_SAS_DEBUGFS_REG(AM_CFG_SINGLE_PORT_MAX_TRANS), ++ HISI_SAS_DEBUGFS_REG(AXI_CFG), ++ HISI_SAS_DEBUGFS_REG(AM_ROB_ECC_ERR_ADDR), ++ {} ++}; ++ ++static const struct hisi_sas_debugfs_reg debugfs_axi_reg = { ++ .lu = debugfs_axi_reg_lu, ++ .count = 0x61, ++ .base_off = AXI_MASTER_CFG_BASE, ++ .read_global_reg = hisi_sas_read32, ++}; ++ ++static const struct hisi_sas_debugfs_reg_lu debugfs_ras_reg_lu[] = { ++ HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR1), ++ HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR0_MASK), ++ HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR1_MASK), ++ HISI_SAS_DEBUGFS_REG(CFG_SAS_RAS_INTR_MASK), ++ HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR2), ++ HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR2_MASK), ++ {} ++}; ++ ++static const struct hisi_sas_debugfs_reg debugfs_ras_reg = { ++ .lu = debugfs_ras_reg_lu, ++ .count = 0x10, ++ .base_off = RAS_BASE, ++ .read_global_reg = hisi_sas_read32, ++}; ++ + static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; +@@ -3487,7 +3519,9 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = { + .get_events = phy_get_events_v3_hw, + .write_gpio = write_gpio_v3_hw, + .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw, +- .debugfs_reg_global = &debugfs_global_reg, ++ .debugfs_reg_array[DEBUGFS_GLOBAL] = &debugfs_global_reg, ++ .debugfs_reg_array[DEBUGFS_AXI] = &debugfs_axi_reg, ++ .debugfs_reg_array[DEBUGFS_RAS] = &debugfs_ras_reg, + .debugfs_reg_port = &debugfs_port_reg, + .snapshot_prepare = debugfs_snapshot_prepare_v3_hw, + .snapshot_restore = debugfs_snapshot_restore_v3_hw, +-- +2.27.0 + diff --git a/patches/0658-scsi-hisi_sas-Drop-kmap_atomic-in-SMP-command-comple.patch b/patches/0658-scsi-hisi_sas-Drop-kmap_atomic-in-SMP-command-comple.patch new file mode 100644 index 0000000..81be92e --- /dev/null +++ b/patches/0658-scsi-hisi_sas-Drop-kmap_atomic-in-SMP-command-comple.patch @@ -0,0 +1,105 @@ +From cbae06fc72a006cdf74016bed6e2f2179f4f2e8c Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Mon, 5 Aug 2019 21:48:06 +0800 +Subject: [PATCH 010/108] scsi: hisi_sas: Drop kmap_atomic() in SMP command + completion + +mainline inclusion +from mainline-v5.4-rc1 +commit 1c003146c64bb3ae86f1a08d73a7e4551d7cd04a +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1c003146c64bb3ae86f1a08d73a7e4551d7cd04a + +---------------------------------------------------------------------- + +The call to kmap_atomic() in the SMP command completion code is +unnecessary, since kmap() is only really concerned with highmem, which is +not relevant on arm64. The controller only finds itself in arm64 systems. + +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 +--- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 +--- + 3 files changed, 3 insertions(+), 9 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index 1e03e673ceb5..eebc774ba443 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1283,11 +1283,10 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, + } + case SAS_PROTOCOL_SMP: + { +- void *to; + struct scatterlist *sg_resp = &task->smp_task.smp_resp; ++ void *to = page_address(sg_page(sg_resp)); + + ts->stat = SAM_STAT_GOOD; +- to = kmap_atomic(sg_page(sg_resp)); + + dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, + DMA_FROM_DEVICE); +@@ -1297,7 +1296,6 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, + hisi_sas_status_buf_addr_mem(slot) + + sizeof(struct hisi_sas_err_record), + sg_dma_len(sg_resp)); +- kunmap_atomic(to); + break; + } + case SAS_PROTOCOL_SATA: +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index ff197bc06453..a2689ca8421a 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -2441,10 +2441,9 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + case SAS_PROTOCOL_SMP: + { + struct scatterlist *sg_resp = &task->smp_task.smp_resp; +- void *to; ++ void *to = page_address(sg_page(sg_resp)); + + ts->stat = SAM_STAT_GOOD; +- to = kmap_atomic(sg_page(sg_resp)); + + dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, + DMA_FROM_DEVICE); +@@ -2454,7 +2453,6 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + hisi_sas_status_buf_addr_mem(slot) + + sizeof(struct hisi_sas_err_record), + sg_dma_len(sg_resp)); +- kunmap_atomic(to); + break; + } + case SAS_PROTOCOL_SATA: +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 9500a02ae9c2..c3b8432c5c34 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2533,10 +2533,9 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + } + case SAS_PROTOCOL_SMP: { + struct scatterlist *sg_resp = &task->smp_task.smp_resp; +- void *to; ++ void *to = page_address(sg_page(sg_resp)); + + ts->stat = SAM_STAT_GOOD; +- to = kmap_atomic(sg_page(sg_resp)); + + dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, + DMA_FROM_DEVICE); +@@ -2546,7 +2545,6 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + hisi_sas_status_buf_addr_mem(slot) + + sizeof(struct hisi_sas_err_record), + sg_dma_len(sg_resp)); +- kunmap_atomic(to); + break; + } + case SAS_PROTOCOL_SATA: +-- +2.27.0 + diff --git a/patches/0659-scsi-hisi_sas-Drop-SMP-resp-frame-DMA-mapping.patch b/patches/0659-scsi-hisi_sas-Drop-SMP-resp-frame-DMA-mapping.patch new file mode 100644 index 0000000..7b1362e --- /dev/null +++ b/patches/0659-scsi-hisi_sas-Drop-SMP-resp-frame-DMA-mapping.patch @@ -0,0 +1,190 @@ +From 737944bcc3de8f2d70f7a05ced45d46c43e96b69 Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Mon, 5 Aug 2019 21:48:07 +0800 +Subject: [PATCH 011/108] scsi: hisi_sas: Drop SMP resp frame DMA mapping + +mainline inclusion +from mainline-v5.4-rc1 +commit 5f6c32d7ce576e9275ab2e9b21192f5cd5f24273 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5f6c32d7ce576e9275ab2e9b21192f5cd5f24273 + +---------------------------------------------------------------------- + +The SMP frame response is written to the command table and not the SMP +response pointer from libsas, so don't bother DMA mapping (and unmapping) +the SMP response from libsas. + +Suggested-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 30 +++++++------------------- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 +--- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 +--- + 4 files changed, 11 insertions(+), 31 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 11c27ae7c0a2..f57b8689fc3d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -300,8 +300,8 @@ static void hisi_sas_task_prep_abort(struct hisi_hba *hisi_hba, + } + + static void hisi_sas_dma_unmap(struct hisi_hba *hisi_hba, +- struct sas_task *task, int n_elem, +- int n_elem_req, int n_elem_resp) ++ struct sas_task *task, int n_elem, ++ int n_elem_req) + { + struct device *dev = hisi_hba->dev; + +@@ -315,22 +315,19 @@ static void hisi_sas_dma_unmap(struct hisi_hba *hisi_hba, + if (n_elem_req) + dma_unmap_sg(dev, &task->smp_task.smp_req, + 1, DMA_TO_DEVICE); +- if (n_elem_resp) +- dma_unmap_sg(dev, &task->smp_task.smp_resp, +- 1, DMA_FROM_DEVICE); + } + } + } + + static int hisi_sas_dma_map(struct hisi_hba *hisi_hba, + struct sas_task *task, int *n_elem, +- int *n_elem_req, int *n_elem_resp) ++ int *n_elem_req) + { + struct device *dev = hisi_hba->dev; + int rc; + + if (!sas_protocol_ata(task->task_proto)) { +- unsigned int req_len, resp_len; ++ unsigned int req_len; + + if (task->num_scatter) { + *n_elem = dma_map_sg(dev, task->scatter, +@@ -351,17 +348,6 @@ static int hisi_sas_dma_map(struct hisi_hba *hisi_hba, + rc = -EINVAL; + goto err_out_dma_unmap; + } +- *n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp, +- 1, DMA_FROM_DEVICE); +- if (!*n_elem_resp) { +- rc = -ENOMEM; +- goto err_out_dma_unmap; +- } +- resp_len = sg_dma_len(&task->smp_task.smp_resp); +- if (resp_len & 0x3) { +- rc = -EINVAL; +- goto err_out_dma_unmap; +- } + } + } else + *n_elem = task->num_scatter; +@@ -376,7 +362,7 @@ static int hisi_sas_dma_map(struct hisi_hba *hisi_hba, + + err_out_dma_unmap: + hisi_sas_dma_unmap(hisi_hba, task, *n_elem, +- *n_elem_req, *n_elem_resp); ++ *n_elem_req); + prep_out: + return rc; + } +@@ -450,7 +436,7 @@ static int hisi_sas_task_prep(struct sas_task *task, + struct asd_sas_port *sas_port = device->port; + struct device *dev = hisi_hba->dev; + int dlvry_queue_slot, dlvry_queue, rc, slot_idx; +- int n_elem = 0, n_elem_dif = 0, n_elem_req = 0, n_elem_resp = 0; ++ int n_elem = 0, n_elem_dif = 0, n_elem_req = 0; + struct hisi_sas_dq *dq; + unsigned long flags; + int wr_q_index; +@@ -487,7 +473,7 @@ static int hisi_sas_task_prep(struct sas_task *task, + } + + rc = hisi_sas_dma_map(hisi_hba, task, &n_elem, +- &n_elem_req, &n_elem_resp); ++ &n_elem_req); + if (rc < 0) + goto prep_out; + +@@ -580,7 +566,7 @@ static int hisi_sas_task_prep(struct sas_task *task, + hisi_sas_dif_dma_unmap(hisi_hba, task, n_elem_dif); + err_out_dma_unmap: + hisi_sas_dma_unmap(hisi_hba, task, n_elem, +- n_elem_req, n_elem_resp); ++ n_elem_req); + prep_out: + dev_err(dev, "task prep: failed[%d]!\n", rc); + return rc; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index eebc774ba443..fb64684384c6 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1288,14 +1288,12 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, + + ts->stat = SAM_STAT_GOOD; + +- dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, +- DMA_FROM_DEVICE); + dma_unmap_sg(dev, &task->smp_task.smp_req, 1, + DMA_TO_DEVICE); + memcpy(to + sg_resp->offset, + hisi_sas_status_buf_addr_mem(slot) + + sizeof(struct hisi_sas_err_record), +- sg_dma_len(sg_resp)); ++ sg_resp->length); + break; + } + case SAS_PROTOCOL_SATA: +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index a2689ca8421a..d1453a6c6dda 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -2445,14 +2445,12 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + + ts->stat = SAM_STAT_GOOD; + +- dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, +- DMA_FROM_DEVICE); + dma_unmap_sg(dev, &task->smp_task.smp_req, 1, + DMA_TO_DEVICE); + memcpy(to + sg_resp->offset, + hisi_sas_status_buf_addr_mem(slot) + + sizeof(struct hisi_sas_err_record), +- sg_dma_len(sg_resp)); ++ sg_resp->length); + break; + } + case SAS_PROTOCOL_SATA: +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index c3b8432c5c34..19be76c54b4c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2537,14 +2537,12 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + + ts->stat = SAM_STAT_GOOD; + +- dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, +- DMA_FROM_DEVICE); + dma_unmap_sg(dev, &task->smp_task.smp_req, 1, + DMA_TO_DEVICE); + memcpy(to + sg_resp->offset, + hisi_sas_status_buf_addr_mem(slot) + + sizeof(struct hisi_sas_err_record), +- sg_dma_len(sg_resp)); ++ sg_resp->length); + break; + } + case SAS_PROTOCOL_SATA: +-- +2.27.0 + diff --git a/patches/0660-scsi-hisi_sas-Drop-free_irq-when-devm_request_irq-fa.patch b/patches/0660-scsi-hisi_sas-Drop-free_irq-when-devm_request_irq-fa.patch new file mode 100644 index 0000000..298b767 --- /dev/null +++ b/patches/0660-scsi-hisi_sas-Drop-free_irq-when-devm_request_irq-fa.patch @@ -0,0 +1,175 @@ +From 12a777e0d70446a646dea4d16820eba3f6ec0cf2 Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Mon, 5 Aug 2019 21:48:08 +0800 +Subject: [PATCH 012/108] scsi: hisi_sas: Drop free_irq() when + devm_request_irq() failed + +mainline inclusion +from mainline-v5.4-rc1 +commit e16963f378faf82d307cad2796953f198497c614 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e16963f378faf82d307cad2796953f198497c614 + +---------------------------------------------------------------------- + +It will free irq automatically if devm_request_irq() failed, so drop +free_irq() if devm_request_irq() failed. + +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 33 ++++++-------------------- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 22 ++++------------- + 2 files changed, 11 insertions(+), 44 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index d1453a6c6dda..bb1efab2b682 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3329,8 +3329,8 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) + { + struct platform_device *pdev = hisi_hba->platform_dev; + struct device *dev = &pdev->dev; +- int irq, rc, irq_map[128]; +- int i, phy_no, fatal_no, queue_no, k; ++ int irq, rc = 0, irq_map[128]; ++ int i, phy_no, fatal_no, queue_no; + + for (i = 0; i < 128; i++) + irq_map[i] = platform_get_irq(pdev, i); +@@ -3343,7 +3343,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) + dev_err(dev, "irq init: could not request phy interrupt %d, rc=%d\n", + irq, rc); + rc = -ENOENT; +- goto free_phy_int_irqs; ++ goto err_out; + } + } + +@@ -3357,7 +3357,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) + dev_err(dev, "irq init: could not request sata interrupt %d, rc=%d\n", + irq, rc); + rc = -ENOENT; +- goto free_sata_int_irqs; ++ goto err_out; + } + } + +@@ -3369,7 +3369,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) + dev_err(dev, "irq init: could not request fatal interrupt %d, rc=%d\n", + irq, rc); + rc = -ENOENT; +- goto free_fatal_int_irqs; ++ goto err_out; + } + } + +@@ -3384,34 +3384,15 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) + dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", + irq, rc); + rc = -ENOENT; +- goto free_cq_int_irqs; ++ goto err_out; + } + tasklet_init(t, cq_tasklet_v2_hw, (unsigned long)cq); + } + + hisi_hba->nvecs = hisi_hba->queue_count; + hisi_hba->dq_num_per_node = hisi_hba->queue_count / num_online_nodes(); +- return 0; +- +-free_cq_int_irqs: +- for (k = 0; k < queue_no; k++) { +- struct hisi_sas_cq *cq = &hisi_hba->cq[k]; + +- free_irq(irq_map[k + 96], cq); +- tasklet_kill(&cq->tasklet); +- } +-free_fatal_int_irqs: +- for (k = 0; k < fatal_no; k++) +- free_irq(irq_map[k + 81], hisi_hba); +-free_sata_int_irqs: +- for (k = 0; k < phy_no; k++) { +- struct hisi_sas_phy *phy = &hisi_hba->phy[k]; +- +- free_irq(irq_map[k + 72], phy); +- } +-free_phy_int_irqs: +- for (k = 0; k < i; k++) +- free_irq(irq_map[k + 1], hisi_hba); ++err_out: + return rc; + } + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 19be76c54b4c..75161290bcc7 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2706,8 +2706,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; + struct pci_dev *pdev = hisi_hba->pci_dev; +- int vectors, rc; +- int i, k; ++ int vectors, rc, i; + int max_dq_num, online_numa_num; + int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi; + +@@ -2765,7 +2764,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + if (rc) { + dev_err(dev, "could not request chnl interrupt, rc=%d\n", rc); + rc = -ENOENT; +- goto free_phy_irq; ++ goto free_irq_vectors; + } + + rc = devm_request_irq(dev, pci_irq_vector(pdev, PCI_IRQ_AXI_FATAL), +@@ -2774,7 +2773,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + if (rc) { + dev_err(dev, "could not request fatal interrupt, rc=%d\n", rc); + rc = -ENOENT; +- goto free_chnl_interrupt; ++ goto free_irq_vectors; + } + + /* Init tasklets for cq only */ +@@ -2792,7 +2791,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + dev_err(dev, "could not request cq%d interrupt, rc=%d\n", + i, rc); + rc = -ENOENT; +- goto free_cq_irqs; ++ goto free_irq_vectors; + } + + tasklet_init(t, cq_tasklet_v3_hw, (uintptr_t)cq); +@@ -2800,19 +2799,6 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + + return 0; + +-free_cq_irqs: +- for (k = 0; k < i; k++) { +- struct hisi_sas_cq *cq = &hisi_hba->cq[k]; +- int nr = hisi_sas_intr_conv ? PCI_IRQ_CQ_BASE : +- PCI_IRQ_CQ_BASE + k; +- +- free_irq(pci_irq_vector(pdev, nr), cq); +- } +- free_irq(pci_irq_vector(pdev, PCI_IRQ_AXI_FATAL), hisi_hba); +-free_chnl_interrupt: +- free_irq(pci_irq_vector(pdev, PCI_IRQ_CHANNEL), hisi_hba); +-free_phy_irq: +- free_irq(pci_irq_vector(pdev, PCI_IRQ_PHY), hisi_hba); + free_irq_vectors: + pci_free_irq_vectors(pdev); + return rc; +-- +2.27.0 + diff --git a/patches/0661-scsi-hisi_sas-Modify-return-type-of-debugfs-function.patch b/patches/0661-scsi-hisi_sas-Modify-return-type-of-debugfs-function.patch new file mode 100644 index 0000000..e6ff432 --- /dev/null +++ b/patches/0661-scsi-hisi_sas-Modify-return-type-of-debugfs-function.patch @@ -0,0 +1,168 @@ +From 93a73f485b94487d2e0df33be7de906e1c1b42f1 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Mon, 5 Aug 2019 21:48:09 +0800 +Subject: [PATCH 013/108] scsi: hisi_sas: Modify return type of debugfs + functions + +mainline inclusion +from mainline-v5.4-rc1 +commit 7bf18e849d80e1beb118fd6d3bd5ccfcb1267d09 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7bf18e849d80e1beb118fd6d3bd5ccfcb1267d09 + +---------------------------------------------------------------------- + +For functions which always return 0, which is never checked, make to return +void. + +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 51 ++++++++++----------------- + 1 file changed, 18 insertions(+), 33 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index f57b8689fc3d..525f6ba94459 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -3404,8 +3404,8 @@ static const struct file_operations hisi_sas_debugfs_port_fops = { + .owner = THIS_MODULE, + }; + +-static int hisi_sas_show_row_64(struct seq_file *s, int index, +- int sz, __le64 *ptr) ++static void hisi_sas_show_row_64(struct seq_file *s, int index, ++ int sz, __le64 *ptr) + { + int i; + +@@ -3419,12 +3419,10 @@ static int hisi_sas_show_row_64(struct seq_file *s, int index, + } + + seq_puts(s, "\n"); +- +- return 0; + } + +-static int hisi_sas_show_row_32(struct seq_file *s, int index, +- int sz, __le32 *ptr) ++static void hisi_sas_show_row_32(struct seq_file *s, int index, ++ int sz, __le32 *ptr) + { + int i; + +@@ -3437,11 +3435,9 @@ static int hisi_sas_show_row_32(struct seq_file *s, int index, + seq_puts(s, "\n\t"); + } + seq_puts(s, "\n"); +- +- return 0; + } + +-static int hisi_sas_cq_show_slot(struct seq_file *s, int slot, void *cq_ptr) ++static void hisi_sas_cq_show_slot(struct seq_file *s, int slot, void *cq_ptr) + { + struct hisi_sas_cq *cq = cq_ptr; + struct hisi_hba *hisi_hba = cq->hisi_hba; +@@ -3449,20 +3445,18 @@ static int hisi_sas_cq_show_slot(struct seq_file *s, int slot, void *cq_ptr) + u64 offset = hisi_hba->hw->complete_hdr_size * slot; + __le32 *complete_hdr = complete_queue + offset; + +- return hisi_sas_show_row_32(s, slot, +- hisi_hba->hw->complete_hdr_size, +- complete_hdr); ++ hisi_sas_show_row_32(s, slot, ++ hisi_hba->hw->complete_hdr_size, ++ complete_hdr); + } + + static int hisi_sas_debugfs_cq_show(struct seq_file *s, void *p) + { + struct hisi_sas_cq *cq = s->private; +- int slot, ret; ++ int slot; + + for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) { +- ret = hisi_sas_cq_show_slot(s, slot, cq); +- if (ret) +- return ret; ++ hisi_sas_cq_show_slot(s, slot, cq); + } + return 0; + } +@@ -3480,7 +3474,7 @@ static const struct file_operations hisi_sas_debugfs_cq_fops = { + .owner = THIS_MODULE, + }; + +-static int hisi_sas_dq_show_slot(struct seq_file *s, int slot, void *dq_ptr) ++static void hisi_sas_dq_show_slot(struct seq_file *s, int slot, void *dq_ptr) + { + struct hisi_sas_dq *dq = dq_ptr; + struct hisi_hba *hisi_hba = dq->hisi_hba; +@@ -3488,18 +3482,15 @@ static int hisi_sas_dq_show_slot(struct seq_file *s, int slot, void *dq_ptr) + u64 offset = sizeof(struct hisi_sas_cmd_hdr) * slot; + __le32 *cmd_hdr = cmd_queue + offset; + +- return hisi_sas_show_row_32(s, slot, sizeof(struct hisi_sas_cmd_hdr), +- cmd_hdr); ++ hisi_sas_show_row_32(s, slot, sizeof(struct hisi_sas_cmd_hdr), cmd_hdr); + } + + static int hisi_sas_debugfs_dq_show(struct seq_file *s, void *p) + { +- int slot, ret; ++ int slot; + + for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) { +- ret = hisi_sas_dq_show_slot(s, slot, s->private); +- if (ret) +- return ret; ++ hisi_sas_dq_show_slot(s, slot, s->private); + } + return 0; + } +@@ -3521,15 +3512,12 @@ static int hisi_sas_debugfs_iost_show(struct seq_file *s, void *p) + { + struct hisi_hba *hisi_hba = s->private; + struct hisi_sas_iost *debugfs_iost = hisi_hba->debugfs_iost; +- int i, ret, max_command_entries = HISI_SAS_MAX_COMMANDS; ++ int i, max_command_entries = HISI_SAS_MAX_COMMANDS; + + for (i = 0; i < max_command_entries; i++, debugfs_iost++) { + __le64 *iost = &debugfs_iost->qw0; + +- ret = hisi_sas_show_row_64(s, i, sizeof(*debugfs_iost), +- iost); +- if (ret) +- return ret; ++ hisi_sas_show_row_64(s, i, sizeof(*debugfs_iost), iost); + } + + return 0; +@@ -3590,17 +3578,14 @@ static const struct file_operations hisi_sas_debugfs_iost_cache_fops = { + + static int hisi_sas_debugfs_itct_show(struct seq_file *s, void *p) + { +- int i, ret; ++ int i; + struct hisi_hba *hisi_hba = s->private; + struct hisi_sas_itct *debugfs_itct = hisi_hba->debugfs_itct; + + for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, debugfs_itct++) { + __le64 *itct = &debugfs_itct->qw0; + +- ret = hisi_sas_show_row_64(s, i, sizeof(*debugfs_itct), +- itct); +- if (ret) +- return ret; ++ hisi_sas_show_row_64(s, i, sizeof(*debugfs_itct), itct); + } + + return 0; +-- +2.27.0 + diff --git a/patches/0662-scsi-hisi_sas-Remove-some-unnecessary-code.patch b/patches/0662-scsi-hisi_sas-Remove-some-unnecessary-code.patch new file mode 100644 index 0000000..920e5be --- /dev/null +++ b/patches/0662-scsi-hisi_sas-Remove-some-unnecessary-code.patch @@ -0,0 +1,55 @@ +From aa8d594c61620c3c36441b08b98380f3abb4d3af Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Mon, 5 Aug 2019 21:48:10 +0800 +Subject: [PATCH 014/108] scsi: hisi_sas: Remove some unnecessary code + +mainline inclusion +from mainline-v5.4-rc1 +commit a07b48766c5232b98154f68010512a9269f2841e +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a07b48766c5232b98154f68010512a9269f2841e + +---------------------------------------------------------------------- + +Remove some unnecessary code, including: + + - Explicit zeroing of memory allocated for dmam_alloc_coherent() + + - Some duplicated code + + - Some redundant masking + +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 75161290bcc7..722ef2be390a 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3543,8 +3543,6 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev) + else + hisi_hba->enable_dix_dif = enable_dix_dif; + +- timer_setup(&hisi_hba->timer, NULL, 0); +- + if (hisi_sas_get_fw_info(hisi_hba) < 0) + goto err_out; + +@@ -3636,7 +3634,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + sha->lldd_module = THIS_MODULE; + sha->sas_addr = &hisi_hba->sas_addr[0]; + sha->num_phys = hisi_hba->n_phy; +- sha->core.shost = hisi_hba->shost; + + for (i = 0; i < hisi_hba->n_phy; i++) { + sha->sas_phy[i] = &hisi_hba->phy[i].sas_phy; +-- +2.27.0 + diff --git a/patches/0663-scsi-hisi_sas-remove-set-but-not-used-variable-irq_v.patch b/patches/0663-scsi-hisi_sas-remove-set-but-not-used-variable-irq_v.patch new file mode 100644 index 0000000..6ffae1b --- /dev/null +++ b/patches/0663-scsi-hisi_sas-remove-set-but-not-used-variable-irq_v.patch @@ -0,0 +1,50 @@ +From 3df93a59b5905b569c5e4f13906e76b22b154fba Mon Sep 17 00:00:00 2001 +From: zhengbin +Date: Thu, 22 Aug 2019 22:20:47 +0800 +Subject: [PATCH 015/108] scsi: hisi_sas: remove set but not used variable + 'irq_value' + +mainline inclusion +from mainline-v5.4-rc1 +commit 328bc6debf3dcaf8859dd1323882e8e24ec6e3f8 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=328bc6debf3dcaf8859dd1323882e8e24ec6e3f8 + +---------------------------------------------------------------------- + +Fixes gcc '-Wunused-but-set-variable' warning: + +drivers/scsi/hisi_sas/hisi_sas_v1_hw.c: In function cq_interrupt_v1_hw: +drivers/scsi/hisi_sas/hisi_sas_v1_hw.c:1542:6: warning: variable irq_value set but not used [-Wunused-but-set-variable] + +Reported-by: Hulk Robot +Signed-off-by: zhengbin +Acked-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index fb64684384c6..7ec286b11973 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1505,11 +1505,9 @@ static irqreturn_t cq_interrupt_v1_hw(int irq, void *p) + struct hisi_sas_complete_v1_hdr *complete_queue = + (struct hisi_sas_complete_v1_hdr *) + hisi_hba->complete_hdr[queue]; +- u32 irq_value, rd_point = cq->rd_point, wr_point; ++ u32 rd_point = cq->rd_point, wr_point; + + spin_lock(&hisi_hba->lock); +- irq_value = hisi_sas_read32(hisi_hba, OQ_INT_SRC); +- + hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); + wr_point = hisi_sas_read32(hisi_hba, + COMPL_Q_0_WR_PTR + (0x14 * queue)); +-- +2.27.0 + diff --git a/patches/0664-scsi-hisi_sas-use-devm_platform_ioremap_resource-to-.patch b/patches/0664-scsi-hisi_sas-use-devm_platform_ioremap_resource-to-.patch new file mode 100644 index 0000000..f271236 --- /dev/null +++ b/patches/0664-scsi-hisi_sas-use-devm_platform_ioremap_resource-to-.patch @@ -0,0 +1,46 @@ +From 02261391c0bff0f574d3d661940261bd00683af5 Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Wed, 4 Sep 2019 21:02:56 +0800 +Subject: [PATCH 016/108] scsi: hisi_sas: use devm_platform_ioremap_resource() + to simplify code + +mainline inclusion +from mainline-v5.4-rc1 +commit c0c1a71e9542e6b0b58642332eb86fd32c9b2ed8 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c0c1a71e9542e6b0b58642332eb86fd32c9b2ed8 + +---------------------------------------------------------------------- + +Use devm_platform_ioremap_resource() to simplify the code a bit. +This is detected by coccinelle. + +Link: https://lore.kernel.org/r/20190904130256.24704-1-yuehaibing@huawei.com +Reported-by: Hulk Robot +Signed-off-by: YueHaibing +Acked-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 525f6ba94459..ce6fe08cf18b 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2659,8 +2659,7 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, + goto err_out; + } + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- hisi_hba->regs = devm_ioremap_resource(dev, res); ++ hisi_hba->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(hisi_hba->regs)) + goto err_out; + +-- +2.27.0 + diff --git a/patches/0665-scsi-hisi_sas-add-debugfs-auto-trigger-for-internal-.patch b/patches/0665-scsi-hisi_sas-add-debugfs-auto-trigger-for-internal-.patch new file mode 100644 index 0000000..d5bc2d6 --- /dev/null +++ b/patches/0665-scsi-hisi_sas-add-debugfs-auto-trigger-for-internal-.patch @@ -0,0 +1,44 @@ +From 090426a30ddb53ae410666802203fa01b923afc6 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Fri, 6 Sep 2019 20:55:25 +0800 +Subject: [PATCH 017/108] scsi: hisi_sas: add debugfs auto-trigger for internal + abort time out + +mainline inclusion +from mainline-v5.4-rc1 +commit 7105e68afaec062c0329910a491e57c9f3a82bef +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F808 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7105e68afaec062c0329910a491e57c9f3a82bef + +---------------------------------------------------------------------- + +This trigger is add at _hisi_sas_internal_task_abort() + +Link: https://lore.kernel.org/r/1567774537-20003-2-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index ce6fe08cf18b..bb8d872958c1 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2132,6 +2132,9 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + + /* Internal abort timed out */ + if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { ++ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct) ++ queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); ++ + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { + struct hisi_sas_slot *slot = task->lldd_task; + +-- +2.27.0 + diff --git a/patches/0666-scsi-hisi_sas-Remove-hisi_sas_hw.slot_complete.patch b/patches/0666-scsi-hisi_sas-Remove-hisi_sas_hw.slot_complete.patch new file mode 100644 index 0000000..bfa9cad --- /dev/null +++ b/patches/0666-scsi-hisi_sas-Remove-hisi_sas_hw.slot_complete.patch @@ -0,0 +1,84 @@ +From 6126cc39b7b0412a9512ce7a802c7e2d339b100f Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Fri, 6 Sep 2019 20:55:32 +0800 +Subject: [PATCH 018/108] scsi: hisi_sas: Remove hisi_sas_hw.slot_complete + +mainline inclusion +from mainline-v5.4-rc1 +commit 971b59443f213d8085d122fae65aa96087b269bc +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=971b59443f213d8085d122fae65aa96087b269bc + +---------------------------------------------------------------------- + +We never call hisi_sas_hw.slot_complete, so remove it. + +Link: https://lore.kernel.org/r/1567774537-20003-9-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h +--- + drivers/scsi/hisi_sas/hisi_sas.h | 2 -- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 1 - + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 1 - + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 1 - + 4 files changed, 5 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index de5752f07987..3fc67664c22a 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -331,8 +331,6 @@ struct hisi_sas_hw { + struct hisi_sas_slot *slot, + unsigned int device_id, + int abort_flag, int tag_to_abort); +- int (*slot_complete)(struct hisi_hba *hisi_hba, +- struct hisi_sas_slot *slot); + void (*phys_init)(struct hisi_hba *hisi_hba); + void (*phy_start)(struct hisi_hba *hisi_hba, int phy_no); + void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index 7ec286b11973..1228f282d443 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1790,7 +1790,6 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = { + .prep_smp = prep_smp_v1_hw, + .prep_ssp = prep_ssp_v1_hw, + .start_delivery = start_delivery_v1_hw, +- .slot_complete = slot_complete_v1_hw, + .phys_init = phys_init_v1_hw, + .phy_start = start_phy_v1_hw, + .phy_disable = disable_phy_v1_hw, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index bb1efab2b682..a835487fd406 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3586,7 +3586,6 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = { + .prep_stp = prep_ata_v2_hw, + .prep_abort = prep_abort_v2_hw, + .start_delivery = start_delivery_v2_hw, +- .slot_complete = slot_complete_v2_hw, + .phys_init = phys_init_v2_hw, + .phy_start = start_phy_v2_hw, + .phy_disable = disable_phy_v2_hw, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 722ef2be390a..eee696afb28d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3488,7 +3488,6 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = { + .prep_stp = prep_ata_v3_hw, + .prep_abort = prep_abort_v3_hw, + .start_delivery = start_delivery_v3_hw, +- .slot_complete = slot_complete_v3_hw, + .phys_init = phys_init_v3_hw, + .phy_start = start_phy_v3_hw, + .phy_disable = disable_phy_v3_hw, +-- +2.27.0 + diff --git a/patches/0667-scsi-hisi_sas-Remove-redundant-work-declaration.patch b/patches/0667-scsi-hisi_sas-Remove-redundant-work-declaration.patch new file mode 100644 index 0000000..c5e8997 --- /dev/null +++ b/patches/0667-scsi-hisi_sas-Remove-redundant-work-declaration.patch @@ -0,0 +1,41 @@ +From eb054b613e26f0538610903c950bba4e5a890c3a Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Fri, 6 Sep 2019 20:55:33 +0800 +Subject: [PATCH 019/108] scsi: hisi_sas: Remove redundant work declaration + +mainline inclusion +from mainline-v5.4-rc1 +commit 27f22723c3f4a1a3e66642b3da7a3d16ee602972 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=27f22723c3f4a1a3e66642b3da7a3d16ee602972 + +---------------------------------------------------------------------- + +Remove redundant work declaration in HISI_SAS_DECLARE_RST_WORK_ON_STACK + +Link: https://lore.kernel.org/r/1567774537-20003-10-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 3fc67664c22a..ba4470bf99da 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -153,7 +153,6 @@ struct hisi_sas_rst { + + #define HISI_SAS_DECLARE_RST_WORK_ON_STACK(r) \ + DECLARE_COMPLETION_ONSTACK(c); \ +- DECLARE_WORK(w, hisi_sas_sync_rst_work_handler); \ + struct hisi_sas_rst r = HISI_SAS_RST_WORK_INIT(r, c) + + enum hisi_sas_bit_err_type { +-- +2.27.0 + diff --git a/patches/0668-scsi-hisi_sas-Remove-some-unused-function-arguments.patch b/patches/0668-scsi-hisi_sas-Remove-some-unused-function-arguments.patch new file mode 100644 index 0000000..3ba18cc --- /dev/null +++ b/patches/0668-scsi-hisi_sas-Remove-some-unused-function-arguments.patch @@ -0,0 +1,153 @@ +From 08640edf1ce99ba02985af9a3ea500836365cebf Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Fri, 6 Sep 2019 20:55:34 +0800 +Subject: [PATCH 020/108] scsi: hisi_sas: Remove some unused function arguments + +mainline inclusion +from mainline-v5.4-rc1 +commit 4bc058097aa8b1af046fa000fbc6bf5408ace9bf +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4bc058097aa8b1af046fa000fbc6bf5408ace9bf + +---------------------------------------------------------------------- + +Some function arguments are unused, so remove them. + +Also move the timeout print in for wait_cmds_complete_timeout_vX_hw() +callsites into that same function. + +Link: https://lore.kernel.org/r/1567774537-20003-11-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 2 +- + drivers/scsi/hisi_sas/hisi_sas_main.c | 5 ++--- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 9 +++++---- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 15 ++++++--------- + 4 files changed, 14 insertions(+), 17 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index ba4470bf99da..4b974461cb41 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -348,7 +348,7 @@ struct hisi_sas_hw { + u32 (*get_phys_state)(struct hisi_hba *hisi_hba); + int (*write_gpio)(struct hisi_hba *hisi_hba, u8 reg_type, + u8 reg_index, u8 reg_count, u8 *write_data); +- int (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba, ++ void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba, + int delay_ms, int timeout_ms); + void (*snapshot_prepare)(struct hisi_hba *hisi_hba); + void (*snapshot_restore)(struct hisi_hba *hisi_hba); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index bb8d872958c1..7df98ca85e86 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1438,8 +1438,7 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba) + } + } + +-static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 old_state, +- u32 state) ++static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state) + { + struct sas_ha_struct *sas_ha = &hisi_hba->sha; + struct asd_sas_port *_sas_port = NULL; +@@ -1615,7 +1614,7 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) + clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + + state = hisi_hba->hw->get_phys_state(hisi_hba); +- hisi_sas_rescan_topology(hisi_hba, hisi_hba->phy_state, state); ++ hisi_sas_rescan_topology(hisi_hba, state); + } + EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done); + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index a835487fd406..55faa3ec72f9 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3521,7 +3521,7 @@ static int write_gpio_v2_hw(struct hisi_hba *hisi_hba, u8 reg_type, + return 0; + } + +-static int wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba, ++static void wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba, + int delay_ms, int timeout_ms) + { + struct device *dev = hisi_hba->dev; +@@ -3536,12 +3536,13 @@ static int wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba, + msleep(delay_ms); + } + +- if (time >= timeout_ms) +- return -ETIMEDOUT; ++ if (time >= timeout_ms) { ++ dev_dbg(dev, "Wait commands complete timeout!\n"); ++ return; ++ } + + dev_dbg(dev, "wait commands complete %dms\n", time); + +- return 0; + } + + struct device_attribute *host_attrs_v2_hw[] = { +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index eee696afb28d..e55442525ae6 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2978,7 +2978,7 @@ static int write_gpio_v3_hw(struct hisi_hba *hisi_hba, u8 reg_type, + return 0; + } + +-static int wait_cmds_complete_timeout_v3_hw(struct hisi_hba *hisi_hba, ++static void wait_cmds_complete_timeout_v3_hw(struct hisi_hba *hisi_hba, + int delay_ms, int timeout_ms) + { + struct device *dev = hisi_hba->dev; +@@ -2993,12 +2993,12 @@ static int wait_cmds_complete_timeout_v3_hw(struct hisi_hba *hisi_hba, + msleep(delay_ms); + } + +- if (time >= timeout_ms) +- return -ETIMEDOUT; ++ if (time >= timeout_ms) { ++ dev_dbg(dev, "Wait commands complete timeout!\n"); ++ return; ++ } + + dev_dbg(dev, "wait commands complete %dms\n", time); +- +- return 0; + } + + static ssize_t intr_conv_show(struct device *dev, +@@ -3280,15 +3280,12 @@ static const struct hisi_sas_debugfs_reg debugfs_ras_reg = { + + static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) + { +- struct device *dev = hisi_hba->dev; +- + set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0); + + /* delay:100ms, timeout:5s */ +- if (wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000) == -ETIMEDOUT) +- dev_dbg(dev, "Wait commands complete timeout!\n"); ++ wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000); + + hisi_sas_kill_tasklets(hisi_hba); + } +-- +2.27.0 + diff --git a/patches/0669-scsi-hisi_sas-Add-hisi_sas_debugfs_alloc-to-centrali.patch b/patches/0669-scsi-hisi_sas-Add-hisi_sas_debugfs_alloc-to-centrali.patch new file mode 100644 index 0000000..d46b4a8 --- /dev/null +++ b/patches/0669-scsi-hisi_sas-Add-hisi_sas_debugfs_alloc-to-centrali.patch @@ -0,0 +1,257 @@ +From b05fdcf79d18f6a29e00ae9ec18e6067d952aaab Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Fri, 6 Sep 2019 20:55:35 +0800 +Subject: [PATCH 021/108] scsi: hisi_sas: Add hisi_sas_debugfs_alloc() to + centralise allocation + +mainline inclusion +from mainline-v5.4-rc1 +commit 7ec7082c57ecdd8d37040d31203951f7e2e8e218 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F808 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7ec7082c57ecdd8d37040d31203951f7e2e8e218 + +---------------------------------------------------------------------- + +We extract the code of memory allocate and construct an new function for +it. We think it's convenient for subsequent optimization. + +Link: https://lore.kernel.org/r/1567774537-20003-12-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 117 +++++++++++++++----------- + 1 file changed, 66 insertions(+), 51 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 7df98ca85e86..6e49a91aa492 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -3783,60 +3783,77 @@ void hisi_sas_debugfs_work_handler(struct work_struct *work) + } + EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler); + +-void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) ++void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) ++{ ++ struct device *dev = hisi_hba->dev; ++ int i; ++ ++ devm_kfree(dev, hisi_hba->debugfs_iost_cache); ++ devm_kfree(dev, hisi_hba->debugfs_itct_cache); ++ devm_kfree(dev, hisi_hba->debugfs_iost); ++ ++ for (i = 0; i < hisi_hba->queue_count; i++) ++ devm_kfree(dev, hisi_hba->debugfs_cmd_hdr[i]); ++ ++ for (i = 0; i < hisi_hba->queue_count; i++) ++ devm_kfree(dev, hisi_hba->debugfs_complete_hdr[i]); ++ ++ for (i = 0; i < DEBUGFS_REGS_NUM; i++) ++ devm_kfree(dev, hisi_hba->debugfs_regs[i]); ++ ++ for (i = 0; i < hisi_hba->n_phy; i++) ++ devm_kfree(dev, hisi_hba->debugfs_port_reg[i]); ++} ++ ++int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + { +- int max_command_entries = HISI_SAS_MAX_COMMANDS; + const struct hisi_sas_hw *hw = hisi_hba->hw; + struct device *dev = hisi_hba->dev; +- int p, i, c, d; ++ int p, c, d; + size_t sz; + +- hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), +- hisi_sas_debugfs_dir); ++ hisi_hba->debugfs_dump_dentry = ++ debugfs_create_dir("dump", hisi_hba->debugfs_dir); + +- debugfs_create_file("trigger_dump", 0600, +- hisi_hba->debugfs_dir, +- hisi_hba, +- &hisi_sas_debugfs_trigger_dump_fops); + /* create bist structures */ + hisi_hba->debugfs_bist_dentry = debugfs_create_dir("bist", + hisi_hba->debugfs_dir); + if (!hisi_hba->debugfs_bist_dentry) +- goto fail_global; ++ goto fail; + + if (!debugfs_create_file("link_rate", 0644, + hisi_hba->debugfs_bist_dentry, hisi_hba, + &hisi_sas_debugfs_bist_linkrate_ops)) +- goto fail_global; ++ goto fail; + + if (!debugfs_create_file("code_mode", 0644, + hisi_hba->debugfs_bist_dentry, hisi_hba, + &hisi_sas_debugfs_bist_code_mode_ops)) +- goto fail_global; ++ goto fail; + + if (!debugfs_create_file("phy_id", 0644, hisi_hba->debugfs_bist_dentry, + hisi_hba, &hisi_sas_debugfs_bist_phy_ops)) +- goto fail_global; ++ goto fail; + + if (!debugfs_create_u32("cnt", 0644, hisi_hba->debugfs_bist_dentry, + &hisi_hba->bist_loopback_cnt)) +- goto fail_global; ++ goto fail; + + if (!debugfs_create_file("loopback_mode", 0400, + hisi_hba->debugfs_bist_dentry, + hisi_hba, &hisi_sas_debugfs_bist_mode_ops)) +- goto fail_global; ++ goto fail; + + if (!debugfs_create_file("enable", 0644, hisi_hba->debugfs_bist_dentry, + hisi_hba, &hisi_sas_debugfs_bist_enable_ops)) +- goto fail_global; ++ goto fail; + + sz = hw->debugfs_reg_array[DEBUGFS_GLOBAL]->count * 4; + hisi_hba->debugfs_regs[DEBUGFS_GLOBAL] = + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->debugfs_regs[DEBUGFS_GLOBAL]) +- goto fail_global; ++ goto fail; + + sz = hw->debugfs_reg_port->count * 4; + for (p = 0; p < hisi_hba->n_phy; p++) { +@@ -3844,7 +3861,7 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->debugfs_port_reg[p]) +- goto fail_port; ++ goto fail; + } + + sz = hw->debugfs_reg_array[DEBUGFS_AXI]->count * 4; +@@ -3852,14 +3869,14 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->debugfs_regs[DEBUGFS_AXI]) +- goto fail_axi; ++ goto fail; + + sz = hw->debugfs_reg_array[DEBUGFS_RAS]->count * 4; + hisi_hba->debugfs_regs[DEBUGFS_RAS] = + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->debugfs_regs[DEBUGFS_RAS]) +- goto fail_ras; ++ goto fail; + + sz = hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + for (c = 0; c < hisi_hba->queue_count; c++) { +@@ -3867,7 +3884,7 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->debugfs_complete_hdr[c]) +- goto fail_cq; ++ goto fail; + } + + sz = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; +@@ -3876,60 +3893,58 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + devm_kmalloc(dev, sz, GFP_KERNEL); + + if (!hisi_hba->debugfs_cmd_hdr[d]) +- goto fail_iost_dq; ++ goto fail; + } + +- sz = max_command_entries * sizeof(struct hisi_sas_iost); ++ sz = HISI_SAS_MAX_COMMANDS * sizeof(struct hisi_sas_iost); + + hisi_hba->debugfs_iost = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->debugfs_iost) +- goto fail_iost_dq; ++ goto fail; + + sz = HISI_SAS_IOST_ITCT_CACHE_NUM * + sizeof(struct hisi_sas_iost_itct_cache); + + hisi_hba->debugfs_iost_cache = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->debugfs_iost_cache) +- goto fail_iost_cache; ++ goto fail; + + sz = HISI_SAS_IOST_ITCT_CACHE_NUM * + sizeof(struct hisi_sas_iost_itct_cache); + + hisi_hba->debugfs_itct_cache = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->debugfs_itct_cache) +- goto fail_itct_cache; ++ goto fail; + + /* New memory allocation must be locate before itct */ + sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); + + hisi_hba->debugfs_itct = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->debugfs_itct) +- goto fail_itct; ++ goto fail; ++ ++ return 0; ++fail: ++ hisi_sas_debugfs_release(hisi_hba); ++ return -ENOMEM; ++} ++ ++void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) ++{ ++ struct device *dev = hisi_hba->dev; ++ ++ hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), ++ hisi_sas_debugfs_dir); ++ debugfs_create_file("trigger_dump", 0600, ++ hisi_hba->debugfs_dir, ++ hisi_hba, ++ &hisi_sas_debugfs_trigger_dump_fops); ++ ++ if (hisi_sas_debugfs_alloc(hisi_hba)) { ++ debugfs_remove_recursive(hisi_hba->debugfs_dir); ++ dev_dbg(dev, "failed to init debugfs!\n"); ++ } + +- return; +-fail_itct: +- devm_kfree(dev, hisi_hba->debugfs_iost_cache); +-fail_itct_cache: +- devm_kfree(dev, hisi_hba->debugfs_iost_cache); +-fail_iost_cache: +- devm_kfree(dev, hisi_hba->debugfs_iost); +-fail_iost_dq: +- for (i = 0; i < d; i++) +- devm_kfree(dev, hisi_hba->debugfs_cmd_hdr[i]); +-fail_cq: +- for (i = 0; i < c; i++) +- devm_kfree(dev, hisi_hba->debugfs_complete_hdr[i]); +- devm_kfree(dev, hisi_hba->debugfs_regs[DEBUGFS_RAS]); +-fail_ras: +- devm_kfree(dev, hisi_hba->debugfs_regs[DEBUGFS_AXI]); +-fail_axi: +-fail_port: +- for (i = 0; i < p; i++) +- devm_kfree(dev, hisi_hba->debugfs_port_reg[i]); +- devm_kfree(dev, hisi_hba->debugfs_regs[DEBUGFS_GLOBAL]); +-fail_global: +- hisi_sas_debugfs_exit(hisi_hba); +- dev_info(dev, "failed to init debugfs!\n"); + } + EXPORT_SYMBOL_GPL(hisi_sas_debugfs_init); + +-- +2.27.0 + diff --git a/patches/0670-scsi-hisi_sas-fix-spelling-mistake-digial-digital.patch b/patches/0670-scsi-hisi_sas-fix-spelling-mistake-digial-digital.patch new file mode 100644 index 0000000..22f26e2 --- /dev/null +++ b/patches/0670-scsi-hisi_sas-fix-spelling-mistake-digial-digital.patch @@ -0,0 +1,45 @@ +From 09c5526db5bf67b309573b14c53a521368b25252 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Mon, 16 Sep 2019 10:17:06 +0100 +Subject: [PATCH 022/108] scsi: hisi_sas: fix spelling mistake "digial" -> + "digital" + +mainline inclusion +from mainline-v5.5-rc1 +commit b1000fcca1760d3e81f0943f0ca8b9be3ed3b999 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b1000fcca1760d3e81f0943f0ca8b9be3ed3b999 + +---------------------------------------------------------------------- + +There is a spelling mistake in literal string. Fix it. + +Link: https://lore.kernel.org/r/20190916091706.32268-1-colin.king@canonical.com +Signed-off-by: Colin Ian King +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 6e49a91aa492..4e1bdfa370d9 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -3182,7 +3182,7 @@ static struct { + int value; + char *name; + } hisi_sas_debugfs_loop_modes[] = { +- { HISI_SAS_BIST_LOOPBACK_MODE_DIGITAL, "digial" }, ++ { HISI_SAS_BIST_LOOPBACK_MODE_DIGITAL, "digital" }, + { HISI_SAS_BIST_LOOPBACK_MODE_SERDES, "serdes" }, + { HISI_SAS_BIST_LOOPBACK_MODE_REMOTE, "remote" }, + }; +-- +2.27.0 + diff --git a/patches/0671-scsi-hisi_sas-Make-three-functions-static.patch b/patches/0671-scsi-hisi_sas-Make-three-functions-static.patch new file mode 100644 index 0000000..3aec75d --- /dev/null +++ b/patches/0671-scsi-hisi_sas-Make-three-functions-static.patch @@ -0,0 +1,59 @@ +From 45f35ecb26c40f04e11df7a7314bd74d9f7551ed Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Mon, 23 Sep 2019 13:40:35 +0800 +Subject: [PATCH 023/108] scsi: hisi_sas: Make three functions static + +mainline inclusion +from mainline-v5.4-rc2 +commit 4b6b1bb68628ec49e4cbfabd8ac17a169f079cd8 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4b6b1bb68628ec49e4cbfabd8ac17a169f079cd8 + +---------------------------------------------------------------------- + +Fix sparse warnings: + +drivers/scsi/hisi_sas/hisi_sas_main.c:3686:6: + warning: symbol 'hisi_sas_debugfs_release' was not declared. Should it be static? +drivers/scsi/hisi_sas/hisi_sas_main.c:3708:5: + warning: symbol 'hisi_sas_debugfs_alloc' was not declared. Should it be static? +drivers/scsi/hisi_sas/hisi_sas_main.c:3799:6: + warning: symbol 'hisi_sas_debugfs_bist_init' was not declared. Should it be static? + +Link: https://lore.kernel.org/r/20190923054035.19036-1-yuehaibing@huawei.com +Reported-by: Hulk Robot +Signed-off-by: YueHaibing +Acked-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 4e1bdfa370d9..31820f024340 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -3783,7 +3783,7 @@ void hisi_sas_debugfs_work_handler(struct work_struct *work) + } + EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler); + +-void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) ++static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; + int i; +@@ -3805,7 +3805,7 @@ void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) + devm_kfree(dev, hisi_hba->debugfs_port_reg[i]); + } + +-int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) ++static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + { + const struct hisi_sas_hw *hw = hisi_hba->hw; + struct device *dev = hisi_hba->dev; +-- +2.27.0 + diff --git a/patches/0672-scsi-hisi_sas-Don-t-create-debugfs-dump-folder-twice.patch b/patches/0672-scsi-hisi_sas-Don-t-create-debugfs-dump-folder-twice.patch new file mode 100644 index 0000000..e89581e --- /dev/null +++ b/patches/0672-scsi-hisi_sas-Don-t-create-debugfs-dump-folder-twice.patch @@ -0,0 +1,55 @@ +From c65ff1406fb2dc4c8c74b0c1c5ba3fb44184eaeb Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Thu, 24 Oct 2019 22:08:08 +0800 +Subject: [PATCH 024/108] scsi: hisi_sas: Don't create debugfs dump folder + twice + +mainline inclusion +from mainline-v5.5-rc1 +commit 35160421b63d4753a72e9f72ebcdd9d6f88f84b9 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=35160421b63d4753a72e9f72ebcdd9d6f88f84b9 + +---------------------------------------------------------------------- + +Due to a merge error, we attempt to create 2x debugfs dump folders, which +fails: +[ 861.101914] debugfs: Directory 'dump' with parent '0000:74:02.0' +already present! + +This breaks the dump function. + +To fix, remove the superfluous attempt to create the folder. + +Fixes: 7ec7082c57ec ("scsi: hisi_sas: Add hisi_sas_debugfs_alloc() to centralise allocation") +Link: https://lore.kernel.org/r/1571926105-74636-2-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 31820f024340..bb0287eed0dc 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -3812,9 +3812,6 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + int p, c, d; + size_t sz; + +- hisi_hba->debugfs_dump_dentry = +- debugfs_create_dir("dump", hisi_hba->debugfs_dir); +- + /* create bist structures */ + hisi_hba->debugfs_bist_dentry = debugfs_create_dir("bist", + hisi_hba->debugfs_dir); +-- +2.27.0 + diff --git a/patches/0673-scsi-hisi_sas-Add-timestamp-for-a-debugfs-dump.patch b/patches/0673-scsi-hisi_sas-Add-timestamp-for-a-debugfs-dump.patch new file mode 100644 index 0000000..ab9d8e3 --- /dev/null +++ b/patches/0673-scsi-hisi_sas-Add-timestamp-for-a-debugfs-dump.patch @@ -0,0 +1,93 @@ +From 5b57c5fd3dc7f4d55412395cf972cec8c6b776bf Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:12 +0800 +Subject: [PATCH 025/108] scsi: hisi_sas: Add timestamp for a debugfs dump + +mainline inclusion +from mainline-v5.5-rc1 +commit d28ed83b769378deefa82456f962e14a4b0afadf +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d28ed83b769378deefa82456f962e14a4b0afadf + +---------------------------------------------------------------------- + +It's useful to know when the dump occurred, so add a timestamp file for +this. + +Link: https://lore.kernel.org/r/1571926105-74636-6-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h +--- + drivers/scsi/hisi_sas/hisi_sas.h | 2 ++ + drivers/scsi/hisi_sas/hisi_sas_main.c | 8 ++++++++ + 2 files changed, 10 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 4b974461cb41..70af2568877d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -452,6 +453,7 @@ struct hisi_hba { + struct hisi_sas_iost *debugfs_iost; + struct hisi_sas_itct *debugfs_itct; + u64 *debugfs_iost_cache; ++ u64 debugfs_timestamp; + u64 *debugfs_itct_cache; + + struct dentry *debugfs_dir; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index bb0287eed0dc..5c761b49d0de 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -3647,6 +3647,7 @@ static const struct file_operations hisi_sas_debugfs_itct_cache_fops = { + + static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + { ++ u64 *debugfs_timestamp; + struct dentry *dump_dentry; + struct dentry *dentry; + char name[256]; +@@ -3654,11 +3655,15 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + int c; + int d; + ++ debugfs_timestamp = &hisi_hba->debugfs_timestamp; + /* Create dump dir inside device dir */ + dump_dentry = debugfs_create_dir("dump", hisi_hba->debugfs_dir); + + hisi_hba->debugfs_dump_dentry = dump_dentry; + ++ debugfs_create_u64("timestamp", 0400, dump_dentry, ++ debugfs_timestamp); ++ + debugfs_create_file("global", 0400, dump_dentry, hisi_hba, + &hisi_sas_debugfs_global_fops); + +@@ -3774,7 +3779,10 @@ void hisi_sas_debugfs_work_handler(struct work_struct *work) + { + struct hisi_hba *hisi_hba = + container_of(work, struct hisi_hba, debugfs_work); ++ u64 timestamp = local_clock(); + ++ do_div(timestamp, NSEC_PER_MSEC); ++ hisi_hba->debugfs_timestamp = timestamp; + if (hisi_hba->debugfs_snapshot) + return; + hisi_hba->debugfs_snapshot = true; +-- +2.27.0 + diff --git a/patches/0674-scsi-hisi_sas-Add-debugfs-file-structure-for-CQ.patch b/patches/0674-scsi-hisi_sas-Add-debugfs-file-structure-for-CQ.patch new file mode 100644 index 0000000..6b905a2 --- /dev/null +++ b/patches/0674-scsi-hisi_sas-Add-debugfs-file-structure-for-CQ.patch @@ -0,0 +1,141 @@ +From a40ee65a814fbc39c3434d7aa401f9a9dac0f1c7 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:13 +0800 +Subject: [PATCH 026/108] scsi: hisi_sas: Add debugfs file structure for CQ + +mainline inclusion +from mainline-v5.5-rc1 +commit 35ea630b2bad4fe9f7db34624eaab3663bb2cb42 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=35ea630b2bad4fe9f7db34624eaab3663bb2cb42 + +---------------------------------------------------------------------- + +Create a file structure which was used to save the memory address and CQ +pointer for CQ at debugfs. This structure is bound to the corresponding +debugfs file, it can help callback function of debugfs file to get what it +need. + +Link: https://lore.kernel.org/r/1571926105-74636-7-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 7 ++++++- + drivers/scsi/hisi_sas/hisi_sas_main.c | 26 ++++++++++++++------------ + 2 files changed, 20 insertions(+), 13 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 70af2568877d..8692c01c8dc3 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -367,6 +367,11 @@ struct hisi_sas_hw { + int (*set_bist)(struct hisi_hba *hisi_hba, bool enable); + }; + ++struct hisi_sas_debugfs_cq { ++ struct hisi_sas_cq *cq; ++ void *complete_hdr; ++}; ++ + struct hisi_hba { + /* This must be the first element, used by SHOST_TO_SAS_HA */ + struct sas_ha_struct *p; +@@ -448,7 +453,7 @@ struct hisi_hba { + /* Put Global AXI and RAS Register into register array */ + u32 *debugfs_regs[DEBUGFS_REGS_NUM]; + u32 *debugfs_port_reg[HISI_SAS_MAX_PHYS]; +- void *debugfs_complete_hdr[HISI_SAS_MAX_QUEUES]; ++ struct hisi_sas_debugfs_cq debugfs_cq[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_cmd_hdr *debugfs_cmd_hdr[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_iost *debugfs_iost; + struct hisi_sas_itct *debugfs_itct; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 5c761b49d0de..f3fddd1ab961 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2775,7 +2775,7 @@ static void hisi_sas_debugfs_snapshot_cq_reg(struct hisi_hba *hisi_hba) + int i; + + for (i = 0; i < hisi_hba->queue_count; i++) +- memcpy(hisi_hba->debugfs_complete_hdr[i], ++ memcpy(hisi_hba->debugfs_cq[i].complete_hdr, + hisi_hba->complete_hdr[i], + HISI_SAS_QUEUE_SLOTS * queue_entry_size); + } +@@ -3438,13 +3438,13 @@ static void hisi_sas_show_row_32(struct seq_file *s, int index, + seq_puts(s, "\n"); + } + +-static void hisi_sas_cq_show_slot(struct seq_file *s, int slot, void *cq_ptr) ++static void hisi_sas_cq_show_slot(struct seq_file *s, int slot, ++ struct hisi_sas_debugfs_cq *debugfs_cq) + { +- struct hisi_sas_cq *cq = cq_ptr; ++ struct hisi_sas_cq *cq = debugfs_cq->cq; + struct hisi_hba *hisi_hba = cq->hisi_hba; +- void *complete_queue = hisi_hba->debugfs_complete_hdr[cq->id]; + u64 offset = hisi_hba->hw->complete_hdr_size * slot; +- __le32 *complete_hdr = complete_queue + offset; ++ __le32 *complete_hdr = debugfs_cq->complete_hdr + offset; + + hisi_sas_show_row_32(s, slot, + hisi_hba->hw->complete_hdr_size, +@@ -3453,11 +3453,11 @@ static void hisi_sas_cq_show_slot(struct seq_file *s, int slot, void *cq_ptr) + + static int hisi_sas_debugfs_cq_show(struct seq_file *s, void *p) + { +- struct hisi_sas_cq *cq = s->private; ++ struct hisi_sas_debugfs_cq *debugfs_cq = s->private; + int slot; + + for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) { +- hisi_sas_cq_show_slot(s, slot, cq); ++ hisi_sas_cq_show_slot(s, slot, debugfs_cq); + } + return 0; + } +@@ -3684,7 +3684,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + snprintf(name, sizeof(name), "%d", c); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->cq[c], ++ &hisi_hba->debugfs_cq[c], + &hisi_sas_debugfs_cq_fops); + } + +@@ -3804,7 +3804,7 @@ static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) + devm_kfree(dev, hisi_hba->debugfs_cmd_hdr[i]); + + for (i = 0; i < hisi_hba->queue_count; i++) +- devm_kfree(dev, hisi_hba->debugfs_complete_hdr[i]); ++ devm_kfree(dev, hisi_hba->debugfs_cq[i].complete_hdr); + + for (i = 0; i < DEBUGFS_REGS_NUM; i++) + devm_kfree(dev, hisi_hba->debugfs_regs[i]); +@@ -3885,11 +3885,13 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + + sz = hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + for (c = 0; c < hisi_hba->queue_count; c++) { +- hisi_hba->debugfs_complete_hdr[c] = +- devm_kmalloc(dev, sz, GFP_KERNEL); ++ struct hisi_sas_debugfs_cq *cq = ++ &hisi_hba->debugfs_cq[c]; + +- if (!hisi_hba->debugfs_complete_hdr[c]) ++ cq->complete_hdr = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!cq->complete_hdr) + goto fail; ++ cq->cq = &hisi_hba->cq[c]; + } + + sz = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; +-- +2.27.0 + diff --git a/patches/0675-scsi-hisi_sas-Add-debugfs-file-structure-for-DQ.patch b/patches/0675-scsi-hisi_sas-Add-debugfs-file-structure-for-DQ.patch new file mode 100644 index 0000000..a8e1108 --- /dev/null +++ b/patches/0675-scsi-hisi_sas-Add-debugfs-file-structure-for-DQ.patch @@ -0,0 +1,121 @@ +From 5b21f7795e2009317ba8832f84149d09fd20aa2c Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:14 +0800 +Subject: [PATCH 027/108] scsi: hisi_sas: Add debugfs file structure for DQ + +mainline inclusion +from mainline-v5.5-rc1 +commit 1b54c4db725d875dcae645a3da74625b9e4b3bdf +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1b54c4db725d875dcae645a3da74625b9e4b3bdf + +---------------------------------------------------------------------- + +Create a file structure which was used to save the memory address and DQ +pointer for DQ at debugfs. This structure is bound to the corresponding +debugfs file, it can help callback function of debugfs file to get what it +need. + +Link: https://lore.kernel.org/r/1571926105-74636-8-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 7 ++++++- + drivers/scsi/hisi_sas/hisi_sas_main.c | 19 ++++++++++--------- + 2 files changed, 16 insertions(+), 10 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 8692c01c8dc3..95a29c345c30 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -372,6 +372,11 @@ struct hisi_sas_debugfs_cq { + void *complete_hdr; + }; + ++struct hisi_sas_debugfs_dq { ++ struct hisi_sas_dq *dq; ++ struct hisi_sas_cmd_hdr *hdr; ++}; ++ + struct hisi_hba { + /* This must be the first element, used by SHOST_TO_SAS_HA */ + struct sas_ha_struct *p; +@@ -454,7 +459,7 @@ struct hisi_hba { + u32 *debugfs_regs[DEBUGFS_REGS_NUM]; + u32 *debugfs_port_reg[HISI_SAS_MAX_PHYS]; + struct hisi_sas_debugfs_cq debugfs_cq[HISI_SAS_MAX_QUEUES]; +- struct hisi_sas_cmd_hdr *debugfs_cmd_hdr[HISI_SAS_MAX_QUEUES]; ++ struct hisi_sas_debugfs_dq debugfs_dq[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_iost *debugfs_iost; + struct hisi_sas_itct *debugfs_itct; + u64 *debugfs_iost_cache; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index f3fddd1ab961..fe8c998e3e9f 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2786,7 +2786,7 @@ static void hisi_sas_debugfs_snapshot_dq_reg(struct hisi_hba *hisi_hba) + int i; + + for (i = 0; i < hisi_hba->queue_count; i++) +- memcpy(hisi_hba->debugfs_cmd_hdr[i], ++ memcpy(hisi_hba->debugfs_dq[i].hdr, + hisi_hba->cmd_hdr[i], + HISI_SAS_QUEUE_SLOTS * queue_entry_size); + } +@@ -3477,9 +3477,8 @@ static const struct file_operations hisi_sas_debugfs_cq_fops = { + + static void hisi_sas_dq_show_slot(struct seq_file *s, int slot, void *dq_ptr) + { +- struct hisi_sas_dq *dq = dq_ptr; +- struct hisi_hba *hisi_hba = dq->hisi_hba; +- void *cmd_queue = hisi_hba->debugfs_cmd_hdr[dq->id]; ++ struct hisi_sas_debugfs_dq *debugfs_dq = dq_ptr; ++ void *cmd_queue = debugfs_dq->hdr; + u64 offset = sizeof(struct hisi_sas_cmd_hdr) * slot; + __le32 *cmd_hdr = cmd_queue + offset; + +@@ -3695,7 +3694,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + snprintf(name, sizeof(name), "%d", d); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->dq[d], ++ &hisi_hba->debugfs_dq[d], + &hisi_sas_debugfs_dq_fops); + } + +@@ -3801,7 +3800,7 @@ static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) + devm_kfree(dev, hisi_hba->debugfs_iost); + + for (i = 0; i < hisi_hba->queue_count; i++) +- devm_kfree(dev, hisi_hba->debugfs_cmd_hdr[i]); ++ devm_kfree(dev, hisi_hba->debugfs_dq[i].hdr); + + for (i = 0; i < hisi_hba->queue_count; i++) + devm_kfree(dev, hisi_hba->debugfs_cq[i].complete_hdr); +@@ -3896,11 +3895,13 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + + sz = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; + for (d = 0; d < hisi_hba->queue_count; d++) { +- hisi_hba->debugfs_cmd_hdr[d] = +- devm_kmalloc(dev, sz, GFP_KERNEL); ++ struct hisi_sas_debugfs_dq *dq = ++ &hisi_hba->debugfs_dq[d]; + +- if (!hisi_hba->debugfs_cmd_hdr[d]) ++ dq->hdr = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!dq->hdr) + goto fail; ++ dq->dq = &hisi_hba->dq[d]; + } + + sz = HISI_SAS_MAX_COMMANDS * sizeof(struct hisi_sas_iost); +-- +2.27.0 + diff --git a/patches/0676-scsi-hisi_sas-Add-debugfs-file-structure-for-registe.patch b/patches/0676-scsi-hisi_sas-Add-debugfs-file-structure-for-registe.patch new file mode 100644 index 0000000..841b319 --- /dev/null +++ b/patches/0676-scsi-hisi_sas-Add-debugfs-file-structure-for-registe.patch @@ -0,0 +1,224 @@ +From 693b66a39d5a6bbb82d9dab8475fbd9e42581cc1 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:15 +0800 +Subject: [PATCH 028/108] scsi: hisi_sas: Add debugfs file structure for + registers + +mainline inclusion +from mainline-v5.5-rc1 +commit c61163981076476e0bcf2d453dcddf8db605f115 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c61163981076476e0bcf2d453dcddf8db605f115 + +---------------------------------------------------------------------- + +Create a file structure which was used to save the memory address and +hisi_hba pointer for REGS at debugfs. This structure is bound to the +corresponding debugfs file, it can help callback function of debugfs file +to get what it need. + +Link: https://lore.kernel.org/r/1571926105-74636-9-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 7 ++- + drivers/scsi/hisi_sas/hisi_sas_main.c | 62 +++++++++++++-------------- + 2 files changed, 35 insertions(+), 34 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 95a29c345c30..fd8a128cf4d3 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -377,6 +377,11 @@ struct hisi_sas_debugfs_dq { + struct hisi_sas_cmd_hdr *hdr; + }; + ++struct hisi_sas_debugfs_regs { ++ struct hisi_hba *hisi_hba; ++ u32 *data; ++}; ++ + struct hisi_hba { + /* This must be the first element, used by SHOST_TO_SAS_HA */ + struct sas_ha_struct *p; +@@ -456,7 +461,7 @@ struct hisi_hba { + + /* debugfs memories */ + /* Put Global AXI and RAS Register into register array */ +- u32 *debugfs_regs[DEBUGFS_REGS_NUM]; ++ struct hisi_sas_debugfs_regs debugfs_regs[DEBUGFS_REGS_NUM]; + u32 *debugfs_port_reg[HISI_SAS_MAX_PHYS]; + struct hisi_sas_debugfs_cq debugfs_cq[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_debugfs_dq debugfs_dq[HISI_SAS_MAX_QUEUES]; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index fe8c998e3e9f..504c83e4f620 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2811,7 +2811,7 @@ static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) + { +- u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_GLOBAL]; ++ u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_GLOBAL].data; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *global = + hw->debugfs_reg_array[DEBUGFS_GLOBAL]; +@@ -2823,7 +2823,7 @@ static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) + { +- u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_AXI]; ++ u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_AXI].data; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *axi = + hw->debugfs_reg_array[DEBUGFS_AXI]; +@@ -2836,7 +2836,7 @@ static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) + { +- u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_RAS]; ++ u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_RAS].data; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *ras = + hw->debugfs_reg_array[DEBUGFS_RAS]; +@@ -2920,11 +2920,12 @@ static void hisi_sas_debugfs_print_reg(u32 *regs_val, const void *ptr, + + static int hisi_sas_debugfs_global_show(struct seq_file *s, void *p) + { +- struct hisi_hba *hisi_hba = s->private; ++ struct hisi_sas_debugfs_regs *global = s->private; ++ struct hisi_hba *hisi_hba = global->hisi_hba; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const void *reg_global = hw->debugfs_reg_array[DEBUGFS_GLOBAL]; + +- hisi_sas_debugfs_print_reg(hisi_hba->debugfs_regs[DEBUGFS_GLOBAL], ++ hisi_sas_debugfs_print_reg(global->data, + reg_global, s); + + return 0; +@@ -3328,11 +3329,12 @@ static const struct file_operations hisi_sas_debugfs_bist_enable_ops = { + + static int hisi_sas_debugfs_axi_show(struct seq_file *s, void *p) + { +- struct hisi_hba *hisi_hba = s->private; ++ struct hisi_sas_debugfs_regs *ras = s->private; ++ struct hisi_hba *hisi_hba = ras->hisi_hba; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const void *reg_axi = hw->debugfs_reg_array[DEBUGFS_AXI]; + +- hisi_sas_debugfs_print_reg(hisi_hba->debugfs_regs[DEBUGFS_AXI], ++ hisi_sas_debugfs_print_reg(ras->data, + reg_axi, s); + + return 0; +@@ -3354,11 +3356,12 @@ static const struct file_operations hisi_sas_debugfs_axi_fops = { + + static int hisi_sas_debugfs_ras_show(struct seq_file *s, void *p) + { +- struct hisi_hba *hisi_hba = s->private; ++ struct hisi_sas_debugfs_regs *ras = s->private; ++ struct hisi_hba *hisi_hba = ras->hisi_hba; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const void *reg_ras = hw->debugfs_reg_array[DEBUGFS_RAS]; + +- hisi_sas_debugfs_print_reg(hisi_hba->debugfs_regs[DEBUGFS_RAS], ++ hisi_sas_debugfs_print_reg(ras->data, + reg_ras, s); + + return 0; +@@ -3663,7 +3666,8 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + debugfs_create_u64("timestamp", 0400, dump_dentry, + debugfs_timestamp); + +- debugfs_create_file("global", 0400, dump_dentry, hisi_hba, ++ debugfs_create_file("global", 0400, dump_dentry, ++ &hisi_hba->debugfs_regs[DEBUGFS_GLOBAL], + &hisi_sas_debugfs_global_fops); + + /* Create port dir and files */ +@@ -3710,10 +3714,12 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + debugfs_create_file("itct_cache", 0400, dump_dentry, hisi_hba, + &hisi_sas_debugfs_itct_cache_fops); + +- debugfs_create_file("axi", 0400, dump_dentry, hisi_hba, ++ debugfs_create_file("axi", 0400, dump_dentry, ++ &hisi_hba->debugfs_regs[DEBUGFS_AXI], + &hisi_sas_debugfs_axi_fops); + +- debugfs_create_file("ras", 0400, dump_dentry, hisi_hba, ++ debugfs_create_file("ras", 0400, dump_dentry, ++ &hisi_hba->debugfs_regs[DEBUGFS_RAS], + &hisi_sas_debugfs_ras_fops); + + return; +@@ -3806,7 +3812,7 @@ static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) + devm_kfree(dev, hisi_hba->debugfs_cq[i].complete_hdr); + + for (i = 0; i < DEBUGFS_REGS_NUM; i++) +- devm_kfree(dev, hisi_hba->debugfs_regs[i]); ++ devm_kfree(dev, hisi_hba->debugfs_regs[i].data); + + for (i = 0; i < hisi_hba->n_phy; i++) + devm_kfree(dev, hisi_hba->debugfs_port_reg[i]); +@@ -3816,7 +3822,7 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + { + const struct hisi_sas_hw *hw = hisi_hba->hw; + struct device *dev = hisi_hba->dev; +- int p, c, d; ++ int p, c, d, r; + size_t sz; + + /* create bist structures */ +@@ -3852,12 +3858,16 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + hisi_hba, &hisi_sas_debugfs_bist_enable_ops)) + goto fail; + +- sz = hw->debugfs_reg_array[DEBUGFS_GLOBAL]->count * 4; +- hisi_hba->debugfs_regs[DEBUGFS_GLOBAL] = +- devm_kmalloc(dev, sz, GFP_KERNEL); ++ for (r = 0; r < DEBUGFS_REGS_NUM; r++) { ++ struct hisi_sas_debugfs_regs *regs = ++ &hisi_hba->debugfs_regs[r]; + +- if (!hisi_hba->debugfs_regs[DEBUGFS_GLOBAL]) +- goto fail; ++ sz = hw->debugfs_reg_array[r]->count * 4; ++ regs->data = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!regs->data) ++ goto fail; ++ regs->hisi_hba = hisi_hba; ++ } + + sz = hw->debugfs_reg_port->count * 4; + for (p = 0; p < hisi_hba->n_phy; p++) { +@@ -3868,20 +3878,6 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + goto fail; + } + +- sz = hw->debugfs_reg_array[DEBUGFS_AXI]->count * 4; +- hisi_hba->debugfs_regs[DEBUGFS_AXI] = +- devm_kmalloc(dev, sz, GFP_KERNEL); +- +- if (!hisi_hba->debugfs_regs[DEBUGFS_AXI]) +- goto fail; +- +- sz = hw->debugfs_reg_array[DEBUGFS_RAS]->count * 4; +- hisi_hba->debugfs_regs[DEBUGFS_RAS] = +- devm_kmalloc(dev, sz, GFP_KERNEL); +- +- if (!hisi_hba->debugfs_regs[DEBUGFS_RAS]) +- goto fail; +- + sz = hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + for (c = 0; c < hisi_hba->queue_count; c++) { + struct hisi_sas_debugfs_cq *cq = +-- +2.27.0 + diff --git a/patches/0677-scsi-hisi_sas-Add-debugfs-file-structure-for-port.patch b/patches/0677-scsi-hisi_sas-Add-debugfs-file-structure-for-port.patch new file mode 100644 index 0000000..72e33a6 --- /dev/null +++ b/patches/0677-scsi-hisi_sas-Add-debugfs-file-structure-for-port.patch @@ -0,0 +1,126 @@ +From 9dbbe44702be4f7bfba4ef991acf0ae5bc31d962 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:16 +0800 +Subject: [PATCH 029/108] scsi: hisi_sas: Add debugfs file structure for port + +mainline inclusion +from mainline-v5.5-rc1 +commit 1f66e1fd26bddb4c9275b61934dbaaf4b0b0bd79 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1f66e1fd26bddb4c9275b61934dbaaf4b0b0bd79 + +---------------------------------------------------------------------- + +Create a file structure which was used to save the memory address and phy +pointer for port at debugfs. This structure is bound to the corresponding +debugfs file, it can help callback function of debugfs file to get what it +need. + +Link: https://lore.kernel.org/r/1571926105-74636-10-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 7 ++++++- + drivers/scsi/hisi_sas/hisi_sas_main.c | 20 +++++++++++--------- + 2 files changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index fd8a128cf4d3..646ab7d6ad05 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -382,6 +382,11 @@ struct hisi_sas_debugfs_regs { + u32 *data; + }; + ++struct hisi_sas_debugfs_port { ++ struct hisi_sas_phy *phy; ++ u32 *data; ++}; ++ + struct hisi_hba { + /* This must be the first element, used by SHOST_TO_SAS_HA */ + struct sas_ha_struct *p; +@@ -462,7 +467,7 @@ struct hisi_hba { + /* debugfs memories */ + /* Put Global AXI and RAS Register into register array */ + struct hisi_sas_debugfs_regs debugfs_regs[DEBUGFS_REGS_NUM]; +- u32 *debugfs_port_reg[HISI_SAS_MAX_PHYS]; ++ struct hisi_sas_debugfs_port debugfs_port_reg[HISI_SAS_MAX_PHYS]; + struct hisi_sas_debugfs_cq debugfs_cq[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_debugfs_dq debugfs_dq[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_iost *debugfs_iost; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 504c83e4f620..637308372ec3 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2800,7 +2800,7 @@ static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) + u32 *databuf; + + for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) { +- databuf = (u32 *)hisi_hba->debugfs_port_reg[phy_cnt]; ++ databuf = hisi_hba->debugfs_port_reg[phy_cnt].data; + for (i = 0; i < port->count; i++, databuf++) { + offset = port->base_off + 4 * i; + *databuf = port->read_port_reg(hisi_hba, phy_cnt, +@@ -3384,13 +3384,13 @@ static const struct file_operations hisi_sas_debugfs_ras_fops = { + + static int hisi_sas_debugfs_port_show(struct seq_file *s, void *p) + { +- struct hisi_sas_phy *phy = s->private; ++ struct hisi_sas_debugfs_port *port = s->private; ++ struct hisi_sas_phy *phy = port->phy; + struct hisi_hba *hisi_hba = phy->hisi_hba; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *reg_port = hw->debugfs_reg_port; +- u32 *databuf = hisi_hba->debugfs_port_reg[phy->sas_phy.id]; + +- hisi_sas_debugfs_print_reg(databuf, reg_port, s); ++ hisi_sas_debugfs_print_reg(port->data, reg_port, s); + + return 0; + } +@@ -3676,7 +3676,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + for (p = 0; p < hisi_hba->n_phy; p++) { + snprintf(name, sizeof(name), "%d", p); + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->phy[p], ++ &hisi_hba->debugfs_port_reg[p], + &hisi_sas_debugfs_port_fops); + } + +@@ -3815,7 +3815,7 @@ static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) + devm_kfree(dev, hisi_hba->debugfs_regs[i].data); + + for (i = 0; i < hisi_hba->n_phy; i++) +- devm_kfree(dev, hisi_hba->debugfs_port_reg[i]); ++ devm_kfree(dev, hisi_hba->debugfs_port_reg[i].data); + } + + static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) +@@ -3871,11 +3871,13 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + + sz = hw->debugfs_reg_port->count * 4; + for (p = 0; p < hisi_hba->n_phy; p++) { +- hisi_hba->debugfs_port_reg[p] = +- devm_kmalloc(dev, sz, GFP_KERNEL); ++ struct hisi_sas_debugfs_port *port = ++ &hisi_hba->debugfs_port_reg[p]; + +- if (!hisi_hba->debugfs_port_reg[p]) ++ port->data = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!port->data) + goto fail; ++ port->phy = &hisi_hba->phy[p]; + } + + sz = hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; +-- +2.27.0 + diff --git a/patches/0678-scsi-hisi_sas-Add-debugfs-file-structure-for-IOST.patch b/patches/0678-scsi-hisi_sas-Add-debugfs-file-structure-for-IOST.patch new file mode 100644 index 0000000..cb9b3cf --- /dev/null +++ b/patches/0678-scsi-hisi_sas-Add-debugfs-file-structure-for-IOST.patch @@ -0,0 +1,119 @@ +From 989f21b61f1c4ad5b7ed36e55ef00e30dc9f6861 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:17 +0800 +Subject: [PATCH 030/108] scsi: hisi_sas: Add debugfs file structure for IOST + +mainline inclusion +from mainline-v5.5-rc1 +commit e15f2e2dff5b809dce923839f21362d6b0d06b1e +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e15f2e2dff5b809dce923839f21362d6b0d06b1e + +---------------------------------------------------------------------- + +Create a file structure which was used to save the memory address for IOST +at debugfs. This structure is bound to the corresponding debugfs file, it +can help callback function of debugfs file to get what it needs. + +Link: https://lore.kernel.org/r/1571926105-74636-11-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 6 +++++- + drivers/scsi/hisi_sas/hisi_sas_main.c | 21 +++++++++++---------- + 2 files changed, 16 insertions(+), 11 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 646ab7d6ad05..efedf889b91c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -387,6 +387,10 @@ struct hisi_sas_debugfs_port { + u32 *data; + }; + ++struct hisi_sas_debugfs_iost { ++ struct hisi_sas_iost *iost; ++}; ++ + struct hisi_hba { + /* This must be the first element, used by SHOST_TO_SAS_HA */ + struct sas_ha_struct *p; +@@ -470,7 +474,7 @@ struct hisi_hba { + struct hisi_sas_debugfs_port debugfs_port_reg[HISI_SAS_MAX_PHYS]; + struct hisi_sas_debugfs_cq debugfs_cq[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_debugfs_dq debugfs_dq[HISI_SAS_MAX_QUEUES]; +- struct hisi_sas_iost *debugfs_iost; ++ struct hisi_sas_debugfs_iost debugfs_iost; + struct hisi_sas_itct *debugfs_itct; + u64 *debugfs_iost_cache; + u64 debugfs_timestamp; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 637308372ec3..4edecfc3e7b7 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2869,7 +2869,7 @@ static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba) + { + int max_command_entries = HISI_SAS_MAX_COMMANDS; + void *cachebuf = hisi_hba->debugfs_iost_cache; +- void *databuf = hisi_hba->debugfs_iost; ++ void *databuf = hisi_hba->debugfs_iost.iost; + struct hisi_sas_iost *iost; + int i; + +@@ -3513,14 +3513,14 @@ static const struct file_operations hisi_sas_debugfs_dq_fops = { + + static int hisi_sas_debugfs_iost_show(struct seq_file *s, void *p) + { +- struct hisi_hba *hisi_hba = s->private; +- struct hisi_sas_iost *debugfs_iost = hisi_hba->debugfs_iost; ++ struct hisi_sas_debugfs_iost *debugfs_iost = s->private; ++ struct hisi_sas_iost *iost = debugfs_iost->iost; + int i, max_command_entries = HISI_SAS_MAX_COMMANDS; + +- for (i = 0; i < max_command_entries; i++, debugfs_iost++) { +- __le64 *iost = &debugfs_iost->qw0; ++ for (i = 0; i < max_command_entries; i++, iost++) { ++ __le64 *data = &iost->qw0; + +- hisi_sas_show_row_64(s, i, sizeof(*debugfs_iost), iost); ++ hisi_sas_show_row_64(s, i, sizeof(*iost), data); + } + + return 0; +@@ -3702,7 +3702,8 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + &hisi_sas_debugfs_dq_fops); + } + +- debugfs_create_file("iost", 0400, dump_dentry, hisi_hba, ++ debugfs_create_file("iost", 0400, dump_dentry, ++ &hisi_hba->debugfs_iost, + &hisi_sas_debugfs_iost_fops); + + debugfs_create_file("iost_cache", 0400, dump_dentry, hisi_hba, +@@ -3803,7 +3804,7 @@ static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) + + devm_kfree(dev, hisi_hba->debugfs_iost_cache); + devm_kfree(dev, hisi_hba->debugfs_itct_cache); +- devm_kfree(dev, hisi_hba->debugfs_iost); ++ devm_kfree(dev, hisi_hba->debugfs_iost.iost); + + for (i = 0; i < hisi_hba->queue_count; i++) + devm_kfree(dev, hisi_hba->debugfs_dq[i].hdr); +@@ -3904,8 +3905,8 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + + sz = HISI_SAS_MAX_COMMANDS * sizeof(struct hisi_sas_iost); + +- hisi_hba->debugfs_iost = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_iost) ++ hisi_hba->debugfs_iost.iost = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_iost.iost) + goto fail; + + sz = HISI_SAS_IOST_ITCT_CACHE_NUM * +-- +2.27.0 + diff --git a/patches/0679-scsi-hisi_sas-Add-debugfs-file-structure-for-ITCT.patch b/patches/0679-scsi-hisi_sas-Add-debugfs-file-structure-for-ITCT.patch new file mode 100644 index 0000000..9efe789 --- /dev/null +++ b/patches/0679-scsi-hisi_sas-Add-debugfs-file-structure-for-ITCT.patch @@ -0,0 +1,132 @@ +From df452ec00576ff7201a4234b32bec1d760799ca7 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:18 +0800 +Subject: [PATCH 031/108] scsi: hisi_sas: Add debugfs file structure for ITCT + +mainline inclusion +from mainline-v5.5-rc1 +commit 0161d55f23a1e020e5e6892177caf92a61e5c161 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0161d55f23a1e020e5e6892177caf92a61e5c161 + +---------------------------------------------------------------------- + +Create a file structure which was used to save the memory address for ITCT +at debugfs. This structure is bound to the corresponding debugfs file, it +can help callback function of debugfs file to get what it needs. + +Link: https://lore.kernel.org/r/1571926105-74636-12-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 6 +++++- + drivers/scsi/hisi_sas/hisi_sas_main.c | 25 +++++++++++++------------ + 2 files changed, 18 insertions(+), 13 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index efedf889b91c..97ca00c2ece4 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -391,6 +391,10 @@ struct hisi_sas_debugfs_iost { + struct hisi_sas_iost *iost; + }; + ++struct hisi_sas_debugfs_itct { ++ struct hisi_sas_itct *itct; ++}; ++ + struct hisi_hba { + /* This must be the first element, used by SHOST_TO_SAS_HA */ + struct sas_ha_struct *p; +@@ -475,7 +479,7 @@ struct hisi_hba { + struct hisi_sas_debugfs_cq debugfs_cq[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_debugfs_dq debugfs_dq[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_debugfs_iost debugfs_iost; +- struct hisi_sas_itct *debugfs_itct; ++ struct hisi_sas_debugfs_itct debugfs_itct; + u64 *debugfs_iost_cache; + u64 debugfs_timestamp; + u64 *debugfs_itct_cache; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 4edecfc3e7b7..69efd0639964 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1630,7 +1630,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) + if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + return -EPERM; + +- if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct) ++ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct.itct) + hisi_hba->hw->debugfs_work_handler(&hisi_hba->debugfs_work); + + dev_info(dev, "controller resetting...\n"); +@@ -2131,7 +2131,7 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + + /* Internal abort timed out */ + if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { +- if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct) ++ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct.itct) + queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); + + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { +@@ -2850,7 +2850,7 @@ static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) + static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + { + void *cachebuf = hisi_hba->debugfs_itct_cache; +- void *databuf = hisi_hba->debugfs_itct; ++ void *databuf = hisi_hba->debugfs_itct.itct; + struct hisi_sas_itct *itct; + int i; + +@@ -3582,13 +3582,13 @@ static const struct file_operations hisi_sas_debugfs_iost_cache_fops = { + static int hisi_sas_debugfs_itct_show(struct seq_file *s, void *p) + { + int i; +- struct hisi_hba *hisi_hba = s->private; +- struct hisi_sas_itct *debugfs_itct = hisi_hba->debugfs_itct; ++ struct hisi_sas_debugfs_itct *debugfs_itct = s->private; ++ struct hisi_sas_itct *itct = debugfs_itct->itct; + +- for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, debugfs_itct++) { +- __le64 *itct = &debugfs_itct->qw0; ++ for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) { ++ __le64 *data = &itct->qw0; + +- hisi_sas_show_row_64(s, i, sizeof(*debugfs_itct), itct); ++ hisi_sas_show_row_64(s, i, sizeof(*itct), data); + } + + return 0; +@@ -3709,8 +3709,9 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + debugfs_create_file("iost_cache", 0400, dump_dentry, hisi_hba, + &hisi_sas_debugfs_iost_cache_fops); + +- debugfs_create_file("itct", 0400, dump_dentry, hisi_hba, +- &hisi_sas_debugfs_itct_fops); ++ debugfs_create_file("itct", 0400, dump_dentry, ++ &hisi_hba->debugfs_itct, ++ &hisi_sas_debugfs_itct_fops); + + debugfs_create_file("itct_cache", 0400, dump_dentry, hisi_hba, + &hisi_sas_debugfs_itct_cache_fops); +@@ -3926,8 +3927,8 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + /* New memory allocation must be locate before itct */ + sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); + +- hisi_hba->debugfs_itct = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_itct) ++ hisi_hba->debugfs_itct.itct = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_itct.itct) + goto fail; + + return 0; +-- +2.27.0 + diff --git a/patches/0680-scsi-hisi_sas-Add-debugfs-file-structure-for-IOST-ca.patch b/patches/0680-scsi-hisi_sas-Add-debugfs-file-structure-for-IOST-ca.patch new file mode 100644 index 0000000..55cc04d --- /dev/null +++ b/patches/0680-scsi-hisi_sas-Add-debugfs-file-structure-for-IOST-ca.patch @@ -0,0 +1,113 @@ +From c5497e230789548ae6a7fe4e54dd16607038db49 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:19 +0800 +Subject: [PATCH 032/108] scsi: hisi_sas: Add debugfs file structure for IOST + cache + +mainline inclusion +from mainline-v5.5-rc1 +commit b714dd8f36dc609dd4b0078cf5563978134838ed +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b714dd8f36dc609dd4b0078cf5563978134838ed + +---------------------------------------------------------------------- + +Create a file structure which was used to save the memory address for IOST +cache at debugfs. This structure is bound to the corresponding debugfs +file, it can help callback function of debugfs file to get what it needs. + +Link: https://lore.kernel.org/r/1571926105-74636-13-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 6 +++++- + drivers/scsi/hisi_sas/hisi_sas_main.c | 16 ++++++++-------- + 2 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 97ca00c2ece4..729eb47f1d5d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -395,6 +395,10 @@ struct hisi_sas_debugfs_itct { + struct hisi_sas_itct *itct; + }; + ++struct hisi_sas_debugfs_iost_cache { ++ struct hisi_sas_iost_itct_cache *cache; ++}; ++ + struct hisi_hba { + /* This must be the first element, used by SHOST_TO_SAS_HA */ + struct sas_ha_struct *p; +@@ -480,8 +484,8 @@ struct hisi_hba { + struct hisi_sas_debugfs_dq debugfs_dq[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_debugfs_iost debugfs_iost; + struct hisi_sas_debugfs_itct debugfs_itct; +- u64 *debugfs_iost_cache; + u64 debugfs_timestamp; ++ struct hisi_sas_debugfs_iost_cache debugfs_iost_cache; + u64 *debugfs_itct_cache; + + struct dentry *debugfs_dir; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 69efd0639964..30f6cd0fc190 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2868,7 +2868,7 @@ static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba) + { + int max_command_entries = HISI_SAS_MAX_COMMANDS; +- void *cachebuf = hisi_hba->debugfs_iost_cache; ++ void *cachebuf = hisi_hba->debugfs_iost_cache.cache; + void *databuf = hisi_hba->debugfs_iost.iost; + struct hisi_sas_iost *iost; + int i; +@@ -3541,9 +3541,8 @@ static const struct file_operations hisi_sas_debugfs_iost_fops = { + + static int hisi_sas_debugfs_iost_cache_show(struct seq_file *s, void *p) + { +- struct hisi_hba *hisi_hba = s->private; +- struct hisi_sas_iost_itct_cache *iost_cache = +- (struct hisi_sas_iost_itct_cache *)hisi_hba->debugfs_iost_cache; ++ struct hisi_sas_debugfs_iost_cache *debugfs_iost_cache = s->private; ++ struct hisi_sas_iost_itct_cache *iost_cache = debugfs_iost_cache->cache; + u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; + int i, tab_idx; + __le64 *iost; +@@ -3706,7 +3705,8 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + &hisi_hba->debugfs_iost, + &hisi_sas_debugfs_iost_fops); + +- debugfs_create_file("iost_cache", 0400, dump_dentry, hisi_hba, ++ debugfs_create_file("iost_cache", 0400, dump_dentry, ++ &hisi_hba->debugfs_iost_cache, + &hisi_sas_debugfs_iost_cache_fops); + + debugfs_create_file("itct", 0400, dump_dentry, +@@ -3803,7 +3803,7 @@ static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) + struct device *dev = hisi_hba->dev; + int i; + +- devm_kfree(dev, hisi_hba->debugfs_iost_cache); ++ devm_kfree(dev, hisi_hba->debugfs_iost_cache.cache); + devm_kfree(dev, hisi_hba->debugfs_itct_cache); + devm_kfree(dev, hisi_hba->debugfs_iost.iost); + +@@ -3913,8 +3913,8 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + sz = HISI_SAS_IOST_ITCT_CACHE_NUM * + sizeof(struct hisi_sas_iost_itct_cache); + +- hisi_hba->debugfs_iost_cache = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_iost_cache) ++ hisi_hba->debugfs_iost_cache.cache = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_iost_cache.cache) + goto fail; + + sz = HISI_SAS_IOST_ITCT_CACHE_NUM * +-- +2.27.0 + diff --git a/patches/0681-scsi-hisi_sas-Add-debugfs-file-structure-for-ITCT-ca.patch b/patches/0681-scsi-hisi_sas-Add-debugfs-file-structure-for-ITCT-ca.patch new file mode 100644 index 0000000..b99859d --- /dev/null +++ b/patches/0681-scsi-hisi_sas-Add-debugfs-file-structure-for-ITCT-ca.patch @@ -0,0 +1,112 @@ +From 796db3815987915dbc3e60bcf1b4605413040b0c Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:20 +0800 +Subject: [PATCH 033/108] scsi: hisi_sas: Add debugfs file structure for ITCT + cache + +mainline inclusion +from mainline-v5.5-rc1 +commit 357e4fc7a933ed5bfbf1eb2fad9c198afe6a11e1 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=357e4fc7a933ed5bfbf1eb2fad9c198afe6a11e1 + +---------------------------------------------------------------------- + +Create a file structure which was used to save the memory address for +ITCT cache at debugfs. This structure is bound to the corresponding debugfs +file, it can help callback function of debugfs file to get what it needs. + +Link: https://lore.kernel.org/r/1571926105-74636-14-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 6 +++++- + drivers/scsi/hisi_sas/hisi_sas_main.c | 16 ++++++++-------- + 2 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 729eb47f1d5d..505d74780eab 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -399,6 +399,10 @@ struct hisi_sas_debugfs_iost_cache { + struct hisi_sas_iost_itct_cache *cache; + }; + ++struct hisi_sas_debugfs_itct_cache { ++ struct hisi_sas_iost_itct_cache *cache; ++}; ++ + struct hisi_hba { + /* This must be the first element, used by SHOST_TO_SAS_HA */ + struct sas_ha_struct *p; +@@ -486,7 +490,7 @@ struct hisi_hba { + struct hisi_sas_debugfs_itct debugfs_itct; + u64 debugfs_timestamp; + struct hisi_sas_debugfs_iost_cache debugfs_iost_cache; +- u64 *debugfs_itct_cache; ++ struct hisi_sas_debugfs_itct_cache debugfs_itct_cache; + + struct dentry *debugfs_dir; + struct dentry *debugfs_dump_dentry; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 30f6cd0fc190..e218a95cfd38 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2849,7 +2849,7 @@ static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + { +- void *cachebuf = hisi_hba->debugfs_itct_cache; ++ void *cachebuf = hisi_hba->debugfs_itct_cache.cache; + void *databuf = hisi_hba->debugfs_itct.itct; + struct hisi_sas_itct *itct; + int i; +@@ -3608,9 +3608,8 @@ static const struct file_operations hisi_sas_debugfs_itct_fops = { + + static int hisi_sas_debugfs_itct_cache_show(struct seq_file *s, void *p) + { +- struct hisi_hba *hisi_hba = s->private; +- struct hisi_sas_iost_itct_cache *itct_cache = +- (struct hisi_sas_iost_itct_cache *)hisi_hba->debugfs_itct_cache; ++ struct hisi_sas_debugfs_itct_cache *debugfs_itct_cache = s->private; ++ struct hisi_sas_iost_itct_cache *itct_cache = debugfs_itct_cache->cache; + u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; + int i, tab_idx; + __le64 *itct; +@@ -3713,7 +3712,8 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + &hisi_hba->debugfs_itct, + &hisi_sas_debugfs_itct_fops); + +- debugfs_create_file("itct_cache", 0400, dump_dentry, hisi_hba, ++ debugfs_create_file("itct_cache", 0400, dump_dentry, ++ &hisi_hba->debugfs_itct_cache, + &hisi_sas_debugfs_itct_cache_fops); + + debugfs_create_file("axi", 0400, dump_dentry, +@@ -3804,7 +3804,7 @@ static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) + int i; + + devm_kfree(dev, hisi_hba->debugfs_iost_cache.cache); +- devm_kfree(dev, hisi_hba->debugfs_itct_cache); ++ devm_kfree(dev, hisi_hba->debugfs_itct_cache.cache); + devm_kfree(dev, hisi_hba->debugfs_iost.iost); + + for (i = 0; i < hisi_hba->queue_count; i++) +@@ -3920,8 +3920,8 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + sz = HISI_SAS_IOST_ITCT_CACHE_NUM * + sizeof(struct hisi_sas_iost_itct_cache); + +- hisi_hba->debugfs_itct_cache = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_itct_cache) ++ hisi_hba->debugfs_itct_cache.cache = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_itct_cache.cache) + goto fail; + + /* New memory allocation must be locate before itct */ +-- +2.27.0 + diff --git a/patches/0682-scsi-hisi_sas-Allocate-memory-for-multiple-dumps-of-.patch b/patches/0682-scsi-hisi_sas-Allocate-memory-for-multiple-dumps-of-.patch new file mode 100644 index 0000000..a32be24 --- /dev/null +++ b/patches/0682-scsi-hisi_sas-Allocate-memory-for-multiple-dumps-of-.patch @@ -0,0 +1,403 @@ +From 7217b601a76b1e50cce369dfa3cc0f02254c3af4 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:21 +0800 +Subject: [PATCH 034/108] scsi: hisi_sas: Allocate memory for multiple dumps of + debugfs + +mainline inclusion +from mainline-v5.5-rc1 +commit a70e33eae363e6f3e2ad9498daaccd231790f7f5 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a70e33eae363e6f3e2ad9498daaccd231790f7f5 + +---------------------------------------------------------------------- + +We add multiple dumps for debugfs, but only allocate memory this time and +only dump #0. + +Link: https://lore.kernel.org/r/1571926105-74636-15-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 25 ++++-- + drivers/scsi/hisi_sas/hisi_sas_main.c | 111 ++++++++++++++------------ + 2 files changed, 79 insertions(+), 57 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 505d74780eab..785f0c3f7cb9 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -367,6 +367,8 @@ struct hisi_sas_hw { + int (*set_bist)(struct hisi_hba *hisi_hba, bool enable); + }; + ++#define HISI_SAS_MAX_DEBUGFS_DUMP (50) ++ + struct hisi_sas_debugfs_cq { + struct hisi_sas_cq *cq; + void *complete_hdr; +@@ -482,15 +484,22 @@ struct hisi_hba { + + /* debugfs memories */ + /* Put Global AXI and RAS Register into register array */ +- struct hisi_sas_debugfs_regs debugfs_regs[DEBUGFS_REGS_NUM]; +- struct hisi_sas_debugfs_port debugfs_port_reg[HISI_SAS_MAX_PHYS]; +- struct hisi_sas_debugfs_cq debugfs_cq[HISI_SAS_MAX_QUEUES]; +- struct hisi_sas_debugfs_dq debugfs_dq[HISI_SAS_MAX_QUEUES]; +- struct hisi_sas_debugfs_iost debugfs_iost; +- struct hisi_sas_debugfs_itct debugfs_itct; ++ struct hisi_sas_debugfs_regs ++ debugfs_regs[HISI_SAS_MAX_DEBUGFS_DUMP][DEBUGFS_REGS_NUM]; ++ struct hisi_sas_debugfs_port ++ debugfs_port_reg[HISI_SAS_MAX_DEBUGFS_DUMP][HISI_SAS_MAX_PHYS]; ++ struct hisi_sas_debugfs_cq ++ debugfs_cq[HISI_SAS_MAX_DEBUGFS_DUMP][HISI_SAS_MAX_QUEUES]; ++ struct hisi_sas_debugfs_dq ++ debugfs_dq[HISI_SAS_MAX_DEBUGFS_DUMP][HISI_SAS_MAX_QUEUES]; ++ struct hisi_sas_debugfs_iost debugfs_iost[HISI_SAS_MAX_DEBUGFS_DUMP]; ++ struct hisi_sas_debugfs_itct debugfs_itct[HISI_SAS_MAX_DEBUGFS_DUMP]; ++ struct hisi_sas_debugfs_iost_cache ++ debugfs_iost_cache[HISI_SAS_MAX_DEBUGFS_DUMP]; ++ struct hisi_sas_debugfs_itct_cache ++ debugfs_itct_cache[HISI_SAS_MAX_DEBUGFS_DUMP]; ++ + u64 debugfs_timestamp; +- struct hisi_sas_debugfs_iost_cache debugfs_iost_cache; +- struct hisi_sas_debugfs_itct_cache debugfs_itct_cache; + + struct dentry *debugfs_dir; + struct dentry *debugfs_dump_dentry; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index e218a95cfd38..4f9fd39991fc 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1630,7 +1630,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) + if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + return -EPERM; + +- if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct.itct) ++ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) + hisi_hba->hw->debugfs_work_handler(&hisi_hba->debugfs_work); + + dev_info(dev, "controller resetting...\n"); +@@ -2131,7 +2131,7 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + + /* Internal abort timed out */ + if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { +- if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct.itct) ++ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) + queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); + + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { +@@ -2775,7 +2775,7 @@ static void hisi_sas_debugfs_snapshot_cq_reg(struct hisi_hba *hisi_hba) + int i; + + for (i = 0; i < hisi_hba->queue_count; i++) +- memcpy(hisi_hba->debugfs_cq[i].complete_hdr, ++ memcpy(hisi_hba->debugfs_cq[0][i].complete_hdr, + hisi_hba->complete_hdr[i], + HISI_SAS_QUEUE_SLOTS * queue_entry_size); + } +@@ -2786,7 +2786,7 @@ static void hisi_sas_debugfs_snapshot_dq_reg(struct hisi_hba *hisi_hba) + int i; + + for (i = 0; i < hisi_hba->queue_count; i++) +- memcpy(hisi_hba->debugfs_dq[i].hdr, ++ memcpy(hisi_hba->debugfs_dq[0][i].hdr, + hisi_hba->cmd_hdr[i], + HISI_SAS_QUEUE_SLOTS * queue_entry_size); + } +@@ -2800,7 +2800,7 @@ static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) + u32 *databuf; + + for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) { +- databuf = hisi_hba->debugfs_port_reg[phy_cnt].data; ++ databuf = hisi_hba->debugfs_port_reg[0][phy_cnt].data; + for (i = 0; i < port->count; i++, databuf++) { + offset = port->base_off + 4 * i; + *databuf = port->read_port_reg(hisi_hba, phy_cnt, +@@ -2811,7 +2811,7 @@ static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) + { +- u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_GLOBAL].data; ++ u32 *databuf = hisi_hba->debugfs_regs[0][DEBUGFS_GLOBAL].data; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *global = + hw->debugfs_reg_array[DEBUGFS_GLOBAL]; +@@ -2823,7 +2823,7 @@ static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) + { +- u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_AXI].data; ++ u32 *databuf = hisi_hba->debugfs_regs[0][DEBUGFS_AXI].data; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *axi = + hw->debugfs_reg_array[DEBUGFS_AXI]; +@@ -2836,7 +2836,7 @@ static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) + { +- u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_RAS].data; ++ u32 *databuf = hisi_hba->debugfs_regs[0][DEBUGFS_RAS].data; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *ras = + hw->debugfs_reg_array[DEBUGFS_RAS]; +@@ -2849,8 +2849,8 @@ static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + { +- void *cachebuf = hisi_hba->debugfs_itct_cache.cache; +- void *databuf = hisi_hba->debugfs_itct.itct; ++ void *cachebuf = hisi_hba->debugfs_itct_cache[0].cache; ++ void *databuf = hisi_hba->debugfs_itct[0].itct; + struct hisi_sas_itct *itct; + int i; + +@@ -2868,8 +2868,8 @@ static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba) + { + int max_command_entries = HISI_SAS_MAX_COMMANDS; +- void *cachebuf = hisi_hba->debugfs_iost_cache.cache; +- void *databuf = hisi_hba->debugfs_iost.iost; ++ void *cachebuf = hisi_hba->debugfs_iost_cache[0].cache; ++ void *databuf = hisi_hba->debugfs_iost[0].iost; + struct hisi_sas_iost *iost; + int i; + +@@ -3665,7 +3665,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + debugfs_timestamp); + + debugfs_create_file("global", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[DEBUGFS_GLOBAL], ++ &hisi_hba->debugfs_regs[0][DEBUGFS_GLOBAL], + &hisi_sas_debugfs_global_fops); + + /* Create port dir and files */ +@@ -3674,7 +3674,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + for (p = 0; p < hisi_hba->n_phy; p++) { + snprintf(name, sizeof(name), "%d", p); + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_port_reg[p], ++ &hisi_hba->debugfs_port_reg[0][p], + &hisi_sas_debugfs_port_fops); + } + +@@ -3685,7 +3685,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + snprintf(name, sizeof(name), "%d", c); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_cq[c], ++ &hisi_hba->debugfs_cq[0][c], + &hisi_sas_debugfs_cq_fops); + } + +@@ -3696,32 +3696,32 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + snprintf(name, sizeof(name), "%d", d); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_dq[d], ++ &hisi_hba->debugfs_dq[0][d], + &hisi_sas_debugfs_dq_fops); + } + + debugfs_create_file("iost", 0400, dump_dentry, +- &hisi_hba->debugfs_iost, ++ &hisi_hba->debugfs_iost[0], + &hisi_sas_debugfs_iost_fops); + + debugfs_create_file("iost_cache", 0400, dump_dentry, +- &hisi_hba->debugfs_iost_cache, ++ &hisi_hba->debugfs_iost_cache[0], + &hisi_sas_debugfs_iost_cache_fops); + + debugfs_create_file("itct", 0400, dump_dentry, +- &hisi_hba->debugfs_itct, ++ &hisi_hba->debugfs_itct[0], + &hisi_sas_debugfs_itct_fops); + + debugfs_create_file("itct_cache", 0400, dump_dentry, +- &hisi_hba->debugfs_itct_cache, ++ &hisi_hba->debugfs_itct_cache[0], + &hisi_sas_debugfs_itct_cache_fops); + + debugfs_create_file("axi", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[DEBUGFS_AXI], ++ &hisi_hba->debugfs_regs[0][DEBUGFS_AXI], + &hisi_sas_debugfs_axi_fops); + + debugfs_create_file("ras", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[DEBUGFS_RAS], ++ &hisi_hba->debugfs_regs[0][DEBUGFS_RAS], + &hisi_sas_debugfs_ras_fops); + + return; +@@ -3798,33 +3798,35 @@ void hisi_sas_debugfs_work_handler(struct work_struct *work) + } + EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler); + +-static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) ++static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba, int dump_index) + { + struct device *dev = hisi_hba->dev; + int i; + +- devm_kfree(dev, hisi_hba->debugfs_iost_cache.cache); +- devm_kfree(dev, hisi_hba->debugfs_itct_cache.cache); +- devm_kfree(dev, hisi_hba->debugfs_iost.iost); ++ devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache); ++ devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache); ++ devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost); ++ devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct); + + for (i = 0; i < hisi_hba->queue_count; i++) +- devm_kfree(dev, hisi_hba->debugfs_dq[i].hdr); ++ devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr); + + for (i = 0; i < hisi_hba->queue_count; i++) +- devm_kfree(dev, hisi_hba->debugfs_cq[i].complete_hdr); ++ devm_kfree(dev, ++ hisi_hba->debugfs_cq[dump_index][i].complete_hdr); + + for (i = 0; i < DEBUGFS_REGS_NUM; i++) +- devm_kfree(dev, hisi_hba->debugfs_regs[i].data); ++ devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data); + + for (i = 0; i < hisi_hba->n_phy; i++) +- devm_kfree(dev, hisi_hba->debugfs_port_reg[i].data); ++ devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data); + } + +-static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) ++static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba, int dump_index) + { + const struct hisi_sas_hw *hw = hisi_hba->hw; + struct device *dev = hisi_hba->dev; +- int p, c, d, r; ++ int p, c, d, r, i; + size_t sz; + + /* create bist structures */ +@@ -3862,7 +3864,7 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + + for (r = 0; r < DEBUGFS_REGS_NUM; r++) { + struct hisi_sas_debugfs_regs *regs = +- &hisi_hba->debugfs_regs[r]; ++ &hisi_hba->debugfs_regs[dump_index][r]; + + sz = hw->debugfs_reg_array[r]->count * 4; + regs->data = devm_kmalloc(dev, sz, GFP_KERNEL); +@@ -3874,7 +3876,7 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + sz = hw->debugfs_reg_port->count * 4; + for (p = 0; p < hisi_hba->n_phy; p++) { + struct hisi_sas_debugfs_port *port = +- &hisi_hba->debugfs_port_reg[p]; ++ &hisi_hba->debugfs_port_reg[dump_index][p]; + + port->data = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!port->data) +@@ -3885,7 +3887,7 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + sz = hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; + for (c = 0; c < hisi_hba->queue_count; c++) { + struct hisi_sas_debugfs_cq *cq = +- &hisi_hba->debugfs_cq[c]; ++ &hisi_hba->debugfs_cq[dump_index][c]; + + cq->complete_hdr = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!cq->complete_hdr) +@@ -3896,7 +3898,7 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + sz = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; + for (d = 0; d < hisi_hba->queue_count; d++) { + struct hisi_sas_debugfs_dq *dq = +- &hisi_hba->debugfs_dq[d]; ++ &hisi_hba->debugfs_dq[dump_index][d]; + + dq->hdr = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!dq->hdr) +@@ -3906,40 +3908,46 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) + + sz = HISI_SAS_MAX_COMMANDS * sizeof(struct hisi_sas_iost); + +- hisi_hba->debugfs_iost.iost = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_iost.iost) ++ hisi_hba->debugfs_iost[dump_index].iost = ++ devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_iost[dump_index].iost) + goto fail; + + sz = HISI_SAS_IOST_ITCT_CACHE_NUM * + sizeof(struct hisi_sas_iost_itct_cache); + +- hisi_hba->debugfs_iost_cache.cache = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_iost_cache.cache) ++ hisi_hba->debugfs_iost_cache[dump_index].cache = ++ devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_iost_cache[dump_index].cache) + goto fail; + + sz = HISI_SAS_IOST_ITCT_CACHE_NUM * + sizeof(struct hisi_sas_iost_itct_cache); + +- hisi_hba->debugfs_itct_cache.cache = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_itct_cache.cache) ++ hisi_hba->debugfs_itct_cache[dump_index].cache = ++ devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_itct_cache[dump_index].cache) + goto fail; + + /* New memory allocation must be locate before itct */ + sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); + +- hisi_hba->debugfs_itct.itct = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_itct.itct) ++ hisi_hba->debugfs_itct[dump_index].itct = ++ devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_itct[dump_index].itct) + goto fail; + + return 0; + fail: +- hisi_sas_debugfs_release(hisi_hba); ++ for (i = 0; i < HISI_SAS_MAX_DEBUGFS_DUMP; i++) ++ hisi_sas_debugfs_release(hisi_hba, i); + return -ENOMEM; + } + + void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; ++ int i; + + hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), + hisi_sas_debugfs_dir); +@@ -3948,11 +3956,16 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + hisi_hba, + &hisi_sas_debugfs_trigger_dump_fops); + +- if (hisi_sas_debugfs_alloc(hisi_hba)) { +- debugfs_remove_recursive(hisi_hba->debugfs_dir); +- dev_dbg(dev, "failed to init debugfs!\n"); +- } ++ hisi_hba->debugfs_dump_dentry = ++ debugfs_create_dir("dump", hisi_hba->debugfs_dir); + ++ for (i = 0; i < HISI_SAS_MAX_DEBUGFS_DUMP; i++) { ++ if (hisi_sas_debugfs_alloc(hisi_hba, i)) { ++ debugfs_remove_recursive(hisi_hba->debugfs_dir); ++ dev_dbg(dev, "failed to init debugfs!\n"); ++ break; ++ } ++ } + } + EXPORT_SYMBOL_GPL(hisi_sas_debugfs_init); + +-- +2.27.0 + diff --git a/patches/0683-scsi-hisi_sas-Add-module-parameter-for-debugfs-dump-.patch b/patches/0683-scsi-hisi_sas-Add-module-parameter-for-debugfs-dump-.patch new file mode 100644 index 0000000..dddb1d9 --- /dev/null +++ b/patches/0683-scsi-hisi_sas-Add-module-parameter-for-debugfs-dump-.patch @@ -0,0 +1,91 @@ +From 8a3c2ddfe0c3cb15b17c5436f98c4a5809f6ad1f Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:22 +0800 +Subject: [PATCH 035/108] scsi: hisi_sas: Add module parameter for debugfs dump + count + +mainline inclusion +from mainline-v5.5-rc1 +commit 905ab01faf5fc81ba2fc46dddcd21ad5a2dd137b +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=905ab01faf5fc81ba2fc46dddcd21ad5a2dd137b + +---------------------------------------------------------------------- + +We still only use dump index #0 however. + +Link: https://lore.kernel.org/r/1571926105-74636-16-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 + + drivers/scsi/hisi_sas/hisi_sas_main.c | 16 +++++++++++++--- + 2 files changed, 14 insertions(+), 3 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 785f0c3f7cb9..5604e6d7bc25 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -649,6 +649,7 @@ struct hisi_sas_slot_dif_buf_table { + }; + + extern bool hisi_sas_debugfs_enable; ++extern u32 hisi_sas_debugfs_dump_count; + extern struct dentry *hisi_sas_debugfs_dir; + extern int skip_bus_flag; + extern struct scsi_transport_template *hisi_sas_stt; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 4f9fd39991fc..ab7e07f1ed51 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -3939,7 +3939,7 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba, int dump_index) + + return 0; + fail: +- for (i = 0; i < HISI_SAS_MAX_DEBUGFS_DUMP; i++) ++ for (i = 0; i < hisi_sas_debugfs_dump_count; i++) + hisi_sas_debugfs_release(hisi_hba, i); + return -ENOMEM; + } +@@ -3959,7 +3959,7 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + hisi_hba->debugfs_dump_dentry = + debugfs_create_dir("dump", hisi_hba->debugfs_dir); + +- for (i = 0; i < HISI_SAS_MAX_DEBUGFS_DUMP; i++) { ++ for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { + if (hisi_sas_debugfs_alloc(hisi_hba, i)) { + debugfs_remove_recursive(hisi_hba->debugfs_dir); + dev_dbg(dev, "failed to init debugfs!\n"); +@@ -3999,14 +3999,24 @@ EXPORT_SYMBOL_GPL(hisi_sas_debugfs_enable); + module_param_named(debugfs_enable, hisi_sas_debugfs_enable, bool, 0444); + MODULE_PARM_DESC(hisi_sas_debugfs_enable, "Enable driver debugfs (default disabled)"); + ++u32 hisi_sas_debugfs_dump_count = 1; ++EXPORT_SYMBOL_GPL(hisi_sas_debugfs_dump_count); ++module_param_named(debugfs_dump_count, hisi_sas_debugfs_dump_count, uint, 0444); ++MODULE_PARM_DESC(hisi_sas_debugfs_dump_count, "Number of debugfs dumps to allow"); ++ + static __init int hisi_sas_init(void) + { + hisi_sas_stt = sas_domain_attach_transport(&hisi_sas_transport_ops); + if (!hisi_sas_stt) + return -ENOMEM; + +- if (hisi_sas_debugfs_enable) ++ if (hisi_sas_debugfs_enable) { + hisi_sas_debugfs_dir = debugfs_create_dir("hisi_sas", NULL); ++ if (hisi_sas_debugfs_dump_count > HISI_SAS_MAX_DEBUGFS_DUMP) { ++ pr_info("hisi_sas: Limiting debugfs dump count\n"); ++ hisi_sas_debugfs_dump_count = HISI_SAS_MAX_DEBUGFS_DUMP; ++ } ++ } + + return 0; + } +-- +2.27.0 + diff --git a/patches/0684-scsi-hisi_sas-Add-ability-to-have-multiple-debugfs-d.patch b/patches/0684-scsi-hisi_sas-Add-ability-to-have-multiple-debugfs-d.patch new file mode 100644 index 0000000..b61a002 --- /dev/null +++ b/patches/0684-scsi-hisi_sas-Add-ability-to-have-multiple-debugfs-d.patch @@ -0,0 +1,283 @@ +From 52c2392546528eef79f633119446e17588b2428c Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:23 +0800 +Subject: [PATCH 036/108] scsi: hisi_sas: Add ability to have multiple debugfs + dumps + +mainline inclusion +from mainline-v5.5-rc1 +commit 8f6432986e610612688dc77c2683657d7289546f +category: feature +bugzilla: https://gitee.com/openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8f6432986e610612688dc77c2683657d7289546f + +---------------------------------------------------------------------- + +We use the module parameter debugfs_dump_count to manage the upper limit of +the memory block for multiple dumps. + +Link: https://lore.kernel.org/r/1571926105-74636-17-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 5 +- + drivers/scsi/hisi_sas/hisi_sas_main.c | 72 ++++++++++++++++----------- + 2 files changed, 46 insertions(+), 31 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 5604e6d7bc25..9eba71ad47fd 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -499,8 +499,8 @@ struct hisi_hba { + struct hisi_sas_debugfs_itct_cache + debugfs_itct_cache[HISI_SAS_MAX_DEBUGFS_DUMP]; + +- u64 debugfs_timestamp; +- ++ u64 debugfs_timestamp[HISI_SAS_MAX_DEBUGFS_DUMP]; ++ int debugfs_dump_index; + struct dentry *debugfs_dir; + struct dentry *debugfs_dump_dentry; + struct dentry *debugfs_bist_dentry; +@@ -509,7 +509,6 @@ struct hisi_hba { + unsigned int dq_idx[NR_CPUS]; + int nvecs; + unsigned int dq_num_per_node; +- bool debugfs_snapshot; + }; + + /* Generic HW DMA host memory structures */ +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index ab7e07f1ed51..5d890758059b 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2772,10 +2772,11 @@ struct dentry *hisi_sas_debugfs_dir; + static void hisi_sas_debugfs_snapshot_cq_reg(struct hisi_hba *hisi_hba) + { + int queue_entry_size = hisi_hba->hw->complete_hdr_size; ++ int dump_index = hisi_hba->debugfs_dump_index; + int i; + + for (i = 0; i < hisi_hba->queue_count; i++) +- memcpy(hisi_hba->debugfs_cq[0][i].complete_hdr, ++ memcpy(hisi_hba->debugfs_cq[dump_index][i].complete_hdr, + hisi_hba->complete_hdr[i], + HISI_SAS_QUEUE_SLOTS * queue_entry_size); + } +@@ -2783,16 +2784,18 @@ static void hisi_sas_debugfs_snapshot_cq_reg(struct hisi_hba *hisi_hba) + static void hisi_sas_debugfs_snapshot_dq_reg(struct hisi_hba *hisi_hba) + { + int queue_entry_size = sizeof(struct hisi_sas_cmd_hdr); ++ int dump_index = hisi_hba->debugfs_dump_index; + int i; + + for (i = 0; i < hisi_hba->queue_count; i++) +- memcpy(hisi_hba->debugfs_dq[0][i].hdr, ++ memcpy(hisi_hba->debugfs_dq[dump_index][i].hdr, + hisi_hba->cmd_hdr[i], + HISI_SAS_QUEUE_SLOTS * queue_entry_size); + } + + static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) + { ++ int dump_index = hisi_hba->debugfs_dump_index; + const struct hisi_sas_debugfs_reg *port = + hisi_hba->hw->debugfs_reg_port; + int i, phy_cnt; +@@ -2800,7 +2803,7 @@ static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) + u32 *databuf; + + for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) { +- databuf = hisi_hba->debugfs_port_reg[0][phy_cnt].data; ++ databuf = hisi_hba->debugfs_port_reg[dump_index][phy_cnt].data; + for (i = 0; i < port->count; i++, databuf++) { + offset = port->base_off + 4 * i; + *databuf = port->read_port_reg(hisi_hba, phy_cnt, +@@ -2811,7 +2814,8 @@ static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) + { +- u32 *databuf = hisi_hba->debugfs_regs[0][DEBUGFS_GLOBAL].data; ++ int dump_index = hisi_hba->debugfs_dump_index; ++ u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL].data; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *global = + hw->debugfs_reg_array[DEBUGFS_GLOBAL]; +@@ -2823,7 +2827,8 @@ static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) + { +- u32 *databuf = hisi_hba->debugfs_regs[0][DEBUGFS_AXI].data; ++ int dump_index = hisi_hba->debugfs_dump_index; ++ u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI].data; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *axi = + hw->debugfs_reg_array[DEBUGFS_AXI]; +@@ -2836,7 +2841,8 @@ static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) + { +- u32 *databuf = hisi_hba->debugfs_regs[0][DEBUGFS_RAS].data; ++ int dump_index = hisi_hba->debugfs_dump_index; ++ u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS].data; + const struct hisi_sas_hw *hw = hisi_hba->hw; + const struct hisi_sas_debugfs_reg *ras = + hw->debugfs_reg_array[DEBUGFS_RAS]; +@@ -2849,8 +2855,9 @@ static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + { +- void *cachebuf = hisi_hba->debugfs_itct_cache[0].cache; +- void *databuf = hisi_hba->debugfs_itct[0].itct; ++ int dump_index = hisi_hba->debugfs_dump_index; ++ void *cachebuf = hisi_hba->debugfs_itct_cache[dump_index].cache; ++ void *databuf = hisi_hba->debugfs_itct[dump_index].itct; + struct hisi_sas_itct *itct; + int i; + +@@ -2867,9 +2874,10 @@ static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) + + static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba) + { ++ int dump_index = hisi_hba->debugfs_dump_index; + int max_command_entries = HISI_SAS_MAX_COMMANDS; +- void *cachebuf = hisi_hba->debugfs_iost_cache[0].cache; +- void *databuf = hisi_hba->debugfs_iost[0].iost; ++ void *cachebuf = hisi_hba->debugfs_iost_cache[dump_index].cache; ++ void *databuf = hisi_hba->debugfs_iost[dump_index].iost; + struct hisi_sas_iost *iost; + int i; + +@@ -3648,6 +3656,7 @@ static const struct file_operations hisi_sas_debugfs_itct_cache_fops = { + static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + { + u64 *debugfs_timestamp; ++ int dump_index = hisi_hba->debugfs_dump_index; + struct dentry *dump_dentry; + struct dentry *dentry; + char name[256]; +@@ -3655,17 +3664,17 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + int c; + int d; + +- debugfs_timestamp = &hisi_hba->debugfs_timestamp; +- /* Create dump dir inside device dir */ +- dump_dentry = debugfs_create_dir("dump", hisi_hba->debugfs_dir); ++ snprintf(name, 256, "%d", dump_index); + +- hisi_hba->debugfs_dump_dentry = dump_dentry; ++ dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry); ++ ++ debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index]; + + debugfs_create_u64("timestamp", 0400, dump_dentry, + debugfs_timestamp); + + debugfs_create_file("global", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[0][DEBUGFS_GLOBAL], ++ &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL], + &hisi_sas_debugfs_global_fops); + + /* Create port dir and files */ +@@ -3674,7 +3683,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + for (p = 0; p < hisi_hba->n_phy; p++) { + snprintf(name, sizeof(name), "%d", p); + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_port_reg[0][p], ++ &hisi_hba->debugfs_port_reg[dump_index][p], + &hisi_sas_debugfs_port_fops); + } + +@@ -3685,7 +3694,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + snprintf(name, sizeof(name), "%d", c); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_cq[0][c], ++ &hisi_hba->debugfs_cq[dump_index][c], + &hisi_sas_debugfs_cq_fops); + } + +@@ -3696,32 +3705,32 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) + snprintf(name, sizeof(name), "%d", d); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_dq[0][d], ++ &hisi_hba->debugfs_dq[dump_index][d], + &hisi_sas_debugfs_dq_fops); + } + + debugfs_create_file("iost", 0400, dump_dentry, +- &hisi_hba->debugfs_iost[0], ++ &hisi_hba->debugfs_iost[dump_index], + &hisi_sas_debugfs_iost_fops); + + debugfs_create_file("iost_cache", 0400, dump_dentry, +- &hisi_hba->debugfs_iost_cache[0], ++ &hisi_hba->debugfs_iost_cache[dump_index], + &hisi_sas_debugfs_iost_cache_fops); + + debugfs_create_file("itct", 0400, dump_dentry, +- &hisi_hba->debugfs_itct[0], ++ &hisi_hba->debugfs_itct[dump_index], + &hisi_sas_debugfs_itct_fops); + + debugfs_create_file("itct_cache", 0400, dump_dentry, +- &hisi_hba->debugfs_itct_cache[0], ++ &hisi_hba->debugfs_itct_cache[dump_index], + &hisi_sas_debugfs_itct_cache_fops); + + debugfs_create_file("axi", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[0][DEBUGFS_AXI], ++ &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI], + &hisi_sas_debugfs_axi_fops); + + debugfs_create_file("ras", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[0][DEBUGFS_RAS], ++ &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS], + &hisi_sas_debugfs_ras_fops); + + return; +@@ -3761,6 +3770,8 @@ static ssize_t hisi_sas_debugfs_trigger_dump_write(struct file *file, + * If not 0, will return -EFAULT. + * Keep manual dump as one time only + */ ++ if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count) ++ return -EFAULT; + + /* Not allow to input more than 8 char */ + if (count > sizeof(buf)) +@@ -3786,15 +3797,20 @@ void hisi_sas_debugfs_work_handler(struct work_struct *work) + { + struct hisi_hba *hisi_hba = + container_of(work, struct hisi_hba, debugfs_work); ++ int debugfs_dump_index = hisi_hba->debugfs_dump_index; ++ struct device *dev = hisi_hba->dev; + u64 timestamp = local_clock(); + +- do_div(timestamp, NSEC_PER_MSEC); +- hisi_hba->debugfs_timestamp = timestamp; +- if (hisi_hba->debugfs_snapshot) ++ if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { ++ dev_warn(dev, "dump count exceeded!\n"); + return; +- hisi_hba->debugfs_snapshot = true; ++ } ++ ++ do_div(timestamp, NSEC_PER_MSEC); ++ hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; + + hisi_sas_debugfs_snapshot_regs(hisi_hba); ++ hisi_hba->debugfs_dump_index++; + } + EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler); + +-- +2.27.0 + diff --git a/patches/0685-scsi-hisi_sas-Delete-the-debugfs-folder-of-hisi_sas-.patch b/patches/0685-scsi-hisi_sas-Delete-the-debugfs-folder-of-hisi_sas-.patch new file mode 100644 index 0000000..4e4cf5b --- /dev/null +++ b/patches/0685-scsi-hisi_sas-Delete-the-debugfs-folder-of-hisi_sas-.patch @@ -0,0 +1,63 @@ +From 7a90ffb588c34ac9fc2d0f6c5926bc3ec92edf50 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:24 +0800 +Subject: [PATCH 037/108] scsi: hisi_sas: Delete the debugfs folder of hisi_sas + when the probe fails + +mainline inclusion +from mainline-v5.5-rc1 +commit cabe7c10c97a0857a9fb14b6c772ab784947995d +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cabe7c10c97a0857a9fb14b6c772ab784947995d + +---------------------------------------------------------------------- + +Although if the debugfs initialization fails, we will delete the debugfs +folder of hisi_sas, but we did not consider the scenario where debugfs was +successfully initialized, but the probe failed for other reasons. We found +out that hisi_sas folder is still remain after the probe failed. + +When probe fail, we should delete debugfs folder to avoid the above issue. + +Link: https://lore.kernel.org/r/1571926105-74636-18-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 1 + + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 5d890758059b..d25fbb051bd3 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2761,6 +2761,7 @@ int hisi_sas_probe(struct platform_device *pdev, + err_out_register_ha: + scsi_remove_host(shost); + err_out: ++ hisi_sas_debugfs_exit(hisi_hba); + hisi_sas_free(hisi_hba); + scsi_host_put(shost); + return rc; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index e55442525ae6..e83a5ad2a491 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3665,6 +3665,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + err_out_register_ha: + scsi_remove_host(shost); + err_out_ha: ++ hisi_sas_debugfs_exit(hisi_hba); + scsi_host_put(shost); + err_out_regions: + pci_release_regions(pdev); +-- +2.27.0 + diff --git a/patches/0686-scsi-hisi_sas-Record-the-phy-down-event-in-debugfs.patch b/patches/0686-scsi-hisi_sas-Record-the-phy-down-event-in-debugfs.patch new file mode 100644 index 0000000..0b43627 --- /dev/null +++ b/patches/0686-scsi-hisi_sas-Record-the-phy-down-event-in-debugfs.patch @@ -0,0 +1,153 @@ +From 2b7991f02b392f8272d69a9a327ec69a8c2774d8 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Thu, 24 Oct 2019 22:08:25 +0800 +Subject: [PATCH 038/108] scsi: hisi_sas: Record the phy down event in debugfs + +mainline inclusion +from mainline-v5.5-rc1 +commit f873b66119f2d6fc7b932a68df8d77a26357bab6 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f873b66119f2d6fc7b932a68df8d77a26357bab6 + +---------------------------------------------------------------------- + +The number of phy down reflects the quality of the link between SAS +controller and disk. In order to allow the user to confirm the link quality +of the system, we record the number of phy down for each phy. + +The user can check the current phy down count by reading the debugfs file +corresponding to the specific phy, or clear the phy down count by writing 0 +to the debugfs file. + +Link: https://lore.kernel.org/r/1571926105-74636-19-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 + + drivers/scsi/hisi_sas/hisi_sas_main.c | 63 ++++++++++++++++++++++++++ + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 + + 3 files changed, 66 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 9eba71ad47fd..6b66c056ecc8 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -188,6 +188,7 @@ struct hisi_sas_phy { + enum sas_linkrate maximum_linkrate; + u32 code_error_count; + int enable; ++ atomic_t down_cnt; + }; + + struct hisi_sas_port { +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index d25fbb051bd3..356ebe30b5c0 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -3794,6 +3794,52 @@ static const struct file_operations hisi_sas_debugfs_trigger_dump_fops = { + .owner = THIS_MODULE, + }; + ++static ssize_t hisi_sas_debugfs_phy_down_cnt_write(struct file *filp, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *s = filp->private_data; ++ struct hisi_sas_phy *phy = s->private; ++ unsigned int set_val; ++ int res; ++ ++ res = kstrtouint_from_user(buf, count, 0, &set_val); ++ if (res) ++ return res; ++ ++ if (set_val > 0) ++ return -EINVAL; ++ ++ atomic_set(&phy->down_cnt, 0); ++ ++ return count; ++} ++ ++static int hisi_sas_debugfs_phy_down_cnt_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_phy *phy = s->private; ++ ++ seq_printf(s, "%d\n", atomic_read(&phy->down_cnt)); ++ ++ return 0; ++} ++ ++static int hisi_sas_debugfs_phy_down_cnt_open(struct inode *inode, ++ struct file *filp) ++{ ++ return single_open(filp, hisi_sas_debugfs_phy_down_cnt_show, ++ inode->i_private); ++} ++ ++static const struct file_operations hisi_sas_debugfs_phy_down_cnt_ops = { ++ .open = hisi_sas_debugfs_phy_down_cnt_open, ++ .read = seq_read, ++ .write = hisi_sas_debugfs_phy_down_cnt_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ + void hisi_sas_debugfs_work_handler(struct work_struct *work) + { + struct hisi_hba *hisi_hba = +@@ -3961,6 +4007,21 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba, int dump_index) + return -ENOMEM; + } + ++static void hisi_sas_debugfs_phy_down_cnt_init(struct hisi_hba *hisi_hba) ++{ ++ struct dentry *dir = debugfs_create_dir("phy_down_cnt", ++ hisi_hba->debugfs_dir); ++ char name[16]; ++ int phy_no; ++ ++ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { ++ snprintf(name, 16, "%d", phy_no); ++ debugfs_create_file(name, 0600, dir, ++ &hisi_hba->phy[phy_no], ++ &hisi_sas_debugfs_phy_down_cnt_ops); ++ } ++} ++ + void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; +@@ -3976,6 +4037,8 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + hisi_hba->debugfs_dump_dentry = + debugfs_create_dir("dump", hisi_hba->debugfs_dir); + ++ hisi_sas_debugfs_phy_down_cnt_init(hisi_hba); ++ + for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { + if (hisi_sas_debugfs_alloc(hisi_hba, i)) { + debugfs_remove_recursive(hisi_hba->debugfs_dir); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index e83a5ad2a491..35fee5d5d141 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1704,6 +1704,8 @@ static irqreturn_t phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + u32 phy_state, sl_ctrl, txid_auto; + struct device *dev = hisi_hba->dev; + ++ atomic_inc(&phy->down_cnt); ++ + del_timer(&phy->timer); + hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 1); + +-- +2.27.0 + diff --git a/patches/0687-scsi-hisi_sas-Return-directly-if-init-hardware-faile.patch b/patches/0687-scsi-hisi_sas-Return-directly-if-init-hardware-faile.patch new file mode 100644 index 0000000..15e1ac5 --- /dev/null +++ b/patches/0687-scsi-hisi_sas-Return-directly-if-init-hardware-faile.patch @@ -0,0 +1,43 @@ +From 6a76d5c41754a2f4ec27e8cc9881bb7e63ba3a4b Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Tue, 12 Nov 2019 17:30:57 +0800 +Subject: [PATCH 039/108] scsi: hisi_sas: Return directly if init hardware + failed + +mainline inclusion +from mainline-v5.5-rc1 +commit 547fde8b5a1923050f388caae4f76613b5a620e0 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=547fde8b5a1923050f388caae4f76613b5a620e0 + +---------------------------------------------------------------------- + +Need to return directly if init hardware failed. + +Fixes: 73a4925d154c ("scsi: hisi_sas: Update all the registers after suspend and resume") +Link: https://lore.kernel.org/r/1573551059-107873-3-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 35fee5d5d141..500fd6e54f38 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3832,6 +3832,7 @@ static int hisi_sas_v3_resume(struct pci_dev *pdev) + if (rc) { + scsi_remove_host(shost); + pci_disable_device(pdev); ++ return rc; + } + hisi_hba->hw->phys_init(hisi_hba); + sas_resume_ha(sha); +-- +2.27.0 + diff --git a/patches/0688-scsi-hisi_sas-Stop-converting-a-bool-into-a-bool.patch b/patches/0688-scsi-hisi_sas-Stop-converting-a-bool-into-a-bool.patch new file mode 100644 index 0000000..a2c40a1 --- /dev/null +++ b/patches/0688-scsi-hisi_sas-Stop-converting-a-bool-into-a-bool.patch @@ -0,0 +1,42 @@ +From 40525c4530b6b829cce3711c4c2e3c77d8259a6d Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Tue, 12 Nov 2019 17:30:59 +0800 +Subject: [PATCH 040/108] scsi: hisi_sas: Stop converting a bool into a bool + +mainline inclusion +from mainline-v5.5-rc1 +commit 964231aa0c7ef53ebc9c2a6889bbc50d8a3f2220 +category: feature +bugzilla: https://gitee.com/openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=964231aa0c7ef53ebc9c2a6889bbc50d8a3f2220 + +---------------------------------------------------------------------- + +The !! operator on a bool is pointless, so remove an example in +hisi_sas_rescan_topology(). + +Link: https://lore.kernel.org/r/1573551059-107873-5-git-send-email-john.garry@huawei.com +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 356ebe30b5c0..ee2b22ba37f9 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1448,7 +1448,7 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state) + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct asd_sas_port *sas_port = sas_phy->port; +- bool do_port_check = !!(_sas_port != sas_port); ++ bool do_port_check = _sas_port != sas_port; + + if (!sas_phy->phy->enabled) + continue; +-- +2.27.0 + diff --git a/patches/0689-scsi-hisi_sas-Replace-magic-number-when-handle-chann.patch b/patches/0689-scsi-hisi_sas-Replace-magic-number-when-handle-chann.patch new file mode 100644 index 0000000..6d6ca92 --- /dev/null +++ b/patches/0689-scsi-hisi_sas-Replace-magic-number-when-handle-chann.patch @@ -0,0 +1,81 @@ +From 44fcad1ae412d4d1743c3242302c05f1f3400a4a Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Mon, 20 Jan 2020 20:22:33 +0800 +Subject: [PATCH 041/108] scsi: hisi_sas: Replace magic number when handle + channel interrupt + +mainline inclusion +from mainline-v5.6-rc1 +commit d2815fdf9a0e6c629d062f9a7e24cb7cdbef3dee +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d2815fdf9a0e6c629d062f9a7e24cb7cdbef3dee + +---------------------------------------------------------------------- + +We use magic number as offset and mask when handle channel interrupt, so +use macro to replace it. + +Link: https://lore.kernel.org/r/1579522957-4393-4-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 500fd6e54f38..c8328e1ef166 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -540,6 +540,13 @@ struct hisi_sas_err_record_v3 { + (op == READ_16) || (op == WRITE_16) || \ + (op == READ_32) || (op == WRITE_32)) + ++#define CHNL_INT_STS_MSK 0xeeeeeeee ++#define CHNL_INT_STS_PHY_MSK 0xe ++#define CHNL_INT_STS_INT0_MSK BIT(1) ++#define CHNL_INT_STS_INT1_MSK BIT(2) ++#define CHNL_INT_STS_INT2_MSK BIT(3) ++#define CHNL_WIDTH 4 ++ + enum { + DSM_FUNC_ERR_HANDLE_MSI = 0, + }; +@@ -1945,22 +1952,23 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p) + int phy_no = 0; + + irq_msk = hisi_sas_read32(hisi_hba, CHNL_INT_STATUS) +- & 0xeeeeeeee; ++ & CHNL_INT_STS_MSK; ++ + /* + * These three irqs mask save at high 3 bit, the last bit + * is reserved. So we use 0xe to clear those after handle. + */ + while (irq_msk) { +- if (irq_msk & (2 << (phy_no * 4))) ++ if (irq_msk & (CHNL_INT_STS_INT0_MSK << (phy_no * CHNL_WIDTH))) + handle_chl_int0_v3_hw(hisi_hba, phy_no); + +- if (irq_msk & (4 << (phy_no * 4))) ++ if (irq_msk & (CHNL_INT_STS_INT1_MSK << (phy_no * CHNL_WIDTH))) + handle_chl_int1_v3_hw(hisi_hba, phy_no); + +- if (irq_msk & (8 << (phy_no * 4))) ++ if (irq_msk & (CHNL_INT_STS_INT2_MSK << (phy_no * CHNL_WIDTH))) + handle_chl_int2_v3_hw(hisi_hba, phy_no); + +- irq_msk &= ~(0xe << (phy_no * 4)); ++ irq_msk &= ~(CHNL_INT_STS_PHY_MSK << (phy_no * CHNL_WIDTH)); + phy_no++; + } + +-- +2.27.0 + diff --git a/patches/0690-scsi-hisi_sas-Modify-the-file-permissions-of-trigger.patch b/patches/0690-scsi-hisi_sas-Modify-the-file-permissions-of-trigger.patch new file mode 100644 index 0000000..a9e90d2 --- /dev/null +++ b/patches/0690-scsi-hisi_sas-Modify-the-file-permissions-of-trigger.patch @@ -0,0 +1,45 @@ +From 5bcbc20e6442a32daf48971070e2f02a4bf524d2 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Mon, 20 Jan 2020 20:22:34 +0800 +Subject: [PATCH 042/108] scsi: hisi_sas: Modify the file permissions of + trigger_dump to write only + +mainline inclusion +from mainline-v5.6-rc1 +commit 3cd2f3c35d29a50947a975feffdcbe2d6a2418c0 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3cd2f3c35d29a50947a975feffdcbe2d6a2418c0 + +---------------------------------------------------------------------- + +The trigger_dump file is only used to manually trigger the dump, and did +not provide a read callback function for it, so its file permission +setting to 600 is wrong,and should be changed to 200. + +Link: https://lore.kernel.org/r/1579522957-4393-5-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index ee2b22ba37f9..7185cc263597 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -4029,7 +4029,7 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) + + hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), + hisi_sas_debugfs_dir); +- debugfs_create_file("trigger_dump", 0600, ++ debugfs_create_file("trigger_dump", 0200, + hisi_hba->debugfs_dir, + hisi_hba, + &hisi_sas_debugfs_trigger_dump_fops); +-- +2.27.0 + diff --git a/patches/0691-scsi-hisi_sas-Add-prints-for-v3-hw-interrupt-converg.patch b/patches/0691-scsi-hisi_sas-Add-prints-for-v3-hw-interrupt-converg.patch new file mode 100644 index 0000000..ab270f6 --- /dev/null +++ b/patches/0691-scsi-hisi_sas-Add-prints-for-v3-hw-interrupt-converg.patch @@ -0,0 +1,56 @@ +From 5dd6d7e47b85afcb3b9b01796a648866a27a18f5 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Mon, 20 Jan 2020 20:22:35 +0800 +Subject: [PATCH 043/108] scsi: hisi_sas: Add prints for v3 hw interrupt + converge and automatic affinity + +mainline inclusion +from mainline-v5.6-rc1 +commit 33c77c31b752c561dd4b3c25661f949014c31370 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=33c77c31b752c561dd4b3c25661f949014c31370 + +---------------------------------------------------------------------- + +Add prints to inform the user of enabled features. + +Link: https://lore.kernel.org/r/1579522957-4393-6-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index c8328e1ef166..6a64653a68b9 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2725,6 +2725,8 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + .pre_vectors = HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW, + }; + ++ dev_info(dev, "Enable MSI auto-affinity\n"); ++ + min_msi = HISI_SAS_MIN_VECTORS_V3_HW; + + hisi_hba->reply_map = devm_kcalloc(dev, nr_cpu_ids, +@@ -2786,6 +2788,9 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + goto free_irq_vectors; + } + ++ if (hisi_sas_intr_conv) ++ dev_info(dev, "Enable interrupt converge\n"); ++ + /* Init tasklets for cq only */ + for (i = 0; i < hisi_hba->nvecs; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; +-- +2.27.0 + diff --git a/patches/0692-scsi-hisi_sas-Use-dev_err-in-read_iost_itct_cache_v3.patch b/patches/0692-scsi-hisi_sas-Use-dev_err-in-read_iost_itct_cache_v3.patch new file mode 100644 index 0000000..84ec9d9 --- /dev/null +++ b/patches/0692-scsi-hisi_sas-Use-dev_err-in-read_iost_itct_cache_v3.patch @@ -0,0 +1,55 @@ +From f6b042bc6658185ce2b050b8c0ce2c987c498c76 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Wed, 11 Mar 2020 23:22:24 +0800 +Subject: [PATCH 044/108] scsi: hisi_sas: Use dev_err() in + read_iost_itct_cache_v3_hw() + +mainline inclusion +from mainline-v5.7-rc1 +commit 1e067dd8a3681310a36302640dc33c4f3fb0c190 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1e067dd8a3681310a36302640dc33c4f3fb0c190 + +---------------------------------------------------------------------- + +The print of pr_err() does not come with device information, so replace it +with dev_err(). Also improve the grammar in the message. + +Link: https://lore.kernel.org/r/1583940144-230800-1-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 6a64653a68b9..62dd7b599911 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3440,6 +3440,7 @@ static void read_iost_itct_cache_v3_hw(struct hisi_hba *hisi_hba, + { + u32 cache_dw_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * + HISI_SAS_IOST_ITCT_CACHE_NUM; ++ struct device *dev = hisi_hba->dev; + u32 *buf = cache; + u32 i, val; + +@@ -3452,7 +3453,7 @@ static void read_iost_itct_cache_v3_hw(struct hisi_hba *hisi_hba, + } + + if (val != 0xffffffff) { +- pr_err("Issue occur when reading IOST/ITCT cache!\n"); ++ dev_err(dev, "Issue occurred in reading IOST/ITCT cache!\n"); + return; + } + +-- +2.27.0 + diff --git a/patches/0693-scsi-hisi_sas-Fix-build-error-without-SATA_HOST.patch b/patches/0693-scsi-hisi_sas-Fix-build-error-without-SATA_HOST.patch new file mode 100644 index 0000000..7820db3 --- /dev/null +++ b/patches/0693-scsi-hisi_sas-Fix-build-error-without-SATA_HOST.patch @@ -0,0 +1,50 @@ +From d66c6441a9b7313704a64ab01225a12c02bd9fd3 Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Thu, 2 Apr 2020 16:58:12 +0800 +Subject: [PATCH 045/108] scsi: hisi_sas: Fix build error without SATA_HOST + +mainline inclusion +from mainline-v5.7-rc2 +commit 1d95b8a2d41f0cfbf3cefb5d986941bde2e1378f +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1d95b8a2d41f0cfbf3cefb5d986941bde2e1378f + +---------------------------------------------------------------------- + +If SATA_HOST is n, build fails: + +drivers/scsi/hisi_sas/hisi_sas_main.o: In function +`hisi_sas_fill_ata_reset_cmd': hisi_sas_main.c:(.text+0x2500): undefined +reference to `ata_tf_to_fis' + +Select SATA_HOST to fix this. + +Link: https://lore.kernel.org/r/20200402085812.32948-1-yuehaibing@huawei.com +Fixes: bd322af15ce9 ("ata: make SATA_PMP option selectable only if any SATA host driver is enabled") +Reported-by: Hulk Robot +Reviewed-by: Bartlomiej Zolnierkiewicz +Acked-by: John Garry +Signed-off-by: YueHaibing +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig +index 57183fce70fb..79ad42352825 100644 +--- a/drivers/scsi/hisi_sas/Kconfig ++++ b/drivers/scsi/hisi_sas/Kconfig +@@ -5,6 +5,7 @@ config SCSI_HISI_SAS + select SCSI_SAS_LIBSAS + select BLK_DEV_INTEGRITY + depends on ATA ++ select SATA_HOST + help + This driver supports HiSilicon's SAS HBA, including support based + on platform device +-- +2.27.0 + diff --git a/patches/0694-scsi-hisi_sas-Display-proc_name-in-sysfs.patch b/patches/0694-scsi-hisi_sas-Display-proc_name-in-sysfs.patch new file mode 100644 index 0000000..4f6710b --- /dev/null +++ b/patches/0694-scsi-hisi_sas-Display-proc_name-in-sysfs.patch @@ -0,0 +1,78 @@ +From b2bdaceb05aa8a5a8355d9e200cd6270351f6ec0 Mon Sep 17 00:00:00 2001 +From: Jason Yan +Date: Tue, 12 May 2020 19:32:58 +0800 +Subject: [PATCH 046/108] scsi: hisi_sas: Display proc_name in sysfs + +mainline inclusion +from mainline-v5.8-rc1 +commit 55ce24b3bfd75f76696a00f2666caaf806eebea2 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=55ce24b3bfd75f76696a00f2666caaf806eebea2 + +---------------------------------------------------------------------- + +The 'proc_name' entry in sysfs for hisi_sas is 'null' now because it is not +initialized in scsi_host_template. It looks like: + +[root@localhost ~]# cat /sys/class/scsi_host/host2/proc_name +(null) + +While the other driver's entry looks like: + +linux-vnMQMU:~ # cat /sys/class/scsi_host/host0/proc_name +megaraid_sas + +Link: https://lore.kernel.org/r/20200512113258.30781-1-yanaijie@huawei.com +Cc: John Garry +Cc: Xiang Chen +Acked-by: John Garry +Signed-off-by: Jason Yan +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 1 + + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 1 + + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index 1228f282d443..c21a18703cab 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1761,6 +1761,7 @@ static struct device_attribute *host_attrs_v1_hw[] = { + + static struct scsi_host_template sht_v1_hw = { + .name = DRV_NAME, ++ .proc_name = DRV_NAME, + .module = THIS_MODULE, + .queuecommand = sas_queuecommand, + .target_alloc = sas_target_alloc, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index 55faa3ec72f9..c044ce0a0f18 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3552,6 +3552,7 @@ struct device_attribute *host_attrs_v2_hw[] = { + + static struct scsi_host_template sht_v2_hw = { + .name = DRV_NAME, ++ .proc_name = DRV_NAME, + .module = THIS_MODULE, + .queuecommand = sas_queuecommand, + .target_alloc = sas_target_alloc, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 62dd7b599911..23eeb3678da2 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3466,6 +3466,7 @@ static void read_iost_itct_cache_v3_hw(struct hisi_hba *hisi_hba, + + static struct scsi_host_template sht_v3_hw = { + .name = DRV_NAME, ++ .proc_name = DRV_NAME, + .module = THIS_MODULE, + .queuecommand = sas_queuecommand, + .target_alloc = sas_target_alloc, +-- +2.27.0 + diff --git a/patches/0695-scsi-hisi_sas-Modify-the-commit-information-for-DSM-.patch b/patches/0695-scsi-hisi_sas-Modify-the-commit-information-for-DSM-.patch new file mode 100644 index 0000000..83ea48c --- /dev/null +++ b/patches/0695-scsi-hisi_sas-Modify-the-commit-information-for-DSM-.patch @@ -0,0 +1,54 @@ +From 8117524e3fc1de6fbe2f0f4d0986073395baccb6 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Fri, 15 May 2020 22:13:43 +0800 +Subject: [PATCH 047/108] scsi: hisi_sas: Modify the commit information for DSM + method + +mainline inclusion +from mainline-v5.8-rc1 +commit 1e954d1f002db802937deb87a868c3f62fe1badf +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1e954d1f002db802937deb87a868c3f62fe1badf + +---------------------------------------------------------------------- + +Make it clear that BIOS may modify some register settings. + +Link: https://lore.kernel.org/r/1589552025-165012-3-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 23eeb3678da2..ec48413dcf1e 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1010,12 +1010,14 @@ static int hw_init_v3_hw(struct hisi_hba *hisi_hba) + } + + /* +- * Switch over to MSI handling due to non-standard PCI implementation. ++ * This DSM handles some hardware-related configurations: ++ * 1. Switch over to MSI error handling in kernel ++ * 2. BIOS *may* reset some register values through this method + */ + obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &guid, 0, + DSM_FUNC_ERR_HANDLE_MSI, NULL); + if (!obj) +- dev_warn(dev, "Switch over to MSI handling failed\n"); ++ dev_warn(dev, "can not find DSM method, ignore\n"); + else + ACPI_FREE(obj); + +-- +2.27.0 + diff --git a/patches/0696-scsi-hisi_sas-Add-SAS_RAS_INTR0-to-debugfs-register-.patch b/patches/0696-scsi-hisi_sas-Add-SAS_RAS_INTR0-to-debugfs-register-.patch new file mode 100644 index 0000000..86a4bea --- /dev/null +++ b/patches/0696-scsi-hisi_sas-Add-SAS_RAS_INTR0-to-debugfs-register-.patch @@ -0,0 +1,44 @@ +From b85bd98ae38cdb6c957ed34ebdff1706b963fd86 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Fri, 15 May 2020 22:13:44 +0800 +Subject: [PATCH 048/108] scsi: hisi_sas: Add SAS_RAS_INTR0 to debugfs register + name list + +mainline inclusion +from mainline-v5.8-rc1 +commit 1a0efb55b2bb9e970b8842030ce65d645ddba90c +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1a0efb55b2bb9e970b8842030ce65d645ddba90c + +---------------------------------------------------------------------- + +Register SAS_RAS_INTR0 can help us to figure out which ECC error has +occurred. This register is helpful to identify RAS issue, so we add it to +the list of debugfs register name list for easier retrieval. + +Link: https://lore.kernel.org/r/1589552025-165012-4-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index ec48413dcf1e..abef129a2290 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3279,6 +3279,7 @@ static const struct hisi_sas_debugfs_reg debugfs_axi_reg = { + }; + + static const struct hisi_sas_debugfs_reg_lu debugfs_ras_reg_lu[] = { ++ HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR0), + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR1), + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR0_MASK), + HISI_SAS_DEBUGFS_REG(SAS_RAS_INTR1_MASK), +-- +2.27.0 + diff --git a/patches/0697-scsi-hisi_sas-Stop-returning-error-code-from-slot_co.patch b/patches/0697-scsi-hisi_sas-Stop-returning-error-code-from-slot_co.patch new file mode 100644 index 0000000..89fc06b --- /dev/null +++ b/patches/0697-scsi-hisi_sas-Stop-returning-error-code-from-slot_co.patch @@ -0,0 +1,233 @@ +From d637cc02edc2d41441f2d9de0e825949438a0604 Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Fri, 15 May 2020 22:13:45 +0800 +Subject: [PATCH 049/108] scsi: hisi_sas: Stop returning error code from + slot_complete_vX_hw() + +mainline inclusion +from mainline-v5.8-rc1 +commit 1cdee004426164d1b00b66d3f6e7308c3714def6 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1cdee004426164d1b00b66d3f6e7308c3714def6 + +---------------------------------------------------------------------- + +The error codes are never checked, stop returning them. + +Link: https://lore.kernel.org/r/1589552025-165012-5-git-send-email-john.garry@huawei.com +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 12 ++++-------- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 16 ++++++---------- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 16 ++++++---------- + 3 files changed, 16 insertions(+), 28 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index c21a18703cab..09cc42e66dd5 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1179,15 +1179,14 @@ static void slot_err_v1_hw(struct hisi_hba *hisi_hba, + + } + +-static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, +- struct hisi_sas_slot *slot) ++static void slot_complete_v1_hw(struct hisi_hba *hisi_hba, ++ struct hisi_sas_slot *slot) + { + struct sas_task *task = slot->task; + struct hisi_sas_device *sas_dev; + struct device *dev = hisi_hba->dev; + struct task_status_struct *ts; + struct domain_device *device; +- enum exec_status sts; + struct hisi_sas_complete_v1_hdr *complete_queue = + hisi_hba->complete_hdr[slot->cmplt_queue]; + struct hisi_sas_complete_v1_hdr *complete_hdr; +@@ -1198,7 +1197,7 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, + cmplt_hdr_data = le32_to_cpu(complete_hdr->data); + + if (unlikely(!task || !task->lldd_task || !task->dev)) +- return -EINVAL; ++ return; + + ts = &task->task_status; + device = task->dev; +@@ -1265,7 +1264,7 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, + slot_err_v1_hw(hisi_hba, task, slot); + if (unlikely(slot->abort)) { + sas_task_abort(task); +- return ts->stat; ++ return; + } + goto out; + } +@@ -1315,12 +1314,9 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, + + out: + hisi_sas_slot_task_free(hisi_hba, task, slot, true); +- sts = ts->stat; + + if (task->task_done) + task->task_done(task); +- +- return sts; + } + + /* Interrupts */ +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index c044ce0a0f18..6de3fe10c5be 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -2332,8 +2332,8 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba, + } + } + +-static int +-slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) ++static void slot_complete_v2_hw(struct hisi_hba *hisi_hba, ++ struct hisi_sas_slot *slot) + { + struct sas_task *task = slot->task; + struct hisi_sas_device *sas_dev; +@@ -2341,7 +2341,6 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + struct task_status_struct *ts; + struct domain_device *device; + struct sas_ha_struct *ha; +- enum exec_status sts; + struct hisi_sas_complete_v2_hdr *complete_queue = + hisi_hba->complete_hdr[slot->cmplt_queue]; + struct hisi_sas_complete_v2_hdr *complete_hdr = +@@ -2351,7 +2350,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + u32 dw0; + + if (unlikely(!task || !task->lldd_task || !task->dev)) +- return -EINVAL; ++ return; + + ts = &task->task_status; + device = task->dev; +@@ -2422,7 +2421,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + + if (unlikely(slot->abort)) { + sas_task_abort(task); +- return ts->stat; ++ return; + } + goto out; + } +@@ -2474,12 +2473,11 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + } + + out: +- sts = ts->stat; + spin_lock_irqsave(&task->task_state_lock, flags); + if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { + spin_unlock_irqrestore(&task->task_state_lock, flags); + dev_info(dev, "slot complete: task(%pK) aborted\n", task); +- return SAS_ABORTED_TASK; ++ return; + } + task->task_state_flags |= SAS_TASK_STATE_DONE; + spin_unlock_irqrestore(&task->task_state_lock, flags); +@@ -2491,15 +2489,13 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + spin_unlock_irqrestore(&device->done_lock, flags); + dev_info(dev, "slot complete: task(%pK) ignored\n", + task); +- return sts; ++ return; + } + spin_unlock_irqrestore(&device->done_lock, flags); + } + + if (task->task_done) + task->task_done(task); +- +- return sts; + } + + static void prep_ata_v2_hw(struct hisi_hba *hisi_hba, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index abef129a2290..ecc91ca8a54d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2389,8 +2389,8 @@ static int ssp_need_spin_up(struct hisi_sas_slot *slot) + return 0; + } + +-static int +-slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) ++static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, ++ struct hisi_sas_slot *slot) + { + struct sas_task *task = slot->task; + struct hisi_sas_device *sas_dev; +@@ -2398,7 +2398,6 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + struct task_status_struct *ts; + struct domain_device *device; + struct sas_ha_struct *ha; +- enum exec_status sts; + struct hisi_sas_complete_v3_hdr *complete_queue = + hisi_hba->complete_hdr[slot->cmplt_queue]; + struct hisi_sas_complete_v3_hdr *complete_hdr = +@@ -2408,7 +2407,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + u32 dw0, dw1, dw3; + + if (unlikely(!task || !task->lldd_task || !task->dev)) +- return -EINVAL; ++ return; + + ts = &task->task_status; + device = task->dev; +@@ -2518,7 +2517,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + else + sas_task_abort(task); + +- return ts->stat; ++ return; + } + goto out; + } +@@ -2576,12 +2575,11 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + } + + out: +- sts = ts->stat; + spin_lock_irqsave(&task->task_state_lock, flags); + if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { + spin_unlock_irqrestore(&task->task_state_lock, flags); + dev_info(dev, "slot complete: task(%pK) aborted\n", task); +- return SAS_ABORTED_TASK; ++ return; + } + task->task_state_flags |= SAS_TASK_STATE_DONE; + spin_unlock_irqrestore(&task->task_state_lock, flags); +@@ -2593,15 +2591,13 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) + spin_unlock_irqrestore(&device->done_lock, flags); + dev_info(dev, "slot complete: task(%pK) ignored\n ", + task); +- return sts; ++ return; + } + spin_unlock_irqrestore(&device->done_lock, flags); + } + + if (task->task_done) + task->task_done(task); +- +- return sts; + } + + static void hisi_sas_disk_err_handler(struct hisi_hba *hisi_hba, +-- +2.27.0 + diff --git a/patches/0698-scsi-hisi_sas-Do-not-reset-phy-timer-to-wait-for-str.patch b/patches/0698-scsi-hisi_sas-Do-not-reset-phy-timer-to-wait-for-str.patch new file mode 100644 index 0000000..e3d6c40 --- /dev/null +++ b/patches/0698-scsi-hisi_sas-Do-not-reset-phy-timer-to-wait-for-str.patch @@ -0,0 +1,54 @@ +From e6f35e96226fb1f9c372a2dfe5f46860052af6fd Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Fri, 15 May 2020 22:13:42 +0800 +Subject: [PATCH 050/108] scsi: hisi_sas: Do not reset phy timer to wait for + stray phy up + +mainline inclusion +from mainline-v5.8-rc1 +commit e16b9ed61e078d836a0f24a82080cf29d7539c7e +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e16b9ed61e078d836a0f24a82080cf29d7539c7e + +---------------------------------------------------------------------- + +We found out that after phy up, the hardware reports another oob interrupt +but did not follow a phy up interrupt: + +oob ready -> phy up -> DEV found -> oob read -> wait phy up -> timeout + +We run link reset when wait phy up timeout, and it send a normal disk into +reset processing. So we made some circumvention action in the code, so that +this abnormal oob interrupt will not start the timer to wait for phy up. + +Link: https://lore.kernel.org/r/1589552025-165012-2-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 7185cc263597..a741a597fecf 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -917,8 +917,11 @@ void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no) + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct device *dev = hisi_hba->dev; + ++ dev_dbg(dev, "phy%d OOB ready\n", phy_no); ++ if (phy->phy_attached) ++ return; ++ + if (!timer_pending(&phy->timer)) { +- dev_dbg(dev, "phy%d OOB ready\n", phy_no); + phy->timer.expires = jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT * HZ; + add_timer(&phy->timer); + } +-- +2.27.0 + diff --git a/patches/0699-scsi-hisi_sas-Remove-one-kerneldoc-comment.patch b/patches/0699-scsi-hisi_sas-Remove-one-kerneldoc-comment.patch new file mode 100644 index 0000000..cb3565a --- /dev/null +++ b/patches/0699-scsi-hisi_sas-Remove-one-kerneldoc-comment.patch @@ -0,0 +1,42 @@ +From ab5e96ce3e7817e404fef6fea5abe06ec027e4a5 Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Mon, 13 Jul 2020 16:04:31 +0800 +Subject: [PATCH 051/108] scsi: hisi_sas: Remove one kerneldoc comment + +mainline inclusion +from mainline-v5.9-rc1 +commit 3d570a28ee8d7e724fc740019746a6e79c8db06c +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3d570a28ee8d7e724fc740019746a6e79c8db06c + +---------------------------------------------------------------------- + +The comment for interrupt_init_v2_hw() should not be a kerneldoc +comment. Remove it. + +Link: https://lore.kernel.org/r/1594627471-235395-3-git-send-email-john.garry@huawei.com +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index 6de3fe10c5be..7e0059d3b3ef 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3317,7 +3317,7 @@ static irq_handler_t fatal_interrupts[HISI_SAS_FATAL_INT_NR] = { + fatal_axi_int_v2_hw + }; + +-/** ++/* + * There is a limitation in the hip06 chipset that we need + * to map in all mbigen interrupts, even if they are not used. + */ +-- +2.27.0 + diff --git a/patches/0700-scsi-hisi_sas-Modify-macro-name-for-OOB-phy-linkrate.patch b/patches/0700-scsi-hisi_sas-Modify-macro-name-for-OOB-phy-linkrate.patch new file mode 100644 index 0000000..7b712ba --- /dev/null +++ b/patches/0700-scsi-hisi_sas-Modify-macro-name-for-OOB-phy-linkrate.patch @@ -0,0 +1,74 @@ +From 478d8d61ceb8d8b1effff96e027020e860f967f3 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 1 Sep 2020 19:13:04 +0800 +Subject: [PATCH 052/108] scsi: hisi_sas: Modify macro name for OOB phy + linkrate + +mainline inclusion +from mainline-v5.10-rc1 +commit 4b3a1f1feda62b0b15536548b6d31ca549de2e3a +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4b3a1f1feda62b0b15536548b6d31ca549de2e3a + +---------------------------------------------------------------------- + +The macro for OOB phy linkrate is named CFG_PROG_PHY_LINK_RATE_* but that +is inaccurate. For clarification, include OOB in macro name. + +Link: https://lore.kernel.org/r/1598958790-232272-3-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index ecc91ca8a54d..343160b1f6a3 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -199,8 +199,8 @@ + #define PHY_CFG_PHY_RST_OFF 3 + #define PHY_CFG_PHY_RST_MSK (0x1 << PHY_CFG_PHY_RST_OFF) + #define PROG_PHY_LINK_RATE (PORT_BASE + 0x8) +-#define CFG_PROG_PHY_LINK_RATE_OFF 8 +-#define CFG_PROG_PHY_LINK_RATE_MSK (0xf << CFG_PROG_PHY_LINK_RATE_OFF) ++#define CFG_PROG_OOB_PHY_LINK_RATE_OFF 8 ++#define CFG_PROG_OOB_PHY_LINK_RATE_MSK (0xf << CFG_PROG_OOB_PHY_LINK_RATE_OFF) + #define PHY_CTRL (PORT_BASE + 0x14) + #define PHY_CTRL_RESET_OFF 0 + #define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF) +@@ -3345,10 +3345,9 @@ static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba) + /*restore the linkrate*/ + reg_val = hisi_sas_phy_read32(hisi_hba, phy_id, PROG_PHY_LINK_RATE); + /* init OOB link rate as 1.5 Gbits */ +- reg_val &= ~CFG_PROG_PHY_LINK_RATE_MSK; +- reg_val |= (0x800 << CFG_PROG_PHY_LINK_RATE_OFF); +- hisi_sas_phy_write32(hisi_hba, phy_id, +- PROG_PHY_LINK_RATE, reg_val); ++ reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK; ++ reg_val |= (0x8 << CFG_PROG_OOB_PHY_LINK_RATE_OFF); ++ hisi_sas_phy_write32(hisi_hba, phy_id, PROG_PHY_LINK_RATE, reg_val); + + /* enable PHY */ + hisi_sas_phy_enable(hisi_hba, phy_id, 1); +@@ -3372,8 +3371,8 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + /* set linkrate of bit test*/ + reg_val = hisi_sas_phy_read32(hisi_hba, phy_id, + PROG_PHY_LINK_RATE); +- reg_val &= ~CFG_PROG_PHY_LINK_RATE_MSK; +- reg_val |= (linkrate << CFG_PROG_PHY_LINK_RATE_OFF); ++ reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK; ++ reg_val |= (linkrate << CFG_PROG_OOB_PHY_LINK_RATE_OFF); + hisi_sas_phy_write32(hisi_hba, phy_id, + PROG_PHY_LINK_RATE, reg_val); + +-- +2.27.0 + diff --git a/patches/0701-scsi-hisi_sas-Do-not-modify-upper-fields-of-PROG_PHY.patch b/patches/0701-scsi-hisi_sas-Do-not-modify-upper-fields-of-PROG_PHY.patch new file mode 100644 index 0000000..d2810cf --- /dev/null +++ b/patches/0701-scsi-hisi_sas-Do-not-modify-upper-fields-of-PROG_PHY.patch @@ -0,0 +1,96 @@ +From 4eb7b05822b08060912123ccd681845c9fae435d Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 1 Sep 2020 19:13:05 +0800 +Subject: [PATCH 053/108] scsi: hisi_sas: Do not modify upper fields of + PROG_PHY_LINK_RATE reg + +mainline inclusion +from mainline-v5.10-rc1 +commit caeddc0453b9215669a39ea335f1af1f3f91cc99 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=caeddc0453b9215669a39ea335f1af1f3f91cc99 + +---------------------------------------------------------------------- + +When updating PROG_PHY_LINK_RATE to set linkrate for a phy we used a +hard-coded initial value instead of getting the current value from the +register. The assumption was that this register would not be modified, but +in fact it was partially modified in a new version of hardware. The +hard-coded value we used changed the default value of the register to a an +incorrect setting and as a result the SAS controller could not change +linkrate for the phy. + +Delete hard-coded value and always read the latest value of register before +updating it. + +Link: https://lore.kernel.org/r/1598958790-232272-4-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 343160b1f6a3..e278d5d8c0d9 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -199,6 +199,8 @@ + #define PHY_CFG_PHY_RST_OFF 3 + #define PHY_CFG_PHY_RST_MSK (0x1 << PHY_CFG_PHY_RST_OFF) + #define PROG_PHY_LINK_RATE (PORT_BASE + 0x8) ++#define CFG_PROG_PHY_LINK_RATE_OFF 0 ++#define CFG_PROG_PHY_LINK_RATE_MSK (0xff << CFG_PROG_PHY_LINK_RATE_OFF) + #define CFG_PROG_OOB_PHY_LINK_RATE_OFF 8 + #define CFG_PROG_OOB_PHY_LINK_RATE_MSK (0xf << CFG_PROG_OOB_PHY_LINK_RATE_OFF) + #define PHY_CTRL (PORT_BASE + 0x14) +@@ -659,20 +661,20 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + } + + for (i = 0; i < hisi_hba->n_phy; i++) { ++ enum sas_linkrate max; + struct hisi_sas_phy *phy = &hisi_hba->phy[i]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; +- u32 prog_phy_link_rate = 0x800; ++ u32 prog_phy_link_rate = hisi_sas_phy_read32(hisi_hba, i, ++ PROG_PHY_LINK_RATE); + ++ prog_phy_link_rate &= ~CFG_PROG_PHY_LINK_RATE_MSK; + if (!sas_phy->phy || (sas_phy->phy->maximum_linkrate < + SAS_LINK_RATE_1_5_GBPS)) { +- prog_phy_link_rate = 0x855; ++ max = SAS_LINK_RATE_12_0_GBPS; + } else { +- enum sas_linkrate max = sas_phy->phy->maximum_linkrate; +- +- prog_phy_link_rate = +- hisi_sas_get_prog_phy_linkrate_mask(max) | +- 0x800; ++ max = sas_phy->phy->maximum_linkrate; + } ++ prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max); + + if (skip_bus_flag) { + hisi_sas_phy_write32(hisi_hba, i, +@@ -2836,9 +2838,10 @@ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no, + struct sas_phy_linkrates *r) + { + enum sas_linkrate max = r->maximum_linkrate; +- /* init OOB link rate as 1.5 Gbits */ +- u32 prog_phy_link_rate = 0x800; ++ u32 prog_phy_link_rate = hisi_sas_phy_read32(hisi_hba, phy_no, ++ PROG_PHY_LINK_RATE); + ++ prog_phy_link_rate &= ~CFG_PROG_PHY_LINK_RATE_MSK; + prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max); + hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, + prog_phy_link_rate); +-- +2.27.0 + diff --git a/patches/0702-scsi-hisi_sas-Make-phy-index-variable-name-consisten.patch b/patches/0702-scsi-hisi_sas-Make-phy-index-variable-name-consisten.patch new file mode 100644 index 0000000..3a874d5 --- /dev/null +++ b/patches/0702-scsi-hisi_sas-Make-phy-index-variable-name-consisten.patch @@ -0,0 +1,162 @@ +From f7d6e01a03bdad472e3b2bb3b905c91f7ea2015b Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 1 Sep 2020 19:13:06 +0800 +Subject: [PATCH 054/108] scsi: hisi_sas: Make phy index variable name + consistent + +mainline inclusion +from mainline-v5.10-rc1 +commit ca06f2cd01d08fe01b155ee774a2c6518b03b275 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ca06f2cd01d08fe01b155ee774a2c6518b03b275 + +---------------------------------------------------------------------- + +We use "phy_id" to identify phy in the BIST code but the rest of code +always uses "phy_no". Change it for consistency. + +Link: https://lore.kernel.org/r/1598958790-232272-5-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 52 +++++++++++++------------- + 1 file changed, 26 insertions(+), 26 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index e278d5d8c0d9..b45fb3ccc851 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3318,69 +3318,69 @@ static void debugfs_snapshot_restore_v3_hw(struct hisi_hba *hisi_hba) + static void hisi_sas_bist_test_prep_v3_hw(struct hisi_hba *hisi_hba) + { + u32 reg_val; +- int phy_id = hisi_hba->bist_loopback_phy_id; ++ int phy_no = hisi_hba->bist_loopback_phy_id; + + /* disable PHY */ +- hisi_sas_phy_enable(hisi_hba, phy_id, 0); ++ hisi_sas_phy_enable(hisi_hba, phy_no, 0); + + /* disable ALOS */ +- reg_val = hisi_sas_phy_read32(hisi_hba, phy_id, SERDES_CFG); ++ reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SERDES_CFG); + reg_val |= CFG_ALOS_CHK_DISABLE_MSK; +- hisi_sas_phy_write32(hisi_hba, phy_id, SERDES_CFG, reg_val); ++ hisi_sas_phy_write32(hisi_hba, phy_no, SERDES_CFG, reg_val); + } + + static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba) + { + u32 reg_val; +- int phy_id = hisi_hba->bist_loopback_phy_id; ++ int phy_no = hisi_hba->bist_loopback_phy_id; + + /* disable loopback */ +- reg_val = hisi_sas_phy_read32(hisi_hba, phy_id, SAS_PHY_BIST_CTRL); ++ reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL); + reg_val &= ~(CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK | + CFG_BIST_TEST_MSK); +- hisi_sas_phy_write32(hisi_hba, phy_id, SAS_PHY_BIST_CTRL, reg_val); ++ hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, reg_val); + +- /* enable ALOS*/ +- reg_val = hisi_sas_phy_read32(hisi_hba, phy_id, SERDES_CFG); ++ /* enable ALOS */ ++ reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SERDES_CFG); + reg_val &= ~CFG_ALOS_CHK_DISABLE_MSK; +- hisi_sas_phy_write32(hisi_hba, phy_id, SERDES_CFG, reg_val); ++ hisi_sas_phy_write32(hisi_hba, phy_no, SERDES_CFG, reg_val); + +- /*restore the linkrate*/ +- reg_val = hisi_sas_phy_read32(hisi_hba, phy_id, PROG_PHY_LINK_RATE); ++ /* restore the linkrate */ ++ reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE); + /* init OOB link rate as 1.5 Gbits */ + reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK; + reg_val |= (0x8 << CFG_PROG_OOB_PHY_LINK_RATE_OFF); +- hisi_sas_phy_write32(hisi_hba, phy_id, PROG_PHY_LINK_RATE, reg_val); ++ hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, reg_val); + + /* enable PHY */ +- hisi_sas_phy_enable(hisi_hba, phy_id, 1); ++ hisi_sas_phy_enable(hisi_hba, phy_no, 1); + } + + static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + { + u32 reg_val, mode_tmp; + u32 linkrate = hisi_hba->bist_loopback_linkrate; +- u32 phy_id = hisi_hba->bist_loopback_phy_id; ++ u32 phy_no = hisi_hba->bist_loopback_phy_id; + u32 code_mode = hisi_hba->bist_loopback_code_mode; + u32 path_mode = hisi_hba->bist_loopback_mode; + +- pr_err("linkrate=%d phy_id=%d code_mode=%d path_mode=%d\n", linkrate, +- phy_id, code_mode, path_mode); ++ pr_err("linkrate=%d phy_no=%d code_mode=%d path_mode=%d\n", linkrate, ++ phy_no, code_mode, path_mode); + mode_tmp = path_mode ? 2 : 1; + if (enable) { + /* some preparations before bist test */ + hisi_sas_bist_test_prep_v3_hw(hisi_hba); + + /* set linkrate of bit test*/ +- reg_val = hisi_sas_phy_read32(hisi_hba, phy_id, ++ reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, + PROG_PHY_LINK_RATE); + reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK; + reg_val |= (linkrate << CFG_PROG_OOB_PHY_LINK_RATE_OFF); +- hisi_sas_phy_write32(hisi_hba, phy_id, ++ hisi_sas_phy_write32(hisi_hba, phy_no, + PROG_PHY_LINK_RATE, reg_val); + + /* set code mode of bit test */ +- reg_val = hisi_sas_phy_read32(hisi_hba, phy_id, ++ reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, + SAS_PHY_BIST_CTRL); + reg_val &= ~(CFG_BIST_MODE_SEL_MSK | + CFG_LOOP_TEST_MODE_MSK | +@@ -3390,27 +3390,27 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + reg_val |= ((code_mode << CFG_BIST_MODE_SEL_OFF) | + (mode_tmp << CFG_LOOP_TEST_MODE_OFF) | + CFG_BIST_TEST_MSK); +- hisi_sas_phy_write32(hisi_hba, phy_id, ++ hisi_sas_phy_write32(hisi_hba, phy_no, + SAS_PHY_BIST_CTRL, reg_val); + + /*set the bist init data*/ +- hisi_sas_phy_write32(hisi_hba, phy_id, ++ hisi_sas_phy_write32(hisi_hba, phy_no, + SAS_PHY_BIST_CODE, 0x1); +- hisi_sas_phy_write32(hisi_hba, phy_id, ++ hisi_sas_phy_write32(hisi_hba, phy_no, + SAS_PHY_BIST_CODE1, 0x80); + + mdelay(100); + reg_val |= (CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK); +- hisi_sas_phy_write32(hisi_hba, phy_id, ++ hisi_sas_phy_write32(hisi_hba, phy_no, + SAS_PHY_BIST_CTRL, reg_val); + + /* clear error bit */ + mdelay(100); +- hisi_sas_phy_read32(hisi_hba, phy_id, SAS_BIST_ERR_CNT); ++ hisi_sas_phy_read32(hisi_hba, phy_no, SAS_BIST_ERR_CNT); + } else { + /* disable bist test and recover it */ + hisi_hba->bist_loopback_cnt += hisi_sas_phy_read32(hisi_hba, +- phy_id, SAS_BIST_ERR_CNT); ++ phy_no, SAS_BIST_ERR_CNT); + hisi_sas_bist_test_restore_v3_hw(hisi_hba); + } + +-- +2.27.0 + diff --git a/patches/0703-scsi-hisi_sas-Add-BIST-support-for-phy-FFE.patch b/patches/0703-scsi-hisi_sas-Add-BIST-support-for-phy-FFE.patch new file mode 100644 index 0000000..df16f2d --- /dev/null +++ b/patches/0703-scsi-hisi_sas-Add-BIST-support-for-phy-FFE.patch @@ -0,0 +1,75 @@ +From 188031fc5d10d4b702e33dc1b062f9ffe4a27974 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 1 Sep 2020 19:13:07 +0800 +Subject: [PATCH 055/108] scsi: hisi_sas: Add BIST support for phy FFE + +mainline inclusion +from mainline-v5.10-rc1 +commit 2c4d582322ff412f83f5c538e33c9440a30db73d +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2c4d582322ff412f83f5c538e33c9440a30db73d + +---------------------------------------------------------------------- + +Add BIST support for phy FFE (Feed forward equalizer) setting. The user can +configure FFE through the new debugfs interface. + +FFE is a parameter used for link layer control. It will affect the link +quality between the SAS controller and the backplane. In the BIST test, the +FFE interface is provided to assist board testers in optimizing link +parameters. + +The modification of the FFE parameter will affect the test after BIST or +the normal running of the board. The user should save the initial FFE +values and restore them after BIST test is complete. + +Link: https://lore.kernel.org/r/1598958790-232272-6-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h + drivers/scsi/hisi_sas/hisi_sas_main.c + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 6b66c056ecc8..94514b3615e2 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -313,6 +313,18 @@ enum hisi_sas_debugfs_cache_type { + HISI_SAS_IOST_CACHE, + }; + ++enum hisi_sas_debugfs_bist_ffe_cfg { ++ FFE_SAS_1_5_GBPS, ++ FFE_SAS_3_0_GBPS, ++ FFE_SAS_6_0_GBPS, ++ FFE_SAS_12_0_GBPS, ++ FFE_RESV, ++ FFE_SATA_1_5_GBPS, ++ FFE_SATA_3_0_GBPS, ++ FFE_SATA_6_0_GBPS, ++ FFE_CFG_MAX ++}; ++ + struct hisi_sas_hw { + int (*hw_init)(struct hisi_hba *hisi_hba); + void (*setup_itct)(struct hisi_hba *hisi_hba, +@@ -479,6 +491,7 @@ struct hisi_hba { + int bist_loopback_mode; + u32 bist_loopback_cnt; + int bist_loopback_enable; ++ u32 debugfs_bist_ffe[HISI_SAS_MAX_PHYS][FFE_CFG_MAX]; + + int enable_dix_dif; + unsigned int *reply_map; +-- +2.27.0 + diff --git a/patches/0704-scsi-hisi_sas-Add-BIST-support-for-fixed-code-patter.patch b/patches/0704-scsi-hisi_sas-Add-BIST-support-for-fixed-code-patter.patch new file mode 100644 index 0000000..bdbf8de --- /dev/null +++ b/patches/0704-scsi-hisi_sas-Add-BIST-support-for-fixed-code-patter.patch @@ -0,0 +1,332 @@ +From 50527061356720fb572267227ce06b1267373214 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 1 Sep 2020 19:13:08 +0800 +Subject: [PATCH 056/108] scsi: hisi_sas: Add BIST support for fixed code + pattern + +mainline inclusion +from mainline-v5.10-rc1 +commit 981cc23e741a641ca92c37c7a3df180ced702118 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=981cc23e741a641ca92c37c7a3df180ced702118 + +---------------------------------------------------------------------- + +Through the new debugfs interface the user can select fixed code +patterns. Add two new interfaces fixed_code and fixed_code1. + +Link: https://lore.kernel.org/r/1598958790-232272-7-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 37 +++++++------ + drivers/scsi/hisi_sas/hisi_sas_main.c | 75 ++++++++++++++++++++++++++ + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 68 +++++++++++++++++------ + 3 files changed, 149 insertions(+), 31 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 94514b3615e2..f9512b6c2d02 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -282,21 +282,6 @@ enum { + HISI_SAS_BIST_LOOPBACK_MODE_REMOTE, + }; + +-enum { +- HISI_SAS_BIST_CODE_MODE_PRBS7 = 0, +- HISI_SAS_BIST_CODE_MODE_PRBS23, +- HISI_SAS_BIST_CODE_MODE_PRBS31, +- HISI_SAS_BIST_CODE_MODE_JTPAT, +- HISI_SAS_BIST_CODE_MODE_CJTPAT, +- HISI_SAS_BIST_CODE_MODE_SCRAMBED_0, +- HISI_SAS_BIST_CODE_MODE_TRAIN, +- HISI_SAS_BIST_CODE_MODE_TRAIN_DONE, +- HISI_SAS_BIST_CODE_MODE_HFTP, +- HISI_SAS_BIST_CODE_MODE_MFTP, +- HISI_SAS_BIST_CODE_MODE_LFTP, +- HISI_SAS_BIST_CODE_MODE_FIXED_DATA, +-}; +- + struct hisi_sas_iost_itct_cache { + u32 data[HISI_SAS_IOST_ITCT_CACHE_DW_SZ]; + }; +@@ -325,6 +310,27 @@ enum hisi_sas_debugfs_bist_ffe_cfg { + FFE_CFG_MAX + }; + ++enum hisi_sas_debugfs_bist_fixed_code { ++ FIXED_CODE, ++ FIXED_CODE_1, ++ FIXED_CODE_MAX ++}; ++ ++enum { ++ HISI_SAS_BIST_CODE_MODE_PRBS7, ++ HISI_SAS_BIST_CODE_MODE_PRBS23, ++ HISI_SAS_BIST_CODE_MODE_PRBS31, ++ HISI_SAS_BIST_CODE_MODE_JTPAT, ++ HISI_SAS_BIST_CODE_MODE_CJTPAT, ++ HISI_SAS_BIST_CODE_MODE_SCRAMBED_0, ++ HISI_SAS_BIST_CODE_MODE_TRAIN, ++ HISI_SAS_BIST_CODE_MODE_TRAIN_DONE, ++ HISI_SAS_BIST_CODE_MODE_HFTP, ++ HISI_SAS_BIST_CODE_MODE_MFTP, ++ HISI_SAS_BIST_CODE_MODE_LFTP, ++ HISI_SAS_BIST_CODE_MODE_FIXED_DATA, ++}; ++ + struct hisi_sas_hw { + int (*hw_init)(struct hisi_hba *hisi_hba); + void (*setup_itct)(struct hisi_hba *hisi_hba, +@@ -492,6 +498,7 @@ struct hisi_hba { + u32 bist_loopback_cnt; + int bist_loopback_enable; + u32 debugfs_bist_ffe[HISI_SAS_MAX_PHYS][FFE_CFG_MAX]; ++ u32 debugfs_bist_fixed_code[FIXED_CODE_MAX]; + + int enable_dix_dif; + unsigned int *reply_map; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index a741a597fecf..41b656c0a0cd 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -3797,6 +3797,58 @@ static const struct file_operations hisi_sas_debugfs_trigger_dump_fops = { + .owner = THIS_MODULE, + }; + ++static const struct { ++ char *name; ++} hisi_sas_debugfs_ffe_name[FFE_CFG_MAX] = { ++ { "SAS_1_5_GBPS" }, ++ { "SAS_3_0_GBPS" }, ++ { "SAS_6_0_GBPS" }, ++ { "SAS_12_0_GBPS" }, ++ { "FFE_RESV" }, ++ { "SATA_1_5_GBPS" }, ++ { "SATA_3_0_GBPS" }, ++ { "SATA_6_0_GBPS" }, ++}; ++ ++static ssize_t hisi_sas_debugfs_write(struct file *filp, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *m = filp->private_data; ++ u32 *val = m->private; ++ int res; ++ ++ res = kstrtouint_from_user(buf, count, 0, val); ++ if (res) ++ return res; ++ ++ return count; ++} ++ ++static int hisi_sas_debugfs_show(struct seq_file *s, void *p) ++{ ++ u32 *val = s->private; ++ ++ seq_printf(s, "0x%x\n", *val); ++ ++ return 0; ++} ++ ++static int hisi_sas_debugfs_open(struct inode *inode, struct file *filp) ++{ ++ return single_open(filp, hisi_sas_debugfs_show, ++ inode->i_private); ++} ++ ++static const struct file_operations hisi_sas_debugfs_ops = { ++ .open = hisi_sas_debugfs_open, ++ .read = seq_read, ++ .write = hisi_sas_debugfs_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ + static ssize_t hisi_sas_debugfs_phy_down_cnt_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +@@ -3894,6 +3946,8 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba, int dump_index) + struct device *dev = hisi_hba->dev; + int p, c, d, r, i; + size_t sz; ++ struct dentry *ports_dentry; ++ int phy_no; + + /* create bist structures */ + hisi_hba->debugfs_bist_dentry = debugfs_create_dir("bist", +@@ -3928,6 +3982,27 @@ static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba, int dump_index) + hisi_hba, &hisi_sas_debugfs_bist_enable_ops)) + goto fail; + ++ ports_dentry = debugfs_create_dir("port", ++ hisi_hba->debugfs_bist_dentry); ++ ++ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { ++ struct dentry *port_dentry; ++ struct dentry *ffe_dentry; ++ char name[256]; ++ ++ snprintf(name, 256, "%d", phy_no); ++ port_dentry = debugfs_create_dir(name, ports_dentry); ++ ffe_dentry = debugfs_create_dir("ffe", port_dentry); ++ for (i = 0; i < FFE_CFG_MAX; i++) { ++ if (i == FFE_RESV) ++ continue; ++ debugfs_create_file(hisi_sas_debugfs_ffe_name[i].name, ++ 0600, ffe_dentry, ++ &hisi_hba->debugfs_bist_ffe[phy_no][i], ++ &hisi_sas_debugfs_ops); ++ } ++ } ++ + for (r = 0; r < DEBUGFS_REGS_NUM; r++) { + struct hisi_sas_debugfs_regs *regs = + &hisi_hba->debugfs_regs[dump_index][r]; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index b45fb3ccc851..761f0cf46770 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -306,6 +306,7 @@ + #define DMA_RX_STATUS_BUSY_MSK (0x1 << DMA_RX_STATUS_BUSY_OFF) + + #define COARSETUNE_TIME (PORT_BASE + 0x304) ++#define TXDEEMPH_G1 (PORT_BASE + 0x350) + #define ERR_CNT_DWS_LOST (PORT_BASE + 0x380) + #define ERR_CNT_RESET_PROB (PORT_BASE + 0x384) + #define ERR_CNT_INVLD_DW (PORT_BASE + 0x390) +@@ -620,7 +621,7 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba, + + static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + { +- int i; ++ int i, j; + + /* Global registers init */ + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, +@@ -723,6 +724,13 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + /* used for 12G negotiate */ + hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e); + hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff); ++ ++ /* get default FFE configuration for BIST */ ++ for (j = 0; j < FFE_CFG_MAX; j++) { ++ u32 val = hisi_sas_phy_read32(hisi_hba, i, ++ TXDEEMPH_G1 + (j * 0x4)); ++ hisi_hba->debugfs_bist_ffe[i][j] = val; ++ } + } + + for (i = 0; i < hisi_hba->queue_count; i++) { +@@ -3319,10 +3327,16 @@ static void hisi_sas_bist_test_prep_v3_hw(struct hisi_hba *hisi_hba) + { + u32 reg_val; + int phy_no = hisi_hba->bist_loopback_phy_id; ++ int i; + + /* disable PHY */ + hisi_sas_phy_enable(hisi_hba, phy_no, 0); + ++ /* update FFE */ ++ for (i = 0; i < FFE_CFG_MAX; i++) ++ hisi_sas_phy_write32(hisi_hba, phy_no, TXDEEMPH_G1 + (i * 0x4), ++ hisi_hba->debugfs_bist_ffe[phy_no][i]); ++ + /* disable ALOS */ + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, SERDES_CFG); + reg_val |= CFG_ALOS_CHK_DISABLE_MSK; +@@ -3356,16 +3370,28 @@ static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba) + hisi_sas_phy_enable(hisi_hba, phy_no, 1); + } + ++#define SAS_PHY_BIST_CODE_INIT 0x1 ++#define SAS_PHY_BIST_CODE1_INIT 0x80 + static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + { + u32 reg_val, mode_tmp; + u32 linkrate = hisi_hba->bist_loopback_linkrate; + u32 phy_no = hisi_hba->bist_loopback_phy_id; ++ u32 *ffe = hisi_hba->debugfs_bist_ffe[phy_no]; + u32 code_mode = hisi_hba->bist_loopback_code_mode; + u32 path_mode = hisi_hba->bist_loopback_mode; ++ u32 *fix_code = &hisi_hba->debugfs_bist_fixed_code[0]; ++ struct device *dev = hisi_hba->dev; ++ ++ ++ dev_info(dev, "BIST info:phy%d link_rate=%d code_mode=%d path_mode=%d ffe={0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x} fixed_code={0x%x, 0x%x}\n", ++ phy_no, linkrate, code_mode, path_mode, ++ ffe[FFE_SAS_1_5_GBPS], ffe[FFE_SAS_3_0_GBPS], ++ ffe[FFE_SAS_6_0_GBPS], ffe[FFE_SAS_12_0_GBPS], ++ ffe[FFE_SATA_1_5_GBPS], ffe[FFE_SATA_3_0_GBPS], ++ ffe[FFE_SATA_6_0_GBPS], fix_code[FIXED_CODE], ++ fix_code[FIXED_CODE_1]); + +- pr_err("linkrate=%d phy_no=%d code_mode=%d path_mode=%d\n", linkrate, +- phy_no, code_mode, path_mode); + mode_tmp = path_mode ? 2 : 1; + if (enable) { + /* some preparations before bist test */ +@@ -3382,27 +3408,37 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + /* set code mode of bit test */ + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, + SAS_PHY_BIST_CTRL); +- reg_val &= ~(CFG_BIST_MODE_SEL_MSK | +- CFG_LOOP_TEST_MODE_MSK | +- CFG_RX_BIST_EN_MSK | +- CFG_TX_BIST_EN_MSK | +- CFG_BIST_TEST_MSK); ++ reg_val &= ~(CFG_BIST_MODE_SEL_MSK | CFG_LOOP_TEST_MODE_MSK | ++ CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK | ++ CFG_BIST_TEST_MSK); + reg_val |= ((code_mode << CFG_BIST_MODE_SEL_OFF) | + (mode_tmp << CFG_LOOP_TEST_MODE_OFF) | + CFG_BIST_TEST_MSK); +- hisi_sas_phy_write32(hisi_hba, phy_no, +- SAS_PHY_BIST_CTRL, reg_val); ++ hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, ++ reg_val); + + /*set the bist init data*/ +- hisi_sas_phy_write32(hisi_hba, phy_no, +- SAS_PHY_BIST_CODE, 0x1); +- hisi_sas_phy_write32(hisi_hba, phy_no, +- SAS_PHY_BIST_CODE1, 0x80); ++ if (code_mode == HISI_SAS_BIST_CODE_MODE_FIXED_DATA) { ++ reg_val = hisi_hba->debugfs_bist_fixed_code[0]; ++ hisi_sas_phy_write32(hisi_hba, phy_no, ++ SAS_PHY_BIST_CODE, reg_val); ++ ++ reg_val = hisi_hba->debugfs_bist_fixed_code[1]; ++ hisi_sas_phy_write32(hisi_hba, phy_no, ++ SAS_PHY_BIST_CODE1, reg_val); ++ } else { ++ hisi_sas_phy_write32(hisi_hba, phy_no, ++ SAS_PHY_BIST_CODE, ++ SAS_PHY_BIST_CODE_INIT); ++ hisi_sas_phy_write32(hisi_hba, phy_no, ++ SAS_PHY_BIST_CODE1, ++ SAS_PHY_BIST_CODE1_INIT); ++ } + + mdelay(100); + reg_val |= (CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK); +- hisi_sas_phy_write32(hisi_hba, phy_no, +- SAS_PHY_BIST_CTRL, reg_val); ++ hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, ++ reg_val); + + /* clear error bit */ + mdelay(100); +-- +2.27.0 + diff --git a/patches/0705-scsi-hisi_sas-Add-missing-newlines.patch b/patches/0705-scsi-hisi_sas-Add-missing-newlines.patch new file mode 100644 index 0000000..24efdcf --- /dev/null +++ b/patches/0705-scsi-hisi_sas-Add-missing-newlines.patch @@ -0,0 +1,155 @@ +From 950b6a6462d8d0772a675f04eb4ad63bf0e540b8 Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Tue, 1 Sep 2020 19:13:09 +0800 +Subject: [PATCH 057/108] scsi: hisi_sas: Add missing newlines + +mainline inclusion +from mainline-v5.10-rc1 +commit b601577df68af896e563ca62ca07d8681912eabc +category: cleanup +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b601577df68af896e563ca62ca07d8681912eabc + +---------------------------------------------------------------------- + +Newline is missing from some printk() statements. Add them. + +Link: https://lore.kernel.org/r/1598958790-232272-8-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 24 ++++++++++++------------ + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- + 4 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 41b656c0a0cd..a311812438f4 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -353,7 +353,7 @@ static int hisi_sas_dma_map(struct hisi_hba *hisi_hba, + *n_elem = task->num_scatter; + + if (*n_elem > HISI_SAS_SGE_PAGE_CNT) { +- dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT", ++ dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT\n", + *n_elem); + rc = -EINVAL; + goto err_out_dma_unmap; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index 09cc42e66dd5..c82abcf2567c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -756,7 +756,7 @@ static int hw_init_v1_hw(struct hisi_hba *hisi_hba) + + rc = reset_hw_v1_hw(hisi_hba); + if (rc) { +- dev_err(dev, "hisi_sas_reset_hw failed, rc=%d", rc); ++ dev_err(dev, "hisi_sas_reset_hw failed, rc=%d\n", rc); + return rc; + } + +@@ -1170,7 +1170,7 @@ static void slot_err_v1_hw(struct hisi_hba *hisi_hba, + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: + { +- dev_err(dev, "slot err: SATA/STP not supported"); ++ dev_err(dev, "slot err: SATA/STP not supported\n"); + } + break; + default: +@@ -1222,35 +1222,35 @@ static void slot_complete_v1_hw(struct hisi_hba *hisi_hba, + u32 info_reg = hisi_sas_read32(hisi_hba, HGC_INVLD_DQE_INFO); + + if (info_reg & HGC_INVLD_DQE_INFO_DQ_MSK) +- dev_err(dev, "slot complete: [%d:%d] has dq IPTT err", ++ dev_err(dev, "slot complete: [%d:%d] has dq IPTT err\n", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_TYPE_MSK) +- dev_err(dev, "slot complete: [%d:%d] has dq type err", ++ dev_err(dev, "slot complete: [%d:%d] has dq type err\n", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_FORCE_MSK) +- dev_err(dev, "slot complete: [%d:%d] has dq force phy err", ++ dev_err(dev, "slot complete: [%d:%d] has dq force phy err\n", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_PHY_MSK) +- dev_err(dev, "slot complete: [%d:%d] has dq phy id err", ++ dev_err(dev, "slot complete: [%d:%d] has dq phy id err\n", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_ABORT_MSK) +- dev_err(dev, "slot complete: [%d:%d] has dq abort flag err", ++ dev_err(dev, "slot complete: [%d:%d] has dq abort flag err\n", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_IPTT_OF_MSK) +- dev_err(dev, "slot complete: [%d:%d] has dq IPTT or ICT err", ++ dev_err(dev, "slot complete: [%d:%d] has dq IPTT or ICT err\n", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_SSP_ERR_MSK) +- dev_err(dev, "slot complete: [%d:%d] has dq SSP frame type err", ++ dev_err(dev, "slot complete: [%d:%d] has dq SSP frame type err\n", + slot->cmplt_queue, slot->cmplt_queue_slot); + + if (info_reg & HGC_INVLD_DQE_INFO_OFL_MSK) +- dev_err(dev, "slot complete: [%d:%d] has dq order frame len err", ++ dev_err(dev, "slot complete: [%d:%d] has dq order frame len err\n", + slot->cmplt_queue, slot->cmplt_queue_slot); + + ts->stat = SAS_OPEN_REJECT; +@@ -1298,7 +1298,7 @@ static void slot_complete_v1_hw(struct hisi_hba *hisi_hba, + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: +- dev_err(dev, "slot complete: SATA/STP not supported"); ++ dev_err(dev, "slot complete: SATA/STP not supported\n"); + break; + + default: +@@ -1421,7 +1421,7 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p) + irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2); + + if (!(irq_value & CHL_INT2_SL_RX_BC_ACK_MSK)) { +- dev_err(dev, "bcast: irq_value = %x not set enable bit", ++ dev_err(dev, "bcast: irq_value = %x not set enable bit\n", + irq_value); + res = IRQ_NONE; + goto end; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index 7e0059d3b3ef..404bbf228b78 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -1389,7 +1389,7 @@ static int hw_init_v2_hw(struct hisi_hba *hisi_hba) + + rc = reset_hw_v2_hw(hisi_hba); + if (rc) { +- dev_err(dev, "hisi_sas_reset_hw failed, rc=%d", rc); ++ dev_err(dev, "hisi_sas_reset_hw failed, rc=%d\n", rc); + return rc; + } + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 761f0cf46770..9581f8d237f7 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1006,7 +1006,7 @@ static int hw_init_v3_hw(struct hisi_hba *hisi_hba) + + rc = reset_hw_v3_hw(hisi_hba); + if (rc) { +- dev_err(dev, "hisi_sas_reset_hw failed, rc=%d", rc); ++ dev_err(dev, "hisi_sas_reset_hw failed, rc=%d\n", rc); + return rc; + } + +-- +2.27.0 + diff --git a/patches/0706-scsi-hisi_sas-Code-style-cleanup.patch b/patches/0706-scsi-hisi_sas-Code-style-cleanup.patch new file mode 100644 index 0000000..22abd31 --- /dev/null +++ b/patches/0706-scsi-hisi_sas-Code-style-cleanup.patch @@ -0,0 +1,85 @@ +From 35323cad27039b57654be782637812e304cde7e0 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 1 Sep 2020 19:13:10 +0800 +Subject: [PATCH 058/108] scsi: hisi_sas: Code style cleanup + +mainline inclusion +from mainline-v5.10-rc1 +commit 26f84f9bc3ba04dd415a93e4ca16eda896cf94ea +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=26f84f9bc3ba04dd415a93e4ca16eda896cf94ea + +---------------------------------------------------------------------- + +Remove extra blank lines and add spaces around operators. + +Link: https://lore.kernel.org/r/1598958790-232272-9-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 1 - + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 +--- + 3 files changed, 2 insertions(+), 5 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index a311812438f4..154bd66a5915 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1470,7 +1470,6 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state) + } else { + hisi_sas_phy_down(hisi_hba, phy_no, 0); + } +- + } + } + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index 404bbf228b78..1d1ee655c9fb 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -1209,7 +1209,7 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba) + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0x7ffe20fe); + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0xfff00c30); + for (i = 0; i < hisi_hba->queue_count; i++) +- hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK+0x4*i, 0); ++ hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0); + + hisi_sas_write32(hisi_hba, AXI_AHB_CLK_CFG, 1); + hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 9581f8d237f7..ebab606f9f9a 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -651,7 +651,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + hisi_sas_write32(hisi_hba, AWQOS_AWCACHE_CFG, 0xf0f0); + hisi_sas_write32(hisi_hba, ARQOS_ARCACHE_CFG, 0xf0f0); + for (i = 0; i < hisi_hba->queue_count; i++) +- hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK+0x4*i, 0); ++ hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0); + + hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1); + +@@ -1495,7 +1495,6 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba, + + hdr->cmd_table_addr = cpu_to_le64(req_dma_addr); + hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot)); +- + } + + static void prep_ata_v3_hw(struct hisi_hba *hisi_hba, +@@ -1607,7 +1606,6 @@ static void prep_abort_v3_hw(struct hisi_hba *hisi_hba, + /* dw7 */ + hdr->dw7 = cpu_to_le32(tag_to_abort << CMD_HDR_ABORT_IPTT_OFF); + hdr->transfer_tags = cpu_to_le32(slot->idx); +- + } + + static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) +-- +2.27.0 + diff --git a/patches/0707-scsi-hisi_sas-Switch-to-new-framework-to-support-sus.patch b/patches/0707-scsi-hisi_sas-Switch-to-new-framework-to-support-sus.patch new file mode 100644 index 0000000..617ddc3 --- /dev/null +++ b/patches/0707-scsi-hisi_sas-Switch-to-new-framework-to-support-sus.patch @@ -0,0 +1,87 @@ +From 01ce568fbfc1e950db1691cddc07be406b650433 Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Fri, 2 Oct 2020 22:30:33 +0800 +Subject: [PATCH 059/108] scsi: hisi_sas: Switch to new framework to support + suspend and resume + +mainline inclusion +from mainline-v5.10-rc1 +commit 6c459ea1542b8937779cbeefb2b1cc77a554c29c +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81U + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6c459ea1542b8937779cbeefb2b1cc77a554c29c + +---------------------------------------------------------------------- + +For v3 hw we will add support for runtime PM which is only supported in new +framework. Legacy PM support and new framework are not allowed to be used +together. Switch to new framework to support suspend and resume. + +Link: https://lore.kernel.org/r/1601649038-25534-3-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index ebab606f9f9a..26626823f175 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3808,8 +3808,9 @@ enum { + hip08, + }; + +-static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state) ++static int suspend_v3_hw(struct device *device) + { ++ struct pci_dev *pdev = to_pci_dev(device); + struct sas_ha_struct *sha = pci_get_drvdata(pdev); + struct hisi_hba *hisi_hba = sha->lldd_ha; + struct device *dev = hisi_hba->dev; +@@ -3840,7 +3841,7 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state) + + hisi_sas_init_mem(hisi_hba); + +- device_state = pci_choose_state(pdev, state); ++ device_state = pci_choose_state(pdev, PMSG_SUSPEND); + dev_warn(dev, "entering operating state [D%d]\n", + device_state); + pci_save_state(pdev); +@@ -3853,8 +3854,9 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state) + return 0; + } + +-static int hisi_sas_v3_resume(struct pci_dev *pdev) ++static int resume_v3_hw(struct device *device) + { ++ struct pci_dev *pdev = to_pci_dev(device); + struct sas_ha_struct *sha = pci_get_drvdata(pdev); + struct hisi_hba *hisi_hba = sha->lldd_ha; + struct Scsi_Host *shost = hisi_hba->shost; +@@ -3902,14 +3904,17 @@ static const struct pci_error_handlers hisi_sas_err_handler = { + .reset_done = hisi_sas_reset_done_v3_hw, + }; + ++static const struct dev_pm_ops hisi_sas_v3_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(suspend_v3_hw, resume_v3_hw) ++}; ++ + static struct pci_driver sas_v3_pci_driver = { + .name = DRV_NAME, + .id_table = sas_v3_pci_table, + .probe = hisi_sas_v3_probe, + .remove = hisi_sas_v3_remove, +- .suspend = hisi_sas_v3_suspend, +- .resume = hisi_sas_v3_resume, + .err_handler = &hisi_sas_err_handler, ++ .driver.pm = &hisi_sas_v3_pm_ops, + }; + + module_pci_driver(sas_v3_pci_driver); +-- +2.27.0 + diff --git a/patches/0708-scsi-hisi_sas-Add-controller-runtime-PM-support-for-.patch b/patches/0708-scsi-hisi_sas-Add-controller-runtime-PM-support-for-.patch new file mode 100644 index 0000000..6d995c0 --- /dev/null +++ b/patches/0708-scsi-hisi_sas-Add-controller-runtime-PM-support-for-.patch @@ -0,0 +1,155 @@ +From 3d30a9dada3bef0ff3138cf4cb86ae390762c770 Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Fri, 2 Oct 2020 22:30:34 +0800 +Subject: [PATCH 060/108] scsi: hisi_sas: Add controller runtime PM support for + v3 hw + +mainline inclusion +from mainline-v5.10-rc1 +commit 65ff4aef7e9bde00871875c5fbc9c6b79df6f5ba +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81U + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=65ff4aef7e9bde00871875c5fbc9c6b79df6f5ba + +---------------------------------------------------------------------- + +Add controller runtime PM support for v3 hw. + +Link: https://lore.kernel.org/r/1601649038-25534-4-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 2 + + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 56 +++++++++++++++++++++++++- + 2 files changed, 56 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index f9512b6c2d02..b2a368e41f0c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -38,6 +39,7 @@ + #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES + #define HISI_SAS_RESET_BIT 0 + #define HISI_SAS_REJECT_CMD_BIT 1 ++#define HISI_SAS_PM_BIT 2 + #define HISI_SAS_MAX_COMMANDS (HISI_SAS_QUEUE_SLOTS) + #define HISI_SAS_RESERVED_IPTT 96 + #define HISI_SAS_UNRESERVED_IPTT \ +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 26626823f175..ad39439bc04d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3712,6 +3712,17 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + scsi_scan_host(shost); + ++ /* ++ * For the situation that there are ATA disks connected with SAS ++ * controller, it additionally creates ata_port which will affect the ++ * child_count of hisi_hba->dev. Even if suspended all the disks, ++ * ata_port is still and the child_count of hisi_hba->dev is not 0. ++ * So use pm_suspend_ignore_children() to ignore the effect to ++ * hisi_hba->dev. ++ */ ++ pm_suspend_ignore_children(dev, true); ++ pm_runtime_put_noidle(&pdev->dev); ++ + return 0; + + err_out_register_ha: +@@ -3752,6 +3763,7 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev) + struct hisi_hba *hisi_hba = sha->lldd_ha; + struct Scsi_Host *shost = sha->core.shost; + ++ pm_runtime_get_noresume(dev); + if (timer_pending(&hisi_hba->timer)) + del_timer(&hisi_hba->timer); + +@@ -3808,7 +3820,7 @@ enum { + hip08, + }; + +-static int suspend_v3_hw(struct device *device) ++static int _suspend_v3_hw(struct device *device) + { + struct pci_dev *pdev = to_pci_dev(device); + struct sas_ha_struct *sha = pci_get_drvdata(pdev); +@@ -3854,7 +3866,7 @@ static int suspend_v3_hw(struct device *device) + return 0; + } + +-static int resume_v3_hw(struct device *device) ++static int _resume_v3_hw(struct device *device) + { + struct pci_dev *pdev = to_pci_dev(device); + struct sas_ha_struct *sha = pci_get_drvdata(pdev); +@@ -3893,6 +3905,34 @@ static int resume_v3_hw(struct device *device) + return 0; + } + ++static int suspend_v3_hw(struct device *device) ++{ ++ struct pci_dev *pdev = to_pci_dev(device); ++ struct sas_ha_struct *sha = pci_get_drvdata(pdev); ++ struct hisi_hba *hisi_hba = sha->lldd_ha; ++ int rc; ++ ++ set_bit(HISI_SAS_PM_BIT, &hisi_hba->flags); ++ ++ rc = _suspend_v3_hw(device); ++ if (rc) ++ clear_bit(HISI_SAS_PM_BIT, &hisi_hba->flags); ++ ++ return rc; ++} ++ ++static int resume_v3_hw(struct device *device) ++{ ++ struct pci_dev *pdev = to_pci_dev(device); ++ struct sas_ha_struct *sha = pci_get_drvdata(pdev); ++ struct hisi_hba *hisi_hba = sha->lldd_ha; ++ int rc = _resume_v3_hw(device); ++ ++ clear_bit(HISI_SAS_PM_BIT, &hisi_hba->flags); ++ ++ return rc; ++} ++ + static const struct pci_device_id sas_v3_pci_table[] = { + { PCI_VDEVICE(HUAWEI, 0xa230), hip08 }, + {} +@@ -3904,8 +3944,20 @@ static const struct pci_error_handlers hisi_sas_err_handler = { + .reset_done = hisi_sas_reset_done_v3_hw, + }; + ++static int runtime_suspend_v3_hw(struct device *dev) ++{ ++ return suspend_v3_hw(dev); ++} ++ ++static int runtime_resume_v3_hw(struct device *dev) ++{ ++ return resume_v3_hw(dev); ++} ++ + static const struct dev_pm_ops hisi_sas_v3_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(suspend_v3_hw, resume_v3_hw) ++ SET_RUNTIME_PM_OPS(runtime_suspend_v3_hw, ++ runtime_resume_v3_hw, NULL) + }; + + static struct pci_driver sas_v3_pci_driver = { +-- +2.27.0 + diff --git a/patches/0709-scsi-hisi_sas-Add-check-for-methods-_PS0-and-_PR0.patch b/patches/0709-scsi-hisi_sas-Add-check-for-methods-_PS0-and-_PR0.patch new file mode 100644 index 0000000..4f94ff7 --- /dev/null +++ b/patches/0709-scsi-hisi_sas-Add-check-for-methods-_PS0-and-_PR0.patch @@ -0,0 +1,69 @@ +From 22f0eb461f795aebe1123bd3c12e01f5ffbb5bca Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Fri, 2 Oct 2020 22:30:35 +0800 +Subject: [PATCH 061/108] scsi: hisi_sas: Add check for methods _PS0 and _PR0 + +mainline inclusion +from mainline-v5.10-rc1 +commit e06596d5000c58f35721f334fe2eee28e3b01a77 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81U + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e06596d5000c58f35721f334fe2eee28e3b01a77 + +---------------------------------------------------------------------- + +To support system suspend/resume or runtime suspend/resume, need to use the +function pci_set_power_state() to change the power state which requires at +least method _PS0 or _PR0 be filled by platform for v3 hw. So check whether +the method is supported, if not, print a warning. + +A Kconfig dependency is added as there is no stub for +acpi_device_power_manageable(). + +Link: https://lore.kernel.org/r/1601649038-25534-5-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/Kconfig | 1 + + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 ++++ + 2 files changed, 5 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig +index 79ad42352825..11c46b217caa 100644 +--- a/drivers/scsi/hisi_sas/Kconfig ++++ b/drivers/scsi/hisi_sas/Kconfig +@@ -14,5 +14,6 @@ config SCSI_HISI_SAS_PCI + tristate "HiSilicon SAS on PCI bus" + depends on SCSI_HISI_SAS + depends on PCI ++ depends on ACPI + help + This driver supports HiSilicon's SAS HBA based on PCI device +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index ad39439bc04d..2d4615f2d9dc 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1000,6 +1000,7 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba) + static int hw_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; ++ struct acpi_device *acpi_dev; + union acpi_object *obj; + guid_t guid; + int rc; +@@ -1031,6 +1032,9 @@ static int hw_init_v3_hw(struct hisi_hba *hisi_hba) + else + ACPI_FREE(obj); + ++ acpi_dev = ACPI_COMPANION(dev); ++ if (!acpi_device_power_manageable(acpi_dev)) ++ dev_notice(dev, "neither _PS0 nor _PR0 is defined\n"); + return 0; + } + +-- +2.27.0 + diff --git a/patches/0710-scsi-hisi_sas-Add-device-link-between-SCSI-devices-a.patch b/patches/0710-scsi-hisi_sas-Add-device-link-between-SCSI-devices-a.patch new file mode 100644 index 0000000..e94c1a4 --- /dev/null +++ b/patches/0710-scsi-hisi_sas-Add-device-link-between-SCSI-devices-a.patch @@ -0,0 +1,86 @@ +From 82a7b4f70b95b35421967afd55c1989017c635c4 Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Fri, 2 Oct 2020 22:30:36 +0800 +Subject: [PATCH 062/108] scsi: hisi_sas: Add device link between SCSI devices + and hisi_hba + +mainline inclusion +from mainline-v5.10-rc1 +commit 16fd4a7c5917097e9a3da03b39a92381eee40724 +category: feature +bugzilla: https://gitee.com/openeuler/kernel/issues/I8F81U + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=16fd4a7c5917097e9a3da03b39a92381eee40724 + +---------------------------------------------------------------------- + +Runtime PM of SCSI devices is already supported in SCSI layer, we can +suspend/resume every SCSI device separately. But if there is no link +between hisi_hba and SCSI devices or SCSI targets it will cause issues if +the controller is suspended while SCSI devices are still resuming. Only +when all the SCSI devices under the controller are suspended, the +controller can be suspended. Add the device link between SCSI devices +and the controller. + +Link: https://lore.kernel.org/r/1601649038-25534-6-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 29 +++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 2d4615f2d9dc..587ab9616340 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3130,6 +3130,33 @@ static ssize_t intr_coal_count_store(struct device *dev, + } + static DEVICE_ATTR_RW(intr_coal_count); + ++static int slave_configure_v3_hw(struct scsi_device *sdev) ++{ ++ struct Scsi_Host *shost = dev_to_shost(&sdev->sdev_gendev); ++ struct domain_device *ddev = sdev_to_domain_dev(sdev); ++ struct hisi_hba *hisi_hba = shost_priv(shost); ++ struct device *dev = hisi_hba->dev; ++ int ret = sas_slave_configure(sdev); ++ ++ if (ret) ++ return ret; ++ if (!dev_is_sata(ddev)) ++ sas_change_queue_depth(sdev, 64); ++ ++ if (sdev->type == TYPE_ENCLOSURE) ++ return 0; ++ ++ if (!device_link_add(&sdev->sdev_gendev, dev, ++ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE)) { ++ if (pm_runtime_enabled(dev)) { ++ dev_info(dev, "add device link failed, disable runtime PM for the host\n"); ++ pm_runtime_disable(dev); ++ } ++ } ++ ++ return 0; ++} ++ + static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = { + HISI_SAS_DEBUGFS_REG(PHY_CFG), + HISI_SAS_DEBUGFS_REG(HARD_PHY_LINKRATE), +@@ -3509,7 +3536,7 @@ static struct scsi_host_template sht_v3_hw = { + .module = THIS_MODULE, + .queuecommand = sas_queuecommand, + .target_alloc = sas_target_alloc, +- .slave_configure = hisi_sas_slave_configure, ++ .slave_configure = slave_configure_v3_hw, + .scan_finished = hisi_sas_scan_finished, + .scan_start = hisi_sas_scan_start, + .change_queue_depth = sas_change_queue_depth, +-- +2.27.0 + diff --git a/patches/0711-scsi-hisi_sas-Recover-PHY-state-according-to-the-sta.patch b/patches/0711-scsi-hisi_sas-Recover-PHY-state-according-to-the-sta.patch new file mode 100644 index 0000000..39799e0 --- /dev/null +++ b/patches/0711-scsi-hisi_sas-Recover-PHY-state-according-to-the-sta.patch @@ -0,0 +1,55 @@ +From 1ff296a7a65974658659d6740768edeea826448a Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Fri, 2 Oct 2020 22:30:38 +0800 +Subject: [PATCH 063/108] scsi: hisi_sas: Recover PHY state according to the + status before reset + +mainline inclusion +from mainline-v5.10-rc1 +commit 69f4ec1edb136d2d2511d1ef96f94ef0aeecefdf +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81U + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=69f4ec1edb136d2d2511d1ef96f94ef0aeecefdf + +---------------------------------------------------------------------- + +Currently the PHY state is set according to the state of the PHYs after +reset. This is invalid as the PHYs are already re-initialized. + +Set PHY state according to the state before the reset instead of after. + +Link: https://lore.kernel.org/r/1601649038-25534-8-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 154bd66a5915..ea1f238b9213 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1599,7 +1599,6 @@ EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_prepare); + void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) + { + struct Scsi_Host *shost = hisi_hba->shost; +- u32 state; + + /* Init and wait for PHYs to come up and all libsas event finished. */ + hisi_hba->hw->phys_init(hisi_hba); +@@ -1615,8 +1614,7 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) + scsi_unblock_requests(shost); + clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + +- state = hisi_hba->hw->get_phys_state(hisi_hba); +- hisi_sas_rescan_topology(hisi_hba, state); ++ hisi_sas_rescan_topology(hisi_hba, hisi_hba->phy_state); + } + EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done); + +-- +2.27.0 + diff --git a/patches/0712-scsi-hisi_sas-Fix-up-probe-error-handling-for-v3-hw.patch b/patches/0712-scsi-hisi_sas-Fix-up-probe-error-handling-for-v3-hw.patch new file mode 100644 index 0000000..1bdc9e9 --- /dev/null +++ b/patches/0712-scsi-hisi_sas-Fix-up-probe-error-handling-for-v3-hw.patch @@ -0,0 +1,111 @@ +From 56f4085b040b8ea37e339aed713024a08dde0c7b Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Thu, 7 Jan 2021 07:40:36 +0000 +Subject: [PATCH 064/108] scsi: hisi_sas: Fix up probe error handling for v3 hw + +mainline inclusion +from mainline-v5.11-rc1 +commit 2ebde94f2ea4cffd812ece2f318c2f4922239b1d +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2ebde94f2ea4cffd812ece2f318c2f4922239b1d + +---------------------------------------------------------------------- + +[ Upstream commit 2ebde94f2ea4cffd812ece2f318c2f4922239b1d ] + +Fix some rollbacks in function hisi_sas_v3_probe() and +interrupt_init_v3_hw(). + +Link: https://lore.kernel.org/r/1606207594-196362-3-git-send-email-john.garry@huawei.com +Fixes: 8d98416a55eb ("scsi: hisi_sas: Switch v3 hw to MQ") +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +Signed-off-by: Chen Jun +Acked-by: Xie XiuQi +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 22 ++++++++-------------- + 1 file changed, 8 insertions(+), 14 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 587ab9616340..ed0d0a258145 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2776,8 +2776,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + DRV_NAME " phy", hisi_hba); + if (rc) { + dev_err(dev, "could not request phy interrupt, rc=%d\n", rc); +- rc = -ENOENT; +- goto free_irq_vectors; ++ return -ENOENT; + } + + rc = devm_request_irq(dev, pci_irq_vector(pdev, PCI_IRQ_CHANNEL), +@@ -2785,8 +2784,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + DRV_NAME " channel", hisi_hba); + if (rc) { + dev_err(dev, "could not request chnl interrupt, rc=%d\n", rc); +- rc = -ENOENT; +- goto free_irq_vectors; ++ return -ENOENT; + } + + rc = devm_request_irq(dev, pci_irq_vector(pdev, PCI_IRQ_AXI_FATAL), +@@ -2794,8 +2792,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + DRV_NAME " fatal", hisi_hba); + if (rc) { + dev_err(dev, "could not request fatal interrupt, rc=%d\n", rc); +- rc = -ENOENT; +- goto free_irq_vectors; ++ return -ENOENT; + } + + if (hisi_sas_intr_conv) +@@ -2815,18 +2812,13 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + if (rc) { + dev_err(dev, "could not request cq%d interrupt, rc=%d\n", + i, rc); +- rc = -ENOENT; +- goto free_irq_vectors; ++ return -ENOENT; + } + + tasklet_init(t, cq_tasklet_v3_hw, (uintptr_t)cq); + } + + return 0; +- +-free_irq_vectors: +- pci_free_irq_vectors(pdev); +- return rc; + } + + static int hisi_sas_v3_init(struct hisi_hba *hisi_hba) +@@ -3731,7 +3723,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + rc = scsi_add_host(shost, dev); + if (rc) +- goto err_out_ha; ++ goto err_out_debugfs; + + rc = sas_register_ha(sha); + if (rc) +@@ -3758,8 +3750,10 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + err_out_register_ha: + scsi_remove_host(shost); +-err_out_ha: ++err_out_debugfs: + hisi_sas_debugfs_exit(hisi_hba); ++err_out_ha: ++ hisi_sas_free(hisi_hba); + scsi_host_put(shost); + err_out_regions: + pci_release_regions(pdev); +-- +2.27.0 + diff --git a/patches/0713-scsi-hisi_sas-Reduce-some-indirection-in-v3-hw-drive.patch b/patches/0713-scsi-hisi_sas-Reduce-some-indirection-in-v3-hw-drive.patch new file mode 100644 index 0000000..1deb1e0 --- /dev/null +++ b/patches/0713-scsi-hisi_sas-Reduce-some-indirection-in-v3-hw-drive.patch @@ -0,0 +1,67 @@ +From bb59b66d331e6f831a9230267ce23f5aaa042336 Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Tue, 3 Aug 2021 14:47:26 +0800 +Subject: [PATCH 065/108] scsi: hisi_sas: Reduce some indirection in v3 hw + driver + +mainline inclusion +from mainline-v5.11-rc1 +commit bec99e5250bfe1c575e72a971bc2b2b21cf6c8b4 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bec99e5250bfe1c575e72a971bc2b2b21cf6c8b4 + +------------------------------------------------------------------------ + +Sometimes local functions are called indirectly from the hw driver, which +only makes the code harder to follow. Remove these. + +Method .hw_init is only called from platform driver probe, which is not +relevant, so don't set this either. + +Link: https://lore.kernel.org/r/1606207594-196362-2-git-send-email-john.garry@huawei.com +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index ed0d0a258145..3aea33e85a52 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3549,7 +3549,6 @@ static struct scsi_host_template sht_v3_hw = { + }; + + static const struct hisi_sas_hw hisi_sas_v3_hw = { +- .hw_init = hisi_sas_v3_init, + .setup_itct = setup_itct_v3_hw, + .get_wideport_bitmap = get_wideport_bitmap_v3_hw, + .complete_hdr_size = sizeof(struct hisi_sas_complete_v3_hdr), +@@ -3729,7 +3728,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + if (rc) + goto err_out_register_ha; + +- rc = hisi_hba->hw->hw_init(hisi_hba); ++ rc = hisi_sas_v3_init(hisi_hba); + if (rc) + goto err_out_register_ha; + +@@ -3923,7 +3922,7 @@ static int _resume_v3_hw(struct device *device) + pci_disable_device(pdev); + return rc; + } +- hisi_hba->hw->phys_init(hisi_hba); ++ phys_init_v3_hw(hisi_hba); + sas_resume_ha(sha); + clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + +-- +2.27.0 + diff --git a/patches/0714-scsi-hisi_sas-Move-debugfs-code-to-v3-hw-driver.patch b/patches/0714-scsi-hisi_sas-Move-debugfs-code-to-v3-hw-driver.patch new file mode 100644 index 0000000..ccef640 --- /dev/null +++ b/patches/0714-scsi-hisi_sas-Move-debugfs-code-to-v3-hw-driver.patch @@ -0,0 +1,2796 @@ +From eae6b7ab7dbc352bf4cd5c5a7a44c606c49ea982 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:47:27 +0800 +Subject: [PATCH 066/108] scsi: hisi_sas: Move debugfs code to v3 hw driver + +mainline inclusion +from mainline-v5.11-rc1 +commit 623a4b6d5c2a7595f677fa17348dbca6b461f16a +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=623a4b6d5c2a7595f677fa17348dbca6b461f16a + +---------------------------------------------------------------------- + +Relocate all the debugfs code for DFX to v3 hw since no other versions +support it. + +Link: https://lore.kernel.org/r/1606207594-196362-4-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h + drivers/scsi/hisi_sas/hisi_sas_main.c + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 28 - + drivers/scsi/hisi_sas/hisi_sas_main.c | 1367 +----------------------- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 1222 ++++++++++++++++++++- + 3 files changed, 1208 insertions(+), 1409 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index b2a368e41f0c..707ee782faa5 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -260,24 +260,6 @@ struct hisi_sas_slot { + int idx; + }; + +-#define HISI_SAS_DEBUGFS_REG(x) {#x, x} +- +-struct hisi_sas_debugfs_reg_lu { +- char *name; +- int off; +-}; +- +-struct hisi_sas_debugfs_reg { +- const struct hisi_sas_debugfs_reg_lu *lu; +- int count; +- int base_off; +- union { +- u32 (*read_global_reg)(struct hisi_hba *hisi_hba, u32 off); +- u32 (*read_port_reg)(struct hisi_hba *hisi_hba, int port, +- u32 off); +- }; +-}; +- + enum { + HISI_SAS_BIST_LOOPBACK_MODE_DIGITAL = 0, + HISI_SAS_BIST_LOOPBACK_MODE_SERDES, +@@ -377,15 +359,8 @@ struct hisi_sas_hw { + const struct cpumask *(*get_managed_irq_aff)(struct hisi_hba + *hisi_hba, int queue); + void (*debugfs_work_handler)(struct work_struct *work); +- void (*read_iost_itct_cache)(struct hisi_hba *hisi_hba, +- enum hisi_sas_debugfs_cache_type type, +- u32 *cache); + int complete_hdr_size; + struct scsi_host_template *sht; +- +- const struct hisi_sas_debugfs_reg *debugfs_reg_array[DEBUGFS_REGS_NUM]; +- const struct hisi_sas_debugfs_reg *debugfs_reg_port; +- int (*set_bist)(struct hisi_hba *hisi_hba, bool enable); + }; + + #define HISI_SAS_MAX_DEBUGFS_DUMP (50) +@@ -710,8 +685,5 @@ extern void hisi_sas_release_tasks(struct hisi_hba *hisi_hba); + extern u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max); + extern void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba); + extern void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba); +-extern void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba); +-extern void hisi_sas_debugfs_exit(struct hisi_hba *hisi_hba); + extern void hisi_sas_snapshot_regs(struct hisi_hba *hisi_hba); +-extern void hisi_sas_debugfs_work_handler(struct work_struct *work); + #endif +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index ea1f238b9213..c0a870202484 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2761,1376 +2761,12 @@ int hisi_sas_probe(struct platform_device *pdev, + err_out_register_ha: + scsi_remove_host(shost); + err_out: +- hisi_sas_debugfs_exit(hisi_hba); + hisi_sas_free(hisi_hba); + scsi_host_put(shost); + return rc; + } + EXPORT_SYMBOL_GPL(hisi_sas_probe); + +-struct dentry *hisi_sas_debugfs_dir; +- +-static void hisi_sas_debugfs_snapshot_cq_reg(struct hisi_hba *hisi_hba) +-{ +- int queue_entry_size = hisi_hba->hw->complete_hdr_size; +- int dump_index = hisi_hba->debugfs_dump_index; +- int i; +- +- for (i = 0; i < hisi_hba->queue_count; i++) +- memcpy(hisi_hba->debugfs_cq[dump_index][i].complete_hdr, +- hisi_hba->complete_hdr[i], +- HISI_SAS_QUEUE_SLOTS * queue_entry_size); +-} +- +-static void hisi_sas_debugfs_snapshot_dq_reg(struct hisi_hba *hisi_hba) +-{ +- int queue_entry_size = sizeof(struct hisi_sas_cmd_hdr); +- int dump_index = hisi_hba->debugfs_dump_index; +- int i; +- +- for (i = 0; i < hisi_hba->queue_count; i++) +- memcpy(hisi_hba->debugfs_dq[dump_index][i].hdr, +- hisi_hba->cmd_hdr[i], +- HISI_SAS_QUEUE_SLOTS * queue_entry_size); +-} +- +-static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) +-{ +- int dump_index = hisi_hba->debugfs_dump_index; +- const struct hisi_sas_debugfs_reg *port = +- hisi_hba->hw->debugfs_reg_port; +- int i, phy_cnt; +- u32 offset; +- u32 *databuf; +- +- for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) { +- databuf = hisi_hba->debugfs_port_reg[dump_index][phy_cnt].data; +- for (i = 0; i < port->count; i++, databuf++) { +- offset = port->base_off + 4 * i; +- *databuf = port->read_port_reg(hisi_hba, phy_cnt, +- offset); +- } +- } +-} +- +-static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) +-{ +- int dump_index = hisi_hba->debugfs_dump_index; +- u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL].data; +- const struct hisi_sas_hw *hw = hisi_hba->hw; +- const struct hisi_sas_debugfs_reg *global = +- hw->debugfs_reg_array[DEBUGFS_GLOBAL]; +- int i; +- +- for (i = 0; i < global->count; i++, databuf++) +- *databuf = global->read_global_reg(hisi_hba, 4 * i); +-} +- +-static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) +-{ +- int dump_index = hisi_hba->debugfs_dump_index; +- u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI].data; +- const struct hisi_sas_hw *hw = hisi_hba->hw; +- const struct hisi_sas_debugfs_reg *axi = +- hw->debugfs_reg_array[DEBUGFS_AXI]; +- int i; +- +- for (i = 0; i < axi->count; i++, databuf++) +- *databuf = axi->read_global_reg(hisi_hba, +- 4 * i + axi->base_off); +-} +- +-static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) +-{ +- int dump_index = hisi_hba->debugfs_dump_index; +- u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS].data; +- const struct hisi_sas_hw *hw = hisi_hba->hw; +- const struct hisi_sas_debugfs_reg *ras = +- hw->debugfs_reg_array[DEBUGFS_RAS]; +- int i; +- +- for (i = 0; i < ras->count; i++, databuf++) +- *databuf = ras->read_global_reg(hisi_hba, +- 4 * i + ras->base_off); +-} +- +-static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) +-{ +- int dump_index = hisi_hba->debugfs_dump_index; +- void *cachebuf = hisi_hba->debugfs_itct_cache[dump_index].cache; +- void *databuf = hisi_hba->debugfs_itct[dump_index].itct; +- struct hisi_sas_itct *itct; +- int i; +- +- hisi_hba->hw->read_iost_itct_cache(hisi_hba, HISI_SAS_ITCT_CACHE, +- cachebuf); +- +- itct = hisi_hba->itct; +- +- for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) { +- memcpy(databuf, itct, sizeof(struct hisi_sas_itct)); +- databuf += sizeof(struct hisi_sas_itct); +- } +-} +- +-static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba) +-{ +- int dump_index = hisi_hba->debugfs_dump_index; +- int max_command_entries = HISI_SAS_MAX_COMMANDS; +- void *cachebuf = hisi_hba->debugfs_iost_cache[dump_index].cache; +- void *databuf = hisi_hba->debugfs_iost[dump_index].iost; +- struct hisi_sas_iost *iost; +- int i; +- +- hisi_hba->hw->read_iost_itct_cache(hisi_hba, HISI_SAS_IOST_CACHE, +- cachebuf); +- +- iost = hisi_hba->iost; +- +- for (i = 0; i < max_command_entries; i++, iost++) { +- memcpy(databuf, iost, sizeof(struct hisi_sas_iost)); +- databuf += sizeof(struct hisi_sas_iost); +- } +-} +- +-static const char * +-hisi_sas_debugfs_to_reg_name(int off, int base_off, +- const struct hisi_sas_debugfs_reg_lu *lu) +-{ +- for (; lu->name; lu++) { +- if (off == lu->off - base_off) +- return lu->name; +- } +- +- return NULL; +-} +- +-static void hisi_sas_debugfs_print_reg(u32 *regs_val, const void *ptr, +- struct seq_file *s) +-{ +- const struct hisi_sas_debugfs_reg *reg = ptr; +- int i; +- +- for (i = 0; i < reg->count; i++) { +- int off = i * 4; +- const char *name; +- +- name = hisi_sas_debugfs_to_reg_name(off, reg->base_off, +- reg->lu); +- +- if (name) +- seq_printf(s, "0x%08x 0x%08x %s\n", off, +- regs_val[i], name); +- else +- seq_printf(s, "0x%08x 0x%08x\n", off, +- regs_val[i]); +- } +-} +- +-static int hisi_sas_debugfs_global_show(struct seq_file *s, void *p) +-{ +- struct hisi_sas_debugfs_regs *global = s->private; +- struct hisi_hba *hisi_hba = global->hisi_hba; +- const struct hisi_sas_hw *hw = hisi_hba->hw; +- const void *reg_global = hw->debugfs_reg_array[DEBUGFS_GLOBAL]; +- +- hisi_sas_debugfs_print_reg(global->data, +- reg_global, s); +- +- return 0; +-} +- +-static int hisi_sas_debugfs_global_open(struct inode *inode, struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_global_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_global_fops = { +- .open = hisi_sas_debugfs_global_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static struct { +- int value; +- char *name; +-} hisi_sas_debugfs_loop_linkrate[] = { +- { SAS_LINK_RATE_1_5_GBPS, "1.5 Gbit" }, +- { SAS_LINK_RATE_3_0_GBPS, "3.0 Gbit" }, +- { SAS_LINK_RATE_6_0_GBPS, "6.0 Gbit" }, +- { SAS_LINK_RATE_12_0_GBPS, "12.0 Gbit"}, +-}; +- +-static int hisi_sas_debugfs_bist_linkrate_show(struct seq_file *s, void *p) +-{ +- struct hisi_hba *hisi_hba = s->private; +- int i; +- +- for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_linkrate); i++) { +- int match = (hisi_hba->bist_loopback_linkrate == +- hisi_sas_debugfs_loop_linkrate[i].value); +- +- seq_printf(s, "%s%s%s ", match ? "[" : "", +- hisi_sas_debugfs_loop_linkrate[i].name, +- match ? "]" : ""); +- } +- seq_puts(s, "\n"); +- +- return 0; +-} +- +-ssize_t hisi_sas_debugfs_bist_linkrate_write(struct file *filp, +- const char __user *buf, +- size_t count, loff_t *ppos) +-{ +- struct seq_file *m = filp->private_data; +- struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; +- bool found = false; +- int i; +- +- if (hisi_hba->bist_loopback_enable) +- return -EINVAL; +- +- if (count >= sizeof(kbuf)) +- return -EINVAL; +- +- if (copy_from_user(kbuf, buf, count)) +- return -EINVAL; +- +- pkbuf = strstrip(kbuf); +- +- for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_linkrate); i++) { +- if (!strncmp(hisi_sas_debugfs_loop_linkrate[i].name, +- pkbuf, 16)) { +- hisi_hba->bist_loopback_linkrate = +- hisi_sas_debugfs_loop_linkrate[i].value; +- found = true; +- break; +- } +- } +- +- if (!found) { +- dev_err(hisi_hba->dev, "unknown mode\n"); +- return -EINVAL; +- } +- +- return count; +-} +- +-static int hisi_sas_debugfs_bist_linkrate_open(struct inode *inode, +- struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_bist_linkrate_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_bist_linkrate_ops = { +- .open = hisi_sas_debugfs_bist_linkrate_open, +- .read = seq_read, +- .write = hisi_sas_debugfs_bist_linkrate_write, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static struct { +- int value; +- char *name; +-} hisi_sas_debugfs_loop_code_mode[] = { +- { HISI_SAS_BIST_CODE_MODE_PRBS7, "PRBS7" }, +- { HISI_SAS_BIST_CODE_MODE_PRBS23, "PRBS23" }, +- { HISI_SAS_BIST_CODE_MODE_PRBS31, "PRBS31" }, +- { HISI_SAS_BIST_CODE_MODE_JTPAT, "JTPAT" }, +- { HISI_SAS_BIST_CODE_MODE_CJTPAT, "CJTPAT" }, +- { HISI_SAS_BIST_CODE_MODE_SCRAMBED_0, "SCRAMBED_0" }, +- { HISI_SAS_BIST_CODE_MODE_TRAIN, "TRAIN" }, +- { HISI_SAS_BIST_CODE_MODE_TRAIN_DONE, "TRAIN_DONE" }, +- { HISI_SAS_BIST_CODE_MODE_HFTP, "HFTP" }, +- { HISI_SAS_BIST_CODE_MODE_MFTP, "MFTP" }, +- { HISI_SAS_BIST_CODE_MODE_LFTP, "LFTP" }, +- { HISI_SAS_BIST_CODE_MODE_FIXED_DATA, "FIXED_DATA" }, +-}; +- +-static int hisi_sas_debugfs_bist_code_mode_show(struct seq_file *s, void *p) +-{ +- struct hisi_hba *hisi_hba = s->private; +- int i; +- +- for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_code_mode); i++) { +- int match = (hisi_hba->bist_loopback_code_mode == +- hisi_sas_debugfs_loop_code_mode[i].value); +- +- seq_printf(s, "%s%s%s ", match ? "[" : "", +- hisi_sas_debugfs_loop_code_mode[i].name, +- match ? "]" : ""); +- } +- seq_puts(s, "\n"); +- +- return 0; +-} +- +-ssize_t hisi_sas_debugfs_bist_code_mode_write(struct file *filp, +- const char __user *buf, +- size_t count, loff_t *ppos) +-{ +- struct seq_file *m = filp->private_data; +- struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; +- bool found = false; +- int i; +- +- if (hisi_hba->bist_loopback_enable) +- return -EINVAL; +- +- if (count >= sizeof(kbuf)) +- return -EINVAL; +- +- if (copy_from_user(kbuf, buf, count)) +- return -EINVAL; +- +- pkbuf = strstrip(kbuf); +- +- for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_code_mode); i++) { +- if (!strncmp(hisi_sas_debugfs_loop_code_mode[i].name, +- pkbuf, 16)) { +- hisi_hba->bist_loopback_code_mode = +- hisi_sas_debugfs_loop_code_mode[i].value; +- found = true; +- break; +- } +- } +- +- if (!found) { +- dev_err(hisi_hba->dev, "unknown mode\n"); +- return -EINVAL; +- } +- +- return count; +-} +- +-static int hisi_sas_debugfs_bist_code_mode_open(struct inode *inode, +- struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_bist_code_mode_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_bist_code_mode_ops = { +- .open = hisi_sas_debugfs_bist_code_mode_open, +- .read = seq_read, +- .write = hisi_sas_debugfs_bist_code_mode_write, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-ssize_t hisi_sas_debugfs_bist_phy_write(struct file *filp, +- const char __user *buf, +- size_t count, loff_t *ppos) +-{ +- struct seq_file *m = filp->private_data; +- struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; +- unsigned int phy; +- int val; +- +- if (hisi_hba->bist_loopback_enable) +- return -EINVAL; +- +- if (count >= sizeof(kbuf)) +- return -EINVAL; +- +- if (copy_from_user(kbuf, buf, count)) +- return -EINVAL; +- +- pkbuf = strstrip(kbuf); +- +- val = kstrtouint(pkbuf, 0, &phy); +- if (val < 0) +- return val; +- +- if (phy >= hisi_hba->n_phy) { +- dev_err(hisi_hba->dev, "phy index %d exceeds limit\n", phy); +- return -EINVAL; +- } +- +- hisi_hba->bist_loopback_phy_id = phy; +- +- return count; +-} +- +-static int hisi_sas_debugfs_bist_phy_show(struct seq_file *s, void *p) +-{ +- struct hisi_hba *hisi_hba = s->private; +- +- seq_printf(s, "%d\n", hisi_hba->bist_loopback_phy_id); +- +- return 0; +-} +- +-static int hisi_sas_debugfs_bist_phy_open(struct inode *inode, +- struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_bist_phy_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_bist_phy_ops = { +- .open = hisi_sas_debugfs_bist_phy_open, +- .read = seq_read, +- .write = hisi_sas_debugfs_bist_phy_write, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static struct { +- int value; +- char *name; +-} hisi_sas_debugfs_loop_modes[] = { +- { HISI_SAS_BIST_LOOPBACK_MODE_DIGITAL, "digital" }, +- { HISI_SAS_BIST_LOOPBACK_MODE_SERDES, "serdes" }, +- { HISI_SAS_BIST_LOOPBACK_MODE_REMOTE, "remote" }, +-}; +- +-static int hisi_sas_debugfs_bist_mode_show(struct seq_file *s, void *p) +-{ +- struct hisi_hba *hisi_hba = s->private; +- int i; +- +- for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_modes); i++) { +- int match = (hisi_hba->bist_loopback_mode == +- hisi_sas_debugfs_loop_modes[i].value); +- +- seq_printf(s, "%s%s%s ", match ? "[" : "", +- hisi_sas_debugfs_loop_modes[i].name, +- match ? "]" : ""); +- } +- seq_puts(s, "\n"); +- +- return 0; +-} +- +-ssize_t hisi_sas_debugfs_bist_mode_write(struct file *filp, +- const char __user *buf, +- size_t count, loff_t *ppos) +-{ +- struct seq_file *m = filp->private_data; +- struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; +- bool found = false; +- int i; +- +- if (hisi_hba->bist_loopback_enable) +- return -EINVAL; +- +- if (count >= sizeof(kbuf)) +- return -EINVAL; +- +- if (copy_from_user(kbuf, buf, count)) +- return -EINVAL; +- +- pkbuf = strstrip(kbuf); +- +- for (i = 0; i < ARRAY_SIZE(hisi_sas_debugfs_loop_modes); i++) { +- if (!strncmp(hisi_sas_debugfs_loop_modes[i].name, pkbuf, 16)) { +- hisi_hba->bist_loopback_mode = +- hisi_sas_debugfs_loop_modes[i].value; +- found = true; +- break; +- } +- } +- +- if (!found) { +- dev_err(hisi_hba->dev, "unknown mode\n"); +- return -EINVAL; +- } +- +- return count; +-} +- +-static int hisi_sas_debugfs_bist_mode_open(struct inode *inode, +- struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_bist_mode_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_bist_mode_ops = { +- .open = hisi_sas_debugfs_bist_mode_open, +- .read = seq_read, +- .write = hisi_sas_debugfs_bist_mode_write, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-ssize_t hisi_sas_debugfs_bist_enable_write(struct file *filp, +- const char __user *buf, +- size_t count, loff_t *ppos) +-{ +- struct seq_file *m = filp->private_data; +- struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; +- int val; +- unsigned int enable; +- +- if (count >= sizeof(kbuf)) +- return -EINVAL; +- +- if (copy_from_user(kbuf, buf, count)) +- return -EINVAL; +- +- pkbuf = strstrip(kbuf); +- +- val = kstrtoint(pkbuf, 0, &enable); +- if (val < 0) +- return val; +- +- if (enable > 1) { +- dev_err(hisi_hba->dev, "must be 0 or 1\n"); +- return -EINVAL; +- } +- +- if (enable == hisi_hba->bist_loopback_enable) +- return count; +- +- if (!hisi_hba->hw->set_bist) +- return -EPERM; +- +- val = hisi_hba->hw->set_bist(hisi_hba, (bool)enable); +- if (val < 0) +- return val; +- +- hisi_hba->bist_loopback_enable = enable; +- +- return count; +-} +- +-static int hisi_sas_debugfs_bist_enable_show(struct seq_file *s, void *p) +-{ +- struct hisi_hba *hisi_hba = s->private; +- +- seq_printf(s, "%d\n", hisi_hba->bist_loopback_enable); +- +- return 0; +-} +- +-static int hisi_sas_debugfs_bist_enable_open(struct inode *inode, +- struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_bist_enable_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_bist_enable_ops = { +- .open = hisi_sas_debugfs_bist_enable_open, +- .read = seq_read, +- .write = hisi_sas_debugfs_bist_enable_write, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static int hisi_sas_debugfs_axi_show(struct seq_file *s, void *p) +-{ +- struct hisi_sas_debugfs_regs *ras = s->private; +- struct hisi_hba *hisi_hba = ras->hisi_hba; +- const struct hisi_sas_hw *hw = hisi_hba->hw; +- const void *reg_axi = hw->debugfs_reg_array[DEBUGFS_AXI]; +- +- hisi_sas_debugfs_print_reg(ras->data, +- reg_axi, s); +- +- return 0; +-} +- +-static int hisi_sas_debugfs_axi_open(struct inode *inode, struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_axi_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_axi_fops = { +- .open = hisi_sas_debugfs_axi_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static int hisi_sas_debugfs_ras_show(struct seq_file *s, void *p) +-{ +- struct hisi_sas_debugfs_regs *ras = s->private; +- struct hisi_hba *hisi_hba = ras->hisi_hba; +- const struct hisi_sas_hw *hw = hisi_hba->hw; +- const void *reg_ras = hw->debugfs_reg_array[DEBUGFS_RAS]; +- +- hisi_sas_debugfs_print_reg(ras->data, +- reg_ras, s); +- +- return 0; +-} +- +-static int hisi_sas_debugfs_ras_open(struct inode *inode, struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_ras_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_ras_fops = { +- .open = hisi_sas_debugfs_ras_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +- +-static int hisi_sas_debugfs_port_show(struct seq_file *s, void *p) +-{ +- struct hisi_sas_debugfs_port *port = s->private; +- struct hisi_sas_phy *phy = port->phy; +- struct hisi_hba *hisi_hba = phy->hisi_hba; +- const struct hisi_sas_hw *hw = hisi_hba->hw; +- const struct hisi_sas_debugfs_reg *reg_port = hw->debugfs_reg_port; +- +- hisi_sas_debugfs_print_reg(port->data, reg_port, s); +- +- return 0; +-} +- +-static int hisi_sas_debugfs_port_open(struct inode *inode, struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_port_show, inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_port_fops = { +- .open = hisi_sas_debugfs_port_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static void hisi_sas_show_row_64(struct seq_file *s, int index, +- int sz, __le64 *ptr) +-{ +- int i; +- +- /* completion header size not fixed per HW version */ +- seq_printf(s, "index %04d:\n\t", index); +- /* Convert unit of sz to 8 bytes before compare */ +- for (i = 1; i <= sz / 8; i++, ptr++) { +- seq_printf(s, " 0x%016llx", le64_to_cpu(*ptr)); +- if (!(i % 2)) +- seq_puts(s, "\n\t"); +- } +- +- seq_puts(s, "\n"); +-} +- +-static void hisi_sas_show_row_32(struct seq_file *s, int index, +- int sz, __le32 *ptr) +-{ +- int i; +- +- /* completion header size not fixed per HW version */ +- seq_printf(s, "index %04d:\n\t", index); +- /* Convert unit of sz to 4 bytes before compare */ +- for (i = 1; i <= sz / 4; i++, ptr++) { +- seq_printf(s, " 0x%08x", le32_to_cpu(*ptr)); +- if (!(i % 4)) +- seq_puts(s, "\n\t"); +- } +- seq_puts(s, "\n"); +-} +- +-static void hisi_sas_cq_show_slot(struct seq_file *s, int slot, +- struct hisi_sas_debugfs_cq *debugfs_cq) +-{ +- struct hisi_sas_cq *cq = debugfs_cq->cq; +- struct hisi_hba *hisi_hba = cq->hisi_hba; +- u64 offset = hisi_hba->hw->complete_hdr_size * slot; +- __le32 *complete_hdr = debugfs_cq->complete_hdr + offset; +- +- hisi_sas_show_row_32(s, slot, +- hisi_hba->hw->complete_hdr_size, +- complete_hdr); +-} +- +-static int hisi_sas_debugfs_cq_show(struct seq_file *s, void *p) +-{ +- struct hisi_sas_debugfs_cq *debugfs_cq = s->private; +- int slot; +- +- for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) { +- hisi_sas_cq_show_slot(s, slot, debugfs_cq); +- } +- return 0; +-} +- +-static int hisi_sas_debugfs_cq_open(struct inode *inode, struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_cq_show, inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_cq_fops = { +- .open = hisi_sas_debugfs_cq_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static void hisi_sas_dq_show_slot(struct seq_file *s, int slot, void *dq_ptr) +-{ +- struct hisi_sas_debugfs_dq *debugfs_dq = dq_ptr; +- void *cmd_queue = debugfs_dq->hdr; +- u64 offset = sizeof(struct hisi_sas_cmd_hdr) * slot; +- __le32 *cmd_hdr = cmd_queue + offset; +- +- hisi_sas_show_row_32(s, slot, sizeof(struct hisi_sas_cmd_hdr), cmd_hdr); +-} +- +-static int hisi_sas_debugfs_dq_show(struct seq_file *s, void *p) +-{ +- int slot; +- +- for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) { +- hisi_sas_dq_show_slot(s, slot, s->private); +- } +- return 0; +-} +- +-static int hisi_sas_debugfs_dq_open(struct inode *inode, struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_dq_show, inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_dq_fops = { +- .open = hisi_sas_debugfs_dq_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static int hisi_sas_debugfs_iost_show(struct seq_file *s, void *p) +-{ +- struct hisi_sas_debugfs_iost *debugfs_iost = s->private; +- struct hisi_sas_iost *iost = debugfs_iost->iost; +- int i, max_command_entries = HISI_SAS_MAX_COMMANDS; +- +- for (i = 0; i < max_command_entries; i++, iost++) { +- __le64 *data = &iost->qw0; +- +- hisi_sas_show_row_64(s, i, sizeof(*iost), data); +- } +- +- return 0; +-} +- +-static int hisi_sas_debugfs_iost_open(struct inode *inode, struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_iost_show, inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_iost_fops = { +- .open = hisi_sas_debugfs_iost_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static int hisi_sas_debugfs_iost_cache_show(struct seq_file *s, void *p) +-{ +- struct hisi_sas_debugfs_iost_cache *debugfs_iost_cache = s->private; +- struct hisi_sas_iost_itct_cache *iost_cache = debugfs_iost_cache->cache; +- u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; +- int i, tab_idx; +- __le64 *iost; +- +- for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) { +- /* +- * Data struct of IOST cache: +- * Data[1]: BIT0~15: Table index +- * Bit16: Valid mask +- * Data[2]~[9]: IOST table +- */ +- tab_idx = (iost_cache->data[1] & 0xffff); +- iost = (__le64 *)iost_cache; +- +- hisi_sas_show_row_64(s, tab_idx, cache_size, iost); +- } +- +- return 0; +-} +- +-static int hisi_sas_debugfs_iost_cache_open(struct inode *inode, +- struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_iost_cache_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_iost_cache_fops = { +- .open = hisi_sas_debugfs_iost_cache_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static int hisi_sas_debugfs_itct_show(struct seq_file *s, void *p) +-{ +- int i; +- struct hisi_sas_debugfs_itct *debugfs_itct = s->private; +- struct hisi_sas_itct *itct = debugfs_itct->itct; +- +- for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) { +- __le64 *data = &itct->qw0; +- +- hisi_sas_show_row_64(s, i, sizeof(*itct), data); +- } +- +- return 0; +-} +- +-static int hisi_sas_debugfs_itct_open(struct inode *inode, struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_itct_show, inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_itct_fops = { +- .open = hisi_sas_debugfs_itct_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static int hisi_sas_debugfs_itct_cache_show(struct seq_file *s, void *p) +-{ +- struct hisi_sas_debugfs_itct_cache *debugfs_itct_cache = s->private; +- struct hisi_sas_iost_itct_cache *itct_cache = debugfs_itct_cache->cache; +- u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; +- int i, tab_idx; +- __le64 *itct; +- +- for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) { +- /* +- * Data struct of ITCT cache: +- * Data[1]: BIT0~15: Table index +- * Bit16: Valid mask +- * Data[2]~[9]: ITCT table +- */ +- tab_idx = itct_cache->data[1] & 0xffff; +- itct = (__le64 *)itct_cache; +- +- hisi_sas_show_row_64(s, tab_idx, cache_size, itct); +- } +- +- return 0; +-} +- +-static int hisi_sas_debugfs_itct_cache_open(struct inode *inode, +- struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_itct_cache_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_itct_cache_fops = { +- .open = hisi_sas_debugfs_itct_cache_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) +-{ +- u64 *debugfs_timestamp; +- int dump_index = hisi_hba->debugfs_dump_index; +- struct dentry *dump_dentry; +- struct dentry *dentry; +- char name[256]; +- int p; +- int c; +- int d; +- +- snprintf(name, 256, "%d", dump_index); +- +- dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry); +- +- debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index]; +- +- debugfs_create_u64("timestamp", 0400, dump_dentry, +- debugfs_timestamp); +- +- debugfs_create_file("global", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL], +- &hisi_sas_debugfs_global_fops); +- +- /* Create port dir and files */ +- dentry = debugfs_create_dir("port", dump_dentry); +- +- for (p = 0; p < hisi_hba->n_phy; p++) { +- snprintf(name, sizeof(name), "%d", p); +- debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_port_reg[dump_index][p], +- &hisi_sas_debugfs_port_fops); +- } +- +- /* Create CQ dir and files */ +- dentry = debugfs_create_dir("cq", dump_dentry); +- +- for (c = 0; c < hisi_hba->queue_count; c++) { +- snprintf(name, sizeof(name), "%d", c); +- +- debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_cq[dump_index][c], +- &hisi_sas_debugfs_cq_fops); +- } +- +- /* Create DQ dir and files */ +- dentry = debugfs_create_dir("dq", dump_dentry); +- +- for (d = 0; d < hisi_hba->queue_count; d++) { +- snprintf(name, sizeof(name), "%d", d); +- +- debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_dq[dump_index][d], +- &hisi_sas_debugfs_dq_fops); +- } +- +- debugfs_create_file("iost", 0400, dump_dentry, +- &hisi_hba->debugfs_iost[dump_index], +- &hisi_sas_debugfs_iost_fops); +- +- debugfs_create_file("iost_cache", 0400, dump_dentry, +- &hisi_hba->debugfs_iost_cache[dump_index], +- &hisi_sas_debugfs_iost_cache_fops); +- +- debugfs_create_file("itct", 0400, dump_dentry, +- &hisi_hba->debugfs_itct[dump_index], +- &hisi_sas_debugfs_itct_fops); +- +- debugfs_create_file("itct_cache", 0400, dump_dentry, +- &hisi_hba->debugfs_itct_cache[dump_index], +- &hisi_sas_debugfs_itct_cache_fops); +- +- debugfs_create_file("axi", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI], +- &hisi_sas_debugfs_axi_fops); +- +- debugfs_create_file("ras", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS], +- &hisi_sas_debugfs_ras_fops); +- +- return; +-} +- +-static void hisi_sas_debugfs_snapshot_regs(struct hisi_hba *hisi_hba) +-{ +- hisi_hba->hw->snapshot_prepare(hisi_hba); +- +- hisi_sas_debugfs_snapshot_global_reg(hisi_hba); +- hisi_sas_debugfs_snapshot_port_reg(hisi_hba); +- hisi_sas_debugfs_snapshot_axi_reg(hisi_hba); +- hisi_sas_debugfs_snapshot_ras_reg(hisi_hba); +- hisi_sas_debugfs_snapshot_cq_reg(hisi_hba); +- hisi_sas_debugfs_snapshot_dq_reg(hisi_hba); +- hisi_sas_debugfs_snapshot_itct_reg(hisi_hba); +- hisi_sas_debugfs_snapshot_iost_reg(hisi_hba); +- +- /* Avoid re-create files here */ +- if (!hisi_hba->debugfs_dump_dentry) +- hisi_sas_debugfs_create_files(hisi_hba); +- +- hisi_hba->hw->snapshot_restore(hisi_hba); +-} +- +-static ssize_t hisi_sas_debugfs_trigger_dump_write(struct file *file, +- const char __user *user_buf, +- size_t count, +- loff_t *ppos) +-{ +- struct hisi_hba *hisi_hba = file->f_inode->i_private; +- u8 buf[8]; +- +- /* +- * The code, which used for upstream, check +- * the value of debugfs_snapshot here. +- * If not 0, will return -EFAULT. +- * Keep manual dump as one time only +- */ +- if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count) +- return -EFAULT; +- +- /* Not allow to input more than 8 char */ +- if (count > sizeof(buf)) +- return -EFAULT; +- +- if (copy_from_user(buf, user_buf, count)) +- return -EFAULT; +- +- if (buf[0] == '1') +- queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); +- else +- return -EFAULT; +- +- return count; +-} +- +-static const struct file_operations hisi_sas_debugfs_trigger_dump_fops = { +- .write = &hisi_sas_debugfs_trigger_dump_write, +- .owner = THIS_MODULE, +-}; +- +-static const struct { +- char *name; +-} hisi_sas_debugfs_ffe_name[FFE_CFG_MAX] = { +- { "SAS_1_5_GBPS" }, +- { "SAS_3_0_GBPS" }, +- { "SAS_6_0_GBPS" }, +- { "SAS_12_0_GBPS" }, +- { "FFE_RESV" }, +- { "SATA_1_5_GBPS" }, +- { "SATA_3_0_GBPS" }, +- { "SATA_6_0_GBPS" }, +-}; +- +-static ssize_t hisi_sas_debugfs_write(struct file *filp, +- const char __user *buf, +- size_t count, loff_t *ppos) +-{ +- struct seq_file *m = filp->private_data; +- u32 *val = m->private; +- int res; +- +- res = kstrtouint_from_user(buf, count, 0, val); +- if (res) +- return res; +- +- return count; +-} +- +-static int hisi_sas_debugfs_show(struct seq_file *s, void *p) +-{ +- u32 *val = s->private; +- +- seq_printf(s, "0x%x\n", *val); +- +- return 0; +-} +- +-static int hisi_sas_debugfs_open(struct inode *inode, struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_ops = { +- .open = hisi_sas_debugfs_open, +- .read = seq_read, +- .write = hisi_sas_debugfs_write, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-static ssize_t hisi_sas_debugfs_phy_down_cnt_write(struct file *filp, +- const char __user *buf, +- size_t count, loff_t *ppos) +-{ +- struct seq_file *s = filp->private_data; +- struct hisi_sas_phy *phy = s->private; +- unsigned int set_val; +- int res; +- +- res = kstrtouint_from_user(buf, count, 0, &set_val); +- if (res) +- return res; +- +- if (set_val > 0) +- return -EINVAL; +- +- atomic_set(&phy->down_cnt, 0); +- +- return count; +-} +- +-static int hisi_sas_debugfs_phy_down_cnt_show(struct seq_file *s, void *p) +-{ +- struct hisi_sas_phy *phy = s->private; +- +- seq_printf(s, "%d\n", atomic_read(&phy->down_cnt)); +- +- return 0; +-} +- +-static int hisi_sas_debugfs_phy_down_cnt_open(struct inode *inode, +- struct file *filp) +-{ +- return single_open(filp, hisi_sas_debugfs_phy_down_cnt_show, +- inode->i_private); +-} +- +-static const struct file_operations hisi_sas_debugfs_phy_down_cnt_ops = { +- .open = hisi_sas_debugfs_phy_down_cnt_open, +- .read = seq_read, +- .write = hisi_sas_debugfs_phy_down_cnt_write, +- .llseek = seq_lseek, +- .release = single_release, +- .owner = THIS_MODULE, +-}; +- +-void hisi_sas_debugfs_work_handler(struct work_struct *work) +-{ +- struct hisi_hba *hisi_hba = +- container_of(work, struct hisi_hba, debugfs_work); +- int debugfs_dump_index = hisi_hba->debugfs_dump_index; +- struct device *dev = hisi_hba->dev; +- u64 timestamp = local_clock(); +- +- if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { +- dev_warn(dev, "dump count exceeded!\n"); +- return; +- } +- +- do_div(timestamp, NSEC_PER_MSEC); +- hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; +- +- hisi_sas_debugfs_snapshot_regs(hisi_hba); +- hisi_hba->debugfs_dump_index++; +-} +-EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler); +- +-static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba, int dump_index) +-{ +- struct device *dev = hisi_hba->dev; +- int i; +- +- devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache); +- devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache); +- devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost); +- devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct); +- +- for (i = 0; i < hisi_hba->queue_count; i++) +- devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr); +- +- for (i = 0; i < hisi_hba->queue_count; i++) +- devm_kfree(dev, +- hisi_hba->debugfs_cq[dump_index][i].complete_hdr); +- +- for (i = 0; i < DEBUGFS_REGS_NUM; i++) +- devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data); +- +- for (i = 0; i < hisi_hba->n_phy; i++) +- devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data); +-} +- +-static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba, int dump_index) +-{ +- const struct hisi_sas_hw *hw = hisi_hba->hw; +- struct device *dev = hisi_hba->dev; +- int p, c, d, r, i; +- size_t sz; +- struct dentry *ports_dentry; +- int phy_no; +- +- /* create bist structures */ +- hisi_hba->debugfs_bist_dentry = debugfs_create_dir("bist", +- hisi_hba->debugfs_dir); +- if (!hisi_hba->debugfs_bist_dentry) +- goto fail; +- +- if (!debugfs_create_file("link_rate", 0644, +- hisi_hba->debugfs_bist_dentry, hisi_hba, +- &hisi_sas_debugfs_bist_linkrate_ops)) +- goto fail; +- +- if (!debugfs_create_file("code_mode", 0644, +- hisi_hba->debugfs_bist_dentry, hisi_hba, +- &hisi_sas_debugfs_bist_code_mode_ops)) +- goto fail; +- +- if (!debugfs_create_file("phy_id", 0644, hisi_hba->debugfs_bist_dentry, +- hisi_hba, &hisi_sas_debugfs_bist_phy_ops)) +- goto fail; +- +- if (!debugfs_create_u32("cnt", 0644, hisi_hba->debugfs_bist_dentry, +- &hisi_hba->bist_loopback_cnt)) +- goto fail; +- +- if (!debugfs_create_file("loopback_mode", 0400, +- hisi_hba->debugfs_bist_dentry, +- hisi_hba, &hisi_sas_debugfs_bist_mode_ops)) +- goto fail; +- +- if (!debugfs_create_file("enable", 0644, hisi_hba->debugfs_bist_dentry, +- hisi_hba, &hisi_sas_debugfs_bist_enable_ops)) +- goto fail; +- +- ports_dentry = debugfs_create_dir("port", +- hisi_hba->debugfs_bist_dentry); +- +- for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { +- struct dentry *port_dentry; +- struct dentry *ffe_dentry; +- char name[256]; +- +- snprintf(name, 256, "%d", phy_no); +- port_dentry = debugfs_create_dir(name, ports_dentry); +- ffe_dentry = debugfs_create_dir("ffe", port_dentry); +- for (i = 0; i < FFE_CFG_MAX; i++) { +- if (i == FFE_RESV) +- continue; +- debugfs_create_file(hisi_sas_debugfs_ffe_name[i].name, +- 0600, ffe_dentry, +- &hisi_hba->debugfs_bist_ffe[phy_no][i], +- &hisi_sas_debugfs_ops); +- } +- } +- +- for (r = 0; r < DEBUGFS_REGS_NUM; r++) { +- struct hisi_sas_debugfs_regs *regs = +- &hisi_hba->debugfs_regs[dump_index][r]; +- +- sz = hw->debugfs_reg_array[r]->count * 4; +- regs->data = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!regs->data) +- goto fail; +- regs->hisi_hba = hisi_hba; +- } +- +- sz = hw->debugfs_reg_port->count * 4; +- for (p = 0; p < hisi_hba->n_phy; p++) { +- struct hisi_sas_debugfs_port *port = +- &hisi_hba->debugfs_port_reg[dump_index][p]; +- +- port->data = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!port->data) +- goto fail; +- port->phy = &hisi_hba->phy[p]; +- } +- +- sz = hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; +- for (c = 0; c < hisi_hba->queue_count; c++) { +- struct hisi_sas_debugfs_cq *cq = +- &hisi_hba->debugfs_cq[dump_index][c]; +- +- cq->complete_hdr = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!cq->complete_hdr) +- goto fail; +- cq->cq = &hisi_hba->cq[c]; +- } +- +- sz = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; +- for (d = 0; d < hisi_hba->queue_count; d++) { +- struct hisi_sas_debugfs_dq *dq = +- &hisi_hba->debugfs_dq[dump_index][d]; +- +- dq->hdr = devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!dq->hdr) +- goto fail; +- dq->dq = &hisi_hba->dq[d]; +- } +- +- sz = HISI_SAS_MAX_COMMANDS * sizeof(struct hisi_sas_iost); +- +- hisi_hba->debugfs_iost[dump_index].iost = +- devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_iost[dump_index].iost) +- goto fail; +- +- sz = HISI_SAS_IOST_ITCT_CACHE_NUM * +- sizeof(struct hisi_sas_iost_itct_cache); +- +- hisi_hba->debugfs_iost_cache[dump_index].cache = +- devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_iost_cache[dump_index].cache) +- goto fail; +- +- sz = HISI_SAS_IOST_ITCT_CACHE_NUM * +- sizeof(struct hisi_sas_iost_itct_cache); +- +- hisi_hba->debugfs_itct_cache[dump_index].cache = +- devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_itct_cache[dump_index].cache) +- goto fail; +- +- /* New memory allocation must be locate before itct */ +- sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); +- +- hisi_hba->debugfs_itct[dump_index].itct = +- devm_kmalloc(dev, sz, GFP_KERNEL); +- if (!hisi_hba->debugfs_itct[dump_index].itct) +- goto fail; +- +- return 0; +-fail: +- for (i = 0; i < hisi_sas_debugfs_dump_count; i++) +- hisi_sas_debugfs_release(hisi_hba, i); +- return -ENOMEM; +-} +- +-static void hisi_sas_debugfs_phy_down_cnt_init(struct hisi_hba *hisi_hba) +-{ +- struct dentry *dir = debugfs_create_dir("phy_down_cnt", +- hisi_hba->debugfs_dir); +- char name[16]; +- int phy_no; +- +- for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { +- snprintf(name, 16, "%d", phy_no); +- debugfs_create_file(name, 0600, dir, +- &hisi_hba->phy[phy_no], +- &hisi_sas_debugfs_phy_down_cnt_ops); +- } +-} +- +-void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) +-{ +- struct device *dev = hisi_hba->dev; +- int i; +- +- hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), +- hisi_sas_debugfs_dir); +- debugfs_create_file("trigger_dump", 0200, +- hisi_hba->debugfs_dir, +- hisi_hba, +- &hisi_sas_debugfs_trigger_dump_fops); +- +- hisi_hba->debugfs_dump_dentry = +- debugfs_create_dir("dump", hisi_hba->debugfs_dir); +- +- hisi_sas_debugfs_phy_down_cnt_init(hisi_hba); +- +- for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { +- if (hisi_sas_debugfs_alloc(hisi_hba, i)) { +- debugfs_remove_recursive(hisi_hba->debugfs_dir); +- dev_dbg(dev, "failed to init debugfs!\n"); +- break; +- } +- } +-} +-EXPORT_SYMBOL_GPL(hisi_sas_debugfs_init); +- +-void hisi_sas_debugfs_exit(struct hisi_hba *hisi_hba) +-{ +- debugfs_remove_recursive(hisi_hba->debugfs_dir); +- hisi_hba->debugfs_dir = NULL; +-} +-EXPORT_SYMBOL_GPL(hisi_sas_debugfs_exit); +- + int hisi_sas_remove(struct platform_device *pdev) + { + struct sas_ha_struct *sha = platform_get_drvdata(pdev); +@@ -4159,6 +2795,9 @@ EXPORT_SYMBOL_GPL(hisi_sas_debugfs_dump_count); + module_param_named(debugfs_dump_count, hisi_sas_debugfs_dump_count, uint, 0444); + MODULE_PARM_DESC(hisi_sas_debugfs_dump_count, "Number of debugfs dumps to allow"); + ++struct dentry *hisi_sas_debugfs_dir; ++EXPORT_SYMBOL_GPL(hisi_sas_debugfs_dir); ++ + static __init int hisi_sas_init(void) + { + hisi_sas_stt = sas_domain_attach_transport(&hisi_sas_transport_ops); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 3aea33e85a52..5d99587b48f5 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -573,6 +573,8 @@ module_param(auto_affine_msi_experimental, bool, 0444); + MODULE_PARM_DESC(auto_affine_msi_experimental, "Enable auto-affinity of MSI IRQs as experimental:\n" + "default is off"); + ++static void debugfs_work_handler_v3_hw(struct work_struct *work); ++ + static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) + { + void __iomem *regs = hisi_hba->regs + off; +@@ -3148,6 +3150,18 @@ static int slave_configure_v3_hw(struct scsi_device *sdev) + + return 0; + } ++#define HISI_SAS_DEBUGFS_REG(x) {#x, x} ++ ++struct hisi_sas_debugfs_reg_lu { ++ char *name; ++ int off; ++}; ++ ++struct hisi_sas_debugfs_reg { ++ const struct hisi_sas_debugfs_reg_lu *lu; ++ int count; ++ int base_off; ++}; + + static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = { + HISI_SAS_DEBUGFS_REG(PHY_CFG), +@@ -3204,7 +3218,6 @@ static const struct hisi_sas_debugfs_reg debugfs_port_reg = { + .lu = debugfs_port_reg_lu, + .count = 0x100, /* number of port regs */ + .base_off = PORT_BASE, +- .read_port_reg = hisi_sas_phy_read32, + }; + + static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = { +@@ -3288,7 +3301,6 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = { + static const struct hisi_sas_debugfs_reg debugfs_global_reg = { + .lu = debugfs_global_reg_lu, + .count = 0x800, /* number of global regs */ +- .read_global_reg = hisi_sas_read32, + }; + + static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = { +@@ -3303,7 +3315,6 @@ static const struct hisi_sas_debugfs_reg debugfs_axi_reg = { + .lu = debugfs_axi_reg_lu, + .count = 0x61, + .base_off = AXI_MASTER_CFG_BASE, +- .read_global_reg = hisi_sas_read32, + }; + + static const struct hisi_sas_debugfs_reg_lu debugfs_ras_reg_lu[] = { +@@ -3321,7 +3332,6 @@ static const struct hisi_sas_debugfs_reg debugfs_ras_reg = { + .lu = debugfs_ras_reg_lu, + .count = 0x10, + .base_off = RAS_BASE, +- .read_global_reg = hisi_sas_read32, + }; + + static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) +@@ -3571,16 +3581,8 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = { + .get_events = phy_get_events_v3_hw, + .write_gpio = write_gpio_v3_hw, + .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw, +- .debugfs_reg_array[DEBUGFS_GLOBAL] = &debugfs_global_reg, +- .debugfs_reg_array[DEBUGFS_AXI] = &debugfs_axi_reg, +- .debugfs_reg_array[DEBUGFS_RAS] = &debugfs_ras_reg, +- .debugfs_reg_port = &debugfs_port_reg, +- .snapshot_prepare = debugfs_snapshot_prepare_v3_hw, +- .snapshot_restore = debugfs_snapshot_restore_v3_hw, +- .set_bist = debugfs_set_bist_v3_hw, + .get_managed_irq_aff = get_managed_irq_aff_v3_hw, +- .debugfs_work_handler = hisi_sas_debugfs_work_handler, +- .read_iost_itct_cache = read_iost_itct_cache_v3_hw, ++ .debugfs_work_handler = debugfs_work_handler_v3_hw, + }; + + static struct Scsi_Host * +@@ -3598,7 +3600,7 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev) + hisi_hba = shost_priv(shost); + + INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler); +- INIT_WORK(&hisi_hba->debugfs_work, hisi_sas_debugfs_work_handler); ++ INIT_WORK(&hisi_hba->debugfs_work, debugfs_work_handler_v3_hw); + INIT_WORK(&hisi_hba->notify_work, ssp_notify_work_handler); + hisi_hba->hw = &hisi_sas_v3_hw; + hisi_hba->pci_dev = pdev; +@@ -3628,6 +3630,1192 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev) + return NULL; + } + ++static void debugfs_snapshot_cq_reg_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int queue_entry_size = hisi_hba->hw->complete_hdr_size; ++ int dump_index = hisi_hba->debugfs_dump_index; ++ int i; ++ ++ for (i = 0; i < hisi_hba->queue_count; i++) ++ memcpy(hisi_hba->debugfs_cq[dump_index][i].complete_hdr, ++ hisi_hba->complete_hdr[i], ++ HISI_SAS_QUEUE_SLOTS * queue_entry_size); ++} ++ ++static void debugfs_snapshot_dq_reg_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int queue_entry_size = sizeof(struct hisi_sas_cmd_hdr); ++ int dump_index = hisi_hba->debugfs_dump_index; ++ int i; ++ ++ for (i = 0; i < hisi_hba->queue_count; i++) { ++ struct hisi_sas_cmd_hdr *debugfs_cmd_hdr, *cmd_hdr; ++ int j; ++ ++ debugfs_cmd_hdr = hisi_hba->debugfs_dq[dump_index][i].hdr; ++ cmd_hdr = hisi_hba->cmd_hdr[i]; ++ ++ for (j = 0; j < HISI_SAS_QUEUE_SLOTS; j++) ++ memcpy(&debugfs_cmd_hdr[j], &cmd_hdr[j], ++ queue_entry_size); ++ } ++} ++ ++static void debugfs_snapshot_port_reg_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int dump_index = hisi_hba->debugfs_dump_index; ++ const struct hisi_sas_debugfs_reg *port = &debugfs_port_reg; ++ int i, phy_cnt; ++ u32 offset; ++ u32 *databuf; ++ ++ for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) { ++ databuf = hisi_hba->debugfs_port_reg[dump_index][phy_cnt].data; ++ for (i = 0; i < port->count; i++, databuf++) { ++ offset = port->base_off + 4 * i; ++ *databuf = hisi_sas_phy_read32(hisi_hba, phy_cnt, ++ offset); ++ } ++ } ++} ++ ++static void debugfs_snapshot_global_reg_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int dump_index = hisi_hba->debugfs_dump_index; ++ u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL].data; ++ int i; ++ ++ for (i = 0; i < debugfs_axi_reg.count; i++, databuf++) ++ *databuf = hisi_sas_read32(hisi_hba, 4 * i); ++} ++ ++static void debugfs_snapshot_axi_reg_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int dump_index = hisi_hba->debugfs_dump_index; ++ u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI].data; ++ const struct hisi_sas_debugfs_reg *axi = &debugfs_axi_reg; ++ int i; ++ ++ for (i = 0; i < axi->count; i++, databuf++) ++ *databuf = hisi_sas_read32(hisi_hba, 4 * i + axi->base_off); ++} ++ ++static void debugfs_snapshot_ras_reg_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int dump_index = hisi_hba->debugfs_dump_index; ++ u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS].data; ++ const struct hisi_sas_debugfs_reg *ras = &debugfs_ras_reg; ++ int i; ++ ++ for (i = 0; i < ras->count; i++, databuf++) ++ *databuf = hisi_sas_read32(hisi_hba, 4 * i + ras->base_off); ++} ++ ++static void debugfs_snapshot_itct_reg_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int dump_index = hisi_hba->debugfs_dump_index; ++ void *cachebuf = hisi_hba->debugfs_itct_cache[dump_index].cache; ++ void *databuf = hisi_hba->debugfs_itct[dump_index].itct; ++ struct hisi_sas_itct *itct; ++ int i; ++ ++ read_iost_itct_cache_v3_hw(hisi_hba, HISI_SAS_ITCT_CACHE, cachebuf); ++ ++ itct = hisi_hba->itct; ++ ++ for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) { ++ memcpy(databuf, itct, sizeof(struct hisi_sas_itct)); ++ databuf += sizeof(struct hisi_sas_itct); ++ } ++} ++ ++static void debugfs_snapshot_iost_reg_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int dump_index = hisi_hba->debugfs_dump_index; ++ int max_command_entries = HISI_SAS_MAX_COMMANDS; ++ void *cachebuf = hisi_hba->debugfs_iost_cache[dump_index].cache; ++ void *databuf = hisi_hba->debugfs_iost[dump_index].iost; ++ struct hisi_sas_iost *iost; ++ int i; ++ ++ read_iost_itct_cache_v3_hw(hisi_hba, HISI_SAS_IOST_CACHE, cachebuf); ++ ++ iost = hisi_hba->iost; ++ ++ for (i = 0; i < max_command_entries; i++, iost++) { ++ memcpy(databuf, iost, sizeof(struct hisi_sas_iost)); ++ databuf += sizeof(struct hisi_sas_iost); ++ } ++} ++ ++static const char * ++debugfs_to_reg_name_v3_hw(int off, int base_off, ++ const struct hisi_sas_debugfs_reg_lu *lu) ++{ ++ for (; lu->name; lu++) { ++ if (off == lu->off - base_off) ++ return lu->name; ++ } ++ ++ return NULL; ++} ++ ++static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s, ++ const struct hisi_sas_debugfs_reg *reg) ++{ ++ int i; ++ ++ for (i = 0; i < reg->count; i++) { ++ int off = i * 4; ++ const char *name; ++ ++ name = debugfs_to_reg_name_v3_hw(off, reg->base_off, ++ reg->lu); ++ ++ if (name) ++ seq_printf(s, "0x%08x 0x%08x %s\n", off, ++ regs_val[i], name); ++ else ++ seq_printf(s, "0x%08x 0x%08x\n", off, ++ regs_val[i]); ++ } ++} ++ ++static int debugfs_global_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_debugfs_regs *global = s->private; ++ ++ debugfs_print_reg_v3_hw(global->data, s, ++ &debugfs_global_reg); ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_global_v3_hw); ++ ++static int debugfs_axi_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_debugfs_regs *axi = s->private; ++ ++ debugfs_print_reg_v3_hw(axi->data, s, ++ &debugfs_axi_reg); ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_axi_v3_hw); ++ ++static int debugfs_ras_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_debugfs_regs *ras = s->private; ++ ++ debugfs_print_reg_v3_hw(ras->data, s, ++ &debugfs_ras_reg); ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_ras_v3_hw); ++ ++static int debugfs_port_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_debugfs_port *port = s->private; ++ const struct hisi_sas_debugfs_reg *reg_port = &debugfs_port_reg; ++ ++ debugfs_print_reg_v3_hw(port->data, s, reg_port); ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_port_v3_hw); ++ ++static void debugfs_show_row_64_v3_hw(struct seq_file *s, int index, ++ int sz, __le64 *ptr) ++{ ++ int i; ++ ++ /* completion header size not fixed per HW version */ ++ seq_printf(s, "index %04d:\n\t", index); ++ for (i = 1; i <= sz / 8; i++, ptr++) { ++ seq_printf(s, " 0x%016llx", le64_to_cpu(*ptr)); ++ if (!(i % 2)) ++ seq_puts(s, "\n\t"); ++ } ++ ++ seq_puts(s, "\n"); ++} ++ ++static void debugfs_show_row_32_v3_hw(struct seq_file *s, int index, ++ int sz, __le32 *ptr) ++{ ++ int i; ++ ++ /* completion header size not fixed per HW version */ ++ seq_printf(s, "index %04d:\n\t", index); ++ for (i = 1; i <= sz / 4; i++, ptr++) { ++ seq_printf(s, " 0x%08x", le32_to_cpu(*ptr)); ++ if (!(i % 4)) ++ seq_puts(s, "\n\t"); ++ } ++ seq_puts(s, "\n"); ++} ++ ++static void debugfs_cq_show_slot_v3_hw(struct seq_file *s, int slot, ++ struct hisi_sas_debugfs_cq *debugfs_cq) ++{ ++ struct hisi_sas_cq *cq = debugfs_cq->cq; ++ struct hisi_hba *hisi_hba = cq->hisi_hba; ++ __le32 *complete_hdr = debugfs_cq->complete_hdr + ++ (hisi_hba->hw->complete_hdr_size * slot); ++ ++ debugfs_show_row_32_v3_hw(s, slot, ++ hisi_hba->hw->complete_hdr_size, ++ complete_hdr); ++} ++ ++static int debugfs_cq_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_debugfs_cq *debugfs_cq = s->private; ++ int slot; ++ ++ for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) ++ debugfs_cq_show_slot_v3_hw(s, slot, debugfs_cq); ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_cq_v3_hw); ++ ++static void debugfs_dq_show_slot_v3_hw(struct seq_file *s, int slot, ++ void *dq_ptr) ++{ ++ struct hisi_sas_debugfs_dq *debugfs_dq = dq_ptr; ++ void *cmd_queue = debugfs_dq->hdr; ++ __le32 *cmd_hdr = cmd_queue + ++ sizeof(struct hisi_sas_cmd_hdr) * slot; ++ ++ debugfs_show_row_32_v3_hw(s, slot, sizeof(struct hisi_sas_cmd_hdr), ++ cmd_hdr); ++} ++ ++static int debugfs_dq_v3_hw_show(struct seq_file *s, void *p) ++{ ++ int slot; ++ ++ for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) ++ debugfs_dq_show_slot_v3_hw(s, slot, s->private); ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_dq_v3_hw); ++ ++static int debugfs_iost_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_debugfs_iost *debugfs_iost = s->private; ++ struct hisi_sas_iost *iost = debugfs_iost->iost; ++ int i, max_command_entries = HISI_SAS_MAX_COMMANDS; ++ ++ for (i = 0; i < max_command_entries; i++, iost++) { ++ __le64 *data = &iost->qw0; ++ ++ debugfs_show_row_64_v3_hw(s, i, sizeof(*iost), data); ++ } ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_iost_v3_hw); ++ ++static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_debugfs_iost_cache *debugfs_iost_cache = s->private; ++ struct hisi_sas_iost_itct_cache *iost_cache = ++ debugfs_iost_cache->cache; ++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; ++ int i, tab_idx; ++ __le64 *iost; ++ ++ for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) { ++ /* ++ * Data struct of IOST cache: ++ * Data[1]: BIT0~15: Table index ++ * Bit16: Valid mask ++ * Data[2]~[9]: IOST table ++ */ ++ tab_idx = (iost_cache->data[1] & 0xffff); ++ iost = (__le64 *)iost_cache; ++ ++ debugfs_show_row_64_v3_hw(s, tab_idx, cache_size, iost); ++ } ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_iost_cache_v3_hw); ++ ++static int debugfs_itct_v3_hw_show(struct seq_file *s, void *p) ++{ ++ int i; ++ struct hisi_sas_debugfs_itct *debugfs_itct = s->private; ++ struct hisi_sas_itct *itct = debugfs_itct->itct; ++ ++ for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) { ++ __le64 *data = &itct->qw0; ++ ++ debugfs_show_row_64_v3_hw(s, i, sizeof(*itct), data); ++ } ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_itct_v3_hw); ++ ++static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_debugfs_itct_cache *debugfs_itct_cache = s->private; ++ struct hisi_sas_iost_itct_cache *itct_cache = ++ debugfs_itct_cache->cache; ++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; ++ int i, tab_idx; ++ __le64 *itct; ++ ++ for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) { ++ /* ++ * Data struct of ITCT cache: ++ * Data[1]: BIT0~15: Table index ++ * Bit16: Valid mask ++ * Data[2]~[9]: ITCT table ++ */ ++ tab_idx = itct_cache->data[1] & 0xffff; ++ itct = (__le64 *)itct_cache; ++ ++ debugfs_show_row_64_v3_hw(s, tab_idx, cache_size, itct); ++ } ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_itct_cache_v3_hw); ++ ++static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ u64 *debugfs_timestamp; ++ int dump_index = hisi_hba->debugfs_dump_index; ++ struct dentry *dump_dentry; ++ struct dentry *dentry; ++ char name[256]; ++ int p; ++ int c; ++ int d; ++ ++ snprintf(name, 256, "%d", dump_index); ++ ++ dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry); ++ ++ debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index]; ++ ++ debugfs_create_u64("timestamp", 0400, dump_dentry, ++ debugfs_timestamp); ++ ++ debugfs_create_file("global", 0400, dump_dentry, ++ &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL], ++ &debugfs_global_v3_hw_fops); ++ ++ /* Create port dir and files */ ++ dentry = debugfs_create_dir("port", dump_dentry); ++ for (p = 0; p < hisi_hba->n_phy; p++) { ++ snprintf(name, 256, "%d", p); ++ ++ debugfs_create_file(name, 0400, dentry, ++ &hisi_hba->debugfs_port_reg[dump_index][p], ++ &debugfs_port_v3_hw_fops); ++ } ++ ++ /* Create CQ dir and files */ ++ dentry = debugfs_create_dir("cq", dump_dentry); ++ for (c = 0; c < hisi_hba->queue_count; c++) { ++ snprintf(name, 256, "%d", c); ++ ++ debugfs_create_file(name, 0400, dentry, ++ &hisi_hba->debugfs_cq[dump_index][c], ++ &debugfs_cq_v3_hw_fops); ++ } ++ ++ /* Create DQ dir and files */ ++ dentry = debugfs_create_dir("dq", dump_dentry); ++ for (d = 0; d < hisi_hba->queue_count; d++) { ++ snprintf(name, 256, "%d", d); ++ ++ debugfs_create_file(name, 0400, dentry, ++ &hisi_hba->debugfs_dq[dump_index][d], ++ &debugfs_dq_v3_hw_fops); ++ } ++ ++ debugfs_create_file("iost", 0400, dump_dentry, ++ &hisi_hba->debugfs_iost[dump_index], ++ &debugfs_iost_v3_hw_fops); ++ ++ debugfs_create_file("iost_cache", 0400, dump_dentry, ++ &hisi_hba->debugfs_iost_cache[dump_index], ++ &debugfs_iost_cache_v3_hw_fops); ++ ++ debugfs_create_file("itct", 0400, dump_dentry, ++ &hisi_hba->debugfs_itct[dump_index], ++ &debugfs_itct_v3_hw_fops); ++ ++ debugfs_create_file("itct_cache", 0400, dump_dentry, ++ &hisi_hba->debugfs_itct_cache[dump_index], ++ &debugfs_itct_cache_v3_hw_fops); ++ ++ debugfs_create_file("axi", 0400, dump_dentry, ++ &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI], ++ &debugfs_axi_v3_hw_fops); ++ ++ debugfs_create_file("ras", 0400, dump_dentry, ++ &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS], ++ &debugfs_ras_v3_hw_fops); ++} ++ ++static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ debugfs_snapshot_prepare_v3_hw(hisi_hba); ++ ++ debugfs_snapshot_global_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_port_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_axi_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_ras_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_cq_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_dq_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_itct_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_iost_reg_v3_hw(hisi_hba); ++ ++ debugfs_create_files_v3_hw(hisi_hba); ++ ++ debugfs_snapshot_restore_v3_hw(hisi_hba); ++} ++ ++static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct hisi_hba *hisi_hba = file->f_inode->i_private; ++ char buf[8]; ++ ++ if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count) ++ return -EFAULT; ++ ++ if (count > 8) ++ return -EFAULT; ++ ++ if (copy_from_user(buf, user_buf, count)) ++ return -EFAULT; ++ ++ if (buf[0] != '1') ++ return -EFAULT; ++ ++ queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); ++ ++ return count; ++} ++ ++static const struct file_operations debugfs_trigger_dump_v3_hw_fops = { ++ .write = &debugfs_trigger_dump_v3_hw_write, ++ .owner = THIS_MODULE, ++}; ++ ++static const struct { ++ int value; ++ char *name; ++} debugfs_loop_linkrate_v3_hw[] = { ++ { SAS_LINK_RATE_1_5_GBPS, "1.5 Gbit" }, ++ { SAS_LINK_RATE_3_0_GBPS, "3.0 Gbit" }, ++ { SAS_LINK_RATE_6_0_GBPS, "6.0 Gbit" }, ++ { SAS_LINK_RATE_12_0_GBPS, "12.0 Gbit" }, ++}; ++ ++static int debugfs_bist_linkrate_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_hba *hisi_hba = s->private; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(debugfs_loop_linkrate_v3_hw); i++) { ++ int match = (hisi_hba->bist_loopback_linkrate == ++ debugfs_loop_linkrate_v3_hw[i].value); ++ ++ seq_printf(s, "%s%s%s ", match ? "[" : "", ++ debugfs_loop_linkrate_v3_hw[i].name, ++ match ? "]" : ""); ++ } ++ seq_puts(s, "\n"); ++ ++ return 0; ++} ++ ++static ssize_t debugfs_bist_linkrate_v3_hw_write(struct file *filp, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *m = filp->private_data; ++ struct hisi_hba *hisi_hba = m->private; ++ char kbuf[16] = {}, *pkbuf; ++ bool found = false; ++ int i; ++ ++ if (hisi_hba->bist_loopback_enable) ++ return -EPERM; ++ ++ if (count >= sizeof(kbuf)) ++ return -EOVERFLOW; ++ ++ if (copy_from_user(kbuf, buf, count)) ++ return -EINVAL; ++ ++ pkbuf = strstrip(kbuf); ++ ++ for (i = 0; i < ARRAY_SIZE(debugfs_loop_linkrate_v3_hw); i++) { ++ if (!strncmp(debugfs_loop_linkrate_v3_hw[i].name, ++ pkbuf, 16)) { ++ hisi_hba->bist_loopback_linkrate = ++ debugfs_loop_linkrate_v3_hw[i].value; ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ return -EINVAL; ++ ++ return count; ++} ++ ++static int debugfs_bist_linkrate_v3_hw_open(struct inode *inode, ++ struct file *filp) ++{ ++ return single_open(filp, debugfs_bist_linkrate_v3_hw_show, ++ inode->i_private); ++} ++ ++static const struct file_operations debugfs_bist_linkrate_v3_hw_fops = { ++ .open = debugfs_bist_linkrate_v3_hw_open, ++ .read = seq_read, ++ .write = debugfs_bist_linkrate_v3_hw_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ ++static const struct { ++ int value; ++ char *name; ++} debugfs_loop_code_mode_v3_hw[] = { ++ { HISI_SAS_BIST_CODE_MODE_PRBS7, "PRBS7" }, ++ { HISI_SAS_BIST_CODE_MODE_PRBS23, "PRBS23" }, ++ { HISI_SAS_BIST_CODE_MODE_PRBS31, "PRBS31" }, ++ { HISI_SAS_BIST_CODE_MODE_JTPAT, "JTPAT" }, ++ { HISI_SAS_BIST_CODE_MODE_CJTPAT, "CJTPAT" }, ++ { HISI_SAS_BIST_CODE_MODE_SCRAMBED_0, "SCRAMBED_0" }, ++ { HISI_SAS_BIST_CODE_MODE_TRAIN, "TRAIN" }, ++ { HISI_SAS_BIST_CODE_MODE_TRAIN_DONE, "TRAIN_DONE" }, ++ { HISI_SAS_BIST_CODE_MODE_HFTP, "HFTP" }, ++ { HISI_SAS_BIST_CODE_MODE_MFTP, "MFTP" }, ++ { HISI_SAS_BIST_CODE_MODE_LFTP, "LFTP" }, ++ { HISI_SAS_BIST_CODE_MODE_FIXED_DATA, "FIXED_DATA" }, ++}; ++ ++static int debugfs_bist_code_mode_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_hba *hisi_hba = s->private; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(debugfs_loop_code_mode_v3_hw); i++) { ++ int match = (hisi_hba->bist_loopback_code_mode == ++ debugfs_loop_code_mode_v3_hw[i].value); ++ ++ seq_printf(s, "%s%s%s ", match ? "[" : "", ++ debugfs_loop_code_mode_v3_hw[i].name, ++ match ? "]" : ""); ++ } ++ seq_puts(s, "\n"); ++ ++ return 0; ++} ++ ++static ssize_t debugfs_bist_code_mode_v3_hw_write(struct file *filp, ++ const char __user *buf, ++ size_t count, ++ loff_t *ppos) ++{ ++ struct seq_file *m = filp->private_data; ++ struct hisi_hba *hisi_hba = m->private; ++ char kbuf[16] = {}, *pkbuf; ++ bool found = false; ++ int i; ++ ++ if (hisi_hba->bist_loopback_enable) ++ return -EPERM; ++ ++ if (count >= sizeof(kbuf)) ++ return -EINVAL; ++ ++ if (copy_from_user(kbuf, buf, count)) ++ return -EOVERFLOW; ++ ++ pkbuf = strstrip(kbuf); ++ ++ for (i = 0; i < ARRAY_SIZE(debugfs_loop_code_mode_v3_hw); i++) { ++ if (!strncmp(debugfs_loop_code_mode_v3_hw[i].name, ++ pkbuf, 16)) { ++ hisi_hba->bist_loopback_code_mode = ++ debugfs_loop_code_mode_v3_hw[i].value; ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ return -EINVAL; ++ ++ return count; ++} ++ ++static int debugfs_bist_code_mode_v3_hw_open(struct inode *inode, ++ struct file *filp) ++{ ++ return single_open(filp, debugfs_bist_code_mode_v3_hw_show, ++ inode->i_private); ++} ++ ++static const struct file_operations debugfs_bist_code_mode_v3_hw_fops = { ++ .open = debugfs_bist_code_mode_v3_hw_open, ++ .read = seq_read, ++ .write = debugfs_bist_code_mode_v3_hw_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ ++static ssize_t debugfs_bist_phy_v3_hw_write(struct file *filp, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *m = filp->private_data; ++ struct hisi_hba *hisi_hba = m->private; ++ unsigned int phy_no; ++ int val; ++ ++ if (hisi_hba->bist_loopback_enable) ++ return -EPERM; ++ ++ val = kstrtouint_from_user(buf, count, 0, &phy_no); ++ if (val) ++ return val; ++ ++ if (phy_no >= hisi_hba->n_phy) ++ return -EINVAL; ++ ++ hisi_hba->bist_loopback_phy_id = phy_no; ++ ++ return count; ++} ++ ++static int debugfs_bist_phy_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_hba *hisi_hba = s->private; ++ ++ seq_printf(s, "%d\n", hisi_hba->bist_loopback_phy_id); ++ ++ return 0; ++} ++ ++static int debugfs_bist_phy_v3_hw_open(struct inode *inode, ++ struct file *filp) ++{ ++ return single_open(filp, debugfs_bist_phy_v3_hw_show, ++ inode->i_private); ++} ++ ++static const struct file_operations debugfs_bist_phy_v3_hw_fops = { ++ .open = debugfs_bist_phy_v3_hw_open, ++ .read = seq_read, ++ .write = debugfs_bist_phy_v3_hw_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ ++static const struct { ++ int value; ++ char *name; ++} debugfs_loop_modes_v3_hw[] = { ++ { HISI_SAS_BIST_LOOPBACK_MODE_DIGITAL, "digital" }, ++ { HISI_SAS_BIST_LOOPBACK_MODE_SERDES, "serdes" }, ++ { HISI_SAS_BIST_LOOPBACK_MODE_REMOTE, "remote" }, ++}; ++ ++static int debugfs_bist_mode_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_hba *hisi_hba = s->private; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(debugfs_loop_modes_v3_hw); i++) { ++ int match = (hisi_hba->bist_loopback_mode == ++ debugfs_loop_modes_v3_hw[i].value); ++ ++ seq_printf(s, "%s%s%s ", match ? "[" : "", ++ debugfs_loop_modes_v3_hw[i].name, ++ match ? "]" : ""); ++ } ++ seq_puts(s, "\n"); ++ ++ return 0; ++} ++ ++static ssize_t debugfs_bist_mode_v3_hw_write(struct file *filp, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *m = filp->private_data; ++ struct hisi_hba *hisi_hba = m->private; ++ char kbuf[16] = {}, *pkbuf; ++ bool found = false; ++ int i; ++ ++ if (hisi_hba->bist_loopback_enable) ++ return -EPERM; ++ ++ if (count >= sizeof(kbuf)) ++ return -EINVAL; ++ ++ if (copy_from_user(kbuf, buf, count)) ++ return -EOVERFLOW; ++ ++ pkbuf = strstrip(kbuf); ++ ++ for (i = 0; i < ARRAY_SIZE(debugfs_loop_modes_v3_hw); i++) { ++ if (!strncmp(debugfs_loop_modes_v3_hw[i].name, pkbuf, 16)) { ++ hisi_hba->bist_loopback_mode = ++ debugfs_loop_modes_v3_hw[i].value; ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ return -EINVAL; ++ ++ return count; ++} ++ ++static int debugfs_bist_mode_v3_hw_open(struct inode *inode, ++ struct file *filp) ++{ ++ return single_open(filp, debugfs_bist_mode_v3_hw_show, ++ inode->i_private); ++} ++ ++static const struct file_operations debugfs_bist_mode_v3_hw_fops = { ++ .open = debugfs_bist_mode_v3_hw_open, ++ .read = seq_read, ++ .write = debugfs_bist_mode_v3_hw_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ ++static ssize_t debugfs_bist_enable_v3_hw_write(struct file *filp, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *m = filp->private_data; ++ struct hisi_hba *hisi_hba = m->private; ++ unsigned int enable; ++ int val; ++ ++ val = kstrtouint_from_user(buf, count, 0, &enable); ++ if (val) ++ return val; ++ ++ if (enable > 1) ++ return -EINVAL; ++ ++ if (enable == hisi_hba->bist_loopback_enable) ++ return count; ++ ++ val = debugfs_set_bist_v3_hw(hisi_hba, enable); ++ if (val < 0) ++ return val; ++ ++ hisi_hba->bist_loopback_enable = enable; ++ ++ return count; ++} ++ ++static int debugfs_bist_enable_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_hba *hisi_hba = s->private; ++ ++ seq_printf(s, "%d\n", hisi_hba->bist_loopback_enable); ++ ++ return 0; ++} ++ ++static int debugfs_bist_enable_v3_hw_open(struct inode *inode, ++ struct file *filp) ++{ ++ return single_open(filp, debugfs_bist_enable_v3_hw_show, ++ inode->i_private); ++} ++ ++static const struct file_operations debugfs_bist_enable_v3_hw_fops = { ++ .open = debugfs_bist_enable_v3_hw_open, ++ .read = seq_read, ++ .write = debugfs_bist_enable_v3_hw_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ ++static const struct { ++ char *name; ++} debugfs_ffe_name_v3_hw[FFE_CFG_MAX] = { ++ { "SAS_1_5_GBPS" }, ++ { "SAS_3_0_GBPS" }, ++ { "SAS_6_0_GBPS" }, ++ { "SAS_12_0_GBPS" }, ++ { "FFE_RESV" }, ++ { "SATA_1_5_GBPS" }, ++ { "SATA_3_0_GBPS" }, ++ { "SATA_6_0_GBPS" }, ++}; ++ ++static ssize_t debugfs_v3_hw_write(struct file *filp, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *m = filp->private_data; ++ u32 *val = m->private; ++ int res; ++ ++ res = kstrtouint_from_user(buf, count, 0, val); ++ if (res) ++ return res; ++ ++ return count; ++} ++ ++static int debugfs_v3_hw_show(struct seq_file *s, void *p) ++{ ++ u32 *val = s->private; ++ ++ seq_printf(s, "0x%x\n", *val); ++ ++ return 0; ++} ++ ++static int debugfs_v3_hw_open(struct inode *inode, struct file *filp) ++{ ++ return single_open(filp, debugfs_v3_hw_show, ++ inode->i_private); ++} ++ ++static const struct file_operations debugfs_v3_hw_fops = { ++ .open = debugfs_v3_hw_open, ++ .read = seq_read, ++ .write = debugfs_v3_hw_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ ++static ssize_t debugfs_phy_down_cnt_v3_hw_write(struct file *filp, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *s = filp->private_data; ++ struct hisi_sas_phy *phy = s->private; ++ unsigned int set_val; ++ int res; ++ ++ res = kstrtouint_from_user(buf, count, 0, &set_val); ++ if (res) ++ return res; ++ ++ if (set_val > 0) ++ return -EINVAL; ++ ++ atomic_set(&phy->down_cnt, 0); ++ ++ return count; ++} ++ ++static int debugfs_phy_down_cnt_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_phy *phy = s->private; ++ ++ seq_printf(s, "%d\n", atomic_read(&phy->down_cnt)); ++ ++ return 0; ++} ++ ++static int debugfs_phy_down_cnt_v3_hw_open(struct inode *inode, ++ struct file *filp) ++{ ++ return single_open(filp, debugfs_phy_down_cnt_v3_hw_show, ++ inode->i_private); ++} ++ ++static const struct file_operations debugfs_phy_down_cnt_v3_hw_fops = { ++ .open = debugfs_phy_down_cnt_v3_hw_open, ++ .read = seq_read, ++ .write = debugfs_phy_down_cnt_v3_hw_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ ++static void debugfs_work_handler_v3_hw(struct work_struct *work) ++{ ++ struct hisi_hba *hisi_hba = ++ container_of(work, struct hisi_hba, debugfs_work); ++ int debugfs_dump_index = hisi_hba->debugfs_dump_index; ++ struct device *dev = hisi_hba->dev; ++ u64 timestamp = local_clock(); ++ ++ if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { ++ dev_warn(dev, "dump count exceeded!\n"); ++ return; ++ } ++ ++ do_div(timestamp, NSEC_PER_MSEC); ++ hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; ++ ++ debugfs_snapshot_regs_v3_hw(hisi_hba); ++ hisi_hba->debugfs_dump_index++; ++} ++ ++static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index) ++{ ++ struct device *dev = hisi_hba->dev; ++ int i; ++ ++ devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache); ++ devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache); ++ devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost); ++ devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct); ++ ++ for (i = 0; i < hisi_hba->queue_count; i++) ++ devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr); ++ ++ for (i = 0; i < hisi_hba->queue_count; i++) ++ devm_kfree(dev, ++ hisi_hba->debugfs_cq[dump_index][i].complete_hdr); ++ ++ for (i = 0; i < DEBUGFS_REGS_NUM; i++) ++ devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data); ++ ++ for (i = 0; i < hisi_hba->n_phy; i++) ++ devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data); ++} ++ ++static const ++struct hisi_sas_debugfs_reg *debugfs_reg_array_v3_hw[DEBUGFS_REGS_NUM] = { ++ [DEBUGFS_GLOBAL] = &debugfs_global_reg, ++ [DEBUGFS_AXI] = &debugfs_axi_reg, ++ [DEBUGFS_RAS] = &debugfs_ras_reg, ++}; ++ ++static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index) ++{ ++ const struct hisi_sas_hw *hw = hisi_hba->hw; ++ struct device *dev = hisi_hba->dev; ++ int p, c, d, r, i; ++ size_t sz; ++ ++ for (r = 0; r < DEBUGFS_REGS_NUM; r++) { ++ struct hisi_sas_debugfs_regs *regs = ++ &hisi_hba->debugfs_regs[dump_index][r]; ++ ++ sz = debugfs_reg_array_v3_hw[r]->count * 4; ++ regs->data = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!regs->data) ++ goto fail; ++ regs->hisi_hba = hisi_hba; ++ } ++ ++ sz = debugfs_port_reg.count * 4; ++ for (p = 0; p < hisi_hba->n_phy; p++) { ++ struct hisi_sas_debugfs_port *port = ++ &hisi_hba->debugfs_port_reg[dump_index][p]; ++ ++ port->data = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!port->data) ++ goto fail; ++ port->phy = &hisi_hba->phy[p]; ++ } ++ ++ sz = hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; ++ for (c = 0; c < hisi_hba->queue_count; c++) { ++ struct hisi_sas_debugfs_cq *cq = ++ &hisi_hba->debugfs_cq[dump_index][c]; ++ ++ cq->complete_hdr = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!cq->complete_hdr) ++ goto fail; ++ cq->cq = &hisi_hba->cq[c]; ++ } ++ ++ sz = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; ++ for (d = 0; d < hisi_hba->queue_count; d++) { ++ struct hisi_sas_debugfs_dq *dq = ++ &hisi_hba->debugfs_dq[dump_index][d]; ++ ++ dq->hdr = devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!dq->hdr) ++ goto fail; ++ dq->dq = &hisi_hba->dq[d]; ++ } ++ ++ sz = HISI_SAS_MAX_COMMANDS * sizeof(struct hisi_sas_iost); ++ ++ hisi_hba->debugfs_iost[dump_index].iost = ++ devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_iost[dump_index].iost) ++ goto fail; ++ ++ sz = HISI_SAS_IOST_ITCT_CACHE_NUM * ++ sizeof(struct hisi_sas_iost_itct_cache); ++ ++ hisi_hba->debugfs_iost_cache[dump_index].cache = ++ devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_iost_cache[dump_index].cache) ++ goto fail; ++ ++ sz = HISI_SAS_IOST_ITCT_CACHE_NUM * ++ sizeof(struct hisi_sas_iost_itct_cache); ++ ++ hisi_hba->debugfs_itct_cache[dump_index].cache = ++ devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_itct_cache[dump_index].cache) ++ goto fail; ++ ++ /* New memory allocation must be locate before itct */ ++ sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); ++ ++ hisi_hba->debugfs_itct[dump_index].itct = ++ devm_kmalloc(dev, sz, GFP_KERNEL); ++ if (!hisi_hba->debugfs_itct[dump_index].itct) ++ goto fail; ++ ++ return 0; ++fail: ++ for (i = 0; i < hisi_sas_debugfs_dump_count; i++) ++ debugfs_release_v3_hw(hisi_hba, i); ++ return -ENOMEM; ++} ++ ++static void debugfs_phy_down_cnt_init_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ struct dentry *dir = debugfs_create_dir("phy_down_cnt", ++ hisi_hba->debugfs_dir); ++ char name[16]; ++ int phy_no; ++ ++ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { ++ snprintf(name, 16, "%d", phy_no); ++ debugfs_create_file(name, 0600, dir, ++ &hisi_hba->phy[phy_no], ++ &debugfs_phy_down_cnt_v3_hw_fops); ++ } ++} ++ ++static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ struct dentry *ports_dentry; ++ int phy_no; ++ ++ hisi_hba->debugfs_bist_dentry = ++ debugfs_create_dir("bist", hisi_hba->debugfs_dir); ++ debugfs_create_file("link_rate", 0600, ++ hisi_hba->debugfs_bist_dentry, hisi_hba, ++ &debugfs_bist_linkrate_v3_hw_fops); ++ ++ debugfs_create_file("code_mode", 0600, ++ hisi_hba->debugfs_bist_dentry, hisi_hba, ++ &debugfs_bist_code_mode_v3_hw_fops); ++ ++ debugfs_create_file("fixed_code", 0600, ++ hisi_hba->debugfs_bist_dentry, ++ &hisi_hba->debugfs_bist_fixed_code[0], ++ &debugfs_v3_hw_fops); ++ ++ debugfs_create_file("fixed_code_1", 0600, ++ hisi_hba->debugfs_bist_dentry, ++ &hisi_hba->debugfs_bist_fixed_code[1], ++ &debugfs_v3_hw_fops); ++ ++ debugfs_create_file("phy_id", 0600, hisi_hba->debugfs_bist_dentry, ++ hisi_hba, &debugfs_bist_phy_v3_hw_fops); ++ ++ debugfs_create_u32("cnt", 0600, hisi_hba->debugfs_bist_dentry, ++ &hisi_hba->bist_loopback_cnt); ++ ++ debugfs_create_file("loopback_mode", 0600, ++ hisi_hba->debugfs_bist_dentry, ++ hisi_hba, &debugfs_bist_mode_v3_hw_fops); ++ ++ debugfs_create_file("enable", 0600, hisi_hba->debugfs_bist_dentry, ++ hisi_hba, &debugfs_bist_enable_v3_hw_fops); ++ ++ ports_dentry = debugfs_create_dir("port", ++ hisi_hba->debugfs_bist_dentry); ++ ++ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { ++ struct dentry *port_dentry; ++ struct dentry *ffe_dentry; ++ char name[256]; ++ int i; ++ ++ snprintf(name, 256, "%d", phy_no); ++ port_dentry = debugfs_create_dir(name, ports_dentry); ++ ffe_dentry = debugfs_create_dir("ffe", port_dentry); ++ for (i = 0; i < FFE_CFG_MAX; i++) { ++ if (i == FFE_RESV) ++ continue; ++ debugfs_create_file(debugfs_ffe_name_v3_hw[i].name, ++ 0600, ffe_dentry, ++ &hisi_hba->debugfs_bist_ffe[phy_no][i], ++ &debugfs_v3_hw_fops); ++ } ++ } ++ ++ hisi_hba->bist_loopback_linkrate = SAS_LINK_RATE_1_5_GBPS; ++} ++ ++static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ struct device *dev = hisi_hba->dev; ++ int i; ++ ++ hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), ++ hisi_sas_debugfs_dir); ++ debugfs_create_file("trigger_dump", 0200, ++ hisi_hba->debugfs_dir, ++ hisi_hba, ++ &debugfs_trigger_dump_v3_hw_fops); ++ ++ /* create bist structures */ ++ debugfs_bist_init_v3_hw(hisi_hba); ++ ++ hisi_hba->debugfs_dump_dentry = ++ debugfs_create_dir("dump", hisi_hba->debugfs_dir); ++ ++ debugfs_phy_down_cnt_init_v3_hw(hisi_hba); ++ ++ for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { ++ if (debugfs_alloc_v3_hw(hisi_hba, i)) { ++ debugfs_remove_recursive(hisi_hba->debugfs_dir); ++ dev_dbg(dev, "failed to init debugfs!\n"); ++ break; ++ } ++ } ++} ++ ++static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ debugfs_remove_recursive(hisi_hba->debugfs_dir); ++} ++ + static int + hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + { +@@ -3711,7 +4899,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + } + + if (hisi_sas_debugfs_enable) +- hisi_sas_debugfs_init(hisi_hba); ++ debugfs_init_v3_hw(hisi_hba); + + if (hisi_hba->enable_dix_dif) { + scsi_host_set_prot(hisi_hba->shost, +@@ -3750,7 +4938,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + err_out_register_ha: + scsi_remove_host(shost); + err_out_debugfs: +- hisi_sas_debugfs_exit(hisi_hba); ++ debugfs_exit_v3_hw(hisi_hba); + err_out_ha: + hisi_sas_free(hisi_hba); + scsi_host_put(shost); +@@ -3800,7 +4988,7 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev) + pci_release_regions(pdev); + pci_disable_device(pdev); + hisi_sas_free(hisi_hba); +- hisi_sas_debugfs_exit(hisi_hba); ++ debugfs_exit_v3_hw(hisi_hba); + scsi_host_put(shost); + } + +-- +2.27.0 + diff --git a/patches/0715-scsi-hisi_sas-Remove-preemptible.patch b/patches/0715-scsi-hisi_sas-Remove-preemptible.patch new file mode 100644 index 0000000..fa095e2 --- /dev/null +++ b/patches/0715-scsi-hisi_sas-Remove-preemptible.patch @@ -0,0 +1,72 @@ +From 0929404331a090441751d87f27dee83b60f48c06 Mon Sep 17 00:00:00 2001 +From: "Ahmed S. Darwish" +Date: Tue, 3 Aug 2021 14:47:28 +0800 +Subject: [PATCH 067/108] scsi: hisi_sas: Remove preemptible() + +mainline inclusion +from mainline-v5.11-rc1 +commit 18577cdcaeeb7a1ca5c3adc4d92ed2ba75699625 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=18577cdcaeeb7a1ca5c3adc4d92ed2ba75699625 + +---------------------------------------------------------------------- + +hisi_sas_task_exec() uses preemptible() to see if it's safe to block. This +does not work for CONFIG_PREEMPT_COUNT=n kernels in which preemptible() +always returns 0. + +The problem is masked when enabling some of the common Kconfig.debug +options (like CONFIG_DEBUG_ATOMIC_SLEEP), as they implicitly enable the +preemption counter. + +In general, driver leaf functions should not make logic decisions based on +the context they're called from. The caller should be the entity +responsible for explicitly indicating context. + +Since hisi_sas_task_exec() already has a gfp_t flags parameter, use it as +the explicit context marker. + +Link: https://lore.kernel.org/r/20201126132952.2287996-3-bigeasy@linutronix.de +Fixes: 214e702d4b70 ("scsi: hisi_sas: Adjust task reject period during host reset") +Fixes: 550c0d89d52d ("scsi: hisi_sas: Replace in_softirq() check in hisi_sas_task_exec()") +Cc: Xiaofei Tan +Cc: Xiang Chen +Cc: John Garry +Acked-by: John Garry +Signed-off-by: Ahmed S. Darwish +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index c0a870202484..4b58e2f3ca03 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -601,9 +601,10 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags, + hisi_hba = dev_to_hisi_hba(device); + dev = hisi_hba->dev; + +- if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) +- return -EINVAL; +- ++ if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) { ++ if (!gfpflags_allow_blocking(gfp_flags)) ++ return -EINVAL; ++ } + + /* protect task_prep and start_delivery sequence */ + rc = hisi_sas_task_prep(task, is_tmf, tmf, &pass, &dq); +-- +2.27.0 + diff --git a/patches/0716-scsi-hisi_sas-use-threaded-irq-to-process-CQ-interru.patch b/patches/0716-scsi-hisi_sas-use-threaded-irq-to-process-CQ-interru.patch new file mode 100644 index 0000000..7b2a068 --- /dev/null +++ b/patches/0716-scsi-hisi_sas-use-threaded-irq-to-process-CQ-interru.patch @@ -0,0 +1,325 @@ +From 26e11334126ba91dd21fc47aca10d58d5c936c09 Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Mon, 20 Jan 2020 20:22:31 +0800 +Subject: [PATCH 068/108] scsi: hisi_sas: use threaded irq to process CQ + interrupts + +mainline inclusion +from mainline-v5.6-rc1 +commit 81f338e9709db0b67d05bab02809d6a4e6694884 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=81f338e9709db0b67d05bab02809d6a4e6694884 + +---------------------------------------------------------------------- + +Currently IRQ_EFFECTIVE_AFF_MASK is enabled for ARM_GIC and ARM_GIC3, so it +only allows a single target CPU in the affinity mask to process interrupts +and also interrupt thread, and the performance of using threaded irq is +almost the same as tasklet. But if the config is not enabled, the interrupt +thread will be allowed all the CPUs in the affinity mask. At that situation +it improves the performance (about 20%). + +Note: IRQ_EFFECTIVE_AFF_MASK is configured differently for different +architecture chip, and it seems to be better to make it be configured +easily. + +Link: https://lore.kernel.org/r/1579522957-4393-2-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 4 ++-- + drivers/scsi/hisi_sas/hisi_sas_main.c | 22 +++++++++--------- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 26 ++++++++------------- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 32 ++++++++++++++------------ + 4 files changed, 40 insertions(+), 44 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 707ee782faa5..c9ff2e34d708 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -202,9 +202,9 @@ struct hisi_sas_port { + struct hisi_sas_cq { + struct hisi_hba *hisi_hba; + const struct cpumask *pci_irq_mask; +- struct tasklet_struct tasklet; + int rd_point; + int id; ++ int irq_no; + }; + + struct hisi_sas_dq { +@@ -677,7 +677,7 @@ extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, + extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba); + extern void hisi_sas_rst_work_handler(struct work_struct *work); + extern void hisi_sas_sync_rst_work_handler(struct work_struct *work); +-extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba); ++extern void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba); + extern void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no); + extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy, + enum hisi_sas_phy_event event); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 4b58e2f3ca03..62fc39c27af8 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1270,10 +1270,10 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, + struct hisi_sas_cq *cq = + &hisi_hba->cq[slot->dlvry_queue]; + /* +- * flush tasklet to avoid free'ing task ++ * sync irq to avoid free'ing task + * before using task in IO completion + */ +- tasklet_kill(&cq->tasklet); ++ synchronize_irq(cq->irq_no); + slot->task = NULL; + } + +@@ -1677,11 +1677,11 @@ static int hisi_sas_abort_task(struct sas_task *task) + + if (slot) { + /* +- * flush tasklet to avoid free'ing task ++ * sync irq to avoid free'ing task + * before using task in IO completion + */ + cq = &hisi_hba->cq[slot->dlvry_queue]; +- tasklet_kill(&cq->tasklet); ++ synchronize_irq(cq->irq_no); + } + spin_unlock_irqrestore(&task->task_state_lock, flags); + rc = TMF_RESP_FUNC_COMPLETE; +@@ -1755,10 +1755,10 @@ static int hisi_sas_abort_task(struct sas_task *task) + if (((rc < 0) || (rc == TMF_RESP_FUNC_FAILED)) && + task->lldd_task) { + /* +- * flush tasklet to avoid free'ing task ++ * sync irq to avoid free'ing task + * before using task in IO completion + */ +- tasklet_kill(&cq->tasklet); ++ synchronize_irq(cq->irq_no); + slot->task = NULL; + } + } +@@ -2142,10 +2142,10 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + struct hisi_sas_cq *cq = + &hisi_hba->cq[slot->dlvry_queue]; + /* +- * flush tasklet to avoid free'ing task ++ * sync irq to avoid free'ing task + * before using task in IO completion + */ +- tasklet_kill(&cq->tasklet); ++ synchronize_irq(cq->irq_no); + slot->task = NULL; + } + dev_err(dev, "internal task abort: timeout and not done.\n"); +@@ -2298,17 +2298,17 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) + } + EXPORT_SYMBOL_GPL(hisi_sas_phy_down); + +-void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba) ++void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba) + { + int i; + + for (i = 0; i < hisi_hba->nvecs; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; + +- tasklet_kill(&cq->tasklet); ++ synchronize_irq(cq->irq_no); + } + } +-EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets); ++EXPORT_SYMBOL_GPL(hisi_sas_sync_irqs); + + int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type) + { +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index 1d1ee655c9fb..55331ffa3be5 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3128,9 +3128,9 @@ static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p) + return IRQ_HANDLED; + } + +-static void cq_tasklet_v2_hw(unsigned long val) ++static irqreturn_t cq_thread_v2_hw(int irq_no, void *p) + { +- struct hisi_sas_cq *cq = (struct hisi_sas_cq *)val; ++ struct hisi_sas_cq *cq = p; + struct hisi_hba *hisi_hba = cq->hisi_hba; + struct hisi_sas_slot *slot; + struct hisi_sas_itct *itct; +@@ -3192,6 +3192,8 @@ static void cq_tasklet_v2_hw(unsigned long val) + /* update rd_point */ + cq->rd_point = rd_point; + hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); ++ ++ return IRQ_HANDLED; + } + + static irqreturn_t cq_interrupt_v2_hw(int irq_no, void *p) +@@ -3202,9 +3204,7 @@ static irqreturn_t cq_interrupt_v2_hw(int irq_no, void *p) + + hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); + +- tasklet_schedule(&cq->tasklet); +- +- return IRQ_HANDLED; ++ return IRQ_WAKE_THREAD; + } + + static irqreturn_t sata_int_v2_hw(int irq_no, void *p) +@@ -3371,18 +3371,18 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) + + for (queue_no = 0; queue_no < hisi_hba->queue_count; queue_no++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[queue_no]; +- struct tasklet_struct *t = &cq->tasklet; + +- irq = irq_map[queue_no + 96]; +- rc = devm_request_irq(dev, irq, cq_interrupt_v2_hw, 0, +- DRV_NAME " cq", cq); ++ cq->irq_no = irq_map[queue_no + 96]; ++ rc = devm_request_threaded_irq(dev, cq->irq_no, ++ cq_interrupt_v2_hw, ++ cq_thread_v2_hw, IRQF_ONESHOT, ++ DRV_NAME " cq", cq); + if (rc) { + dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", + irq, rc); + rc = -ENOENT; + goto err_out; + } +- tasklet_init(t, cq_tasklet_v2_hw, (unsigned long)cq); + } + + hisi_hba->nvecs = hisi_hba->queue_count; +@@ -3444,7 +3444,6 @@ static int soft_reset_v2_hw(struct hisi_hba *hisi_hba) + + interrupt_disable_v2_hw(hisi_hba); + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); +- hisi_sas_kill_tasklets(hisi_hba); + + hisi_sas_stop_phys(hisi_hba); + +@@ -3618,11 +3617,6 @@ static int hisi_sas_v2_probe(struct platform_device *pdev) + + static int hisi_sas_v2_remove(struct platform_device *pdev) + { +- struct sas_ha_struct *sha = platform_get_drvdata(pdev); +- struct hisi_hba *hisi_hba = sha->lldd_ha; +- +- hisi_sas_kill_tasklets(hisi_hba); +- + return hisi_sas_remove(pdev); + } + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 5d99587b48f5..5c04df84b6eb 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2639,9 +2639,9 @@ static void hisi_sas_disk_err_handler(struct hisi_hba *hisi_hba, + hisi_sas_ata_device_link_abort(device); + } + +-static void cq_tasklet_v3_hw(unsigned long val) ++static irqreturn_t cq_thread_v3_hw(int irq_no, void *p) + { +- struct hisi_sas_cq *cq = (struct hisi_sas_cq *)val; ++ struct hisi_sas_cq *cq = p; + struct hisi_hba *hisi_hba = cq->hisi_hba; + struct hisi_sas_slot *slot; + struct hisi_sas_complete_v3_hdr *complete_queue; +@@ -2685,6 +2685,8 @@ static void cq_tasklet_v3_hw(unsigned long val) + hisi_sas_write32(hisi_hba, + COMPL_Q_0_RD_PTR + (NEXT_DQCQ_REG_OFF * queue), + rd_point); ++ ++ return IRQ_HANDLED; + } + + static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p) +@@ -2695,9 +2697,7 @@ static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p) + + hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); + +- tasklet_schedule(&cq->tasklet); +- +- return IRQ_HANDLED; ++ return IRQ_WAKE_THREAD; + } + + static void setup_reply_map_v3_hw(struct hisi_hba *hisi_hba, int nvecs) +@@ -2800,24 +2800,28 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + if (hisi_sas_intr_conv) + dev_info(dev, "Enable interrupt converge\n"); + +- /* Init tasklets for cq only */ + for (i = 0; i < hisi_hba->nvecs; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; +- struct tasklet_struct *t = &cq->tasklet; + int nr = hisi_sas_intr_conv ? PCI_IRQ_CQ_BASE : + PCI_IRQ_CQ_BASE + i; +- unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : 0; + +- rc = devm_request_irq(dev, pci_irq_vector(pdev, nr), +- cq_interrupt_v3_hw, irqflags, +- DRV_NAME " cq", cq); ++ unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : ++ IRQF_ONESHOT; ++ ++ cq->irq_no = pci_irq_vector(pdev, nr); ++ ++ rc = devm_request_threaded_irq(dev, cq->irq_no, ++ cq_interrupt_v3_hw, ++ cq_thread_v3_hw, ++ irqflags, ++ DRV_NAME " cq", cq); ++ + if (rc) { + dev_err(dev, "could not request cq%d interrupt, rc=%d\n", + i, rc); + return -ENOENT; + } + +- tasklet_init(t, cq_tasklet_v3_hw, (uintptr_t)cq); + } + + return 0; +@@ -2924,7 +2928,6 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba) + + interrupt_disable_v3_hw(hisi_hba); + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); +- hisi_sas_kill_tasklets(hisi_hba); + + hisi_sas_stop_phys(hisi_hba); + +@@ -3343,7 +3346,7 @@ static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) + /* delay:100ms, timeout:5s */ + wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000); + +- hisi_sas_kill_tasklets(hisi_hba); ++ hisi_sas_sync_irqs(hisi_hba); + } + + static void debugfs_snapshot_restore_v3_hw(struct hisi_hba *hisi_hba) +@@ -4984,7 +4987,6 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev) + sas_remove_host(sha->core.shost); + + hisi_sas_v3_destroy_irqs(pdev, hisi_hba); +- hisi_sas_kill_tasklets(hisi_hba); + pci_release_regions(pdev); + pci_disable_device(pdev); + hisi_sas_free(hisi_hba); +-- +2.27.0 + diff --git a/patches/0717-scsi-hisi_sas-Remove-deferred-probe-check-in-hisi_sa.patch b/patches/0717-scsi-hisi_sas-Remove-deferred-probe-check-in-hisi_sa.patch new file mode 100644 index 0000000..f82949a --- /dev/null +++ b/patches/0717-scsi-hisi_sas-Remove-deferred-probe-check-in-hisi_sa.patch @@ -0,0 +1,60 @@ +From 2ac8249ba497e08f4839edced8a06e55561dd614 Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Tue, 3 Aug 2021 14:47:48 +0800 +Subject: [PATCH 069/108] scsi: hisi_sas: Remove deferred probe check in + hisi_sas_v2_probe() + +mainline inclusion +from mainline-v5.12-rc1 +commit 4d287d8bae1f395b5e5d79bc9673dacab7975e36 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4d287d8bae1f395b5e5d79bc9673dacab7975e36 + +---------------------------------------------------------------------- + +The platform_get_irq() check for -EPROBE_DEFER was to ensure that all the +steps to add the SCSI host are not done and then only to realise that the +probe needs to be deferred. + +However, since there is now an earlier check for this in +hisi_sas_interrupt_preinit(), this check is superfluous and may be removed. + +Link: https://lore.kernel.org/r/1611659068-131975-2-git-send-email-john.garry@huawei.com +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index 55331ffa3be5..078404d2754a 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3600,18 +3600,6 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = { + + static int hisi_sas_v2_probe(struct platform_device *pdev) + { +- /* +- * Check if we should defer the probe before we probe the +- * upper layer, as it's hard to defer later on. +- */ +- int ret = platform_get_irq(pdev, 0); +- +- if (ret < 0) { +- if (ret != -EPROBE_DEFER) +- dev_err(&pdev->dev, "cannot obtain irq\n"); +- return ret; +- } +- + return hisi_sas_probe(pdev, &hisi_sas_v2_hw); + } + +-- +2.27.0 + diff --git a/patches/0718-scsi-hisi_sas-Enable-debugfs-support-by-default.patch b/patches/0718-scsi-hisi_sas-Enable-debugfs-support-by-default.patch new file mode 100644 index 0000000..9327fdb --- /dev/null +++ b/patches/0718-scsi-hisi_sas-Enable-debugfs-support-by-default.patch @@ -0,0 +1,81 @@ +From 5cad5cf497bcd5fc97f9c966b7d680b4722e5d18 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:47:50 +0800 +Subject: [PATCH 070/108] scsi: hisi_sas: Enable debugfs support by default + +mainline inclusion +from mainline-v5.12-rc1 +commit 1dbe61bf7d760547d16ccf057572e641a653ad4a +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1dbe61bf7d760547d16ccf057572e641a653ad4a + +---------------------------------------------------------------------- + +Add a config option to enable debugfs support by default. And if debugfs +support is enabled by default, dump count default value is increased to 50 +as generally users want something bigger than the current default in that +situation. + +Link: https://lore.kernel.org/r/1611659068-131975-4-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/Kconfig | 6 ++++++ + drivers/scsi/hisi_sas/hisi_sas_main.c | 13 +++++++++++-- + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig +index 11c46b217caa..a8999964d3e9 100644 +--- a/drivers/scsi/hisi_sas/Kconfig ++++ b/drivers/scsi/hisi_sas/Kconfig +@@ -17,3 +17,9 @@ config SCSI_HISI_SAS_PCI + depends on ACPI + help + This driver supports HiSilicon's SAS HBA based on PCI device ++ ++config SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE ++ bool "HiSilicon SAS debugging default enable" ++ depends on SCSI_HISI_SAS ++ help ++ Set Y to default enable DEBUGFS for SCSI_HISI_SAS +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 62fc39c27af8..133791f6223b 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2786,12 +2786,21 @@ int hisi_sas_remove(struct platform_device *pdev) + } + EXPORT_SYMBOL_GPL(hisi_sas_remove); + ++#if IS_ENABLED(CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE) ++#define DEBUGFS_ENABLE_DEFAULT "enabled" + bool hisi_sas_debugfs_enable = true; ++u32 hisi_sas_debugfs_dump_count = 50; ++#else ++#define DEBUGFS_ENABLE_DEFAULT "disabled" ++bool hisi_sas_debugfs_enable; ++u32 hisi_sas_debugfs_dump_count = 1; ++#endif ++ + EXPORT_SYMBOL_GPL(hisi_sas_debugfs_enable); + module_param_named(debugfs_enable, hisi_sas_debugfs_enable, bool, 0444); +-MODULE_PARM_DESC(hisi_sas_debugfs_enable, "Enable driver debugfs (default disabled)"); ++MODULE_PARM_DESC(hisi_sas_debugfs_enable, ++ "Enable driver debugfs (default "DEBUGFS_ENABLE_DEFAULT")"); + +-u32 hisi_sas_debugfs_dump_count = 1; + EXPORT_SYMBOL_GPL(hisi_sas_debugfs_dump_count); + module_param_named(debugfs_dump_count, hisi_sas_debugfs_dump_count, uint, 0444); + MODULE_PARM_DESC(hisi_sas_debugfs_dump_count, "Number of debugfs dumps to allow"); +-- +2.27.0 + diff --git a/patches/0719-scsi-hisi_sas-Add-trace-FIFO-debugfs-support.patch b/patches/0719-scsi-hisi_sas-Add-trace-FIFO-debugfs-support.patch new file mode 100644 index 0000000..9acd7de --- /dev/null +++ b/patches/0719-scsi-hisi_sas-Add-trace-FIFO-debugfs-support.patch @@ -0,0 +1,385 @@ +From a5572f06382a85ffc2b858bfae1c82ed96398bd1 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:47:52 +0800 +Subject: [PATCH 071/108] scsi: hisi_sas: Add trace FIFO debugfs support + +mainline inclusion +from mainline-v5.12-rc1 +commit cd96fe600cc4924d8d0cc6e3161870219c0d2c12 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F825 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cd96fe600cc4924d8d0cc6e3161870219c0d2c12 + +---------------------------------------------------------------------- + +The controller provides trace FIFO DFX tool to assist link fault debugging +and link optimization. This tool can be helpful when debugging link faults +without SAS analyzers. Each PHY has an independent trace FIFO interface. + +The user can configure the trace FIFO tool of one PHY by using the +following six interfaces: + +signal_sel: select signal group applies to different scenarios. + 0x0: linkrate negotiation + 0x1: Host 12G TX train + 0x2: Disk 12G TX train + 0x3: SAS PHY CTRL DFX 0 + 0x4: SAS PHY CTRL DFX 1 + 0x5: SAS PCS DFX + other: linkrate negotiation +dump_mask: The masked hardware status bit will not be updated. +dump_mode: determines how to dump data after trigger signal is generated. + 0x0: dump forever + 0x1: dump 32 data after trigger signal is generated + 0x2: no more dump after trigger signal is generated +trigger_mode: determines the trigger mode, level or edge. + 0x0: dump when trigger signal changed + 0x1: dump when trigger signal's level equal to trigger_level + 0x2: dump when trigger signal's level different from trigger_level +trigger_level: determines the trigger level. +trigger_msk: mask trigger signal + +The user can get 32-byte values from hardware by reading the rd_data. +These values consitute the status record of the hardware at different time +points. + +Link: https://lore.kernel.org/r/1611659068-131975-6-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 15 ++ + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 251 +++++++++++++++++++++++++ + 2 files changed, 266 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index c9ff2e34d708..27c061a401a9 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -47,6 +47,7 @@ + + #define HISI_SAS_IOST_ITCT_CACHE_NUM 64 + #define HISI_SAS_IOST_ITCT_CACHE_DW_SZ 10 ++#define HISI_SAS_FIFO_DATA_DW_SIZE 32 + + #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer)) + #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table)) +@@ -169,6 +170,16 @@ enum hisi_sas_phy_event { + HISI_PHYES_NUM, + }; + ++struct hisi_sas_debugfs_fifo { ++ u32 signal_sel; ++ u32 dump_msk; ++ u32 dump_mode; ++ u32 trigger; ++ u32 trigger_msk; ++ u32 trigger_mode; ++ u32 rd_data[HISI_SAS_FIFO_DATA_DW_SIZE]; ++}; ++ + struct hisi_sas_phy { + struct work_struct works[HISI_PHYES_NUM]; + struct hisi_hba *hisi_hba; +@@ -191,6 +202,9 @@ struct hisi_sas_phy { + u32 code_error_count; + int enable; + atomic_t down_cnt; ++ ++ /* Trace FIFO */ ++ struct hisi_sas_debugfs_fifo fifo; + }; + + struct hisi_sas_port { +@@ -502,6 +516,7 @@ struct hisi_hba { + struct dentry *debugfs_dir; + struct dentry *debugfs_dump_dentry; + struct dentry *debugfs_bist_dentry; ++ struct dentry *debugfs_fifo_dentry; + + bool user_ctl_irq; + unsigned int dq_idx[NR_CPUS]; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 5c04df84b6eb..ba1eba2d3d68 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -312,6 +312,19 @@ + #define ERR_CNT_INVLD_DW (PORT_BASE + 0x390) + #define ERR_CNT_CODE_ERR (PORT_BASE + 0x394) + #define ERR_CNT_DISP_ERR (PORT_BASE + 0x398) ++#define DFX_FIFO_CTRL (PORT_BASE + 0x3a0) ++#define DFX_FIFO_CTRL_TRIGGER_MODE_OFF 0 ++#define DFX_FIFO_CTRL_TRIGGER_MODE_MSK (0x7 << DFX_FIFO_CTRL_TRIGGER_MODE_OFF) ++#define DFX_FIFO_CTRL_DUMP_MODE_OFF 3 ++#define DFX_FIFO_CTRL_DUMP_MODE_MSK (0x7 << DFX_FIFO_CTRL_DUMP_MODE_OFF) ++#define DFX_FIFO_CTRL_SIGNAL_SEL_OFF 6 ++#define DFX_FIFO_CTRL_SIGNAL_SEL_MSK (0xF << DFX_FIFO_CTRL_SIGNAL_SEL_OFF) ++#define DFX_FIFO_CTRL_DUMP_DISABLE_OFF 10 ++#define DFX_FIFO_CTRL_DUMP_DISABLE_MSK (0x1 << DFX_FIFO_CTRL_DUMP_DISABLE_OFF) ++#define DFX_FIFO_TRIGGER (PORT_BASE + 0x3a4) ++#define DFX_FIFO_TRIGGER_MSK (PORT_BASE + 0x3a8) ++#define DFX_FIFO_DUMP_MSK (PORT_BASE + 0x3aC) ++#define DFX_FIFO_RD_DATA (PORT_BASE + 0x3b0) + + #define DEFAULT_ITCT_HW 2048 /* reset value, not reprogrammed */ + #if (HISI_SAS_MAX_DEVICES > DEFAULT_ITCT_HW) +@@ -4567,6 +4580,243 @@ static const struct file_operations debugfs_phy_down_cnt_v3_hw_fops = { + .owner = THIS_MODULE, + }; + ++enum fifo_dump_mode_v3_hw { ++ FIFO_DUMP_FORVER = (1U << 0), ++ FIFO_DUMP_AFTER_TRIGGER = (1U << 1), ++ FIFO_DUMP_UNTILL_TRIGGER = (1U << 2), ++}; ++ ++enum fifo_trigger_mode_v3_hw { ++ FIFO_TRIGGER_EDGE = (1U << 0), ++ FIFO_TRIGGER_SAME_LEVEL = (1U << 1), ++ FIFO_TRIGGER_DIFF_LEVEL = (1U << 2), ++}; ++ ++static int debugfs_is_fifo_config_valid_v3_hw(struct hisi_sas_phy *phy) ++{ ++ struct hisi_hba *hisi_hba = phy->hisi_hba; ++ ++ if (phy->fifo.signal_sel > 0xf) { ++ dev_info(hisi_hba->dev, "Invalid signal select: %u\n", ++ phy->fifo.signal_sel); ++ return -EINVAL; ++ } ++ ++ switch (phy->fifo.dump_mode) { ++ case FIFO_DUMP_FORVER: ++ case FIFO_DUMP_AFTER_TRIGGER: ++ case FIFO_DUMP_UNTILL_TRIGGER: ++ break; ++ default: ++ dev_info(hisi_hba->dev, "Invalid dump mode: %u\n", ++ phy->fifo.dump_mode); ++ return -EINVAL; ++ } ++ ++ /* when FIFO_DUMP_FORVER, no need to check trigger_mode */ ++ if (phy->fifo.dump_mode == FIFO_DUMP_FORVER) ++ return 0; ++ ++ switch (phy->fifo.trigger_mode) { ++ case FIFO_TRIGGER_EDGE: ++ case FIFO_TRIGGER_SAME_LEVEL: ++ case FIFO_TRIGGER_DIFF_LEVEL: ++ break; ++ default: ++ dev_info(hisi_hba->dev, "Invalid trigger mode: %u\n", ++ phy->fifo.trigger_mode); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int debugfs_update_fifo_config_v3_hw(struct hisi_sas_phy *phy) ++{ ++ u32 trigger_mode = phy->fifo.trigger_mode; ++ u32 signal_sel = phy->fifo.signal_sel; ++ u32 dump_mode = phy->fifo.dump_mode; ++ struct hisi_hba *hisi_hba = phy->hisi_hba; ++ int phy_no = phy->sas_phy.id; ++ u32 reg_val; ++ int res; ++ ++ /* Check the validity of trace FIFO configuration */ ++ res = debugfs_is_fifo_config_valid_v3_hw(phy); ++ if (res) ++ return res; ++ ++ reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); ++ /* Disable trace FIFO before update configuration */ ++ reg_val |= DFX_FIFO_CTRL_DUMP_DISABLE_MSK; ++ ++ /* Update trace FIFO configuration */ ++ reg_val &= ~(DFX_FIFO_CTRL_DUMP_MODE_MSK | ++ DFX_FIFO_CTRL_SIGNAL_SEL_MSK | ++ DFX_FIFO_CTRL_TRIGGER_MODE_MSK); ++ ++ reg_val |= ((trigger_mode << DFX_FIFO_CTRL_TRIGGER_MODE_OFF) | ++ (dump_mode << DFX_FIFO_CTRL_DUMP_MODE_OFF) | ++ (signal_sel << DFX_FIFO_CTRL_SIGNAL_SEL_OFF)); ++ hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, reg_val); ++ ++ hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_DUMP_MSK, ++ phy->fifo.dump_msk); ++ ++ hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_TRIGGER, ++ phy->fifo.trigger); ++ ++ hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_TRIGGER_MSK, ++ phy->fifo.trigger_msk); ++ ++ /* Enable trace FIFO after updated configuration */ ++ reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); ++ reg_val &= ~DFX_FIFO_CTRL_DUMP_DISABLE_MSK; ++ hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, reg_val); ++ ++ return 0; ++} ++ ++static ssize_t debugfs_fifo_update_cfg_v3_hw_write(struct file *filp, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct hisi_sas_phy *phy = filp->private_data; ++ bool update; ++ int val; ++ ++ val = kstrtobool_from_user(buf, count, &update); ++ if (val) ++ return val; ++ ++ if (update != 1) ++ return -EINVAL; ++ ++ val = debugfs_update_fifo_config_v3_hw(phy); ++ if (val) ++ return val; ++ ++ return count; ++} ++ ++static const struct file_operations debugfs_fifo_update_cfg_v3_hw_fops = { ++ .open = simple_open, ++ .write = debugfs_fifo_update_cfg_v3_hw_write, ++ .owner = THIS_MODULE, ++}; ++ ++static void debugfs_read_fifo_data_v3_hw(struct hisi_sas_phy *phy) ++{ ++ struct hisi_hba *hisi_hba = phy->hisi_hba; ++ u32 *buf = phy->fifo.rd_data; ++ int phy_no = phy->sas_phy.id; ++ u32 val; ++ int i; ++ ++ memset(buf, 0, sizeof(phy->fifo.rd_data)); ++ ++ /* Disable trace FIFO before read data */ ++ val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); ++ val |= DFX_FIFO_CTRL_DUMP_DISABLE_MSK; ++ hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, val); ++ ++ for (i = 0; i < HISI_SAS_FIFO_DATA_DW_SIZE; i++) { ++ val = hisi_sas_phy_read32(hisi_hba, phy_no, ++ DFX_FIFO_RD_DATA); ++ buf[i] = val; ++ } ++ ++ /* Enable trace FIFO after read data */ ++ val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); ++ val &= ~DFX_FIFO_CTRL_DUMP_DISABLE_MSK; ++ hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, val); ++} ++ ++static int debugfs_fifo_data_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_sas_phy *phy = s->private; ++ ++ debugfs_read_fifo_data_v3_hw(phy); ++ ++ debugfs_show_row_32_v3_hw(s, 0, HISI_SAS_FIFO_DATA_DW_SIZE * 4, ++ phy->fifo.rd_data); ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(debugfs_fifo_data_v3_hw); ++ ++static void debugfs_fifo_init_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int phy_no; ++ ++ hisi_hba->debugfs_fifo_dentry = ++ debugfs_create_dir("fifo", hisi_hba->debugfs_dir); ++ ++ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { ++ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; ++ struct dentry *port_dentry; ++ char name[256]; ++ u32 val; ++ ++ /* get default configuration for trace FIFO */ ++ val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); ++ val &= DFX_FIFO_CTRL_DUMP_MODE_MSK; ++ val >>= DFX_FIFO_CTRL_DUMP_MODE_OFF; ++ phy->fifo.dump_mode = val; ++ ++ val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); ++ val &= DFX_FIFO_CTRL_TRIGGER_MODE_MSK; ++ val >>= DFX_FIFO_CTRL_TRIGGER_MODE_OFF; ++ phy->fifo.trigger_mode = val; ++ ++ val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); ++ val &= DFX_FIFO_CTRL_SIGNAL_SEL_MSK; ++ val >>= DFX_FIFO_CTRL_SIGNAL_SEL_OFF; ++ phy->fifo.signal_sel = val; ++ ++ val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_DUMP_MSK); ++ phy->fifo.dump_msk = val; ++ ++ val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_TRIGGER); ++ phy->fifo.trigger = val; ++ val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_TRIGGER_MSK); ++ phy->fifo.trigger_msk = val; ++ ++ snprintf(name, 256, "%d", phy_no); ++ port_dentry = debugfs_create_dir(name, ++ hisi_hba->debugfs_fifo_dentry); ++ ++ debugfs_create_file("update_config", 0200, port_dentry, phy, ++ &debugfs_fifo_update_cfg_v3_hw_fops); ++ ++ debugfs_create_file("signal_sel", 0600, port_dentry, ++ &phy->fifo.signal_sel, ++ &debugfs_v3_hw_fops); ++ ++ debugfs_create_file("dump_msk", 0600, port_dentry, ++ &phy->fifo.dump_msk, ++ &debugfs_v3_hw_fops); ++ ++ debugfs_create_file("dump_mode", 0600, port_dentry, ++ &phy->fifo.dump_mode, ++ &debugfs_v3_hw_fops); ++ ++ debugfs_create_file("trigger_mode", 0600, port_dentry, ++ &phy->fifo.trigger_mode, ++ &debugfs_v3_hw_fops); ++ ++ debugfs_create_file("trigger", 0600, port_dentry, ++ &phy->fifo.trigger, ++ &debugfs_v3_hw_fops); ++ ++ debugfs_create_file("trigger_msk", 0600, port_dentry, ++ &phy->fifo.trigger_msk, ++ &debugfs_v3_hw_fops); ++ ++ debugfs_create_file("fifo_data", 0400, port_dentry, phy, ++ &debugfs_fifo_data_v3_hw_fops); ++ } ++} ++ + static void debugfs_work_handler_v3_hw(struct work_struct *work) + { + struct hisi_hba *hisi_hba = +@@ -4804,6 +5054,7 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) + debugfs_create_dir("dump", hisi_hba->debugfs_dir); + + debugfs_phy_down_cnt_init_v3_hw(hisi_hba); ++ debugfs_fifo_init_v3_hw(hisi_hba); + + for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { + if (debugfs_alloc_v3_hw(hisi_hba, i)) { +-- +2.27.0 + diff --git a/patches/0720-scsi-hisi_sas-Print-SAS-address-for-v3-hw-erroneous-.patch b/patches/0720-scsi-hisi_sas-Print-SAS-address-for-v3-hw-erroneous-.patch new file mode 100644 index 0000000..bde7bff --- /dev/null +++ b/patches/0720-scsi-hisi_sas-Print-SAS-address-for-v3-hw-erroneous-.patch @@ -0,0 +1,57 @@ +From 5ab56b9fc4e36baf645c70b9e7a3ecbbdd21fbf8 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:47:54 +0800 +Subject: [PATCH 072/108] scsi: hisi_sas: Print SAS address for v3 hw erroneous + completion print + +mainline inclusion +from mainline-v5.13-rc1 +commit 4da0b7f6fac331f2d2336df3ca88a335f545b4dc +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4da0b7f6fac331f2d2336df3ca88a335f545b4dc + +---------------------------------------------------------------------- + +To help debugging efforts, print the device SAS address for v3 hw erroneous +completion log. + +Here is an example print: + +hisi_sas_v3_hw 0000:b4:02.0: erroneous completion iptt=2193 task=000000002b0c13f8 dev id=17 addr=570fd45f9d17b001 + +Link: https://lore.kernel.org/r/1617709711-195853-3-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index ba1eba2d3d68..be5c7b7dfd7e 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2493,9 +2493,9 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, + + set_aborted_iptt(hisi_hba, slot); + slot_err_v3_hw(hisi_hba, task, slot); +- dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d sas_addr=0x%llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", ++ dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr%016llx sas_addr=0x%llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", + slot->idx, task, sas_dev->device_id, +- itct->sas_addr, ++ SAS_ADDR(device->sas_addr), itct->sas_addr, + dw0, dw1, + complete_hdr->act, dw3, + error_info[0], error_info[1], +-- +2.27.0 + diff --git a/patches/0721-scsi-hisi_sas-Call-sas_unregister_ha-to-roll-back-if.patch b/patches/0721-scsi-hisi_sas-Call-sas_unregister_ha-to-roll-back-if.patch new file mode 100644 index 0000000..d95b488 --- /dev/null +++ b/patches/0721-scsi-hisi_sas-Call-sas_unregister_ha-to-roll-back-if.patch @@ -0,0 +1,78 @@ +From a7b5c8dea24439571a34f2cdcc45ea2915330bda Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Tue, 3 Aug 2021 14:47:55 +0800 +Subject: [PATCH 073/108] scsi: hisi_sas: Call sas_unregister_ha() to roll back + if .hw_init() fails + +mainline inclusion +from mainline-v5.13-rc1 +commit f467666504bf0c7eae95b929d0c86f77ff9b4356 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f467666504bf0c7eae95b929d0c86f77ff9b4356 + +---------------------------------------------------------------------- + +Function sas_unregister_ha() needs to be called to roll back if +hisi_hba->hw->hw_init() fails in function hisi_sas_probe() or +hisi_sas_v3_probe(). Make that change. + +Link: https://lore.kernel.org/r/1617709711-195853-4-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 4 +++- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 +++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 133791f6223b..b7cc4ef60169 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2753,12 +2753,14 @@ int hisi_sas_probe(struct platform_device *pdev, + + rc = hisi_hba->hw->hw_init(hisi_hba); + if (rc) +- goto err_out_register_ha; ++ goto err_out_hw_init; + + scsi_scan_host(shost); + + return 0; + ++err_out_hw_init: ++ sas_unregister_ha(sha); + err_out_register_ha: + scsi_remove_host(shost); + err_out: +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index be5c7b7dfd7e..6f48312ee1d6 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -5172,7 +5172,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + rc = hisi_sas_v3_init(hisi_hba); + if (rc) +- goto err_out_register_ha; ++ goto err_out_hw_init; + + scsi_scan_host(shost); + +@@ -5189,6 +5189,8 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + return 0; + ++err_out_hw_init: ++ sas_unregister_ha(sha); + err_out_register_ha: + scsi_remove_host(shost); + err_out_debugfs: +-- +2.27.0 + diff --git a/patches/0722-scsi-hisi_sas-Directly-snapshot-registers-when-execu.patch b/patches/0722-scsi-hisi_sas-Directly-snapshot-registers-when-execu.patch new file mode 100644 index 0000000..828506f --- /dev/null +++ b/patches/0722-scsi-hisi_sas-Directly-snapshot-registers-when-execu.patch @@ -0,0 +1,175 @@ +From 7764ae0693eaf3aa29183be6c5e510b307b08810 Mon Sep 17 00:00:00 2001 +From: Jianqin Xie +Date: Tue, 3 Aug 2021 14:47:56 +0800 +Subject: [PATCH 074/108] scsi: hisi_sas: Directly snapshot registers when + executing a reset + +mainline inclusion +from mainline-v5.13-rc1 +commit 2c74cb1f9222ebfcc204c02018275ad167d25212 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2c74cb1f9222ebfcc204c02018275ad167d25212 + +---------------------------------------------------------------------- + +The debugfs snapshot should be executed before the reset occurs to ensure +that the register contents are saved properly. + +As such, it is incorrect to queue the debugfs dump when running a reset as +the reset will occur prior to the snapshot work item is handler. + +Therefore, directly snapshot registers in the reset work handler. + +Link: https://lore.kernel.org/r/1617709711-195853-5-git-send-email-john.garry@huawei.com +Signed-off-by: Jianqin Xie +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 + + drivers/scsi/hisi_sas/hisi_sas_main.c | 25 +++++++++++++++++++----- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 27 ++++++++++++++------------ + 3 files changed, 36 insertions(+), 17 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 27c061a401a9..47e767fb0acf 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -373,6 +373,7 @@ struct hisi_sas_hw { + const struct cpumask *(*get_managed_irq_aff)(struct hisi_hba + *hisi_hba, int queue); + void (*debugfs_work_handler)(struct work_struct *work); ++ void (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba); + int complete_hdr_size; + struct scsi_host_template *sht; + }; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index b7cc4ef60169..edda95fe48d3 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1619,12 +1619,8 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) + } + EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done); + +-static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) ++static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba) + { +- struct device *dev = hisi_hba->dev; +- struct Scsi_Host *shost = hisi_hba->shost; +- int rc; +- + if (!hisi_hba->hw->soft_reset) + return -EINVAL; + +@@ -1634,6 +1630,18 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) + if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) + hisi_hba->hw->debugfs_work_handler(&hisi_hba->debugfs_work); + ++ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) ++ hisi_hba->hw->debugfs_snapshot_regs(hisi_hba); ++ ++ return 0; ++} ++ ++static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) ++{ ++ struct device *dev = hisi_hba->dev; ++ struct Scsi_Host *shost = hisi_hba->shost; ++ int rc; ++ + dev_info(dev, "controller resetting...\n"); + hisi_sas_controller_reset_prepare(hisi_hba); + +@@ -2545,6 +2553,9 @@ void hisi_sas_rst_work_handler(struct work_struct *work) + struct hisi_hba *hisi_hba = + container_of(work, struct hisi_hba, rst_work); + ++ if (hisi_sas_controller_prereset(hisi_hba)) ++ return; ++ + hisi_sas_controller_reset(hisi_hba); + } + EXPORT_SYMBOL_GPL(hisi_sas_rst_work_handler); +@@ -2554,8 +2565,12 @@ void hisi_sas_sync_rst_work_handler(struct work_struct *work) + struct hisi_sas_rst *rst = + container_of(work, struct hisi_sas_rst, work); + ++ if (hisi_sas_controller_prereset(rst->hisi_hba)) ++ goto rst_complete; ++ + if (!hisi_sas_controller_reset(rst->hisi_hba)) + rst->done = true; ++rst_complete: + complete(rst->completion); + } + EXPORT_SYMBOL_GPL(hisi_sas_sync_rst_work_handler); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 6f48312ee1d6..dfe2dba65dbd 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -587,6 +587,7 @@ MODULE_PARM_DESC(auto_affine_msi_experimental, "Enable auto-affinity of MSI IRQs + "default is off"); + + static void debugfs_work_handler_v3_hw(struct work_struct *work); ++static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba); + + static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) + { +@@ -3599,6 +3600,7 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = { + .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw, + .get_managed_irq_aff = get_managed_irq_aff_v3_hw, + .debugfs_work_handler = debugfs_work_handler_v3_hw, ++ .debugfs_snapshot_regs = debugfs_snapshot_regs_v3_hw, + }; + + static struct Scsi_Host * +@@ -4085,6 +4087,19 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) + + static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) + { ++ int debugfs_dump_index = hisi_hba->debugfs_dump_index; ++ struct device *dev = hisi_hba->dev; ++ u64 timestamp = local_clock(); ++ ++ if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { ++ dev_warn(dev, "dump count exceeded!\n"); ++ return; ++ } ++ ++ do_div(timestamp, NSEC_PER_MSEC); ++ hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; ++ hisi_hba->debugfs_dump_index++; ++ + debugfs_snapshot_prepare_v3_hw(hisi_hba); + + debugfs_snapshot_global_reg_v3_hw(hisi_hba); +@@ -4821,20 +4836,8 @@ static void debugfs_work_handler_v3_hw(struct work_struct *work) + { + struct hisi_hba *hisi_hba = + container_of(work, struct hisi_hba, debugfs_work); +- int debugfs_dump_index = hisi_hba->debugfs_dump_index; +- struct device *dev = hisi_hba->dev; +- u64 timestamp = local_clock(); +- +- if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { +- dev_warn(dev, "dump count exceeded!\n"); +- return; +- } +- +- do_div(timestamp, NSEC_PER_MSEC); +- hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; + + debugfs_snapshot_regs_v3_hw(hisi_hba); +- hisi_hba->debugfs_dump_index++; + } + + static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index) +-- +2.27.0 + diff --git a/patches/0723-scsi-hisi_sas-Warn-in-v3-hw-channel-interrupt-handle.patch b/patches/0723-scsi-hisi_sas-Warn-in-v3-hw-channel-interrupt-handle.patch new file mode 100644 index 0000000..4e86b37 --- /dev/null +++ b/patches/0723-scsi-hisi_sas-Warn-in-v3-hw-channel-interrupt-handle.patch @@ -0,0 +1,66 @@ +From fe6bf545050fcdedee0acfff0f9e4dfdd172e340 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:47:57 +0800 +Subject: [PATCH 075/108] scsi: hisi_sas: Warn in v3 hw channel interrupt + handler when status reg cleared + +mainline inclusion +from mainline-v5.13-rc1 +commit 2d31cb20a3cd611a9a544f9586eb3908ee2085cf +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2d31cb20a3cd611a9a544f9586eb3908ee2085cf + +---------------------------------------------------------------------- + +If a channel interrupt occurs without any status bit set, the handler will +return directly. However, if such redundant interrupts are received, it's +better to check what happen, so add logs for this. + +Link: https://lore.kernel.org/r/1617709711-195853-6-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: Yihang Li +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index dfe2dba65dbd..74aa794a70b4 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1877,8 +1877,11 @@ static void handle_chl_int1_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + int i; + + irq_value &= ~irq_msk; +- if (!irq_value) ++ if (!irq_value) { ++ dev_warn(dev, "phy%d channel int 1 received with status bits cleared\n", ++ phy_no); + return; ++ } + + for (i = 0; i < ARRAY_SIZE(port_axi_error); i++) { + const struct hisi_sas_hw_error *error = &port_axi_error[i]; +@@ -1906,8 +1909,11 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + BIT(CHL_INT2_RX_INVLD_DW_OFF); + + irq_value &= ~irq_msk; +- if (!irq_value) ++ if (!irq_value) { ++ dev_warn(dev, "phy%d channel int 2 received with status bits cleared\n", ++ phy_no); + return; ++ } + + if (irq_value & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) { + dev_warn(dev, "phy%d identify timeout\n", phy_no); +-- +2.27.0 + diff --git a/patches/0724-scsi-hisi_sas-Print-SATA-device-SAS-address-for-soft.patch b/patches/0724-scsi-hisi_sas-Print-SATA-device-SAS-address-for-soft.patch new file mode 100644 index 0000000..abac61b --- /dev/null +++ b/patches/0724-scsi-hisi_sas-Print-SATA-device-SAS-address-for-soft.patch @@ -0,0 +1,53 @@ +From 9513f66b00179c5daa0bbd60c15c461d6f8c9edc Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:47:58 +0800 +Subject: [PATCH 076/108] scsi: hisi_sas: Print SATA device SAS address for + soft reset failure + +mainline inclusion +from mainline-v5.13-rc1 +commit f4df167ad5a2274c12680ba3e7d816d32d1fc375 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f4df167ad5a2274c12680ba3e7d816d32d1fc375 + +---------------------------------------------------------------------- + +Add (pseudo) SAS address for ATA software reset failure log to assist in +debugging. + +Link: https://lore.kernel.org/r/1617709711-195853-7-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index edda95fe48d3..b9face46ec0f 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1376,10 +1376,12 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device) + rc = hisi_sas_exec_internal_tmf_task(device, &fis, + s, NULL); + if (rc != TMF_RESP_FUNC_COMPLETE) +- dev_err(dev, "ata disk de-reset failed\n"); ++ dev_err(dev, "ata disk %016llx de-reset failed\n", ++ SAS_ADDR(device->sas_addr)); + } + } else { +- dev_err(dev, "ata disk reset failed\n"); ++ dev_err(dev, "ata disk %016llx reset failed\n", ++ SAS_ADDR(device->sas_addr)); + } + + if (rc == TMF_RESP_FUNC_COMPLETE) +-- +2.27.0 + diff --git a/patches/0725-scsi-hisi_sas-Put-a-limit-of-link-reset-retries.patch b/patches/0725-scsi-hisi_sas-Put-a-limit-of-link-reset-retries.patch new file mode 100644 index 0000000..bf8e960 --- /dev/null +++ b/patches/0725-scsi-hisi_sas-Put-a-limit-of-link-reset-retries.patch @@ -0,0 +1,90 @@ +From 401a97e648e11cb20b472cb1388461a167930dd3 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:48:01 +0800 +Subject: [PATCH 077/108] scsi: hisi_sas: Put a limit of link reset retries + +mainline inclusion +from mainline-v5.14-rc1 +commit 366da0da1f5fe4e7e702f5864a557e57f485431f +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=366da0da1f5fe4e7e702f5864a557e57f485431f + +---------------------------------------------------------------------- + +If an OOB event is received but the phy still fails to come up, a link +reset will be issued repeatedly at an interval of 20s until the phy comes +up. + +Set a limit for link reset issue retries to avoid printing the timeout +message endlessly. + +Link: https://lore.kernel.org/r/1623058179-80434-2-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 + + drivers/scsi/hisi_sas/hisi_sas_main.c | 15 +++++++++++++-- + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 47e767fb0acf..cbcb8a1da74f 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -201,6 +201,7 @@ struct hisi_sas_phy { + enum sas_linkrate maximum_linkrate; + u32 code_error_count; + int enable; ++ int wait_phyup_cnt; + atomic_t down_cnt; + + /* Trace FIFO */ +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index b9face46ec0f..d0b5f8d84ad5 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -871,6 +871,7 @@ static void hisi_sas_phyup_work(struct work_struct *work) + struct asd_sas_phy *sas_phy = &phy->sas_phy; + int phy_no = sas_phy->id; + ++ phy->wait_phyup_cnt = 0; + if (phy->identify.target_port_protocols == SAS_PROTOCOL_SSP) + hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no); + hisi_sas_bytes_dmaed(hisi_hba, phy_no); +@@ -913,6 +914,8 @@ static void hisi_sas_wait_phyup_timedout(struct timer_list *t) + hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); + } + ++#define HISI_SAS_WAIT_PHYUP_RETRIES 10 ++ + void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no) + { + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; +@@ -923,8 +926,16 @@ void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no) + return; + + if (!timer_pending(&phy->timer)) { +- phy->timer.expires = jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT * HZ; +- add_timer(&phy->timer); ++ if (phy->wait_phyup_cnt < HISI_SAS_WAIT_PHYUP_RETRIES) { ++ phy->wait_phyup_cnt++; ++ phy->timer.expires = jiffies + ++ HISI_SAS_WAIT_PHYUP_TIMEOUT * HZ; ++ add_timer(&phy->timer); ++ } else { ++ dev_warn(dev, "phy%d failed to come up %d times, giving up\n", ++ phy_no, phy->wait_phyup_cnt); ++ phy->wait_phyup_cnt = 0; ++ } + } + } + EXPORT_SYMBOL_GPL(hisi_sas_phy_oob_ready); +-- +2.27.0 + diff --git a/patches/0726-scsi-hisi_sas-Run-I_T-nexus-resets-in-parallel-for-c.patch b/patches/0726-scsi-hisi_sas-Run-I_T-nexus-resets-in-parallel-for-c.patch new file mode 100644 index 0000000..86a6e55 --- /dev/null +++ b/patches/0726-scsi-hisi_sas-Run-I_T-nexus-resets-in-parallel-for-c.patch @@ -0,0 +1,98 @@ +From 022ef921e55a9e9d864d5a478cee8cec03bdd7b4 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:48:02 +0800 +Subject: [PATCH 078/108] scsi: hisi_sas: Run I_T nexus resets in parallel for + clear nexus reset + +mainline inclusion +from mainline-v5.14-rc1 +commit 0f757339919d31533aeadbbfd62f2dd4a49e851f +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0f757339919d31533aeadbbfd62f2dd4a49e851f + +---------------------------------------------------------------------- + +For a clear nexus reset operation, the I_T nexus resets are executed +serially for each device. For devices attached through an expander, this +may take 2s per device; so, in total, could take a long time. + +Reduce the total time by running the I_T nexus resets in parallel through +async operations. + +Link: https://lore.kernel.org/r/1623058179-80434-3-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 + + drivers/scsi/hisi_sas/hisi_sas_main.c | 23 +++++++++++++++++------ + 2 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index cbcb8a1da74f..6fd4ca989194 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -13,6 +13,7 @@ + #define _HISI_SAS_H_ + + #include ++#include + #include + #include + #include +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index d0b5f8d84ad5..4070ffe3af8c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1954,12 +1954,24 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun) + return rc; + } + ++static void hisi_sas_async_I_T_nexus_reset(void *data, async_cookie_t cookie) ++{ ++ struct domain_device *device = data; ++ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); ++ int rc; ++ ++ rc = hisi_sas_debug_I_T_nexus_reset(device); ++ if (rc != TMF_RESP_FUNC_COMPLETE) ++ dev_info(hisi_hba->dev, "I_T_nexus reset fail for dev:%016llx rc=%d\n", ++ SAS_ADDR(device->sas_addr), rc); ++} ++ + static int hisi_sas_clear_nexus_ha(struct sas_ha_struct *sas_ha) + { + struct hisi_hba *hisi_hba = sas_ha->lldd_ha; +- struct device *dev = hisi_hba->dev; + HISI_SAS_DECLARE_RST_WORK_ON_STACK(r); +- int rc, i; ++ ASYNC_DOMAIN_EXCLUSIVE(async); ++ int i; + + queue_work(hisi_hba->wq, &r.work); + wait_for_completion(r.completion); +@@ -1974,12 +1986,11 @@ static int hisi_sas_clear_nexus_ha(struct sas_ha_struct *sas_ha) + DEV_IS_EXPANDER(device->dev_type)) + continue; + +- rc = hisi_sas_debug_I_T_nexus_reset(device); +- if (rc != TMF_RESP_FUNC_COMPLETE) +- dev_info(dev, "clear nexus ha: for device[%d] rc=%d\n", +- sas_dev->device_id, rc); ++ async_schedule_domain(hisi_sas_async_I_T_nexus_reset, ++ device, &async); + } + ++ async_synchronize_full_domain(&async); + hisi_sas_release_tasks(hisi_hba); + + return TMF_RESP_FUNC_COMPLETE; +-- +2.27.0 + diff --git a/patches/0727-scsi-hisi_sas-Include-HZ-in-timer-macros.patch b/patches/0727-scsi-hisi_sas-Include-HZ-in-timer-macros.patch new file mode 100644 index 0000000..5c669ed --- /dev/null +++ b/patches/0727-scsi-hisi_sas-Include-HZ-in-timer-macros.patch @@ -0,0 +1,140 @@ +From 9ce4fa5b0a24b62d6e52b78f2375946b1b38f37d Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:48:03 +0800 +Subject: [PATCH 079/108] scsi: hisi_sas: Include HZ in timer macros + +mainline inclusion +from mainline-v5.14-rc1 +commit 2f12a499511f40c268d6dfa4bf7fbe2344d2e6d3 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2f12a499511f40c268d6dfa4bf7fbe2344d2e6d3 + +---------------------------------------------------------------------- + +Include HZ in timer macros to make the code more concise. + +Link: https://lore.kernel.org/r/1623058179-80434-4-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas.h + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas.h | 2 +- + drivers/scsi/hisi_sas/hisi_sas_main.c | 16 +++++++++------- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- + 4 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 6fd4ca989194..b959ec7bb5a1 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -100,7 +100,7 @@ + #define HISI_SAS_PROT_MASK (HISI_SAS_DIF_PROT_MASK | HISI_SAS_DIX_PROT_MASK) + + #define HISI_SAS_WAIT_PHYUP_TIMEOUT (30 * HZ) +-#define CLEAR_ITCT_TIMEOUT 20 ++#define HISI_SAS_CLEAR_ITCT_TIMEOUT (20 * HZ) + + struct hisi_hba; + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 4070ffe3af8c..281f03203f9f 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -929,7 +929,7 @@ void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no) + if (phy->wait_phyup_cnt < HISI_SAS_WAIT_PHYUP_RETRIES) { + phy->wait_phyup_cnt++; + phy->timer.expires = jiffies + +- HISI_SAS_WAIT_PHYUP_TIMEOUT * HZ; ++ HISI_SAS_WAIT_PHYUP_TIMEOUT; + add_timer(&phy->timer); + } else { + dev_warn(dev, "phy%d failed to come up %d times, giving up\n", +@@ -1227,9 +1227,9 @@ static void hisi_sas_tmf_timedout(struct timer_list *t) + complete(&task->slow_task->completion); + } + +-#define TASK_TIMEOUT 20 +-#define TASK_RETRY 3 +-#define INTERNAL_ABORT_TIMEOUT 6 ++#define TASK_TIMEOUT (20 * HZ) ++#define TASK_RETRY 3 ++#define INTERNAL_ABORT_TIMEOUT (6 * HZ) + static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, + void *parameter, u32 para_len, + struct hisi_sas_tmf_task *tmf) +@@ -1257,7 +1257,7 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, + task->task_done = hisi_sas_task_done; + + task->slow_task->timer.function = hisi_sas_tmf_timedout; +- task->slow_task->timer.expires = jiffies + TASK_TIMEOUT * HZ; ++ task->slow_task->timer.expires = jiffies + TASK_TIMEOUT; + add_timer(&task->slow_task->timer); + + res = hisi_sas_task_exec(task, GFP_KERNEL, 1, tmf); +@@ -1825,6 +1825,8 @@ static int hisi_sas_clear_aca(struct domain_device *device, u8 *lun) + return rc; + } + ++#define I_T_NEXUS_RESET_PHYUP_TIMEOUT (2 * HZ) ++ + static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) + { + struct sas_phy *local_phy = sas_get_local_phy(device); +@@ -1860,7 +1862,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) + container_of(sas_phy, struct hisi_sas_phy, sas_phy); + /* Wait for I_T reset complete, time out after 2s */ + int ret = wait_for_completion_timeout(&phyreset, +- HISI_SAS_WAIT_PHYUP_TIMEOUT); ++ I_T_NEXUS_RESET_PHYUP_TIMEOUT); + unsigned long flags; + + spin_lock_irqsave(&phy->lock, flags); +@@ -2148,7 +2150,7 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + task->task_proto = device->tproto; + task->task_done = hisi_sas_task_done; + task->slow_task->timer.function = hisi_sas_tmf_timedout; +- task->slow_task->timer.expires = jiffies + INTERNAL_ABORT_TIMEOUT * HZ; ++ task->slow_task->timer.expires = jiffies + INTERNAL_ABORT_TIMEOUT; + add_timer(&task->slow_task->timer); + + res = hisi_sas_internal_abort_task_exec(hisi_hba, sas_dev->device_id, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index 078404d2754a..46a0a321ff54 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -1000,7 +1000,7 @@ static int clear_itct_v2_hw(struct hisi_hba *hisi_hba, + reg_val = ITCT_CLR_EN_MSK | (dev_id & ITCT_DEV_MSK); + hisi_sas_write32(hisi_hba, ITCT_CLR, reg_val); + if (!wait_for_completion_timeout(sas_dev->completion, +- CLEAR_ITCT_TIMEOUT * HZ)) { ++ HISI_SAS_CLEAR_ITCT_TIMEOUT)) { + dev_warn(dev, "failed to clear ITCT\n"); + return -ETIMEDOUT; + } +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 74aa794a70b4..d12194d04a1e 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -939,7 +939,7 @@ static int clear_itct_v3_hw(struct hisi_hba *hisi_hba, + hisi_sas_write32(hisi_hba, ITCT_CLR, reg_val); + + if (!wait_for_completion_timeout(sas_dev->completion, +- CLEAR_ITCT_TIMEOUT * HZ)) { ++ HISI_SAS_CLEAR_ITCT_TIMEOUT)) { + dev_warn(dev, "failed to clear ITCT\n"); + return -ETIMEDOUT; + } +-- +2.27.0 + diff --git a/patches/0728-scsi-hisi_sas-Reset-controller-for-internal-abort-ti.patch b/patches/0728-scsi-hisi_sas-Reset-controller-for-internal-abort-ti.patch new file mode 100644 index 0000000..62cf57b --- /dev/null +++ b/patches/0728-scsi-hisi_sas-Reset-controller-for-internal-abort-ti.patch @@ -0,0 +1,194 @@ +From b8f5de9b6ec83c7aa33e502b3329f3fcb8df053e Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:48:04 +0800 +Subject: [PATCH 080/108] scsi: hisi_sas: Reset controller for internal abort + timeout + +mainline inclusion +from mainline-v5.14-rc1 +commit 63ece9eb350312ee33327269480482dfac8555db +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=63ece9eb350312ee33327269480482dfac8555db + +---------------------------------------------------------------------- + +If an internal task abort timeout occurs, the controller has developed a +fault, and needs to be reset to be recovered. However if a timeout occurs +during SCSI error handling, issuing a controller reset immediately may +conflict with the error handling. + +To handle internal abort in these two scenarios, only queue the reset when +not in an error handling function. In the case of a timeout during error +handling, do nothing and rely on the inevitable ha nexus reset to reset the +controller. + +Link: https://lore.kernel.org/r/1623058179-80434-5-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 45 ++++++++++++++++++--------- + 1 file changed, 30 insertions(+), 15 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 281f03203f9f..434d8187e55c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -20,7 +20,7 @@ static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device, + static int + hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + struct domain_device *device, +- int abort_flag, int tag); ++ int abort_flag, int tag, bool rst_to_recover); + static int hisi_sas_softreset_ata_disk(struct domain_device *device); + static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, + void *funcdata); +@@ -1097,7 +1097,7 @@ static void hisi_sas_dev_gone(struct domain_device *device) + down(&hisi_hba->sem); + if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) { + rc0 = hisi_sas_internal_task_abort(hisi_hba, device, +- HISI_SAS_INT_ABT_DEV, 0); ++ HISI_SAS_INT_ABT_DEV, 0, true); + + hisi_sas_dereg_device(hisi_hba, device); + if (!list_empty(&sas_dev->list)) { +@@ -1564,7 +1564,8 @@ static void hisi_sas_terminate_stp_reject(struct hisi_hba *hisi_hba) + continue; + + rc = hisi_sas_internal_task_abort(hisi_hba, device, +- HISI_SAS_INT_ABT_DEV, 0); ++ HISI_SAS_INT_ABT_DEV, 0, ++ false); + if (rc < 0) + dev_err(dev, "STP reject: abort dev failed %d\n", rc); + } +@@ -1724,7 +1725,8 @@ static int hisi_sas_abort_task(struct sas_task *task) + &tmf_task); + + rc2 = hisi_sas_internal_task_abort(hisi_hba, device, +- HISI_SAS_INT_ABT_CMD, tag); ++ HISI_SAS_INT_ABT_CMD, tag, ++ false); + if (rc2 < 0) { + dev_err(dev, "abort task: internal abort (%d)\n", rc2); + return TMF_RESP_FUNC_FAILED; +@@ -1747,7 +1749,8 @@ static int hisi_sas_abort_task(struct sas_task *task) + struct ata_queued_cmd *qc = task->uldd_task; + + rc = hisi_sas_internal_task_abort(hisi_hba, device, +- HISI_SAS_INT_ABT_DEV, 0); ++ HISI_SAS_INT_ABT_DEV, ++ 0, false); + if (rc < 0) { + dev_err(dev, "abort task: internal abort failed\n"); + goto out; +@@ -1772,7 +1775,8 @@ static int hisi_sas_abort_task(struct sas_task *task) + struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue]; + + rc = hisi_sas_internal_task_abort(hisi_hba, device, +- HISI_SAS_INT_ABT_CMD, tag); ++ HISI_SAS_INT_ABT_CMD, tag, ++ false); + if (((rc < 0) || (rc == TMF_RESP_FUNC_FAILED)) && + task->lldd_task) { + /* +@@ -1798,7 +1802,7 @@ static int hisi_sas_abort_task_set(struct domain_device *device, u8 *lun) + int rc; + + rc = hisi_sas_internal_task_abort(hisi_hba, device, +- HISI_SAS_INT_ABT_DEV, 0); ++ HISI_SAS_INT_ABT_DEV, 0, false); + if (rc < 0) { + dev_err(dev, "abort task set: internal abort rc=%d\n", rc); + return TMF_RESP_FUNC_FAILED; +@@ -1894,7 +1898,7 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device) + sas_dev->dev_status = HISI_SAS_DEV_NORMAL; + + rc = hisi_sas_internal_task_abort(hisi_hba, device, +- HISI_SAS_INT_ABT_DEV, 0); ++ HISI_SAS_INT_ABT_DEV, 0, false); + if (rc < 0) { + dev_err(dev, "I_T nexus reset: internal abort (%d)\n", rc); + return TMF_RESP_FUNC_FAILED; +@@ -1925,7 +1929,7 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun) + + /* Clear internal IO and then lu reset */ + rc = hisi_sas_internal_task_abort(hisi_hba, device, +- HISI_SAS_INT_ABT_DEV, 0); ++ HISI_SAS_INT_ABT_DEV, 0, false); + if (rc < 0) { + dev_err(dev, "lu_reset: internal abort failed\n"); + goto out; +@@ -2122,11 +2126,14 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, + * @tag: tag of IO to be aborted (only relevant to single + * IO mode) + * @dq: delivery queue for this internal abort command ++ * @rst_to_recover: If rst_to_recover set, queue a controller ++ * reset if an internal abort times out. + */ + static int + _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, +- struct domain_device *device, +- int abort_flag, int tag, struct hisi_sas_dq *dq) ++ struct domain_device *device, int abort_flag, ++ int tag, struct hisi_sas_dq *dq, ++ bool rst_to_recover) + { + struct sas_task *task; + struct hisi_sas_device *sas_dev = device->lldd_dev; +@@ -2182,7 +2189,13 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + synchronize_irq(cq->irq_no); + slot->task = NULL; + } +- dev_err(dev, "internal task abort: timeout and not done.\n"); ++ ++ if (rst_to_recover) { ++ dev_err(dev, "internal task abort: timeout and not done. Queuing reset.\n"); ++ queue_work(hisi_hba->wq, &hisi_hba->rst_work); ++ } else { ++ dev_err(dev, "internal task abort: timeout and not done.\n"); ++ } + + res = -EIO; + goto exit; +@@ -2215,7 +2228,7 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + static int + hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + struct domain_device *device, +- int abort_flag, int tag) ++ int abort_flag, int tag, bool rst_to_recover) + { + struct hisi_sas_slot *slot; + struct device *dev = hisi_hba->dev; +@@ -2227,7 +2240,8 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + slot = &hisi_hba->slot_info[tag]; + dq = &hisi_hba->dq[slot->dlvry_queue]; + return _hisi_sas_internal_task_abort(hisi_hba, device, +- abort_flag, tag, dq); ++ abort_flag, tag, dq, ++ rst_to_recover); + case HISI_SAS_INT_ABT_DEV: + for (i = 0; i < hisi_hba->nvecs; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; +@@ -2245,7 +2259,8 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + continue; + dq = &hisi_hba->dq[i]; + rc = _hisi_sas_internal_task_abort(hisi_hba, device, +- abort_flag, tag, dq); ++ abort_flag, tag, ++ dq, rst_to_recover); + if (rc) + return rc; + } +-- +2.27.0 + diff --git a/patches/0729-scsi-hisi_sas-Speed-up-error-handling-when-internal-.patch b/patches/0729-scsi-hisi_sas-Speed-up-error-handling-when-internal-.patch new file mode 100644 index 0000000..5a8aaa7 --- /dev/null +++ b/patches/0729-scsi-hisi_sas-Speed-up-error-handling-when-internal-.patch @@ -0,0 +1,90 @@ +From 9435ad6f67a4242190f661802f0686fccd7e08c4 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing +Date: Tue, 3 Aug 2021 14:48:05 +0800 +Subject: [PATCH 081/108] scsi: hisi_sas: Speed up error handling when internal + abort timeout occurs + +mainline inclusion +from mainline-v5.14-rc1 +commit e8a4d0daaef6fc8f965ca0b8e9585aa9698a0f24 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e8a4d0daaef6fc8f965ca0b8e9585aa9698a0f24 + +---------------------------------------------------------------------- + +If an internal task abort timeout occurs, the controller has developed a +fault, and needs to be reset to be recovered. + +When this occurs during error handling, the current policy is to allow +error handling to continue, and the inevitable nexus ha reset will handle +the required reset. + +However various steps of error handling need to taken before this happens. +These also involve some level of HW interaction, which will also fail with +various timeouts. + +Speed up this process by recording a HW fault bit for an internal abort +timeout - when this is set, just automatically error any HW interaction, +and essentially go straight to clear nexus ha (to reset the controller). + +Link: https://lore.kernel.org/r/1623058179-80434-6-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 + + drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ++++++ + 2 files changed, 7 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index b959ec7bb5a1..d381dfda8f99 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -41,6 +41,7 @@ + #define HISI_SAS_RESET_BIT 0 + #define HISI_SAS_REJECT_CMD_BIT 1 + #define HISI_SAS_PM_BIT 2 ++#define HISI_SAS_HW_FAULT_BIT 3 + #define HISI_SAS_MAX_COMMANDS (HISI_SAS_QUEUE_SLOTS) + #define HISI_SAS_RESERVED_IPTT 96 + #define HISI_SAS_UNRESERVED_IPTT \ +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 434d8187e55c..b56778a1402a 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1670,6 +1670,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) + } + + hisi_sas_controller_reset_done(hisi_hba); ++ clear_bit(HISI_SAS_HW_FAULT_BIT, &hisi_hba->flags); + dev_info(dev, "controller reset complete\n"); + + return 0; +@@ -2149,6 +2150,9 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + if (!hisi_hba->hw->prep_abort) + return TMF_RESP_FUNC_FAILED; + ++ if (test_bit(HISI_SAS_HW_FAULT_BIT, &hisi_hba->flags)) ++ return -EIO; ++ + task = sas_alloc_slow_task(GFP_KERNEL); + if (!task) + return -ENOMEM; +@@ -2179,6 +2183,8 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { + struct hisi_sas_slot *slot = task->lldd_task; + ++ set_bit(HISI_SAS_HW_FAULT_BIT, &hisi_hba->flags); ++ + if (slot) { + struct hisi_sas_cq *cq = + &hisi_hba->cq[slot->dlvry_queue]; +-- +2.27.0 + diff --git a/patches/0730-scsi-hisi_sas-Initialise-devices-in-.slave_alloc-cal.patch b/patches/0730-scsi-hisi_sas-Initialise-devices-in-.slave_alloc-cal.patch new file mode 100644 index 0000000..f3490ee --- /dev/null +++ b/patches/0730-scsi-hisi_sas-Initialise-devices-in-.slave_alloc-cal.patch @@ -0,0 +1,127 @@ +From 53a0b5245e3afc807fcc6985a4f3fb54b319794e Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Tue, 19 Apr 2022 17:06:51 +0800 +Subject: [PATCH 082/108] scsi: hisi_sas: Initialise devices in .slave_alloc + callback + +mainline inclusion +from mainline-v5.16-rc1 +commit 36c6b7613ef1ffd88637315f11c71896f3ce4856 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F803 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=36c6b7613ef1ffd88637315f11c71896f3ce4856 + +---------------------------------------------------------------------- + +Perform driver-specific SCSI device initialization in the designated SCSI +midlayer callback instead of relying on the libsas "device found" callback. + +The SCSI midlayer .slave_alloc interface is called prior to sending any I/O +to the device. + +Link: https://lore.kernel.org/r/1634041588-74824-2-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: Fujai Ni +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 + + drivers/scsi/hisi_sas/hisi_sas_main.c | 17 ++++++++++++++--- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- + 5 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index d381dfda8f99..d403d6855ed6 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -683,6 +683,7 @@ extern int hisi_sas_probe(struct platform_device *pdev, + extern int hisi_sas_remove(struct platform_device *pdev); + + extern int hisi_sas_slave_configure(struct scsi_device *sdev); ++extern int hisi_sas_slave_alloc(struct scsi_device *sdev); + extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time); + extern void hisi_sas_scan_start(struct Scsi_Host *shost); + extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index b56778a1402a..749bc5498530 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -764,6 +764,20 @@ static int hisi_sas_init_device(struct domain_device *device) + return rc; + } + ++int hisi_sas_slave_alloc(struct scsi_device *sdev) ++{ ++ struct domain_device *ddev; ++ int rc; ++ ++ rc = sas_slave_alloc(sdev); ++ if (rc) ++ return rc; ++ ddev = sdev_to_domain_dev(sdev); ++ ++ return hisi_sas_init_device(ddev); ++} ++EXPORT_SYMBOL_GPL(hisi_sas_slave_alloc); ++ + static int hisi_sas_dev_found(struct domain_device *device) + { + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); +@@ -810,9 +824,6 @@ static int hisi_sas_dev_found(struct domain_device *device) + dev_info(dev, "dev[%d:%x] found\n", + sas_dev->device_id, sas_dev->dev_type); + +- rc = hisi_sas_init_device(device); +- if (rc) +- goto err_out; + sas_dev->dev_status = HISI_SAS_DEV_NORMAL; + return 0; + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index c82abcf2567c..540ca255d65e 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1772,7 +1772,7 @@ static struct scsi_host_template sht_v1_hw = { + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler = sas_eh_device_reset_handler, + .eh_target_reset_handler = sas_eh_target_reset_handler, +- .slave_alloc = sas_slave_alloc, ++ .slave_alloc = hisi_sas_slave_alloc, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, + .shost_attrs = host_attrs_v1_hw, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index 46a0a321ff54..f9381df36cfa 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3562,7 +3562,7 @@ static struct scsi_host_template sht_v2_hw = { + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler = sas_eh_device_reset_handler, + .eh_target_reset_handler = sas_eh_target_reset_handler, +- .slave_alloc = sas_slave_alloc, ++ .slave_alloc = hisi_sas_slave_alloc, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, + .shost_attrs = host_attrs_v2_hw, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index d12194d04a1e..33882a4ef00a 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3573,7 +3573,7 @@ static struct scsi_host_template sht_v3_hw = { + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler = sas_eh_device_reset_handler, + .eh_target_reset_handler = sas_eh_target_reset_handler, +- .slave_alloc = sas_slave_alloc, ++ .slave_alloc = hisi_sas_slave_alloc, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, + .shost_attrs = host_attrs_v3_hw, +-- +2.27.0 + diff --git a/patches/0731-scsi-hisi_sas-Wait-for-phyup-in-hisi_sas_control_phy.patch b/patches/0731-scsi-hisi_sas-Wait-for-phyup-in-hisi_sas_control_phy.patch new file mode 100644 index 0000000..b6474fe --- /dev/null +++ b/patches/0731-scsi-hisi_sas-Wait-for-phyup-in-hisi_sas_control_phy.patch @@ -0,0 +1,265 @@ +From f594a4bb5169a6d2a35d273a58d2a6c657dc3f2f Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Tue, 19 Apr 2022 17:06:52 +0800 +Subject: [PATCH 083/108] scsi: hisi_sas: Wait for phyup in + hisi_sas_control_phy() + +mainline inclusion +from mainline-v5.16-rc1 +commit 046ab7d0f5943dd74c351e1f3a771dea785fe25d +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F803 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=046ab7d0f5943dd74c351e1f3a771dea785fe25d + +---------------------------------------------------------------------- + +When issuing a hardreset/linkreset/phy_set_linkrate from sysfs, the phy +will be disabled and re-enabled for the directly attached scenario. + +It takes some time for the phy to come back up after re-enabling the phy. +If the controller becomes suspended while waiting for the phy to come back, +the phy up may be lost (along with the disk). + +To solve this problem, wait for the phy up to occur with a timeout. Indeed +this is already done in hisi_sas_debug_I_T_nexus_reset() for local phys, so +just relocate the functionality to hisi_sas_control_phy(). + +Since the HA workqueue is drained when suspending the controller, and the +phy control function is called from the same workqueue, we can guarantee +that the controller will not be suspended during this period. + +Link: https://lore.kernel.org/r/1634041588-74824-3-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: Fujai Ni +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 44 +++++++++++++++++++------- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 11 ++----- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 17 ++-------- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 9 ++---- + 4 files changed, 39 insertions(+), 42 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 749bc5498530..40bf4b6e30d4 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1179,9 +1179,17 @@ static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, + static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, + void *funcdata) + { ++ struct hisi_sas_phy *phy = container_of(sas_phy, ++ struct hisi_sas_phy, sas_phy); + struct sas_ha_struct *sas_ha = sas_phy->ha; + struct hisi_hba *hisi_hba = sas_ha->lldd_ha; ++ struct device *dev = hisi_hba->dev; ++ DECLARE_COMPLETION_ONSTACK(completion); + int phy_no = sas_phy->id; ++ u8 sts = phy->phy_attached; ++ int ret = 0; ++ ++ phy->reset_completion = &completion; + + switch (func) { + case PHY_FUNC_HARD_RESET: +@@ -1197,21 +1205,35 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, + + case PHY_FUNC_DISABLE: + hisi_sas_phy_enable(hisi_hba, phy_no, 0); +- break; ++ goto out; + + case PHY_FUNC_SET_LINK_RATE: +- return hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata); ++ ret = hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata); ++ break; ++ + case PHY_FUNC_GET_EVENTS: + if (hisi_hba->hw->get_events) { + hisi_hba->hw->get_events(hisi_hba, phy_no); +- break; ++ goto out; + } + /* fallthru */ + case PHY_FUNC_RELEASE_SPINUP_HOLD: + default: +- return -EOPNOTSUPP; ++ ret = -EOPNOTSUPP; ++ goto out; + } +- return 0; ++ ++ if (sts && !wait_for_completion_timeout(&completion, 2 * HZ)) { ++ dev_warn(dev, "phy%d wait phyup timed out for func %d\n", ++ phy_no, func); ++ if (phy->in_reset) ++ ret = -ETIMEDOUT; ++ } ++ ++out: ++ phy->reset_completion = NULL; ++ ++ return ret; + } + + static void hisi_sas_task_done(struct sas_task *task) +@@ -1852,7 +1874,6 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct device *dev = hisi_hba->dev; + struct sas_ha_struct *sas_ha = &hisi_hba->sha; +- DECLARE_COMPLETION_ONSTACK(phyreset); + + if (!local_phy->enabled) { + sas_put_local_phy(local_phy); +@@ -1864,8 +1885,11 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) + sas_ha->sas_phy[local_phy->number]; + struct hisi_sas_phy *phy = + container_of(sas_phy, struct hisi_sas_phy, sas_phy); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&phy->lock, flags); + phy->in_reset = 1; +- phy->reset_completion = &phyreset; ++ spin_unlock_irqrestore(&phy->lock, flags); + } + + rc = sas_phy_reset(local_phy, reset_type); +@@ -1876,18 +1900,14 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) + sas_ha->sas_phy[local_phy->number]; + struct hisi_sas_phy *phy = + container_of(sas_phy, struct hisi_sas_phy, sas_phy); +- /* Wait for I_T reset complete, time out after 2s */ +- int ret = wait_for_completion_timeout(&phyreset, +- I_T_NEXUS_RESET_PHYUP_TIMEOUT); + unsigned long flags; + + spin_lock_irqsave(&phy->lock, flags); +- phy->reset_completion = NULL; + phy->in_reset = 0; + spin_unlock_irqrestore(&phy->lock, flags); + + /* report PHY down if timed out */ +- if (!ret) { ++ if (rc == -ETIMEDOUT) { + dev_warn(dev, "phy%d reset timeout\n", sas_phy->id); + hisi_sas_phy_down(hisi_hba, sas_phy->id, 0); + } +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +index 540ca255d65e..5c79e9962022 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1331,7 +1331,6 @@ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) + u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd; + struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd; + irqreturn_t res = IRQ_HANDLED; +- unsigned long flags; + + irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2); + if (!(irq_value & CHL_INT2_SL_PHY_ENA_MSK)) { +@@ -1384,15 +1383,9 @@ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) + phy->identify.target_port_protocols = + SAS_PROTOCOL_SMP; + hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); +- +- spin_lock_irqsave(&phy->lock, flags); +- if (phy->reset_completion) { +- phy->in_reset = 0; +- complete(phy->reset_completion); +- } +- spin_unlock_irqrestore(&phy->lock, flags); +- + end: ++ if (phy->reset_completion) ++ complete(phy->reset_completion); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, + CHL_INT2_SL_PHY_ENA_MSK); + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +index f9381df36cfa..af330b313aed 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -2662,7 +2662,6 @@ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) + struct device *dev = hisi_hba->dev; + u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd; + struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd; +- unsigned long flags; + + hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); + +@@ -2717,14 +2716,9 @@ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) + set_link_timer_quirk(hisi_hba); + } + hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); +- spin_lock_irqsave(&phy->lock, flags); +- if (phy->reset_completion) { +- phy->in_reset = 0; +- complete(phy->reset_completion); +- } +- spin_unlock_irqrestore(&phy->lock, flags); +- + end: ++ if (phy->reset_completion) ++ complete(phy->reset_completion); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, + CHL_INT0_SL_PHY_ENABLE_MSK); + hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0); +@@ -3218,7 +3212,6 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p) + u32 ent_tmp, ent_msk, ent_int, port_id, link_rate, hard_phy_linkrate; + irqreturn_t res = IRQ_HANDLED; + u8 attached_sas_addr[SAS_ADDR_SIZE] = {0}; +- unsigned long flags; + int phy_no, offset; + + del_timer(&phy->timer); +@@ -3294,12 +3287,8 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p) + phy->identify.target_port_protocols = SAS_PROTOCOL_SATA; + hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); + +- spin_lock_irqsave(&phy->lock, flags); +- if (phy->reset_completion) { +- phy->in_reset = 0; ++ if (phy->reset_completion) + complete(phy->reset_completion); +- } +- spin_unlock_irqrestore(&phy->lock, flags); + end: + hisi_sas_write32(hisi_hba, ENT_INT_SRC1 + offset, ent_tmp); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1 + offset, ent_msk); +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 33882a4ef00a..04d2c8a54633 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1636,7 +1636,6 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct device *dev = hisi_hba->dev; +- unsigned long flags; + + del_timer(&phy->timer); + hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); +@@ -1721,13 +1720,9 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + phy->phy_attached = 1; + hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); + res = IRQ_HANDLED; +- spin_lock_irqsave(&phy->lock, flags); +- if (phy->reset_completion) { +- phy->in_reset = 0; +- complete(phy->reset_completion); +- } +- spin_unlock_irqrestore(&phy->lock, flags); + end: ++ if (phy->reset_completion) ++ complete(phy->reset_completion); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, + CHL_INT0_SL_PHY_ENABLE_MSK); + hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0); +-- +2.27.0 + diff --git a/patches/0732-scsi-hisi_sas-Add-more-logs-for-runtime-suspend-resu.patch b/patches/0732-scsi-hisi_sas-Add-more-logs-for-runtime-suspend-resu.patch new file mode 100644 index 0000000..707382a --- /dev/null +++ b/patches/0732-scsi-hisi_sas-Add-more-logs-for-runtime-suspend-resu.patch @@ -0,0 +1,68 @@ +From 31528afff33d3511b7e14442e59969e7b0a56521 Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Tue, 19 Apr 2022 17:07:00 +0800 +Subject: [PATCH 084/108] scsi: hisi_sas: Add more logs for runtime + suspend/resume + +mainline inclusion +from mainline-v5.17-rc1 +commit 97f4100939844a6381ba61b99d6d2b1f2fccb79f +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F803 +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=97f4100939844a6381ba61b99d6d2b1f2fccb79f + +---------------------------------------------------------------------- + +Add some logs at the beginning and end of suspend/resume. + +Link: https://lore.kernel.org/r/1639999298-244569-9-git-send-email-chenxiang66@hisilicon.com +Acked-by: John Garry +Signed-off-by: Xiang Chen +Signed-off-by: Martin K. Petersen +Signed-off-by: Fujai Ni +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 04d2c8a54633..ca0b76e6088c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -5309,6 +5309,8 @@ static int _suspend_v3_hw(struct device *device) + if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + return -EPERM; + ++ dev_warn(dev, "entering suspend state\n"); ++ + scsi_block_requests(shost); + set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + flush_workqueue(hisi_hba->wq); +@@ -5334,6 +5336,8 @@ static int _suspend_v3_hw(struct device *device) + hisi_sas_release_tasks(hisi_hba); + + sas_suspend_ha(sha); ++ ++ dev_warn(dev, "end of suspending controller\n"); + return 0; + } + +@@ -5373,6 +5377,8 @@ static int _resume_v3_hw(struct device *device) + sas_resume_ha(sha); + clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + ++ dev_warn(dev, "end of resuming controller\n"); ++ + return 0; + } + +-- +2.27.0 + diff --git a/patches/0733-scsi-hisi_sas-Keep-controller-active-between-ISR-of-.patch b/patches/0733-scsi-hisi_sas-Keep-controller-active-between-ISR-of-.patch new file mode 100644 index 0000000..31c9cc8 --- /dev/null +++ b/patches/0733-scsi-hisi_sas-Keep-controller-active-between-ISR-of-.patch @@ -0,0 +1,121 @@ +From ea4831c2b52ae9468a59af459f78b873058a17bb Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Tue, 19 Apr 2022 17:07:05 +0800 +Subject: [PATCH 085/108] scsi: hisi_sas: Keep controller active between ISR of + phyup and the event being processed + +mainline inclusion +from mainline-v5.17-rc1 +commit ae9b69e85eb7ecb32ddce7c04a10a3c69ad60e52 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F803 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ae9b69e85eb7ecb32ddce7c04a10a3c69ad60e52 + +---------------------------------------------------------------------- + +It is possible that controller may become suspended between processing a +phyup interrupt and the event being processed by libsas. As such, we can't +ensure the controller is active when processing the phyup event - this may +cause the phyup event to be lost or other issues. To avoid any possible +issues, add pm_runtime_get_noresume() in phyup interrupt handler and +pm_runtime_put_sync() in the work handler exit to ensure that we stay +always active. Since we only want to call pm_runtime_get_noresume() for v3 +hw, signal this will a new event, HISI_PHYE_PHY_UP_PM. + +Link: https://lore.kernel.org/r/1639999298-244569-14-git-send-email-chenxiang66@hisilicon.com +Acked-by: John Garry +Signed-off-by: Xiang Chen +Signed-off-by: Martin K. Petersen +Signed-off-by: Fujai Ni +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 + + drivers/scsi/hisi_sas/hisi_sas_main.c | 22 ++++++++++++++++++++-- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 +++- + 3 files changed, 24 insertions(+), 3 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index d403d6855ed6..003b8c9b86bb 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -169,6 +169,7 @@ enum hisi_sas_bit_err_type { + enum hisi_sas_phy_event { + HISI_PHYE_PHY_UP = 0U, + HISI_PHYE_LINK_RESET, ++ HISI_PHYE_PHY_UP_PM, + HISI_PHYES_NUM, + }; + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 40bf4b6e30d4..77188195d198 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -874,10 +874,11 @@ int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time) + } + EXPORT_SYMBOL_GPL(hisi_sas_scan_finished); + +-static void hisi_sas_phyup_work(struct work_struct *work) ++static void hisi_sas_phyup_work_common(struct work_struct *work, ++ enum hisi_sas_phy_event event) + { + struct hisi_sas_phy *phy = +- container_of(work, typeof(*phy), works[HISI_PHYE_PHY_UP]); ++ container_of(work, typeof(*phy), works[event]); + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + int phy_no = sas_phy->id; +@@ -888,6 +889,11 @@ static void hisi_sas_phyup_work(struct work_struct *work) + hisi_sas_bytes_dmaed(hisi_hba, phy_no); + } + ++static void hisi_sas_phyup_work(struct work_struct *work) ++{ ++ hisi_sas_phyup_work_common(work, HISI_PHYE_PHY_UP); ++} ++ + static void hisi_sas_linkreset_work(struct work_struct *work) + { + struct hisi_sas_phy *phy = +@@ -897,9 +903,21 @@ static void hisi_sas_linkreset_work(struct work_struct *work) + hisi_sas_control_phy(sas_phy, PHY_FUNC_LINK_RESET, NULL); + } + ++static void hisi_sas_phyup_pm_work(struct work_struct *work) ++{ ++ struct hisi_sas_phy *phy = ++ container_of(work, typeof(*phy), works[HISI_PHYE_PHY_UP_PM]); ++ struct hisi_hba *hisi_hba = phy->hisi_hba; ++ struct device *dev = hisi_hba->dev; ++ ++ hisi_sas_phyup_work_common(work, HISI_PHYE_PHY_UP_PM); ++ pm_runtime_put_sync(dev); ++} ++ + static const work_func_t hisi_sas_phye_fns[HISI_PHYES_NUM] = { + [HISI_PHYE_PHY_UP] = hisi_sas_phyup_work, + [HISI_PHYE_LINK_RESET] = hisi_sas_linkreset_work, ++ [HISI_PHYE_PHY_UP_PM] = hisi_sas_phyup_pm_work, + }; + + bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy, +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index ca0b76e6088c..dc076d1f7bb0 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1718,7 +1718,9 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + + phy->port_id = port_id; + phy->phy_attached = 1; +- hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); ++ /* Call pm_runtime_put_sync() with pairs in hisi_sas_phyup_pm_work() */ ++ pm_runtime_get_noresume(dev); ++ hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP_PM); + res = IRQ_HANDLED; + end: + if (phy->reset_completion) +-- +2.27.0 + diff --git a/patches/0734-scsi-hisi_sas-Use-autosuspend-for-the-host-controlle.patch b/patches/0734-scsi-hisi_sas-Use-autosuspend-for-the-host-controlle.patch new file mode 100644 index 0000000..97755a3 --- /dev/null +++ b/patches/0734-scsi-hisi_sas-Use-autosuspend-for-the-host-controlle.patch @@ -0,0 +1,50 @@ +From e0aa96e89959951337e26802422de18a95a158b6 Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Tue, 19 Apr 2022 17:07:07 +0800 +Subject: [PATCH 086/108] scsi: hisi_sas: Use autosuspend for the host + controller + +mainline inclusion +from mainline-v5.17-rc1 +commit b4cc09492263e07bad4fc4bf34fed3246fa95057 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F803 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b4cc09492263e07bad4fc4bf34fed3246fa95057 + +---------------------------------------------------------------------- + +The controller may frequently enter and exit suspend for each I/O which we +need to deal with. This is inefficient and may cause too much suspend and +resume activity for the controller. To avoid this, use a default 5s +autosuspend for the controller to stop frequently suspending and +resuming. This value may still be modified via sysfs interfaces. + +Link: https://lore.kernel.org/r/1639999298-244569-16-git-send-email-chenxiang66@hisilicon.com +Acked-by: John Garry +Signed-off-by: Xiang Chen +Signed-off-by: Martin K. Petersen +Signed-off-by: Fujai Ni +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index dc076d1f7bb0..17b078abe2a8 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -5182,6 +5182,8 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + scsi_scan_host(shost); + ++ pm_runtime_set_autosuspend_delay(dev, 5000); ++ pm_runtime_use_autosuspend(dev); + /* + * For the situation that there are ATA disks connected with SAS + * controller, it additionally creates ata_port which will affect the +-- +2.27.0 + diff --git a/patches/0735-scsi-hisi_sas-Limit-users-changing-debugfs-BIST-coun.patch b/patches/0735-scsi-hisi_sas-Limit-users-changing-debugfs-BIST-coun.patch new file mode 100644 index 0000000..a6b400a --- /dev/null +++ b/patches/0735-scsi-hisi_sas-Limit-users-changing-debugfs-BIST-coun.patch @@ -0,0 +1,109 @@ +From 410d1a5b83b161dc189e6df90cbfa4cdeb016b8d Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Thu, 21 Apr 2022 21:50:06 +0800 +Subject: [PATCH 087/108] scsi: hisi_sas: Limit users changing debugfs BIST + count value + +mainline inclusion +from mainline-v5.17-rc1 +commit ae9b69e85eb7ecb32ddce7c04a10a3c69ad60e52 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ae9b69e85eb7ecb32ddce7c04a10a3c69ad60e52 + +---------------------------------------------------------------------- + +Add a file operation for "cnt" file under bist directory, so users can only +read "cnt" or clear "cnt" to zero, but cannot randomly modify. + +Link: https://lore.kernel.org/r/1645703489-87194-6-git-send-email-john.garry@huawei.com +Signed-off-by: Xiang Chen +Signed-off-by: Qi Liu +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: Fujai Ni +Reviewed-by: Jason Yan +Reviewed-by: Qi Liu +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 52 +++++++++++++++++++++++++- + 1 file changed, 50 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 17b078abe2a8..e917d6e9da10 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -4368,6 +4368,54 @@ static const struct file_operations debugfs_bist_phy_v3_hw_fops = { + .owner = THIS_MODULE, + }; + ++static ssize_t debugfs_bist_cnt_v3_hw_write(struct file *filp, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *m = filp->private_data; ++ struct hisi_hba *hisi_hba = m->private; ++ unsigned int cnt; ++ int val; ++ ++ if (hisi_hba->bist_loopback_enable) ++ return -EPERM; ++ ++ val = kstrtouint_from_user(buf, count, 0, &cnt); ++ if (val) ++ return val; ++ ++ if (cnt) ++ return -EINVAL; ++ ++ hisi_hba->bist_loopback_cnt = 0; ++ return count; ++} ++ ++static int debugfs_bist_cnt_v3_hw_show(struct seq_file *s, void *p) ++{ ++ struct hisi_hba *hisi_hba = s->private; ++ ++ seq_printf(s, "%u\n", hisi_hba->bist_loopback_cnt); ++ ++ return 0; ++} ++ ++static int debugfs_bist_cnt_v3_hw_open(struct inode *inode, ++ struct file *filp) ++{ ++ return single_open(filp, debugfs_bist_cnt_v3_hw_show, ++ inode->i_private); ++} ++ ++static const struct file_operations debugfs_bist_cnt_v3_hw_ops = { ++ .open = debugfs_bist_cnt_v3_hw_open, ++ .read = seq_read, ++ .write = debugfs_bist_cnt_v3_hw_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .owner = THIS_MODULE, ++}; ++ + static const struct { + int value; + char *name; +@@ -5006,8 +5054,8 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba) + debugfs_create_file("phy_id", 0600, hisi_hba->debugfs_bist_dentry, + hisi_hba, &debugfs_bist_phy_v3_hw_fops); + +- debugfs_create_u32("cnt", 0600, hisi_hba->debugfs_bist_dentry, +- &hisi_hba->bist_loopback_cnt); ++ debugfs_create_file("cnt", 0600, hisi_hba->debugfs_bist_dentry, ++ hisi_hba, &debugfs_bist_cnt_v3_hw_ops); + + debugfs_create_file("loopback_mode", 0600, + hisi_hba->debugfs_bist_dentry, +-- +2.27.0 + diff --git a/patches/0736-scsi-hisi_sas-Prevent-parallel-controller-reset-and-.patch b/patches/0736-scsi-hisi_sas-Prevent-parallel-controller-reset-and-.patch new file mode 100644 index 0000000..5d513fc --- /dev/null +++ b/patches/0736-scsi-hisi_sas-Prevent-parallel-controller-reset-and-.patch @@ -0,0 +1,62 @@ +From 885afeb361cb2e1bde59312a7edddfb9ff443f28 Mon Sep 17 00:00:00 2001 +From: Qi Liu +Date: Tue, 15 Nov 2022 23:03:40 +0800 +Subject: [PATCH 088/108] scsi: hisi_sas: Prevent parallel controller reset and + control phy command + +mainline inclusion +from mainline-v5.17-rc1 +commit 20c634932ae8978435645b466c99b3fc1a80545a +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82X + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=20c634932ae8978435645b466c99b3fc1a80545a + +---------------------------------------------------------------------- + +A user may issue a control phy command from sysfs at any time, even if the +controller is resetting. + +If a phy is disabled by hardreset/linkreset command before calling +get_phys_state() in the reset path, the saved phy state may be incorrect. + +To avoid incorrectly recording the phy state, use hisi_hba.sem to ensure +that the controller reset may not run at the same time as when the phy +control function is running. + +Link: https://lore.kernel.org/r/1639579061-179473-6-git-send-email-john.garry@huawei.com +Signed-off-by: Qi Liu +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: xiabing +Reviewed-by: Xiang Chen +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 77188195d198..966308955831 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1207,6 +1207,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, + u8 sts = phy->phy_attached; + int ret = 0; + ++ down(&hisi_hba->sem); + phy->reset_completion = &completion; + + switch (func) { +@@ -1251,6 +1252,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, + out: + phy->reset_completion = NULL; + ++ up(&hisi_hba->sem); + return ret; + } + +-- +2.27.0 + diff --git a/patches/0737-scsi-hisi_sas-Fix-phyup-timeout-on-FPGA.patch b/patches/0737-scsi-hisi_sas-Fix-phyup-timeout-on-FPGA.patch new file mode 100644 index 0000000..bfdbe9e --- /dev/null +++ b/patches/0737-scsi-hisi_sas-Fix-phyup-timeout-on-FPGA.patch @@ -0,0 +1,114 @@ +From 88439e5fcb32a4593b0e8cbfc7572a15793bcb3d Mon Sep 17 00:00:00 2001 +From: Qi Liu +Date: Tue, 15 Nov 2022 23:03:42 +0800 +Subject: [PATCH 089/108] scsi: hisi_sas: Fix phyup timeout on FPGA + +mainline inclusion +from mainline-v5.17-rc1 +commit 37310bad7fa645b21653fd7f13cb6b376d80c919 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EKNE + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=37310bad7fa645b21653fd7f13cb6b376d80c919 + +---------------------------------------------------------------------- + +The OOB interrupt and phyup interrupt handlers may run out-of-order in high +CPU usage scenarios. Since the hisi_sas_phy.timer is added in +hisi_sas_phy_oob_ready() and disarmed in phy_up_v3_hw(), this out-of-order +execution will cause hisi_sas_phy.timer timeout to trigger. + +To solve, protect hisi_sas_phy.timer and .attached with a lock, and ensure +that the timer won't be added after phyup handler completes. + +Link: https://lore.kernel.org/r/1639579061-179473-8-git-send-email-john.garry@huawei.com +Signed-off-by: Qi Liu +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: xiabing +Reviewed-by: Xiang Chen +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 18 +++++++++++++----- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 10 ++++++++-- + 2 files changed, 21 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 966308955831..48831be1b912 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -949,10 +949,14 @@ void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no) + { + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + struct device *dev = hisi_hba->dev; ++ unsigned long flags; + + dev_dbg(dev, "phy%d OOB ready\n", phy_no); +- if (phy->phy_attached) ++ spin_lock_irqsave(&phy->lock, flags); ++ if (phy->phy_attached) { ++ spin_unlock_irqrestore(&phy->lock, flags); + return; ++ } + + if (!timer_pending(&phy->timer)) { + if (phy->wait_phyup_cnt < HISI_SAS_WAIT_PHYUP_RETRIES) { +@@ -960,13 +964,17 @@ void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no) + phy->timer.expires = jiffies + + HISI_SAS_WAIT_PHYUP_TIMEOUT; + add_timer(&phy->timer); +- } else { +- dev_warn(dev, "phy%d failed to come up %d times, giving up\n", +- phy_no, phy->wait_phyup_cnt); +- phy->wait_phyup_cnt = 0; ++ spin_unlock_irqrestore(&phy->lock, flags); ++ return; + } ++ ++ dev_warn(dev, "phy%d failed to come up %d times, giving up\n", ++ phy_no, phy->wait_phyup_cnt); ++ phy->wait_phyup_cnt = 0; + } ++ spin_unlock_irqrestore(&phy->lock, flags); + } ++ + EXPORT_SYMBOL_GPL(hisi_sas_phy_oob_ready); + + static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index e917d6e9da10..adeddff88326 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1637,7 +1637,6 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct device *dev = hisi_hba->dev; + +- del_timer(&phy->timer); + hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); + + /* Port id store in 4 bits */ +@@ -1717,11 +1716,18 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + } + + phy->port_id = port_id; +- phy->phy_attached = 1; ++ + /* Call pm_runtime_put_sync() with pairs in hisi_sas_phyup_pm_work() */ + pm_runtime_get_noresume(dev); + hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP_PM); ++ + res = IRQ_HANDLED; ++ ++ spin_lock(&phy->lock); ++ /* Delete timer and set phy_attached atomically */ ++ del_timer(&phy->timer); ++ phy->phy_attached = 1; ++ spin_unlock(&phy->lock); + end: + if (phy->reset_completion) + complete(phy->reset_completion); +-- +2.27.0 + diff --git a/patches/0738-scsi-hisi_sas-Modify-v3-HW-SSP-underflow-error-proce.patch b/patches/0738-scsi-hisi_sas-Modify-v3-HW-SSP-underflow-error-proce.patch new file mode 100644 index 0000000..b575dd5 --- /dev/null +++ b/patches/0738-scsi-hisi_sas-Modify-v3-HW-SSP-underflow-error-proce.patch @@ -0,0 +1,197 @@ +From e6d56756c53e62a83a3372e3480bebdd0d01d774 Mon Sep 17 00:00:00 2001 +From: Xingui Yang +Date: Tue, 15 Nov 2022 23:03:44 +0800 +Subject: [PATCH 090/108] scsi: hisi_sas: Modify v3 HW SSP underflow error + processing + +mainline inclusion +from mainline-v5.18-rc1 +commit 62413199cd6d2906c121c2dfa3d7b82fd05f08db +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F84O + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=62413199cd6d2906c121c2dfa3d7b82fd05f08db + +---------------------------------------------------------------------- + +In case of SSP underflow allow the response frame IU to be examined for +setting the response stat value rather than always setting +SAS_DATA_UNDERRUN. + +This will mean that we call sas_ssp_task_response() in those scenarios and +may send sense data to upper layer. + +Such a condition would be for bad blocks were we just reporting an +underflow error to upper layer, but now the sense data will tell +immediately that the media is faulty. + +Link: https://lore.kernel.org/r/1645703489-87194-7-git-send-email-john.garry@huawei.com +Signed-off-by: Xingui Yang +Signed-off-by: Qi Liu +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: xiabing +Reviewed-by: Xiang Chen +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 113 ++++++++++++++----------- + 1 file changed, 62 insertions(+), 51 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index adeddff88326..d56bca524f79 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2333,7 +2333,7 @@ static void set_aborted_iptt(struct hisi_hba *hisi_hba, + 1 << CFG_ABT_SET_IPTT_DONE_OFF); + } + +-static void ++static bool + slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, + struct hisi_sas_slot *slot) + { +@@ -2353,6 +2353,15 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, + switch (task->task_proto) { + case SAS_PROTOCOL_SSP: + if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { ++ /* ++ * If returned response frame is incorrect because of data underflow, ++ * but I/O information has been written to the host memory, we examine ++ * response IU. ++ */ ++ if (!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) && ++ (complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)) ++ return false; ++ + ts->residual = trans_tx_fail_type; + ts->stat = SAS_DATA_UNDERRUN; + if (!(dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) && +@@ -2401,6 +2410,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, + default: + break; + } ++ return true; + } + + static int ssp_need_spin_up(struct hisi_sas_slot *slot) +@@ -2502,61 +2512,62 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_itct *itct = &hisi_hba->itct[device_id]; + + set_aborted_iptt(hisi_hba, slot); +- slot_err_v3_hw(hisi_hba, task, slot); +- dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr%016llx sas_addr=0x%llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", +- slot->idx, task, sas_dev->device_id, +- SAS_ADDR(device->sas_addr), itct->sas_addr, +- dw0, dw1, +- complete_hdr->act, dw3, +- error_info[0], error_info[1], +- error_info[2], error_info[3]); +- +- if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) && +- (task->task_proto & SAS_PROTOCOL_SATA || +- task->task_proto & SAS_PROTOCOL_STP)) { +- struct hisi_sas_status_buffer *status_buf = ++ if (slot_err_v3_hw(hisi_hba, task, slot)) { ++ dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr%016llx sas_addr=0x%llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", ++ slot->idx, task, sas_dev->device_id, ++ SAS_ADDR(device->sas_addr), itct->sas_addr, ++ dw0, dw1, ++ complete_hdr->act, dw3, ++ error_info[0], error_info[1], ++ error_info[2], error_info[3]); ++ ++ if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) && ++ (task->task_proto & SAS_PROTOCOL_SATA || ++ task->task_proto & SAS_PROTOCOL_STP)) { ++ struct hisi_sas_status_buffer *status_buf = + hisi_sas_status_buf_addr_mem(slot); +- u8 *iu = &status_buf->iu[0]; +- struct dev_to_host_fis *d2h = +- (struct dev_to_host_fis *)iu; ++ u8 *iu = &status_buf->iu[0]; ++ struct dev_to_host_fis *d2h = ++ (struct dev_to_host_fis *)iu; + +- dev_info(dev, "sata d2h status 0x%02x, error 0x%02x\n", +- d2h->status, d2h->error); +- } ++ dev_info(dev, "sata d2h status 0x%02x, error 0x%02x\n", ++ d2h->status, d2h->error); ++ } + +- if ((error_info[3] & RX_DATA_LEN_UNDERFLOW_MSK) && +- (task->task_proto == SAS_PROTOCOL_SSP)) { +- /*print detail sense info when data underflow happened*/ +- bool rc; +- int sb_len; +- u8 *sense_buffer; +- struct scsi_sense_hdr sshdr; +- struct ssp_response_iu *iu = +- hisi_sas_status_buf_addr_mem(slot) + +- sizeof(struct hisi_sas_err_record); +- +- sb_len = iu->sense_data_len; +- sense_buffer = iu->sense_data; +- rc = scsi_normalize_sense(sense_buffer, sb_len, &sshdr); +- if (rc) +- dev_info(dev, "data underflow, rsp_code:0x%x, sensekey:0x%x, ASC:0x%x, ASCQ:0x%x.\n", +- sshdr.response_code, +- sshdr.sense_key, +- sshdr.asc, +- sshdr.ascq); +- else +- dev_info(dev, "data underflow without sense, rsp_code:0x%02x.\n", +- iu->resp_data[0]); +- } +- if (unlikely(slot->abort)) { +- if (dev_is_sata(device) && task->ata_task.use_ncq) +- hisi_sas_ata_device_link_abort(device); +- else +- sas_task_abort(task); ++ if ((error_info[3] & RX_DATA_LEN_UNDERFLOW_MSK) && ++ (task->task_proto == SAS_PROTOCOL_SSP)) { ++ /*print detail sense info when data underflow happened*/ ++ bool rc; ++ int sb_len; ++ u8 *sense_buffer; ++ struct scsi_sense_hdr sshdr; ++ struct ssp_response_iu *iu = ++ hisi_sas_status_buf_addr_mem(slot) + ++ sizeof(struct hisi_sas_err_record); ++ ++ sb_len = iu->sense_data_len; ++ sense_buffer = iu->sense_data; ++ rc = scsi_normalize_sense(sense_buffer, sb_len, &sshdr); ++ if (rc) ++ dev_info(dev, "data underflow, rsp_code:0x%x, sensekey:0x%x, ASC:0x%x, ASCQ:0x%x.\n", ++ sshdr.response_code, ++ sshdr.sense_key, ++ sshdr.asc, ++ sshdr.ascq); ++ else ++ dev_info(dev, "data underflow without sense, rsp_code:0x%02x.\n", ++ iu->resp_data[0]); ++ } ++ if (unlikely(slot->abort)) { ++ if (dev_is_sata(device) && task->ata_task.use_ncq) ++ hisi_sas_ata_device_link_abort(device); ++ else ++ sas_task_abort(task); + +- return; ++ return; ++ } ++ goto out; + } +- goto out; + } + + switch (task->task_proto) { +-- +2.27.0 + diff --git a/patches/0739-scsi-hisi_sas-Fix-rescan-after-deleting-a-disk.patch b/patches/0739-scsi-hisi_sas-Fix-rescan-after-deleting-a-disk.patch new file mode 100644 index 0000000..351f4d5 --- /dev/null +++ b/patches/0739-scsi-hisi_sas-Fix-rescan-after-deleting-a-disk.patch @@ -0,0 +1,154 @@ +From 9b807d024192580ae0e7dfda33f72a06379047f8 Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Tue, 15 Nov 2022 23:03:48 +0800 +Subject: [PATCH 091/108] scsi: hisi_sas: Fix rescan after deleting a disk + +mainline inclusion +from mainline-v5.19-rc1 +commit e9dedc13bb11bc553754abecb322e5e41d1b4fef +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F85H + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e9dedc13bb11bc553754abecb322e5e41d1b4fef + +---------------------------------------------------------------------- + +Removing an ATA device via sysfs means that the device may not be found +through re-scanning: + +root@ubuntu:/home/john# lsscsi +[0:0:0:0] disk SanDisk LT0200MO P404 /dev/sda +[0:0:1:0] disk ATA HGST HUS724040AL A8B0 /dev/sdb +[0:0:8:0] enclosu 12G SAS Expander RevB - +root@ubuntu:/home/john# echo 1 > /sys/block/sdb/device/delete +root@ubuntu:/home/john# echo "- - -" > /sys/class/scsi_host/host0/scan +root@ubuntu:/home/john# lsscsi +[0:0:0:0] disk SanDisk LT0200MO P404 /dev/sda +[0:0:8:0] enclosu 12G SAS Expander RevB - +root@ubuntu:/home/john# + +The problem is that the rescan of the device may conflict with the device +in being re-initialized, as follows: + + - In the rescan we call hisi_sas_slave_alloc() in store_scan() -> + sas_user_scan() -> [__]scsi_scan_target() -> scsi_probe_and_add_lunc() + -> scsi_alloc_sdev() -> hisi_sas_slave_alloc() -> hisi_sas_init_device() + In hisi_sas_init_device() we issue an IT nexus reset for ATA devices + + - That IT nexus causes the remote PHY to go down and this triggers a bcast + event + + - In parallel libsas processes the bcast event, finds that the phy is down + and marks the device as gone + +The hard reset issued in hisi_sas_init_device() is unncessary - as +described in the code comment - so remove it. Also set dev status as +HISI_SAS_DEV_NORMAL as the hisi_sas_init_device() call. + +Link: https://lore.kernel.org/r/1652354134-171343-4-git-send-email-john.garry@huawei.com +Fixes: 36c6b7613ef1 ("scsi: hisi_sas: Initialise devices in .slave_alloc callback") +Tested-by: Yihang Li +Reviewed-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: xiabing +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 48 ++++++++++----------------- + 1 file changed, 18 insertions(+), 30 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 48831be1b912..e53444568c12 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -704,8 +704,6 @@ static int hisi_sas_init_device(struct domain_device *device) + struct hisi_sas_tmf_task tmf_task; + int retry = HISI_SAS_DISK_RECOVER_CNT; + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); +- struct device *dev = hisi_hba->dev; +- struct sas_phy *local_phy; + + switch (device->dev_type) { + case SAS_END_DEVICE: +@@ -726,31 +724,18 @@ static int hisi_sas_init_device(struct domain_device *device) + case SAS_SATA_PM_PORT: + case SAS_SATA_PENDING: + /* +- * send HARD RESET to clear previous affiliation of +- * STP target port ++ * If an expander is swapped when a SATA disk is attached then ++ * we should issue a hard reset to clear previous affiliation ++ * of STP target port, see SPL (chapter 6.19.4). ++ * ++ * However we don't need to issue a hard reset here for these ++ * reasons: ++ * a. When probing the device, libsas/libata already issues a ++ * hard reset in sas_probe_sata() -> ata_sas_async_probe(). ++ * Note that in hisi_sas_debug_I_T_nexus_reset() we take care ++ * to issue a hard reset by checking the dev status (== INIT). ++ * b. When resetting the controller, this is simply unnecessary. + */ +- local_phy = sas_get_local_phy(device); +- if (!scsi_is_sas_phy_local(local_phy) && +- !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) { +- unsigned long deadline = ata_deadline(jiffies, 20000); +- struct sata_device *sata_dev = &device->sata_dev; +- struct ata_host *ata_host = sata_dev->ata_host; +- struct ata_port_operations *ops = ata_host->ops; +- struct ata_port *ap = sata_dev->ap; +- struct ata_link *link; +- unsigned int classes; +- +- ata_for_each_link(link, ap, EDGE) +- rc = ops->hardreset(link, &classes, +- deadline); +- } +- sas_put_local_phy(local_phy); +- if (rc) { +- dev_warn(dev, "SATA disk hardreset fail: %d\n", +- rc); +- return rc; +- } +- + while (retry-- > 0) { + rc = hisi_sas_softreset_ata_disk(device); + if (!rc) +@@ -766,15 +751,19 @@ static int hisi_sas_init_device(struct domain_device *device) + + int hisi_sas_slave_alloc(struct scsi_device *sdev) + { +- struct domain_device *ddev; ++ struct domain_device *ddev = sdev_to_domain_dev(sdev); ++ struct hisi_sas_device *sas_dev = ddev->lldd_dev; + int rc; + + rc = sas_slave_alloc(sdev); + if (rc) + return rc; +- ddev = sdev_to_domain_dev(sdev); + +- return hisi_sas_init_device(ddev); ++ rc = hisi_sas_init_device(ddev); ++ if (rc) ++ return rc; ++ sas_dev->dev_status = HISI_SAS_DEV_NORMAL; ++ return 0; + } + EXPORT_SYMBOL_GPL(hisi_sas_slave_alloc); + +@@ -824,7 +813,6 @@ static int hisi_sas_dev_found(struct domain_device *device) + dev_info(dev, "dev[%d:%x] found\n", + sas_dev->device_id, sas_dev->dev_type); + +- sas_dev->dev_status = HISI_SAS_DEV_NORMAL; + return 0; + + err_out: +-- +2.27.0 + diff --git a/patches/0740-scsi-hisi_sas-Undo-RPM-resume-for-failed-notify-phy-.patch b/patches/0740-scsi-hisi_sas-Undo-RPM-resume-for-failed-notify-phy-.patch new file mode 100644 index 0000000..4684110 --- /dev/null +++ b/patches/0740-scsi-hisi_sas-Undo-RPM-resume-for-failed-notify-phy-.patch @@ -0,0 +1,59 @@ +From 40b769493ef587495b958ae4ba171534f4f627cb Mon Sep 17 00:00:00 2001 +From: Xiang Chen +Date: Tue, 15 Nov 2022 23:03:45 +0800 +Subject: [PATCH 092/108] scsi: hisi_sas: Undo RPM resume for failed notify phy + event for v3 HW + +mainline inclusion +from mainline-v5.19-rc1 +commit 9b5387fe5af38116b452259d87cd66594b6277c1 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F803 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9b5387fe5af38116b452259d87cd66594b6277c1 + +---------------------------------------------------------------------- + +If we fail to notify the phy up event then undo the RPM resume, as the phy +up notify event handling pairs with that RPM resume. + +Link: https://lore.kernel.org/r/1651839939-101188-1-git-send-email-john.garry@huawei.com +Reported-by: Yihang Li +Tested-by: Yihang Li +Signed-off-by: Xiang Chen +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: xiabing +Reviewed-by: Xiang Chen +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index d56bca524f79..e1c327dedb97 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1717,9 +1717,15 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + + phy->port_id = port_id; + +- /* Call pm_runtime_put_sync() with pairs in hisi_sas_phyup_pm_work() */ ++ /* ++ * Call pm_runtime_get_noresume() which pairs with ++ * hisi_sas_phyup_pm_work() -> pm_runtime_put_sync(). ++ * For failure call pm_runtime_put() as we are in a hardirq context. ++ */ + pm_runtime_get_noresume(dev); +- hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP_PM); ++ res = hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP_PM); ++ if (!res) ++ pm_runtime_put(dev); + + res = IRQ_HANDLED; + +-- +2.27.0 + diff --git a/patches/0741-scsi-hisi_sas-Use-abort-task-set-to-reset-SAS-disks-.patch b/patches/0741-scsi-hisi_sas-Use-abort-task-set-to-reset-SAS-disks-.patch new file mode 100644 index 0000000..9d71074 --- /dev/null +++ b/patches/0741-scsi-hisi_sas-Use-abort-task-set-to-reset-SAS-disks-.patch @@ -0,0 +1,47 @@ +From c3270db80b03c47c7ab62b9511158a0d2d12400d Mon Sep 17 00:00:00 2001 +From: Xingui Yang +Date: Thu, 16 Mar 2023 20:21:39 +0800 +Subject: [PATCH 093/108] scsi: hisi_sas: Use abort task set to reset SAS disks + when discovered + +mainline inclusion +from mainline-v6.2-rc4 +commit 037b48057e8b485a8d72f808122796aeadbbee32 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=037b48057e8b485a8d72f808122796aeadbbee32 + +---------------------------------------------------------------------- + +Currently clear task set is used to abort all commands remaining in the +disk when the SAS disk is discovered, and if the disk is discovered by two +initiators, other I_T nexuses are also affected. So use abort task set +instead and take effect only on the specified I_T nexus. + +Signed-off-by: Xingui Yang +Signed-off-by: Xiang Chen +Link: https://lore.kernel.org/r/1672805000-141102-2-git-send-email-chenxiang66@hisilicon.com +Signed-off-by: Martin K. Petersen +Signed-off-by: xiabing +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index e53444568c12..0ab8b324f82c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -709,7 +709,7 @@ static int hisi_sas_init_device(struct domain_device *device) + case SAS_END_DEVICE: + int_to_scsilun(0, &lun); + +- tmf_task.tmf = TMF_CLEAR_TASK_SET; ++ tmf_task.tmf = TMF_ABORT_TASK_SET; + while (retry-- > 0) { + rc = hisi_sas_debug_issue_ssp_tmf(device, lun.scsi_lun, + &tmf_task); +-- +2.27.0 + diff --git a/patches/0742-scsi-hisi_sas-Disable-SATA-disk-phy-for-severe-I_T-n.patch b/patches/0742-scsi-hisi_sas-Disable-SATA-disk-phy-for-severe-I_T-n.patch new file mode 100644 index 0000000..d6cb948 --- /dev/null +++ b/patches/0742-scsi-hisi_sas-Disable-SATA-disk-phy-for-severe-I_T-n.patch @@ -0,0 +1,90 @@ +From 5ed48c3e9af21e878fa33661fa5dbd2fc1e8af0f Mon Sep 17 00:00:00 2001 +From: nifujia +Date: Tue, 18 Jan 2022 21:23:43 +0800 +Subject: [PATCH 094/108] scsi: hisi_sas: + Disable-SATA-disk-phy-for-severe-I_T-nexus reset failure + +mainline inclusion +from mainline-v5.16-rc1 +commit 21c7e972475e6a975fbe97f8974c96fe4713077c +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=21c7e972475e6a975fbe97f8974c96fe4713077c + +---------------------------------------------------------------------- + +If the softreset fails in the I_T reset, libsas will then continue to issue +a controller reset to try to recover. + +However a faulty disk may cause the softreset to fail, and resetting the +controller will not help this scenario. Indeed, we will just continue the +cycle of error handle handling to try to recover. + +So if the softreset fails upon certain conditions, just disable the phy +associated with the disk. The user needs to handle this problem. + +Link: https://lore.kernel.org/r/1634041588-74824-5-git-send-email-john.garry@huawei.com +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Reviewed-by: Jason Yan +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 27 ++++++++++++++++++++++++--- + 1 file changed, 24 insertions(+), 3 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 0ab8b324f82c..48644ab23e4c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1953,15 +1953,36 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device) + } + hisi_sas_dereg_device(hisi_hba, device); + +- if (dev_is_sata(device)) { ++ rc = hisi_sas_debug_I_T_nexus_reset(device); ++ if (rc == TMF_RESP_FUNC_COMPLETE && dev_is_sata(device)) { ++ struct sas_phy *local_phy; ++ + rc = hisi_sas_softreset_ata_disk(device); + if (rc) + dev_err(dev, "I_T nexus reset: softreset failed (%d)\n", + rc); ++ switch (rc) { ++ case -ECOMM: ++ rc = -ENODEV; ++ break; ++ case TMF_RESP_FUNC_FAILED: ++ case -EMSGSIZE: ++ case -EIO: ++ local_phy = sas_get_local_phy(device); ++ rc = sas_phy_enable(local_phy, 0); ++ if (!rc) { ++ local_phy->enabled = 0; ++ dev_err(dev, "Disabled local phy of ATA disk %016llx due to softreset fail (%d)\n", ++ SAS_ADDR(device->sas_addr), rc); ++ rc = -ENODEV; ++ } ++ sas_put_local_phy(local_phy); ++ break; ++ default: ++ break; ++ } + } + +- rc = hisi_sas_debug_I_T_nexus_reset(device); +- + if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV)) + hisi_sas_release_task(hisi_hba, device); + +-- +2.27.0 + diff --git a/patches/0743-Revert-scsi-hisi_sas-Disable-SATA-disk-phy-for-sever.patch b/patches/0743-Revert-scsi-hisi_sas-Disable-SATA-disk-phy-for-sever.patch new file mode 100644 index 0000000..dc413e7 --- /dev/null +++ b/patches/0743-Revert-scsi-hisi_sas-Disable-SATA-disk-phy-for-sever.patch @@ -0,0 +1,87 @@ +From 0770577c0180258f9f17ec16961fb4b9b1eb4a6d Mon Sep 17 00:00:00 2001 +From: Yihang Li +Date: Fri, 17 Mar 2023 15:04:19 +0800 +Subject: [PATCH 095/108] Revert "scsi: hisi_sas: Disable SATA disk phy for + severe I_T nexus reset failure" + +driver inclusion +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P +CVE: NA + +---------------------------------------------------------------------- + +In that commit, if the softreset fails upon certain conditions, just +disable the PHY associated with the disk. The user needs to restore the +PHY. + +SATA disks do not support simultaneous connection of multiple hosts. +Therefore, when multiple controllers are connected to a SATA disk at the +same time, the controller which is connected later failed to issue an ATA +softreset to the SATA disk. As a result, the PHY associated with the disk +is disabled and cannot be automatically recovered. + +Now that, we will not focus on the execution result of softreset. No +matter whether the execution is successful or not, we will directly carry +out I_T_nexus_reset. + +Fixes: c723ada86707 ("scsi: hisi_sas: Disable SATA disk phy for severe I_T nexus reset failure") +Signed-off-by: Yihang Li +Signed-off-by: xiabing +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 29 +++++---------------------- + 1 file changed, 5 insertions(+), 24 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 48644ab23e4c..4f534b8a9206 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1953,36 +1953,17 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device) + } + hisi_sas_dereg_device(hisi_hba, device); + +- rc = hisi_sas_debug_I_T_nexus_reset(device); +- if (rc == TMF_RESP_FUNC_COMPLETE && dev_is_sata(device)) { +- struct sas_phy *local_phy; +- ++ if (dev_is_sata(device)) { + rc = hisi_sas_softreset_ata_disk(device); + if (rc) + dev_err(dev, "I_T nexus reset: softreset failed (%d)\n", + rc); +- switch (rc) { +- case -ECOMM: +- rc = -ENODEV; +- break; +- case TMF_RESP_FUNC_FAILED: +- case -EMSGSIZE: +- case -EIO: +- local_phy = sas_get_local_phy(device); +- rc = sas_phy_enable(local_phy, 0); +- if (!rc) { +- local_phy->enabled = 0; +- dev_err(dev, "Disabled local phy of ATA disk %016llx due to softreset fail (%d)\n", +- SAS_ADDR(device->sas_addr), rc); +- rc = -ENODEV; +- } +- sas_put_local_phy(local_phy); +- break; +- default: +- break; +- } ++ if (rc == TMF_RESP_FUNC_FAILED) ++ dev_err(dev, "ata disk %016llx reset (%d)\n", ++ SAS_ADDR(device->sas_addr), rc); + } + ++ rc = hisi_sas_debug_I_T_nexus_reset(device); + if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV)) + hisi_sas_release_task(hisi_hba, device); + +-- +2.27.0 + diff --git a/patches/0744-scsi-hisi_sas-Set-a-port-invalid-only-if-there-are-n.patch b/patches/0744-scsi-hisi_sas-Set-a-port-invalid-only-if-there-are-n.patch new file mode 100644 index 0000000..3b08755 --- /dev/null +++ b/patches/0744-scsi-hisi_sas-Set-a-port-invalid-only-if-there-are-n.patch @@ -0,0 +1,50 @@ +From 09a96afdd384a3bded3fad7c03e9ffce83310c64 Mon Sep 17 00:00:00 2001 +From: Yihang Li +Date: Fri, 14 Apr 2023 16:20:40 +0800 +Subject: [PATCH 096/108] scsi: hisi_sas: Set a port invalid only if there are + no devices attached when refreshing port id + +mainline inclusion +from mainline-v6.2-rc4 +commit f58c89700630da6554b24fd3df293a24874c10c1 +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f58c89700630da6554b24fd3df293a24874c10c1 + +---------------------------------------------------------------------- + +Currently the driver sets the port invalid if one phy in the port is not +enabled, which may cause issues in expander situation. In directly attached +situation, if phy up doesn't occur in time when refreshing port id, the +port is incorrectly set to invalid which will also cause disk lost. + +Therefore set a port invalid only if there are no devices attached to the +port. + +Signed-off-by: Yihang Li +Signed-off-by: Xiang Chen +Link: https://lore.kernel.org/r/1672805000-141102-3-git-send-email-chenxiang66@hisilicon.com +Signed-off-by: Martin K. Petersen +Signed-off-by: xiabing +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 4f534b8a9206..91146ce048b8 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1499,7 +1499,7 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba) + device->linkrate = phy->sas_phy.linkrate; + + hisi_hba->hw->setup_itct(hisi_hba, sas_dev); +- } else ++ } else if (!port->port_attached) + port->id = 0xff; + } + } +-- +2.27.0 + diff --git a/patches/0745-scsi-hisi_sas-Exit-suspending-state-when-usage-count.patch b/patches/0745-scsi-hisi_sas-Exit-suspending-state-when-usage-count.patch new file mode 100644 index 0000000..589e87e --- /dev/null +++ b/patches/0745-scsi-hisi_sas-Exit-suspending-state-when-usage-count.patch @@ -0,0 +1,291 @@ +From 1ec5b3c4853239f55ce96bdb600db57adff5ff82 Mon Sep 17 00:00:00 2001 +From: Yihang Li +Date: Fri, 14 Apr 2023 16:20:41 +0800 +Subject: [PATCH 097/108] scsi: hisi_sas: Exit suspending state when usage + count is greater than 0 + +driver inclusion +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P +CVE: NA + +---------------------------------------------------------------------- + +When the current status of the host controller is suspended, enabling a +local PHY just after disabling all local PHYs in expander envirnment, +a hung as follows occurs. + +[ 486.854655] INFO: task kworker/u256:1:899 blocked for more than 120 seconds. +[ 486.862207] Not tainted 6.1.0-rc4+ #1 +[ 486.870545] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 486.878893] task:kworker/u256:1 state:D stack:0 pid:899 ppid:2 flags:0x00000008 +[ 486.887745] Workqueue: 0000:74:02.0_disco_q sas_discover_domain [libsas] +[ 486.894704] Call trace: +[ 486.897400] __switch_to+0xf0/0x170 +[ 486.901146] __schedule+0x3e4/0x1160 +[ 486.904970] schedule+0x64/0x104 +[ 486.908442] rpm_resume+0x158/0x6a0 +[ 486.912163] __pm_runtime_resume+0x5c/0x84 +[ 486.916489] smp_execute_task_sg+0x1f8/0x264 [libsas] +[ 486.921773] sas_discover_expander.part.0+0xbc/0x720 [libsas] +[ 486.927750] sas_discover_root_expander+0x90/0x154 [libsas] +[ 486.933552] sas_discover_domain+0x444/0x6d0 [libsas] +[ 486.938826] process_one_work+0x1e0/0x450 +[ 486.943057] worker_thread+0x150/0x44c +[ 486.947015] kthread+0x114/0x120 +[ 486.950447] ret_from_fork+0x10/0x20 +[ 486.954292] INFO: task kworker/u256:2:1780 blocked for more than 120 seconds. +[ 486.961637] Not tainted 6.1.0-rc4+ #1 +[ 486.966087] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 486.974356] task:kworker/u256:2 state:D stack:0 pid:1780 ppid:2 flags:0x00000208 +[ 486.983141] Workqueue: 0000:74:02.0_event_q sas_port_event_worker [libsas] +[ 486.990252] Call trace: +[ 486.992930] __switch_to+0xf0/0x170 +[ 486.996645] __schedule+0x3e4/0x1160 +[ 487.000439] schedule+0x64/0x104 +[ 487.003886] schedule_timeout+0x17c/0x1c0 +[ 487.008102] wait_for_completion+0x7c/0x160 +[ 487.012488] __flush_workqueue+0x104/0x3e0 +[ 487.016782] sas_porte_bytes_dmaed+0x414/0x454 [libsas] +[ 487.022203] sas_port_event_worker+0x38/0x60 [libsas] +[ 487.027449] process_one_work+0x1e0/0x450 +[ 487.031645] worker_thread+0x150/0x44c +[ 487.035594] kthread+0x114/0x120 +[ 487.039017] ret_from_fork+0x10/0x20 +[ 487.042828] INFO: task bash:11488 blocked for more than 121 seconds. +[ 487.049366] Not tainted 6.1.0-rc4+ #1 +[ 487.053746] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 487.061953] task:bash state:D stack:0 pid:11488 ppid:10977 flags:0x00000204 +[ 487.070698] Call trace: +[ 487.073355] __switch_to+0xf0/0x170 +[ 487.077050] __schedule+0x3e4/0x1160 +[ 487.080833] schedule+0x64/0x104 +[ 487.084270] schedule_timeout+0x17c/0x1c0 +[ 487.088474] wait_for_completion+0x7c/0x160 +[ 487.092851] __flush_workqueue+0x104/0x3e0 +[ 487.097137] drain_workqueue+0xb8/0x160 +[ 487.101159] __sas_drain_work+0x50/0x90 [libsas] +[ 487.105963] sas_suspend_ha+0x64/0xd4 [libsas] +[ 487.110590] suspend_v3_hw+0x198/0x1e8 [hisi_sas_v3_hw] +[ 487.115989] pci_pm_runtime_suspend+0x5c/0x1d0 +[ 487.120606] __rpm_callback+0x50/0x150 +[ 487.124535] rpm_callback+0x74/0x80 +[ 487.128204] rpm_suspend+0x110/0x640 +[ 487.131955] rpm_idle+0x1f4/0x2d0 +[ 487.135447] __pm_runtime_idle+0x58/0x94 +[ 487.139538] queue_phy_enable+0xcc/0xf0 [libsas] +[ 487.144330] store_sas_phy_enable+0x74/0x100 +[ 487.148770] dev_attr_store+0x20/0x34 +[ 487.152606] sysfs_kf_write+0x4c/0x5c +[ 487.156437] kernfs_fop_write_iter+0x120/0x1b0 +[ 487.161049] vfs_write+0x2d0/0x36c +[ 487.164625] ksys_write+0x70/0x100 +[ 487.168194] __arm64_sys_write+0x24/0x30 +[ 487.172280] invoke_syscall+0x50/0x120 +[ 487.176186] el0_svc_common.constprop.0+0x168/0x190 +[ 487.181214] do_el0_svc+0x34/0xc0 +[ 487.184680] el0_svc+0x2c/0xb4 +[ 487.187879] el0t_64_sync_handler+0xb8/0xbc +[ 487.192205] el0t_64_sync+0x19c/0x1a0 + +We find that when all local PHYs are disabled, all the devices will be +removed, the ->runtime_suspend() callback suspend_v3_hw() directly execute +since the controller usage count drop to 0. On the other side, the first +local PHY is enabled through the sysfs interface, and ensures that +function phy_up_v3_hw() is completed due to suspend_v3_hw()-> +interrupt_disable_v3_hw(). In the expander scenario, +sas_discover_root_expander() is executed in event work +DISCE_DISCOVER_DOMAIN, which will increases the controller usage count and +carry out a resume and sends SMPIO, it cannot be completed because the +runtime PM status of the controller is RPM_SUSPENDING. At the same time, +the ->runtime_suspend() callback suspend_v3_hw() also cannot complete the +process because of drain libsas event queue in sas_suspend_ha(), so hung +occurs. + + (thread 1) | (thread 2) +... | +rpm_idle() | + ... | + __update_runtime_status(RPM_SUSPENDING)| + ... | ... + suspend_v3_hw() | smp_execute_task_sg() + ... | ... + interrupt_disable_v3_hw() | pm_runtime_get_sync() + | ... + ... | rpm_resume() //RPM_SUSPENDING + | + __sas_drain_work() | + +To fix it, check if the current runtime PM status of the controller allows +to be suspended continue after interrupt_disable_v3_hw(), return +immediately if not. + +Signed-off-by: Yihang Li +Signed-off-by: Xiang Chen +Signed-off-by: xiabing +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 71 ++++++++++++++++++++------ + 1 file changed, 56 insertions(+), 15 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index e1c327dedb97..001a2bad4442 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -635,6 +635,27 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba, + readl_poll_timeout_atomic(regs, val, cond, delay_us, timeout_us);\ + }) + ++static void interrupt_enable_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int i; ++ ++ for (i = 0; i < hisi_hba->queue_count; i++) ++ hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0); ++ ++ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe); ++ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe); ++ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffc220ff); ++ hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x155555); ++ ++ for (i = 0; i < hisi_hba->n_phy; i++) { ++ hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xf2057fff); ++ hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe); ++ hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0); ++ hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0); ++ hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0); ++ } ++} ++ + static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + { + int i, j; +@@ -657,18 +678,11 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff); +- hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe); +- hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe); +- hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffc220ff); + hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0); + hisi_sas_write32(hisi_hba, CHNL_ENT_INT_MSK, 0x0); + hisi_sas_write32(hisi_hba, HGC_COM_INT_MSK, 0x0); +- hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x155555); + hisi_sas_write32(hisi_hba, AWQOS_AWCACHE_CFG, 0xf0f0); + hisi_sas_write32(hisi_hba, ARQOS_ARCACHE_CFG, 0xf0f0); +- for (i = 0; i < hisi_hba->queue_count; i++) +- hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0); +- + hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1); + + if (skip_bus_flag) { +@@ -677,6 +691,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE, 0x10000); + } + ++ interrupt_enable_v3_hw(hisi_hba); + for (i = 0; i < hisi_hba->n_phy; i++) { + enum sas_linkrate max; + struct hisi_sas_phy *phy = &hisi_hba->phy[i]; +@@ -709,10 +724,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff); + hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000); +- hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xf2057fff); +- hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe); + hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0); +- hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0); + hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0); + hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0); + hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0); +@@ -2966,7 +2978,6 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba) + u32 status, reg_val; + int rc; + +- interrupt_disable_v3_hw(hisi_hba); + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); + + hisi_sas_stop_phys(hisi_hba); +@@ -2997,6 +3008,7 @@ static int soft_reset_v3_hw(struct hisi_hba *hisi_hba) + struct device *dev = hisi_hba->dev; + int rc; + ++ interrupt_disable_v3_hw(hisi_hba); + rc = disable_host_v3_hw(hisi_hba); + if (rc) { + dev_err(dev, "soft reset: disable host failed rc=%d\n", rc); +@@ -5337,6 +5349,7 @@ static void hisi_sas_reset_prepare_v3_hw(struct pci_dev *pdev) + set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + hisi_sas_controller_reset_prepare(hisi_hba); + ++ interrupt_disable_v3_hw(hisi_hba); + rc = disable_host_v3_hw(hisi_hba); + if (rc) + dev_err(dev, "FLR: disable host failed rc=%d\n", rc); +@@ -5366,6 +5379,21 @@ enum { + hip08, + }; + ++static void enable_host_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ u32 reg_val; ++ ++ hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, ++ (u32)((1ULL << hisi_hba->queue_count) - 1)); ++ ++ phys_init_v3_hw(hisi_hba); ++ reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE + ++ AM_CTRL_GLOBAL); ++ reg_val &= ~AM_CTRL_SHUTDOWN_REQ_MSK; ++ hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE + ++ AM_CTRL_GLOBAL, reg_val); ++} ++ + static int _suspend_v3_hw(struct device *device) + { + struct pci_dev *pdev = to_pci_dev(device); +@@ -5389,14 +5417,18 @@ static int _suspend_v3_hw(struct device *device) + scsi_block_requests(shost); + set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + flush_workqueue(hisi_hba->wq); ++ interrupt_disable_v3_hw(hisi_hba); ++ ++ if (atomic_read(&device->power.usage_count)) { ++ dev_err(dev, "PM suspend: host status cannot be suspended\n"); ++ rc = -EBUSY; ++ goto err_out; ++ } + + rc = disable_host_v3_hw(hisi_hba); + if (rc) { + dev_err(dev, "PM suspend: disable host failed rc=%d\n", rc); +- clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); +- clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); +- scsi_unblock_requests(shost); +- return rc; ++ goto err_out_recover_host; + } + + hisi_sas_init_mem(hisi_hba); +@@ -5414,6 +5446,15 @@ static int _suspend_v3_hw(struct device *device) + + dev_warn(dev, "end of suspending controller\n"); + return 0; ++ ++err_out_recover_host: ++ enable_host_v3_hw(hisi_hba); ++err_out: ++ interrupt_enable_v3_hw(hisi_hba); ++ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); ++ clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); ++ scsi_unblock_requests(shost); ++ return rc; + } + + static int _resume_v3_hw(struct device *device) +-- +2.27.0 + diff --git a/patches/0746-scsi-hisi_sas-Ensure-all-enabled-PHYs-up-during-cont.patch b/patches/0746-scsi-hisi_sas-Ensure-all-enabled-PHYs-up-during-cont.patch new file mode 100644 index 0000000..894191a --- /dev/null +++ b/patches/0746-scsi-hisi_sas-Ensure-all-enabled-PHYs-up-during-cont.patch @@ -0,0 +1,113 @@ +From a298b5be71c788b006321a316b2f45a9a6937832 Mon Sep 17 00:00:00 2001 +From: Yihang Li +Date: Fri, 14 Apr 2023 16:20:42 +0800 +Subject: [PATCH 098/108] scsi: hisi_sas: Ensure all enabled PHYs up during + controller reset + +mainline inclusion +from mainline-v6.4-rc1 +commit 89954f024c3ae5e8674d9b5313a7cc08e79c6f6d +category: feature +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=89954f024c3ae5e8674d9b5313a7cc08e79c6f6d + +---------------------------------------------------------------------- + +For the controller reset operation, hisi_sas_phy_enable() is executed for +each enabled local PHY, and refresh the port id of each device based on +the latest hisi_sas_phy->port_id after 1 second sleep, +hisi_sas_phy->port_id is configured in the interrupt processing function +phy_up_v3_hw(). However, in directly attached scenario, for some SATA +disks the amount of time for phyup more than 1s sometimes. In this case, +incorrect port id may be configured in hisi_sas_refresh_port_id(). +As a result, all the internal IOs fail and disk lost, such as follows: + +[10717.666565] hisi_sas_v3_hw 0000:74:02.0: phyup: phy1 link_rate=10(sata) +[10718.826813] hisi_sas_v3_hw 0000:74:02.0: erroneous completion iptt=63 +task=00000000c1ab1c2b dev id=200 addr=5000000000000501 CQ hdr: 0x8000007 0xc8003f 0x0 +0x0 Error info: 0x0 0x0 0x0 0x0 +[10718.843428] sas: TMF task open reject failed 5000000000000501 +[10718.849242] hisi_sas_v3_hw 0000:74:02.0: erroneous completion iptt=64 +task=00000000c1ab1c2b dev id=200 addr=5000000000000501 CQ hdr: 0x8000007 0xc80040 0x0 +0x0 Error info: 0x0 0x0 0x0 0x0 +[10718.865856] sas: TMF task open reject failed 5000000000000501 +[10718.871670] hisi_sas_v3_hw 0000:74:02.0: erroneous completion iptt=65 +task=00000000c1ab1c2b dev id=200 addr=5000000000000501 CQ hdr: 0x8000007 0xc80041 0x0 +0x0 Error info: 0x0 0x0 0x0 0x0 +[10718.888284] sas: TMF task open reject failed 5000000000000501 +[10718.894093] sas: executing TMF for 5000000000000501 failed after 3 attempts! +[10718.901114] hisi_sas_v3_hw 0000:74:02.0: ata disk 5000000000000501 reset failed +[10718.908410] hisi_sas_v3_hw 0000:74:02.0: controller reset complete +..... +[10773.298633] ata216.00: revalidation failed (errno=-19) +[10773.303753] ata216.00: disable device + +So the time of waitting for PHYs up is 1s which may be not enough. To +solve the issue, running hisi_sas_phy_enable() in parallel through +async operations and use wait_for_completion_timeout() to wait for PHYs +come up instead of directly sleep for 1 second. + +Signed-off-by: Yihang Li +Signed-off-by: Xiang Chen +Signed-off-by: xiabing +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_main.c +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 33 ++++++++++++++++++++++++--- + 1 file changed, 30 insertions(+), 3 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 91146ce048b8..9d2e0d2df0b6 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1660,14 +1660,41 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba) + } + EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_prepare); + ++static void hisi_sas_async_init_wait_phyup(void *data, async_cookie_t cookie) ++{ ++ struct hisi_sas_phy *phy = data; ++ struct hisi_hba *hisi_hba = phy->hisi_hba; ++ struct device *dev = hisi_hba->dev; ++ DECLARE_COMPLETION_ONSTACK(completion); ++ int phy_no = phy->sas_phy.id; ++ ++ phy->reset_completion = &completion; ++ hisi_sas_phy_enable(hisi_hba, phy_no, 1); ++ if (!wait_for_completion_timeout(&completion, ++ HISI_SAS_WAIT_PHYUP_TIMEOUT)) ++ dev_warn(dev, "phy%d wait phyup timed out\n", phy_no); ++ ++ phy->reset_completion = NULL; ++} ++ + void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) + { + struct Scsi_Host *shost = hisi_hba->shost; ++ ASYNC_DOMAIN_EXCLUSIVE(async); ++ int phy_no; + + /* Init and wait for PHYs to come up and all libsas event finished. */ +- hisi_hba->hw->phys_init(hisi_hba); +- /* Sleep 1s to wait for phy up */ +- msleep(1000); ++ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { ++ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; ++ ++ if (!(hisi_hba->phy_state & BIT(phy_no))) ++ continue; ++ ++ async_schedule_domain(hisi_sas_async_init_wait_phyup, ++ phy, &async); ++ } ++ ++ async_synchronize_full_domain(&async); + hisi_sas_refresh_port_id(hisi_hba); + clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + +-- +2.27.0 + diff --git a/patches/0747-scsi-hisi_sas-Increase-debugfs_dump_index-after-dump.patch b/patches/0747-scsi-hisi_sas-Increase-debugfs_dump_index-after-dump.patch new file mode 100644 index 0000000..bcb78c7 --- /dev/null +++ b/patches/0747-scsi-hisi_sas-Increase-debugfs_dump_index-after-dump.patch @@ -0,0 +1,55 @@ +From d29c3fa57c6df88b0fb882af5fc9296deb0a45d3 Mon Sep 17 00:00:00 2001 +From: Ni Fujia +Date: Wed, 12 Jan 2022 15:17:15 +0800 +Subject: [PATCH 099/108] scsi: hisi_sas: Increase debugfs_dump_index after + dump is completed + +mainline inclusion +from mainline-v5.16-rc1 +commit 9aec5ffa6e39926cff1a6b576c815a9cee90e259 +category: feature +bugzilla: https://gitee.com/openeuler/kernel/issues/I8F81U + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9aec5ffa6e39926cff1a6b576c815a9cee90e259 + +---------------------------------------------------------------------- + +The hisi_hba debugfs_dump_index member should increased after a dump +insertion completed, and not before it has started, so fix the code to do +so. + +Signed-off-by: Luo Jiaxing +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Reviewed-by: Wei Li +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 001a2bad4442..562b9553f7bb 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -4136,7 +4136,6 @@ static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) + + do_div(timestamp, NSEC_PER_MSEC); + hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; +- hisi_hba->debugfs_dump_index++; + + debugfs_snapshot_prepare_v3_hw(hisi_hba); + +@@ -4152,6 +4151,7 @@ static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) + debugfs_create_files_v3_hw(hisi_hba); + + debugfs_snapshot_restore_v3_hw(hisi_hba); ++ hisi_hba->debugfs_dump_index++; + } + + static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, +-- +2.27.0 + diff --git a/patches/0748-scsi-hisi_sas-Configure-the-initialization-registers.patch b/patches/0748-scsi-hisi_sas-Configure-the-initialization-registers.patch new file mode 100644 index 0000000..44fc1fa --- /dev/null +++ b/patches/0748-scsi-hisi_sas-Configure-the-initialization-registers.patch @@ -0,0 +1,103 @@ +From aa07d835c879dd55d7f3bb2806385ababfc720f1 Mon Sep 17 00:00:00 2001 +From: Yihang Li +Date: Fri, 28 Apr 2023 14:39:18 +0800 +Subject: [PATCH 100/108] scsi: hisi_sas: Configure the initialization + registers according to HBA model + +mainline inclusion +from mainline-v6.5-rc1 +commit b68daae9660b45a0bb3ac9df1f1746d15693d254 +category: feature +bugzilla: https://gitee.com/openeuler/kernel/issues/I8F81U + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b68daae9660b45a0bb3ac9df1f1746d15693d254 + +---------------------------------------------------------------------- + +We use init_reg_v3_hw() to set some registers, for the latest HBA devices, +some of these HW registers are set through firmware. Therefore, different +HBA models are distinguished through pci_dev->revision. + +Signed-off-by: Yihang Li +Reviewed-by: Xiang Chen +Signed-off-by: xiabing +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 562b9553f7bb..5bb3f0466338 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -658,12 +658,12 @@ static void interrupt_enable_v3_hw(struct hisi_hba *hisi_hba) + + static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + { ++ struct pci_dev *pdev = hisi_hba->pci_dev; + int i, j; + + /* Global registers init */ + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, + (u32)((1ULL << hisi_hba->queue_count) - 1)); +- hisi_sas_write32(hisi_hba, SAS_AXI_USER3, 0); + hisi_sas_write32(hisi_hba, CFG_MAX_TAG, 0xfff0400); + /* time / CLK_AHB = 2.5s / 2ns = 0x4A817C80 */ + hisi_sas_write32(hisi_hba, TRANS_LOCK_ICT_TIME, 0x4A817C80); +@@ -691,6 +691,9 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE, 0x10000); + } + ++ if (pdev->revision < 0x30) ++ hisi_sas_write32(hisi_hba, SAS_AXI_USER3, 0); ++ + interrupt_enable_v3_hw(hisi_hba); + for (i = 0; i < hisi_hba->n_phy; i++) { + enum sas_linkrate max; +@@ -719,7 +722,6 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + SAS_RX_TRAIN_TIMER, 0x13e80); + } + +- hisi_sas_phy_write32(hisi_hba, i, SERDES_CFG, 0xffc00); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff); +@@ -746,13 +748,18 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01); + hisi_sas_phy_write32(hisi_hba, i, SAS_EC_INT_COAL_TIME, + 0x30f4240); +- hisi_sas_phy_write32(hisi_hba, i, +- SAS_SSP_CON_TIMER_CFG, 0x32); +- +- /* used for 12G negotiate */ +- hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e); + hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff); + ++ /* set value through firmware for the latest HBA */ ++ if (pdev->revision < 0x30) { ++ hisi_sas_phy_write32(hisi_hba, i, ++ SAS_SSP_CON_TIMER_CFG, 0x32); ++ hisi_sas_phy_write32(hisi_hba, i, SERDES_CFG, 0xffc00); ++ /* used for 12G negotiate */ ++ hisi_sas_phy_write32(hisi_hba, i, ++ COARSETUNE_TIME, 0x1e); ++ } ++ + /* get default FFE configuration for BIST */ + for (j = 0; j < FFE_CFG_MAX; j++) { + u32 val = hisi_sas_phy_read32(hisi_hba, i, +@@ -764,7 +771,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) + for (i = 0; i < hisi_hba->queue_count; i++) { + /* Delivery queue */ + hisi_sas_write32(hisi_hba, +- DLVRY_Q_0_BASE_ADDR_HI + ++ DLVRY_Q_0_BASE_ADDR_HI + + (i * NEXT_DQCQ_REG_OFF), + upper_32_bits(hisi_hba->cmd_hdr_dma[i])); + +-- +2.27.0 + diff --git a/patches/0749-scsi-hisi_sas-Add-slave_destroy-interface-for-v3-hw.patch b/patches/0749-scsi-hisi_sas-Add-slave_destroy-interface-for-v3-hw.patch new file mode 100644 index 0000000..73b33fb --- /dev/null +++ b/patches/0749-scsi-hisi_sas-Add-slave_destroy-interface-for-v3-hw.patch @@ -0,0 +1,87 @@ +From 6b88d4e6eb70241e337f56725f3908bb52633e17 Mon Sep 17 00:00:00 2001 +From: Qi Liu +Date: Thu, 8 Jun 2023 11:04:48 +0800 +Subject: [PATCH 101/108] scsi: hisi_sas: Add slave_destroy interface for v3 hw + +driver inclusion +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81U +CVE: NA + +---------------------------------------------------------------------- + +A WARNING is triggered when executing link reset of remote PHY +and rmmod SAS driver simultaneously. Following is the WARNING log: + +WARNING: CPU: 61 PID: 21818 at drivers/base/core.c:1347 __device_links_no_driver+0xb4/0xc0 + Call trace: + __device_links_no_driver+0xb4/0xc0 + device_links_driver_cleanup+0xb0/0xfc + __device_release_driver+0x198/0x23c + device_release_driver+0x38/0x50 + bus_remove_device+0x130/0x140 + device_del+0x184/0x434 + __scsi_remove_device+0x118/0x150 + scsi_remove_target+0x1bc/0x240 + sas_rphy_remove+0x90/0x94 + sas_rphy_delete+0x24/0x3c + sas_destruct_devices+0x64/0xa0 [libsas] + sas_revalidate_domain+0xe4/0x150 [libsas] + process_one_work+0x1e0/0x46c + worker_thread+0x15c/0x464 + kthread+0x160/0x170 + ret_from_fork+0x10/0x20 + ---[ end trace 71e059eb58f85d4a ]--- + +During SAS phy up, link->status is set to DL_STATE_AVAILABLE in +device_links_driver_bound, then this setting influences +__device_links_no_driver() before driver rmmod and caused WARNING. + +So we add the slave_destroy interface, to make sure link is removed +after flush workque. + +Fixes: 16fd4a7c59170 ("scsi: hisi_sas: Add device link between SCSI devices and hisi_hba") +Signed-off-by: Qi Liu +Signed-off-by: John Garry +Signed-off-by: xiabing +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 5bb3f0466338..e3fb9a9cd875 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3212,6 +3212,17 @@ static int slave_configure_v3_hw(struct scsi_device *sdev) + + return 0; + } ++ ++static void slave_destroy_v3_hw(struct scsi_device *sdev) ++{ ++ struct Scsi_Host *shost = dev_to_shost(&sdev->sdev_gendev); ++ struct hisi_hba *hisi_hba = shost_priv(shost); ++ struct device *dev = hisi_hba->dev; ++ ++ device_link_remove(&sdev->sdev_gendev, dev); ++} ++ ++ + #define HISI_SAS_DEBUGFS_REG(x) {#x, x} + + struct hisi_sas_debugfs_reg_lu { +@@ -3613,6 +3624,7 @@ static struct scsi_host_template sht_v3_hw = { + .eh_device_reset_handler = sas_eh_device_reset_handler, + .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = hisi_sas_slave_alloc, ++ .slave_destroy = slave_destroy_v3_hw, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, + .shost_attrs = host_attrs_v3_hw, +-- +2.27.0 + diff --git a/patches/0750-scsi-hisi_sas-Block-requests-before-take-debugfs-sna.patch b/patches/0750-scsi-hisi_sas-Block-requests-before-take-debugfs-sna.patch new file mode 100644 index 0000000..f6376da --- /dev/null +++ b/patches/0750-scsi-hisi_sas-Block-requests-before-take-debugfs-sna.patch @@ -0,0 +1,68 @@ +From 71ee4048cf244043c9b67398e05a8f9fb3cd2e23 Mon Sep 17 00:00:00 2001 +From: Yihang Li +Date: Thu, 8 Jun 2023 11:04:49 +0800 +Subject: [PATCH 102/108] scsi: hisi_sas: Block requests before take debugfs + snapshot + +driver inclusion +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F82P +CVE: NA + +---------------------------------------------------------------------- + +When the FIO is running and the dump is triggered continuously, some SATA +I/Os fail to be returned to the upper layer due to the setting of +HISI_SAS_REJECT_CMD_BIT. The SCSI layer invokes the error processing +thread. However, sas_ata_hard_reset() also fails to be reset due to the +setting of HISI_SAS_REJECT_CMD_BIT. As a result, the device is disabled. +Call scsi_block_requests() and wait command complete before setting +HISI_SAS_REJECT_CMD_BIT to avoid SATA I/O failures. + +Signed-off-by: Yihang Li +Signed-off-by: xiabing +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index e3fb9a9cd875..dc24bf2ad2c0 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3409,22 +3409,25 @@ static const struct hisi_sas_debugfs_reg debugfs_ras_reg = { + + static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) + { +- set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); +- +- hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0); ++ struct Scsi_Host *shost = hisi_hba->shost; + ++ scsi_block_requests(shost); + /* delay:100ms, timeout:5s */ + wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000); +- ++ set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + hisi_sas_sync_irqs(hisi_hba); ++ hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0); + } + + static void debugfs_snapshot_restore_v3_hw(struct hisi_hba *hisi_hba) + { ++ struct Scsi_Host *shost = hisi_hba->shost; ++ + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, + (u32)((1ULL << hisi_hba->queue_count) - 1)); + + clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); ++ scsi_unblock_requests(shost); + } + + static void hisi_sas_bist_test_prep_v3_hw(struct hisi_hba *hisi_hba) +-- +2.27.0 + diff --git a/patches/0751-scsi-hisi_sas-Work-around-build-failure-in-suspend-f.patch b/patches/0751-scsi-hisi_sas-Work-around-build-failure-in-suspend-f.patch new file mode 100644 index 0000000..039c9d0 --- /dev/null +++ b/patches/0751-scsi-hisi_sas-Work-around-build-failure-in-suspend-f.patch @@ -0,0 +1,81 @@ +From a4b0d9775e1555a3f65947c5fefc3c0cc4840d9a Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 8 Jun 2023 20:00:00 +0800 +Subject: [PATCH 103/108] scsi: hisi_sas: Work around build failure in suspend + function + +mainline inclusion +from mainline-v6.4-rc1 +commit e01e2290f0948ea6d383a5b715738911308b4d2b +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F803 + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e01e2290f0948ea6d383a5b715738911308b4d2b + +---------------------------------------------------------------------- + +The suspend/resume functions in this driver seem to have multiple problems, +the latest one just got introduced by a bugfix: + +drivers/scsi/hisi_sas/hisi_sas_v3_hw.c: In function '_suspend_v3_hw': +drivers/scsi/hisi_sas/hisi_sas_v3_hw.c:5142:39: error: 'struct dev_pm_info' has no member named 'usage_count' + 5142 | if (atomic_read(&device->power.usage_count)) { +drivers/scsi/hisi_sas/hisi_sas_v3_hw.c: In function '_suspend_v3_hw': +drivers/scsi/hisi_sas/hisi_sas_v3_hw.c:5142:39: error: 'struct dev_pm_info' has no member named 'usage_count' + 5142 | if (atomic_read(&device->power.usage_count)) { + +As far as I can tell, the 'usage_count' is not meant to be accessed by +device drivers at all, though I don't know what the driver is supposed to +do instead. + +Another problem is the use of the deprecated UNIVERSAL_DEV_PM_OPS(), and +marking functions as __maybe_unused to avoid warnings about unused +functions. This should probably be changed to using +DEFINE_RUNTIME_DEV_PM_OPS(). + +Both changes require actually understanding what the driver needs to do, +and being able to test this, so instead here is the simplest patch to make +it pass the randconfig builds instead. + +Fixes: e368d38cb952 ("scsi: hisi_sas: Exit suspend state when usage count is greater than 0") +Signed-off-by: Arnd Bergmann +Link: https://lore.kernel.org/r/20230405083611.3376739-1-arnd@kernel.org +Reviewed-by: Xiang Chen +Signed-off-by: Martin K. Petersen +Signed-off-by: xiabing +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index dc24bf2ad2c0..e286bfc14eca 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -5441,11 +5441,13 @@ static int _suspend_v3_hw(struct device *device) + flush_workqueue(hisi_hba->wq); + interrupt_disable_v3_hw(hisi_hba); + ++#ifdef CONFIG_PM + if (atomic_read(&device->power.usage_count)) { + dev_err(dev, "PM suspend: host status cannot be suspended\n"); + rc = -EBUSY; + goto err_out; + } ++#endif + + rc = disable_host_v3_hw(hisi_hba); + if (rc) { +@@ -5471,7 +5473,9 @@ static int _suspend_v3_hw(struct device *device) + + err_out_recover_host: + enable_host_v3_hw(hisi_hba); ++#ifdef CONFIG_PM + err_out: ++#endif + interrupt_enable_v3_hw(hisi_hba); + clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); +-- +2.27.0 + diff --git a/patches/0752-scsi-hisi_sas-Check-usage-count-only-when-the-runtim.patch b/patches/0752-scsi-hisi_sas-Check-usage-count-only-when-the-runtim.patch new file mode 100644 index 0000000..5d68749 --- /dev/null +++ b/patches/0752-scsi-hisi_sas-Check-usage-count-only-when-the-runtim.patch @@ -0,0 +1,62 @@ +From 75e571e9d7ab42b0a9551ec0219045be5c365d60 Mon Sep 17 00:00:00 2001 +From: Yihang Li +Date: Thu, 8 Jun 2023 11:04:51 +0800 +Subject: [PATCH 104/108] scsi: hisi_sas: Check usage count only when the + runtime PM status is RPM_SUSPENDING + +driver inclusion +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F803 +CVE: NA + +---------------------------------------------------------------------- + +Users can suspend the machine with 'echo disk > /sys/power/state', but the +suspend will fail because the SAS controller cannot be suspended: + +[root@localhost ~]# echo freeze > /sys/power/state +-bash: echo: write error: Device or resource busy +[15104.142955] PM: suspend entry (s2idle) +... +[15104.283465] hisi_sas_v3_hw 0000:32:04.0: entering suspend state +[15104.283480] hisi_sas_v3_hw 0000:30:04.0: entering suspend state +[15104.283500] hisi_sas_v3_hw 0000:32:04.0: PM suspend: host status cannot be suspended +[15104.283508] hisi_sas_v3_hw 0000:30:04.0: PM suspend: host status cannot be suspended +[15104.283516] hisi_sas_v3_hw 0000:32:04.0: PM: pci_pm_suspend(): suspend_v3_hw+0x0/0x210 [hisi_sas_v3_hw] returns -16 +[15104.283527] hisi_sas_v3_hw 0000:32:04.0: PM: dpm_run_callback(): pci_pm_suspend+0x0/0x1c0 returns -16 +[15104.283524] hisi_sas_v3_hw 0000:30:04.0: PM: pci_pm_suspend(): suspend_v3_hw+0x0/0x210 [hisi_sas_v3_hw] returns -16 +[15104.283533] hisi_sas_v3_hw 0000:32:04.0: PM: failed to suspend async: error -16 +[15104.283536] hisi_sas_v3_hw 0000:30:04.0: PM: dpm_run_callback(): pci_pm_suspend+0x0/0x1c0 returns -16 +[15104.283542] hisi_sas_v3_hw 0000:30:04.0: PM: failed to suspend async: error -16 + +The problem is that when the ->runtime_suspend() callback suspend_v3_hw() +is executing, the current runtime PM status is RPM_ACTIVE and the usage +count of the controller is not 0, so return immediately. + +To fix it, Check the device usage count only when the runtime PM status is +RPM_SUSPENDING. + +Signed-off-by: Yihang Li +Signed-off-by: xiabing +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index e286bfc14eca..373a820f7808 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -5442,7 +5442,8 @@ static int _suspend_v3_hw(struct device *device) + interrupt_disable_v3_hw(hisi_hba); + + #ifdef CONFIG_PM +- if (atomic_read(&device->power.usage_count)) { ++ if ((device->power.runtime_status == RPM_SUSPENDING) && ++ atomic_read(&device->power.usage_count)) { + dev_err(dev, "PM suspend: host status cannot be suspended\n"); + rc = -EBUSY; + goto err_out; +-- +2.27.0 + diff --git a/patches/0753-scsi-hisi_sas_v3_hw-Don-t-use-PCI-helper-functions.patch b/patches/0753-scsi-hisi_sas_v3_hw-Don-t-use-PCI-helper-functions.patch new file mode 100644 index 0000000..06ef2b9 --- /dev/null +++ b/patches/0753-scsi-hisi_sas_v3_hw-Don-t-use-PCI-helper-functions.patch @@ -0,0 +1,91 @@ +From 472a4cae39ed9b327178b22ac5b8702def5ac8a3 Mon Sep 17 00:00:00 2001 +From: Vaibhav Gupta +Date: Tue, 3 Aug 2021 14:47:24 +0800 +Subject: [PATCH 105/108] scsi: hisi_sas_v3_hw: Don't use PCI helper functions + +mainline inclusion +from mainline-v5.11-rc1 +commit 027e508aea458719390eb6a83a297940e8ae79f1 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81U +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=027e508aea458719390eb6a83a297940e8ae79f1 + +------------------------------------------------------------------------ + +Drivers using new-framework/generic-framework should not handle standard +power management operations. These operations were performed by legacy +framework through PCI helper functions like pci_save/restore_state(), +pci_set_power_state(), etc. + +Drivers should not use them now. + +Link: https://lore.kernel.org/r/20201102164730.324035-14-vaibhavgupta40@gmail.com +Signed-off-by: Vaibhav Gupta +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 18 +----------------- + 1 file changed, 1 insertion(+), 17 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 373a820f7808..0d5135fb0b37 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -5423,7 +5423,6 @@ static int _suspend_v3_hw(struct device *device) + struct hisi_hba *hisi_hba = sha->lldd_ha; + struct device *dev = hisi_hba->dev; + struct Scsi_Host *shost = hisi_hba->shost; +- u32 device_state; + int rc; + + if (!pdev->pm_cap) { +@@ -5458,12 +5457,7 @@ static int _suspend_v3_hw(struct device *device) + + hisi_sas_init_mem(hisi_hba); + +- device_state = pci_choose_state(pdev, PMSG_SUSPEND); +- dev_warn(dev, "entering operating state [D%d]\n", +- device_state); +- pci_save_state(pdev); +- pci_disable_device(pdev); +- pci_set_power_state(pdev, device_state); ++ dev_warn(dev, "entering suspend state\n"); + + hisi_sas_release_tasks(hisi_hba); + +@@ -5496,16 +5490,7 @@ static int _resume_v3_hw(struct device *device) + + dev_warn(dev, "resuming from operating state [D%d]\n", + device_state); +- pci_set_power_state(pdev, PCI_D0); +- pci_enable_wake(pdev, PCI_D0, 0); +- pci_restore_state(pdev); +- rc = pci_enable_device(pdev); +- if (rc) { +- dev_err(dev, "enable device failed during resume (%d)\n", rc); +- return rc; +- } + +- pci_set_master(pdev); + scsi_unblock_requests(shost); + clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + +@@ -5513,7 +5498,6 @@ static int _resume_v3_hw(struct device *device) + rc = hw_init_v3_hw(hisi_hba); + if (rc) { + scsi_remove_host(shost); +- pci_disable_device(pdev); + return rc; + } + phys_init_v3_hw(hisi_hba); +-- +2.27.0 + diff --git a/patches/0754-scsi-hisi_sas_v3_hw-Remove-extra-function-calls-for-.patch b/patches/0754-scsi-hisi_sas_v3_hw-Remove-extra-function-calls-for-.patch new file mode 100644 index 0000000..57fce6a --- /dev/null +++ b/patches/0754-scsi-hisi_sas_v3_hw-Remove-extra-function-calls-for-.patch @@ -0,0 +1,89 @@ +From 17bc9c66f66d914e10cae2d2acb31b9a0d3cc1ed Mon Sep 17 00:00:00 2001 +From: Vaibhav Gupta +Date: Tue, 3 Aug 2021 14:47:25 +0800 +Subject: [PATCH 106/108] scsi: hisi_sas_v3_hw: Remove extra function calls for + runtime pm + +mainline inclusion +from mainline-v5.11-rc1 +commit 71c8f15e1dbcd202f0b27d7560ce191c5a3b7286 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81U +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=71c8f15e1dbcd202f0b27d7560ce191c5a3b7286 + +------------------------------------------------------------------------ + +Both runtime_suspend_v3_hw() and runtime_resume_v3_hw() do nothing else but +invoke suspend_v3_hw() and resume_v3_hw() respectively. This is the case of +unnecessary function calls. To use those functions for runtime pm as well, +simply use UNIVERSAL_DEV_PM_OPS. + +make -j$(nproc) W=1, with CONFIG_PM disabled, throws '-Wunused-function' +warning for runtime_suspend_v3_hw() and runtime_resume_v3_hw(). After +dropping those function definitions, the warning was thrown for +suspend_v3_hw() and resume_v3_hw(). Hence, mark them as '__maybe_unused'. + +Link: https://lore.kernel.org/r/20201102164730.324035-15-vaibhavgupta40@gmail.com +Signed-off-by: Vaibhav Gupta +Signed-off-by: Martin K. Petersen +Reviewed-by: Ouyangdelong +Signed-off-by: Nifujia +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 23 ++++++----------------- + 1 file changed, 6 insertions(+), 17 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 0d5135fb0b37..db43cd17b615 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -5509,7 +5509,7 @@ static int _resume_v3_hw(struct device *device) + return 0; + } + +-static int suspend_v3_hw(struct device *device) ++static int __maybe_unused suspend_v3_hw(struct device *device) + { + struct pci_dev *pdev = to_pci_dev(device); + struct sas_ha_struct *sha = pci_get_drvdata(pdev); +@@ -5525,7 +5525,7 @@ static int suspend_v3_hw(struct device *device) + return rc; + } + +-static int resume_v3_hw(struct device *device) ++static int __maybe_unused resume_v3_hw(struct device *device) + { + struct pci_dev *pdev = to_pci_dev(device); + struct sas_ha_struct *sha = pci_get_drvdata(pdev); +@@ -5548,21 +5548,10 @@ static const struct pci_error_handlers hisi_sas_err_handler = { + .reset_done = hisi_sas_reset_done_v3_hw, + }; + +-static int runtime_suspend_v3_hw(struct device *dev) +-{ +- return suspend_v3_hw(dev); +-} +- +-static int runtime_resume_v3_hw(struct device *dev) +-{ +- return resume_v3_hw(dev); +-} +- +-static const struct dev_pm_ops hisi_sas_v3_pm_ops = { +- SET_SYSTEM_SLEEP_PM_OPS(suspend_v3_hw, resume_v3_hw) +- SET_RUNTIME_PM_OPS(runtime_suspend_v3_hw, +- runtime_resume_v3_hw, NULL) +-}; ++static UNIVERSAL_DEV_PM_OPS(hisi_sas_v3_pm_ops, ++ suspend_v3_hw, ++ resume_v3_hw, ++ NULL); + + static struct pci_driver sas_v3_pci_driver = { + .name = DRV_NAME, +-- +2.27.0 + diff --git a/patches/0755-config-arm64-Enable-dubugfs-config-of-hisi-sas.patch b/patches/0755-config-arm64-Enable-dubugfs-config-of-hisi-sas.patch new file mode 100644 index 0000000..4ce7334 --- /dev/null +++ b/patches/0755-config-arm64-Enable-dubugfs-config-of-hisi-sas.patch @@ -0,0 +1,34 @@ +From abcb449a6f7f5c70e9909eb87718e4ca6fbc5c79 Mon Sep 17 00:00:00 2001 +From: YunYi Yang +Date: Mon, 20 Nov 2023 10:16:31 +0800 +Subject: [PATCH 107/108] config: arm64: Enable dubugfs config of hisi sas + +driver inclusion +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F81L + +---------------------------------------------------------------------------- + +Enable dubugfs config of hisi sas. Set +CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE to y. + +Signed-off-by: YunYi Yang +--- + arch/arm64/configs/openeuler_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig +index b89c386c1bc7..f3b055bc18f0 100644 +--- a/arch/arm64/configs/openeuler_defconfig ++++ b/arch/arm64/configs/openeuler_defconfig +@@ -2134,6 +2134,7 @@ CONFIG_SCSI_AACRAID=m + # CONFIG_SCSI_AIC94XX is not set + CONFIG_SCSI_HISI_SAS=m + CONFIG_SCSI_HISI_SAS_PCI=m ++CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE=y + # CONFIG_SCSI_MVSAS is not set + # CONFIG_SCSI_MVUMI is not set + # CONFIG_SCSI_ADVANSYS is not set +-- +2.27.0 + diff --git a/series.conf b/series.conf index 9da341a..866340f 100644 --- a/series.conf +++ b/series.conf @@ -649,3 +649,110 @@ patches/0645-irqchip-gic-v3-Collection-table-support-muti-pages.patch patches/0646-genirq-Increase-the-number-of-IRQ-descriptors.patch patches/0647-cpufreq-change-.set_boost-to-act-on-one-policy.patch patches/0648-cpufreq-CPPC-add-SW-BOOST-support.patch +patches/0649-scsi-hisi_sas-No-need-to-check-return-value-of-debug.patch +patches/0650-scsi-hisi_sas-Fix-type-casting-and-missing-static-qu.patch +patches/0651-scsi-hisi_sas-Fix-losing-directly-attached-disk-when.patch +patches/0652-scsi-hisi_sas-Use-pci_irq_get_affinity-for-v3-hw-as-.patch +patches/0653-scsi-hisi_sas-Some-misc-tidy-up.patch +patches/0654-scsi-hisi_sas-Make-max-IPTT-count-equal-for-all-hw-r.patch +patches/0655-scsi-hisi_sas-Fix-pointer-usage-error-in-show-debugf.patch +patches/0656-scsi-hisi_sas-Snapshot-HW-cache-of-IOST-and-ITCT-at-.patch +patches/0657-scsi-hisi_sas-Snapshot-AXI-and-RAS-register-at-debug.patch +patches/0658-scsi-hisi_sas-Drop-kmap_atomic-in-SMP-command-comple.patch +patches/0659-scsi-hisi_sas-Drop-SMP-resp-frame-DMA-mapping.patch +patches/0660-scsi-hisi_sas-Drop-free_irq-when-devm_request_irq-fa.patch +patches/0661-scsi-hisi_sas-Modify-return-type-of-debugfs-function.patch +patches/0662-scsi-hisi_sas-Remove-some-unnecessary-code.patch +patches/0663-scsi-hisi_sas-remove-set-but-not-used-variable-irq_v.patch +patches/0664-scsi-hisi_sas-use-devm_platform_ioremap_resource-to-.patch +patches/0665-scsi-hisi_sas-add-debugfs-auto-trigger-for-internal-.patch +patches/0666-scsi-hisi_sas-Remove-hisi_sas_hw.slot_complete.patch +patches/0667-scsi-hisi_sas-Remove-redundant-work-declaration.patch +patches/0668-scsi-hisi_sas-Remove-some-unused-function-arguments.patch +patches/0669-scsi-hisi_sas-Add-hisi_sas_debugfs_alloc-to-centrali.patch +patches/0670-scsi-hisi_sas-fix-spelling-mistake-digial-digital.patch +patches/0671-scsi-hisi_sas-Make-three-functions-static.patch +patches/0672-scsi-hisi_sas-Don-t-create-debugfs-dump-folder-twice.patch +patches/0673-scsi-hisi_sas-Add-timestamp-for-a-debugfs-dump.patch +patches/0674-scsi-hisi_sas-Add-debugfs-file-structure-for-CQ.patch +patches/0675-scsi-hisi_sas-Add-debugfs-file-structure-for-DQ.patch +patches/0676-scsi-hisi_sas-Add-debugfs-file-structure-for-registe.patch +patches/0677-scsi-hisi_sas-Add-debugfs-file-structure-for-port.patch +patches/0678-scsi-hisi_sas-Add-debugfs-file-structure-for-IOST.patch +patches/0679-scsi-hisi_sas-Add-debugfs-file-structure-for-ITCT.patch +patches/0680-scsi-hisi_sas-Add-debugfs-file-structure-for-IOST-ca.patch +patches/0681-scsi-hisi_sas-Add-debugfs-file-structure-for-ITCT-ca.patch +patches/0682-scsi-hisi_sas-Allocate-memory-for-multiple-dumps-of-.patch +patches/0683-scsi-hisi_sas-Add-module-parameter-for-debugfs-dump-.patch +patches/0684-scsi-hisi_sas-Add-ability-to-have-multiple-debugfs-d.patch +patches/0685-scsi-hisi_sas-Delete-the-debugfs-folder-of-hisi_sas-.patch +patches/0686-scsi-hisi_sas-Record-the-phy-down-event-in-debugfs.patch +patches/0687-scsi-hisi_sas-Return-directly-if-init-hardware-faile.patch +patches/0688-scsi-hisi_sas-Stop-converting-a-bool-into-a-bool.patch +patches/0689-scsi-hisi_sas-Replace-magic-number-when-handle-chann.patch +patches/0690-scsi-hisi_sas-Modify-the-file-permissions-of-trigger.patch +patches/0691-scsi-hisi_sas-Add-prints-for-v3-hw-interrupt-converg.patch +patches/0692-scsi-hisi_sas-Use-dev_err-in-read_iost_itct_cache_v3.patch +patches/0693-scsi-hisi_sas-Fix-build-error-without-SATA_HOST.patch +patches/0694-scsi-hisi_sas-Display-proc_name-in-sysfs.patch +patches/0695-scsi-hisi_sas-Modify-the-commit-information-for-DSM-.patch +patches/0696-scsi-hisi_sas-Add-SAS_RAS_INTR0-to-debugfs-register-.patch +patches/0697-scsi-hisi_sas-Stop-returning-error-code-from-slot_co.patch +patches/0698-scsi-hisi_sas-Do-not-reset-phy-timer-to-wait-for-str.patch +patches/0699-scsi-hisi_sas-Remove-one-kerneldoc-comment.patch +patches/0700-scsi-hisi_sas-Modify-macro-name-for-OOB-phy-linkrate.patch +patches/0701-scsi-hisi_sas-Do-not-modify-upper-fields-of-PROG_PHY.patch +patches/0702-scsi-hisi_sas-Make-phy-index-variable-name-consisten.patch +patches/0703-scsi-hisi_sas-Add-BIST-support-for-phy-FFE.patch +patches/0704-scsi-hisi_sas-Add-BIST-support-for-fixed-code-patter.patch +patches/0705-scsi-hisi_sas-Add-missing-newlines.patch +patches/0706-scsi-hisi_sas-Code-style-cleanup.patch +patches/0707-scsi-hisi_sas-Switch-to-new-framework-to-support-sus.patch +patches/0708-scsi-hisi_sas-Add-controller-runtime-PM-support-for-.patch +patches/0709-scsi-hisi_sas-Add-check-for-methods-_PS0-and-_PR0.patch +patches/0710-scsi-hisi_sas-Add-device-link-between-SCSI-devices-a.patch +patches/0711-scsi-hisi_sas-Recover-PHY-state-according-to-the-sta.patch +patches/0712-scsi-hisi_sas-Fix-up-probe-error-handling-for-v3-hw.patch +patches/0713-scsi-hisi_sas-Reduce-some-indirection-in-v3-hw-drive.patch +patches/0714-scsi-hisi_sas-Move-debugfs-code-to-v3-hw-driver.patch +patches/0715-scsi-hisi_sas-Remove-preemptible.patch +patches/0716-scsi-hisi_sas-use-threaded-irq-to-process-CQ-interru.patch +patches/0717-scsi-hisi_sas-Remove-deferred-probe-check-in-hisi_sa.patch +patches/0718-scsi-hisi_sas-Enable-debugfs-support-by-default.patch +patches/0719-scsi-hisi_sas-Add-trace-FIFO-debugfs-support.patch +patches/0720-scsi-hisi_sas-Print-SAS-address-for-v3-hw-erroneous-.patch +patches/0721-scsi-hisi_sas-Call-sas_unregister_ha-to-roll-back-if.patch +patches/0722-scsi-hisi_sas-Directly-snapshot-registers-when-execu.patch +patches/0723-scsi-hisi_sas-Warn-in-v3-hw-channel-interrupt-handle.patch +patches/0724-scsi-hisi_sas-Print-SATA-device-SAS-address-for-soft.patch +patches/0725-scsi-hisi_sas-Put-a-limit-of-link-reset-retries.patch +patches/0726-scsi-hisi_sas-Run-I_T-nexus-resets-in-parallel-for-c.patch +patches/0727-scsi-hisi_sas-Include-HZ-in-timer-macros.patch +patches/0728-scsi-hisi_sas-Reset-controller-for-internal-abort-ti.patch +patches/0729-scsi-hisi_sas-Speed-up-error-handling-when-internal-.patch +patches/0730-scsi-hisi_sas-Initialise-devices-in-.slave_alloc-cal.patch +patches/0731-scsi-hisi_sas-Wait-for-phyup-in-hisi_sas_control_phy.patch +patches/0732-scsi-hisi_sas-Add-more-logs-for-runtime-suspend-resu.patch +patches/0733-scsi-hisi_sas-Keep-controller-active-between-ISR-of-.patch +patches/0734-scsi-hisi_sas-Use-autosuspend-for-the-host-controlle.patch +patches/0735-scsi-hisi_sas-Limit-users-changing-debugfs-BIST-coun.patch +patches/0736-scsi-hisi_sas-Prevent-parallel-controller-reset-and-.patch +patches/0737-scsi-hisi_sas-Fix-phyup-timeout-on-FPGA.patch +patches/0738-scsi-hisi_sas-Modify-v3-HW-SSP-underflow-error-proce.patch +patches/0739-scsi-hisi_sas-Fix-rescan-after-deleting-a-disk.patch +patches/0740-scsi-hisi_sas-Undo-RPM-resume-for-failed-notify-phy-.patch +patches/0741-scsi-hisi_sas-Use-abort-task-set-to-reset-SAS-disks-.patch +patches/0742-scsi-hisi_sas-Disable-SATA-disk-phy-for-severe-I_T-n.patch +patches/0743-Revert-scsi-hisi_sas-Disable-SATA-disk-phy-for-sever.patch +patches/0744-scsi-hisi_sas-Set-a-port-invalid-only-if-there-are-n.patch +patches/0745-scsi-hisi_sas-Exit-suspending-state-when-usage-count.patch +patches/0746-scsi-hisi_sas-Ensure-all-enabled-PHYs-up-during-cont.patch +patches/0747-scsi-hisi_sas-Increase-debugfs_dump_index-after-dump.patch +patches/0748-scsi-hisi_sas-Configure-the-initialization-registers.patch +patches/0749-scsi-hisi_sas-Add-slave_destroy-interface-for-v3-hw.patch +patches/0750-scsi-hisi_sas-Block-requests-before-take-debugfs-sna.patch +patches/0751-scsi-hisi_sas-Work-around-build-failure-in-suspend-f.patch +patches/0752-scsi-hisi_sas-Check-usage-count-only-when-the-runtim.patch +patches/0753-scsi-hisi_sas_v3_hw-Don-t-use-PCI-helper-functions.patch +patches/0754-scsi-hisi_sas_v3_hw-Remove-extra-function-calls-for-.patch +patches/0755-config-arm64-Enable-dubugfs-config-of-hisi-sas.patch