-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This fix helped resolve some crashes, but seems to cause others. This reverts part of commit b8ce142.
- Loading branch information
1 parent
f71ad98
commit c9188b1
Showing
1 changed file
with
67 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 +++++++ | ||
|
@@ -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; | ||
+} | ||
+ | ||
|
@@ -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); | ||
|