Annotation of /trunk/kernel26-magellan/patches-2.6.31-r4/0108-2.6.31.9-all-fixes.patch
Parent Directory | Revision Log
Revision 968 -
(hide annotations)
(download)
Fri Jan 1 14:52:51 2010 UTC (14 years, 8 months ago) by niro
File size: 121020 byte(s)
Fri Jan 1 14:52:51 2010 UTC (14 years, 8 months ago) by niro
File size: 121020 byte(s)
-2.6.31-magellan-r4: -updated to linux-2.6.31.9
1 | niro | 968 | diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt |
2 | index 7936b80..3d5a958 100644 | ||
3 | --- a/Documentation/kernel-parameters.txt | ||
4 | +++ b/Documentation/kernel-parameters.txt | ||
5 | @@ -2561,6 +2561,8 @@ and is between 256 and 4096 characters. It is defined in the file | ||
6 | to a common usb-storage quirk flag as follows: | ||
7 | a = SANE_SENSE (collect more than 18 bytes | ||
8 | of sense data); | ||
9 | + b = BAD_SENSE (don't collect more than 18 | ||
10 | + bytes of sense data); | ||
11 | c = FIX_CAPACITY (decrease the reported | ||
12 | device capacity by one sector); | ||
13 | h = CAPACITY_HEURISTICS (decrease the | ||
14 | diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt | ||
15 | index d0a9ee3..03d58d2 100644 | ||
16 | --- a/Documentation/video4linux/gspca.txt | ||
17 | +++ b/Documentation/video4linux/gspca.txt | ||
18 | @@ -37,6 +37,7 @@ ov519 041e:405f Creative Live! VISTA VF0330 | ||
19 | ov519 041e:4060 Creative Live! VISTA VF0350 | ||
20 | ov519 041e:4061 Creative Live! VISTA VF0400 | ||
21 | ov519 041e:4064 Creative Live! VISTA VF0420 | ||
22 | +ov519 041e:4067 Creative Live! Cam Video IM (VF0350) | ||
23 | ov519 041e:4068 Creative Live! VISTA VF0470 | ||
24 | spca561 0458:7004 Genius VideoCAM Express V2 | ||
25 | sunplus 0458:7006 Genius Dsc 1.3 Smart | ||
26 | diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c | ||
27 | index 9cd0946..110e1f1 100644 | ||
28 | --- a/arch/arm/mach-pxa/em-x270.c | ||
29 | +++ b/arch/arm/mach-pxa/em-x270.c | ||
30 | @@ -497,16 +497,15 @@ static int em_x270_usb_hub_init(void) | ||
31 | goto err_free_vbus_gpio; | ||
32 | |||
33 | /* USB Hub power-on and reset */ | ||
34 | - gpio_direction_output(usb_hub_reset, 0); | ||
35 | + gpio_direction_output(usb_hub_reset, 1); | ||
36 | + gpio_direction_output(GPIO9_USB_VBUS_EN, 0); | ||
37 | regulator_enable(em_x270_usb_ldo); | ||
38 | - gpio_set_value(usb_hub_reset, 1); | ||
39 | gpio_set_value(usb_hub_reset, 0); | ||
40 | + gpio_set_value(usb_hub_reset, 1); | ||
41 | regulator_disable(em_x270_usb_ldo); | ||
42 | regulator_enable(em_x270_usb_ldo); | ||
43 | - gpio_set_value(usb_hub_reset, 1); | ||
44 | - | ||
45 | - /* enable VBUS */ | ||
46 | - gpio_direction_output(GPIO9_USB_VBUS_EN, 1); | ||
47 | + gpio_set_value(usb_hub_reset, 0); | ||
48 | + gpio_set_value(GPIO9_USB_VBUS_EN, 1); | ||
49 | |||
50 | return 0; | ||
51 | |||
52 | diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S | ||
53 | index ea4d646..419f492 100644 | ||
54 | --- a/arch/powerpc/kernel/vector.S | ||
55 | +++ b/arch/powerpc/kernel/vector.S | ||
56 | @@ -58,7 +58,7 @@ _GLOBAL(load_up_altivec) | ||
57 | * all 1's | ||
58 | */ | ||
59 | mfspr r4,SPRN_VRSAVE | ||
60 | - cmpdi 0,r4,0 | ||
61 | + cmpwi 0,r4,0 | ||
62 | bne+ 1f | ||
63 | li r4,-1 | ||
64 | mtspr SPRN_VRSAVE,r4 | ||
65 | diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h | ||
66 | index 0b2f829..1e31356 100644 | ||
67 | --- a/arch/s390/include/asm/kvm.h | ||
68 | +++ b/arch/s390/include/asm/kvm.h | ||
69 | @@ -1,6 +1,5 @@ | ||
70 | #ifndef __LINUX_KVM_S390_H | ||
71 | #define __LINUX_KVM_S390_H | ||
72 | - | ||
73 | /* | ||
74 | * asm-s390/kvm.h - KVM s390 specific structures and definitions | ||
75 | * | ||
76 | @@ -24,6 +23,8 @@ struct kvm_ioapic_state { | ||
77 | /* no IOAPIC for s390 */ | ||
78 | }; | ||
79 | |||
80 | +#define __KVM_S390 | ||
81 | + | ||
82 | /* for KVM_GET_REGS and KVM_SET_REGS */ | ||
83 | struct kvm_regs { | ||
84 | /* general purpose regs for s390 */ | ||
85 | diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c | ||
86 | index 90d9d1b..475fc29 100644 | ||
87 | --- a/arch/s390/kvm/kvm-s390.c | ||
88 | +++ b/arch/s390/kvm/kvm-s390.c | ||
89 | @@ -115,10 +115,16 @@ long kvm_arch_dev_ioctl(struct file *filp, | ||
90 | |||
91 | int kvm_dev_ioctl_check_extension(long ext) | ||
92 | { | ||
93 | + int r; | ||
94 | + | ||
95 | switch (ext) { | ||
96 | + case KVM_CAP_S390_PSW: | ||
97 | + r = 1; | ||
98 | + break; | ||
99 | default: | ||
100 | - return 0; | ||
101 | + r = 0; | ||
102 | } | ||
103 | + return r; | ||
104 | } | ||
105 | |||
106 | /* Section: vm related */ | ||
107 | @@ -422,8 +428,10 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw) | ||
108 | vcpu_load(vcpu); | ||
109 | if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING) | ||
110 | rc = -EBUSY; | ||
111 | - else | ||
112 | - vcpu->arch.sie_block->gpsw = psw; | ||
113 | + else { | ||
114 | + vcpu->run->psw_mask = psw.mask; | ||
115 | + vcpu->run->psw_addr = psw.addr; | ||
116 | + } | ||
117 | vcpu_put(vcpu); | ||
118 | return rc; | ||
119 | } | ||
120 | @@ -505,9 +513,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
121 | |||
122 | switch (kvm_run->exit_reason) { | ||
123 | case KVM_EXIT_S390_SIEIC: | ||
124 | - vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask; | ||
125 | - vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr; | ||
126 | - break; | ||
127 | case KVM_EXIT_UNKNOWN: | ||
128 | case KVM_EXIT_S390_RESET: | ||
129 | break; | ||
130 | @@ -515,6 +520,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
131 | BUG(); | ||
132 | } | ||
133 | |||
134 | + vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask; | ||
135 | + vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr; | ||
136 | + | ||
137 | might_fault(); | ||
138 | |||
139 | do { | ||
140 | @@ -529,8 +537,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
141 | /* intercept cannot be handled in-kernel, prepare kvm-run */ | ||
142 | kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; | ||
143 | kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode; | ||
144 | - kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask; | ||
145 | - kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr; | ||
146 | kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa; | ||
147 | kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb; | ||
148 | rc = 0; | ||
149 | @@ -542,6 +548,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
150 | rc = 0; | ||
151 | } | ||
152 | |||
153 | + kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask; | ||
154 | + kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr; | ||
155 | + | ||
156 | if (vcpu->sigset_active) | ||
157 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | ||
158 | |||
159 | diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile | ||
160 | index 6c21179..ef9a6b0 100644 | ||
161 | --- a/arch/sparc/Makefile | ||
162 | +++ b/arch/sparc/Makefile | ||
163 | @@ -27,6 +27,7 @@ AS := $(AS) -32 | ||
164 | LDFLAGS := -m elf32_sparc | ||
165 | CHECKFLAGS += -D__sparc__ | ||
166 | export BITS := 32 | ||
167 | +UTS_MACHINE := sparc | ||
168 | |||
169 | #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7 | ||
170 | KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 | ||
171 | @@ -50,6 +51,7 @@ CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64 | ||
172 | |||
173 | LDFLAGS := -m elf64_sparc | ||
174 | export BITS := 64 | ||
175 | +UTS_MACHINE := sparc64 | ||
176 | |||
177 | KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \ | ||
178 | -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \ | ||
179 | diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c | ||
180 | index cb3c72c..e0ba898 100644 | ||
181 | --- a/arch/sparc/kernel/ldc.c | ||
182 | +++ b/arch/sparc/kernel/ldc.c | ||
183 | @@ -1242,13 +1242,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name) | ||
184 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); | ||
185 | |||
186 | err = request_irq(lp->cfg.rx_irq, ldc_rx, | ||
187 | - IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED, | ||
188 | + IRQF_SAMPLE_RANDOM | IRQF_DISABLED, | ||
189 | lp->rx_irq_name, lp); | ||
190 | if (err) | ||
191 | return err; | ||
192 | |||
193 | err = request_irq(lp->cfg.tx_irq, ldc_tx, | ||
194 | - IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED, | ||
195 | + IRQF_SAMPLE_RANDOM | IRQF_DISABLED, | ||
196 | lp->tx_irq_name, lp); | ||
197 | if (err) { | ||
198 | free_irq(lp->cfg.rx_irq, lp); | ||
199 | diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c | ||
200 | index 881947e..0a6f2d1 100644 | ||
201 | --- a/arch/sparc/kernel/of_device_64.c | ||
202 | +++ b/arch/sparc/kernel/of_device_64.c | ||
203 | @@ -104,9 +104,19 @@ static int of_bus_pci_map(u32 *addr, const u32 *range, | ||
204 | int i; | ||
205 | |||
206 | /* Check address type match */ | ||
207 | - if ((addr[0] ^ range[0]) & 0x03000000) | ||
208 | - return -EINVAL; | ||
209 | + if (!((addr[0] ^ range[0]) & 0x03000000)) | ||
210 | + goto type_match; | ||
211 | + | ||
212 | + /* Special exception, we can map a 64-bit address into | ||
213 | + * a 32-bit range. | ||
214 | + */ | ||
215 | + if ((addr[0] & 0x03000000) == 0x03000000 && | ||
216 | + (range[0] & 0x03000000) == 0x02000000) | ||
217 | + goto type_match; | ||
218 | + | ||
219 | + return -EINVAL; | ||
220 | |||
221 | +type_match: | ||
222 | if (of_out_of_range(addr + 1, range + 1, range + na + pna, | ||
223 | na - 1, ns)) | ||
224 | return -EINVAL; | ||
225 | diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S | ||
226 | index 7ce9c65..24b8b12 100644 | ||
227 | --- a/arch/sparc/lib/mcount.S | ||
228 | +++ b/arch/sparc/lib/mcount.S | ||
229 | @@ -64,8 +64,9 @@ mcount: | ||
230 | 2: sethi %hi(softirq_stack), %g3 | ||
231 | or %g3, %lo(softirq_stack), %g3 | ||
232 | ldx [%g3 + %g1], %g7 | ||
233 | + sub %g7, STACK_BIAS, %g7 | ||
234 | cmp %sp, %g7 | ||
235 | - bleu,pt %xcc, 2f | ||
236 | + bleu,pt %xcc, 3f | ||
237 | sethi %hi(THREAD_SIZE), %g3 | ||
238 | add %g7, %g3, %g7 | ||
239 | cmp %sp, %g7 | ||
240 | @@ -75,7 +76,7 @@ mcount: | ||
241 | * again, we are already trying to output the stack overflow | ||
242 | * message. | ||
243 | */ | ||
244 | - sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough | ||
245 | +3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough | ||
246 | or %g7, %lo(ovstack), %g7 | ||
247 | add %g7, OVSTACKSIZE, %g3 | ||
248 | sub %g3, STACK_BIAS + 192, %g3 | ||
249 | diff --git a/arch/sparc/mm/init_64.h b/arch/sparc/mm/init_64.h | ||
250 | index c2f772d..77d1b31 100644 | ||
251 | --- a/arch/sparc/mm/init_64.h | ||
252 | +++ b/arch/sparc/mm/init_64.h | ||
253 | @@ -45,7 +45,7 @@ extern void free_initmem(void); | ||
254 | #define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK) | ||
255 | |||
256 | #define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \ | ||
257 | - sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT) | ||
258 | + sizeof(struct page)) >> VMEMMAP_CHUNK_SHIFT) | ||
259 | extern unsigned long vmemmap_table[VMEMMAP_SIZE]; | ||
260 | #endif | ||
261 | |||
262 | diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h | ||
263 | index 5cdd8d1..1d16c97 100644 | ||
264 | --- a/arch/x86/include/asm/mce.h | ||
265 | +++ b/arch/x86/include/asm/mce.h | ||
266 | @@ -214,5 +214,11 @@ void mce_log_therm_throt_event(__u64 status); | ||
267 | static inline void mce_log_therm_throt_event(__u64 status) {} | ||
268 | #endif | ||
269 | |||
270 | +#ifdef CONFIG_X86_THERMAL_VECTOR | ||
271 | +extern void mcheck_intel_therm_init(void); | ||
272 | +#else | ||
273 | +static inline void mcheck_intel_therm_init(void) { } | ||
274 | +#endif | ||
275 | + | ||
276 | #endif /* __KERNEL__ */ | ||
277 | #endif /* _ASM_X86_MCE_H */ | ||
278 | diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c | ||
279 | index 59cdfa4..2e837f5 100644 | ||
280 | --- a/arch/x86/kernel/acpi/cstate.c | ||
281 | +++ b/arch/x86/kernel/acpi/cstate.c | ||
282 | @@ -48,7 +48,7 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, | ||
283 | * P4, Core and beyond CPUs | ||
284 | */ | ||
285 | if (c->x86_vendor == X86_VENDOR_INTEL && | ||
286 | - (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 14))) | ||
287 | + (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f))) | ||
288 | flags->bm_control = 0; | ||
289 | } | ||
290 | EXPORT_SYMBOL(acpi_processor_power_init_bm_check); | ||
291 | diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c | ||
292 | index f5cb46a..d7be38c 100644 | ||
293 | --- a/arch/x86/kernel/amd_iommu.c | ||
294 | +++ b/arch/x86/kernel/amd_iommu.c | ||
295 | @@ -1873,10 +1873,10 @@ static void prealloc_protection_domains(void) | ||
296 | struct pci_dev *dev = NULL; | ||
297 | struct dma_ops_domain *dma_dom; | ||
298 | struct amd_iommu *iommu; | ||
299 | - u16 devid; | ||
300 | + u16 devid, __devid; | ||
301 | |||
302 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | ||
303 | - devid = calc_devid(dev->bus->number, dev->devfn); | ||
304 | + __devid = devid = calc_devid(dev->bus->number, dev->devfn); | ||
305 | if (devid > amd_iommu_last_bdf) | ||
306 | continue; | ||
307 | devid = amd_iommu_alias_table[devid]; | ||
308 | @@ -1891,6 +1891,10 @@ static void prealloc_protection_domains(void) | ||
309 | init_unity_mappings_for_device(dma_dom, devid); | ||
310 | dma_dom->target_dev = devid; | ||
311 | |||
312 | + attach_device(iommu, &dma_dom->domain, devid); | ||
313 | + if (__devid != devid) | ||
314 | + attach_device(iommu, &dma_dom->domain, __devid); | ||
315 | + | ||
316 | list_add_tail(&dma_dom->list, &iommu_pd_list); | ||
317 | } | ||
318 | } | ||
319 | diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c | ||
320 | index 1e423b2..ecd9050 100644 | ||
321 | --- a/arch/x86/kernel/amd_iommu_init.c | ||
322 | +++ b/arch/x86/kernel/amd_iommu_init.c | ||
323 | @@ -915,7 +915,7 @@ static int __init init_iommu_all(struct acpi_table_header *table) | ||
324 | * | ||
325 | ****************************************************************************/ | ||
326 | |||
327 | -static int __init iommu_setup_msi(struct amd_iommu *iommu) | ||
328 | +static int iommu_setup_msi(struct amd_iommu *iommu) | ||
329 | { | ||
330 | int r; | ||
331 | |||
332 | diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c | ||
333 | index 789efe2..781130f 100644 | ||
334 | --- a/arch/x86/kernel/cpu/intel_cacheinfo.c | ||
335 | +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | ||
336 | @@ -93,7 +93,7 @@ static const struct _cache_table __cpuinitconst cache_table[] = | ||
337 | { 0xd1, LVL_3, 1024 }, /* 4-way set assoc, 64 byte line size */ | ||
338 | { 0xd2, LVL_3, 2048 }, /* 4-way set assoc, 64 byte line size */ | ||
339 | { 0xd6, LVL_3, 1024 }, /* 8-way set assoc, 64 byte line size */ | ||
340 | - { 0xd7, LVL_3, 2038 }, /* 8-way set assoc, 64 byte line size */ | ||
341 | + { 0xd7, LVL_3, 2048 }, /* 8-way set assoc, 64 byte line size */ | ||
342 | { 0xd8, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */ | ||
343 | { 0xdc, LVL_3, 2048 }, /* 12-way set assoc, 64 byte line size */ | ||
344 | { 0xdd, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */ | ||
345 | @@ -101,6 +101,9 @@ static const struct _cache_table __cpuinitconst cache_table[] = | ||
346 | { 0xe2, LVL_3, 2048 }, /* 16-way set assoc, 64 byte line size */ | ||
347 | { 0xe3, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */ | ||
348 | { 0xe4, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */ | ||
349 | + { 0xea, LVL_3, 12288 }, /* 24-way set assoc, 64 byte line size */ | ||
350 | + { 0xeb, LVL_3, 18432 }, /* 24-way set assoc, 64 byte line size */ | ||
351 | + { 0xec, LVL_3, 24576 }, /* 24-way set assoc, 64 byte line size */ | ||
352 | { 0x00, 0, 0} | ||
353 | }; | ||
354 | |||
355 | diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c | ||
356 | index 0121304..4192c50 100644 | ||
357 | --- a/arch/x86/kernel/cpu/mcheck/mce.c | ||
358 | +++ b/arch/x86/kernel/cpu/mcheck/mce.c | ||
359 | @@ -1327,13 +1327,14 @@ static void mce_init_timer(void) | ||
360 | struct timer_list *t = &__get_cpu_var(mce_timer); | ||
361 | int *n = &__get_cpu_var(next_interval); | ||
362 | |||
363 | + setup_timer(t, mcheck_timer, smp_processor_id()); | ||
364 | + | ||
365 | if (mce_ignore_ce) | ||
366 | return; | ||
367 | |||
368 | *n = check_interval * HZ; | ||
369 | if (!*n) | ||
370 | return; | ||
371 | - setup_timer(t, mcheck_timer, smp_processor_id()); | ||
372 | t->expires = round_jiffies(jiffies + *n); | ||
373 | add_timer_on(t, smp_processor_id()); | ||
374 | } | ||
375 | diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c | ||
376 | index 600e724..a14a451 100644 | ||
377 | --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c | ||
378 | +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | ||
379 | @@ -49,6 +49,8 @@ static DEFINE_PER_CPU(struct thermal_state, thermal_state); | ||
380 | |||
381 | static atomic_t therm_throt_en = ATOMIC_INIT(0); | ||
382 | |||
383 | +static u32 lvtthmr_init __read_mostly; | ||
384 | + | ||
385 | #ifdef CONFIG_SYSFS | ||
386 | #define define_therm_throt_sysdev_one_ro(_name) \ | ||
387 | static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL) | ||
388 | @@ -254,6 +256,18 @@ asmlinkage void smp_thermal_interrupt(struct pt_regs *regs) | ||
389 | ack_APIC_irq(); | ||
390 | } | ||
391 | |||
392 | +void __init mcheck_intel_therm_init(void) | ||
393 | +{ | ||
394 | + /* | ||
395 | + * This function is only called on boot CPU. Save the init thermal | ||
396 | + * LVT value on BSP and use that value to restore APs' thermal LVT | ||
397 | + * entry BIOS programmed later | ||
398 | + */ | ||
399 | + if (cpu_has(&boot_cpu_data, X86_FEATURE_ACPI) && | ||
400 | + cpu_has(&boot_cpu_data, X86_FEATURE_ACC)) | ||
401 | + lvtthmr_init = apic_read(APIC_LVTTHMR); | ||
402 | +} | ||
403 | + | ||
404 | void intel_init_thermal(struct cpuinfo_x86 *c) | ||
405 | { | ||
406 | unsigned int cpu = smp_processor_id(); | ||
407 | @@ -270,7 +284,20 @@ void intel_init_thermal(struct cpuinfo_x86 *c) | ||
408 | * since it might be delivered via SMI already: | ||
409 | */ | ||
410 | rdmsr(MSR_IA32_MISC_ENABLE, l, h); | ||
411 | - h = apic_read(APIC_LVTTHMR); | ||
412 | + | ||
413 | + /* | ||
414 | + * The initial value of thermal LVT entries on all APs always reads | ||
415 | + * 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI | ||
416 | + * sequence to them and LVT registers are reset to 0s except for | ||
417 | + * the mask bits which are set to 1s when APs receive INIT IPI. | ||
418 | + * Always restore the value that BIOS has programmed on AP based on | ||
419 | + * BSP's info we saved since BIOS is always setting the same value | ||
420 | + * for all threads/cores | ||
421 | + */ | ||
422 | + apic_write(APIC_LVTTHMR, lvtthmr_init); | ||
423 | + | ||
424 | + h = lvtthmr_init; | ||
425 | + | ||
426 | if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) { | ||
427 | printk(KERN_DEBUG | ||
428 | "CPU%d: Thermal monitoring handled by SMI\n", cpu); | ||
429 | diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c | ||
430 | index e60ed74..d23746e 100644 | ||
431 | --- a/arch/x86/kernel/cpu/perfctr-watchdog.c | ||
432 | +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c | ||
433 | @@ -711,7 +711,7 @@ static void probe_nmi_watchdog(void) | ||
434 | switch (boot_cpu_data.x86_vendor) { | ||
435 | case X86_VENDOR_AMD: | ||
436 | if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 && | ||
437 | - boot_cpu_data.x86 != 16) | ||
438 | + boot_cpu_data.x86 != 16 && boot_cpu_data.x86 != 17) | ||
439 | return; | ||
440 | wd_ops = &k7_wd_ops; | ||
441 | break; | ||
442 | diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c | ||
443 | index 971a3be..e6ec8a2 100644 | ||
444 | --- a/arch/x86/kernel/pci-calgary_64.c | ||
445 | +++ b/arch/x86/kernel/pci-calgary_64.c | ||
446 | @@ -318,13 +318,15 @@ static inline struct iommu_table *find_iommu_table(struct device *dev) | ||
447 | |||
448 | pdev = to_pci_dev(dev); | ||
449 | |||
450 | + /* search up the device tree for an iommu */ | ||
451 | pbus = pdev->bus; | ||
452 | - | ||
453 | - /* is the device behind a bridge? Look for the root bus */ | ||
454 | - while (pbus->parent) | ||
455 | + do { | ||
456 | + tbl = pci_iommu(pbus); | ||
457 | + if (tbl && tbl->it_busno == pbus->number) | ||
458 | + break; | ||
459 | + tbl = NULL; | ||
460 | pbus = pbus->parent; | ||
461 | - | ||
462 | - tbl = pci_iommu(pbus); | ||
463 | + } while (pbus); | ||
464 | |||
465 | BUG_ON(tbl && (tbl->it_busno != pbus->number)); | ||
466 | |||
467 | diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c | ||
468 | index 1a041bc..953667c 100644 | ||
469 | --- a/arch/x86/kernel/pci-dma.c | ||
470 | +++ b/arch/x86/kernel/pci-dma.c | ||
471 | @@ -203,7 +203,7 @@ static __init int iommu_setup(char *p) | ||
472 | if (!strncmp(p, "allowdac", 8)) | ||
473 | forbid_dac = 0; | ||
474 | if (!strncmp(p, "nodac", 5)) | ||
475 | - forbid_dac = -1; | ||
476 | + forbid_dac = 1; | ||
477 | if (!strncmp(p, "usedac", 6)) { | ||
478 | forbid_dac = -1; | ||
479 | return 1; | ||
480 | diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c | ||
481 | index d2e56b8..6f711b3 100644 | ||
482 | --- a/arch/x86/kernel/pci-gart_64.c | ||
483 | +++ b/arch/x86/kernel/pci-gart_64.c | ||
484 | @@ -856,7 +856,7 @@ void __init gart_parse_options(char *p) | ||
485 | #endif | ||
486 | if (isdigit(*p) && get_option(&p, &arg)) | ||
487 | iommu_size = arg; | ||
488 | - if (!strncmp(p, "fullflush", 8)) | ||
489 | + if (!strncmp(p, "fullflush", 9)) | ||
490 | iommu_fullflush = 1; | ||
491 | if (!strncmp(p, "nofullflush", 11)) | ||
492 | iommu_fullflush = 0; | ||
493 | diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c | ||
494 | index a06e8d1..df1e1cb 100644 | ||
495 | --- a/arch/x86/kernel/reboot.c | ||
496 | +++ b/arch/x86/kernel/reboot.c | ||
497 | @@ -257,6 +257,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | ||
498 | DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"), | ||
499 | }, | ||
500 | }, | ||
501 | + { /* Handle problems with rebooting on ASUS P4S800 */ | ||
502 | + .callback = set_bios_reboot, | ||
503 | + .ident = "ASUS P4S800", | ||
504 | + .matches = { | ||
505 | + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
506 | + DMI_MATCH(DMI_BOARD_NAME, "P4S800"), | ||
507 | + }, | ||
508 | + }, | ||
509 | { } | ||
510 | }; | ||
511 | |||
512 | diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c | ||
513 | index 63f32d2..860ed56 100644 | ||
514 | --- a/arch/x86/kernel/setup.c | ||
515 | +++ b/arch/x86/kernel/setup.c | ||
516 | @@ -107,6 +107,7 @@ | ||
517 | #ifdef CONFIG_X86_64 | ||
518 | #include <asm/numa_64.h> | ||
519 | #endif | ||
520 | +#include <asm/mce.h> | ||
521 | |||
522 | #ifndef ARCH_SETUP | ||
523 | #define ARCH_SETUP | ||
524 | @@ -1030,6 +1031,8 @@ void __init setup_arch(char **cmdline_p) | ||
525 | conswitchp = &dummy_con; | ||
526 | #endif | ||
527 | #endif | ||
528 | + | ||
529 | + mcheck_intel_therm_init(); | ||
530 | } | ||
531 | |||
532 | #ifdef CONFIG_X86_32 | ||
533 | diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c | ||
534 | index 122c786..ca5f8d7 100644 | ||
535 | --- a/drivers/ata/pata_hpt37x.c | ||
536 | +++ b/drivers/ata/pata_hpt37x.c | ||
537 | @@ -24,7 +24,7 @@ | ||
538 | #include <linux/libata.h> | ||
539 | |||
540 | #define DRV_NAME "pata_hpt37x" | ||
541 | -#define DRV_VERSION "0.6.12" | ||
542 | +#define DRV_VERSION "0.6.14" | ||
543 | |||
544 | struct hpt_clock { | ||
545 | u8 xfer_speed; | ||
546 | @@ -404,9 +404,8 @@ static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
547 | |||
548 | pci_read_config_dword(pdev, addr1, ®); | ||
549 | mode = hpt37x_find_mode(ap, adev->pio_mode); | ||
550 | - mode &= ~0x8000000; /* No FIFO in PIO */ | ||
551 | - mode &= ~0x30070000; /* Leave config bits alone */ | ||
552 | - reg &= 0x30070000; /* Strip timing bits */ | ||
553 | + mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ | ||
554 | + reg &= ~0xCFC3FFFF; /* Strip timing bits */ | ||
555 | pci_write_config_dword(pdev, addr1, reg | mode); | ||
556 | } | ||
557 | |||
558 | @@ -423,8 +422,7 @@ static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) | ||
559 | { | ||
560 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
561 | u32 addr1, addr2; | ||
562 | - u32 reg; | ||
563 | - u32 mode; | ||
564 | + u32 reg, mode, mask; | ||
565 | u8 fast; | ||
566 | |||
567 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); | ||
568 | @@ -436,11 +434,12 @@ static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) | ||
569 | fast |= 0x01; | ||
570 | pci_write_config_byte(pdev, addr2, fast); | ||
571 | |||
572 | + mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; | ||
573 | + | ||
574 | pci_read_config_dword(pdev, addr1, ®); | ||
575 | mode = hpt37x_find_mode(ap, adev->dma_mode); | ||
576 | - mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ | ||
577 | - mode &= ~0xC0000000; /* Leave config bits alone */ | ||
578 | - reg &= 0xC0000000; /* Strip timing bits */ | ||
579 | + mode &= mask; | ||
580 | + reg &= ~mask; | ||
581 | pci_write_config_dword(pdev, addr1, reg | mode); | ||
582 | } | ||
583 | |||
584 | @@ -508,9 +507,8 @@ static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
585 | mode = hpt37x_find_mode(ap, adev->pio_mode); | ||
586 | |||
587 | printk("Find mode for %d reports %X\n", adev->pio_mode, mode); | ||
588 | - mode &= ~0x80000000; /* No FIFO in PIO */ | ||
589 | - mode &= ~0x30070000; /* Leave config bits alone */ | ||
590 | - reg &= 0x30070000; /* Strip timing bits */ | ||
591 | + mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ | ||
592 | + reg &= ~0xCFC3FFFF; /* Strip timing bits */ | ||
593 | pci_write_config_dword(pdev, addr1, reg | mode); | ||
594 | } | ||
595 | |||
596 | @@ -527,8 +525,7 @@ static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) | ||
597 | { | ||
598 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
599 | u32 addr1, addr2; | ||
600 | - u32 reg; | ||
601 | - u32 mode; | ||
602 | + u32 reg, mode, mask; | ||
603 | u8 fast; | ||
604 | |||
605 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); | ||
606 | @@ -539,12 +536,13 @@ static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) | ||
607 | fast &= ~0x07; | ||
608 | pci_write_config_byte(pdev, addr2, fast); | ||
609 | |||
610 | + mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; | ||
611 | + | ||
612 | pci_read_config_dword(pdev, addr1, ®); | ||
613 | mode = hpt37x_find_mode(ap, adev->dma_mode); | ||
614 | printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode); | ||
615 | - mode &= ~0xC0000000; /* Leave config bits alone */ | ||
616 | - mode |= 0x80000000; /* FIFO in MWDMA or UDMA */ | ||
617 | - reg &= 0xC0000000; /* Strip timing bits */ | ||
618 | + mode &= mask; | ||
619 | + reg &= ~mask; | ||
620 | pci_write_config_dword(pdev, addr1, reg | mode); | ||
621 | } | ||
622 | |||
623 | diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c | ||
624 | index 3d59fe0..21c5bd6 100644 | ||
625 | --- a/drivers/ata/pata_hpt3x2n.c | ||
626 | +++ b/drivers/ata/pata_hpt3x2n.c | ||
627 | @@ -25,7 +25,7 @@ | ||
628 | #include <linux/libata.h> | ||
629 | |||
630 | #define DRV_NAME "pata_hpt3x2n" | ||
631 | -#define DRV_VERSION "0.3.4" | ||
632 | +#define DRV_VERSION "0.3.7" | ||
633 | |||
634 | enum { | ||
635 | HPT_PCI_FAST = (1 << 31), | ||
636 | @@ -185,9 +185,8 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
637 | |||
638 | pci_read_config_dword(pdev, addr1, ®); | ||
639 | mode = hpt3x2n_find_mode(ap, adev->pio_mode); | ||
640 | - mode &= ~0x8000000; /* No FIFO in PIO */ | ||
641 | - mode &= ~0x30070000; /* Leave config bits alone */ | ||
642 | - reg &= 0x30070000; /* Strip timing bits */ | ||
643 | + mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ | ||
644 | + reg &= ~0xCFC3FFFF; /* Strip timing bits */ | ||
645 | pci_write_config_dword(pdev, addr1, reg | mode); | ||
646 | } | ||
647 | |||
648 | @@ -204,8 +203,7 @@ static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) | ||
649 | { | ||
650 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
651 | u32 addr1, addr2; | ||
652 | - u32 reg; | ||
653 | - u32 mode; | ||
654 | + u32 reg, mode, mask; | ||
655 | u8 fast; | ||
656 | |||
657 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); | ||
658 | @@ -216,11 +214,12 @@ static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) | ||
659 | fast &= ~0x07; | ||
660 | pci_write_config_byte(pdev, addr2, fast); | ||
661 | |||
662 | + mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; | ||
663 | + | ||
664 | pci_read_config_dword(pdev, addr1, ®); | ||
665 | mode = hpt3x2n_find_mode(ap, adev->dma_mode); | ||
666 | - mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ | ||
667 | - mode &= ~0xC0000000; /* Leave config bits alone */ | ||
668 | - reg &= 0xC0000000; /* Strip timing bits */ | ||
669 | + mode &= mask; | ||
670 | + reg &= ~mask; | ||
671 | pci_write_config_dword(pdev, addr1, reg | mode); | ||
672 | } | ||
673 | |||
674 | diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c | ||
675 | index 76b321b..e5827da 100644 | ||
676 | --- a/drivers/firewire/ohci.c | ||
677 | +++ b/drivers/firewire/ohci.c | ||
678 | @@ -2180,6 +2180,13 @@ static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base, | ||
679 | page = payload >> PAGE_SHIFT; | ||
680 | offset = payload & ~PAGE_MASK; | ||
681 | rest = p->payload_length; | ||
682 | + /* | ||
683 | + * The controllers I've tested have not worked correctly when | ||
684 | + * second_req_count is zero. Rather than do something we know won't | ||
685 | + * work, return an error | ||
686 | + */ | ||
687 | + if (rest == 0) | ||
688 | + return -EINVAL; | ||
689 | |||
690 | /* FIXME: make packet-per-buffer/dual-buffer a context option */ | ||
691 | while (rest > 0) { | ||
692 | @@ -2233,7 +2240,7 @@ static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base, | ||
693 | unsigned long payload) | ||
694 | { | ||
695 | struct iso_context *ctx = container_of(base, struct iso_context, base); | ||
696 | - struct descriptor *d = NULL, *pd = NULL; | ||
697 | + struct descriptor *d, *pd; | ||
698 | struct fw_iso_packet *p = packet; | ||
699 | dma_addr_t d_bus, page_bus; | ||
700 | u32 z, header_z, rest; | ||
701 | @@ -2271,8 +2278,9 @@ static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base, | ||
702 | d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d))); | ||
703 | |||
704 | rest = payload_per_buffer; | ||
705 | + pd = d; | ||
706 | for (j = 1; j < z; j++) { | ||
707 | - pd = d + j; | ||
708 | + pd++; | ||
709 | pd->control = cpu_to_le16(DESCRIPTOR_STATUS | | ||
710 | DESCRIPTOR_INPUT_MORE); | ||
711 | |||
712 | diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c | ||
713 | index f85aaf2..f298434 100644 | ||
714 | --- a/drivers/gpu/drm/drm_irq.c | ||
715 | +++ b/drivers/gpu/drm/drm_irq.c | ||
716 | @@ -402,15 +402,21 @@ int drm_vblank_get(struct drm_device *dev, int crtc) | ||
717 | |||
718 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
719 | /* Going from 0->1 means we have to enable interrupts again */ | ||
720 | - if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 && | ||
721 | - !dev->vblank_enabled[crtc]) { | ||
722 | - ret = dev->driver->enable_vblank(dev, crtc); | ||
723 | - DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); | ||
724 | - if (ret) | ||
725 | + if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { | ||
726 | + if (!dev->vblank_enabled[crtc]) { | ||
727 | + ret = dev->driver->enable_vblank(dev, crtc); | ||
728 | + DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); | ||
729 | + if (ret) | ||
730 | + atomic_dec(&dev->vblank_refcount[crtc]); | ||
731 | + else { | ||
732 | + dev->vblank_enabled[crtc] = 1; | ||
733 | + drm_update_vblank_count(dev, crtc); | ||
734 | + } | ||
735 | + } | ||
736 | + } else { | ||
737 | + if (!dev->vblank_enabled[crtc]) { | ||
738 | atomic_dec(&dev->vblank_refcount[crtc]); | ||
739 | - else { | ||
740 | - dev->vblank_enabled[crtc] = 1; | ||
741 | - drm_update_vblank_count(dev, crtc); | ||
742 | + ret = -EINVAL; | ||
743 | } | ||
744 | } | ||
745 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
746 | @@ -437,6 +443,18 @@ void drm_vblank_put(struct drm_device *dev, int crtc) | ||
747 | } | ||
748 | EXPORT_SYMBOL(drm_vblank_put); | ||
749 | |||
750 | +void drm_vblank_off(struct drm_device *dev, int crtc) | ||
751 | +{ | ||
752 | + unsigned long irqflags; | ||
753 | + | ||
754 | + spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
755 | + DRM_WAKEUP(&dev->vbl_queue[crtc]); | ||
756 | + dev->vblank_enabled[crtc] = 0; | ||
757 | + dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); | ||
758 | + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
759 | +} | ||
760 | +EXPORT_SYMBOL(drm_vblank_off); | ||
761 | + | ||
762 | /** | ||
763 | * drm_vblank_pre_modeset - account for vblanks across mode sets | ||
764 | * @dev: DRM device | ||
765 | diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h | ||
766 | index 88b3eff..d3f365d 100644 | ||
767 | --- a/drivers/gpu/drm/i915/i915_drv.h | ||
768 | +++ b/drivers/gpu/drm/i915/i915_drv.h | ||
769 | @@ -264,6 +264,7 @@ typedef struct drm_i915_private { | ||
770 | u32 saveDSPASURF; | ||
771 | u32 saveDSPATILEOFF; | ||
772 | u32 savePFIT_PGM_RATIOS; | ||
773 | + u32 saveBLC_HIST_CTL; | ||
774 | u32 saveBLC_PWM_CTL; | ||
775 | u32 saveBLC_PWM_CTL2; | ||
776 | u32 saveFPB0; | ||
777 | @@ -837,6 +838,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | ||
778 | #define IS_I85X(dev) ((dev)->pci_device == 0x3582) | ||
779 | #define IS_I855(dev) ((dev)->pci_device == 0x3582) | ||
780 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) | ||
781 | +#define IS_I8XX(dev) (IS_I830(dev) || IS_845G(dev) || IS_I85X(dev) || IS_I865G(dev)) | ||
782 | |||
783 | #define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a) | ||
784 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) | ||
785 | @@ -898,9 +900,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | ||
786 | */ | ||
787 | #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ | ||
788 | IS_I915GM(dev))) | ||
789 | +#define SUPPORTS_DIGITAL_OUTPUTS(dev) (IS_I9XX(dev) && !IS_IGD(dev)) | ||
790 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
791 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
792 | #define SUPPORTS_EDP(dev) (IS_IGDNG_M(dev)) | ||
793 | +#define SUPPORTS_TV(dev) (IS_I9XX(dev) && IS_MOBILE(dev) && \ | ||
794 | + !IS_IGDNG(dev) && !IS_IGD(dev)) | ||
795 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) | ||
796 | /* dsparb controlled by hw only */ | ||
797 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
798 | diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h | ||
799 | index c017fa1..9917749 100644 | ||
800 | --- a/drivers/gpu/drm/i915/i915_reg.h | ||
801 | +++ b/drivers/gpu/drm/i915/i915_reg.h | ||
802 | @@ -915,6 +915,8 @@ | ||
803 | #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) | ||
804 | #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) | ||
805 | |||
806 | +#define BLC_HIST_CTL 0x61260 | ||
807 | + | ||
808 | /* TV port control */ | ||
809 | #define TV_CTL 0x68000 | ||
810 | /** Enables the TV encoder */ | ||
811 | diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c | ||
812 | index 1d04e19..2e4aca6 100644 | ||
813 | --- a/drivers/gpu/drm/i915/i915_suspend.c | ||
814 | +++ b/drivers/gpu/drm/i915/i915_suspend.c | ||
815 | @@ -416,6 +416,7 @@ int i915_save_state(struct drm_device *dev) | ||
816 | dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); | ||
817 | dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); | ||
818 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); | ||
819 | + dev_priv->saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL); | ||
820 | if (IS_I965G(dev)) | ||
821 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); | ||
822 | if (IS_MOBILE(dev) && !IS_I830(dev)) | ||
823 | @@ -560,6 +561,7 @@ int i915_restore_state(struct drm_device *dev) | ||
824 | |||
825 | I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); | ||
826 | I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); | ||
827 | + I915_WRITE(BLC_HIST_CTL, dev_priv->saveBLC_HIST_CTL); | ||
828 | I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); | ||
829 | I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); | ||
830 | I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); | ||
831 | diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c | ||
832 | index 5ae4c1a..046027f 100644 | ||
833 | --- a/drivers/gpu/drm/i915/intel_crt.c | ||
834 | +++ b/drivers/gpu/drm/i915/intel_crt.c | ||
835 | @@ -234,8 +234,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | ||
836 | } while (time_after(timeout, jiffies)); | ||
837 | } | ||
838 | |||
839 | - if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) == | ||
840 | - CRT_HOTPLUG_MONITOR_COLOR) | ||
841 | + if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) != | ||
842 | + CRT_HOTPLUG_MONITOR_NONE) | ||
843 | return true; | ||
844 | |||
845 | return false; | ||
846 | diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c | ||
847 | index 318ba47..3ac3b7c 100644 | ||
848 | --- a/drivers/gpu/drm/i915/intel_display.c | ||
849 | +++ b/drivers/gpu/drm/i915/intel_display.c | ||
850 | @@ -1182,6 +1182,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
851 | case DRM_MODE_DPMS_STANDBY: | ||
852 | case DRM_MODE_DPMS_SUSPEND: | ||
853 | DRM_DEBUG("crtc %d dpms on\n", pipe); | ||
854 | + | ||
855 | + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | ||
856 | + temp = I915_READ(PCH_LVDS); | ||
857 | + if ((temp & LVDS_PORT_EN) == 0) { | ||
858 | + I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN); | ||
859 | + POSTING_READ(PCH_LVDS); | ||
860 | + } | ||
861 | + } | ||
862 | + | ||
863 | if (HAS_eDP) { | ||
864 | /* enable eDP PLL */ | ||
865 | igdng_enable_pll_edp(crtc); | ||
866 | @@ -1366,8 +1375,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
867 | case DRM_MODE_DPMS_OFF: | ||
868 | DRM_DEBUG("crtc %d dpms off\n", pipe); | ||
869 | |||
870 | - i915_disable_vga(dev); | ||
871 | - | ||
872 | /* Disable display plane */ | ||
873 | temp = I915_READ(dspcntr_reg); | ||
874 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { | ||
875 | @@ -1377,6 +1384,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
876 | I915_READ(dspbase_reg); | ||
877 | } | ||
878 | |||
879 | + i915_disable_vga(dev); | ||
880 | + | ||
881 | /* disable cpu pipe, disable after all planes disabled */ | ||
882 | temp = I915_READ(pipeconf_reg); | ||
883 | if ((temp & PIPEACONF_ENABLE) != 0) { | ||
884 | @@ -1397,9 +1406,15 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
885 | } else | ||
886 | DRM_DEBUG("crtc %d is disabled\n", pipe); | ||
887 | |||
888 | - if (HAS_eDP) { | ||
889 | - igdng_disable_pll_edp(crtc); | ||
890 | + udelay(100); | ||
891 | + | ||
892 | + /* Disable PF */ | ||
893 | + temp = I915_READ(pf_ctl_reg); | ||
894 | + if ((temp & PF_ENABLE) != 0) { | ||
895 | + I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
896 | + I915_READ(pf_ctl_reg); | ||
897 | } | ||
898 | + I915_WRITE(pf_win_size, 0); | ||
899 | |||
900 | /* disable CPU FDI tx and PCH FDI rx */ | ||
901 | temp = I915_READ(fdi_tx_reg); | ||
902 | @@ -1425,6 +1440,13 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
903 | |||
904 | udelay(100); | ||
905 | |||
906 | + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | ||
907 | + temp = I915_READ(PCH_LVDS); | ||
908 | + I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN); | ||
909 | + I915_READ(PCH_LVDS); | ||
910 | + udelay(100); | ||
911 | + } | ||
912 | + | ||
913 | /* disable PCH transcoder */ | ||
914 | temp = I915_READ(transconf_reg); | ||
915 | if ((temp & TRANS_ENABLE) != 0) { | ||
916 | @@ -1444,6 +1466,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
917 | } | ||
918 | } | ||
919 | |||
920 | + udelay(100); | ||
921 | + | ||
922 | /* disable PCH DPLL */ | ||
923 | temp = I915_READ(pch_dpll_reg); | ||
924 | if ((temp & DPLL_VCO_ENABLE) != 0) { | ||
925 | @@ -1451,14 +1475,20 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
926 | I915_READ(pch_dpll_reg); | ||
927 | } | ||
928 | |||
929 | - temp = I915_READ(fdi_rx_reg); | ||
930 | - if ((temp & FDI_RX_PLL_ENABLE) != 0) { | ||
931 | - temp &= ~FDI_SEL_PCDCLK; | ||
932 | - temp &= ~FDI_RX_PLL_ENABLE; | ||
933 | - I915_WRITE(fdi_rx_reg, temp); | ||
934 | - I915_READ(fdi_rx_reg); | ||
935 | + if (HAS_eDP) { | ||
936 | + igdng_disable_pll_edp(crtc); | ||
937 | } | ||
938 | |||
939 | + temp = I915_READ(fdi_rx_reg); | ||
940 | + temp &= ~FDI_SEL_PCDCLK; | ||
941 | + I915_WRITE(fdi_rx_reg, temp); | ||
942 | + I915_READ(fdi_rx_reg); | ||
943 | + | ||
944 | + temp = I915_READ(fdi_rx_reg); | ||
945 | + temp &= ~FDI_RX_PLL_ENABLE; | ||
946 | + I915_WRITE(fdi_rx_reg, temp); | ||
947 | + I915_READ(fdi_rx_reg); | ||
948 | + | ||
949 | /* Disable CPU FDI TX PLL */ | ||
950 | temp = I915_READ(fdi_tx_reg); | ||
951 | if ((temp & FDI_TX_PLL_ENABLE) != 0) { | ||
952 | @@ -1467,16 +1497,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
953 | udelay(100); | ||
954 | } | ||
955 | |||
956 | - /* Disable PF */ | ||
957 | - temp = I915_READ(pf_ctl_reg); | ||
958 | - if ((temp & PF_ENABLE) != 0) { | ||
959 | - I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
960 | - I915_READ(pf_ctl_reg); | ||
961 | - } | ||
962 | - I915_WRITE(pf_win_size, 0); | ||
963 | - | ||
964 | /* Wait for the clocks to turn off. */ | ||
965 | - udelay(150); | ||
966 | + udelay(100); | ||
967 | break; | ||
968 | } | ||
969 | } | ||
970 | @@ -1540,6 +1562,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
971 | intel_update_watermarks(dev); | ||
972 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | ||
973 | //intel_crtc_dpms_video(crtc, FALSE); TODO | ||
974 | + drm_vblank_off(dev, pipe); | ||
975 | |||
976 | /* Disable the VGA plane that we never use */ | ||
977 | i915_disable_vga(dev); | ||
978 | @@ -3325,7 +3348,7 @@ static void intel_setup_outputs(struct drm_device *dev) | ||
979 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | ||
980 | intel_dp_init(dev, PCH_DP_D); | ||
981 | |||
982 | - } else if (IS_I9XX(dev)) { | ||
983 | + } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { | ||
984 | bool found = false; | ||
985 | |||
986 | if (I915_READ(SDVOB) & SDVO_DETECTED) { | ||
987 | @@ -3352,10 +3375,10 @@ static void intel_setup_outputs(struct drm_device *dev) | ||
988 | |||
989 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) | ||
990 | intel_dp_init(dev, DP_D); | ||
991 | - } else | ||
992 | + } else if (IS_I8XX(dev)) | ||
993 | intel_dvo_init(dev); | ||
994 | |||
995 | - if (IS_I9XX(dev) && IS_MOBILE(dev) && !IS_IGDNG(dev)) | ||
996 | + if (SUPPORTS_TV(dev)) | ||
997 | intel_tv_init(dev); | ||
998 | |||
999 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
1000 | diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c | ||
1001 | index 5b1c9e9..05f6fe4 100644 | ||
1002 | --- a/drivers/gpu/drm/i915/intel_tv.c | ||
1003 | +++ b/drivers/gpu/drm/i915/intel_tv.c | ||
1004 | @@ -1212,20 +1212,17 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | ||
1005 | tv_ctl |= TV_TRILEVEL_SYNC; | ||
1006 | if (tv_mode->pal_burst) | ||
1007 | tv_ctl |= TV_PAL_BURST; | ||
1008 | + | ||
1009 | scctl1 = 0; | ||
1010 | - /* dda1 implies valid video levels */ | ||
1011 | - if (tv_mode->dda1_inc) { | ||
1012 | + if (tv_mode->dda1_inc) | ||
1013 | scctl1 |= TV_SC_DDA1_EN; | ||
1014 | - } | ||
1015 | - | ||
1016 | if (tv_mode->dda2_inc) | ||
1017 | scctl1 |= TV_SC_DDA2_EN; | ||
1018 | - | ||
1019 | if (tv_mode->dda3_inc) | ||
1020 | scctl1 |= TV_SC_DDA3_EN; | ||
1021 | - | ||
1022 | scctl1 |= tv_mode->sc_reset; | ||
1023 | - scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; | ||
1024 | + if (video_levels) | ||
1025 | + scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; | ||
1026 | scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT; | ||
1027 | |||
1028 | scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT | | ||
1029 | diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c | ||
1030 | index fcfe5c0..7bae834 100644 | ||
1031 | --- a/drivers/gpu/drm/radeon/radeon_atombios.c | ||
1032 | +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | ||
1033 | @@ -134,6 +134,14 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | ||
1034 | } | ||
1035 | } | ||
1036 | |||
1037 | + /* HIS X1300 is DVI+VGA, not DVI+DVI */ | ||
1038 | + if ((dev->pdev->device == 0x7146) && | ||
1039 | + (dev->pdev->subsystem_vendor == 0x17af) && | ||
1040 | + (dev->pdev->subsystem_device == 0x2058)) { | ||
1041 | + if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) | ||
1042 | + return false; | ||
1043 | + } | ||
1044 | + | ||
1045 | /* Funky macbooks */ | ||
1046 | if ((dev->pdev->device == 0x71C5) && | ||
1047 | (dev->pdev->subsystem_vendor == 0x106b) && | ||
1048 | diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | ||
1049 | index 0da72f1..ff9c18d 100644 | ||
1050 | --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | ||
1051 | +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | ||
1052 | @@ -291,8 +291,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
1053 | uint32_t mask; | ||
1054 | |||
1055 | if (radeon_crtc->crtc_id) | ||
1056 | - mask = (RADEON_CRTC2_EN | | ||
1057 | - RADEON_CRTC2_DISP_DIS | | ||
1058 | + mask = (RADEON_CRTC2_DISP_DIS | | ||
1059 | RADEON_CRTC2_VSYNC_DIS | | ||
1060 | RADEON_CRTC2_HSYNC_DIS | | ||
1061 | RADEON_CRTC2_DISP_REQ_EN_B); | ||
1062 | @@ -304,7 +303,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
1063 | switch (mode) { | ||
1064 | case DRM_MODE_DPMS_ON: | ||
1065 | if (radeon_crtc->crtc_id) | ||
1066 | - WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask); | ||
1067 | + WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask)); | ||
1068 | else { | ||
1069 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | | ||
1070 | RADEON_CRTC_DISP_REQ_EN_B)); | ||
1071 | @@ -318,7 +317,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
1072 | case DRM_MODE_DPMS_OFF: | ||
1073 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); | ||
1074 | if (radeon_crtc->crtc_id) | ||
1075 | - WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); | ||
1076 | + WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); | ||
1077 | else { | ||
1078 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | | ||
1079 | RADEON_CRTC_DISP_REQ_EN_B)); | ||
1080 | diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c | ||
1081 | index 680e597..ca0c46f 100644 | ||
1082 | --- a/drivers/ide/cmd64x.c | ||
1083 | +++ b/drivers/ide/cmd64x.c | ||
1084 | @@ -379,7 +379,8 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | ||
1085 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, | ||
1086 | .port_ops = &cmd64x_port_ops, | ||
1087 | .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | | ||
1088 | - IDE_HFLAG_ABUSE_PREFETCH, | ||
1089 | + IDE_HFLAG_ABUSE_PREFETCH | | ||
1090 | + IDE_HFLAG_SERIALIZE, | ||
1091 | .pio_mask = ATA_PIO5, | ||
1092 | .mwdma_mask = ATA_MWDMA2, | ||
1093 | .udma_mask = 0x00, /* no udma */ | ||
1094 | @@ -389,7 +390,8 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | ||
1095 | .init_chipset = init_chipset_cmd64x, | ||
1096 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | ||
1097 | .port_ops = &cmd648_port_ops, | ||
1098 | - .host_flags = IDE_HFLAG_ABUSE_PREFETCH, | ||
1099 | + .host_flags = IDE_HFLAG_ABUSE_PREFETCH | | ||
1100 | + IDE_HFLAG_SERIALIZE, | ||
1101 | .pio_mask = ATA_PIO5, | ||
1102 | .mwdma_mask = ATA_MWDMA2, | ||
1103 | .udma_mask = ATA_UDMA2, | ||
1104 | diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c | ||
1105 | index e246d3d..b05ee08 100644 | ||
1106 | --- a/drivers/ide/ide-ioctls.c | ||
1107 | +++ b/drivers/ide/ide-ioctls.c | ||
1108 | @@ -162,7 +162,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) | ||
1109 | if (tf->command == ATA_CMD_SET_FEATURES && | ||
1110 | tf->feature == SETFEATURES_XFER && | ||
1111 | tf->nsect >= XFER_SW_DMA_0) { | ||
1112 | - xfer_rate = ide_find_dma_mode(drive, XFER_UDMA_6); | ||
1113 | + xfer_rate = ide_find_dma_mode(drive, tf->nsect); | ||
1114 | if (xfer_rate != tf->nsect) { | ||
1115 | err = -EINVAL; | ||
1116 | goto abort; | ||
1117 | diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c | ||
1118 | index 1bb106f..ad33db2 100644 | ||
1119 | --- a/drivers/ide/ide-probe.c | ||
1120 | +++ b/drivers/ide/ide-probe.c | ||
1121 | @@ -1035,15 +1035,6 @@ static void ide_port_init_devices(ide_hwif_t *hwif) | ||
1122 | if (port_ops && port_ops->init_dev) | ||
1123 | port_ops->init_dev(drive); | ||
1124 | } | ||
1125 | - | ||
1126 | - ide_port_for_each_dev(i, drive, hwif) { | ||
1127 | - /* | ||
1128 | - * default to PIO Mode 0 before we figure out | ||
1129 | - * the most suited mode for the attached device | ||
1130 | - */ | ||
1131 | - if (port_ops && port_ops->set_pio_mode) | ||
1132 | - port_ops->set_pio_mode(drive, 0); | ||
1133 | - } | ||
1134 | } | ||
1135 | |||
1136 | static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | ||
1137 | diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c | ||
1138 | index 9aec78d..1ccfb40 100644 | ||
1139 | --- a/drivers/ide/slc90e66.c | ||
1140 | +++ b/drivers/ide/slc90e66.c | ||
1141 | @@ -91,8 +91,7 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed) | ||
1142 | |||
1143 | if (!(reg48 & u_flag)) | ||
1144 | pci_write_config_word(dev, 0x48, reg48|u_flag); | ||
1145 | - /* FIXME: (reg4a & a_speed) ? */ | ||
1146 | - if ((reg4a & u_speed) != u_speed) { | ||
1147 | + if ((reg4a & a_speed) != u_speed) { | ||
1148 | pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); | ||
1149 | pci_read_config_word(dev, 0x4a, ®4a); | ||
1150 | pci_write_config_word(dev, 0x4a, reg4a|u_speed); | ||
1151 | diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c | ||
1152 | index aa30b5c..9a9dc3b 100644 | ||
1153 | --- a/drivers/isdn/i4l/isdn_ppp.c | ||
1154 | +++ b/drivers/isdn/i4l/isdn_ppp.c | ||
1155 | @@ -1535,10 +1535,8 @@ static int isdn_ppp_mp_bundle_array_init(void) | ||
1156 | int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); | ||
1157 | if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL ) | ||
1158 | return -ENOMEM; | ||
1159 | - for (i = 0; i < ISDN_MAX_CHANNELS; i++) { | ||
1160 | + for( i = 0; i < ISDN_MAX_CHANNELS; i++ ) | ||
1161 | spin_lock_init(&isdn_ppp_bundle_arr[i].lock); | ||
1162 | - skb_queue_head_init(&isdn_ppp_bundle_arr[i].frags); | ||
1163 | - } | ||
1164 | return 0; | ||
1165 | } | ||
1166 | |||
1167 | @@ -1571,7 +1569,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) | ||
1168 | if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) | ||
1169 | return -ENOMEM; | ||
1170 | lp->next = lp->last = lp; /* nobody else in a queue */ | ||
1171 | - skb_queue_head_init(&lp->netdev->pb->frags); | ||
1172 | + lp->netdev->pb->frags = NULL; | ||
1173 | lp->netdev->pb->frames = 0; | ||
1174 | lp->netdev->pb->seq = UINT_MAX; | ||
1175 | } | ||
1176 | @@ -1583,29 +1581,28 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) | ||
1177 | |||
1178 | static u32 isdn_ppp_mp_get_seq( int short_seq, | ||
1179 | struct sk_buff * skb, u32 last_seq ); | ||
1180 | -static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, | ||
1181 | - struct sk_buff *to); | ||
1182 | -static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp, | ||
1183 | - struct sk_buff *from, struct sk_buff *to, | ||
1184 | - u32 lastseq); | ||
1185 | -static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb); | ||
1186 | +static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, | ||
1187 | + struct sk_buff * from, struct sk_buff * to ); | ||
1188 | +static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, | ||
1189 | + struct sk_buff * from, struct sk_buff * to ); | ||
1190 | +static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb ); | ||
1191 | static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); | ||
1192 | |||
1193 | static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | ||
1194 | - struct sk_buff *skb) | ||
1195 | + struct sk_buff *skb) | ||
1196 | { | ||
1197 | - struct sk_buff *newfrag, *frag, *start, *nextf; | ||
1198 | - u32 newseq, minseq, thisseq; | ||
1199 | - isdn_mppp_stats *stats; | ||
1200 | struct ippp_struct *is; | ||
1201 | + isdn_net_local * lpq; | ||
1202 | + ippp_bundle * mp; | ||
1203 | + isdn_mppp_stats * stats; | ||
1204 | + struct sk_buff * newfrag, * frag, * start, *nextf; | ||
1205 | + u32 newseq, minseq, thisseq; | ||
1206 | unsigned long flags; | ||
1207 | - isdn_net_local *lpq; | ||
1208 | - ippp_bundle *mp; | ||
1209 | int slot; | ||
1210 | |||
1211 | spin_lock_irqsave(&net_dev->pb->lock, flags); | ||
1212 | - mp = net_dev->pb; | ||
1213 | - stats = &mp->stats; | ||
1214 | + mp = net_dev->pb; | ||
1215 | + stats = &mp->stats; | ||
1216 | slot = lp->ppp_slot; | ||
1217 | if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { | ||
1218 | printk(KERN_ERR "%s: lp->ppp_slot(%d)\n", | ||
1219 | @@ -1616,19 +1613,20 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | ||
1220 | return; | ||
1221 | } | ||
1222 | is = ippp_table[slot]; | ||
1223 | - if (++mp->frames > stats->max_queue_len) | ||
1224 | + if( ++mp->frames > stats->max_queue_len ) | ||
1225 | stats->max_queue_len = mp->frames; | ||
1226 | |||
1227 | if (is->debug & 0x8) | ||
1228 | isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb); | ||
1229 | |||
1230 | newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, | ||
1231 | - skb, is->last_link_seqno); | ||
1232 | + skb, is->last_link_seqno); | ||
1233 | + | ||
1234 | |||
1235 | /* if this packet seq # is less than last already processed one, | ||
1236 | * toss it right away, but check for sequence start case first | ||
1237 | */ | ||
1238 | - if (mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT)) { | ||
1239 | + if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) { | ||
1240 | mp->seq = newseq; /* the first packet: required for | ||
1241 | * rfc1990 non-compliant clients -- | ||
1242 | * prevents constant packet toss */ | ||
1243 | @@ -1659,31 +1657,22 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | ||
1244 | * packets */ | ||
1245 | newfrag = skb; | ||
1246 | |||
1247 | - /* Insert new fragment into the proper sequence slot. */ | ||
1248 | - skb_queue_walk(&mp->frags, frag) { | ||
1249 | - if (MP_SEQ(frag) == newseq) { | ||
1250 | - isdn_ppp_mp_free_skb(mp, newfrag); | ||
1251 | - newfrag = NULL; | ||
1252 | - break; | ||
1253 | - } | ||
1254 | - if (MP_LT(newseq, MP_SEQ(frag))) { | ||
1255 | - __skb_queue_before(&mp->frags, frag, newfrag); | ||
1256 | - newfrag = NULL; | ||
1257 | - break; | ||
1258 | - } | ||
1259 | - } | ||
1260 | - if (newfrag) | ||
1261 | - __skb_queue_tail(&mp->frags, newfrag); | ||
1262 | + /* if this new fragment is before the first one, then enqueue it now. */ | ||
1263 | + if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) { | ||
1264 | + newfrag->next = frag; | ||
1265 | + mp->frags = frag = newfrag; | ||
1266 | + newfrag = NULL; | ||
1267 | + } | ||
1268 | |||
1269 | - frag = skb_peek(&mp->frags); | ||
1270 | - start = ((MP_FLAGS(frag) & MP_BEGIN_FRAG) && | ||
1271 | - (MP_SEQ(frag) == mp->seq)) ? frag : NULL; | ||
1272 | - if (!start) | ||
1273 | - goto check_overflow; | ||
1274 | + start = MP_FLAGS(frag) & MP_BEGIN_FRAG && | ||
1275 | + MP_SEQ(frag) == mp->seq ? frag : NULL; | ||
1276 | |||
1277 | - /* main fragment traversing loop | ||
1278 | + /* | ||
1279 | + * main fragment traversing loop | ||
1280 | * | ||
1281 | * try to accomplish several tasks: | ||
1282 | + * - insert new fragment into the proper sequence slot (once that's done | ||
1283 | + * newfrag will be set to NULL) | ||
1284 | * - reassemble any complete fragment sequence (non-null 'start' | ||
1285 | * indicates there is a continguous sequence present) | ||
1286 | * - discard any incomplete sequences that are below minseq -- due | ||
1287 | @@ -1692,46 +1681,71 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | ||
1288 | * come to complete such sequence and it should be discarded | ||
1289 | * | ||
1290 | * loop completes when we accomplished the following tasks: | ||
1291 | + * - new fragment is inserted in the proper sequence ('newfrag' is | ||
1292 | + * set to NULL) | ||
1293 | * - we hit a gap in the sequence, so no reassembly/processing is | ||
1294 | * possible ('start' would be set to NULL) | ||
1295 | * | ||
1296 | * algorithm for this code is derived from code in the book | ||
1297 | * 'PPP Design And Debugging' by James Carlson (Addison-Wesley) | ||
1298 | */ | ||
1299 | - skb_queue_walk_safe(&mp->frags, frag, nextf) { | ||
1300 | - thisseq = MP_SEQ(frag); | ||
1301 | - | ||
1302 | - /* check for misplaced start */ | ||
1303 | - if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { | ||
1304 | - printk(KERN_WARNING"isdn_mppp(seq %d): new " | ||
1305 | - "BEGIN flag with no prior END", thisseq); | ||
1306 | - stats->seqerrs++; | ||
1307 | - stats->frame_drops++; | ||
1308 | - isdn_ppp_mp_discard(mp, start, frag); | ||
1309 | - start = frag; | ||
1310 | - } else if (MP_LE(thisseq, minseq)) { | ||
1311 | - if (MP_FLAGS(frag) & MP_BEGIN_FRAG) | ||
1312 | + while (start != NULL || newfrag != NULL) { | ||
1313 | + | ||
1314 | + thisseq = MP_SEQ(frag); | ||
1315 | + nextf = frag->next; | ||
1316 | + | ||
1317 | + /* drop any duplicate fragments */ | ||
1318 | + if (newfrag != NULL && thisseq == newseq) { | ||
1319 | + isdn_ppp_mp_free_skb(mp, newfrag); | ||
1320 | + newfrag = NULL; | ||
1321 | + } | ||
1322 | + | ||
1323 | + /* insert new fragment before next element if possible. */ | ||
1324 | + if (newfrag != NULL && (nextf == NULL || | ||
1325 | + MP_LT(newseq, MP_SEQ(nextf)))) { | ||
1326 | + newfrag->next = nextf; | ||
1327 | + frag->next = nextf = newfrag; | ||
1328 | + newfrag = NULL; | ||
1329 | + } | ||
1330 | + | ||
1331 | + if (start != NULL) { | ||
1332 | + /* check for misplaced start */ | ||
1333 | + if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { | ||
1334 | + printk(KERN_WARNING"isdn_mppp(seq %d): new " | ||
1335 | + "BEGIN flag with no prior END", thisseq); | ||
1336 | + stats->seqerrs++; | ||
1337 | + stats->frame_drops++; | ||
1338 | + start = isdn_ppp_mp_discard(mp, start,frag); | ||
1339 | + nextf = frag->next; | ||
1340 | + } | ||
1341 | + } else if (MP_LE(thisseq, minseq)) { | ||
1342 | + if (MP_FLAGS(frag) & MP_BEGIN_FRAG) | ||
1343 | start = frag; | ||
1344 | - else { | ||
1345 | + else { | ||
1346 | if (MP_FLAGS(frag) & MP_END_FRAG) | ||
1347 | - stats->frame_drops++; | ||
1348 | - __skb_unlink(skb, &mp->frags); | ||
1349 | + stats->frame_drops++; | ||
1350 | + if( mp->frags == frag ) | ||
1351 | + mp->frags = nextf; | ||
1352 | isdn_ppp_mp_free_skb(mp, frag); | ||
1353 | + frag = nextf; | ||
1354 | continue; | ||
1355 | - } | ||
1356 | + } | ||
1357 | } | ||
1358 | |||
1359 | - /* if we have end fragment, then we have full reassembly | ||
1360 | - * sequence -- reassemble and process packet now | ||
1361 | + /* if start is non-null and we have end fragment, then | ||
1362 | + * we have full reassembly sequence -- reassemble | ||
1363 | + * and process packet now | ||
1364 | */ | ||
1365 | - if (MP_FLAGS(frag) & MP_END_FRAG) { | ||
1366 | - minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; | ||
1367 | - /* Reassemble the packet then dispatch it */ | ||
1368 | - isdn_ppp_mp_reassembly(net_dev, lp, start, frag, thisseq); | ||
1369 | + if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) { | ||
1370 | + minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; | ||
1371 | + /* Reassemble the packet then dispatch it */ | ||
1372 | + isdn_ppp_mp_reassembly(net_dev, lp, start, nextf); | ||
1373 | |||
1374 | - start = NULL; | ||
1375 | - frag = NULL; | ||
1376 | - } | ||
1377 | + start = NULL; | ||
1378 | + frag = NULL; | ||
1379 | + | ||
1380 | + mp->frags = nextf; | ||
1381 | + } | ||
1382 | |||
1383 | /* check if need to update start pointer: if we just | ||
1384 | * reassembled the packet and sequence is contiguous | ||
1385 | @@ -1742,25 +1756,26 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | ||
1386 | * below low watermark and set start to the next frag or | ||
1387 | * clear start ptr. | ||
1388 | */ | ||
1389 | - if (nextf != (struct sk_buff *)&mp->frags && | ||
1390 | + if (nextf != NULL && | ||
1391 | ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) { | ||
1392 | - /* if we just reassembled and the next one is here, | ||
1393 | - * then start another reassembly. | ||
1394 | - */ | ||
1395 | - if (frag == NULL) { | ||
1396 | + /* if we just reassembled and the next one is here, | ||
1397 | + * then start another reassembly. */ | ||
1398 | + | ||
1399 | + if (frag == NULL) { | ||
1400 | if (MP_FLAGS(nextf) & MP_BEGIN_FRAG) | ||
1401 | - start = nextf; | ||
1402 | - else { | ||
1403 | - printk(KERN_WARNING"isdn_mppp(seq %d):" | ||
1404 | - " END flag with no following " | ||
1405 | - "BEGIN", thisseq); | ||
1406 | + start = nextf; | ||
1407 | + else | ||
1408 | + { | ||
1409 | + printk(KERN_WARNING"isdn_mppp(seq %d):" | ||
1410 | + " END flag with no following " | ||
1411 | + "BEGIN", thisseq); | ||
1412 | stats->seqerrs++; | ||
1413 | } | ||
1414 | } | ||
1415 | - } else { | ||
1416 | - if (nextf != (struct sk_buff *)&mp->frags && | ||
1417 | - frag != NULL && | ||
1418 | - MP_LT(thisseq, minseq)) { | ||
1419 | + | ||
1420 | + } else { | ||
1421 | + if ( nextf != NULL && frag != NULL && | ||
1422 | + MP_LT(thisseq, minseq)) { | ||
1423 | /* we've got a break in the sequence | ||
1424 | * and we not at the end yet | ||
1425 | * and we did not just reassembled | ||
1426 | @@ -1769,39 +1784,41 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | ||
1427 | * discard all the frames below low watermark | ||
1428 | * and start over */ | ||
1429 | stats->frame_drops++; | ||
1430 | - isdn_ppp_mp_discard(mp, start, nextf); | ||
1431 | + mp->frags = isdn_ppp_mp_discard(mp,start,nextf); | ||
1432 | } | ||
1433 | /* break in the sequence, no reassembly */ | ||
1434 | - start = NULL; | ||
1435 | - } | ||
1436 | - if (!start) | ||
1437 | - break; | ||
1438 | - } | ||
1439 | + start = NULL; | ||
1440 | + } | ||
1441 | + | ||
1442 | + frag = nextf; | ||
1443 | + } /* while -- main loop */ | ||
1444 | + | ||
1445 | + if (mp->frags == NULL) | ||
1446 | + mp->frags = frag; | ||
1447 | |||
1448 | -check_overflow: | ||
1449 | /* rather straighforward way to deal with (not very) possible | ||
1450 | - * queue overflow | ||
1451 | - */ | ||
1452 | + * queue overflow */ | ||
1453 | if (mp->frames > MP_MAX_QUEUE_LEN) { | ||
1454 | stats->overflows++; | ||
1455 | - skb_queue_walk_safe(&mp->frags, frag, nextf) { | ||
1456 | - if (mp->frames <= MP_MAX_QUEUE_LEN) | ||
1457 | - break; | ||
1458 | - __skb_unlink(frag, &mp->frags); | ||
1459 | - isdn_ppp_mp_free_skb(mp, frag); | ||
1460 | + while (mp->frames > MP_MAX_QUEUE_LEN) { | ||
1461 | + frag = mp->frags->next; | ||
1462 | + isdn_ppp_mp_free_skb(mp, mp->frags); | ||
1463 | + mp->frags = frag; | ||
1464 | } | ||
1465 | } | ||
1466 | spin_unlock_irqrestore(&mp->lock, flags); | ||
1467 | } | ||
1468 | |||
1469 | -static void isdn_ppp_mp_cleanup(isdn_net_local *lp) | ||
1470 | +static void isdn_ppp_mp_cleanup( isdn_net_local * lp ) | ||
1471 | { | ||
1472 | - struct sk_buff *skb, *tmp; | ||
1473 | - | ||
1474 | - skb_queue_walk_safe(&lp->netdev->pb->frags, skb, tmp) { | ||
1475 | - __skb_unlink(skb, &lp->netdev->pb->frags); | ||
1476 | - isdn_ppp_mp_free_skb(lp->netdev->pb, skb); | ||
1477 | - } | ||
1478 | + struct sk_buff * frag = lp->netdev->pb->frags; | ||
1479 | + struct sk_buff * nextfrag; | ||
1480 | + while( frag ) { | ||
1481 | + nextfrag = frag->next; | ||
1482 | + isdn_ppp_mp_free_skb(lp->netdev->pb, frag); | ||
1483 | + frag = nextfrag; | ||
1484 | + } | ||
1485 | + lp->netdev->pb->frags = NULL; | ||
1486 | } | ||
1487 | |||
1488 | static u32 isdn_ppp_mp_get_seq( int short_seq, | ||
1489 | @@ -1838,115 +1855,72 @@ static u32 isdn_ppp_mp_get_seq( int short_seq, | ||
1490 | return seq; | ||
1491 | } | ||
1492 | |||
1493 | -static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, | ||
1494 | - struct sk_buff *to) | ||
1495 | +struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, | ||
1496 | + struct sk_buff * from, struct sk_buff * to ) | ||
1497 | { | ||
1498 | - if (from) { | ||
1499 | - struct sk_buff *skb, *tmp; | ||
1500 | - int freeing = 0; | ||
1501 | - | ||
1502 | - skb_queue_walk_safe(&mp->frags, skb, tmp) { | ||
1503 | - if (skb == to) | ||
1504 | - break; | ||
1505 | - if (skb == from) | ||
1506 | - freeing = 1; | ||
1507 | - if (!freeing) | ||
1508 | - continue; | ||
1509 | - __skb_unlink(skb, &mp->frags); | ||
1510 | - isdn_ppp_mp_free_skb(mp, skb); | ||
1511 | + if( from ) | ||
1512 | + while (from != to) { | ||
1513 | + struct sk_buff * next = from->next; | ||
1514 | + isdn_ppp_mp_free_skb(mp, from); | ||
1515 | + from = next; | ||
1516 | } | ||
1517 | - } | ||
1518 | + return from; | ||
1519 | } | ||
1520 | |||
1521 | -static unsigned int calc_tot_len(struct sk_buff_head *queue, | ||
1522 | - struct sk_buff *from, struct sk_buff *to) | ||
1523 | +void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, | ||
1524 | + struct sk_buff * from, struct sk_buff * to ) | ||
1525 | { | ||
1526 | - unsigned int tot_len = 0; | ||
1527 | - struct sk_buff *skb; | ||
1528 | - int found_start = 0; | ||
1529 | - | ||
1530 | - skb_queue_walk(queue, skb) { | ||
1531 | - if (skb == from) | ||
1532 | - found_start = 1; | ||
1533 | - if (!found_start) | ||
1534 | - continue; | ||
1535 | - tot_len += skb->len - MP_HEADER_LEN; | ||
1536 | - if (skb == to) | ||
1537 | - break; | ||
1538 | - } | ||
1539 | - return tot_len; | ||
1540 | -} | ||
1541 | - | ||
1542 | -/* Reassemble packet using fragments in the reassembly queue from | ||
1543 | - * 'from' until 'to', inclusive. | ||
1544 | - */ | ||
1545 | -static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp, | ||
1546 | - struct sk_buff *from, struct sk_buff *to, | ||
1547 | - u32 lastseq) | ||
1548 | -{ | ||
1549 | - ippp_bundle *mp = net_dev->pb; | ||
1550 | - unsigned int tot_len; | ||
1551 | - struct sk_buff *skb; | ||
1552 | + ippp_bundle * mp = net_dev->pb; | ||
1553 | int proto; | ||
1554 | + struct sk_buff * skb; | ||
1555 | + unsigned int tot_len; | ||
1556 | |||
1557 | if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { | ||
1558 | printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", | ||
1559 | __func__, lp->ppp_slot); | ||
1560 | return; | ||
1561 | } | ||
1562 | - | ||
1563 | - tot_len = calc_tot_len(&mp->frags, from, to); | ||
1564 | - | ||
1565 | - if (MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG)) { | ||
1566 | - if (ippp_table[lp->ppp_slot]->debug & 0x40) | ||
1567 | + if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) { | ||
1568 | + if( ippp_table[lp->ppp_slot]->debug & 0x40 ) | ||
1569 | printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, " | ||
1570 | - "len %d\n", MP_SEQ(from), from->len); | ||
1571 | + "len %d\n", MP_SEQ(from), from->len ); | ||
1572 | skb = from; | ||
1573 | skb_pull(skb, MP_HEADER_LEN); | ||
1574 | - __skb_unlink(skb, &mp->frags); | ||
1575 | mp->frames--; | ||
1576 | } else { | ||
1577 | - struct sk_buff *walk, *tmp; | ||
1578 | - int found_start = 0; | ||
1579 | + struct sk_buff * frag; | ||
1580 | + int n; | ||
1581 | |||
1582 | - if (ippp_table[lp->ppp_slot]->debug & 0x40) | ||
1583 | - printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " | ||
1584 | - "to %d, len %d\n", MP_SEQ(from), lastseq, | ||
1585 | - tot_len); | ||
1586 | + for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++) | ||
1587 | + tot_len += frag->len - MP_HEADER_LEN; | ||
1588 | |||
1589 | - skb = dev_alloc_skb(tot_len); | ||
1590 | - if (!skb) | ||
1591 | + if( ippp_table[lp->ppp_slot]->debug & 0x40 ) | ||
1592 | + printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " | ||
1593 | + "to %d, len %d\n", MP_SEQ(from), | ||
1594 | + (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len ); | ||
1595 | + if( (skb = dev_alloc_skb(tot_len)) == NULL ) { | ||
1596 | printk(KERN_ERR "isdn_mppp: cannot allocate sk buff " | ||
1597 | - "of size %d\n", tot_len); | ||
1598 | - | ||
1599 | - found_start = 0; | ||
1600 | - skb_queue_walk_safe(&mp->frags, walk, tmp) { | ||
1601 | - if (walk == from) | ||
1602 | - found_start = 1; | ||
1603 | - if (!found_start) | ||
1604 | - continue; | ||
1605 | + "of size %d\n", tot_len); | ||
1606 | + isdn_ppp_mp_discard(mp, from, to); | ||
1607 | + return; | ||
1608 | + } | ||
1609 | |||
1610 | - if (skb) { | ||
1611 | - unsigned int len = walk->len - MP_HEADER_LEN; | ||
1612 | - skb_copy_from_linear_data_offset(walk, MP_HEADER_LEN, | ||
1613 | - skb_put(skb, len), | ||
1614 | - len); | ||
1615 | - } | ||
1616 | - __skb_unlink(walk, &mp->frags); | ||
1617 | - isdn_ppp_mp_free_skb(mp, walk); | ||
1618 | + while( from != to ) { | ||
1619 | + unsigned int len = from->len - MP_HEADER_LEN; | ||
1620 | |||
1621 | - if (walk == to) | ||
1622 | - break; | ||
1623 | + skb_copy_from_linear_data_offset(from, MP_HEADER_LEN, | ||
1624 | + skb_put(skb,len), | ||
1625 | + len); | ||
1626 | + frag = from->next; | ||
1627 | + isdn_ppp_mp_free_skb(mp, from); | ||
1628 | + from = frag; | ||
1629 | } | ||
1630 | } | ||
1631 | - if (!skb) | ||
1632 | - return; | ||
1633 | - | ||
1634 | proto = isdn_ppp_strip_proto(skb); | ||
1635 | isdn_ppp_push_higher(net_dev, lp, skb, proto); | ||
1636 | } | ||
1637 | |||
1638 | -static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb) | ||
1639 | +static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb) | ||
1640 | { | ||
1641 | dev_kfree_skb(skb); | ||
1642 | mp->frames--; | ||
1643 | diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c | ||
1644 | index 556f0fe..386a797 100644 | ||
1645 | --- a/drivers/macintosh/therm_adt746x.c | ||
1646 | +++ b/drivers/macintosh/therm_adt746x.c | ||
1647 | @@ -79,6 +79,7 @@ struct thermostat { | ||
1648 | u8 limits[3]; | ||
1649 | int last_speed[2]; | ||
1650 | int last_var[2]; | ||
1651 | + int pwm_inv[2]; | ||
1652 | }; | ||
1653 | |||
1654 | static enum {ADT7460, ADT7467} therm_type; | ||
1655 | @@ -229,19 +230,23 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan) | ||
1656 | |||
1657 | if (speed >= 0) { | ||
1658 | manual = read_reg(th, MANUAL_MODE[fan]); | ||
1659 | + manual &= ~INVERT_MASK; | ||
1660 | write_reg(th, MANUAL_MODE[fan], | ||
1661 | - (manual|MANUAL_MASK) & (~INVERT_MASK)); | ||
1662 | + manual | MANUAL_MASK | th->pwm_inv[fan]); | ||
1663 | write_reg(th, FAN_SPD_SET[fan], speed); | ||
1664 | } else { | ||
1665 | /* back to automatic */ | ||
1666 | if(therm_type == ADT7460) { | ||
1667 | manual = read_reg(th, | ||
1668 | MANUAL_MODE[fan]) & (~MANUAL_MASK); | ||
1669 | - | ||
1670 | + manual &= ~INVERT_MASK; | ||
1671 | + manual |= th->pwm_inv[fan]; | ||
1672 | write_reg(th, | ||
1673 | MANUAL_MODE[fan], manual|REM_CONTROL[fan]); | ||
1674 | } else { | ||
1675 | manual = read_reg(th, MANUAL_MODE[fan]); | ||
1676 | + manual &= ~INVERT_MASK; | ||
1677 | + manual |= th->pwm_inv[fan]; | ||
1678 | write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK)); | ||
1679 | } | ||
1680 | } | ||
1681 | @@ -418,6 +423,10 @@ static int probe_thermostat(struct i2c_client *client, | ||
1682 | |||
1683 | thermostat = th; | ||
1684 | |||
1685 | + /* record invert bit status because fw can corrupt it after suspend */ | ||
1686 | + th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK; | ||
1687 | + th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK; | ||
1688 | + | ||
1689 | /* be sure to really write fan speed the first time */ | ||
1690 | th->last_speed[0] = -2; | ||
1691 | th->last_speed[1] = -2; | ||
1692 | diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c | ||
1693 | index 3319c2f..0aee97a 100644 | ||
1694 | --- a/drivers/md/bitmap.c | ||
1695 | +++ b/drivers/md/bitmap.c | ||
1696 | @@ -1077,23 +1077,31 @@ static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, | ||
1697 | * out to disk | ||
1698 | */ | ||
1699 | |||
1700 | -void bitmap_daemon_work(struct bitmap *bitmap) | ||
1701 | +void bitmap_daemon_work(mddev_t *mddev) | ||
1702 | { | ||
1703 | + struct bitmap *bitmap; | ||
1704 | unsigned long j; | ||
1705 | unsigned long flags; | ||
1706 | struct page *page = NULL, *lastpage = NULL; | ||
1707 | int blocks; | ||
1708 | void *paddr; | ||
1709 | |||
1710 | - if (bitmap == NULL) | ||
1711 | + /* Use a mutex to guard daemon_work against | ||
1712 | + * bitmap_destroy. | ||
1713 | + */ | ||
1714 | + mutex_lock(&mddev->bitmap_mutex); | ||
1715 | + bitmap = mddev->bitmap; | ||
1716 | + if (bitmap == NULL) { | ||
1717 | + mutex_unlock(&mddev->bitmap_mutex); | ||
1718 | return; | ||
1719 | + } | ||
1720 | if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ)) | ||
1721 | goto done; | ||
1722 | |||
1723 | bitmap->daemon_lastrun = jiffies; | ||
1724 | if (bitmap->allclean) { | ||
1725 | bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; | ||
1726 | - return; | ||
1727 | + goto done; | ||
1728 | } | ||
1729 | bitmap->allclean = 1; | ||
1730 | |||
1731 | @@ -1202,6 +1210,7 @@ void bitmap_daemon_work(struct bitmap *bitmap) | ||
1732 | done: | ||
1733 | if (bitmap->allclean == 0) | ||
1734 | bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ; | ||
1735 | + mutex_unlock(&mddev->bitmap_mutex); | ||
1736 | } | ||
1737 | |||
1738 | static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, | ||
1739 | @@ -1538,9 +1547,9 @@ void bitmap_flush(mddev_t *mddev) | ||
1740 | */ | ||
1741 | sleep = bitmap->daemon_sleep; | ||
1742 | bitmap->daemon_sleep = 0; | ||
1743 | - bitmap_daemon_work(bitmap); | ||
1744 | - bitmap_daemon_work(bitmap); | ||
1745 | - bitmap_daemon_work(bitmap); | ||
1746 | + bitmap_daemon_work(mddev); | ||
1747 | + bitmap_daemon_work(mddev); | ||
1748 | + bitmap_daemon_work(mddev); | ||
1749 | bitmap->daemon_sleep = sleep; | ||
1750 | bitmap_update_sb(bitmap); | ||
1751 | } | ||
1752 | @@ -1571,6 +1580,7 @@ static void bitmap_free(struct bitmap *bitmap) | ||
1753 | kfree(bp); | ||
1754 | kfree(bitmap); | ||
1755 | } | ||
1756 | + | ||
1757 | void bitmap_destroy(mddev_t *mddev) | ||
1758 | { | ||
1759 | struct bitmap *bitmap = mddev->bitmap; | ||
1760 | @@ -1578,7 +1588,9 @@ void bitmap_destroy(mddev_t *mddev) | ||
1761 | if (!bitmap) /* there was no bitmap */ | ||
1762 | return; | ||
1763 | |||
1764 | + mutex_lock(&mddev->bitmap_mutex); | ||
1765 | mddev->bitmap = NULL; /* disconnect from the md device */ | ||
1766 | + mutex_unlock(&mddev->bitmap_mutex); | ||
1767 | if (mddev->thread) | ||
1768 | mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; | ||
1769 | |||
1770 | diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h | ||
1771 | index e989006..7e38d13 100644 | ||
1772 | --- a/drivers/md/bitmap.h | ||
1773 | +++ b/drivers/md/bitmap.h | ||
1774 | @@ -282,7 +282,7 @@ void bitmap_close_sync(struct bitmap *bitmap); | ||
1775 | void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector); | ||
1776 | |||
1777 | void bitmap_unplug(struct bitmap *bitmap); | ||
1778 | -void bitmap_daemon_work(struct bitmap *bitmap); | ||
1779 | +void bitmap_daemon_work(mddev_t *mddev); | ||
1780 | #endif | ||
1781 | |||
1782 | #endif | ||
1783 | diff --git a/drivers/md/md.c b/drivers/md/md.c | ||
1784 | index 78871cd..5ff27aa 100644 | ||
1785 | --- a/drivers/md/md.c | ||
1786 | +++ b/drivers/md/md.c | ||
1787 | @@ -361,6 +361,7 @@ static mddev_t * mddev_find(dev_t unit) | ||
1788 | |||
1789 | mutex_init(&new->open_mutex); | ||
1790 | mutex_init(&new->reconfig_mutex); | ||
1791 | + mutex_init(&new->bitmap_mutex); | ||
1792 | INIT_LIST_HEAD(&new->disks); | ||
1793 | INIT_LIST_HEAD(&new->all_mddevs); | ||
1794 | init_timer(&new->safemode_timer); | ||
1795 | @@ -6595,7 +6596,7 @@ void md_check_recovery(mddev_t *mddev) | ||
1796 | |||
1797 | |||
1798 | if (mddev->bitmap) | ||
1799 | - bitmap_daemon_work(mddev->bitmap); | ||
1800 | + bitmap_daemon_work(mddev); | ||
1801 | |||
1802 | if (mddev->ro) | ||
1803 | return; | ||
1804 | diff --git a/drivers/md/md.h b/drivers/md/md.h | ||
1805 | index f8fc188..d7aad83 100644 | ||
1806 | --- a/drivers/md/md.h | ||
1807 | +++ b/drivers/md/md.h | ||
1808 | @@ -289,6 +289,7 @@ struct mddev_s | ||
1809 | * hot-adding a bitmap. It should | ||
1810 | * eventually be settable by sysfs. | ||
1811 | */ | ||
1812 | + struct mutex bitmap_mutex; | ||
1813 | |||
1814 | struct list_head all_mddevs; | ||
1815 | }; | ||
1816 | diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c | ||
1817 | index 2d02698..7eb1bf7 100644 | ||
1818 | --- a/drivers/media/common/tuners/mxl5007t.c | ||
1819 | +++ b/drivers/media/common/tuners/mxl5007t.c | ||
1820 | @@ -196,7 +196,7 @@ static void copy_reg_bits(struct reg_pair_t *reg_pair1, | ||
1821 | i = j = 0; | ||
1822 | |||
1823 | while (reg_pair1[i].reg || reg_pair1[i].val) { | ||
1824 | - while (reg_pair2[j].reg || reg_pair2[j].reg) { | ||
1825 | + while (reg_pair2[j].reg || reg_pair2[j].val) { | ||
1826 | if (reg_pair1[i].reg != reg_pair2[j].reg) { | ||
1827 | j++; | ||
1828 | continue; | ||
1829 | diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c | ||
1830 | index 2f6e135..5578865 100644 | ||
1831 | --- a/drivers/media/video/gspca/ov519.c | ||
1832 | +++ b/drivers/media/video/gspca/ov519.c | ||
1833 | @@ -3364,6 +3364,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | ||
1834 | {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, | ||
1835 | {USB_DEVICE(0x041e, 0x4064), | ||
1836 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | ||
1837 | + {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 }, | ||
1838 | {USB_DEVICE(0x041e, 0x4068), | ||
1839 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | ||
1840 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, | ||
1841 | diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c | ||
1842 | index d3c734f..2f6ae78 100644 | ||
1843 | --- a/drivers/net/au1000_eth.c | ||
1844 | +++ b/drivers/net/au1000_eth.c | ||
1845 | @@ -1089,7 +1089,14 @@ static struct net_device * au1000_probe(int port_num) | ||
1846 | return NULL; | ||
1847 | } | ||
1848 | |||
1849 | - if ((err = register_netdev(dev)) != 0) { | ||
1850 | + dev->base_addr = base; | ||
1851 | + dev->irq = irq; | ||
1852 | + dev->netdev_ops = &au1000_netdev_ops; | ||
1853 | + SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1854 | + dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1855 | + | ||
1856 | + err = register_netdev(dev); | ||
1857 | + if (err != 0) { | ||
1858 | printk(KERN_ERR "%s: Cannot register net device, error %d\n", | ||
1859 | DRV_NAME, err); | ||
1860 | free_netdev(dev); | ||
1861 | @@ -1207,12 +1214,6 @@ static struct net_device * au1000_probe(int port_num) | ||
1862 | aup->tx_db_inuse[i] = pDB; | ||
1863 | } | ||
1864 | |||
1865 | - dev->base_addr = base; | ||
1866 | - dev->irq = irq; | ||
1867 | - dev->netdev_ops = &au1000_netdev_ops; | ||
1868 | - SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1869 | - dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1870 | - | ||
1871 | /* | ||
1872 | * The boot code uses the ethernet controller, so reset it to start | ||
1873 | * fresh. au1000_init() expects that the device is in reset state. | ||
1874 | diff --git a/drivers/net/b44.c b/drivers/net/b44.c | ||
1875 | index bafca67..351a258 100644 | ||
1876 | --- a/drivers/net/b44.c | ||
1877 | +++ b/drivers/net/b44.c | ||
1878 | @@ -913,9 +913,6 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id) | ||
1879 | bp->istat = istat; | ||
1880 | __b44_disable_ints(bp); | ||
1881 | __napi_schedule(&bp->napi); | ||
1882 | - } else { | ||
1883 | - printk(KERN_ERR PFX "%s: Error, poll already scheduled\n", | ||
1884 | - dev->name); | ||
1885 | } | ||
1886 | |||
1887 | irq_ack: | ||
1888 | @@ -1505,8 +1502,7 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset) | ||
1889 | for (k = 0; k< ethaddr_bytes; k++) { | ||
1890 | ppattern[offset + magicsync + | ||
1891 | (j * ETH_ALEN) + k] = macaddr[k]; | ||
1892 | - len++; | ||
1893 | - set_bit(len, (unsigned long *) pmask); | ||
1894 | + set_bit(len++, (unsigned long *) pmask); | ||
1895 | } | ||
1896 | } | ||
1897 | return len - 1; | ||
1898 | diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c | ||
1899 | index 7567f51..d8ed1b6 100644 | ||
1900 | --- a/drivers/net/smc91x.c | ||
1901 | +++ b/drivers/net/smc91x.c | ||
1902 | @@ -2283,7 +2283,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev) | ||
1903 | |||
1904 | ndev->irq = ires->start; | ||
1905 | |||
1906 | - if (ires->flags & IRQF_TRIGGER_MASK) | ||
1907 | + if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK) | ||
1908 | irq_flags = ires->flags & IRQF_TRIGGER_MASK; | ||
1909 | |||
1910 | ret = smc_request_attrib(pdev, ndev); | ||
1911 | diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c | ||
1912 | index 60abdb1..97ababd 100644 | ||
1913 | --- a/drivers/net/smsc9420.c | ||
1914 | +++ b/drivers/net/smsc9420.c | ||
1915 | @@ -252,6 +252,9 @@ static int smsc9420_ethtool_get_settings(struct net_device *dev, | ||
1916 | { | ||
1917 | struct smsc9420_pdata *pd = netdev_priv(dev); | ||
1918 | |||
1919 | + if (!pd->phy_dev) | ||
1920 | + return -ENODEV; | ||
1921 | + | ||
1922 | cmd->maxtxpkt = 1; | ||
1923 | cmd->maxrxpkt = 1; | ||
1924 | return phy_ethtool_gset(pd->phy_dev, cmd); | ||
1925 | @@ -262,6 +265,9 @@ static int smsc9420_ethtool_set_settings(struct net_device *dev, | ||
1926 | { | ||
1927 | struct smsc9420_pdata *pd = netdev_priv(dev); | ||
1928 | |||
1929 | + if (!pd->phy_dev) | ||
1930 | + return -ENODEV; | ||
1931 | + | ||
1932 | return phy_ethtool_sset(pd->phy_dev, cmd); | ||
1933 | } | ||
1934 | |||
1935 | @@ -290,6 +296,10 @@ static void smsc9420_ethtool_set_msglevel(struct net_device *netdev, u32 data) | ||
1936 | static int smsc9420_ethtool_nway_reset(struct net_device *netdev) | ||
1937 | { | ||
1938 | struct smsc9420_pdata *pd = netdev_priv(netdev); | ||
1939 | + | ||
1940 | + if (!pd->phy_dev) | ||
1941 | + return -ENODEV; | ||
1942 | + | ||
1943 | return phy_start_aneg(pd->phy_dev); | ||
1944 | } | ||
1945 | |||
1946 | @@ -312,6 +322,10 @@ smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs, | ||
1947 | for (i = 0; i < 0x100; i += (sizeof(u32))) | ||
1948 | data[j++] = smsc9420_reg_read(pd, i); | ||
1949 | |||
1950 | + // cannot read phy registers if the net device is down | ||
1951 | + if (!phy_dev) | ||
1952 | + return; | ||
1953 | + | ||
1954 | for (i = 0; i <= 31; i++) | ||
1955 | data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i); | ||
1956 | } | ||
1957 | diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c | ||
1958 | index c56b494..fb32785 100644 | ||
1959 | --- a/drivers/net/wireless/ath/ath5k/eeprom.c | ||
1960 | +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | ||
1961 | @@ -97,6 +97,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) | ||
1962 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
1963 | int ret; | ||
1964 | u16 val; | ||
1965 | + u32 cksum, offset; | ||
1966 | |||
1967 | /* | ||
1968 | * Read values from EEPROM and store them in the capability structure | ||
1969 | @@ -111,7 +112,6 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) | ||
1970 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) | ||
1971 | return 0; | ||
1972 | |||
1973 | -#ifdef notyet | ||
1974 | /* | ||
1975 | * Validate the checksum of the EEPROM date. There are some | ||
1976 | * devices with invalid EEPROMs. | ||
1977 | @@ -124,7 +124,6 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) | ||
1978 | ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); | ||
1979 | return -EIO; | ||
1980 | } | ||
1981 | -#endif | ||
1982 | |||
1983 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), | ||
1984 | ee_ant_gain); | ||
1985 | diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c | ||
1986 | index 0981fb4..5c0e31b 100644 | ||
1987 | --- a/drivers/net/wireless/ath/ath5k/phy.c | ||
1988 | +++ b/drivers/net/wireless/ath/ath5k/phy.c | ||
1989 | @@ -2931,8 +2931,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | ||
1990 | ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower); | ||
1991 | return -EINVAL; | ||
1992 | } | ||
1993 | - if (txpower == 0) | ||
1994 | - txpower = AR5K_TUNE_DEFAULT_TXPOWER; | ||
1995 | |||
1996 | /* Reset TX power values */ | ||
1997 | memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); | ||
1998 | diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c | ||
1999 | index 8783022..d579df7 100644 | ||
2000 | --- a/drivers/net/wireless/b43legacy/rfkill.c | ||
2001 | +++ b/drivers/net/wireless/b43legacy/rfkill.c | ||
2002 | @@ -34,6 +34,13 @@ bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | ||
2003 | & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK)) | ||
2004 | return 1; | ||
2005 | } else { | ||
2006 | + /* To prevent CPU fault on PPC, do not read a register | ||
2007 | + * unless the interface is started; however, on resume | ||
2008 | + * for hibernation, this routine is entered early. When | ||
2009 | + * that happens, unconditionally return TRUE. | ||
2010 | + */ | ||
2011 | + if (b43legacy_status(dev) < B43legacy_STAT_STARTED) | ||
2012 | + return 1; | ||
2013 | if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO) | ||
2014 | & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK) | ||
2015 | return 1; | ||
2016 | diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c | ||
2017 | index 7424323..d04350b 100644 | ||
2018 | --- a/drivers/net/wireless/ipw2x00/ipw2100.c | ||
2019 | +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | ||
2020 | @@ -6487,6 +6487,16 @@ static int ipw2100_resume(struct pci_dev *pci_dev) | ||
2021 | } | ||
2022 | #endif | ||
2023 | |||
2024 | +static void ipw2100_shutdown(struct pci_dev *pci_dev) | ||
2025 | +{ | ||
2026 | + struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); | ||
2027 | + | ||
2028 | + /* Take down the device; powers it off, etc. */ | ||
2029 | + ipw2100_down(priv); | ||
2030 | + | ||
2031 | + pci_disable_device(pci_dev); | ||
2032 | +} | ||
2033 | + | ||
2034 | #define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x } | ||
2035 | |||
2036 | static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = { | ||
2037 | @@ -6550,6 +6560,7 @@ static struct pci_driver ipw2100_pci_driver = { | ||
2038 | .suspend = ipw2100_suspend, | ||
2039 | .resume = ipw2100_resume, | ||
2040 | #endif | ||
2041 | + .shutdown = ipw2100_shutdown, | ||
2042 | }; | ||
2043 | |||
2044 | /** | ||
2045 | diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c | ||
2046 | index 6e1b889..b17ec7f 100644 | ||
2047 | --- a/drivers/net/wireless/p54/p54usb.c | ||
2048 | +++ b/drivers/net/wireless/p54/p54usb.c | ||
2049 | @@ -427,12 +427,16 @@ static const char p54u_romboot_3887[] = "~~~~"; | ||
2050 | static int p54u_firmware_reset_3887(struct ieee80211_hw *dev) | ||
2051 | { | ||
2052 | struct p54u_priv *priv = dev->priv; | ||
2053 | - u8 buf[4]; | ||
2054 | + u8 *buf; | ||
2055 | int ret; | ||
2056 | |||
2057 | - memcpy(&buf, p54u_romboot_3887, sizeof(buf)); | ||
2058 | + buf = kmalloc(4, GFP_KERNEL); | ||
2059 | + if (!buf) | ||
2060 | + return -ENOMEM; | ||
2061 | + memcpy(buf, p54u_romboot_3887, 4); | ||
2062 | ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, | ||
2063 | - buf, sizeof(buf)); | ||
2064 | + buf, 4); | ||
2065 | + kfree(buf); | ||
2066 | if (ret) | ||
2067 | dev_err(&priv->udev->dev, "(p54usb) unable to jump to " | ||
2068 | "boot ROM (%d)!\n", ret); | ||
2069 | diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c | ||
2070 | index db657bb..fae1951 100644 | ||
2071 | --- a/drivers/platform/x86/asus-laptop.c | ||
2072 | +++ b/drivers/platform/x86/asus-laptop.c | ||
2073 | @@ -1172,8 +1172,8 @@ static int asus_hotk_add(struct acpi_device *device) | ||
2074 | hotk->ledd_status = 0xFFF; | ||
2075 | |||
2076 | /* Set initial values of light sensor and level */ | ||
2077 | - hotk->light_switch = 1; /* Default to light sensor disabled */ | ||
2078 | - hotk->light_level = 0; /* level 5 for sensor sensitivity */ | ||
2079 | + hotk->light_switch = 0; /* Default to light sensor disabled */ | ||
2080 | + hotk->light_level = 5; /* level 5 for sensor sensitivity */ | ||
2081 | |||
2082 | if (ls_switch_handle) | ||
2083 | set_light_sens_switch(hotk->light_switch); | ||
2084 | diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c | ||
2085 | index e5a7eab..05e5d56 100644 | ||
2086 | --- a/drivers/platform/x86/thinkpad_acpi.c | ||
2087 | +++ b/drivers/platform/x86/thinkpad_acpi.c | ||
2088 | @@ -3406,15 +3406,6 @@ enum { | ||
2089 | |||
2090 | #define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" | ||
2091 | |||
2092 | -static void bluetooth_suspend(pm_message_t state) | ||
2093 | -{ | ||
2094 | - /* Try to make sure radio will resume powered off */ | ||
2095 | - if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", | ||
2096 | - TP_ACPI_BLTH_PWR_OFF_ON_RESUME)) | ||
2097 | - vdbg_printk(TPACPI_DBG_RFKILL, | ||
2098 | - "bluetooth power down on resume request failed\n"); | ||
2099 | -} | ||
2100 | - | ||
2101 | static int bluetooth_get_status(void) | ||
2102 | { | ||
2103 | int status; | ||
2104 | @@ -3448,10 +3439,9 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state) | ||
2105 | #endif | ||
2106 | |||
2107 | /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ | ||
2108 | + status = TP_ACPI_BLUETOOTH_RESUMECTRL; | ||
2109 | if (state == TPACPI_RFK_RADIO_ON) | ||
2110 | - status = TP_ACPI_BLUETOOTH_RADIOSSW; | ||
2111 | - else | ||
2112 | - status = 0; | ||
2113 | + status |= TP_ACPI_BLUETOOTH_RADIOSSW; | ||
2114 | |||
2115 | if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) | ||
2116 | return -EIO; | ||
2117 | @@ -3590,7 +3580,6 @@ static struct ibm_struct bluetooth_driver_data = { | ||
2118 | .read = bluetooth_read, | ||
2119 | .write = bluetooth_write, | ||
2120 | .exit = bluetooth_exit, | ||
2121 | - .suspend = bluetooth_suspend, | ||
2122 | .shutdown = bluetooth_shutdown, | ||
2123 | }; | ||
2124 | |||
2125 | @@ -3608,15 +3597,6 @@ enum { | ||
2126 | |||
2127 | #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" | ||
2128 | |||
2129 | -static void wan_suspend(pm_message_t state) | ||
2130 | -{ | ||
2131 | - /* Try to make sure radio will resume powered off */ | ||
2132 | - if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd", | ||
2133 | - TP_ACPI_WGSV_PWR_OFF_ON_RESUME)) | ||
2134 | - vdbg_printk(TPACPI_DBG_RFKILL, | ||
2135 | - "WWAN power down on resume request failed\n"); | ||
2136 | -} | ||
2137 | - | ||
2138 | static int wan_get_status(void) | ||
2139 | { | ||
2140 | int status; | ||
2141 | @@ -3649,11 +3629,10 @@ static int wan_set_status(enum tpacpi_rfkill_state state) | ||
2142 | } | ||
2143 | #endif | ||
2144 | |||
2145 | - /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ | ||
2146 | + /* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */ | ||
2147 | + status = TP_ACPI_WANCARD_RESUMECTRL; | ||
2148 | if (state == TPACPI_RFK_RADIO_ON) | ||
2149 | - status = TP_ACPI_WANCARD_RADIOSSW; | ||
2150 | - else | ||
2151 | - status = 0; | ||
2152 | + status |= TP_ACPI_WANCARD_RADIOSSW; | ||
2153 | |||
2154 | if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) | ||
2155 | return -EIO; | ||
2156 | @@ -3791,7 +3770,6 @@ static struct ibm_struct wan_driver_data = { | ||
2157 | .read = wan_read, | ||
2158 | .write = wan_write, | ||
2159 | .exit = wan_exit, | ||
2160 | - .suspend = wan_suspend, | ||
2161 | .shutdown = wan_shutdown, | ||
2162 | }; | ||
2163 | |||
2164 | @@ -5663,8 +5641,8 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { | ||
2165 | |||
2166 | /* Models with Intel Extreme Graphics 2 */ | ||
2167 | TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), | ||
2168 | - TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), | ||
2169 | - TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), | ||
2170 | + TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | ||
2171 | + TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | ||
2172 | |||
2173 | /* Models with Intel GMA900 */ | ||
2174 | TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */ | ||
2175 | diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c | ||
2176 | index fb867a9..524f6ab 100644 | ||
2177 | --- a/drivers/serial/8250.c | ||
2178 | +++ b/drivers/serial/8250.c | ||
2179 | @@ -1337,14 +1337,12 @@ static void serial8250_start_tx(struct uart_port *port) | ||
2180 | serial_out(up, UART_IER, up->ier); | ||
2181 | |||
2182 | if (up->bugs & UART_BUG_TXEN) { | ||
2183 | - unsigned char lsr, iir; | ||
2184 | + unsigned char lsr; | ||
2185 | lsr = serial_in(up, UART_LSR); | ||
2186 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | ||
2187 | - iir = serial_in(up, UART_IIR) & 0x0f; | ||
2188 | if ((up->port.type == PORT_RM9000) ? | ||
2189 | - (lsr & UART_LSR_THRE && | ||
2190 | - (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) : | ||
2191 | - (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)) | ||
2192 | + (lsr & UART_LSR_THRE) : | ||
2193 | + (lsr & UART_LSR_TEMT)) | ||
2194 | transmit_chars(up); | ||
2195 | } | ||
2196 | } | ||
2197 | diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c | ||
2198 | index a2d4a19..ed7d958 100644 | ||
2199 | --- a/drivers/serial/suncore.c | ||
2200 | +++ b/drivers/serial/suncore.c | ||
2201 | @@ -53,20 +53,21 @@ void sunserial_unregister_minors(struct uart_driver *drv, int count) | ||
2202 | EXPORT_SYMBOL(sunserial_unregister_minors); | ||
2203 | |||
2204 | int sunserial_console_match(struct console *con, struct device_node *dp, | ||
2205 | - struct uart_driver *drv, int line) | ||
2206 | + struct uart_driver *drv, int line, bool ignore_line) | ||
2207 | { | ||
2208 | - int off; | ||
2209 | - | ||
2210 | if (!con || of_console_device != dp) | ||
2211 | return 0; | ||
2212 | |||
2213 | - off = 0; | ||
2214 | - if (of_console_options && | ||
2215 | - *of_console_options == 'b') | ||
2216 | - off = 1; | ||
2217 | + if (!ignore_line) { | ||
2218 | + int off = 0; | ||
2219 | |||
2220 | - if ((line & 1) != off) | ||
2221 | - return 0; | ||
2222 | + if (of_console_options && | ||
2223 | + *of_console_options == 'b') | ||
2224 | + off = 1; | ||
2225 | + | ||
2226 | + if ((line & 1) != off) | ||
2227 | + return 0; | ||
2228 | + } | ||
2229 | |||
2230 | con->index = line; | ||
2231 | drv->cons = con; | ||
2232 | @@ -76,23 +77,24 @@ int sunserial_console_match(struct console *con, struct device_node *dp, | ||
2233 | } | ||
2234 | EXPORT_SYMBOL(sunserial_console_match); | ||
2235 | |||
2236 | -void | ||
2237 | -sunserial_console_termios(struct console *con) | ||
2238 | +void sunserial_console_termios(struct console *con, struct device_node *uart_dp) | ||
2239 | { | ||
2240 | - struct device_node *dp; | ||
2241 | - const char *od, *mode, *s; | ||
2242 | + const char *mode, *s; | ||
2243 | char mode_prop[] = "ttyX-mode"; | ||
2244 | int baud, bits, stop, cflag; | ||
2245 | char parity; | ||
2246 | |||
2247 | - dp = of_find_node_by_path("/options"); | ||
2248 | - od = of_get_property(dp, "output-device", NULL); | ||
2249 | - if (!strcmp(od, "rsc")) { | ||
2250 | - mode = of_get_property(of_console_device, | ||
2251 | + if (!strcmp(uart_dp->name, "rsc") || | ||
2252 | + !strcmp(uart_dp->name, "rsc-console") || | ||
2253 | + !strcmp(uart_dp->name, "rsc-control")) { | ||
2254 | + mode = of_get_property(uart_dp, | ||
2255 | "ssp-console-modes", NULL); | ||
2256 | if (!mode) | ||
2257 | mode = "115200,8,n,1,-"; | ||
2258 | + } else if (!strcmp(uart_dp->name, "lom-console")) { | ||
2259 | + mode = "9600,8,n,1,-"; | ||
2260 | } else { | ||
2261 | + struct device_node *dp; | ||
2262 | char c; | ||
2263 | |||
2264 | c = 'a'; | ||
2265 | @@ -101,6 +103,7 @@ sunserial_console_termios(struct console *con) | ||
2266 | |||
2267 | mode_prop[3] = c; | ||
2268 | |||
2269 | + dp = of_find_node_by_path("/options"); | ||
2270 | mode = of_get_property(dp, mode_prop, NULL); | ||
2271 | if (!mode) | ||
2272 | mode = "9600,8,n,1,-"; | ||
2273 | diff --git a/drivers/serial/suncore.h b/drivers/serial/suncore.h | ||
2274 | index 042668a..db20579 100644 | ||
2275 | --- a/drivers/serial/suncore.h | ||
2276 | +++ b/drivers/serial/suncore.h | ||
2277 | @@ -26,7 +26,8 @@ extern int sunserial_register_minors(struct uart_driver *, int); | ||
2278 | extern void sunserial_unregister_minors(struct uart_driver *, int); | ||
2279 | |||
2280 | extern int sunserial_console_match(struct console *, struct device_node *, | ||
2281 | - struct uart_driver *, int); | ||
2282 | -extern void sunserial_console_termios(struct console *); | ||
2283 | + struct uart_driver *, int, bool); | ||
2284 | +extern void sunserial_console_termios(struct console *, | ||
2285 | + struct device_node *); | ||
2286 | |||
2287 | #endif /* !(_SERIAL_SUN_H) */ | ||
2288 | diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c | ||
2289 | index 1df5325..3b6953a 100644 | ||
2290 | --- a/drivers/serial/sunhv.c | ||
2291 | +++ b/drivers/serial/sunhv.c | ||
2292 | @@ -566,7 +566,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m | ||
2293 | goto out_free_con_read_page; | ||
2294 | |||
2295 | sunserial_console_match(&sunhv_console, op->node, | ||
2296 | - &sunhv_reg, port->line); | ||
2297 | + &sunhv_reg, port->line, false); | ||
2298 | |||
2299 | err = uart_add_one_port(&sunhv_reg, port); | ||
2300 | if (err) | ||
2301 | diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c | ||
2302 | index 0355efe..9cbf597 100644 | ||
2303 | --- a/drivers/serial/sunsab.c | ||
2304 | +++ b/drivers/serial/sunsab.c | ||
2305 | @@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options) | ||
2306 | printk("Console: ttyS%d (SAB82532)\n", | ||
2307 | (sunsab_reg.minor - 64) + con->index); | ||
2308 | |||
2309 | - sunserial_console_termios(con); | ||
2310 | + sunserial_console_termios(con, to_of_device(up->port.dev)->node); | ||
2311 | |||
2312 | switch (con->cflag & CBAUD) { | ||
2313 | case B150: baud = 150; break; | ||
2314 | @@ -1027,10 +1027,12 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * | ||
2315 | goto out1; | ||
2316 | |||
2317 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, | ||
2318 | - &sunsab_reg, up[0].port.line); | ||
2319 | + &sunsab_reg, up[0].port.line, | ||
2320 | + false); | ||
2321 | |||
2322 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, | ||
2323 | - &sunsab_reg, up[1].port.line); | ||
2324 | + &sunsab_reg, up[1].port.line, | ||
2325 | + false); | ||
2326 | |||
2327 | err = uart_add_one_port(&sunsab_reg, &up[0].port); | ||
2328 | if (err) | ||
2329 | @@ -1116,7 +1118,6 @@ static int __init sunsab_init(void) | ||
2330 | if (!sunsab_ports) | ||
2331 | return -ENOMEM; | ||
2332 | |||
2333 | - sunsab_reg.cons = SUNSAB_CONSOLE(); | ||
2334 | err = sunserial_register_minors(&sunsab_reg, num_channels); | ||
2335 | if (err) { | ||
2336 | kfree(sunsab_ports); | ||
2337 | diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c | ||
2338 | index 47c6837..ab91166 100644 | ||
2339 | --- a/drivers/serial/sunsu.c | ||
2340 | +++ b/drivers/serial/sunsu.c | ||
2341 | @@ -1329,11 +1329,9 @@ static void sunsu_console_write(struct console *co, const char *s, | ||
2342 | */ | ||
2343 | static int __init sunsu_console_setup(struct console *co, char *options) | ||
2344 | { | ||
2345 | + static struct ktermios dummy; | ||
2346 | + struct ktermios termios; | ||
2347 | struct uart_port *port; | ||
2348 | - int baud = 9600; | ||
2349 | - int bits = 8; | ||
2350 | - int parity = 'n'; | ||
2351 | - int flow = 'n'; | ||
2352 | |||
2353 | printk("Console: ttyS%d (SU)\n", | ||
2354 | (sunsu_reg.minor - 64) + co->index); | ||
2355 | @@ -1352,10 +1350,15 @@ static int __init sunsu_console_setup(struct console *co, char *options) | ||
2356 | */ | ||
2357 | spin_lock_init(&port->lock); | ||
2358 | |||
2359 | - if (options) | ||
2360 | - uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
2361 | + /* Get firmware console settings. */ | ||
2362 | + sunserial_console_termios(co, to_of_device(port->dev)->node); | ||
2363 | |||
2364 | - return uart_set_options(port, co, baud, parity, bits, flow); | ||
2365 | + memset(&termios, 0, sizeof(struct ktermios)); | ||
2366 | + termios.c_cflag = co->cflag; | ||
2367 | + port->mctrl |= TIOCM_DTR; | ||
2368 | + port->ops->set_termios(port, &termios, &dummy); | ||
2369 | + | ||
2370 | + return 0; | ||
2371 | } | ||
2372 | |||
2373 | static struct console sunsu_console = { | ||
2374 | @@ -1409,6 +1412,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | ||
2375 | struct uart_sunsu_port *up; | ||
2376 | struct resource *rp; | ||
2377 | enum su_type type; | ||
2378 | + bool ignore_line; | ||
2379 | int err; | ||
2380 | |||
2381 | type = su_get_type(dp); | ||
2382 | @@ -1467,8 +1471,14 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | ||
2383 | |||
2384 | up->port.ops = &sunsu_pops; | ||
2385 | |||
2386 | + ignore_line = false; | ||
2387 | + if (!strcmp(dp->name, "rsc-console") || | ||
2388 | + !strcmp(dp->name, "lom-console")) | ||
2389 | + ignore_line = true; | ||
2390 | + | ||
2391 | sunserial_console_match(SUNSU_CONSOLE(), dp, | ||
2392 | - &sunsu_reg, up->port.line); | ||
2393 | + &sunsu_reg, up->port.line, | ||
2394 | + ignore_line); | ||
2395 | err = uart_add_one_port(&sunsu_reg, &up->port); | ||
2396 | if (err) | ||
2397 | goto out_unmap; | ||
2398 | @@ -1517,6 +1527,10 @@ static const struct of_device_id su_match[] = { | ||
2399 | .name = "serial", | ||
2400 | .compatible = "su", | ||
2401 | }, | ||
2402 | + { | ||
2403 | + .type = "serial", | ||
2404 | + .compatible = "su", | ||
2405 | + }, | ||
2406 | {}, | ||
2407 | }; | ||
2408 | MODULE_DEVICE_TABLE(of, su_match); | ||
2409 | @@ -1548,6 +1562,12 @@ static int __init sunsu_init(void) | ||
2410 | num_uart++; | ||
2411 | } | ||
2412 | } | ||
2413 | + for_each_node_by_type(dp, "serial") { | ||
2414 | + if (of_device_is_compatible(dp, "su")) { | ||
2415 | + if (su_get_type(dp) == SU_PORT_PORT) | ||
2416 | + num_uart++; | ||
2417 | + } | ||
2418 | + } | ||
2419 | |||
2420 | if (num_uart) { | ||
2421 | err = sunserial_register_minors(&sunsu_reg, num_uart); | ||
2422 | diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c | ||
2423 | index e09d3ce..0a2a333 100644 | ||
2424 | --- a/drivers/serial/sunzilog.c | ||
2425 | +++ b/drivers/serial/sunzilog.c | ||
2426 | @@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) | ||
2427 | (sunzilog_reg.minor - 64) + con->index, con->index); | ||
2428 | |||
2429 | /* Get firmware console settings. */ | ||
2430 | - sunserial_console_termios(con); | ||
2431 | + sunserial_console_termios(con, to_of_device(up->port.dev)->node); | ||
2432 | |||
2433 | /* Firmware console speed is limited to 150-->38400 baud so | ||
2434 | * this hackish cflag thing is OK. | ||
2435 | @@ -1416,7 +1416,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | ||
2436 | |||
2437 | if (!keyboard_mouse) { | ||
2438 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, | ||
2439 | - &sunzilog_reg, up[0].port.line)) | ||
2440 | + &sunzilog_reg, up[0].port.line, | ||
2441 | + false)) | ||
2442 | up->flags |= SUNZILOG_FLAG_IS_CONS; | ||
2443 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); | ||
2444 | if (err) { | ||
2445 | @@ -1425,7 +1426,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | ||
2446 | return err; | ||
2447 | } | ||
2448 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, | ||
2449 | - &sunzilog_reg, up[1].port.line)) | ||
2450 | + &sunzilog_reg, up[1].port.line, | ||
2451 | + false)) | ||
2452 | up->flags |= SUNZILOG_FLAG_IS_CONS; | ||
2453 | err = uart_add_one_port(&sunzilog_reg, &up[1].port); | ||
2454 | if (err) { | ||
2455 | diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c | ||
2456 | index 8943015..eb70843 100644 | ||
2457 | --- a/drivers/ssb/sprom.c | ||
2458 | +++ b/drivers/ssb/sprom.c | ||
2459 | @@ -13,6 +13,8 @@ | ||
2460 | |||
2461 | #include "ssb_private.h" | ||
2462 | |||
2463 | +#include <linux/ctype.h> | ||
2464 | + | ||
2465 | |||
2466 | static const struct ssb_sprom *fallback_sprom; | ||
2467 | |||
2468 | @@ -33,17 +35,27 @@ static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, | ||
2469 | static int hex2sprom(u16 *sprom, const char *dump, size_t len, | ||
2470 | size_t sprom_size_words) | ||
2471 | { | ||
2472 | - char tmp[5] = { 0 }; | ||
2473 | - int cnt = 0; | ||
2474 | + char c, tmp[5] = { 0 }; | ||
2475 | + int err, cnt = 0; | ||
2476 | unsigned long parsed; | ||
2477 | |||
2478 | - if (len < sprom_size_words * 2) | ||
2479 | + /* Strip whitespace at the end. */ | ||
2480 | + while (len) { | ||
2481 | + c = dump[len - 1]; | ||
2482 | + if (!isspace(c) && c != '\0') | ||
2483 | + break; | ||
2484 | + len--; | ||
2485 | + } | ||
2486 | + /* Length must match exactly. */ | ||
2487 | + if (len != sprom_size_words * 4) | ||
2488 | return -EINVAL; | ||
2489 | |||
2490 | while (cnt < sprom_size_words) { | ||
2491 | memcpy(tmp, dump, 4); | ||
2492 | dump += 4; | ||
2493 | - parsed = simple_strtoul(tmp, NULL, 16); | ||
2494 | + err = strict_strtoul(tmp, 16, &parsed); | ||
2495 | + if (err) | ||
2496 | + return err; | ||
2497 | sprom[cnt++] = swab16((u16)parsed); | ||
2498 | } | ||
2499 | |||
2500 | diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c | ||
2501 | index 21b3719..aa145f7 100644 | ||
2502 | --- a/drivers/usb/class/usbtmc.c | ||
2503 | +++ b/drivers/usb/class/usbtmc.c | ||
2504 | @@ -545,10 +545,16 @@ static ssize_t usbtmc_write(struct file *filp, const char __user *buf, | ||
2505 | n_bytes = roundup(12 + this_part, 4); | ||
2506 | memset(buffer + 12 + this_part, 0, n_bytes - (12 + this_part)); | ||
2507 | |||
2508 | - retval = usb_bulk_msg(data->usb_dev, | ||
2509 | - usb_sndbulkpipe(data->usb_dev, | ||
2510 | - data->bulk_out), | ||
2511 | - buffer, n_bytes, &actual, USBTMC_TIMEOUT); | ||
2512 | + do { | ||
2513 | + retval = usb_bulk_msg(data->usb_dev, | ||
2514 | + usb_sndbulkpipe(data->usb_dev, | ||
2515 | + data->bulk_out), | ||
2516 | + buffer, n_bytes, | ||
2517 | + &actual, USBTMC_TIMEOUT); | ||
2518 | + if (retval != 0) | ||
2519 | + break; | ||
2520 | + n_bytes -= actual; | ||
2521 | + } while (n_bytes); | ||
2522 | |||
2523 | data->bTag_last_write = data->bTag; | ||
2524 | data->bTag++; | ||
2525 | diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c | ||
2526 | index a26f738..b661dbd 100644 | ||
2527 | --- a/drivers/usb/core/usb.c | ||
2528 | +++ b/drivers/usb/core/usb.c | ||
2529 | @@ -132,7 +132,7 @@ EXPORT_SYMBOL_GPL(usb_altnum_to_altsetting); | ||
2530 | |||
2531 | struct find_interface_arg { | ||
2532 | int minor; | ||
2533 | - struct usb_interface *interface; | ||
2534 | + struct device_driver *drv; | ||
2535 | }; | ||
2536 | |||
2537 | static int __find_interface(struct device *dev, void *data) | ||
2538 | @@ -143,12 +143,10 @@ static int __find_interface(struct device *dev, void *data) | ||
2539 | if (!is_usb_interface(dev)) | ||
2540 | return 0; | ||
2541 | |||
2542 | + if (dev->driver != arg->drv) | ||
2543 | + return 0; | ||
2544 | intf = to_usb_interface(dev); | ||
2545 | - if (intf->minor != -1 && intf->minor == arg->minor) { | ||
2546 | - arg->interface = intf; | ||
2547 | - return 1; | ||
2548 | - } | ||
2549 | - return 0; | ||
2550 | + return intf->minor == arg->minor; | ||
2551 | } | ||
2552 | |||
2553 | /** | ||
2554 | @@ -156,21 +154,24 @@ static int __find_interface(struct device *dev, void *data) | ||
2555 | * @drv: the driver whose current configuration is considered | ||
2556 | * @minor: the minor number of the desired device | ||
2557 | * | ||
2558 | - * This walks the driver device list and returns a pointer to the interface | ||
2559 | - * with the matching minor. Note, this only works for devices that share the | ||
2560 | - * USB major number. | ||
2561 | + * This walks the bus device list and returns a pointer to the interface | ||
2562 | + * with the matching minor and driver. Note, this only works for devices | ||
2563 | + * that share the USB major number. | ||
2564 | */ | ||
2565 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) | ||
2566 | { | ||
2567 | struct find_interface_arg argb; | ||
2568 | - int retval; | ||
2569 | + struct device *dev; | ||
2570 | |||
2571 | argb.minor = minor; | ||
2572 | - argb.interface = NULL; | ||
2573 | - /* eat the error, it will be in argb.interface */ | ||
2574 | - retval = driver_for_each_device(&drv->drvwrap.driver, NULL, &argb, | ||
2575 | - __find_interface); | ||
2576 | - return argb.interface; | ||
2577 | + argb.drv = &drv->drvwrap.driver; | ||
2578 | + | ||
2579 | + dev = bus_find_device(&usb_bus_type, NULL, &argb, __find_interface); | ||
2580 | + | ||
2581 | + /* Drop reference count from bus_find_device */ | ||
2582 | + put_device(dev); | ||
2583 | + | ||
2584 | + return dev ? to_usb_interface(dev) : NULL; | ||
2585 | } | ||
2586 | EXPORT_SYMBOL_GPL(usb_find_interface); | ||
2587 | |||
2588 | diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c | ||
2589 | index 7a67786..a243276 100644 | ||
2590 | --- a/drivers/usb/musb/musb_gadget_ep0.c | ||
2591 | +++ b/drivers/usb/musb/musb_gadget_ep0.c | ||
2592 | @@ -199,7 +199,6 @@ service_in_request(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest) | ||
2593 | static void musb_g_ep0_giveback(struct musb *musb, struct usb_request *req) | ||
2594 | { | ||
2595 | musb_g_giveback(&musb->endpoints[0].ep_in, req, 0); | ||
2596 | - musb->ep0_state = MUSB_EP0_STAGE_SETUP; | ||
2597 | } | ||
2598 | |||
2599 | /* | ||
2600 | diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c | ||
2601 | index dd50b78..e2a2e85 100644 | ||
2602 | --- a/drivers/usb/serial/option.c | ||
2603 | +++ b/drivers/usb/serial/option.c | ||
2604 | @@ -577,12 +577,48 @@ static struct usb_device_id option_ids[] = { | ||
2605 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, | ||
2606 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, | ||
2607 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, | ||
2608 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff) }, | ||
2609 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, | ||
2610 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, | ||
2611 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff) }, | ||
2612 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, | ||
2613 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, | ||
2614 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, | ||
2615 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, | ||
2616 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) }, | ||
2617 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) }, | ||
2618 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, | ||
2619 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) }, | ||
2620 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, | ||
2621 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, | ||
2622 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, | ||
2623 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) }, | ||
2624 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) }, | ||
2625 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0146, 0xff, 0xff, 0xff) }, | ||
2626 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, | ||
2627 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) }, | ||
2628 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0149, 0xff, 0xff, 0xff) }, | ||
2629 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0150, 0xff, 0xff, 0xff) }, | ||
2630 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) }, | ||
2631 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, | ||
2632 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) }, | ||
2633 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0154, 0xff, 0xff, 0xff) }, | ||
2634 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) }, | ||
2635 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, | ||
2636 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) }, | ||
2637 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) }, | ||
2638 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, | ||
2639 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) }, | ||
2640 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, | ||
2641 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, | ||
2642 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ | ||
2643 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, | ||
2644 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, | ||
2645 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) }, | ||
2646 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, | ||
2647 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, | ||
2648 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, | ||
2649 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, | ||
2650 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, | ||
2651 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, | ||
2652 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | ||
2653 | @@ -596,6 +632,7 @@ static struct usb_device_id option_ids[] = { | ||
2654 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, | ||
2655 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ | ||
2656 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, | ||
2657 | + { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) }, | ||
2658 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, | ||
2659 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, | ||
2660 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, | ||
2661 | diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c | ||
2662 | index 589f6b4..cc313d1 100644 | ||
2663 | --- a/drivers/usb/storage/transport.c | ||
2664 | +++ b/drivers/usb/storage/transport.c | ||
2665 | @@ -666,10 +666,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) | ||
2666 | * to wait for at least one CHECK_CONDITION to determine | ||
2667 | * SANE_SENSE support | ||
2668 | */ | ||
2669 | - if ((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) && | ||
2670 | + if (unlikely((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) && | ||
2671 | result == USB_STOR_TRANSPORT_GOOD && | ||
2672 | !(us->fflags & US_FL_SANE_SENSE) && | ||
2673 | - !(srb->cmnd[2] & 0x20)) { | ||
2674 | + !(us->fflags & US_FL_BAD_SENSE) && | ||
2675 | + !(srb->cmnd[2] & 0x20))) { | ||
2676 | US_DEBUGP("-- SAT supported, increasing auto-sense\n"); | ||
2677 | us->fflags |= US_FL_SANE_SENSE; | ||
2678 | } | ||
2679 | @@ -718,6 +719,12 @@ Retry_Sense: | ||
2680 | if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { | ||
2681 | US_DEBUGP("-- auto-sense aborted\n"); | ||
2682 | srb->result = DID_ABORT << 16; | ||
2683 | + | ||
2684 | + /* If SANE_SENSE caused this problem, disable it */ | ||
2685 | + if (sense_size != US_SENSE_SIZE) { | ||
2686 | + us->fflags &= ~US_FL_SANE_SENSE; | ||
2687 | + us->fflags |= US_FL_BAD_SENSE; | ||
2688 | + } | ||
2689 | goto Handle_Errors; | ||
2690 | } | ||
2691 | |||
2692 | @@ -727,10 +734,11 @@ Retry_Sense: | ||
2693 | * (small) sense request. This fixes some USB GSM modems | ||
2694 | */ | ||
2695 | if (temp_result == USB_STOR_TRANSPORT_FAILED && | ||
2696 | - (us->fflags & US_FL_SANE_SENSE) && | ||
2697 | - sense_size != US_SENSE_SIZE) { | ||
2698 | + sense_size != US_SENSE_SIZE) { | ||
2699 | US_DEBUGP("-- auto-sense failure, retry small sense\n"); | ||
2700 | sense_size = US_SENSE_SIZE; | ||
2701 | + us->fflags &= ~US_FL_SANE_SENSE; | ||
2702 | + us->fflags |= US_FL_BAD_SENSE; | ||
2703 | goto Retry_Sense; | ||
2704 | } | ||
2705 | |||
2706 | @@ -754,6 +762,7 @@ Retry_Sense: | ||
2707 | */ | ||
2708 | if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) && | ||
2709 | !(us->fflags & US_FL_SANE_SENSE) && | ||
2710 | + !(us->fflags & US_FL_BAD_SENSE) && | ||
2711 | (srb->sense_buffer[0] & 0x7C) == 0x70) { | ||
2712 | US_DEBUGP("-- SANE_SENSE support enabled\n"); | ||
2713 | us->fflags |= US_FL_SANE_SENSE; | ||
2714 | diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h | ||
2715 | index 7477d41..ee69eae 100644 | ||
2716 | --- a/drivers/usb/storage/unusual_devs.h | ||
2717 | +++ b/drivers/usb/storage/unusual_devs.h | ||
2718 | @@ -838,6 +838,13 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, | ||
2719 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
2720 | US_FL_FIX_CAPACITY ), | ||
2721 | |||
2722 | +/* Reported by Daniel Kukula <daniel.kuku@gmail.com> */ | ||
2723 | +UNUSUAL_DEV( 0x067b, 0x1063, 0x0100, 0x0100, | ||
2724 | + "Prolific Technology, Inc.", | ||
2725 | + "Prolific Storage Gadget", | ||
2726 | + US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
2727 | + US_FL_BAD_SENSE ), | ||
2728 | + | ||
2729 | /* Reported by Rogerio Brito <rbrito@ime.usp.br> */ | ||
2730 | UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001, | ||
2731 | "Prolific Technology, Inc.", | ||
2732 | diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c | ||
2733 | index 8060b85..716c8d7 100644 | ||
2734 | --- a/drivers/usb/storage/usb.c | ||
2735 | +++ b/drivers/usb/storage/usb.c | ||
2736 | @@ -228,6 +228,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data, | ||
2737 | if (data_len<36) // You lose. | ||
2738 | return; | ||
2739 | |||
2740 | + memset(data+8, ' ', 28); | ||
2741 | if(data[0]&0x20) { /* USB device currently not connected. Return | ||
2742 | peripheral qualifier 001b ("...however, the | ||
2743 | physical device is not currently connected | ||
2744 | @@ -237,15 +238,15 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data, | ||
2745 | device, it may return zeros or ASCII spaces | ||
2746 | (20h) in those fields until the data is | ||
2747 | available from the device."). */ | ||
2748 | - memset(data+8,0,28); | ||
2749 | } else { | ||
2750 | u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice); | ||
2751 | - memcpy(data+8, us->unusual_dev->vendorName, | ||
2752 | - strlen(us->unusual_dev->vendorName) > 8 ? 8 : | ||
2753 | - strlen(us->unusual_dev->vendorName)); | ||
2754 | - memcpy(data+16, us->unusual_dev->productName, | ||
2755 | - strlen(us->unusual_dev->productName) > 16 ? 16 : | ||
2756 | - strlen(us->unusual_dev->productName)); | ||
2757 | + int n; | ||
2758 | + | ||
2759 | + n = strlen(us->unusual_dev->vendorName); | ||
2760 | + memcpy(data+8, us->unusual_dev->vendorName, min(8, n)); | ||
2761 | + n = strlen(us->unusual_dev->productName); | ||
2762 | + memcpy(data+16, us->unusual_dev->productName, min(16, n)); | ||
2763 | + | ||
2764 | data[32] = 0x30 + ((bcdDevice>>12) & 0x0F); | ||
2765 | data[33] = 0x30 + ((bcdDevice>>8) & 0x0F); | ||
2766 | data[34] = 0x30 + ((bcdDevice>>4) & 0x0F); | ||
2767 | @@ -459,6 +460,9 @@ static void adjust_quirks(struct us_data *us) | ||
2768 | case 'a': | ||
2769 | f |= US_FL_SANE_SENSE; | ||
2770 | break; | ||
2771 | + case 'b': | ||
2772 | + f |= US_FL_BAD_SENSE; | ||
2773 | + break; | ||
2774 | case 'c': | ||
2775 | f |= US_FL_FIX_CAPACITY; | ||
2776 | break; | ||
2777 | diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c | ||
2778 | index b644947..a482dd7 100644 | ||
2779 | --- a/drivers/video/backlight/lcd.c | ||
2780 | +++ b/drivers/video/backlight/lcd.c | ||
2781 | @@ -56,7 +56,7 @@ static int fb_notifier_callback(struct notifier_block *self, | ||
2782 | |||
2783 | static int lcd_register_fb(struct lcd_device *ld) | ||
2784 | { | ||
2785 | - memset(&ld->fb_notif, 0, sizeof(&ld->fb_notif)); | ||
2786 | + memset(&ld->fb_notif, 0, sizeof(ld->fb_notif)); | ||
2787 | ld->fb_notif.notifier_call = fb_notifier_callback; | ||
2788 | return fb_register_client(&ld->fb_notif); | ||
2789 | } | ||
2790 | diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c | ||
2791 | index d42346e..3dcb6d2 100644 | ||
2792 | --- a/drivers/video/matrox/g450_pll.c | ||
2793 | +++ b/drivers/video/matrox/g450_pll.c | ||
2794 | @@ -341,7 +341,8 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | ||
2795 | M1064_XDVICLKCTRL_C1DVICLKEN | | ||
2796 | M1064_XDVICLKCTRL_DVILOOPCTL | | ||
2797 | M1064_XDVICLKCTRL_P1LOOPBWDTCTL; | ||
2798 | - matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL,tmp); | ||
2799 | + /* Setting this breaks PC systems so don't do it */ | ||
2800 | + /* matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL,tmp); */ | ||
2801 | matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, | ||
2802 | xpwrctrl); | ||
2803 | |||
2804 | diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c | ||
2805 | index d22438e..39c6ee8 100644 | ||
2806 | --- a/fs/debugfs/inode.c | ||
2807 | +++ b/fs/debugfs/inode.c | ||
2808 | @@ -32,7 +32,9 @@ static struct vfsmount *debugfs_mount; | ||
2809 | static int debugfs_mount_count; | ||
2810 | static bool debugfs_registered; | ||
2811 | |||
2812 | -static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev) | ||
2813 | +static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev, | ||
2814 | + void *data, const struct file_operations *fops) | ||
2815 | + | ||
2816 | { | ||
2817 | struct inode *inode = new_inode(sb); | ||
2818 | |||
2819 | @@ -44,14 +46,18 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d | ||
2820 | init_special_inode(inode, mode, dev); | ||
2821 | break; | ||
2822 | case S_IFREG: | ||
2823 | - inode->i_fop = &debugfs_file_operations; | ||
2824 | + inode->i_fop = fops ? fops : &debugfs_file_operations; | ||
2825 | + inode->i_private = data; | ||
2826 | break; | ||
2827 | case S_IFLNK: | ||
2828 | inode->i_op = &debugfs_link_operations; | ||
2829 | + inode->i_fop = fops; | ||
2830 | + inode->i_private = data; | ||
2831 | break; | ||
2832 | case S_IFDIR: | ||
2833 | inode->i_op = &simple_dir_inode_operations; | ||
2834 | - inode->i_fop = &simple_dir_operations; | ||
2835 | + inode->i_fop = fops ? fops : &simple_dir_operations; | ||
2836 | + inode->i_private = data; | ||
2837 | |||
2838 | /* directory inodes start off with i_nlink == 2 | ||
2839 | * (for "." entry) */ | ||
2840 | @@ -64,7 +70,8 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d | ||
2841 | |||
2842 | /* SMP-safe */ | ||
2843 | static int debugfs_mknod(struct inode *dir, struct dentry *dentry, | ||
2844 | - int mode, dev_t dev) | ||
2845 | + int mode, dev_t dev, void *data, | ||
2846 | + const struct file_operations *fops) | ||
2847 | { | ||
2848 | struct inode *inode; | ||
2849 | int error = -EPERM; | ||
2850 | @@ -72,7 +79,7 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry, | ||
2851 | if (dentry->d_inode) | ||
2852 | return -EEXIST; | ||
2853 | |||
2854 | - inode = debugfs_get_inode(dir->i_sb, mode, dev); | ||
2855 | + inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops); | ||
2856 | if (inode) { | ||
2857 | d_instantiate(dentry, inode); | ||
2858 | dget(dentry); | ||
2859 | @@ -81,12 +88,13 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry, | ||
2860 | return error; | ||
2861 | } | ||
2862 | |||
2863 | -static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | ||
2864 | +static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode, | ||
2865 | + void *data, const struct file_operations *fops) | ||
2866 | { | ||
2867 | int res; | ||
2868 | |||
2869 | mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; | ||
2870 | - res = debugfs_mknod(dir, dentry, mode, 0); | ||
2871 | + res = debugfs_mknod(dir, dentry, mode, 0, data, fops); | ||
2872 | if (!res) { | ||
2873 | inc_nlink(dir); | ||
2874 | fsnotify_mkdir(dir, dentry); | ||
2875 | @@ -94,18 +102,20 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | ||
2876 | return res; | ||
2877 | } | ||
2878 | |||
2879 | -static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode) | ||
2880 | +static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode, | ||
2881 | + void *data, const struct file_operations *fops) | ||
2882 | { | ||
2883 | mode = (mode & S_IALLUGO) | S_IFLNK; | ||
2884 | - return debugfs_mknod(dir, dentry, mode, 0); | ||
2885 | + return debugfs_mknod(dir, dentry, mode, 0, data, fops); | ||
2886 | } | ||
2887 | |||
2888 | -static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode) | ||
2889 | +static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode, | ||
2890 | + void *data, const struct file_operations *fops) | ||
2891 | { | ||
2892 | int res; | ||
2893 | |||
2894 | mode = (mode & S_IALLUGO) | S_IFREG; | ||
2895 | - res = debugfs_mknod(dir, dentry, mode, 0); | ||
2896 | + res = debugfs_mknod(dir, dentry, mode, 0, data, fops); | ||
2897 | if (!res) | ||
2898 | fsnotify_create(dir, dentry); | ||
2899 | return res; | ||
2900 | @@ -139,7 +149,9 @@ static struct file_system_type debug_fs_type = { | ||
2901 | |||
2902 | static int debugfs_create_by_name(const char *name, mode_t mode, | ||
2903 | struct dentry *parent, | ||
2904 | - struct dentry **dentry) | ||
2905 | + struct dentry **dentry, | ||
2906 | + void *data, | ||
2907 | + const struct file_operations *fops) | ||
2908 | { | ||
2909 | int error = 0; | ||
2910 | |||
2911 | @@ -164,13 +176,16 @@ static int debugfs_create_by_name(const char *name, mode_t mode, | ||
2912 | if (!IS_ERR(*dentry)) { | ||
2913 | switch (mode & S_IFMT) { | ||
2914 | case S_IFDIR: | ||
2915 | - error = debugfs_mkdir(parent->d_inode, *dentry, mode); | ||
2916 | + error = debugfs_mkdir(parent->d_inode, *dentry, mode, | ||
2917 | + data, fops); | ||
2918 | break; | ||
2919 | case S_IFLNK: | ||
2920 | - error = debugfs_link(parent->d_inode, *dentry, mode); | ||
2921 | + error = debugfs_link(parent->d_inode, *dentry, mode, | ||
2922 | + data, fops); | ||
2923 | break; | ||
2924 | default: | ||
2925 | - error = debugfs_create(parent->d_inode, *dentry, mode); | ||
2926 | + error = debugfs_create(parent->d_inode, *dentry, mode, | ||
2927 | + data, fops); | ||
2928 | break; | ||
2929 | } | ||
2930 | dput(*dentry); | ||
2931 | @@ -221,19 +236,13 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode, | ||
2932 | if (error) | ||
2933 | goto exit; | ||
2934 | |||
2935 | - error = debugfs_create_by_name(name, mode, parent, &dentry); | ||
2936 | + error = debugfs_create_by_name(name, mode, parent, &dentry, | ||
2937 | + data, fops); | ||
2938 | if (error) { | ||
2939 | dentry = NULL; | ||
2940 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | ||
2941 | goto exit; | ||
2942 | } | ||
2943 | - | ||
2944 | - if (dentry->d_inode) { | ||
2945 | - if (data) | ||
2946 | - dentry->d_inode->i_private = data; | ||
2947 | - if (fops) | ||
2948 | - dentry->d_inode->i_fop = fops; | ||
2949 | - } | ||
2950 | exit: | ||
2951 | return dentry; | ||
2952 | } | ||
2953 | diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c | ||
2954 | index 75efb02..e1925c7 100644 | ||
2955 | --- a/fs/devpts/inode.c | ||
2956 | +++ b/fs/devpts/inode.c | ||
2957 | @@ -518,11 +518,23 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) | ||
2958 | |||
2959 | struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number) | ||
2960 | { | ||
2961 | + struct dentry *dentry; | ||
2962 | + struct tty_struct *tty; | ||
2963 | + | ||
2964 | BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); | ||
2965 | |||
2966 | + /* Ensure dentry has not been deleted by devpts_pty_kill() */ | ||
2967 | + dentry = d_find_alias(pts_inode); | ||
2968 | + if (!dentry) | ||
2969 | + return NULL; | ||
2970 | + | ||
2971 | + tty = NULL; | ||
2972 | if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) | ||
2973 | - return (struct tty_struct *)pts_inode->i_private; | ||
2974 | - return NULL; | ||
2975 | + tty = (struct tty_struct *)pts_inode->i_private; | ||
2976 | + | ||
2977 | + dput(dentry); | ||
2978 | + | ||
2979 | + return tty; | ||
2980 | } | ||
2981 | |||
2982 | void devpts_pty_kill(struct tty_struct *tty) | ||
2983 | diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c | ||
2984 | index b49908a..6244b0c 100644 | ||
2985 | --- a/fs/ext3/inode.c | ||
2986 | +++ b/fs/ext3/inode.c | ||
2987 | @@ -1137,6 +1137,16 @@ static int do_journal_get_write_access(handle_t *handle, | ||
2988 | return ext3_journal_get_write_access(handle, bh); | ||
2989 | } | ||
2990 | |||
2991 | +/* | ||
2992 | + * Truncate blocks that were not used by write. We have to truncate the | ||
2993 | + * pagecache as well so that corresponding buffers get properly unmapped. | ||
2994 | + */ | ||
2995 | +static void ext3_truncate_failed_write(struct inode *inode) | ||
2996 | +{ | ||
2997 | + truncate_inode_pages(inode->i_mapping, inode->i_size); | ||
2998 | + ext3_truncate(inode); | ||
2999 | +} | ||
3000 | + | ||
3001 | static int ext3_write_begin(struct file *file, struct address_space *mapping, | ||
3002 | loff_t pos, unsigned len, unsigned flags, | ||
3003 | struct page **pagep, void **fsdata) | ||
3004 | @@ -1195,7 +1205,7 @@ write_begin_failed: | ||
3005 | unlock_page(page); | ||
3006 | page_cache_release(page); | ||
3007 | if (pos + len > inode->i_size) | ||
3008 | - ext3_truncate(inode); | ||
3009 | + ext3_truncate_failed_write(inode); | ||
3010 | } | ||
3011 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) | ||
3012 | goto retry; | ||
3013 | @@ -1290,7 +1300,7 @@ static int ext3_ordered_write_end(struct file *file, | ||
3014 | page_cache_release(page); | ||
3015 | |||
3016 | if (pos + len > inode->i_size) | ||
3017 | - ext3_truncate(inode); | ||
3018 | + ext3_truncate_failed_write(inode); | ||
3019 | return ret ? ret : copied; | ||
3020 | } | ||
3021 | |||
3022 | @@ -1316,7 +1326,7 @@ static int ext3_writeback_write_end(struct file *file, | ||
3023 | page_cache_release(page); | ||
3024 | |||
3025 | if (pos + len > inode->i_size) | ||
3026 | - ext3_truncate(inode); | ||
3027 | + ext3_truncate_failed_write(inode); | ||
3028 | return ret ? ret : copied; | ||
3029 | } | ||
3030 | |||
3031 | @@ -1369,7 +1379,7 @@ static int ext3_journalled_write_end(struct file *file, | ||
3032 | page_cache_release(page); | ||
3033 | |||
3034 | if (pos + len > inode->i_size) | ||
3035 | - ext3_truncate(inode); | ||
3036 | + ext3_truncate_failed_write(inode); | ||
3037 | return ret ? ret : copied; | ||
3038 | } | ||
3039 | |||
3040 | diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c | ||
3041 | index 6d98f11..424b033 100644 | ||
3042 | --- a/fs/hfs/catalog.c | ||
3043 | +++ b/fs/hfs/catalog.c | ||
3044 | @@ -289,6 +289,10 @@ int hfs_cat_move(u32 cnid, struct inode *src_dir, struct qstr *src_name, | ||
3045 | err = hfs_brec_find(&src_fd); | ||
3046 | if (err) | ||
3047 | goto out; | ||
3048 | + if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) { | ||
3049 | + err = -EIO; | ||
3050 | + goto out; | ||
3051 | + } | ||
3052 | |||
3053 | hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, | ||
3054 | src_fd.entrylength); | ||
3055 | diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c | ||
3056 | index 7c69b98..2b3b861 100644 | ||
3057 | --- a/fs/hfs/dir.c | ||
3058 | +++ b/fs/hfs/dir.c | ||
3059 | @@ -79,6 +79,11 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | ||
3060 | filp->f_pos++; | ||
3061 | /* fall through */ | ||
3062 | case 1: | ||
3063 | + if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { | ||
3064 | + err = -EIO; | ||
3065 | + goto out; | ||
3066 | + } | ||
3067 | + | ||
3068 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); | ||
3069 | if (entry.type != HFS_CDR_THD) { | ||
3070 | printk(KERN_ERR "hfs: bad catalog folder thread\n"); | ||
3071 | @@ -109,6 +114,12 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | ||
3072 | err = -EIO; | ||
3073 | goto out; | ||
3074 | } | ||
3075 | + | ||
3076 | + if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { | ||
3077 | + err = -EIO; | ||
3078 | + goto out; | ||
3079 | + } | ||
3080 | + | ||
3081 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); | ||
3082 | type = entry.type; | ||
3083 | len = hfs_mac2asc(sb, strbuf, &fd.key->cat.CName); | ||
3084 | diff --git a/fs/hfs/super.c b/fs/hfs/super.c | ||
3085 | index f7fcbe4..5ed7252 100644 | ||
3086 | --- a/fs/hfs/super.c | ||
3087 | +++ b/fs/hfs/super.c | ||
3088 | @@ -409,8 +409,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | ||
3089 | /* try to get the root inode */ | ||
3090 | hfs_find_init(HFS_SB(sb)->cat_tree, &fd); | ||
3091 | res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd); | ||
3092 | - if (!res) | ||
3093 | + if (!res) { | ||
3094 | + if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) { | ||
3095 | + res = -EIO; | ||
3096 | + goto bail; | ||
3097 | + } | ||
3098 | hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength); | ||
3099 | + } | ||
3100 | if (res) { | ||
3101 | hfs_find_exit(&fd); | ||
3102 | goto bail_no_root; | ||
3103 | diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c | ||
3104 | index 4b74149..ead427c 100644 | ||
3105 | --- a/fs/jbd2/journal.c | ||
3106 | +++ b/fs/jbd2/journal.c | ||
3107 | @@ -1421,6 +1421,13 @@ int jbd2_journal_load(journal_t *journal) | ||
3108 | if (jbd2_journal_recover(journal)) | ||
3109 | goto recovery_error; | ||
3110 | |||
3111 | + if (journal->j_failed_commit) { | ||
3112 | + printk(KERN_ERR "JBD2: journal transaction %u on %s " | ||
3113 | + "is corrupt.\n", journal->j_failed_commit, | ||
3114 | + journal->j_devname); | ||
3115 | + return -EIO; | ||
3116 | + } | ||
3117 | + | ||
3118 | /* OK, we've finished with the dynamic journal bits: | ||
3119 | * reinitialise the dynamic contents of the superblock in memory | ||
3120 | * and reset them on disk. */ | ||
3121 | diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c | ||
3122 | index 090c556..3b6f2fa 100644 | ||
3123 | --- a/fs/jffs2/gc.c | ||
3124 | +++ b/fs/jffs2/gc.c | ||
3125 | @@ -700,7 +700,8 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ | ||
3126 | struct jffs2_raw_inode ri; | ||
3127 | struct jffs2_node_frag *last_frag; | ||
3128 | union jffs2_device_node dev; | ||
3129 | - char *mdata = NULL, mdatalen = 0; | ||
3130 | + char *mdata = NULL; | ||
3131 | + int mdatalen = 0; | ||
3132 | uint32_t alloclen, ilen; | ||
3133 | int ret; | ||
3134 | |||
3135 | diff --git a/include/drm/drmP.h b/include/drm/drmP.h | ||
3136 | index 45b67d9..4637dce 100644 | ||
3137 | --- a/include/drm/drmP.h | ||
3138 | +++ b/include/drm/drmP.h | ||
3139 | @@ -1268,6 +1268,7 @@ extern u32 drm_vblank_count(struct drm_device *dev, int crtc); | ||
3140 | extern void drm_handle_vblank(struct drm_device *dev, int crtc); | ||
3141 | extern int drm_vblank_get(struct drm_device *dev, int crtc); | ||
3142 | extern void drm_vblank_put(struct drm_device *dev, int crtc); | ||
3143 | +extern void drm_vblank_off(struct drm_device *dev, int crtc); | ||
3144 | extern void drm_vblank_cleanup(struct drm_device *dev); | ||
3145 | /* Modesetting support */ | ||
3146 | extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); | ||
3147 | diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h | ||
3148 | index 4759917..5c66f2e 100644 | ||
3149 | --- a/include/linux/hrtimer.h | ||
3150 | +++ b/include/linux/hrtimer.h | ||
3151 | @@ -448,7 +448,7 @@ extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf, | ||
3152 | |||
3153 | static inline void timer_stats_account_hrtimer(struct hrtimer *timer) | ||
3154 | { | ||
3155 | - if (likely(!timer->start_site)) | ||
3156 | + if (likely(!timer_stats_active)) | ||
3157 | return; | ||
3158 | timer_stats_update_stats(timer, timer->start_pid, timer->start_site, | ||
3159 | timer->function, timer->start_comm, 0); | ||
3160 | @@ -459,8 +459,6 @@ extern void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer, | ||
3161 | |||
3162 | static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) | ||
3163 | { | ||
3164 | - if (likely(!timer_stats_active)) | ||
3165 | - return; | ||
3166 | __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0)); | ||
3167 | } | ||
3168 | |||
3169 | diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h | ||
3170 | index 4c218ee..8687a7d 100644 | ||
3171 | --- a/include/linux/isdn_ppp.h | ||
3172 | +++ b/include/linux/isdn_ppp.h | ||
3173 | @@ -157,7 +157,7 @@ typedef struct { | ||
3174 | |||
3175 | typedef struct { | ||
3176 | int mp_mrru; /* unused */ | ||
3177 | - struct sk_buff_head frags; /* fragments sl list */ | ||
3178 | + struct sk_buff * frags; /* fragments sl list -- use skb->next */ | ||
3179 | long frames; /* number of frames in the frame list */ | ||
3180 | unsigned int seq; /* last processed packet seq #: any packets | ||
3181 | * with smaller seq # will be dropped | ||
3182 | diff --git a/include/linux/kvm.h b/include/linux/kvm.h | ||
3183 | index 3db5d8d..bd3dc67 100644 | ||
3184 | --- a/include/linux/kvm.h | ||
3185 | +++ b/include/linux/kvm.h | ||
3186 | @@ -104,6 +104,11 @@ struct kvm_run { | ||
3187 | __u64 cr8; | ||
3188 | __u64 apic_base; | ||
3189 | |||
3190 | +#ifdef __KVM_S390 | ||
3191 | + /* the processor status word for s390 */ | ||
3192 | + __u64 psw_mask; /* psw upper half */ | ||
3193 | + __u64 psw_addr; /* psw lower half */ | ||
3194 | +#endif | ||
3195 | union { | ||
3196 | /* KVM_EXIT_UNKNOWN */ | ||
3197 | struct { | ||
3198 | @@ -155,8 +160,6 @@ struct kvm_run { | ||
3199 | /* KVM_EXIT_S390_SIEIC */ | ||
3200 | struct { | ||
3201 | __u8 icptcode; | ||
3202 | - __u64 mask; /* psw upper half */ | ||
3203 | - __u64 addr; /* psw lower half */ | ||
3204 | __u16 ipa; | ||
3205 | __u32 ipb; | ||
3206 | } s390_sieic; | ||
3207 | @@ -453,6 +456,7 @@ struct kvm_irq_routing { | ||
3208 | }; | ||
3209 | |||
3210 | #endif | ||
3211 | +#define KVM_CAP_S390_PSW 42 | ||
3212 | |||
3213 | /* | ||
3214 | * ioctls for VM fds | ||
3215 | diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h | ||
3216 | index 3d15fb9..a4b947e 100644 | ||
3217 | --- a/include/linux/usb_usual.h | ||
3218 | +++ b/include/linux/usb_usual.h | ||
3219 | @@ -56,7 +56,9 @@ | ||
3220 | US_FLAG(SANE_SENSE, 0x00008000) \ | ||
3221 | /* Sane Sense (> 18 bytes) */ \ | ||
3222 | US_FLAG(CAPACITY_OK, 0x00010000) \ | ||
3223 | - /* READ CAPACITY response is correct */ | ||
3224 | + /* READ CAPACITY response is correct */ \ | ||
3225 | + US_FLAG(BAD_SENSE, 0x00020000) \ | ||
3226 | + /* Bad Sense (never more than 18 bytes) */ | ||
3227 | |||
3228 | #define US_FLAG(name, value) US_FL_##name = value , | ||
3229 | enum { US_DO_ALL_FLAGS }; | ||
3230 | diff --git a/kernel/acct.c b/kernel/acct.c | ||
3231 | index 9a4715a..a6605ca 100644 | ||
3232 | --- a/kernel/acct.c | ||
3233 | +++ b/kernel/acct.c | ||
3234 | @@ -536,7 +536,8 @@ static void do_acct_process(struct bsd_acct_struct *acct, | ||
3235 | do_div(elapsed, AHZ); | ||
3236 | ac.ac_btime = get_seconds() - elapsed; | ||
3237 | /* we really need to bite the bullet and change layout */ | ||
3238 | - current_uid_gid(&ac.ac_uid, &ac.ac_gid); | ||
3239 | + ac.ac_uid = orig_cred->uid; | ||
3240 | + ac.ac_gid = orig_cred->gid; | ||
3241 | #if ACCT_VERSION==2 | ||
3242 | ac.ac_ahz = AHZ; | ||
3243 | #endif | ||
3244 | diff --git a/kernel/futex.c b/kernel/futex.c | ||
3245 | index c0a020f..ba7f0be 100644 | ||
3246 | --- a/kernel/futex.c | ||
3247 | +++ b/kernel/futex.c | ||
3248 | @@ -303,8 +303,14 @@ void put_futex_key(int fshared, union futex_key *key) | ||
3249 | */ | ||
3250 | static int fault_in_user_writeable(u32 __user *uaddr) | ||
3251 | { | ||
3252 | - int ret = get_user_pages(current, current->mm, (unsigned long)uaddr, | ||
3253 | - 1, 1, 0, NULL, NULL); | ||
3254 | + struct mm_struct *mm = current->mm; | ||
3255 | + int ret; | ||
3256 | + | ||
3257 | + down_read(&mm->mmap_sem); | ||
3258 | + ret = get_user_pages(current, mm, (unsigned long)uaddr, | ||
3259 | + 1, 1, 0, NULL, NULL); | ||
3260 | + up_read(&mm->mmap_sem); | ||
3261 | + | ||
3262 | return ret < 0 ? ret : 0; | ||
3263 | } | ||
3264 | |||
3265 | diff --git a/mm/mincore.c b/mm/mincore.c | ||
3266 | index 8cb508f..7a3436e 100644 | ||
3267 | --- a/mm/mincore.c | ||
3268 | +++ b/mm/mincore.c | ||
3269 | @@ -14,6 +14,7 @@ | ||
3270 | #include <linux/syscalls.h> | ||
3271 | #include <linux/swap.h> | ||
3272 | #include <linux/swapops.h> | ||
3273 | +#include <linux/hugetlb.h> | ||
3274 | |||
3275 | #include <asm/uaccess.h> | ||
3276 | #include <asm/pgtable.h> | ||
3277 | @@ -72,6 +73,42 @@ static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pag | ||
3278 | if (!vma || addr < vma->vm_start) | ||
3279 | return -ENOMEM; | ||
3280 | |||
3281 | +#ifdef CONFIG_HUGETLB_PAGE | ||
3282 | + if (is_vm_hugetlb_page(vma)) { | ||
3283 | + struct hstate *h; | ||
3284 | + unsigned long nr_huge; | ||
3285 | + unsigned char present; | ||
3286 | + | ||
3287 | + i = 0; | ||
3288 | + nr = min(pages, (vma->vm_end - addr) >> PAGE_SHIFT); | ||
3289 | + h = hstate_vma(vma); | ||
3290 | + nr_huge = ((addr + pages * PAGE_SIZE - 1) >> huge_page_shift(h)) | ||
3291 | + - (addr >> huge_page_shift(h)) + 1; | ||
3292 | + nr_huge = min(nr_huge, | ||
3293 | + (vma->vm_end - addr) >> huge_page_shift(h)); | ||
3294 | + while (1) { | ||
3295 | + /* hugepage always in RAM for now, | ||
3296 | + * but generally it needs to be check */ | ||
3297 | + ptep = huge_pte_offset(current->mm, | ||
3298 | + addr & huge_page_mask(h)); | ||
3299 | + present = !!(ptep && | ||
3300 | + !huge_pte_none(huge_ptep_get(ptep))); | ||
3301 | + while (1) { | ||
3302 | + vec[i++] = present; | ||
3303 | + addr += PAGE_SIZE; | ||
3304 | + /* reach buffer limit */ | ||
3305 | + if (i == nr) | ||
3306 | + return nr; | ||
3307 | + /* check hugepage border */ | ||
3308 | + if (!((addr & ~huge_page_mask(h)) | ||
3309 | + >> PAGE_SHIFT)) | ||
3310 | + break; | ||
3311 | + } | ||
3312 | + } | ||
3313 | + return nr; | ||
3314 | + } | ||
3315 | +#endif | ||
3316 | + | ||
3317 | /* | ||
3318 | * Calculate how many pages there are left in the last level of the | ||
3319 | * PTE array for our address. | ||
3320 | diff --git a/mm/pagewalk.c b/mm/pagewalk.c | ||
3321 | index d5878be..a286915 100644 | ||
3322 | --- a/mm/pagewalk.c | ||
3323 | +++ b/mm/pagewalk.c | ||
3324 | @@ -1,6 +1,7 @@ | ||
3325 | #include <linux/mm.h> | ||
3326 | #include <linux/highmem.h> | ||
3327 | #include <linux/sched.h> | ||
3328 | +#include <linux/hugetlb.h> | ||
3329 | |||
3330 | static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | ||
3331 | struct mm_walk *walk) | ||
3332 | @@ -107,6 +108,7 @@ int walk_page_range(unsigned long addr, unsigned long end, | ||
3333 | pgd_t *pgd; | ||
3334 | unsigned long next; | ||
3335 | int err = 0; | ||
3336 | + struct vm_area_struct *vma; | ||
3337 | |||
3338 | if (addr >= end) | ||
3339 | return err; | ||
3340 | @@ -117,11 +119,22 @@ int walk_page_range(unsigned long addr, unsigned long end, | ||
3341 | pgd = pgd_offset(walk->mm, addr); | ||
3342 | do { | ||
3343 | next = pgd_addr_end(addr, end); | ||
3344 | + | ||
3345 | + /* skip hugetlb vma to avoid hugepage PMD being cleared | ||
3346 | + * in pmd_none_or_clear_bad(). */ | ||
3347 | + vma = find_vma(walk->mm, addr); | ||
3348 | + if (vma && is_vm_hugetlb_page(vma)) { | ||
3349 | + if (vma->vm_end < next) | ||
3350 | + next = vma->vm_end; | ||
3351 | + continue; | ||
3352 | + } | ||
3353 | + | ||
3354 | if (pgd_none_or_clear_bad(pgd)) { | ||
3355 | if (walk->pte_hole) | ||
3356 | err = walk->pte_hole(addr, next, walk); | ||
3357 | if (err) | ||
3358 | break; | ||
3359 | + pgd++; | ||
3360 | continue; | ||
3361 | } | ||
3362 | if (walk->pgd_entry) | ||
3363 | @@ -131,7 +144,8 @@ int walk_page_range(unsigned long addr, unsigned long end, | ||
3364 | err = walk_pud_range(pgd, addr, next, walk); | ||
3365 | if (err) | ||
3366 | break; | ||
3367 | - } while (pgd++, addr = next, addr != end); | ||
3368 | + pgd++; | ||
3369 | + } while (addr = next, addr != end); | ||
3370 | |||
3371 | return err; | ||
3372 | } | ||
3373 | diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c | ||
3374 | index fe64908..db09b94 100644 | ||
3375 | --- a/net/8021q/vlan.c | ||
3376 | +++ b/net/8021q/vlan.c | ||
3377 | @@ -287,8 +287,11 @@ out_uninit_applicant: | ||
3378 | if (ngrp) | ||
3379 | vlan_gvrp_uninit_applicant(real_dev); | ||
3380 | out_free_group: | ||
3381 | - if (ngrp) | ||
3382 | - vlan_group_free(ngrp); | ||
3383 | + if (ngrp) { | ||
3384 | + hlist_del_rcu(&ngrp->hlist); | ||
3385 | + /* Free the group, after all cpu's are done. */ | ||
3386 | + call_rcu(&ngrp->rcu, vlan_rcu_free); | ||
3387 | + } | ||
3388 | return err; | ||
3389 | } | ||
3390 | |||
3391 | diff --git a/net/core/dev.c b/net/core/dev.c | ||
3392 | index a2f575b..4225097 100644 | ||
3393 | --- a/net/core/dev.c | ||
3394 | +++ b/net/core/dev.c | ||
3395 | @@ -933,14 +933,15 @@ rollback: | ||
3396 | ret = notifier_to_errno(ret); | ||
3397 | |||
3398 | if (ret) { | ||
3399 | - if (err) { | ||
3400 | - printk(KERN_ERR | ||
3401 | - "%s: name change rollback failed: %d.\n", | ||
3402 | - dev->name, ret); | ||
3403 | - } else { | ||
3404 | + /* err >= 0 after dev_alloc_name() or stores the first errno */ | ||
3405 | + if (err >= 0) { | ||
3406 | err = ret; | ||
3407 | memcpy(dev->name, oldname, IFNAMSIZ); | ||
3408 | goto rollback; | ||
3409 | + } else { | ||
3410 | + printk(KERN_ERR | ||
3411 | + "%s: name change rollback failed: %d.\n", | ||
3412 | + dev->name, ret); | ||
3413 | } | ||
3414 | } | ||
3415 | |||
3416 | @@ -4807,6 +4808,11 @@ int register_netdevice(struct net_device *dev) | ||
3417 | rollback_registered(dev); | ||
3418 | dev->reg_state = NETREG_UNREGISTERED; | ||
3419 | } | ||
3420 | + /* | ||
3421 | + * Prevent userspace races by waiting until the network | ||
3422 | + * device is fully setup before sending notifications. | ||
3423 | + */ | ||
3424 | + rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); | ||
3425 | |||
3426 | out: | ||
3427 | return ret; | ||
3428 | @@ -5342,6 +5348,12 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | ||
3429 | /* Notify protocols, that a new device appeared. */ | ||
3430 | call_netdevice_notifiers(NETDEV_REGISTER, dev); | ||
3431 | |||
3432 | + /* | ||
3433 | + * Prevent userspace races by waiting until the network | ||
3434 | + * device is fully setup before sending notifications. | ||
3435 | + */ | ||
3436 | + rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); | ||
3437 | + | ||
3438 | synchronize_net(); | ||
3439 | err = 0; | ||
3440 | out: | ||
3441 | diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c | ||
3442 | index d78030f..93f1845 100644 | ||
3443 | --- a/net/core/rtnetlink.c | ||
3444 | +++ b/net/core/rtnetlink.c | ||
3445 | @@ -1347,13 +1347,11 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi | ||
3446 | case NETDEV_UNREGISTER: | ||
3447 | rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); | ||
3448 | break; | ||
3449 | - case NETDEV_REGISTER: | ||
3450 | - rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); | ||
3451 | - break; | ||
3452 | case NETDEV_UP: | ||
3453 | case NETDEV_DOWN: | ||
3454 | rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); | ||
3455 | break; | ||
3456 | + case NETDEV_REGISTER: | ||
3457 | case NETDEV_CHANGE: | ||
3458 | case NETDEV_GOING_DOWN: | ||
3459 | break; | ||
3460 | diff --git a/net/core/skbuff.c b/net/core/skbuff.c | ||
3461 | index 9e0597d..79ae895 100644 | ||
3462 | --- a/net/core/skbuff.c | ||
3463 | +++ b/net/core/skbuff.c | ||
3464 | @@ -2704,7 +2704,8 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | ||
3465 | |||
3466 | NAPI_GRO_CB(skb)->free = 1; | ||
3467 | goto done; | ||
3468 | - } | ||
3469 | + } else if (skb_gro_len(p) != pinfo->gso_size) | ||
3470 | + return -E2BIG; | ||
3471 | |||
3472 | headroom = skb_headroom(p); | ||
3473 | nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); | ||
3474 | diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c | ||
3475 | index 7ffcd96..4d64a80 100644 | ||
3476 | --- a/net/ipv4/ip_output.c | ||
3477 | +++ b/net/ipv4/ip_output.c | ||
3478 | @@ -500,8 +500,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | ||
3479 | if (skb->sk) { | ||
3480 | frag->sk = skb->sk; | ||
3481 | frag->destructor = sock_wfree; | ||
3482 | - truesizes += frag->truesize; | ||
3483 | } | ||
3484 | + truesizes += frag->truesize; | ||
3485 | } | ||
3486 | |||
3487 | /* Everything is OK. Generate! */ | ||
3488 | diff --git a/net/mac80211/util.c b/net/mac80211/util.c | ||
3489 | index 915e777..005016d 100644 | ||
3490 | --- a/net/mac80211/util.c | ||
3491 | +++ b/net/mac80211/util.c | ||
3492 | @@ -537,7 +537,7 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | ||
3493 | if (elen > left) | ||
3494 | break; | ||
3495 | |||
3496 | - if (calc_crc && id < 64 && (filter & BIT(id))) | ||
3497 | + if (calc_crc && id < 64 && (filter & (1ULL << id))) | ||
3498 | crc = crc32_be(crc, pos - 2, elen + 2); | ||
3499 | |||
3500 | switch (id) { | ||
3501 | diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c | ||
3502 | index 7c1333c..27a15f5 100644 | ||
3503 | --- a/net/netfilter/ipvs/ip_vs_ctl.c | ||
3504 | +++ b/net/netfilter/ipvs/ip_vs_ctl.c | ||
3505 | @@ -2713,6 +2713,8 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, | ||
3506 | if (!(nla_af && (nla_fwmark || (nla_port && nla_protocol && nla_addr)))) | ||
3507 | return -EINVAL; | ||
3508 | |||
3509 | + memset(usvc, 0, sizeof(*usvc)); | ||
3510 | + | ||
3511 | usvc->af = nla_get_u16(nla_af); | ||
3512 | #ifdef CONFIG_IP_VS_IPV6 | ||
3513 | if (usvc->af != AF_INET && usvc->af != AF_INET6) | ||
3514 | @@ -2900,6 +2902,8 @@ static int ip_vs_genl_parse_dest(struct ip_vs_dest_user_kern *udest, | ||
3515 | if (!(nla_addr && nla_port)) | ||
3516 | return -EINVAL; | ||
3517 | |||
3518 | + memset(udest, 0, sizeof(*udest)); | ||
3519 | + | ||
3520 | nla_memcpy(&udest->addr, nla_addr, sizeof(udest->addr)); | ||
3521 | udest->port = nla_get_u16(nla_port); | ||
3522 | |||
3523 | diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c | ||
3524 | index 66d458f..836c50e 100644 | ||
3525 | --- a/net/sunrpc/auth_gss/auth_gss.c | ||
3526 | +++ b/net/sunrpc/auth_gss/auth_gss.c | ||
3527 | @@ -485,7 +485,7 @@ gss_refresh_upcall(struct rpc_task *task) | ||
3528 | dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, | ||
3529 | cred->cr_uid); | ||
3530 | gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); | ||
3531 | - if (IS_ERR(gss_msg) == -EAGAIN) { | ||
3532 | + if (PTR_ERR(gss_msg) == -EAGAIN) { | ||
3533 | /* XXX: warning on the first, under the assumption we | ||
3534 | * shouldn't normally hit this case on a refresh. */ | ||
3535 | warn_gssd(); | ||
3536 | diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c | ||
3537 | index 34c7d48..7f4d744 100644 | ||
3538 | --- a/sound/core/hrtimer.c | ||
3539 | +++ b/sound/core/hrtimer.c | ||
3540 | @@ -37,14 +37,22 @@ static unsigned int resolution; | ||
3541 | struct snd_hrtimer { | ||
3542 | struct snd_timer *timer; | ||
3543 | struct hrtimer hrt; | ||
3544 | + atomic_t running; | ||
3545 | }; | ||
3546 | |||
3547 | static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) | ||
3548 | { | ||
3549 | struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt); | ||
3550 | struct snd_timer *t = stime->timer; | ||
3551 | + | ||
3552 | + if (!atomic_read(&stime->running)) | ||
3553 | + return HRTIMER_NORESTART; | ||
3554 | + | ||
3555 | hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution)); | ||
3556 | snd_timer_interrupt(stime->timer, t->sticks); | ||
3557 | + | ||
3558 | + if (!atomic_read(&stime->running)) | ||
3559 | + return HRTIMER_NORESTART; | ||
3560 | return HRTIMER_RESTART; | ||
3561 | } | ||
3562 | |||
3563 | @@ -58,6 +66,7 @@ static int snd_hrtimer_open(struct snd_timer *t) | ||
3564 | hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
3565 | stime->timer = t; | ||
3566 | stime->hrt.function = snd_hrtimer_callback; | ||
3567 | + atomic_set(&stime->running, 0); | ||
3568 | t->private_data = stime; | ||
3569 | return 0; | ||
3570 | } | ||
3571 | @@ -78,16 +87,18 @@ static int snd_hrtimer_start(struct snd_timer *t) | ||
3572 | { | ||
3573 | struct snd_hrtimer *stime = t->private_data; | ||
3574 | |||
3575 | + atomic_set(&stime->running, 0); | ||
3576 | + hrtimer_cancel(&stime->hrt); | ||
3577 | hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution), | ||
3578 | HRTIMER_MODE_REL); | ||
3579 | + atomic_set(&stime->running, 1); | ||
3580 | return 0; | ||
3581 | } | ||
3582 | |||
3583 | static int snd_hrtimer_stop(struct snd_timer *t) | ||
3584 | { | ||
3585 | struct snd_hrtimer *stime = t->private_data; | ||
3586 | - | ||
3587 | - hrtimer_cancel(&stime->hrt); | ||
3588 | + atomic_set(&stime->running, 0); | ||
3589 | return 0; | ||
3590 | } | ||
3591 | |||
3592 | diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c | ||
3593 | index 175f07a..d6f93b0 100644 | ||
3594 | --- a/sound/pci/hda/hda_intel.c | ||
3595 | +++ b/sound/pci/hda/hda_intel.c | ||
3596 | @@ -2392,6 +2392,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | ||
3597 | } | ||
3598 | } | ||
3599 | |||
3600 | + /* disable 64bit DMA address for Teradici */ | ||
3601 | + /* it does not work with device 6549:1200 subsys e4a2:040b */ | ||
3602 | + if (chip->driver_type == AZX_DRIVER_TERA) | ||
3603 | + gcap &= ~ICH6_GCAP_64OK; | ||
3604 | + | ||
3605 | /* allow 64bit DMA address if supported by H/W */ | ||
3606 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | ||
3607 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); |