Annotation of /trunk/kernel26-alx/patches-2.6.33-r2/0100-2.6.33.1-all-fixes.patch
Parent Directory | Revision Log
Revision 1192 -
(hide annotations)
(download)
Sat Nov 20 15:43:20 2010 UTC (13 years, 10 months ago) by niro
File size: 172319 byte(s)
Sat Nov 20 15:43:20 2010 UTC (13 years, 10 months ago) by niro
File size: 172319 byte(s)
added fixes for intel-agp and i915 module loading issues
1 | niro | 1192 | diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt |
2 | index e7848a0..e2c7487 100644 | ||
3 | --- a/Documentation/kernel-parameters.txt | ||
4 | +++ b/Documentation/kernel-parameters.txt | ||
5 | @@ -2703,6 +2703,13 @@ and is between 256 and 4096 characters. It is defined in the file | ||
6 | medium is write-protected). | ||
7 | Example: quirks=0419:aaf5:rl,0421:0433:rc | ||
8 | |||
9 | + userpte= | ||
10 | + [X86] Flags controlling user PTE allocations. | ||
11 | + | ||
12 | + nohigh = do not allocate PTE pages in | ||
13 | + HIGHMEM regardless of setting | ||
14 | + of CONFIG_HIGHPTE. | ||
15 | + | ||
16 | vdso= [X86,SH] | ||
17 | vdso=2: enable compat VDSO (default with COMPAT_VDSO) | ||
18 | vdso=1: enable VDSO (default) | ||
19 | diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt | ||
20 | index 75afa12..39c0a09 100644 | ||
21 | --- a/Documentation/laptops/thinkpad-acpi.txt | ||
22 | +++ b/Documentation/laptops/thinkpad-acpi.txt | ||
23 | @@ -650,6 +650,10 @@ LCD, CRT or DVI (if available). The following commands are available: | ||
24 | echo expand_toggle > /proc/acpi/ibm/video | ||
25 | echo video_switch > /proc/acpi/ibm/video | ||
26 | |||
27 | +NOTE: Access to this feature is restricted to processes owning the | ||
28 | +CAP_SYS_ADMIN capability for safety reasons, as it can interact badly | ||
29 | +enough with some versions of X.org to crash it. | ||
30 | + | ||
31 | Each video output device can be enabled or disabled individually. | ||
32 | Reading /proc/acpi/ibm/video shows the status of each device. | ||
33 | |||
34 | diff --git a/arch/Kconfig b/arch/Kconfig | ||
35 | index 9d055b4..25e69f7 100644 | ||
36 | --- a/arch/Kconfig | ||
37 | +++ b/arch/Kconfig | ||
38 | @@ -6,8 +6,6 @@ config OPROFILE | ||
39 | tristate "OProfile system profiling (EXPERIMENTAL)" | ||
40 | depends on PROFILING | ||
41 | depends on HAVE_OPROFILE | ||
42 | - depends on TRACING_SUPPORT | ||
43 | - select TRACING | ||
44 | select RING_BUFFER | ||
45 | select RING_BUFFER_ALLOW_SWAP | ||
46 | help | ||
47 | diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c | ||
48 | index f9f4724..14531ab 100644 | ||
49 | --- a/arch/x86/ia32/ia32_aout.c | ||
50 | +++ b/arch/x86/ia32/ia32_aout.c | ||
51 | @@ -327,7 +327,6 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) | ||
52 | current->mm->free_area_cache = TASK_UNMAPPED_BASE; | ||
53 | current->mm->cached_hole_size = 0; | ||
54 | |||
55 | - current->mm->mmap = NULL; | ||
56 | install_exec_creds(bprm); | ||
57 | current->flags &= ~PF_FORKNOEXEC; | ||
58 | |||
59 | diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h | ||
60 | index 7c7c16c..5f61f6e 100644 | ||
61 | --- a/arch/x86/include/asm/io_apic.h | ||
62 | +++ b/arch/x86/include/asm/io_apic.h | ||
63 | @@ -160,6 +160,7 @@ extern int io_apic_get_redir_entries(int ioapic); | ||
64 | struct io_apic_irq_attr; | ||
65 | extern int io_apic_set_pci_routing(struct device *dev, int irq, | ||
66 | struct io_apic_irq_attr *irq_attr); | ||
67 | +void setup_IO_APIC_irq_extra(u32 gsi); | ||
68 | extern int (*ioapic_renumber_irq)(int ioapic, int irq); | ||
69 | extern void ioapic_init_mappings(void); | ||
70 | extern void ioapic_insert_resources(void); | ||
71 | diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h | ||
72 | index 0e8c2a0..271de94 100644 | ||
73 | --- a/arch/x86/include/asm/pgalloc.h | ||
74 | +++ b/arch/x86/include/asm/pgalloc.h | ||
75 | @@ -23,6 +23,11 @@ static inline void paravirt_release_pud(unsigned long pfn) {} | ||
76 | #endif | ||
77 | |||
78 | /* | ||
79 | + * Flags to use when allocating a user page table page. | ||
80 | + */ | ||
81 | +extern gfp_t __userpte_alloc_gfp; | ||
82 | + | ||
83 | +/* | ||
84 | * Allocate and free page tables. | ||
85 | */ | ||
86 | extern pgd_t *pgd_alloc(struct mm_struct *); | ||
87 | diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h | ||
88 | index 40be813..14cc74b 100644 | ||
89 | --- a/arch/x86/include/asm/uv/uv_hub.h | ||
90 | +++ b/arch/x86/include/asm/uv/uv_hub.h | ||
91 | @@ -329,7 +329,8 @@ static inline unsigned long uv_read_global_mmr64(int pnode, unsigned long offset | ||
92 | */ | ||
93 | static inline unsigned long uv_global_gru_mmr_address(int pnode, unsigned long offset) | ||
94 | { | ||
95 | - return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val); | ||
96 | + return UV_GLOBAL_GRU_MMR_BASE | offset | | ||
97 | + ((unsigned long)pnode << uv_hub_info->m_val); | ||
98 | } | ||
99 | |||
100 | static inline void uv_write_global_mmr8(int pnode, unsigned long offset, unsigned char val) | ||
101 | diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h | ||
102 | index 2b49454..8f6b011 100644 | ||
103 | --- a/arch/x86/include/asm/vmx.h | ||
104 | +++ b/arch/x86/include/asm/vmx.h | ||
105 | @@ -251,6 +251,7 @@ enum vmcs_field { | ||
106 | #define EXIT_REASON_MSR_READ 31 | ||
107 | #define EXIT_REASON_MSR_WRITE 32 | ||
108 | #define EXIT_REASON_MWAIT_INSTRUCTION 36 | ||
109 | +#define EXIT_REASON_MONITOR_INSTRUCTION 39 | ||
110 | #define EXIT_REASON_PAUSE_INSTRUCTION 40 | ||
111 | #define EXIT_REASON_MCE_DURING_VMENTRY 41 | ||
112 | #define EXIT_REASON_TPR_BELOW_THRESHOLD 43 | ||
113 | diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c | ||
114 | index af1c583..0a2b21a 100644 | ||
115 | --- a/arch/x86/kernel/acpi/boot.c | ||
116 | +++ b/arch/x86/kernel/acpi/boot.c | ||
117 | @@ -446,6 +446,12 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) | ||
118 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | ||
119 | { | ||
120 | *irq = gsi; | ||
121 | + | ||
122 | +#ifdef CONFIG_X86_IO_APIC | ||
123 | + if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) | ||
124 | + setup_IO_APIC_irq_extra(gsi); | ||
125 | +#endif | ||
126 | + | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | @@ -473,7 +479,8 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) | ||
131 | plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity); | ||
132 | } | ||
133 | #endif | ||
134 | - acpi_gsi_to_irq(plat_gsi, &irq); | ||
135 | + irq = plat_gsi; | ||
136 | + | ||
137 | return irq; | ||
138 | } | ||
139 | |||
140 | diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c | ||
141 | index 53243ca..be37059 100644 | ||
142 | --- a/arch/x86/kernel/apic/io_apic.c | ||
143 | +++ b/arch/x86/kernel/apic/io_apic.c | ||
144 | @@ -1539,6 +1539,56 @@ static void __init setup_IO_APIC_irqs(void) | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | + * for the gsit that is not in first ioapic | ||
149 | + * but could not use acpi_register_gsi() | ||
150 | + * like some special sci in IBM x3330 | ||
151 | + */ | ||
152 | +void setup_IO_APIC_irq_extra(u32 gsi) | ||
153 | +{ | ||
154 | + int apic_id = 0, pin, idx, irq; | ||
155 | + int node = cpu_to_node(boot_cpu_id); | ||
156 | + struct irq_desc *desc; | ||
157 | + struct irq_cfg *cfg; | ||
158 | + | ||
159 | + /* | ||
160 | + * Convert 'gsi' to 'ioapic.pin'. | ||
161 | + */ | ||
162 | + apic_id = mp_find_ioapic(gsi); | ||
163 | + if (apic_id < 0) | ||
164 | + return; | ||
165 | + | ||
166 | + pin = mp_find_ioapic_pin(apic_id, gsi); | ||
167 | + idx = find_irq_entry(apic_id, pin, mp_INT); | ||
168 | + if (idx == -1) | ||
169 | + return; | ||
170 | + | ||
171 | + irq = pin_2_irq(idx, apic_id, pin); | ||
172 | +#ifdef CONFIG_SPARSE_IRQ | ||
173 | + desc = irq_to_desc(irq); | ||
174 | + if (desc) | ||
175 | + return; | ||
176 | +#endif | ||
177 | + desc = irq_to_desc_alloc_node(irq, node); | ||
178 | + if (!desc) { | ||
179 | + printk(KERN_INFO "can not get irq_desc for %d\n", irq); | ||
180 | + return; | ||
181 | + } | ||
182 | + | ||
183 | + cfg = desc->chip_data; | ||
184 | + add_pin_to_irq_node(cfg, node, apic_id, pin); | ||
185 | + | ||
186 | + if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) { | ||
187 | + pr_debug("Pin %d-%d already programmed\n", | ||
188 | + mp_ioapics[apic_id].apicid, pin); | ||
189 | + return; | ||
190 | + } | ||
191 | + set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed); | ||
192 | + | ||
193 | + setup_IO_APIC_irq(apic_id, pin, irq, desc, | ||
194 | + irq_trigger(idx), irq_polarity(idx)); | ||
195 | +} | ||
196 | + | ||
197 | +/* | ||
198 | * Set up the timer pin, possibly with the 8259A-master behind. | ||
199 | */ | ||
200 | static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, | ||
201 | @@ -3228,12 +3278,9 @@ unsigned int create_irq_nr(unsigned int irq_want, int node) | ||
202 | } | ||
203 | spin_unlock_irqrestore(&vector_lock, flags); | ||
204 | |||
205 | - if (irq > 0) { | ||
206 | - dynamic_irq_init(irq); | ||
207 | - /* restore it, in case dynamic_irq_init clear it */ | ||
208 | - if (desc_new) | ||
209 | - desc_new->chip_data = cfg_new; | ||
210 | - } | ||
211 | + if (irq > 0) | ||
212 | + dynamic_irq_init_keep_chip_data(irq); | ||
213 | + | ||
214 | return irq; | ||
215 | } | ||
216 | |||
217 | @@ -3256,17 +3303,12 @@ void destroy_irq(unsigned int irq) | ||
218 | { | ||
219 | unsigned long flags; | ||
220 | struct irq_cfg *cfg; | ||
221 | - struct irq_desc *desc; | ||
222 | |||
223 | - /* store it, in case dynamic_irq_cleanup clear it */ | ||
224 | - desc = irq_to_desc(irq); | ||
225 | - cfg = desc->chip_data; | ||
226 | - dynamic_irq_cleanup(irq); | ||
227 | - /* connect back irq_cfg */ | ||
228 | - desc->chip_data = cfg; | ||
229 | + dynamic_irq_cleanup_keep_chip_data(irq); | ||
230 | |||
231 | free_irte(irq); | ||
232 | spin_lock_irqsave(&vector_lock, flags); | ||
233 | + cfg = irq_to_desc(irq)->chip_data; | ||
234 | __clear_irq_vector(irq, cfg); | ||
235 | spin_unlock_irqrestore(&vector_lock, flags); | ||
236 | } | ||
237 | diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c | ||
238 | index 704bddc..8e1aac8 100644 | ||
239 | --- a/arch/x86/kernel/reboot.c | ||
240 | +++ b/arch/x86/kernel/reboot.c | ||
241 | @@ -461,6 +461,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { | ||
242 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"), | ||
243 | }, | ||
244 | }, | ||
245 | + { /* Handle problems with rebooting on the iMac9,1. */ | ||
246 | + .callback = set_pci_reboot, | ||
247 | + .ident = "Apple iMac9,1", | ||
248 | + .matches = { | ||
249 | + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
250 | + DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), | ||
251 | + }, | ||
252 | + }, | ||
253 | { } | ||
254 | }; | ||
255 | |||
256 | diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c | ||
257 | index 7e8faea..c998d27 100644 | ||
258 | --- a/arch/x86/kvm/emulate.c | ||
259 | +++ b/arch/x86/kvm/emulate.c | ||
260 | @@ -76,6 +76,7 @@ | ||
261 | #define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ | ||
262 | #define GroupMask 0xff /* Group number stored in bits 0:7 */ | ||
263 | /* Misc flags */ | ||
264 | +#define Priv (1<<27) /* instruction generates #GP if current CPL != 0 */ | ||
265 | #define No64 (1<<28) | ||
266 | /* Source 2 operand type */ | ||
267 | #define Src2None (0<<29) | ||
268 | @@ -88,6 +89,7 @@ | ||
269 | enum { | ||
270 | Group1_80, Group1_81, Group1_82, Group1_83, | ||
271 | Group1A, Group3_Byte, Group3, Group4, Group5, Group7, | ||
272 | + Group8, Group9, | ||
273 | }; | ||
274 | |||
275 | static u32 opcode_table[256] = { | ||
276 | @@ -210,7 +212,7 @@ static u32 opcode_table[256] = { | ||
277 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | ||
278 | /* 0xF0 - 0xF7 */ | ||
279 | 0, 0, 0, 0, | ||
280 | - ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, | ||
281 | + ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3, | ||
282 | /* 0xF8 - 0xFF */ | ||
283 | ImplicitOps, 0, ImplicitOps, ImplicitOps, | ||
284 | ImplicitOps, ImplicitOps, Group | Group4, Group | Group5, | ||
285 | @@ -218,16 +220,20 @@ static u32 opcode_table[256] = { | ||
286 | |||
287 | static u32 twobyte_table[256] = { | ||
288 | /* 0x00 - 0x0F */ | ||
289 | - 0, Group | GroupDual | Group7, 0, 0, 0, ImplicitOps, ImplicitOps, 0, | ||
290 | - ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, | ||
291 | + 0, Group | GroupDual | Group7, 0, 0, | ||
292 | + 0, ImplicitOps, ImplicitOps | Priv, 0, | ||
293 | + ImplicitOps | Priv, ImplicitOps | Priv, 0, 0, | ||
294 | + 0, ImplicitOps | ModRM, 0, 0, | ||
295 | /* 0x10 - 0x1F */ | ||
296 | 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, | ||
297 | /* 0x20 - 0x2F */ | ||
298 | - ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0, | ||
299 | + ModRM | ImplicitOps | Priv, ModRM | Priv, | ||
300 | + ModRM | ImplicitOps | Priv, ModRM | Priv, | ||
301 | + 0, 0, 0, 0, | ||
302 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
303 | /* 0x30 - 0x3F */ | ||
304 | - ImplicitOps, 0, ImplicitOps, 0, | ||
305 | - ImplicitOps, ImplicitOps, 0, 0, | ||
306 | + ImplicitOps | Priv, 0, ImplicitOps | Priv, 0, | ||
307 | + ImplicitOps, ImplicitOps | Priv, 0, 0, | ||
308 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
309 | /* 0x40 - 0x47 */ | ||
310 | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, | ||
311 | @@ -267,11 +273,12 @@ static u32 twobyte_table[256] = { | ||
312 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, | ||
313 | DstReg | SrcMem16 | ModRM | Mov, | ||
314 | /* 0xB8 - 0xBF */ | ||
315 | - 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp, | ||
316 | + 0, 0, Group | Group8, DstMem | SrcReg | ModRM | BitOp, | ||
317 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, | ||
318 | DstReg | SrcMem16 | ModRM | Mov, | ||
319 | /* 0xC0 - 0xCF */ | ||
320 | - 0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM, | ||
321 | + 0, 0, 0, DstMem | SrcReg | ModRM | Mov, | ||
322 | + 0, 0, 0, Group | GroupDual | Group9, | ||
323 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
324 | /* 0xD0 - 0xDF */ | ||
325 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
326 | @@ -320,16 +327,24 @@ static u32 group_table[] = { | ||
327 | SrcMem | ModRM | Stack, 0, | ||
328 | SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0, | ||
329 | [Group7*8] = | ||
330 | - 0, 0, ModRM | SrcMem, ModRM | SrcMem, | ||
331 | + 0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv, | ||
332 | SrcNone | ModRM | DstMem | Mov, 0, | ||
333 | - SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp, | ||
334 | + SrcMem16 | ModRM | Mov | Priv, SrcMem | ModRM | ByteOp | Priv, | ||
335 | + [Group8*8] = | ||
336 | + 0, 0, 0, 0, | ||
337 | + DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, | ||
338 | + DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, | ||
339 | + [Group9*8] = | ||
340 | + 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, | ||
341 | }; | ||
342 | |||
343 | static u32 group2_table[] = { | ||
344 | [Group7*8] = | ||
345 | - SrcNone | ModRM, 0, 0, SrcNone | ModRM, | ||
346 | + SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM, | ||
347 | SrcNone | ModRM | DstMem | Mov, 0, | ||
348 | SrcMem16 | ModRM | Mov, 0, | ||
349 | + [Group9*8] = | ||
350 | + 0, 0, 0, 0, 0, 0, 0, 0, | ||
351 | }; | ||
352 | |||
353 | /* EFLAGS bit definitions. */ | ||
354 | @@ -1640,12 +1655,6 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | ||
355 | return -1; | ||
356 | } | ||
357 | |||
358 | - /* sysexit must be called from CPL 0 */ | ||
359 | - if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) { | ||
360 | - kvm_inject_gp(ctxt->vcpu, 0); | ||
361 | - return -1; | ||
362 | - } | ||
363 | - | ||
364 | setup_syscalls_segments(ctxt, &cs, &ss); | ||
365 | |||
366 | if ((c->rex_prefix & 0x8) != 0x0) | ||
367 | @@ -1709,6 +1718,12 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | ||
368 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); | ||
369 | saved_eip = c->eip; | ||
370 | |||
371 | + /* Privileged instruction can be executed only in CPL=0 */ | ||
372 | + if ((c->d & Priv) && kvm_x86_ops->get_cpl(ctxt->vcpu)) { | ||
373 | + kvm_inject_gp(ctxt->vcpu, 0); | ||
374 | + goto done; | ||
375 | + } | ||
376 | + | ||
377 | if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs)) | ||
378 | memop = c->modrm_ea; | ||
379 | |||
380 | @@ -1982,6 +1997,12 @@ special_insn: | ||
381 | int err; | ||
382 | |||
383 | sel = c->src.val; | ||
384 | + | ||
385 | + if (c->modrm_reg == VCPU_SREG_CS) { | ||
386 | + kvm_queue_exception(ctxt->vcpu, UD_VECTOR); | ||
387 | + goto done; | ||
388 | + } | ||
389 | + | ||
390 | if (c->modrm_reg == VCPU_SREG_SS) | ||
391 | toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS); | ||
392 | |||
393 | diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c | ||
394 | index d4918d6..8a8e139 100644 | ||
395 | --- a/arch/x86/kvm/vmx.c | ||
396 | +++ b/arch/x86/kvm/vmx.c | ||
397 | @@ -1224,6 +1224,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | ||
398 | CPU_BASED_USE_IO_BITMAPS | | ||
399 | CPU_BASED_MOV_DR_EXITING | | ||
400 | CPU_BASED_USE_TSC_OFFSETING | | ||
401 | + CPU_BASED_MWAIT_EXITING | | ||
402 | + CPU_BASED_MONITOR_EXITING | | ||
403 | CPU_BASED_INVLPG_EXITING; | ||
404 | opt = CPU_BASED_TPR_SHADOW | | ||
405 | CPU_BASED_USE_MSR_BITMAPS | | ||
406 | @@ -3416,6 +3418,12 @@ static int handle_pause(struct kvm_vcpu *vcpu) | ||
407 | return 1; | ||
408 | } | ||
409 | |||
410 | +static int handle_invalid_op(struct kvm_vcpu *vcpu) | ||
411 | +{ | ||
412 | + kvm_queue_exception(vcpu, UD_VECTOR); | ||
413 | + return 1; | ||
414 | +} | ||
415 | + | ||
416 | /* | ||
417 | * The exit handlers return 1 if the exit was handled fully and guest execution | ||
418 | * may resume. Otherwise they set the kvm_run parameter to indicate what needs | ||
419 | @@ -3453,6 +3461,8 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { | ||
420 | [EXIT_REASON_EPT_VIOLATION] = handle_ept_violation, | ||
421 | [EXIT_REASON_EPT_MISCONFIG] = handle_ept_misconfig, | ||
422 | [EXIT_REASON_PAUSE_INSTRUCTION] = handle_pause, | ||
423 | + [EXIT_REASON_MWAIT_INSTRUCTION] = handle_invalid_op, | ||
424 | + [EXIT_REASON_MONITOR_INSTRUCTION] = handle_invalid_op, | ||
425 | }; | ||
426 | |||
427 | static const int kvm_vmx_max_exit_handlers = | ||
428 | diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c | ||
429 | index ed34f5e..c9ba9de 100644 | ||
430 | --- a/arch/x86/mm/pgtable.c | ||
431 | +++ b/arch/x86/mm/pgtable.c | ||
432 | @@ -6,6 +6,14 @@ | ||
433 | |||
434 | #define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO | ||
435 | |||
436 | +#ifdef CONFIG_HIGHPTE | ||
437 | +#define PGALLOC_USER_GFP __GFP_HIGHMEM | ||
438 | +#else | ||
439 | +#define PGALLOC_USER_GFP 0 | ||
440 | +#endif | ||
441 | + | ||
442 | +gfp_t __userpte_alloc_gfp = PGALLOC_GFP | PGALLOC_USER_GFP; | ||
443 | + | ||
444 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | ||
445 | { | ||
446 | return (pte_t *)__get_free_page(PGALLOC_GFP); | ||
447 | @@ -15,16 +23,29 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) | ||
448 | { | ||
449 | struct page *pte; | ||
450 | |||
451 | -#ifdef CONFIG_HIGHPTE | ||
452 | - pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0); | ||
453 | -#else | ||
454 | - pte = alloc_pages(PGALLOC_GFP, 0); | ||
455 | -#endif | ||
456 | + pte = alloc_pages(__userpte_alloc_gfp, 0); | ||
457 | if (pte) | ||
458 | pgtable_page_ctor(pte); | ||
459 | return pte; | ||
460 | } | ||
461 | |||
462 | +static int __init setup_userpte(char *arg) | ||
463 | +{ | ||
464 | + if (!arg) | ||
465 | + return -EINVAL; | ||
466 | + | ||
467 | + /* | ||
468 | + * "userpte=nohigh" disables allocation of user pagetables in | ||
469 | + * high memory. | ||
470 | + */ | ||
471 | + if (strcmp(arg, "nohigh") == 0) | ||
472 | + __userpte_alloc_gfp &= ~__GFP_HIGHMEM; | ||
473 | + else | ||
474 | + return -EINVAL; | ||
475 | + return 0; | ||
476 | +} | ||
477 | +early_param("userpte", setup_userpte); | ||
478 | + | ||
479 | void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) | ||
480 | { | ||
481 | pgtable_page_dtor(pte); | ||
482 | diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c | ||
483 | index 3347f69..2c505ee 100644 | ||
484 | --- a/arch/x86/oprofile/nmi_int.c | ||
485 | +++ b/arch/x86/oprofile/nmi_int.c | ||
486 | @@ -159,7 +159,7 @@ static int nmi_setup_mux(void) | ||
487 | |||
488 | for_each_possible_cpu(i) { | ||
489 | per_cpu(cpu_msrs, i).multiplex = | ||
490 | - kmalloc(multiplex_size, GFP_KERNEL); | ||
491 | + kzalloc(multiplex_size, GFP_KERNEL); | ||
492 | if (!per_cpu(cpu_msrs, i).multiplex) | ||
493 | return 0; | ||
494 | } | ||
495 | @@ -179,7 +179,6 @@ static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) | ||
496 | if (counter_config[i].enabled) { | ||
497 | multiplex[i].saved = -(u64)counter_config[i].count; | ||
498 | } else { | ||
499 | - multiplex[i].addr = 0; | ||
500 | multiplex[i].saved = 0; | ||
501 | } | ||
502 | } | ||
503 | @@ -189,25 +188,27 @@ static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) | ||
504 | |||
505 | static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs) | ||
506 | { | ||
507 | + struct op_msr *counters = msrs->counters; | ||
508 | struct op_msr *multiplex = msrs->multiplex; | ||
509 | int i; | ||
510 | |||
511 | for (i = 0; i < model->num_counters; ++i) { | ||
512 | int virt = op_x86_phys_to_virt(i); | ||
513 | - if (multiplex[virt].addr) | ||
514 | - rdmsrl(multiplex[virt].addr, multiplex[virt].saved); | ||
515 | + if (counters[i].addr) | ||
516 | + rdmsrl(counters[i].addr, multiplex[virt].saved); | ||
517 | } | ||
518 | } | ||
519 | |||
520 | static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs) | ||
521 | { | ||
522 | + struct op_msr *counters = msrs->counters; | ||
523 | struct op_msr *multiplex = msrs->multiplex; | ||
524 | int i; | ||
525 | |||
526 | for (i = 0; i < model->num_counters; ++i) { | ||
527 | int virt = op_x86_phys_to_virt(i); | ||
528 | - if (multiplex[virt].addr) | ||
529 | - wrmsrl(multiplex[virt].addr, multiplex[virt].saved); | ||
530 | + if (counters[i].addr) | ||
531 | + wrmsrl(counters[i].addr, multiplex[virt].saved); | ||
532 | } | ||
533 | } | ||
534 | |||
535 | @@ -303,11 +304,11 @@ static int allocate_msrs(void) | ||
536 | |||
537 | int i; | ||
538 | for_each_possible_cpu(i) { | ||
539 | - per_cpu(cpu_msrs, i).counters = kmalloc(counters_size, | ||
540 | + per_cpu(cpu_msrs, i).counters = kzalloc(counters_size, | ||
541 | GFP_KERNEL); | ||
542 | if (!per_cpu(cpu_msrs, i).counters) | ||
543 | return 0; | ||
544 | - per_cpu(cpu_msrs, i).controls = kmalloc(controls_size, | ||
545 | + per_cpu(cpu_msrs, i).controls = kzalloc(controls_size, | ||
546 | GFP_KERNEL); | ||
547 | if (!per_cpu(cpu_msrs, i).controls) | ||
548 | return 0; | ||
549 | diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c | ||
550 | index 39686c2..1ed963d 100644 | ||
551 | --- a/arch/x86/oprofile/op_model_amd.c | ||
552 | +++ b/arch/x86/oprofile/op_model_amd.c | ||
553 | @@ -76,19 +76,6 @@ static struct op_ibs_config ibs_config; | ||
554 | |||
555 | #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX | ||
556 | |||
557 | -static void op_mux_fill_in_addresses(struct op_msrs * const msrs) | ||
558 | -{ | ||
559 | - int i; | ||
560 | - | ||
561 | - for (i = 0; i < NUM_VIRT_COUNTERS; i++) { | ||
562 | - int hw_counter = op_x86_virt_to_phys(i); | ||
563 | - if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) | ||
564 | - msrs->multiplex[i].addr = MSR_K7_PERFCTR0 + hw_counter; | ||
565 | - else | ||
566 | - msrs->multiplex[i].addr = 0; | ||
567 | - } | ||
568 | -} | ||
569 | - | ||
570 | static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, | ||
571 | struct op_msrs const * const msrs) | ||
572 | { | ||
573 | @@ -98,7 +85,7 @@ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, | ||
574 | /* enable active counters */ | ||
575 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
576 | int virt = op_x86_phys_to_virt(i); | ||
577 | - if (!counter_config[virt].enabled) | ||
578 | + if (!reset_value[virt]) | ||
579 | continue; | ||
580 | rdmsrl(msrs->controls[i].addr, val); | ||
581 | val &= model->reserved; | ||
582 | @@ -107,10 +94,6 @@ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, | ||
583 | } | ||
584 | } | ||
585 | |||
586 | -#else | ||
587 | - | ||
588 | -static inline void op_mux_fill_in_addresses(struct op_msrs * const msrs) { } | ||
589 | - | ||
590 | #endif | ||
591 | |||
592 | /* functions for op_amd_spec */ | ||
593 | @@ -122,18 +105,12 @@ static void op_amd_fill_in_addresses(struct op_msrs * const msrs) | ||
594 | for (i = 0; i < NUM_COUNTERS; i++) { | ||
595 | if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) | ||
596 | msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; | ||
597 | - else | ||
598 | - msrs->counters[i].addr = 0; | ||
599 | } | ||
600 | |||
601 | for (i = 0; i < NUM_CONTROLS; i++) { | ||
602 | if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) | ||
603 | msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; | ||
604 | - else | ||
605 | - msrs->controls[i].addr = 0; | ||
606 | } | ||
607 | - | ||
608 | - op_mux_fill_in_addresses(msrs); | ||
609 | } | ||
610 | |||
611 | static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, | ||
612 | @@ -144,7 +121,8 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, | ||
613 | |||
614 | /* setup reset_value */ | ||
615 | for (i = 0; i < NUM_VIRT_COUNTERS; ++i) { | ||
616 | - if (counter_config[i].enabled) | ||
617 | + if (counter_config[i].enabled | ||
618 | + && msrs->counters[op_x86_virt_to_phys(i)].addr) | ||
619 | reset_value[i] = counter_config[i].count; | ||
620 | else | ||
621 | reset_value[i] = 0; | ||
622 | @@ -169,9 +147,7 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, | ||
623 | /* enable active counters */ | ||
624 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
625 | int virt = op_x86_phys_to_virt(i); | ||
626 | - if (!counter_config[virt].enabled) | ||
627 | - continue; | ||
628 | - if (!msrs->counters[i].addr) | ||
629 | + if (!reset_value[virt]) | ||
630 | continue; | ||
631 | |||
632 | /* setup counter registers */ | ||
633 | @@ -405,16 +381,6 @@ static int init_ibs_nmi(void) | ||
634 | return 1; | ||
635 | } | ||
636 | |||
637 | -#ifdef CONFIG_NUMA | ||
638 | - /* Sanity check */ | ||
639 | - /* Works only for 64bit with proper numa implementation. */ | ||
640 | - if (nodes != num_possible_nodes()) { | ||
641 | - printk(KERN_DEBUG "Failed to setup CPU node(s) for IBS, " | ||
642 | - "found: %d, expected %d", | ||
643 | - nodes, num_possible_nodes()); | ||
644 | - return 1; | ||
645 | - } | ||
646 | -#endif | ||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c | ||
651 | index ac6b354..e6a160a 100644 | ||
652 | --- a/arch/x86/oprofile/op_model_p4.c | ||
653 | +++ b/arch/x86/oprofile/op_model_p4.c | ||
654 | @@ -394,12 +394,6 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs) | ||
655 | setup_num_counters(); | ||
656 | stag = get_stagger(); | ||
657 | |||
658 | - /* initialize some registers */ | ||
659 | - for (i = 0; i < num_counters; ++i) | ||
660 | - msrs->counters[i].addr = 0; | ||
661 | - for (i = 0; i < num_controls; ++i) | ||
662 | - msrs->controls[i].addr = 0; | ||
663 | - | ||
664 | /* the counter & cccr registers we pay attention to */ | ||
665 | for (i = 0; i < num_counters; ++i) { | ||
666 | addr = p4_counters[VIRT_CTR(stag, i)].counter_address; | ||
667 | diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c | ||
668 | index 8eb0587..2873c00 100644 | ||
669 | --- a/arch/x86/oprofile/op_model_ppro.c | ||
670 | +++ b/arch/x86/oprofile/op_model_ppro.c | ||
671 | @@ -37,15 +37,11 @@ static void ppro_fill_in_addresses(struct op_msrs * const msrs) | ||
672 | for (i = 0; i < num_counters; i++) { | ||
673 | if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) | ||
674 | msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; | ||
675 | - else | ||
676 | - msrs->counters[i].addr = 0; | ||
677 | } | ||
678 | |||
679 | for (i = 0; i < num_counters; i++) { | ||
680 | if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) | ||
681 | msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; | ||
682 | - else | ||
683 | - msrs->controls[i].addr = 0; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | @@ -57,7 +53,7 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model, | ||
688 | int i; | ||
689 | |||
690 | if (!reset_value) { | ||
691 | - reset_value = kmalloc(sizeof(reset_value[0]) * num_counters, | ||
692 | + reset_value = kzalloc(sizeof(reset_value[0]) * num_counters, | ||
693 | GFP_ATOMIC); | ||
694 | if (!reset_value) | ||
695 | return; | ||
696 | diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c | ||
697 | index b19d1e5..8f3f9a5 100644 | ||
698 | --- a/arch/x86/pci/mmconfig-shared.c | ||
699 | +++ b/arch/x86/pci/mmconfig-shared.c | ||
700 | @@ -303,22 +303,17 @@ static void __init pci_mmcfg_check_end_bus_number(void) | ||
701 | { | ||
702 | struct pci_mmcfg_region *cfg, *cfgx; | ||
703 | |||
704 | - /* last one*/ | ||
705 | - cfg = list_entry(pci_mmcfg_list.prev, typeof(*cfg), list); | ||
706 | - if (cfg) | ||
707 | - if (cfg->end_bus < cfg->start_bus) | ||
708 | - cfg->end_bus = 255; | ||
709 | - | ||
710 | - if (list_is_singular(&pci_mmcfg_list)) | ||
711 | - return; | ||
712 | - | ||
713 | - /* don't overlap please */ | ||
714 | + /* Fixup overlaps */ | ||
715 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { | ||
716 | if (cfg->end_bus < cfg->start_bus) | ||
717 | cfg->end_bus = 255; | ||
718 | |||
719 | + /* Don't access the list head ! */ | ||
720 | + if (cfg->list.next == &pci_mmcfg_list) | ||
721 | + break; | ||
722 | + | ||
723 | cfgx = list_entry(cfg->list.next, typeof(*cfg), list); | ||
724 | - if (cfg != cfgx && cfg->end_bus >= cfgx->start_bus) | ||
725 | + if (cfg->end_bus >= cfgx->start_bus) | ||
726 | cfg->end_bus = cfgx->start_bus - 1; | ||
727 | } | ||
728 | } | ||
729 | diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c | ||
730 | index 36daccb..b607239 100644 | ||
731 | --- a/arch/x86/xen/enlighten.c | ||
732 | +++ b/arch/x86/xen/enlighten.c | ||
733 | @@ -50,6 +50,7 @@ | ||
734 | #include <asm/traps.h> | ||
735 | #include <asm/setup.h> | ||
736 | #include <asm/desc.h> | ||
737 | +#include <asm/pgalloc.h> | ||
738 | #include <asm/pgtable.h> | ||
739 | #include <asm/tlbflush.h> | ||
740 | #include <asm/reboot.h> | ||
741 | @@ -1094,6 +1095,12 @@ asmlinkage void __init xen_start_kernel(void) | ||
742 | |||
743 | __supported_pte_mask |= _PAGE_IOMAP; | ||
744 | |||
745 | + /* | ||
746 | + * Prevent page tables from being allocated in highmem, even | ||
747 | + * if CONFIG_HIGHPTE is enabled. | ||
748 | + */ | ||
749 | + __userpte_alloc_gfp &= ~__GFP_HIGHMEM; | ||
750 | + | ||
751 | /* Work out if we support NX */ | ||
752 | x86_configure_nx(); | ||
753 | |||
754 | diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c | ||
755 | index bf4cd6b..350a3de 100644 | ||
756 | --- a/arch/x86/xen/mmu.c | ||
757 | +++ b/arch/x86/xen/mmu.c | ||
758 | @@ -1432,14 +1432,15 @@ static void *xen_kmap_atomic_pte(struct page *page, enum km_type type) | ||
759 | { | ||
760 | pgprot_t prot = PAGE_KERNEL; | ||
761 | |||
762 | + /* | ||
763 | + * We disable highmem allocations for page tables so we should never | ||
764 | + * see any calls to kmap_atomic_pte on a highmem page. | ||
765 | + */ | ||
766 | + BUG_ON(PageHighMem(page)); | ||
767 | + | ||
768 | if (PagePinned(page)) | ||
769 | prot = PAGE_KERNEL_RO; | ||
770 | |||
771 | - if (0 && PageHighMem(page)) | ||
772 | - printk("mapping highpte %lx type %d prot %s\n", | ||
773 | - page_to_pfn(page), type, | ||
774 | - (unsigned long)pgprot_val(prot) & _PAGE_RW ? "WRITE" : "READ"); | ||
775 | - | ||
776 | return kmap_atomic_prot(page, type, prot); | ||
777 | } | ||
778 | #endif | ||
779 | diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c | ||
780 | index b343903..a6a736a 100644 | ||
781 | --- a/drivers/ata/ahci.c | ||
782 | +++ b/drivers/ata/ahci.c | ||
783 | @@ -3082,8 +3082,16 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
784 | ahci_save_initial_config(pdev, hpriv); | ||
785 | |||
786 | /* prepare host */ | ||
787 | - if (hpriv->cap & HOST_CAP_NCQ) | ||
788 | - pi.flags |= ATA_FLAG_NCQ | ATA_FLAG_FPDMA_AA; | ||
789 | + if (hpriv->cap & HOST_CAP_NCQ) { | ||
790 | + pi.flags |= ATA_FLAG_NCQ; | ||
791 | + /* Auto-activate optimization is supposed to be supported on | ||
792 | + all AHCI controllers indicating NCQ support, but it seems | ||
793 | + to be broken at least on some NVIDIA MCP79 chipsets. | ||
794 | + Until we get info on which NVIDIA chipsets don't have this | ||
795 | + issue, if any, disable AA on all NVIDIA AHCIs. */ | ||
796 | + if (pdev->vendor != PCI_VENDOR_ID_NVIDIA) | ||
797 | + pi.flags |= ATA_FLAG_FPDMA_AA; | ||
798 | + } | ||
799 | |||
800 | if (hpriv->cap & HOST_CAP_PMP) | ||
801 | pi.flags |= ATA_FLAG_PMP; | ||
802 | diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c | ||
803 | index dd26bc7..269b5db 100644 | ||
804 | --- a/drivers/ata/pata_hpt3x2n.c | ||
805 | +++ b/drivers/ata/pata_hpt3x2n.c | ||
806 | @@ -25,7 +25,7 @@ | ||
807 | #include <linux/libata.h> | ||
808 | |||
809 | #define DRV_NAME "pata_hpt3x2n" | ||
810 | -#define DRV_VERSION "0.3.8" | ||
811 | +#define DRV_VERSION "0.3.9" | ||
812 | |||
813 | enum { | ||
814 | HPT_PCI_FAST = (1 << 31), | ||
815 | @@ -544,16 +544,16 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | ||
816 | pci_mhz); | ||
817 | /* Set our private data up. We only need a few flags so we use | ||
818 | it directly */ | ||
819 | - if (pci_mhz > 60) { | ||
820 | + if (pci_mhz > 60) | ||
821 | hpriv = (void *)(PCI66 | USE_DPLL); | ||
822 | - /* | ||
823 | - * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in | ||
824 | - * the MISC. register to stretch the UltraDMA Tss timing. | ||
825 | - * NOTE: This register is only writeable via I/O space. | ||
826 | - */ | ||
827 | - if (dev->device == PCI_DEVICE_ID_TTI_HPT371) | ||
828 | - outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); | ||
829 | - } | ||
830 | + | ||
831 | + /* | ||
832 | + * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in | ||
833 | + * the MISC. register to stretch the UltraDMA Tss timing. | ||
834 | + * NOTE: This register is only writeable via I/O space. | ||
835 | + */ | ||
836 | + if (dev->device == PCI_DEVICE_ID_TTI_HPT371) | ||
837 | + outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); | ||
838 | |||
839 | /* Now kick off ATA set up */ | ||
840 | return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv); | ||
841 | diff --git a/drivers/base/core.c b/drivers/base/core.c | ||
842 | index 2820257..fb4bc4f 100644 | ||
843 | --- a/drivers/base/core.c | ||
844 | +++ b/drivers/base/core.c | ||
845 | @@ -607,6 +607,7 @@ static struct kobject *get_device_parent(struct device *dev, | ||
846 | int retval; | ||
847 | |||
848 | if (dev->class) { | ||
849 | + static DEFINE_MUTEX(gdp_mutex); | ||
850 | struct kobject *kobj = NULL; | ||
851 | struct kobject *parent_kobj; | ||
852 | struct kobject *k; | ||
853 | @@ -623,6 +624,8 @@ static struct kobject *get_device_parent(struct device *dev, | ||
854 | else | ||
855 | parent_kobj = &parent->kobj; | ||
856 | |||
857 | + mutex_lock(&gdp_mutex); | ||
858 | + | ||
859 | /* find our class-directory at the parent and reference it */ | ||
860 | spin_lock(&dev->class->p->class_dirs.list_lock); | ||
861 | list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) | ||
862 | @@ -631,20 +634,26 @@ static struct kobject *get_device_parent(struct device *dev, | ||
863 | break; | ||
864 | } | ||
865 | spin_unlock(&dev->class->p->class_dirs.list_lock); | ||
866 | - if (kobj) | ||
867 | + if (kobj) { | ||
868 | + mutex_unlock(&gdp_mutex); | ||
869 | return kobj; | ||
870 | + } | ||
871 | |||
872 | /* or create a new class-directory at the parent device */ | ||
873 | k = kobject_create(); | ||
874 | - if (!k) | ||
875 | + if (!k) { | ||
876 | + mutex_unlock(&gdp_mutex); | ||
877 | return NULL; | ||
878 | + } | ||
879 | k->kset = &dev->class->p->class_dirs; | ||
880 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); | ||
881 | if (retval < 0) { | ||
882 | + mutex_unlock(&gdp_mutex); | ||
883 | kobject_put(k); | ||
884 | return NULL; | ||
885 | } | ||
886 | /* do not emit an uevent for this simple "glue" directory */ | ||
887 | + mutex_unlock(&gdp_mutex); | ||
888 | return k; | ||
889 | } | ||
890 | |||
891 | diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c | ||
892 | index 42ae452..dac478c 100644 | ||
893 | --- a/drivers/base/devtmpfs.c | ||
894 | +++ b/drivers/base/devtmpfs.c | ||
895 | @@ -301,6 +301,19 @@ int devtmpfs_delete_node(struct device *dev) | ||
896 | if (dentry->d_inode) { | ||
897 | err = vfs_getattr(nd.path.mnt, dentry, &stat); | ||
898 | if (!err && dev_mynode(dev, dentry->d_inode, &stat)) { | ||
899 | + struct iattr newattrs; | ||
900 | + /* | ||
901 | + * before unlinking this node, reset permissions | ||
902 | + * of possible references like hardlinks | ||
903 | + */ | ||
904 | + newattrs.ia_uid = 0; | ||
905 | + newattrs.ia_gid = 0; | ||
906 | + newattrs.ia_mode = stat.mode & ~0777; | ||
907 | + newattrs.ia_valid = | ||
908 | + ATTR_UID|ATTR_GID|ATTR_MODE; | ||
909 | + mutex_lock(&dentry->d_inode->i_mutex); | ||
910 | + notify_change(dentry, &newattrs); | ||
911 | + mutex_unlock(&dentry->d_inode->i_mutex); | ||
912 | err = vfs_unlink(nd.path.dentry->d_inode, | ||
913 | dentry); | ||
914 | if (!err || err == -ENOENT) | ||
915 | diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c | ||
916 | index 3f653f7..500e740 100644 | ||
917 | --- a/drivers/char/tty_ldisc.c | ||
918 | +++ b/drivers/char/tty_ldisc.c | ||
919 | @@ -706,12 +706,13 @@ static void tty_reset_termios(struct tty_struct *tty) | ||
920 | /** | ||
921 | * tty_ldisc_reinit - reinitialise the tty ldisc | ||
922 | * @tty: tty to reinit | ||
923 | + * @ldisc: line discipline to reinitialize | ||
924 | * | ||
925 | - * Switch the tty back to N_TTY line discipline and leave the | ||
926 | - * ldisc state closed | ||
927 | + * Switch the tty to a line discipline and leave the ldisc | ||
928 | + * state closed | ||
929 | */ | ||
930 | |||
931 | -static void tty_ldisc_reinit(struct tty_struct *tty) | ||
932 | +static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc) | ||
933 | { | ||
934 | struct tty_ldisc *ld; | ||
935 | |||
936 | @@ -721,10 +722,10 @@ static void tty_ldisc_reinit(struct tty_struct *tty) | ||
937 | /* | ||
938 | * Switch the line discipline back | ||
939 | */ | ||
940 | - ld = tty_ldisc_get(N_TTY); | ||
941 | + ld = tty_ldisc_get(ldisc); | ||
942 | BUG_ON(IS_ERR(ld)); | ||
943 | tty_ldisc_assign(tty, ld); | ||
944 | - tty_set_termios_ldisc(tty, N_TTY); | ||
945 | + tty_set_termios_ldisc(tty, ldisc); | ||
946 | } | ||
947 | |||
948 | /** | ||
949 | @@ -745,6 +746,8 @@ static void tty_ldisc_reinit(struct tty_struct *tty) | ||
950 | void tty_ldisc_hangup(struct tty_struct *tty) | ||
951 | { | ||
952 | struct tty_ldisc *ld; | ||
953 | + int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS; | ||
954 | + int err = 0; | ||
955 | |||
956 | /* | ||
957 | * FIXME! What are the locking issues here? This may me overdoing | ||
958 | @@ -772,25 +775,32 @@ void tty_ldisc_hangup(struct tty_struct *tty) | ||
959 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); | ||
960 | /* | ||
961 | * Shutdown the current line discipline, and reset it to | ||
962 | - * N_TTY. | ||
963 | + * N_TTY if need be. | ||
964 | + * | ||
965 | + * Avoid racing set_ldisc or tty_ldisc_release | ||
966 | */ | ||
967 | - if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | ||
968 | - /* Avoid racing set_ldisc or tty_ldisc_release */ | ||
969 | - mutex_lock(&tty->ldisc_mutex); | ||
970 | - tty_ldisc_halt(tty); | ||
971 | - if (tty->ldisc) { /* Not yet closed */ | ||
972 | - /* Switch back to N_TTY */ | ||
973 | - tty_ldisc_reinit(tty); | ||
974 | - /* At this point we have a closed ldisc and we want to | ||
975 | - reopen it. We could defer this to the next open but | ||
976 | - it means auditing a lot of other paths so this is | ||
977 | - a FIXME */ | ||
978 | + mutex_lock(&tty->ldisc_mutex); | ||
979 | + tty_ldisc_halt(tty); | ||
980 | + /* At this point we have a closed ldisc and we want to | ||
981 | + reopen it. We could defer this to the next open but | ||
982 | + it means auditing a lot of other paths so this is | ||
983 | + a FIXME */ | ||
984 | + if (tty->ldisc) { /* Not yet closed */ | ||
985 | + if (reset == 0) { | ||
986 | + tty_ldisc_reinit(tty, tty->termios->c_line); | ||
987 | + err = tty_ldisc_open(tty, tty->ldisc); | ||
988 | + } | ||
989 | + /* If the re-open fails or we reset then go to N_TTY. The | ||
990 | + N_TTY open cannot fail */ | ||
991 | + if (reset || err) { | ||
992 | + tty_ldisc_reinit(tty, N_TTY); | ||
993 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); | ||
994 | - tty_ldisc_enable(tty); | ||
995 | } | ||
996 | - mutex_unlock(&tty->ldisc_mutex); | ||
997 | - tty_reset_termios(tty); | ||
998 | + tty_ldisc_enable(tty); | ||
999 | } | ||
1000 | + mutex_unlock(&tty->ldisc_mutex); | ||
1001 | + if (reset) | ||
1002 | + tty_reset_termios(tty); | ||
1003 | } | ||
1004 | |||
1005 | /** | ||
1006 | diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c | ||
1007 | index 6b3e0c2..6fe4f77 100644 | ||
1008 | --- a/drivers/clocksource/sh_cmt.c | ||
1009 | +++ b/drivers/clocksource/sh_cmt.c | ||
1010 | @@ -603,18 +603,13 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | ||
1011 | p->irqaction.handler = sh_cmt_interrupt; | ||
1012 | p->irqaction.dev_id = p; | ||
1013 | p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL; | ||
1014 | - ret = setup_irq(irq, &p->irqaction); | ||
1015 | - if (ret) { | ||
1016 | - pr_err("sh_cmt: failed to request irq %d\n", irq); | ||
1017 | - goto err1; | ||
1018 | - } | ||
1019 | |||
1020 | /* get hold of clock */ | ||
1021 | p->clk = clk_get(&p->pdev->dev, cfg->clk); | ||
1022 | if (IS_ERR(p->clk)) { | ||
1023 | pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk); | ||
1024 | ret = PTR_ERR(p->clk); | ||
1025 | - goto err2; | ||
1026 | + goto err1; | ||
1027 | } | ||
1028 | |||
1029 | if (resource_size(res) == 6) { | ||
1030 | @@ -627,14 +622,25 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | ||
1031 | p->clear_bits = ~0xc000; | ||
1032 | } | ||
1033 | |||
1034 | - return sh_cmt_register(p, cfg->name, | ||
1035 | - cfg->clockevent_rating, | ||
1036 | - cfg->clocksource_rating); | ||
1037 | - err2: | ||
1038 | - remove_irq(irq, &p->irqaction); | ||
1039 | - err1: | ||
1040 | + ret = sh_cmt_register(p, cfg->name, | ||
1041 | + cfg->clockevent_rating, | ||
1042 | + cfg->clocksource_rating); | ||
1043 | + if (ret) { | ||
1044 | + pr_err("sh_cmt: registration failed\n"); | ||
1045 | + goto err1; | ||
1046 | + } | ||
1047 | + | ||
1048 | + ret = setup_irq(irq, &p->irqaction); | ||
1049 | + if (ret) { | ||
1050 | + pr_err("sh_cmt: failed to request irq %d\n", irq); | ||
1051 | + goto err1; | ||
1052 | + } | ||
1053 | + | ||
1054 | + return 0; | ||
1055 | + | ||
1056 | +err1: | ||
1057 | iounmap(p->mapbase); | ||
1058 | - err0: | ||
1059 | +err0: | ||
1060 | return ret; | ||
1061 | } | ||
1062 | |||
1063 | diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c | ||
1064 | index 973e714..4c8a759 100644 | ||
1065 | --- a/drivers/clocksource/sh_mtu2.c | ||
1066 | +++ b/drivers/clocksource/sh_mtu2.c | ||
1067 | @@ -221,15 +221,15 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p, | ||
1068 | ced->cpumask = cpumask_of(0); | ||
1069 | ced->set_mode = sh_mtu2_clock_event_mode; | ||
1070 | |||
1071 | + pr_info("sh_mtu2: %s used for clock events\n", ced->name); | ||
1072 | + clockevents_register_device(ced); | ||
1073 | + | ||
1074 | ret = setup_irq(p->irqaction.irq, &p->irqaction); | ||
1075 | if (ret) { | ||
1076 | pr_err("sh_mtu2: failed to request irq %d\n", | ||
1077 | p->irqaction.irq); | ||
1078 | return; | ||
1079 | } | ||
1080 | - | ||
1081 | - pr_info("sh_mtu2: %s used for clock events\n", ced->name); | ||
1082 | - clockevents_register_device(ced); | ||
1083 | } | ||
1084 | |||
1085 | static int sh_mtu2_register(struct sh_mtu2_priv *p, char *name, | ||
1086 | diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c | ||
1087 | index 93c2322..961f5b5 100644 | ||
1088 | --- a/drivers/clocksource/sh_tmu.c | ||
1089 | +++ b/drivers/clocksource/sh_tmu.c | ||
1090 | @@ -323,15 +323,15 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p, | ||
1091 | ced->set_next_event = sh_tmu_clock_event_next; | ||
1092 | ced->set_mode = sh_tmu_clock_event_mode; | ||
1093 | |||
1094 | + pr_info("sh_tmu: %s used for clock events\n", ced->name); | ||
1095 | + clockevents_register_device(ced); | ||
1096 | + | ||
1097 | ret = setup_irq(p->irqaction.irq, &p->irqaction); | ||
1098 | if (ret) { | ||
1099 | pr_err("sh_tmu: failed to request irq %d\n", | ||
1100 | p->irqaction.irq); | ||
1101 | return; | ||
1102 | } | ||
1103 | - | ||
1104 | - pr_info("sh_tmu: %s used for clock events\n", ced->name); | ||
1105 | - clockevents_register_device(ced); | ||
1106 | } | ||
1107 | |||
1108 | static int sh_tmu_register(struct sh_tmu_priv *p, char *name, | ||
1109 | diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c | ||
1110 | index 0fdbe94..0c3c498 100644 | ||
1111 | --- a/drivers/gpio/cs5535-gpio.c | ||
1112 | +++ b/drivers/gpio/cs5535-gpio.c | ||
1113 | @@ -154,7 +154,7 @@ static int chip_gpio_request(struct gpio_chip *c, unsigned offset) | ||
1114 | |||
1115 | static int chip_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
1116 | { | ||
1117 | - return cs5535_gpio_isset(offset, GPIO_OUTPUT_VAL); | ||
1118 | + return cs5535_gpio_isset(offset, GPIO_READ_BACK); | ||
1119 | } | ||
1120 | |||
1121 | static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | ||
1122 | @@ -172,6 +172,7 @@ static int chip_direction_input(struct gpio_chip *c, unsigned offset) | ||
1123 | |||
1124 | spin_lock_irqsave(&chip->lock, flags); | ||
1125 | __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE); | ||
1126 | + __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE); | ||
1127 | spin_unlock_irqrestore(&chip->lock, flags); | ||
1128 | |||
1129 | return 0; | ||
1130 | @@ -184,6 +185,7 @@ static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val) | ||
1131 | |||
1132 | spin_lock_irqsave(&chip->lock, flags); | ||
1133 | |||
1134 | + __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE); | ||
1135 | __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE); | ||
1136 | if (val) | ||
1137 | __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL); | ||
1138 | diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c | ||
1139 | index b4468b6..c5a00f7 100644 | ||
1140 | --- a/drivers/gpio/wm831x-gpio.c | ||
1141 | +++ b/drivers/gpio/wm831x-gpio.c | ||
1142 | @@ -60,23 +60,31 @@ static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
1143 | return 0; | ||
1144 | } | ||
1145 | |||
1146 | -static int wm831x_gpio_direction_out(struct gpio_chip *chip, | ||
1147 | - unsigned offset, int value) | ||
1148 | +static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
1149 | { | ||
1150 | struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); | ||
1151 | struct wm831x *wm831x = wm831x_gpio->wm831x; | ||
1152 | |||
1153 | - return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, | ||
1154 | - WM831X_GPN_DIR | WM831X_GPN_TRI, 0); | ||
1155 | + wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset, | ||
1156 | + value << offset); | ||
1157 | } | ||
1158 | |||
1159 | -static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
1160 | +static int wm831x_gpio_direction_out(struct gpio_chip *chip, | ||
1161 | + unsigned offset, int value) | ||
1162 | { | ||
1163 | struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); | ||
1164 | struct wm831x *wm831x = wm831x_gpio->wm831x; | ||
1165 | + int ret; | ||
1166 | |||
1167 | - wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset, | ||
1168 | - value << offset); | ||
1169 | + ret = wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, | ||
1170 | + WM831X_GPN_DIR | WM831X_GPN_TRI, 0); | ||
1171 | + if (ret < 0) | ||
1172 | + return ret; | ||
1173 | + | ||
1174 | + /* Can only set GPIO state once it's in output mode */ | ||
1175 | + wm831x_gpio_set(chip, offset, value); | ||
1176 | + | ||
1177 | + return 0; | ||
1178 | } | ||
1179 | |||
1180 | static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
1181 | diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c | ||
1182 | index c2e8a45..93031a7 100644 | ||
1183 | --- a/drivers/gpu/drm/i915/intel_lvds.c | ||
1184 | +++ b/drivers/gpu/drm/i915/intel_lvds.c | ||
1185 | @@ -655,8 +655,15 @@ static const struct dmi_system_id bad_lid_status[] = { | ||
1186 | */ | ||
1187 | static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) | ||
1188 | { | ||
1189 | + struct drm_device *dev = connector->dev; | ||
1190 | enum drm_connector_status status = connector_status_connected; | ||
1191 | |||
1192 | + /* ACPI lid methods were generally unreliable in this generation, so | ||
1193 | + * don't even bother. | ||
1194 | + */ | ||
1195 | + if (IS_I8XX(dev)) | ||
1196 | + return connector_status_connected; | ||
1197 | + | ||
1198 | if (!dmi_check_system(bad_lid_status) && !acpi_lid_open()) | ||
1199 | status = connector_status_disconnected; | ||
1200 | |||
1201 | diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c | ||
1202 | index 82678d3..48daee5 100644 | ||
1203 | --- a/drivers/gpu/drm/i915/intel_sdvo.c | ||
1204 | +++ b/drivers/gpu/drm/i915/intel_sdvo.c | ||
1205 | @@ -35,6 +35,7 @@ | ||
1206 | #include "i915_drm.h" | ||
1207 | #include "i915_drv.h" | ||
1208 | #include "intel_sdvo_regs.h" | ||
1209 | +#include <linux/dmi.h> | ||
1210 | |||
1211 | static char *tv_format_names[] = { | ||
1212 | "NTSC_M" , "NTSC_J" , "NTSC_443", | ||
1213 | @@ -2283,6 +2284,25 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) | ||
1214 | return 0x72; | ||
1215 | } | ||
1216 | |||
1217 | +static int intel_sdvo_bad_tv_callback(const struct dmi_system_id *id) | ||
1218 | +{ | ||
1219 | + DRM_DEBUG_KMS("Ignoring bad SDVO TV connector for %s\n", id->ident); | ||
1220 | + return 1; | ||
1221 | +} | ||
1222 | + | ||
1223 | +static struct dmi_system_id intel_sdvo_bad_tv[] = { | ||
1224 | + { | ||
1225 | + .callback = intel_sdvo_bad_tv_callback, | ||
1226 | + .ident = "IntelG45/ICH10R/DME1737", | ||
1227 | + .matches = { | ||
1228 | + DMI_MATCH(DMI_SYS_VENDOR, "IBM CORPORATION"), | ||
1229 | + DMI_MATCH(DMI_PRODUCT_NAME, "4800784"), | ||
1230 | + }, | ||
1231 | + }, | ||
1232 | + | ||
1233 | + { } /* terminating entry */ | ||
1234 | +}; | ||
1235 | + | ||
1236 | static bool | ||
1237 | intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | ||
1238 | { | ||
1239 | @@ -2323,7 +2343,8 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | ||
1240 | (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
1241 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
1242 | } | ||
1243 | - } else if (flags & SDVO_OUTPUT_SVID0) { | ||
1244 | + } else if ((flags & SDVO_OUTPUT_SVID0) && | ||
1245 | + !dmi_check_system(intel_sdvo_bad_tv)) { | ||
1246 | |||
1247 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; | ||
1248 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
1249 | diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c | ||
1250 | index 7f152f6..d75788f 100644 | ||
1251 | --- a/drivers/gpu/drm/radeon/atom.c | ||
1252 | +++ b/drivers/gpu/drm/radeon/atom.c | ||
1253 | @@ -881,8 +881,6 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) | ||
1254 | uint8_t attr = U8((*ptr)++), shift; | ||
1255 | uint32_t saved, dst; | ||
1256 | int dptr = *ptr; | ||
1257 | - attr &= 0x38; | ||
1258 | - attr |= atom_def_dst[attr >> 3] << 6; | ||
1259 | SDEBUG(" dst: "); | ||
1260 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | ||
1261 | shift = atom_get_src(ctx, attr, ptr); | ||
1262 | @@ -897,8 +895,6 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg) | ||
1263 | uint8_t attr = U8((*ptr)++), shift; | ||
1264 | uint32_t saved, dst; | ||
1265 | int dptr = *ptr; | ||
1266 | - attr &= 0x38; | ||
1267 | - attr |= atom_def_dst[attr >> 3] << 6; | ||
1268 | SDEBUG(" dst: "); | ||
1269 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | ||
1270 | shift = atom_get_src(ctx, attr, ptr); | ||
1271 | diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c | ||
1272 | index 3d47a2c..a759170 100644 | ||
1273 | --- a/drivers/gpu/drm/ttm/ttm_tt.c | ||
1274 | +++ b/drivers/gpu/drm/ttm/ttm_tt.c | ||
1275 | @@ -480,7 +480,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) | ||
1276 | void *from_virtual; | ||
1277 | void *to_virtual; | ||
1278 | int i; | ||
1279 | - int ret; | ||
1280 | + int ret = -ENOMEM; | ||
1281 | |||
1282 | if (ttm->page_flags & TTM_PAGE_FLAG_USER) { | ||
1283 | ret = ttm_tt_set_user(ttm, ttm->tsk, ttm->start, | ||
1284 | @@ -499,8 +499,10 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) | ||
1285 | |||
1286 | for (i = 0; i < ttm->num_pages; ++i) { | ||
1287 | from_page = read_mapping_page(swap_space, i, NULL); | ||
1288 | - if (IS_ERR(from_page)) | ||
1289 | + if (IS_ERR(from_page)) { | ||
1290 | + ret = PTR_ERR(from_page); | ||
1291 | goto out_err; | ||
1292 | + } | ||
1293 | to_page = __ttm_tt_get_page(ttm, i); | ||
1294 | if (unlikely(to_page == NULL)) | ||
1295 | goto out_err; | ||
1296 | @@ -523,7 +525,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) | ||
1297 | return 0; | ||
1298 | out_err: | ||
1299 | ttm_tt_free_alloced_pages(ttm); | ||
1300 | - return -ENOMEM; | ||
1301 | + return ret; | ||
1302 | } | ||
1303 | |||
1304 | int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) | ||
1305 | @@ -535,6 +537,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) | ||
1306 | void *from_virtual; | ||
1307 | void *to_virtual; | ||
1308 | int i; | ||
1309 | + int ret = -ENOMEM; | ||
1310 | |||
1311 | BUG_ON(ttm->state != tt_unbound && ttm->state != tt_unpopulated); | ||
1312 | BUG_ON(ttm->caching_state != tt_cached); | ||
1313 | @@ -557,7 +560,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) | ||
1314 | 0); | ||
1315 | if (unlikely(IS_ERR(swap_storage))) { | ||
1316 | printk(KERN_ERR "Failed allocating swap storage.\n"); | ||
1317 | - return -ENOMEM; | ||
1318 | + return PTR_ERR(swap_storage); | ||
1319 | } | ||
1320 | } else | ||
1321 | swap_storage = persistant_swap_storage; | ||
1322 | @@ -569,9 +572,10 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) | ||
1323 | if (unlikely(from_page == NULL)) | ||
1324 | continue; | ||
1325 | to_page = read_mapping_page(swap_space, i, NULL); | ||
1326 | - if (unlikely(to_page == NULL)) | ||
1327 | + if (unlikely(IS_ERR(to_page))) { | ||
1328 | + ret = PTR_ERR(to_page); | ||
1329 | goto out_err; | ||
1330 | - | ||
1331 | + } | ||
1332 | preempt_disable(); | ||
1333 | from_virtual = kmap_atomic(from_page, KM_USER0); | ||
1334 | to_virtual = kmap_atomic(to_page, KM_USER1); | ||
1335 | @@ -595,5 +599,5 @@ out_err: | ||
1336 | if (!persistant_swap_storage) | ||
1337 | fput(swap_storage); | ||
1338 | |||
1339 | - return -ENOMEM; | ||
1340 | + return ret; | ||
1341 | } | ||
1342 | diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c | ||
1343 | index eabe5f8..8455f3d 100644 | ||
1344 | --- a/drivers/hid/hid-core.c | ||
1345 | +++ b/drivers/hid/hid-core.c | ||
1346 | @@ -1661,8 +1661,6 @@ static const struct hid_device_id hid_ignore_list[] = { | ||
1347 | { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, | ||
1348 | { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) }, | ||
1349 | { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, | ||
1350 | - { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, | ||
1351 | - { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, | ||
1352 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, | ||
1353 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, | ||
1354 | { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, | ||
1355 | diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h | ||
1356 | index 010368e..793691f 100644 | ||
1357 | --- a/drivers/hid/hid-ids.h | ||
1358 | +++ b/drivers/hid/hid-ids.h | ||
1359 | @@ -402,10 +402,6 @@ | ||
1360 | #define USB_VENDOR_ID_SUNPLUS 0x04fc | ||
1361 | #define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 | ||
1362 | |||
1363 | -#define USB_VENDOR_ID_TENX 0x1130 | ||
1364 | -#define USB_DEVICE_ID_TENX_IBUDDY1 0x0001 | ||
1365 | -#define USB_DEVICE_ID_TENX_IBUDDY2 0x0002 | ||
1366 | - | ||
1367 | #define USB_VENDOR_ID_THRUSTMASTER 0x044f | ||
1368 | |||
1369 | #define USB_VENDOR_ID_TOPMAX 0x0663 | ||
1370 | diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c | ||
1371 | index e2997a8..2f84237 100644 | ||
1372 | --- a/drivers/hid/usbhid/hid-core.c | ||
1373 | +++ b/drivers/hid/usbhid/hid-core.c | ||
1374 | @@ -316,6 +316,7 @@ static int hid_submit_out(struct hid_device *hid) | ||
1375 | err_hid("usb_submit_urb(out) failed"); | ||
1376 | return -1; | ||
1377 | } | ||
1378 | + usbhid->last_out = jiffies; | ||
1379 | } else { | ||
1380 | /* | ||
1381 | * queue work to wake up the device. | ||
1382 | @@ -377,6 +378,7 @@ static int hid_submit_ctrl(struct hid_device *hid) | ||
1383 | err_hid("usb_submit_urb(ctrl) failed"); | ||
1384 | return -1; | ||
1385 | } | ||
1386 | + usbhid->last_ctrl = jiffies; | ||
1387 | } else { | ||
1388 | /* | ||
1389 | * queue work to wake up the device. | ||
1390 | @@ -512,9 +514,20 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re | ||
1391 | usbhid->out[usbhid->outhead].report = report; | ||
1392 | usbhid->outhead = head; | ||
1393 | |||
1394 | - if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) | ||
1395 | + if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) { | ||
1396 | if (hid_submit_out(hid)) | ||
1397 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); | ||
1398 | + } else { | ||
1399 | + /* | ||
1400 | + * the queue is known to run | ||
1401 | + * but an earlier request may be stuck | ||
1402 | + * we may need to time out | ||
1403 | + * no race because this is called under | ||
1404 | + * spinlock | ||
1405 | + */ | ||
1406 | + if (time_after(jiffies, usbhid->last_out + HZ * 5)) | ||
1407 | + usb_unlink_urb(usbhid->urbout); | ||
1408 | + } | ||
1409 | return; | ||
1410 | } | ||
1411 | |||
1412 | @@ -535,9 +548,20 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re | ||
1413 | usbhid->ctrl[usbhid->ctrlhead].dir = dir; | ||
1414 | usbhid->ctrlhead = head; | ||
1415 | |||
1416 | - if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) | ||
1417 | + if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) { | ||
1418 | if (hid_submit_ctrl(hid)) | ||
1419 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); | ||
1420 | + } else { | ||
1421 | + /* | ||
1422 | + * the queue is known to run | ||
1423 | + * but an earlier request may be stuck | ||
1424 | + * we may need to time out | ||
1425 | + * no race because this is called under | ||
1426 | + * spinlock | ||
1427 | + */ | ||
1428 | + if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) | ||
1429 | + usb_unlink_urb(usbhid->urbctrl); | ||
1430 | + } | ||
1431 | } | ||
1432 | |||
1433 | void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) | ||
1434 | diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h | ||
1435 | index 08f505c..ec20400 100644 | ||
1436 | --- a/drivers/hid/usbhid/usbhid.h | ||
1437 | +++ b/drivers/hid/usbhid/usbhid.h | ||
1438 | @@ -80,12 +80,14 @@ struct usbhid_device { | ||
1439 | unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */ | ||
1440 | char *ctrlbuf; /* Control buffer */ | ||
1441 | dma_addr_t ctrlbuf_dma; /* Control buffer dma */ | ||
1442 | + unsigned long last_ctrl; /* record of last output for timeouts */ | ||
1443 | |||
1444 | struct urb *urbout; /* Output URB */ | ||
1445 | struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ | ||
1446 | unsigned char outhead, outtail; /* Output pipe fifo head & tail */ | ||
1447 | char *outbuf; /* Output buffer */ | ||
1448 | dma_addr_t outbuf_dma; /* Output buffer dma */ | ||
1449 | + unsigned long last_out; /* record of last output for timeouts */ | ||
1450 | |||
1451 | spinlock_t lock; /* fifo spinlock */ | ||
1452 | unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ | ||
1453 | diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c | ||
1454 | index 6c9ace1..2ad62c3 100644 | ||
1455 | --- a/drivers/hwmon/ams/ams-core.c | ||
1456 | +++ b/drivers/hwmon/ams/ams-core.c | ||
1457 | @@ -213,7 +213,7 @@ int __init ams_init(void) | ||
1458 | return -ENODEV; | ||
1459 | } | ||
1460 | |||
1461 | -void ams_exit(void) | ||
1462 | +void ams_sensor_detach(void) | ||
1463 | { | ||
1464 | /* Remove input device */ | ||
1465 | ams_input_exit(); | ||
1466 | @@ -221,9 +221,6 @@ void ams_exit(void) | ||
1467 | /* Remove attributes */ | ||
1468 | device_remove_file(&ams_info.of_dev->dev, &dev_attr_current); | ||
1469 | |||
1470 | - /* Shut down implementation */ | ||
1471 | - ams_info.exit(); | ||
1472 | - | ||
1473 | /* Flush interrupt worker | ||
1474 | * | ||
1475 | * We do this after ams_info.exit(), because an interrupt might | ||
1476 | @@ -239,6 +236,12 @@ void ams_exit(void) | ||
1477 | pmf_unregister_irq_client(&ams_freefall_client); | ||
1478 | } | ||
1479 | |||
1480 | +static void __exit ams_exit(void) | ||
1481 | +{ | ||
1482 | + /* Shut down implementation */ | ||
1483 | + ams_info.exit(); | ||
1484 | +} | ||
1485 | + | ||
1486 | MODULE_AUTHOR("Stelian Pop, Michael Hanselmann"); | ||
1487 | MODULE_DESCRIPTION("Apple Motion Sensor driver"); | ||
1488 | MODULE_LICENSE("GPL"); | ||
1489 | diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c | ||
1490 | index 2cbf8a6..abeecd2 100644 | ||
1491 | --- a/drivers/hwmon/ams/ams-i2c.c | ||
1492 | +++ b/drivers/hwmon/ams/ams-i2c.c | ||
1493 | @@ -238,6 +238,8 @@ static int ams_i2c_probe(struct i2c_client *client, | ||
1494 | static int ams_i2c_remove(struct i2c_client *client) | ||
1495 | { | ||
1496 | if (ams_info.has_device) { | ||
1497 | + ams_sensor_detach(); | ||
1498 | + | ||
1499 | /* Disable interrupts */ | ||
1500 | ams_i2c_set_irq(AMS_IRQ_ALL, 0); | ||
1501 | |||
1502 | diff --git a/drivers/hwmon/ams/ams-pmu.c b/drivers/hwmon/ams/ams-pmu.c | ||
1503 | index fb18b3d..4f61b3e 100644 | ||
1504 | --- a/drivers/hwmon/ams/ams-pmu.c | ||
1505 | +++ b/drivers/hwmon/ams/ams-pmu.c | ||
1506 | @@ -133,6 +133,8 @@ static void ams_pmu_get_xyz(s8 *x, s8 *y, s8 *z) | ||
1507 | |||
1508 | static void ams_pmu_exit(void) | ||
1509 | { | ||
1510 | + ams_sensor_detach(); | ||
1511 | + | ||
1512 | /* Disable interrupts */ | ||
1513 | ams_pmu_set_irq(AMS_IRQ_ALL, 0); | ||
1514 | |||
1515 | diff --git a/drivers/hwmon/ams/ams.h b/drivers/hwmon/ams/ams.h | ||
1516 | index 5ed387b..b28d7e2 100644 | ||
1517 | --- a/drivers/hwmon/ams/ams.h | ||
1518 | +++ b/drivers/hwmon/ams/ams.h | ||
1519 | @@ -61,6 +61,7 @@ extern struct ams ams_info; | ||
1520 | |||
1521 | extern void ams_sensors(s8 *x, s8 *y, s8 *z); | ||
1522 | extern int ams_sensor_attach(void); | ||
1523 | +extern void ams_sensor_detach(void); | ||
1524 | |||
1525 | extern int ams_pmu_init(struct device_node *np); | ||
1526 | extern int ams_i2c_init(struct device_node *np); | ||
1527 | diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c | ||
1528 | index fa07282..0627f7a 100644 | ||
1529 | --- a/drivers/hwmon/fschmd.c | ||
1530 | +++ b/drivers/hwmon/fschmd.c | ||
1531 | @@ -267,7 +267,7 @@ struct fschmd_data { | ||
1532 | struct list_head list; /* member of the watchdog_data_list */ | ||
1533 | struct kref kref; | ||
1534 | struct miscdevice watchdog_miscdev; | ||
1535 | - int kind; | ||
1536 | + enum chips kind; | ||
1537 | unsigned long watchdog_is_open; | ||
1538 | char watchdog_expect_close; | ||
1539 | char watchdog_name[10]; /* must be unique to avoid sysfs conflict */ | ||
1540 | @@ -325,8 +325,7 @@ static ssize_t show_in_value(struct device *dev, | ||
1541 | int index = to_sensor_dev_attr(devattr)->index; | ||
1542 | struct fschmd_data *data = fschmd_update_device(dev); | ||
1543 | |||
1544 | - /* fscher / fschrc - 1 as data->kind is an array index, not a chips */ | ||
1545 | - if (data->kind == (fscher - 1) || data->kind >= (fschrc - 1)) | ||
1546 | + if (data->kind == fscher || data->kind >= fschrc) | ||
1547 | return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref * | ||
1548 | dmi_mult[index]) / 255 + dmi_offset[index]); | ||
1549 | else | ||
1550 | @@ -492,7 +491,7 @@ static ssize_t show_pwm_auto_point1_pwm(struct device *dev, | ||
1551 | int val = data->fan_min[index]; | ||
1552 | |||
1553 | /* 0 = allow turning off (except on the syl), 1-255 = 50-100% */ | ||
1554 | - if (val || data->kind == fscsyl - 1) | ||
1555 | + if (val || data->kind == fscsyl) | ||
1556 | val = val / 2 + 128; | ||
1557 | |||
1558 | return sprintf(buf, "%d\n", val); | ||
1559 | @@ -506,7 +505,7 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev, | ||
1560 | unsigned long v = simple_strtoul(buf, NULL, 10); | ||
1561 | |||
1562 | /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */ | ||
1563 | - if (v || data->kind == fscsyl - 1) { | ||
1564 | + if (v || data->kind == fscsyl) { | ||
1565 | v = SENSORS_LIMIT(v, 128, 255); | ||
1566 | v = (v - 128) * 2 + 1; | ||
1567 | } | ||
1568 | @@ -1037,7 +1036,7 @@ static int fschmd_detect(struct i2c_client *client, | ||
1569 | else | ||
1570 | return -ENODEV; | ||
1571 | |||
1572 | - strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE); | ||
1573 | + strlcpy(info->type, fschmd_id[kind].name, I2C_NAME_SIZE); | ||
1574 | |||
1575 | return 0; | ||
1576 | } | ||
1577 | @@ -1065,6 +1064,7 @@ static int fschmd_probe(struct i2c_client *client, | ||
1578 | (where the client is found through a data ptr instead of the | ||
1579 | otherway around) */ | ||
1580 | data->client = client; | ||
1581 | + data->kind = kind; | ||
1582 | |||
1583 | if (kind == fscpos) { | ||
1584 | /* The Poseidon has hardwired temp limits, fill these | ||
1585 | @@ -1085,9 +1085,6 @@ static int fschmd_probe(struct i2c_client *client, | ||
1586 | } | ||
1587 | } | ||
1588 | |||
1589 | - /* i2c kind goes from 1-6, we want from 0-5 to address arrays */ | ||
1590 | - data->kind = kind - 1; | ||
1591 | - | ||
1592 | /* Read in some never changing registers */ | ||
1593 | data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION); | ||
1594 | data->global_control = i2c_smbus_read_byte_data(client, | ||
1595 | diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c | ||
1596 | index a13b30e..d14a1af 100644 | ||
1597 | --- a/drivers/hwmon/tmp401.c | ||
1598 | +++ b/drivers/hwmon/tmp401.c | ||
1599 | @@ -134,7 +134,7 @@ struct tmp401_data { | ||
1600 | struct mutex update_lock; | ||
1601 | char valid; /* zero until following fields are valid */ | ||
1602 | unsigned long last_updated; /* in jiffies */ | ||
1603 | - int kind; | ||
1604 | + enum chips kind; | ||
1605 | |||
1606 | /* register values */ | ||
1607 | u8 status; | ||
1608 | @@ -524,7 +524,7 @@ static int tmp401_detect(struct i2c_client *client, | ||
1609 | if (reg > 15) | ||
1610 | return -ENODEV; | ||
1611 | |||
1612 | - strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE); | ||
1613 | + strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE); | ||
1614 | |||
1615 | return 0; | ||
1616 | } | ||
1617 | @@ -572,8 +572,7 @@ static int tmp401_probe(struct i2c_client *client, | ||
1618 | goto exit_remove; | ||
1619 | } | ||
1620 | |||
1621 | - dev_info(&client->dev, "Detected TI %s chip\n", | ||
1622 | - names[data->kind - 1]); | ||
1623 | + dev_info(&client->dev, "Detected TI %s chip\n", names[data->kind]); | ||
1624 | |||
1625 | return 0; | ||
1626 | |||
1627 | diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c | ||
1628 | index 4f7c051..738c472 100644 | ||
1629 | --- a/drivers/hwmon/tmp421.c | ||
1630 | +++ b/drivers/hwmon/tmp421.c | ||
1631 | @@ -61,9 +61,9 @@ static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 }; | ||
1632 | #define TMP423_DEVICE_ID 0x23 | ||
1633 | |||
1634 | static const struct i2c_device_id tmp421_id[] = { | ||
1635 | - { "tmp421", tmp421 }, | ||
1636 | - { "tmp422", tmp422 }, | ||
1637 | - { "tmp423", tmp423 }, | ||
1638 | + { "tmp421", 2 }, | ||
1639 | + { "tmp422", 3 }, | ||
1640 | + { "tmp423", 4 }, | ||
1641 | { } | ||
1642 | }; | ||
1643 | MODULE_DEVICE_TABLE(i2c, tmp421_id); | ||
1644 | @@ -73,21 +73,23 @@ struct tmp421_data { | ||
1645 | struct mutex update_lock; | ||
1646 | char valid; | ||
1647 | unsigned long last_updated; | ||
1648 | - int kind; | ||
1649 | + int channels; | ||
1650 | u8 config; | ||
1651 | s16 temp[4]; | ||
1652 | }; | ||
1653 | |||
1654 | static int temp_from_s16(s16 reg) | ||
1655 | { | ||
1656 | - int temp = reg; | ||
1657 | + /* Mask out status bits */ | ||
1658 | + int temp = reg & ~0xf; | ||
1659 | |||
1660 | return (temp * 1000 + 128) / 256; | ||
1661 | } | ||
1662 | |||
1663 | static int temp_from_u16(u16 reg) | ||
1664 | { | ||
1665 | - int temp = reg; | ||
1666 | + /* Mask out status bits */ | ||
1667 | + int temp = reg & ~0xf; | ||
1668 | |||
1669 | /* Add offset for extended temperature range. */ | ||
1670 | temp -= 64 * 256; | ||
1671 | @@ -107,7 +109,7 @@ static struct tmp421_data *tmp421_update_device(struct device *dev) | ||
1672 | data->config = i2c_smbus_read_byte_data(client, | ||
1673 | TMP421_CONFIG_REG_1); | ||
1674 | |||
1675 | - for (i = 0; i <= data->kind; i++) { | ||
1676 | + for (i = 0; i < data->channels; i++) { | ||
1677 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
1678 | TMP421_TEMP_MSB[i]) << 8; | ||
1679 | data->temp[i] |= i2c_smbus_read_byte_data(client, | ||
1680 | @@ -166,7 +168,7 @@ static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a, | ||
1681 | devattr = container_of(a, struct device_attribute, attr); | ||
1682 | index = to_sensor_dev_attr(devattr)->index; | ||
1683 | |||
1684 | - if (data->kind > index) | ||
1685 | + if (index < data->channels) | ||
1686 | return a->mode; | ||
1687 | |||
1688 | return 0; | ||
1689 | @@ -252,9 +254,9 @@ static int tmp421_detect(struct i2c_client *client, | ||
1690 | return -ENODEV; | ||
1691 | } | ||
1692 | |||
1693 | - strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE); | ||
1694 | + strlcpy(info->type, tmp421_id[kind].name, I2C_NAME_SIZE); | ||
1695 | dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n", | ||
1696 | - names[kind - 1], client->addr); | ||
1697 | + names[kind], client->addr); | ||
1698 | |||
1699 | return 0; | ||
1700 | } | ||
1701 | @@ -271,7 +273,7 @@ static int tmp421_probe(struct i2c_client *client, | ||
1702 | |||
1703 | i2c_set_clientdata(client, data); | ||
1704 | mutex_init(&data->update_lock); | ||
1705 | - data->kind = id->driver_data; | ||
1706 | + data->channels = id->driver_data; | ||
1707 | |||
1708 | err = tmp421_init_client(client); | ||
1709 | if (err) | ||
1710 | diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c | ||
1711 | index 5ff47ba..58809b0 100644 | ||
1712 | --- a/drivers/macintosh/therm_adt746x.c | ||
1713 | +++ b/drivers/macintosh/therm_adt746x.c | ||
1714 | @@ -90,6 +90,8 @@ static struct task_struct *thread_therm = NULL; | ||
1715 | |||
1716 | static void write_both_fan_speed(struct thermostat *th, int speed); | ||
1717 | static void write_fan_speed(struct thermostat *th, int speed, int fan); | ||
1718 | +static void thermostat_create_files(void); | ||
1719 | +static void thermostat_remove_files(void); | ||
1720 | |||
1721 | static int | ||
1722 | write_reg(struct thermostat* th, int reg, u8 data) | ||
1723 | @@ -161,6 +163,8 @@ remove_thermostat(struct i2c_client *client) | ||
1724 | struct thermostat *th = i2c_get_clientdata(client); | ||
1725 | int i; | ||
1726 | |||
1727 | + thermostat_remove_files(); | ||
1728 | + | ||
1729 | if (thread_therm != NULL) { | ||
1730 | kthread_stop(thread_therm); | ||
1731 | } | ||
1732 | @@ -449,6 +453,8 @@ static int probe_thermostat(struct i2c_client *client, | ||
1733 | return -ENOMEM; | ||
1734 | } | ||
1735 | |||
1736 | + thermostat_create_files(); | ||
1737 | + | ||
1738 | return 0; | ||
1739 | } | ||
1740 | |||
1741 | @@ -566,7 +572,6 @@ thermostat_init(void) | ||
1742 | struct device_node* np; | ||
1743 | const u32 *prop; | ||
1744 | int i = 0, offset = 0; | ||
1745 | - int err; | ||
1746 | |||
1747 | np = of_find_node_by_name(NULL, "fan"); | ||
1748 | if (!np) | ||
1749 | @@ -633,6 +638,17 @@ thermostat_init(void) | ||
1750 | return -ENODEV; | ||
1751 | } | ||
1752 | |||
1753 | +#ifndef CONFIG_I2C_POWERMAC | ||
1754 | + request_module("i2c-powermac"); | ||
1755 | +#endif | ||
1756 | + | ||
1757 | + return i2c_add_driver(&thermostat_driver); | ||
1758 | +} | ||
1759 | + | ||
1760 | +static void thermostat_create_files(void) | ||
1761 | +{ | ||
1762 | + int err; | ||
1763 | + | ||
1764 | err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); | ||
1765 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); | ||
1766 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); | ||
1767 | @@ -647,16 +663,9 @@ thermostat_init(void) | ||
1768 | if (err) | ||
1769 | printk(KERN_WARNING | ||
1770 | "Failed to create tempertaure attribute file(s).\n"); | ||
1771 | - | ||
1772 | -#ifndef CONFIG_I2C_POWERMAC | ||
1773 | - request_module("i2c-powermac"); | ||
1774 | -#endif | ||
1775 | - | ||
1776 | - return i2c_add_driver(&thermostat_driver); | ||
1777 | } | ||
1778 | |||
1779 | -static void __exit | ||
1780 | -thermostat_exit(void) | ||
1781 | +static void thermostat_remove_files(void) | ||
1782 | { | ||
1783 | if (of_dev) { | ||
1784 | device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature); | ||
1785 | @@ -673,9 +682,14 @@ thermostat_exit(void) | ||
1786 | device_remove_file(&of_dev->dev, | ||
1787 | &dev_attr_sensor2_fan_speed); | ||
1788 | |||
1789 | - of_device_unregister(of_dev); | ||
1790 | } | ||
1791 | +} | ||
1792 | + | ||
1793 | +static void __exit | ||
1794 | +thermostat_exit(void) | ||
1795 | +{ | ||
1796 | i2c_del_driver(&thermostat_driver); | ||
1797 | + of_device_unregister(of_dev); | ||
1798 | } | ||
1799 | |||
1800 | module_init(thermostat_init); | ||
1801 | diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c | ||
1802 | index 1d66932..e3cf568 100644 | ||
1803 | --- a/drivers/md/dm-ioctl.c | ||
1804 | +++ b/drivers/md/dm-ioctl.c | ||
1805 | @@ -897,16 +897,17 @@ static int do_resume(struct dm_ioctl *param) | ||
1806 | set_disk_ro(dm_disk(md), 1); | ||
1807 | } | ||
1808 | |||
1809 | - if (dm_suspended_md(md)) | ||
1810 | + if (dm_suspended_md(md)) { | ||
1811 | r = dm_resume(md); | ||
1812 | + if (!r) | ||
1813 | + dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr); | ||
1814 | + } | ||
1815 | |||
1816 | if (old_map) | ||
1817 | dm_table_destroy(old_map); | ||
1818 | |||
1819 | - if (!r) { | ||
1820 | - dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr); | ||
1821 | + if (!r) | ||
1822 | r = __dev_status(md, param); | ||
1823 | - } | ||
1824 | |||
1825 | dm_put(md); | ||
1826 | return r; | ||
1827 | diff --git a/drivers/md/dm.c b/drivers/md/dm.c | ||
1828 | index aa4e2aa..fa786b9 100644 | ||
1829 | --- a/drivers/md/dm.c | ||
1830 | +++ b/drivers/md/dm.c | ||
1831 | @@ -635,8 +635,10 @@ static void dec_pending(struct dm_io *io, int error) | ||
1832 | if (!md->barrier_error && io_error != -EOPNOTSUPP) | ||
1833 | md->barrier_error = io_error; | ||
1834 | end_io_acct(io); | ||
1835 | + free_io(md, io); | ||
1836 | } else { | ||
1837 | end_io_acct(io); | ||
1838 | + free_io(md, io); | ||
1839 | |||
1840 | if (io_error != DM_ENDIO_REQUEUE) { | ||
1841 | trace_block_bio_complete(md->queue, bio); | ||
1842 | @@ -644,8 +646,6 @@ static void dec_pending(struct dm_io *io, int error) | ||
1843 | bio_endio(bio, io_error); | ||
1844 | } | ||
1845 | } | ||
1846 | - | ||
1847 | - free_io(md, io); | ||
1848 | } | ||
1849 | } | ||
1850 | |||
1851 | diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c | ||
1852 | index 8b8558f..b11533f 100644 | ||
1853 | --- a/drivers/media/dvb/dvb-core/dvb_net.c | ||
1854 | +++ b/drivers/media/dvb/dvb-core/dvb_net.c | ||
1855 | @@ -504,6 +504,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | ||
1856 | "bytes left in TS. Resyncing.\n", ts_remain); | ||
1857 | priv->ule_sndu_len = 0; | ||
1858 | priv->need_pusi = 1; | ||
1859 | + ts += TS_SZ; | ||
1860 | continue; | ||
1861 | } | ||
1862 | |||
1863 | diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c | ||
1864 | index 9154870..0493e40 100644 | ||
1865 | --- a/drivers/media/video/gspca/mr97310a.c | ||
1866 | +++ b/drivers/media/video/gspca/mr97310a.c | ||
1867 | @@ -697,6 +697,12 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) | ||
1868 | {0x13, 0x00, {0x01}, 1}, | ||
1869 | {0, 0, {0}, 0} | ||
1870 | }; | ||
1871 | + /* Without this command the cam won't work with USB-UHCI */ | ||
1872 | + gspca_dev->usb_buf[0] = 0x0a; | ||
1873 | + gspca_dev->usb_buf[1] = 0x00; | ||
1874 | + err_code = mr_write(gspca_dev, 2); | ||
1875 | + if (err_code < 0) | ||
1876 | + return err_code; | ||
1877 | err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, | ||
1878 | ARRAY_SIZE(cif_sensor1_init_data)); | ||
1879 | } | ||
1880 | diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c | ||
1881 | index f8d5c87..a4c0ef4 100644 | ||
1882 | --- a/drivers/media/video/soc_mediabus.c | ||
1883 | +++ b/drivers/media/video/soc_mediabus.c | ||
1884 | @@ -134,7 +134,8 @@ EXPORT_SYMBOL(soc_mbus_bytes_per_line); | ||
1885 | const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( | ||
1886 | enum v4l2_mbus_pixelcode code) | ||
1887 | { | ||
1888 | - if ((unsigned int)(code - V4L2_MBUS_FMT_FIXED) > ARRAY_SIZE(mbus_fmt)) | ||
1889 | + if (code - V4L2_MBUS_FMT_FIXED > ARRAY_SIZE(mbus_fmt) || | ||
1890 | + code <= V4L2_MBUS_FMT_FIXED) | ||
1891 | return NULL; | ||
1892 | return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1; | ||
1893 | } | ||
1894 | diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c | ||
1895 | index d96e1ab..2fdf768 100644 | ||
1896 | --- a/drivers/mmc/host/s3cmci.c | ||
1897 | +++ b/drivers/mmc/host/s3cmci.c | ||
1898 | @@ -1179,7 +1179,7 @@ static int s3cmci_card_present(struct mmc_host *mmc) | ||
1899 | struct s3c24xx_mci_pdata *pdata = host->pdata; | ||
1900 | int ret; | ||
1901 | |||
1902 | - if (pdata->gpio_detect == 0) | ||
1903 | + if (pdata->no_detect) | ||
1904 | return -ENOSYS; | ||
1905 | |||
1906 | ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1; | ||
1907 | @@ -1360,6 +1360,8 @@ static struct mmc_host_ops s3cmci_ops = { | ||
1908 | static struct s3c24xx_mci_pdata s3cmci_def_pdata = { | ||
1909 | /* This is currently here to avoid a number of if (host->pdata) | ||
1910 | * checks. Any zero fields to ensure reasonable defaults are picked. */ | ||
1911 | + .no_wprotect = 1, | ||
1912 | + .no_detect = 1, | ||
1913 | }; | ||
1914 | |||
1915 | #ifdef CONFIG_CPU_FREQ | ||
1916 | diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c | ||
1917 | index 4331d67..2a9f029 100644 | ||
1918 | --- a/drivers/net/wireless/airo.c | ||
1919 | +++ b/drivers/net/wireless/airo.c | ||
1920 | @@ -5254,11 +5254,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key, | ||
1921 | WepKeyRid wkr; | ||
1922 | int rc; | ||
1923 | |||
1924 | - if (keylen == 0) { | ||
1925 | - airo_print_err(ai->dev->name, "%s: key length to set was zero", | ||
1926 | - __func__); | ||
1927 | - return -1; | ||
1928 | - } | ||
1929 | + WARN_ON(keylen == 0); | ||
1930 | |||
1931 | memset(&wkr, 0, sizeof(wkr)); | ||
1932 | wkr.len = cpu_to_le16(sizeof(wkr)); | ||
1933 | @@ -6405,11 +6401,7 @@ static int airo_set_encode(struct net_device *dev, | ||
1934 | if (dwrq->length > MIN_KEY_SIZE) | ||
1935 | key.len = MAX_KEY_SIZE; | ||
1936 | else | ||
1937 | - if (dwrq->length > 0) | ||
1938 | - key.len = MIN_KEY_SIZE; | ||
1939 | - else | ||
1940 | - /* Disable the key */ | ||
1941 | - key.len = 0; | ||
1942 | + key.len = MIN_KEY_SIZE; | ||
1943 | /* Check if the key is not marked as invalid */ | ||
1944 | if(!(dwrq->flags & IW_ENCODE_NOKEY)) { | ||
1945 | /* Cleanup */ | ||
1946 | @@ -6590,12 +6582,22 @@ static int airo_set_encodeext(struct net_device *dev, | ||
1947 | default: | ||
1948 | return -EINVAL; | ||
1949 | } | ||
1950 | - /* Send the key to the card */ | ||
1951 | - rc = set_wep_key(local, idx, key.key, key.len, perm, 1); | ||
1952 | - if (rc < 0) { | ||
1953 | - airo_print_err(local->dev->name, "failed to set WEP key" | ||
1954 | - " at index %d: %d.", idx, rc); | ||
1955 | - return rc; | ||
1956 | + if (key.len == 0) { | ||
1957 | + rc = set_wep_tx_idx(local, idx, perm, 1); | ||
1958 | + if (rc < 0) { | ||
1959 | + airo_print_err(local->dev->name, | ||
1960 | + "failed to set WEP transmit index to %d: %d.", | ||
1961 | + idx, rc); | ||
1962 | + return rc; | ||
1963 | + } | ||
1964 | + } else { | ||
1965 | + rc = set_wep_key(local, idx, key.key, key.len, perm, 1); | ||
1966 | + if (rc < 0) { | ||
1967 | + airo_print_err(local->dev->name, | ||
1968 | + "failed to set WEP key at index %d: %d.", | ||
1969 | + idx, rc); | ||
1970 | + return rc; | ||
1971 | + } | ||
1972 | } | ||
1973 | } | ||
1974 | |||
1975 | diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h | ||
1976 | index 6a2a967..bbd2f31 100644 | ||
1977 | --- a/drivers/net/wireless/ath/ath5k/ath5k.h | ||
1978 | +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | ||
1979 | @@ -541,7 +541,6 @@ struct ath5k_txq_info { | ||
1980 | /* | ||
1981 | * Transmit packet types. | ||
1982 | * used on tx control descriptor | ||
1983 | - * TODO: Use them inside base.c corectly | ||
1984 | */ | ||
1985 | enum ath5k_pkt_type { | ||
1986 | AR5K_PKT_TYPE_NORMAL = 0, | ||
1987 | diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c | ||
1988 | index e63b7c4..d6ee8ac 100644 | ||
1989 | --- a/drivers/net/wireless/ath/ath5k/base.c | ||
1990 | +++ b/drivers/net/wireless/ath/ath5k/base.c | ||
1991 | @@ -1246,6 +1246,29 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | ||
1992 | return 0; | ||
1993 | } | ||
1994 | |||
1995 | +static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb) | ||
1996 | +{ | ||
1997 | + struct ieee80211_hdr *hdr; | ||
1998 | + enum ath5k_pkt_type htype; | ||
1999 | + __le16 fc; | ||
2000 | + | ||
2001 | + hdr = (struct ieee80211_hdr *)skb->data; | ||
2002 | + fc = hdr->frame_control; | ||
2003 | + | ||
2004 | + if (ieee80211_is_beacon(fc)) | ||
2005 | + htype = AR5K_PKT_TYPE_BEACON; | ||
2006 | + else if (ieee80211_is_probe_resp(fc)) | ||
2007 | + htype = AR5K_PKT_TYPE_PROBE_RESP; | ||
2008 | + else if (ieee80211_is_atim(fc)) | ||
2009 | + htype = AR5K_PKT_TYPE_ATIM; | ||
2010 | + else if (ieee80211_is_pspoll(fc)) | ||
2011 | + htype = AR5K_PKT_TYPE_PSPOLL; | ||
2012 | + else | ||
2013 | + htype = AR5K_PKT_TYPE_NORMAL; | ||
2014 | + | ||
2015 | + return htype; | ||
2016 | +} | ||
2017 | + | ||
2018 | static int | ||
2019 | ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | ||
2020 | struct ath5k_txq *txq) | ||
2021 | @@ -1300,7 +1323,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | ||
2022 | sc->vif, pktlen, info)); | ||
2023 | } | ||
2024 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | ||
2025 | - ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, | ||
2026 | + ieee80211_get_hdrlen_from_skb(skb), | ||
2027 | + get_hw_packet_type(skb), | ||
2028 | (sc->power_level * 2), | ||
2029 | hw_rate, | ||
2030 | info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, | ||
2031 | diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c | ||
2032 | index 1660ef1..06eaaa9 100644 | ||
2033 | --- a/drivers/net/wireless/ath/ath9k/beacon.c | ||
2034 | +++ b/drivers/net/wireless/ath/ath9k/beacon.c | ||
2035 | @@ -525,16 +525,13 @@ static void ath_beacon_config_ap(struct ath_softc *sc, | ||
2036 | { | ||
2037 | u32 nexttbtt, intval; | ||
2038 | |||
2039 | - /* Configure the timers only when the TSF has to be reset */ | ||
2040 | - | ||
2041 | - if (!(sc->sc_flags & SC_OP_TSF_RESET)) | ||
2042 | - return; | ||
2043 | - | ||
2044 | /* NB: the beacon interval is kept internally in TU's */ | ||
2045 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; | ||
2046 | intval /= ATH_BCBUF; /* for staggered beacons */ | ||
2047 | nexttbtt = intval; | ||
2048 | - intval |= ATH9K_BEACON_RESET_TSF; | ||
2049 | + | ||
2050 | + if (sc->sc_flags & SC_OP_TSF_RESET) | ||
2051 | + intval |= ATH9K_BEACON_RESET_TSF; | ||
2052 | |||
2053 | /* | ||
2054 | * In AP mode we enable the beacon timers and SWBA interrupts to | ||
2055 | diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c | ||
2056 | index ae37144..7c64aa5 100644 | ||
2057 | --- a/drivers/net/wireless/ath/ath9k/hw.c | ||
2058 | +++ b/drivers/net/wireless/ath/ath9k/hw.c | ||
2059 | @@ -1345,6 +1345,16 @@ static void ath9k_hw_override_ini(struct ath_hw *ah, | ||
2060 | * Necessary to avoid issues on AR5416 2.0 | ||
2061 | */ | ||
2062 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); | ||
2063 | + | ||
2064 | + /* | ||
2065 | + * Disable RIFS search on some chips to avoid baseband | ||
2066 | + * hang issues. | ||
2067 | + */ | ||
2068 | + if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) { | ||
2069 | + val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); | ||
2070 | + val &= ~AR_PHY_RIFS_INIT_DELAY; | ||
2071 | + REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); | ||
2072 | + } | ||
2073 | } | ||
2074 | |||
2075 | static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah, | ||
2076 | diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c | ||
2077 | index 643bea3..4faafbd 100644 | ||
2078 | --- a/drivers/net/wireless/ath/ath9k/main.c | ||
2079 | +++ b/drivers/net/wireless/ath/ath9k/main.c | ||
2080 | @@ -928,6 +928,7 @@ static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf | ||
2081 | |||
2082 | clear_bit(key->hw_key_idx + 64, common->keymap); | ||
2083 | if (common->splitmic) { | ||
2084 | + ath9k_hw_keyreset(ah, key->hw_key_idx + 32); | ||
2085 | clear_bit(key->hw_key_idx + 32, common->keymap); | ||
2086 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); | ||
2087 | } | ||
2088 | @@ -1848,6 +1849,8 @@ bad_free_hw: | ||
2089 | |||
2090 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
2091 | { | ||
2092 | + struct ath_hw *ah = sc->sc_ah; | ||
2093 | + | ||
2094 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
2095 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
2096 | IEEE80211_HW_SIGNAL_DBM | | ||
2097 | @@ -1865,7 +1868,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
2098 | BIT(NL80211_IFTYPE_ADHOC) | | ||
2099 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
2100 | |||
2101 | - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
2102 | + if (AR_SREV_5416(ah)) | ||
2103 | + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
2104 | |||
2105 | hw->queues = 4; | ||
2106 | hw->max_rates = 4; | ||
2107 | diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h | ||
2108 | index 31de27d..0999a49 100644 | ||
2109 | --- a/drivers/net/wireless/ath/ath9k/phy.h | ||
2110 | +++ b/drivers/net/wireless/ath/ath9k/phy.h | ||
2111 | @@ -384,6 +384,9 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah, | ||
2112 | |||
2113 | #define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0 | ||
2114 | |||
2115 | +#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99EC | ||
2116 | +#define AR_PHY_RIFS_INIT_DELAY 0x03ff0000 | ||
2117 | + | ||
2118 | #define AR_PHY_M_SLEEP 0x99f0 | ||
2119 | #define AR_PHY_REFCLKDLY 0x99f4 | ||
2120 | #define AR_PHY_REFCLKPD 0x99f8 | ||
2121 | diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c | ||
2122 | index 70fdb9d..1d6cf7d 100644 | ||
2123 | --- a/drivers/net/wireless/ath/ath9k/rc.c | ||
2124 | +++ b/drivers/net/wireless/ath/ath9k/rc.c | ||
2125 | @@ -668,7 +668,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | ||
2126 | struct ieee80211_tx_rate *rates = tx_info->control.rates; | ||
2127 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
2128 | __le16 fc = hdr->frame_control; | ||
2129 | - u8 try_per_rate, i = 0, rix, nrix; | ||
2130 | + u8 try_per_rate, i = 0, rix; | ||
2131 | int is_probe = 0; | ||
2132 | |||
2133 | if (rate_control_send_low(sta, priv_sta, txrc)) | ||
2134 | @@ -688,26 +688,25 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | ||
2135 | |||
2136 | rate_table = sc->cur_rate_table; | ||
2137 | rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); | ||
2138 | - nrix = rix; | ||
2139 | |||
2140 | if (is_probe) { | ||
2141 | /* set one try for probe rates. For the | ||
2142 | * probes don't enable rts */ | ||
2143 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | ||
2144 | - 1, nrix, 0); | ||
2145 | + 1, rix, 0); | ||
2146 | |||
2147 | /* Get the next tried/allowed rate. No RTS for the next series | ||
2148 | * after the probe rate | ||
2149 | */ | ||
2150 | - ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); | ||
2151 | + ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); | ||
2152 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | ||
2153 | - try_per_rate, nrix, 0); | ||
2154 | + try_per_rate, rix, 0); | ||
2155 | |||
2156 | tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
2157 | } else { | ||
2158 | /* Set the choosen rate. No RTS for first series entry. */ | ||
2159 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | ||
2160 | - try_per_rate, nrix, 0); | ||
2161 | + try_per_rate, rix, 0); | ||
2162 | } | ||
2163 | |||
2164 | /* Fill in the other rates for multirate retry */ | ||
2165 | @@ -716,10 +715,10 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | ||
2166 | if (i + 1 == 4) | ||
2167 | try_per_rate = 4; | ||
2168 | |||
2169 | - ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); | ||
2170 | + ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); | ||
2171 | /* All other rates in the series have RTS enabled */ | ||
2172 | ath_rc_rate_set_series(rate_table, &rates[i], txrc, | ||
2173 | - try_per_rate, nrix, 1); | ||
2174 | + try_per_rate, rix, 1); | ||
2175 | } | ||
2176 | |||
2177 | /* | ||
2178 | diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c | ||
2179 | index 490fb45..b59166c 100644 | ||
2180 | --- a/drivers/net/wireless/b43/main.c | ||
2181 | +++ b/drivers/net/wireless/b43/main.c | ||
2182 | @@ -3970,6 +3970,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev) | ||
2183 | } | ||
2184 | |||
2185 | /* We are ready to run. */ | ||
2186 | + ieee80211_wake_queues(dev->wl->hw); | ||
2187 | b43_set_status(dev, B43_STAT_STARTED); | ||
2188 | |||
2189 | /* Start data flow (TX/RX). */ | ||
2190 | @@ -4379,8 +4380,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | ||
2191 | |||
2192 | ieee80211_wake_queues(dev->wl->hw); | ||
2193 | |||
2194 | - ieee80211_wake_queues(dev->wl->hw); | ||
2195 | - | ||
2196 | b43_set_status(dev, B43_STAT_INITIALIZED); | ||
2197 | |||
2198 | out: | ||
2199 | diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c | ||
2200 | index 4a905b6..6d21b49 100644 | ||
2201 | --- a/drivers/net/wireless/b43legacy/main.c | ||
2202 | +++ b/drivers/net/wireless/b43legacy/main.c | ||
2203 | @@ -2921,6 +2921,7 @@ static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev) | ||
2204 | goto out; | ||
2205 | } | ||
2206 | /* We are ready to run. */ | ||
2207 | + ieee80211_wake_queues(dev->wl->hw); | ||
2208 | b43legacy_set_status(dev, B43legacy_STAT_STARTED); | ||
2209 | |||
2210 | /* Start data flow (TX/RX) */ | ||
2211 | @@ -3341,6 +3342,7 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) | ||
2212 | b43legacy_security_init(dev); | ||
2213 | b43legacy_rng_init(wl); | ||
2214 | |||
2215 | + ieee80211_wake_queues(dev->wl->hw); | ||
2216 | b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); | ||
2217 | |||
2218 | b43legacy_leds_init(dev); | ||
2219 | diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c | ||
2220 | index a72f7c2..4bf4c21 100644 | ||
2221 | --- a/drivers/net/wireless/p54/p54pci.c | ||
2222 | +++ b/drivers/net/wireless/p54/p54pci.c | ||
2223 | @@ -157,6 +157,14 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev, | ||
2224 | skb_tail_pointer(skb), | ||
2225 | priv->common.rx_mtu + 32, | ||
2226 | PCI_DMA_FROMDEVICE); | ||
2227 | + | ||
2228 | + if (pci_dma_mapping_error(priv->pdev, mapping)) { | ||
2229 | + dev_kfree_skb_any(skb); | ||
2230 | + dev_err(&priv->pdev->dev, | ||
2231 | + "RX DMA Mapping error\n"); | ||
2232 | + break; | ||
2233 | + } | ||
2234 | + | ||
2235 | desc->host_addr = cpu_to_le32(mapping); | ||
2236 | desc->device_addr = 0; // FIXME: necessary? | ||
2237 | desc->len = cpu_to_le16(priv->common.rx_mtu + 32); | ||
2238 | @@ -325,14 +333,20 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | ||
2239 | u32 device_idx, idx, i; | ||
2240 | |||
2241 | spin_lock_irqsave(&priv->lock, flags); | ||
2242 | - | ||
2243 | device_idx = le32_to_cpu(ring_control->device_idx[1]); | ||
2244 | idx = le32_to_cpu(ring_control->host_idx[1]); | ||
2245 | i = idx % ARRAY_SIZE(ring_control->tx_data); | ||
2246 | |||
2247 | - priv->tx_buf_data[i] = skb; | ||
2248 | mapping = pci_map_single(priv->pdev, skb->data, skb->len, | ||
2249 | PCI_DMA_TODEVICE); | ||
2250 | + if (pci_dma_mapping_error(priv->pdev, mapping)) { | ||
2251 | + spin_unlock_irqrestore(&priv->lock, flags); | ||
2252 | + p54_free_skb(dev, skb); | ||
2253 | + dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); | ||
2254 | + return ; | ||
2255 | + } | ||
2256 | + priv->tx_buf_data[i] = skb; | ||
2257 | + | ||
2258 | desc = &ring_control->tx_data[i]; | ||
2259 | desc->host_addr = cpu_to_le32(mapping); | ||
2260 | desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; | ||
2261 | diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c | ||
2262 | index 92af9b9..8742640 100644 | ||
2263 | --- a/drivers/net/wireless/p54/p54usb.c | ||
2264 | +++ b/drivers/net/wireless/p54/p54usb.c | ||
2265 | @@ -60,6 +60,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | ||
2266 | {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ | ||
2267 | {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ | ||
2268 | {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ | ||
2269 | + {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ | ||
2270 | {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ | ||
2271 | {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */ | ||
2272 | {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */ | ||
2273 | diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c | ||
2274 | index c1abac8..5becbde 100644 | ||
2275 | --- a/drivers/pci/hotplug/ibmphp_ebda.c | ||
2276 | +++ b/drivers/pci/hotplug/ibmphp_ebda.c | ||
2277 | @@ -245,7 +245,7 @@ static void __init print_ebda_hpc (void) | ||
2278 | |||
2279 | int __init ibmphp_access_ebda (void) | ||
2280 | { | ||
2281 | - u8 format, num_ctlrs, rio_complete, hs_complete; | ||
2282 | + u8 format, num_ctlrs, rio_complete, hs_complete, ebda_sz; | ||
2283 | u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base; | ||
2284 | int rc = 0; | ||
2285 | |||
2286 | @@ -260,7 +260,16 @@ int __init ibmphp_access_ebda (void) | ||
2287 | iounmap (io_mem); | ||
2288 | debug ("returned ebda segment: %x\n", ebda_seg); | ||
2289 | |||
2290 | - io_mem = ioremap(ebda_seg<<4, 1024); | ||
2291 | + io_mem = ioremap(ebda_seg<<4, 1); | ||
2292 | + if (!io_mem) | ||
2293 | + return -ENOMEM; | ||
2294 | + ebda_sz = readb(io_mem); | ||
2295 | + iounmap(io_mem); | ||
2296 | + debug("ebda size: %d(KiB)\n", ebda_sz); | ||
2297 | + if (ebda_sz == 0) | ||
2298 | + return -ENOMEM; | ||
2299 | + | ||
2300 | + io_mem = ioremap(ebda_seg<<4, (ebda_sz * 1024)); | ||
2301 | if (!io_mem ) | ||
2302 | return -ENOMEM; | ||
2303 | next_offset = 0x180; | ||
2304 | diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig | ||
2305 | index f526e73..11fce79 100644 | ||
2306 | --- a/drivers/platform/x86/Kconfig | ||
2307 | +++ b/drivers/platform/x86/Kconfig | ||
2308 | @@ -319,9 +319,15 @@ config THINKPAD_ACPI_VIDEO | ||
2309 | server running, phase of the moon, and the current mood of | ||
2310 | Schroedinger's cat. If you can use X.org's RandR to control | ||
2311 | your ThinkPad's video output ports instead of this feature, | ||
2312 | - don't think twice: do it and say N here to save some memory. | ||
2313 | + don't think twice: do it and say N here to save memory and avoid | ||
2314 | + bad interactions with X.org. | ||
2315 | |||
2316 | - If you are not sure, say Y here. | ||
2317 | + NOTE: access to this feature is limited to processes with the | ||
2318 | + CAP_SYS_ADMIN capability, to avoid local DoS issues in platforms | ||
2319 | + where it interacts badly with X.org. | ||
2320 | + | ||
2321 | + If you are not sure, say Y here but do try to check if you could | ||
2322 | + be using X.org RandR instead. | ||
2323 | |||
2324 | config THINKPAD_ACPI_HOTKEY_POLL | ||
2325 | bool "Support NVRAM polling for hot keys" | ||
2326 | diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c | ||
2327 | index e2be6bb..6a47bb7 100644 | ||
2328 | --- a/drivers/platform/x86/eeepc-laptop.c | ||
2329 | +++ b/drivers/platform/x86/eeepc-laptop.c | ||
2330 | @@ -1277,7 +1277,8 @@ static void eeepc_dmi_check(struct eeepc_laptop *eeepc) | ||
2331 | * hotplug code. In fact, current hotplug code seems to unplug another | ||
2332 | * device... | ||
2333 | */ | ||
2334 | - if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0) { | ||
2335 | + if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 || | ||
2336 | + strcmp(model, "1005PE") == 0) { | ||
2337 | eeepc->hotplug_disabled = true; | ||
2338 | pr_info("wlan hotplug disabled\n"); | ||
2339 | } | ||
2340 | diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c | ||
2341 | index eb603f1..e7b0c3b 100644 | ||
2342 | --- a/drivers/platform/x86/thinkpad_acpi.c | ||
2343 | +++ b/drivers/platform/x86/thinkpad_acpi.c | ||
2344 | @@ -286,6 +286,7 @@ struct ibm_init_struct { | ||
2345 | char param[32]; | ||
2346 | |||
2347 | int (*init) (struct ibm_init_struct *); | ||
2348 | + mode_t base_procfs_mode; | ||
2349 | struct ibm_struct *data; | ||
2350 | }; | ||
2351 | |||
2352 | @@ -2082,6 +2083,7 @@ static struct attribute_set *hotkey_dev_attributes; | ||
2353 | |||
2354 | static void tpacpi_driver_event(const unsigned int hkey_event); | ||
2355 | static void hotkey_driver_event(const unsigned int scancode); | ||
2356 | +static void hotkey_poll_setup(const bool may_warn); | ||
2357 | |||
2358 | /* HKEY.MHKG() return bits */ | ||
2359 | #define TP_HOTKEY_TABLET_MASK (1 << 3) | ||
2360 | @@ -2264,6 +2266,8 @@ static int tpacpi_hotkey_driver_mask_set(const u32 mask) | ||
2361 | |||
2362 | rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) & | ||
2363 | ~hotkey_source_mask); | ||
2364 | + hotkey_poll_setup(true); | ||
2365 | + | ||
2366 | mutex_unlock(&hotkey_mutex); | ||
2367 | |||
2368 | return rc; | ||
2369 | @@ -2548,7 +2552,7 @@ static void hotkey_poll_stop_sync(void) | ||
2370 | } | ||
2371 | |||
2372 | /* call with hotkey_mutex held */ | ||
2373 | -static void hotkey_poll_setup(bool may_warn) | ||
2374 | +static void hotkey_poll_setup(const bool may_warn) | ||
2375 | { | ||
2376 | const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask; | ||
2377 | const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask; | ||
2378 | @@ -2579,7 +2583,7 @@ static void hotkey_poll_setup(bool may_warn) | ||
2379 | } | ||
2380 | } | ||
2381 | |||
2382 | -static void hotkey_poll_setup_safe(bool may_warn) | ||
2383 | +static void hotkey_poll_setup_safe(const bool may_warn) | ||
2384 | { | ||
2385 | mutex_lock(&hotkey_mutex); | ||
2386 | hotkey_poll_setup(may_warn); | ||
2387 | @@ -2597,7 +2601,11 @@ static void hotkey_poll_set_freq(unsigned int freq) | ||
2388 | |||
2389 | #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ | ||
2390 | |||
2391 | -static void hotkey_poll_setup_safe(bool __unused) | ||
2392 | +static void hotkey_poll_setup(const bool __unused) | ||
2393 | +{ | ||
2394 | +} | ||
2395 | + | ||
2396 | +static void hotkey_poll_setup_safe(const bool __unused) | ||
2397 | { | ||
2398 | } | ||
2399 | |||
2400 | @@ -2607,16 +2615,11 @@ static int hotkey_inputdev_open(struct input_dev *dev) | ||
2401 | { | ||
2402 | switch (tpacpi_lifecycle) { | ||
2403 | case TPACPI_LIFE_INIT: | ||
2404 | - /* | ||
2405 | - * hotkey_init will call hotkey_poll_setup_safe | ||
2406 | - * at the appropriate moment | ||
2407 | - */ | ||
2408 | - return 0; | ||
2409 | - case TPACPI_LIFE_EXITING: | ||
2410 | - return -EBUSY; | ||
2411 | case TPACPI_LIFE_RUNNING: | ||
2412 | hotkey_poll_setup_safe(false); | ||
2413 | return 0; | ||
2414 | + case TPACPI_LIFE_EXITING: | ||
2415 | + return -EBUSY; | ||
2416 | } | ||
2417 | |||
2418 | /* Should only happen if tpacpi_lifecycle is corrupt */ | ||
2419 | @@ -2627,7 +2630,7 @@ static int hotkey_inputdev_open(struct input_dev *dev) | ||
2420 | static void hotkey_inputdev_close(struct input_dev *dev) | ||
2421 | { | ||
2422 | /* disable hotkey polling when possible */ | ||
2423 | - if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING && | ||
2424 | + if (tpacpi_lifecycle != TPACPI_LIFE_EXITING && | ||
2425 | !(hotkey_source_mask & hotkey_driver_mask)) | ||
2426 | hotkey_poll_setup_safe(false); | ||
2427 | } | ||
2428 | @@ -3655,13 +3658,19 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | ||
2429 | break; | ||
2430 | case 3: | ||
2431 | /* 0x3000-0x3FFF: bay-related wakeups */ | ||
2432 | - if (hkey == TP_HKEY_EV_BAYEJ_ACK) { | ||
2433 | + switch (hkey) { | ||
2434 | + case TP_HKEY_EV_BAYEJ_ACK: | ||
2435 | hotkey_autosleep_ack = 1; | ||
2436 | printk(TPACPI_INFO | ||
2437 | "bay ejected\n"); | ||
2438 | hotkey_wakeup_hotunplug_complete_notify_change(); | ||
2439 | known_ev = true; | ||
2440 | - } else { | ||
2441 | + break; | ||
2442 | + case TP_HKEY_EV_OPTDRV_EJ: | ||
2443 | + /* FIXME: kick libata if SATA link offline */ | ||
2444 | + known_ev = true; | ||
2445 | + break; | ||
2446 | + default: | ||
2447 | known_ev = false; | ||
2448 | } | ||
2449 | break; | ||
2450 | @@ -3870,7 +3879,7 @@ enum { | ||
2451 | TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ | ||
2452 | TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ | ||
2453 | TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume: | ||
2454 | - off / last state */ | ||
2455 | + 0 = disable, 1 = enable */ | ||
2456 | }; | ||
2457 | |||
2458 | enum { | ||
2459 | @@ -3916,10 +3925,11 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state) | ||
2460 | } | ||
2461 | #endif | ||
2462 | |||
2463 | - /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ | ||
2464 | - status = TP_ACPI_BLUETOOTH_RESUMECTRL; | ||
2465 | if (state == TPACPI_RFK_RADIO_ON) | ||
2466 | - status |= TP_ACPI_BLUETOOTH_RADIOSSW; | ||
2467 | + status = TP_ACPI_BLUETOOTH_RADIOSSW | ||
2468 | + | TP_ACPI_BLUETOOTH_RESUMECTRL; | ||
2469 | + else | ||
2470 | + status = 0; | ||
2471 | |||
2472 | if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) | ||
2473 | return -EIO; | ||
2474 | @@ -4070,7 +4080,7 @@ enum { | ||
2475 | TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ | ||
2476 | TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ | ||
2477 | TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume: | ||
2478 | - off / last state */ | ||
2479 | + 0 = disable, 1 = enable */ | ||
2480 | }; | ||
2481 | |||
2482 | #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" | ||
2483 | @@ -4107,10 +4117,11 @@ static int wan_set_status(enum tpacpi_rfkill_state state) | ||
2484 | } | ||
2485 | #endif | ||
2486 | |||
2487 | - /* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */ | ||
2488 | - status = TP_ACPI_WANCARD_RESUMECTRL; | ||
2489 | if (state == TPACPI_RFK_RADIO_ON) | ||
2490 | - status |= TP_ACPI_WANCARD_RADIOSSW; | ||
2491 | + status = TP_ACPI_WANCARD_RADIOSSW | ||
2492 | + | TP_ACPI_WANCARD_RESUMECTRL; | ||
2493 | + else | ||
2494 | + status = 0; | ||
2495 | |||
2496 | if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) | ||
2497 | return -EIO; | ||
2498 | @@ -4619,6 +4630,10 @@ static int video_read(struct seq_file *m) | ||
2499 | return 0; | ||
2500 | } | ||
2501 | |||
2502 | + /* Even reads can crash X.org, so... */ | ||
2503 | + if (!capable(CAP_SYS_ADMIN)) | ||
2504 | + return -EPERM; | ||
2505 | + | ||
2506 | status = video_outputsw_get(); | ||
2507 | if (status < 0) | ||
2508 | return status; | ||
2509 | @@ -4652,6 +4667,10 @@ static int video_write(char *buf) | ||
2510 | if (video_supported == TPACPI_VIDEO_NONE) | ||
2511 | return -ENODEV; | ||
2512 | |||
2513 | + /* Even reads can crash X.org, let alone writes... */ | ||
2514 | + if (!capable(CAP_SYS_ADMIN)) | ||
2515 | + return -EPERM; | ||
2516 | + | ||
2517 | enable = 0; | ||
2518 | disable = 0; | ||
2519 | |||
2520 | @@ -6133,13 +6152,13 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { | ||
2521 | TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ | ||
2522 | |||
2523 | /* Models with ATI GPUs that can use ECNVRAM */ | ||
2524 | - TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), | ||
2525 | + TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), /* R50,51 T40-42 */ | ||
2526 | TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | ||
2527 | - TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | ||
2528 | + TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC), /* R52 */ | ||
2529 | TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | ||
2530 | |||
2531 | /* Models with Intel Extreme Graphics 2 */ | ||
2532 | - TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), | ||
2533 | + TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), /* X40 */ | ||
2534 | TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | ||
2535 | TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | ||
2536 | |||
2537 | @@ -6522,7 +6541,8 @@ static int volume_set_status(const u8 status) | ||
2538 | return volume_set_status_ec(status); | ||
2539 | } | ||
2540 | |||
2541 | -static int volume_set_mute_ec(const bool mute) | ||
2542 | +/* returns < 0 on error, 0 on no change, 1 on change */ | ||
2543 | +static int __volume_set_mute_ec(const bool mute) | ||
2544 | { | ||
2545 | int rc; | ||
2546 | u8 s, n; | ||
2547 | @@ -6537,22 +6557,37 @@ static int volume_set_mute_ec(const bool mute) | ||
2548 | n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK : | ||
2549 | s & ~TP_EC_AUDIO_MUTESW_MSK; | ||
2550 | |||
2551 | - if (n != s) | ||
2552 | + if (n != s) { | ||
2553 | rc = volume_set_status_ec(n); | ||
2554 | + if (!rc) | ||
2555 | + rc = 1; | ||
2556 | + } | ||
2557 | |||
2558 | unlock: | ||
2559 | mutex_unlock(&volume_mutex); | ||
2560 | return rc; | ||
2561 | } | ||
2562 | |||
2563 | +static int volume_alsa_set_mute(const bool mute) | ||
2564 | +{ | ||
2565 | + dbg_printk(TPACPI_DBG_MIXER, "ALSA: trying to %smute\n", | ||
2566 | + (mute) ? "" : "un"); | ||
2567 | + return __volume_set_mute_ec(mute); | ||
2568 | +} | ||
2569 | + | ||
2570 | static int volume_set_mute(const bool mute) | ||
2571 | { | ||
2572 | + int rc; | ||
2573 | + | ||
2574 | dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n", | ||
2575 | (mute) ? "" : "un"); | ||
2576 | - return volume_set_mute_ec(mute); | ||
2577 | + | ||
2578 | + rc = __volume_set_mute_ec(mute); | ||
2579 | + return (rc < 0) ? rc : 0; | ||
2580 | } | ||
2581 | |||
2582 | -static int volume_set_volume_ec(const u8 vol) | ||
2583 | +/* returns < 0 on error, 0 on no change, 1 on change */ | ||
2584 | +static int __volume_set_volume_ec(const u8 vol) | ||
2585 | { | ||
2586 | int rc; | ||
2587 | u8 s, n; | ||
2588 | @@ -6569,19 +6604,22 @@ static int volume_set_volume_ec(const u8 vol) | ||
2589 | |||
2590 | n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol; | ||
2591 | |||
2592 | - if (n != s) | ||
2593 | + if (n != s) { | ||
2594 | rc = volume_set_status_ec(n); | ||
2595 | + if (!rc) | ||
2596 | + rc = 1; | ||
2597 | + } | ||
2598 | |||
2599 | unlock: | ||
2600 | mutex_unlock(&volume_mutex); | ||
2601 | return rc; | ||
2602 | } | ||
2603 | |||
2604 | -static int volume_set_volume(const u8 vol) | ||
2605 | +static int volume_alsa_set_volume(const u8 vol) | ||
2606 | { | ||
2607 | dbg_printk(TPACPI_DBG_MIXER, | ||
2608 | - "trying to set volume level to %hu\n", vol); | ||
2609 | - return volume_set_volume_ec(vol); | ||
2610 | + "ALSA: trying to set volume level to %hu\n", vol); | ||
2611 | + return __volume_set_volume_ec(vol); | ||
2612 | } | ||
2613 | |||
2614 | static void volume_alsa_notify_change(void) | ||
2615 | @@ -6628,7 +6666,7 @@ static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol, | ||
2616 | static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol, | ||
2617 | struct snd_ctl_elem_value *ucontrol) | ||
2618 | { | ||
2619 | - return volume_set_volume(ucontrol->value.integer.value[0]); | ||
2620 | + return volume_alsa_set_volume(ucontrol->value.integer.value[0]); | ||
2621 | } | ||
2622 | |||
2623 | #define volume_alsa_mute_info snd_ctl_boolean_mono_info | ||
2624 | @@ -6651,7 +6689,7 @@ static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol, | ||
2625 | static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol, | ||
2626 | struct snd_ctl_elem_value *ucontrol) | ||
2627 | { | ||
2628 | - return volume_set_mute(!ucontrol->value.integer.value[0]); | ||
2629 | + return volume_alsa_set_mute(!ucontrol->value.integer.value[0]); | ||
2630 | } | ||
2631 | |||
2632 | static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = { | ||
2633 | @@ -8477,9 +8515,10 @@ static int __init ibm_init(struct ibm_init_struct *iibm) | ||
2634 | "%s installed\n", ibm->name); | ||
2635 | |||
2636 | if (ibm->read) { | ||
2637 | - mode_t mode; | ||
2638 | + mode_t mode = iibm->base_procfs_mode; | ||
2639 | |||
2640 | - mode = S_IRUGO; | ||
2641 | + if (!mode) | ||
2642 | + mode = S_IRUGO; | ||
2643 | if (ibm->write) | ||
2644 | mode |= S_IWUSR; | ||
2645 | entry = proc_create_data(ibm->name, mode, proc_dir, | ||
2646 | @@ -8670,6 +8709,7 @@ static struct ibm_init_struct ibms_init[] __initdata = { | ||
2647 | #ifdef CONFIG_THINKPAD_ACPI_VIDEO | ||
2648 | { | ||
2649 | .init = video_init, | ||
2650 | + .base_procfs_mode = S_IRUSR, | ||
2651 | .data = &video_driver_data, | ||
2652 | }, | ||
2653 | #endif | ||
2654 | @@ -9032,6 +9072,9 @@ static int __init thinkpad_acpi_module_init(void) | ||
2655 | return ret; | ||
2656 | } | ||
2657 | } | ||
2658 | + | ||
2659 | + tpacpi_lifecycle = TPACPI_LIFE_RUNNING; | ||
2660 | + | ||
2661 | ret = input_register_device(tpacpi_inputdev); | ||
2662 | if (ret < 0) { | ||
2663 | printk(TPACPI_ERR "unable to register input device\n"); | ||
2664 | @@ -9041,7 +9084,6 @@ static int __init thinkpad_acpi_module_init(void) | ||
2665 | tp_features.input_device_registered = 1; | ||
2666 | } | ||
2667 | |||
2668 | - tpacpi_lifecycle = TPACPI_LIFE_RUNNING; | ||
2669 | return 0; | ||
2670 | } | ||
2671 | |||
2672 | diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c | ||
2673 | index be5a6b7..40845c7 100644 | ||
2674 | --- a/drivers/rtc/class.c | ||
2675 | +++ b/drivers/rtc/class.c | ||
2676 | @@ -226,6 +226,7 @@ static void __exit rtc_exit(void) | ||
2677 | { | ||
2678 | rtc_dev_exit(); | ||
2679 | class_destroy(rtc_class); | ||
2680 | + idr_destroy(&rtc_idr); | ||
2681 | } | ||
2682 | |||
2683 | subsys_initcall(rtc_init); | ||
2684 | diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c | ||
2685 | index 03ea530..44c4399 100644 | ||
2686 | --- a/drivers/rtc/rtc-coh901331.c | ||
2687 | +++ b/drivers/rtc/rtc-coh901331.c | ||
2688 | @@ -271,12 +271,13 @@ static int coh901331_resume(struct platform_device *pdev) | ||
2689 | { | ||
2690 | struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); | ||
2691 | |||
2692 | - if (device_may_wakeup(&pdev->dev)) | ||
2693 | + if (device_may_wakeup(&pdev->dev)) { | ||
2694 | disable_irq_wake(rtap->irq); | ||
2695 | - else | ||
2696 | + } else { | ||
2697 | clk_enable(rtap->clk); | ||
2698 | writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK); | ||
2699 | clk_disable(rtap->clk); | ||
2700 | + } | ||
2701 | return 0; | ||
2702 | } | ||
2703 | #else | ||
2704 | diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | ||
2705 | index efabea1..cd55176 100644 | ||
2706 | --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c | ||
2707 | +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | ||
2708 | @@ -5998,6 +5998,8 @@ _scsih_remove(struct pci_dev *pdev) | ||
2709 | struct _sas_port *mpt2sas_port; | ||
2710 | struct _sas_device *sas_device; | ||
2711 | struct _sas_node *expander_sibling; | ||
2712 | + struct _raid_device *raid_device, *next; | ||
2713 | + struct MPT2SAS_TARGET *sas_target_priv_data; | ||
2714 | struct workqueue_struct *wq; | ||
2715 | unsigned long flags; | ||
2716 | |||
2717 | @@ -6011,6 +6013,21 @@ _scsih_remove(struct pci_dev *pdev) | ||
2718 | if (wq) | ||
2719 | destroy_workqueue(wq); | ||
2720 | |||
2721 | + /* release all the volumes */ | ||
2722 | + list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, | ||
2723 | + list) { | ||
2724 | + if (raid_device->starget) { | ||
2725 | + sas_target_priv_data = | ||
2726 | + raid_device->starget->hostdata; | ||
2727 | + sas_target_priv_data->deleted = 1; | ||
2728 | + scsi_remove_target(&raid_device->starget->dev); | ||
2729 | + } | ||
2730 | + printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid" | ||
2731 | + "(0x%016llx)\n", ioc->name, raid_device->handle, | ||
2732 | + (unsigned long long) raid_device->wwid); | ||
2733 | + _scsih_raid_device_remove(ioc, raid_device); | ||
2734 | + } | ||
2735 | + | ||
2736 | /* free ports attached to the sas_host */ | ||
2737 | retry_again: | ||
2738 | list_for_each_entry(mpt2sas_port, | ||
2739 | diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c | ||
2740 | index 8371d91..49ac414 100644 | ||
2741 | --- a/drivers/scsi/qla1280.c | ||
2742 | +++ b/drivers/scsi/qla1280.c | ||
2743 | @@ -1640,8 +1640,10 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha) | ||
2744 | uint16_t mb[MAILBOX_REGISTER_COUNT], i; | ||
2745 | int err; | ||
2746 | |||
2747 | + spin_unlock_irq(ha->host->host_lock); | ||
2748 | err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, | ||
2749 | &ha->pdev->dev); | ||
2750 | + spin_lock_irq(ha->host->host_lock); | ||
2751 | if (err) { | ||
2752 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", | ||
2753 | ql1280_board_tbl[ha->devnum].fwname, err); | ||
2754 | @@ -1699,8 +1701,10 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) | ||
2755 | return -ENOMEM; | ||
2756 | #endif | ||
2757 | |||
2758 | + spin_unlock_irq(ha->host->host_lock); | ||
2759 | err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, | ||
2760 | &ha->pdev->dev); | ||
2761 | + spin_lock_irq(ha->host->host_lock); | ||
2762 | if (err) { | ||
2763 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", | ||
2764 | ql1280_board_tbl[ha->devnum].fwname, err); | ||
2765 | diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c | ||
2766 | index 60d665a..d00fcf8 100644 | ||
2767 | --- a/drivers/serial/imx.c | ||
2768 | +++ b/drivers/serial/imx.c | ||
2769 | @@ -1279,7 +1279,7 @@ static int serial_imx_probe(struct platform_device *pdev) | ||
2770 | sport->use_irda = 1; | ||
2771 | #endif | ||
2772 | |||
2773 | - if (pdata->init) { | ||
2774 | + if (pdata && pdata->init) { | ||
2775 | ret = pdata->init(pdev); | ||
2776 | if (ret) | ||
2777 | goto clkput; | ||
2778 | @@ -1292,7 +1292,7 @@ static int serial_imx_probe(struct platform_device *pdev) | ||
2779 | |||
2780 | return 0; | ||
2781 | deinit: | ||
2782 | - if (pdata->exit) | ||
2783 | + if (pdata && pdata->exit) | ||
2784 | pdata->exit(pdev); | ||
2785 | clkput: | ||
2786 | clk_put(sport->clk); | ||
2787 | @@ -1321,7 +1321,7 @@ static int serial_imx_remove(struct platform_device *pdev) | ||
2788 | |||
2789 | clk_disable(sport->clk); | ||
2790 | |||
2791 | - if (pdata->exit) | ||
2792 | + if (pdata && pdata->exit) | ||
2793 | pdata->exit(pdev); | ||
2794 | |||
2795 | iounmap(sport->port.membase); | ||
2796 | diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig | ||
2797 | index fc2e963..ed77d88 100644 | ||
2798 | --- a/drivers/staging/Kconfig | ||
2799 | +++ b/drivers/staging/Kconfig | ||
2800 | @@ -81,8 +81,6 @@ source "drivers/staging/rtl8192u/Kconfig" | ||
2801 | |||
2802 | source "drivers/staging/rtl8192e/Kconfig" | ||
2803 | |||
2804 | -source "drivers/staging/mimio/Kconfig" | ||
2805 | - | ||
2806 | source "drivers/staging/frontier/Kconfig" | ||
2807 | |||
2808 | source "drivers/staging/dream/Kconfig" | ||
2809 | diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile | ||
2810 | index b5e67b8..6035bff 100644 | ||
2811 | --- a/drivers/staging/Makefile | ||
2812 | +++ b/drivers/staging/Makefile | ||
2813 | @@ -23,7 +23,6 @@ obj-$(CONFIG_R8187SE) += rtl8187se/ | ||
2814 | obj-$(CONFIG_RTL8192SU) += rtl8192su/ | ||
2815 | obj-$(CONFIG_RTL8192U) += rtl8192u/ | ||
2816 | obj-$(CONFIG_RTL8192E) += rtl8192e/ | ||
2817 | -obj-$(CONFIG_INPUT_MIMIO) += mimio/ | ||
2818 | obj-$(CONFIG_TRANZPORT) += frontier/ | ||
2819 | obj-$(CONFIG_DREAM) += dream/ | ||
2820 | obj-$(CONFIG_POHMELFS) += pohmelfs/ | ||
2821 | diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c | ||
2822 | index 894eecf..6acc49a 100644 | ||
2823 | --- a/drivers/staging/hv/vmbus_drv.c | ||
2824 | +++ b/drivers/staging/hv/vmbus_drv.c | ||
2825 | @@ -24,6 +24,8 @@ | ||
2826 | #include <linux/irq.h> | ||
2827 | #include <linux/interrupt.h> | ||
2828 | #include <linux/sysctl.h> | ||
2829 | +#include <linux/pci.h> | ||
2830 | +#include <linux/dmi.h> | ||
2831 | #include "osd.h" | ||
2832 | #include "logging.h" | ||
2833 | #include "vmbus.h" | ||
2834 | @@ -946,6 +948,19 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) | ||
2835 | } | ||
2836 | } | ||
2837 | |||
2838 | +static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = { | ||
2839 | + { | ||
2840 | + .ident = "Hyper-V", | ||
2841 | + .matches = { | ||
2842 | + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), | ||
2843 | + DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), | ||
2844 | + DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), | ||
2845 | + }, | ||
2846 | + }, | ||
2847 | + { }, | ||
2848 | +}; | ||
2849 | +MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table); | ||
2850 | + | ||
2851 | static int __init vmbus_init(void) | ||
2852 | { | ||
2853 | int ret = 0; | ||
2854 | @@ -957,6 +972,9 @@ static int __init vmbus_init(void) | ||
2855 | vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel)); | ||
2856 | /* Todo: it is used for loglevel, to be ported to new kernel. */ | ||
2857 | |||
2858 | + if (!dmi_check_system(microsoft_hv_dmi_table)) | ||
2859 | + return -ENODEV; | ||
2860 | + | ||
2861 | ret = vmbus_bus_init(VmbusInitialize); | ||
2862 | |||
2863 | DPRINT_EXIT(VMBUS_DRV); | ||
2864 | @@ -973,6 +991,18 @@ static void __exit vmbus_exit(void) | ||
2865 | return; | ||
2866 | } | ||
2867 | |||
2868 | +/* | ||
2869 | + * We use a PCI table to determine if we should autoload this driver This is | ||
2870 | + * needed by distro tools to determine if the hyperv drivers should be | ||
2871 | + * installed and/or configured. We don't do anything else with the table, but | ||
2872 | + * it needs to be present. | ||
2873 | + */ | ||
2874 | +const static struct pci_device_id microsoft_hv_pci_table[] = { | ||
2875 | + { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ | ||
2876 | + { 0 } | ||
2877 | +}; | ||
2878 | +MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); | ||
2879 | + | ||
2880 | MODULE_LICENSE("GPL"); | ||
2881 | module_param(vmbus_irq, int, S_IRUGO); | ||
2882 | module_param(vmbus_loglevel, int, S_IRUGO); | ||
2883 | diff --git a/drivers/staging/mimio/Kconfig b/drivers/staging/mimio/Kconfig | ||
2884 | deleted file mode 100644 | ||
2885 | index 505dcb2..0000000 | ||
2886 | --- a/drivers/staging/mimio/Kconfig | ||
2887 | +++ /dev/null | ||
2888 | @@ -1,10 +0,0 @@ | ||
2889 | -config INPUT_MIMIO | ||
2890 | - tristate "Mimio Xi interactive whiteboard support" | ||
2891 | - depends on USB && INPUT | ||
2892 | - default N | ||
2893 | - help | ||
2894 | - Say Y here if you want to use a Mimio Xi interactive | ||
2895 | - whiteboard device. | ||
2896 | - | ||
2897 | - To compile this driver as a module, choose M here: the | ||
2898 | - module will be called mimio. | ||
2899 | diff --git a/drivers/staging/mimio/Makefile b/drivers/staging/mimio/Makefile | ||
2900 | deleted file mode 100644 | ||
2901 | index 77807ee..0000000 | ||
2902 | --- a/drivers/staging/mimio/Makefile | ||
2903 | +++ /dev/null | ||
2904 | @@ -1 +0,0 @@ | ||
2905 | -obj-$(CONFIG_INPUT_MIMIO) += mimio.o | ||
2906 | diff --git a/drivers/staging/mimio/mimio.c b/drivers/staging/mimio/mimio.c | ||
2907 | deleted file mode 100644 | ||
2908 | index 1ba8103..0000000 | ||
2909 | --- a/drivers/staging/mimio/mimio.c | ||
2910 | +++ /dev/null | ||
2911 | @@ -1,914 +0,0 @@ | ||
2912 | -/* | ||
2913 | - * Hardware event => input event mapping: | ||
2914 | - * | ||
2915 | - * | ||
2916 | - * | ||
2917 | - input.h:#define BTN_TOOL_PEN 0x140 black | ||
2918 | - input.h:#define BTN_TOOL_RUBBER 0x141 blue | ||
2919 | - input.h:#define BTN_TOOL_BRUSH 0x142 green | ||
2920 | - input.h:#define BTN_TOOL_PENCIL 0x143 red | ||
2921 | - input.h:#define BTN_TOOL_AIRBRUSH 0x144 eraser | ||
2922 | - input.h:#define BTN_TOOL_FINGER 0x145 small eraser | ||
2923 | - input.h:#define BTN_TOOL_MOUSE 0x146 mimio interactive | ||
2924 | - input.h:#define BTN_TOOL_LENS 0x147 mimio interactive but1 | ||
2925 | - input.h:#define LOCALBTN_TOOL_EXTRA1 0x14a mimio interactive but2 == BTN_TOUCH | ||
2926 | - input.h:#define LOCALBTN_TOOL_EXTRA2 0x14b mimio extra pens (orange, brown, yellow, purple) == BTN_STYLUS | ||
2927 | - input.h:#define LOCALBTN_TOOL_EXTRA3 0x14c unused == BTN_STYLUS2 | ||
2928 | - input.h:#define BTN_TOOL_DOUBLETAP 0x14d unused | ||
2929 | - input.h:#define BTN_TOOL_TRIPLETAP 0x14e unused | ||
2930 | - * | ||
2931 | - * MIMIO_EV_PENDOWN(MIMIO_PEN_K) => EV_KEY BIT(BTN_TOOL_PEN) | ||
2932 | - * MIMIO_EV_PENDOWN(MIMIO_PEN_B) => EV_KEY BIT(BTN_TOOL_RUBBER) | ||
2933 | - * MIMIO_EV_PENDOWN(MIMIO_PEN_G) => EV_KEY BIT(BTN_TOOL_BRUSH) | ||
2934 | - * MIMIO_EV_PENDOWN(MIMIO_PEN_R) => EV_KEY BIT(BTN_TOOL_PENCIL) | ||
2935 | - * MIMIO_EV_PENDOWN(MIMIO_PEN_E) => EV_KEY BIT(BTN_TOOL_AIRBRUSH) | ||
2936 | - * MIMIO_EV_PENDOWN(MIMIO_PEN_ES) => EV_KEY BIT(BTN_TOOL_FINGER) | ||
2937 | - * MIMIO_EV_PENDOWN(MIMIO_PEN_I) => EV_KEY BIT(BTN_TOOL_MOUSE) | ||
2938 | - * MIMIO_EV_PENDOWN(MIMIO_PEN_IL) => EV_KEY BIT(BTN_TOOL_LENS) | ||
2939 | - * MIMIO_EV_PENDOWN(MIMIO_PEN_IR) => EV_KEY BIT(BTN_TOOL_DOUBLETAP) | ||
2940 | - * MIMIO_EV_PENDOWN(MIMIO_PEN_EX) => EV_KEY BIT(BTN_TOOL_TRIPLETAP) | ||
2941 | - * MIMIO_EV_PENDATA => EV_ABS BIT(ABS_X), BIT(ABS_Y) | ||
2942 | - * MIMIO_EV_MEMRESET => EV_KEY BIT(BTN_0) | ||
2943 | - * MIMIO_EV_ACC(ACC_NEWPAGE) => EV_KEY BIT(BTN_1) | ||
2944 | - * MIMIO_EV_ACC(ACC_TAGPAGE) => EV_KEY BIT(BTN_2) | ||
2945 | - * MIMIO_EV_ACC(ACC_PRINTPAGE) => EV_KEY BIT(BTN_3) | ||
2946 | - * MIMIO_EV_ACC(ACC_MAXIMIZE) => EV_KEY BIT(BTN_4) | ||
2947 | - * MIMIO_EV_ACC(ACC_FINDCTLPNL) => EV_KEY BIT(BTN_5) | ||
2948 | - * | ||
2949 | - * | ||
2950 | - * open issues: | ||
2951 | - * - cold-load of data captured when mimio in standalone mode not yet | ||
2952 | - * supported; need to snoop Win32 box to see datastream for this. | ||
2953 | - * - mimio mouse not yet supported; need to snoop Win32 box to see the | ||
2954 | - * datastream for this. | ||
2955 | - */ | ||
2956 | -#include <linux/kernel.h> | ||
2957 | -#include <linux/init.h> | ||
2958 | -#include <linux/slab.h> | ||
2959 | -#include <linux/spinlock.h> | ||
2960 | -#include <linux/input.h> | ||
2961 | -#include <linux/usb.h> | ||
2962 | - | ||
2963 | -#define DRIVER_VERSION "v0.031" | ||
2964 | -#define DRIVER_AUTHOR "mwilder@cs.nmsu.edu" | ||
2965 | -#define DRIVER_DESC "USB mimio-xi driver" | ||
2966 | - | ||
2967 | -enum {UPVALUE, DOWNVALUE, MOVEVALUE}; | ||
2968 | - | ||
2969 | -#define MIMIO_XRANGE_MAX 9600 | ||
2970 | -#define MIMIO_YRANGE_MAX 4800 | ||
2971 | - | ||
2972 | -#define LOCALBTN_TOOL_EXTRA1 BTN_TOUCH | ||
2973 | -#define LOCALBTN_TOOL_EXTRA2 BTN_STYLUS | ||
2974 | -#define LOCALBTN_TOOL_EXTRA3 BTN_STYLUS2 | ||
2975 | - | ||
2976 | -#define MIMIO_VENDOR_ID 0x08d3 | ||
2977 | -#define MIMIO_PRODUCT_ID 0x0001 | ||
2978 | -#define MIMIO_MAXPAYLOAD (8) | ||
2979 | -#define MIMIO_MAXNAMELEN (64) | ||
2980 | -#define MIMIO_TXWAIT (1) | ||
2981 | -#define MIMIO_TXDONE (2) | ||
2982 | - | ||
2983 | -#define MIMIO_EV_PENDOWN (0x22) | ||
2984 | -#define MIMIO_EV_PENDATA (0x24) | ||
2985 | -#define MIMIO_EV_PENUP (0x51) | ||
2986 | -#define MIMIO_EV_MEMRESET (0x45) | ||
2987 | -#define MIMIO_EV_ACC (0xb2) | ||
2988 | - | ||
2989 | -#define MIMIO_PEN_K (1) /* black pen */ | ||
2990 | -#define MIMIO_PEN_B (2) /* blue pen */ | ||
2991 | -#define MIMIO_PEN_G (3) /* green pen */ | ||
2992 | -#define MIMIO_PEN_R (4) /* red pen */ | ||
2993 | -/* 5, 6, 7, 8 are extra pens */ | ||
2994 | -#define MIMIO_PEN_E (9) /* big eraser */ | ||
2995 | -#define MIMIO_PEN_ES (10) /* lil eraser */ | ||
2996 | -#define MIMIO_PENJUMP_START (10) | ||
2997 | -#define MIMIO_PENJUMP (6) | ||
2998 | -#define MIMIO_PEN_I (17) /* mimio interactive */ | ||
2999 | -#define MIMIO_PEN_IL (18) /* mimio interactive button 1 */ | ||
3000 | -#define MIMIO_PEN_IR (19) /* mimio interactive button 2 */ | ||
3001 | - | ||
3002 | -#define MIMIO_PEN_MAX (MIMIO_PEN_IR) | ||
3003 | - | ||
3004 | -#define ACC_DONE (0) | ||
3005 | -#define ACC_NEWPAGE (1) | ||
3006 | -#define ACC_TAGPAGE (2) | ||
3007 | -#define ACC_PRINTPAGE (4) | ||
3008 | -#define ACC_MAXIMIZE (8) | ||
3009 | -#define ACC_FINDCTLPNL (16) | ||
3010 | - | ||
3011 | -#define isvalidtxsize(n) ((n) > 0 && (n) <= MIMIO_MAXPAYLOAD) | ||
3012 | - | ||
3013 | - | ||
3014 | -struct pktbuf { | ||
3015 | - unsigned char instr; | ||
3016 | - unsigned char buf[16]; | ||
3017 | - unsigned char *p; | ||
3018 | - unsigned char *q; | ||
3019 | -}; | ||
3020 | - | ||
3021 | -struct usbintendpt { | ||
3022 | - dma_addr_t dma; | ||
3023 | - struct urb *urb; | ||
3024 | - unsigned char *buf; | ||
3025 | - struct usb_endpoint_descriptor *desc; | ||
3026 | -}; | ||
3027 | - | ||
3028 | -struct mimio { | ||
3029 | - struct input_dev *idev; | ||
3030 | - struct usb_device *udev; | ||
3031 | - struct usb_interface *uifc; | ||
3032 | - int open; | ||
3033 | - int present; | ||
3034 | - int greeted; | ||
3035 | - int txflags; | ||
3036 | - char phys[MIMIO_MAXNAMELEN]; | ||
3037 | - struct usbintendpt in; | ||
3038 | - struct usbintendpt out; | ||
3039 | - struct pktbuf pktbuf; | ||
3040 | - unsigned char minor; | ||
3041 | - wait_queue_head_t waitq; | ||
3042 | - spinlock_t txlock; | ||
3043 | - void (*rxhandler)(struct mimio *, unsigned char *, unsigned int); | ||
3044 | - int last_pen_down; | ||
3045 | -}; | ||
3046 | - | ||
3047 | -static void mimio_close(struct input_dev *); | ||
3048 | -static void mimio_dealloc(struct mimio *); | ||
3049 | -static void mimio_disconnect(struct usb_interface *); | ||
3050 | -static int mimio_greet(struct mimio *); | ||
3051 | -static void mimio_irq_in(struct urb *); | ||
3052 | -static void mimio_irq_out(struct urb *); | ||
3053 | -static int mimio_open(struct input_dev *); | ||
3054 | -static int mimio_probe(struct usb_interface *, const struct usb_device_id *); | ||
3055 | -static void mimio_rx_handler(struct mimio *, unsigned char *, unsigned int); | ||
3056 | -static int mimio_tx(struct mimio *, const char *, int); | ||
3057 | - | ||
3058 | -static char mimio_name[] = "VirtualInk mimio-Xi"; | ||
3059 | -static struct usb_device_id mimio_table [] = { | ||
3060 | - { USB_DEVICE(MIMIO_VENDOR_ID, MIMIO_PRODUCT_ID) }, | ||
3061 | - { USB_DEVICE(0x0525, 0xa4a0) }, /* gadget zero firmware */ | ||
3062 | - { } | ||
3063 | -}; | ||
3064 | - | ||
3065 | -MODULE_DEVICE_TABLE(usb, mimio_table); | ||
3066 | - | ||
3067 | -static struct usb_driver mimio_driver = { | ||
3068 | - .name = "mimio", | ||
3069 | - .probe = mimio_probe, | ||
3070 | - .disconnect = mimio_disconnect, | ||
3071 | - .id_table = mimio_table, | ||
3072 | -}; | ||
3073 | - | ||
3074 | -static DECLARE_MUTEX(disconnect_sem); | ||
3075 | - | ||
3076 | -static void mimio_close(struct input_dev *idev) | ||
3077 | -{ | ||
3078 | - struct mimio *mimio; | ||
3079 | - | ||
3080 | - mimio = input_get_drvdata(idev); | ||
3081 | - if (!mimio) { | ||
3082 | - dev_err(&idev->dev, "null mimio attached to input device\n"); | ||
3083 | - return; | ||
3084 | - } | ||
3085 | - | ||
3086 | - if (mimio->open <= 0) | ||
3087 | - dev_err(&idev->dev, "mimio not open.\n"); | ||
3088 | - else | ||
3089 | - mimio->open--; | ||
3090 | - | ||
3091 | - if (mimio->present == 0 && mimio->open == 0) | ||
3092 | - mimio_dealloc(mimio); | ||
3093 | -} | ||
3094 | - | ||
3095 | -static void mimio_dealloc(struct mimio *mimio) | ||
3096 | -{ | ||
3097 | - if (mimio == NULL) | ||
3098 | - return; | ||
3099 | - | ||
3100 | - usb_kill_urb(mimio->in.urb); | ||
3101 | - | ||
3102 | - usb_kill_urb(mimio->out.urb); | ||
3103 | - | ||
3104 | - if (mimio->idev) { | ||
3105 | - input_unregister_device(mimio->idev); | ||
3106 | - if (mimio->idev->grab) | ||
3107 | - input_close_device(mimio->idev->grab); | ||
3108 | - else | ||
3109 | - dev_dbg(&mimio->idev->dev, "mimio->idev->grab == NULL" | ||
3110 | - " -- didn't call input_close_device\n"); | ||
3111 | - } | ||
3112 | - | ||
3113 | - usb_free_urb(mimio->in.urb); | ||
3114 | - | ||
3115 | - usb_free_urb(mimio->out.urb); | ||
3116 | - | ||
3117 | - if (mimio->in.buf) { | ||
3118 | - usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->in.buf, | ||
3119 | - mimio->in.dma); | ||
3120 | - } | ||
3121 | - | ||
3122 | - if (mimio->out.buf) | ||
3123 | - usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->out.buf, | ||
3124 | - mimio->out.dma); | ||
3125 | - | ||
3126 | - if (mimio->idev) | ||
3127 | - input_free_device(mimio->idev); | ||
3128 | - | ||
3129 | - kfree(mimio); | ||
3130 | -} | ||
3131 | - | ||
3132 | -static void mimio_disconnect(struct usb_interface *ifc) | ||
3133 | -{ | ||
3134 | - struct mimio *mimio; | ||
3135 | - | ||
3136 | - down(&disconnect_sem); | ||
3137 | - | ||
3138 | - mimio = usb_get_intfdata(ifc); | ||
3139 | - usb_set_intfdata(ifc, NULL); | ||
3140 | - dev_dbg(&mimio->idev->dev, "disconnect\n"); | ||
3141 | - | ||
3142 | - if (mimio) { | ||
3143 | - mimio->present = 0; | ||
3144 | - | ||
3145 | - if (mimio->open <= 0) | ||
3146 | - mimio_dealloc(mimio); | ||
3147 | - } | ||
3148 | - | ||
3149 | - up(&disconnect_sem); | ||
3150 | -} | ||
3151 | - | ||
3152 | -static int mimio_greet(struct mimio *mimio) | ||
3153 | -{ | ||
3154 | - const struct grtpkt { | ||
3155 | - int nbytes; | ||
3156 | - unsigned delay; | ||
3157 | - char data[8]; | ||
3158 | - } grtpkts[] = { | ||
3159 | - { 3, 0, { 0x11, 0x55, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 } }, | ||
3160 | - { 5, 0, { 0x53, 0x55, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 } }, | ||
3161 | - { 5, 0, { 0x43, 0x55, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00 } }, | ||
3162 | - { 5, 0, { 0x33, 0x55, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00 } }, | ||
3163 | - { 5, 0, { 0x13, 0x00, 0x5e, 0x02, 0x4f, 0x00, 0x00, 0x00 } }, | ||
3164 | - { 5, 0, { 0x13, 0x00, 0x04, 0x03, 0x14, 0x00, 0x00, 0x00 } }, | ||
3165 | - { 5, 2, { 0x13, 0x00, 0x00, 0x04, 0x17, 0x00, 0x00, 0x00 } }, | ||
3166 | - { 5, 0, { 0x13, 0x00, 0x0d, 0x08, 0x16, 0x00, 0x00, 0x00 } }, | ||
3167 | - { 5, 0, { 0x13, 0x00, 0x4d, 0x01, 0x5f, 0x00, 0x00, 0x00 } }, | ||
3168 | - { 3, 0, { 0xf1, 0x55, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00 } }, | ||
3169 | - { 7, 2, { 0x52, 0x55, 0x00, 0x07, 0x31, 0x55, 0x64, 0x00 } }, | ||
3170 | - { 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, | ||
3171 | - }; | ||
3172 | - int rslt; | ||
3173 | - const struct grtpkt *pkt; | ||
3174 | - | ||
3175 | - for (pkt = grtpkts; pkt->nbytes; pkt++) { | ||
3176 | - rslt = mimio_tx(mimio, pkt->data, pkt->nbytes); | ||
3177 | - if (rslt) | ||
3178 | - return rslt; | ||
3179 | - if (pkt->delay) | ||
3180 | - msleep(pkt->delay); | ||
3181 | - } | ||
3182 | - | ||
3183 | - return 0; | ||
3184 | -} | ||
3185 | - | ||
3186 | -static void mimio_irq_in(struct urb *urb) | ||
3187 | -{ | ||
3188 | - int rslt; | ||
3189 | - char *data; | ||
3190 | - const char *reason = "going down"; | ||
3191 | - struct mimio *mimio; | ||
3192 | - | ||
3193 | - mimio = urb->context; | ||
3194 | - | ||
3195 | - if (mimio == NULL) | ||
3196 | - /* paranoia */ | ||
3197 | - return; | ||
3198 | - | ||
3199 | - switch (urb->status) { | ||
3200 | - case 0: | ||
3201 | - /* success */ | ||
3202 | - break; | ||
3203 | - case -ETIMEDOUT: | ||
3204 | - reason = "timeout -- unplugged?"; | ||
3205 | - case -ECONNRESET: | ||
3206 | - case -ENOENT: | ||
3207 | - case -ESHUTDOWN: | ||
3208 | - dev_dbg(&mimio->idev->dev, "%s.\n", reason); | ||
3209 | - return; | ||
3210 | - default: | ||
3211 | - dev_dbg(&mimio->idev->dev, "unknown urb-status: %d.\n", | ||
3212 | - urb->status); | ||
3213 | - goto exit; | ||
3214 | - } | ||
3215 | - data = mimio->in.buf; | ||
3216 | - | ||
3217 | - if (mimio->rxhandler) | ||
3218 | - mimio->rxhandler(mimio, data, urb->actual_length); | ||
3219 | -exit: | ||
3220 | - /* | ||
3221 | - * Keep listening to device on same urb. | ||
3222 | - */ | ||
3223 | - rslt = usb_submit_urb(urb, GFP_ATOMIC); | ||
3224 | - if (rslt) | ||
3225 | - dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n", | ||
3226 | - rslt); | ||
3227 | -} | ||
3228 | - | ||
3229 | -static void mimio_irq_out(struct urb *urb) | ||
3230 | -{ | ||
3231 | - unsigned long flags; | ||
3232 | - struct mimio *mimio; | ||
3233 | - | ||
3234 | - mimio = urb->context; | ||
3235 | - | ||
3236 | - if (urb->status) | ||
3237 | - dev_dbg(&mimio->idev->dev, "urb-status: %d.\n", urb->status); | ||
3238 | - | ||
3239 | - spin_lock_irqsave(&mimio->txlock, flags); | ||
3240 | - mimio->txflags |= MIMIO_TXDONE; | ||
3241 | - spin_unlock_irqrestore(&mimio->txlock, flags); | ||
3242 | - wmb(); | ||
3243 | - wake_up(&mimio->waitq); | ||
3244 | -} | ||
3245 | - | ||
3246 | -static int mimio_open(struct input_dev *idev) | ||
3247 | -{ | ||
3248 | - int rslt; | ||
3249 | - struct mimio *mimio; | ||
3250 | - | ||
3251 | - rslt = 0; | ||
3252 | - down(&disconnect_sem); | ||
3253 | - mimio = input_get_drvdata(idev); | ||
3254 | - dev_dbg(&idev->dev, "mimio_open\n"); | ||
3255 | - | ||
3256 | - if (mimio == NULL) { | ||
3257 | - dev_err(&idev->dev, "null mimio.\n"); | ||
3258 | - rslt = -ENODEV; | ||
3259 | - goto exit; | ||
3260 | - } | ||
3261 | - | ||
3262 | - if (mimio->open++) | ||
3263 | - goto exit; | ||
3264 | - | ||
3265 | - if (mimio->present && !mimio->greeted) { | ||
3266 | - struct urb *urb = mimio->in.urb; | ||
3267 | - mimio->in.urb->dev = mimio->udev; | ||
3268 | - rslt = usb_submit_urb(mimio->in.urb, GFP_KERNEL); | ||
3269 | - if (rslt) { | ||
3270 | - dev_err(&idev->dev, "usb_submit_urb failure " | ||
3271 | - "(res = %d: %s). Not greeting.\n", | ||
3272 | - rslt, | ||
3273 | - (!urb ? "urb is NULL" : | ||
3274 | - (urb->hcpriv ? "urb->hcpriv is non-NULL" : | ||
3275 | - (!urb->complete ? "urb is not complete" : | ||
3276 | - (urb->number_of_packets <= 0 ? "urb has no packets" : | ||
3277 | - (urb->interval <= 0 ? "urb interval too small" : | ||
3278 | - "urb interval too large or some other error")))))); | ||
3279 | - rslt = -EIO; | ||
3280 | - goto exit; | ||
3281 | - } | ||
3282 | - rslt = mimio_greet(mimio); | ||
3283 | - if (rslt == 0) { | ||
3284 | - dev_dbg(&idev->dev, "Mimio greeted OK.\n"); | ||
3285 | - mimio->greeted = 1; | ||
3286 | - } else { | ||
3287 | - dev_dbg(&idev->dev, "Mimio greet Failure (%d)\n", | ||
3288 | - rslt); | ||
3289 | - } | ||
3290 | - } | ||
3291 | - | ||
3292 | -exit: | ||
3293 | - up(&disconnect_sem); | ||
3294 | - return rslt; | ||
3295 | -} | ||
3296 | - | ||
3297 | -static int mimio_probe(struct usb_interface *ifc, | ||
3298 | - const struct usb_device_id *id) | ||
3299 | -{ | ||
3300 | - char path[64]; | ||
3301 | - int pipe, maxp; | ||
3302 | - struct mimio *mimio; | ||
3303 | - struct usb_device *udev; | ||
3304 | - struct usb_host_interface *hostifc; | ||
3305 | - struct input_dev *input_dev; | ||
3306 | - int res = 0; | ||
3307 | - int i; | ||
3308 | - | ||
3309 | - udev = interface_to_usbdev(ifc); | ||
3310 | - | ||
3311 | - mimio = kzalloc(sizeof(struct mimio), GFP_KERNEL); | ||
3312 | - if (!mimio) | ||
3313 | - return -ENOMEM; | ||
3314 | - | ||
3315 | - input_dev = input_allocate_device(); | ||
3316 | - if (!input_dev) { | ||
3317 | - mimio_dealloc(mimio); | ||
3318 | - return -ENOMEM; | ||
3319 | - } | ||
3320 | - | ||
3321 | - mimio->uifc = ifc; | ||
3322 | - mimio->udev = udev; | ||
3323 | - mimio->pktbuf.p = mimio->pktbuf.buf; | ||
3324 | - mimio->pktbuf.q = mimio->pktbuf.buf; | ||
3325 | - /* init_input_dev(mimio->idev); */ | ||
3326 | - mimio->idev = input_dev; | ||
3327 | - init_waitqueue_head(&mimio->waitq); | ||
3328 | - spin_lock_init(&mimio->txlock); | ||
3329 | - hostifc = ifc->cur_altsetting; | ||
3330 | - | ||
3331 | - if (hostifc->desc.bNumEndpoints != 2) { | ||
3332 | - dev_err(&udev->dev, "Unexpected endpoint count: %d.\n", | ||
3333 | - hostifc->desc.bNumEndpoints); | ||
3334 | - mimio_dealloc(mimio); | ||
3335 | - return -ENODEV; | ||
3336 | - } | ||
3337 | - | ||
3338 | - mimio->in.desc = &(hostifc->endpoint[0].desc); | ||
3339 | - mimio->out.desc = &(hostifc->endpoint[1].desc); | ||
3340 | - | ||
3341 | - mimio->in.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL, | ||
3342 | - &mimio->in.dma); | ||
3343 | - mimio->out.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL, | ||
3344 | - &mimio->out.dma); | ||
3345 | - | ||
3346 | - if (mimio->in.buf == NULL || mimio->out.buf == NULL) { | ||
3347 | - dev_err(&udev->dev, "usb_buffer_alloc failure.\n"); | ||
3348 | - mimio_dealloc(mimio); | ||
3349 | - return -ENOMEM; | ||
3350 | - } | ||
3351 | - | ||
3352 | - mimio->in.urb = usb_alloc_urb(0, GFP_KERNEL); | ||
3353 | - mimio->out.urb = usb_alloc_urb(0, GFP_KERNEL); | ||
3354 | - | ||
3355 | - if (mimio->in.urb == NULL || mimio->out.urb == NULL) { | ||
3356 | - dev_err(&udev->dev, "usb_alloc_urb failure.\n"); | ||
3357 | - mimio_dealloc(mimio); | ||
3358 | - return -ENOMEM; | ||
3359 | - } | ||
3360 | - | ||
3361 | - /* | ||
3362 | - * Build the input urb. | ||
3363 | - */ | ||
3364 | - pipe = usb_rcvintpipe(udev, mimio->in.desc->bEndpointAddress); | ||
3365 | - maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | ||
3366 | - if (maxp > MIMIO_MAXPAYLOAD) | ||
3367 | - maxp = MIMIO_MAXPAYLOAD; | ||
3368 | - usb_fill_int_urb(mimio->in.urb, udev, pipe, mimio->in.buf, maxp, | ||
3369 | - mimio_irq_in, mimio, mimio->in.desc->bInterval); | ||
3370 | - mimio->in.urb->transfer_dma = mimio->in.dma; | ||
3371 | - mimio->in.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
3372 | - | ||
3373 | - /* | ||
3374 | - * Build the output urb. | ||
3375 | - */ | ||
3376 | - pipe = usb_sndintpipe(udev, mimio->out.desc->bEndpointAddress); | ||
3377 | - maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | ||
3378 | - if (maxp > MIMIO_MAXPAYLOAD) | ||
3379 | - maxp = MIMIO_MAXPAYLOAD; | ||
3380 | - usb_fill_int_urb(mimio->out.urb, udev, pipe, mimio->out.buf, maxp, | ||
3381 | - mimio_irq_out, mimio, mimio->out.desc->bInterval); | ||
3382 | - mimio->out.urb->transfer_dma = mimio->out.dma; | ||
3383 | - mimio->out.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
3384 | - | ||
3385 | - /* | ||
3386 | - * Build input device info | ||
3387 | - */ | ||
3388 | - usb_make_path(udev, path, 64); | ||
3389 | - snprintf(mimio->phys, MIMIO_MAXNAMELEN, "%s/input0", path); | ||
3390 | - input_set_drvdata(input_dev, mimio); | ||
3391 | - /* input_dev->dev = &ifc->dev; */ | ||
3392 | - input_dev->open = mimio_open; | ||
3393 | - input_dev->close = mimio_close; | ||
3394 | - input_dev->name = mimio_name; | ||
3395 | - input_dev->phys = mimio->phys; | ||
3396 | - input_dev->dev.parent = &ifc->dev; | ||
3397 | - | ||
3398 | - input_dev->id.bustype = BUS_USB; | ||
3399 | - input_dev->id.vendor = le16_to_cpu(udev->descriptor.idVendor); | ||
3400 | - input_dev->id.product = le16_to_cpu(udev->descriptor.idProduct); | ||
3401 | - input_dev->id.version = le16_to_cpu(udev->descriptor.bcdDevice); | ||
3402 | - | ||
3403 | - input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); | ||
3404 | - for (i = BTN_TOOL_PEN; i <= LOCALBTN_TOOL_EXTRA2; ++i) | ||
3405 | - set_bit(i, input_dev->keybit); | ||
3406 | - | ||
3407 | - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | | ||
3408 | - BIT_MASK(BTN_1) | | ||
3409 | - BIT_MASK(BTN_2) | | ||
3410 | - BIT_MASK(BTN_3) | | ||
3411 | - BIT_MASK(BTN_4) | | ||
3412 | - BIT_MASK(BTN_5); | ||
3413 | - /* input_dev->keybit[BTN_MOUSE] |= BIT(BTN_LEFT); */ | ||
3414 | - input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y); | ||
3415 | - input_set_abs_params(input_dev, ABS_X, 0, MIMIO_XRANGE_MAX, 0, 0); | ||
3416 | - input_set_abs_params(input_dev, ABS_Y, 0, MIMIO_YRANGE_MAX, 0, 0); | ||
3417 | - input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); | ||
3418 | - | ||
3419 | -#if 0 | ||
3420 | - input_dev->absmin[ABS_X] = 0; | ||
3421 | - input_dev->absmin[ABS_Y] = 0; | ||
3422 | - input_dev->absmax[ABS_X] = 9600; | ||
3423 | - input_dev->absmax[ABS_Y] = 4800; | ||
3424 | - input_dev->absfuzz[ABS_X] = 0; | ||
3425 | - input_dev->absfuzz[ABS_Y] = 0; | ||
3426 | - input_dev->absflat[ABS_X] = 0; | ||
3427 | - input_dev->absflat[ABS_Y] = 0; | ||
3428 | -#endif | ||
3429 | - | ||
3430 | -#if 0 | ||
3431 | - /* this will just reduce the precision */ | ||
3432 | - input_dev->absfuzz[ABS_X] = 8; /* experimental; may need to change */ | ||
3433 | - input_dev->absfuzz[ABS_Y] = 8; /* experimental; may need to change */ | ||
3434 | -#endif | ||
3435 | - | ||
3436 | - /* | ||
3437 | - * Register the input device. | ||
3438 | - */ | ||
3439 | - res = input_register_device(mimio->idev); | ||
3440 | - if (res) { | ||
3441 | - dev_err(&udev->dev, "input_register_device failure (%d)\n", | ||
3442 | - res); | ||
3443 | - mimio_dealloc(mimio); | ||
3444 | - return -EIO; | ||
3445 | - } | ||
3446 | - dev_dbg(&mimio->idev->dev, "input: %s on %s (res = %d).\n", | ||
3447 | - input_dev->name, input_dev->phys, res); | ||
3448 | - | ||
3449 | - usb_set_intfdata(ifc, mimio); | ||
3450 | - mimio->present = 1; | ||
3451 | - | ||
3452 | - /* | ||
3453 | - * Submit the input urb to the usb subsystem. | ||
3454 | - */ | ||
3455 | - mimio->in.urb->dev = mimio->udev; | ||
3456 | - res = usb_submit_urb(mimio->in.urb, GFP_KERNEL); | ||
3457 | - if (res) { | ||
3458 | - dev_err(&mimio->idev->dev, "usb_submit_urb failure (%d)\n", | ||
3459 | - res); | ||
3460 | - mimio_dealloc(mimio); | ||
3461 | - return -EIO; | ||
3462 | - } | ||
3463 | - | ||
3464 | - /* | ||
3465 | - * Attempt to greet the mimio after giving | ||
3466 | - * it some post-init settling time. | ||
3467 | - * | ||
3468 | - * note: sometimes this sleep interval isn't | ||
3469 | - * long enough to permit the device to re-init | ||
3470 | - * after a hot-swap; maybe need to bump it up. | ||
3471 | - * | ||
3472 | - * As it is, this probably breaks module unloading support! | ||
3473 | - */ | ||
3474 | - msleep(1024); | ||
3475 | - | ||
3476 | - res = mimio_greet(mimio); | ||
3477 | - if (res == 0) { | ||
3478 | - dev_dbg(&mimio->idev->dev, "Mimio greeted OK.\n"); | ||
3479 | - mimio->greeted = 1; | ||
3480 | - mimio->rxhandler = mimio_rx_handler; | ||
3481 | - } else { | ||
3482 | - dev_dbg(&mimio->idev->dev, "Mimio greet Failure (%d)\n", res); | ||
3483 | - } | ||
3484 | - | ||
3485 | - return 0; | ||
3486 | -} | ||
3487 | - | ||
3488 | -static int handle_mimio_rx_penupdown(struct mimio *mimio, | ||
3489 | - int down, | ||
3490 | - const char *const instr[], | ||
3491 | - const int instr_ofst[]) | ||
3492 | -{ | ||
3493 | - int penid, x; | ||
3494 | - if (mimio->pktbuf.q - mimio->pktbuf.p < (down ? 4 : 3)) | ||
3495 | - return 1; /* partial pkt */ | ||
3496 | - | ||
3497 | - if (down) { | ||
3498 | - x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ | ||
3499 | - *(mimio->pktbuf.p + 2); | ||
3500 | - if (x != *(mimio->pktbuf.p + 3)) { | ||
3501 | - dev_dbg(&mimio->idev->dev, "EV_PEN%s: bad xsum.\n", | ||
3502 | - down ? "DOWN":"UP"); | ||
3503 | - /* skip this event data */ | ||
3504 | - mimio->pktbuf.p += 4; | ||
3505 | - /* decode any remaining events */ | ||
3506 | - return 0; | ||
3507 | - } | ||
3508 | - penid = mimio->pktbuf.instr = *(mimio->pktbuf.p + 2); | ||
3509 | - if (penid > MIMIO_PEN_MAX) { | ||
3510 | - dev_dbg(&mimio->idev->dev, | ||
3511 | - "Unmapped penID (not in [0, %d]): %d\n", | ||
3512 | - MIMIO_PEN_MAX, (int)mimio->pktbuf.instr); | ||
3513 | - penid = mimio->pktbuf.instr = 0; | ||
3514 | - } | ||
3515 | - mimio->last_pen_down = penid; | ||
3516 | - } else { | ||
3517 | - penid = mimio->last_pen_down; | ||
3518 | - } | ||
3519 | - dev_dbg(&mimio->idev->dev, "%s (id %d, code %d) %s.\n", instr[penid], | ||
3520 | - instr_ofst[penid], penid, down ? "down" : "up"); | ||
3521 | - | ||
3522 | - if (instr_ofst[penid] >= 0) { | ||
3523 | - int code = BTN_TOOL_PEN + instr_ofst[penid]; | ||
3524 | - int value = down ? DOWNVALUE : UPVALUE; | ||
3525 | - if (code > KEY_MAX) | ||
3526 | - dev_dbg(&mimio->idev->dev, "input_event will ignore " | ||
3527 | - "-- code (%d) > KEY_MAX\n", code); | ||
3528 | - if (!test_bit(code, mimio->idev->keybit)) | ||
3529 | - dev_dbg(&mimio->idev->dev, "input_event will ignore " | ||
3530 | - "-- bit for code (%d) not enabled\n", code); | ||
3531 | - if (!!test_bit(code, mimio->idev->key) == value) | ||
3532 | - dev_dbg(&mimio->idev->dev, "input_event will ignore " | ||
3533 | - "-- bit for code (%d) already set to %d\n", | ||
3534 | - code, value); | ||
3535 | - if (value != DOWNVALUE) { | ||
3536 | - /* input_regs(mimio->idev, regs); */ | ||
3537 | - input_report_key(mimio->idev, code, value); | ||
3538 | - input_sync(mimio->idev); | ||
3539 | - } else { | ||
3540 | - /* wait until we get some coordinates */ | ||
3541 | - } | ||
3542 | - } else { | ||
3543 | - dev_dbg(&mimio->idev->dev, "penID offset[%d] == %d is < 0 " | ||
3544 | - "- not sending\n", penid, instr_ofst[penid]); | ||
3545 | - } | ||
3546 | - mimio->pktbuf.p += down ? 4 : 3; /* 3 for up, 4 for down */ | ||
3547 | - return 0; | ||
3548 | -} | ||
3549 | - | ||
3550 | -/* | ||
3551 | - * Stay tuned for partial-packet excitement. | ||
3552 | - * | ||
3553 | - * This routine buffers data packets received from the mimio device | ||
3554 | - * in the mimio's data space. This buffering is necessary because | ||
3555 | - * the mimio's in endpoint can serve us partial packets of data, and | ||
3556 | - * we want the driver to support the servicing of multiple mimios. | ||
3557 | - * Empirical evidence gathered so far suggests that the method of | ||
3558 | - * buffering packet data in the mimio's data space works. Previous | ||
3559 | - * versions of this driver did not buffer packet data in each mimio's | ||
3560 | - * data-space, and were therefore not able to service multiple mimios. | ||
3561 | - * Note that since the caller of this routine is running in interrupt | ||
3562 | - * context, care needs to be taken to ensure that this routine does not | ||
3563 | - * become bloated, and it may be that another spinlock is needed in each | ||
3564 | - * mimio to guard the buffered packet data properly. | ||
3565 | - */ | ||
3566 | -static void mimio_rx_handler(struct mimio *mimio, | ||
3567 | - unsigned char *data, | ||
3568 | - unsigned int nbytes) | ||
3569 | -{ | ||
3570 | - struct device *dev = &mimio->idev->dev; | ||
3571 | - unsigned int x; | ||
3572 | - unsigned int y; | ||
3573 | - static const char * const instr[] = { | ||
3574 | - "?0", | ||
3575 | - "black pen", "blue pen", "green pen", "red pen", | ||
3576 | - "brown pen", "orange pen", "purple pen", "yellow pen", | ||
3577 | - "big eraser", "lil eraser", | ||
3578 | - "?11", "?12", "?13", "?14", "?15", "?16", | ||
3579 | - "mimio interactive", "interactive button1", | ||
3580 | - "interactive button2" | ||
3581 | - }; | ||
3582 | - | ||
3583 | - /* Mimio Interactive gives: | ||
3584 | - * down: [0x22 0x01 0x11 0x32 0x24] | ||
3585 | - * b1 : [0x22 0x01 0x12 0x31 0x24] | ||
3586 | - * b2 : [0x22 0x01 0x13 0x30 0x24] | ||
3587 | - */ | ||
3588 | - static const int instr_ofst[] = { | ||
3589 | - -1, | ||
3590 | - 0, 1, 2, 3, | ||
3591 | - 9, 9, 9, 9, | ||
3592 | - 4, 5, | ||
3593 | - -1, -1, -1, -1, -1, -1, | ||
3594 | - 6, 7, 8, | ||
3595 | - }; | ||
3596 | - | ||
3597 | - memcpy(mimio->pktbuf.q, data, nbytes); | ||
3598 | - mimio->pktbuf.q += nbytes; | ||
3599 | - | ||
3600 | - while (mimio->pktbuf.p < mimio->pktbuf.q) { | ||
3601 | - int t = *mimio->pktbuf.p; | ||
3602 | - switch (t) { | ||
3603 | - case MIMIO_EV_PENUP: | ||
3604 | - case MIMIO_EV_PENDOWN: | ||
3605 | - if (handle_mimio_rx_penupdown(mimio, | ||
3606 | - t == MIMIO_EV_PENDOWN, | ||
3607 | - instr, instr_ofst)) | ||
3608 | - return; /* partial packet */ | ||
3609 | - break; | ||
3610 | - | ||
3611 | - case MIMIO_EV_PENDATA: | ||
3612 | - if (mimio->pktbuf.q - mimio->pktbuf.p < 6) | ||
3613 | - /* partial pkt */ | ||
3614 | - return; | ||
3615 | - x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ | ||
3616 | - *(mimio->pktbuf.p + 2) ^ | ||
3617 | - *(mimio->pktbuf.p + 3) ^ | ||
3618 | - *(mimio->pktbuf.p + 4); | ||
3619 | - if (x != *(mimio->pktbuf.p + 5)) { | ||
3620 | - dev_dbg(dev, "EV_PENDATA: bad xsum.\n"); | ||
3621 | - mimio->pktbuf.p += 6; /* skip this event data */ | ||
3622 | - break; /* decode any remaining events */ | ||
3623 | - } | ||
3624 | - x = *(mimio->pktbuf.p + 1); | ||
3625 | - x <<= 8; | ||
3626 | - x |= *(mimio->pktbuf.p + 2); | ||
3627 | - y = *(mimio->pktbuf.p + 3); | ||
3628 | - y <<= 8; | ||
3629 | - y |= *(mimio->pktbuf.p + 4); | ||
3630 | - dev_dbg(dev, "coord: (%d, %d)\n", x, y); | ||
3631 | - if (instr_ofst[mimio->pktbuf.instr] >= 0) { | ||
3632 | - int code = BTN_TOOL_PEN + | ||
3633 | - instr_ofst[mimio->last_pen_down]; | ||
3634 | -#if 0 | ||
3635 | - /* Utter hack to ensure we get forwarded _AND_ | ||
3636 | - * so we can identify when a complete signal is | ||
3637 | - * received */ | ||
3638 | - mimio->idev->abs[ABS_Y] = -1; | ||
3639 | - mimio->idev->abs[ABS_X] = -1; | ||
3640 | -#endif | ||
3641 | - /* input_regs(mimio->idev, regs); */ | ||
3642 | - input_report_abs(mimio->idev, ABS_X, x); | ||
3643 | - input_report_abs(mimio->idev, ABS_Y, y); | ||
3644 | - /* fake a penup */ | ||
3645 | - change_bit(code, mimio->idev->key); | ||
3646 | - input_report_key(mimio->idev, | ||
3647 | - code, | ||
3648 | - DOWNVALUE); | ||
3649 | - /* always sync here */ | ||
3650 | - mimio->idev->sync = 0; | ||
3651 | - input_sync(mimio->idev); | ||
3652 | - } | ||
3653 | - mimio->pktbuf.p += 6; | ||
3654 | - break; | ||
3655 | - case MIMIO_EV_MEMRESET: | ||
3656 | - if (mimio->pktbuf.q - mimio->pktbuf.p < 7) | ||
3657 | - /* partial pkt */ | ||
3658 | - return; | ||
3659 | - dev_dbg(dev, "mem-reset.\n"); | ||
3660 | - /* input_regs(mimio->idev, regs); */ | ||
3661 | - input_event(mimio->idev, EV_KEY, BTN_0, 1); | ||
3662 | - input_event(mimio->idev, EV_KEY, BTN_0, 0); | ||
3663 | - input_sync(mimio->idev); | ||
3664 | - mimio->pktbuf.p += 7; | ||
3665 | - break; | ||
3666 | - case MIMIO_EV_ACC: | ||
3667 | - if (mimio->pktbuf.q - mimio->pktbuf.p < 4) | ||
3668 | - /* partial pkt */ | ||
3669 | - return; | ||
3670 | - x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ | ||
3671 | - *(mimio->pktbuf.p + 2); | ||
3672 | - if (x != *(mimio->pktbuf.p + 3)) { | ||
3673 | - dev_dbg(dev, "EV_ACC: bad xsum.\n"); | ||
3674 | - mimio->pktbuf.p += 4; /* skip this event data */ | ||
3675 | - break; /* decode any remaining events */ | ||
3676 | - } | ||
3677 | - switch (*(mimio->pktbuf.p + 2)) { | ||
3678 | - case ACC_NEWPAGE: | ||
3679 | - dev_dbg(&mimio->idev->dev, "new-page.\n"); | ||
3680 | - /* input_regs(mimio->idev, regs); */ | ||
3681 | - input_event(mimio->idev, EV_KEY, BTN_1, 1); | ||
3682 | - input_event(mimio->idev, EV_KEY, BTN_1, 0); | ||
3683 | - input_sync(mimio->idev); | ||
3684 | - break; | ||
3685 | - case ACC_TAGPAGE: | ||
3686 | - dev_dbg(&mimio->idev->dev, "tag-page.\n"); | ||
3687 | - /* input_regs(mimio->idev, regs); */ | ||
3688 | - input_event(mimio->idev, EV_KEY, BTN_2, 1); | ||
3689 | - input_event(mimio->idev, EV_KEY, BTN_2, 0); | ||
3690 | - input_sync(mimio->idev); | ||
3691 | - break; | ||
3692 | - case ACC_PRINTPAGE: | ||
3693 | - dev_dbg(&mimio->idev->dev, "print-page.\n"); | ||
3694 | - /* input_regs(mimio->idev, regs);*/ | ||
3695 | - input_event(mimio->idev, EV_KEY, BTN_3, 1); | ||
3696 | - input_event(mimio->idev, EV_KEY, BTN_3, 0); | ||
3697 | - input_sync(mimio->idev); | ||
3698 | - break; | ||
3699 | - case ACC_MAXIMIZE: | ||
3700 | - dev_dbg(&mimio->idev->dev, | ||
3701 | - "maximize-window.\n"); | ||
3702 | - /* input_regs(mimio->idev, regs); */ | ||
3703 | - input_event(mimio->idev, EV_KEY, BTN_4, 1); | ||
3704 | - input_event(mimio->idev, EV_KEY, BTN_4, 0); | ||
3705 | - input_sync(mimio->idev); | ||
3706 | - break; | ||
3707 | - case ACC_FINDCTLPNL: | ||
3708 | - dev_dbg(&mimio->idev->dev, "find-ctl-panel.\n"); | ||
3709 | - /* input_regs(mimio->idev, regs); */ | ||
3710 | - input_event(mimio->idev, EV_KEY, BTN_5, 1); | ||
3711 | - input_event(mimio->idev, EV_KEY, BTN_5, 0); | ||
3712 | - input_sync(mimio->idev); | ||
3713 | - break; | ||
3714 | - case ACC_DONE: | ||
3715 | - dev_dbg(&mimio->idev->dev, "acc-done.\n"); | ||
3716 | - /* no event is dispatched to the input | ||
3717 | - * subsystem for this device event. | ||
3718 | - */ | ||
3719 | - break; | ||
3720 | - default: | ||
3721 | - dev_dbg(dev, "unknown acc event.\n"); | ||
3722 | - break; | ||
3723 | - } | ||
3724 | - mimio->pktbuf.p += 4; | ||
3725 | - break; | ||
3726 | - default: | ||
3727 | - mimio->pktbuf.p++; | ||
3728 | - break; | ||
3729 | - } | ||
3730 | - } | ||
3731 | - | ||
3732 | - /* | ||
3733 | - * No partial event was received, so reset mimio's pktbuf ptrs. | ||
3734 | - */ | ||
3735 | - mimio->pktbuf.p = mimio->pktbuf.q = mimio->pktbuf.buf; | ||
3736 | -} | ||
3737 | - | ||
3738 | -static int mimio_tx(struct mimio *mimio, const char *buf, int nbytes) | ||
3739 | -{ | ||
3740 | - int rslt; | ||
3741 | - int timeout; | ||
3742 | - unsigned long flags; | ||
3743 | - DECLARE_WAITQUEUE(wait, current); | ||
3744 | - | ||
3745 | - if (!(isvalidtxsize(nbytes))) { | ||
3746 | - dev_err(&mimio->idev->dev, "invalid arg: nbytes: %d.\n", | ||
3747 | - nbytes); | ||
3748 | - return -EINVAL; | ||
3749 | - } | ||
3750 | - | ||
3751 | - /* | ||
3752 | - * Init the out urb and copy the data to send. | ||
3753 | - */ | ||
3754 | - mimio->out.urb->dev = mimio->udev; | ||
3755 | - mimio->out.urb->transfer_buffer_length = nbytes; | ||
3756 | - memcpy(mimio->out.urb->transfer_buffer, buf, nbytes); | ||
3757 | - | ||
3758 | - /* | ||
3759 | - * Send the data. | ||
3760 | - */ | ||
3761 | - spin_lock_irqsave(&mimio->txlock, flags); | ||
3762 | - mimio->txflags = MIMIO_TXWAIT; | ||
3763 | - rslt = usb_submit_urb(mimio->out.urb, GFP_ATOMIC); | ||
3764 | - spin_unlock_irqrestore(&mimio->txlock, flags); | ||
3765 | - dev_dbg(&mimio->idev->dev, "rslt: %d.\n", rslt); | ||
3766 | - | ||
3767 | - if (rslt) { | ||
3768 | - dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n", | ||
3769 | - rslt); | ||
3770 | - return rslt; | ||
3771 | - } | ||
3772 | - | ||
3773 | - /* | ||
3774 | - * Wait for completion to be signalled (the mimio_irq_out | ||
3775 | - * completion routine will or MIMIO_TXDONE in with txflags). | ||
3776 | - */ | ||
3777 | - timeout = HZ; | ||
3778 | - set_current_state(TASK_INTERRUPTIBLE); | ||
3779 | - add_wait_queue(&mimio->waitq, &wait); | ||
3780 | - | ||
3781 | - while (timeout && ((mimio->txflags & MIMIO_TXDONE) == 0)) { | ||
3782 | - timeout = schedule_timeout(timeout); | ||
3783 | - rmb(); | ||
3784 | - } | ||
3785 | - | ||
3786 | - if ((mimio->txflags & MIMIO_TXDONE) == 0) | ||
3787 | - dev_dbg(&mimio->idev->dev, "tx timed out.\n"); | ||
3788 | - | ||
3789 | - /* | ||
3790 | - * Now that completion has been signalled, | ||
3791 | - * unlink the urb so that it can be recycled. | ||
3792 | - */ | ||
3793 | - set_current_state(TASK_RUNNING); | ||
3794 | - remove_wait_queue(&mimio->waitq, &wait); | ||
3795 | - usb_unlink_urb(mimio->out.urb); | ||
3796 | - | ||
3797 | - return rslt; | ||
3798 | -} | ||
3799 | - | ||
3800 | -static int __init mimio_init(void) | ||
3801 | -{ | ||
3802 | - int rslt; | ||
3803 | - | ||
3804 | - rslt = usb_register(&mimio_driver); | ||
3805 | - if (rslt != 0) { | ||
3806 | - err("%s: usb_register failure: %d", __func__, rslt); | ||
3807 | - return rslt; | ||
3808 | - } | ||
3809 | - | ||
3810 | - printk(KERN_INFO KBUILD_MODNAME ":" | ||
3811 | - DRIVER_DESC " " DRIVER_VERSION "\n"); | ||
3812 | - return rslt; | ||
3813 | -} | ||
3814 | - | ||
3815 | -static void __exit mimio_exit(void) | ||
3816 | -{ | ||
3817 | - usb_deregister(&mimio_driver); | ||
3818 | -} | ||
3819 | - | ||
3820 | -module_init(mimio_init); | ||
3821 | -module_exit(mimio_exit); | ||
3822 | - | ||
3823 | -MODULE_AUTHOR(DRIVER_AUTHOR); | ||
3824 | -MODULE_DESCRIPTION(DRIVER_DESC); | ||
3825 | -MODULE_LICENSE("GPL"); | ||
3826 | diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c | ||
3827 | index f69b778..cd25811 100644 | ||
3828 | --- a/drivers/staging/pohmelfs/inode.c | ||
3829 | +++ b/drivers/staging/pohmelfs/inode.c | ||
3830 | @@ -36,6 +36,7 @@ | ||
3831 | #define POHMELFS_MAGIC_NUM 0x504f482e | ||
3832 | |||
3833 | static struct kmem_cache *pohmelfs_inode_cache; | ||
3834 | +static atomic_t psb_bdi_num = ATOMIC_INIT(0); | ||
3835 | |||
3836 | /* | ||
3837 | * Removes inode from all trees, drops local name cache and removes all queued | ||
3838 | @@ -1331,6 +1332,8 @@ static void pohmelfs_put_super(struct super_block *sb) | ||
3839 | pohmelfs_crypto_exit(psb); | ||
3840 | pohmelfs_state_exit(psb); | ||
3841 | |||
3842 | + bdi_destroy(&psb->bdi); | ||
3843 | + | ||
3844 | kfree(psb); | ||
3845 | sb->s_fs_info = NULL; | ||
3846 | } | ||
3847 | @@ -1815,11 +1818,22 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) | ||
3848 | if (!psb) | ||
3849 | goto err_out_exit; | ||
3850 | |||
3851 | + err = bdi_init(&psb->bdi); | ||
3852 | + if (err) | ||
3853 | + goto err_out_free_sb; | ||
3854 | + | ||
3855 | + err = bdi_register(&psb->bdi, NULL, "pfs-%d", atomic_inc_return(&psb_bdi_num)); | ||
3856 | + if (err) { | ||
3857 | + bdi_destroy(&psb->bdi); | ||
3858 | + goto err_out_free_sb; | ||
3859 | + } | ||
3860 | + | ||
3861 | sb->s_fs_info = psb; | ||
3862 | sb->s_op = &pohmelfs_sb_ops; | ||
3863 | sb->s_magic = POHMELFS_MAGIC_NUM; | ||
3864 | sb->s_maxbytes = MAX_LFS_FILESIZE; | ||
3865 | sb->s_blocksize = PAGE_SIZE; | ||
3866 | + sb->s_bdi = &psb->bdi; | ||
3867 | |||
3868 | psb->sb = sb; | ||
3869 | |||
3870 | @@ -1863,11 +1877,11 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) | ||
3871 | |||
3872 | err = pohmelfs_parse_options((char *) data, psb, 0); | ||
3873 | if (err) | ||
3874 | - goto err_out_free_sb; | ||
3875 | + goto err_out_free_bdi; | ||
3876 | |||
3877 | err = pohmelfs_copy_crypto(psb); | ||
3878 | if (err) | ||
3879 | - goto err_out_free_sb; | ||
3880 | + goto err_out_free_bdi; | ||
3881 | |||
3882 | err = pohmelfs_state_init(psb); | ||
3883 | if (err) | ||
3884 | @@ -1916,6 +1930,8 @@ err_out_state_exit: | ||
3885 | err_out_free_strings: | ||
3886 | kfree(psb->cipher_string); | ||
3887 | kfree(psb->hash_string); | ||
3888 | +err_out_free_bdi: | ||
3889 | + bdi_destroy(&psb->bdi); | ||
3890 | err_out_free_sb: | ||
3891 | kfree(psb); | ||
3892 | err_out_exit: | ||
3893 | diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h | ||
3894 | index 623a07d..01cba00 100644 | ||
3895 | --- a/drivers/staging/pohmelfs/netfs.h | ||
3896 | +++ b/drivers/staging/pohmelfs/netfs.h | ||
3897 | @@ -18,6 +18,7 @@ | ||
3898 | |||
3899 | #include <linux/types.h> | ||
3900 | #include <linux/connector.h> | ||
3901 | +#include <linux/backing-dev.h> | ||
3902 | |||
3903 | #define POHMELFS_CN_IDX 5 | ||
3904 | #define POHMELFS_CN_VAL 0 | ||
3905 | @@ -624,6 +625,8 @@ struct pohmelfs_sb { | ||
3906 | |||
3907 | struct super_block *sb; | ||
3908 | |||
3909 | + struct backing_dev_info bdi; | ||
3910 | + | ||
3911 | /* | ||
3912 | * Algorithm strings. | ||
3913 | */ | ||
3914 | diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig | ||
3915 | index f44294b..f1af507 100644 | ||
3916 | --- a/drivers/staging/wlan-ng/Kconfig | ||
3917 | +++ b/drivers/staging/wlan-ng/Kconfig | ||
3918 | @@ -1,6 +1,7 @@ | ||
3919 | config PRISM2_USB | ||
3920 | tristate "Prism2.5/3 USB driver" | ||
3921 | depends on WLAN && USB && WIRELESS_EXT | ||
3922 | + select WEXT_PRIV | ||
3923 | default n | ||
3924 | ---help--- | ||
3925 | This is the wlan-ng prism 2.5/3 USB driver for a wide range of | ||
3926 | diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c | ||
3927 | index 60a45f1..ca479a7 100644 | ||
3928 | --- a/drivers/usb/core/driver.c | ||
3929 | +++ b/drivers/usb/core/driver.c | ||
3930 | @@ -691,9 +691,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
3931 | { | ||
3932 | struct usb_device *usb_dev; | ||
3933 | |||
3934 | - /* driver is often null here; dev_dbg() would oops */ | ||
3935 | - pr_debug("usb %s: uevent\n", dev_name(dev)); | ||
3936 | - | ||
3937 | if (is_usb_device(dev)) { | ||
3938 | usb_dev = to_usb_device(dev); | ||
3939 | } else if (is_usb_interface(dev)) { | ||
3940 | @@ -705,6 +702,7 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
3941 | } | ||
3942 | |||
3943 | if (usb_dev->devnum < 0) { | ||
3944 | + /* driver is often null here; dev_dbg() would oops */ | ||
3945 | pr_debug("usb %s: already deleted?\n", dev_name(dev)); | ||
3946 | return -ENODEV; | ||
3947 | } | ||
3948 | diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c | ||
3949 | index 80995ef..0477616 100644 | ||
3950 | --- a/drivers/usb/core/hcd.c | ||
3951 | +++ b/drivers/usb/core/hcd.c | ||
3952 | @@ -141,7 +141,7 @@ static const u8 usb3_rh_dev_descriptor[18] = { | ||
3953 | 0x09, /* __u8 bMaxPacketSize0; 2^9 = 512 Bytes */ | ||
3954 | |||
3955 | 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ | ||
3956 | - 0x02, 0x00, /* __le16 idProduct; device 0x0002 */ | ||
3957 | + 0x03, 0x00, /* __le16 idProduct; device 0x0003 */ | ||
3958 | KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ | ||
3959 | |||
3960 | 0x03, /* __u8 iManufacturer; */ | ||
3961 | diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h | ||
3962 | index bbe2b92..89613a7 100644 | ||
3963 | --- a/drivers/usb/core/hcd.h | ||
3964 | +++ b/drivers/usb/core/hcd.h | ||
3965 | @@ -248,7 +248,7 @@ struct hc_driver { | ||
3966 | /* xHCI specific functions */ | ||
3967 | /* Called by usb_alloc_dev to alloc HC device structures */ | ||
3968 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); | ||
3969 | - /* Called by usb_release_dev to free HC device structures */ | ||
3970 | + /* Called by usb_disconnect to free HC device structures */ | ||
3971 | void (*free_dev)(struct usb_hcd *, struct usb_device *); | ||
3972 | |||
3973 | /* Bandwidth computation functions */ | ||
3974 | diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c | ||
3975 | index 35cc8b9..9cc0aba 100644 | ||
3976 | --- a/drivers/usb/core/hub.c | ||
3977 | +++ b/drivers/usb/core/hub.c | ||
3978 | @@ -1554,6 +1554,15 @@ static inline void usb_stop_pm(struct usb_device *udev) | ||
3979 | |||
3980 | #endif | ||
3981 | |||
3982 | +static void hub_free_dev(struct usb_device *udev) | ||
3983 | +{ | ||
3984 | + struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
3985 | + | ||
3986 | + /* Root hubs aren't real devices, so don't free HCD resources */ | ||
3987 | + if (hcd->driver->free_dev && udev->parent) | ||
3988 | + hcd->driver->free_dev(hcd, udev); | ||
3989 | +} | ||
3990 | + | ||
3991 | /** | ||
3992 | * usb_disconnect - disconnect a device (usbcore-internal) | ||
3993 | * @pdev: pointer to device being disconnected | ||
3994 | @@ -1624,6 +1633,8 @@ void usb_disconnect(struct usb_device **pdev) | ||
3995 | |||
3996 | usb_stop_pm(udev); | ||
3997 | |||
3998 | + hub_free_dev(udev); | ||
3999 | + | ||
4000 | put_device(&udev->dev); | ||
4001 | } | ||
4002 | |||
4003 | @@ -3191,6 +3202,7 @@ loop_disable: | ||
4004 | loop: | ||
4005 | usb_ep0_reinit(udev); | ||
4006 | release_address(udev); | ||
4007 | + hub_free_dev(udev); | ||
4008 | usb_put_dev(udev); | ||
4009 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) | ||
4010 | break; | ||
4011 | diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c | ||
4012 | index 0daff0d..ced0776 100644 | ||
4013 | --- a/drivers/usb/core/usb.c | ||
4014 | +++ b/drivers/usb/core/usb.c | ||
4015 | @@ -228,9 +228,6 @@ static void usb_release_dev(struct device *dev) | ||
4016 | hcd = bus_to_hcd(udev->bus); | ||
4017 | |||
4018 | usb_destroy_configuration(udev); | ||
4019 | - /* Root hubs aren't real devices, so don't free HCD resources */ | ||
4020 | - if (hcd->driver->free_dev && udev->parent) | ||
4021 | - hcd->driver->free_dev(hcd, udev); | ||
4022 | usb_put_hcd(hcd); | ||
4023 | kfree(udev->product); | ||
4024 | kfree(udev->manufacturer); | ||
4025 | diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c | ||
4026 | index a37640e..73f9bbd 100644 | ||
4027 | --- a/drivers/usb/gadget/f_mass_storage.c | ||
4028 | +++ b/drivers/usb/gadget/f_mass_storage.c | ||
4029 | @@ -2852,7 +2852,6 @@ error_release: | ||
4030 | /* Call fsg_common_release() directly, ref might be not | ||
4031 | * initialised */ | ||
4032 | fsg_common_release(&common->ref); | ||
4033 | - complete(&common->thread_notifier); | ||
4034 | return ERR_PTR(rc); | ||
4035 | } | ||
4036 | |||
4037 | diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c | ||
4038 | index 2769326..cd74bbd 100644 | ||
4039 | --- a/drivers/usb/host/ohci-pnx4008.c | ||
4040 | +++ b/drivers/usb/host/ohci-pnx4008.c | ||
4041 | @@ -327,7 +327,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) | ||
4042 | } | ||
4043 | i2c_adap = i2c_get_adapter(2); | ||
4044 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); | ||
4045 | - strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE); | ||
4046 | + strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE); | ||
4047 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, | ||
4048 | normal_i2c); | ||
4049 | i2c_put_adapter(i2c_adap); | ||
4050 | @@ -411,7 +411,7 @@ out3: | ||
4051 | out2: | ||
4052 | clk_put(usb_clk); | ||
4053 | out1: | ||
4054 | - i2c_unregister_client(isp1301_i2c_client); | ||
4055 | + i2c_unregister_device(isp1301_i2c_client); | ||
4056 | isp1301_i2c_client = NULL; | ||
4057 | out_i2c_driver: | ||
4058 | i2c_del_driver(&isp1301_driver); | ||
4059 | @@ -430,7 +430,7 @@ static int usb_hcd_pnx4008_remove(struct platform_device *pdev) | ||
4060 | pnx4008_unset_usb_bits(); | ||
4061 | clk_disable(usb_clk); | ||
4062 | clk_put(usb_clk); | ||
4063 | - i2c_unregister_client(isp1301_i2c_client); | ||
4064 | + i2c_unregister_device(isp1301_i2c_client); | ||
4065 | isp1301_i2c_client = NULL; | ||
4066 | i2c_del_driver(&isp1301_driver); | ||
4067 | |||
4068 | diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c | ||
4069 | index 99cd00f..0919706 100644 | ||
4070 | --- a/drivers/usb/host/uhci-hcd.c | ||
4071 | +++ b/drivers/usb/host/uhci-hcd.c | ||
4072 | @@ -735,6 +735,7 @@ static void uhci_stop(struct usb_hcd *hcd) | ||
4073 | uhci_hc_died(uhci); | ||
4074 | uhci_scan_schedule(uhci); | ||
4075 | spin_unlock_irq(&uhci->lock); | ||
4076 | + synchronize_irq(hcd->irq); | ||
4077 | |||
4078 | del_timer_sync(&uhci->fsbr_timer); | ||
4079 | release_uhci(uhci); | ||
4080 | diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h | ||
4081 | index ecc131c..78c4eda 100644 | ||
4082 | --- a/drivers/usb/host/xhci-ext-caps.h | ||
4083 | +++ b/drivers/usb/host/xhci-ext-caps.h | ||
4084 | @@ -101,12 +101,15 @@ static inline int xhci_find_next_cap_offset(void __iomem *base, int ext_offset) | ||
4085 | |||
4086 | next = readl(base + ext_offset); | ||
4087 | |||
4088 | - if (ext_offset == XHCI_HCC_PARAMS_OFFSET) | ||
4089 | + if (ext_offset == XHCI_HCC_PARAMS_OFFSET) { | ||
4090 | /* Find the first extended capability */ | ||
4091 | next = XHCI_HCC_EXT_CAPS(next); | ||
4092 | - else | ||
4093 | + ext_offset = 0; | ||
4094 | + } else { | ||
4095 | /* Find the next extended capability */ | ||
4096 | next = XHCI_EXT_CAPS_NEXT(next); | ||
4097 | + } | ||
4098 | + | ||
4099 | if (!next) | ||
4100 | return 0; | ||
4101 | /* | ||
4102 | diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c | ||
4103 | index bd254ec..7d920f2 100644 | ||
4104 | --- a/drivers/usb/serial/cp210x.c | ||
4105 | +++ b/drivers/usb/serial/cp210x.c | ||
4106 | @@ -91,11 +91,12 @@ static struct usb_device_id id_table [] = { | ||
4107 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ | ||
4108 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ | ||
4109 | { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ | ||
4110 | + { USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */ | ||
4111 | { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */ | ||
4112 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ | ||
4113 | { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ | ||
4114 | { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ | ||
4115 | - { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ | ||
4116 | + { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesys ETRX2USB */ | ||
4117 | { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ | ||
4118 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ | ||
4119 | { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ | ||
4120 | diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c | ||
4121 | index 7638828..34acf6c 100644 | ||
4122 | --- a/drivers/usb/serial/ftdi_sio.c | ||
4123 | +++ b/drivers/usb/serial/ftdi_sio.c | ||
4124 | @@ -614,6 +614,7 @@ static struct usb_device_id id_table_combined [] = { | ||
4125 | { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, | ||
4126 | { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, | ||
4127 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, | ||
4128 | + { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, | ||
4129 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, | ||
4130 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, | ||
4131 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, | ||
4132 | @@ -737,6 +738,10 @@ static struct usb_device_id id_table_combined [] = { | ||
4133 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
4134 | { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, | ||
4135 | { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, | ||
4136 | + { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) }, | ||
4137 | + { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, | ||
4138 | + { USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) }, | ||
4139 | + { USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) }, | ||
4140 | { }, /* Optional parameter entry */ | ||
4141 | { } /* Terminating entry */ | ||
4142 | }; | ||
4143 | diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h | ||
4144 | index c8951ae..d10b5a8 100644 | ||
4145 | --- a/drivers/usb/serial/ftdi_sio_ids.h | ||
4146 | +++ b/drivers/usb/serial/ftdi_sio_ids.h | ||
4147 | @@ -494,6 +494,13 @@ | ||
4148 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | ||
4149 | |||
4150 | /* | ||
4151 | + * Contec products (http://www.contec.com) | ||
4152 | + * Submitted by Daniel Sangorrin | ||
4153 | + */ | ||
4154 | +#define CONTEC_VID 0x06CE /* Vendor ID */ | ||
4155 | +#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ | ||
4156 | + | ||
4157 | +/* | ||
4158 | * Definitions for B&B Electronics products. | ||
4159 | */ | ||
4160 | #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ | ||
4161 | @@ -1002,3 +1009,11 @@ | ||
4162 | #define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ | ||
4163 | #define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ | ||
4164 | #define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ | ||
4165 | + | ||
4166 | +/* | ||
4167 | + * MJS Gadgets HD Radio / XM Radio / Sirius Radio interfaces (using VID 0x0403) | ||
4168 | + */ | ||
4169 | +#define MJSG_GENERIC_PID 0x9378 | ||
4170 | +#define MJSG_SR_RADIO_PID 0x9379 | ||
4171 | +#define MJSG_XM_RADIO_PID 0x937A | ||
4172 | +#define MJSG_HD_RADIO_PID 0x937C | ||
4173 | diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c | ||
4174 | index 3eb6143..0cfd621 100644 | ||
4175 | --- a/drivers/usb/serial/sierra.c | ||
4176 | +++ b/drivers/usb/serial/sierra.c | ||
4177 | @@ -604,14 +604,17 @@ static void sierra_indat_callback(struct urb *urb) | ||
4178 | } else { | ||
4179 | if (urb->actual_length) { | ||
4180 | tty = tty_port_tty_get(&port->port); | ||
4181 | - | ||
4182 | - tty_buffer_request_room(tty, urb->actual_length); | ||
4183 | - tty_insert_flip_string(tty, data, urb->actual_length); | ||
4184 | - tty_flip_buffer_push(tty); | ||
4185 | - | ||
4186 | - tty_kref_put(tty); | ||
4187 | - usb_serial_debug_data(debug, &port->dev, __func__, | ||
4188 | - urb->actual_length, data); | ||
4189 | + if (tty) { | ||
4190 | + tty_buffer_request_room(tty, | ||
4191 | + urb->actual_length); | ||
4192 | + tty_insert_flip_string(tty, data, | ||
4193 | + urb->actual_length); | ||
4194 | + tty_flip_buffer_push(tty); | ||
4195 | + | ||
4196 | + tty_kref_put(tty); | ||
4197 | + usb_serial_debug_data(debug, &port->dev, | ||
4198 | + __func__, urb->actual_length, data); | ||
4199 | + } | ||
4200 | } else { | ||
4201 | dev_dbg(&port->dev, "%s: empty read urb" | ||
4202 | " received\n", __func__); | ||
4203 | diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h | ||
4204 | index 49575fb..98b549b 100644 | ||
4205 | --- a/drivers/usb/storage/unusual_devs.h | ||
4206 | +++ b/drivers/usb/storage/unusual_devs.h | ||
4207 | @@ -1147,8 +1147,8 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000, | ||
4208 | 0 ), | ||
4209 | |||
4210 | /* Reported by Jan Dumon <j.dumon@option.com> | ||
4211 | - * This device (wrongly) has a vendor-specific device descriptor. | ||
4212 | - * The entry is needed so usb-storage can bind to it's mass-storage | ||
4213 | + * These devices (wrongly) have a vendor-specific device descriptor. | ||
4214 | + * These entries are needed so usb-storage can bind to their mass-storage | ||
4215 | * interface as an interface driver */ | ||
4216 | UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, | ||
4217 | "Option", | ||
4218 | @@ -1156,6 +1156,90 @@ UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, | ||
4219 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4220 | 0 ), | ||
4221 | |||
4222 | +UNUSUAL_DEV( 0x0af0, 0x7701, 0x0000, 0x0000, | ||
4223 | + "Option", | ||
4224 | + "GI 0451 SD-Card", | ||
4225 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4226 | + 0 ), | ||
4227 | + | ||
4228 | +UNUSUAL_DEV( 0x0af0, 0x7706, 0x0000, 0x0000, | ||
4229 | + "Option", | ||
4230 | + "GI 0451 SD-Card", | ||
4231 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4232 | + 0 ), | ||
4233 | + | ||
4234 | +UNUSUAL_DEV( 0x0af0, 0x7901, 0x0000, 0x0000, | ||
4235 | + "Option", | ||
4236 | + "GI 0452 SD-Card", | ||
4237 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4238 | + 0 ), | ||
4239 | + | ||
4240 | +UNUSUAL_DEV( 0x0af0, 0x7A01, 0x0000, 0x0000, | ||
4241 | + "Option", | ||
4242 | + "GI 0461 SD-Card", | ||
4243 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4244 | + 0 ), | ||
4245 | + | ||
4246 | +UNUSUAL_DEV( 0x0af0, 0x7A05, 0x0000, 0x0000, | ||
4247 | + "Option", | ||
4248 | + "GI 0461 SD-Card", | ||
4249 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4250 | + 0 ), | ||
4251 | + | ||
4252 | +UNUSUAL_DEV( 0x0af0, 0x8300, 0x0000, 0x0000, | ||
4253 | + "Option", | ||
4254 | + "GI 033x SD-Card", | ||
4255 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4256 | + 0 ), | ||
4257 | + | ||
4258 | +UNUSUAL_DEV( 0x0af0, 0x8302, 0x0000, 0x0000, | ||
4259 | + "Option", | ||
4260 | + "GI 033x SD-Card", | ||
4261 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4262 | + 0 ), | ||
4263 | + | ||
4264 | +UNUSUAL_DEV( 0x0af0, 0x8304, 0x0000, 0x0000, | ||
4265 | + "Option", | ||
4266 | + "GI 033x SD-Card", | ||
4267 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4268 | + 0 ), | ||
4269 | + | ||
4270 | +UNUSUAL_DEV( 0x0af0, 0xc100, 0x0000, 0x0000, | ||
4271 | + "Option", | ||
4272 | + "GI 070x SD-Card", | ||
4273 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4274 | + 0 ), | ||
4275 | + | ||
4276 | +UNUSUAL_DEV( 0x0af0, 0xd057, 0x0000, 0x0000, | ||
4277 | + "Option", | ||
4278 | + "GI 1505 SD-Card", | ||
4279 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4280 | + 0 ), | ||
4281 | + | ||
4282 | +UNUSUAL_DEV( 0x0af0, 0xd058, 0x0000, 0x0000, | ||
4283 | + "Option", | ||
4284 | + "GI 1509 SD-Card", | ||
4285 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4286 | + 0 ), | ||
4287 | + | ||
4288 | +UNUSUAL_DEV( 0x0af0, 0xd157, 0x0000, 0x0000, | ||
4289 | + "Option", | ||
4290 | + "GI 1515 SD-Card", | ||
4291 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4292 | + 0 ), | ||
4293 | + | ||
4294 | +UNUSUAL_DEV( 0x0af0, 0xd257, 0x0000, 0x0000, | ||
4295 | + "Option", | ||
4296 | + "GI 1215 SD-Card", | ||
4297 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4298 | + 0 ), | ||
4299 | + | ||
4300 | +UNUSUAL_DEV( 0x0af0, 0xd357, 0x0000, 0x0000, | ||
4301 | + "Option", | ||
4302 | + "GI 1505 SD-Card", | ||
4303 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
4304 | + 0 ), | ||
4305 | + | ||
4306 | /* Reported by Ben Efros <ben@pc-doctor.com> */ | ||
4307 | UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, | ||
4308 | "Seagate", | ||
4309 | diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c | ||
4310 | index 18b9507..4cd5049 100644 | ||
4311 | --- a/drivers/video/sunxvr500.c | ||
4312 | +++ b/drivers/video/sunxvr500.c | ||
4313 | @@ -400,6 +400,7 @@ static void __devexit e3d_pci_unregister(struct pci_dev *pdev) | ||
4314 | |||
4315 | static struct pci_device_id e3d_pci_table[] = { | ||
4316 | { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a0), }, | ||
4317 | + { PCI_DEVICE(0x1091, 0x7a0), }, | ||
4318 | { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a2), }, | ||
4319 | { .vendor = PCI_VENDOR_ID_3DLABS, | ||
4320 | .device = PCI_ANY_ID, | ||
4321 | diff --git a/fs/file_table.c b/fs/file_table.c | ||
4322 | index b98404b..32d12b7 100644 | ||
4323 | --- a/fs/file_table.c | ||
4324 | +++ b/fs/file_table.c | ||
4325 | @@ -393,7 +393,9 @@ retry: | ||
4326 | continue; | ||
4327 | if (!(f->f_mode & FMODE_WRITE)) | ||
4328 | continue; | ||
4329 | + spin_lock(&f->f_lock); | ||
4330 | f->f_mode &= ~FMODE_WRITE; | ||
4331 | + spin_unlock(&f->f_lock); | ||
4332 | if (file_check_writeable(f) != 0) | ||
4333 | continue; | ||
4334 | file_release_write(f); | ||
4335 | diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c | ||
4336 | index 95e1ca7..3f0cd4d 100644 | ||
4337 | --- a/fs/nfs/dns_resolve.c | ||
4338 | +++ b/fs/nfs/dns_resolve.c | ||
4339 | @@ -36,6 +36,19 @@ struct nfs_dns_ent { | ||
4340 | }; | ||
4341 | |||
4342 | |||
4343 | +static void nfs_dns_ent_update(struct cache_head *cnew, | ||
4344 | + struct cache_head *ckey) | ||
4345 | +{ | ||
4346 | + struct nfs_dns_ent *new; | ||
4347 | + struct nfs_dns_ent *key; | ||
4348 | + | ||
4349 | + new = container_of(cnew, struct nfs_dns_ent, h); | ||
4350 | + key = container_of(ckey, struct nfs_dns_ent, h); | ||
4351 | + | ||
4352 | + memcpy(&new->addr, &key->addr, key->addrlen); | ||
4353 | + new->addrlen = key->addrlen; | ||
4354 | +} | ||
4355 | + | ||
4356 | static void nfs_dns_ent_init(struct cache_head *cnew, | ||
4357 | struct cache_head *ckey) | ||
4358 | { | ||
4359 | @@ -49,8 +62,7 @@ static void nfs_dns_ent_init(struct cache_head *cnew, | ||
4360 | new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL); | ||
4361 | if (new->hostname) { | ||
4362 | new->namelen = key->namelen; | ||
4363 | - memcpy(&new->addr, &key->addr, key->addrlen); | ||
4364 | - new->addrlen = key->addrlen; | ||
4365 | + nfs_dns_ent_update(cnew, ckey); | ||
4366 | } else { | ||
4367 | new->namelen = 0; | ||
4368 | new->addrlen = 0; | ||
4369 | @@ -234,7 +246,7 @@ static struct cache_detail nfs_dns_resolve = { | ||
4370 | .cache_show = nfs_dns_show, | ||
4371 | .match = nfs_dns_match, | ||
4372 | .init = nfs_dns_ent_init, | ||
4373 | - .update = nfs_dns_ent_init, | ||
4374 | + .update = nfs_dns_ent_update, | ||
4375 | .alloc = nfs_dns_ent_alloc, | ||
4376 | }; | ||
4377 | |||
4378 | diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c | ||
4379 | index f19ed86..fcafe60 100644 | ||
4380 | --- a/fs/nfsd/nfs4state.c | ||
4381 | +++ b/fs/nfsd/nfs4state.c | ||
4382 | @@ -1998,7 +1998,9 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access) | ||
4383 | { | ||
4384 | if (share_access & NFS4_SHARE_ACCESS_WRITE) { | ||
4385 | drop_file_write_access(filp); | ||
4386 | + spin_lock(&filp->f_lock); | ||
4387 | filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE; | ||
4388 | + spin_unlock(&filp->f_lock); | ||
4389 | } | ||
4390 | } | ||
4391 | |||
4392 | diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c | ||
4393 | index 7e9df11..4c2a6d2 100644 | ||
4394 | --- a/fs/ocfs2/aops.c | ||
4395 | +++ b/fs/ocfs2/aops.c | ||
4396 | @@ -577,8 +577,9 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock, | ||
4397 | goto bail; | ||
4398 | } | ||
4399 | |||
4400 | - /* We should already CoW the refcounted extent. */ | ||
4401 | - BUG_ON(ext_flags & OCFS2_EXT_REFCOUNTED); | ||
4402 | + /* We should already CoW the refcounted extent in case of create. */ | ||
4403 | + BUG_ON(create && (ext_flags & OCFS2_EXT_REFCOUNTED)); | ||
4404 | + | ||
4405 | /* | ||
4406 | * get_more_blocks() expects us to describe a hole by clearing | ||
4407 | * the mapped bit on bh_result(). | ||
4408 | diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c | ||
4409 | index 699f371..5c4703d 100644 | ||
4410 | --- a/fs/sysfs/dir.c | ||
4411 | +++ b/fs/sysfs/dir.c | ||
4412 | @@ -837,11 +837,46 @@ static inline unsigned char dt_type(struct sysfs_dirent *sd) | ||
4413 | return (sd->s_mode >> 12) & 15; | ||
4414 | } | ||
4415 | |||
4416 | +static int sysfs_dir_release(struct inode *inode, struct file *filp) | ||
4417 | +{ | ||
4418 | + sysfs_put(filp->private_data); | ||
4419 | + return 0; | ||
4420 | +} | ||
4421 | + | ||
4422 | +static struct sysfs_dirent *sysfs_dir_pos(struct sysfs_dirent *parent_sd, | ||
4423 | + ino_t ino, struct sysfs_dirent *pos) | ||
4424 | +{ | ||
4425 | + if (pos) { | ||
4426 | + int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) && | ||
4427 | + pos->s_parent == parent_sd && | ||
4428 | + ino == pos->s_ino; | ||
4429 | + sysfs_put(pos); | ||
4430 | + if (valid) | ||
4431 | + return pos; | ||
4432 | + } | ||
4433 | + pos = NULL; | ||
4434 | + if ((ino > 1) && (ino < INT_MAX)) { | ||
4435 | + pos = parent_sd->s_dir.children; | ||
4436 | + while (pos && (ino > pos->s_ino)) | ||
4437 | + pos = pos->s_sibling; | ||
4438 | + } | ||
4439 | + return pos; | ||
4440 | +} | ||
4441 | + | ||
4442 | +static struct sysfs_dirent *sysfs_dir_next_pos(struct sysfs_dirent *parent_sd, | ||
4443 | + ino_t ino, struct sysfs_dirent *pos) | ||
4444 | +{ | ||
4445 | + pos = sysfs_dir_pos(parent_sd, ino, pos); | ||
4446 | + if (pos) | ||
4447 | + pos = pos->s_sibling; | ||
4448 | + return pos; | ||
4449 | +} | ||
4450 | + | ||
4451 | static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | ||
4452 | { | ||
4453 | struct dentry *dentry = filp->f_path.dentry; | ||
4454 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; | ||
4455 | - struct sysfs_dirent *pos; | ||
4456 | + struct sysfs_dirent *pos = filp->private_data; | ||
4457 | ino_t ino; | ||
4458 | |||
4459 | if (filp->f_pos == 0) { | ||
4460 | @@ -857,29 +892,31 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | ||
4461 | if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0) | ||
4462 | filp->f_pos++; | ||
4463 | } | ||
4464 | - if ((filp->f_pos > 1) && (filp->f_pos < INT_MAX)) { | ||
4465 | - mutex_lock(&sysfs_mutex); | ||
4466 | - | ||
4467 | - /* Skip the dentries we have already reported */ | ||
4468 | - pos = parent_sd->s_dir.children; | ||
4469 | - while (pos && (filp->f_pos > pos->s_ino)) | ||
4470 | - pos = pos->s_sibling; | ||
4471 | - | ||
4472 | - for ( ; pos; pos = pos->s_sibling) { | ||
4473 | - const char * name; | ||
4474 | - int len; | ||
4475 | - | ||
4476 | - name = pos->s_name; | ||
4477 | - len = strlen(name); | ||
4478 | - filp->f_pos = ino = pos->s_ino; | ||
4479 | + mutex_lock(&sysfs_mutex); | ||
4480 | + for (pos = sysfs_dir_pos(parent_sd, filp->f_pos, pos); | ||
4481 | + pos; | ||
4482 | + pos = sysfs_dir_next_pos(parent_sd, filp->f_pos, pos)) { | ||
4483 | + const char * name; | ||
4484 | + unsigned int type; | ||
4485 | + int len, ret; | ||
4486 | + | ||
4487 | + name = pos->s_name; | ||
4488 | + len = strlen(name); | ||
4489 | + ino = pos->s_ino; | ||
4490 | + type = dt_type(pos); | ||
4491 | + filp->f_pos = ino; | ||
4492 | + filp->private_data = sysfs_get(pos); | ||
4493 | |||
4494 | - if (filldir(dirent, name, len, filp->f_pos, ino, | ||
4495 | - dt_type(pos)) < 0) | ||
4496 | - break; | ||
4497 | - } | ||
4498 | - if (!pos) | ||
4499 | - filp->f_pos = INT_MAX; | ||
4500 | mutex_unlock(&sysfs_mutex); | ||
4501 | + ret = filldir(dirent, name, len, filp->f_pos, ino, type); | ||
4502 | + mutex_lock(&sysfs_mutex); | ||
4503 | + if (ret < 0) | ||
4504 | + break; | ||
4505 | + } | ||
4506 | + mutex_unlock(&sysfs_mutex); | ||
4507 | + if ((filp->f_pos > 1) && !pos) { /* EOF */ | ||
4508 | + filp->f_pos = INT_MAX; | ||
4509 | + filp->private_data = NULL; | ||
4510 | } | ||
4511 | return 0; | ||
4512 | } | ||
4513 | @@ -888,5 +925,6 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | ||
4514 | const struct file_operations sysfs_dir_operations = { | ||
4515 | .read = generic_read_dir, | ||
4516 | .readdir = sysfs_readdir, | ||
4517 | + .release = sysfs_dir_release, | ||
4518 | .llseek = generic_file_llseek, | ||
4519 | }; | ||
4520 | diff --git a/include/linux/fs.h b/include/linux/fs.h | ||
4521 | index ebb1cd5..f2f68ce 100644 | ||
4522 | --- a/include/linux/fs.h | ||
4523 | +++ b/include/linux/fs.h | ||
4524 | @@ -87,6 +87,9 @@ struct inodes_stat_t { | ||
4525 | */ | ||
4526 | #define FMODE_NOCMTIME ((__force fmode_t)2048) | ||
4527 | |||
4528 | +/* Expect random access pattern */ | ||
4529 | +#define FMODE_RANDOM ((__force fmode_t)4096) | ||
4530 | + | ||
4531 | /* | ||
4532 | * The below are the various read and write types that we support. Some of | ||
4533 | * them include behavioral modifiers that send information down to the | ||
4534 | diff --git a/include/linux/irq.h b/include/linux/irq.h | ||
4535 | index 451481c..4d9b26e 100644 | ||
4536 | --- a/include/linux/irq.h | ||
4537 | +++ b/include/linux/irq.h | ||
4538 | @@ -400,7 +400,9 @@ static inline int irq_has_action(unsigned int irq) | ||
4539 | |||
4540 | /* Dynamic irq helper functions */ | ||
4541 | extern void dynamic_irq_init(unsigned int irq); | ||
4542 | +void dynamic_irq_init_keep_chip_data(unsigned int irq); | ||
4543 | extern void dynamic_irq_cleanup(unsigned int irq); | ||
4544 | +void dynamic_irq_cleanup_keep_chip_data(unsigned int irq); | ||
4545 | |||
4546 | /* Set/get chip/data for an IRQ: */ | ||
4547 | extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); | ||
4548 | diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h | ||
4549 | index a3fccc8..99914e6 100644 | ||
4550 | --- a/include/linux/netdevice.h | ||
4551 | +++ b/include/linux/netdevice.h | ||
4552 | @@ -136,7 +136,7 @@ static inline bool dev_xmit_complete(int rc) | ||
4553 | * used. | ||
4554 | */ | ||
4555 | |||
4556 | -#if defined(CONFIG_WLAN_80211) || defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) | ||
4557 | +#if defined(CONFIG_WLAN) || defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) | ||
4558 | # if defined(CONFIG_MAC80211_MESH) | ||
4559 | # define LL_MAX_HEADER 128 | ||
4560 | # else | ||
4561 | diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h | ||
4562 | index a177698..c8ea0c7 100644 | ||
4563 | --- a/include/linux/perf_event.h | ||
4564 | +++ b/include/linux/perf_event.h | ||
4565 | @@ -496,9 +496,8 @@ struct hw_perf_event { | ||
4566 | atomic64_t period_left; | ||
4567 | u64 interrupts; | ||
4568 | |||
4569 | - u64 freq_count; | ||
4570 | - u64 freq_interrupts; | ||
4571 | - u64 freq_stamp; | ||
4572 | + u64 freq_time_stamp; | ||
4573 | + u64 freq_count_stamp; | ||
4574 | #endif | ||
4575 | }; | ||
4576 | |||
4577 | diff --git a/include/linux/sched.h b/include/linux/sched.h | ||
4578 | index 78efe7c..1f5fa53 100644 | ||
4579 | --- a/include/linux/sched.h | ||
4580 | +++ b/include/linux/sched.h | ||
4581 | @@ -878,7 +878,10 @@ static inline int sd_balance_for_mc_power(void) | ||
4582 | if (sched_smt_power_savings) | ||
4583 | return SD_POWERSAVINGS_BALANCE; | ||
4584 | |||
4585 | - return SD_PREFER_SIBLING; | ||
4586 | + if (!sched_mc_power_savings) | ||
4587 | + return SD_PREFER_SIBLING; | ||
4588 | + | ||
4589 | + return 0; | ||
4590 | } | ||
4591 | |||
4592 | static inline int sd_balance_for_package_power(void) | ||
4593 | diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h | ||
4594 | index ae836fd..ec226a2 100644 | ||
4595 | --- a/include/linux/skbuff.h | ||
4596 | +++ b/include/linux/skbuff.h | ||
4597 | @@ -315,22 +315,23 @@ struct sk_buff { | ||
4598 | struct sk_buff *next; | ||
4599 | struct sk_buff *prev; | ||
4600 | |||
4601 | - struct sock *sk; | ||
4602 | ktime_t tstamp; | ||
4603 | + | ||
4604 | + struct sock *sk; | ||
4605 | struct net_device *dev; | ||
4606 | |||
4607 | - unsigned long _skb_dst; | ||
4608 | -#ifdef CONFIG_XFRM | ||
4609 | - struct sec_path *sp; | ||
4610 | -#endif | ||
4611 | /* | ||
4612 | * This is the control buffer. It is free to use for every | ||
4613 | * layer. Please put your private variables there. If you | ||
4614 | * want to keep them across layers you have to do a skb_clone() | ||
4615 | * first. This is owned by whoever has the skb queued ATM. | ||
4616 | */ | ||
4617 | - char cb[48]; | ||
4618 | + char cb[48] __aligned(8); | ||
4619 | |||
4620 | + unsigned long _skb_dst; | ||
4621 | +#ifdef CONFIG_XFRM | ||
4622 | + struct sec_path *sp; | ||
4623 | +#endif | ||
4624 | unsigned int len, | ||
4625 | data_len; | ||
4626 | __u16 mac_len, | ||
4627 | diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h | ||
4628 | index 207466a..2540770 100644 | ||
4629 | --- a/include/linux/syscalls.h | ||
4630 | +++ b/include/linux/syscalls.h | ||
4631 | @@ -132,7 +132,8 @@ struct perf_event_attr; | ||
4632 | |||
4633 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ | ||
4634 | static const struct syscall_metadata __syscall_meta_##sname; \ | ||
4635 | - static struct ftrace_event_call event_enter_##sname; \ | ||
4636 | + static struct ftrace_event_call \ | ||
4637 | + __attribute__((__aligned__(4))) event_enter_##sname; \ | ||
4638 | static struct trace_event enter_syscall_print_##sname = { \ | ||
4639 | .trace = print_syscall_enter, \ | ||
4640 | }; \ | ||
4641 | @@ -154,7 +155,8 @@ struct perf_event_attr; | ||
4642 | |||
4643 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ | ||
4644 | static const struct syscall_metadata __syscall_meta_##sname; \ | ||
4645 | - static struct ftrace_event_call event_exit_##sname; \ | ||
4646 | + static struct ftrace_event_call \ | ||
4647 | + __attribute__((__aligned__(4))) event_exit_##sname; \ | ||
4648 | static struct trace_event exit_syscall_print_##sname = { \ | ||
4649 | .trace = print_syscall_exit, \ | ||
4650 | }; \ | ||
4651 | diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h | ||
4652 | index c6fe03e..1ca4990 100644 | ||
4653 | --- a/include/trace/ftrace.h | ||
4654 | +++ b/include/trace/ftrace.h | ||
4655 | @@ -65,7 +65,8 @@ | ||
4656 | }; | ||
4657 | #undef DEFINE_EVENT | ||
4658 | #define DEFINE_EVENT(template, name, proto, args) \ | ||
4659 | - static struct ftrace_event_call event_##name | ||
4660 | + static struct ftrace_event_call \ | ||
4661 | + __attribute__((__aligned__(4))) event_##name | ||
4662 | |||
4663 | #undef DEFINE_EVENT_PRINT | ||
4664 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | ||
4665 | diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c | ||
4666 | index ecc3fa2..d70394f 100644 | ||
4667 | --- a/kernel/irq/chip.c | ||
4668 | +++ b/kernel/irq/chip.c | ||
4669 | @@ -18,11 +18,7 @@ | ||
4670 | |||
4671 | #include "internals.h" | ||
4672 | |||
4673 | -/** | ||
4674 | - * dynamic_irq_init - initialize a dynamically allocated irq | ||
4675 | - * @irq: irq number to initialize | ||
4676 | - */ | ||
4677 | -void dynamic_irq_init(unsigned int irq) | ||
4678 | +static void dynamic_irq_init_x(unsigned int irq, bool keep_chip_data) | ||
4679 | { | ||
4680 | struct irq_desc *desc; | ||
4681 | unsigned long flags; | ||
4682 | @@ -41,7 +37,8 @@ void dynamic_irq_init(unsigned int irq) | ||
4683 | desc->depth = 1; | ||
4684 | desc->msi_desc = NULL; | ||
4685 | desc->handler_data = NULL; | ||
4686 | - desc->chip_data = NULL; | ||
4687 | + if (!keep_chip_data) | ||
4688 | + desc->chip_data = NULL; | ||
4689 | desc->action = NULL; | ||
4690 | desc->irq_count = 0; | ||
4691 | desc->irqs_unhandled = 0; | ||
4692 | @@ -55,10 +52,26 @@ void dynamic_irq_init(unsigned int irq) | ||
4693 | } | ||
4694 | |||
4695 | /** | ||
4696 | - * dynamic_irq_cleanup - cleanup a dynamically allocated irq | ||
4697 | + * dynamic_irq_init - initialize a dynamically allocated irq | ||
4698 | * @irq: irq number to initialize | ||
4699 | */ | ||
4700 | -void dynamic_irq_cleanup(unsigned int irq) | ||
4701 | +void dynamic_irq_init(unsigned int irq) | ||
4702 | +{ | ||
4703 | + dynamic_irq_init_x(irq, false); | ||
4704 | +} | ||
4705 | + | ||
4706 | +/** | ||
4707 | + * dynamic_irq_init_keep_chip_data - initialize a dynamically allocated irq | ||
4708 | + * @irq: irq number to initialize | ||
4709 | + * | ||
4710 | + * does not set irq_to_desc(irq)->chip_data to NULL | ||
4711 | + */ | ||
4712 | +void dynamic_irq_init_keep_chip_data(unsigned int irq) | ||
4713 | +{ | ||
4714 | + dynamic_irq_init_x(irq, true); | ||
4715 | +} | ||
4716 | + | ||
4717 | +static void dynamic_irq_cleanup_x(unsigned int irq, bool keep_chip_data) | ||
4718 | { | ||
4719 | struct irq_desc *desc = irq_to_desc(irq); | ||
4720 | unsigned long flags; | ||
4721 | @@ -77,7 +90,8 @@ void dynamic_irq_cleanup(unsigned int irq) | ||
4722 | } | ||
4723 | desc->msi_desc = NULL; | ||
4724 | desc->handler_data = NULL; | ||
4725 | - desc->chip_data = NULL; | ||
4726 | + if (!keep_chip_data) | ||
4727 | + desc->chip_data = NULL; | ||
4728 | desc->handle_irq = handle_bad_irq; | ||
4729 | desc->chip = &no_irq_chip; | ||
4730 | desc->name = NULL; | ||
4731 | @@ -85,6 +99,26 @@ void dynamic_irq_cleanup(unsigned int irq) | ||
4732 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
4733 | } | ||
4734 | |||
4735 | +/** | ||
4736 | + * dynamic_irq_cleanup - cleanup a dynamically allocated irq | ||
4737 | + * @irq: irq number to initialize | ||
4738 | + */ | ||
4739 | +void dynamic_irq_cleanup(unsigned int irq) | ||
4740 | +{ | ||
4741 | + dynamic_irq_cleanup_x(irq, false); | ||
4742 | +} | ||
4743 | + | ||
4744 | +/** | ||
4745 | + * dynamic_irq_cleanup_keep_chip_data - cleanup a dynamically allocated irq | ||
4746 | + * @irq: irq number to initialize | ||
4747 | + * | ||
4748 | + * does not set irq_to_desc(irq)->chip_data to NULL | ||
4749 | + */ | ||
4750 | +void dynamic_irq_cleanup_keep_chip_data(unsigned int irq) | ||
4751 | +{ | ||
4752 | + dynamic_irq_cleanup_x(irq, true); | ||
4753 | +} | ||
4754 | + | ||
4755 | |||
4756 | /** | ||
4757 | * set_irq_chip - set the irq chip for an irq | ||
4758 | diff --git a/kernel/perf_event.c b/kernel/perf_event.c | ||
4759 | index 2ae7409..b707465 100644 | ||
4760 | --- a/kernel/perf_event.c | ||
4761 | +++ b/kernel/perf_event.c | ||
4762 | @@ -248,7 +248,7 @@ static void perf_unpin_context(struct perf_event_context *ctx) | ||
4763 | |||
4764 | static inline u64 perf_clock(void) | ||
4765 | { | ||
4766 | - return cpu_clock(smp_processor_id()); | ||
4767 | + return cpu_clock(raw_smp_processor_id()); | ||
4768 | } | ||
4769 | |||
4770 | /* | ||
4771 | @@ -1350,14 +1350,83 @@ static void perf_event_cpu_sched_in(struct perf_cpu_context *cpuctx, int cpu) | ||
4772 | |||
4773 | static void perf_log_throttle(struct perf_event *event, int enable); | ||
4774 | |||
4775 | -static void perf_adjust_period(struct perf_event *event, u64 events) | ||
4776 | +static u64 perf_calculate_period(struct perf_event *event, u64 nsec, u64 count) | ||
4777 | +{ | ||
4778 | + u64 frequency = event->attr.sample_freq; | ||
4779 | + u64 sec = NSEC_PER_SEC; | ||
4780 | + u64 divisor, dividend; | ||
4781 | + | ||
4782 | + int count_fls, nsec_fls, frequency_fls, sec_fls; | ||
4783 | + | ||
4784 | + count_fls = fls64(count); | ||
4785 | + nsec_fls = fls64(nsec); | ||
4786 | + frequency_fls = fls64(frequency); | ||
4787 | + sec_fls = 30; | ||
4788 | + | ||
4789 | + /* | ||
4790 | + * We got @count in @nsec, with a target of sample_freq HZ | ||
4791 | + * the target period becomes: | ||
4792 | + * | ||
4793 | + * @count * 10^9 | ||
4794 | + * period = ------------------- | ||
4795 | + * @nsec * sample_freq | ||
4796 | + * | ||
4797 | + */ | ||
4798 | + | ||
4799 | + /* | ||
4800 | + * Reduce accuracy by one bit such that @a and @b converge | ||
4801 | + * to a similar magnitude. | ||
4802 | + */ | ||
4803 | +#define REDUCE_FLS(a, b) \ | ||
4804 | +do { \ | ||
4805 | + if (a##_fls > b##_fls) { \ | ||
4806 | + a >>= 1; \ | ||
4807 | + a##_fls--; \ | ||
4808 | + } else { \ | ||
4809 | + b >>= 1; \ | ||
4810 | + b##_fls--; \ | ||
4811 | + } \ | ||
4812 | +} while (0) | ||
4813 | + | ||
4814 | + /* | ||
4815 | + * Reduce accuracy until either term fits in a u64, then proceed with | ||
4816 | + * the other, so that finally we can do a u64/u64 division. | ||
4817 | + */ | ||
4818 | + while (count_fls + sec_fls > 64 && nsec_fls + frequency_fls > 64) { | ||
4819 | + REDUCE_FLS(nsec, frequency); | ||
4820 | + REDUCE_FLS(sec, count); | ||
4821 | + } | ||
4822 | + | ||
4823 | + if (count_fls + sec_fls > 64) { | ||
4824 | + divisor = nsec * frequency; | ||
4825 | + | ||
4826 | + while (count_fls + sec_fls > 64) { | ||
4827 | + REDUCE_FLS(count, sec); | ||
4828 | + divisor >>= 1; | ||
4829 | + } | ||
4830 | + | ||
4831 | + dividend = count * sec; | ||
4832 | + } else { | ||
4833 | + dividend = count * sec; | ||
4834 | + | ||
4835 | + while (nsec_fls + frequency_fls > 64) { | ||
4836 | + REDUCE_FLS(nsec, frequency); | ||
4837 | + dividend >>= 1; | ||
4838 | + } | ||
4839 | + | ||
4840 | + divisor = nsec * frequency; | ||
4841 | + } | ||
4842 | + | ||
4843 | + return div64_u64(dividend, divisor); | ||
4844 | +} | ||
4845 | + | ||
4846 | +static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) | ||
4847 | { | ||
4848 | struct hw_perf_event *hwc = &event->hw; | ||
4849 | u64 period, sample_period; | ||
4850 | s64 delta; | ||
4851 | |||
4852 | - events *= hwc->sample_period; | ||
4853 | - period = div64_u64(events, event->attr.sample_freq); | ||
4854 | + period = perf_calculate_period(event, nsec, count); | ||
4855 | |||
4856 | delta = (s64)(period - hwc->sample_period); | ||
4857 | delta = (delta + 7) / 8; /* low pass filter */ | ||
4858 | @@ -1368,13 +1437,22 @@ static void perf_adjust_period(struct perf_event *event, u64 events) | ||
4859 | sample_period = 1; | ||
4860 | |||
4861 | hwc->sample_period = sample_period; | ||
4862 | + | ||
4863 | + if (atomic64_read(&hwc->period_left) > 8*sample_period) { | ||
4864 | + perf_disable(); | ||
4865 | + event->pmu->disable(event); | ||
4866 | + atomic64_set(&hwc->period_left, 0); | ||
4867 | + event->pmu->enable(event); | ||
4868 | + perf_enable(); | ||
4869 | + } | ||
4870 | } | ||
4871 | |||
4872 | static void perf_ctx_adjust_freq(struct perf_event_context *ctx) | ||
4873 | { | ||
4874 | struct perf_event *event; | ||
4875 | struct hw_perf_event *hwc; | ||
4876 | - u64 interrupts, freq; | ||
4877 | + u64 interrupts, now; | ||
4878 | + s64 delta; | ||
4879 | |||
4880 | raw_spin_lock(&ctx->lock); | ||
4881 | list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { | ||
4882 | @@ -1395,44 +1473,18 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) | ||
4883 | if (interrupts == MAX_INTERRUPTS) { | ||
4884 | perf_log_throttle(event, 1); | ||
4885 | event->pmu->unthrottle(event); | ||
4886 | - interrupts = 2*sysctl_perf_event_sample_rate/HZ; | ||
4887 | } | ||
4888 | |||
4889 | if (!event->attr.freq || !event->attr.sample_freq) | ||
4890 | continue; | ||
4891 | |||
4892 | - /* | ||
4893 | - * if the specified freq < HZ then we need to skip ticks | ||
4894 | - */ | ||
4895 | - if (event->attr.sample_freq < HZ) { | ||
4896 | - freq = event->attr.sample_freq; | ||
4897 | - | ||
4898 | - hwc->freq_count += freq; | ||
4899 | - hwc->freq_interrupts += interrupts; | ||
4900 | - | ||
4901 | - if (hwc->freq_count < HZ) | ||
4902 | - continue; | ||
4903 | - | ||
4904 | - interrupts = hwc->freq_interrupts; | ||
4905 | - hwc->freq_interrupts = 0; | ||
4906 | - hwc->freq_count -= HZ; | ||
4907 | - } else | ||
4908 | - freq = HZ; | ||
4909 | - | ||
4910 | - perf_adjust_period(event, freq * interrupts); | ||
4911 | + event->pmu->read(event); | ||
4912 | + now = atomic64_read(&event->count); | ||
4913 | + delta = now - hwc->freq_count_stamp; | ||
4914 | + hwc->freq_count_stamp = now; | ||
4915 | |||
4916 | - /* | ||
4917 | - * In order to avoid being stalled by an (accidental) huge | ||
4918 | - * sample period, force reset the sample period if we didn't | ||
4919 | - * get any events in this freq period. | ||
4920 | - */ | ||
4921 | - if (!interrupts) { | ||
4922 | - perf_disable(); | ||
4923 | - event->pmu->disable(event); | ||
4924 | - atomic64_set(&hwc->period_left, 0); | ||
4925 | - event->pmu->enable(event); | ||
4926 | - perf_enable(); | ||
4927 | - } | ||
4928 | + if (delta > 0) | ||
4929 | + perf_adjust_period(event, TICK_NSEC, delta); | ||
4930 | } | ||
4931 | raw_spin_unlock(&ctx->lock); | ||
4932 | } | ||
4933 | @@ -3688,12 +3740,12 @@ static int __perf_event_overflow(struct perf_event *event, int nmi, | ||
4934 | |||
4935 | if (event->attr.freq) { | ||
4936 | u64 now = perf_clock(); | ||
4937 | - s64 delta = now - hwc->freq_stamp; | ||
4938 | + s64 delta = now - hwc->freq_time_stamp; | ||
4939 | |||
4940 | - hwc->freq_stamp = now; | ||
4941 | + hwc->freq_time_stamp = now; | ||
4942 | |||
4943 | - if (delta > 0 && delta < TICK_NSEC) | ||
4944 | - perf_adjust_period(event, NSEC_PER_SEC / (int)delta); | ||
4945 | + if (delta > 0 && delta < 2*TICK_NSEC) | ||
4946 | + perf_adjust_period(event, delta, hwc->last_period); | ||
4947 | } | ||
4948 | |||
4949 | /* | ||
4950 | diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c | ||
4951 | index 36cb168..fc9ed15 100644 | ||
4952 | --- a/kernel/power/snapshot.c | ||
4953 | +++ b/kernel/power/snapshot.c | ||
4954 | @@ -1181,7 +1181,7 @@ static void free_unnecessary_pages(void) | ||
4955 | |||
4956 | memory_bm_position_reset(©_bm); | ||
4957 | |||
4958 | - while (to_free_normal > 0 && to_free_highmem > 0) { | ||
4959 | + while (to_free_normal > 0 || to_free_highmem > 0) { | ||
4960 | unsigned long pfn = memory_bm_next_pfn(©_bm); | ||
4961 | struct page *page = pfn_to_page(pfn); | ||
4962 | |||
4963 | diff --git a/kernel/sched.c b/kernel/sched.c | ||
4964 | index 3a8fb30..00a59b0 100644 | ||
4965 | --- a/kernel/sched.c | ||
4966 | +++ b/kernel/sched.c | ||
4967 | @@ -4119,12 +4119,23 @@ find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle, | ||
4968 | continue; | ||
4969 | |||
4970 | rq = cpu_rq(i); | ||
4971 | - wl = weighted_cpuload(i) * SCHED_LOAD_SCALE; | ||
4972 | - wl /= power; | ||
4973 | + wl = weighted_cpuload(i); | ||
4974 | |||
4975 | + /* | ||
4976 | + * When comparing with imbalance, use weighted_cpuload() | ||
4977 | + * which is not scaled with the cpu power. | ||
4978 | + */ | ||
4979 | if (capacity && rq->nr_running == 1 && wl > imbalance) | ||
4980 | continue; | ||
4981 | |||
4982 | + /* | ||
4983 | + * For the load comparisons with the other cpu's, consider | ||
4984 | + * the weighted_cpuload() scaled with the cpu power, so that | ||
4985 | + * the load can be moved away from the cpu that is potentially | ||
4986 | + * running at a lower capacity. | ||
4987 | + */ | ||
4988 | + wl = (wl * SCHED_LOAD_SCALE) / power; | ||
4989 | + | ||
4990 | if (wl > max_load) { | ||
4991 | max_load = wl; | ||
4992 | busiest = rq; | ||
4993 | @@ -6054,7 +6065,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio) | ||
4994 | unsigned long flags; | ||
4995 | int oldprio, on_rq, running; | ||
4996 | struct rq *rq; | ||
4997 | - const struct sched_class *prev_class = p->sched_class; | ||
4998 | + const struct sched_class *prev_class; | ||
4999 | |||
5000 | BUG_ON(prio < 0 || prio > MAX_PRIO); | ||
5001 | |||
5002 | @@ -6062,6 +6073,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio) | ||
5003 | update_rq_clock(rq); | ||
5004 | |||
5005 | oldprio = p->prio; | ||
5006 | + prev_class = p->sched_class; | ||
5007 | on_rq = p->se.on_rq; | ||
5008 | running = task_current(rq, p); | ||
5009 | if (on_rq) | ||
5010 | @@ -6281,7 +6293,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy, | ||
5011 | { | ||
5012 | int retval, oldprio, oldpolicy = -1, on_rq, running; | ||
5013 | unsigned long flags; | ||
5014 | - const struct sched_class *prev_class = p->sched_class; | ||
5015 | + const struct sched_class *prev_class; | ||
5016 | struct rq *rq; | ||
5017 | int reset_on_fork; | ||
5018 | |||
5019 | @@ -6395,6 +6407,7 @@ recheck: | ||
5020 | p->sched_reset_on_fork = reset_on_fork; | ||
5021 | |||
5022 | oldprio = p->prio; | ||
5023 | + prev_class = p->sched_class; | ||
5024 | __setscheduler(rq, p, policy, param->sched_priority); | ||
5025 | |||
5026 | if (running) | ||
5027 | diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h | ||
5028 | index 4df6a77..a1edaa8 100644 | ||
5029 | --- a/kernel/trace/trace.h | ||
5030 | +++ b/kernel/trace/trace.h | ||
5031 | @@ -791,7 +791,8 @@ extern const char *__stop___trace_bprintk_fmt[]; | ||
5032 | |||
5033 | #undef FTRACE_ENTRY | ||
5034 | #define FTRACE_ENTRY(call, struct_name, id, tstruct, print) \ | ||
5035 | - extern struct ftrace_event_call event_##call; | ||
5036 | + extern struct ftrace_event_call \ | ||
5037 | + __attribute__((__aligned__(4))) event_##call; | ||
5038 | #undef FTRACE_ENTRY_DUP | ||
5039 | #define FTRACE_ENTRY_DUP(call, struct_name, id, tstruct, print) \ | ||
5040 | FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) | ||
5041 | diff --git a/mm/fadvise.c b/mm/fadvise.c | ||
5042 | index e433592..8d723c9 100644 | ||
5043 | --- a/mm/fadvise.c | ||
5044 | +++ b/mm/fadvise.c | ||
5045 | @@ -77,12 +77,20 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) | ||
5046 | switch (advice) { | ||
5047 | case POSIX_FADV_NORMAL: | ||
5048 | file->f_ra.ra_pages = bdi->ra_pages; | ||
5049 | + spin_lock(&file->f_lock); | ||
5050 | + file->f_mode &= ~FMODE_RANDOM; | ||
5051 | + spin_unlock(&file->f_lock); | ||
5052 | break; | ||
5053 | case POSIX_FADV_RANDOM: | ||
5054 | - file->f_ra.ra_pages = 0; | ||
5055 | + spin_lock(&file->f_lock); | ||
5056 | + file->f_mode |= FMODE_RANDOM; | ||
5057 | + spin_unlock(&file->f_lock); | ||
5058 | break; | ||
5059 | case POSIX_FADV_SEQUENTIAL: | ||
5060 | file->f_ra.ra_pages = bdi->ra_pages * 2; | ||
5061 | + spin_lock(&file->f_lock); | ||
5062 | + file->f_mode &= ~FMODE_RANDOM; | ||
5063 | + spin_unlock(&file->f_lock); | ||
5064 | break; | ||
5065 | case POSIX_FADV_WILLNEED: | ||
5066 | if (!mapping->a_ops->readpage) { | ||
5067 | diff --git a/mm/readahead.c b/mm/readahead.c | ||
5068 | index 033bc13..337b20e 100644 | ||
5069 | --- a/mm/readahead.c | ||
5070 | +++ b/mm/readahead.c | ||
5071 | @@ -501,6 +501,12 @@ void page_cache_sync_readahead(struct address_space *mapping, | ||
5072 | if (!ra->ra_pages) | ||
5073 | return; | ||
5074 | |||
5075 | + /* be dumb */ | ||
5076 | + if (filp->f_mode & FMODE_RANDOM) { | ||
5077 | + force_page_cache_readahead(mapping, filp, offset, req_size); | ||
5078 | + return; | ||
5079 | + } | ||
5080 | + | ||
5081 | /* do read-ahead */ | ||
5082 | ondemand_readahead(mapping, ra, filp, false, offset, req_size); | ||
5083 | } | ||
5084 | diff --git a/mm/slab.c b/mm/slab.c | ||
5085 | index 7451bda..ff44eb2 100644 | ||
5086 | --- a/mm/slab.c | ||
5087 | +++ b/mm/slab.c | ||
5088 | @@ -983,13 +983,11 @@ static struct array_cache **alloc_alien_cache(int node, int limit, gfp_t gfp) | ||
5089 | |||
5090 | if (limit > 1) | ||
5091 | limit = 12; | ||
5092 | - ac_ptr = kmalloc_node(memsize, gfp, node); | ||
5093 | + ac_ptr = kzalloc_node(memsize, gfp, node); | ||
5094 | if (ac_ptr) { | ||
5095 | for_each_node(i) { | ||
5096 | - if (i == node || !node_online(i)) { | ||
5097 | - ac_ptr[i] = NULL; | ||
5098 | + if (i == node || !node_online(i)) | ||
5099 | continue; | ||
5100 | - } | ||
5101 | ac_ptr[i] = alloc_arraycache(node, limit, 0xbaadf00d, gfp); | ||
5102 | if (!ac_ptr[i]) { | ||
5103 | for (i--; i >= 0; i--) | ||
5104 | diff --git a/net/core/scm.c b/net/core/scm.c | ||
5105 | index b7ba91b..9b26463 100644 | ||
5106 | --- a/net/core/scm.c | ||
5107 | +++ b/net/core/scm.c | ||
5108 | @@ -156,6 +156,8 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | ||
5109 | switch (cmsg->cmsg_type) | ||
5110 | { | ||
5111 | case SCM_RIGHTS: | ||
5112 | + if (!sock->ops || sock->ops->family != PF_UNIX) | ||
5113 | + goto error; | ||
5114 | err=scm_fp_copy(cmsg, &p->fp); | ||
5115 | if (err<0) | ||
5116 | goto error; | ||
5117 | diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c | ||
5118 | index 5e3a7ec..304b0b6 100644 | ||
5119 | --- a/net/mac80211/agg-tx.c | ||
5120 | +++ b/net/mac80211/agg-tx.c | ||
5121 | @@ -179,7 +179,8 @@ static void sta_addba_resp_timer_expired(unsigned long data) | ||
5122 | |||
5123 | /* check if the TID waits for addBA response */ | ||
5124 | spin_lock_bh(&sta->lock); | ||
5125 | - if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) != | ||
5126 | + if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK | | ||
5127 | + HT_AGG_STATE_REQ_STOP_BA_MSK)) != | ||
5128 | HT_ADDBA_REQUESTED_MSK) { | ||
5129 | spin_unlock_bh(&sta->lock); | ||
5130 | *state = HT_AGG_STATE_IDLE; | ||
5131 | diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c | ||
5132 | index 82a30c1..da92cde 100644 | ||
5133 | --- a/net/mac80211/rx.c | ||
5134 | +++ b/net/mac80211/rx.c | ||
5135 | @@ -1788,6 +1788,7 @@ static ieee80211_rx_result debug_noinline | ||
5136 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | ||
5137 | { | ||
5138 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
5139 | + struct ieee80211_local *local = rx->local; | ||
5140 | struct net_device *dev = sdata->dev; | ||
5141 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | ||
5142 | __le16 fc = hdr->frame_control; | ||
5143 | @@ -1819,6 +1820,13 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | ||
5144 | dev->stats.rx_packets++; | ||
5145 | dev->stats.rx_bytes += rx->skb->len; | ||
5146 | |||
5147 | + if (ieee80211_is_data(hdr->frame_control) && | ||
5148 | + !is_multicast_ether_addr(hdr->addr1) && | ||
5149 | + local->hw.conf.dynamic_ps_timeout > 0 && local->ps_sdata) { | ||
5150 | + mod_timer(&local->dynamic_ps_timer, jiffies + | ||
5151 | + msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | ||
5152 | + } | ||
5153 | + | ||
5154 | ieee80211_deliver_skb(rx); | ||
5155 | |||
5156 | return RX_QUEUED; | ||
5157 | diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c | ||
5158 | index ac210b5..70c79c3 100644 | ||
5159 | --- a/net/mac80211/tx.c | ||
5160 | +++ b/net/mac80211/tx.c | ||
5161 | @@ -1052,8 +1052,11 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | ||
5162 | |||
5163 | hdr = (struct ieee80211_hdr *) skb->data; | ||
5164 | |||
5165 | - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
5166 | + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { | ||
5167 | tx->sta = rcu_dereference(sdata->u.vlan.sta); | ||
5168 | + if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) | ||
5169 | + return TX_DROP; | ||
5170 | + } | ||
5171 | if (!tx->sta) | ||
5172 | tx->sta = sta_info_get(local, hdr->addr1); | ||
5173 | |||
5174 | diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c | ||
5175 | index fc70a49..43e83a4 100644 | ||
5176 | --- a/net/netfilter/xt_recent.c | ||
5177 | +++ b/net/netfilter/xt_recent.c | ||
5178 | @@ -173,10 +173,10 @@ recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr, | ||
5179 | |||
5180 | static void recent_entry_update(struct recent_table *t, struct recent_entry *e) | ||
5181 | { | ||
5182 | + e->index %= ip_pkt_list_tot; | ||
5183 | e->stamps[e->index++] = jiffies; | ||
5184 | if (e->index > e->nstamps) | ||
5185 | e->nstamps = e->index; | ||
5186 | - e->index %= ip_pkt_list_tot; | ||
5187 | list_move_tail(&e->lru_list, &t->lru_list); | ||
5188 | } | ||
5189 | |||
5190 | @@ -260,7 +260,7 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par) | ||
5191 | for (i = 0; i < e->nstamps; i++) { | ||
5192 | if (info->seconds && time_after(time, e->stamps[i])) | ||
5193 | continue; | ||
5194 | - if (++hits >= info->hit_count) { | ||
5195 | + if (info->hit_count && ++hits >= info->hit_count) { | ||
5196 | ret = !ret; | ||
5197 | break; | ||
5198 | } | ||
5199 | diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c | ||
5200 | index 7d1f9e9..4f30336 100644 | ||
5201 | --- a/net/sunrpc/svc_xprt.c | ||
5202 | +++ b/net/sunrpc/svc_xprt.c | ||
5203 | @@ -889,11 +889,8 @@ void svc_delete_xprt(struct svc_xprt *xprt) | ||
5204 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) | ||
5205 | serv->sv_tmpcnt--; | ||
5206 | |||
5207 | - for (dr = svc_deferred_dequeue(xprt); dr; | ||
5208 | - dr = svc_deferred_dequeue(xprt)) { | ||
5209 | - svc_xprt_put(xprt); | ||
5210 | + while ((dr = svc_deferred_dequeue(xprt)) != NULL) | ||
5211 | kfree(dr); | ||
5212 | - } | ||
5213 | |||
5214 | svc_xprt_put(xprt); | ||
5215 | spin_unlock_bh(&serv->sv_lock); | ||
5216 | diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c | ||
5217 | index 3d739e5..4df801d 100644 | ||
5218 | --- a/net/sunrpc/xprtsock.c | ||
5219 | +++ b/net/sunrpc/xprtsock.c | ||
5220 | @@ -1912,6 +1912,11 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt, | ||
5221 | case -EALREADY: | ||
5222 | xprt_clear_connecting(xprt); | ||
5223 | return; | ||
5224 | + case -EINVAL: | ||
5225 | + /* Happens, for instance, if the user specified a link | ||
5226 | + * local IPv6 address without a scope-id. | ||
5227 | + */ | ||
5228 | + goto out; | ||
5229 | } | ||
5230 | out_eagain: | ||
5231 | status = -EAGAIN; | ||
5232 | diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl | ||
5233 | index 2f3230d..049c419 100755 | ||
5234 | --- a/scripts/get_maintainer.pl | ||
5235 | +++ b/scripts/get_maintainer.pl | ||
5236 | @@ -314,6 +314,7 @@ foreach my $file (@files) { | ||
5237 | if ($type eq 'X') { | ||
5238 | if (file_match_pattern($file, $value)) { | ||
5239 | $exclude = 1; | ||
5240 | + last; | ||
5241 | } | ||
5242 | } | ||
5243 | } | ||
5244 | @@ -340,8 +341,7 @@ foreach my $file (@files) { | ||
5245 | } | ||
5246 | } | ||
5247 | |||
5248 | - $tvi += ($end - $start); | ||
5249 | - | ||
5250 | + $tvi = $end + 1; | ||
5251 | } | ||
5252 | |||
5253 | foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { | ||
5254 | diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c | ||
5255 | index 0d83edc..2d4d05d 100644 | ||
5256 | --- a/security/integrity/ima/ima_iint.c | ||
5257 | +++ b/security/integrity/ima/ima_iint.c | ||
5258 | @@ -63,12 +63,11 @@ int ima_inode_alloc(struct inode *inode) | ||
5259 | spin_lock(&ima_iint_lock); | ||
5260 | rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint); | ||
5261 | spin_unlock(&ima_iint_lock); | ||
5262 | + radix_tree_preload_end(); | ||
5263 | out: | ||
5264 | if (rc < 0) | ||
5265 | kmem_cache_free(iint_cache, iint); | ||
5266 | |||
5267 | - radix_tree_preload_end(); | ||
5268 | - | ||
5269 | return rc; | ||
5270 | } | ||
5271 | |||
5272 | diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c | ||
5273 | index 68c7348..04b6145 100644 | ||
5274 | --- a/security/selinux/ss/ebitmap.c | ||
5275 | +++ b/security/selinux/ss/ebitmap.c | ||
5276 | @@ -128,7 +128,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap, | ||
5277 | cmap_idx = delta / NETLBL_CATMAP_MAPSIZE; | ||
5278 | cmap_sft = delta % NETLBL_CATMAP_MAPSIZE; | ||
5279 | c_iter->bitmap[cmap_idx] | ||
5280 | - |= e_iter->maps[cmap_idx] << cmap_sft; | ||
5281 | + |= e_iter->maps[i] << cmap_sft; | ||
5282 | } | ||
5283 | e_iter = e_iter->next; | ||
5284 | } | ||
5285 | diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c | ||
5286 | index 25b0641..f7e1c9f 100644 | ||
5287 | --- a/sound/core/pcm_native.c | ||
5288 | +++ b/sound/core/pcm_native.c | ||
5289 | @@ -315,10 +315,10 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, | ||
5290 | if (!params->info) | ||
5291 | params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; | ||
5292 | if (!params->fifo_size) { | ||
5293 | - if (snd_mask_min(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT]) == | ||
5294 | - snd_mask_max(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT]) && | ||
5295 | - snd_mask_min(¶ms->masks[SNDRV_PCM_HW_PARAM_CHANNELS]) == | ||
5296 | - snd_mask_max(¶ms->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) { | ||
5297 | + m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
5298 | + i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
5299 | + if (snd_mask_min(m) == snd_mask_max(m) && | ||
5300 | + snd_interval_min(i) == snd_interval_max(i)) { | ||
5301 | changed = substream->ops->ioctl(substream, | ||
5302 | SNDRV_PCM_IOCTL1_FIFO_SIZE, params); | ||
5303 | if (changed < 0) | ||
5304 | diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c | ||
5305 | index ff6da6f..6d6e307 100644 | ||
5306 | --- a/sound/pci/hda/hda_intel.c | ||
5307 | +++ b/sound/pci/hda/hda_intel.c | ||
5308 | @@ -2261,9 +2261,12 @@ static int azx_dev_free(struct snd_device *device) | ||
5309 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { | ||
5310 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), | ||
5311 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), | ||
5312 | + SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), | ||
5313 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), | ||
5314 | + SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), | ||
5315 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), | ||
5316 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), | ||
5317 | + SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), | ||
5318 | {} | ||
5319 | }; | ||
5320 | |||
5321 | diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c | ||
5322 | index 69a941c..7069441 100644 | ||
5323 | --- a/sound/pci/hda/patch_analog.c | ||
5324 | +++ b/sound/pci/hda/patch_analog.c | ||
5325 | @@ -1008,7 +1008,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { | ||
5326 | SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK), | ||
5327 | SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK), | ||
5328 | SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK), | ||
5329 | - SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), | ||
5330 | + SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK), | ||
5331 | SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), | ||
5332 | SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), | ||
5333 | SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50), | ||
5334 | diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c | ||
5335 | index 8a332d2..03d6aea 100644 | ||
5336 | --- a/sound/pci/via82xx.c | ||
5337 | +++ b/sound/pci/via82xx.c | ||
5338 | @@ -1791,6 +1791,12 @@ static struct ac97_quirk ac97_quirks[] = { | ||
5339 | .type = AC97_TUNE_HP_ONLY | ||
5340 | }, | ||
5341 | { | ||
5342 | + .subvendor = 0x110a, | ||
5343 | + .subdevice = 0x0079, | ||
5344 | + .name = "Fujitsu Siemens D1289", | ||
5345 | + .type = AC97_TUNE_HP_ONLY | ||
5346 | + }, | ||
5347 | + { | ||
5348 | .subvendor = 0x1019, | ||
5349 | .subdevice = 0x0a81, | ||
5350 | .name = "ECS K7VTA3", | ||
5351 | diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c | ||
5352 | index 3a14c6f..0f439ab 100644 | ||
5353 | --- a/sound/soc/codecs/ak4104.c | ||
5354 | +++ b/sound/soc/codecs/ak4104.c | ||
5355 | @@ -90,12 +90,10 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg, | ||
5356 | if (reg >= codec->reg_cache_size) | ||
5357 | return -EINVAL; | ||
5358 | |||
5359 | - reg &= AK4104_REG_MASK; | ||
5360 | - reg |= AK4104_WRITE; | ||
5361 | - | ||
5362 | /* only write to the hardware if value has changed */ | ||
5363 | if (cache[reg] != value) { | ||
5364 | - u8 tmp[2] = { reg, value }; | ||
5365 | + u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value }; | ||
5366 | + | ||
5367 | if (spi_write(spi, tmp, sizeof(tmp))) { | ||
5368 | dev_err(&spi->dev, "SPI write failed\n"); | ||
5369 | return -EIO; | ||
5370 | diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c | ||
5371 | index 9edef46..3c81add 100644 | ||
5372 | --- a/sound/usb/usbaudio.c | ||
5373 | +++ b/sound/usb/usbaudio.c | ||
5374 | @@ -3327,6 +3327,32 @@ static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) | ||
5375 | } | ||
5376 | |||
5377 | /* | ||
5378 | + * This call will put the synth in "USB send" mode, i.e it will send MIDI | ||
5379 | + * messages through USB (this is disabled at startup). The synth will | ||
5380 | + * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB | ||
5381 | + * sign on its LCD. Values here are chosen based on sniffing USB traffic | ||
5382 | + * under Windows. | ||
5383 | + */ | ||
5384 | +static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev) | ||
5385 | +{ | ||
5386 | + int err, actual_length; | ||
5387 | + | ||
5388 | + /* "midi send" enable */ | ||
5389 | + static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 }; | ||
5390 | + | ||
5391 | + void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL); | ||
5392 | + if (!buf) | ||
5393 | + return -ENOMEM; | ||
5394 | + err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf, | ||
5395 | + ARRAY_SIZE(seq), &actual_length, 1000); | ||
5396 | + kfree(buf); | ||
5397 | + if (err < 0) | ||
5398 | + return err; | ||
5399 | + | ||
5400 | + return 0; | ||
5401 | +} | ||
5402 | + | ||
5403 | +/* | ||
5404 | * Setup quirks | ||
5405 | */ | ||
5406 | #define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ | ||
5407 | @@ -3624,6 +3650,12 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | ||
5408 | goto __err_val; | ||
5409 | } | ||
5410 | |||
5411 | + /* Access Music VirusTI Desktop */ | ||
5412 | + if (id == USB_ID(0x133e, 0x0815)) { | ||
5413 | + if (snd_usb_accessmusic_boot_quirk(dev) < 0) | ||
5414 | + goto __err_val; | ||
5415 | + } | ||
5416 | + | ||
5417 | /* | ||
5418 | * found a config. now register to ALSA | ||
5419 | */ | ||
5420 | diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c | ||
5421 | index 6e89b83..b2da478 100644 | ||
5422 | --- a/sound/usb/usbmidi.c | ||
5423 | +++ b/sound/usb/usbmidi.c | ||
5424 | @@ -1162,10 +1162,22 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, | ||
5425 | pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep); | ||
5426 | else | ||
5427 | pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep); | ||
5428 | - if (umidi->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ | ||
5429 | - ep->max_transfer = 4; | ||
5430 | - else | ||
5431 | + switch (umidi->usb_id) { | ||
5432 | + default: | ||
5433 | ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1); | ||
5434 | + break; | ||
5435 | + /* | ||
5436 | + * Various chips declare a packet size larger than 4 bytes, but | ||
5437 | + * do not actually work with larger packets: | ||
5438 | + */ | ||
5439 | + case USB_ID(0x0a92, 0x1020): /* ESI M4U */ | ||
5440 | + case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */ | ||
5441 | + case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */ | ||
5442 | + case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */ | ||
5443 | + case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */ | ||
5444 | + ep->max_transfer = 4; | ||
5445 | + break; | ||
5446 | + } | ||
5447 | for (i = 0; i < OUTPUT_URBS; ++i) { | ||
5448 | buffer = usb_buffer_alloc(umidi->dev, | ||
5449 | ep->max_transfer, GFP_KERNEL, | ||
5450 | @@ -1407,6 +1419,12 @@ static struct port_info { | ||
5451 | EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), | ||
5452 | EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), | ||
5453 | EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), | ||
5454 | + /* Access Music Virus TI */ | ||
5455 | + EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"), | ||
5456 | + PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0, | ||
5457 | + SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | | ||
5458 | + SNDRV_SEQ_PORT_TYPE_HARDWARE | | ||
5459 | + SNDRV_SEQ_PORT_TYPE_SYNTHESIZER), | ||
5460 | }; | ||
5461 | |||
5462 | static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number) | ||
5463 | diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h | ||
5464 | index a892bda..406b74b 100644 | ||
5465 | --- a/sound/usb/usbquirks.h | ||
5466 | +++ b/sound/usb/usbquirks.h | ||
5467 | @@ -2073,6 +2073,33 @@ YAMAHA_DEVICE(0x7010, "UB99"), | ||
5468 | } | ||
5469 | }, | ||
5470 | |||
5471 | +/* Access Music devices */ | ||
5472 | +{ | ||
5473 | + /* VirusTI Desktop */ | ||
5474 | + USB_DEVICE_VENDOR_SPEC(0x133e, 0x0815), | ||
5475 | + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
5476 | + .ifnum = QUIRK_ANY_INTERFACE, | ||
5477 | + .type = QUIRK_COMPOSITE, | ||
5478 | + .data = &(const struct snd_usb_audio_quirk[]) { | ||
5479 | + { | ||
5480 | + .ifnum = 3, | ||
5481 | + .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
5482 | + .data = &(const struct snd_usb_midi_endpoint_info) { | ||
5483 | + .out_cables = 0x0003, | ||
5484 | + .in_cables = 0x0003 | ||
5485 | + } | ||
5486 | + }, | ||
5487 | + { | ||
5488 | + .ifnum = 4, | ||
5489 | + .type = QUIRK_IGNORE_INTERFACE | ||
5490 | + }, | ||
5491 | + { | ||
5492 | + .ifnum = -1 | ||
5493 | + } | ||
5494 | + } | ||
5495 | + } | ||
5496 | +}, | ||
5497 | + | ||
5498 | /* */ | ||
5499 | { | ||
5500 | /* aka. Serato Scratch Live DJ Box */ | ||
5501 | diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c | ||
5502 | index ab92763..72547b9 100644 | ||
5503 | --- a/tools/perf/util/symbol.c | ||
5504 | +++ b/tools/perf/util/symbol.c | ||
5505 | @@ -503,7 +503,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | ||
5506 | return -1; | ||
5507 | |||
5508 | curr_map = map__new2(pos->start, dso, map->type); | ||
5509 | - if (map == NULL) { | ||
5510 | + if (curr_map == NULL) { | ||
5511 | dso__delete(dso); | ||
5512 | return -1; | ||
5513 | } |