From 98889e0c48625c65655d3b45f695212ba18ff3ca Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 1 Apr 2024 12:34:05 +0200 Subject: [PATCH] 6.6-stable patches added patches: scsi-qla2xxx-change-debug-message-during-driver-unload.patch scsi-qla2xxx-delay-i-o-abort-on-pci-error.patch scsi-qla2xxx-fix-command-flush-on-cable-pull.patch scsi-qla2xxx-fix-double-free-of-fcport.patch scsi-qla2xxx-fix-double-free-of-the-ha-vp_map-pointer.patch scsi-qla2xxx-fix-n2n-stuck-connection.patch scsi-qla2xxx-nvme-fcp-prefer-flag-not-being-honored.patch scsi-qla2xxx-prevent-command-send-on-chip-reset.patch scsi-qla2xxx-split-fce-eft-trace-control.patch scsi-qla2xxx-update-manufacturer-detail.patch usb-core-add-hub_get-and-hub_put-routines.patch usb-core-fix-deadlock-in-port-disable-sysfs-attribute.patch usb-core-fix-deadlock-in-usb_deauthorize_interface.patch usb-dwc2-gadget-fix-exiting-from-clock-gating.patch usb-dwc2-gadget-lpm-flow-fix.patch usb-dwc2-host-fix-hibernation-flow.patch usb-dwc2-host-fix-isoc-flow-in-ddma-mode.patch usb-dwc2-host-fix-remote-wakeup-from-hibernation.patch usb-dwc3-properly-set-system-wakeup.patch usb-typec-return-size-of-buffer-if-pd_set-operation-succeeds.patch usb-typec-ucsi-ack-unsupported-commands.patch usb-typec-ucsi-check-for-notifications-after-init.patch usb-typec-ucsi-clear-event_pending-under-ppm-lock.patch usb-typec-ucsi-clear-ucsi_cci_reset_complete-before-reset.patch usb-typec-ucsi_acpi-refactor-and-fix-dell-quirk.patch usb-udc-remove-warning-when-queue-disabled-ep.patch --- ...e-debug-message-during-driver-unload.patch | 36 +++ ...qla2xxx-delay-i-o-abort-on-pci-error.patch | 57 +++++ ...2xxx-fix-command-flush-on-cable-pull.patch | 94 ++++++++ ...si-qla2xxx-fix-double-free-of-fcport.patch | 79 ++++++ ...double-free-of-the-ha-vp_map-pointer.patch | 36 +++ ...csi-qla2xxx-fix-n2n-stuck-connection.patch | 145 ++++++++++++ ...me-fcp-prefer-flag-not-being-honored.patch | 69 ++++++ ...x-prevent-command-send-on-chip-reset.patch | 115 +++++++++ ...-qla2xxx-split-fce-eft-trace-control.patch | 224 ++++++++++++++++++ ...i-qla2xxx-update-manufacturer-detail.patch | 34 +++ queue-6.6/series | 26 ++ ...ore-add-hub_get-and-hub_put-routines.patch | 113 +++++++++ ...lock-in-port-disable-sysfs-attribute.patch | 123 ++++++++++ ...eadlock-in-usb_deauthorize_interface.patch | 70 ++++++ ...gadget-fix-exiting-from-clock-gating.patch | 97 ++++++++ queue-6.6/usb-dwc2-gadget-lpm-flow-fix.patch | 150 ++++++++++++ .../usb-dwc2-host-fix-hibernation-flow.patch | 94 ++++++++ ...dwc2-host-fix-isoc-flow-in-ddma-mode.patch | 134 +++++++++++ ...t-fix-remote-wakeup-from-hibernation.patch | 66 ++++++ .../usb-dwc3-properly-set-system-wakeup.patch | 128 ++++++++++ ...-buffer-if-pd_set-operation-succeeds.patch | 46 ++++ ...-typec-ucsi-ack-unsupported-commands.patch | 40 ++++ ...i-check-for-notifications-after-init.patch | 64 +++++ ...i-clear-event_pending-under-ppm-lock.patch | 44 ++++ ...ucsi_cci_reset_complete-before-reset.patch | 74 ++++++ ...csi_acpi-refactor-and-fix-dell-quirk.patch | 163 +++++++++++++ ...emove-warning-when-queue-disabled-ep.patch | 44 ++++ 27 files changed, 2365 insertions(+) create mode 100644 queue-6.6/scsi-qla2xxx-change-debug-message-during-driver-unload.patch create mode 100644 queue-6.6/scsi-qla2xxx-delay-i-o-abort-on-pci-error.patch create mode 100644 queue-6.6/scsi-qla2xxx-fix-command-flush-on-cable-pull.patch create mode 100644 queue-6.6/scsi-qla2xxx-fix-double-free-of-fcport.patch create mode 100644 queue-6.6/scsi-qla2xxx-fix-double-free-of-the-ha-vp_map-pointer.patch create mode 100644 queue-6.6/scsi-qla2xxx-fix-n2n-stuck-connection.patch create mode 100644 queue-6.6/scsi-qla2xxx-nvme-fcp-prefer-flag-not-being-honored.patch create mode 100644 queue-6.6/scsi-qla2xxx-prevent-command-send-on-chip-reset.patch create mode 100644 queue-6.6/scsi-qla2xxx-split-fce-eft-trace-control.patch create mode 100644 queue-6.6/scsi-qla2xxx-update-manufacturer-detail.patch create mode 100644 queue-6.6/usb-core-add-hub_get-and-hub_put-routines.patch create mode 100644 queue-6.6/usb-core-fix-deadlock-in-port-disable-sysfs-attribute.patch create mode 100644 queue-6.6/usb-core-fix-deadlock-in-usb_deauthorize_interface.patch create mode 100644 queue-6.6/usb-dwc2-gadget-fix-exiting-from-clock-gating.patch create mode 100644 queue-6.6/usb-dwc2-gadget-lpm-flow-fix.patch create mode 100644 queue-6.6/usb-dwc2-host-fix-hibernation-flow.patch create mode 100644 queue-6.6/usb-dwc2-host-fix-isoc-flow-in-ddma-mode.patch create mode 100644 queue-6.6/usb-dwc2-host-fix-remote-wakeup-from-hibernation.patch create mode 100644 queue-6.6/usb-dwc3-properly-set-system-wakeup.patch create mode 100644 queue-6.6/usb-typec-return-size-of-buffer-if-pd_set-operation-succeeds.patch create mode 100644 queue-6.6/usb-typec-ucsi-ack-unsupported-commands.patch create mode 100644 queue-6.6/usb-typec-ucsi-check-for-notifications-after-init.patch create mode 100644 queue-6.6/usb-typec-ucsi-clear-event_pending-under-ppm-lock.patch create mode 100644 queue-6.6/usb-typec-ucsi-clear-ucsi_cci_reset_complete-before-reset.patch create mode 100644 queue-6.6/usb-typec-ucsi_acpi-refactor-and-fix-dell-quirk.patch create mode 100644 queue-6.6/usb-udc-remove-warning-when-queue-disabled-ep.patch diff --git a/queue-6.6/scsi-qla2xxx-change-debug-message-during-driver-unload.patch b/queue-6.6/scsi-qla2xxx-change-debug-message-during-driver-unload.patch new file mode 100644 index 00000000000..0ba0da83e1f --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-change-debug-message-during-driver-unload.patch @@ -0,0 +1,36 @@ +From b5a30840727a3e41d12a336d19f6c0716b299161 Mon Sep 17 00:00:00 2001 +From: Saurav Kashyap +Date: Tue, 27 Feb 2024 22:11:25 +0530 +Subject: scsi: qla2xxx: Change debug message during driver unload + +From: Saurav Kashyap + +commit b5a30840727a3e41d12a336d19f6c0716b299161 upstream. + +Upon driver unload, purge_mbox flag is set and the heartbeat monitor thread +detects this flag and does not send the mailbox command down to FW with a +debug message "Error detected: purge[1] eeh[0] cmd=0x0, Exiting". This +being not a real error, change the debug message. + +Cc: stable@vger.kernel.org +Signed-off-by: Saurav Kashyap +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-10-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_mbx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/qla2xxx/qla_mbx.c ++++ b/drivers/scsi/qla2xxx/qla_mbx.c +@@ -194,7 +194,7 @@ qla2x00_mailbox_command(scsi_qla_host_t + if (ha->flags.purge_mbox || chip_reset != ha->chip_reset || + ha->flags.eeh_busy) { + ql_log(ql_log_warn, vha, 0xd035, +- "Error detected: purge[%d] eeh[%d] cmd=0x%x, Exiting.\n", ++ "Purge mbox: purge[%d] eeh[%d] cmd=0x%x, Exiting.\n", + ha->flags.purge_mbox, ha->flags.eeh_busy, mcp->mb[0]); + rval = QLA_ABORTED; + goto premature_exit; diff --git a/queue-6.6/scsi-qla2xxx-delay-i-o-abort-on-pci-error.patch b/queue-6.6/scsi-qla2xxx-delay-i-o-abort-on-pci-error.patch new file mode 100644 index 00000000000..2eef9de8753 --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-delay-i-o-abort-on-pci-error.patch @@ -0,0 +1,57 @@ +From 591c1fdf2016d118b8fbde427b796fac13f3f070 Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:26 +0530 +Subject: scsi: qla2xxx: Delay I/O Abort on PCI error + +From: Quinn Tran + +commit 591c1fdf2016d118b8fbde427b796fac13f3f070 upstream. + +Currently when PCI error is detected, I/O is aborted manually through the +ABORT IOCB mechanism which is not guaranteed to succeed. + +Instead, wait for the OS or system to notify driver to wind down I/O +through the pci_error_handlers api. Set eeh_busy flag to pause all traffic +and wait for I/O to drain. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-11-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_attr.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -2741,7 +2741,13 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rp + return; + + if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { +- qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); ++ /* Will wait for wind down of adapter */ ++ ql_dbg(ql_dbg_aer, fcport->vha, 0x900c, ++ "%s pci offline detected (id %06x)\n", __func__, ++ fcport->d_id.b24); ++ qla_pci_set_eeh_busy(fcport->vha); ++ qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, ++ 0, WAIT_TARGET); + return; + } + } +@@ -2763,7 +2769,11 @@ qla2x00_terminate_rport_io(struct fc_rpo + vha = fcport->vha; + + if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { +- qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); ++ /* Will wait for wind down of adapter */ ++ ql_dbg(ql_dbg_aer, fcport->vha, 0x900b, ++ "%s pci offline detected (id %06x)\n", __func__, ++ fcport->d_id.b24); ++ qla_pci_set_eeh_busy(vha); + qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, + 0, WAIT_TARGET); + return; diff --git a/queue-6.6/scsi-qla2xxx-fix-command-flush-on-cable-pull.patch b/queue-6.6/scsi-qla2xxx-fix-command-flush-on-cable-pull.patch new file mode 100644 index 00000000000..40686b39c35 --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-fix-command-flush-on-cable-pull.patch @@ -0,0 +1,94 @@ +From a27d4d0e7de305def8a5098a614053be208d1aa1 Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:22 +0530 +Subject: scsi: qla2xxx: Fix command flush on cable pull + +From: Quinn Tran + +commit a27d4d0e7de305def8a5098a614053be208d1aa1 upstream. + +System crash due to command failed to flush back to SCSI layer. + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 + PGD 0 P4D 0 + Oops: 0000 [#1] SMP NOPTI + CPU: 27 PID: 793455 Comm: kworker/u130:6 Kdump: loaded Tainted: G OE --------- - - 4.18.0-372.9.1.el8.x86_64 #1 + Hardware name: HPE ProLiant DL360 Gen10/ProLiant DL360 Gen10, BIOS U32 09/03/2021 + Workqueue: nvme-wq nvme_fc_connect_ctrl_work [nvme_fc] + RIP: 0010:__wake_up_common+0x4c/0x190 + Code: 24 10 4d 85 c9 74 0a 41 f6 01 04 0f 85 9d 00 00 00 48 8b 43 08 48 83 c3 08 4c 8d 48 e8 49 8d 41 18 48 39 c3 0f 84 f0 00 00 00 <49> 8b 41 18 89 54 24 08 31 ed 4c 8d 70 e8 45 8b 29 41 f6 c5 04 75 + RSP: 0018:ffff95f3e0cb7cd0 EFLAGS: 00010086 + RAX: 0000000000000000 RBX: ffff8b08d3b26328 RCX: 0000000000000000 + RDX: 0000000000000001 RSI: 0000000000000003 RDI: ffff8b08d3b26320 + RBP: 0000000000000001 R08: 0000000000000000 R09: ffffffffffffffe8 + R10: 0000000000000000 R11: ffff95f3e0cb7a60 R12: ffff95f3e0cb7d20 + R13: 0000000000000003 R14: 0000000000000000 R15: 0000000000000000 + FS: 0000000000000000(0000) GS:ffff8b2fdf6c0000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 0000002f1e410002 CR4: 00000000007706e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 55555554 + Call Trace: + __wake_up_common_lock+0x7c/0xc0 + qla_nvme_ls_req+0x355/0x4c0 [qla2xxx] + qla2xxx [0000:12:00.1]-f084:3: qlt_free_session_done: se_sess 0000000000000000 / sess ffff8ae1407ca000 from port 21:32:00:02:ac:07:ee:b8 loop_id 0x02 s_id 01:02:00 logout 1 keep 0 els_logo 0 + ? __nvme_fc_send_ls_req+0x260/0x380 [nvme_fc] + qla2xxx [0000:12:00.1]-207d:3: FCPort 21:32:00:02:ac:07:ee:b8 state transitioned from ONLINE to LOST - portid=010200. + ? nvme_fc_send_ls_req.constprop.42+0x1a/0x45 [nvme_fc] + qla2xxx [0000:12:00.1]-2109:3: qla2x00_schedule_rport_del 21320002ac07eeb8. rport ffff8ae598122000 roles 1 + ? nvme_fc_connect_ctrl_work.cold.63+0x1e3/0xa7d [nvme_fc] + qla2xxx [0000:12:00.1]-f084:3: qlt_free_session_done: se_sess 0000000000000000 / sess ffff8ae14801e000 from port 21:32:01:02:ad:f7:ee:b8 loop_id 0x04 s_id 01:02:01 logout 1 keep 0 els_logo 0 + ? __switch_to+0x10c/0x450 + ? process_one_work+0x1a7/0x360 + qla2xxx [0000:12:00.1]-207d:3: FCPort 21:32:01:02:ad:f7:ee:b8 state transitioned from ONLINE to LOST - portid=010201. + ? worker_thread+0x1ce/0x390 + ? create_worker+0x1a0/0x1a0 + qla2xxx [0000:12:00.1]-2109:3: qla2x00_schedule_rport_del 21320102adf7eeb8. rport ffff8ae3b2312800 roles 70 + ? kthread+0x10a/0x120 + qla2xxx [0000:12:00.1]-2112:3: qla_nvme_unregister_remote_port: unregister remoteport on ffff8ae14801e000 21320102adf7eeb8 + ? set_kthread_struct+0x40/0x40 + qla2xxx [0000:12:00.1]-2110:3: remoteport_delete of ffff8ae14801e000 21320102adf7eeb8 completed. + ? ret_from_fork+0x1f/0x40 + qla2xxx [0000:12:00.1]-f086:3: qlt_free_session_done: waiting for sess ffff8ae14801e000 logout + +The system was under memory stress where driver was not able to allocate an +SRB to carry out error recovery of cable pull. The failure to flush causes +upper layer to start modifying scsi_cmnd. When the system frees up some +memory, the subsequent cable pull trigger another command flush. At this +point the driver access a null pointer when attempting to DMA unmap the +SGL. + +Add a check to make sure commands are flush back on session tear down to +prevent the null pointer access. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-7-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_target.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -1062,6 +1062,16 @@ void qlt_free_session_done(struct work_s + "%s: sess %p logout completed\n", __func__, sess); + } + ++ /* check for any straggling io left behind */ ++ if (!(sess->flags & FCF_FCP2_DEVICE) && ++ qla2x00_eh_wait_for_pending_commands(sess->vha, sess->d_id.b24, 0, WAIT_TARGET)) { ++ ql_log(ql_log_warn, vha, 0x3027, ++ "IO not return. Resetting.\n"); ++ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); ++ qla2xxx_wake_dpc(vha); ++ qla2x00_wait_for_chip_reset(vha); ++ } ++ + if (sess->logo_ack_needed) { + sess->logo_ack_needed = 0; + qla24xx_async_notify_ack(vha, sess, diff --git a/queue-6.6/scsi-qla2xxx-fix-double-free-of-fcport.patch b/queue-6.6/scsi-qla2xxx-fix-double-free-of-fcport.patch new file mode 100644 index 00000000000..5de63e572b3 --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-fix-double-free-of-fcport.patch @@ -0,0 +1,79 @@ +From 82f522ae0d97119a43da53e0f729275691b9c525 Mon Sep 17 00:00:00 2001 +From: Saurav Kashyap +Date: Tue, 27 Feb 2024 22:11:24 +0530 +Subject: scsi: qla2xxx: Fix double free of fcport + +From: Saurav Kashyap + +commit 82f522ae0d97119a43da53e0f729275691b9c525 upstream. + +The server was crashing after LOGO because fcport was getting freed twice. + + -----------[ cut here ]----------- + kernel BUG at mm/slub.c:371! + invalid opcode: 0000 1 SMP PTI + CPU: 35 PID: 4610 Comm: bash Kdump: loaded Tainted: G OE --------- - - 4.18.0-425.3.1.el8.x86_64 #1 + Hardware name: HPE ProLiant DL360 Gen10/ProLiant DL360 Gen10, BIOS U32 09/03/2021 + RIP: 0010:set_freepointer.part.57+0x0/0x10 + RSP: 0018:ffffb07107027d90 EFLAGS: 00010246 + RAX: ffff9cb7e3150000 RBX: ffff9cb7e332b9c0 RCX: ffff9cb7e3150400 + RDX: 0000000000001f37 RSI: 0000000000000000 RDI: ffff9cb7c0005500 + RBP: fffff693448c5400 R08: 0000000080000000 R09: 0000000000000009 + R10: 0000000000000000 R11: 0000000000132af0 R12: ffff9cb7c0005500 + R13: ffff9cb7e3150000 R14: ffffffffc06990e0 R15: ffff9cb7ea85ea58 + FS: 00007ff6b79c2740(0000) GS:ffff9cb8f7ec0000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 000055b426b7d700 CR3: 0000000169c18002 CR4: 00000000007706e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 55555554 + Call Trace: + kfree+0x238/0x250 + qla2x00_els_dcmd_sp_free+0x20/0x230 [qla2xxx] + ? qla24xx_els_dcmd_iocb+0x607/0x690 [qla2xxx] + qla2x00_issue_logo+0x28c/0x2a0 [qla2xxx] + ? qla2x00_issue_logo+0x28c/0x2a0 [qla2xxx] + ? kernfs_fop_write+0x11e/0x1a0 + +Remove one of the free calls and add check for valid fcport. Also use +function qla2x00_free_fcport() instead of kfree(). + +Cc: stable@vger.kernel.org +Signed-off-by: Saurav Kashyap +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-9-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_iocb.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -2637,7 +2637,8 @@ static void qla2x00_els_dcmd_sp_free(srb + { + struct srb_iocb *elsio = &sp->u.iocb_cmd; + +- kfree(sp->fcport); ++ if (sp->fcport) ++ qla2x00_free_fcport(sp->fcport); + + if (elsio->u.els_logo.els_logo_pyld) + dma_free_coherent(&sp->vha->hw->pdev->dev, DMA_POOL_SIZE, +@@ -2750,6 +2751,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *v + if (!elsio->u.els_logo.els_logo_pyld) { + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); ++ qla2x00_free_fcport(fcport); + return QLA_FUNCTION_FAILED; + } + +@@ -2784,7 +2786,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *v + fcport->d_id.b.area, fcport->d_id.b.al_pa); + + wait_for_completion(&elsio->u.els_logo.comp); +- qla2x00_free_fcport(fcport); + + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); diff --git a/queue-6.6/scsi-qla2xxx-fix-double-free-of-the-ha-vp_map-pointer.patch b/queue-6.6/scsi-qla2xxx-fix-double-free-of-the-ha-vp_map-pointer.patch new file mode 100644 index 00000000000..c3cc47b0bb1 --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-fix-double-free-of-the-ha-vp_map-pointer.patch @@ -0,0 +1,36 @@ +From e288285d47784fdcf7c81be56df7d65c6f10c58b Mon Sep 17 00:00:00 2001 +From: Saurav Kashyap +Date: Tue, 27 Feb 2024 22:11:23 +0530 +Subject: scsi: qla2xxx: Fix double free of the ha->vp_map pointer + +From: Saurav Kashyap + +commit e288285d47784fdcf7c81be56df7d65c6f10c58b upstream. + +Coverity scan reported potential risk of double free of the pointer +ha->vp_map. ha->vp_map was freed in qla2x00_mem_alloc(), and again freed +in function qla2x00_mem_free(ha). + +Assign NULL to vp_map and kfree take care of NULL. + +Cc: stable@vger.kernel.org +Signed-off-by: Saurav Kashyap +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-8-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_os.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -4601,6 +4601,7 @@ fail_free_init_cb: + ha->init_cb_dma = 0; + fail_free_vp_map: + kfree(ha->vp_map); ++ ha->vp_map = NULL; + fail: + ql_log(ql_log_fatal, NULL, 0x0030, + "Memory allocation failure.\n"); diff --git a/queue-6.6/scsi-qla2xxx-fix-n2n-stuck-connection.patch b/queue-6.6/scsi-qla2xxx-fix-n2n-stuck-connection.patch new file mode 100644 index 00000000000..227627a6de6 --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-fix-n2n-stuck-connection.patch @@ -0,0 +1,145 @@ +From 881eb861ca3877300570db10abbf11494e48548d Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:18 +0530 +Subject: scsi: qla2xxx: Fix N2N stuck connection + +From: Quinn Tran + +commit 881eb861ca3877300570db10abbf11494e48548d upstream. + +Disk failed to rediscover after chip reset error injection. The chip reset +happens at the time when a PLOGI is being sent. This causes a flag to be +left on which blocks the retry. Clear the blocking flag. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-3-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_gbl.h | 2 +- + drivers/scsi/qla2xxx/qla_iocb.c | 32 +++++++++++--------------------- + drivers/scsi/qla2xxx/qla_os.c | 2 +- + 3 files changed, 13 insertions(+), 23 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -44,7 +44,7 @@ extern int qla2x00_fabric_login(scsi_qla + extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); + + extern int qla24xx_els_dcmd_iocb(scsi_qla_host_t *, int, port_id_t); +-extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *, bool); ++extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *); + extern void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, + struct els_plogi *els_plogi); + +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -3041,7 +3041,7 @@ static void qla2x00_els_dcmd2_sp_done(sr + + int + qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, +- fc_port_t *fcport, bool wait) ++ fc_port_t *fcport) + { + srb_t *sp; + struct srb_iocb *elsio = NULL; +@@ -3056,8 +3056,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + if (!sp) { + ql_log(ql_log_info, vha, 0x70e6, + "SRB allocation failed\n"); +- fcport->flags &= ~FCF_ASYNC_ACTIVE; +- return -ENOMEM; ++ goto done; + } + + fcport->flags |= FCF_ASYNC_SENT; +@@ -3066,9 +3065,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + ql_dbg(ql_dbg_io, vha, 0x3073, + "%s Enter: PLOGI portid=%06x\n", __func__, fcport->d_id.b24); + +- if (wait) +- sp->flags = SRB_WAKEUP_ON_COMP; +- + sp->type = SRB_ELS_DCMD; + sp->name = "ELS_DCMD"; + sp->fcport = fcport; +@@ -3084,7 +3080,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + + if (!elsio->u.els_plogi.els_plogi_pyld) { + rval = QLA_FUNCTION_FAILED; +- goto out; ++ goto done_free_sp; + } + + resp_ptr = elsio->u.els_plogi.els_resp_pyld = +@@ -3093,7 +3089,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + + if (!elsio->u.els_plogi.els_resp_pyld) { + rval = QLA_FUNCTION_FAILED; +- goto out; ++ goto done_free_sp; + } + + ql_dbg(ql_dbg_io, vha, 0x3073, "PLOGI %p %p\n", ptr, resp_ptr); +@@ -3109,7 +3105,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + + if (els_opcode == ELS_DCMD_PLOGI && DBELL_ACTIVE(vha)) { + struct fc_els_flogi *p = ptr; +- + p->fl_csp.sp_features |= cpu_to_be16(FC_SP_FT_SEC); + } + +@@ -3118,10 +3113,11 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, + sizeof(*elsio->u.els_plogi.els_plogi_pyld)); + +- init_completion(&elsio->u.els_plogi.comp); + rval = qla2x00_start_sp(sp); + if (rval != QLA_SUCCESS) { +- rval = QLA_FUNCTION_FAILED; ++ fcport->flags |= FCF_LOGIN_NEEDED; ++ set_bit(RELOGIN_NEEDED, &vha->dpc_flags); ++ goto done_free_sp; + } else { + ql_dbg(ql_dbg_disc, vha, 0x3074, + "%s PLOGI sent, hdl=%x, loopid=%x, to port_id %06x from port_id %06x\n", +@@ -3129,21 +3125,15 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + fcport->d_id.b24, vha->d_id.b24); + } + +- if (wait) { +- wait_for_completion(&elsio->u.els_plogi.comp); +- +- if (elsio->u.els_plogi.comp_status != CS_COMPLETE) +- rval = QLA_FUNCTION_FAILED; +- } else { +- goto done; +- } ++ return rval; + +-out: +- fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); ++done_free_sp: + qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi); + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); + done: ++ fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); ++ qla2x00_set_fcport_disc_state(fcport, DSC_DELETED); + return rval; + } + +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -5582,7 +5582,7 @@ qla2x00_do_work(struct scsi_qla_host *vh + break; + case QLA_EVT_ELS_PLOGI: + qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI, +- e->u.fcport.fcport, false); ++ e->u.fcport.fcport); + break; + case QLA_EVT_SA_REPLACE: + rc = qla24xx_issue_sa_replace_iocb(vha, e); diff --git a/queue-6.6/scsi-qla2xxx-nvme-fcp-prefer-flag-not-being-honored.patch b/queue-6.6/scsi-qla2xxx-nvme-fcp-prefer-flag-not-being-honored.patch new file mode 100644 index 00000000000..2ed8e088b45 --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-nvme-fcp-prefer-flag-not-being-honored.patch @@ -0,0 +1,69 @@ +From 69aecdd410106dc3a8f543a4f7ec6379b995b8d0 Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:21 +0530 +Subject: scsi: qla2xxx: NVME|FCP prefer flag not being honored + +From: Quinn Tran + +commit 69aecdd410106dc3a8f543a4f7ec6379b995b8d0 upstream. + +Changing of [FCP|NVME] prefer flag in flash has no effect on driver. For +device that supports both FCP + NVMe over the same connection, driver +continues to connect to this device using the previous successful login +mode. + +On completion of flash update, adapter will be reset. Driver will +reset the prefer flag based on setting from flash. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-6-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_init.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -7501,6 +7501,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) + struct scsi_qla_host *vp, *tvp; + struct req_que *req = ha->req_q_map[0]; + unsigned long flags; ++ fc_port_t *fcport; + + if (vha->flags.online) { + qla2x00_abort_isp_cleanup(vha); +@@ -7569,6 +7570,15 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) + "ISP Abort - ISP reg disconnect post nvmram config, exiting.\n"); + return status; + } ++ ++ /* User may have updated [fcp|nvme] prefer in flash */ ++ list_for_each_entry(fcport, &vha->vp_fcports, list) { ++ if (NVME_PRIORITY(ha, fcport)) ++ fcport->do_prli_nvme = 1; ++ else ++ fcport->do_prli_nvme = 0; ++ } ++ + if (!qla2x00_restart_isp(vha)) { + clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); + +@@ -7639,6 +7649,14 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) + atomic_inc(&vp->vref_count); + spin_unlock_irqrestore(&ha->vport_slock, flags); + ++ /* User may have updated [fcp|nvme] prefer in flash */ ++ list_for_each_entry(fcport, &vp->vp_fcports, list) { ++ if (NVME_PRIORITY(ha, fcport)) ++ fcport->do_prli_nvme = 1; ++ else ++ fcport->do_prli_nvme = 0; ++ } ++ + qla2x00_vp_abort_isp(vp); + + spin_lock_irqsave(&ha->vport_slock, flags); diff --git a/queue-6.6/scsi-qla2xxx-prevent-command-send-on-chip-reset.patch b/queue-6.6/scsi-qla2xxx-prevent-command-send-on-chip-reset.patch new file mode 100644 index 00000000000..268bf320208 --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-prevent-command-send-on-chip-reset.patch @@ -0,0 +1,115 @@ +From 4895009c4bb72f71f2e682f1e7d2c2d96e482087 Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:17 +0530 +Subject: scsi: qla2xxx: Prevent command send on chip reset + +From: Quinn Tran + +commit 4895009c4bb72f71f2e682f1e7d2c2d96e482087 upstream. + +Currently IOCBs are allowed to push through while chip reset could be in +progress. During chip reset the outstanding_cmds array is cleared +twice. Once when any command on this array is returned as failed and +secondly when the array is initialize to zero. If a command is inserted on +to the array between these intervals, then the command will be lost. Check +for chip reset before sending IOCB. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-2-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_init.c | 8 ++++++-- + drivers/scsi/qla2xxx/qla_iocb.c | 33 +++++++++++++++++++++++++++++++-- + 2 files changed, 37 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -1193,8 +1193,12 @@ int qla24xx_async_gnl(struct scsi_qla_ho + return rval; + + done_free_sp: +- /* ref: INIT */ +- kref_put(&sp->cmd_kref, qla2x00_sp_release); ++ /* ++ * use qla24xx_async_gnl_sp_done to purge all pending gnl request. ++ * kref_put is call behind the scene. ++ */ ++ sp->u.iocb_cmd.u.mbx.in_mb[0] = MBS_COMMAND_ERROR; ++ qla24xx_async_gnl_sp_done(sp, QLA_COMMAND_ERROR); + fcport->flags &= ~(FCF_ASYNC_SENT); + done: + fcport->flags &= ~(FCF_ASYNC_ACTIVE); +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -2587,6 +2587,33 @@ void + qla2x00_sp_release(struct kref *kref) + { + struct srb *sp = container_of(kref, struct srb, cmd_kref); ++ struct scsi_qla_host *vha = sp->vha; ++ ++ switch (sp->type) { ++ case SRB_CT_PTHRU_CMD: ++ /* GPSC & GFPNID use fcport->ct_desc.ct_sns for both req & rsp */ ++ if (sp->u.iocb_cmd.u.ctarg.req && ++ (!sp->fcport || ++ sp->u.iocb_cmd.u.ctarg.req != sp->fcport->ct_desc.ct_sns)) { ++ dma_free_coherent(&vha->hw->pdev->dev, ++ sp->u.iocb_cmd.u.ctarg.req_allocated_size, ++ sp->u.iocb_cmd.u.ctarg.req, ++ sp->u.iocb_cmd.u.ctarg.req_dma); ++ sp->u.iocb_cmd.u.ctarg.req = NULL; ++ } ++ if (sp->u.iocb_cmd.u.ctarg.rsp && ++ (!sp->fcport || ++ sp->u.iocb_cmd.u.ctarg.rsp != sp->fcport->ct_desc.ct_sns)) { ++ dma_free_coherent(&vha->hw->pdev->dev, ++ sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, ++ sp->u.iocb_cmd.u.ctarg.rsp, ++ sp->u.iocb_cmd.u.ctarg.rsp_dma); ++ sp->u.iocb_cmd.u.ctarg.rsp = NULL; ++ } ++ break; ++ default: ++ break; ++ } + + sp->free(sp); + } +@@ -2692,7 +2719,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *v + */ + sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); + if (!sp) { +- kfree(fcport); ++ qla2x00_free_fcport(fcport); + ql_log(ql_log_info, vha, 0x70e6, + "SRB allocation failed\n"); + return -ENOMEM; +@@ -2747,6 +2774,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *v + if (rval != QLA_SUCCESS) { + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); ++ qla2x00_free_fcport(fcport); + return QLA_FUNCTION_FAILED; + } + +@@ -2756,6 +2784,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *v + fcport->d_id.b.area, fcport->d_id.b.al_pa); + + wait_for_completion(&elsio->u.els_logo.comp); ++ qla2x00_free_fcport(fcport); + + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); +@@ -3918,7 +3947,7 @@ qla2x00_start_sp(srb_t *sp) + return -EAGAIN; + } + +- pkt = __qla2x00_alloc_iocbs(sp->qpair, sp); ++ pkt = qla2x00_alloc_iocbs_ready(sp->qpair, sp); + if (!pkt) { + rval = -EAGAIN; + ql_log(ql_log_warn, vha, 0x700c, diff --git a/queue-6.6/scsi-qla2xxx-split-fce-eft-trace-control.patch b/queue-6.6/scsi-qla2xxx-split-fce-eft-trace-control.patch new file mode 100644 index 00000000000..91ae3ba43e8 --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-split-fce-eft-trace-control.patch @@ -0,0 +1,224 @@ +From 76a192e1a566e15365704b9f8fb3b70825f85064 Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:19 +0530 +Subject: scsi: qla2xxx: Split FCE|EFT trace control + +From: Quinn Tran + +commit 76a192e1a566e15365704b9f8fb3b70825f85064 upstream. + +Current code combines the allocation of FCE|EFT trace buffers and enables +the features all in 1 step. + +Split this step into separate steps in preparation for follow-on patch to +allow user to have a choice to enable / disable FCE trace feature. + +Cc: stable@vger.kernel.org +Reported-by: kernel test robot +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-4-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_init.c | 102 ++++++++++++++++------------------------ + 1 file changed, 41 insertions(+), 61 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -2669,6 +2669,40 @@ exit: + return rval; + } + ++static void qla_enable_fce_trace(scsi_qla_host_t *vha) ++{ ++ int rval; ++ struct qla_hw_data *ha = vha->hw; ++ ++ if (ha->fce) { ++ ha->flags.fce_enabled = 1; ++ memset(ha->fce, 0, fce_calc_size(ha->fce_bufs)); ++ rval = qla2x00_enable_fce_trace(vha, ++ ha->fce_dma, ha->fce_bufs, ha->fce_mb, &ha->fce_bufs); ++ ++ if (rval) { ++ ql_log(ql_log_warn, vha, 0x8033, ++ "Unable to reinitialize FCE (%d).\n", rval); ++ ha->flags.fce_enabled = 0; ++ } ++ } ++} ++ ++static void qla_enable_eft_trace(scsi_qla_host_t *vha) ++{ ++ int rval; ++ struct qla_hw_data *ha = vha->hw; ++ ++ if (ha->eft) { ++ memset(ha->eft, 0, EFT_SIZE); ++ rval = qla2x00_enable_eft_trace(vha, ha->eft_dma, EFT_NUM_BUFFERS); ++ ++ if (rval) { ++ ql_log(ql_log_warn, vha, 0x8034, ++ "Unable to reinitialize EFT (%d).\n", rval); ++ } ++ } ++} + /* + * qla2x00_initialize_adapter + * Initialize board. +@@ -3672,9 +3706,8 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) + } + + static void +-qla2x00_init_fce_trace(scsi_qla_host_t *vha) ++qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) + { +- int rval; + dma_addr_t tc_dma; + void *tc; + struct qla_hw_data *ha = vha->hw; +@@ -3703,27 +3736,17 @@ qla2x00_init_fce_trace(scsi_qla_host_t * + return; + } + +- rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS, +- ha->fce_mb, &ha->fce_bufs); +- if (rval) { +- ql_log(ql_log_warn, vha, 0x00bf, +- "Unable to initialize FCE (%d).\n", rval); +- dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, tc_dma); +- return; +- } +- + ql_dbg(ql_dbg_init, vha, 0x00c0, + "Allocated (%d KB) for FCE...\n", FCE_SIZE / 1024); + +- ha->flags.fce_enabled = 1; + ha->fce_dma = tc_dma; + ha->fce = tc; ++ ha->fce_bufs = FCE_NUM_BUFFERS; + } + + static void +-qla2x00_init_eft_trace(scsi_qla_host_t *vha) ++qla2x00_alloc_eft_trace(scsi_qla_host_t *vha) + { +- int rval; + dma_addr_t tc_dma; + void *tc; + struct qla_hw_data *ha = vha->hw; +@@ -3748,14 +3771,6 @@ qla2x00_init_eft_trace(scsi_qla_host_t * + return; + } + +- rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS); +- if (rval) { +- ql_log(ql_log_warn, vha, 0x00c2, +- "Unable to initialize EFT (%d).\n", rval); +- dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, tc_dma); +- return; +- } +- + ql_dbg(ql_dbg_init, vha, 0x00c3, + "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); + +@@ -3763,13 +3778,6 @@ qla2x00_init_eft_trace(scsi_qla_host_t * + ha->eft = tc; + } + +-static void +-qla2x00_alloc_offload_mem(scsi_qla_host_t *vha) +-{ +- qla2x00_init_fce_trace(vha); +- qla2x00_init_eft_trace(vha); +-} +- + void + qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) + { +@@ -3824,10 +3832,10 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *v + if (ha->tgt.atio_ring) + mq_size += ha->tgt.atio_q_length * sizeof(request_t); + +- qla2x00_init_fce_trace(vha); ++ qla2x00_alloc_fce_trace(vha); + if (ha->fce) + fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; +- qla2x00_init_eft_trace(vha); ++ qla2x00_alloc_eft_trace(vha); + if (ha->eft) + eft_size = EFT_SIZE; + } +@@ -4257,7 +4265,6 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) + struct qla_hw_data *ha = vha->hw; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + unsigned long flags; +- uint16_t fw_major_version; + int done_once = 0; + + if (IS_P3P_TYPE(ha)) { +@@ -4324,7 +4331,6 @@ execute_fw_with_lr: + goto failed; + + enable_82xx_npiv: +- fw_major_version = ha->fw_major_version; + if (IS_P3P_TYPE(ha)) + qla82xx_check_md_needed(vha); + else +@@ -4353,12 +4359,11 @@ enable_82xx_npiv: + if (rval != QLA_SUCCESS) + goto failed; + +- if (!fw_major_version && !(IS_P3P_TYPE(ha))) +- qla2x00_alloc_offload_mem(vha); +- + if (ql2xallocfwdump && !(IS_P3P_TYPE(ha))) + qla2x00_alloc_fw_dump(vha); + ++ qla_enable_fce_trace(vha); ++ qla_enable_eft_trace(vha); + } else { + goto failed; + } +@@ -7491,7 +7496,6 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_ + int + qla2x00_abort_isp(scsi_qla_host_t *vha) + { +- int rval; + uint8_t status = 0; + struct qla_hw_data *ha = vha->hw; + struct scsi_qla_host *vp, *tvp; +@@ -7585,31 +7589,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) + + if (IS_QLA81XX(ha) || IS_QLA8031(ha)) + qla2x00_get_fw_version(vha); +- if (ha->fce) { +- ha->flags.fce_enabled = 1; +- memset(ha->fce, 0, +- fce_calc_size(ha->fce_bufs)); +- rval = qla2x00_enable_fce_trace(vha, +- ha->fce_dma, ha->fce_bufs, ha->fce_mb, +- &ha->fce_bufs); +- if (rval) { +- ql_log(ql_log_warn, vha, 0x8033, +- "Unable to reinitialize FCE " +- "(%d).\n", rval); +- ha->flags.fce_enabled = 0; +- } +- } + +- if (ha->eft) { +- memset(ha->eft, 0, EFT_SIZE); +- rval = qla2x00_enable_eft_trace(vha, +- ha->eft_dma, EFT_NUM_BUFFERS); +- if (rval) { +- ql_log(ql_log_warn, vha, 0x8034, +- "Unable to reinitialize EFT " +- "(%d).\n", rval); +- } +- } + } else { /* failed the ISP abort */ + vha->flags.online = 1; + if (test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { diff --git a/queue-6.6/scsi-qla2xxx-update-manufacturer-detail.patch b/queue-6.6/scsi-qla2xxx-update-manufacturer-detail.patch new file mode 100644 index 00000000000..811bad702f5 --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-update-manufacturer-detail.patch @@ -0,0 +1,34 @@ +From 688fa069fda6fce24d243cddfe0c7024428acb74 Mon Sep 17 00:00:00 2001 +From: Bikash Hazarika +Date: Tue, 27 Feb 2024 22:11:20 +0530 +Subject: scsi: qla2xxx: Update manufacturer detail + +From: Bikash Hazarika + +commit 688fa069fda6fce24d243cddfe0c7024428acb74 upstream. + +Update manufacturer detail from "Marvell Semiconductor, Inc." to +"Marvell". + +Cc: stable@vger.kernel.org +Signed-off-by: Bikash Hazarika +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-5-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_def.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -82,7 +82,7 @@ typedef union { + #include "qla_nvme.h" + #define QLA2XXX_DRIVER_NAME "qla2xxx" + #define QLA2XXX_APIDEV "ql2xapidev" +-#define QLA2XXX_MANUFACTURER "Marvell Semiconductor, Inc." ++#define QLA2XXX_MANUFACTURER "Marvell" + + /* + * We have MAILBOX_REGISTER_COUNT sized arrays in a few places, diff --git a/queue-6.6/series b/queue-6.6/series index b363799b581..a6012a7c996 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -359,3 +359,29 @@ scsi-sg-avoid-sg-device-teardown-race.patch scsi-core-fix-unremoved-procfs-host-directory-regression.patch staging-vc04_services-changen-strncpy-to-strscpy_pad.patch staging-vc04_services-fix-information-leak-in-create_component.patch +usb-dwc3-properly-set-system-wakeup.patch +usb-core-fix-deadlock-in-usb_deauthorize_interface.patch +usb-core-add-hub_get-and-hub_put-routines.patch +usb-core-fix-deadlock-in-port-disable-sysfs-attribute.patch +usb-dwc2-host-fix-remote-wakeup-from-hibernation.patch +usb-dwc2-host-fix-hibernation-flow.patch +usb-dwc2-host-fix-isoc-flow-in-ddma-mode.patch +usb-dwc2-gadget-fix-exiting-from-clock-gating.patch +usb-dwc2-gadget-lpm-flow-fix.patch +usb-udc-remove-warning-when-queue-disabled-ep.patch +usb-typec-return-size-of-buffer-if-pd_set-operation-succeeds.patch +usb-typec-ucsi-clear-event_pending-under-ppm-lock.patch +usb-typec-ucsi-check-for-notifications-after-init.patch +usb-typec-ucsi-ack-unsupported-commands.patch +usb-typec-ucsi_acpi-refactor-and-fix-dell-quirk.patch +usb-typec-ucsi-clear-ucsi_cci_reset_complete-before-reset.patch +scsi-qla2xxx-prevent-command-send-on-chip-reset.patch +scsi-qla2xxx-fix-n2n-stuck-connection.patch +scsi-qla2xxx-split-fce-eft-trace-control.patch +scsi-qla2xxx-update-manufacturer-detail.patch +scsi-qla2xxx-nvme-fcp-prefer-flag-not-being-honored.patch +scsi-qla2xxx-fix-command-flush-on-cable-pull.patch +scsi-qla2xxx-fix-double-free-of-the-ha-vp_map-pointer.patch +scsi-qla2xxx-fix-double-free-of-fcport.patch +scsi-qla2xxx-change-debug-message-during-driver-unload.patch +scsi-qla2xxx-delay-i-o-abort-on-pci-error.patch diff --git a/queue-6.6/usb-core-add-hub_get-and-hub_put-routines.patch b/queue-6.6/usb-core-add-hub_get-and-hub_put-routines.patch new file mode 100644 index 00000000000..7dec5e83ddb --- /dev/null +++ b/queue-6.6/usb-core-add-hub_get-and-hub_put-routines.patch @@ -0,0 +1,113 @@ +From ee113b860aa169e9a4d2c167c95d0f1961c6e1b8 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 15 Mar 2024 13:04:50 -0400 +Subject: USB: core: Add hub_get() and hub_put() routines + +From: Alan Stern + +commit ee113b860aa169e9a4d2c167c95d0f1961c6e1b8 upstream. + +Create hub_get() and hub_put() routines to encapsulate the kref_get() +and kref_put() calls in hub.c. The new routines will be used by the +next patch in this series. + +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/604da420-ae8a-4a9e-91a4-2d511ff404fb@rowland.harvard.edu +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hub.c | 23 ++++++++++++++++------- + drivers/usb/core/hub.h | 2 ++ + 2 files changed, 18 insertions(+), 7 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -123,7 +123,6 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rws + #define HUB_DEBOUNCE_STEP 25 + #define HUB_DEBOUNCE_STABLE 100 + +-static void hub_release(struct kref *kref); + static int usb_reset_and_verify_device(struct usb_device *udev); + static int hub_port_disable(struct usb_hub *hub, int port1, int set_state); + static bool hub_port_warm_reset_required(struct usb_hub *hub, int port1, +@@ -685,14 +684,14 @@ static void kick_hub_wq(struct usb_hub * + */ + intf = to_usb_interface(hub->intfdev); + usb_autopm_get_interface_no_resume(intf); +- kref_get(&hub->kref); ++ hub_get(hub); + + if (queue_work(hub_wq, &hub->events)) + return; + + /* the work has already been scheduled */ + usb_autopm_put_interface_async(intf); +- kref_put(&hub->kref, hub_release); ++ hub_put(hub); + } + + void usb_kick_hub_wq(struct usb_device *hdev) +@@ -1060,7 +1059,7 @@ static void hub_activate(struct usb_hub + goto init2; + goto init3; + } +- kref_get(&hub->kref); ++ hub_get(hub); + + /* The superspeed hub except for root hub has to use Hub Depth + * value as an offset into the route string to locate the bits +@@ -1308,7 +1307,7 @@ static void hub_activate(struct usb_hub + device_unlock(&hdev->dev); + } + +- kref_put(&hub->kref, hub_release); ++ hub_put(hub); + } + + /* Implement the continuations for the delays above */ +@@ -1724,6 +1723,16 @@ static void hub_release(struct kref *kre + kfree(hub); + } + ++void hub_get(struct usb_hub *hub) ++{ ++ kref_get(&hub->kref); ++} ++ ++void hub_put(struct usb_hub *hub) ++{ ++ kref_put(&hub->kref, hub_release); ++} ++ + static unsigned highspeed_hubs; + + static void hub_disconnect(struct usb_interface *intf) +@@ -1772,7 +1781,7 @@ static void hub_disconnect(struct usb_in + + onboard_hub_destroy_pdevs(&hub->onboard_hub_devs); + +- kref_put(&hub->kref, hub_release); ++ hub_put(hub); + } + + static bool hub_descriptor_is_sane(struct usb_host_interface *desc) +@@ -5890,7 +5899,7 @@ out_hdev_lock: + + /* Balance the stuff in kick_hub_wq() and allow autosuspend */ + usb_autopm_put_interface(intf); +- kref_put(&hub->kref, hub_release); ++ hub_put(hub); + + kcov_remote_stop(); + } +--- a/drivers/usb/core/hub.h ++++ b/drivers/usb/core/hub.h +@@ -126,6 +126,8 @@ extern void usb_hub_remove_port_device(s + extern int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub, + int port1, bool set); + extern struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev); ++extern void hub_get(struct usb_hub *hub); ++extern void hub_put(struct usb_hub *hub); + extern int hub_port_debounce(struct usb_hub *hub, int port1, + bool must_be_connected); + extern int usb_clear_port_feature(struct usb_device *hdev, diff --git a/queue-6.6/usb-core-fix-deadlock-in-port-disable-sysfs-attribute.patch b/queue-6.6/usb-core-fix-deadlock-in-port-disable-sysfs-attribute.patch new file mode 100644 index 00000000000..15514434729 --- /dev/null +++ b/queue-6.6/usb-core-fix-deadlock-in-port-disable-sysfs-attribute.patch @@ -0,0 +1,123 @@ +From f4d1960764d8a70318b02f15203a1be2b2554ca1 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 15 Mar 2024 13:06:33 -0400 +Subject: USB: core: Fix deadlock in port "disable" sysfs attribute + +From: Alan Stern + +commit f4d1960764d8a70318b02f15203a1be2b2554ca1 upstream. + +The show and store callback routines for the "disable" sysfs attribute +file in port.c acquire the device lock for the port's parent hub +device. This can cause problems if another process has locked the hub +to remove it or change its configuration: + + Removing the hub or changing its configuration requires the + hub interface to be removed, which requires the port device + to be removed, and device_del() waits until all outstanding + sysfs attribute callbacks for the ports have returned. The + lock can't be released until then. + + But the disable_show() or disable_store() routine can't return + until after it has acquired the lock. + +The resulting deadlock can be avoided by calling +sysfs_break_active_protection(). This will cause the sysfs core not +to wait for the attribute's callback routine to return, allowing the +removal to proceed. The disadvantage is that after making this call, +there is no guarantee that the hub structure won't be deallocated at +any moment. To prevent this, we have to acquire a reference to it +first by calling hub_get(). + +Signed-off-by: Alan Stern +Cc: stable +Link: https://lore.kernel.org/r/f7a8c135-a495-4ce6-bd49-405a45e7ea9a@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/port.c | 38 ++++++++++++++++++++++++++++++++++---- + 1 file changed, 34 insertions(+), 4 deletions(-) + +--- a/drivers/usb/core/port.c ++++ b/drivers/usb/core/port.c +@@ -55,11 +55,22 @@ static ssize_t disable_show(struct devic + u16 portstatus, unused; + bool disabled; + int rc; ++ struct kernfs_node *kn; + ++ hub_get(hub); + rc = usb_autopm_get_interface(intf); + if (rc < 0) +- return rc; ++ goto out_hub_get; + ++ /* ++ * Prevent deadlock if another process is concurrently ++ * trying to unregister hdev. ++ */ ++ kn = sysfs_break_active_protection(&dev->kobj, &attr->attr); ++ if (!kn) { ++ rc = -ENODEV; ++ goto out_autopm; ++ } + usb_lock_device(hdev); + if (hub->disconnected) { + rc = -ENODEV; +@@ -69,9 +80,13 @@ static ssize_t disable_show(struct devic + usb_hub_port_status(hub, port1, &portstatus, &unused); + disabled = !usb_port_is_power_on(hub, portstatus); + +-out_hdev_lock: ++ out_hdev_lock: + usb_unlock_device(hdev); ++ sysfs_unbreak_active_protection(kn); ++ out_autopm: + usb_autopm_put_interface(intf); ++ out_hub_get: ++ hub_put(hub); + + if (rc) + return rc; +@@ -89,15 +104,26 @@ static ssize_t disable_store(struct devi + int port1 = port_dev->portnum; + bool disabled; + int rc; ++ struct kernfs_node *kn; + + rc = kstrtobool(buf, &disabled); + if (rc) + return rc; + ++ hub_get(hub); + rc = usb_autopm_get_interface(intf); + if (rc < 0) +- return rc; ++ goto out_hub_get; + ++ /* ++ * Prevent deadlock if another process is concurrently ++ * trying to unregister hdev. ++ */ ++ kn = sysfs_break_active_protection(&dev->kobj, &attr->attr); ++ if (!kn) { ++ rc = -ENODEV; ++ goto out_autopm; ++ } + usb_lock_device(hdev); + if (hub->disconnected) { + rc = -ENODEV; +@@ -118,9 +144,13 @@ static ssize_t disable_store(struct devi + if (!rc) + rc = count; + +-out_hdev_lock: ++ out_hdev_lock: + usb_unlock_device(hdev); ++ sysfs_unbreak_active_protection(kn); ++ out_autopm: + usb_autopm_put_interface(intf); ++ out_hub_get: ++ hub_put(hub); + + return rc; + } diff --git a/queue-6.6/usb-core-fix-deadlock-in-usb_deauthorize_interface.patch b/queue-6.6/usb-core-fix-deadlock-in-usb_deauthorize_interface.patch new file mode 100644 index 00000000000..62aa8e32c6b --- /dev/null +++ b/queue-6.6/usb-core-fix-deadlock-in-usb_deauthorize_interface.patch @@ -0,0 +1,70 @@ +From 80ba43e9f799cbdd83842fc27db667289b3150f5 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 12 Mar 2024 11:48:23 -0400 +Subject: USB: core: Fix deadlock in usb_deauthorize_interface() + +From: Alan Stern + +commit 80ba43e9f799cbdd83842fc27db667289b3150f5 upstream. + +Among the attribute file callback routines in +drivers/usb/core/sysfs.c, the interface_authorized_store() function is +the only one which acquires a device lock on an ancestor device: It +calls usb_deauthorize_interface(), which locks the interface's parent +USB device. + +The will lead to deadlock if another process already owns that lock +and tries to remove the interface, whether through a configuration +change or because the device has been disconnected. As part of the +removal procedure, device_del() waits for all ongoing sysfs attribute +callbacks to complete. But usb_deauthorize_interface() can't complete +until the device lock has been released, and the lock won't be +released until the removal has finished. + +The mechanism provided by sysfs to prevent this kind of deadlock is +to use the sysfs_break_active_protection() function, which tells sysfs +not to wait for the attribute callback. + +Reported-and-tested by: Yue Sun +Reported by: xingwei lee + +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/linux-usb/CAEkJfYO6jRVC8Tfrd_R=cjO0hguhrV31fDPrLrNOOHocDkPoAA@mail.gmail.com/#r +Fixes: 310d2b4124c0 ("usb: interface authorization: SysFS part of USB interface authorization") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/1c37eea1-9f56-4534-b9d8-b443438dc869@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/sysfs.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/sysfs.c ++++ b/drivers/usb/core/sysfs.c +@@ -1168,14 +1168,24 @@ static ssize_t interface_authorized_stor + { + struct usb_interface *intf = to_usb_interface(dev); + bool val; ++ struct kernfs_node *kn; + + if (kstrtobool(buf, &val) != 0) + return -EINVAL; + +- if (val) ++ if (val) { + usb_authorize_interface(intf); +- else +- usb_deauthorize_interface(intf); ++ } else { ++ /* ++ * Prevent deadlock if another process is concurrently ++ * trying to unregister intf. ++ */ ++ kn = sysfs_break_active_protection(&dev->kobj, &attr->attr); ++ if (kn) { ++ usb_deauthorize_interface(intf); ++ sysfs_unbreak_active_protection(kn); ++ } ++ } + + return count; + } diff --git a/queue-6.6/usb-dwc2-gadget-fix-exiting-from-clock-gating.patch b/queue-6.6/usb-dwc2-gadget-fix-exiting-from-clock-gating.patch new file mode 100644 index 00000000000..d0762b30c0b --- /dev/null +++ b/queue-6.6/usb-dwc2-gadget-fix-exiting-from-clock-gating.patch @@ -0,0 +1,97 @@ +From 31f42da31417bec88158f3cf62d19db836217f1e Mon Sep 17 00:00:00 2001 +From: Minas Harutyunyan +Date: Wed, 13 Mar 2024 09:22:01 +0000 +Subject: usb: dwc2: gadget: Fix exiting from clock gating + +From: Minas Harutyunyan + +commit 31f42da31417bec88158f3cf62d19db836217f1e upstream. + +Added exiting from the clock gating mode on USB Reset Detect interrupt +if core in the clock gating mode. +Added new condition to check core in clock gating mode or no. + +Fixes: 9b4965d77e11 ("usb: dwc2: Add exit clock gating from session request interrupt") +Fixes: 5d240efddc7f ("usb: dwc2: Add exit clock gating from wakeup interrupt") +Fixes: 16c729f90bdf ("usb: dwc2: Allow exit clock gating in urb enqueue") +Fixes: 401411bbc4e6 ("usb: dwc2: Add exit clock gating before removing driver") +CC: stable@vger.kernel.org +Signed-off-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/cbcc2ccd37e89e339130797ed68ae4597db773ac.1708938774.git.Minas.Harutyunyan@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/core_intr.c | 9 ++++++--- + drivers/usb/dwc2/gadget.c | 6 ++++++ + drivers/usb/dwc2/hcd.c | 2 +- + drivers/usb/dwc2/platform.c | 2 +- + 4 files changed, 14 insertions(+), 5 deletions(-) + +--- a/drivers/usb/dwc2/core_intr.c ++++ b/drivers/usb/dwc2/core_intr.c +@@ -297,7 +297,8 @@ static void dwc2_handle_session_req_intr + + /* Exit gadget mode clock gating. */ + if (hsotg->params.power_down == +- DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended) ++ DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended && ++ !hsotg->params.no_clock_gating) + dwc2_gadget_exit_clock_gating(hsotg, 0); + } + +@@ -408,7 +409,8 @@ static void dwc2_handle_wakeup_detected_ + + /* Exit gadget mode clock gating. */ + if (hsotg->params.power_down == +- DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended) ++ DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended && ++ !hsotg->params.no_clock_gating) + dwc2_gadget_exit_clock_gating(hsotg, 0); + } else { + /* Change to L0 state */ +@@ -425,7 +427,8 @@ static void dwc2_handle_wakeup_detected_ + } + + if (hsotg->params.power_down == +- DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended) ++ DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended && ++ !hsotg->params.no_clock_gating) + dwc2_host_exit_clock_gating(hsotg, 1); + + /* +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -3727,6 +3727,12 @@ irq_retry: + if (hsotg->in_ppd && hsotg->lx_state == DWC2_L2) + dwc2_exit_partial_power_down(hsotg, 0, true); + ++ /* Exit gadget mode clock gating. */ ++ if (hsotg->params.power_down == ++ DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended && ++ !hsotg->params.no_clock_gating) ++ dwc2_gadget_exit_clock_gating(hsotg, 0); ++ + hsotg->lx_state = DWC2_L0; + } + +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -4657,7 +4657,7 @@ static int _dwc2_hcd_urb_enqueue(struct + } + + if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE && +- hsotg->bus_suspended) { ++ hsotg->bus_suspended && !hsotg->params.no_clock_gating) { + if (dwc2_is_device_mode(hsotg)) + dwc2_gadget_exit_clock_gating(hsotg, 0); + else +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -331,7 +331,7 @@ static void dwc2_driver_remove(struct pl + + /* Exit clock gating when driver is removed. */ + if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE && +- hsotg->bus_suspended) { ++ hsotg->bus_suspended && !hsotg->params.no_clock_gating) { + if (dwc2_is_device_mode(hsotg)) + dwc2_gadget_exit_clock_gating(hsotg, 0); + else diff --git a/queue-6.6/usb-dwc2-gadget-lpm-flow-fix.patch b/queue-6.6/usb-dwc2-gadget-lpm-flow-fix.patch new file mode 100644 index 00000000000..140619d3720 --- /dev/null +++ b/queue-6.6/usb-dwc2-gadget-lpm-flow-fix.patch @@ -0,0 +1,150 @@ +From 5d69a3b54e5a630c90d82a4c2bdce3d53dc78710 Mon Sep 17 00:00:00 2001 +From: Minas Harutyunyan +Date: Wed, 13 Mar 2024 09:22:13 +0000 +Subject: usb: dwc2: gadget: LPM flow fix + +From: Minas Harutyunyan + +commit 5d69a3b54e5a630c90d82a4c2bdce3d53dc78710 upstream. + +Added functionality to exit from L1 state by device initiation +using remote wakeup signaling, in case when function driver queuing +request while core in L1 state. + +Fixes: 273d576c4d41 ("usb: dwc2: gadget: Add functionality to exit from LPM L1 state") +Fixes: 88b02f2cb1e1 ("usb: dwc2: Add core state checking") +CC: stable@vger.kernel.org +Signed-off-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/b4d9de5382375dddbf7ef6049d9a82066ad87d5d.1710166393.git.Minas.Harutyunyan@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/core_intr.c | 65 ++++++++++++++++++++++++++++--------------- + drivers/usb/dwc2/gadget.c | 4 ++ + 3 files changed, 48 insertions(+), 22 deletions(-) + +--- a/drivers/usb/dwc2/core.h ++++ b/drivers/usb/dwc2/core.h +@@ -1336,6 +1336,7 @@ int dwc2_backup_global_registers(struct + int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg); + + void dwc2_enable_acg(struct dwc2_hsotg *hsotg); ++void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg, bool remotewakeup); + + /* This function should be called on every hardware interrupt. */ + irqreturn_t dwc2_handle_common_intr(int irq, void *dev); +--- a/drivers/usb/dwc2/core_intr.c ++++ b/drivers/usb/dwc2/core_intr.c +@@ -323,10 +323,11 @@ static void dwc2_handle_session_req_intr + * @hsotg: Programming view of DWC_otg controller + * + */ +-static void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg) ++void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg, bool remotewakeup) + { + u32 glpmcfg; +- u32 i = 0; ++ u32 pcgctl; ++ u32 dctl; + + if (hsotg->lx_state != DWC2_L1) { + dev_err(hsotg->dev, "Core isn't in DWC2_L1 state\n"); +@@ -335,37 +336,57 @@ static void dwc2_wakeup_from_lpm_l1(stru + + glpmcfg = dwc2_readl(hsotg, GLPMCFG); + if (dwc2_is_device_mode(hsotg)) { +- dev_dbg(hsotg->dev, "Exit from L1 state\n"); ++ dev_dbg(hsotg->dev, "Exit from L1 state, remotewakeup=%d\n", remotewakeup); + glpmcfg &= ~GLPMCFG_ENBLSLPM; +- glpmcfg &= ~GLPMCFG_HIRD_THRES_EN; ++ glpmcfg &= ~GLPMCFG_HIRD_THRES_MASK; + dwc2_writel(hsotg, glpmcfg, GLPMCFG); + +- do { +- glpmcfg = dwc2_readl(hsotg, GLPMCFG); +- +- if (!(glpmcfg & (GLPMCFG_COREL1RES_MASK | +- GLPMCFG_L1RESUMEOK | GLPMCFG_SLPSTS))) +- break; ++ pcgctl = dwc2_readl(hsotg, PCGCTL); ++ pcgctl &= ~PCGCTL_ENBL_SLEEP_GATING; ++ dwc2_writel(hsotg, pcgctl, PCGCTL); ++ ++ glpmcfg = dwc2_readl(hsotg, GLPMCFG); ++ if (glpmcfg & GLPMCFG_ENBESL) { ++ glpmcfg |= GLPMCFG_RSTRSLPSTS; ++ dwc2_writel(hsotg, glpmcfg, GLPMCFG); ++ } + +- udelay(1); +- } while (++i < 200); ++ if (remotewakeup) { ++ if (dwc2_hsotg_wait_bit_set(hsotg, GLPMCFG, GLPMCFG_L1RESUMEOK, 1000)) { ++ dev_warn(hsotg->dev, "%s: timeout GLPMCFG_L1RESUMEOK\n", __func__); ++ goto fail; ++ return; ++ } ++ ++ dctl = dwc2_readl(hsotg, DCTL); ++ dctl |= DCTL_RMTWKUPSIG; ++ dwc2_writel(hsotg, dctl, DCTL); ++ ++ if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, GINTSTS_WKUPINT, 1000)) { ++ dev_warn(hsotg->dev, "%s: timeout GINTSTS_WKUPINT\n", __func__); ++ goto fail; ++ return; ++ } ++ } + +- if (i == 200) { +- dev_err(hsotg->dev, "Failed to exit L1 sleep state in 200us.\n"); ++ glpmcfg = dwc2_readl(hsotg, GLPMCFG); ++ if (glpmcfg & GLPMCFG_COREL1RES_MASK || glpmcfg & GLPMCFG_SLPSTS || ++ glpmcfg & GLPMCFG_L1RESUMEOK) { ++ goto fail; + return; + } +- dwc2_gadget_init_lpm(hsotg); ++ ++ /* Inform gadget to exit from L1 */ ++ call_gadget(hsotg, resume); ++ /* Change to L0 state */ ++ hsotg->lx_state = DWC2_L0; ++ hsotg->bus_suspended = false; ++fail: dwc2_gadget_init_lpm(hsotg); + } else { + /* TODO */ + dev_err(hsotg->dev, "Host side LPM is not supported.\n"); + return; + } +- +- /* Change to L0 state */ +- hsotg->lx_state = DWC2_L0; +- +- /* Inform gadget to exit from L1 */ +- call_gadget(hsotg, resume); + } + + /* +@@ -386,7 +407,7 @@ static void dwc2_handle_wakeup_detected_ + dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state); + + if (hsotg->lx_state == DWC2_L1) { +- dwc2_wakeup_from_lpm_l1(hsotg); ++ dwc2_wakeup_from_lpm_l1(hsotg, false); + return; + } + +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -1415,6 +1415,10 @@ static int dwc2_hsotg_ep_queue(struct us + ep->name, req, req->length, req->buf, req->no_interrupt, + req->zero, req->short_not_ok); + ++ if (hs->lx_state == DWC2_L1) { ++ dwc2_wakeup_from_lpm_l1(hs, true); ++ } ++ + /* Prevent new request submission when controller is suspended */ + if (hs->lx_state != DWC2_L0) { + dev_dbg(hs->dev, "%s: submit request only in active state\n", diff --git a/queue-6.6/usb-dwc2-host-fix-hibernation-flow.patch b/queue-6.6/usb-dwc2-host-fix-hibernation-flow.patch new file mode 100644 index 00000000000..b7ebbf58cdb --- /dev/null +++ b/queue-6.6/usb-dwc2-host-fix-hibernation-flow.patch @@ -0,0 +1,94 @@ +From 3c7b9856a82227db01a20171d2e24c7ce305d59b Mon Sep 17 00:00:00 2001 +From: Minas Harutyunyan +Date: Wed, 13 Mar 2024 09:21:11 +0000 +Subject: usb: dwc2: host: Fix hibernation flow + +From: Minas Harutyunyan + +commit 3c7b9856a82227db01a20171d2e24c7ce305d59b upstream. + +Added to backup/restore registers HFLBADDR, HCCHARi, HCSPLTi, +HCTSIZi, HCDMAi and HCDMABi. + +Fixes: 58e52ff6a6c3 ("usb: dwc2: Move register save and restore functions") +Fixes: d17ee77b3044 ("usb: dwc2: add controller hibernation support") +CC: stable@vger.kernel.org +Signed-off-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/c2d10ee6098b9b009a8e94191e046004747d3bdd.1708945444.git.Minas.Harutyunyan@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/core.h | 12 ++++++++++++ + drivers/usb/dwc2/hcd.c | 18 ++++++++++++++++-- + 2 files changed, 28 insertions(+), 2 deletions(-) + +--- a/drivers/usb/dwc2/core.h ++++ b/drivers/usb/dwc2/core.h +@@ -729,8 +729,14 @@ struct dwc2_dregs_backup { + * struct dwc2_hregs_backup - Holds host registers state before + * entering partial power down + * @hcfg: Backup of HCFG register ++ * @hflbaddr: Backup of HFLBADDR register + * @haintmsk: Backup of HAINTMSK register ++ * @hcchar: Backup of HCCHAR register ++ * @hcsplt: Backup of HCSPLT register + * @hcintmsk: Backup of HCINTMSK register ++ * @hctsiz: Backup of HCTSIZ register ++ * @hdma: Backup of HCDMA register ++ * @hcdmab: Backup of HCDMAB register + * @hprt0: Backup of HPTR0 register + * @hfir: Backup of HFIR register + * @hptxfsiz: Backup of HPTXFSIZ register +@@ -738,8 +744,14 @@ struct dwc2_dregs_backup { + */ + struct dwc2_hregs_backup { + u32 hcfg; ++ u32 hflbaddr; + u32 haintmsk; ++ u32 hcchar[MAX_EPS_CHANNELS]; ++ u32 hcsplt[MAX_EPS_CHANNELS]; + u32 hcintmsk[MAX_EPS_CHANNELS]; ++ u32 hctsiz[MAX_EPS_CHANNELS]; ++ u32 hcidma[MAX_EPS_CHANNELS]; ++ u32 hcidmab[MAX_EPS_CHANNELS]; + u32 hprt0; + u32 hfir; + u32 hptxfsiz; +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -5406,9 +5406,16 @@ int dwc2_backup_host_registers(struct dw + /* Backup Host regs */ + hr = &hsotg->hr_backup; + hr->hcfg = dwc2_readl(hsotg, HCFG); ++ hr->hflbaddr = dwc2_readl(hsotg, HFLBADDR); + hr->haintmsk = dwc2_readl(hsotg, HAINTMSK); +- for (i = 0; i < hsotg->params.host_channels; ++i) ++ for (i = 0; i < hsotg->params.host_channels; ++i) { ++ hr->hcchar[i] = dwc2_readl(hsotg, HCCHAR(i)); ++ hr->hcsplt[i] = dwc2_readl(hsotg, HCSPLT(i)); + hr->hcintmsk[i] = dwc2_readl(hsotg, HCINTMSK(i)); ++ hr->hctsiz[i] = dwc2_readl(hsotg, HCTSIZ(i)); ++ hr->hcidma[i] = dwc2_readl(hsotg, HCDMA(i)); ++ hr->hcidmab[i] = dwc2_readl(hsotg, HCDMAB(i)); ++ } + + hr->hprt0 = dwc2_read_hprt0(hsotg); + hr->hfir = dwc2_readl(hsotg, HFIR); +@@ -5442,10 +5449,17 @@ int dwc2_restore_host_registers(struct d + hr->valid = false; + + dwc2_writel(hsotg, hr->hcfg, HCFG); ++ dwc2_writel(hsotg, hr->hflbaddr, HFLBADDR); + dwc2_writel(hsotg, hr->haintmsk, HAINTMSK); + +- for (i = 0; i < hsotg->params.host_channels; ++i) ++ for (i = 0; i < hsotg->params.host_channels; ++i) { ++ dwc2_writel(hsotg, hr->hcchar[i], HCCHAR(i)); ++ dwc2_writel(hsotg, hr->hcsplt[i], HCSPLT(i)); + dwc2_writel(hsotg, hr->hcintmsk[i], HCINTMSK(i)); ++ dwc2_writel(hsotg, hr->hctsiz[i], HCTSIZ(i)); ++ dwc2_writel(hsotg, hr->hcidma[i], HCDMA(i)); ++ dwc2_writel(hsotg, hr->hcidmab[i], HCDMAB(i)); ++ } + + dwc2_writel(hsotg, hr->hprt0, HPRT0); + dwc2_writel(hsotg, hr->hfir, HFIR); diff --git a/queue-6.6/usb-dwc2-host-fix-isoc-flow-in-ddma-mode.patch b/queue-6.6/usb-dwc2-host-fix-isoc-flow-in-ddma-mode.patch new file mode 100644 index 00000000000..cc27819cc0c --- /dev/null +++ b/queue-6.6/usb-dwc2-host-fix-isoc-flow-in-ddma-mode.patch @@ -0,0 +1,134 @@ +From b258e42688501cadb1a6dd658d6f015df9f32d8f Mon Sep 17 00:00:00 2001 +From: Minas Harutyunyan +Date: Wed, 13 Mar 2024 09:21:32 +0000 +Subject: usb: dwc2: host: Fix ISOC flow in DDMA mode + +From: Minas Harutyunyan + +commit b258e42688501cadb1a6dd658d6f015df9f32d8f upstream. + +Fixed ISOC completion flow in DDMA mode. Added isoc +descriptor actual length value and update urb's start_frame +value. +Fixed initialization of ISOC DMA descriptors flow. + +Fixes: 56f5b1cff22a ("staging: Core files for the DWC2 driver") +Fixes: 20f2eb9c4cf8 ("staging: dwc2: add microframe scheduler from downstream Pi kernel") +Fixes: c17b337c1ea4 ("usb: dwc2: host: program descriptor for next frame") +Fixes: dc4c76e7b22c ("staging: HCD descriptor DMA support for the DWC2 driver") +Fixes: 762d3a1a9cd7 ("usb: dwc2: host: process all completed urbs") +CC: stable@vger.kernel.org +Signed-off-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/a8b1e1711cc6cabfb45d92ede12e35445c66f06c.1708944698.git.Minas.Harutyunyan@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/hcd.c | 12 ++++++++++-- + drivers/usb/dwc2/hcd_ddma.c | 17 +++++++++++------ + drivers/usb/dwc2/hw.h | 2 +- + 3 files changed, 22 insertions(+), 9 deletions(-) + +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -2701,8 +2701,11 @@ enum dwc2_transaction_type dwc2_hcd_sele + hsotg->available_host_channels--; + } + qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry); +- if (dwc2_assign_and_init_hc(hsotg, qh)) ++ if (dwc2_assign_and_init_hc(hsotg, qh)) { ++ if (hsotg->params.uframe_sched) ++ hsotg->available_host_channels++; + break; ++ } + + /* + * Move the QH from the periodic ready schedule to the +@@ -2735,8 +2738,11 @@ enum dwc2_transaction_type dwc2_hcd_sele + hsotg->available_host_channels--; + } + +- if (dwc2_assign_and_init_hc(hsotg, qh)) ++ if (dwc2_assign_and_init_hc(hsotg, qh)) { ++ if (hsotg->params.uframe_sched) ++ hsotg->available_host_channels++; + break; ++ } + + /* + * Move the QH from the non-periodic inactive schedule to the +@@ -4143,6 +4149,8 @@ void dwc2_host_complete(struct dwc2_hsot + urb->actual_length); + + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { ++ if (!hsotg->params.dma_desc_enable) ++ urb->start_frame = qtd->qh->start_active_frame; + urb->error_count = dwc2_hcd_urb_get_error_count(qtd->urb); + for (i = 0; i < urb->number_of_packets; ++i) { + urb->iso_frame_desc[i].actual_length = +--- a/drivers/usb/dwc2/hcd_ddma.c ++++ b/drivers/usb/dwc2/hcd_ddma.c +@@ -559,7 +559,7 @@ static void dwc2_init_isoc_dma_desc(stru + idx = qh->td_last; + inc = qh->host_interval; + hsotg->frame_number = dwc2_hcd_get_frame_number(hsotg); +- cur_idx = dwc2_frame_list_idx(hsotg->frame_number); ++ cur_idx = idx; + next_idx = dwc2_desclist_idx_inc(qh->td_last, inc, qh->dev_speed); + + /* +@@ -866,6 +866,8 @@ static int dwc2_cmpl_host_isoc_dma_desc( + { + struct dwc2_dma_desc *dma_desc; + struct dwc2_hcd_iso_packet_desc *frame_desc; ++ u16 frame_desc_idx; ++ struct urb *usb_urb = qtd->urb->priv; + u16 remain = 0; + int rc = 0; + +@@ -878,8 +880,11 @@ static int dwc2_cmpl_host_isoc_dma_desc( + DMA_FROM_DEVICE); + + dma_desc = &qh->desc_list[idx]; ++ frame_desc_idx = (idx - qtd->isoc_td_first) & (usb_urb->number_of_packets - 1); + +- frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index_last]; ++ frame_desc = &qtd->urb->iso_descs[frame_desc_idx]; ++ if (idx == qtd->isoc_td_first) ++ usb_urb->start_frame = dwc2_hcd_get_frame_number(hsotg); + dma_desc->buf = (u32)(qtd->urb->dma + frame_desc->offset); + if (chan->ep_is_in) + remain = (dma_desc->status & HOST_DMA_ISOC_NBYTES_MASK) >> +@@ -900,7 +905,7 @@ static int dwc2_cmpl_host_isoc_dma_desc( + frame_desc->status = 0; + } + +- if (++qtd->isoc_frame_index == qtd->urb->packet_count) { ++ if (++qtd->isoc_frame_index == usb_urb->number_of_packets) { + /* + * urb->status is not used for isoc transfers here. The + * individual frame_desc status are used instead. +@@ -1005,11 +1010,11 @@ static void dwc2_complete_isoc_xfer_ddma + return; + idx = dwc2_desclist_idx_inc(idx, qh->host_interval, + chan->speed); +- if (!rc) ++ if (rc == 0) + continue; + +- if (rc == DWC2_CMPL_DONE) +- break; ++ if (rc == DWC2_CMPL_DONE || rc == DWC2_CMPL_STOP) ++ goto stop_scan; + + /* rc == DWC2_CMPL_STOP */ + +--- a/drivers/usb/dwc2/hw.h ++++ b/drivers/usb/dwc2/hw.h +@@ -698,7 +698,7 @@ + #define TXSTS_QTOP_TOKEN_MASK (0x3 << 25) + #define TXSTS_QTOP_TOKEN_SHIFT 25 + #define TXSTS_QTOP_TERMINATE BIT(24) +-#define TXSTS_QSPCAVAIL_MASK (0xff << 16) ++#define TXSTS_QSPCAVAIL_MASK (0x7f << 16) + #define TXSTS_QSPCAVAIL_SHIFT 16 + #define TXSTS_FSPCAVAIL_MASK (0xffff << 0) + #define TXSTS_FSPCAVAIL_SHIFT 0 diff --git a/queue-6.6/usb-dwc2-host-fix-remote-wakeup-from-hibernation.patch b/queue-6.6/usb-dwc2-host-fix-remote-wakeup-from-hibernation.patch new file mode 100644 index 00000000000..cc2cf8a7521 --- /dev/null +++ b/queue-6.6/usb-dwc2-host-fix-remote-wakeup-from-hibernation.patch @@ -0,0 +1,66 @@ +From bae2bc73a59c200db53b6c15fb26bb758e2c6108 Mon Sep 17 00:00:00 2001 +From: Minas Harutyunyan +Date: Wed, 13 Mar 2024 09:21:21 +0000 +Subject: usb: dwc2: host: Fix remote wakeup from hibernation + +From: Minas Harutyunyan + +commit bae2bc73a59c200db53b6c15fb26bb758e2c6108 upstream. + +Starting from core v4.30a changed order of programming +GPWRDN_PMUACTV to 0 in case of exit from hibernation on +remote wakeup signaling from device. + +Fixes: c5c403dc4336 ("usb: dwc2: Add host/device hibernation functions") +CC: stable@vger.kernel.org +Signed-off-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/99385ec55ce73445b6fbd0f471c9bd40eb1c9b9e.1708939799.git.Minas.Harutyunyan@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/core.h | 1 + + drivers/usb/dwc2/hcd.c | 17 +++++++++++++---- + 2 files changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/usb/dwc2/core.h ++++ b/drivers/usb/dwc2/core.h +@@ -1086,6 +1086,7 @@ struct dwc2_hsotg { + bool needs_byte_swap; + + /* DWC OTG HW Release versions */ ++#define DWC2_CORE_REV_4_30a 0x4f54430a + #define DWC2_CORE_REV_2_71a 0x4f54271a + #define DWC2_CORE_REV_2_72a 0x4f54272a + #define DWC2_CORE_REV_2_80a 0x4f54280a +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -5610,10 +5610,12 @@ int dwc2_host_exit_hibernation(struct dw + dwc2_writel(hsotg, hr->hcfg, HCFG); + + /* De-assert Wakeup Logic */ +- gpwrdn = dwc2_readl(hsotg, GPWRDN); +- gpwrdn &= ~GPWRDN_PMUACTV; +- dwc2_writel(hsotg, gpwrdn, GPWRDN); +- udelay(10); ++ if (!(rem_wakeup && hsotg->hw_params.snpsid >= DWC2_CORE_REV_4_30a)) { ++ gpwrdn = dwc2_readl(hsotg, GPWRDN); ++ gpwrdn &= ~GPWRDN_PMUACTV; ++ dwc2_writel(hsotg, gpwrdn, GPWRDN); ++ udelay(10); ++ } + + hprt0 = hr->hprt0; + hprt0 |= HPRT0_PWR; +@@ -5638,6 +5640,13 @@ int dwc2_host_exit_hibernation(struct dw + hprt0 |= HPRT0_RES; + dwc2_writel(hsotg, hprt0, HPRT0); + ++ /* De-assert Wakeup Logic */ ++ if ((rem_wakeup && hsotg->hw_params.snpsid >= DWC2_CORE_REV_4_30a)) { ++ gpwrdn = dwc2_readl(hsotg, GPWRDN); ++ gpwrdn &= ~GPWRDN_PMUACTV; ++ dwc2_writel(hsotg, gpwrdn, GPWRDN); ++ udelay(10); ++ } + /* Wait for Resume time and then program HPRT again */ + mdelay(100); + hprt0 &= ~HPRT0_RES; diff --git a/queue-6.6/usb-dwc3-properly-set-system-wakeup.patch b/queue-6.6/usb-dwc3-properly-set-system-wakeup.patch new file mode 100644 index 00000000000..ce68488ed0a --- /dev/null +++ b/queue-6.6/usb-dwc3-properly-set-system-wakeup.patch @@ -0,0 +1,128 @@ +From f9aa41130ac69d13a53ce2a153ca79c70d43f39c Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Fri, 8 Mar 2024 02:40:25 +0000 +Subject: usb: dwc3: Properly set system wakeup + +From: Thinh Nguyen + +commit f9aa41130ac69d13a53ce2a153ca79c70d43f39c upstream. + +If the device is configured for system wakeup, then make sure that the +xHCI driver knows about it and make sure to permit wakeup only at the +appropriate time. + +For host mode, if the controller goes through the dwc3 code path, then a +child xHCI platform device is created. Make sure the platform device +also inherits the wakeup setting for xHCI to enable remote wakeup. + +For device mode, make sure to disable system wakeup if no gadget driver +is bound. We may experience unwanted system wakeup due to the wakeup +signal from the controller PMU detecting connection/disconnection when +in low power (D3). E.g. In the case of Steam Deck, the PCI PME prevents +the system staying in suspend. + +Cc: stable@vger.kernel.org +Reported-by: Guilherme G. Piccoli +Closes: https://lore.kernel.org/linux-usb/70a7692d-647c-9be7-00a6-06fc60f77294@igalia.com/T/#mf00d6669c2eff7b308d1162acd1d66c09f0853c7 +Fixes: d07e8819a03d ("usb: dwc3: add xHCI Host support") +Signed-off-by: Thinh Nguyen +Tested-by: Sanath S +Tested-by: Guilherme G. Piccoli # Steam Deck +Link: https://lore.kernel.org/r/667cfda7009b502e08462c8fb3f65841d103cc0a.1709865476.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/core.c | 2 ++ + drivers/usb/dwc3/core.h | 2 ++ + drivers/usb/dwc3/gadget.c | 10 ++++++++++ + drivers/usb/dwc3/host.c | 11 +++++++++++ + 4 files changed, 25 insertions(+) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1493,6 +1493,8 @@ static void dwc3_get_properties(struct d + else + dwc->sysdev = dwc->dev; + ++ dwc->sys_wakeup = device_may_wakeup(dwc->sysdev); ++ + ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name); + if (ret >= 0) { + dwc->usb_psy = power_supply_get_by_name(usb_psy_name); +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -1123,6 +1123,7 @@ struct dwc3_scratchpad_array { + * 3 - Reserved + * @dis_metastability_quirk: set to disable metastability quirk. + * @dis_split_quirk: set to disable split boundary. ++ * @sys_wakeup: set if the device may do system wakeup. + * @wakeup_configured: set if the device is configured for remote wakeup. + * @suspended: set to track suspend event due to U3/L2. + * @imod_interval: set the interrupt moderation interval in 250ns +@@ -1344,6 +1345,7 @@ struct dwc3 { + + unsigned dis_split_quirk:1; + unsigned async_callbacks:1; ++ unsigned sys_wakeup:1; + unsigned wakeup_configured:1; + unsigned suspended:1; + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2968,6 +2968,9 @@ static int dwc3_gadget_start(struct usb_ + dwc->gadget_driver = driver; + spin_unlock_irqrestore(&dwc->lock, flags); + ++ if (dwc->sys_wakeup) ++ device_wakeup_enable(dwc->sysdev); ++ + return 0; + } + +@@ -2983,6 +2986,9 @@ static int dwc3_gadget_stop(struct usb_g + struct dwc3 *dwc = gadget_to_dwc(g); + unsigned long flags; + ++ if (dwc->sys_wakeup) ++ device_wakeup_disable(dwc->sysdev); ++ + spin_lock_irqsave(&dwc->lock, flags); + dwc->gadget_driver = NULL; + dwc->max_cfg_eps = 0; +@@ -4664,6 +4670,10 @@ int dwc3_gadget_init(struct dwc3 *dwc) + else + dwc3_gadget_set_speed(dwc->gadget, dwc->maximum_speed); + ++ /* No system wakeup if no gadget driver bound */ ++ if (dwc->sys_wakeup) ++ device_wakeup_disable(dwc->sysdev); ++ + return 0; + + err5: +--- a/drivers/usb/dwc3/host.c ++++ b/drivers/usb/dwc3/host.c +@@ -123,6 +123,14 @@ int dwc3_host_init(struct dwc3 *dwc) + goto err; + } + ++ if (dwc->sys_wakeup) { ++ /* Restore wakeup setting if switched from device */ ++ device_wakeup_enable(dwc->sysdev); ++ ++ /* Pass on wakeup setting to the new xhci platform device */ ++ device_init_wakeup(&xhci->dev, true); ++ } ++ + return 0; + err: + platform_device_put(xhci); +@@ -131,6 +139,9 @@ err: + + void dwc3_host_exit(struct dwc3 *dwc) + { ++ if (dwc->sys_wakeup) ++ device_init_wakeup(&dwc->xhci->dev, false); ++ + platform_device_unregister(dwc->xhci); + dwc->xhci = NULL; + } diff --git a/queue-6.6/usb-typec-return-size-of-buffer-if-pd_set-operation-succeeds.patch b/queue-6.6/usb-typec-return-size-of-buffer-if-pd_set-operation-succeeds.patch new file mode 100644 index 00000000000..3f62e8c3dd4 --- /dev/null +++ b/queue-6.6/usb-typec-return-size-of-buffer-if-pd_set-operation-succeeds.patch @@ -0,0 +1,46 @@ +From 53f5094fdf5deacd99b8655df692e9278506724d Mon Sep 17 00:00:00 2001 +From: Kyle Tso +Date: Tue, 19 Mar 2024 15:43:09 +0800 +Subject: usb: typec: Return size of buffer if pd_set operation succeeds + +From: Kyle Tso + +commit 53f5094fdf5deacd99b8655df692e9278506724d upstream. + +The attribute writing should return the number of bytes used from the +buffer on success. + +Fixes: a7cff92f0635 ("usb: typec: USB Power Delivery helpers for ports and partners") +Cc: stable@vger.kernel.org +Signed-off-by: Kyle Tso +Reviewed-by: Guenter Roeck +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240319074309.3306579-1-kyletso@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/class.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/usb/typec/class.c ++++ b/drivers/usb/typec/class.c +@@ -1264,6 +1264,7 @@ static ssize_t select_usb_power_delivery + { + struct typec_port *port = to_typec_port(dev); + struct usb_power_delivery *pd; ++ int ret; + + if (!port->ops || !port->ops->pd_set) + return -EOPNOTSUPP; +@@ -1272,7 +1273,11 @@ static ssize_t select_usb_power_delivery + if (!pd) + return -EINVAL; + +- return port->ops->pd_set(port, pd); ++ ret = port->ops->pd_set(port, pd); ++ if (ret) ++ return ret; ++ ++ return size; + } + + static ssize_t select_usb_power_delivery_show(struct device *dev, diff --git a/queue-6.6/usb-typec-ucsi-ack-unsupported-commands.patch b/queue-6.6/usb-typec-ucsi-ack-unsupported-commands.patch new file mode 100644 index 00000000000..68ecbb1e7d6 --- /dev/null +++ b/queue-6.6/usb-typec-ucsi-ack-unsupported-commands.patch @@ -0,0 +1,40 @@ +From 6b5c85ddeea77d18c4b69e3bda60e9374a20c304 Mon Sep 17 00:00:00 2001 +From: "Christian A. Ehrhardt" +Date: Wed, 20 Mar 2024 08:39:24 +0100 +Subject: usb: typec: ucsi: Ack unsupported commands + +From: Christian A. Ehrhardt + +commit 6b5c85ddeea77d18c4b69e3bda60e9374a20c304 upstream. + +If a command completes the OPM must send an ack. This applies +to unsupported commands, too. + +Send the required ACK for unsupported commands. + +Signed-off-by: Christian A. Ehrhardt +Cc: stable +Reviewed-by: Heikki Krogerus +Tested-by: Neil Armstrong # on SM8550-QRD +Link: https://lore.kernel.org/r/20240320073927.1641788-4-lk@c--e.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -138,8 +138,12 @@ static int ucsi_exec_command(struct ucsi + if (!(cci & UCSI_CCI_COMMAND_COMPLETE)) + return -EIO; + +- if (cci & UCSI_CCI_NOT_SUPPORTED) ++ if (cci & UCSI_CCI_NOT_SUPPORTED) { ++ if (ucsi_acknowledge_command(ucsi) < 0) ++ dev_err(ucsi->dev, ++ "ACK of unsupported command failed\n"); + return -EOPNOTSUPP; ++ } + + if (cci & UCSI_CCI_ERROR) { + if (cmd == UCSI_GET_ERROR_STATUS) diff --git a/queue-6.6/usb-typec-ucsi-check-for-notifications-after-init.patch b/queue-6.6/usb-typec-ucsi-check-for-notifications-after-init.patch new file mode 100644 index 00000000000..b3056f2a913 --- /dev/null +++ b/queue-6.6/usb-typec-ucsi-check-for-notifications-after-init.patch @@ -0,0 +1,64 @@ +From 808a8b9e0b87bbc72bcc1f7ddfe5d04746e7ce56 Mon Sep 17 00:00:00 2001 +From: "Christian A. Ehrhardt" +Date: Wed, 20 Mar 2024 08:39:23 +0100 +Subject: usb: typec: ucsi: Check for notifications after init + +From: Christian A. Ehrhardt + +commit 808a8b9e0b87bbc72bcc1f7ddfe5d04746e7ce56 upstream. + +The completion notification for the final SET_NOTIFICATION_ENABLE +command during initialization can include a connector change +notification. However, at the time this completion notification is +processed, the ucsi struct is not ready to handle this notification. +As a result the notification is ignored and the controller +never sends an interrupt again. + +Re-check CCI for a pending connector state change after +initialization is complete. Adjust the corresponding debug +message accordingly. + +Fixes: 71a1fa0df2a3 ("usb: typec: ucsi: Store the notification mask") +Cc: stable@vger.kernel.org +Signed-off-by: Christian A. Ehrhardt +Reviewed-by: Heikki Krogerus +Tested-by: Neil Armstrong # on SM8550-QRD +Link: https://lore.kernel.org/r/20240320073927.1641788-3-lk@c--e.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -955,7 +955,7 @@ void ucsi_connector_change(struct ucsi * + struct ucsi_connector *con = &ucsi->connector[num - 1]; + + if (!(ucsi->ntfy & UCSI_ENABLE_NTFY_CONNECTOR_CHANGE)) { +- dev_dbg(ucsi->dev, "Bogus connector change event\n"); ++ dev_dbg(ucsi->dev, "Early connector change event\n"); + return; + } + +@@ -1352,6 +1352,7 @@ static int ucsi_init(struct ucsi *ucsi) + { + struct ucsi_connector *con, *connector; + u64 command, ntfy; ++ u32 cci; + int ret; + int i; + +@@ -1404,6 +1405,13 @@ static int ucsi_init(struct ucsi *ucsi) + + ucsi->connector = connector; + ucsi->ntfy = ntfy; ++ ++ ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci)); ++ if (ret) ++ return ret; ++ if (UCSI_CCI_CONNECTOR(READ_ONCE(cci))) ++ ucsi_connector_change(ucsi, cci); ++ + return 0; + + err_unregister: diff --git a/queue-6.6/usb-typec-ucsi-clear-event_pending-under-ppm-lock.patch b/queue-6.6/usb-typec-ucsi-clear-event_pending-under-ppm-lock.patch new file mode 100644 index 00000000000..3b45d358e2f --- /dev/null +++ b/queue-6.6/usb-typec-ucsi-clear-event_pending-under-ppm-lock.patch @@ -0,0 +1,44 @@ +From 15b2e71b4653b3e13df34695a29ebeee237c5af2 Mon Sep 17 00:00:00 2001 +From: "Christian A. Ehrhardt" +Date: Wed, 20 Mar 2024 08:39:22 +0100 +Subject: usb: typec: ucsi: Clear EVENT_PENDING under PPM lock + +From: Christian A. Ehrhardt + +commit 15b2e71b4653b3e13df34695a29ebeee237c5af2 upstream. + +Suppose we sleep on the PPM lock after clearing the EVENT_PENDING +bit because the thread for another connector is executing a command. +In this case the command completion of the other command will still +report the connector change for our connector. + +Clear the EVENT_PENDING bit under the PPM lock to avoid another +useless call to ucsi_handle_connector_change() in this case. + +Fixes: c9aed03a0a68 ("usb: ucsi: Add missing ppm_lock") +Cc: stable +Signed-off-by: Christian A. Ehrhardt +Reviewed-by: Heikki Krogerus +Tested-by: Neil Armstrong # on SM8550-QRD +Link: https://lore.kernel.org/r/20240320073927.1641788-2-lk@c--e.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -933,11 +933,11 @@ static void ucsi_handle_connector_change + if (con->status.change & UCSI_CONSTAT_CAM_CHANGE) + ucsi_partner_task(con, ucsi_check_altmodes, 1, 0); + +- clear_bit(EVENT_PENDING, &con->ucsi->flags); +- + mutex_lock(&ucsi->ppm_lock); ++ clear_bit(EVENT_PENDING, &con->ucsi->flags); + ret = ucsi_acknowledge_connector_change(ucsi); + mutex_unlock(&ucsi->ppm_lock); ++ + if (ret) + dev_err(ucsi->dev, "%s: ACK failed (%d)", __func__, ret); + diff --git a/queue-6.6/usb-typec-ucsi-clear-ucsi_cci_reset_complete-before-reset.patch b/queue-6.6/usb-typec-ucsi-clear-ucsi_cci_reset_complete-before-reset.patch new file mode 100644 index 00000000000..8adbc159092 --- /dev/null +++ b/queue-6.6/usb-typec-ucsi-clear-ucsi_cci_reset_complete-before-reset.patch @@ -0,0 +1,74 @@ +From 3de4f996a0b5412aa451729008130a488f71563e Mon Sep 17 00:00:00 2001 +From: "Christian A. Ehrhardt" +Date: Wed, 20 Mar 2024 08:39:26 +0100 +Subject: usb: typec: ucsi: Clear UCSI_CCI_RESET_COMPLETE before reset + +From: Christian A. Ehrhardt + +commit 3de4f996a0b5412aa451729008130a488f71563e upstream. + +Check the UCSI_CCI_RESET_COMPLETE complete flag before starting +another reset. Use a UCSI_SET_NOTIFICATION_ENABLE command to clear +the flag if it is set. + +Signed-off-by: Christian A. Ehrhardt +Cc: stable +Reviewed-by: Heikki Krogerus +Tested-by: Neil Armstrong # on SM8550-QRD +Link: https://lore.kernel.org/r/20240320073927.1641788-6-lk@c--e.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi.c | 36 +++++++++++++++++++++++++++++++++++- + 1 file changed, 35 insertions(+), 1 deletion(-) + +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -982,13 +982,47 @@ static int ucsi_reset_connector(struct u + + static int ucsi_reset_ppm(struct ucsi *ucsi) + { +- u64 command = UCSI_PPM_RESET; ++ u64 command; + unsigned long tmo; + u32 cci; + int ret; + + mutex_lock(&ucsi->ppm_lock); + ++ ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci)); ++ if (ret < 0) ++ goto out; ++ ++ /* ++ * If UCSI_CCI_RESET_COMPLETE is already set we must clear ++ * the flag before we start another reset. Send a ++ * UCSI_SET_NOTIFICATION_ENABLE command to achieve this. ++ * Ignore a timeout and try the reset anyway if this fails. ++ */ ++ if (cci & UCSI_CCI_RESET_COMPLETE) { ++ command = UCSI_SET_NOTIFICATION_ENABLE; ++ ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, &command, ++ sizeof(command)); ++ if (ret < 0) ++ goto out; ++ ++ tmo = jiffies + msecs_to_jiffies(UCSI_TIMEOUT_MS); ++ do { ++ ret = ucsi->ops->read(ucsi, UCSI_CCI, ++ &cci, sizeof(cci)); ++ if (ret < 0) ++ goto out; ++ if (cci & UCSI_CCI_COMMAND_COMPLETE) ++ break; ++ if (time_is_before_jiffies(tmo)) ++ break; ++ msleep(20); ++ } while (1); ++ ++ WARN_ON(cci & UCSI_CCI_RESET_COMPLETE); ++ } ++ ++ command = UCSI_PPM_RESET; + ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, &command, + sizeof(command)); + if (ret < 0) diff --git a/queue-6.6/usb-typec-ucsi_acpi-refactor-and-fix-dell-quirk.patch b/queue-6.6/usb-typec-ucsi_acpi-refactor-and-fix-dell-quirk.patch new file mode 100644 index 00000000000..89f85866b53 --- /dev/null +++ b/queue-6.6/usb-typec-ucsi_acpi-refactor-and-fix-dell-quirk.patch @@ -0,0 +1,163 @@ +From 6aaceb7d9cd00f3e065dc4b054ecfe52c5253b03 Mon Sep 17 00:00:00 2001 +From: "Christian A. Ehrhardt" +Date: Wed, 20 Mar 2024 08:39:25 +0100 +Subject: usb: typec: ucsi_acpi: Refactor and fix DELL quirk + +From: Christian A. Ehrhardt + +commit 6aaceb7d9cd00f3e065dc4b054ecfe52c5253b03 upstream. + +Some DELL systems don't like UCSI_ACK_CC_CI commands with the +UCSI_ACK_CONNECTOR_CHANGE but not the UCSI_ACK_COMMAND_COMPLETE +bit set. The current quirk still leaves room for races because +it requires two consecutive ACK commands to be sent. + +Refactor and significantly simplify the quirk to fix this: +Send a dummy command and bundle the connector change ack with the +command completion ack in a single UCSI_ACK_CC_CI command. +This removes the need to probe for the quirk. + +While there define flag bits for struct ucsi_acpi->flags in ucsi_acpi.c +and don't re-use definitions from ucsi.h for struct ucsi->flags. + +Fixes: f3be347ea42d ("usb: ucsi_acpi: Quirk to ack a connector change ack cmd") +Cc: stable@vger.kernel.org +Signed-off-by: Christian A. Ehrhardt +Reviewed-by: Heikki Krogerus +Tested-by: Neil Armstrong # on SM8550-QRD +Link: https://lore.kernel.org/r/20240320073927.1641788-5-lk@c--e.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi_acpi.c | 71 ++++++++++++++++--------------------- + 1 file changed, 31 insertions(+), 40 deletions(-) + +--- a/drivers/usb/typec/ucsi/ucsi_acpi.c ++++ b/drivers/usb/typec/ucsi/ucsi_acpi.c +@@ -23,10 +23,11 @@ struct ucsi_acpi { + void *base; + struct completion complete; + unsigned long flags; ++#define UCSI_ACPI_SUPPRESS_EVENT 0 ++#define UCSI_ACPI_COMMAND_PENDING 1 ++#define UCSI_ACPI_ACK_PENDING 2 + guid_t guid; + u64 cmd; +- bool dell_quirk_probed; +- bool dell_quirk_active; + }; + + static int ucsi_acpi_dsm(struct ucsi_acpi *ua, int func) +@@ -79,9 +80,9 @@ static int ucsi_acpi_sync_write(struct u + int ret; + + if (ack) +- set_bit(ACK_PENDING, &ua->flags); ++ set_bit(UCSI_ACPI_ACK_PENDING, &ua->flags); + else +- set_bit(COMMAND_PENDING, &ua->flags); ++ set_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags); + + ret = ucsi_acpi_async_write(ucsi, offset, val, val_len); + if (ret) +@@ -92,9 +93,9 @@ static int ucsi_acpi_sync_write(struct u + + out_clear_bit: + if (ack) +- clear_bit(ACK_PENDING, &ua->flags); ++ clear_bit(UCSI_ACPI_ACK_PENDING, &ua->flags); + else +- clear_bit(COMMAND_PENDING, &ua->flags); ++ clear_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags); + + return ret; + } +@@ -129,51 +130,40 @@ static const struct ucsi_operations ucsi + }; + + /* +- * Some Dell laptops expect that an ACK command with the +- * UCSI_ACK_CONNECTOR_CHANGE bit set is followed by a (separate) +- * ACK command that only has the UCSI_ACK_COMMAND_COMPLETE bit set. +- * If this is not done events are not delivered to OSPM and +- * subsequent commands will timeout. ++ * Some Dell laptops don't like ACK commands with the ++ * UCSI_ACK_CONNECTOR_CHANGE but not the UCSI_ACK_COMMAND_COMPLETE ++ * bit set. To work around this send a dummy command and bundle the ++ * UCSI_ACK_CONNECTOR_CHANGE with the UCSI_ACK_COMMAND_COMPLETE ++ * for the dummy command. + */ + static int + ucsi_dell_sync_write(struct ucsi *ucsi, unsigned int offset, + const void *val, size_t val_len) + { + struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); +- u64 cmd = *(u64 *)val, ack = 0; ++ u64 cmd = *(u64 *)val; ++ u64 dummycmd = UCSI_GET_CAPABILITY; + int ret; + +- if (UCSI_COMMAND(cmd) == UCSI_ACK_CC_CI && +- cmd & UCSI_ACK_CONNECTOR_CHANGE) +- ack = UCSI_ACK_CC_CI | UCSI_ACK_COMMAND_COMPLETE; ++ if (cmd == (UCSI_ACK_CC_CI | UCSI_ACK_CONNECTOR_CHANGE)) { ++ cmd |= UCSI_ACK_COMMAND_COMPLETE; + +- ret = ucsi_acpi_sync_write(ucsi, offset, val, val_len); +- if (ret != 0) +- return ret; +- if (ack == 0) +- return ret; +- +- if (!ua->dell_quirk_probed) { +- ua->dell_quirk_probed = true; ++ /* ++ * The UCSI core thinks it is sending a connector change ack ++ * and will accept new connector change events. We don't want ++ * this to happen for the dummy command as its response will ++ * still report the very event that the core is trying to clear. ++ */ ++ set_bit(UCSI_ACPI_SUPPRESS_EVENT, &ua->flags); ++ ret = ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, &dummycmd, ++ sizeof(dummycmd)); ++ clear_bit(UCSI_ACPI_SUPPRESS_EVENT, &ua->flags); + +- cmd = UCSI_GET_CAPABILITY; +- ret = ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, &cmd, +- sizeof(cmd)); +- if (ret == 0) +- return ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, +- &ack, sizeof(ack)); +- if (ret != -ETIMEDOUT) ++ if (ret < 0) + return ret; +- +- ua->dell_quirk_active = true; +- dev_err(ua->dev, "Firmware bug: Additional ACK required after ACKing a connector change.\n"); +- dev_err(ua->dev, "Firmware bug: Enabling workaround\n"); + } + +- if (!ua->dell_quirk_active) +- return ret; +- +- return ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, &ack, sizeof(ack)); ++ return ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd)); + } + + static const struct ucsi_operations ucsi_dell_ops = { +@@ -209,13 +199,14 @@ static void ucsi_acpi_notify(acpi_handle + if (ret) + return; + +- if (UCSI_CCI_CONNECTOR(cci)) ++ if (UCSI_CCI_CONNECTOR(cci) && ++ !test_bit(UCSI_ACPI_SUPPRESS_EVENT, &ua->flags)) + ucsi_connector_change(ua->ucsi, UCSI_CCI_CONNECTOR(cci)); + + if (cci & UCSI_CCI_ACK_COMPLETE && test_bit(ACK_PENDING, &ua->flags)) + complete(&ua->complete); + if (cci & UCSI_CCI_COMMAND_COMPLETE && +- test_bit(COMMAND_PENDING, &ua->flags)) ++ test_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags)) + complete(&ua->complete); + } + diff --git a/queue-6.6/usb-udc-remove-warning-when-queue-disabled-ep.patch b/queue-6.6/usb-udc-remove-warning-when-queue-disabled-ep.patch new file mode 100644 index 00000000000..1028f202415 --- /dev/null +++ b/queue-6.6/usb-udc-remove-warning-when-queue-disabled-ep.patch @@ -0,0 +1,44 @@ +From 2a587a035214fa1b5ef598aea0b81848c5b72e5e Mon Sep 17 00:00:00 2001 +From: yuan linyu +Date: Fri, 15 Mar 2024 10:01:44 +0800 +Subject: usb: udc: remove warning when queue disabled ep + +From: yuan linyu + +commit 2a587a035214fa1b5ef598aea0b81848c5b72e5e upstream. + +It is possible trigger below warning message from mass storage function, + +WARNING: CPU: 6 PID: 3839 at drivers/usb/gadget/udc/core.c:294 usb_ep_queue+0x7c/0x104 +pc : usb_ep_queue+0x7c/0x104 +lr : fsg_main_thread+0x494/0x1b3c + +Root cause is mass storage function try to queue request from main thread, +but other thread may already disable ep when function disable. + +As there is no function failure in the driver, in order to avoid effort +to fix warning, change WARN_ON_ONCE() in usb_ep_queue() to pr_debug(). + +Suggested-by: Alan Stern +Cc: stable@vger.kernel.org +Signed-off-by: yuan linyu +Reviewed-by: Alan Stern +Link: https://lore.kernel.org/r/20240315020144.2715575-1-yuanlinyu@hihonor.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -292,7 +292,9 @@ int usb_ep_queue(struct usb_ep *ep, + { + int ret = 0; + +- if (WARN_ON_ONCE(!ep->enabled && ep->address)) { ++ if (!ep->enabled && ep->address) { ++ pr_debug("USB gadget: queue request to disabled ep 0x%x (%s)\n", ++ ep->address, ep->name); + ret = -ESHUTDOWN; + goto out; + } -- 2.39.5