1 |
commit: 039c34f45053a49cf1de6c87a0efdd27ebaa69c9 |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Oct 18 13:44:00 2017 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Oct 18 13:44:00 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=039c34f4 |
7 |
|
8 |
Linux patch 4.4.93 |
9 |
|
10 |
0000_README | 4 + |
11 |
1092_linux-4.4.93.patch | 933 ++++++++++++++++++++++++++++++++++++++++++++++++ |
12 |
2 files changed, 937 insertions(+) |
13 |
|
14 |
diff --git a/0000_README b/0000_README |
15 |
index a7ddd0f..a90a29a 100644 |
16 |
--- a/0000_README |
17 |
+++ b/0000_README |
18 |
@@ -411,6 +411,10 @@ Patch: 1091_linux-4.4.92.patch |
19 |
From: http://www.kernel.org |
20 |
Desc: Linux 4.4.92 |
21 |
|
22 |
+Patch: 1092_linux-4.4.93.patch |
23 |
+From: http://www.kernel.org |
24 |
+Desc: Linux 4.4.93 |
25 |
+ |
26 |
Patch: 1500_XATTR_USER_PREFIX.patch |
27 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
28 |
Desc: Support for namespace user.pax.* on tmpfs. |
29 |
|
30 |
diff --git a/1092_linux-4.4.93.patch b/1092_linux-4.4.93.patch |
31 |
new file mode 100644 |
32 |
index 0000000..08ef256 |
33 |
--- /dev/null |
34 |
+++ b/1092_linux-4.4.93.patch |
35 |
@@ -0,0 +1,933 @@ |
36 |
+diff --git a/Makefile b/Makefile |
37 |
+index fab2d640a27e..77a17fb24b6d 100644 |
38 |
+--- a/Makefile |
39 |
++++ b/Makefile |
40 |
+@@ -1,6 +1,6 @@ |
41 |
+ VERSION = 4 |
42 |
+ PATCHLEVEL = 4 |
43 |
+-SUBLEVEL = 92 |
44 |
++SUBLEVEL = 93 |
45 |
+ EXTRAVERSION = |
46 |
+ NAME = Blurry Fish Butt |
47 |
+ |
48 |
+diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c |
49 |
+index 6da2e4a6ba39..dd058aa8a3b5 100644 |
50 |
+--- a/arch/mips/math-emu/cp1emu.c |
51 |
++++ b/arch/mips/math-emu/cp1emu.c |
52 |
+@@ -2360,7 +2360,6 @@ dcopuop: |
53 |
+ break; |
54 |
+ default: |
55 |
+ /* Reserved R6 ops */ |
56 |
+- pr_err("Reserved MIPS R6 CMP.condn.S operation\n"); |
57 |
+ return SIGILL; |
58 |
+ } |
59 |
+ } |
60 |
+@@ -2434,7 +2433,6 @@ dcopuop: |
61 |
+ break; |
62 |
+ default: |
63 |
+ /* Reserved R6 ops */ |
64 |
+- pr_err("Reserved MIPS R6 CMP.condn.D operation\n"); |
65 |
+ return SIGILL; |
66 |
+ } |
67 |
+ } |
68 |
+diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h |
69 |
+index e7636bac7372..6c98821fef5e 100644 |
70 |
+--- a/arch/x86/include/asm/alternative-asm.h |
71 |
++++ b/arch/x86/include/asm/alternative-asm.h |
72 |
+@@ -62,8 +62,10 @@ |
73 |
+ #define new_len2 145f-144f |
74 |
+ |
75 |
+ /* |
76 |
+- * max without conditionals. Idea adapted from: |
77 |
++ * gas compatible max based on the idea from: |
78 |
+ * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax |
79 |
++ * |
80 |
++ * The additional "-" is needed because gas uses a "true" value of -1. |
81 |
+ */ |
82 |
+ #define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b))))) |
83 |
+ |
84 |
+diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h |
85 |
+index 7bfc85bbb8ff..09936e9c8154 100644 |
86 |
+--- a/arch/x86/include/asm/alternative.h |
87 |
++++ b/arch/x86/include/asm/alternative.h |
88 |
+@@ -102,12 +102,12 @@ static inline int alternatives_text_reserved(void *start, void *end) |
89 |
+ alt_end_marker ":\n" |
90 |
+ |
91 |
+ /* |
92 |
+- * max without conditionals. Idea adapted from: |
93 |
++ * gas compatible max based on the idea from: |
94 |
+ * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax |
95 |
+ * |
96 |
+- * The additional "-" is needed because gas works with s32s. |
97 |
++ * The additional "-" is needed because gas uses a "true" value of -1. |
98 |
+ */ |
99 |
+-#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") - (" b ")))))" |
100 |
++#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))" |
101 |
+ |
102 |
+ /* |
103 |
+ * Pad the second replacement alternative with additional NOPs if it is |
104 |
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c |
105 |
+index a018dff00808..9114588e3e61 100644 |
106 |
+--- a/arch/x86/kvm/vmx.c |
107 |
++++ b/arch/x86/kvm/vmx.c |
108 |
+@@ -10369,7 +10369,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, |
109 |
+ * (KVM doesn't change it)- no reason to call set_cr4_guest_host_mask(); |
110 |
+ */ |
111 |
+ vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK); |
112 |
+- kvm_set_cr4(vcpu, vmcs12->host_cr4); |
113 |
++ vmx_set_cr4(vcpu, vmcs12->host_cr4); |
114 |
+ |
115 |
+ nested_ept_uninit_mmu_context(vcpu); |
116 |
+ |
117 |
+diff --git a/block/bio.c b/block/bio.c |
118 |
+index 14263fab94d3..68bbc835bacc 100644 |
119 |
+--- a/block/bio.c |
120 |
++++ b/block/bio.c |
121 |
+@@ -1320,6 +1320,7 @@ struct bio *bio_map_user_iov(struct request_queue *q, |
122 |
+ offset = uaddr & ~PAGE_MASK; |
123 |
+ for (j = cur_page; j < page_limit; j++) { |
124 |
+ unsigned int bytes = PAGE_SIZE - offset; |
125 |
++ unsigned short prev_bi_vcnt = bio->bi_vcnt; |
126 |
+ |
127 |
+ if (len <= 0) |
128 |
+ break; |
129 |
+@@ -1334,6 +1335,13 @@ struct bio *bio_map_user_iov(struct request_queue *q, |
130 |
+ bytes) |
131 |
+ break; |
132 |
+ |
133 |
++ /* |
134 |
++ * check if vector was merged with previous |
135 |
++ * drop page reference if needed |
136 |
++ */ |
137 |
++ if (bio->bi_vcnt == prev_bi_vcnt) |
138 |
++ put_page(pages[j]); |
139 |
++ |
140 |
+ len -= bytes; |
141 |
+ offset = 0; |
142 |
+ } |
143 |
+diff --git a/crypto/shash.c b/crypto/shash.c |
144 |
+index 359754591653..b2cd109d9171 100644 |
145 |
+--- a/crypto/shash.c |
146 |
++++ b/crypto/shash.c |
147 |
+@@ -274,12 +274,14 @@ static int shash_async_finup(struct ahash_request *req) |
148 |
+ |
149 |
+ int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc) |
150 |
+ { |
151 |
+- struct scatterlist *sg = req->src; |
152 |
+- unsigned int offset = sg->offset; |
153 |
+ unsigned int nbytes = req->nbytes; |
154 |
++ struct scatterlist *sg; |
155 |
++ unsigned int offset; |
156 |
+ int err; |
157 |
+ |
158 |
+- if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) { |
159 |
++ if (nbytes && |
160 |
++ (sg = req->src, offset = sg->offset, |
161 |
++ nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset))) { |
162 |
+ void *data; |
163 |
+ |
164 |
+ data = kmap_atomic(sg_page(sg)); |
165 |
+diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c |
166 |
+index 16fe773fb846..85674a8d0436 100644 |
167 |
+--- a/drivers/dma/edma.c |
168 |
++++ b/drivers/dma/edma.c |
169 |
+@@ -1126,11 +1126,24 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( |
170 |
+ struct edma_desc *edesc; |
171 |
+ struct device *dev = chan->device->dev; |
172 |
+ struct edma_chan *echan = to_edma_chan(chan); |
173 |
+- unsigned int width, pset_len; |
174 |
++ unsigned int width, pset_len, array_size; |
175 |
+ |
176 |
+ if (unlikely(!echan || !len)) |
177 |
+ return NULL; |
178 |
+ |
179 |
++ /* Align the array size (acnt block) with the transfer properties */ |
180 |
++ switch (__ffs((src | dest | len))) { |
181 |
++ case 0: |
182 |
++ array_size = SZ_32K - 1; |
183 |
++ break; |
184 |
++ case 1: |
185 |
++ array_size = SZ_32K - 2; |
186 |
++ break; |
187 |
++ default: |
188 |
++ array_size = SZ_32K - 4; |
189 |
++ break; |
190 |
++ } |
191 |
++ |
192 |
+ if (len < SZ_64K) { |
193 |
+ /* |
194 |
+ * Transfer size less than 64K can be handled with one paRAM |
195 |
+@@ -1152,7 +1165,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( |
196 |
+ * When the full_length is multibple of 32767 one slot can be |
197 |
+ * used to complete the transfer. |
198 |
+ */ |
199 |
+- width = SZ_32K - 1; |
200 |
++ width = array_size; |
201 |
+ pset_len = rounddown(len, width); |
202 |
+ /* One slot is enough for lengths multiple of (SZ_32K -1) */ |
203 |
+ if (unlikely(pset_len == len)) |
204 |
+@@ -1202,7 +1215,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( |
205 |
+ } |
206 |
+ dest += pset_len; |
207 |
+ src += pset_len; |
208 |
+- pset_len = width = len % (SZ_32K - 1); |
209 |
++ pset_len = width = len % array_size; |
210 |
+ |
211 |
+ ret = edma_config_pset(chan, &edesc->pset[1], src, dest, 1, |
212 |
+ width, pset_len, DMA_MEM_TO_MEM); |
213 |
+diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c |
214 |
+index 0df32fe0e345..b0eeb5090c91 100644 |
215 |
+--- a/drivers/hid/usbhid/hid-core.c |
216 |
++++ b/drivers/hid/usbhid/hid-core.c |
217 |
+@@ -971,6 +971,8 @@ static int usbhid_parse(struct hid_device *hid) |
218 |
+ unsigned int rsize = 0; |
219 |
+ char *rdesc; |
220 |
+ int ret, n; |
221 |
++ int num_descriptors; |
222 |
++ size_t offset = offsetof(struct hid_descriptor, desc); |
223 |
+ |
224 |
+ quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), |
225 |
+ le16_to_cpu(dev->descriptor.idProduct)); |
226 |
+@@ -993,10 +995,18 @@ static int usbhid_parse(struct hid_device *hid) |
227 |
+ return -ENODEV; |
228 |
+ } |
229 |
+ |
230 |
++ if (hdesc->bLength < sizeof(struct hid_descriptor)) { |
231 |
++ dbg_hid("hid descriptor is too short\n"); |
232 |
++ return -EINVAL; |
233 |
++ } |
234 |
++ |
235 |
+ hid->version = le16_to_cpu(hdesc->bcdHID); |
236 |
+ hid->country = hdesc->bCountryCode; |
237 |
+ |
238 |
+- for (n = 0; n < hdesc->bNumDescriptors; n++) |
239 |
++ num_descriptors = min_t(int, hdesc->bNumDescriptors, |
240 |
++ (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor)); |
241 |
++ |
242 |
++ for (n = 0; n < num_descriptors; n++) |
243 |
+ if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) |
244 |
+ rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); |
245 |
+ |
246 |
+diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c |
247 |
+index a0ef57483ebb..52c36394dba5 100644 |
248 |
+--- a/drivers/iommu/amd_iommu.c |
249 |
++++ b/drivers/iommu/amd_iommu.c |
250 |
+@@ -3096,6 +3096,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, |
251 |
+ mutex_unlock(&domain->api_lock); |
252 |
+ |
253 |
+ domain_flush_tlb_pde(domain); |
254 |
++ domain_flush_complete(domain); |
255 |
+ |
256 |
+ return unmap_size; |
257 |
+ } |
258 |
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c |
259 |
+index f18491cf793c..5fecae0ba52e 100644 |
260 |
+--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c |
261 |
++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c |
262 |
+@@ -2903,6 +2903,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, |
263 |
+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config; |
264 |
+ s32 status; |
265 |
+ struct brcmf_escan_result_le *escan_result_le; |
266 |
++ u32 escan_buflen; |
267 |
+ struct brcmf_bss_info_le *bss_info_le; |
268 |
+ struct brcmf_bss_info_le *bss = NULL; |
269 |
+ u32 bi_length; |
270 |
+@@ -2919,11 +2920,23 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, |
271 |
+ |
272 |
+ if (status == BRCMF_E_STATUS_PARTIAL) { |
273 |
+ brcmf_dbg(SCAN, "ESCAN Partial result\n"); |
274 |
++ if (e->datalen < sizeof(*escan_result_le)) { |
275 |
++ brcmf_err("invalid event data length\n"); |
276 |
++ goto exit; |
277 |
++ } |
278 |
+ escan_result_le = (struct brcmf_escan_result_le *) data; |
279 |
+ if (!escan_result_le) { |
280 |
+ brcmf_err("Invalid escan result (NULL pointer)\n"); |
281 |
+ goto exit; |
282 |
+ } |
283 |
++ escan_buflen = le32_to_cpu(escan_result_le->buflen); |
284 |
++ if (escan_buflen > WL_ESCAN_BUF_SIZE || |
285 |
++ escan_buflen > e->datalen || |
286 |
++ escan_buflen < sizeof(*escan_result_le)) { |
287 |
++ brcmf_err("Invalid escan buffer length: %d\n", |
288 |
++ escan_buflen); |
289 |
++ goto exit; |
290 |
++ } |
291 |
+ if (le16_to_cpu(escan_result_le->bss_count) != 1) { |
292 |
+ brcmf_err("Invalid bss_count %d: ignoring\n", |
293 |
+ escan_result_le->bss_count); |
294 |
+@@ -2940,9 +2953,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, |
295 |
+ } |
296 |
+ |
297 |
+ bi_length = le32_to_cpu(bss_info_le->length); |
298 |
+- if (bi_length != (le32_to_cpu(escan_result_le->buflen) - |
299 |
+- WL_ESCAN_RESULTS_FIXED_SIZE)) { |
300 |
+- brcmf_err("Invalid bss_info length %d: ignoring\n", |
301 |
++ if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) { |
302 |
++ brcmf_err("Ignoring invalid bss_info length: %d\n", |
303 |
+ bi_length); |
304 |
+ goto exit; |
305 |
+ } |
306 |
+diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c |
307 |
+index 1a8ea775de08..984cd2f05c4a 100644 |
308 |
+--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c |
309 |
++++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c |
310 |
+@@ -1906,6 +1906,11 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac, |
311 |
+ struct iwl_mvm_mc_iter_data *data = _data; |
312 |
+ struct iwl_mvm *mvm = data->mvm; |
313 |
+ struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd; |
314 |
++ struct iwl_host_cmd hcmd = { |
315 |
++ .id = MCAST_FILTER_CMD, |
316 |
++ .flags = CMD_ASYNC, |
317 |
++ .dataflags[0] = IWL_HCMD_DFL_NOCOPY, |
318 |
++ }; |
319 |
+ int ret, len; |
320 |
+ |
321 |
+ /* if we don't have free ports, mcast frames will be dropped */ |
322 |
+@@ -1920,7 +1925,10 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac, |
323 |
+ memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); |
324 |
+ len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4); |
325 |
+ |
326 |
+- ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd); |
327 |
++ hcmd.len[0] = len; |
328 |
++ hcmd.data[0] = cmd; |
329 |
++ |
330 |
++ ret = iwl_mvm_send_cmd(mvm, &hcmd); |
331 |
+ if (ret) |
332 |
+ IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret); |
333 |
+ } |
334 |
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c |
335 |
+index e2641d4dfdd6..d186d0282a38 100644 |
336 |
+--- a/drivers/usb/gadget/composite.c |
337 |
++++ b/drivers/usb/gadget/composite.c |
338 |
+@@ -1905,6 +1905,8 @@ static DEVICE_ATTR_RO(suspended); |
339 |
+ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) |
340 |
+ { |
341 |
+ struct usb_composite_dev *cdev = get_gadget_data(gadget); |
342 |
++ struct usb_gadget_strings *gstr = cdev->driver->strings[0]; |
343 |
++ struct usb_string *dev_str = gstr->strings; |
344 |
+ |
345 |
+ /* composite_disconnect() must already have been called |
346 |
+ * by the underlying peripheral controller driver! |
347 |
+@@ -1924,6 +1926,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) |
348 |
+ |
349 |
+ composite_dev_cleanup(cdev); |
350 |
+ |
351 |
++ if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer) |
352 |
++ dev_str[USB_GADGET_MANUFACTURER_IDX].s = ""; |
353 |
++ |
354 |
+ kfree(cdev->def_manufacturer); |
355 |
+ kfree(cdev); |
356 |
+ set_gadget_data(gadget, NULL); |
357 |
+diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c |
358 |
+index db645c38055d..8080a11947b7 100644 |
359 |
+--- a/drivers/usb/gadget/udc/dummy_hcd.c |
360 |
++++ b/drivers/usb/gadget/udc/dummy_hcd.c |
361 |
+@@ -420,6 +420,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) |
362 |
+ static void set_link_state(struct dummy_hcd *dum_hcd) |
363 |
+ { |
364 |
+ struct dummy *dum = dum_hcd->dum; |
365 |
++ unsigned int power_bit; |
366 |
+ |
367 |
+ dum_hcd->active = 0; |
368 |
+ if (dum->pullup) |
369 |
+@@ -430,17 +431,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd) |
370 |
+ return; |
371 |
+ |
372 |
+ set_link_state_by_speed(dum_hcd); |
373 |
++ power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ? |
374 |
++ USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER); |
375 |
+ |
376 |
+ if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || |
377 |
+ dum_hcd->active) |
378 |
+ dum_hcd->resuming = 0; |
379 |
+ |
380 |
+ /* Currently !connected or in reset */ |
381 |
+- if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || |
382 |
++ if ((dum_hcd->port_status & power_bit) == 0 || |
383 |
+ (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { |
384 |
+- unsigned disconnect = USB_PORT_STAT_CONNECTION & |
385 |
++ unsigned int disconnect = power_bit & |
386 |
+ dum_hcd->old_status & (~dum_hcd->port_status); |
387 |
+- unsigned reset = USB_PORT_STAT_RESET & |
388 |
++ unsigned int reset = USB_PORT_STAT_RESET & |
389 |
+ (~dum_hcd->old_status) & dum_hcd->port_status; |
390 |
+ |
391 |
+ /* Report reset and disconnect events to the driver */ |
392 |
+diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c |
393 |
+index d95cd1a72b66..8bb9367ada45 100644 |
394 |
+--- a/drivers/usb/renesas_usbhs/fifo.c |
395 |
++++ b/drivers/usb/renesas_usbhs/fifo.c |
396 |
+@@ -858,9 +858,9 @@ static void xfer_work(struct work_struct *work) |
397 |
+ fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); |
398 |
+ |
399 |
+ usbhs_pipe_running(pipe, 1); |
400 |
+- usbhsf_dma_start(pipe, fifo); |
401 |
+ usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); |
402 |
+ dma_async_issue_pending(chan); |
403 |
++ usbhsf_dma_start(pipe, fifo); |
404 |
+ usbhs_pipe_enable(pipe); |
405 |
+ |
406 |
+ xfer_work_end: |
407 |
+diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c |
408 |
+index 3806e7014199..2938153fe7b1 100644 |
409 |
+--- a/drivers/usb/serial/console.c |
410 |
++++ b/drivers/usb/serial/console.c |
411 |
+@@ -189,6 +189,7 @@ static int usb_console_setup(struct console *co, char *options) |
412 |
+ tty_kref_put(tty); |
413 |
+ reset_open_count: |
414 |
+ port->port.count = 0; |
415 |
++ info->port = NULL; |
416 |
+ usb_autopm_put_interface(serial->interface); |
417 |
+ error_get_interface: |
418 |
+ usb_serial_put(serial); |
419 |
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c |
420 |
+index 41a6513646de..1f5ecf905b7d 100644 |
421 |
+--- a/drivers/usb/serial/cp210x.c |
422 |
++++ b/drivers/usb/serial/cp210x.c |
423 |
+@@ -170,6 +170,7 @@ static const struct usb_device_id id_table[] = { |
424 |
+ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ |
425 |
+ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ |
426 |
+ { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ |
427 |
++ { USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */ |
428 |
+ { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ |
429 |
+ { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ |
430 |
+ { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ |
431 |
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c |
432 |
+index e0385d6c0abb..30344efc123f 100644 |
433 |
+--- a/drivers/usb/serial/ftdi_sio.c |
434 |
++++ b/drivers/usb/serial/ftdi_sio.c |
435 |
+@@ -1015,6 +1015,8 @@ static const struct usb_device_id id_table_combined[] = { |
436 |
+ { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, |
437 |
+ { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID), |
438 |
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
439 |
++ { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, |
440 |
++ { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, |
441 |
+ { } /* Terminating entry */ |
442 |
+ }; |
443 |
+ |
444 |
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h |
445 |
+index 4fcf1cecb6d7..f9d15bd62785 100644 |
446 |
+--- a/drivers/usb/serial/ftdi_sio_ids.h |
447 |
++++ b/drivers/usb/serial/ftdi_sio_ids.h |
448 |
+@@ -609,6 +609,13 @@ |
449 |
+ #define ADI_GNICE_PID 0xF000 |
450 |
+ #define ADI_GNICEPLUS_PID 0xF001 |
451 |
+ |
452 |
++/* |
453 |
++ * Cypress WICED USB UART |
454 |
++ */ |
455 |
++#define CYPRESS_VID 0x04B4 |
456 |
++#define CYPRESS_WICED_BT_USB_PID 0x009B |
457 |
++#define CYPRESS_WICED_WL_USB_PID 0xF900 |
458 |
++ |
459 |
+ /* |
460 |
+ * Microchip Technology, Inc. |
461 |
+ * |
462 |
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c |
463 |
+index 2a9944326210..db3d34c2c82e 100644 |
464 |
+--- a/drivers/usb/serial/option.c |
465 |
++++ b/drivers/usb/serial/option.c |
466 |
+@@ -522,6 +522,7 @@ static void option_instat_callback(struct urb *urb); |
467 |
+ |
468 |
+ /* TP-LINK Incorporated products */ |
469 |
+ #define TPLINK_VENDOR_ID 0x2357 |
470 |
++#define TPLINK_PRODUCT_LTE 0x000D |
471 |
+ #define TPLINK_PRODUCT_MA180 0x0201 |
472 |
+ |
473 |
+ /* Changhong products */ |
474 |
+@@ -2011,6 +2012,7 @@ static const struct usb_device_id option_ids[] = { |
475 |
+ { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, |
476 |
+ { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) }, |
477 |
+ { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, |
478 |
++ { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */ |
479 |
+ { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), |
480 |
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
481 |
+ { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ |
482 |
+diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c |
483 |
+index 652b4334b26d..e1c1e329c877 100644 |
484 |
+--- a/drivers/usb/serial/qcserial.c |
485 |
++++ b/drivers/usb/serial/qcserial.c |
486 |
+@@ -174,6 +174,10 @@ static const struct usb_device_id id_table[] = { |
487 |
+ {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ |
488 |
+ {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ |
489 |
+ {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ |
490 |
++ {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ |
491 |
++ {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */ |
492 |
++ {DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */ |
493 |
++ {DEVICE_SWI(0x413c, 0x81d2)}, /* Dell Wireless 5818 */ |
494 |
+ |
495 |
+ /* Huawei devices */ |
496 |
+ {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ |
497 |
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h |
498 |
+index e2f6a79e9b01..8225de3c9743 100644 |
499 |
+--- a/fs/cifs/cifsglob.h |
500 |
++++ b/fs/cifs/cifsglob.h |
501 |
+@@ -351,6 +351,8 @@ struct smb_version_operations { |
502 |
+ unsigned int (*calc_smb_size)(void *); |
503 |
+ /* check for STATUS_PENDING and process it in a positive case */ |
504 |
+ bool (*is_status_pending)(char *, struct TCP_Server_Info *, int); |
505 |
++ /* check for STATUS_NETWORK_SESSION_EXPIRED */ |
506 |
++ bool (*is_session_expired)(char *); |
507 |
+ /* send oplock break response */ |
508 |
+ int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *, |
509 |
+ struct cifsInodeInfo *); |
510 |
+diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c |
511 |
+index b60150e5b5ce..0c92af11f4f4 100644 |
512 |
+--- a/fs/cifs/cifssmb.c |
513 |
++++ b/fs/cifs/cifssmb.c |
514 |
+@@ -1460,6 +1460,13 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) |
515 |
+ return length; |
516 |
+ server->total_read += length; |
517 |
+ |
518 |
++ if (server->ops->is_session_expired && |
519 |
++ server->ops->is_session_expired(buf)) { |
520 |
++ cifs_reconnect(server); |
521 |
++ wake_up(&server->response_q); |
522 |
++ return -1; |
523 |
++ } |
524 |
++ |
525 |
+ if (server->ops->is_status_pending && |
526 |
+ server->ops->is_status_pending(buf, server, 0)) { |
527 |
+ discard_remaining_data(server); |
528 |
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c |
529 |
+index b377aa8f266f..0a2bf9462637 100644 |
530 |
+--- a/fs/cifs/connect.c |
531 |
++++ b/fs/cifs/connect.c |
532 |
+@@ -850,6 +850,13 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) |
533 |
+ cifs_dump_mem("Bad SMB: ", buf, |
534 |
+ min_t(unsigned int, server->total_read, 48)); |
535 |
+ |
536 |
++ if (server->ops->is_session_expired && |
537 |
++ server->ops->is_session_expired(buf)) { |
538 |
++ cifs_reconnect(server); |
539 |
++ wake_up(&server->response_q); |
540 |
++ return -1; |
541 |
++ } |
542 |
++ |
543 |
+ if (server->ops->is_status_pending && |
544 |
+ server->ops->is_status_pending(buf, server, length)) |
545 |
+ return -1; |
546 |
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c |
547 |
+index 1d125d3d0d89..e6b1795fbf2a 100644 |
548 |
+--- a/fs/cifs/smb2ops.c |
549 |
++++ b/fs/cifs/smb2ops.c |
550 |
+@@ -963,6 +963,18 @@ smb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length) |
551 |
+ return true; |
552 |
+ } |
553 |
+ |
554 |
++static bool |
555 |
++smb2_is_session_expired(char *buf) |
556 |
++{ |
557 |
++ struct smb2_hdr *hdr = (struct smb2_hdr *)buf; |
558 |
++ |
559 |
++ if (hdr->Status != STATUS_NETWORK_SESSION_EXPIRED) |
560 |
++ return false; |
561 |
++ |
562 |
++ cifs_dbg(FYI, "Session expired\n"); |
563 |
++ return true; |
564 |
++} |
565 |
++ |
566 |
+ static int |
567 |
+ smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid, |
568 |
+ struct cifsInodeInfo *cinode) |
569 |
+@@ -1552,6 +1564,7 @@ struct smb_version_operations smb20_operations = { |
570 |
+ .close_dir = smb2_close_dir, |
571 |
+ .calc_smb_size = smb2_calc_size, |
572 |
+ .is_status_pending = smb2_is_status_pending, |
573 |
++ .is_session_expired = smb2_is_session_expired, |
574 |
+ .oplock_response = smb2_oplock_response, |
575 |
+ .queryfs = smb2_queryfs, |
576 |
+ .mand_lock = smb2_mand_lock, |
577 |
+@@ -1633,6 +1646,7 @@ struct smb_version_operations smb21_operations = { |
578 |
+ .close_dir = smb2_close_dir, |
579 |
+ .calc_smb_size = smb2_calc_size, |
580 |
+ .is_status_pending = smb2_is_status_pending, |
581 |
++ .is_session_expired = smb2_is_session_expired, |
582 |
+ .oplock_response = smb2_oplock_response, |
583 |
+ .queryfs = smb2_queryfs, |
584 |
+ .mand_lock = smb2_mand_lock, |
585 |
+@@ -1715,6 +1729,7 @@ struct smb_version_operations smb30_operations = { |
586 |
+ .close_dir = smb2_close_dir, |
587 |
+ .calc_smb_size = smb2_calc_size, |
588 |
+ .is_status_pending = smb2_is_status_pending, |
589 |
++ .is_session_expired = smb2_is_session_expired, |
590 |
+ .oplock_response = smb2_oplock_response, |
591 |
+ .queryfs = smb2_queryfs, |
592 |
+ .mand_lock = smb2_mand_lock, |
593 |
+@@ -1803,6 +1818,7 @@ struct smb_version_operations smb311_operations = { |
594 |
+ .close_dir = smb2_close_dir, |
595 |
+ .calc_smb_size = smb2_calc_size, |
596 |
+ .is_status_pending = smb2_is_status_pending, |
597 |
++ .is_session_expired = smb2_is_session_expired, |
598 |
+ .oplock_response = smb2_oplock_response, |
599 |
+ .queryfs = smb2_queryfs, |
600 |
+ .mand_lock = smb2_mand_lock, |
601 |
+diff --git a/fs/direct-io.c b/fs/direct-io.c |
602 |
+index c772fdf36cd9..44f49d86d714 100644 |
603 |
+--- a/fs/direct-io.c |
604 |
++++ b/fs/direct-io.c |
605 |
+@@ -823,7 +823,8 @@ out: |
606 |
+ */ |
607 |
+ if (sdio->boundary) { |
608 |
+ ret = dio_send_cur_page(dio, sdio, map_bh); |
609 |
+- dio_bio_submit(dio, sdio); |
610 |
++ if (sdio->bio) |
611 |
++ dio_bio_submit(dio, sdio); |
612 |
+ page_cache_release(sdio->cur_page); |
613 |
+ sdio->cur_page = NULL; |
614 |
+ } |
615 |
+diff --git a/fs/ext4/file.c b/fs/ext4/file.c |
616 |
+index 45ef9975caec..a8b1749d79a8 100644 |
617 |
+--- a/fs/ext4/file.c |
618 |
++++ b/fs/ext4/file.c |
619 |
+@@ -559,7 +559,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) |
620 |
+ mutex_lock(&inode->i_mutex); |
621 |
+ |
622 |
+ isize = i_size_read(inode); |
623 |
+- if (offset >= isize) { |
624 |
++ if (offset < 0 || offset >= isize) { |
625 |
+ mutex_unlock(&inode->i_mutex); |
626 |
+ return -ENXIO; |
627 |
+ } |
628 |
+@@ -632,7 +632,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) |
629 |
+ mutex_lock(&inode->i_mutex); |
630 |
+ |
631 |
+ isize = i_size_read(inode); |
632 |
+- if (offset >= isize) { |
633 |
++ if (offset < 0 || offset >= isize) { |
634 |
+ mutex_unlock(&inode->i_mutex); |
635 |
+ return -ENXIO; |
636 |
+ } |
637 |
+diff --git a/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h |
638 |
+index a03acd0d398a..695257ae64ac 100644 |
639 |
+--- a/include/sound/seq_virmidi.h |
640 |
++++ b/include/sound/seq_virmidi.h |
641 |
+@@ -60,6 +60,7 @@ struct snd_virmidi_dev { |
642 |
+ int port; /* created/attached port */ |
643 |
+ unsigned int flags; /* SNDRV_VIRMIDI_* */ |
644 |
+ rwlock_t filelist_lock; |
645 |
++ struct rw_semaphore filelist_sem; |
646 |
+ struct list_head filelist; |
647 |
+ }; |
648 |
+ |
649 |
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c |
650 |
+index f07343b54fe5..8a62cbfe1f2f 100644 |
651 |
+--- a/kernel/rcu/tree.c |
652 |
++++ b/kernel/rcu/tree.c |
653 |
+@@ -759,6 +759,12 @@ void rcu_irq_exit(void) |
654 |
+ |
655 |
+ local_irq_save(flags); |
656 |
+ rdtp = this_cpu_ptr(&rcu_dynticks); |
657 |
++ |
658 |
++ /* Page faults can happen in NMI handlers, so check... */ |
659 |
++ if (READ_ONCE(rdtp->dynticks_nmi_nesting)) |
660 |
++ return; |
661 |
++ |
662 |
++ RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_exit() invoked with irqs enabled!!!"); |
663 |
+ oldval = rdtp->dynticks_nesting; |
664 |
+ rdtp->dynticks_nesting--; |
665 |
+ WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && |
666 |
+@@ -887,6 +893,12 @@ void rcu_irq_enter(void) |
667 |
+ |
668 |
+ local_irq_save(flags); |
669 |
+ rdtp = this_cpu_ptr(&rcu_dynticks); |
670 |
++ |
671 |
++ /* Page faults can happen in NMI handlers, so check... */ |
672 |
++ if (READ_ONCE(rdtp->dynticks_nmi_nesting)) |
673 |
++ return; |
674 |
++ |
675 |
++ RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_enter() invoked with irqs enabled!!!"); |
676 |
+ oldval = rdtp->dynticks_nesting; |
677 |
+ rdtp->dynticks_nesting++; |
678 |
+ WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && |
679 |
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c |
680 |
+index 8ece212aa3d2..7950506395a8 100644 |
681 |
+--- a/net/wireless/nl80211.c |
682 |
++++ b/net/wireless/nl80211.c |
683 |
+@@ -485,6 +485,14 @@ nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = { |
684 |
+ [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 }, |
685 |
+ }; |
686 |
+ |
687 |
++/* policy for packet pattern attributes */ |
688 |
++static const struct nla_policy |
689 |
++nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = { |
690 |
++ [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, }, |
691 |
++ [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, }, |
692 |
++ [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 }, |
693 |
++}; |
694 |
++ |
695 |
+ static int nl80211_prepare_wdev_dump(struct sk_buff *skb, |
696 |
+ struct netlink_callback *cb, |
697 |
+ struct cfg80211_registered_device **rdev, |
698 |
+@@ -9410,7 +9418,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) |
699 |
+ u8 *mask_pat; |
700 |
+ |
701 |
+ nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), |
702 |
+- nla_len(pat), NULL); |
703 |
++ nla_len(pat), nl80211_packet_pattern_policy); |
704 |
+ err = -EINVAL; |
705 |
+ if (!pat_tb[NL80211_PKTPAT_MASK] || |
706 |
+ !pat_tb[NL80211_PKTPAT_PATTERN]) |
707 |
+@@ -9660,7 +9668,7 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, |
708 |
+ u8 *mask_pat; |
709 |
+ |
710 |
+ nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), |
711 |
+- nla_len(pat), NULL); |
712 |
++ nla_len(pat), nl80211_packet_pattern_policy); |
713 |
+ if (!pat_tb[NL80211_PKTPAT_MASK] || |
714 |
+ !pat_tb[NL80211_PKTPAT_PATTERN]) |
715 |
+ return -EINVAL; |
716 |
+diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c |
717 |
+index e326c1d80416..e847b9923c19 100644 |
718 |
+--- a/sound/core/seq/seq_clientmgr.c |
719 |
++++ b/sound/core/seq/seq_clientmgr.c |
720 |
+@@ -1260,6 +1260,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, |
721 |
+ struct snd_seq_client_port *port; |
722 |
+ struct snd_seq_port_info info; |
723 |
+ struct snd_seq_port_callback *callback; |
724 |
++ int port_idx; |
725 |
+ |
726 |
+ if (copy_from_user(&info, arg, sizeof(info))) |
727 |
+ return -EFAULT; |
728 |
+@@ -1273,7 +1274,9 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, |
729 |
+ return -ENOMEM; |
730 |
+ |
731 |
+ if (client->type == USER_CLIENT && info.kernel) { |
732 |
+- snd_seq_delete_port(client, port->addr.port); |
733 |
++ port_idx = port->addr.port; |
734 |
++ snd_seq_port_unlock(port); |
735 |
++ snd_seq_delete_port(client, port_idx); |
736 |
+ return -EINVAL; |
737 |
+ } |
738 |
+ if (client->type == KERNEL_CLIENT) { |
739 |
+@@ -1294,6 +1297,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, |
740 |
+ |
741 |
+ snd_seq_set_port_info(port, &info); |
742 |
+ snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); |
743 |
++ snd_seq_port_unlock(port); |
744 |
+ |
745 |
+ if (copy_to_user(arg, &info, sizeof(info))) |
746 |
+ return -EFAULT; |
747 |
+diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c |
748 |
+index fe686ee41c6d..f04714d70bf7 100644 |
749 |
+--- a/sound/core/seq/seq_ports.c |
750 |
++++ b/sound/core/seq/seq_ports.c |
751 |
+@@ -122,7 +122,9 @@ static void port_subs_info_init(struct snd_seq_port_subs_info *grp) |
752 |
+ } |
753 |
+ |
754 |
+ |
755 |
+-/* create a port, port number is returned (-1 on failure) */ |
756 |
++/* create a port, port number is returned (-1 on failure); |
757 |
++ * the caller needs to unref the port via snd_seq_port_unlock() appropriately |
758 |
++ */ |
759 |
+ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, |
760 |
+ int port) |
761 |
+ { |
762 |
+@@ -151,6 +153,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, |
763 |
+ snd_use_lock_init(&new_port->use_lock); |
764 |
+ port_subs_info_init(&new_port->c_src); |
765 |
+ port_subs_info_init(&new_port->c_dest); |
766 |
++ snd_use_lock_use(&new_port->use_lock); |
767 |
+ |
768 |
+ num = port >= 0 ? port : 0; |
769 |
+ mutex_lock(&client->ports_mutex); |
770 |
+@@ -165,9 +168,9 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, |
771 |
+ list_add_tail(&new_port->list, &p->list); |
772 |
+ client->num_ports++; |
773 |
+ new_port->addr.port = num; /* store the port number in the port */ |
774 |
++ sprintf(new_port->name, "port-%d", num); |
775 |
+ write_unlock_irqrestore(&client->ports_lock, flags); |
776 |
+ mutex_unlock(&client->ports_mutex); |
777 |
+- sprintf(new_port->name, "port-%d", num); |
778 |
+ |
779 |
+ return new_port; |
780 |
+ } |
781 |
+diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c |
782 |
+index 81134e067184..3b126af4a026 100644 |
783 |
+--- a/sound/core/seq/seq_virmidi.c |
784 |
++++ b/sound/core/seq/seq_virmidi.c |
785 |
+@@ -77,13 +77,17 @@ static void snd_virmidi_init_event(struct snd_virmidi *vmidi, |
786 |
+ * decode input event and put to read buffer of each opened file |
787 |
+ */ |
788 |
+ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, |
789 |
+- struct snd_seq_event *ev) |
790 |
++ struct snd_seq_event *ev, |
791 |
++ bool atomic) |
792 |
+ { |
793 |
+ struct snd_virmidi *vmidi; |
794 |
+ unsigned char msg[4]; |
795 |
+ int len; |
796 |
+ |
797 |
+- read_lock(&rdev->filelist_lock); |
798 |
++ if (atomic) |
799 |
++ read_lock(&rdev->filelist_lock); |
800 |
++ else |
801 |
++ down_read(&rdev->filelist_sem); |
802 |
+ list_for_each_entry(vmidi, &rdev->filelist, list) { |
803 |
+ if (!vmidi->trigger) |
804 |
+ continue; |
805 |
+@@ -97,7 +101,10 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, |
806 |
+ snd_rawmidi_receive(vmidi->substream, msg, len); |
807 |
+ } |
808 |
+ } |
809 |
+- read_unlock(&rdev->filelist_lock); |
810 |
++ if (atomic) |
811 |
++ read_unlock(&rdev->filelist_lock); |
812 |
++ else |
813 |
++ up_read(&rdev->filelist_sem); |
814 |
+ |
815 |
+ return 0; |
816 |
+ } |
817 |
+@@ -115,7 +122,7 @@ int snd_virmidi_receive(struct snd_rawmidi *rmidi, struct snd_seq_event *ev) |
818 |
+ struct snd_virmidi_dev *rdev; |
819 |
+ |
820 |
+ rdev = rmidi->private_data; |
821 |
+- return snd_virmidi_dev_receive_event(rdev, ev); |
822 |
++ return snd_virmidi_dev_receive_event(rdev, ev, true); |
823 |
+ } |
824 |
+ #endif /* 0 */ |
825 |
+ |
826 |
+@@ -130,7 +137,7 @@ static int snd_virmidi_event_input(struct snd_seq_event *ev, int direct, |
827 |
+ rdev = private_data; |
828 |
+ if (!(rdev->flags & SNDRV_VIRMIDI_USE)) |
829 |
+ return 0; /* ignored */ |
830 |
+- return snd_virmidi_dev_receive_event(rdev, ev); |
831 |
++ return snd_virmidi_dev_receive_event(rdev, ev, atomic); |
832 |
+ } |
833 |
+ |
834 |
+ /* |
835 |
+@@ -209,7 +216,6 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) |
836 |
+ struct snd_virmidi_dev *rdev = substream->rmidi->private_data; |
837 |
+ struct snd_rawmidi_runtime *runtime = substream->runtime; |
838 |
+ struct snd_virmidi *vmidi; |
839 |
+- unsigned long flags; |
840 |
+ |
841 |
+ vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL); |
842 |
+ if (vmidi == NULL) |
843 |
+@@ -223,9 +229,11 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) |
844 |
+ vmidi->client = rdev->client; |
845 |
+ vmidi->port = rdev->port; |
846 |
+ runtime->private_data = vmidi; |
847 |
+- write_lock_irqsave(&rdev->filelist_lock, flags); |
848 |
++ down_write(&rdev->filelist_sem); |
849 |
++ write_lock_irq(&rdev->filelist_lock); |
850 |
+ list_add_tail(&vmidi->list, &rdev->filelist); |
851 |
+- write_unlock_irqrestore(&rdev->filelist_lock, flags); |
852 |
++ write_unlock_irq(&rdev->filelist_lock); |
853 |
++ up_write(&rdev->filelist_sem); |
854 |
+ vmidi->rdev = rdev; |
855 |
+ return 0; |
856 |
+ } |
857 |
+@@ -264,9 +272,11 @@ static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream) |
858 |
+ struct snd_virmidi_dev *rdev = substream->rmidi->private_data; |
859 |
+ struct snd_virmidi *vmidi = substream->runtime->private_data; |
860 |
+ |
861 |
++ down_write(&rdev->filelist_sem); |
862 |
+ write_lock_irq(&rdev->filelist_lock); |
863 |
+ list_del(&vmidi->list); |
864 |
+ write_unlock_irq(&rdev->filelist_lock); |
865 |
++ up_write(&rdev->filelist_sem); |
866 |
+ snd_midi_event_free(vmidi->parser); |
867 |
+ substream->runtime->private_data = NULL; |
868 |
+ kfree(vmidi); |
869 |
+@@ -520,6 +530,7 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi |
870 |
+ rdev->rmidi = rmidi; |
871 |
+ rdev->device = device; |
872 |
+ rdev->client = -1; |
873 |
++ init_rwsem(&rdev->filelist_sem); |
874 |
+ rwlock_init(&rdev->filelist_lock); |
875 |
+ INIT_LIST_HEAD(&rdev->filelist); |
876 |
+ rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH; |
877 |
+diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c |
878 |
+index b871ba407e4e..4458190149d1 100644 |
879 |
+--- a/sound/usb/caiaq/device.c |
880 |
++++ b/sound/usb/caiaq/device.c |
881 |
+@@ -469,10 +469,12 @@ static int init_card(struct snd_usb_caiaqdev *cdev) |
882 |
+ |
883 |
+ err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); |
884 |
+ if (err) |
885 |
+- return err; |
886 |
++ goto err_kill_urb; |
887 |
+ |
888 |
+- if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) |
889 |
+- return -ENODEV; |
890 |
++ if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) { |
891 |
++ err = -ENODEV; |
892 |
++ goto err_kill_urb; |
893 |
++ } |
894 |
+ |
895 |
+ usb_string(usb_dev, usb_dev->descriptor.iManufacturer, |
896 |
+ cdev->vendor_name, CAIAQ_USB_STR_LEN); |
897 |
+@@ -507,6 +509,10 @@ static int init_card(struct snd_usb_caiaqdev *cdev) |
898 |
+ |
899 |
+ setup_card(cdev); |
900 |
+ return 0; |
901 |
++ |
902 |
++ err_kill_urb: |
903 |
++ usb_kill_urb(&cdev->ep1_in_urb); |
904 |
++ return err; |
905 |
+ } |
906 |
+ |
907 |
+ static int snd_probe(struct usb_interface *intf, |
908 |
+diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c |
909 |
+index 183311cb849e..be78078a10ba 100644 |
910 |
+--- a/sound/usb/line6/driver.c |
911 |
++++ b/sound/usb/line6/driver.c |
912 |
+@@ -586,9 +586,10 @@ int line6_probe(struct usb_interface *interface, |
913 |
+ return 0; |
914 |
+ |
915 |
+ error: |
916 |
+- if (line6->disconnect) |
917 |
+- line6->disconnect(line6); |
918 |
+- snd_card_free(card); |
919 |
++ /* we can call disconnect callback here because no close-sync is |
920 |
++ * needed yet at this point |
921 |
++ */ |
922 |
++ line6_disconnect(interface); |
923 |
+ return ret; |
924 |
+ } |
925 |
+ EXPORT_SYMBOL_GPL(line6_probe); |
926 |
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
927 |
+index 696de5ac69be..a23efc8671d6 100644 |
928 |
+--- a/sound/usb/mixer.c |
929 |
++++ b/sound/usb/mixer.c |
930 |
+@@ -2161,6 +2161,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) |
931 |
+ |
932 |
+ static void snd_usb_mixer_free(struct usb_mixer_interface *mixer) |
933 |
+ { |
934 |
++ /* kill pending URBs */ |
935 |
++ snd_usb_mixer_disconnect(mixer); |
936 |
++ |
937 |
+ kfree(mixer->id_elems); |
938 |
+ if (mixer->urb) { |
939 |
+ kfree(mixer->urb->transfer_buffer); |
940 |
+@@ -2504,8 +2507,13 @@ _error: |
941 |
+ |
942 |
+ void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer) |
943 |
+ { |
944 |
+- usb_kill_urb(mixer->urb); |
945 |
+- usb_kill_urb(mixer->rc_urb); |
946 |
++ if (mixer->disconnected) |
947 |
++ return; |
948 |
++ if (mixer->urb) |
949 |
++ usb_kill_urb(mixer->urb); |
950 |
++ if (mixer->rc_urb) |
951 |
++ usb_kill_urb(mixer->rc_urb); |
952 |
++ mixer->disconnected = true; |
953 |
+ } |
954 |
+ |
955 |
+ #ifdef CONFIG_PM |
956 |
+diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h |
957 |
+index 2b4b067646ab..545d99b09706 100644 |
958 |
+--- a/sound/usb/mixer.h |
959 |
++++ b/sound/usb/mixer.h |
960 |
+@@ -22,6 +22,8 @@ struct usb_mixer_interface { |
961 |
+ struct urb *rc_urb; |
962 |
+ struct usb_ctrlrequest *rc_setup_packet; |
963 |
+ u8 rc_buffer[6]; |
964 |
++ |
965 |
++ bool disconnected; |
966 |
+ }; |
967 |
+ |
968 |
+ #define MAX_CHANNELS 16 /* max logical channels */ |