summaryrefslogtreecommitdiff
path: root/patches/collateral-evolutions/network/0053-remove_wait_on_bit_timeout/btusb.patch
blob: bd57e8279118c3a1f97a87e44833ddc2a148e652 (plain)
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -339,6 +339,7 @@
 	int (*recv_bulk)(struct btusb_data *data, void *buffer, int count);
 };
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
 static int btusb_wait_on_bit_timeout(void *word, int bit, unsigned long timeout,
 				     unsigned mode)
 {
@@ -348,6 +349,7 @@
 	return out_of_line_wait_on_bit_timeout(word, bit, bit_wait_timeout,
 					       mode, timeout);
 }
+#endif
 
 static inline void btusb_free_frags(struct btusb_data *data)
 {
@@ -1816,8 +1816,12 @@ static int btusb_recv_event_intel(struct
 			if (test_and_clear_bit(BTUSB_DOWNLOADING,
 					       &data->flags) &&
 			    test_bit(BTUSB_FIRMWARE_LOADED, &data->flags)) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
 				smp_mb__after_atomic();
 				wake_up_bit(&data->flags, BTUSB_DOWNLOADING);
+#else
+				wake_up_interruptible(&hdev->req_wait_q);
+#endif
 			}
 		}
 
@@ -1828,8 +1832,12 @@ static int btusb_recv_event_intel(struct
 		if (skb->len == 9 && hdr->evt == 0xff && hdr->plen == 0x07 &&
 		    skb->data[2] == 0x02) {
 			if (test_and_clear_bit(BTUSB_BOOTING, &data->flags)) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
 				smp_mb__after_atomic();
 				wake_up_bit(&data->flags, BTUSB_BOOTING);
+#else
+				wake_up_interruptible(&hdev->req_wait_q);
+#endif
 			}
 		}
 	}
@@ -2197,6 +2205,7 @@ static int btusb_setup_intel_new(struct
 	 * and thus just timeout if that happens and fail the setup
 	 * of this device.
 	 */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
 	err = btusb_wait_on_bit_timeout(&data->flags, BTUSB_DOWNLOADING,
 					msecs_to_jiffies(5000),
 					TASK_INTERRUPTIBLE);
@@ -2211,6 +2220,31 @@ static int btusb_setup_intel_new(struct
 		err = -ETIMEDOUT;
 		goto done;
 	}
+#else
+	if (test_bit(BTUSB_DOWNLOADING, &data->flags)) {
+		DECLARE_WAITQUEUE(wait, current);
+		signed long timeout;
+
+		add_wait_queue(&hdev->req_wait_q, &wait);
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		timeout = schedule_timeout(msecs_to_jiffies(5000));
+
+		remove_wait_queue(&hdev->req_wait_q, &wait);
+
+		if (signal_pending(current)) {
+			BT_ERR("%s: Firmware loading interrupted", hdev->name);
+			err = -EINTR;
+			goto done;
+		}
+
+		if (!timeout) {
+			BT_ERR("%s: Firmware loading timeout", hdev->name);
+			err = -ETIMEDOUT;
+			goto done;
+		}
+	}
+#endif
 
 	if (test_bit(BTUSB_FIRMWARE_FAILED, &data->flags)) {
 		BT_ERR("%s: Firmware loading failed", hdev->name);
@@ -2250,6 +2284,7 @@ done:
 	 */
 	BT_INFO("%s: Waiting for device to boot", hdev->name);
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
 	err = btusb_wait_on_bit_timeout(&data->flags, BTUSB_BOOTING,
 					msecs_to_jiffies(1000),
 					TASK_INTERRUPTIBLE);
@@ -2263,6 +2298,33 @@ done:
 		BT_ERR("%s: Device boot timeout", hdev->name);
 		return -ETIMEDOUT;
 	}
+#else
+	if (test_bit(BTUSB_BOOTING, &data->flags)) {
+		DECLARE_WAITQUEUE(wait, current);
+		signed long timeout;
+
+		add_wait_queue(&hdev->req_wait_q, &wait);
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		/* Booting into operational firmware should not take
+		 * longer than 1 second. However if that happens, then
+		 * just fail the setup since something went wrong.
+		 */
+		timeout = schedule_timeout(msecs_to_jiffies(1000));
+
+		remove_wait_queue(&hdev->req_wait_q, &wait);
+
+		if (signal_pending(current)) {
+			BT_ERR("%s: Device boot interrupted", hdev->name);
+			return -EINTR;
+		}
+
+		if (!timeout) {
+			BT_ERR("%s: Device boot timeout", hdev->name);
+			return -ETIMEDOUT;
+		}
+	}
+#endif
 
 	rettime = ktime_get();
 	delta = ktime_sub(rettime, calltime);