Contents of /trunk/kernel26-magellan/patches-2.6.25-r5/0113-2.6.25.14-all-fixes.patch
Parent Directory | Revision Log
Revision 677 -
(show annotations)
(download)
Wed Sep 10 21:27:27 2008 UTC (16 years, 1 month ago) by niro
File size: 30765 byte(s)
Wed Sep 10 21:27:27 2008 UTC (16 years, 1 month ago) by niro
File size: 30765 byte(s)
2.6.25-magellan-r5: - updated to linux-2.6.25.17
1 | diff --git a/Makefile b/Makefile |
2 | index dfc5a88..4c589b6 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1126,7 +1126,8 @@ clean: archclean $(clean-dirs) |
6 | @find . $(RCS_FIND_IGNORE) \ |
7 | \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ |
8 | -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ |
9 | - -o -name '*.symtypes' -o -name 'modules.order' \) \ |
10 | + -o -name '*.symtypes' -o -name 'modules.order' \ |
11 | + -o -name 'Module.markers' \) \ |
12 | -type f -print | xargs rm -f |
13 | |
14 | # mrproper - Delete all generated files, including .config |
15 | diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c b/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c |
16 | index 69288f6..3233fe8 100644 |
17 | --- a/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c |
18 | +++ b/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c |
19 | @@ -96,6 +96,12 @@ static int pmi_notifier(struct notifier_block *nb, |
20 | struct cpufreq_frequency_table *cbe_freqs; |
21 | u8 node; |
22 | |
23 | + /* Should this really be called for CPUFREQ_ADJUST, CPUFREQ_INCOMPATIBLE |
24 | + * and CPUFREQ_NOTIFY policy events?) |
25 | + */ |
26 | + if (event == CPUFREQ_START) |
27 | + return 0; |
28 | + |
29 | cbe_freqs = cpufreq_frequency_get_table(policy->cpu); |
30 | node = cbe_cpu_to_node(policy->cpu); |
31 | |
32 | diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c |
33 | index b441a26..c481673 100644 |
34 | --- a/arch/sparc64/kernel/irq.c |
35 | +++ b/arch/sparc64/kernel/irq.c |
36 | @@ -621,8 +621,9 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) |
37 | unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) |
38 | { |
39 | struct irq_handler_data *data; |
40 | - struct ino_bucket *bucket; |
41 | unsigned long hv_err, cookie; |
42 | + struct ino_bucket *bucket; |
43 | + struct irq_desc *desc; |
44 | unsigned int virt_irq; |
45 | |
46 | bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); |
47 | @@ -643,6 +644,13 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) |
48 | if (unlikely(!data)) |
49 | return 0; |
50 | |
51 | + /* In order to make the LDC channel startup sequence easier, |
52 | + * especially wrt. locking, we do not let request_irq() enable |
53 | + * the interrupt. |
54 | + */ |
55 | + desc = irq_desc + virt_irq; |
56 | + desc->status |= IRQ_NOAUTOEN; |
57 | + |
58 | set_irq_chip_data(virt_irq, data); |
59 | |
60 | /* Catch accidental accesses to these things. IMAP/ICLR handling |
61 | diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c |
62 | index 63969f6..d689823 100644 |
63 | --- a/arch/sparc64/kernel/ldc.c |
64 | +++ b/arch/sparc64/kernel/ldc.c |
65 | @@ -1,6 +1,6 @@ |
66 | /* ldc.c: Logical Domain Channel link-layer protocol driver. |
67 | * |
68 | - * Copyright (C) 2007 David S. Miller <davem@davemloft.net> |
69 | + * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net> |
70 | */ |
71 | |
72 | #include <linux/kernel.h> |
73 | @@ -23,8 +23,8 @@ |
74 | |
75 | #define DRV_MODULE_NAME "ldc" |
76 | #define PFX DRV_MODULE_NAME ": " |
77 | -#define DRV_MODULE_VERSION "1.0" |
78 | -#define DRV_MODULE_RELDATE "June 25, 2007" |
79 | +#define DRV_MODULE_VERSION "1.1" |
80 | +#define DRV_MODULE_RELDATE "July 22, 2008" |
81 | |
82 | static char version[] __devinitdata = |
83 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
84 | @@ -1235,13 +1235,9 @@ int ldc_bind(struct ldc_channel *lp, const char *name) |
85 | unsigned long hv_err, flags; |
86 | int err = -EINVAL; |
87 | |
88 | - spin_lock_irqsave(&lp->lock, flags); |
89 | - |
90 | - if (!name) |
91 | - goto out_err; |
92 | - |
93 | - if (lp->state != LDC_STATE_INIT) |
94 | - goto out_err; |
95 | + if (!name || |
96 | + (lp->state != LDC_STATE_INIT)) |
97 | + return -EINVAL; |
98 | |
99 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); |
100 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); |
101 | @@ -1250,25 +1246,32 @@ int ldc_bind(struct ldc_channel *lp, const char *name) |
102 | IRQF_SAMPLE_RANDOM | IRQF_SHARED, |
103 | lp->rx_irq_name, lp); |
104 | if (err) |
105 | - goto out_err; |
106 | + return err; |
107 | |
108 | err = request_irq(lp->cfg.tx_irq, ldc_tx, |
109 | IRQF_SAMPLE_RANDOM | IRQF_SHARED, |
110 | lp->tx_irq_name, lp); |
111 | - if (err) |
112 | - goto out_free_rx_irq; |
113 | + if (err) { |
114 | + free_irq(lp->cfg.rx_irq, lp); |
115 | + return err; |
116 | + } |
117 | + |
118 | |
119 | + spin_lock_irqsave(&lp->lock, flags); |
120 | + |
121 | + enable_irq(lp->cfg.rx_irq); |
122 | + enable_irq(lp->cfg.tx_irq); |
123 | |
124 | lp->flags |= LDC_FLAG_REGISTERED_IRQS; |
125 | |
126 | err = -ENODEV; |
127 | hv_err = sun4v_ldc_tx_qconf(lp->id, 0, 0); |
128 | if (hv_err) |
129 | - goto out_free_tx_irq; |
130 | + goto out_free_irqs; |
131 | |
132 | hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries); |
133 | if (hv_err) |
134 | - goto out_free_tx_irq; |
135 | + goto out_free_irqs; |
136 | |
137 | hv_err = sun4v_ldc_rx_qconf(lp->id, 0, 0); |
138 | if (hv_err) |
139 | @@ -1304,14 +1307,11 @@ out_unmap_rx: |
140 | out_unmap_tx: |
141 | sun4v_ldc_tx_qconf(lp->id, 0, 0); |
142 | |
143 | -out_free_tx_irq: |
144 | +out_free_irqs: |
145 | lp->flags &= ~LDC_FLAG_REGISTERED_IRQS; |
146 | free_irq(lp->cfg.tx_irq, lp); |
147 | - |
148 | -out_free_rx_irq: |
149 | free_irq(lp->cfg.rx_irq, lp); |
150 | |
151 | -out_err: |
152 | spin_unlock_irqrestore(&lp->lock, flags); |
153 | |
154 | return err; |
155 | diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c |
156 | index e5d2389..f464023 100644 |
157 | --- a/arch/sparc64/kernel/time.c |
158 | +++ b/arch/sparc64/kernel/time.c |
159 | @@ -883,6 +883,16 @@ static struct notifier_block sparc64_cpufreq_notifier_block = { |
160 | .notifier_call = sparc64_cpufreq_notifier |
161 | }; |
162 | |
163 | +static int __init register_sparc64_cpufreq_notifier(void) |
164 | +{ |
165 | + |
166 | + cpufreq_register_notifier(&sparc64_cpufreq_notifier_block, |
167 | + CPUFREQ_TRANSITION_NOTIFIER); |
168 | + return 0; |
169 | +} |
170 | + |
171 | +core_initcall(register_sparc64_cpufreq_notifier); |
172 | + |
173 | #endif /* CONFIG_CPU_FREQ */ |
174 | |
175 | static int sparc64_next_event(unsigned long delta, |
176 | @@ -1049,11 +1059,6 @@ void __init time_init(void) |
177 | sparc64_clockevent.mult, sparc64_clockevent.shift); |
178 | |
179 | setup_sparc64_timer(); |
180 | - |
181 | -#ifdef CONFIG_CPU_FREQ |
182 | - cpufreq_register_notifier(&sparc64_cpufreq_notifier_block, |
183 | - CPUFREQ_TRANSITION_NOTIFIER); |
184 | -#endif |
185 | } |
186 | |
187 | unsigned long long sched_clock(void) |
188 | diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu |
189 | index 9304bfb..c308d61 100644 |
190 | --- a/arch/x86/Kconfig.cpu |
191 | +++ b/arch/x86/Kconfig.cpu |
192 | @@ -409,4 +409,4 @@ config X86_MINIMUM_CPU_FAMILY |
193 | |
194 | config X86_DEBUGCTLMSR |
195 | def_bool y |
196 | - depends on !(M586MMX || M586TSC || M586 || M486 || M386) |
197 | + depends on !(MK6 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386) |
198 | diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c |
199 | index b2c5231..8e47740 100644 |
200 | --- a/arch/x86/mm/init_64.c |
201 | +++ b/arch/x86/mm/init_64.c |
202 | @@ -427,7 +427,7 @@ void __init_refok init_memory_mapping(unsigned long start, unsigned long end) |
203 | else |
204 | pud = alloc_low_page(&pud_phys); |
205 | |
206 | - next = start + PGDIR_SIZE; |
207 | + next = (start + PGDIR_SIZE) & PGDIR_MASK; |
208 | if (next > end) |
209 | next = end; |
210 | phys_pud_init(pud, __pa(start), __pa(next)); |
211 | diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c |
212 | index b477a4b..42fb635 100644 |
213 | --- a/drivers/acpi/processor_perflib.c |
214 | +++ b/drivers/acpi/processor_perflib.c |
215 | @@ -64,7 +64,13 @@ static DEFINE_MUTEX(performance_mutex); |
216 | * policy is adjusted accordingly. |
217 | */ |
218 | |
219 | -static unsigned int ignore_ppc = 0; |
220 | +/* ignore_ppc: |
221 | + * -1 -> cpufreq low level drivers not initialized -> _PSS, etc. not called yet |
222 | + * ignore _PPC |
223 | + * 0 -> cpufreq low level drivers initialized -> consider _PPC values |
224 | + * 1 -> ignore _PPC totally -> forced by user through boot param |
225 | + */ |
226 | +static unsigned int ignore_ppc = -1; |
227 | module_param(ignore_ppc, uint, 0644); |
228 | MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \ |
229 | "limited by BIOS, this should help"); |
230 | @@ -72,7 +78,7 @@ MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \ |
231 | #define PPC_REGISTERED 1 |
232 | #define PPC_IN_USE 2 |
233 | |
234 | -static int acpi_processor_ppc_status = 0; |
235 | +static int acpi_processor_ppc_status; |
236 | |
237 | static int acpi_processor_ppc_notifier(struct notifier_block *nb, |
238 | unsigned long event, void *data) |
239 | @@ -81,6 +87,11 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb, |
240 | struct acpi_processor *pr; |
241 | unsigned int ppc = 0; |
242 | |
243 | + if (event == CPUFREQ_START && ignore_ppc <= 0) { |
244 | + ignore_ppc = 0; |
245 | + return 0; |
246 | + } |
247 | + |
248 | if (ignore_ppc) |
249 | return 0; |
250 | |
251 | diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c |
252 | index b1eb4e2..d630502 100644 |
253 | --- a/drivers/ata/ahci.c |
254 | +++ b/drivers/ata/ahci.c |
255 | @@ -634,16 +634,27 @@ static inline void __iomem *ahci_port_base(struct ata_port *ap) |
256 | |
257 | static void ahci_enable_ahci(void __iomem *mmio) |
258 | { |
259 | + int i; |
260 | u32 tmp; |
261 | |
262 | /* turn on AHCI_EN */ |
263 | tmp = readl(mmio + HOST_CTL); |
264 | - if (!(tmp & HOST_AHCI_EN)) { |
265 | + if (tmp & HOST_AHCI_EN) |
266 | + return; |
267 | + |
268 | + /* Some controllers need AHCI_EN to be written multiple times. |
269 | + * Try a few times before giving up. |
270 | + */ |
271 | + for (i = 0; i < 5; i++) { |
272 | tmp |= HOST_AHCI_EN; |
273 | writel(tmp, mmio + HOST_CTL); |
274 | tmp = readl(mmio + HOST_CTL); /* flush && sanity check */ |
275 | - WARN_ON(!(tmp & HOST_AHCI_EN)); |
276 | + if (tmp & HOST_AHCI_EN) |
277 | + return; |
278 | + msleep(10); |
279 | } |
280 | + |
281 | + WARN_ON(1); |
282 | } |
283 | |
284 | /** |
285 | diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c |
286 | index 2053420..a3ede49 100644 |
287 | --- a/drivers/ata/ata_generic.c |
288 | +++ b/drivers/ata/ata_generic.c |
289 | @@ -193,6 +193,12 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id |
290 | if (dev->vendor == PCI_VENDOR_ID_AL) |
291 | ata_pci_clear_simplex(dev); |
292 | |
293 | + if (dev->vendor == PCI_VENDOR_ID_ATI) { |
294 | + int rc = pcim_enable_device(dev); |
295 | + if (rc < 0) |
296 | + return rc; |
297 | + pcim_pin_device(dev); |
298 | + } |
299 | return ata_pci_init_one(dev, ppi); |
300 | } |
301 | |
302 | diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c |
303 | index bdc3b9d..ea354a5 100644 |
304 | --- a/drivers/ata/pata_acpi.c |
305 | +++ b/drivers/ata/pata_acpi.c |
306 | @@ -314,6 +314,12 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id) |
307 | .port_ops = &pacpi_ops, |
308 | }; |
309 | const struct ata_port_info *ppi[] = { &info, NULL }; |
310 | + if (pdev->vendor == PCI_VENDOR_ID_ATI) { |
311 | + int rc = pcim_enable_device(pdev); |
312 | + if (rc < 0) |
313 | + return rc; |
314 | + pcim_pin_device(pdev); |
315 | + } |
316 | return ata_pci_init_one(pdev, ppi); |
317 | } |
318 | |
319 | diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c |
320 | index ebd68c1..e91bf79 100644 |
321 | --- a/drivers/cpufreq/cpufreq.c |
322 | +++ b/drivers/cpufreq/cpufreq.c |
323 | @@ -806,6 +806,9 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) |
324 | policy->user_policy.min = policy->cpuinfo.min_freq; |
325 | policy->user_policy.max = policy->cpuinfo.max_freq; |
326 | |
327 | + blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
328 | + CPUFREQ_START, policy); |
329 | + |
330 | #ifdef CONFIG_SMP |
331 | |
332 | #ifdef CONFIG_HOTPLUG_CPU |
333 | diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c |
334 | index c8d0e87..e54da02 100644 |
335 | --- a/drivers/ide/ide-cd.c |
336 | +++ b/drivers/ide/ide-cd.c |
337 | @@ -1421,13 +1421,30 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, |
338 | req.cmd_flags |= REQ_QUIET; |
339 | |
340 | stat = ide_cd_queue_pc(drive, &req); |
341 | - if (stat == 0) { |
342 | - *capacity = 1 + be32_to_cpu(capbuf.lba); |
343 | - *sectors_per_frame = |
344 | - be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS; |
345 | + if (stat) |
346 | + return stat; |
347 | + |
348 | + /* |
349 | + * Sanity check the given block size |
350 | + */ |
351 | + switch (capbuf.blocklen) { |
352 | + case __constant_cpu_to_be32(512): |
353 | + case __constant_cpu_to_be32(1024): |
354 | + case __constant_cpu_to_be32(2048): |
355 | + case __constant_cpu_to_be32(4096): |
356 | + break; |
357 | + default: |
358 | + printk(KERN_ERR "%s: weird block size %u\n", |
359 | + drive->name, capbuf.blocklen); |
360 | + printk(KERN_ERR "%s: default to 2kb block size\n", |
361 | + drive->name); |
362 | + capbuf.blocklen = __constant_cpu_to_be32(2048); |
363 | + break; |
364 | } |
365 | |
366 | - return stat; |
367 | + *capacity = 1 + be32_to_cpu(capbuf.lba); |
368 | + *sectors_per_frame = be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS; |
369 | + return 0; |
370 | } |
371 | |
372 | static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, |
373 | diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c |
374 | index c2095ce..0094af2 100644 |
375 | --- a/drivers/net/ixgbe/ixgbe_main.c |
376 | +++ b/drivers/net/ixgbe/ixgbe_main.c |
377 | @@ -70,8 +70,6 @@ static struct pci_device_id ixgbe_pci_tbl[] = { |
378 | board_82598 }, |
379 | {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT), |
380 | board_82598 }, |
381 | - {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT_DUAL_PORT), |
382 | - board_82598 }, |
383 | {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4), |
384 | board_82598 }, |
385 | |
386 | diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c |
387 | index bef967c..c3ded21 100644 |
388 | --- a/drivers/net/wireless/ath5k/base.c |
389 | +++ b/drivers/net/wireless/ath5k/base.c |
390 | @@ -484,9 +484,6 @@ ath5k_pci_probe(struct pci_dev *pdev, |
391 | /* Set private data */ |
392 | pci_set_drvdata(pdev, hw); |
393 | |
394 | - /* Enable msi for devices that support it */ |
395 | - pci_enable_msi(pdev); |
396 | - |
397 | /* Setup interrupt handler */ |
398 | ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); |
399 | if (ret) { |
400 | @@ -553,7 +550,6 @@ err_ah: |
401 | err_irq: |
402 | free_irq(pdev->irq, sc); |
403 | err_free: |
404 | - pci_disable_msi(pdev); |
405 | ieee80211_free_hw(hw); |
406 | err_map: |
407 | pci_iounmap(pdev, mem); |
408 | @@ -575,7 +571,6 @@ ath5k_pci_remove(struct pci_dev *pdev) |
409 | ath5k_detach(pdev, hw); |
410 | ath5k_hw_detach(sc->ah); |
411 | free_irq(pdev->irq, sc); |
412 | - pci_disable_msi(pdev); |
413 | pci_iounmap(pdev, sc->iobase); |
414 | pci_release_region(pdev, 0); |
415 | pci_disable_device(pdev); |
416 | diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c |
417 | index 531aeb2..572436c 100644 |
418 | --- a/drivers/net/wireless/b43legacy/main.c |
419 | +++ b/drivers/net/wireless/b43legacy/main.c |
420 | @@ -3792,10 +3792,10 @@ static int b43legacy_resume(struct ssb_device *dev) |
421 | goto out; |
422 | } |
423 | } |
424 | - mutex_unlock(&wl->mutex); |
425 | |
426 | b43legacydbg(wl, "Device resumed.\n"); |
427 | out: |
428 | + mutex_unlock(&wl->mutex); |
429 | return err; |
430 | } |
431 | |
432 | diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c |
433 | index 9072946..f200661 100644 |
434 | --- a/drivers/spi/mpc52xx_psc_spi.c |
435 | +++ b/drivers/spi/mpc52xx_psc_spi.c |
436 | @@ -148,7 +148,6 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi, |
437 | unsigned rfalarm; |
438 | unsigned send_at_once = MPC52xx_PSC_BUFSIZE; |
439 | unsigned recv_at_once; |
440 | - unsigned bpw = mps->bits_per_word / 8; |
441 | |
442 | if (!t->tx_buf && !t->rx_buf && t->len) |
443 | return -EINVAL; |
444 | @@ -164,22 +163,15 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi, |
445 | } |
446 | |
447 | dev_dbg(&spi->dev, "send %d bytes...\n", send_at_once); |
448 | - if (tx_buf) { |
449 | - for (; send_at_once; sb++, send_at_once--) { |
450 | - /* set EOF flag */ |
451 | - if (mps->bits_per_word |
452 | - && (sb + 1) % bpw == 0) |
453 | - out_8(&psc->ircr2, 0x01); |
454 | + for (; send_at_once; sb++, send_at_once--) { |
455 | + /* set EOF flag before the last word is sent */ |
456 | + if (send_at_once == 1) |
457 | + out_8(&psc->ircr2, 0x01); |
458 | + |
459 | + if (tx_buf) |
460 | out_8(&psc->mpc52xx_psc_buffer_8, tx_buf[sb]); |
461 | - } |
462 | - } else { |
463 | - for (; send_at_once; sb++, send_at_once--) { |
464 | - /* set EOF flag */ |
465 | - if (mps->bits_per_word |
466 | - && ((sb + 1) % bpw) == 0) |
467 | - out_8(&psc->ircr2, 0x01); |
468 | + else |
469 | out_8(&psc->mpc52xx_psc_buffer_8, 0); |
470 | - } |
471 | } |
472 | |
473 | |
474 | diff --git a/fs/dquot.c b/fs/dquot.c |
475 | index 41b9dbd..d93f99b 100644 |
476 | --- a/fs/dquot.c |
477 | +++ b/fs/dquot.c |
478 | @@ -554,6 +554,8 @@ static struct shrinker dqcache_shrinker = { |
479 | */ |
480 | static void dqput(struct dquot *dquot) |
481 | { |
482 | + int ret; |
483 | + |
484 | if (!dquot) |
485 | return; |
486 | #ifdef __DQUOT_PARANOIA |
487 | @@ -586,7 +588,19 @@ we_slept: |
488 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) { |
489 | spin_unlock(&dq_list_lock); |
490 | /* Commit dquot before releasing */ |
491 | - dquot->dq_sb->dq_op->write_dquot(dquot); |
492 | + ret = dquot->dq_sb->dq_op->write_dquot(dquot); |
493 | + if (ret < 0) { |
494 | + printk(KERN_ERR "VFS: cannot write quota structure on " |
495 | + "device %s (error %d). Quota may get out of " |
496 | + "sync!\n", dquot->dq_sb->s_id, ret); |
497 | + /* |
498 | + * We clear dirty bit anyway, so that we avoid |
499 | + * infinite loop here |
500 | + */ |
501 | + spin_lock(&dq_list_lock); |
502 | + clear_dquot_dirty(dquot); |
503 | + spin_unlock(&dq_list_lock); |
504 | + } |
505 | goto we_slept; |
506 | } |
507 | /* Clear flag in case dquot was inactive (something bad happened) */ |
508 | diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c |
509 | index 086b312..f144834 100644 |
510 | --- a/fs/ecryptfs/crypto.c |
511 | +++ b/fs/ecryptfs/crypto.c |
512 | @@ -474,8 +474,8 @@ int ecryptfs_encrypt_page(struct page *page) |
513 | { |
514 | struct inode *ecryptfs_inode; |
515 | struct ecryptfs_crypt_stat *crypt_stat; |
516 | - char *enc_extent_virt = NULL; |
517 | - struct page *enc_extent_page; |
518 | + char *enc_extent_virt; |
519 | + struct page *enc_extent_page = NULL; |
520 | loff_t extent_offset; |
521 | int rc = 0; |
522 | |
523 | @@ -491,14 +491,14 @@ int ecryptfs_encrypt_page(struct page *page) |
524 | page->index); |
525 | goto out; |
526 | } |
527 | - enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER); |
528 | - if (!enc_extent_virt) { |
529 | + enc_extent_page = alloc_page(GFP_USER); |
530 | + if (!enc_extent_page) { |
531 | rc = -ENOMEM; |
532 | ecryptfs_printk(KERN_ERR, "Error allocating memory for " |
533 | "encrypted extent\n"); |
534 | goto out; |
535 | } |
536 | - enc_extent_page = virt_to_page(enc_extent_virt); |
537 | + enc_extent_virt = kmap(enc_extent_page); |
538 | for (extent_offset = 0; |
539 | extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size); |
540 | extent_offset++) { |
541 | @@ -526,7 +526,10 @@ int ecryptfs_encrypt_page(struct page *page) |
542 | } |
543 | } |
544 | out: |
545 | - kfree(enc_extent_virt); |
546 | + if (enc_extent_page) { |
547 | + kunmap(enc_extent_page); |
548 | + __free_page(enc_extent_page); |
549 | + } |
550 | return rc; |
551 | } |
552 | |
553 | @@ -608,8 +611,8 @@ int ecryptfs_decrypt_page(struct page *page) |
554 | { |
555 | struct inode *ecryptfs_inode; |
556 | struct ecryptfs_crypt_stat *crypt_stat; |
557 | - char *enc_extent_virt = NULL; |
558 | - struct page *enc_extent_page; |
559 | + char *enc_extent_virt; |
560 | + struct page *enc_extent_page = NULL; |
561 | unsigned long extent_offset; |
562 | int rc = 0; |
563 | |
564 | @@ -626,14 +629,14 @@ int ecryptfs_decrypt_page(struct page *page) |
565 | page->index); |
566 | goto out; |
567 | } |
568 | - enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER); |
569 | - if (!enc_extent_virt) { |
570 | + enc_extent_page = alloc_page(GFP_USER); |
571 | + if (!enc_extent_page) { |
572 | rc = -ENOMEM; |
573 | ecryptfs_printk(KERN_ERR, "Error allocating memory for " |
574 | "encrypted extent\n"); |
575 | goto out; |
576 | } |
577 | - enc_extent_page = virt_to_page(enc_extent_virt); |
578 | + enc_extent_virt = kmap(enc_extent_page); |
579 | for (extent_offset = 0; |
580 | extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size); |
581 | extent_offset++) { |
582 | @@ -661,7 +664,10 @@ int ecryptfs_decrypt_page(struct page *page) |
583 | } |
584 | } |
585 | out: |
586 | - kfree(enc_extent_virt); |
587 | + if (enc_extent_page) { |
588 | + kunmap(enc_extent_page); |
589 | + __free_page(enc_extent_page); |
590 | + } |
591 | return rc; |
592 | } |
593 | |
594 | diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c |
595 | index 6bd48f0..c2fb2dd 100644 |
596 | --- a/fs/isofs/rock.c |
597 | +++ b/fs/isofs/rock.c |
598 | @@ -209,6 +209,11 @@ repeat: |
599 | |
600 | while (rs.len > 2) { /* There may be one byte for padding somewhere */ |
601 | rr = (struct rock_ridge *)rs.chr; |
602 | + /* |
603 | + * Ignore rock ridge info if rr->len is out of range, but |
604 | + * don't return -EIO because that would make the file |
605 | + * invisible. |
606 | + */ |
607 | if (rr->len < 3) |
608 | goto out; /* Something got screwed up here */ |
609 | sig = isonum_721(rs.chr); |
610 | @@ -216,8 +221,12 @@ repeat: |
611 | goto eio; |
612 | rs.chr += rr->len; |
613 | rs.len -= rr->len; |
614 | + /* |
615 | + * As above, just ignore the rock ridge info if rr->len |
616 | + * is bogus. |
617 | + */ |
618 | if (rs.len < 0) |
619 | - goto eio; /* corrupted isofs */ |
620 | + goto out; /* Something got screwed up here */ |
621 | |
622 | switch (sig) { |
623 | case SIG('R', 'R'): |
624 | @@ -307,6 +316,11 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, |
625 | repeat: |
626 | while (rs.len > 2) { /* There may be one byte for padding somewhere */ |
627 | rr = (struct rock_ridge *)rs.chr; |
628 | + /* |
629 | + * Ignore rock ridge info if rr->len is out of range, but |
630 | + * don't return -EIO because that would make the file |
631 | + * invisible. |
632 | + */ |
633 | if (rr->len < 3) |
634 | goto out; /* Something got screwed up here */ |
635 | sig = isonum_721(rs.chr); |
636 | @@ -314,8 +328,12 @@ repeat: |
637 | goto eio; |
638 | rs.chr += rr->len; |
639 | rs.len -= rr->len; |
640 | + /* |
641 | + * As above, just ignore the rock ridge info if rr->len |
642 | + * is bogus. |
643 | + */ |
644 | if (rs.len < 0) |
645 | - goto eio; /* corrupted isofs */ |
646 | + goto out; /* Something got screwed up here */ |
647 | |
648 | switch (sig) { |
649 | #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ |
650 | diff --git a/fs/libfs.c b/fs/libfs.c |
651 | index b004dfa..7c588dc 100644 |
652 | --- a/fs/libfs.c |
653 | +++ b/fs/libfs.c |
654 | @@ -216,8 +216,8 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name, |
655 | |
656 | s->s_flags = MS_NOUSER; |
657 | s->s_maxbytes = ~0ULL; |
658 | - s->s_blocksize = 1024; |
659 | - s->s_blocksize_bits = 10; |
660 | + s->s_blocksize = PAGE_SIZE; |
661 | + s->s_blocksize_bits = PAGE_SHIFT; |
662 | s->s_magic = magic; |
663 | s->s_op = ops ? ops : &simple_super_operations; |
664 | s->s_time_gran = 1; |
665 | diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h |
666 | index 5c60bfc..9a1db20 100644 |
667 | --- a/include/asm-arm/bitops.h |
668 | +++ b/include/asm-arm/bitops.h |
669 | @@ -277,9 +277,16 @@ static inline int constant_fls(int x) |
670 | * the clz instruction for much better code efficiency. |
671 | */ |
672 | |
673 | -#define fls(x) \ |
674 | +#define __fls(x) \ |
675 | ( __builtin_constant_p(x) ? constant_fls(x) : \ |
676 | ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) ) |
677 | + |
678 | +/* Implement fls() in C so that 64-bit args are suitably truncated */ |
679 | +static inline int fls(int x) |
680 | +{ |
681 | + return __fls(x); |
682 | +} |
683 | + |
684 | #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) |
685 | #define __ffs(x) (ffs(x) - 1) |
686 | #define ffz(x) __ffs( ~(x) ) |
687 | diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h |
688 | index f054778..5a544bf 100644 |
689 | --- a/include/asm-generic/vmlinux.lds.h |
690 | +++ b/include/asm-generic/vmlinux.lds.h |
691 | @@ -204,6 +204,7 @@ |
692 | * during second ld run in second ld pass when generating System.map */ |
693 | #define TEXT_TEXT \ |
694 | ALIGN_FUNCTION(); \ |
695 | + *(.text.hot) \ |
696 | *(.text) \ |
697 | *(.ref.text) \ |
698 | *(.text.init.refok) \ |
699 | @@ -213,7 +214,8 @@ |
700 | CPU_KEEP(init.text) \ |
701 | CPU_KEEP(exit.text) \ |
702 | MEM_KEEP(init.text) \ |
703 | - MEM_KEEP(exit.text) |
704 | + MEM_KEEP(exit.text) \ |
705 | + *(.text.unlikely) |
706 | |
707 | |
708 | /* sched.text is aling to function alignment to secure we have same |
709 | diff --git a/include/asm-powerpc/pgtable-ppc64.h b/include/asm-powerpc/pgtable-ppc64.h |
710 | index dd4c26d..8e35c28 100644 |
711 | --- a/include/asm-powerpc/pgtable-ppc64.h |
712 | +++ b/include/asm-powerpc/pgtable-ppc64.h |
713 | @@ -311,6 +311,17 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, |
714 | old = pte_update(mm, addr, ptep, _PAGE_RW, 0); |
715 | } |
716 | |
717 | +#define __HAVE_ARCH_HUGE_PTEP_SET_WRPROTECT |
718 | +static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, |
719 | + unsigned long addr, pte_t *ptep) |
720 | +{ |
721 | + unsigned long old; |
722 | + |
723 | + if ((pte_val(*ptep) & _PAGE_RW) == 0) |
724 | + return; |
725 | + old = pte_update(mm, addr, ptep, _PAGE_RW, 1); |
726 | +} |
727 | + |
728 | /* |
729 | * We currently remove entries from the hashtable regardless of whether |
730 | * the entry was young or dirty. The generic routines only flush if the |
731 | diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h |
732 | index c299b85..56fe3b9 100644 |
733 | --- a/include/asm-sparc64/io.h |
734 | +++ b/include/asm-sparc64/io.h |
735 | @@ -16,7 +16,6 @@ |
736 | /* BIO layer definitions. */ |
737 | extern unsigned long kern_base, kern_size; |
738 | #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) |
739 | -#define BIO_VMERGE_BOUNDARY 8192 |
740 | |
741 | static inline u8 _inb(unsigned long addr) |
742 | { |
743 | diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h |
744 | index ddd8652..87b0e07 100644 |
745 | --- a/include/linux/cpufreq.h |
746 | +++ b/include/linux/cpufreq.h |
747 | @@ -108,6 +108,7 @@ struct cpufreq_policy { |
748 | #define CPUFREQ_ADJUST (0) |
749 | #define CPUFREQ_INCOMPATIBLE (1) |
750 | #define CPUFREQ_NOTIFY (2) |
751 | +#define CPUFREQ_START (3) |
752 | |
753 | #define CPUFREQ_SHARED_TYPE_NONE (0) /* None */ |
754 | #define CPUFREQ_SHARED_TYPE_HW (1) /* HW does needed coordination */ |
755 | diff --git a/kernel/marker.c b/kernel/marker.c |
756 | index 005b959..54ce00f 100644 |
757 | --- a/kernel/marker.c |
758 | +++ b/kernel/marker.c |
759 | @@ -126,6 +126,11 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, |
760 | struct marker_probe_closure *multi; |
761 | int i; |
762 | /* |
763 | + * Read mdata->ptype before mdata->multi. |
764 | + */ |
765 | + smp_rmb(); |
766 | + multi = mdata->multi; |
767 | + /* |
768 | * multi points to an array, therefore accessing the array |
769 | * depends on reading multi. However, even in this case, |
770 | * we must insure that the pointer is read _before_ the array |
771 | @@ -133,7 +138,6 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, |
772 | * in the fast path, so put the explicit barrier here. |
773 | */ |
774 | smp_read_barrier_depends(); |
775 | - multi = mdata->multi; |
776 | for (i = 0; multi[i].func; i++) { |
777 | va_start(args, fmt); |
778 | multi[i].func(multi[i].probe_private, call_private, fmt, |
779 | @@ -176,6 +180,11 @@ void marker_probe_cb_noarg(const struct marker *mdata, |
780 | struct marker_probe_closure *multi; |
781 | int i; |
782 | /* |
783 | + * Read mdata->ptype before mdata->multi. |
784 | + */ |
785 | + smp_rmb(); |
786 | + multi = mdata->multi; |
787 | + /* |
788 | * multi points to an array, therefore accessing the array |
789 | * depends on reading multi. However, even in this case, |
790 | * we must insure that the pointer is read _before_ the array |
791 | @@ -183,7 +192,6 @@ void marker_probe_cb_noarg(const struct marker *mdata, |
792 | * in the fast path, so put the explicit barrier here. |
793 | */ |
794 | smp_read_barrier_depends(); |
795 | - multi = mdata->multi; |
796 | for (i = 0; multi[i].func; i++) |
797 | multi[i].func(multi[i].probe_private, call_private, fmt, |
798 | &args); |
799 | diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c |
800 | index 5b9b467..0fea0ee 100644 |
801 | --- a/kernel/sys_ni.c |
802 | +++ b/kernel/sys_ni.c |
803 | @@ -59,6 +59,7 @@ cond_syscall(sys_epoll_create); |
804 | cond_syscall(sys_epoll_ctl); |
805 | cond_syscall(sys_epoll_wait); |
806 | cond_syscall(sys_epoll_pwait); |
807 | +cond_syscall(compat_sys_epoll_pwait); |
808 | cond_syscall(sys_semget); |
809 | cond_syscall(sys_semop); |
810 | cond_syscall(sys_semtimedop); |
811 | diff --git a/mm/filemap.c b/mm/filemap.c |
812 | index 07e9d92..703f2c8 100644 |
813 | --- a/mm/filemap.c |
814 | +++ b/mm/filemap.c |
815 | @@ -1771,7 +1771,7 @@ void iov_iter_advance(struct iov_iter *i, size_t bytes) |
816 | * The !iov->iov_len check ensures we skip over unlikely |
817 | * zero-length segments (without overruning the iovec). |
818 | */ |
819 | - while (bytes || unlikely(!iov->iov_len && i->count)) { |
820 | + while (bytes || unlikely(i->count && !iov->iov_len)) { |
821 | int copy; |
822 | |
823 | copy = min(bytes, iov->iov_len - base); |
824 | diff --git a/mm/hugetlb.c b/mm/hugetlb.c |
825 | index 51c9e2c..893558a 100644 |
826 | --- a/mm/hugetlb.c |
827 | +++ b/mm/hugetlb.c |
828 | @@ -738,6 +738,10 @@ static void set_huge_ptep_writable(struct vm_area_struct *vma, |
829 | } |
830 | |
831 | |
832 | +#ifndef __HAVE_ARCH_HUGE_PTEP_SET_WRPROTECT |
833 | +#define huge_ptep_set_wrprotect ptep_set_wrprotect |
834 | +#endif |
835 | + |
836 | int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, |
837 | struct vm_area_struct *vma) |
838 | { |
839 | @@ -764,7 +768,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, |
840 | spin_lock(&src->page_table_lock); |
841 | if (!pte_none(*src_pte)) { |
842 | if (cow) |
843 | - ptep_set_wrprotect(src, addr, src_pte); |
844 | + huge_ptep_set_wrprotect(src, addr, src_pte); |
845 | entry = *src_pte; |
846 | ptepage = pte_page(entry); |
847 | get_page(ptepage); |
848 | diff --git a/mm/shmem.c b/mm/shmem.c |
849 | index f514dd3..ba3667f 100644 |
850 | --- a/mm/shmem.c |
851 | +++ b/mm/shmem.c |
852 | @@ -1559,7 +1559,6 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev) |
853 | inode->i_uid = current->fsuid; |
854 | inode->i_gid = current->fsgid; |
855 | inode->i_blocks = 0; |
856 | - inode->i_mapping->a_ops = &shmem_aops; |
857 | inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; |
858 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
859 | inode->i_generation = get_seconds(); |
860 | @@ -1574,6 +1573,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev) |
861 | init_special_inode(inode, mode, dev); |
862 | break; |
863 | case S_IFREG: |
864 | + inode->i_mapping->a_ops = &shmem_aops; |
865 | inode->i_op = &shmem_inode_operations; |
866 | inode->i_fop = &shmem_file_operations; |
867 | mpol_shared_policy_init(&info->policy, sbinfo->policy, |
868 | @@ -1964,6 +1964,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s |
869 | return error; |
870 | } |
871 | unlock_page(page); |
872 | + inode->i_mapping->a_ops = &shmem_aops; |
873 | inode->i_op = &shmem_symlink_inode_operations; |
874 | kaddr = kmap_atomic(page, KM_USER0); |
875 | memcpy(kaddr, symname, len); |
876 | diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c |
877 | index 3180963..25f0f0b 100644 |
878 | --- a/net/ipv4/tcp_input.c |
879 | +++ b/net/ipv4/tcp_input.c |
880 | @@ -3259,6 +3259,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) |
881 | * log. Something worked... |
882 | */ |
883 | sk->sk_err_soft = 0; |
884 | + icsk->icsk_probes_out = 0; |
885 | tp->rcv_tstamp = tcp_time_stamp; |
886 | prior_packets = tp->packets_out; |
887 | if (!prior_packets) |
888 | @@ -3291,8 +3292,6 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) |
889 | return 1; |
890 | |
891 | no_queue: |
892 | - icsk->icsk_probes_out = 0; |
893 | - |
894 | /* If this ack opens up a zero window, clear backoff. It was |
895 | * being used to time the probes, and is probably far higher than |
896 | * it needs to be for normal retransmission. |
897 | diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c |
898 | index fc43e22..3ddf1c0 100644 |
899 | --- a/net/netfilter/nf_conntrack_proto_tcp.c |
900 | +++ b/net/netfilter/nf_conntrack_proto_tcp.c |
901 | @@ -845,9 +845,15 @@ static int tcp_packet(struct nf_conn *ct, |
902 | /* Attempt to reopen a closed/aborted connection. |
903 | * Delete this connection and look up again. */ |
904 | write_unlock_bh(&tcp_lock); |
905 | - if (del_timer(&ct->timeout)) |
906 | + /* Only repeat if we can actually remove the timer. |
907 | + * Destruction may already be in progress in process |
908 | + * context and we must give it a chance to terminate. |
909 | + */ |
910 | + if (del_timer(&ct->timeout)) { |
911 | ct->timeout.function((unsigned long)ct); |
912 | - return -NF_REPEAT; |
913 | + return -NF_REPEAT; |
914 | + } |
915 | + return -NF_DROP; |
916 | } |
917 | /* Fall through */ |
918 | case TCP_CONNTRACK_IGNORE: |
919 | diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost |
920 | index 2d20640..af21ea9 100644 |
921 | --- a/scripts/Makefile.modpost |
922 | +++ b/scripts/Makefile.modpost |
923 | @@ -87,6 +87,7 @@ quiet_cmd_kernel-mod = MODPOST $@ |
924 | cmd_kernel-mod = $(modpost) $@ |
925 | |
926 | vmlinux.o: FORCE |
927 | + @rm -fr $(kernelmarkersfile) |
928 | $(call cmd,kernel-mod) |
929 | |
930 | # Declare generated files as targets for modpost |
931 | diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c |
932 | index 110cf24..7b16b36 100644 |
933 | --- a/scripts/mod/modpost.c |
934 | +++ b/scripts/mod/modpost.c |
935 | @@ -1973,7 +1973,8 @@ static void read_markers(const char *fname) |
936 | mod->skip = 1; |
937 | } |
938 | |
939 | - add_marker(mod, marker, fmt); |
940 | + if (!mod->skip) |
941 | + add_marker(mod, marker, fmt); |
942 | } |
943 | return; |
944 | fail: |
945 | diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c |
946 | index 52a7f0f..37f274f 100644 |
947 | --- a/sound/pci/hda/patch_realtek.c |
948 | +++ b/sound/pci/hda/patch_realtek.c |
949 | @@ -8517,6 +8517,7 @@ static struct hda_verb alc262_sony_unsol_verbs[] = { |
950 | |
951 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
952 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
953 | + {} |
954 | }; |
955 | |
956 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
957 | diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c |
958 | index 71138ff..a9b40a1 100644 |
959 | --- a/sound/pci/trident/trident_main.c |
960 | +++ b/sound/pci/trident/trident_main.c |
961 | @@ -1590,7 +1590,10 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream, |
962 | if (spdif_flag) { |
963 | if (trident->device != TRIDENT_DEVICE_ID_SI7018) { |
964 | outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS)); |
965 | - outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); |
966 | + val = trident->spdif_pcm_ctrl; |
967 | + if (!go) |
968 | + val &= ~(0x28); |
969 | + outb(val, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); |
970 | } else { |
971 | outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS)); |
972 | val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN; |