Annotation of /trunk/kernel-alx/patches-4.9/0156-4.9.57-all-fixes.patch
Parent Directory | Revision Log
Revision 3041 -
(hide annotations)
(download)
Wed Dec 20 11:49:03 2017 UTC (6 years, 6 months ago) by niro
File size: 45967 byte(s)
Wed Dec 20 11:49:03 2017 UTC (6 years, 6 months ago) by niro
File size: 45967 byte(s)
-linux-4.9.57
1 | niro | 3041 | diff --git a/Makefile b/Makefile |
2 | index feab5f5a507c..d5a2ab9b3291 100644 | ||
3 | --- a/Makefile | ||
4 | +++ b/Makefile | ||
5 | @@ -1,6 +1,6 @@ | ||
6 | VERSION = 4 | ||
7 | PATCHLEVEL = 9 | ||
8 | -SUBLEVEL = 56 | ||
9 | +SUBLEVEL = 57 | ||
10 | EXTRAVERSION = | ||
11 | NAME = Roaring Lionus | ||
12 | |||
13 | diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c | ||
14 | index e9385bcd9723..9ade60ca08e0 100644 | ||
15 | --- a/arch/mips/math-emu/cp1emu.c | ||
16 | +++ b/arch/mips/math-emu/cp1emu.c | ||
17 | @@ -2386,7 +2386,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | ||
18 | break; | ||
19 | default: | ||
20 | /* Reserved R6 ops */ | ||
21 | - pr_err("Reserved MIPS R6 CMP.condn.S operation\n"); | ||
22 | return SIGILL; | ||
23 | } | ||
24 | } | ||
25 | @@ -2460,7 +2459,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | ||
26 | break; | ||
27 | default: | ||
28 | /* Reserved R6 ops */ | ||
29 | - pr_err("Reserved MIPS R6 CMP.condn.D operation\n"); | ||
30 | return SIGILL; | ||
31 | } | ||
32 | } | ||
33 | diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h | ||
34 | index e7636bac7372..6c98821fef5e 100644 | ||
35 | --- a/arch/x86/include/asm/alternative-asm.h | ||
36 | +++ b/arch/x86/include/asm/alternative-asm.h | ||
37 | @@ -62,8 +62,10 @@ | ||
38 | #define new_len2 145f-144f | ||
39 | |||
40 | /* | ||
41 | - * max without conditionals. Idea adapted from: | ||
42 | + * gas compatible max based on the idea from: | ||
43 | * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax | ||
44 | + * | ||
45 | + * The additional "-" is needed because gas uses a "true" value of -1. | ||
46 | */ | ||
47 | #define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b))))) | ||
48 | |||
49 | diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h | ||
50 | index 1b020381ab38..d4aea31eec03 100644 | ||
51 | --- a/arch/x86/include/asm/alternative.h | ||
52 | +++ b/arch/x86/include/asm/alternative.h | ||
53 | @@ -103,12 +103,12 @@ static inline int alternatives_text_reserved(void *start, void *end) | ||
54 | alt_end_marker ":\n" | ||
55 | |||
56 | /* | ||
57 | - * max without conditionals. Idea adapted from: | ||
58 | + * gas compatible max based on the idea from: | ||
59 | * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax | ||
60 | * | ||
61 | - * The additional "-" is needed because gas works with s32s. | ||
62 | + * The additional "-" is needed because gas uses a "true" value of -1. | ||
63 | */ | ||
64 | -#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") - (" b ")))))" | ||
65 | +#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))" | ||
66 | |||
67 | /* | ||
68 | * Pad the second replacement alternative with additional NOPs if it is | ||
69 | diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c | ||
70 | index 5f2412704b81..d29c745f10ad 100644 | ||
71 | --- a/arch/x86/kvm/mmu.c | ||
72 | +++ b/arch/x86/kvm/mmu.c | ||
73 | @@ -3648,13 +3648,6 @@ static bool sync_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, gfn_t gfn, | ||
74 | static inline bool is_last_gpte(struct kvm_mmu *mmu, | ||
75 | unsigned level, unsigned gpte) | ||
76 | { | ||
77 | - /* | ||
78 | - * PT_PAGE_TABLE_LEVEL always terminates. The RHS has bit 7 set | ||
79 | - * iff level <= PT_PAGE_TABLE_LEVEL, which for our purpose means | ||
80 | - * level == PT_PAGE_TABLE_LEVEL; set PT_PAGE_SIZE_MASK in gpte then. | ||
81 | - */ | ||
82 | - gpte |= level - PT_PAGE_TABLE_LEVEL - 1; | ||
83 | - | ||
84 | /* | ||
85 | * The RHS has bit 7 set iff level < mmu->last_nonleaf_level. | ||
86 | * If it is clear, there are no large pages at this level, so clear | ||
87 | @@ -3662,6 +3655,13 @@ static inline bool is_last_gpte(struct kvm_mmu *mmu, | ||
88 | */ | ||
89 | gpte &= level - mmu->last_nonleaf_level; | ||
90 | |||
91 | + /* | ||
92 | + * PT_PAGE_TABLE_LEVEL always terminates. The RHS has bit 7 set | ||
93 | + * iff level <= PT_PAGE_TABLE_LEVEL, which for our purpose means | ||
94 | + * level == PT_PAGE_TABLE_LEVEL; set PT_PAGE_SIZE_MASK in gpte then. | ||
95 | + */ | ||
96 | + gpte |= level - PT_PAGE_TABLE_LEVEL - 1; | ||
97 | + | ||
98 | return gpte & PT_PAGE_SIZE_MASK; | ||
99 | } | ||
100 | |||
101 | @@ -4169,6 +4169,7 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly) | ||
102 | |||
103 | update_permission_bitmask(vcpu, context, true); | ||
104 | update_pkru_bitmask(vcpu, context, true); | ||
105 | + update_last_nonleaf_level(vcpu, context); | ||
106 | reset_rsvds_bits_mask_ept(vcpu, context, execonly); | ||
107 | reset_ept_shadow_zero_bits_mask(vcpu, context, execonly); | ||
108 | } | ||
109 | diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h | ||
110 | index a01105485315..37363900297d 100644 | ||
111 | --- a/arch/x86/kvm/paging_tmpl.h | ||
112 | +++ b/arch/x86/kvm/paging_tmpl.h | ||
113 | @@ -324,10 +324,11 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, | ||
114 | --walker->level; | ||
115 | |||
116 | index = PT_INDEX(addr, walker->level); | ||
117 | - | ||
118 | table_gfn = gpte_to_gfn(pte); | ||
119 | offset = index * sizeof(pt_element_t); | ||
120 | pte_gpa = gfn_to_gpa(table_gfn) + offset; | ||
121 | + | ||
122 | + BUG_ON(walker->level < 1); | ||
123 | walker->table_gfn[walker->level - 1] = table_gfn; | ||
124 | walker->pte_gpa[walker->level - 1] = pte_gpa; | ||
125 | |||
126 | diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c | ||
127 | index fb49212d25df..a8ae57acb6f6 100644 | ||
128 | --- a/arch/x86/kvm/vmx.c | ||
129 | +++ b/arch/x86/kvm/vmx.c | ||
130 | @@ -10690,7 +10690,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, | ||
131 | * (KVM doesn't change it)- no reason to call set_cr4_guest_host_mask(); | ||
132 | */ | ||
133 | vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK); | ||
134 | - kvm_set_cr4(vcpu, vmcs12->host_cr4); | ||
135 | + vmx_set_cr4(vcpu, vmcs12->host_cr4); | ||
136 | |||
137 | nested_ept_uninit_mmu_context(vcpu); | ||
138 | |||
139 | diff --git a/block/bio.c b/block/bio.c | ||
140 | index 655c9016052a..07f287b14cff 100644 | ||
141 | --- a/block/bio.c | ||
142 | +++ b/block/bio.c | ||
143 | @@ -1171,8 +1171,8 @@ struct bio *bio_copy_user_iov(struct request_queue *q, | ||
144 | */ | ||
145 | bmd->is_our_pages = map_data ? 0 : 1; | ||
146 | memcpy(bmd->iov, iter->iov, sizeof(struct iovec) * iter->nr_segs); | ||
147 | - iov_iter_init(&bmd->iter, iter->type, bmd->iov, | ||
148 | - iter->nr_segs, iter->count); | ||
149 | + bmd->iter = *iter; | ||
150 | + bmd->iter.iov = bmd->iov; | ||
151 | |||
152 | ret = -ENOMEM; | ||
153 | bio = bio_kmalloc(gfp_mask, nr_pages); | ||
154 | @@ -1266,6 +1266,7 @@ struct bio *bio_map_user_iov(struct request_queue *q, | ||
155 | int ret, offset; | ||
156 | struct iov_iter i; | ||
157 | struct iovec iov; | ||
158 | + struct bio_vec *bvec; | ||
159 | |||
160 | iov_for_each(iov, i, *iter) { | ||
161 | unsigned long uaddr = (unsigned long) iov.iov_base; | ||
162 | @@ -1310,7 +1311,12 @@ struct bio *bio_map_user_iov(struct request_queue *q, | ||
163 | ret = get_user_pages_fast(uaddr, local_nr_pages, | ||
164 | (iter->type & WRITE) != WRITE, | ||
165 | &pages[cur_page]); | ||
166 | - if (ret < local_nr_pages) { | ||
167 | + if (unlikely(ret < local_nr_pages)) { | ||
168 | + for (j = cur_page; j < page_limit; j++) { | ||
169 | + if (!pages[j]) | ||
170 | + break; | ||
171 | + put_page(pages[j]); | ||
172 | + } | ||
173 | ret = -EFAULT; | ||
174 | goto out_unmap; | ||
175 | } | ||
176 | @@ -1318,6 +1324,7 @@ struct bio *bio_map_user_iov(struct request_queue *q, | ||
177 | offset = offset_in_page(uaddr); | ||
178 | for (j = cur_page; j < page_limit; j++) { | ||
179 | unsigned int bytes = PAGE_SIZE - offset; | ||
180 | + unsigned short prev_bi_vcnt = bio->bi_vcnt; | ||
181 | |||
182 | if (len <= 0) | ||
183 | break; | ||
184 | @@ -1332,6 +1339,13 @@ struct bio *bio_map_user_iov(struct request_queue *q, | ||
185 | bytes) | ||
186 | break; | ||
187 | |||
188 | + /* | ||
189 | + * check if vector was merged with previous | ||
190 | + * drop page reference if needed | ||
191 | + */ | ||
192 | + if (bio->bi_vcnt == prev_bi_vcnt) | ||
193 | + put_page(pages[j]); | ||
194 | + | ||
195 | len -= bytes; | ||
196 | offset = 0; | ||
197 | } | ||
198 | @@ -1364,10 +1378,8 @@ struct bio *bio_map_user_iov(struct request_queue *q, | ||
199 | return bio; | ||
200 | |||
201 | out_unmap: | ||
202 | - for (j = 0; j < nr_pages; j++) { | ||
203 | - if (!pages[j]) | ||
204 | - break; | ||
205 | - put_page(pages[j]); | ||
206 | + bio_for_each_segment_all(bvec, bio, j) { | ||
207 | + put_page(bvec->bv_page); | ||
208 | } | ||
209 | out: | ||
210 | kfree(pages); | ||
211 | diff --git a/crypto/shash.c b/crypto/shash.c | ||
212 | index a051541a4a17..4d8a671d1614 100644 | ||
213 | --- a/crypto/shash.c | ||
214 | +++ b/crypto/shash.c | ||
215 | @@ -274,12 +274,14 @@ static int shash_async_finup(struct ahash_request *req) | ||
216 | |||
217 | int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc) | ||
218 | { | ||
219 | - struct scatterlist *sg = req->src; | ||
220 | - unsigned int offset = sg->offset; | ||
221 | unsigned int nbytes = req->nbytes; | ||
222 | + struct scatterlist *sg; | ||
223 | + unsigned int offset; | ||
224 | int err; | ||
225 | |||
226 | - if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) { | ||
227 | + if (nbytes && | ||
228 | + (sg = req->src, offset = sg->offset, | ||
229 | + nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset))) { | ||
230 | void *data; | ||
231 | |||
232 | data = kmap_atomic(sg_page(sg)); | ||
233 | diff --git a/drivers/base/property.c b/drivers/base/property.c | ||
234 | index 06f66687fe0b..7b313b567f4c 100644 | ||
235 | --- a/drivers/base/property.c | ||
236 | +++ b/drivers/base/property.c | ||
237 | @@ -20,6 +20,7 @@ | ||
238 | #include <linux/phy.h> | ||
239 | |||
240 | struct property_set { | ||
241 | + struct device *dev; | ||
242 | struct fwnode_handle fwnode; | ||
243 | struct property_entry *properties; | ||
244 | }; | ||
245 | @@ -817,6 +818,7 @@ static struct property_set *pset_copy_set(const struct property_set *pset) | ||
246 | void device_remove_properties(struct device *dev) | ||
247 | { | ||
248 | struct fwnode_handle *fwnode; | ||
249 | + struct property_set *pset; | ||
250 | |||
251 | fwnode = dev_fwnode(dev); | ||
252 | if (!fwnode) | ||
253 | @@ -826,16 +828,16 @@ void device_remove_properties(struct device *dev) | ||
254 | * the pset. If there is no real firmware node (ACPI/DT) primary | ||
255 | * will hold the pset. | ||
256 | */ | ||
257 | - if (is_pset_node(fwnode)) { | ||
258 | + pset = to_pset_node(fwnode); | ||
259 | + if (pset) { | ||
260 | set_primary_fwnode(dev, NULL); | ||
261 | - pset_free_set(to_pset_node(fwnode)); | ||
262 | } else { | ||
263 | - fwnode = fwnode->secondary; | ||
264 | - if (!IS_ERR(fwnode) && is_pset_node(fwnode)) { | ||
265 | + pset = to_pset_node(fwnode->secondary); | ||
266 | + if (pset && dev == pset->dev) | ||
267 | set_secondary_fwnode(dev, NULL); | ||
268 | - pset_free_set(to_pset_node(fwnode)); | ||
269 | - } | ||
270 | } | ||
271 | + if (pset && dev == pset->dev) | ||
272 | + pset_free_set(pset); | ||
273 | } | ||
274 | EXPORT_SYMBOL_GPL(device_remove_properties); | ||
275 | |||
276 | @@ -863,6 +865,7 @@ int device_add_properties(struct device *dev, struct property_entry *properties) | ||
277 | |||
278 | p->fwnode.type = FWNODE_PDATA; | ||
279 | set_secondary_fwnode(dev, &p->fwnode); | ||
280 | + p->dev = dev; | ||
281 | return 0; | ||
282 | } | ||
283 | EXPORT_SYMBOL_GPL(device_add_properties); | ||
284 | diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c | ||
285 | index 77242b37ef87..57962bff7532 100644 | ||
286 | --- a/drivers/dma/edma.c | ||
287 | +++ b/drivers/dma/edma.c | ||
288 | @@ -1143,11 +1143,24 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( | ||
289 | struct edma_desc *edesc; | ||
290 | struct device *dev = chan->device->dev; | ||
291 | struct edma_chan *echan = to_edma_chan(chan); | ||
292 | - unsigned int width, pset_len; | ||
293 | + unsigned int width, pset_len, array_size; | ||
294 | |||
295 | if (unlikely(!echan || !len)) | ||
296 | return NULL; | ||
297 | |||
298 | + /* Align the array size (acnt block) with the transfer properties */ | ||
299 | + switch (__ffs((src | dest | len))) { | ||
300 | + case 0: | ||
301 | + array_size = SZ_32K - 1; | ||
302 | + break; | ||
303 | + case 1: | ||
304 | + array_size = SZ_32K - 2; | ||
305 | + break; | ||
306 | + default: | ||
307 | + array_size = SZ_32K - 4; | ||
308 | + break; | ||
309 | + } | ||
310 | + | ||
311 | if (len < SZ_64K) { | ||
312 | /* | ||
313 | * Transfer size less than 64K can be handled with one paRAM | ||
314 | @@ -1169,7 +1182,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( | ||
315 | * When the full_length is multibple of 32767 one slot can be | ||
316 | * used to complete the transfer. | ||
317 | */ | ||
318 | - width = SZ_32K - 1; | ||
319 | + width = array_size; | ||
320 | pset_len = rounddown(len, width); | ||
321 | /* One slot is enough for lengths multiple of (SZ_32K -1) */ | ||
322 | if (unlikely(pset_len == len)) | ||
323 | @@ -1217,7 +1230,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( | ||
324 | } | ||
325 | dest += pset_len; | ||
326 | src += pset_len; | ||
327 | - pset_len = width = len % (SZ_32K - 1); | ||
328 | + pset_len = width = len % array_size; | ||
329 | |||
330 | ret = edma_config_pset(chan, &edesc->pset[1], src, dest, 1, | ||
331 | width, pset_len, DMA_MEM_TO_MEM); | ||
332 | diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c | ||
333 | index 2403475a37cf..88a00d06def6 100644 | ||
334 | --- a/drivers/dma/ti-dma-crossbar.c | ||
335 | +++ b/drivers/dma/ti-dma-crossbar.c | ||
336 | @@ -262,13 +262,14 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec, | ||
337 | mutex_lock(&xbar->mutex); | ||
338 | map->xbar_out = find_first_zero_bit(xbar->dma_inuse, | ||
339 | xbar->dma_requests); | ||
340 | - mutex_unlock(&xbar->mutex); | ||
341 | if (map->xbar_out == xbar->dma_requests) { | ||
342 | + mutex_unlock(&xbar->mutex); | ||
343 | dev_err(&pdev->dev, "Run out of free DMA requests\n"); | ||
344 | kfree(map); | ||
345 | return ERR_PTR(-ENOMEM); | ||
346 | } | ||
347 | set_bit(map->xbar_out, xbar->dma_inuse); | ||
348 | + mutex_unlock(&xbar->mutex); | ||
349 | |||
350 | map->xbar_in = (u16)dma_spec->args[0]; | ||
351 | |||
352 | diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c | ||
353 | index 8aeb7f8ee59c..80c5cc5640c1 100644 | ||
354 | --- a/drivers/gpu/drm/i915/intel_bios.c | ||
355 | +++ b/drivers/gpu/drm/i915/intel_bios.c | ||
356 | @@ -1219,7 +1219,7 @@ static void parse_ddi_ports(struct drm_i915_private *dev_priv, | ||
357 | { | ||
358 | enum port port; | ||
359 | |||
360 | - if (!HAS_DDI(dev_priv)) | ||
361 | + if (!HAS_DDI(dev_priv) && !IS_CHERRYVIEW(dev_priv)) | ||
362 | return; | ||
363 | |||
364 | if (!dev_priv->vbt.child_dev_num) | ||
365 | diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c | ||
366 | index f8efd20e4a90..ce32303b3013 100644 | ||
367 | --- a/drivers/gpu/drm/i915/intel_display.c | ||
368 | +++ b/drivers/gpu/drm/i915/intel_display.c | ||
369 | @@ -11471,13 +11471,10 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | ||
370 | { | ||
371 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
372 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
373 | - enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; | ||
374 | + enum transcoder cpu_transcoder; | ||
375 | struct drm_display_mode *mode; | ||
376 | struct intel_crtc_state *pipe_config; | ||
377 | - int htot = I915_READ(HTOTAL(cpu_transcoder)); | ||
378 | - int hsync = I915_READ(HSYNC(cpu_transcoder)); | ||
379 | - int vtot = I915_READ(VTOTAL(cpu_transcoder)); | ||
380 | - int vsync = I915_READ(VSYNC(cpu_transcoder)); | ||
381 | + u32 htot, hsync, vtot, vsync; | ||
382 | enum pipe pipe = intel_crtc->pipe; | ||
383 | |||
384 | mode = kzalloc(sizeof(*mode), GFP_KERNEL); | ||
385 | @@ -11505,6 +11502,13 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | ||
386 | i9xx_crtc_clock_get(intel_crtc, pipe_config); | ||
387 | |||
388 | mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier; | ||
389 | + | ||
390 | + cpu_transcoder = pipe_config->cpu_transcoder; | ||
391 | + htot = I915_READ(HTOTAL(cpu_transcoder)); | ||
392 | + hsync = I915_READ(HSYNC(cpu_transcoder)); | ||
393 | + vtot = I915_READ(VTOTAL(cpu_transcoder)); | ||
394 | + vsync = I915_READ(VSYNC(cpu_transcoder)); | ||
395 | + | ||
396 | mode->hdisplay = (htot & 0xffff) + 1; | ||
397 | mode->htotal = ((htot & 0xffff0000) >> 16) + 1; | ||
398 | mode->hsync_start = (hsync & 0xffff) + 1; | ||
399 | diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c | ||
400 | index 7b06280b23aa..afa3d010c650 100644 | ||
401 | --- a/drivers/gpu/drm/i915/intel_dp.c | ||
402 | +++ b/drivers/gpu/drm/i915/intel_dp.c | ||
403 | @@ -2193,8 +2193,8 @@ static void edp_panel_off(struct intel_dp *intel_dp) | ||
404 | I915_WRITE(pp_ctrl_reg, pp); | ||
405 | POSTING_READ(pp_ctrl_reg); | ||
406 | |||
407 | - intel_dp->panel_power_off_time = ktime_get_boottime(); | ||
408 | wait_panel_off(intel_dp); | ||
409 | + intel_dp->panel_power_off_time = ktime_get_boottime(); | ||
410 | |||
411 | /* We got a reference when we enabled the VDD. */ | ||
412 | power_domain = intel_display_port_aux_power_domain(intel_encoder); | ||
413 | diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c | ||
414 | index ae83af649a60..7838343eb37c 100644 | ||
415 | --- a/drivers/hid/usbhid/hid-core.c | ||
416 | +++ b/drivers/hid/usbhid/hid-core.c | ||
417 | @@ -971,6 +971,8 @@ static int usbhid_parse(struct hid_device *hid) | ||
418 | unsigned int rsize = 0; | ||
419 | char *rdesc; | ||
420 | int ret, n; | ||
421 | + int num_descriptors; | ||
422 | + size_t offset = offsetof(struct hid_descriptor, desc); | ||
423 | |||
424 | quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), | ||
425 | le16_to_cpu(dev->descriptor.idProduct)); | ||
426 | @@ -993,10 +995,18 @@ static int usbhid_parse(struct hid_device *hid) | ||
427 | return -ENODEV; | ||
428 | } | ||
429 | |||
430 | + if (hdesc->bLength < sizeof(struct hid_descriptor)) { | ||
431 | + dbg_hid("hid descriptor is too short\n"); | ||
432 | + return -EINVAL; | ||
433 | + } | ||
434 | + | ||
435 | hid->version = le16_to_cpu(hdesc->bcdHID); | ||
436 | hid->country = hdesc->bCountryCode; | ||
437 | |||
438 | - for (n = 0; n < hdesc->bNumDescriptors; n++) | ||
439 | + num_descriptors = min_t(int, hdesc->bNumDescriptors, | ||
440 | + (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor)); | ||
441 | + | ||
442 | + for (n = 0; n < num_descriptors; n++) | ||
443 | if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) | ||
444 | rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); | ||
445 | |||
446 | diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c | ||
447 | index c380b7e8f1c6..1a0b110f12c0 100644 | ||
448 | --- a/drivers/iommu/amd_iommu.c | ||
449 | +++ b/drivers/iommu/amd_iommu.c | ||
450 | @@ -3120,6 +3120,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, | ||
451 | mutex_unlock(&domain->api_lock); | ||
452 | |||
453 | domain_flush_tlb_pde(domain); | ||
454 | + domain_flush_complete(domain); | ||
455 | |||
456 | return unmap_size; | ||
457 | } | ||
458 | diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig | ||
459 | index 0e75d94972ba..671610c989b6 100644 | ||
460 | --- a/drivers/pinctrl/Kconfig | ||
461 | +++ b/drivers/pinctrl/Kconfig | ||
462 | @@ -82,6 +82,7 @@ config PINCTRL_AMD | ||
463 | tristate "AMD GPIO pin control" | ||
464 | depends on GPIOLIB | ||
465 | select GPIOLIB_IRQCHIP | ||
466 | + select PINMUX | ||
467 | select PINCONF | ||
468 | select GENERIC_PINCONF | ||
469 | help | ||
470 | diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c | ||
471 | index baa7cdcc0ebc..325bf21ba13b 100644 | ||
472 | --- a/drivers/usb/gadget/composite.c | ||
473 | +++ b/drivers/usb/gadget/composite.c | ||
474 | @@ -2018,6 +2018,8 @@ static DEVICE_ATTR_RO(suspended); | ||
475 | static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) | ||
476 | { | ||
477 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | ||
478 | + struct usb_gadget_strings *gstr = cdev->driver->strings[0]; | ||
479 | + struct usb_string *dev_str = gstr->strings; | ||
480 | |||
481 | /* composite_disconnect() must already have been called | ||
482 | * by the underlying peripheral controller driver! | ||
483 | @@ -2037,6 +2039,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) | ||
484 | |||
485 | composite_dev_cleanup(cdev); | ||
486 | |||
487 | + if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer) | ||
488 | + dev_str[USB_GADGET_MANUFACTURER_IDX].s = ""; | ||
489 | + | ||
490 | kfree(cdev->def_manufacturer); | ||
491 | kfree(cdev); | ||
492 | set_gadget_data(gadget, NULL); | ||
493 | diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c | ||
494 | index 3984787f8e97..502a096fc380 100644 | ||
495 | --- a/drivers/usb/gadget/configfs.c | ||
496 | +++ b/drivers/usb/gadget/configfs.c | ||
497 | @@ -1140,11 +1140,12 @@ static struct configfs_attribute *interf_grp_attrs[] = { | ||
498 | NULL | ||
499 | }; | ||
500 | |||
501 | -int usb_os_desc_prepare_interf_dir(struct config_group *parent, | ||
502 | - int n_interf, | ||
503 | - struct usb_os_desc **desc, | ||
504 | - char **names, | ||
505 | - struct module *owner) | ||
506 | +struct config_group *usb_os_desc_prepare_interf_dir( | ||
507 | + struct config_group *parent, | ||
508 | + int n_interf, | ||
509 | + struct usb_os_desc **desc, | ||
510 | + char **names, | ||
511 | + struct module *owner) | ||
512 | { | ||
513 | struct config_group *os_desc_group; | ||
514 | struct config_item_type *os_desc_type, *interface_type; | ||
515 | @@ -1156,7 +1157,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, | ||
516 | |||
517 | char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); | ||
518 | if (!vlabuf) | ||
519 | - return -ENOMEM; | ||
520 | + return ERR_PTR(-ENOMEM); | ||
521 | |||
522 | os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group); | ||
523 | os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type); | ||
524 | @@ -1181,7 +1182,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, | ||
525 | configfs_add_default_group(&d->group, os_desc_group); | ||
526 | } | ||
527 | |||
528 | - return 0; | ||
529 | + return os_desc_group; | ||
530 | } | ||
531 | EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir); | ||
532 | |||
533 | diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h | ||
534 | index 36c468c4f5e9..540d5e92ed22 100644 | ||
535 | --- a/drivers/usb/gadget/configfs.h | ||
536 | +++ b/drivers/usb/gadget/configfs.h | ||
537 | @@ -5,11 +5,12 @@ | ||
538 | |||
539 | void unregister_gadget_item(struct config_item *item); | ||
540 | |||
541 | -int usb_os_desc_prepare_interf_dir(struct config_group *parent, | ||
542 | - int n_interf, | ||
543 | - struct usb_os_desc **desc, | ||
544 | - char **names, | ||
545 | - struct module *owner); | ||
546 | +struct config_group *usb_os_desc_prepare_interf_dir( | ||
547 | + struct config_group *parent, | ||
548 | + int n_interf, | ||
549 | + struct usb_os_desc **desc, | ||
550 | + char **names, | ||
551 | + struct module *owner); | ||
552 | |||
553 | static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item) | ||
554 | { | ||
555 | diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c | ||
556 | index 16562e461121..ba00cdb809d6 100644 | ||
557 | --- a/drivers/usb/gadget/function/f_rndis.c | ||
558 | +++ b/drivers/usb/gadget/function/f_rndis.c | ||
559 | @@ -892,6 +892,7 @@ static void rndis_free_inst(struct usb_function_instance *f) | ||
560 | free_netdev(opts->net); | ||
561 | } | ||
562 | |||
563 | + kfree(opts->rndis_interf_group); /* single VLA chunk */ | ||
564 | kfree(opts); | ||
565 | } | ||
566 | |||
567 | @@ -900,6 +901,7 @@ static struct usb_function_instance *rndis_alloc_inst(void) | ||
568 | struct f_rndis_opts *opts; | ||
569 | struct usb_os_desc *descs[1]; | ||
570 | char *names[1]; | ||
571 | + struct config_group *rndis_interf_group; | ||
572 | |||
573 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); | ||
574 | if (!opts) | ||
575 | @@ -920,8 +922,14 @@ static struct usb_function_instance *rndis_alloc_inst(void) | ||
576 | names[0] = "rndis"; | ||
577 | config_group_init_type_name(&opts->func_inst.group, "", | ||
578 | &rndis_func_type); | ||
579 | - usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, | ||
580 | - names, THIS_MODULE); | ||
581 | + rndis_interf_group = | ||
582 | + usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, | ||
583 | + names, THIS_MODULE); | ||
584 | + if (IS_ERR(rndis_interf_group)) { | ||
585 | + rndis_free_inst(&opts->func_inst); | ||
586 | + return ERR_CAST(rndis_interf_group); | ||
587 | + } | ||
588 | + opts->rndis_interf_group = rndis_interf_group; | ||
589 | |||
590 | return &opts->func_inst; | ||
591 | } | ||
592 | diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h | ||
593 | index 4eafd5050545..4e2ad04fe8d6 100644 | ||
594 | --- a/drivers/usb/gadget/function/u_rndis.h | ||
595 | +++ b/drivers/usb/gadget/function/u_rndis.h | ||
596 | @@ -26,6 +26,7 @@ struct f_rndis_opts { | ||
597 | bool bound; | ||
598 | bool borrowed_net; | ||
599 | |||
600 | + struct config_group *rndis_interf_group; | ||
601 | struct usb_os_desc rndis_os_desc; | ||
602 | char rndis_ext_compat_id[16]; | ||
603 | |||
604 | diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c | ||
605 | index fb17fb23fa9a..b62a3de65075 100644 | ||
606 | --- a/drivers/usb/gadget/udc/dummy_hcd.c | ||
607 | +++ b/drivers/usb/gadget/udc/dummy_hcd.c | ||
608 | @@ -420,6 +420,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) | ||
609 | static void set_link_state(struct dummy_hcd *dum_hcd) | ||
610 | { | ||
611 | struct dummy *dum = dum_hcd->dum; | ||
612 | + unsigned int power_bit; | ||
613 | |||
614 | dum_hcd->active = 0; | ||
615 | if (dum->pullup) | ||
616 | @@ -430,17 +431,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd) | ||
617 | return; | ||
618 | |||
619 | set_link_state_by_speed(dum_hcd); | ||
620 | + power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ? | ||
621 | + USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER); | ||
622 | |||
623 | if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || | ||
624 | dum_hcd->active) | ||
625 | dum_hcd->resuming = 0; | ||
626 | |||
627 | /* Currently !connected or in reset */ | ||
628 | - if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || | ||
629 | + if ((dum_hcd->port_status & power_bit) == 0 || | ||
630 | (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { | ||
631 | - unsigned disconnect = USB_PORT_STAT_CONNECTION & | ||
632 | + unsigned int disconnect = power_bit & | ||
633 | dum_hcd->old_status & (~dum_hcd->port_status); | ||
634 | - unsigned reset = USB_PORT_STAT_RESET & | ||
635 | + unsigned int reset = USB_PORT_STAT_RESET & | ||
636 | (~dum_hcd->old_status) & dum_hcd->port_status; | ||
637 | |||
638 | /* Report reset and disconnect events to the driver */ | ||
639 | diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c | ||
640 | index 8897195396b2..6c6a3a8df07a 100644 | ||
641 | --- a/drivers/usb/renesas_usbhs/fifo.c | ||
642 | +++ b/drivers/usb/renesas_usbhs/fifo.c | ||
643 | @@ -860,9 +860,9 @@ static void xfer_work(struct work_struct *work) | ||
644 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); | ||
645 | |||
646 | usbhs_pipe_running(pipe, 1); | ||
647 | - usbhsf_dma_start(pipe, fifo); | ||
648 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); | ||
649 | dma_async_issue_pending(chan); | ||
650 | + usbhsf_dma_start(pipe, fifo); | ||
651 | usbhs_pipe_enable(pipe); | ||
652 | |||
653 | xfer_work_end: | ||
654 | diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c | ||
655 | index b6f1adefb758..76062ce2d459 100644 | ||
656 | --- a/drivers/usb/serial/console.c | ||
657 | +++ b/drivers/usb/serial/console.c | ||
658 | @@ -186,6 +186,7 @@ static int usb_console_setup(struct console *co, char *options) | ||
659 | tty_kref_put(tty); | ||
660 | reset_open_count: | ||
661 | port->port.count = 0; | ||
662 | + info->port = NULL; | ||
663 | usb_autopm_put_interface(serial->interface); | ||
664 | error_get_interface: | ||
665 | usb_serial_put(serial); | ||
666 | diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c | ||
667 | index 470b17b0c11b..11ee55e080e5 100644 | ||
668 | --- a/drivers/usb/serial/cp210x.c | ||
669 | +++ b/drivers/usb/serial/cp210x.c | ||
670 | @@ -171,6 +171,7 @@ static const struct usb_device_id id_table[] = { | ||
671 | { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ | ||
672 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | ||
673 | { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ | ||
674 | + { USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */ | ||
675 | { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ | ||
676 | { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ | ||
677 | { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ | ||
678 | diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c | ||
679 | index 19394963f675..3249f42b4b93 100644 | ||
680 | --- a/drivers/usb/serial/ftdi_sio.c | ||
681 | +++ b/drivers/usb/serial/ftdi_sio.c | ||
682 | @@ -1015,6 +1015,8 @@ static const struct usb_device_id id_table_combined[] = { | ||
683 | { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, | ||
684 | { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID), | ||
685 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
686 | + { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, | ||
687 | + { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, | ||
688 | { } /* Terminating entry */ | ||
689 | }; | ||
690 | |||
691 | diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h | ||
692 | index 4fcf1cecb6d7..f9d15bd62785 100644 | ||
693 | --- a/drivers/usb/serial/ftdi_sio_ids.h | ||
694 | +++ b/drivers/usb/serial/ftdi_sio_ids.h | ||
695 | @@ -609,6 +609,13 @@ | ||
696 | #define ADI_GNICE_PID 0xF000 | ||
697 | #define ADI_GNICEPLUS_PID 0xF001 | ||
698 | |||
699 | +/* | ||
700 | + * Cypress WICED USB UART | ||
701 | + */ | ||
702 | +#define CYPRESS_VID 0x04B4 | ||
703 | +#define CYPRESS_WICED_BT_USB_PID 0x009B | ||
704 | +#define CYPRESS_WICED_WL_USB_PID 0xF900 | ||
705 | + | ||
706 | /* | ||
707 | * Microchip Technology, Inc. | ||
708 | * | ||
709 | diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c | ||
710 | index 2a9944326210..db3d34c2c82e 100644 | ||
711 | --- a/drivers/usb/serial/option.c | ||
712 | +++ b/drivers/usb/serial/option.c | ||
713 | @@ -522,6 +522,7 @@ static void option_instat_callback(struct urb *urb); | ||
714 | |||
715 | /* TP-LINK Incorporated products */ | ||
716 | #define TPLINK_VENDOR_ID 0x2357 | ||
717 | +#define TPLINK_PRODUCT_LTE 0x000D | ||
718 | #define TPLINK_PRODUCT_MA180 0x0201 | ||
719 | |||
720 | /* Changhong products */ | ||
721 | @@ -2011,6 +2012,7 @@ static const struct usb_device_id option_ids[] = { | ||
722 | { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, | ||
723 | { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) }, | ||
724 | { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, | ||
725 | + { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */ | ||
726 | { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), | ||
727 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
728 | { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ | ||
729 | diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c | ||
730 | index 652b4334b26d..e1c1e329c877 100644 | ||
731 | --- a/drivers/usb/serial/qcserial.c | ||
732 | +++ b/drivers/usb/serial/qcserial.c | ||
733 | @@ -174,6 +174,10 @@ static const struct usb_device_id id_table[] = { | ||
734 | {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ | ||
735 | {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ | ||
736 | {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ | ||
737 | + {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ | ||
738 | + {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */ | ||
739 | + {DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */ | ||
740 | + {DEVICE_SWI(0x413c, 0x81d2)}, /* Dell Wireless 5818 */ | ||
741 | |||
742 | /* Huawei devices */ | ||
743 | {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ | ||
744 | diff --git a/fs/block_dev.c b/fs/block_dev.c | ||
745 | index 07e46b786500..cb936c90ae82 100644 | ||
746 | --- a/fs/block_dev.c | ||
747 | +++ b/fs/block_dev.c | ||
748 | @@ -450,10 +450,12 @@ int bdev_write_page(struct block_device *bdev, sector_t sector, | ||
749 | |||
750 | set_page_writeback(page); | ||
751 | result = ops->rw_page(bdev, sector + get_start_sect(bdev), page, true); | ||
752 | - if (result) | ||
753 | + if (result) { | ||
754 | end_page_writeback(page); | ||
755 | - else | ||
756 | + } else { | ||
757 | + clean_page_buffers(page); | ||
758 | unlock_page(page); | ||
759 | + } | ||
760 | blk_queue_exit(bdev->bd_queue); | ||
761 | return result; | ||
762 | } | ||
763 | diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h | ||
764 | index 48ef401c3c61..7b496a4e650e 100644 | ||
765 | --- a/fs/cifs/cifsglob.h | ||
766 | +++ b/fs/cifs/cifsglob.h | ||
767 | @@ -365,6 +365,8 @@ struct smb_version_operations { | ||
768 | unsigned int (*calc_smb_size)(void *); | ||
769 | /* check for STATUS_PENDING and process it in a positive case */ | ||
770 | bool (*is_status_pending)(char *, struct TCP_Server_Info *, int); | ||
771 | + /* check for STATUS_NETWORK_SESSION_EXPIRED */ | ||
772 | + bool (*is_session_expired)(char *); | ||
773 | /* send oplock break response */ | ||
774 | int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *, | ||
775 | struct cifsInodeInfo *); | ||
776 | diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c | ||
777 | index 1f91c9dadd5b..cc420d6b71f7 100644 | ||
778 | --- a/fs/cifs/cifssmb.c | ||
779 | +++ b/fs/cifs/cifssmb.c | ||
780 | @@ -1457,6 +1457,13 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) | ||
781 | return length; | ||
782 | server->total_read += length; | ||
783 | |||
784 | + if (server->ops->is_session_expired && | ||
785 | + server->ops->is_session_expired(buf)) { | ||
786 | + cifs_reconnect(server); | ||
787 | + wake_up(&server->response_q); | ||
788 | + return -1; | ||
789 | + } | ||
790 | + | ||
791 | if (server->ops->is_status_pending && | ||
792 | server->ops->is_status_pending(buf, server, 0)) { | ||
793 | discard_remaining_data(server); | ||
794 | diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c | ||
795 | index f6712b6128d8..580b3a4ca53a 100644 | ||
796 | --- a/fs/cifs/connect.c | ||
797 | +++ b/fs/cifs/connect.c | ||
798 | @@ -796,6 +796,13 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) | ||
799 | cifs_dump_mem("Bad SMB: ", buf, | ||
800 | min_t(unsigned int, server->total_read, 48)); | ||
801 | |||
802 | + if (server->ops->is_session_expired && | ||
803 | + server->ops->is_session_expired(buf)) { | ||
804 | + cifs_reconnect(server); | ||
805 | + wake_up(&server->response_q); | ||
806 | + return -1; | ||
807 | + } | ||
808 | + | ||
809 | if (server->ops->is_status_pending && | ||
810 | server->ops->is_status_pending(buf, server, length)) | ||
811 | return -1; | ||
812 | diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c | ||
813 | index b6968241c26f..812e4884c392 100644 | ||
814 | --- a/fs/cifs/smb2ops.c | ||
815 | +++ b/fs/cifs/smb2ops.c | ||
816 | @@ -1018,6 +1018,18 @@ smb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length) | ||
817 | return true; | ||
818 | } | ||
819 | |||
820 | +static bool | ||
821 | +smb2_is_session_expired(char *buf) | ||
822 | +{ | ||
823 | + struct smb2_hdr *hdr = (struct smb2_hdr *)buf; | ||
824 | + | ||
825 | + if (hdr->Status != STATUS_NETWORK_SESSION_EXPIRED) | ||
826 | + return false; | ||
827 | + | ||
828 | + cifs_dbg(FYI, "Session expired\n"); | ||
829 | + return true; | ||
830 | +} | ||
831 | + | ||
832 | static int | ||
833 | smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid, | ||
834 | struct cifsInodeInfo *cinode) | ||
835 | @@ -1609,6 +1621,7 @@ struct smb_version_operations smb20_operations = { | ||
836 | .close_dir = smb2_close_dir, | ||
837 | .calc_smb_size = smb2_calc_size, | ||
838 | .is_status_pending = smb2_is_status_pending, | ||
839 | + .is_session_expired = smb2_is_session_expired, | ||
840 | .oplock_response = smb2_oplock_response, | ||
841 | .queryfs = smb2_queryfs, | ||
842 | .mand_lock = smb2_mand_lock, | ||
843 | @@ -1690,6 +1703,7 @@ struct smb_version_operations smb21_operations = { | ||
844 | .close_dir = smb2_close_dir, | ||
845 | .calc_smb_size = smb2_calc_size, | ||
846 | .is_status_pending = smb2_is_status_pending, | ||
847 | + .is_session_expired = smb2_is_session_expired, | ||
848 | .oplock_response = smb2_oplock_response, | ||
849 | .queryfs = smb2_queryfs, | ||
850 | .mand_lock = smb2_mand_lock, | ||
851 | @@ -1773,6 +1787,7 @@ struct smb_version_operations smb30_operations = { | ||
852 | .close_dir = smb2_close_dir, | ||
853 | .calc_smb_size = smb2_calc_size, | ||
854 | .is_status_pending = smb2_is_status_pending, | ||
855 | + .is_session_expired = smb2_is_session_expired, | ||
856 | .oplock_response = smb2_oplock_response, | ||
857 | .queryfs = smb2_queryfs, | ||
858 | .mand_lock = smb2_mand_lock, | ||
859 | @@ -1862,6 +1877,7 @@ struct smb_version_operations smb311_operations = { | ||
860 | .close_dir = smb2_close_dir, | ||
861 | .calc_smb_size = smb2_calc_size, | ||
862 | .is_status_pending = smb2_is_status_pending, | ||
863 | + .is_session_expired = smb2_is_session_expired, | ||
864 | .oplock_response = smb2_oplock_response, | ||
865 | .queryfs = smb2_queryfs, | ||
866 | .mand_lock = smb2_mand_lock, | ||
867 | diff --git a/fs/direct-io.c b/fs/direct-io.c | ||
868 | index c60756e89833..c6220a2daefd 100644 | ||
869 | --- a/fs/direct-io.c | ||
870 | +++ b/fs/direct-io.c | ||
871 | @@ -835,7 +835,8 @@ submit_page_section(struct dio *dio, struct dio_submit *sdio, struct page *page, | ||
872 | */ | ||
873 | if (sdio->boundary) { | ||
874 | ret = dio_send_cur_page(dio, sdio, map_bh); | ||
875 | - dio_bio_submit(dio, sdio); | ||
876 | + if (sdio->bio) | ||
877 | + dio_bio_submit(dio, sdio); | ||
878 | put_page(sdio->cur_page); | ||
879 | sdio->cur_page = NULL; | ||
880 | } | ||
881 | diff --git a/fs/ext4/file.c b/fs/ext4/file.c | ||
882 | index d17d12ed6f73..510e66422f04 100644 | ||
883 | --- a/fs/ext4/file.c | ||
884 | +++ b/fs/ext4/file.c | ||
885 | @@ -527,7 +527,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) | ||
886 | inode_lock(inode); | ||
887 | |||
888 | isize = i_size_read(inode); | ||
889 | - if (offset >= isize) { | ||
890 | + if (offset < 0 || offset >= isize) { | ||
891 | inode_unlock(inode); | ||
892 | return -ENXIO; | ||
893 | } | ||
894 | @@ -590,7 +590,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) | ||
895 | inode_lock(inode); | ||
896 | |||
897 | isize = i_size_read(inode); | ||
898 | - if (offset >= isize) { | ||
899 | + if (offset < 0 || offset >= isize) { | ||
900 | inode_unlock(inode); | ||
901 | return -ENXIO; | ||
902 | } | ||
903 | diff --git a/fs/mpage.c b/fs/mpage.c | ||
904 | index d2fcb149720d..e2ea442bb9e1 100644 | ||
905 | --- a/fs/mpage.c | ||
906 | +++ b/fs/mpage.c | ||
907 | @@ -466,6 +466,16 @@ static void clean_buffers(struct page *page, unsigned first_unmapped) | ||
908 | try_to_free_buffers(page); | ||
909 | } | ||
910 | |||
911 | +/* | ||
912 | + * For situations where we want to clean all buffers attached to a page. | ||
913 | + * We don't need to calculate how many buffers are attached to the page, | ||
914 | + * we just need to specify a number larger than the maximum number of buffers. | ||
915 | + */ | ||
916 | +void clean_page_buffers(struct page *page) | ||
917 | +{ | ||
918 | + clean_buffers(page, ~0U); | ||
919 | +} | ||
920 | + | ||
921 | static int __mpage_writepage(struct page *page, struct writeback_control *wbc, | ||
922 | void *data) | ||
923 | { | ||
924 | @@ -604,10 +614,8 @@ static int __mpage_writepage(struct page *page, struct writeback_control *wbc, | ||
925 | if (bio == NULL) { | ||
926 | if (first_unmapped == blocks_per_page) { | ||
927 | if (!bdev_write_page(bdev, blocks[0] << (blkbits - 9), | ||
928 | - page, wbc)) { | ||
929 | - clean_buffers(page, first_unmapped); | ||
930 | + page, wbc)) | ||
931 | goto out; | ||
932 | - } | ||
933 | } | ||
934 | bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9), | ||
935 | BIO_MAX_PAGES, GFP_NOFS|__GFP_HIGH); | ||
936 | diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h | ||
937 | index ebbacd14d450..447a915db25d 100644 | ||
938 | --- a/include/linux/buffer_head.h | ||
939 | +++ b/include/linux/buffer_head.h | ||
940 | @@ -226,6 +226,7 @@ int generic_write_end(struct file *, struct address_space *, | ||
941 | loff_t, unsigned, unsigned, | ||
942 | struct page *, void *); | ||
943 | void page_zero_new_buffers(struct page *page, unsigned from, unsigned to); | ||
944 | +void clean_page_buffers(struct page *page); | ||
945 | int cont_write_begin(struct file *, struct address_space *, loff_t, | ||
946 | unsigned, unsigned, struct page **, void **, | ||
947 | get_block_t *, loff_t *); | ||
948 | diff --git a/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h | ||
949 | index a03acd0d398a..695257ae64ac 100644 | ||
950 | --- a/include/sound/seq_virmidi.h | ||
951 | +++ b/include/sound/seq_virmidi.h | ||
952 | @@ -60,6 +60,7 @@ struct snd_virmidi_dev { | ||
953 | int port; /* created/attached port */ | ||
954 | unsigned int flags; /* SNDRV_VIRMIDI_* */ | ||
955 | rwlock_t filelist_lock; | ||
956 | + struct rw_semaphore filelist_sem; | ||
957 | struct list_head filelist; | ||
958 | }; | ||
959 | |||
960 | diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c | ||
961 | index 10f62c6f48e7..d1a02877a42c 100644 | ||
962 | --- a/kernel/rcu/tree.c | ||
963 | +++ b/kernel/rcu/tree.c | ||
964 | @@ -792,8 +792,13 @@ void rcu_irq_exit(void) | ||
965 | long long oldval; | ||
966 | struct rcu_dynticks *rdtp; | ||
967 | |||
968 | - RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_exit() invoked with irqs enabled!!!"); | ||
969 | rdtp = this_cpu_ptr(&rcu_dynticks); | ||
970 | + | ||
971 | + /* Page faults can happen in NMI handlers, so check... */ | ||
972 | + if (READ_ONCE(rdtp->dynticks_nmi_nesting)) | ||
973 | + return; | ||
974 | + | ||
975 | + RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_exit() invoked with irqs enabled!!!"); | ||
976 | oldval = rdtp->dynticks_nesting; | ||
977 | rdtp->dynticks_nesting--; | ||
978 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && | ||
979 | @@ -930,8 +935,13 @@ void rcu_irq_enter(void) | ||
980 | struct rcu_dynticks *rdtp; | ||
981 | long long oldval; | ||
982 | |||
983 | - RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_enter() invoked with irqs enabled!!!"); | ||
984 | rdtp = this_cpu_ptr(&rcu_dynticks); | ||
985 | + | ||
986 | + /* Page faults can happen in NMI handlers, so check... */ | ||
987 | + if (READ_ONCE(rdtp->dynticks_nmi_nesting)) | ||
988 | + return; | ||
989 | + | ||
990 | + RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_enter() invoked with irqs enabled!!!"); | ||
991 | oldval = rdtp->dynticks_nesting; | ||
992 | rdtp->dynticks_nesting++; | ||
993 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && | ||
994 | diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c | ||
995 | index ece0fbc08607..c626f679e1c8 100644 | ||
996 | --- a/net/wireless/nl80211.c | ||
997 | +++ b/net/wireless/nl80211.c | ||
998 | @@ -541,6 +541,14 @@ nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = { | ||
999 | [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED }, | ||
1000 | }; | ||
1001 | |||
1002 | +/* policy for packet pattern attributes */ | ||
1003 | +static const struct nla_policy | ||
1004 | +nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = { | ||
1005 | + [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, }, | ||
1006 | + [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, }, | ||
1007 | + [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 }, | ||
1008 | +}; | ||
1009 | + | ||
1010 | static int nl80211_prepare_wdev_dump(struct sk_buff *skb, | ||
1011 | struct netlink_callback *cb, | ||
1012 | struct cfg80211_registered_device **rdev, | ||
1013 | @@ -10009,7 +10017,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | ||
1014 | u8 *mask_pat; | ||
1015 | |||
1016 | nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), | ||
1017 | - nla_len(pat), NULL); | ||
1018 | + nla_len(pat), nl80211_packet_pattern_policy); | ||
1019 | err = -EINVAL; | ||
1020 | if (!pat_tb[NL80211_PKTPAT_MASK] || | ||
1021 | !pat_tb[NL80211_PKTPAT_PATTERN]) | ||
1022 | @@ -10259,7 +10267,7 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, | ||
1023 | u8 *mask_pat; | ||
1024 | |||
1025 | nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), | ||
1026 | - nla_len(pat), NULL); | ||
1027 | + nla_len(pat), nl80211_packet_pattern_policy); | ||
1028 | if (!pat_tb[NL80211_PKTPAT_MASK] || | ||
1029 | !pat_tb[NL80211_PKTPAT_PATTERN]) | ||
1030 | return -EINVAL; | ||
1031 | diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c | ||
1032 | index 67c4c68ce041..c41148353e19 100644 | ||
1033 | --- a/sound/core/seq/seq_clientmgr.c | ||
1034 | +++ b/sound/core/seq/seq_clientmgr.c | ||
1035 | @@ -1259,6 +1259,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) | ||
1036 | struct snd_seq_port_info *info = arg; | ||
1037 | struct snd_seq_client_port *port; | ||
1038 | struct snd_seq_port_callback *callback; | ||
1039 | + int port_idx; | ||
1040 | |||
1041 | /* it is not allowed to create the port for an another client */ | ||
1042 | if (info->addr.client != client->number) | ||
1043 | @@ -1269,7 +1270,9 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) | ||
1044 | return -ENOMEM; | ||
1045 | |||
1046 | if (client->type == USER_CLIENT && info->kernel) { | ||
1047 | - snd_seq_delete_port(client, port->addr.port); | ||
1048 | + port_idx = port->addr.port; | ||
1049 | + snd_seq_port_unlock(port); | ||
1050 | + snd_seq_delete_port(client, port_idx); | ||
1051 | return -EINVAL; | ||
1052 | } | ||
1053 | if (client->type == KERNEL_CLIENT) { | ||
1054 | @@ -1290,6 +1293,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) | ||
1055 | |||
1056 | snd_seq_set_port_info(port, info); | ||
1057 | snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); | ||
1058 | + snd_seq_port_unlock(port); | ||
1059 | |||
1060 | return 0; | ||
1061 | } | ||
1062 | diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c | ||
1063 | index fe686ee41c6d..f04714d70bf7 100644 | ||
1064 | --- a/sound/core/seq/seq_ports.c | ||
1065 | +++ b/sound/core/seq/seq_ports.c | ||
1066 | @@ -122,7 +122,9 @@ static void port_subs_info_init(struct snd_seq_port_subs_info *grp) | ||
1067 | } | ||
1068 | |||
1069 | |||
1070 | -/* create a port, port number is returned (-1 on failure) */ | ||
1071 | +/* create a port, port number is returned (-1 on failure); | ||
1072 | + * the caller needs to unref the port via snd_seq_port_unlock() appropriately | ||
1073 | + */ | ||
1074 | struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, | ||
1075 | int port) | ||
1076 | { | ||
1077 | @@ -151,6 +153,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, | ||
1078 | snd_use_lock_init(&new_port->use_lock); | ||
1079 | port_subs_info_init(&new_port->c_src); | ||
1080 | port_subs_info_init(&new_port->c_dest); | ||
1081 | + snd_use_lock_use(&new_port->use_lock); | ||
1082 | |||
1083 | num = port >= 0 ? port : 0; | ||
1084 | mutex_lock(&client->ports_mutex); | ||
1085 | @@ -165,9 +168,9 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, | ||
1086 | list_add_tail(&new_port->list, &p->list); | ||
1087 | client->num_ports++; | ||
1088 | new_port->addr.port = num; /* store the port number in the port */ | ||
1089 | + sprintf(new_port->name, "port-%d", num); | ||
1090 | write_unlock_irqrestore(&client->ports_lock, flags); | ||
1091 | mutex_unlock(&client->ports_mutex); | ||
1092 | - sprintf(new_port->name, "port-%d", num); | ||
1093 | |||
1094 | return new_port; | ||
1095 | } | ||
1096 | diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c | ||
1097 | index c82ed3e70506..200764948ed1 100644 | ||
1098 | --- a/sound/core/seq/seq_virmidi.c | ||
1099 | +++ b/sound/core/seq/seq_virmidi.c | ||
1100 | @@ -77,13 +77,17 @@ static void snd_virmidi_init_event(struct snd_virmidi *vmidi, | ||
1101 | * decode input event and put to read buffer of each opened file | ||
1102 | */ | ||
1103 | static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, | ||
1104 | - struct snd_seq_event *ev) | ||
1105 | + struct snd_seq_event *ev, | ||
1106 | + bool atomic) | ||
1107 | { | ||
1108 | struct snd_virmidi *vmidi; | ||
1109 | unsigned char msg[4]; | ||
1110 | int len; | ||
1111 | |||
1112 | - read_lock(&rdev->filelist_lock); | ||
1113 | + if (atomic) | ||
1114 | + read_lock(&rdev->filelist_lock); | ||
1115 | + else | ||
1116 | + down_read(&rdev->filelist_sem); | ||
1117 | list_for_each_entry(vmidi, &rdev->filelist, list) { | ||
1118 | if (!vmidi->trigger) | ||
1119 | continue; | ||
1120 | @@ -97,7 +101,10 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, | ||
1121 | snd_rawmidi_receive(vmidi->substream, msg, len); | ||
1122 | } | ||
1123 | } | ||
1124 | - read_unlock(&rdev->filelist_lock); | ||
1125 | + if (atomic) | ||
1126 | + read_unlock(&rdev->filelist_lock); | ||
1127 | + else | ||
1128 | + up_read(&rdev->filelist_sem); | ||
1129 | |||
1130 | return 0; | ||
1131 | } | ||
1132 | @@ -115,7 +122,7 @@ int snd_virmidi_receive(struct snd_rawmidi *rmidi, struct snd_seq_event *ev) | ||
1133 | struct snd_virmidi_dev *rdev; | ||
1134 | |||
1135 | rdev = rmidi->private_data; | ||
1136 | - return snd_virmidi_dev_receive_event(rdev, ev); | ||
1137 | + return snd_virmidi_dev_receive_event(rdev, ev, true); | ||
1138 | } | ||
1139 | #endif /* 0 */ | ||
1140 | |||
1141 | @@ -130,7 +137,7 @@ static int snd_virmidi_event_input(struct snd_seq_event *ev, int direct, | ||
1142 | rdev = private_data; | ||
1143 | if (!(rdev->flags & SNDRV_VIRMIDI_USE)) | ||
1144 | return 0; /* ignored */ | ||
1145 | - return snd_virmidi_dev_receive_event(rdev, ev); | ||
1146 | + return snd_virmidi_dev_receive_event(rdev, ev, atomic); | ||
1147 | } | ||
1148 | |||
1149 | /* | ||
1150 | @@ -209,7 +216,6 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) | ||
1151 | struct snd_virmidi_dev *rdev = substream->rmidi->private_data; | ||
1152 | struct snd_rawmidi_runtime *runtime = substream->runtime; | ||
1153 | struct snd_virmidi *vmidi; | ||
1154 | - unsigned long flags; | ||
1155 | |||
1156 | vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL); | ||
1157 | if (vmidi == NULL) | ||
1158 | @@ -223,9 +229,11 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) | ||
1159 | vmidi->client = rdev->client; | ||
1160 | vmidi->port = rdev->port; | ||
1161 | runtime->private_data = vmidi; | ||
1162 | - write_lock_irqsave(&rdev->filelist_lock, flags); | ||
1163 | + down_write(&rdev->filelist_sem); | ||
1164 | + write_lock_irq(&rdev->filelist_lock); | ||
1165 | list_add_tail(&vmidi->list, &rdev->filelist); | ||
1166 | - write_unlock_irqrestore(&rdev->filelist_lock, flags); | ||
1167 | + write_unlock_irq(&rdev->filelist_lock); | ||
1168 | + up_write(&rdev->filelist_sem); | ||
1169 | vmidi->rdev = rdev; | ||
1170 | return 0; | ||
1171 | } | ||
1172 | @@ -264,9 +272,11 @@ static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream) | ||
1173 | struct snd_virmidi_dev *rdev = substream->rmidi->private_data; | ||
1174 | struct snd_virmidi *vmidi = substream->runtime->private_data; | ||
1175 | |||
1176 | + down_write(&rdev->filelist_sem); | ||
1177 | write_lock_irq(&rdev->filelist_lock); | ||
1178 | list_del(&vmidi->list); | ||
1179 | write_unlock_irq(&rdev->filelist_lock); | ||
1180 | + up_write(&rdev->filelist_sem); | ||
1181 | snd_midi_event_free(vmidi->parser); | ||
1182 | substream->runtime->private_data = NULL; | ||
1183 | kfree(vmidi); | ||
1184 | @@ -520,6 +530,7 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi | ||
1185 | rdev->rmidi = rmidi; | ||
1186 | rdev->device = device; | ||
1187 | rdev->client = -1; | ||
1188 | + init_rwsem(&rdev->filelist_sem); | ||
1189 | rwlock_init(&rdev->filelist_lock); | ||
1190 | INIT_LIST_HEAD(&rdev->filelist); | ||
1191 | rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH; | ||
1192 | diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c | ||
1193 | index b871ba407e4e..4458190149d1 100644 | ||
1194 | --- a/sound/usb/caiaq/device.c | ||
1195 | +++ b/sound/usb/caiaq/device.c | ||
1196 | @@ -469,10 +469,12 @@ static int init_card(struct snd_usb_caiaqdev *cdev) | ||
1197 | |||
1198 | err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); | ||
1199 | if (err) | ||
1200 | - return err; | ||
1201 | + goto err_kill_urb; | ||
1202 | |||
1203 | - if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) | ||
1204 | - return -ENODEV; | ||
1205 | + if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) { | ||
1206 | + err = -ENODEV; | ||
1207 | + goto err_kill_urb; | ||
1208 | + } | ||
1209 | |||
1210 | usb_string(usb_dev, usb_dev->descriptor.iManufacturer, | ||
1211 | cdev->vendor_name, CAIAQ_USB_STR_LEN); | ||
1212 | @@ -507,6 +509,10 @@ static int init_card(struct snd_usb_caiaqdev *cdev) | ||
1213 | |||
1214 | setup_card(cdev); | ||
1215 | return 0; | ||
1216 | + | ||
1217 | + err_kill_urb: | ||
1218 | + usb_kill_urb(&cdev->ep1_in_urb); | ||
1219 | + return err; | ||
1220 | } | ||
1221 | |||
1222 | static int snd_probe(struct usb_interface *intf, | ||
1223 | diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c | ||
1224 | index ab3c280a23d1..58d624938a9f 100644 | ||
1225 | --- a/sound/usb/line6/driver.c | ||
1226 | +++ b/sound/usb/line6/driver.c | ||
1227 | @@ -775,9 +775,10 @@ int line6_probe(struct usb_interface *interface, | ||
1228 | return 0; | ||
1229 | |||
1230 | error: | ||
1231 | - if (line6->disconnect) | ||
1232 | - line6->disconnect(line6); | ||
1233 | - snd_card_free(card); | ||
1234 | + /* we can call disconnect callback here because no close-sync is | ||
1235 | + * needed yet at this point | ||
1236 | + */ | ||
1237 | + line6_disconnect(interface); | ||
1238 | return ret; | ||
1239 | } | ||
1240 | EXPORT_SYMBOL_GPL(line6_probe); | ||
1241 | diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c | ||
1242 | index 49cd4a65e390..5ab9e0c89211 100644 | ||
1243 | --- a/sound/usb/line6/podhd.c | ||
1244 | +++ b/sound/usb/line6/podhd.c | ||
1245 | @@ -307,6 +307,9 @@ static int podhd_init(struct usb_line6 *line6, | ||
1246 | |||
1247 | line6->disconnect = podhd_disconnect; | ||
1248 | |||
1249 | + init_timer(&pod->startup_timer); | ||
1250 | + INIT_WORK(&pod->startup_work, podhd_startup_workqueue); | ||
1251 | + | ||
1252 | if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { | ||
1253 | /* create sysfs entries: */ | ||
1254 | err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group); | ||
1255 | @@ -330,8 +333,6 @@ static int podhd_init(struct usb_line6 *line6, | ||
1256 | } | ||
1257 | |||
1258 | /* init device and delay registering */ | ||
1259 | - init_timer(&pod->startup_timer); | ||
1260 | - INIT_WORK(&pod->startup_work, podhd_startup_workqueue); | ||
1261 | podhd_startup(pod); | ||
1262 | return 0; | ||
1263 | } | ||
1264 | diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c | ||
1265 | index d09c28c1deaf..d82e3c81c258 100644 | ||
1266 | --- a/sound/usb/mixer.c | ||
1267 | +++ b/sound/usb/mixer.c | ||
1268 | @@ -2228,6 +2228,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) | ||
1269 | |||
1270 | static void snd_usb_mixer_free(struct usb_mixer_interface *mixer) | ||
1271 | { | ||
1272 | + /* kill pending URBs */ | ||
1273 | + snd_usb_mixer_disconnect(mixer); | ||
1274 | + | ||
1275 | kfree(mixer->id_elems); | ||
1276 | if (mixer->urb) { | ||
1277 | kfree(mixer->urb->transfer_buffer); | ||
1278 | @@ -2578,8 +2581,13 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | ||
1279 | |||
1280 | void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer) | ||
1281 | { | ||
1282 | - usb_kill_urb(mixer->urb); | ||
1283 | - usb_kill_urb(mixer->rc_urb); | ||
1284 | + if (mixer->disconnected) | ||
1285 | + return; | ||
1286 | + if (mixer->urb) | ||
1287 | + usb_kill_urb(mixer->urb); | ||
1288 | + if (mixer->rc_urb) | ||
1289 | + usb_kill_urb(mixer->rc_urb); | ||
1290 | + mixer->disconnected = true; | ||
1291 | } | ||
1292 | |||
1293 | #ifdef CONFIG_PM | ||
1294 | diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h | ||
1295 | index 2b4b067646ab..545d99b09706 100644 | ||
1296 | --- a/sound/usb/mixer.h | ||
1297 | +++ b/sound/usb/mixer.h | ||
1298 | @@ -22,6 +22,8 @@ struct usb_mixer_interface { | ||
1299 | struct urb *rc_urb; | ||
1300 | struct usb_ctrlrequest *rc_setup_packet; | ||
1301 | u8 rc_buffer[6]; | ||
1302 | + | ||
1303 | + bool disconnected; | ||
1304 | }; | ||
1305 | |||
1306 | #define MAX_CHANNELS 16 /* max logical channels */ |