1 |
Author: psomas |
2 |
Date: 2011-08-29 23:09:32 +0000 (Mon, 29 Aug 2011) |
3 |
New Revision: 1972 |
4 |
|
5 |
Added: |
6 |
genpatches-2.6/trunk/3.0/1003_linux-3.0.4.patch |
7 |
Modified: |
8 |
genpatches-2.6/trunk/3.0/0000_README |
9 |
Log: |
10 |
Linux patch 3.0.4 |
11 |
|
12 |
Modified: genpatches-2.6/trunk/3.0/0000_README |
13 |
=================================================================== |
14 |
--- genpatches-2.6/trunk/3.0/0000_README 2011-08-29 23:08:28 UTC (rev 1971) |
15 |
+++ genpatches-2.6/trunk/3.0/0000_README 2011-08-29 23:09:32 UTC (rev 1972) |
16 |
@@ -51,6 +51,10 @@ |
17 |
From: http://www.kernel.org |
18 |
Desc: Linux 3.0.3 |
19 |
|
20 |
+Patch: 1003_linux-3.0.4.patch |
21 |
+From: http://www.kernel.org |
22 |
+Desc: Linux 3.0.4 |
23 |
+ |
24 |
Patch: 1800_fix-zcache-build.patch |
25 |
From: http://bugs.gentoo.org/show_bug.cgi?id=376325 |
26 |
Desc: Fix zcache build error |
27 |
|
28 |
Added: genpatches-2.6/trunk/3.0/1003_linux-3.0.4.patch |
29 |
=================================================================== |
30 |
--- genpatches-2.6/trunk/3.0/1003_linux-3.0.4.patch (rev 0) |
31 |
+++ genpatches-2.6/trunk/3.0/1003_linux-3.0.4.patch 2011-08-29 23:09:32 UTC (rev 1972) |
32 |
@@ -0,0 +1,1273 @@ |
33 |
+diff --git a/Makefile b/Makefile |
34 |
+index c44d720..7d2192c 100644 |
35 |
+--- a/Makefile |
36 |
++++ b/Makefile |
37 |
+@@ -1,6 +1,6 @@ |
38 |
+ VERSION = 3 |
39 |
+ PATCHLEVEL = 0 |
40 |
+-SUBLEVEL = 3 |
41 |
++SUBLEVEL = 4 |
42 |
+ EXTRAVERSION = |
43 |
+ NAME = Sneaky Weasel |
44 |
+ |
45 |
+diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h |
46 |
+index 64a619d..7ff4669 100644 |
47 |
+--- a/arch/x86/include/asm/xen/page.h |
48 |
++++ b/arch/x86/include/asm/xen/page.h |
49 |
+@@ -39,7 +39,7 @@ typedef struct xpaddr { |
50 |
+ ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE)) |
51 |
+ |
52 |
+ extern unsigned long *machine_to_phys_mapping; |
53 |
+-extern unsigned int machine_to_phys_order; |
54 |
++extern unsigned long machine_to_phys_nr; |
55 |
+ |
56 |
+ extern unsigned long get_phys_to_machine(unsigned long pfn); |
57 |
+ extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); |
58 |
+@@ -87,7 +87,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) |
59 |
+ if (xen_feature(XENFEAT_auto_translated_physmap)) |
60 |
+ return mfn; |
61 |
+ |
62 |
+- if (unlikely((mfn >> machine_to_phys_order) != 0)) { |
63 |
++ if (unlikely(mfn >= machine_to_phys_nr)) { |
64 |
+ pfn = ~0; |
65 |
+ goto try_override; |
66 |
+ } |
67 |
+diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c |
68 |
+index adc66c3..34b1859 100644 |
69 |
+--- a/arch/x86/kernel/apic/x2apic_uv_x.c |
70 |
++++ b/arch/x86/kernel/apic/x2apic_uv_x.c |
71 |
+@@ -207,7 +207,6 @@ static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_ri |
72 |
+ ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | |
73 |
+ APIC_DM_INIT; |
74 |
+ uv_write_global_mmr64(pnode, UVH_IPI_INT, val); |
75 |
+- mdelay(10); |
76 |
+ |
77 |
+ val = (1UL << UVH_IPI_INT_SEND_SHFT) | |
78 |
+ (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | |
79 |
+diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c |
80 |
+index da0d779..ed6086e 100644 |
81 |
+--- a/arch/x86/kernel/cpu/intel.c |
82 |
++++ b/arch/x86/kernel/cpu/intel.c |
83 |
+@@ -465,11 +465,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) |
84 |
+ u64 epb; |
85 |
+ |
86 |
+ rdmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); |
87 |
+- if ((epb & 0xF) == 0) { |
88 |
+- printk_once(KERN_WARNING, "x86: updated energy_perf_bias" |
89 |
+- " to 'normal' from 'performance'\n" |
90 |
+- "You can view and update epb via utility," |
91 |
+- " such as x86_energy_perf_policy(8)\n"); |
92 |
++ if ((epb & 0xF) == ENERGY_PERF_BIAS_PERFORMANCE) { |
93 |
++ printk_once(KERN_WARNING "ENERGY_PERF_BIAS:" |
94 |
++ " Set to 'normal', was 'performance'\n" |
95 |
++ "ENERGY_PERF_BIAS: View and update with" |
96 |
++ " x86_energy_perf_policy(8)\n"); |
97 |
+ epb = (epb & ~0xF) | ENERGY_PERF_BIAS_NORMAL; |
98 |
+ wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); |
99 |
+ } |
100 |
+diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c |
101 |
+index 929739a..3d17bc7 100644 |
102 |
+--- a/arch/x86/kernel/cpu/mtrr/main.c |
103 |
++++ b/arch/x86/kernel/cpu/mtrr/main.c |
104 |
+@@ -248,6 +248,25 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ |
105 |
+ unsigned long flags; |
106 |
+ int cpu; |
107 |
+ |
108 |
++#ifdef CONFIG_SMP |
109 |
++ /* |
110 |
++ * If this cpu is not yet active, we are in the cpu online path. There |
111 |
++ * can be no stop_machine() in parallel, as stop machine ensures this |
112 |
++ * by using get_online_cpus(). We can skip taking the stop_cpus_mutex, |
113 |
++ * as we don't need it and also we can't afford to block while waiting |
114 |
++ * for the mutex. |
115 |
++ * |
116 |
++ * If this cpu is active, we need to prevent stop_machine() happening |
117 |
++ * in parallel by taking the stop cpus mutex. |
118 |
++ * |
119 |
++ * Also, this is called in the context of cpu online path or in the |
120 |
++ * context where cpu hotplug is prevented. So checking the active status |
121 |
++ * of the raw_smp_processor_id() is safe. |
122 |
++ */ |
123 |
++ if (cpu_active(raw_smp_processor_id())) |
124 |
++ mutex_lock(&stop_cpus_mutex); |
125 |
++#endif |
126 |
++ |
127 |
+ preempt_disable(); |
128 |
+ |
129 |
+ data.smp_reg = reg; |
130 |
+@@ -330,6 +349,10 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ |
131 |
+ |
132 |
+ local_irq_restore(flags); |
133 |
+ preempt_enable(); |
134 |
++#ifdef CONFIG_SMP |
135 |
++ if (cpu_active(raw_smp_processor_id())) |
136 |
++ mutex_unlock(&stop_cpus_mutex); |
137 |
++#endif |
138 |
+ } |
139 |
+ |
140 |
+ /** |
141 |
+diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c |
142 |
+index 0060fd5..02e3934 100644 |
143 |
+--- a/arch/x86/platform/olpc/olpc.c |
144 |
++++ b/arch/x86/platform/olpc/olpc.c |
145 |
+@@ -157,13 +157,13 @@ restart: |
146 |
+ if (inbuf && inlen) { |
147 |
+ /* write data to EC */ |
148 |
+ for (i = 0; i < inlen; i++) { |
149 |
++ pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]); |
150 |
++ outb(inbuf[i], 0x68); |
151 |
+ if (wait_on_ibf(0x6c, 0)) { |
152 |
+ printk(KERN_ERR "olpc-ec: timeout waiting for" |
153 |
+ " EC accept data!\n"); |
154 |
+ goto err; |
155 |
+ } |
156 |
+- pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]); |
157 |
+- outb(inbuf[i], 0x68); |
158 |
+ } |
159 |
+ } |
160 |
+ if (outbuf && outlen) { |
161 |
+diff --git a/arch/x86/vdso/vdso32/sysenter.S b/arch/x86/vdso/vdso32/sysenter.S |
162 |
+index e2800af..e354bce 100644 |
163 |
+--- a/arch/x86/vdso/vdso32/sysenter.S |
164 |
++++ b/arch/x86/vdso/vdso32/sysenter.S |
165 |
+@@ -43,7 +43,7 @@ __kernel_vsyscall: |
166 |
+ .space 7,0x90 |
167 |
+ |
168 |
+ /* 14: System call restart point is here! (SYSENTER_RETURN-2) */ |
169 |
+- jmp .Lenter_kernel |
170 |
++ int $0x80 |
171 |
+ /* 16: System call normal return point is here! */ |
172 |
+ VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */ |
173 |
+ pop %ebp |
174 |
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c |
175 |
+index 5325742..67d69f1 100644 |
176 |
+--- a/arch/x86/xen/enlighten.c |
177 |
++++ b/arch/x86/xen/enlighten.c |
178 |
+@@ -77,8 +77,8 @@ EXPORT_SYMBOL_GPL(xen_domain_type); |
179 |
+ |
180 |
+ unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START; |
181 |
+ EXPORT_SYMBOL(machine_to_phys_mapping); |
182 |
+-unsigned int machine_to_phys_order; |
183 |
+-EXPORT_SYMBOL(machine_to_phys_order); |
184 |
++unsigned long machine_to_phys_nr; |
185 |
++EXPORT_SYMBOL(machine_to_phys_nr); |
186 |
+ |
187 |
+ struct start_info *xen_start_info; |
188 |
+ EXPORT_SYMBOL_GPL(xen_start_info); |
189 |
+diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c |
190 |
+index 0ccccb6..5f76c0a 100644 |
191 |
+--- a/arch/x86/xen/mmu.c |
192 |
++++ b/arch/x86/xen/mmu.c |
193 |
+@@ -1626,15 +1626,19 @@ static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) |
194 |
+ void __init xen_setup_machphys_mapping(void) |
195 |
+ { |
196 |
+ struct xen_machphys_mapping mapping; |
197 |
+- unsigned long machine_to_phys_nr_ents; |
198 |
+ |
199 |
+ if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) { |
200 |
+ machine_to_phys_mapping = (unsigned long *)mapping.v_start; |
201 |
+- machine_to_phys_nr_ents = mapping.max_mfn + 1; |
202 |
++ machine_to_phys_nr = mapping.max_mfn + 1; |
203 |
+ } else { |
204 |
+- machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES; |
205 |
++ machine_to_phys_nr = MACH2PHYS_NR_ENTRIES; |
206 |
+ } |
207 |
+- machine_to_phys_order = fls(machine_to_phys_nr_ents - 1); |
208 |
++#ifdef CONFIG_X86_32 |
209 |
++ if ((machine_to_phys_mapping + machine_to_phys_nr) |
210 |
++ < machine_to_phys_mapping) |
211 |
++ machine_to_phys_nr = (unsigned long *)NULL |
212 |
++ - machine_to_phys_mapping; |
213 |
++#endif |
214 |
+ } |
215 |
+ |
216 |
+ #ifdef CONFIG_X86_64 |
217 |
+diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c |
218 |
+index b4533a8..e79dbb9 100644 |
219 |
+--- a/arch/x86/xen/smp.c |
220 |
++++ b/arch/x86/xen/smp.c |
221 |
+@@ -521,8 +521,6 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) |
222 |
+ native_smp_prepare_cpus(max_cpus); |
223 |
+ WARN_ON(xen_smp_intr_init(0)); |
224 |
+ |
225 |
+- if (!xen_have_vector_callback) |
226 |
+- return; |
227 |
+ xen_init_lock_cpu(0); |
228 |
+ xen_init_spinlocks(); |
229 |
+ } |
230 |
+@@ -546,6 +544,8 @@ static void xen_hvm_cpu_die(unsigned int cpu) |
231 |
+ |
232 |
+ void __init xen_hvm_smp_init(void) |
233 |
+ { |
234 |
++ if (!xen_have_vector_callback) |
235 |
++ return; |
236 |
+ smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; |
237 |
+ smp_ops.smp_send_reschedule = xen_smp_send_reschedule; |
238 |
+ smp_ops.cpu_up = xen_hvm_cpu_up; |
239 |
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c |
240 |
+index 76c8da7..2ebacf0 100644 |
241 |
+--- a/drivers/block/loop.c |
242 |
++++ b/drivers/block/loop.c |
243 |
+@@ -750,10 +750,10 @@ static ssize_t loop_attr_backing_file_show(struct loop_device *lo, char *buf) |
244 |
+ ssize_t ret; |
245 |
+ char *p = NULL; |
246 |
+ |
247 |
+- mutex_lock(&lo->lo_ctl_mutex); |
248 |
++ spin_lock_irq(&lo->lo_lock); |
249 |
+ if (lo->lo_backing_file) |
250 |
+ p = d_path(&lo->lo_backing_file->f_path, buf, PAGE_SIZE - 1); |
251 |
+- mutex_unlock(&lo->lo_ctl_mutex); |
252 |
++ spin_unlock_irq(&lo->lo_lock); |
253 |
+ |
254 |
+ if (IS_ERR_OR_NULL(p)) |
255 |
+ ret = PTR_ERR(p); |
256 |
+@@ -1007,7 +1007,9 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) |
257 |
+ |
258 |
+ kthread_stop(lo->lo_thread); |
259 |
+ |
260 |
++ spin_lock_irq(&lo->lo_lock); |
261 |
+ lo->lo_backing_file = NULL; |
262 |
++ spin_unlock_irq(&lo->lo_lock); |
263 |
+ |
264 |
+ loop_release_xfer(lo); |
265 |
+ lo->transfer = NULL; |
266 |
+diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c |
267 |
+index b536a9c..9ea8c25 100644 |
268 |
+--- a/drivers/block/xen-blkfront.c |
269 |
++++ b/drivers/block/xen-blkfront.c |
270 |
+@@ -123,8 +123,8 @@ static DEFINE_SPINLOCK(minor_lock); |
271 |
+ #define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED)) |
272 |
+ #define EMULATED_HD_DISK_MINOR_OFFSET (0) |
273 |
+ #define EMULATED_HD_DISK_NAME_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET / 256) |
274 |
+-#define EMULATED_SD_DISK_MINOR_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET + (4 * 16)) |
275 |
+-#define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_HD_DISK_NAME_OFFSET + 4) |
276 |
++#define EMULATED_SD_DISK_MINOR_OFFSET (0) |
277 |
++#define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_SD_DISK_MINOR_OFFSET / 256) |
278 |
+ |
279 |
+ #define DEV_NAME "xvd" /* name in /dev */ |
280 |
+ |
281 |
+@@ -529,7 +529,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, |
282 |
+ minor = BLKIF_MINOR_EXT(info->vdevice); |
283 |
+ nr_parts = PARTS_PER_EXT_DISK; |
284 |
+ offset = minor / nr_parts; |
285 |
+- if (xen_hvm_domain() && offset <= EMULATED_HD_DISK_NAME_OFFSET + 4) |
286 |
++ if (xen_hvm_domain() && offset < EMULATED_HD_DISK_NAME_OFFSET + 4) |
287 |
+ printk(KERN_WARNING "blkfront: vdevice 0x%x might conflict with " |
288 |
+ "emulated IDE disks,\n\t choose an xvd device name" |
289 |
+ "from xvde on\n", info->vdevice); |
290 |
+diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c |
291 |
+index 04f1e7c..f6cf448 100644 |
292 |
+--- a/drivers/edac/i7core_edac.c |
293 |
++++ b/drivers/edac/i7core_edac.c |
294 |
+@@ -1670,7 +1670,7 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, |
295 |
+ char *type, *optype, *err, *msg; |
296 |
+ unsigned long error = m->status & 0x1ff0000l; |
297 |
+ u32 optypenum = (m->status >> 4) & 0x07; |
298 |
+- u32 core_err_cnt = (m->status >> 38) && 0x7fff; |
299 |
++ u32 core_err_cnt = (m->status >> 38) & 0x7fff; |
300 |
+ u32 dimm = (m->misc >> 16) & 0x3; |
301 |
+ u32 channel = (m->misc >> 18) & 0x3; |
302 |
+ u32 syndrome = m->misc >> 32; |
303 |
+diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c |
304 |
+index 6ab6c41..d1b36f8 100644 |
305 |
+--- a/drivers/gpu/drm/radeon/radeon_connectors.c |
306 |
++++ b/drivers/gpu/drm/radeon/radeon_connectors.c |
307 |
+@@ -466,6 +466,16 @@ static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, |
308 |
+ (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
309 |
+ return true; |
310 |
+ } |
311 |
++ /* TOSHIBA Satellite L300D with ATI Mobility Radeon x1100 |
312 |
++ * (RS690M) sends data to i2c bus for a HDMI connector that |
313 |
++ * is not implemented */ |
314 |
++ if ((dev->pdev->device == 0x791f) && |
315 |
++ (dev->pdev->subsystem_vendor == 0x1179) && |
316 |
++ (dev->pdev->subsystem_device == 0xff68)) { |
317 |
++ if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && |
318 |
++ (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
319 |
++ return true; |
320 |
++ } |
321 |
+ |
322 |
+ /* Default: no EDID header probe required for DDC probing */ |
323 |
+ return false; |
324 |
+diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c |
325 |
+index 2e618b5..b7f0726 100644 |
326 |
+--- a/drivers/gpu/drm/ttm/ttm_bo.c |
327 |
++++ b/drivers/gpu/drm/ttm/ttm_bo.c |
328 |
+@@ -353,8 +353,10 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc) |
329 |
+ |
330 |
+ ret = ttm_tt_set_user(bo->ttm, current, |
331 |
+ bo->buffer_start, bo->num_pages); |
332 |
+- if (unlikely(ret != 0)) |
333 |
++ if (unlikely(ret != 0)) { |
334 |
+ ttm_tt_destroy(bo->ttm); |
335 |
++ bo->ttm = NULL; |
336 |
++ } |
337 |
+ break; |
338 |
+ default: |
339 |
+ printk(KERN_ERR TTM_PFX "Illegal buffer object type\n"); |
340 |
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c |
341 |
+index 58d5436..6d3de08 100644 |
342 |
+--- a/drivers/mmc/host/sdhci.c |
343 |
++++ b/drivers/mmc/host/sdhci.c |
344 |
+@@ -1863,9 +1863,6 @@ static void sdhci_tasklet_finish(unsigned long param) |
345 |
+ |
346 |
+ del_timer(&host->timer); |
347 |
+ |
348 |
+- if (host->version >= SDHCI_SPEC_300) |
349 |
+- del_timer(&host->tuning_timer); |
350 |
+- |
351 |
+ mrq = host->mrq; |
352 |
+ |
353 |
+ /* |
354 |
+diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c |
355 |
+index 0f563c8..493e331 100644 |
356 |
+--- a/drivers/net/igb/e1000_82575.c |
357 |
++++ b/drivers/net/igb/e1000_82575.c |
358 |
+@@ -1735,6 +1735,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) |
359 |
+ ctrl |= E1000_CTRL_RST; |
360 |
+ |
361 |
+ wr32(E1000_CTRL, ctrl); |
362 |
++ wrfl(); |
363 |
+ |
364 |
+ /* Add delay to insure DEV_RST has time to complete */ |
365 |
+ if (global_device_reset) |
366 |
+diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c |
367 |
+index 8f90f62..241a099 100644 |
368 |
+--- a/drivers/net/wireless/rt2x00/rt2x00usb.c |
369 |
++++ b/drivers/net/wireless/rt2x00/rt2x00usb.c |
370 |
+@@ -262,23 +262,20 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) |
371 |
+ struct queue_entry *entry = (struct queue_entry *)urb->context; |
372 |
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
373 |
+ |
374 |
+- if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
375 |
++ if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
376 |
+ return; |
377 |
+- |
378 |
+- if (rt2x00dev->ops->lib->tx_dma_done) |
379 |
+- rt2x00dev->ops->lib->tx_dma_done(entry); |
380 |
+- |
381 |
+- /* |
382 |
+- * Report the frame as DMA done |
383 |
+- */ |
384 |
+- rt2x00lib_dmadone(entry); |
385 |
+- |
386 |
+ /* |
387 |
+ * Check if the frame was correctly uploaded |
388 |
+ */ |
389 |
+ if (urb->status) |
390 |
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
391 |
++ /* |
392 |
++ * Report the frame as DMA done |
393 |
++ */ |
394 |
++ rt2x00lib_dmadone(entry); |
395 |
+ |
396 |
++ if (rt2x00dev->ops->lib->tx_dma_done) |
397 |
++ rt2x00dev->ops->lib->tx_dma_done(entry); |
398 |
+ /* |
399 |
+ * Schedule the delayed work for reading the TX status |
400 |
+ * from the device. |
401 |
+diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c |
402 |
+index 54b8c28..720d885 100644 |
403 |
+--- a/fs/befs/linuxvfs.c |
404 |
++++ b/fs/befs/linuxvfs.c |
405 |
+@@ -474,17 +474,22 @@ befs_follow_link(struct dentry *dentry, struct nameidata *nd) |
406 |
+ befs_data_stream *data = &befs_ino->i_data.ds; |
407 |
+ befs_off_t len = data->size; |
408 |
+ |
409 |
+- befs_debug(sb, "Follow long symlink"); |
410 |
+- |
411 |
+- link = kmalloc(len, GFP_NOFS); |
412 |
+- if (!link) { |
413 |
+- link = ERR_PTR(-ENOMEM); |
414 |
+- } else if (befs_read_lsymlink(sb, data, link, len) != len) { |
415 |
+- kfree(link); |
416 |
+- befs_error(sb, "Failed to read entire long symlink"); |
417 |
++ if (len == 0) { |
418 |
++ befs_error(sb, "Long symlink with illegal length"); |
419 |
+ link = ERR_PTR(-EIO); |
420 |
+ } else { |
421 |
+- link[len - 1] = '\0'; |
422 |
++ befs_debug(sb, "Follow long symlink"); |
423 |
++ |
424 |
++ link = kmalloc(len, GFP_NOFS); |
425 |
++ if (!link) { |
426 |
++ link = ERR_PTR(-ENOMEM); |
427 |
++ } else if (befs_read_lsymlink(sb, data, link, len) != len) { |
428 |
++ kfree(link); |
429 |
++ befs_error(sb, "Failed to read entire long symlink"); |
430 |
++ link = ERR_PTR(-EIO); |
431 |
++ } else { |
432 |
++ link[len - 1] = '\0'; |
433 |
++ } |
434 |
+ } |
435 |
+ } else { |
436 |
+ link = befs_ino->i_data.symlink; |
437 |
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c |
438 |
+index 71cd456..7e20a65 100644 |
439 |
+--- a/fs/btrfs/extent-tree.c |
440 |
++++ b/fs/btrfs/extent-tree.c |
441 |
+@@ -1784,6 +1784,9 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, |
442 |
+ |
443 |
+ |
444 |
+ for (i = 0; i < multi->num_stripes; i++, stripe++) { |
445 |
++ if (!stripe->dev->can_discard) |
446 |
++ continue; |
447 |
++ |
448 |
+ ret = btrfs_issue_discard(stripe->dev->bdev, |
449 |
+ stripe->physical, |
450 |
+ stripe->length); |
451 |
+@@ -1791,11 +1794,16 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, |
452 |
+ discarded_bytes += stripe->length; |
453 |
+ else if (ret != -EOPNOTSUPP) |
454 |
+ break; |
455 |
++ |
456 |
++ /* |
457 |
++ * Just in case we get back EOPNOTSUPP for some reason, |
458 |
++ * just ignore the return value so we don't screw up |
459 |
++ * people calling discard_extent. |
460 |
++ */ |
461 |
++ ret = 0; |
462 |
+ } |
463 |
+ kfree(multi); |
464 |
+ } |
465 |
+- if (discarded_bytes && ret == -EOPNOTSUPP) |
466 |
+- ret = 0; |
467 |
+ |
468 |
+ if (actual_bytes) |
469 |
+ *actual_bytes = discarded_bytes; |
470 |
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c |
471 |
+index 4ce8a9f..7fa128d 100644 |
472 |
+--- a/fs/btrfs/tree-log.c |
473 |
++++ b/fs/btrfs/tree-log.c |
474 |
+@@ -799,14 +799,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, |
475 |
+ struct extent_buffer *eb, int slot, |
476 |
+ struct btrfs_key *key) |
477 |
+ { |
478 |
+- struct inode *dir; |
479 |
+- int ret; |
480 |
+ struct btrfs_inode_ref *ref; |
481 |
++ struct btrfs_dir_item *di; |
482 |
++ struct inode *dir; |
483 |
+ struct inode *inode; |
484 |
+- char *name; |
485 |
+- int namelen; |
486 |
+ unsigned long ref_ptr; |
487 |
+ unsigned long ref_end; |
488 |
++ char *name; |
489 |
++ int namelen; |
490 |
++ int ret; |
491 |
+ int search_done = 0; |
492 |
+ |
493 |
+ /* |
494 |
+@@ -909,6 +910,25 @@ again: |
495 |
+ } |
496 |
+ btrfs_release_path(path); |
497 |
+ |
498 |
++ /* look for a conflicting sequence number */ |
499 |
++ di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir), |
500 |
++ btrfs_inode_ref_index(eb, ref), |
501 |
++ name, namelen, 0); |
502 |
++ if (di && !IS_ERR(di)) { |
503 |
++ ret = drop_one_dir_item(trans, root, path, dir, di); |
504 |
++ BUG_ON(ret); |
505 |
++ } |
506 |
++ btrfs_release_path(path); |
507 |
++ |
508 |
++ /* look for a conflicing name */ |
509 |
++ di = btrfs_lookup_dir_item(trans, root, path, btrfs_ino(dir), |
510 |
++ name, namelen, 0); |
511 |
++ if (di && !IS_ERR(di)) { |
512 |
++ ret = drop_one_dir_item(trans, root, path, dir, di); |
513 |
++ BUG_ON(ret); |
514 |
++ } |
515 |
++ btrfs_release_path(path); |
516 |
++ |
517 |
+ insert: |
518 |
+ /* insert our name */ |
519 |
+ ret = btrfs_add_link(trans, dir, inode, name, namelen, 0, |
520 |
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c |
521 |
+index 19450bc..43baaf0 100644 |
522 |
+--- a/fs/btrfs/volumes.c |
523 |
++++ b/fs/btrfs/volumes.c |
524 |
+@@ -500,6 +500,9 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) |
525 |
+ fs_devices->rw_devices--; |
526 |
+ } |
527 |
+ |
528 |
++ if (device->can_discard) |
529 |
++ fs_devices->num_can_discard--; |
530 |
++ |
531 |
+ new_device = kmalloc(sizeof(*new_device), GFP_NOFS); |
532 |
+ BUG_ON(!new_device); |
533 |
+ memcpy(new_device, device, sizeof(*new_device)); |
534 |
+@@ -508,6 +511,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) |
535 |
+ new_device->bdev = NULL; |
536 |
+ new_device->writeable = 0; |
537 |
+ new_device->in_fs_metadata = 0; |
538 |
++ new_device->can_discard = 0; |
539 |
+ list_replace_rcu(&device->dev_list, &new_device->dev_list); |
540 |
+ |
541 |
+ call_rcu(&device->rcu, free_device); |
542 |
+@@ -547,6 +551,7 @@ int btrfs_close_devices(struct btrfs_fs_devices *fs_devices) |
543 |
+ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, |
544 |
+ fmode_t flags, void *holder) |
545 |
+ { |
546 |
++ struct request_queue *q; |
547 |
+ struct block_device *bdev; |
548 |
+ struct list_head *head = &fs_devices->devices; |
549 |
+ struct btrfs_device *device; |
550 |
+@@ -603,6 +608,12 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, |
551 |
+ seeding = 0; |
552 |
+ } |
553 |
+ |
554 |
++ q = bdev_get_queue(bdev); |
555 |
++ if (blk_queue_discard(q)) { |
556 |
++ device->can_discard = 1; |
557 |
++ fs_devices->num_can_discard++; |
558 |
++ } |
559 |
++ |
560 |
+ device->bdev = bdev; |
561 |
+ device->in_fs_metadata = 0; |
562 |
+ device->mode = flags; |
563 |
+@@ -1542,6 +1553,7 @@ error: |
564 |
+ |
565 |
+ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) |
566 |
+ { |
567 |
++ struct request_queue *q; |
568 |
+ struct btrfs_trans_handle *trans; |
569 |
+ struct btrfs_device *device; |
570 |
+ struct block_device *bdev; |
571 |
+@@ -1611,6 +1623,9 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) |
572 |
+ |
573 |
+ lock_chunks(root); |
574 |
+ |
575 |
++ q = bdev_get_queue(bdev); |
576 |
++ if (blk_queue_discard(q)) |
577 |
++ device->can_discard = 1; |
578 |
+ device->writeable = 1; |
579 |
+ device->work.func = pending_bios_fn; |
580 |
+ generate_random_uuid(device->uuid); |
581 |
+@@ -1646,6 +1661,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) |
582 |
+ root->fs_info->fs_devices->num_devices++; |
583 |
+ root->fs_info->fs_devices->open_devices++; |
584 |
+ root->fs_info->fs_devices->rw_devices++; |
585 |
++ if (device->can_discard) |
586 |
++ root->fs_info->fs_devices->num_can_discard++; |
587 |
+ root->fs_info->fs_devices->total_rw_bytes += device->total_bytes; |
588 |
+ |
589 |
+ if (!blk_queue_nonrot(bdev_get_queue(bdev))) |
590 |
+diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h |
591 |
+index 7c12d61..6d866db 100644 |
592 |
+--- a/fs/btrfs/volumes.h |
593 |
++++ b/fs/btrfs/volumes.h |
594 |
+@@ -48,6 +48,7 @@ struct btrfs_device { |
595 |
+ int writeable; |
596 |
+ int in_fs_metadata; |
597 |
+ int missing; |
598 |
++ int can_discard; |
599 |
+ |
600 |
+ spinlock_t io_lock; |
601 |
+ |
602 |
+@@ -104,6 +105,7 @@ struct btrfs_fs_devices { |
603 |
+ u64 rw_devices; |
604 |
+ u64 missing_devices; |
605 |
+ u64 total_rw_bytes; |
606 |
++ u64 num_can_discard; |
607 |
+ struct block_device *latest_bdev; |
608 |
+ |
609 |
+ /* all of the devices in the FS, protected by a mutex |
610 |
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c |
611 |
+index ccc1afa..e0ea721 100644 |
612 |
+--- a/fs/cifs/connect.c |
613 |
++++ b/fs/cifs/connect.c |
614 |
+@@ -2838,7 +2838,8 @@ cleanup_volume_info_contents(struct smb_vol *volume_info) |
615 |
+ kfree(volume_info->username); |
616 |
+ kzfree(volume_info->password); |
617 |
+ kfree(volume_info->UNC); |
618 |
+- kfree(volume_info->UNCip); |
619 |
++ if (volume_info->UNCip != volume_info->UNC + 2) |
620 |
++ kfree(volume_info->UNCip); |
621 |
+ kfree(volume_info->domainname); |
622 |
+ kfree(volume_info->iocharset); |
623 |
+ kfree(volume_info->prepath); |
624 |
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c |
625 |
+index d8d26f3..16cdd6d 100644 |
626 |
+--- a/fs/cifs/dir.c |
627 |
++++ b/fs/cifs/dir.c |
628 |
+@@ -110,8 +110,8 @@ cifs_bp_rename_retry: |
629 |
+ } |
630 |
+ rcu_read_unlock(); |
631 |
+ if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) { |
632 |
+- cERROR(1, "did not end path lookup where expected namelen is %d", |
633 |
+- namelen); |
634 |
++ cFYI(1, "did not end path lookup where expected. namelen=%d " |
635 |
++ "dfsplen=%d", namelen, dfsplen); |
636 |
+ /* presumably this is only possible if racing with a rename |
637 |
+ of one of the parent directories (we can not lock the dentries |
638 |
+ above us to prevent this, but retrying should be harmless) */ |
639 |
+diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h |
640 |
+index bb85757..5802fa1 100644 |
641 |
+--- a/fs/ext4/ext4_jbd2.h |
642 |
++++ b/fs/ext4/ext4_jbd2.h |
643 |
+@@ -289,10 +289,10 @@ static inline int ext4_should_order_data(struct inode *inode) |
644 |
+ |
645 |
+ static inline int ext4_should_writeback_data(struct inode *inode) |
646 |
+ { |
647 |
+- if (!S_ISREG(inode->i_mode)) |
648 |
+- return 0; |
649 |
+ if (EXT4_JOURNAL(inode) == NULL) |
650 |
+ return 1; |
651 |
++ if (!S_ISREG(inode->i_mode)) |
652 |
++ return 0; |
653 |
+ if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) |
654 |
+ return 0; |
655 |
+ if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) |
656 |
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c |
657 |
+index e3126c0..b864839 100644 |
658 |
+--- a/fs/ext4/inode.c |
659 |
++++ b/fs/ext4/inode.c |
660 |
+@@ -189,6 +189,12 @@ void ext4_evict_inode(struct inode *inode) |
661 |
+ int err; |
662 |
+ |
663 |
+ trace_ext4_evict_inode(inode); |
664 |
++ |
665 |
++ mutex_lock(&inode->i_mutex); |
666 |
++ ext4_flush_completed_IO(inode); |
667 |
++ mutex_unlock(&inode->i_mutex); |
668 |
++ ext4_ioend_wait(inode); |
669 |
++ |
670 |
+ if (inode->i_nlink) { |
671 |
+ truncate_inode_pages(&inode->i_data, 0); |
672 |
+ goto no_delete; |
673 |
+@@ -1849,6 +1855,8 @@ static int ext4_journalled_write_end(struct file *file, |
674 |
+ from = pos & (PAGE_CACHE_SIZE - 1); |
675 |
+ to = from + len; |
676 |
+ |
677 |
++ BUG_ON(!ext4_handle_valid(handle)); |
678 |
++ |
679 |
+ if (copied < len) { |
680 |
+ if (!PageUptodate(page)) |
681 |
+ copied = 0; |
682 |
+@@ -2148,7 +2156,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, |
683 |
+ else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT)) |
684 |
+ err = ext4_bio_write_page(&io_submit, page, |
685 |
+ len, mpd->wbc); |
686 |
+- else |
687 |
++ else if (buffer_uninit(page_bufs)) { |
688 |
++ ext4_set_bh_endio(page_bufs, inode); |
689 |
++ err = block_write_full_page_endio(page, |
690 |
++ noalloc_get_block_write, |
691 |
++ mpd->wbc, ext4_end_io_buffer_write); |
692 |
++ } else |
693 |
+ err = block_write_full_page(page, |
694 |
+ noalloc_get_block_write, mpd->wbc); |
695 |
+ |
696 |
+@@ -2564,6 +2577,8 @@ static int __ext4_journalled_writepage(struct page *page, |
697 |
+ goto out; |
698 |
+ } |
699 |
+ |
700 |
++ BUG_ON(!ext4_handle_valid(handle)); |
701 |
++ |
702 |
+ ret = walk_page_buffers(handle, page_bufs, 0, len, NULL, |
703 |
+ do_journal_get_write_access); |
704 |
+ |
705 |
+@@ -3635,8 +3650,15 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate) |
706 |
+ goto out; |
707 |
+ } |
708 |
+ |
709 |
+- io_end->flag = EXT4_IO_END_UNWRITTEN; |
710 |
++ /* |
711 |
++ * It may be over-defensive here to check EXT4_IO_END_UNWRITTEN now, |
712 |
++ * but being more careful is always safe for the future change. |
713 |
++ */ |
714 |
+ inode = io_end->inode; |
715 |
++ if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) { |
716 |
++ io_end->flag |= EXT4_IO_END_UNWRITTEN; |
717 |
++ atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten); |
718 |
++ } |
719 |
+ |
720 |
+ /* Add the io_end to per-inode completed io list*/ |
721 |
+ spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags); |
722 |
+diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c |
723 |
+index 7bb8f76..97e5e98 100644 |
724 |
+--- a/fs/ext4/page-io.c |
725 |
++++ b/fs/ext4/page-io.c |
726 |
+@@ -338,8 +338,10 @@ submit_and_retry: |
727 |
+ if ((io_end->num_io_pages >= MAX_IO_PAGES) && |
728 |
+ (io_end->pages[io_end->num_io_pages-1] != io_page)) |
729 |
+ goto submit_and_retry; |
730 |
+- if (buffer_uninit(bh)) |
731 |
+- io->io_end->flag |= EXT4_IO_END_UNWRITTEN; |
732 |
++ if (buffer_uninit(bh) && !(io_end->flag & EXT4_IO_END_UNWRITTEN)) { |
733 |
++ io_end->flag |= EXT4_IO_END_UNWRITTEN; |
734 |
++ atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten); |
735 |
++ } |
736 |
+ io->io_end->size += bh->b_size; |
737 |
+ io->io_next_block++; |
738 |
+ ret = bio_add_page(io->io_bio, bh->b_page, bh->b_size, bh_offset(bh)); |
739 |
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c |
740 |
+index 9ea71aa..111ed9d 100644 |
741 |
+--- a/fs/ext4/super.c |
742 |
++++ b/fs/ext4/super.c |
743 |
+@@ -892,7 +892,6 @@ static void ext4_i_callback(struct rcu_head *head) |
744 |
+ |
745 |
+ static void ext4_destroy_inode(struct inode *inode) |
746 |
+ { |
747 |
+- ext4_ioend_wait(inode); |
748 |
+ if (!list_empty(&(EXT4_I(inode)->i_orphan))) { |
749 |
+ ext4_msg(inode->i_sb, KERN_ERR, |
750 |
+ "Inode %lu (%p): orphan list check failed!", |
751 |
+diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c |
752 |
+index 640fc22..168a80f 100644 |
753 |
+--- a/fs/fuse/dev.c |
754 |
++++ b/fs/fuse/dev.c |
755 |
+@@ -1358,6 +1358,10 @@ static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, |
756 |
+ if (outarg.namelen > FUSE_NAME_MAX) |
757 |
+ goto err; |
758 |
+ |
759 |
++ err = -EINVAL; |
760 |
++ if (size != sizeof(outarg) + outarg.namelen + 1) |
761 |
++ goto err; |
762 |
++ |
763 |
+ name.name = buf; |
764 |
+ name.len = outarg.namelen; |
765 |
+ err = fuse_copy_one(cs, buf, outarg.namelen + 1); |
766 |
+diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h |
767 |
+index b257383..07df5f1 100644 |
768 |
+--- a/fs/nfs/callback.h |
769 |
++++ b/fs/nfs/callback.h |
770 |
+@@ -38,6 +38,7 @@ enum nfs4_callback_opnum { |
771 |
+ struct cb_process_state { |
772 |
+ __be32 drc_status; |
773 |
+ struct nfs_client *clp; |
774 |
++ int slotid; |
775 |
+ }; |
776 |
+ |
777 |
+ struct cb_compound_hdr_arg { |
778 |
+@@ -166,7 +167,6 @@ extern unsigned nfs4_callback_layoutrecall( |
779 |
+ void *dummy, struct cb_process_state *cps); |
780 |
+ |
781 |
+ extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses); |
782 |
+-extern void nfs4_cb_take_slot(struct nfs_client *clp); |
783 |
+ |
784 |
+ struct cb_devicenotifyitem { |
785 |
+ uint32_t cbd_notify_type; |
786 |
+diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c |
787 |
+index d4d1954..aaa09e9 100644 |
788 |
+--- a/fs/nfs/callback_proc.c |
789 |
++++ b/fs/nfs/callback_proc.c |
790 |
+@@ -333,7 +333,7 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) |
791 |
+ /* Normal */ |
792 |
+ if (likely(args->csa_sequenceid == slot->seq_nr + 1)) { |
793 |
+ slot->seq_nr++; |
794 |
+- return htonl(NFS4_OK); |
795 |
++ goto out_ok; |
796 |
+ } |
797 |
+ |
798 |
+ /* Replay */ |
799 |
+@@ -352,11 +352,14 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) |
800 |
+ /* Wraparound */ |
801 |
+ if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) { |
802 |
+ slot->seq_nr = 1; |
803 |
+- return htonl(NFS4_OK); |
804 |
++ goto out_ok; |
805 |
+ } |
806 |
+ |
807 |
+ /* Misordered request */ |
808 |
+ return htonl(NFS4ERR_SEQ_MISORDERED); |
809 |
++out_ok: |
810 |
++ tbl->highest_used_slotid = args->csa_slotid; |
811 |
++ return htonl(NFS4_OK); |
812 |
+ } |
813 |
+ |
814 |
+ /* |
815 |
+@@ -418,26 +421,37 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, |
816 |
+ struct cb_sequenceres *res, |
817 |
+ struct cb_process_state *cps) |
818 |
+ { |
819 |
++ struct nfs4_slot_table *tbl; |
820 |
+ struct nfs_client *clp; |
821 |
+ int i; |
822 |
+ __be32 status = htonl(NFS4ERR_BADSESSION); |
823 |
+ |
824 |
+- cps->clp = NULL; |
825 |
+- |
826 |
+ clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid); |
827 |
+ if (clp == NULL) |
828 |
+ goto out; |
829 |
+ |
830 |
++ tbl = &clp->cl_session->bc_slot_table; |
831 |
++ |
832 |
++ spin_lock(&tbl->slot_tbl_lock); |
833 |
+ /* state manager is resetting the session */ |
834 |
+ if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) { |
835 |
+- status = NFS4ERR_DELAY; |
836 |
++ spin_unlock(&tbl->slot_tbl_lock); |
837 |
++ status = htonl(NFS4ERR_DELAY); |
838 |
++ /* Return NFS4ERR_BADSESSION if we're draining the session |
839 |
++ * in order to reset it. |
840 |
++ */ |
841 |
++ if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)) |
842 |
++ status = htonl(NFS4ERR_BADSESSION); |
843 |
+ goto out; |
844 |
+ } |
845 |
+ |
846 |
+ status = validate_seqid(&clp->cl_session->bc_slot_table, args); |
847 |
++ spin_unlock(&tbl->slot_tbl_lock); |
848 |
+ if (status) |
849 |
+ goto out; |
850 |
+ |
851 |
++ cps->slotid = args->csa_slotid; |
852 |
++ |
853 |
+ /* |
854 |
+ * Check for pending referring calls. If a match is found, a |
855 |
+ * related callback was received before the response to the original |
856 |
+@@ -454,7 +468,6 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, |
857 |
+ res->csr_slotid = args->csa_slotid; |
858 |
+ res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; |
859 |
+ res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; |
860 |
+- nfs4_cb_take_slot(clp); |
861 |
+ |
862 |
+ out: |
863 |
+ cps->clp = clp; /* put in nfs4_callback_compound */ |
864 |
+diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c |
865 |
+index c6c86a7..918ad64 100644 |
866 |
+--- a/fs/nfs/callback_xdr.c |
867 |
++++ b/fs/nfs/callback_xdr.c |
868 |
+@@ -754,26 +754,15 @@ static void nfs4_callback_free_slot(struct nfs4_session *session) |
869 |
+ * Let the state manager know callback processing done. |
870 |
+ * A single slot, so highest used slotid is either 0 or -1 |
871 |
+ */ |
872 |
+- tbl->highest_used_slotid--; |
873 |
++ tbl->highest_used_slotid = -1; |
874 |
+ nfs4_check_drain_bc_complete(session); |
875 |
+ spin_unlock(&tbl->slot_tbl_lock); |
876 |
+ } |
877 |
+ |
878 |
+-static void nfs4_cb_free_slot(struct nfs_client *clp) |
879 |
++static void nfs4_cb_free_slot(struct cb_process_state *cps) |
880 |
+ { |
881 |
+- if (clp && clp->cl_session) |
882 |
+- nfs4_callback_free_slot(clp->cl_session); |
883 |
+-} |
884 |
+- |
885 |
+-/* A single slot, so highest used slotid is either 0 or -1 */ |
886 |
+-void nfs4_cb_take_slot(struct nfs_client *clp) |
887 |
+-{ |
888 |
+- struct nfs4_slot_table *tbl = &clp->cl_session->bc_slot_table; |
889 |
+- |
890 |
+- spin_lock(&tbl->slot_tbl_lock); |
891 |
+- tbl->highest_used_slotid++; |
892 |
+- BUG_ON(tbl->highest_used_slotid != 0); |
893 |
+- spin_unlock(&tbl->slot_tbl_lock); |
894 |
++ if (cps->slotid != -1) |
895 |
++ nfs4_callback_free_slot(cps->clp->cl_session); |
896 |
+ } |
897 |
+ |
898 |
+ #else /* CONFIG_NFS_V4_1 */ |
899 |
+@@ -784,7 +773,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) |
900 |
+ return htonl(NFS4ERR_MINOR_VERS_MISMATCH); |
901 |
+ } |
902 |
+ |
903 |
+-static void nfs4_cb_free_slot(struct nfs_client *clp) |
904 |
++static void nfs4_cb_free_slot(struct cb_process_state *cps) |
905 |
+ { |
906 |
+ } |
907 |
+ #endif /* CONFIG_NFS_V4_1 */ |
908 |
+@@ -866,6 +855,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r |
909 |
+ struct cb_process_state cps = { |
910 |
+ .drc_status = 0, |
911 |
+ .clp = NULL, |
912 |
++ .slotid = -1, |
913 |
+ }; |
914 |
+ unsigned int nops = 0; |
915 |
+ |
916 |
+@@ -906,7 +896,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r |
917 |
+ |
918 |
+ *hdr_res.status = status; |
919 |
+ *hdr_res.nops = htonl(nops); |
920 |
+- nfs4_cb_free_slot(cps.clp); |
921 |
++ nfs4_cb_free_slot(&cps); |
922 |
+ nfs_put_client(cps.clp); |
923 |
+ dprintk("%s: done, status = %u\n", __func__, ntohl(status)); |
924 |
+ return rpc_success; |
925 |
+diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c |
926 |
+index 8ff2ea3..1d1dc1e 100644 |
927 |
+--- a/fs/nfs/objlayout/objio_osd.c |
928 |
++++ b/fs/nfs/objlayout/objio_osd.c |
929 |
+@@ -479,7 +479,6 @@ static int _io_check(struct objio_state *ios, bool is_write) |
930 |
+ for (i = 0; i < ios->numdevs; i++) { |
931 |
+ struct osd_sense_info osi; |
932 |
+ struct osd_request *or = ios->per_dev[i].or; |
933 |
+- unsigned dev; |
934 |
+ int ret; |
935 |
+ |
936 |
+ if (!or) |
937 |
+@@ -500,9 +499,8 @@ static int _io_check(struct objio_state *ios, bool is_write) |
938 |
+ |
939 |
+ continue; /* we recovered */ |
940 |
+ } |
941 |
+- dev = ios->per_dev[i].dev; |
942 |
+- objlayout_io_set_result(&ios->ol_state, dev, |
943 |
+- &ios->layout->comps[dev].oc_object_id, |
944 |
++ objlayout_io_set_result(&ios->ol_state, i, |
945 |
++ &ios->layout->comps[i].oc_object_id, |
946 |
+ osd_pri_2_pnfs_err(osi.osd_err_pri), |
947 |
+ ios->per_dev[i].offset, |
948 |
+ ios->per_dev[i].length, |
949 |
+@@ -589,22 +587,19 @@ static void _calc_stripe_info(struct objio_state *ios, u64 file_offset, |
950 |
+ } |
951 |
+ |
952 |
+ static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg, |
953 |
+- unsigned pgbase, struct _objio_per_comp *per_dev, int cur_len, |
954 |
++ unsigned pgbase, struct _objio_per_comp *per_dev, int len, |
955 |
+ gfp_t gfp_flags) |
956 |
+ { |
957 |
+ unsigned pg = *cur_pg; |
958 |
++ int cur_len = len; |
959 |
+ struct request_queue *q = |
960 |
+ osd_request_queue(_io_od(ios, per_dev->dev)); |
961 |
+ |
962 |
+- per_dev->length += cur_len; |
963 |
+- |
964 |
+ if (per_dev->bio == NULL) { |
965 |
+- unsigned stripes = ios->layout->num_comps / |
966 |
+- ios->layout->mirrors_p1; |
967 |
+- unsigned pages_in_stripe = stripes * |
968 |
++ unsigned pages_in_stripe = ios->layout->group_width * |
969 |
+ (ios->layout->stripe_unit / PAGE_SIZE); |
970 |
+ unsigned bio_size = (ios->ol_state.nr_pages + pages_in_stripe) / |
971 |
+- stripes; |
972 |
++ ios->layout->group_width; |
973 |
+ |
974 |
+ if (BIO_MAX_PAGES_KMALLOC < bio_size) |
975 |
+ bio_size = BIO_MAX_PAGES_KMALLOC; |
976 |
+@@ -632,6 +627,7 @@ static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg, |
977 |
+ } |
978 |
+ BUG_ON(cur_len); |
979 |
+ |
980 |
++ per_dev->length += len; |
981 |
+ *cur_pg = pg; |
982 |
+ return 0; |
983 |
+ } |
984 |
+@@ -650,7 +646,7 @@ static int _prepare_one_group(struct objio_state *ios, u64 length, |
985 |
+ int ret = 0; |
986 |
+ |
987 |
+ while (length) { |
988 |
+- struct _objio_per_comp *per_dev = &ios->per_dev[dev]; |
989 |
++ struct _objio_per_comp *per_dev = &ios->per_dev[dev - first_dev]; |
990 |
+ unsigned cur_len, page_off = 0; |
991 |
+ |
992 |
+ if (!per_dev->length) { |
993 |
+@@ -670,8 +666,8 @@ static int _prepare_one_group(struct objio_state *ios, u64 length, |
994 |
+ cur_len = stripe_unit; |
995 |
+ } |
996 |
+ |
997 |
+- if (max_comp < dev) |
998 |
+- max_comp = dev; |
999 |
++ if (max_comp < dev - first_dev) |
1000 |
++ max_comp = dev - first_dev; |
1001 |
+ } else { |
1002 |
+ cur_len = stripe_unit; |
1003 |
+ } |
1004 |
+@@ -806,7 +802,7 @@ static int _read_mirrors(struct objio_state *ios, unsigned cur_comp) |
1005 |
+ struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp]; |
1006 |
+ unsigned dev = per_dev->dev; |
1007 |
+ struct pnfs_osd_object_cred *cred = |
1008 |
+- &ios->layout->comps[dev]; |
1009 |
++ &ios->layout->comps[cur_comp]; |
1010 |
+ struct osd_obj_id obj = { |
1011 |
+ .partition = cred->oc_object_id.oid_partition_id, |
1012 |
+ .id = cred->oc_object_id.oid_object_id, |
1013 |
+@@ -904,7 +900,7 @@ static int _write_mirrors(struct objio_state *ios, unsigned cur_comp) |
1014 |
+ for (; cur_comp < last_comp; ++cur_comp, ++dev) { |
1015 |
+ struct osd_request *or = NULL; |
1016 |
+ struct pnfs_osd_object_cred *cred = |
1017 |
+- &ios->layout->comps[dev]; |
1018 |
++ &ios->layout->comps[cur_comp]; |
1019 |
+ struct osd_obj_id obj = { |
1020 |
+ .partition = cred->oc_object_id.oid_partition_id, |
1021 |
+ .id = cred->oc_object_id.oid_object_id, |
1022 |
+diff --git a/fs/nfs/objlayout/pnfs_osd_xdr_cli.c b/fs/nfs/objlayout/pnfs_osd_xdr_cli.c |
1023 |
+index 16fc758..b3918f7 100644 |
1024 |
+--- a/fs/nfs/objlayout/pnfs_osd_xdr_cli.c |
1025 |
++++ b/fs/nfs/objlayout/pnfs_osd_xdr_cli.c |
1026 |
+@@ -170,6 +170,9 @@ int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout, |
1027 |
+ p = _osd_xdr_decode_data_map(p, &layout->olo_map); |
1028 |
+ layout->olo_comps_index = be32_to_cpup(p++); |
1029 |
+ layout->olo_num_comps = be32_to_cpup(p++); |
1030 |
++ dprintk("%s: olo_comps_index=%d olo_num_comps=%d\n", __func__, |
1031 |
++ layout->olo_comps_index, layout->olo_num_comps); |
1032 |
++ |
1033 |
+ iter->total_comps = layout->olo_num_comps; |
1034 |
+ return 0; |
1035 |
+ } |
1036 |
+diff --git a/include/linux/personality.h b/include/linux/personality.h |
1037 |
+index eec3bae..8fc7dd1a 100644 |
1038 |
+--- a/include/linux/personality.h |
1039 |
++++ b/include/linux/personality.h |
1040 |
+@@ -22,6 +22,7 @@ extern int __set_personality(unsigned int); |
1041 |
+ * These occupy the top three bytes. |
1042 |
+ */ |
1043 |
+ enum { |
1044 |
++ UNAME26 = 0x0020000, |
1045 |
+ ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA space */ |
1046 |
+ FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs point to descriptors |
1047 |
+ * (signal handling) |
1048 |
+diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h |
1049 |
+index 092dc9b..14d3524 100644 |
1050 |
+--- a/include/linux/stop_machine.h |
1051 |
++++ b/include/linux/stop_machine.h |
1052 |
+@@ -27,6 +27,8 @@ struct cpu_stop_work { |
1053 |
+ struct cpu_stop_done *done; |
1054 |
+ }; |
1055 |
+ |
1056 |
++extern struct mutex stop_cpus_mutex; |
1057 |
++ |
1058 |
+ int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg); |
1059 |
+ void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg, |
1060 |
+ struct cpu_stop_work *work_buf); |
1061 |
+diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c |
1062 |
+index 3a2cab4..e38544d 100644 |
1063 |
+--- a/kernel/irq/generic-chip.c |
1064 |
++++ b/kernel/irq/generic-chip.c |
1065 |
+@@ -246,7 +246,7 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, |
1066 |
+ gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask); |
1067 |
+ |
1068 |
+ for (i = gc->irq_base; msk; msk >>= 1, i++) { |
1069 |
+- if (!msk & 0x01) |
1070 |
++ if (!(msk & 0x01)) |
1071 |
+ continue; |
1072 |
+ |
1073 |
+ if (flags & IRQ_GC_INIT_NESTED_LOCK) |
1074 |
+@@ -301,7 +301,7 @@ void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, |
1075 |
+ raw_spin_unlock(&gc_lock); |
1076 |
+ |
1077 |
+ for (; msk; msk >>= 1, i++) { |
1078 |
+- if (!msk & 0x01) |
1079 |
++ if (!(msk & 0x01)) |
1080 |
+ continue; |
1081 |
+ |
1082 |
+ /* Remove handler first. That will mask the irq line */ |
1083 |
+diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c |
1084 |
+index e3516b2..0cae1cc 100644 |
1085 |
+--- a/kernel/stop_machine.c |
1086 |
++++ b/kernel/stop_machine.c |
1087 |
+@@ -132,8 +132,8 @@ void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg, |
1088 |
+ cpu_stop_queue_work(&per_cpu(cpu_stopper, cpu), work_buf); |
1089 |
+ } |
1090 |
+ |
1091 |
++DEFINE_MUTEX(stop_cpus_mutex); |
1092 |
+ /* static data for stop_cpus */ |
1093 |
+-static DEFINE_MUTEX(stop_cpus_mutex); |
1094 |
+ static DEFINE_PER_CPU(struct cpu_stop_work, stop_cpus_work); |
1095 |
+ |
1096 |
+ int __stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg) |
1097 |
+diff --git a/kernel/sys.c b/kernel/sys.c |
1098 |
+index e4128b2..5c942cf 100644 |
1099 |
+--- a/kernel/sys.c |
1100 |
++++ b/kernel/sys.c |
1101 |
+@@ -38,6 +38,8 @@ |
1102 |
+ #include <linux/fs_struct.h> |
1103 |
+ #include <linux/gfp.h> |
1104 |
+ #include <linux/syscore_ops.h> |
1105 |
++#include <linux/version.h> |
1106 |
++#include <linux/ctype.h> |
1107 |
+ |
1108 |
+ #include <linux/compat.h> |
1109 |
+ #include <linux/syscalls.h> |
1110 |
+@@ -45,6 +47,8 @@ |
1111 |
+ #include <linux/user_namespace.h> |
1112 |
+ |
1113 |
+ #include <linux/kmsg_dump.h> |
1114 |
++/* Move somewhere else to avoid recompiling? */ |
1115 |
++#include <generated/utsrelease.h> |
1116 |
+ |
1117 |
+ #include <asm/uaccess.h> |
1118 |
+ #include <asm/io.h> |
1119 |
+@@ -1124,6 +1128,34 @@ DECLARE_RWSEM(uts_sem); |
1120 |
+ #define override_architecture(name) 0 |
1121 |
+ #endif |
1122 |
+ |
1123 |
++/* |
1124 |
++ * Work around broken programs that cannot handle "Linux 3.0". |
1125 |
++ * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40 |
1126 |
++ */ |
1127 |
++static int override_release(char __user *release, int len) |
1128 |
++{ |
1129 |
++ int ret = 0; |
1130 |
++ char buf[len]; |
1131 |
++ |
1132 |
++ if (current->personality & UNAME26) { |
1133 |
++ char *rest = UTS_RELEASE; |
1134 |
++ int ndots = 0; |
1135 |
++ unsigned v; |
1136 |
++ |
1137 |
++ while (*rest) { |
1138 |
++ if (*rest == '.' && ++ndots >= 3) |
1139 |
++ break; |
1140 |
++ if (!isdigit(*rest) && *rest != '.') |
1141 |
++ break; |
1142 |
++ rest++; |
1143 |
++ } |
1144 |
++ v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40; |
1145 |
++ snprintf(buf, len, "2.6.%u%s", v, rest); |
1146 |
++ ret = copy_to_user(release, buf, len); |
1147 |
++ } |
1148 |
++ return ret; |
1149 |
++} |
1150 |
++ |
1151 |
+ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) |
1152 |
+ { |
1153 |
+ int errno = 0; |
1154 |
+@@ -1133,6 +1165,8 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) |
1155 |
+ errno = -EFAULT; |
1156 |
+ up_read(&uts_sem); |
1157 |
+ |
1158 |
++ if (!errno && override_release(name->release, sizeof(name->release))) |
1159 |
++ errno = -EFAULT; |
1160 |
+ if (!errno && override_architecture(name)) |
1161 |
+ errno = -EFAULT; |
1162 |
+ return errno; |
1163 |
+@@ -1154,6 +1188,8 @@ SYSCALL_DEFINE1(uname, struct old_utsname __user *, name) |
1164 |
+ error = -EFAULT; |
1165 |
+ up_read(&uts_sem); |
1166 |
+ |
1167 |
++ if (!error && override_release(name->release, sizeof(name->release))) |
1168 |
++ error = -EFAULT; |
1169 |
+ if (!error && override_architecture(name)) |
1170 |
+ error = -EFAULT; |
1171 |
+ return error; |
1172 |
+@@ -1188,6 +1224,8 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) |
1173 |
+ |
1174 |
+ if (!error && override_architecture(name)) |
1175 |
+ error = -EFAULT; |
1176 |
++ if (!error && override_release(name->release, sizeof(name->release))) |
1177 |
++ error = -EFAULT; |
1178 |
+ return error ? -EFAULT : 0; |
1179 |
+ } |
1180 |
+ #endif |
1181 |
+diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c |
1182 |
+index 200c9a1..a872d0a 100644 |
1183 |
+--- a/sound/pci/ac97/ac97_patch.c |
1184 |
++++ b/sound/pci/ac97/ac97_patch.c |
1185 |
+@@ -1909,6 +1909,7 @@ static unsigned int ad1981_jacks_whitelist[] = { |
1186 |
+ 0x103c0944, /* HP nc6220 */ |
1187 |
+ 0x103c0934, /* HP nc8220 */ |
1188 |
+ 0x103c006d, /* HP nx9105 */ |
1189 |
++ 0x103c300d, /* HP Compaq dc5100 SFF(PT003AW) */ |
1190 |
+ 0x17340088, /* FSC Scenic-W */ |
1191 |
+ 0 /* end */ |
1192 |
+ }; |
1193 |
+diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c |
1194 |
+index aa52b3e..2cf87f5 100644 |
1195 |
+--- a/sound/usb/caiaq/audio.c |
1196 |
++++ b/sound/usb/caiaq/audio.c |
1197 |
+@@ -139,8 +139,12 @@ static void stream_stop(struct snd_usb_caiaqdev *dev) |
1198 |
+ |
1199 |
+ for (i = 0; i < N_URBS; i++) { |
1200 |
+ usb_kill_urb(dev->data_urbs_in[i]); |
1201 |
+- usb_kill_urb(dev->data_urbs_out[i]); |
1202 |
++ |
1203 |
++ if (test_bit(i, &dev->outurb_active_mask)) |
1204 |
++ usb_kill_urb(dev->data_urbs_out[i]); |
1205 |
+ } |
1206 |
++ |
1207 |
++ dev->outurb_active_mask = 0; |
1208 |
+ } |
1209 |
+ |
1210 |
+ static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) |
1211 |
+@@ -612,8 +616,8 @@ static void read_completed(struct urb *urb) |
1212 |
+ { |
1213 |
+ struct snd_usb_caiaq_cb_info *info = urb->context; |
1214 |
+ struct snd_usb_caiaqdev *dev; |
1215 |
+- struct urb *out; |
1216 |
+- int frame, len, send_it = 0, outframe = 0; |
1217 |
++ struct urb *out = NULL; |
1218 |
++ int i, frame, len, send_it = 0, outframe = 0; |
1219 |
+ size_t offset = 0; |
1220 |
+ |
1221 |
+ if (urb->status || !info) |
1222 |
+@@ -624,7 +628,17 @@ static void read_completed(struct urb *urb) |
1223 |
+ if (!dev->streaming) |
1224 |
+ return; |
1225 |
+ |
1226 |
+- out = dev->data_urbs_out[info->index]; |
1227 |
++ /* find an unused output urb that is unused */ |
1228 |
++ for (i = 0; i < N_URBS; i++) |
1229 |
++ if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) { |
1230 |
++ out = dev->data_urbs_out[i]; |
1231 |
++ break; |
1232 |
++ } |
1233 |
++ |
1234 |
++ if (!out) { |
1235 |
++ log("Unable to find an output urb to use\n"); |
1236 |
++ goto requeue; |
1237 |
++ } |
1238 |
+ |
1239 |
+ /* read the recently received packet and send back one which has |
1240 |
+ * the same layout */ |
1241 |
+@@ -655,8 +669,12 @@ static void read_completed(struct urb *urb) |
1242 |
+ out->number_of_packets = outframe; |
1243 |
+ out->transfer_flags = URB_ISO_ASAP; |
1244 |
+ usb_submit_urb(out, GFP_ATOMIC); |
1245 |
++ } else { |
1246 |
++ struct snd_usb_caiaq_cb_info *oinfo = out->context; |
1247 |
++ clear_bit(oinfo->index, &dev->outurb_active_mask); |
1248 |
+ } |
1249 |
+ |
1250 |
++requeue: |
1251 |
+ /* re-submit inbound urb */ |
1252 |
+ for (frame = 0; frame < FRAMES_PER_URB; frame++) { |
1253 |
+ urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; |
1254 |
+@@ -678,6 +696,8 @@ static void write_completed(struct urb *urb) |
1255 |
+ dev->output_running = 1; |
1256 |
+ wake_up(&dev->prepare_wait_queue); |
1257 |
+ } |
1258 |
++ |
1259 |
++ clear_bit(info->index, &dev->outurb_active_mask); |
1260 |
+ } |
1261 |
+ |
1262 |
+ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) |
1263 |
+@@ -829,6 +849,9 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) |
1264 |
+ if (!dev->data_cb_info) |
1265 |
+ return -ENOMEM; |
1266 |
+ |
1267 |
++ dev->outurb_active_mask = 0; |
1268 |
++ BUILD_BUG_ON(N_URBS > (sizeof(dev->outurb_active_mask) * 8)); |
1269 |
++ |
1270 |
+ for (i = 0; i < N_URBS; i++) { |
1271 |
+ dev->data_cb_info[i].dev = dev; |
1272 |
+ dev->data_cb_info[i].index = i; |
1273 |
+diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h |
1274 |
+index b2b3101..3f9c633 100644 |
1275 |
+--- a/sound/usb/caiaq/device.h |
1276 |
++++ b/sound/usb/caiaq/device.h |
1277 |
+@@ -96,6 +96,7 @@ struct snd_usb_caiaqdev { |
1278 |
+ int input_panic, output_panic, warned; |
1279 |
+ char *audio_in_buf, *audio_out_buf; |
1280 |
+ unsigned int samplerates, bpp; |
1281 |
++ unsigned long outurb_active_mask; |
1282 |
+ |
1283 |
+ struct snd_pcm_substream *sub_playback[MAX_STREAMS]; |
1284 |
+ struct snd_pcm_substream *sub_capture[MAX_STREAMS]; |
1285 |
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
1286 |
+index c04d7c7..cdd19d7 100644 |
1287 |
+--- a/sound/usb/mixer.c |
1288 |
++++ b/sound/usb/mixer.c |
1289 |
+@@ -152,6 +152,7 @@ static inline void check_mapped_dB(const struct usbmix_name_map *p, |
1290 |
+ if (p && p->dB) { |
1291 |
+ cval->dBmin = p->dB->min; |
1292 |
+ cval->dBmax = p->dB->max; |
1293 |
++ cval->initialized = 1; |
1294 |
+ } |
1295 |
+ } |
1296 |
+ |
1297 |
+@@ -1092,7 +1093,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, |
1298 |
+ " Switch" : " Volume"); |
1299 |
+ if (control == UAC_FU_VOLUME) { |
1300 |
+ check_mapped_dB(map, cval); |
1301 |
+- if (cval->dBmin < cval->dBmax) { |
1302 |
++ if (cval->dBmin < cval->dBmax || !cval->initialized) { |
1303 |
+ kctl->tlv.c = mixer_vol_tlv; |
1304 |
+ kctl->vd[0].access |= |
1305 |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ | |