Files
BPI-CM9-Linux/build/patch/kernel/archive/uefi-x86-6.19/1003-Fix-freezing-on-turning-off-camera.patch

73 lines
2.7 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: mnural <[email protected]>
Date: Mon, 14 Apr 2025 14:44:20 +0530
Subject: Fix freezing on turning off camera
Detailed logs and reason behind can be seen here:
https://github.com/t2linux/T2-Debian-and-Ubuntu-Kernel/issues/130#issuecomment-2799130835
---
drivers/staging/apple-bce/vhci/transfer.c | 16 ++++++++--
drivers/staging/apple-bce/vhci/transfer.h | 4 ++-
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/apple-bce/vhci/transfer.c b/drivers/staging/apple-bce/vhci/transfer.c
index 111111111111..222222222222 100644
--- a/drivers/staging/apple-bce/vhci/transfer.c
+++ b/drivers/staging/apple-bce/vhci/transfer.c
@@ -400,6 +400,7 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u
struct bce_vhci_urb *vurb;
unsigned long flags;
int ret;
+ enum bce_vhci_urb_state old_state;
spin_lock_irqsave(&q->urb_lock, flags);
if ((ret = usb_hcd_check_unlink_urb(q->vhci->hcd, urb, status))) {
@@ -408,8 +409,19 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u
}
vurb = urb->hcpriv;
+
+ old_state = vurb->state; /* save old state to use later because we'll set state as cancelled */
+
+ if (old_state == BCE_VHCI_URB_CANCELLED) {
+ spin_unlock_irqrestore(&q->urb_lock, flags);
+ pr_debug("bce-vhci: URB %p is already cancelled, skipping\n", urb);
+ return 0;
+ }
+
+ vurb->state = BCE_VHCI_URB_CANCELLED;
+
/* If the URB wasn't posted to the device yet, we can still remove it on the host without pausing the queue. */
- if (vurb->state != BCE_VHCI_URB_INIT_PENDING) {
+ if (old_state != BCE_VHCI_URB_INIT_PENDING) {
pr_debug("bce-vhci: [%02x] Cancelling URB\n", q->endp_addr);
spin_unlock_irqrestore(&q->urb_lock, flags);
@@ -425,7 +437,7 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u
usb_hcd_giveback_urb(q->vhci->hcd, urb, status);
- if (vurb->state != BCE_VHCI_URB_INIT_PENDING)
+ if (old_state != BCE_VHCI_URB_INIT_PENDING)
bce_vhci_transfer_queue_resume(q, BCE_VHCI_PAUSE_INTERNAL_WQ);
kfree(vurb);
diff --git a/drivers/staging/apple-bce/vhci/transfer.h b/drivers/staging/apple-bce/vhci/transfer.h
index 111111111111..222222222222 100644
--- a/drivers/staging/apple-bce/vhci/transfer.h
+++ b/drivers/staging/apple-bce/vhci/transfer.h
@@ -44,7 +44,9 @@ enum bce_vhci_urb_state {
BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST,
BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION,
- BCE_VHCI_URB_CONTROL_COMPLETE
+ BCE_VHCI_URB_CONTROL_COMPLETE,
+
+ BCE_VHCI_URB_CANCELLED
};
struct bce_vhci_urb {
struct urb *urb;
--
Armbian