1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
From: Bryan Kemp <bryan@kempville.com>
Date: Sat, 7 Jul 2012 16:24:07 -0500
Subject: [PATCH] Updating dwc_otg driver to fix issue releasing pcm stream
see: https://github.com/raspberrypi/firmware/issues/51
---
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
index 6a89b1e..68664e5 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
@@ -70,6 +70,7 @@
#include "dwc_otg_hcd_if.h"
#include "dwc_otg_dbg.h"
#include "dwc_otg_driver.h"
+#include "dwc_otg_hcd.h"
/**
* Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
@@ -267,6 +268,7 @@ extern unsigned int g_dwc_otg_interrupt_counts[10];
static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
{
+ uint64_t flags;
struct urb *urb = (struct urb *)urb_handle;
#ifdef DEBUG_SOF_FIX
@@ -356,7 +358,9 @@ static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb);
#else
+ DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb);
+ DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
#endif
return 0;
@@ -767,6 +771,8 @@ static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
#endif
{
+ int rc;
+ uint64_t flags;
dwc_otg_hcd_t *dwc_otg_hcd;
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
@@ -788,8 +794,18 @@ static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
usb_hcd_giveback_urb(hcd, urb);
#else
- usb_hcd_unlink_urb_from_ep(hcd, urb);
- usb_hcd_giveback_urb(hcd, urb, status);
+ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
+ rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if(!rc)
+ {
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ }
+
+ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
+ if (!rc)
+ {
+ usb_hcd_giveback_urb(hcd, urb, status);
+ }
#endif
if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
DWC_PRINTF("Called usb_hcd_giveback_urb()\n");
|