Skip to content

Commit

Permalink
revert vhci urb cancel partial fix
Browse files Browse the repository at this point in the history
This fix helped resolve some crashes, but seems to cause others.

This reverts part of commit b8ce142.
  • Loading branch information
Redecorating committed Nov 19, 2023
1 parent f71ad98 commit c9188b1
Showing 1 changed file with 67 additions and 22 deletions.
89 changes: 67 additions & 22 deletions 1001-Add-apple-bce-driver.patch
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
From 80093f92d42d77f27de6b204550baf4622070732 Mon Sep 17 00:00:00 2001
From 28d876289e6c7fe64a6fcdbc377035a99edbae44 Mon Sep 17 00:00:00 2001
From: Aditya Garg <[email protected]>
Date: Tue, 12 Sep 2023 12:26:12 +0530
Date: Wed, 21 Sep 2022 23:12:21 +0530
Subject: [PATCH] Add apple-bce driver

---
drivers/staging/apple-bce/Makefile | 28 +
drivers/staging/apple-bce/apple_bce.c | 443 ++++++++++
drivers/staging/apple-bce/apple_bce.c | 438 ++++++++++
drivers/staging/apple-bce/apple_bce.h | 38 +
drivers/staging/apple-bce/audio/audio.c | 711 ++++++++++++++++
drivers/staging/apple-bce/audio/audio.c | 706 ++++++++++++++++
drivers/staging/apple-bce/audio/audio.h | 123 +++
drivers/staging/apple-bce/audio/description.h | 42 +
drivers/staging/apple-bce/audio/pcm.c | 308 +++++++
Expand Down Expand Up @@ -4680,41 +4680,79 @@ index 000000000..8226363d6
+ list_add_tail(&real_urb->urb_list, &q->giveback_urb_list);
+}
+
+static int bce_vhci_urb_dequeue_unlink(struct bce_vhci_transfer_queue *q, struct urb *urb, int status)
+{
+ struct bce_vhci_urb *vurb;
+ int ret = 0;
+ if ((ret = usb_hcd_check_unlink_urb(q->vhci->hcd, urb, status)))
+ return ret;
+ usb_hcd_unlink_urb_from_ep(q->vhci->hcd, urb);
+
+ vurb = urb->hcpriv;
+ if (vurb->state != BCE_VHCI_URB_INIT_PENDING)
+ ++q->remaining_active_requests;
+ return ret;
+}
+
+static int bce_vhci_urb_remove(struct bce_vhci_transfer_queue *q, struct urb *urb, int status)
+{
+ unsigned long flags;
+ int ret;
+ struct bce_vhci_urb *vurb;
+ spin_lock_irqsave(&q->urb_lock, flags);
+ ret = bce_vhci_urb_dequeue_unlink(q, urb, status);
+ spin_unlock_irqrestore(&q->urb_lock, flags);
+ if (ret)
+ return ret;
+ vurb = urb->hcpriv;
+ kfree(vurb);
+ usb_hcd_giveback_urb(q->vhci->hcd, urb, status);
+ return 0;
+}
+
+static void bce_vhci_urb_cancel_w(struct work_struct *ws)
+{
+ struct bce_vhci_transfer_queue_urb_cancel_work *w =
+ container_of(ws, struct bce_vhci_transfer_queue_urb_cancel_work, ws);
+
+ pr_debug("bce-vhci: [%02x] Cancelling URB\n", w->q->endp_addr);
+ bce_vhci_transfer_queue_pause(w->q, BCE_VHCI_PAUSE_INTERNAL_WQ);
+ bce_vhci_urb_remove(w->q, w->urb, w->status);
+ bce_vhci_transfer_queue_resume(w->q, BCE_VHCI_PAUSE_INTERNAL_WQ);
+ kfree(w);
+}
+
+int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *urb, int status)
+{
+ struct bce_vhci_transfer_queue_urb_cancel_work *w;
+ struct bce_vhci_urb *vurb;
+ unsigned long flags;
+ int ret;
+
+ /* Quick check to try to avoid pausing; must past 0 as status we won't be able to call it again. */
+ spin_lock_irqsave(&q->urb_lock, flags);
+ if ((ret = usb_hcd_check_unlink_urb(q->vhci->hcd, urb, status))) {
+ if ((ret = usb_hcd_check_unlink_urb(q->vhci->hcd, urb, 0))) {
+ spin_unlock_irqrestore(&q->urb_lock, flags);
+ return ret;
+ }
+
+ vurb = urb->hcpriv;
+ /* 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) {
+ pr_debug("bce-vhci: [%02x] Cancelling URB\n", q->endp_addr);
+
+ if (vurb->state == BCE_VHCI_URB_INIT_PENDING) {
+ bce_vhci_urb_dequeue_unlink(q, urb, status);
+ spin_unlock_irqrestore(&q->urb_lock, flags);
+ bce_vhci_transfer_queue_pause(q, BCE_VHCI_PAUSE_INTERNAL_WQ);
+ spin_lock_irqsave(&q->urb_lock, flags);
+
+ ++q->remaining_active_requests;
+ kfree(vurb);
+ usb_hcd_giveback_urb(q->vhci->hcd, urb, status);
+ return 0;
+ }
+
+ usb_hcd_unlink_urb_from_ep(q->vhci->hcd, urb);
+
+ spin_unlock_irqrestore(&q->urb_lock, flags);
+
+ usb_hcd_giveback_urb(q->vhci->hcd, urb, status);
+
+ if (vurb->state != BCE_VHCI_URB_INIT_PENDING)
+ bce_vhci_transfer_queue_resume(q, BCE_VHCI_PAUSE_INTERNAL_WQ);
+
+ kfree(vurb);
+
+ w = kzalloc(sizeof(struct bce_vhci_transfer_queue_urb_cancel_work), GFP_KERNEL);
+ INIT_WORK(&w->ws, bce_vhci_urb_cancel_w);
+ w->q = q;
+ w->urb = urb;
+ w->status = status;
+ queue_work(q->vhci->tq_state_wq, &w->ws);
+ return 0;
+}
+
Expand Down Expand Up @@ -5009,6 +5047,13 @@ index 000000000..6a62a00b2
+ u32 receive_offset;
+};
+
+struct bce_vhci_transfer_queue_urb_cancel_work {
+ struct work_struct ws;
+ struct bce_vhci_transfer_queue *q;
+ struct urb *urb;
+ int status;
+};
+
+void bce_vhci_create_transfer_queue(struct bce_vhci *vhci, struct bce_vhci_transfer_queue *q,
+ struct usb_host_endpoint *endp, bce_vhci_device_t dev_addr, enum dma_data_direction dir);
+void bce_vhci_destroy_transfer_queue(struct bce_vhci *vhci, struct bce_vhci_transfer_queue *q);
Expand Down

0 comments on commit c9188b1

Please sign in to comment.