Contents of /trunk/kernel26-magellan/patches-2.6.25-r5/0114-2.6.25.15-all-fixes.patch
Parent Directory | Revision Log
Revision 677 -
(show annotations)
(download)
Wed Sep 10 21:27:27 2008 UTC (16 years ago) by niro
File size: 51825 byte(s)
Wed Sep 10 21:27:27 2008 UTC (16 years ago) by niro
File size: 51825 byte(s)
2.6.25-magellan-r5: - updated to linux-2.6.25.17
1 | diff --git a/arch/powerpc/kernel/ppc32.h b/arch/powerpc/kernel/ppc32.h |
2 | index 90e5627..fda05e2 100644 |
3 | --- a/arch/powerpc/kernel/ppc32.h |
4 | +++ b/arch/powerpc/kernel/ppc32.h |
5 | @@ -135,4 +135,6 @@ struct ucontext32 { |
6 | struct mcontext32 uc_mcontext; |
7 | }; |
8 | |
9 | +extern int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s); |
10 | + |
11 | #endif /* _PPC64_PPC32_H */ |
12 | diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c |
13 | index 4c1de6a..9d30e10 100644 |
14 | --- a/arch/powerpc/kernel/ptrace32.c |
15 | +++ b/arch/powerpc/kernel/ptrace32.c |
16 | @@ -29,12 +29,15 @@ |
17 | #include <linux/security.h> |
18 | #include <linux/signal.h> |
19 | #include <linux/compat.h> |
20 | +#include <linux/elf.h> |
21 | |
22 | #include <asm/uaccess.h> |
23 | #include <asm/page.h> |
24 | #include <asm/pgtable.h> |
25 | #include <asm/system.h> |
26 | |
27 | +#include "ppc32.h" |
28 | + |
29 | /* |
30 | * does not yet catch signals sent when the child dies. |
31 | * in exit.c or in signal.c. |
32 | @@ -64,6 +67,27 @@ static long compat_ptrace_old(struct task_struct *child, long request, |
33 | return -EPERM; |
34 | } |
35 | |
36 | +static int compat_ptrace_getsiginfo(struct task_struct *child, compat_siginfo_t __user *data) |
37 | +{ |
38 | + siginfo_t lastinfo; |
39 | + int error = -ESRCH; |
40 | + |
41 | + read_lock(&tasklist_lock); |
42 | + if (likely(child->sighand != NULL)) { |
43 | + error = -EINVAL; |
44 | + spin_lock_irq(&child->sighand->siglock); |
45 | + if (likely(child->last_siginfo != NULL)) { |
46 | + lastinfo = *child->last_siginfo; |
47 | + error = 0; |
48 | + } |
49 | + spin_unlock_irq(&child->sighand->siglock); |
50 | + } |
51 | + read_unlock(&tasklist_lock); |
52 | + if (!error) |
53 | + return copy_siginfo_to_user32(data, &lastinfo); |
54 | + return error; |
55 | +} |
56 | + |
57 | long compat_arch_ptrace(struct task_struct *child, compat_long_t request, |
58 | compat_ulong_t caddr, compat_ulong_t cdata) |
59 | { |
60 | @@ -282,6 +306,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, |
61 | 0, PT_REGS_COUNT * sizeof(compat_long_t), |
62 | compat_ptr(data)); |
63 | |
64 | + case PTRACE_GETSIGINFO: |
65 | + return compat_ptrace_getsiginfo(child, compat_ptr(data)); |
66 | + |
67 | case PTRACE_GETFPREGS: |
68 | case PTRACE_SETFPREGS: |
69 | case PTRACE_GETVRREGS: |
70 | diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c |
71 | index 794895c..f96b2e4 100644 |
72 | --- a/arch/x86/mm/ioremap.c |
73 | +++ b/arch/x86/mm/ioremap.c |
74 | @@ -39,7 +39,7 @@ EXPORT_SYMBOL(__phys_addr); |
75 | |
76 | int page_is_ram(unsigned long pagenr) |
77 | { |
78 | - unsigned long addr, end; |
79 | + resource_size_t addr, end; |
80 | int i; |
81 | |
82 | /* |
83 | @@ -109,7 +109,8 @@ static int ioremap_change_attr(unsigned long vaddr, unsigned long size, |
84 | static void __iomem *__ioremap(resource_size_t phys_addr, unsigned long size, |
85 | enum ioremap_mode mode) |
86 | { |
87 | - unsigned long pfn, offset, last_addr, vaddr; |
88 | + unsigned long pfn, offset, vaddr; |
89 | + resource_size_t last_addr; |
90 | struct vm_struct *area; |
91 | pgprot_t prot; |
92 | |
93 | diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c |
94 | index 1fa8681..a845062 100644 |
95 | --- a/drivers/acpi/bay.c |
96 | +++ b/drivers/acpi/bay.c |
97 | @@ -299,16 +299,20 @@ static int bay_add(acpi_handle handle, int id) |
98 | */ |
99 | pdev->dev.uevent_suppress = 0; |
100 | |
101 | - if (acpi_bay_add_fs(new_bay)) { |
102 | - platform_device_unregister(new_bay->pdev); |
103 | - goto bay_add_err; |
104 | - } |
105 | - |
106 | /* register for events on this device */ |
107 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, |
108 | bay_notify, new_bay); |
109 | if (ACPI_FAILURE(status)) { |
110 | - printk(KERN_ERR PREFIX "Error installing bay notify handler\n"); |
111 | + printk(KERN_INFO PREFIX "Error installing bay notify handler\n"); |
112 | + platform_device_unregister(new_bay->pdev); |
113 | + goto bay_add_err; |
114 | + } |
115 | + |
116 | + if (acpi_bay_add_fs(new_bay)) { |
117 | + acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, |
118 | + bay_notify); |
119 | + platform_device_unregister(new_bay->pdev); |
120 | + goto bay_add_err; |
121 | } |
122 | |
123 | /* if we are on a dock station, we should register for dock |
124 | diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c |
125 | index 1bcecc7..a32aed9 100644 |
126 | --- a/drivers/acpi/thermal.c |
127 | +++ b/drivers/acpi/thermal.c |
128 | @@ -359,10 +359,17 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) |
129 | if (flag & ACPI_TRIPS_CRITICAL) { |
130 | status = acpi_evaluate_integer(tz->device->handle, |
131 | "_CRT", NULL, &tz->trips.critical.temperature); |
132 | - if (ACPI_FAILURE(status)) { |
133 | + /* |
134 | + * Treat freezing temperatures as invalid as well; some |
135 | + * BIOSes return really low values and cause reboots at startup. |
136 | + * Below zero (Celcius) values clearly aren't right for sure.. |
137 | + * ... so lets discard those as invalid. |
138 | + */ |
139 | + if (ACPI_FAILURE(status) || |
140 | + tz->trips.critical.temperature <= 2732) { |
141 | tz->trips.critical.flags.valid = 0; |
142 | ACPI_EXCEPTION((AE_INFO, status, |
143 | - "No critical threshold")); |
144 | + "No or invalid critical threshold")); |
145 | return -ENODEV; |
146 | } else { |
147 | tz->trips.critical.flags.valid = 1; |
148 | @@ -884,10 +891,15 @@ static void acpi_thermal_check(void *data) |
149 | static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf) |
150 | { |
151 | struct acpi_thermal *tz = thermal->devdata; |
152 | + int result; |
153 | |
154 | if (!tz) |
155 | return -EINVAL; |
156 | |
157 | + result = acpi_thermal_get_temperature(tz); |
158 | + if (result) |
159 | + return result; |
160 | + |
161 | return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature)); |
162 | } |
163 | |
164 | diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c |
165 | index 8dd3942..ce6fdec 100644 |
166 | --- a/drivers/input/mouse/appletouch.c |
167 | +++ b/drivers/input/mouse/appletouch.c |
168 | @@ -589,6 +589,21 @@ static void atp_close(struct input_dev *input) |
169 | dev->open = 0; |
170 | } |
171 | |
172 | +static int atp_handle_geyser(struct atp *dev) |
173 | +{ |
174 | + struct usb_device *udev = dev->udev; |
175 | + |
176 | + if (!atp_is_fountain(dev)) { |
177 | + /* switch to raw sensor mode */ |
178 | + if (atp_geyser_init(udev)) |
179 | + return -EIO; |
180 | + |
181 | + printk(KERN_INFO "appletouch: Geyser mode initialized.\n"); |
182 | + } |
183 | + |
184 | + return 0; |
185 | +} |
186 | + |
187 | static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id) |
188 | { |
189 | struct atp *dev; |
190 | @@ -633,14 +648,6 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id |
191 | else |
192 | dev->datalen = 81; |
193 | |
194 | - if (!atp_is_fountain(dev)) { |
195 | - /* switch to raw sensor mode */ |
196 | - if (atp_geyser_init(udev)) |
197 | - goto err_free_devs; |
198 | - |
199 | - printk(KERN_INFO "appletouch: Geyser mode initialized.\n"); |
200 | - } |
201 | - |
202 | dev->urb = usb_alloc_urb(0, GFP_KERNEL); |
203 | if (!dev->urb) |
204 | goto err_free_devs; |
205 | @@ -654,6 +661,10 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id |
206 | usb_rcvintpipe(udev, int_in_endpointAddr), |
207 | dev->data, dev->datalen, atp_complete, dev, 1); |
208 | |
209 | + error = atp_handle_geyser(dev); |
210 | + if (error) |
211 | + goto err_free_buffer; |
212 | + |
213 | usb_make_path(udev, dev->phys, sizeof(dev->phys)); |
214 | strlcat(dev->phys, "/input0", sizeof(dev->phys)); |
215 | |
216 | @@ -744,6 +755,20 @@ static void atp_disconnect(struct usb_interface *iface) |
217 | printk(KERN_INFO "input: appletouch disconnected\n"); |
218 | } |
219 | |
220 | +static int atp_recover(struct atp *dev) |
221 | +{ |
222 | + int error; |
223 | + |
224 | + error = atp_handle_geyser(dev); |
225 | + if (error) |
226 | + return error; |
227 | + |
228 | + if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC)) |
229 | + return -EIO; |
230 | + |
231 | + return 0; |
232 | +} |
233 | + |
234 | static int atp_suspend(struct usb_interface *iface, pm_message_t message) |
235 | { |
236 | struct atp *dev = usb_get_intfdata(iface); |
237 | @@ -764,12 +789,20 @@ static int atp_resume(struct usb_interface *iface) |
238 | return 0; |
239 | } |
240 | |
241 | +static int atp_reset_resume(struct usb_interface *iface) |
242 | +{ |
243 | + struct atp *dev = usb_get_intfdata(iface); |
244 | + |
245 | + return atp_recover(dev); |
246 | +} |
247 | + |
248 | static struct usb_driver atp_driver = { |
249 | .name = "appletouch", |
250 | .probe = atp_probe, |
251 | .disconnect = atp_disconnect, |
252 | .suspend = atp_suspend, |
253 | .resume = atp_resume, |
254 | + .reset_resume = atp_reset_resume, |
255 | .id_table = atp_table, |
256 | }; |
257 | |
258 | diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h |
259 | index 60931ac..17a3568 100644 |
260 | --- a/drivers/input/serio/i8042-x86ia64io.h |
261 | +++ b/drivers/input/serio/i8042-x86ia64io.h |
262 | @@ -63,7 +63,7 @@ static inline void i8042_write_command(int val) |
263 | outb(val, I8042_COMMAND_REG); |
264 | } |
265 | |
266 | -#if defined(__i386__) || defined(__x86_64__) |
267 | +#ifdef CONFIG_X86 |
268 | |
269 | #include <linux/dmi.h> |
270 | |
271 | @@ -193,6 +193,20 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { |
272 | }, |
273 | }, |
274 | { |
275 | + .ident = "Fujitsu-Siemens Amilo Pro 2030", |
276 | + .matches = { |
277 | + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
278 | + DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), |
279 | + }, |
280 | + }, |
281 | + { |
282 | + .ident = "Fujitsu-Siemens Amilo Pro 2010", |
283 | + .matches = { |
284 | + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
285 | + DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), |
286 | + }, |
287 | + }, |
288 | + { |
289 | /* |
290 | * No data is coming from the touchscreen unless KBC |
291 | * is in legacy mode. |
292 | @@ -284,17 +298,36 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { |
293 | DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), |
294 | }, |
295 | }, |
296 | + { |
297 | + .ident = "Acer Aspire 1360", |
298 | + .matches = { |
299 | + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
300 | + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), |
301 | + }, |
302 | + }, |
303 | { } |
304 | }; |
305 | |
306 | - |
307 | - |
308 | +#ifdef CONFIG_PNP |
309 | +static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { |
310 | + { |
311 | + .ident = "Intel MBO Desktop D845PESV", |
312 | + .matches = { |
313 | + DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), |
314 | + DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), |
315 | + }, |
316 | + }, |
317 | + { |
318 | + .ident = "Gericom Bellagio", |
319 | + .matches = { |
320 | + DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), |
321 | + DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), |
322 | + }, |
323 | + }, |
324 | + { } |
325 | +}; |
326 | #endif |
327 | |
328 | -#ifdef CONFIG_X86 |
329 | - |
330 | -#include <linux/dmi.h> |
331 | - |
332 | /* |
333 | * Some Wistron based laptops need us to explicitly enable the 'Dritek |
334 | * keyboard extension' to make their extra keys start generating scancodes. |
335 | @@ -342,7 +375,6 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = { |
336 | |
337 | #endif /* CONFIG_X86 */ |
338 | |
339 | - |
340 | #ifdef CONFIG_PNP |
341 | #include <linux/pnp.h> |
342 | |
343 | @@ -452,6 +484,11 @@ static int __init i8042_pnp_init(void) |
344 | int pnp_data_busted = 0; |
345 | int err; |
346 | |
347 | +#ifdef CONFIG_X86 |
348 | + if (dmi_check_system(i8042_dmi_nopnp_table)) |
349 | + i8042_nopnp = 1; |
350 | +#endif |
351 | + |
352 | if (i8042_nopnp) { |
353 | printk(KERN_INFO "i8042: PNP detection disabled\n"); |
354 | return 0; |
355 | @@ -577,15 +614,13 @@ static int __init i8042_platform_init(void) |
356 | i8042_reset = 1; |
357 | #endif |
358 | |
359 | -#if defined(__i386__) || defined(__x86_64__) |
360 | +#ifdef CONFIG_X86 |
361 | if (dmi_check_system(i8042_dmi_noloop_table)) |
362 | i8042_noloop = 1; |
363 | |
364 | if (dmi_check_system(i8042_dmi_nomux_table)) |
365 | i8042_nomux = 1; |
366 | -#endif |
367 | |
368 | -#ifdef CONFIG_X86 |
369 | if (dmi_check_system(i8042_dmi_dritek_table)) |
370 | i8042_dritek = 1; |
371 | #endif /* CONFIG_X86 */ |
372 | diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c |
373 | index 65a74cf..f3228ae 100644 |
374 | --- a/drivers/input/serio/i8042.c |
375 | +++ b/drivers/input/serio/i8042.c |
376 | @@ -938,8 +938,12 @@ static int i8042_resume(struct platform_device *dev) |
377 | i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS; |
378 | i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT); |
379 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
380 | - printk(KERN_ERR "i8042: Can't write CTR to resume\n"); |
381 | - return -EIO; |
382 | + printk(KERN_WARNING "i8042: Can't write CTR to resume, retrying...\n"); |
383 | + msleep(50); |
384 | + if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
385 | + printk(KERN_ERR "i8042: CTR write retry failed\n"); |
386 | + return -EIO; |
387 | + } |
388 | } |
389 | |
390 | if (i8042_mux_present) { |
391 | diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c |
392 | index c3ded21..28b52c8 100644 |
393 | --- a/drivers/net/wireless/ath5k/base.c |
394 | +++ b/drivers/net/wireless/ath5k/base.c |
395 | @@ -2864,7 +2864,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
396 | |
397 | switch(key->alg) { |
398 | case ALG_WEP: |
399 | - break; |
400 | + /* XXX: fix hardware encryption, its not working. For now |
401 | + * allow software encryption */ |
402 | + /* break; */ |
403 | case ALG_TKIP: |
404 | case ALG_CCMP: |
405 | return -EOPNOTSUPP; |
406 | diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c |
407 | index e887aa4..8d55044 100644 |
408 | --- a/drivers/pci/quirks.c |
409 | +++ b/drivers/pci/quirks.c |
410 | @@ -1675,6 +1675,7 @@ static void __init quirk_disable_all_msi(struct pci_dev *dev) |
411 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi); |
412 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); |
413 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); |
414 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3336, quirk_disable_all_msi); |
415 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); |
416 | |
417 | /* Disable MSI on chipsets that are known to not support it */ |
418 | diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c |
419 | index 6c9592c..85edf94 100644 |
420 | --- a/drivers/ps3/ps3-lpm.c |
421 | +++ b/drivers/ps3/ps3-lpm.c |
422 | @@ -22,6 +22,7 @@ |
423 | #include <linux/module.h> |
424 | #include <linux/interrupt.h> |
425 | #include <linux/uaccess.h> |
426 | +#include <asm/time.h> |
427 | #include <asm/ps3.h> |
428 | #include <asm/lv1call.h> |
429 | #include <asm/cell-pmu.h> |
430 | diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c |
431 | index 9f04192..2d0ee60 100644 |
432 | --- a/drivers/scsi/megaraid/megaraid_mbox.c |
433 | +++ b/drivers/scsi/megaraid/megaraid_mbox.c |
434 | @@ -3168,6 +3168,23 @@ megaraid_mbox_support_random_del(adapter_t *adapter) |
435 | uint8_t raw_mbox[sizeof(mbox_t)]; |
436 | int rval; |
437 | |
438 | + /* |
439 | + * Newer firmware on Dell CERC expect a different |
440 | + * random deletion handling, so disable it. |
441 | + */ |
442 | + if (adapter->pdev->vendor == PCI_VENDOR_ID_AMI && |
443 | + adapter->pdev->device == PCI_DEVICE_ID_AMI_MEGARAID3 && |
444 | + adapter->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && |
445 | + adapter->pdev->subsystem_device == PCI_SUBSYS_ID_CERC_ATA100_4CH && |
446 | + (adapter->fw_version[0] > '6' || |
447 | + (adapter->fw_version[0] == '6' && |
448 | + adapter->fw_version[2] > '6') || |
449 | + (adapter->fw_version[0] == '6' |
450 | + && adapter->fw_version[2] == '6' |
451 | + && adapter->fw_version[3] > '1'))) { |
452 | + con_log(CL_DLEVEL1, ("megaraid: disable random deletion\n")); |
453 | + return 0; |
454 | + } |
455 | |
456 | mbox = (mbox_t *)raw_mbox; |
457 | |
458 | diff --git a/drivers/scsi/megaraid/megaraid_mbox.h b/drivers/scsi/megaraid/megaraid_mbox.h |
459 | index 626459d..c1d86d9 100644 |
460 | --- a/drivers/scsi/megaraid/megaraid_mbox.h |
461 | +++ b/drivers/scsi/megaraid/megaraid_mbox.h |
462 | @@ -88,6 +88,7 @@ |
463 | #define PCI_SUBSYS_ID_PERC3_QC 0x0471 |
464 | #define PCI_SUBSYS_ID_PERC3_DC 0x0493 |
465 | #define PCI_SUBSYS_ID_PERC3_SC 0x0475 |
466 | +#define PCI_SUBSYS_ID_CERC_ATA100_4CH 0x0511 |
467 | |
468 | |
469 | #define MBOX_MAX_SCSI_CMDS 128 // number of cmds reserved for kernel |
470 | diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c |
471 | index dfc5418..c06d0ea 100644 |
472 | --- a/drivers/usb/core/quirks.c |
473 | +++ b/drivers/usb/core/quirks.c |
474 | @@ -47,6 +47,9 @@ static const struct usb_device_id usb_quirk_list[] = { |
475 | /* Edirol SD-20 */ |
476 | { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, |
477 | |
478 | + /* appletouch */ |
479 | + { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, |
480 | + |
481 | /* M-Systems Flash Disk Pioneers */ |
482 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
483 | |
484 | diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c |
485 | index 4e065e5..fe930d5 100644 |
486 | --- a/drivers/usb/host/ehci-hub.c |
487 | +++ b/drivers/usb/host/ehci-hub.c |
488 | @@ -621,7 +621,7 @@ static int ehci_hub_control ( |
489 | } |
490 | break; |
491 | case USB_PORT_FEAT_C_SUSPEND: |
492 | - /* we auto-clear this feature */ |
493 | + clear_bit(wIndex, &ehci->port_c_suspend); |
494 | break; |
495 | case USB_PORT_FEAT_POWER: |
496 | if (HCS_PPC (ehci->hcs_params)) |
497 | @@ -700,7 +700,7 @@ static int ehci_hub_control ( |
498 | /* resume completed? */ |
499 | else if (time_after_eq(jiffies, |
500 | ehci->reset_done[wIndex])) { |
501 | - status |= 1 << USB_PORT_FEAT_C_SUSPEND; |
502 | + set_bit(wIndex, &ehci->port_c_suspend); |
503 | ehci->reset_done[wIndex] = 0; |
504 | |
505 | /* stop resume signaling */ |
506 | @@ -777,6 +777,8 @@ static int ehci_hub_control ( |
507 | status |= 1 << USB_PORT_FEAT_RESET; |
508 | if (temp & PORT_POWER) |
509 | status |= 1 << USB_PORT_FEAT_POWER; |
510 | + if (test_bit(wIndex, &ehci->port_c_suspend)) |
511 | + status |= 1 << USB_PORT_FEAT_C_SUSPEND; |
512 | |
513 | #ifndef EHCI_VERBOSE_DEBUG |
514 | if (status & ~0xffff) /* only if wPortChange is interesting */ |
515 | diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h |
516 | index 888e81e..4769ba2 100644 |
517 | --- a/drivers/usb/host/ehci.h |
518 | +++ b/drivers/usb/host/ehci.h |
519 | @@ -97,6 +97,8 @@ struct ehci_hcd { /* one per controller */ |
520 | dedicated to the companion controller */ |
521 | unsigned long owned_ports; /* which ports are |
522 | owned by the companion during a bus suspend */ |
523 | + unsigned long port_c_suspend; /* which ports have |
524 | + the change-suspend feature turned on */ |
525 | |
526 | /* per-HC memory pools (could be per-bus, but ...) */ |
527 | struct dma_pool *qh_pool; /* qh per active urb */ |
528 | diff --git a/fs/fat/inode.c b/fs/fat/inode.c |
529 | index 53f3cf6..98f0e87 100644 |
530 | --- a/fs/fat/inode.c |
531 | +++ b/fs/fat/inode.c |
532 | @@ -1208,7 +1208,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, |
533 | */ |
534 | |
535 | media = b->media; |
536 | - if (!FAT_VALID_MEDIA(media)) { |
537 | + if (!fat_valid_media(media)) { |
538 | if (!silent) |
539 | printk(KERN_ERR "FAT: invalid media value (0x%02x)\n", |
540 | media); |
541 | diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c |
542 | index a38c718..cd931ef 100644 |
543 | --- a/fs/jbd/commit.c |
544 | +++ b/fs/jbd/commit.c |
545 | @@ -407,22 +407,6 @@ void journal_commit_transaction(journal_t *journal) |
546 | jbd_debug (3, "JBD: commit phase 2\n"); |
547 | |
548 | /* |
549 | - * First, drop modified flag: all accesses to the buffers |
550 | - * will be tracked for a new trasaction only -bzzz |
551 | - */ |
552 | - spin_lock(&journal->j_list_lock); |
553 | - if (commit_transaction->t_buffers) { |
554 | - new_jh = jh = commit_transaction->t_buffers->b_tnext; |
555 | - do { |
556 | - J_ASSERT_JH(new_jh, new_jh->b_modified == 1 || |
557 | - new_jh->b_modified == 0); |
558 | - new_jh->b_modified = 0; |
559 | - new_jh = new_jh->b_tnext; |
560 | - } while (new_jh != jh); |
561 | - } |
562 | - spin_unlock(&journal->j_list_lock); |
563 | - |
564 | - /* |
565 | * Now start flushing things to disk, in the order they appear |
566 | * on the transaction lists. Data blocks go first. |
567 | */ |
568 | @@ -488,6 +472,9 @@ void journal_commit_transaction(journal_t *journal) |
569 | */ |
570 | commit_transaction->t_state = T_COMMIT; |
571 | |
572 | + J_ASSERT(commit_transaction->t_nr_buffers <= |
573 | + commit_transaction->t_outstanding_credits); |
574 | + |
575 | descriptor = NULL; |
576 | bufs = 0; |
577 | while (commit_transaction->t_buffers) { |
578 | diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c |
579 | index 2c9e8f5..7665e01 100644 |
580 | --- a/fs/jbd/transaction.c |
581 | +++ b/fs/jbd/transaction.c |
582 | @@ -609,6 +609,12 @@ repeat: |
583 | goto done; |
584 | |
585 | /* |
586 | + * this is the first time this transaction is touching this buffer, |
587 | + * reset the modified flag |
588 | + */ |
589 | + jh->b_modified = 0; |
590 | + |
591 | + /* |
592 | * If there is already a copy-out version of this buffer, then we don't |
593 | * need to make another one |
594 | */ |
595 | @@ -820,9 +826,16 @@ int journal_get_create_access(handle_t *handle, struct buffer_head *bh) |
596 | |
597 | if (jh->b_transaction == NULL) { |
598 | jh->b_transaction = transaction; |
599 | + |
600 | + /* first access by this transaction */ |
601 | + jh->b_modified = 0; |
602 | + |
603 | JBUFFER_TRACE(jh, "file as BJ_Reserved"); |
604 | __journal_file_buffer(jh, transaction, BJ_Reserved); |
605 | } else if (jh->b_transaction == journal->j_committing_transaction) { |
606 | + /* first access by this transaction */ |
607 | + jh->b_modified = 0; |
608 | + |
609 | JBUFFER_TRACE(jh, "set next transaction"); |
610 | jh->b_next_transaction = transaction; |
611 | } |
612 | @@ -1222,6 +1235,7 @@ int journal_forget (handle_t *handle, struct buffer_head *bh) |
613 | struct journal_head *jh; |
614 | int drop_reserve = 0; |
615 | int err = 0; |
616 | + int was_modified = 0; |
617 | |
618 | BUFFER_TRACE(bh, "entry"); |
619 | |
620 | @@ -1240,6 +1254,9 @@ int journal_forget (handle_t *handle, struct buffer_head *bh) |
621 | goto not_jbd; |
622 | } |
623 | |
624 | + /* keep track of wether or not this transaction modified us */ |
625 | + was_modified = jh->b_modified; |
626 | + |
627 | /* |
628 | * The buffer's going from the transaction, we must drop |
629 | * all references -bzzz |
630 | @@ -1257,7 +1274,12 @@ int journal_forget (handle_t *handle, struct buffer_head *bh) |
631 | |
632 | JBUFFER_TRACE(jh, "belongs to current transaction: unfile"); |
633 | |
634 | - drop_reserve = 1; |
635 | + /* |
636 | + * we only want to drop a reference if this transaction |
637 | + * modified the buffer |
638 | + */ |
639 | + if (was_modified) |
640 | + drop_reserve = 1; |
641 | |
642 | /* |
643 | * We are no longer going to journal this buffer. |
644 | @@ -1297,7 +1319,13 @@ int journal_forget (handle_t *handle, struct buffer_head *bh) |
645 | if (jh->b_next_transaction) { |
646 | J_ASSERT(jh->b_next_transaction == transaction); |
647 | jh->b_next_transaction = NULL; |
648 | - drop_reserve = 1; |
649 | + |
650 | + /* |
651 | + * only drop a reference if this transaction modified |
652 | + * the buffer |
653 | + */ |
654 | + if (was_modified) |
655 | + drop_reserve = 1; |
656 | } |
657 | } |
658 | |
659 | @@ -1620,12 +1648,42 @@ out: |
660 | return; |
661 | } |
662 | |
663 | +/* |
664 | + * journal_try_to_free_buffers() could race with journal_commit_transaction() |
665 | + * The latter might still hold the a count on buffers when inspecting |
666 | + * them on t_syncdata_list or t_locked_list. |
667 | + * |
668 | + * journal_try_to_free_buffers() will call this function to |
669 | + * wait for the current transaction to finish syncing data buffers, before |
670 | + * tryinf to free that buffer. |
671 | + * |
672 | + * Called with journal->j_state_lock held. |
673 | + */ |
674 | +static void journal_wait_for_transaction_sync_data(journal_t *journal) |
675 | +{ |
676 | + transaction_t *transaction = NULL; |
677 | + tid_t tid; |
678 | + |
679 | + spin_lock(&journal->j_state_lock); |
680 | + transaction = journal->j_committing_transaction; |
681 | + |
682 | + if (!transaction) { |
683 | + spin_unlock(&journal->j_state_lock); |
684 | + return; |
685 | + } |
686 | + |
687 | + tid = transaction->t_tid; |
688 | + spin_unlock(&journal->j_state_lock); |
689 | + log_wait_commit(journal, tid); |
690 | +} |
691 | |
692 | /** |
693 | * int journal_try_to_free_buffers() - try to free page buffers. |
694 | * @journal: journal for operation |
695 | * @page: to try and free |
696 | - * @unused_gfp_mask: unused |
697 | + * @gfp_mask: we use the mask to detect how hard should we try to release |
698 | + * buffers. If __GFP_WAIT and __GFP_FS is set, we wait for commit code to |
699 | + * release the buffers. |
700 | * |
701 | * |
702 | * For all the buffers on this page, |
703 | @@ -1654,9 +1712,11 @@ out: |
704 | * journal_try_to_free_buffer() is changing its state. But that |
705 | * cannot happen because we never reallocate freed data as metadata |
706 | * while the data is part of a transaction. Yes? |
707 | + * |
708 | + * Return 0 on failure, 1 on success |
709 | */ |
710 | int journal_try_to_free_buffers(journal_t *journal, |
711 | - struct page *page, gfp_t unused_gfp_mask) |
712 | + struct page *page, gfp_t gfp_mask) |
713 | { |
714 | struct buffer_head *head; |
715 | struct buffer_head *bh; |
716 | @@ -1685,7 +1745,28 @@ int journal_try_to_free_buffers(journal_t *journal, |
717 | if (buffer_jbd(bh)) |
718 | goto busy; |
719 | } while ((bh = bh->b_this_page) != head); |
720 | + |
721 | ret = try_to_free_buffers(page); |
722 | + |
723 | + /* |
724 | + * There are a number of places where journal_try_to_free_buffers() |
725 | + * could race with journal_commit_transaction(), the later still |
726 | + * holds the reference to the buffers to free while processing them. |
727 | + * try_to_free_buffers() failed to free those buffers. Some of the |
728 | + * caller of releasepage() request page buffers to be dropped, otherwise |
729 | + * treat the fail-to-free as errors (such as generic_file_direct_IO()) |
730 | + * |
731 | + * So, if the caller of try_to_release_page() wants the synchronous |
732 | + * behaviour(i.e make sure buffers are dropped upon return), |
733 | + * let's wait for the current transaction to finish flush of |
734 | + * dirty data buffers, then try to free those buffers again, |
735 | + * with the journal locked. |
736 | + */ |
737 | + if (ret == 0 && (gfp_mask & __GFP_WAIT) && (gfp_mask & __GFP_FS)) { |
738 | + journal_wait_for_transaction_sync_data(journal); |
739 | + ret = try_to_free_buffers(page); |
740 | + } |
741 | + |
742 | busy: |
743 | return ret; |
744 | } |
745 | @@ -2069,7 +2150,7 @@ void __journal_refile_buffer(struct journal_head *jh) |
746 | jh->b_transaction = jh->b_next_transaction; |
747 | jh->b_next_transaction = NULL; |
748 | __journal_file_buffer(jh, jh->b_transaction, |
749 | - was_dirty ? BJ_Metadata : BJ_Reserved); |
750 | + jh->b_modified ? BJ_Metadata : BJ_Reserved); |
751 | J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING); |
752 | |
753 | if (was_dirty) |
754 | diff --git a/fs/namei.c b/fs/namei.c |
755 | index 8cf9bb9..a6fdd95 100644 |
756 | --- a/fs/namei.c |
757 | +++ b/fs/namei.c |
758 | @@ -514,7 +514,14 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s |
759 | */ |
760 | result = d_lookup(parent, name); |
761 | if (!result) { |
762 | - struct dentry * dentry = d_alloc(parent, name); |
763 | + struct dentry *dentry; |
764 | + |
765 | + /* Don't create child dentry for a dead directory. */ |
766 | + result = ERR_PTR(-ENOENT); |
767 | + if (IS_DEADDIR(dir)) |
768 | + goto out_unlock; |
769 | + |
770 | + dentry = d_alloc(parent, name); |
771 | result = ERR_PTR(-ENOMEM); |
772 | if (dentry) { |
773 | result = dir->i_op->lookup(dir, dentry, nd); |
774 | @@ -523,6 +530,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s |
775 | else |
776 | result = dentry; |
777 | } |
778 | +out_unlock: |
779 | mutex_unlock(&dir->i_mutex); |
780 | return result; |
781 | } |
782 | @@ -1313,7 +1321,14 @@ static struct dentry *__lookup_hash(struct qstr *name, |
783 | |
784 | dentry = cached_lookup(base, name, nd); |
785 | if (!dentry) { |
786 | - struct dentry *new = d_alloc(base, name); |
787 | + struct dentry *new; |
788 | + |
789 | + /* Don't create child dentry for a dead directory. */ |
790 | + dentry = ERR_PTR(-ENOENT); |
791 | + if (IS_DEADDIR(inode)) |
792 | + goto out; |
793 | + |
794 | + new = d_alloc(base, name); |
795 | dentry = ERR_PTR(-ENOMEM); |
796 | if (!new) |
797 | goto out; |
798 | @@ -1904,18 +1919,22 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir) |
799 | if (IS_ERR(dentry)) |
800 | goto fail; |
801 | |
802 | + if (dentry->d_inode) |
803 | + goto eexist; |
804 | /* |
805 | * Special case - lookup gave negative, but... we had foo/bar/ |
806 | * From the vfs_mknod() POV we just have a negative dentry - |
807 | * all is fine. Let's be bastards - you had / on the end, you've |
808 | * been asking for (non-existent) directory. -ENOENT for you. |
809 | */ |
810 | - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) |
811 | - goto enoent; |
812 | + if (unlikely(!is_dir && nd->last.name[nd->last.len])) { |
813 | + dput(dentry); |
814 | + dentry = ERR_PTR(-ENOENT); |
815 | + } |
816 | return dentry; |
817 | -enoent: |
818 | +eexist: |
819 | dput(dentry); |
820 | - dentry = ERR_PTR(-ENOENT); |
821 | + dentry = ERR_PTR(-EEXIST); |
822 | fail: |
823 | return dentry; |
824 | } |
825 | diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c |
826 | index 6f88d7c..f83fb73 100644 |
827 | --- a/fs/nfs/inode.c |
828 | +++ b/fs/nfs/inode.c |
829 | @@ -57,8 +57,6 @@ static int enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED; |
830 | static void nfs_invalidate_inode(struct inode *); |
831 | static int nfs_update_inode(struct inode *, struct nfs_fattr *); |
832 | |
833 | -static void nfs_zap_acl_cache(struct inode *); |
834 | - |
835 | static struct kmem_cache * nfs_inode_cachep; |
836 | |
837 | static inline unsigned long |
838 | @@ -167,7 +165,7 @@ void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) |
839 | } |
840 | } |
841 | |
842 | -static void nfs_zap_acl_cache(struct inode *inode) |
843 | +void nfs_zap_acl_cache(struct inode *inode) |
844 | { |
845 | void (*clear_acl_cache)(struct inode *); |
846 | |
847 | diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h |
848 | index 9319927..4c62be1 100644 |
849 | --- a/fs/nfs/internal.h |
850 | +++ b/fs/nfs/internal.h |
851 | @@ -153,6 +153,7 @@ extern void nfs_clear_inode(struct inode *); |
852 | #ifdef CONFIG_NFS_V4 |
853 | extern void nfs4_clear_inode(struct inode *); |
854 | #endif |
855 | +void nfs_zap_acl_cache(struct inode *inode); |
856 | |
857 | /* super.c */ |
858 | extern struct file_system_type nfs_xdev_fs_type; |
859 | diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c |
860 | index 9b73625..423842f 100644 |
861 | --- a/fs/nfs/nfs3acl.c |
862 | +++ b/fs/nfs/nfs3acl.c |
863 | @@ -5,6 +5,8 @@ |
864 | #include <linux/posix_acl_xattr.h> |
865 | #include <linux/nfsacl.h> |
866 | |
867 | +#include "internal.h" |
868 | + |
869 | #define NFSDBG_FACILITY NFSDBG_PROC |
870 | |
871 | ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size) |
872 | @@ -205,6 +207,8 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type) |
873 | status = nfs_revalidate_inode(server, inode); |
874 | if (status < 0) |
875 | return ERR_PTR(status); |
876 | + if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) |
877 | + nfs_zap_acl_cache(inode); |
878 | acl = nfs3_get_cached_acl(inode, type); |
879 | if (acl != ERR_PTR(-EAGAIN)) |
880 | return acl; |
881 | @@ -319,9 +323,8 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, |
882 | dprintk("NFS call setacl\n"); |
883 | msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL]; |
884 | status = rpc_call_sync(server->client_acl, &msg, 0); |
885 | - spin_lock(&inode->i_lock); |
886 | - NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS; |
887 | - spin_unlock(&inode->i_lock); |
888 | + nfs_access_zap_cache(inode); |
889 | + nfs_zap_acl_cache(inode); |
890 | dprintk("NFS reply setacl: %d\n", status); |
891 | |
892 | /* pages may have been allocated at the xdr layer. */ |
893 | diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c |
894 | index 7ce0786..3a2ff77 100644 |
895 | --- a/fs/nfs/nfs4proc.c |
896 | +++ b/fs/nfs/nfs4proc.c |
897 | @@ -52,6 +52,7 @@ |
898 | #include "nfs4_fs.h" |
899 | #include "delegation.h" |
900 | #include "iostat.h" |
901 | +#include "internal.h" |
902 | |
903 | #define NFSDBG_FACILITY NFSDBG_PROC |
904 | |
905 | @@ -2707,6 +2708,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) |
906 | ret = nfs_revalidate_inode(server, inode); |
907 | if (ret < 0) |
908 | return ret; |
909 | + if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) |
910 | + nfs_zap_acl_cache(inode); |
911 | ret = nfs4_read_cached_acl(inode, buf, buflen); |
912 | if (ret != -ENOENT) |
913 | return ret; |
914 | @@ -2734,7 +2737,8 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl |
915 | nfs_inode_return_delegation(inode); |
916 | buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); |
917 | ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); |
918 | - nfs_zap_caches(inode); |
919 | + nfs_access_zap_cache(inode); |
920 | + nfs_zap_acl_cache(inode); |
921 | return ret; |
922 | } |
923 | |
924 | diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c |
925 | index 5567ec0..7965118 100644 |
926 | --- a/fs/partitions/msdos.c |
927 | +++ b/fs/partitions/msdos.c |
928 | @@ -18,7 +18,7 @@ |
929 | * |
930 | * Re-organised Feb 1998 Russell King |
931 | */ |
932 | - |
933 | +#include <linux/msdos_fs.h> |
934 | |
935 | #include "check.h" |
936 | #include "msdos.h" |
937 | @@ -419,6 +419,7 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) |
938 | Sector sect; |
939 | unsigned char *data; |
940 | struct partition *p; |
941 | + struct fat_boot_sector *fb; |
942 | int slot; |
943 | |
944 | data = read_dev_sector(bdev, 0, §); |
945 | @@ -444,8 +445,21 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) |
946 | p = (struct partition *) (data + 0x1be); |
947 | for (slot = 1; slot <= 4; slot++, p++) { |
948 | if (p->boot_ind != 0 && p->boot_ind != 0x80) { |
949 | - put_dev_sector(sect); |
950 | - return 0; |
951 | + /* |
952 | + * Even without a valid boot inidicator value |
953 | + * its still possible this is valid FAT filesystem |
954 | + * without a partition table. |
955 | + */ |
956 | + fb = (struct fat_boot_sector *) data; |
957 | + if (slot == 1 && fb->reserved && fb->fats |
958 | + && fat_valid_media(fb->media)) { |
959 | + printk("\n"); |
960 | + put_dev_sector(sect); |
961 | + return 1; |
962 | + } else { |
963 | + put_dev_sector(sect); |
964 | + return 0; |
965 | + } |
966 | } |
967 | } |
968 | |
969 | diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c |
970 | index 3f13d49..35e5c6e 100644 |
971 | --- a/fs/romfs/inode.c |
972 | +++ b/fs/romfs/inode.c |
973 | @@ -418,7 +418,8 @@ static int |
974 | romfs_readpage(struct file *file, struct page * page) |
975 | { |
976 | struct inode *inode = page->mapping->host; |
977 | - loff_t offset, avail, readlen; |
978 | + loff_t offset, size; |
979 | + unsigned long filled; |
980 | void *buf; |
981 | int result = -EIO; |
982 | |
983 | @@ -430,21 +431,29 @@ romfs_readpage(struct file *file, struct page * page) |
984 | |
985 | /* 32 bit warning -- but not for us :) */ |
986 | offset = page_offset(page); |
987 | - if (offset < i_size_read(inode)) { |
988 | - avail = inode->i_size-offset; |
989 | - readlen = min_t(unsigned long, avail, PAGE_SIZE); |
990 | - if (romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen) == readlen) { |
991 | - if (readlen < PAGE_SIZE) { |
992 | - memset(buf + readlen,0,PAGE_SIZE-readlen); |
993 | - } |
994 | - SetPageUptodate(page); |
995 | - result = 0; |
996 | + size = i_size_read(inode); |
997 | + filled = 0; |
998 | + result = 0; |
999 | + if (offset < size) { |
1000 | + unsigned long readlen; |
1001 | + |
1002 | + size -= offset; |
1003 | + readlen = size > PAGE_SIZE ? PAGE_SIZE : size; |
1004 | + |
1005 | + filled = romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen); |
1006 | + |
1007 | + if (filled != readlen) { |
1008 | + SetPageError(page); |
1009 | + filled = 0; |
1010 | + result = -EIO; |
1011 | } |
1012 | } |
1013 | - if (result) { |
1014 | - memset(buf, 0, PAGE_SIZE); |
1015 | - SetPageError(page); |
1016 | - } |
1017 | + |
1018 | + if (filled < PAGE_SIZE) |
1019 | + memset(buf + filled, 0, PAGE_SIZE-filled); |
1020 | + |
1021 | + if (!result) |
1022 | + SetPageUptodate(page); |
1023 | flush_dcache_page(page); |
1024 | |
1025 | unlock_page(page); |
1026 | diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h |
1027 | index f950921..20277ad 100644 |
1028 | --- a/include/linux/msdos_fs.h |
1029 | +++ b/include/linux/msdos_fs.h |
1030 | @@ -58,7 +58,11 @@ |
1031 | #define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */ |
1032 | |
1033 | /* media of boot sector */ |
1034 | -#define FAT_VALID_MEDIA(x) ((0xF8 <= (x) && (x) <= 0xFF) || (x) == 0xF0) |
1035 | +static inline int fat_valid_media(u8 media) |
1036 | +{ |
1037 | + return 0xf8 <= media || media == 0xf0; |
1038 | +} |
1039 | + |
1040 | #define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \ |
1041 | MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x)) |
1042 | |
1043 | diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h |
1044 | index 0148058..771e4b3 100644 |
1045 | --- a/include/sound/ac97_codec.h |
1046 | +++ b/include/sound/ac97_codec.h |
1047 | @@ -504,6 +504,7 @@ struct snd_ac97 { |
1048 | unsigned short pcmreg[3]; // PCM registers |
1049 | unsigned short codec_cfg[3]; // CODEC_CFG bits |
1050 | unsigned char swap_mic_linein; // AD1986/AD1986A only |
1051 | + unsigned char lo_as_master; /* LO as master */ |
1052 | } ad18xx; |
1053 | unsigned int dev_flags; /* device specific */ |
1054 | } spec; |
1055 | diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h |
1056 | index 7b7b9b1..10ee28e 100644 |
1057 | --- a/include/sound/emu10k1.h |
1058 | +++ b/include/sound/emu10k1.h |
1059 | @@ -1670,6 +1670,7 @@ struct snd_emu_chip_details { |
1060 | unsigned char spi_dac; /* SPI interface for DAC */ |
1061 | unsigned char i2c_adc; /* I2C interface for ADC */ |
1062 | unsigned char adc_1361t; /* Use Philips 1361T ADC */ |
1063 | + unsigned char invert_shared_spdif; /* analog/digital switch inverted */ |
1064 | const char *driver; |
1065 | const char *name; |
1066 | const char *id; /* for backward compatibility - can be NULL if not needed */ |
1067 | diff --git a/mm/filemap.c b/mm/filemap.c |
1068 | index 703f2c8..d721ad5 100644 |
1069 | --- a/mm/filemap.c |
1070 | +++ b/mm/filemap.c |
1071 | @@ -2574,9 +2574,8 @@ out: |
1072 | * Otherwise return zero. |
1073 | * |
1074 | * The @gfp_mask argument specifies whether I/O may be performed to release |
1075 | - * this page (__GFP_IO), and whether the call may block (__GFP_WAIT). |
1076 | + * this page (__GFP_IO), and whether the call may block (__GFP_WAIT & __GFP_FS). |
1077 | * |
1078 | - * NOTE: @gfp_mask may go away, and this function may become non-blocking. |
1079 | */ |
1080 | int try_to_release_page(struct page *page, gfp_t gfp_mask) |
1081 | { |
1082 | diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c |
1083 | index 347e935..2f0ffc3 100644 |
1084 | --- a/net/bluetooth/bnep/core.c |
1085 | +++ b/net/bluetooth/bnep/core.c |
1086 | @@ -507,6 +507,11 @@ static int bnep_session(void *arg) |
1087 | /* Delete network device */ |
1088 | unregister_netdev(dev); |
1089 | |
1090 | + /* Wakeup user-space polling for socket errors */ |
1091 | + s->sock->sk->sk_err = EUNATCH; |
1092 | + |
1093 | + wake_up_interruptible(s->sock->sk->sk_sleep); |
1094 | + |
1095 | /* Release the socket */ |
1096 | fput(s->sock->file); |
1097 | |
1098 | diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c |
1099 | index 519cdb9..96434d7 100644 |
1100 | --- a/net/bluetooth/hidp/core.c |
1101 | +++ b/net/bluetooth/hidp/core.c |
1102 | @@ -581,6 +581,12 @@ static int hidp_session(void *arg) |
1103 | hid_free_device(session->hid); |
1104 | } |
1105 | |
1106 | + /* Wakeup user-space polling for socket errors */ |
1107 | + session->intr_sock->sk->sk_err = EUNATCH; |
1108 | + session->ctrl_sock->sk->sk_err = EUNATCH; |
1109 | + |
1110 | + hidp_schedule(session); |
1111 | + |
1112 | fput(session->intr_sock->file); |
1113 | |
1114 | wait_event_timeout(*(ctrl_sk->sk_sleep), |
1115 | @@ -879,6 +885,10 @@ int hidp_del_connection(struct hidp_conndel_req *req) |
1116 | skb_queue_purge(&session->ctrl_transmit); |
1117 | skb_queue_purge(&session->intr_transmit); |
1118 | |
1119 | + /* Wakeup user-space polling for socket errors */ |
1120 | + session->intr_sock->sk->sk_err = EUNATCH; |
1121 | + session->ctrl_sock->sk->sk_err = EUNATCH; |
1122 | + |
1123 | /* Kill session thread */ |
1124 | atomic_inc(&session->terminate); |
1125 | hidp_schedule(session); |
1126 | diff --git a/sound/core/init.c b/sound/core/init.c |
1127 | index e3338d6..6200f42 100644 |
1128 | --- a/sound/core/init.c |
1129 | +++ b/sound/core/init.c |
1130 | @@ -311,6 +311,9 @@ int snd_card_disconnect(struct snd_card *card) |
1131 | struct file *file; |
1132 | int err; |
1133 | |
1134 | + if (!card) |
1135 | + return -EINVAL; |
1136 | + |
1137 | spin_lock(&card->files_lock); |
1138 | if (card->shutdown) { |
1139 | spin_unlock(&card->files_lock); |
1140 | @@ -322,6 +325,7 @@ int snd_card_disconnect(struct snd_card *card) |
1141 | /* phase 1: disable fops (user space) operations for ALSA API */ |
1142 | mutex_lock(&snd_card_mutex); |
1143 | snd_cards[card->number] = NULL; |
1144 | + snd_cards_lock &= ~(1 << card->number); |
1145 | mutex_unlock(&snd_card_mutex); |
1146 | |
1147 | /* phase 2: replace file->f_op with special dummy operations */ |
1148 | @@ -360,6 +364,15 @@ int snd_card_disconnect(struct snd_card *card) |
1149 | snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number); |
1150 | |
1151 | snd_info_card_disconnect(card); |
1152 | +#ifndef CONFIG_SYSFS_DEPRECATED |
1153 | + if (card->card_dev) { |
1154 | + device_unregister(card->card_dev); |
1155 | + card->card_dev = NULL; |
1156 | + } |
1157 | +#endif |
1158 | +#ifdef CONFIG_PM |
1159 | + wake_up(&card->power_sleep); |
1160 | +#endif |
1161 | return 0; |
1162 | } |
1163 | |
1164 | @@ -401,33 +414,14 @@ static int snd_card_do_free(struct snd_card *card) |
1165 | snd_printk(KERN_WARNING "unable to free card info\n"); |
1166 | /* Not fatal error */ |
1167 | } |
1168 | -#ifndef CONFIG_SYSFS_DEPRECATED |
1169 | - if (card->card_dev) |
1170 | - device_unregister(card->card_dev); |
1171 | -#endif |
1172 | kfree(card); |
1173 | return 0; |
1174 | } |
1175 | |
1176 | -static int snd_card_free_prepare(struct snd_card *card) |
1177 | -{ |
1178 | - if (card == NULL) |
1179 | - return -EINVAL; |
1180 | - (void) snd_card_disconnect(card); |
1181 | - mutex_lock(&snd_card_mutex); |
1182 | - snd_cards[card->number] = NULL; |
1183 | - snd_cards_lock &= ~(1 << card->number); |
1184 | - mutex_unlock(&snd_card_mutex); |
1185 | -#ifdef CONFIG_PM |
1186 | - wake_up(&card->power_sleep); |
1187 | -#endif |
1188 | - return 0; |
1189 | -} |
1190 | - |
1191 | int snd_card_free_when_closed(struct snd_card *card) |
1192 | { |
1193 | int free_now = 0; |
1194 | - int ret = snd_card_free_prepare(card); |
1195 | + int ret = snd_card_disconnect(card); |
1196 | if (ret) |
1197 | return ret; |
1198 | |
1199 | @@ -447,7 +441,7 @@ EXPORT_SYMBOL(snd_card_free_when_closed); |
1200 | |
1201 | int snd_card_free(struct snd_card *card) |
1202 | { |
1203 | - int ret = snd_card_free_prepare(card); |
1204 | + int ret = snd_card_disconnect(card); |
1205 | if (ret) |
1206 | return ret; |
1207 | |
1208 | diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c |
1209 | index 75daed2..581aa2c 100644 |
1210 | --- a/sound/core/oss/mixer_oss.c |
1211 | +++ b/sound/core/oss/mixer_oss.c |
1212 | @@ -1257,6 +1257,8 @@ static void snd_mixer_oss_build(struct snd_mixer_oss *mixer) |
1213 | { SOUND_MIXER_DIGITAL3, "Digital", 2 }, |
1214 | { SOUND_MIXER_PHONEIN, "Phone", 0 }, |
1215 | { SOUND_MIXER_PHONEOUT, "Master Mono", 0 }, |
1216 | + { SOUND_MIXER_PHONEOUT, "Speaker", 0 }, /*fallback*/ |
1217 | + { SOUND_MIXER_PHONEOUT, "Mono", 0 }, /*fallback*/ |
1218 | { SOUND_MIXER_PHONEOUT, "Phone", 0 }, /* fallback */ |
1219 | { SOUND_MIXER_VIDEO, "Video", 0 }, |
1220 | { SOUND_MIXER_RADIO, "Radio", 0 }, |
1221 | diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c |
1222 | index ab570a0..2490259 100644 |
1223 | --- a/sound/core/seq/oss/seq_oss_synth.c |
1224 | +++ b/sound/core/seq/oss/seq_oss_synth.c |
1225 | @@ -599,6 +599,9 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in |
1226 | { |
1227 | struct seq_oss_synth *rec; |
1228 | |
1229 | + if (dev < 0 || dev >= dp->max_synthdev) |
1230 | + return -ENXIO; |
1231 | + |
1232 | if (dp->synths[dev].is_midi) { |
1233 | struct midi_info minf; |
1234 | snd_seq_oss_midi_make_info(dp, dp->synths[dev].midi_mapped, &minf); |
1235 | diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c |
1236 | index 50c637e..3d70241 100644 |
1237 | --- a/sound/pci/ac97/ac97_patch.c |
1238 | +++ b/sound/pci/ac97/ac97_patch.c |
1239 | @@ -1960,6 +1960,9 @@ static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd |
1240 | |
1241 | val = ac97->regs[AC97_AD_MISC]; |
1242 | ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL); |
1243 | + if (ac97->spec.ad18xx.lo_as_master) |
1244 | + ucontrol->value.integer.value[0] = |
1245 | + !ucontrol->value.integer.value[0]; |
1246 | return 0; |
1247 | } |
1248 | |
1249 | @@ -1968,8 +1971,10 @@ static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol *kcontrol, struct snd |
1250 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
1251 | unsigned short val; |
1252 | |
1253 | - val = !ucontrol->value.integer.value[0] |
1254 | - ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0; |
1255 | + val = !ucontrol->value.integer.value[0]; |
1256 | + if (ac97->spec.ad18xx.lo_as_master) |
1257 | + val = !val; |
1258 | + val = val ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0; |
1259 | return snd_ac97_update_bits(ac97, AC97_AD_MISC, |
1260 | AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val); |
1261 | } |
1262 | @@ -2020,7 +2025,7 @@ static void ad1888_update_jacks(struct snd_ac97 *ac97) |
1263 | { |
1264 | unsigned short val = 0; |
1265 | /* clear LODIS if shared jack is to be used for Surround out */ |
1266 | - if (is_shared_linein(ac97)) |
1267 | + if (!ac97->spec.ad18xx.lo_as_master && is_shared_linein(ac97)) |
1268 | val |= (1 << 12); |
1269 | /* clear CLDIS if shared jack is to be used for C/LFE out */ |
1270 | if (is_shared_micin(ac97)) |
1271 | @@ -2056,9 +2061,13 @@ static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = { |
1272 | |
1273 | static int patch_ad1888_specific(struct snd_ac97 *ac97) |
1274 | { |
1275 | - /* rename 0x04 as "Master" and 0x02 as "Master Surround" */ |
1276 | - snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Master Surround Playback"); |
1277 | - snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback"); |
1278 | + if (!ac97->spec.ad18xx.lo_as_master) { |
1279 | + /* rename 0x04 as "Master" and 0x02 as "Master Surround" */ |
1280 | + snd_ac97_rename_vol_ctl(ac97, "Master Playback", |
1281 | + "Master Surround Playback"); |
1282 | + snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", |
1283 | + "Master Playback"); |
1284 | + } |
1285 | return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls)); |
1286 | } |
1287 | |
1288 | @@ -2077,16 +2086,27 @@ static int patch_ad1888(struct snd_ac97 * ac97) |
1289 | |
1290 | patch_ad1881(ac97); |
1291 | ac97->build_ops = &patch_ad1888_build_ops; |
1292 | - /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */ |
1293 | - /* it seems that most vendors connect line-out connector to headphone out of AC'97 */ |
1294 | + |
1295 | + /* |
1296 | + * LO can be used as a real line-out on some devices, |
1297 | + * and we need to revert the front/surround mixer switches |
1298 | + */ |
1299 | + if (ac97->subsystem_vendor == 0x1043 && |
1300 | + ac97->subsystem_device == 0x1193) /* ASUS A9T laptop */ |
1301 | + ac97->spec.ad18xx.lo_as_master = 1; |
1302 | + |
1303 | + misc = snd_ac97_read(ac97, AC97_AD_MISC); |
1304 | /* AD-compatible mode */ |
1305 | /* Stereo mutes enabled */ |
1306 | - misc = snd_ac97_read(ac97, AC97_AD_MISC); |
1307 | - snd_ac97_write_cache(ac97, AC97_AD_MISC, misc | |
1308 | - AC97_AD198X_LOSEL | |
1309 | - AC97_AD198X_HPSEL | |
1310 | - AC97_AD198X_MSPLT | |
1311 | - AC97_AD198X_AC97NC); |
1312 | + misc |= AC97_AD198X_MSPLT | AC97_AD198X_AC97NC; |
1313 | + if (!ac97->spec.ad18xx.lo_as_master) |
1314 | + /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */ |
1315 | + /* it seems that most vendors connect line-out connector to |
1316 | + * headphone out of AC'97 |
1317 | + */ |
1318 | + misc |= AC97_AD198X_LOSEL | AC97_AD198X_HPSEL; |
1319 | + |
1320 | + snd_ac97_write_cache(ac97, AC97_AD_MISC, misc); |
1321 | ac97->flags |= AC97_STEREO_MUTES; |
1322 | return 0; |
1323 | } |
1324 | diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c |
1325 | index d0330d8..df278ba 100644 |
1326 | --- a/sound/pci/emu10k1/emu10k1_main.c |
1327 | +++ b/sound/pci/emu10k1/emu10k1_main.c |
1328 | @@ -1527,6 +1527,7 @@ static struct snd_emu_chip_details emu_chip_details[] = { |
1329 | .ca0151_chip = 1, |
1330 | .spk71 = 1, |
1331 | .spdif_bug = 1, |
1332 | + .invert_shared_spdif = 1, /* digital/analog switch swapped */ |
1333 | .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */ |
1334 | .ac97_chip = 1} , |
1335 | {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, |
1336 | diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c |
1337 | index fd22120..9f77692 100644 |
1338 | --- a/sound/pci/emu10k1/emumixer.c |
1339 | +++ b/sound/pci/emu10k1/emumixer.c |
1340 | @@ -1578,6 +1578,10 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol, |
1341 | ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0; |
1342 | else |
1343 | ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0; |
1344 | + if (emu->card_capabilities->invert_shared_spdif) |
1345 | + ucontrol->value.integer.value[0] = |
1346 | + !ucontrol->value.integer.value[0]; |
1347 | + |
1348 | return 0; |
1349 | } |
1350 | |
1351 | @@ -1586,15 +1590,18 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, |
1352 | { |
1353 | unsigned long flags; |
1354 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1355 | - unsigned int reg, val; |
1356 | + unsigned int reg, val, sw; |
1357 | int change = 0; |
1358 | |
1359 | + sw = ucontrol->value.integer.value[0]; |
1360 | + if (emu->card_capabilities->invert_shared_spdif) |
1361 | + sw = !sw; |
1362 | spin_lock_irqsave(&emu->reg_lock, flags); |
1363 | if ( emu->card_capabilities->i2c_adc) { |
1364 | /* Do nothing for Audigy 2 ZS Notebook */ |
1365 | } else if (emu->audigy) { |
1366 | reg = inl(emu->port + A_IOCFG); |
1367 | - val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0; |
1368 | + val = sw ? A_IOCFG_GPOUT0 : 0; |
1369 | change = (reg & A_IOCFG_GPOUT0) != val; |
1370 | if (change) { |
1371 | reg &= ~A_IOCFG_GPOUT0; |
1372 | @@ -1603,7 +1610,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, |
1373 | } |
1374 | } |
1375 | reg = inl(emu->port + HCFG); |
1376 | - val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0; |
1377 | + val = sw ? HCFG_GPOUT0 : 0; |
1378 | change |= (reg & HCFG_GPOUT0) != val; |
1379 | if (change) { |
1380 | reg &= ~HCFG_GPOUT0; |
1381 | diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c |
1382 | index c864928..d7cba53 100644 |
1383 | --- a/sound/pci/hda/patch_analog.c |
1384 | +++ b/sound/pci/hda/patch_analog.c |
1385 | @@ -1563,6 +1563,7 @@ static const char *ad1981_models[AD1981_MODELS] = { |
1386 | |
1387 | static struct snd_pci_quirk ad1981_cfg_tbl[] = { |
1388 | SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), |
1389 | + SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), |
1390 | /* All HP models */ |
1391 | SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP), |
1392 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA), |
1393 | @@ -2557,7 +2558,7 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, |
1394 | { |
1395 | struct ad198x_spec *spec = codec->spec; |
1396 | hda_nid_t nid; |
1397 | - int idx, err; |
1398 | + int i, idx, err; |
1399 | char name[32]; |
1400 | |
1401 | if (! pin) |
1402 | @@ -2565,16 +2566,26 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, |
1403 | |
1404 | idx = ad1988_pin_idx(pin); |
1405 | nid = ad1988_idx_to_dac(codec, idx); |
1406 | - /* specify the DAC as the extra output */ |
1407 | - if (! spec->multiout.hp_nid) |
1408 | - spec->multiout.hp_nid = nid; |
1409 | - else |
1410 | - spec->multiout.extra_out_nid[0] = nid; |
1411 | - /* control HP volume/switch on the output mixer amp */ |
1412 | - sprintf(name, "%s Playback Volume", pfx); |
1413 | - if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, |
1414 | - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) |
1415 | - return err; |
1416 | + /* check whether the corresponding DAC was already taken */ |
1417 | + for (i = 0; i < spec->autocfg.line_outs; i++) { |
1418 | + hda_nid_t pin = spec->autocfg.line_out_pins[i]; |
1419 | + hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin)); |
1420 | + if (dac == nid) |
1421 | + break; |
1422 | + } |
1423 | + if (i >= spec->autocfg.line_outs) { |
1424 | + /* specify the DAC as the extra output */ |
1425 | + if (!spec->multiout.hp_nid) |
1426 | + spec->multiout.hp_nid = nid; |
1427 | + else |
1428 | + spec->multiout.extra_out_nid[0] = nid; |
1429 | + /* control HP volume/switch on the output mixer amp */ |
1430 | + sprintf(name, "%s Playback Volume", pfx); |
1431 | + err = add_control(spec, AD_CTL_WIDGET_VOL, name, |
1432 | + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); |
1433 | + if (err < 0) |
1434 | + return err; |
1435 | + } |
1436 | nid = ad1988_mixer_nids[idx]; |
1437 | sprintf(name, "%s Playback Switch", pfx); |
1438 | if ((err = add_control(spec, AD_CTL_BIND_MUTE, name, |
1439 | diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c |
1440 | index f48838a..d0bc988 100644 |
1441 | --- a/sound/usb/usbaudio.c |
1442 | +++ b/sound/usb/usbaudio.c |
1443 | @@ -1762,8 +1762,10 @@ static int check_hw_params_convention(struct snd_usb_substream *subs) |
1444 | |
1445 | channels = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL); |
1446 | rates = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL); |
1447 | - if (!channels || !rates) |
1448 | + if (!channels || !rates) { |
1449 | + err = -ENOMEM; |
1450 | goto __out; |
1451 | + } |
1452 | |
1453 | list_for_each(p, &subs->fmt_list) { |
1454 | struct audioformat *f; |
1455 | @@ -1916,7 +1918,10 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre |
1456 | 1000 * MIN_PACKS_URB, |
1457 | /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX); |
1458 | |
1459 | - if (check_hw_params_convention(subs)) { |
1460 | + err = check_hw_params_convention(subs); |
1461 | + if (err < 0) |
1462 | + return err; |
1463 | + else if (err) { |
1464 | hwc_debug("setting extra hw constraints...\n"); |
1465 | if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
1466 | hw_rule_rate, subs, |
1467 | @@ -2463,11 +2468,12 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor |
1468 | } |
1469 | break; |
1470 | case USB_AUDIO_FORMAT_PCM8: |
1471 | - /* Dallas DS4201 workaround */ |
1472 | + pcm_format = SNDRV_PCM_FORMAT_U8; |
1473 | + |
1474 | + /* Dallas DS4201 workaround: it advertises U8 format, but really |
1475 | + supports S8. */ |
1476 | if (chip->usb_id == USB_ID(0x04fa, 0x4201)) |
1477 | pcm_format = SNDRV_PCM_FORMAT_S8; |
1478 | - else |
1479 | - pcm_format = SNDRV_PCM_FORMAT_U8; |
1480 | break; |
1481 | case USB_AUDIO_FORMAT_IEEE_FLOAT: |
1482 | pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE; |
1483 | @@ -2671,12 +2677,23 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) |
1484 | int format; |
1485 | struct audioformat *fp; |
1486 | unsigned char *fmt, *csep; |
1487 | + int num; |
1488 | |
1489 | dev = chip->dev; |
1490 | |
1491 | /* parse the interface's altsettings */ |
1492 | iface = usb_ifnum_to_if(dev, iface_no); |
1493 | - for (i = 0; i < iface->num_altsetting; i++) { |
1494 | + |
1495 | + num = iface->num_altsetting; |
1496 | + |
1497 | + /* |
1498 | + * Dallas DS4201 workaround: It presents 5 altsettings, but the last |
1499 | + * one misses syncpipe, and does not produce any sound. |
1500 | + */ |
1501 | + if (chip->usb_id == USB_ID(0x04fa, 0x4201)) |
1502 | + num = 4; |
1503 | + |
1504 | + for (i = 0; i < num; i++) { |
1505 | alts = &iface->altsetting[i]; |
1506 | altsd = get_iface_desc(alts); |
1507 | /* skip invalid one */ |
1508 | @@ -3406,7 +3423,6 @@ static void snd_usb_audio_create_proc(struct snd_usb_audio *chip) |
1509 | |
1510 | static int snd_usb_audio_free(struct snd_usb_audio *chip) |
1511 | { |
1512 | - usb_chip[chip->index] = NULL; |
1513 | kfree(chip); |
1514 | return 0; |
1515 | } |
1516 | @@ -3600,8 +3616,8 @@ static void *snd_usb_audio_probe(struct usb_device *dev, |
1517 | snd_card_set_dev(chip->card, &intf->dev); |
1518 | break; |
1519 | } |
1520 | - if (! chip) { |
1521 | - snd_printk(KERN_ERR "no available usb audio device\n"); |
1522 | + if (!chip) { |
1523 | + printk(KERN_ERR "no available usb audio device\n"); |
1524 | goto __error; |
1525 | } |
1526 | } |
1527 | @@ -3671,6 +3687,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) |
1528 | list_for_each(p, &chip->mixer_list) { |
1529 | snd_usb_mixer_disconnect(p); |
1530 | } |
1531 | + usb_chip[chip->index] = NULL; |
1532 | mutex_unlock(®ister_mutex); |
1533 | snd_card_free_when_closed(card); |
1534 | } else { |
1535 | diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h |
1536 | index 938dff5..82a8d14 100644 |
1537 | --- a/sound/usb/usbquirks.h |
1538 | +++ b/sound/usb/usbquirks.h |
1539 | @@ -39,6 +39,30 @@ |
1540 | .idProduct = prod, \ |
1541 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC |
1542 | |
1543 | +/* Creative/E-Mu devices */ |
1544 | +{ |
1545 | + USB_DEVICE(0x041e, 0x3010), |
1546 | + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1547 | + .vendor_name = "Creative Labs", |
1548 | + .product_name = "Sound Blaster MP3+", |
1549 | + .ifnum = QUIRK_NO_INTERFACE |
1550 | + } |
1551 | +}, |
1552 | +{ |
1553 | + /* E-Mu 0202 USB */ |
1554 | + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
1555 | + .idVendor = 0x041e, |
1556 | + .idProduct = 0x3f02, |
1557 | + .bInterfaceClass = USB_CLASS_AUDIO, |
1558 | +}, |
1559 | +{ |
1560 | + /* E-Mu 0404 USB */ |
1561 | + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
1562 | + .idVendor = 0x041e, |
1563 | + .idProduct = 0x3f04, |
1564 | + .bInterfaceClass = USB_CLASS_AUDIO, |
1565 | +}, |
1566 | + |
1567 | /* |
1568 | * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface |
1569 | * class matches do not take effect without an explicit ID match. |
1570 | @@ -97,19 +121,7 @@ |
1571 | .bInterfaceClass = USB_CLASS_AUDIO, |
1572 | .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL |
1573 | }, |
1574 | -/* E-Mu devices */ |
1575 | -{ |
1576 | - .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
1577 | - .idVendor = 0x041e, |
1578 | - .idProduct = 0x3f02, |
1579 | - .bInterfaceClass = USB_CLASS_AUDIO, |
1580 | -}, |
1581 | -{ |
1582 | - .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
1583 | - .idVendor = 0x041e, |
1584 | - .idProduct = 0x3f04, |
1585 | - .bInterfaceClass = USB_CLASS_AUDIO, |
1586 | -}, |
1587 | + |
1588 | /* |
1589 | * Yamaha devices |
1590 | */ |
1591 | @@ -1165,19 +1177,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), |
1592 | } |
1593 | } |
1594 | }, |
1595 | -{ |
1596 | - USB_DEVICE(0x582, 0x00a6), |
1597 | - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1598 | - .vendor_name = "Roland", |
1599 | - .product_name = "Juno-G", |
1600 | - .ifnum = 0, |
1601 | - .type = QUIRK_MIDI_FIXED_ENDPOINT, |
1602 | - .data = & (const struct snd_usb_midi_endpoint_info) { |
1603 | - .out_cables = 0x0001, |
1604 | - .in_cables = 0x0001 |
1605 | - } |
1606 | - } |
1607 | -}, |
1608 | { /* |
1609 | * This quirk is for the "Advanced" modes of the Edirol UA-25. |
1610 | * If the switch is not in an advanced setting, the UA-25 has |
1611 | @@ -1336,6 +1335,19 @@ YAMAHA_DEVICE(0x7010, "UB99"), |
1612 | }, |
1613 | /* TODO: add Edirol MD-P1 support */ |
1614 | { |
1615 | + USB_DEVICE(0x582, 0x00a6), |
1616 | + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1617 | + .vendor_name = "Roland", |
1618 | + .product_name = "Juno-G", |
1619 | + .ifnum = 0, |
1620 | + .type = QUIRK_MIDI_FIXED_ENDPOINT, |
1621 | + .data = & (const struct snd_usb_midi_endpoint_info) { |
1622 | + .out_cables = 0x0001, |
1623 | + .in_cables = 0x0001 |
1624 | + } |
1625 | + } |
1626 | +}, |
1627 | +{ |
1628 | /* Roland SH-201 */ |
1629 | USB_DEVICE(0x0582, 0x00ad), |
1630 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1631 | @@ -1719,17 +1731,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), |
1632 | } |
1633 | }, |
1634 | |
1635 | -{ |
1636 | - /* Creative Sound Blaster MP3+ */ |
1637 | - USB_DEVICE(0x041e, 0x3010), |
1638 | - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1639 | - .vendor_name = "Creative Labs", |
1640 | - .product_name = "Sound Blaster MP3+", |
1641 | - .ifnum = QUIRK_NO_INTERFACE |
1642 | - } |
1643 | - |
1644 | -}, |
1645 | - |
1646 | /* Emagic devices */ |
1647 | { |
1648 | USB_DEVICE(0x086a, 0x0001), |