Merge branch 'audit.b10' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current
* 'audit.b10' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current:
[PATCH] Audit Filter Performance
[PATCH] Rework of IPC auditing
[PATCH] More user space subject labels
[PATCH] Reworked patch for labels on user space messages
[PATCH] change lspp ipc auditing
[PATCH] audit inode patch
[PATCH] support for context based audit filtering, part 2
[PATCH] support for context based audit filtering
[PATCH] no need to wank with task_lock() and pinning task down in audit_syscall_exit()
[PATCH] drop task argument of audit_syscall_{entry,exit}
[PATCH] drop gfp_mask in audit_log_exit()
[PATCH] move call of audit_free() into do_exit()
[PATCH] sockaddr patch
[PATCH] deal with deadlocks in audit_free()
diff --git a/Documentation/sound/alsa/Audiophile-Usb.txt b/Documentation/sound/alsa/Audiophile-Usb.txt
index 4692c8e..b535c2a 100644
--- a/Documentation/sound/alsa/Audiophile-Usb.txt
+++ b/Documentation/sound/alsa/Audiophile-Usb.txt
@@ -1,4 +1,4 @@
- Guide to using M-Audio Audiophile USB with ALSA and Jack v1.2
+ Guide to using M-Audio Audiophile USB with ALSA and Jack v1.3
========================================================
Thibault Le Meur <Thibault.LeMeur@supelec.fr>
@@ -22,16 +22,16 @@
* Midi In (Mi)
* Midi Out (Mo)
-The internal DAC/ADC has the following caracteristics:
+The internal DAC/ADC has the following characteristics:
* sample depth of 16 or 24 bits
* sample rate from 8kHz to 96kHz
-* Two ports can't use different sample depths at the same time.Moreover, the
+* Two ports can't use different sample depths at the same time. Moreover, the
Audiophile USB documentation gives the following Warning: "Please exit any
audio application running before switching between bit depths"
Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be
activated at the same time depending on the audio mode selected:
- * 16-bit/48kHz ==> 4 channels in/ 4 channels out
+ * 16-bit/48kHz ==> 4 channels in/4 channels out
- Ai+Ao+Di+Do
* 24-bit/48kHz ==> 4 channels in/2 channels out,
or 2 channels in/4 channels out
@@ -41,8 +41,8 @@
Important facts about the Digital interface:
--------------------------------------------
- * The Do port additionnaly supports surround-encoded AC-3 and DTS passthrough,
-though I haven't tested it under linux
+ * The Do port additionally supports surround-encoded AC-3 and DTS passthrough,
+though I haven't tested it under Linux
- Note that in this setup only the Do interface can be enabled
* Apart from recording an audio digital stream, enabling the Di port is a way
to synchronize the device to an external sample clock
@@ -60,24 +60,23 @@
The Audiophile USB MIDI ports will be automatically supported once the
following modules have been loaded:
* snd-usb-audio
- * snd-seq
* snd-seq-midi
-No additionnal setting is required.
+No additional setting is required.
2.2 - Audio ports
-----------------
Audio functions of the Audiophile USB device are handled by the snd-usb-audio
module. This module can work in a default mode (without any device-specific
-parameter), or in an advanced mode with the device-specific parameter called
+parameter), or in an "advanced" mode with the device-specific parameter called
"device_setup".
2.2.1 - Default Alsa driver mode
-The default behaviour of the snd-usb-audio driver is to parse the device
+The default behavior of the snd-usb-audio driver is to parse the device
capabilities at startup and enable all functions inside the device (including
-all ports at any sample rates and any sample depths supported). This approach
+all ports at any supported sample rates and sample depths). This approach
has the advantage to let the driver easily switch from sample rates/depths
automatically according to the need of the application claiming the device.
@@ -114,9 +113,9 @@
For people having this problem, the snd-usb-audio module has a new module
parameter called "device_setup".
-2.2.2.1 - Initializing the working mode of the Audiohile USB
+2.2.2.1 - Initializing the working mode of the Audiophile USB
-As far as the Audiohile USB device is concerned, this value let the user
+As far as the Audiophile USB device is concerned, this value let the user
specify:
* the sample depth
* the sample rate
@@ -174,20 +173,20 @@
IMPORTANT NOTE WHEN SWITCHING CONFIGURATION:
-------------------------------------------
- * You may need to _first_ intialize the module with the correct device_setup
+ * You may need to _first_ initialize the module with the correct device_setup
parameter and _only_after_ turn on the Audiophile USB device
* This is especially true when switching the sample depth:
- - first trun off the device
- - de-register the snd-usb-audio module
- - change the device_setup parameter (by either manually reprobing the module
- or changing modprobe.conf)
+ - first turn off the device
+ - de-register the snd-usb-audio module (modprobe -r)
+ - change the device_setup parameter by changing the device_setup
+ option in /etc/modprobe.conf
- turn on the device
2.2.2.3 - Audiophile USB's device_setup structure
If you want to understand the device_setup magic numbers for the Audiophile
USB, you need some very basic understanding of binary computation. However,
-this is not required to use the parameter and you may skip thi section.
+this is not required to use the parameter and you may skip this section.
The device_setup is one byte long and its structure is the following:
@@ -231,11 +230,11 @@
2.2.3 - USB implementation details for this device
-You may safely skip this section if you're not interrested in driver
+You may safely skip this section if you're not interested in driver
development.
-This section describes some internals aspect of the device and summarize the
-data I got by usb-snooping the windows and linux drivers.
+This section describes some internal aspects of the device and summarize the
+data I got by usb-snooping the windows and Linux drivers.
The M-Audio Audiophile USB has 7 USB Interfaces:
a "USB interface":
@@ -277,9 +276,9 @@
- 16-bit depth, 8-48kHz sample mode
- Synch playback (Do), audio format type III IEC1937_AC-3
-In order to ensure a correct intialization of the device, the driver
+In order to ensure a correct initialization of the device, the driver
_must_know_ how the device will be used:
- * if DTS is choosen, only Interface 2 with AltSet nb.6 must be
+ * if DTS is chosen, only Interface 2 with AltSet nb.6 must be
registered
* if 96KHz only AltSets nb.1 of each interface must be selected
* if samples are using 24bits/48KHz then AltSet 2 must me used if
@@ -290,7 +289,7 @@
is not connected
When device_setup is given as a parameter to the snd-usb-audio module, the
-parse_audio_enpoint function uses a quirk called
+parse_audio_endpoints function uses a quirk called
"audiophile_skip_setting_quirk" in order to prevent AltSettings not
corresponding to device_setup from being registered in the driver.
@@ -317,9 +316,8 @@
using the "default" ALSA device. This is less efficient than it could be.
Consider using a hardware device instead rather than using the plug layer."
-
3.2 - Patching alsa to use direct pcm device
--------------------------------------------
+--------------------------------------------
A patch for Jack by Andreas Steinmetz adds support for Big Endian devices.
However it has not been included in the CVS tree.
@@ -331,3 +329,32 @@
line:
% jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1
+3.2 - Getting 2 input and/or output interfaces in Jack
+------------------------------------------------------
+
+As you can see, starting the Jack server this way will only enable 1 stereo
+input (Di or Ai) and 1 stereo output (Ao or Do).
+
+This is due to the following restrictions:
+* Jack can only open one capture device and one playback device at a time
+* The Audiophile USB is seen as 2 (or three) Alsa devices: hw:1,0, hw:1,1
+ (and optionally hw:1,2)
+If you want to get Ai+Di and/or Ao+Do support with Jack, you would need to
+combine the Alsa devices into one logical "complex" device.
+
+If you want to give it a try, I recommend reading the information from
+this page: http://www.sound-man.co.uk/linuxaudio/ice1712multi.html
+It is related to another device (ice1712) but can be adapted to suit
+the Audiophile USB.
+
+Enabling multiple Audiophile USB interfaces for Jackd will certainly require:
+* patching Jack with the previously mentioned "Big Endian" patch
+* patching Jackd with the MMAP_COMPLEX patch (see the ice1712 page)
+* patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page)
+* define a multi device (combination of hw:1,0 and hw:1,1) in your .asoundrc
+ file
+* start jackd with this device
+
+I had no success in testing this for now, but this may be due to my OS
+configuration. If you have any success with this kind of setup, please
+drop me an email.
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 68eeebc..1faf763 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -1172,7 +1172,7 @@
}
/* PCI IDs */
- static struct pci_device_id snd_mychip_ids[] = {
+ static struct pci_device_id snd_mychip_ids[] __devinitdata = {
{ PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
....
@@ -1565,7 +1565,7 @@
<informalexample>
<programlisting>
<![CDATA[
- static struct pci_device_id snd_mychip_ids[] = {
+ static struct pci_device_id snd_mychip_ids[] __devinitdata = {
{ PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
....
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 049a255..4c785a6 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -215,7 +215,7 @@
{
struct acpi_table_madt *madt = NULL;
- if (!phys_addr || !size || !cpu_has_apic)
+ if (!phys_addr || !size)
return -EINVAL;
madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size);
@@ -1151,6 +1151,9 @@
acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
+ if (!cpu_has_apic)
+ return -ENODEV;
+
/*
* set sci_int and PM timer address
*/
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 254cee9..013b85d 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -757,10 +757,6 @@
apic_verbosity = APIC_DEBUG;
else if (strcmp("verbose", str) == 0)
apic_verbosity = APIC_VERBOSE;
- else
- printk(KERN_WARNING "APIC Verbosity level %s not recognised"
- " use apic=verbose or apic=debug\n", str);
-
return 1;
}
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 80cb3b2..d77e89a 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -970,8 +970,10 @@
* not-overlapping, which is the case
*/
int __init
-e820_all_mapped(unsigned long start, unsigned long end, unsigned type)
+e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
{
+ u64 start = s;
+ u64 end = e;
int i;
for (i = 0; i < e820.nr_map; i++) {
struct e820entry *ei = &e820.map[i];
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index 5e41ee2..f1187dd 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -279,7 +279,7 @@
{
struct cpufreq_freqs *freq = data;
- if (val != CPUFREQ_RESUMECHANGE)
+ if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE)
write_seqlock_irq(&xtime_lock);
if (!ref_freq) {
if (!freq->old){
@@ -312,7 +312,7 @@
}
end:
- if (val != CPUFREQ_RESUMECHANGE)
+ if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE)
write_sequnlock_irq(&xtime_lock);
return 0;
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index ed737ca..5bc2585 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -322,13 +322,31 @@
}
}
}
+
+int sysfs_add_device_to_node(struct sys_device *dev, int nid)
+{
+ struct node *node = &node_devices[nid];
+ return sysfs_create_link(&node->sysdev.kobj, &dev->kobj,
+ kobject_name(&dev->kobj));
+}
+
+void sysfs_remove_device_from_node(struct sys_device *dev, int nid)
+{
+ struct node *node = &node_devices[nid];
+ sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj));
+}
+
#else
static void register_nodes(void)
{
return;
}
+
#endif
+EXPORT_SYMBOL_GPL(sysfs_add_device_to_node);
+EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
+
/* Only valid if CPU is present. */
static ssize_t show_physical_id(struct sys_device *dev, char *buf)
{
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 0a335f3..092355f 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -194,7 +194,7 @@
/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
* info is found.
*/
-static int of_node_to_nid(struct device_node *device)
+static int of_node_to_nid_single(struct device_node *device)
{
int nid = -1;
unsigned int *tmp;
@@ -216,6 +216,28 @@
return nid;
}
+/* Walk the device tree upwards, looking for an associativity id */
+int of_node_to_nid(struct device_node *device)
+{
+ struct device_node *tmp;
+ int nid = -1;
+
+ of_node_get(device);
+ while (device) {
+ nid = of_node_to_nid_single(device);
+ if (nid != -1)
+ break;
+
+ tmp = device;
+ device = of_get_parent(tmp);
+ of_node_put(tmp);
+ }
+ of_node_put(device);
+
+ return nid;
+}
+EXPORT_SYMBOL_GPL(of_node_to_nid);
+
/*
* In theory, the "ibm,associativity" property may contain multiple
* associativity lists because a resource may be multiply connected
@@ -300,7 +322,7 @@
goto out;
}
- nid = of_node_to_nid(cpu);
+ nid = of_node_to_nid_single(cpu);
if (nid < 0 || !node_online(nid))
nid = any_online_node(NODE_MASK_ALL);
@@ -393,7 +415,7 @@
cpu = find_cpu_node(i);
BUG_ON(!cpu);
- nid = of_node_to_nid(cpu);
+ nid = of_node_to_nid_single(cpu);
of_node_put(cpu);
/*
@@ -437,7 +459,7 @@
* have associativity properties. If none, then
* everything goes to default_nid.
*/
- nid = of_node_to_nid(memory);
+ nid = of_node_to_nid_single(memory);
if (nid < 0)
nid = default_nid;
node_set_online(nid);
@@ -776,7 +798,7 @@
ha_new_range:
start = read_n_cells(n_mem_addr_cells, &memcell_buf);
size = read_n_cells(n_mem_size_cells, &memcell_buf);
- nid = of_node_to_nid(memory);
+ nid = of_node_to_nid_single(memory);
/* Domains not present at boot default to 0 */
if (nid < 0 || !node_online(nid))
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index c2a3db8..6a02d51 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -12,7 +12,8 @@
config SPUFS_MMAP
bool
- depends on SPU_FS && SPARSEMEM && !PPC_64K_PAGES
+ depends on SPU_FS && SPARSEMEM
+ select MEMORY_HOTPLUG
default y
endmenu
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index dac5d03..6574b22 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -29,6 +29,8 @@
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/console.h>
+#include <linux/mutex.h>
+#include <linux/memory_hotplug.h>
#include <asm/mmu.h>
#include <asm/processor.h>
@@ -46,6 +48,7 @@
#include <asm/cputable.h>
#include <asm/ppc-pci.h>
#include <asm/irq.h>
+#include <asm/spu.h>
#include "interrupt.h"
#include "iommu.h"
@@ -69,77 +72,6 @@
of_node_put(root);
}
-#ifdef CONFIG_SPARSEMEM
-static int __init find_spu_node_id(struct device_node *spe)
-{
- unsigned int *id;
-#ifdef CONFIG_NUMA
- struct device_node *cpu;
- cpu = spe->parent->parent;
- id = (unsigned int *)get_property(cpu, "node-id", NULL);
-#else
- id = NULL;
-#endif
- return id ? *id : 0;
-}
-
-static void __init cell_spuprop_present(struct device_node *spe,
- const char *prop, int early)
-{
- struct address_prop {
- unsigned long address;
- unsigned int len;
- } __attribute__((packed)) *p;
- int proplen;
-
- unsigned long start_pfn, end_pfn, pfn;
- int node_id;
-
- p = (void*)get_property(spe, prop, &proplen);
- WARN_ON(proplen != sizeof (*p));
-
- node_id = find_spu_node_id(spe);
-
- start_pfn = p->address >> PAGE_SHIFT;
- end_pfn = (p->address + p->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
- /* We need to call memory_present *before* the call to sparse_init,
- but we can initialize the page structs only *after* that call.
- Thus, we're being called twice. */
- if (early)
- memory_present(node_id, start_pfn, end_pfn);
- else {
- /* As the pages backing SPU LS and I/O are outside the range
- of regular memory, their page structs were not initialized
- by free_area_init. Do it here instead. */
- for (pfn = start_pfn; pfn < end_pfn; pfn++) {
- struct page *page = pfn_to_page(pfn);
- set_page_links(page, ZONE_DMA, node_id, pfn);
- init_page_count(page);
- reset_page_mapcount(page);
- SetPageReserved(page);
- INIT_LIST_HEAD(&page->lru);
- }
- }
-}
-
-static void __init cell_spumem_init(int early)
-{
- struct device_node *node;
- for (node = of_find_node_by_type(NULL, "spe");
- node; node = of_find_node_by_type(node, "spe")) {
- cell_spuprop_present(node, "local-store", early);
- cell_spuprop_present(node, "problem", early);
- cell_spuprop_present(node, "priv1", early);
- cell_spuprop_present(node, "priv2", early);
- }
-}
-#else
-static void __init cell_spumem_init(int early)
-{
-}
-#endif
-
static void cell_progress(char *s, unsigned short hex)
{
printk("*** %04x : %s\n", hex, s ? s : "");
@@ -172,8 +104,6 @@
#endif
mmio_nvram_init();
-
- cell_spumem_init(0);
}
/*
@@ -189,8 +119,6 @@
ppc64_interrupt_controller = IC_CELL_PIC;
- cell_spumem_init(1);
-
DBG(" <- cell_init_early()\n");
}
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index ef47a62..ad141fe 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -520,8 +520,50 @@
}
EXPORT_SYMBOL_GPL(spu_irq_setaffinity);
-static void __iomem * __init map_spe_prop(struct device_node *n,
- const char *name)
+static int __init find_spu_node_id(struct device_node *spe)
+{
+ unsigned int *id;
+ struct device_node *cpu;
+ cpu = spe->parent->parent;
+ id = (unsigned int *)get_property(cpu, "node-id", NULL);
+ return id ? *id : 0;
+}
+
+static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
+ const char *prop)
+{
+ static DEFINE_MUTEX(add_spumem_mutex);
+
+ struct address_prop {
+ unsigned long address;
+ unsigned int len;
+ } __attribute__((packed)) *p;
+ int proplen;
+
+ unsigned long start_pfn, nr_pages;
+ struct pglist_data *pgdata;
+ struct zone *zone;
+ int ret;
+
+ p = (void*)get_property(spe, prop, &proplen);
+ WARN_ON(proplen != sizeof (*p));
+
+ start_pfn = p->address >> PAGE_SHIFT;
+ nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ pgdata = NODE_DATA(spu->nid);
+ zone = pgdata->node_zones;
+
+ /* XXX rethink locking here */
+ mutex_lock(&add_spumem_mutex);
+ ret = __add_pages(zone, start_pfn, nr_pages);
+ mutex_unlock(&add_spumem_mutex);
+
+ return ret;
+}
+
+static void __iomem * __init map_spe_prop(struct spu *spu,
+ struct device_node *n, const char *name)
{
struct address_prop {
unsigned long address;
@@ -530,6 +572,8 @@
void *p;
int proplen;
+ void* ret = NULL;
+ int err = 0;
p = get_property(n, name, &proplen);
if (proplen != sizeof (struct address_prop))
@@ -537,7 +581,14 @@
prop = p;
- return ioremap(prop->address, prop->len);
+ err = cell_spuprop_present(spu, n, name);
+ if (err && (err != -EEXIST))
+ goto out;
+
+ ret = ioremap(prop->address, prop->len);
+
+ out:
+ return ret;
}
static void spu_unmap(struct spu *spu)
@@ -548,44 +599,45 @@
iounmap((u8 __iomem *)spu->local_store);
}
-static int __init spu_map_device(struct spu *spu, struct device_node *spe)
+static int __init spu_map_device(struct spu *spu, struct device_node *node)
{
char *prop;
int ret;
ret = -ENODEV;
- prop = get_property(spe, "isrc", NULL);
+ prop = get_property(node, "isrc", NULL);
if (!prop)
goto out;
spu->isrc = *(unsigned int *)prop;
- spu->name = get_property(spe, "name", NULL);
+ spu->name = get_property(node, "name", NULL);
if (!spu->name)
goto out;
- prop = get_property(spe, "local-store", NULL);
+ prop = get_property(node, "local-store", NULL);
if (!prop)
goto out;
spu->local_store_phys = *(unsigned long *)prop;
/* we use local store as ram, not io memory */
- spu->local_store = (void __force *)map_spe_prop(spe, "local-store");
+ spu->local_store = (void __force *)
+ map_spe_prop(spu, node, "local-store");
if (!spu->local_store)
goto out;
- prop = get_property(spe, "problem", NULL);
+ prop = get_property(node, "problem", NULL);
if (!prop)
goto out_unmap;
spu->problem_phys = *(unsigned long *)prop;
- spu->problem= map_spe_prop(spe, "problem");
+ spu->problem= map_spe_prop(spu, node, "problem");
if (!spu->problem)
goto out_unmap;
- spu->priv1= map_spe_prop(spe, "priv1");
+ spu->priv1= map_spe_prop(spu, node, "priv1");
/* priv1 is not available on a hypervisor */
- spu->priv2= map_spe_prop(spe, "priv2");
+ spu->priv2= map_spe_prop(spu, node, "priv2");
if (!spu->priv2)
goto out_unmap;
ret = 0;
@@ -597,17 +649,6 @@
return ret;
}
-static int __init find_spu_node_id(struct device_node *spe)
-{
- unsigned int *id;
- struct device_node *cpu;
-
- cpu = spe->parent->parent;
- id = (unsigned int *)get_property(cpu, "node-id", NULL);
-
- return id ? *id : 0;
-}
-
static int __init create_spu(struct device_node *spe)
{
struct spu *spu;
@@ -624,6 +665,10 @@
goto out_free;
spu->node = find_spu_node_id(spe);
+ spu->nid = of_node_to_nid(spe);
+ if (spu->nid == -1)
+ spu->nid = 0;
+
spu->stop_code = 0;
spu->slb_replace = 0;
spu->mm = NULL;
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index ae1927e..d48cfc7 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -358,8 +358,9 @@
} else {
regs->gprs[14] = (unsigned long)
frame->retcode | PSW_ADDR_AMODE;
- err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
- (u16 __user *)(frame->retcode));
+ if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
+ (u16 __user *)(frame->retcode)))
+ goto give_sigsegv;
}
/* Set up backchain. */
diff --git a/arch/sparc64/mm/tlb.c b/arch/sparc64/mm/tlb.c
index a079cf4..3f10fc9 100644
--- a/arch/sparc64/mm/tlb.c
+++ b/arch/sparc64/mm/tlb.c
@@ -8,6 +8,7 @@
#include <linux/percpu.h>
#include <linux/mm.h>
#include <linux/swap.h>
+#include <linux/preempt.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -24,6 +25,8 @@
{
struct mmu_gather *mp = &__get_cpu_var(mmu_gathers);
+ preempt_disable();
+
if (mp->tlb_nr) {
flush_tsb_user(mp);
@@ -38,6 +41,8 @@
}
mp->tlb_nr = 0;
}
+
+ preempt_enable();
}
void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig)
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 05fbb20..76e85bb 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -57,20 +57,6 @@
chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
here.
-config HOST_2G_2G
- bool "2G/2G host address space split"
- default n
- depends on MODE_TT
- help
- This is needed when the host on which you run has a 2G/2G memory
- split, instead of the customary 3G/1G.
-
- Note that to enable such a host
- configuration, which makes sense only in some cases, you need special
- host patches.
-
- So, if you do not know what to do here, say 'N'.
-
config KERNEL_HALF_GIGS
int "Kernel address space size (in .5G units)"
default "1"
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386
index 85e6a55..f6eb72d 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -16,6 +16,19 @@
bool
default y
+config HOST_2G_2G
+ bool "2G/2G host address space split"
+ default n
+ help
+ This is needed when the host on which you run has a 2G/2G memory
+ split, instead of the customary 3G/1G.
+
+ Note that to enable such a host
+ configuration, which makes sense only in some cases, you need special
+ host patches.
+
+ So, if you do not know what to do here, say 'N'.
+
config TOP_ADDR
hex
default 0xc0000000 if !HOST_2G_2G
@@ -35,11 +48,13 @@
config STUB_CODE
hex
- default 0xbfffe000
+ default 0xbfffe000 if !HOST_2G_2G
+ default 0x7fffe000 if HOST_2G_2G
config STUB_DATA
hex
- default 0xbffff000
+ default 0xbffff000 if !HOST_2G_2G
+ default 0x7ffff000 if HOST_2G_2G
config STUB_START
hex
diff --git a/arch/um/Makefile b/arch/um/Makefile
index a508e7a..f6ad832 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -96,7 +96,8 @@
all: linux
linux: vmlinux
- ln -f $< $@
+ @echo ' LINK $@'
+ $(Q)ln -f $< $@
define archhelp
echo '* linux - Binary kernel image (./linux) - for backward'
@@ -117,6 +118,10 @@
LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
+CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \
+ $(call cc-option, -fno-stack-protector,) \
+ $(call cc-option, -fno-stack-protector-all,)
+
CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT
CONFIG_KERNEL_STACK_ORDER ?= 2
STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
@@ -203,8 +208,8 @@
$(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h
$(call filechk,umlconfig)
-$(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c
- $(CC) $(USER_CFLAGS) -S -o $@ $<
+$(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s: FORCE
+ $(Q)$(MAKE) $(build)=$(ARCH_DIR)/sys-$(SUBARCH) $@
define filechk_gen-asm-offsets
(set -e; \
@@ -219,13 +224,11 @@
echo ""; )
endef
-$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/user-offsets.s
+$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s
$(call filechk,gen-asm-offsets)
-CLEAN_FILES += $(ARCH_DIR)/user-offsets.s
-
$(ARCH_DIR)/include/kern_constants.h: $(objtree)/$(ARCH_DIR)/include
@echo ' SYMLINK $@'
- $(Q) ln -sf ../../../include/asm-um/asm-offsets.h $@
+ $(Q)ln -sf ../../../include/asm-um/asm-offsets.h $@
-export SUBARCH USER_CFLAGS OS
+export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS
diff --git a/arch/um/defconfig b/arch/um/defconfig
index 80d30d1..402a74d 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -1,14 +1,13 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc6-mm1
-# Tue Jun 14 18:22:21 2005
+# Linux kernel version: 2.6.17-rc3
+# Fri Apr 28 09:31:20 2006
#
CONFIG_GENERIC_HARDIRQS=y
CONFIG_UML=y
CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_IRQ_RELEASE_METHOD=y
#
# UML-specific options
@@ -16,8 +15,50 @@
# CONFIG_MODE_TT is not set
# CONFIG_STATIC_LINK is not set
CONFIG_MODE_SKAS=y
+
+#
+# Host processor type and features
+#
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+CONFIG_M686=y
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+# CONFIG_X86_GENERIC is not set
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=5
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_TSC=y
CONFIG_UML_X86=y
# CONFIG_64BIT is not set
+CONFIG_SEMAPHORE_SLEEPERS=y
+# CONFIG_HOST_2G_2G is not set
CONFIG_TOP_ADDR=0xc0000000
# CONFIG_3_LEVEL_PGTABLES is not set
CONFIG_STUB_CODE=0xbfffe000
@@ -25,22 +66,24 @@
CONFIG_STUB_START=0xbfffe000
CONFIG_ARCH_HAS_SC_SIGNALS=y
CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_LD_SCRIPT_DYN=y
CONFIG_NET=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
# CONFIG_HOSTFS is not set
+# CONFIG_HPPFS is not set
CONFIG_MCONSOLE=y
# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_HOST_2G_2G is not set
CONFIG_NEST_LEVEL=0
-CONFIG_KERNEL_HALF_GIGS=1
# CONFIG_HIGHMEM is not set
CONFIG_KERNEL_STACK_ORDER=2
CONFIG_UML_REAL_TIME_CLOCK=y
@@ -49,7 +92,6 @@
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -57,6 +99,7 @@
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -64,26 +107,28 @@
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
+CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -91,18 +136,43 @@
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
#
-# Generic Driver Options
+# Block layer
#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_UBD=y
+# CONFIG_BLK_DEV_UBD_SYNC is not set
+CONFIG_BLK_DEV_COW_COMMON=y
+# CONFIG_MMAPPER is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_ATA_OVER_ETH is not set
#
# Character Devices
@@ -127,50 +197,23 @@
CONFIG_SOUND=m
CONFIG_HOSTAUDIO=m
CONFIG_UML_RANDOM=y
-# CONFIG_MMAPPER is not set
#
-# Block devices
+# Generic Driver Options
#
-CONFIG_BLK_DEV_UBD=y
-CONFIG_BLK_DEV_UBD_SYNC=y
-CONFIG_BLK_DEV_COW_COMMON=y
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-CONFIG_NETDEVICES=y
-
-#
-# UML Network Devices
-#
-CONFIG_UML_NET=y
-CONFIG_UML_NET_ETHERTAP=y
-CONFIG_UML_NET_TUNTAP=y
-CONFIG_UML_NET_SLIP=y
-CONFIG_UML_NET_DAEMON=y
-CONFIG_UML_NET_MCAST=y
-CONFIG_UML_NET_SLIRP=y
-
-#
-# Networking support
+# Networking
#
#
# Networking options
#
+# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -178,6 +221,7 @@
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
@@ -186,27 +230,31 @@
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETFILTER is not set
#
-# TCP congestion control
+# DCCP Configuration (EXPERIMENTAL)
#
-CONFIG_TCP_CONG_BIC=y
-CONFIG_TCP_CONG_WESTWOOD=y
-CONFIG_TCP_CONG_HTCP=y
-# CONFIG_TCP_CONG_HSTCP is not set
-# CONFIG_TCP_CONG_HYBLA is not set
-# CONFIG_TCP_CONG_VEGAS is not set
-# CONFIG_TCP_CONG_SCALABLE is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
@@ -224,27 +272,47 @@
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_KGDBOE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NETPOLL_RX is not set
-# CONFIG_NETPOLL_TRAP is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_IEEE80211 is not set
+
+#
+# UML Network Devices
+#
+CONFIG_UML_NET=y
+CONFIG_UML_NET_ETHERTAP=y
+CONFIG_UML_NET_TUNTAP=y
+CONFIG_UML_NET_SLIP=y
+CONFIG_UML_NET_DAEMON=y
+CONFIG_UML_NET_MCAST=y
+# CONFIG_UML_NET_PCAP is not set
+CONFIG_UML_NET_SLIRP=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
#
+# PHY device support
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
# Wan interfaces
#
# CONFIG_WAN is not set
@@ -263,6 +331,13 @@
# CONFIG_SLIP_MODE_SLIP6 is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
#
# File systems
@@ -274,17 +349,14 @@
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
-# CONFIG_REISER4_FS is not set
CONFIG_REISERFS_FS=y
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_REISERFS_FS_XATTR is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
@@ -295,11 +367,6 @@
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
# CONFIG_FUSE_FS is not set
#
@@ -323,14 +390,10 @@
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
-# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -430,6 +493,7 @@
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=m
# CONFIG_LIBCRC32C is not set
@@ -448,12 +512,18 @@
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SLAB_LEAK is not set
+# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_GPROF is not set
# CONFIG_GCOV is not set
# CONFIG_SYSCALL_DEBUG is not set
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index 6ab852b..0ec4052 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -100,7 +100,7 @@
__u32 alignment;
__u32 cow_format;
char backing_file[PATH_LEN_V3];
-} __attribute__((packed));
+};
/* COW format definitions - for now, we have only the usual COW bitmap */
#define COW_BITMAP 0
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index c39ea3a..2ffda01 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -89,16 +89,18 @@
struct irq_fd *irq_fd;
int n;
- if(smp_sigio_handler()) return;
- while(1){
+ if (smp_sigio_handler())
+ return;
+
+ while (1) {
n = os_waiting_for_events(active_fds);
if (n <= 0) {
if(n == -EINTR) continue;
else break;
}
- for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
- if(irq_fd->current_events != 0){
+ for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
+ if (irq_fd->current_events != 0) {
irq_fd->current_events = 0;
do_IRQ(irq_fd->irq, regs);
}
@@ -110,19 +112,17 @@
static void maybe_sigio_broken(int fd, int type)
{
- if(os_isatty(fd)){
- if((type == IRQ_WRITE) && !pty_output_sigio){
+ if (os_isatty(fd)) {
+ if ((type == IRQ_WRITE) && !pty_output_sigio) {
write_sigio_workaround();
add_sigio_fd(fd, 0);
- }
- else if((type == IRQ_READ) && !pty_close_sigio){
+ } else if ((type == IRQ_READ) && !pty_close_sigio) {
write_sigio_workaround();
add_sigio_fd(fd, 1);
}
}
}
-
int activate_fd(int irq, int fd, int type, void *dev_id)
{
struct pollfd *tmp_pfd;
@@ -132,16 +132,18 @@
pid = os_getpid();
err = os_set_fd_async(fd, pid);
- if(err < 0)
+ if (err < 0)
goto out;
new_fd = um_kmalloc(sizeof(*new_fd));
err = -ENOMEM;
- if(new_fd == NULL)
+ if (new_fd == NULL)
goto out;
- if(type == IRQ_READ) events = UM_POLLIN | UM_POLLPRI;
- else events = UM_POLLOUT;
+ if (type == IRQ_READ)
+ events = UM_POLLIN | UM_POLLPRI;
+ else
+ events = UM_POLLOUT;
*new_fd = ((struct irq_fd) { .next = NULL,
.id = dev_id,
.fd = fd,
@@ -165,8 +167,8 @@
* a semaphore.
*/
flags = irq_lock();
- for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
- if((irq_fd->fd == fd) && (irq_fd->type == type)){
+ for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
+ if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
printk("Registering fd %d twice\n", fd);
printk("Irqs : %d, %d\n", irq_fd->irq, irq);
printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id);
@@ -175,13 +177,13 @@
}
/*-------------*/
- if(type == IRQ_WRITE)
+ if (type == IRQ_WRITE)
fd = -1;
tmp_pfd = NULL;
n = 0;
- while(1){
+ while (1) {
n = os_create_pollfd(fd, events, tmp_pfd, n);
if (n == 0)
break;
@@ -198,10 +200,8 @@
* then we free the buffer tmp_fds and try again.
*/
irq_unlock(flags);
- if (tmp_pfd != NULL) {
- kfree(tmp_pfd);
- tmp_pfd = NULL;
- }
+ kfree(tmp_pfd);
+ tmp_pfd = NULL;
tmp_pfd = um_kmalloc(n);
if (tmp_pfd == NULL)
@@ -249,7 +249,7 @@
{
struct irq_and_dev *data = d;
- return((irq->irq == data->irq) && (irq->id == data->dev));
+ return ((irq->irq == data->irq) && (irq->id == data->dev));
}
void free_irq_by_irq_and_dev(unsigned int irq, void *dev)
@@ -262,7 +262,7 @@
static int same_fd(struct irq_fd *irq, void *fd)
{
- return(irq->fd == *((int *) fd));
+ return (irq->fd == *((int *)fd));
}
void free_irq_by_fd(int fd)
@@ -276,16 +276,17 @@
int i = 0;
int fdi;
- for(irq=active_fds; irq != NULL; irq = irq->next){
- if((irq->fd == fd) && (irq->irq == irqnum)) break;
+ for (irq = active_fds; irq != NULL; irq = irq->next) {
+ if ((irq->fd == fd) && (irq->irq == irqnum))
+ break;
i++;
}
- if(irq == NULL){
+ if (irq == NULL) {
printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
goto out;
}
fdi = os_get_pollfd(i);
- if((fdi != -1) && (fdi != fd)){
+ if ((fdi != -1) && (fdi != fd)) {
printk("find_irq_by_fd - mismatch between active_fds and "
"pollfds, fd %d vs %d, need %d\n", irq->fd,
fdi, fd);
@@ -294,7 +295,7 @@
}
*index_out = i;
out:
- return(irq);
+ return irq;
}
void reactivate_fd(int fd, int irqnum)
@@ -305,7 +306,7 @@
flags = irq_lock();
irq = find_irq_by_fd(fd, irqnum, &i);
- if(irq == NULL){
+ if (irq == NULL) {
irq_unlock(flags);
return;
}
@@ -326,7 +327,7 @@
flags = irq_lock();
irq = find_irq_by_fd(fd, irqnum, &i);
- if(irq == NULL)
+ if (irq == NULL)
goto out;
os_set_pollfd(i, -1);
out:
@@ -338,15 +339,15 @@
struct irq_fd *irq;
int err;
- for(irq=active_fds;irq != NULL;irq = irq->next){
+ for (irq = active_fds; irq != NULL; irq = irq->next) {
err = os_clear_fd_async(irq->fd);
- if(err)
- return(err);
+ if (err)
+ return err;
}
/* If there is a signal already queued, after unblocking ignore it */
os_set_ioignore();
- return(0);
+ return 0;
}
void forward_interrupts(int pid)
@@ -356,9 +357,9 @@
int err;
flags = irq_lock();
- for(irq=active_fds;irq != NULL;irq = irq->next){
+ for (irq = active_fds; irq != NULL; irq = irq->next) {
err = os_set_owner(irq->fd, pid);
- if(err < 0){
+ if (err < 0) {
/* XXX Just remove the irq rather than
* print out an infinite stream of these
*/
@@ -379,7 +380,7 @@
unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
{
irq_enter();
- __do_IRQ(irq, (struct pt_regs *) regs);
+ __do_IRQ(irq, (struct pt_regs *)regs);
irq_exit();
return 1;
}
@@ -392,12 +393,12 @@
int err;
err = request_irq(irq, handler, irqflags, devname, dev_id);
- if(err)
- return(err);
+ if (err)
+ return err;
- if(fd != -1)
+ if (fd != -1)
err = activate_fd(irq, fd, type, dev_id);
- return(err);
+ return err;
}
EXPORT_SYMBOL(um_request_irq);
EXPORT_SYMBOL(reactivate_fd);
@@ -409,7 +410,7 @@
unsigned long flags;
spin_lock_irqsave(&irq_spinlock, flags);
- return(flags);
+ return flags;
}
void irq_unlock(unsigned long flags)
@@ -452,7 +453,7 @@
irq_desc[TIMER_IRQ].depth = 1;
irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
enable_irq(TIMER_IRQ);
- for(i=1;i<NR_IRQS;i++){
+ for (i = 1; i < NR_IRQS; i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = NULL;
irq_desc[i].depth = 1;
@@ -467,7 +468,7 @@
int fds[2], err;
err = os_pipe(fds, 1, 1);
- if(err){
+ if (err) {
printk("init_aio_irq - os_pipe failed, err = %d\n", -err);
goto out;
}
@@ -475,7 +476,7 @@
err = um_request_irq(irq, fds[0], IRQ_READ, handler,
SA_INTERRUPT | SA_SAMPLE_RANDOM, name,
(void *) (long) fds[0]);
- if(err){
+ if (err) {
printk("init_aio_irq - : um_request_irq failed, err = %d\n",
err);
goto out_close;
@@ -488,5 +489,5 @@
os_close_file(fds[0]);
os_close_file(fds[1]);
out:
- return(err);
+ return err;
}
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 0500800..fc0f0b0 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -407,6 +407,8 @@
*len_out = region->size;
return(region->virt);
}
+
+ region = region->next;
}
return(0);
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index 57181a9..ea3a8e4 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -6,9 +6,11 @@
obj-y := clone.o exec_kern.o mem.o mmu.o process_kern.o \
syscall.o tlb.o uaccess.o
-USER_OBJS := clone.o
+# clone.o is in the stub, so it can't be built with profiling
+# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work ->
+# disable it
+
+CFLAGS_clone.o := $(CFLAGS_NO_HARDENING)
+UNPROFILE_OBJS := clone.o
include arch/um/scripts/Makefile.rules
-
-# clone.o is in the stub, so it can't be built with profiling
-$(obj)/clone.o : c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS))
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 3bd10de..0925133 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -171,7 +171,7 @@
flags = fcntl(master, F_GETFL);
if(flags < 0)
- return errno;
+ return -errno;
if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
(fcntl(master, F_SETOWN, os_getpid()) < 0))
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index e599be4..3788d45 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -29,21 +29,21 @@
int i, n, err;
n = poll(pollfds, pollfds_num, 0);
- if(n < 0){
+ if (n < 0) {
err = -errno;
- if(errno != EINTR)
+ if (errno != EINTR)
printk("sigio_handler: os_waiting_for_events:"
" poll returned %d, errno = %d\n", n, errno);
return err;
}
- if(n == 0)
+ if (n == 0)
return 0;
irq_fd = active_fds;
- for(i = 0; i < pollfds_num; i++){
- if(pollfds[i].revents != 0){
+ for (i = 0; i < pollfds_num; i++) {
+ if (pollfds[i].revents != 0) {
irq_fd->current_events = pollfds[i].revents;
pollfds[i].fd = -1;
}
@@ -54,7 +54,7 @@
int os_isatty(int fd)
{
- return(isatty(fd));
+ return isatty(fd);
}
int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds)
@@ -65,7 +65,7 @@
return((pollfds_size + 1) * sizeof(pollfds[0]));
}
- if(pollfds != NULL){
+ if (pollfds != NULL) {
memcpy(tmp_pfd, pollfds,
sizeof(pollfds[0]) * pollfds_size);
/* remove old pollfds */
@@ -73,18 +73,15 @@
}
pollfds = tmp_pfd;
pollfds_size++;
- } else {
- /* remove not used tmp_pfd */
- if (tmp_pfd != NULL)
- kfree(tmp_pfd);
- }
+ } else
+ kfree(tmp_pfd); /* remove not used tmp_pfd */
- pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
- .events = events,
- .revents = 0 });
+ pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
+ .events = events,
+ .revents = 0 });
pollfds_num++;
- return(0);
+ return 0;
}
void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
@@ -94,11 +91,11 @@
int i = 0;
prev = &active_fds;
- while(*prev != NULL){
- if((*test)(*prev, arg)){
+ while (*prev != NULL) {
+ if ((*test)(*prev, arg)) {
struct irq_fd *old_fd = *prev;
- if((pollfds[i].fd != -1) &&
- (pollfds[i].fd != (*prev)->fd)){
+ if ((pollfds[i].fd != -1) &&
+ (pollfds[i].fd != (*prev)->fd)) {
printk("os_free_irq_by_cb - mismatch between "
"active_fds and pollfds, fd %d vs %d\n",
(*prev)->fd, pollfds[i].fd);
@@ -110,7 +107,6 @@
/* This moves the *whole* array after pollfds[i]
* (though it doesn't spot as such)!
*/
-
memmove(&pollfds[i], &pollfds[i + 1],
(pollfds_num - i) * sizeof(pollfds[0]));
if(*last_irq_ptr2 == &old_fd->next)
@@ -129,10 +125,9 @@
return;
}
-
int os_get_pollfd(int i)
{
- return(pollfds[i].fd);
+ return pollfds[i].fd;
}
void os_set_pollfd(int i, int fd)
@@ -151,8 +146,10 @@
int flags;
flags = on_sigstack ? SA_ONSTACK : 0;
- if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
- else h = boot_timer_handler;
+ if (timer_irq_inited)
+ h = (__sighandler_t)alarm_handler;
+ else
+ h = boot_timer_handler;
set_handler(SIGVTALRM, h, flags | SA_RESTART,
SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 2878e89..3a0ac38 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -74,6 +74,34 @@
exit(1);
}
+#define UML_LIB_PATH ":/usr/lib/uml"
+
+static void setup_env_path(void)
+{
+ char *new_path = NULL;
+ char *old_path = NULL;
+ int path_len = 0;
+
+ old_path = getenv("PATH");
+ /* if no PATH variable is set or it has an empty value
+ * just use the default + /usr/lib/uml
+ */
+ if (!old_path || (path_len = strlen(old_path)) == 0) {
+ putenv("PATH=:/bin:/usr/bin/" UML_LIB_PATH);
+ return;
+ }
+
+ /* append /usr/lib/uml to the existing path */
+ path_len += strlen("PATH=" UML_LIB_PATH) + 1;
+ new_path = malloc(path_len);
+ if (!new_path) {
+ perror("coudn't malloc to set a new PATH");
+ return;
+ }
+ snprintf(new_path, path_len, "PATH=%s" UML_LIB_PATH, old_path);
+ putenv(new_path);
+}
+
extern int uml_exitcode;
extern void scan_elf_aux( char **envp);
@@ -114,6 +142,8 @@
set_stklim();
+ setup_env_path();
+
new_argv = malloc((argc + 1) * sizeof(char *));
if(new_argv == NULL){
perror("Mallocing argv");
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 3505f44..233be2f 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -206,29 +206,36 @@
int can_drop_memory(void)
{
void *addr;
- int fd;
+ int fd, ok = 0;
printk("Checking host MADV_REMOVE support...");
fd = create_mem_file(UM_KERN_PAGE_SIZE);
if(fd < 0){
printk("Creating test memory file failed, err = %d\n", -fd);
- return 0;
+ goto out;
}
addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if(addr == MAP_FAILED){
printk("Mapping test memory file failed, err = %d\n", -errno);
- return 0;
+ goto out_close;
}
if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){
printk("MADV_REMOVE failed, err = %d\n", -errno);
- return 0;
+ goto out_unmap;
}
printk("OK\n");
- return 1;
+ ok = 1;
+
+out_unmap:
+ munmap(addr, UM_KERN_PAGE_SIZE);
+out_close:
+ close(fd);
+out:
+ return ok;
}
void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 0776bc1..bd89c6b 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -344,12 +344,12 @@
err = ptrace_setregs(pid, regs);
if(err < 0)
panic("copy_context_skas0 : PTRACE_SETREGS failed, "
- "pid = %d, errno = %d\n", pid, errno);
+ "pid = %d, errno = %d\n", pid, -err);
err = ptrace_setfpregs(pid, fp_regs);
if(err < 0)
panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
- "pid = %d, errno = %d\n", pid, errno);
+ "pid = %d, errno = %d\n", pid, -err);
/* set a well known return code for detection of child write failure */
child_data->err = 12345678;
@@ -362,7 +362,7 @@
pid = data->err;
if(pid < 0)
panic("copy_context_skas0 - stub-parent reports error %d\n",
- pid);
+ -pid);
/* Wait, until child has finished too: read child's result from
* child's stack and check it.
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 7a6f6b9..516f66d 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -104,7 +104,7 @@
err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
if(err)
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
- err);
+ errno);
errno = 0;
err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
@@ -119,7 +119,7 @@
err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
if(err)
panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
- err);
+ errno);
}
void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index 001941f..becd898 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -62,12 +62,12 @@
err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
if(err)
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
- err);
+ errno);
err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
if(err)
panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
- err);
+ errno);
}
void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index 34bfc1b..362db05 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -178,14 +178,14 @@
fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644);
if(fd < 0){
printk("Open of machine pid file \"%s\" failed: %s\n",
- file, strerror(-fd));
+ file, strerror(errno));
return;
}
snprintf(pid, sizeof(pid), "%d\n", getpid());
n = write(fd, pid, strlen(pid));
if(n != strlen(pid))
- printk("Write of pid file failed - err = %d\n", -n);
+ printk("Write of pid file failed - err = %d\n", errno);
close(fd);
}
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
index 2598158..3f33165 100644
--- a/arch/um/os-Linux/user_syms.c
+++ b/arch/um/os-Linux/user_syms.c
@@ -96,6 +96,13 @@
EXPORT_SYMBOL_PROTO(fsync);
EXPORT_SYMBOL_PROTO(fdatasync);
+/* Export symbols used by GCC for the stack protector. */
+extern void __stack_smash_handler(void *) __attribute__((weak));
+EXPORT_SYMBOL(__stack_smash_handler);
+
+extern long __guard __attribute__((weak));
+EXPORT_SYMBOL(__guard);
+
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 5e7a9c3..1347dc6 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -7,11 +7,19 @@
USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
-$(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \
- c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@))
+$(USER_OBJS:.o=.%): \
+ c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(*F).o)
$(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
-Dunix -D__unix__ -D__$(SUBARCH)__
+# These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of
+# using it directly.
+UNPROFILE_OBJS := $(foreach file,$(UNPROFILE_OBJS),$(obj)/$(file))
+
+$(UNPROFILE_OBJS:.o=.%): \
+ c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(*F).o)
+$(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
+ -Dunix -D__unix__ -D__$(SUBARCH)__
# The stubs and unmap.o can't try to call mcount or update basic block data
define unprofile
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 98b20b7..374d61a 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -8,11 +8,16 @@
subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o
subarch-obj-$(CONFIG_MODULES) += kernel/module.o
-USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o stub_segv.o
+USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
-include arch/um/scripts/Makefile.rules
+USER_OBJS += user-offsets.s
+extra-y += user-offsets.s
extra-$(CONFIG_MODE_TT) += unmap.o
-$(obj)/stub_segv.o $(obj)/unmap.o: \
- _c_flags = $(call unprofile,$(CFLAGS))
+UNPROFILE_OBJS := stub_segv.o
+CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING)
+
+include arch/um/scripts/Makefile.rules
+
+$(obj)/unmap.%: _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index b5fc22b..c19794d 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -16,11 +16,16 @@
ldt-y = ../sys-i386/ldt.o
-USER_OBJS := ptrace_user.o sigcontext.o stub_segv.o
+USER_OBJS := ptrace_user.o sigcontext.o
-include arch/um/scripts/Makefile.rules
+USER_OBJS += user-offsets.s
+extra-y += user-offsets.s
extra-$(CONFIG_MODE_TT) += unmap.o
-$(obj)/stub_segv.o $(obj)/unmap.o: \
- _c_flags = $(call unprofile,$(CFLAGS))
+UNPROFILE_OBJS := stub_segv.o
+CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING)
+
+include arch/um/scripts/Makefile.rules
+
+$(obj)/unmap.%: _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 57fc37e..5a92fed 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -695,4 +695,5 @@
.quad sys_splice
.quad sys_sync_file_range
.quad sys_tee
+ .quad compat_sys_vmsplice
ia32_syscall_end:
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 759070c..ebc3c33 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -1426,3 +1426,22 @@
.show = show_cpuinfo,
};
+#ifdef CONFIG_INPUT_PCSPKR
+#include <linux/platform_device.h>
+static __init int add_pcspkr(void)
+{
+ struct platform_device *pd;
+ int ret;
+
+ pd = platform_device_alloc("pcspkr", -1);
+ if (!pd)
+ return -ENOMEM;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ platform_device_put(pd);
+
+ return ret;
+}
+device_initcall(add_pcspkr);
+#endif
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index d3a2bc3..588fca5 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -200,13 +200,13 @@
/* first test allows optimizer to nuke this case for 32-bit machines */
if (sizeof (int) != sizeof (long) && count == sizeof (unsigned int)) {
unsigned int uidata = data;
- retval = put_user(uidata, (unsigned long __user *)buf);
+ retval = put_user(uidata, (unsigned int __user *)buf) ?:
+ sizeof(unsigned int);
}
else {
- retval = put_user(data, (unsigned long __user *)buf);
+ retval = put_user(data, (unsigned long __user *)buf) ?:
+ sizeof(unsigned long);
}
- if (!retval)
- retval = sizeof(unsigned long);
out:
current->state = TASK_RUNNING;
remove_wait_queue(&gen_rtc_wait, &wait);
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 935670a..5755b7e 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -860,9 +860,32 @@
}
/* by default, 300ms interval for combination release */
-static long brl_timeout = 300;
-MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for combination on first release, < 0 for dead characters)");
-module_param(brl_timeout, long, 0644);
+static unsigned brl_timeout = 300;
+MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)");
+module_param(brl_timeout, uint, 0644);
+
+static unsigned brl_nbchords = 1;
+MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");
+module_param(brl_nbchords, uint, 0644);
+
+static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag, struct pt_regs *regs)
+{
+ static unsigned long chords;
+ static unsigned committed;
+
+ if (!brl_nbchords)
+ k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag, regs);
+ else {
+ committed |= pattern;
+ chords++;
+ if (chords == brl_nbchords) {
+ k_unicode(vc, BRL_UC_ROW | committed, up_flag, regs);
+ chords = 0;
+ committed = 0;
+ }
+ }
+}
+
static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
{
static unsigned pressed,committing;
@@ -882,11 +905,6 @@
if (value > 8)
return;
- if (brl_timeout < 0) {
- k_deadunicode(vc, BRL_UC_ROW | (1 << (value - 1)), up_flag, regs);
- return;
- }
-
if (up_flag) {
if (brl_timeout) {
if (!committing ||
@@ -897,13 +915,13 @@
pressed &= ~(1 << (value - 1));
if (!pressed) {
if (committing) {
- k_unicode(vc, BRL_UC_ROW | committing, 0, regs);
+ k_brlcommit(vc, committing, 0, regs);
committing = 0;
}
}
} else {
if (committing) {
- k_unicode(vc, BRL_UC_ROW | committing, 0, regs);
+ k_brlcommit(vc, committing, 0, regs);
committing = 0;
}
pressed &= ~(1 << (value - 1));
diff --git a/drivers/infiniband/hw/ipath/ipath_debug.h b/drivers/infiniband/hw/ipath/ipath_debug.h
index 593e289..4676238 100644
--- a/drivers/infiniband/hw/ipath/ipath_debug.h
+++ b/drivers/infiniband/hw/ipath/ipath_debug.h
@@ -60,11 +60,11 @@
#define __IPATH_KERNEL_SEND 0x2000 /* use kernel mode send */
#define __IPATH_EPKTDBG 0x4000 /* print ethernet packet data */
#define __IPATH_SMADBG 0x8000 /* sma packet debug */
-#define __IPATH_IPATHDBG 0x10000 /* Ethernet (IPATH) general debug on */
-#define __IPATH_IPATHWARN 0x20000 /* Ethernet (IPATH) warnings on */
-#define __IPATH_IPATHERR 0x40000 /* Ethernet (IPATH) errors on */
-#define __IPATH_IPATHPD 0x80000 /* Ethernet (IPATH) packet dump on */
-#define __IPATH_IPATHTABLE 0x100000 /* Ethernet (IPATH) table dump on */
+#define __IPATH_IPATHDBG 0x10000 /* Ethernet (IPATH) gen debug */
+#define __IPATH_IPATHWARN 0x20000 /* Ethernet (IPATH) warnings */
+#define __IPATH_IPATHERR 0x40000 /* Ethernet (IPATH) errors */
+#define __IPATH_IPATHPD 0x80000 /* Ethernet (IPATH) packet dump */
+#define __IPATH_IPATHTABLE 0x100000 /* Ethernet (IPATH) table dump */
#else /* _IPATH_DEBUGGING */
@@ -79,11 +79,12 @@
#define __IPATH_TRSAMPLE 0x0 /* generate trace buffer sample entries */
#define __IPATH_VERBDBG 0x0 /* very verbose debug */
#define __IPATH_PKTDBG 0x0 /* print packet data */
-#define __IPATH_PROCDBG 0x0 /* print process startup (init)/exit messages */
+#define __IPATH_PROCDBG 0x0 /* process startup (init)/exit messages */
/* print mmap/nopage stuff, not using VDBG any more */
#define __IPATH_MMDBG 0x0
#define __IPATH_EPKTDBG 0x0 /* print ethernet packet data */
-#define __IPATH_SMADBG 0x0 /* print process startup (init)/exit messages */#define __IPATH_IPATHDBG 0x0 /* Ethernet (IPATH) table dump on */
+#define __IPATH_SMADBG 0x0 /* process startup (init)/exit messages */
+#define __IPATH_IPATHDBG 0x0 /* Ethernet (IPATH) table dump on */
#define __IPATH_IPATHWARN 0x0 /* Ethernet (IPATH) warnings on */
#define __IPATH_IPATHERR 0x0 /* Ethernet (IPATH) errors on */
#define __IPATH_IPATHPD 0x0 /* Ethernet (IPATH) packet dump on */
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c
index 7d3fb69..28ddceb 100644
--- a/drivers/infiniband/hw/ipath/ipath_diag.c
+++ b/drivers/infiniband/hw/ipath/ipath_diag.c
@@ -277,13 +277,14 @@
bail:
spin_unlock_irqrestore(&ipath_devs_lock, flags);
- mutex_unlock(&ipath_mutex);
/* Only expose a way to reset the device if we
make it into diag mode. */
if (ret == 0)
ipath_expose_reset(&dd->pcidev->dev);
+ mutex_unlock(&ipath_mutex);
+
return ret;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index e7617c3..398add4 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -418,9 +418,19 @@
ret = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
if (ret) {
- dev_info(&pdev->dev, "pci_set_dma_mask unit %u "
- "fails: %d\n", dd->ipath_unit, ret);
- goto bail_regions;
+ /*
+ * if the 64 bit setup fails, try 32 bit. Some systems
+ * do not setup 64 bit maps on systems with 2GB or less
+ * memory installed.
+ */
+ ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (ret) {
+ dev_info(&pdev->dev, "pci_set_dma_mask unit %u "
+ "fails: %d\n", dd->ipath_unit, ret);
+ goto bail_regions;
+ }
+ else
+ ipath_dbg("No 64bit DMA mask, used 32 bit mask\n");
}
pci_set_master(pdev);
@@ -1949,7 +1959,7 @@
}
if (dd->ipath_pd)
- for (i = 1; i < dd->ipath_portcnt; i++) {
+ for (i = 1; i < dd->ipath_cfgports; i++) {
if (dd->ipath_pd[i] && dd->ipath_pd[i]->port_cnt) {
ipath_dbg("unit %u port %d is in use "
"(PID %u cmd %s), can't reset\n",
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 2823ff9..16f640e 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -53,13 +53,19 @@
/*
* Number of buffers reserved for driver (layered drivers and SMA
- * send). Reserved at end of buffer list.
+ * send). Reserved at end of buffer list. Initialized based on
+ * number of PIO buffers if not set via module interface.
+ * The problem with this is that it's global, but we'll use different
+ * numbers for different chip types. So the default value is not
+ * very useful. I've redefined it for the 1.3 release so that it's
+ * zero unless set by the user to something else, in which case we
+ * try to respect it.
*/
-static ushort ipath_kpiobufs = 32;
+static ushort ipath_kpiobufs;
static int ipath_set_kpiobufs(const char *val, struct kernel_param *kp);
-module_param_call(kpiobufs, ipath_set_kpiobufs, param_get_uint,
+module_param_call(kpiobufs, ipath_set_kpiobufs, param_get_ushort,
&ipath_kpiobufs, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(kpiobufs, "Set number of PIO buffers for driver");
@@ -531,8 +537,11 @@
* Don't clear ipath_flags as 8bit mode was set before
* entering this func. However, we do set the linkstate to
* unknown, so we can watch for a transition.
+ * PRESENT is set because we want register reads to work,
+ * and the kernel infrastructure saw it in config space;
+ * We clear it if we have failures.
*/
- dd->ipath_flags |= IPATH_LINKUNK;
+ dd->ipath_flags |= IPATH_LINKUNK | IPATH_PRESENT;
dd->ipath_flags &= ~(IPATH_LINKACTIVE | IPATH_LINKARMED |
IPATH_LINKDOWN | IPATH_LINKINIT);
@@ -560,6 +569,7 @@
|| (dd->ipath_uregbase & 0xffffffff) == 0xffffffff) {
ipath_dev_err(dd, "Register read failures from chip, "
"giving up initialization\n");
+ dd->ipath_flags &= ~IPATH_PRESENT;
ret = -ENODEV;
goto done;
}
@@ -682,16 +692,14 @@
*/
dd->ipath_pioavregs = ALIGN(val, sizeof(u64) * BITS_PER_BYTE / 2)
/ (sizeof(u64) * BITS_PER_BYTE / 2);
- if (!ipath_kpiobufs) /* have to have at least 1, for SMA */
- kpiobufs = ipath_kpiobufs = 1;
- else if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) <
- (dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT)) {
- dev_info(&dd->pcidev->dev, "Too few PIO buffers (%u) "
- "for %u ports to have %u each!\n",
- dd->ipath_piobcnt2k + dd->ipath_piobcnt4k,
- dd->ipath_cfgports, IPATH_MIN_USER_PORT_BUFCNT);
- kpiobufs = 1; /* reserve just the minimum for SMA/ether */
- } else
+ if (ipath_kpiobufs == 0) {
+ /* not set by user, or set explictly to default */
+ if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) > 128)
+ kpiobufs = 32;
+ else
+ kpiobufs = 16;
+ }
+ else
kpiobufs = ipath_kpiobufs;
if (kpiobufs >
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 0bcb428..3e72a1f 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -665,14 +665,14 @@
ret = __ipath_layer_intr(dd, IPATH_LAYER_INT_SEND_CONTINUE);
if (ret > 0)
- goto clear;
+ goto set;
ret = __ipath_verbs_piobufavail(dd);
if (ret > 0)
- goto clear;
+ goto set;
return;
-clear:
+set:
set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl);
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
dd->ipath_sendctrl);
@@ -719,11 +719,24 @@
irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
{
struct ipath_devdata *dd = data;
- u32 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus);
+ u32 istat;
ipath_err_t estat = 0;
static unsigned unexpected = 0;
irqreturn_t ret;
+ if(!(dd->ipath_flags & IPATH_PRESENT)) {
+ /* this is mostly so we don't try to touch the chip while
+ * it is being reset */
+ /*
+ * This return value is perhaps odd, but we do not want the
+ * interrupt core code to remove our interrupt handler
+ * because we don't appear to be handling an interrupt
+ * during a chip reset.
+ */
+ return IRQ_HANDLED;
+ }
+
+ istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus);
if (unlikely(!istat)) {
ipath_stats.sps_nullintr++;
ret = IRQ_NONE; /* not our interrupt, or already handled */
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 0ce5f19..e6507f8 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -731,7 +731,7 @@
static inline u32 ipath_read_ureg32(const struct ipath_devdata *dd,
ipath_ureg regno, int port)
{
- if (!dd->ipath_kregbase)
+ if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT))
return 0;
return readl(regno + (u64 __iomem *)
@@ -762,7 +762,7 @@
static inline u32 ipath_read_kreg32(const struct ipath_devdata *dd,
ipath_kreg regno)
{
- if (!dd->ipath_kregbase)
+ if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT))
return -1;
return readl((u32 __iomem *) & dd->ipath_kregbase[regno]);
}
@@ -770,7 +770,7 @@
static inline u64 ipath_read_kreg64(const struct ipath_devdata *dd,
ipath_kreg regno)
{
- if (!dd->ipath_kregbase)
+ if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT))
return -1;
return readq(&dd->ipath_kregbase[regno]);
@@ -786,7 +786,7 @@
static inline u64 ipath_read_creg(const struct ipath_devdata *dd,
ipath_sreg regno)
{
- if (!dd->ipath_kregbase)
+ if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT))
return 0;
return readq(regno + (u64 __iomem *)
@@ -797,7 +797,7 @@
static inline u32 ipath_read_creg32(const struct ipath_devdata *dd,
ipath_sreg regno)
{
- if (!dd->ipath_kregbase)
+ if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT))
return 0;
return readl(regno + (u64 __iomem *)
(dd->ipath_cregbase +
diff --git a/drivers/infiniband/hw/ipath/ipath_layer.c b/drivers/infiniband/hw/ipath/ipath_layer.c
index 69ed110..9cb5258 100644
--- a/drivers/infiniband/hw/ipath/ipath_layer.c
+++ b/drivers/infiniband/hw/ipath/ipath_layer.c
@@ -46,13 +46,15 @@
/* Acquire before ipath_devs_lock. */
static DEFINE_MUTEX(ipath_layer_mutex);
+static int ipath_verbs_registered;
+
u16 ipath_layer_rcv_opcode;
+
static int (*layer_intr)(void *, u32);
static int (*layer_rcv)(void *, void *, struct sk_buff *);
static int (*layer_rcv_lid)(void *, void *);
static int (*verbs_piobufavail)(void *);
static void (*verbs_rcv)(void *, void *, void *, u32);
-static int ipath_verbs_registered;
static void *(*layer_add_one)(int, struct ipath_devdata *);
static void (*layer_remove_one)(void *);
@@ -586,6 +588,8 @@
verbs_rcv = NULL;
verbs_timer_cb = NULL;
+ ipath_verbs_registered = 0;
+
mutex_unlock(&ipath_layer_mutex);
}
diff --git a/drivers/infiniband/hw/ipath/ipath_pe800.c b/drivers/infiniband/hw/ipath/ipath_pe800.c
index e1dc4f7..6318067 100644
--- a/drivers/infiniband/hw/ipath/ipath_pe800.c
+++ b/drivers/infiniband/hw/ipath/ipath_pe800.c
@@ -972,6 +972,8 @@
/* Use ERROR so it shows up in logs, etc. */
ipath_dev_err(dd, "Resetting PE-800 unit %u\n",
dd->ipath_unit);
+ /* keep chip from being accessed in a few places */
+ dd->ipath_flags &= ~(IPATH_INITTED|IPATH_PRESENT);
val = dd->ipath_control | INFINIPATH_C_RESET;
ipath_write_kreg(dd, dd->ipath_kregs->kr_control, val);
mb();
@@ -997,6 +999,8 @@
if ((r = pci_enable_device(dd->pcidev)))
ipath_dev_err(dd, "pci_enable_device failed after "
"reset: %d\n", r);
+ /* whether it worked or not, mark as present, again */
+ dd->ipath_flags |= IPATH_PRESENT;
val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_revision);
if (val == dd->ipath_revision) {
ipath_cdbg(VERBOSE, "Got matching revision "
diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h
index 1e59750..402126e 100644
--- a/drivers/infiniband/hw/ipath/ipath_registers.h
+++ b/drivers/infiniband/hw/ipath/ipath_registers.h
@@ -34,8 +34,9 @@
#define _IPATH_REGISTERS_H
/*
- * This file should only be included by kernel source, and by the diags.
- * It defines the registers, and their contents, for the InfiniPath HT-400 chip
+ * This file should only be included by kernel source, and by the diags. It
+ * defines the registers, and their contents, for the InfiniPath HT-400
+ * chip.
*/
/*
@@ -156,8 +157,10 @@
#define INFINIPATH_IBCC_FLOWCTRLWATERMARK_SHIFT 8
#define INFINIPATH_IBCC_LINKINITCMD_MASK 0x3ULL
#define INFINIPATH_IBCC_LINKINITCMD_DISABLE 1
-#define INFINIPATH_IBCC_LINKINITCMD_POLL 2 /* cycle through TS1/TS2 till OK */
-#define INFINIPATH_IBCC_LINKINITCMD_SLEEP 3 /* wait for TS1, then go on */
+/* cycle through TS1/TS2 till OK */
+#define INFINIPATH_IBCC_LINKINITCMD_POLL 2
+/* wait for TS1, then go on */
+#define INFINIPATH_IBCC_LINKINITCMD_SLEEP 3
#define INFINIPATH_IBCC_LINKINITCMD_SHIFT 16
#define INFINIPATH_IBCC_LINKCMD_MASK 0x3ULL
#define INFINIPATH_IBCC_LINKCMD_INIT 1 /* move to 0x11 */
@@ -182,7 +185,8 @@
#define INFINIPATH_IBCS_LINKSTATE_SHIFT 4
#define INFINIPATH_IBCS_TXREADY 0x40000000
#define INFINIPATH_IBCS_TXCREDITOK 0x80000000
-/* link training states (shift by INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) */
+/* link training states (shift by
+ INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) */
#define INFINIPATH_IBCS_LT_STATE_DISABLED 0x00
#define INFINIPATH_IBCS_LT_STATE_LINKUP 0x01
#define INFINIPATH_IBCS_LT_STATE_POLLACTIVE 0x02
@@ -267,10 +271,12 @@
/* kr_serdesconfig0 bits */
#define INFINIPATH_SERDC0_RESET_MASK 0xfULL /* overal reset bits */
#define INFINIPATH_SERDC0_RESET_PLL 0x10000000ULL /* pll reset */
-#define INFINIPATH_SERDC0_TXIDLE 0xF000ULL /* tx idle enables (per lane) */
-#define INFINIPATH_SERDC0_RXDETECT_EN 0xF0000ULL /* rx detect enables (per lane) */
-#define INFINIPATH_SERDC0_L1PWR_DN 0xF0ULL /* L1 Power down; use with RXDETECT,
- Otherwise not used on IB side */
+/* tx idle enables (per lane) */
+#define INFINIPATH_SERDC0_TXIDLE 0xF000ULL
+/* rx detect enables (per lane) */
+#define INFINIPATH_SERDC0_RXDETECT_EN 0xF0000ULL
+/* L1 Power down; use with RXDETECT, Otherwise not used on IB side */
+#define INFINIPATH_SERDC0_L1PWR_DN 0xF0ULL
/* kr_xgxsconfig bits */
#define INFINIPATH_XGXS_RESET 0x7ULL
@@ -390,12 +396,13 @@
ipath_kreg kr_txintmemsize;
ipath_kreg kr_xgxsconfig;
ipath_kreg kr_ibpllcfg;
- /* use these two (and the following N ports) only with ipath_k*_kreg64_port();
- * not *kreg64() */
+ /* use these two (and the following N ports) only with
+ * ipath_k*_kreg64_port(); not *kreg64() */
ipath_kreg kr_rcvhdraddr;
ipath_kreg kr_rcvhdrtailaddr;
- /* remaining registers are not present on all types of infinipath chips */
+ /* remaining registers are not present on all types of infinipath
+ chips */
ipath_kreg kr_rcvpktledcnt;
ipath_kreg kr_pcierbuftestreg0;
ipath_kreg kr_pcierbuftestreg1;
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c
index f232e77..eb81424 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -531,19 +531,12 @@
}
wqe->wr.num_sge = j;
qp->s_head = next;
- /*
- * Wake up the send tasklet if the QP is not waiting
- * for an RNR timeout.
- */
- next = qp->s_rnr_timeout;
spin_unlock_irqrestore(&qp->s_lock, flags);
- if (next == 0) {
- if (qp->ibqp.qp_type == IB_QPT_UC)
- ipath_do_uc_send((unsigned long) qp);
- else
- ipath_do_rc_send((unsigned long) qp);
- }
+ if (qp->ibqp.qp_type == IB_QPT_UC)
+ ipath_do_uc_send((unsigned long) qp);
+ else
+ ipath_do_rc_send((unsigned long) qp);
ret = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c
index 32acd80..f323791 100644
--- a/drivers/infiniband/hw/ipath/ipath_sysfs.c
+++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c
@@ -711,10 +711,22 @@
* enters diag mode. A device reset is quite likely to crash the
* machine entirely, so we don't want to normally make it
* available.
+ *
+ * Called with ipath_mutex held.
*/
int ipath_expose_reset(struct device *dev)
{
- return device_create_file(dev, &dev_attr_reset);
+ static int exposed;
+ int ret;
+
+ if (!exposed) {
+ ret = device_create_file(dev, &dev_attr_reset);
+ exposed = 1;
+ }
+ else
+ ret = 0;
+
+ return ret;
}
int ipath_driver_create_group(struct device_driver *drv)
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 01cfb30..e606daf 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -46,8 +46,10 @@
* This is called from ipath_post_ud_send() to forward a WQE addressed
* to the same HCA.
*/
-static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_sge_state *ss,
- u32 length, struct ib_send_wr *wr, struct ib_wc *wc)
+static void ipath_ud_loopback(struct ipath_qp *sqp,
+ struct ipath_sge_state *ss,
+ u32 length, struct ib_send_wr *wr,
+ struct ib_wc *wc)
{
struct ipath_ibdev *dev = to_idev(sqp->ibqp.device);
struct ipath_qp *qp;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 8d2558a..cb9e387 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -449,7 +449,6 @@
{
struct ipath_ibdev *dev = (struct ipath_ibdev *) arg;
struct ipath_qp *resend = NULL;
- struct ipath_qp *rnr = NULL;
struct list_head *last;
struct ipath_qp *qp;
unsigned long flags;
@@ -465,32 +464,18 @@
last = &dev->pending[dev->pending_index];
while (!list_empty(last)) {
qp = list_entry(last->next, struct ipath_qp, timerwait);
- if (last->next == LIST_POISON1 ||
- last->next != &qp->timerwait ||
- qp->timerwait.prev != last) {
- INIT_LIST_HEAD(last);
- } else {
- list_del(&qp->timerwait);
- qp->timerwait.prev = (struct list_head *) resend;
- resend = qp;
- atomic_inc(&qp->refcount);
- }
+ list_del(&qp->timerwait);
+ qp->timer_next = resend;
+ resend = qp;
+ atomic_inc(&qp->refcount);
}
last = &dev->rnrwait;
if (!list_empty(last)) {
qp = list_entry(last->next, struct ipath_qp, timerwait);
if (--qp->s_rnr_timeout == 0) {
do {
- if (last->next == LIST_POISON1 ||
- last->next != &qp->timerwait ||
- qp->timerwait.prev != last) {
- INIT_LIST_HEAD(last);
- break;
- }
list_del(&qp->timerwait);
- qp->timerwait.prev =
- (struct list_head *) rnr;
- rnr = qp;
+ tasklet_hi_schedule(&qp->s_task);
if (list_empty(last))
break;
qp = list_entry(last->next, struct ipath_qp,
@@ -530,8 +515,7 @@
spin_unlock_irqrestore(&dev->pending_lock, flags);
/* XXX What if timer fires again while this is running? */
- for (qp = resend; qp != NULL;
- qp = (struct ipath_qp *) qp->timerwait.prev) {
+ for (qp = resend; qp != NULL; qp = qp->timer_next) {
struct ib_wc wc;
spin_lock_irqsave(&qp->s_lock, flags);
@@ -545,9 +529,6 @@
if (atomic_dec_and_test(&qp->refcount))
wake_up(&qp->wait);
}
- for (qp = rnr; qp != NULL;
- qp = (struct ipath_qp *) qp->timerwait.prev)
- tasklet_hi_schedule(&qp->s_task);
}
/**
@@ -556,9 +537,9 @@
*
* This is called from ipath_intr() at interrupt level when a PIO buffer is
* available after ipath_verbs_send() returned an error that no buffers were
- * available. Return 0 if we consumed all the PIO buffers and we still have
+ * available. Return 1 if we consumed all the PIO buffers and we still have
* QPs waiting for buffers (for now, just do a tasklet_hi_schedule and
- * return one).
+ * return zero).
*/
static int ipath_ib_piobufavail(void *arg)
{
@@ -579,7 +560,7 @@
spin_unlock_irqrestore(&dev->pending_lock, flags);
bail:
- return 1;
+ return 0;
}
static int ipath_query_device(struct ib_device *ibdev,
@@ -1159,7 +1140,7 @@
len = sprintf(buf,
"RC resends %d\n"
- "RC QACKs %d\n"
+ "RC no QACK %d\n"
"RC ACKs %d\n"
"RC SEQ NAKs %d\n"
"RC RDMA seq %d\n"
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index fcafbc7..4f8d593 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -282,7 +282,8 @@
*/
struct ipath_qp {
struct ib_qp ibqp;
- struct ipath_qp *next; /* link list for QPN hash table */
+ struct ipath_qp *next; /* link list for QPN hash table */
+ struct ipath_qp *timer_next; /* link list for ipath_ib_timer() */
struct list_head piowait; /* link for wait PIO buf */
struct list_head timerwait; /* link for waiting for timeouts */
struct ib_ah_attr remote_ah_attr;
diff --git a/drivers/infiniband/hw/ipath/ips_common.h b/drivers/infiniband/hw/ipath/ips_common.h
index 410a764..ab7cbbb 100644
--- a/drivers/infiniband/hw/ipath/ips_common.h
+++ b/drivers/infiniband/hw/ipath/ips_common.h
@@ -95,7 +95,7 @@
__u8 seq_num;
__le32 len;
/* MUST be of word size due to PIO write requirements */
- __u32 csum;
+ __le32 csum;
__le16 csum_offset;
__le16 flags;
__u16 first_2_bytes;
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 565a24b..a2eae8a 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -306,7 +306,7 @@
goto out;
}
- memcpy(gid->raw + 8, out_mad->data + (index % 8) * 16, 8);
+ memcpy(gid->raw + 8, out_mad->data + (index % 8) * 8, 8);
out:
kfree(in_mad);
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index a34e3d9..ba325f1 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -403,6 +403,27 @@
case EVIOCGID:
if (copy_to_user(p, &dev->id, sizeof(struct input_id)))
return -EFAULT;
+ return 0;
+
+ case EVIOCGREP:
+ if (!test_bit(EV_REP, dev->evbit))
+ return -ENOSYS;
+ if (put_user(dev->rep[REP_DELAY], ip))
+ return -EFAULT;
+ if (put_user(dev->rep[REP_PERIOD], ip + 1))
+ return -EFAULT;
+ return 0;
+
+ case EVIOCSREP:
+ if (!test_bit(EV_REP, dev->evbit))
+ return -ENOSYS;
+ if (get_user(u, ip))
+ return -EFAULT;
+ if (get_user(v, ip + 1))
+ return -EFAULT;
+
+ input_event(dev, EV_REP, REP_DELAY, u);
+ input_event(dev, EV_REP, REP_PERIOD, v);
return 0;
diff --git a/drivers/input/input.c b/drivers/input/input.c
index a935abe..3038c26 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -155,6 +155,9 @@
if (code > SND_MAX || !test_bit(code, dev->sndbit))
return;
+ if (!!test_bit(code, dev->snd) != !!value)
+ change_bit(code, dev->snd);
+
if (dev->event) dev->event(dev, type, code, value);
break;
@@ -286,19 +289,19 @@
for (; id->flags || id->driver_info; id++) {
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
- if (id->id.bustype != dev->id.bustype)
+ if (id->bustype != dev->id.bustype)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
- if (id->id.vendor != dev->id.vendor)
+ if (id->vendor != dev->id.vendor)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
- if (id->id.product != dev->id.product)
+ if (id->product != dev->id.product)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
- if (id->id.version != dev->id.version)
+ if (id->version != dev->id.version)
continue;
MATCH_BIT(evbit, EV_MAX);
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index bc61cf8..1d238a9 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -53,8 +53,8 @@
KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0, /* 1-16 */
0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */
KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0, /* 33-48 */
- SPITZ_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */
- SPITZ_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 65-80 */
+ SPITZ_KEY_ADDRESS, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */
+ SPITZ_KEY_CALENDER, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 65-80 */
SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0, /* 81-96 */
KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0 /* 97-112 */
};
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 4b415d9..36cd2e0 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -273,6 +273,18 @@
{ KE_END, 0 }
};
+static struct key_entry keymap_fujitsu_n3510[] = {
+ { KE_KEY, 0x11, KEY_PROG1 },
+ { KE_KEY, 0x12, KEY_PROG2 },
+ { KE_KEY, 0x36, KEY_WWW },
+ { KE_KEY, 0x31, KEY_MAIL },
+ { KE_KEY, 0x71, KEY_STOPCD },
+ { KE_KEY, 0x72, KEY_PLAYPAUSE },
+ { KE_KEY, 0x74, KEY_REWIND },
+ { KE_KEY, 0x78, KEY_FORWARD },
+ { KE_END, 0 }
+};
+
static struct key_entry keymap_wistron_ms2141[] = {
{ KE_KEY, 0x11, KEY_PROG1 },
{ KE_KEY, 0x12, KEY_PROG2 },
@@ -323,6 +335,24 @@
},
{
.callback = dmi_matched,
+ .ident = "Fujitsu-Siemens Amilo M7400",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "),
+ },
+ .driver_data = keymap_fs_amilo_pro_v2000
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Fujitsu N3510",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N3510"),
+ },
+ .driver_data = keymap_fujitsu_n3510
+ },
+ {
+ .callback = dmi_matched,
.ident = "Acer Aspire 1500",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 32d70ed..136321a 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -302,8 +302,10 @@
* Check if this is a new device announcement (0xAA 0x00)
*/
if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {
- if (psmouse->pktcnt == 1)
+ if (psmouse->pktcnt == 1) {
+ psmouse->last = jiffies;
goto out;
+ }
if (psmouse->packet[1] == PSMOUSE_RET_ID) {
__psmouse_set_state(psmouse, PSMOUSE_IGNORE);
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 46d1fec..1494175 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -2,6 +2,8 @@
* ADS7846 based touchscreen and sensor driver
*
* Copyright (c) 2005 David Brownell
+ * Copyright (c) 2006 Nokia Corporation
+ * Various changes: Imre Deak <imre.deak@nokia.com>
*
* Using code from:
* - corgi_ts.c
@@ -34,17 +36,25 @@
/*
- * This code has been lightly tested on an ads7846.
+ * This code has been tested on an ads7846 / N770 device.
* Support for ads7843 and ads7845 has only been stubbed in.
*
- * Not yet done: investigate the values reported. Are x/y/pressure
- * event values sane enough for X11? How accurate are the temperature
- * and voltage readings? (System-specific calibration should support
+ * Not yet done: How accurate are the temperature and voltage
+ * readings? (System-specific calibration should support
* accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.)
*
+ * IRQ handling needs a workaround because of a shortcoming in handling
+ * edge triggered IRQs on some platforms like the OMAP1/2. These
+ * platforms don't handle the ARM lazy IRQ disabling properly, thus we
+ * have to maintain our own SW IRQ disabled status. This should be
+ * removed as soon as the affected platform's IRQ handling is fixed.
+ *
* app note sbaa036 talks in more detail about accurate sampling...
* that ought to help in situations like LCDs inducing noise (which
* can also be helped by using synch signals) and more generally.
+ * This driver tries to utilize the measures described in the app
+ * note. The strength of filtering can be set in the board-* specific
+ * files.
*/
#define TS_POLL_PERIOD msecs_to_jiffies(10)
@@ -61,6 +71,7 @@
__be16 x;
__be16 y;
__be16 z1, z2;
+ int ignore;
};
struct ads7846 {
@@ -71,12 +82,23 @@
u16 model;
u16 vref_delay_usecs;
u16 x_plate_ohms;
+ u16 pressure_max;
- u8 read_x, read_y, read_z1, read_z2;
+ u8 read_x, read_y, read_z1, read_z2, pwrdown;
+ u16 dummy; /* for the pwrdown read */
struct ts_event tc;
- struct spi_transfer xfer[8];
- struct spi_message msg;
+ struct spi_transfer xfer[10];
+ struct spi_message msg[5];
+ struct spi_message *last_msg;
+ int msg_idx;
+ int read_cnt;
+ int read_rep;
+ int last_read;
+
+ u16 debounce_max;
+ u16 debounce_tol;
+ u16 debounce_rep;
spinlock_t lock;
struct timer_list timer; /* P: lock */
@@ -84,6 +106,9 @@
unsigned pending:1; /* P: lock */
// FIXME remove "irq_disabled"
unsigned irq_disabled:1; /* P: lock */
+ unsigned disabled:1;
+
+ int (*get_pendown_state)(void);
};
/* leave chip selected when we're done, for quicker re-select? */
@@ -125,7 +150,9 @@
#define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON)
#define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON)
#define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON)
-#define READ_X (READ_12BIT_DFR(x) | ADS_PD10_PDOWN) /* LAST */
+
+#define READ_X (READ_12BIT_DFR(x) | ADS_PD10_ADC_ON)
+#define PWRDOWN (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) /* LAST */
/* single-ended samples need to first power up reference voltage;
* we leave both ADC and VREF powered
@@ -152,6 +179,15 @@
struct spi_transfer xfer[6];
};
+static void ads7846_enable(struct ads7846 *ts);
+static void ads7846_disable(struct ads7846 *ts);
+
+static int device_suspended(struct device *dev)
+{
+ struct ads7846 *ts = dev_get_drvdata(dev);
+ return dev->power.power_state.event != PM_EVENT_ON || ts->disabled;
+}
+
static int ads7846_read12_ser(struct device *dev, unsigned command)
{
struct spi_device *spi = to_spi_device(dev);
@@ -164,7 +200,7 @@
if (!req)
return -ENOMEM;
- INIT_LIST_HEAD(&req->msg.transfers);
+ spi_message_init(&req->msg);
/* activate reference, so it has time to settle; */
req->ref_on = REF_ON;
@@ -204,8 +240,10 @@
for (i = 0; i < 6; i++)
spi_message_add_tail(&req->xfer[i], &req->msg);
+ ts->irq_disabled = 1;
disable_irq(spi->irq);
status = spi_sync(spi, &req->msg);
+ ts->irq_disabled = 0;
enable_irq(spi->irq);
if (req->msg.status)
@@ -233,6 +271,52 @@
SHOW(vaux)
SHOW(vbatt)
+static int is_pen_down(struct device *dev)
+{
+ struct ads7846 *ts = dev_get_drvdata(dev);
+
+ return ts->pendown;
+}
+
+static ssize_t ads7846_pen_down_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", is_pen_down(dev));
+}
+
+static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL);
+
+static ssize_t ads7846_disable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ads7846 *ts = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", ts->disabled);
+}
+
+static ssize_t ads7846_disable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ads7846 *ts = dev_get_drvdata(dev);
+ char *endp;
+ int i;
+
+ i = simple_strtoul(buf, &endp, 10);
+ spin_lock_irq(&ts->lock);
+
+ if (i)
+ ads7846_disable(ts);
+ else
+ ads7846_enable(ts);
+
+ spin_unlock_irq(&ts->lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store);
+
/*--------------------------------------------------------------------------*/
/*
@@ -264,7 +348,7 @@
if (x == MAX_12BIT)
x = 0;
- if (x && z1 && ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
+ if (likely(x && z1 && !device_suspended(&ts->spi->dev))) {
/* compute touch pressure resistance using equation #2 */
Rt = z2;
Rt -= z1;
@@ -275,6 +359,14 @@
} else
Rt = 0;
+ /* Sample found inconsistent by debouncing or pressure is beyond
+ * the maximum. Don't report it to user space, repeat at least
+ * once more the measurement */
+ if (ts->tc.ignore || Rt > ts->pressure_max) {
+ mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
+ return;
+ }
+
/* NOTE: "pendown" is inferred from pressure; we don't rely on
* being able to check nPENIRQ status, or "friendly" trigger modes
* (both-edges is much better than just-falling or low-level).
@@ -296,11 +388,13 @@
if (Rt) {
input_report_abs(input_dev, ABS_X, x);
input_report_abs(input_dev, ABS_Y, y);
- input_report_abs(input_dev, ABS_PRESSURE, Rt);
sync = 1;
}
- if (sync)
+
+ if (sync) {
+ input_report_abs(input_dev, ABS_PRESSURE, Rt);
input_sync(input_dev);
+ }
#ifdef VERBOSE
if (Rt || ts->pendown)
@@ -308,80 +402,138 @@
x, y, Rt, Rt ? "" : " UP");
#endif
- /* don't retrigger while we're suspended */
spin_lock_irqsave(&ts->lock, flags);
ts->pendown = (Rt != 0);
- ts->pending = 0;
-
- if (ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
- if (ts->pendown)
- mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
- else if (ts->irq_disabled) {
- ts->irq_disabled = 0;
- enable_irq(ts->spi->irq);
- }
- }
+ mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
spin_unlock_irqrestore(&ts->lock, flags);
}
+static void ads7846_debounce(void *ads)
+{
+ struct ads7846 *ts = ads;
+ struct spi_message *m;
+ struct spi_transfer *t;
+ int val;
+ int status;
+
+ m = &ts->msg[ts->msg_idx];
+ t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
+ val = (*(u16 *)t->rx_buf) >> 3;
+ if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol)) {
+ /* Repeat it, if this was the first read or the read
+ * wasn't consistent enough. */
+ if (ts->read_cnt < ts->debounce_max) {
+ ts->last_read = val;
+ ts->read_cnt++;
+ } else {
+ /* Maximum number of debouncing reached and still
+ * not enough number of consistent readings. Abort
+ * the whole sample, repeat it in the next sampling
+ * period.
+ */
+ ts->tc.ignore = 1;
+ ts->read_cnt = 0;
+ /* Last message will contain ads7846_rx() as the
+ * completion function.
+ */
+ m = ts->last_msg;
+ }
+ /* Start over collecting consistent readings. */
+ ts->read_rep = 0;
+ } else {
+ if (++ts->read_rep > ts->debounce_rep) {
+ /* Got a good reading for this coordinate,
+ * go for the next one. */
+ ts->tc.ignore = 0;
+ ts->msg_idx++;
+ ts->read_cnt = 0;
+ ts->read_rep = 0;
+ m++;
+ } else
+ /* Read more values that are consistent. */
+ ts->read_cnt++;
+ }
+ status = spi_async(ts->spi, m);
+ if (status)
+ dev_err(&ts->spi->dev, "spi_async --> %d\n",
+ status);
+}
+
static void ads7846_timer(unsigned long handle)
{
struct ads7846 *ts = (void *)handle;
int status = 0;
- unsigned long flags;
- spin_lock_irqsave(&ts->lock, flags);
- if (!ts->pending) {
- ts->pending = 1;
- if (!ts->irq_disabled) {
- ts->irq_disabled = 1;
- disable_irq(ts->spi->irq);
+ spin_lock_irq(&ts->lock);
+
+ if (unlikely(ts->msg_idx && !ts->pendown)) {
+ /* measurment cycle ended */
+ if (!device_suspended(&ts->spi->dev)) {
+ ts->irq_disabled = 0;
+ enable_irq(ts->spi->irq);
}
- status = spi_async(ts->spi, &ts->msg);
+ ts->pending = 0;
+ ts->msg_idx = 0;
+ } else {
+ /* pen is still down, continue with the measurement */
+ ts->msg_idx = 0;
+ status = spi_async(ts->spi, &ts->msg[0]);
if (status)
- dev_err(&ts->spi->dev, "spi_async --> %d\n",
- status);
+ dev_err(&ts->spi->dev, "spi_async --> %d\n", status);
}
- spin_unlock_irqrestore(&ts->lock, flags);
+
+ spin_unlock_irq(&ts->lock);
}
static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
{
- ads7846_timer((unsigned long) handle);
+ struct ads7846 *ts = handle;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ts->lock, flags);
+ if (likely(ts->get_pendown_state())) {
+ if (!ts->irq_disabled) {
+ /* REVISIT irq logic for many ARM chips has cloned a
+ * bug wherein disabling an irq in its handler won't
+ * work;(it's disabled lazily, and too late to work.
+ * until all their irq logic is fixed, we must shadow
+ * that state here.
+ */
+ ts->irq_disabled = 1;
+ disable_irq(ts->spi->irq);
+ ts->pending = 1;
+ mod_timer(&ts->timer, jiffies);
+ }
+ }
+ spin_unlock_irqrestore(&ts->lock, flags);
+
return IRQ_HANDLED;
}
/*--------------------------------------------------------------------------*/
-static int
-ads7846_suspend(struct spi_device *spi, pm_message_t message)
+/* Must be called with ts->lock held */
+static void ads7846_disable(struct ads7846 *ts)
{
- struct ads7846 *ts = dev_get_drvdata(&spi->dev);
- unsigned long flags;
+ if (ts->disabled)
+ return;
- spin_lock_irqsave(&ts->lock, flags);
-
- spi->dev.power.power_state = message;
+ ts->disabled = 1;
/* are we waiting for IRQ, or polling? */
- if (!ts->pendown) {
- if (!ts->irq_disabled) {
- ts->irq_disabled = 1;
- disable_irq(ts->spi->irq);
- }
+ if (!ts->pending) {
+ ts->irq_disabled = 1;
+ disable_irq(ts->spi->irq);
} else {
- /* polling; force a final SPI completion;
- * that will clean things up neatly
+ /* the timer will run at least once more, and
+ * leave everything in a clean state, IRQ disabled
*/
- if (!ts->pending)
- mod_timer(&ts->timer, jiffies);
-
- while (ts->pendown || ts->pending) {
- spin_unlock_irqrestore(&ts->lock, flags);
- udelay(10);
- spin_lock_irqsave(&ts->lock, flags);
+ while (ts->pending) {
+ spin_unlock_irq(&ts->lock);
+ msleep(1);
+ spin_lock_irq(&ts->lock);
}
}
@@ -389,17 +541,45 @@
* leave it that way after every request
*/
- spin_unlock_irqrestore(&ts->lock, flags);
+}
+
+/* Must be called with ts->lock held */
+static void ads7846_enable(struct ads7846 *ts)
+{
+ if (!ts->disabled)
+ return;
+
+ ts->disabled = 0;
+ ts->irq_disabled = 0;
+ enable_irq(ts->spi->irq);
+}
+
+static int ads7846_suspend(struct spi_device *spi, pm_message_t message)
+{
+ struct ads7846 *ts = dev_get_drvdata(&spi->dev);
+
+ spin_lock_irq(&ts->lock);
+
+ spi->dev.power.power_state = message;
+ ads7846_disable(ts);
+
+ spin_unlock_irq(&ts->lock);
+
return 0;
+
}
static int ads7846_resume(struct spi_device *spi)
{
struct ads7846 *ts = dev_get_drvdata(&spi->dev);
- ts->irq_disabled = 0;
- enable_irq(ts->spi->irq);
+ spin_lock_irq(&ts->lock);
+
spi->dev.power.power_state = PMSG_ON;
+ ads7846_enable(ts);
+
+ spin_unlock_irq(&ts->lock);
+
return 0;
}
@@ -408,6 +588,7 @@
struct ads7846 *ts;
struct input_dev *input_dev;
struct ads7846_platform_data *pdata = spi->dev.platform_data;
+ struct spi_message *m;
struct spi_transfer *x;
int err;
@@ -428,6 +609,11 @@
return -EINVAL;
}
+ if (pdata->get_pendown_state == NULL) {
+ dev_dbg(&spi->dev, "no get_pendown_state function?\n");
+ return -EINVAL;
+ }
+
/* We'd set the wordsize to 12 bits ... except that some controllers
* will then treat the 8 bit command words as 12 bits (and drop the
* four MSBs of the 12 bit result). Result: inputs must be shifted
@@ -451,9 +637,21 @@
ts->timer.data = (unsigned long) ts;
ts->timer.function = ads7846_timer;
+ spin_lock_init(&ts->lock);
+
ts->model = pdata->model ? : 7846;
ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
+ ts->pressure_max = pdata->pressure_max ? : ~0;
+ if (pdata->debounce_max) {
+ ts->debounce_max = pdata->debounce_max;
+ ts->debounce_tol = pdata->debounce_tol;
+ ts->debounce_rep = pdata->debounce_rep;
+ if (ts->debounce_rep > ts->debounce_max + 1)
+ ts->debounce_rep = ts->debounce_max - 1;
+ } else
+ ts->debounce_tol = ~0;
+ ts->get_pendown_state = pdata->get_pendown_state;
snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id);
@@ -477,60 +675,100 @@
/* set up the transfers to read touchscreen state; this assumes we
* use formula #2 for pressure, not #3.
*/
- INIT_LIST_HEAD(&ts->msg.transfers);
+ m = &ts->msg[0];
x = ts->xfer;
+ spi_message_init(m);
+
/* y- still on; turn on only y+ (and ADC) */
ts->read_y = READ_Y;
x->tx_buf = &ts->read_y;
x->len = 1;
- spi_message_add_tail(x, &ts->msg);
+ spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->tc.y;
x->len = 2;
- spi_message_add_tail(x, &ts->msg);
+ spi_message_add_tail(x, m);
- /* turn y+ off, x- on; we'll use formula #2 */
- if (ts->model == 7846) {
- x++;
- ts->read_z1 = READ_Z1;
- x->tx_buf = &ts->read_z1;
- x->len = 1;
- spi_message_add_tail(x, &ts->msg);
+ m->complete = ads7846_debounce;
+ m->context = ts;
- x++;
- x->rx_buf = &ts->tc.z1;
- x->len = 2;
- spi_message_add_tail(x, &ts->msg);
-
- x++;
- ts->read_z2 = READ_Z2;
- x->tx_buf = &ts->read_z2;
- x->len = 1;
- spi_message_add_tail(x, &ts->msg);
-
- x++;
- x->rx_buf = &ts->tc.z2;
- x->len = 2;
- spi_message_add_tail(x, &ts->msg);
- }
+ m++;
+ spi_message_init(m);
/* turn y- off, x+ on, then leave in lowpower */
x++;
ts->read_x = READ_X;
x->tx_buf = &ts->read_x;
x->len = 1;
- spi_message_add_tail(x, &ts->msg);
+ spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->tc.x;
x->len = 2;
- CS_CHANGE(*x);
- spi_message_add_tail(x, &ts->msg);
+ spi_message_add_tail(x, m);
- ts->msg.complete = ads7846_rx;
- ts->msg.context = ts;
+ m->complete = ads7846_debounce;
+ m->context = ts;
+
+ /* turn y+ off, x- on; we'll use formula #2 */
+ if (ts->model == 7846) {
+ m++;
+ spi_message_init(m);
+
+ x++;
+ ts->read_z1 = READ_Z1;
+ x->tx_buf = &ts->read_z1;
+ x->len = 1;
+ spi_message_add_tail(x, m);
+
+ x++;
+ x->rx_buf = &ts->tc.z1;
+ x->len = 2;
+ spi_message_add_tail(x, m);
+
+ m->complete = ads7846_debounce;
+ m->context = ts;
+
+ m++;
+ spi_message_init(m);
+
+ x++;
+ ts->read_z2 = READ_Z2;
+ x->tx_buf = &ts->read_z2;
+ x->len = 1;
+ spi_message_add_tail(x, m);
+
+ x++;
+ x->rx_buf = &ts->tc.z2;
+ x->len = 2;
+ spi_message_add_tail(x, m);
+
+ m->complete = ads7846_debounce;
+ m->context = ts;
+ }
+
+ /* power down */
+ m++;
+ spi_message_init(m);
+
+ x++;
+ ts->pwrdown = PWRDOWN;
+ x->tx_buf = &ts->pwrdown;
+ x->len = 1;
+ spi_message_add_tail(x, m);
+
+ x++;
+ x->rx_buf = &ts->dummy;
+ x->len = 2;
+ CS_CHANGE(*x);
+ spi_message_add_tail(x, m);
+
+ m->complete = ads7846_rx;
+ m->context = ts;
+
+ ts->last_msg = m;
if (request_irq(spi->irq, ads7846_irq,
SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING,
@@ -559,13 +797,27 @@
device_create_file(&spi->dev, &dev_attr_vbatt);
device_create_file(&spi->dev, &dev_attr_vaux);
+ device_create_file(&spi->dev, &dev_attr_pen_down);
+
+ device_create_file(&spi->dev, &dev_attr_disable);
+
err = input_register_device(input_dev);
if (err)
- goto err_free_irq;
+ goto err_remove_attr;
return 0;
- err_free_irq:
+ err_remove_attr:
+ device_remove_file(&spi->dev, &dev_attr_disable);
+ device_remove_file(&spi->dev, &dev_attr_pen_down);
+ if (ts->model == 7846) {
+ device_remove_file(&spi->dev, &dev_attr_temp1);
+ device_remove_file(&spi->dev, &dev_attr_temp0);
+ }
+ if (ts->model != 7845)
+ device_remove_file(&spi->dev, &dev_attr_vbatt);
+ device_remove_file(&spi->dev, &dev_attr_vaux);
+
free_irq(spi->irq, ts);
err_free_mem:
input_free_device(input_dev);
@@ -577,20 +829,24 @@
{
struct ads7846 *ts = dev_get_drvdata(&spi->dev);
- ads7846_suspend(spi, PMSG_SUSPEND);
- free_irq(ts->spi->irq, ts);
- if (ts->irq_disabled)
- enable_irq(ts->spi->irq);
+ input_unregister_device(ts->input);
+ ads7846_suspend(spi, PMSG_SUSPEND);
+
+ device_remove_file(&spi->dev, &dev_attr_disable);
+ device_remove_file(&spi->dev, &dev_attr_pen_down);
if (ts->model == 7846) {
- device_remove_file(&spi->dev, &dev_attr_temp0);
device_remove_file(&spi->dev, &dev_attr_temp1);
+ device_remove_file(&spi->dev, &dev_attr_temp0);
}
if (ts->model != 7845)
device_remove_file(&spi->dev, &dev_attr_vbatt);
device_remove_file(&spi->dev, &dev_attr_vaux);
- input_unregister_device(ts->input);
+ free_irq(ts->spi->irq, ts);
+ /* suspend left the IRQ disabled */
+ enable_irq(ts->spi->irq);
+
kfree(ts);
dev_dbg(&spi->dev, "unregistered touchscreen\n");
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 6081941..4070eff 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -315,10 +315,11 @@
if (r1_bio->bios[mirror] == bio)
break;
- if (error == -ENOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) {
+ if (error == -EOPNOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) {
set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags);
set_bit(R1BIO_BarrierRetry, &r1_bio->state);
r1_bio->mddev->barriers_work = 0;
+ /* Don't rdev_dec_pending in this branch - keep it for the retry */
} else {
/*
* this branch is our 'one mirror IO has finished' event handler:
@@ -365,6 +366,7 @@
}
}
}
+ rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
}
/*
*
@@ -374,11 +376,9 @@
if (atomic_dec_and_test(&r1_bio->remaining)) {
if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
reschedule_retry(r1_bio);
- /* Don't dec_pending yet, we want to hold
- * the reference over the retry
- */
goto out;
}
+ /* it really is the end of this request */
if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
/* free extra copy of the data pages */
int i = bio->bi_vcnt;
@@ -393,8 +393,6 @@
md_write_end(r1_bio->mddev);
raid_end_bio_io(r1_bio);
}
-
- rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
out:
if (to_put)
bio_put(to_put);
@@ -753,18 +751,24 @@
const int rw = bio_data_dir(bio);
int do_barriers;
- if (unlikely(!mddev->barriers_work && bio_barrier(bio))) {
- bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
- return 0;
- }
-
/*
* Register the new request and wait if the reconstruction
* thread has put up a bar for new requests.
* Continue immediately if no resync is active currently.
+ * We test barriers_work *after* md_write_start as md_write_start
+ * may cause the first superblock write, and that will check out
+ * if barriers work.
*/
+
md_write_start(mddev, bio); /* wait on superblock update early */
+ if (unlikely(!mddev->barriers_work && bio_barrier(bio))) {
+ if (rw == WRITE)
+ md_write_end(mddev);
+ bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+ return 0;
+ }
+
wait_barrier(conf);
disk_stat_inc(mddev->gendisk, ios[rw]);
@@ -1404,10 +1408,11 @@
unplug = 1;
} else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
/* some requests in the r1bio were BIO_RW_BARRIER
- * requests which failed with -ENOTSUPP. Hohumm..
+ * requests which failed with -EOPNOTSUPP. Hohumm..
* Better resubmit without the barrier.
* We know which devices to resubmit for, because
* all others have had their bios[] entry cleared.
+ * We already have a nr_pending reference on these rdevs.
*/
int i;
clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 617012b..1440935 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1407,43 +1407,54 @@
if (s > (PAGE_SIZE>>9))
s = PAGE_SIZE >> 9;
+ rcu_read_lock();
do {
int d = r10_bio->devs[sl].devnum;
- rdev = conf->mirrors[d].rdev;
+ rdev = rcu_dereference(conf->mirrors[d].rdev);
if (rdev &&
- test_bit(In_sync, &rdev->flags) &&
- sync_page_io(rdev->bdev,
- r10_bio->devs[sl].addr +
- sect + rdev->data_offset,
- s<<9,
- conf->tmppage, READ))
- success = 1;
- else {
- sl++;
- if (sl == conf->copies)
- sl = 0;
+ test_bit(In_sync, &rdev->flags)) {
+ atomic_inc(&rdev->nr_pending);
+ rcu_read_unlock();
+ success = sync_page_io(rdev->bdev,
+ r10_bio->devs[sl].addr +
+ sect + rdev->data_offset,
+ s<<9,
+ conf->tmppage, READ);
+ rdev_dec_pending(rdev, mddev);
+ rcu_read_lock();
+ if (success)
+ break;
}
+ sl++;
+ if (sl == conf->copies)
+ sl = 0;
} while (!success && sl != r10_bio->read_slot);
+ rcu_read_unlock();
if (success) {
int start = sl;
/* write it back and re-read */
+ rcu_read_lock();
while (sl != r10_bio->read_slot) {
int d;
if (sl==0)
sl = conf->copies;
sl--;
d = r10_bio->devs[sl].devnum;
- rdev = conf->mirrors[d].rdev;
- atomic_add(s, &rdev->corrected_errors);
+ rdev = rcu_dereference(conf->mirrors[d].rdev);
if (rdev &&
test_bit(In_sync, &rdev->flags)) {
+ atomic_inc(&rdev->nr_pending);
+ rcu_read_unlock();
+ atomic_add(s, &rdev->corrected_errors);
if (sync_page_io(rdev->bdev,
r10_bio->devs[sl].addr +
sect + rdev->data_offset,
s<<9, conf->tmppage, WRITE) == 0)
/* Well, this device is dead */
md_error(mddev, rdev);
+ rdev_dec_pending(rdev, mddev);
+ rcu_read_lock();
}
}
sl = start;
@@ -1453,17 +1464,22 @@
sl = conf->copies;
sl--;
d = r10_bio->devs[sl].devnum;
- rdev = conf->mirrors[d].rdev;
+ rdev = rcu_dereference(conf->mirrors[d].rdev);
if (rdev &&
test_bit(In_sync, &rdev->flags)) {
+ atomic_inc(&rdev->nr_pending);
+ rcu_read_unlock();
if (sync_page_io(rdev->bdev,
r10_bio->devs[sl].addr +
sect + rdev->data_offset,
s<<9, conf->tmppage, READ) == 0)
/* Well, this device is dead */
md_error(mddev, rdev);
+ rdev_dec_pending(rdev, mddev);
+ rcu_read_lock();
}
}
+ rcu_read_unlock();
} else {
/* Cannot read from anywhere -- bye bye array */
md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev);
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index f9d87b8..320b3d9 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -616,7 +616,7 @@
* Only boards with eeprom and byte 1 at eeprom=1 have it
*/
-static struct pci_device_id cx88_audio_pci_tbl[] = {
+static struct pci_device_id cx88_audio_pci_tbl[] __devinitdata = {
{0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
{0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
{0, }
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 73e271e..beeb612 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -69,8 +69,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.56"
-#define DRV_MODULE_RELDATE "Apr 1, 2006"
+#define DRV_MODULE_VERSION "3.57"
+#define DRV_MODULE_RELDATE "Apr 28, 2006"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -974,6 +974,8 @@
return err;
}
+static void tg3_link_report(struct tg3 *);
+
/* This will reset the tigon3 PHY if there is no valid
* link unless the FORCE argument is non-zero.
*/
@@ -987,6 +989,11 @@
if (err != 0)
return -EBUSY;
+ if (netif_running(tp->dev) && netif_carrier_ok(tp->dev)) {
+ netif_carrier_off(tp->dev);
+ tg3_link_report(tp);
+ }
+
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
@@ -1023,6 +1030,12 @@
tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x14e2);
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
}
+ else if (tp->tg3_flags2 & TG3_FLG2_PHY_JITTER_BUG) {
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
+ tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b);
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+ }
/* Set Extended packet length bit (bit 14) on all chips that */
/* support jumbo frames */
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
@@ -3531,7 +3544,7 @@
return IRQ_RETVAL(0);
}
-static int tg3_init_hw(struct tg3 *);
+static int tg3_init_hw(struct tg3 *, int);
static int tg3_halt(struct tg3 *, int, int);
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -3567,7 +3580,7 @@
tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
- tg3_init_hw(tp);
+ tg3_init_hw(tp, 1);
tg3_netif_start(tp);
@@ -4042,7 +4055,7 @@
tg3_set_mtu(dev, tp, new_mtu);
- tg3_init_hw(tp);
+ tg3_init_hw(tp, 0);
tg3_netif_start(tp);
@@ -5719,9 +5732,23 @@
if (!netif_running(dev))
return 0;
- spin_lock_bh(&tp->lock);
- __tg3_set_mac_addr(tp);
- spin_unlock_bh(&tp->lock);
+ if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+ /* Reset chip so that ASF can re-init any MAC addresses it
+ * needs.
+ */
+ tg3_netif_stop(tp);
+ tg3_full_lock(tp, 1);
+
+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+ tg3_init_hw(tp, 0);
+
+ tg3_netif_start(tp);
+ tg3_full_unlock(tp);
+ } else {
+ spin_lock_bh(&tp->lock);
+ __tg3_set_mac_addr(tp);
+ spin_unlock_bh(&tp->lock);
+ }
return 0;
}
@@ -5771,7 +5798,7 @@
}
/* tp->lock is held. */
-static int tg3_reset_hw(struct tg3 *tp)
+static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
{
u32 val, rdmac_mode;
int i, err, limit;
@@ -5786,7 +5813,7 @@
tg3_abort_hw(tp, 1);
}
- if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+ if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && reset_phy)
tg3_phy_reset(tp);
err = tg3_chip_reset(tp);
@@ -6327,7 +6354,7 @@
tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
}
- err = tg3_setup_phy(tp, 1);
+ err = tg3_setup_phy(tp, reset_phy);
if (err)
return err;
@@ -6400,7 +6427,7 @@
/* Called at device open time to get the chip ready for
* packet processing. Invoked with tp->lock held.
*/
-static int tg3_init_hw(struct tg3 *tp)
+static int tg3_init_hw(struct tg3 *tp, int reset_phy)
{
int err;
@@ -6413,7 +6440,7 @@
tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
- err = tg3_reset_hw(tp);
+ err = tg3_reset_hw(tp, reset_phy);
out:
return err;
@@ -6683,7 +6710,7 @@
tg3_full_lock(tp, 1);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
- err = tg3_init_hw(tp);
+ err = tg3_init_hw(tp, 1);
tg3_full_unlock(tp);
@@ -6748,7 +6775,7 @@
tg3_full_lock(tp, 0);
- err = tg3_init_hw(tp);
+ err = tg3_init_hw(tp, 1);
if (err) {
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_free_rings(tp);
@@ -7839,7 +7866,7 @@
if (netif_running(dev)) {
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
- tg3_init_hw(tp);
+ tg3_init_hw(tp, 1);
tg3_netif_start(tp);
}
@@ -7884,7 +7911,7 @@
if (netif_running(dev)) {
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
- tg3_init_hw(tp);
+ tg3_init_hw(tp, 1);
tg3_netif_start(tp);
}
@@ -8522,7 +8549,7 @@
if (!netif_running(tp->dev))
return TG3_LOOPBACK_FAILED;
- tg3_reset_hw(tp);
+ tg3_reset_hw(tp, 1);
if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
err |= TG3_MAC_LOOPBACK_FAILED;
@@ -8596,7 +8623,7 @@
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) {
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
- tg3_init_hw(tp);
+ tg3_init_hw(tp, 1);
tg3_netif_start(tp);
}
@@ -9377,7 +9404,7 @@
if ((page_off == 0) || (i == 0))
nvram_cmd |= NVRAM_CMD_FIRST;
- else if (page_off == (tp->nvram_pagesize - 4))
+ if (page_off == (tp->nvram_pagesize - 4))
nvram_cmd |= NVRAM_CMD_LAST;
if (i == (len - 4))
@@ -10353,10 +10380,13 @@
if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG;
- if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
- (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) &&
- (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787))
- tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+ tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
+ else
+ tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
+ }
tp->coalesce_mode = 0;
if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX &&
@@ -11569,7 +11599,7 @@
tg3_full_lock(tp, 0);
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
- tg3_init_hw(tp);
+ tg3_init_hw(tp, 1);
tp->timer.expires = jiffies + tp->timer_offset;
add_timer(&tp->timer);
@@ -11603,7 +11633,7 @@
tg3_full_lock(tp, 0);
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
- tg3_init_hw(tp);
+ tg3_init_hw(tp, 1);
tp->timer.expires = jiffies + tp->timer_offset;
add_timer(&tp->timer);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 8c8b987..0e29b88 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2215,6 +2215,7 @@
#define TG3_FLG2_HW_TSO_2 0x08000000
#define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2)
#define TG3_FLG2_1SHOT_MSI 0x10000000
+#define TG3_FLG2_PHY_JITTER_BUG 0x20000000
u32 split_mode_max_reqs;
#define SPLIT_MODE_5704_MAX_REQ 3
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index b1e3e61..6c9ad92 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -58,7 +58,7 @@
unsigned long data;
ssize_t ret;
- if (count < sizeof(unsigned long))
+ if (count != sizeof(unsigned int) && count < sizeof(unsigned long))
return -EINVAL;
add_wait_queue(&rtc->irq_queue, &wait);
@@ -90,11 +90,16 @@
if (ret == 0) {
/* Check for any data updates */
if (rtc->ops->read_callback)
- data = rtc->ops->read_callback(rtc->class_dev.dev, data);
+ data = rtc->ops->read_callback(rtc->class_dev.dev,
+ data);
- ret = put_user(data, (unsigned long __user *)buf);
- if (ret == 0)
- ret = sizeof(unsigned long);
+ if (sizeof(int) != sizeof(long) &&
+ count == sizeof(unsigned int))
+ ret = put_user(data, (unsigned int __user *)buf) ?:
+ sizeof(unsigned int);
+ else
+ ret = put_user(data, (unsigned long __user *)buf) ?:
+ sizeof(unsigned long);
}
return ret;
}
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index b3c6e79..cb14642 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -8014,7 +8014,6 @@
static struct neigh_ops arp_direct_ops_template = {
.family = AF_INET,
- .destructor = NULL,
.solicit = NULL,
.error_report = NULL,
.output = dev_queue_xmit,
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 5ae1480..f99e553 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/workqueue.h>
+#include <linux/time.h>
#include <asm/lowcore.h>
@@ -363,7 +364,7 @@
}
#define MAX_IPD_COUNT 29
-#define MAX_IPD_TIME (5 * 60 * 100 * 1000) /* 5 minutes */
+#define MAX_IPD_TIME (5 * 60 * USEC_PER_SEC) /* 5 minutes */
/*
* machine check handler.
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c
index 0b49ff7..501316b 100644
--- a/drivers/sn/ioc3.c
+++ b/drivers/sn/ioc3.c
@@ -678,7 +678,7 @@
/* Track PCI-device specific data */
pci_set_drvdata(pdev, idd);
down_write(&ioc3_devices_rwsem);
- list_add(&idd->list, &ioc3_devices);
+ list_add_tail(&idd->list, &ioc3_devices);
idd->id = ioc3_counter++;
up_write(&ioc3_devices_rwsem);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index af88c43..f5958f4 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1104,6 +1104,8 @@
.readv = generic_file_readv,
.writev = generic_file_write_nolock,
.sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
};
int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
diff --git a/fs/compat.c b/fs/compat.c
index 2e32bd3..3f3e8f4 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1317,6 +1317,26 @@
return ret;
}
+asmlinkage long
+compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32,
+ unsigned int nr_segs, unsigned int flags)
+{
+ unsigned i;
+ struct iovec *iov;
+ if (nr_segs >= UIO_MAXIOV)
+ return -EINVAL;
+ iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec));
+ for (i = 0; i < nr_segs; i++) {
+ struct compat_iovec v;
+ if (get_user(v.iov_base, &iov32[i].iov_base) ||
+ get_user(v.iov_len, &iov32[i].iov_len) ||
+ put_user(compat_ptr(v.iov_base), &iov[i].iov_base) ||
+ put_user(v.iov_len, &iov[i].iov_len))
+ return -EFAULT;
+ }
+ return sys_vmsplice(fd, iov, nr_segs, flags);
+}
+
/*
* Exactly like fs/open.c:sys_open(), except that it doesn't set the
* O_LARGEFILE flag.
diff --git a/fs/pipe.c b/fs/pipe.c
index 7fefb10..3941a7f 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -55,7 +55,8 @@
}
static int
-pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len)
+pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len,
+ int atomic)
{
unsigned long copy;
@@ -64,8 +65,13 @@
iov++;
copy = min_t(unsigned long, len, iov->iov_len);
- if (copy_from_user(to, iov->iov_base, copy))
- return -EFAULT;
+ if (atomic) {
+ if (__copy_from_user_inatomic(to, iov->iov_base, copy))
+ return -EFAULT;
+ } else {
+ if (copy_from_user(to, iov->iov_base, copy))
+ return -EFAULT;
+ }
to += copy;
len -= copy;
iov->iov_base += copy;
@@ -75,7 +81,8 @@
}
static int
-pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len)
+pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len,
+ int atomic)
{
unsigned long copy;
@@ -84,8 +91,13 @@
iov++;
copy = min_t(unsigned long, len, iov->iov_len);
- if (copy_to_user(iov->iov_base, from, copy))
- return -EFAULT;
+ if (atomic) {
+ if (__copy_to_user_inatomic(iov->iov_base, from, copy))
+ return -EFAULT;
+ } else {
+ if (copy_to_user(iov->iov_base, from, copy))
+ return -EFAULT;
+ }
from += copy;
len -= copy;
iov->iov_base += copy;
@@ -94,13 +106,52 @@
return 0;
}
+/*
+ * Attempt to pre-fault in the user memory, so we can use atomic copies.
+ * Returns the number of bytes not faulted in.
+ */
+static int iov_fault_in_pages_write(struct iovec *iov, unsigned long len)
+{
+ while (!iov->iov_len)
+ iov++;
+
+ while (len > 0) {
+ unsigned long this_len;
+
+ this_len = min_t(unsigned long, len, iov->iov_len);
+ if (fault_in_pages_writeable(iov->iov_base, this_len))
+ break;
+
+ len -= this_len;
+ iov++;
+ }
+
+ return len;
+}
+
+/*
+ * Pre-fault in the user memory, so we can use atomic copies.
+ */
+static void iov_fault_in_pages_read(struct iovec *iov, unsigned long len)
+{
+ while (!iov->iov_len)
+ iov++;
+
+ while (len > 0) {
+ unsigned long this_len;
+
+ this_len = min_t(unsigned long, len, iov->iov_len);
+ fault_in_pages_readable(iov->iov_base, this_len);
+ len -= this_len;
+ iov++;
+ }
+}
+
static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{
struct page *page = buf->page;
- buf->flags &= ~PIPE_BUF_FLAG_STOLEN;
-
/*
* If nobody else uses this page, and we don't already have a
* temporary page, let's keep track of it as a one-deep
@@ -112,38 +163,58 @@
page_cache_release(page);
}
-static void * anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe,
- struct pipe_buffer *buf)
+void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
+ struct pipe_buffer *buf, int atomic)
{
+ if (atomic) {
+ buf->flags |= PIPE_BUF_FLAG_ATOMIC;
+ return kmap_atomic(buf->page, KM_USER0);
+ }
+
return kmap(buf->page);
}
-static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe,
- struct pipe_buffer *buf)
+void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
+ struct pipe_buffer *buf, void *map_data)
{
- kunmap(buf->page);
+ if (buf->flags & PIPE_BUF_FLAG_ATOMIC) {
+ buf->flags &= ~PIPE_BUF_FLAG_ATOMIC;
+ kunmap_atomic(map_data, KM_USER0);
+ } else
+ kunmap(buf->page);
}
static int anon_pipe_buf_steal(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{
- buf->flags |= PIPE_BUF_FLAG_STOLEN;
- return 0;
+ struct page *page = buf->page;
+
+ if (page_count(page) == 1) {
+ lock_page(page);
+ return 0;
+ }
+
+ return 1;
}
-static void anon_pipe_buf_get(struct pipe_inode_info *info,
- struct pipe_buffer *buf)
+void generic_pipe_buf_get(struct pipe_inode_info *info, struct pipe_buffer *buf)
{
page_cache_get(buf->page);
}
+int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf)
+{
+ return 0;
+}
+
static struct pipe_buf_operations anon_pipe_buf_ops = {
.can_merge = 1,
- .map = anon_pipe_buf_map,
- .unmap = anon_pipe_buf_unmap,
+ .map = generic_pipe_buf_map,
+ .unmap = generic_pipe_buf_unmap,
+ .pin = generic_pipe_buf_pin,
.release = anon_pipe_buf_release,
.steal = anon_pipe_buf_steal,
- .get = anon_pipe_buf_get,
+ .get = generic_pipe_buf_get,
};
static ssize_t
@@ -174,22 +245,33 @@
struct pipe_buf_operations *ops = buf->ops;
void *addr;
size_t chars = buf->len;
- int error;
+ int error, atomic;
if (chars > total_len)
chars = total_len;
- addr = ops->map(filp, pipe, buf);
- if (IS_ERR(addr)) {
+ error = ops->pin(pipe, buf);
+ if (error) {
if (!ret)
- ret = PTR_ERR(addr);
+ error = ret;
break;
}
- error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars);
- ops->unmap(pipe, buf);
+
+ atomic = !iov_fault_in_pages_write(iov, chars);
+redo:
+ addr = ops->map(pipe, buf, atomic);
+ error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic);
+ ops->unmap(pipe, buf, addr);
if (unlikely(error)) {
+ /*
+ * Just retry with the slow path if we failed.
+ */
+ if (atomic) {
+ atomic = 0;
+ goto redo;
+ }
if (!ret)
- ret = -EFAULT;
+ ret = error;
break;
}
ret += chars;
@@ -293,21 +375,28 @@
int offset = buf->offset + buf->len;
if (ops->can_merge && offset + chars <= PAGE_SIZE) {
+ int error, atomic = 1;
void *addr;
- int error;
- addr = ops->map(filp, pipe, buf);
- if (IS_ERR(addr)) {
- error = PTR_ERR(addr);
- goto out;
- }
- error = pipe_iov_copy_from_user(offset + addr, iov,
- chars);
- ops->unmap(pipe, buf);
- ret = error;
- do_wakeup = 1;
+ error = ops->pin(pipe, buf);
if (error)
goto out;
+
+ iov_fault_in_pages_read(iov, chars);
+redo1:
+ addr = ops->map(pipe, buf, atomic);
+ error = pipe_iov_copy_from_user(offset + addr, iov,
+ chars, atomic);
+ ops->unmap(pipe, buf, addr);
+ ret = error;
+ do_wakeup = 1;
+ if (error) {
+ if (atomic) {
+ atomic = 0;
+ goto redo1;
+ }
+ goto out;
+ }
buf->len += chars;
total_len -= chars;
ret = chars;
@@ -330,7 +419,8 @@
int newbuf = (pipe->curbuf + bufs) & (PIPE_BUFFERS-1);
struct pipe_buffer *buf = pipe->bufs + newbuf;
struct page *page = pipe->tmp_page;
- int error;
+ char *src;
+ int error, atomic = 1;
if (!page) {
page = alloc_page(GFP_HIGHUSER);
@@ -350,11 +440,27 @@
if (chars > total_len)
chars = total_len;
- error = pipe_iov_copy_from_user(kmap(page), iov, chars);
- kunmap(page);
+ iov_fault_in_pages_read(iov, chars);
+redo2:
+ if (atomic)
+ src = kmap_atomic(page, KM_USER0);
+ else
+ src = kmap(page);
+
+ error = pipe_iov_copy_from_user(src, iov, chars,
+ atomic);
+ if (atomic)
+ kunmap_atomic(src, KM_USER0);
+ else
+ kunmap(page);
+
if (unlikely(error)) {
+ if (atomic) {
+ atomic = 0;
+ goto redo2;
+ }
if (!ret)
- ret = -EFAULT;
+ ret = error;
break;
}
ret += chars;
diff --git a/fs/splice.c b/fs/splice.c
index a46ddd2..b150493 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -78,7 +78,7 @@
return 1;
}
- buf->flags |= PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU;
+ buf->flags |= PIPE_BUF_FLAG_LRU;
return 0;
}
@@ -87,12 +87,11 @@
{
page_cache_release(buf->page);
buf->page = NULL;
- buf->flags &= ~(PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU);
+ buf->flags &= ~PIPE_BUF_FLAG_LRU;
}
-static void *page_cache_pipe_buf_map(struct file *file,
- struct pipe_inode_info *info,
- struct pipe_buffer *buf)
+static int page_cache_pipe_buf_pin(struct pipe_inode_info *info,
+ struct pipe_buffer *buf)
{
struct page *page = buf->page;
int err;
@@ -118,64 +117,44 @@
}
/*
- * Page is ok afterall, fall through to mapping.
+ * Page is ok afterall, we are done.
*/
unlock_page(page);
}
- return kmap(page);
+ return 0;
error:
unlock_page(page);
- return ERR_PTR(err);
-}
-
-static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info,
- struct pipe_buffer *buf)
-{
- kunmap(buf->page);
-}
-
-static void *user_page_pipe_buf_map(struct file *file,
- struct pipe_inode_info *pipe,
- struct pipe_buffer *buf)
-{
- return kmap(buf->page);
-}
-
-static void user_page_pipe_buf_unmap(struct pipe_inode_info *pipe,
- struct pipe_buffer *buf)
-{
- kunmap(buf->page);
-}
-
-static void page_cache_pipe_buf_get(struct pipe_inode_info *info,
- struct pipe_buffer *buf)
-{
- page_cache_get(buf->page);
+ return err;
}
static struct pipe_buf_operations page_cache_pipe_buf_ops = {
.can_merge = 0,
- .map = page_cache_pipe_buf_map,
- .unmap = page_cache_pipe_buf_unmap,
+ .map = generic_pipe_buf_map,
+ .unmap = generic_pipe_buf_unmap,
+ .pin = page_cache_pipe_buf_pin,
.release = page_cache_pipe_buf_release,
.steal = page_cache_pipe_buf_steal,
- .get = page_cache_pipe_buf_get,
+ .get = generic_pipe_buf_get,
};
static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{
- return 1;
+ if (!(buf->flags & PIPE_BUF_FLAG_GIFT))
+ return 1;
+
+ return 0;
}
static struct pipe_buf_operations user_page_pipe_buf_ops = {
.can_merge = 0,
- .map = user_page_pipe_buf_map,
- .unmap = user_page_pipe_buf_unmap,
+ .map = generic_pipe_buf_map,
+ .unmap = generic_pipe_buf_unmap,
+ .pin = generic_pipe_buf_pin,
.release = page_cache_pipe_buf_release,
.steal = user_page_pipe_buf_steal,
- .get = page_cache_pipe_buf_get,
+ .get = generic_pipe_buf_get,
};
/*
@@ -210,6 +189,9 @@
buf->offset = spd->partial[page_nr].offset;
buf->len = spd->partial[page_nr].len;
buf->ops = spd->ops;
+ if (spd->flags & SPLICE_F_GIFT)
+ buf->flags |= PIPE_BUF_FLAG_GIFT;
+
pipe->nrbufs++;
page_nr++;
ret += buf->len;
@@ -326,6 +308,12 @@
page = find_get_page(mapping, index);
if (!page) {
/*
+ * Make sure the read-ahead engine is notified
+ * about this failure.
+ */
+ handle_ra_miss(mapping, &in->f_ra, index);
+
+ /*
* page didn't exist, allocate one.
*/
page = page_cache_alloc_cold(mapping);
@@ -517,26 +505,16 @@
{
struct file *file = sd->file;
loff_t pos = sd->pos;
- ssize_t ret;
- void *ptr;
- int more;
+ int ret, more;
- /*
- * Sub-optimal, but we are limited by the pipe ->map. We don't
- * need a kmap'ed buffer here, we just want to make sure we
- * have the page pinned if the pipe page originates from the
- * page cache.
- */
- ptr = buf->ops->map(file, info, buf);
- if (IS_ERR(ptr))
- return PTR_ERR(ptr);
+ ret = buf->ops->pin(info, buf);
+ if (!ret) {
+ more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
- more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
+ ret = file->f_op->sendpage(file, buf->page, buf->offset,
+ sd->len, &pos, more);
+ }
- ret = file->f_op->sendpage(file, buf->page, buf->offset, sd->len,
- &pos, more);
-
- buf->ops->unmap(info, buf);
return ret;
}
@@ -569,15 +547,14 @@
unsigned int offset, this_len;
struct page *page;
pgoff_t index;
- char *src;
int ret;
/*
* make sure the data in this buffer is uptodate
*/
- src = buf->ops->map(file, info, buf);
- if (IS_ERR(src))
- return PTR_ERR(src);
+ ret = buf->ops->pin(info, buf);
+ if (unlikely(ret))
+ return ret;
index = sd->pos >> PAGE_CACHE_SHIFT;
offset = sd->pos & ~PAGE_CACHE_MASK;
@@ -587,9 +564,10 @@
this_len = PAGE_CACHE_SIZE - offset;
/*
- * Reuse buf page, if SPLICE_F_MOVE is set.
+ * Reuse buf page, if SPLICE_F_MOVE is set and we are doing a full
+ * page.
*/
- if (sd->flags & SPLICE_F_MOVE) {
+ if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) {
/*
* If steal succeeds, buf->page is now pruned from the vm
* side (LRU and page cache) and we can reuse it. The page
@@ -599,8 +577,12 @@
goto find_page;
page = buf->page;
- if (add_to_page_cache(page, mapping, index, gfp_mask))
+ if (add_to_page_cache(page, mapping, index, gfp_mask)) {
+ unlock_page(page);
goto find_page;
+ }
+
+ page_cache_get(page);
if (!(buf->flags & PIPE_BUF_FLAG_LRU))
lru_cache_add(page);
@@ -660,34 +642,36 @@
} else if (ret)
goto out;
- if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) {
- char *dst = kmap_atomic(page, KM_USER0);
+ if (buf->page != page) {
+ /*
+ * Careful, ->map() uses KM_USER0!
+ */
+ char *src = buf->ops->map(info, buf, 1);
+ char *dst = kmap_atomic(page, KM_USER1);
memcpy(dst + offset, src + buf->offset, this_len);
flush_dcache_page(page);
- kunmap_atomic(dst, KM_USER0);
+ kunmap_atomic(dst, KM_USER1);
+ buf->ops->unmap(info, buf, src);
}
ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len);
- if (ret == AOP_TRUNCATED_PAGE) {
+ if (!ret) {
+ /*
+ * Return the number of bytes written and mark page as
+ * accessed, we are now done!
+ */
+ ret = this_len;
+ mark_page_accessed(page);
+ balance_dirty_pages_ratelimited(mapping);
+ } else if (ret == AOP_TRUNCATED_PAGE) {
page_cache_release(page);
goto find_page;
- } else if (ret)
- goto out;
-
- /*
- * Return the number of bytes written.
- */
- ret = this_len;
- mark_page_accessed(page);
- balance_dirty_pages_ratelimited(mapping);
+ }
out:
- if (!(buf->flags & PIPE_BUF_FLAG_STOLEN))
- page_cache_release(page);
-
+ page_cache_release(page);
unlock_page(page);
out_nomem:
- buf->ops->unmap(info, buf);
return ret;
}
@@ -1095,7 +1079,7 @@
*/
static int get_iovec_page_array(const struct iovec __user *iov,
unsigned int nr_vecs, struct page **pages,
- struct partial_page *partial)
+ struct partial_page *partial, int aligned)
{
int buffers = 0, error = 0;
@@ -1135,6 +1119,15 @@
* in the user pages.
*/
off = (unsigned long) base & ~PAGE_MASK;
+
+ /*
+ * If asked for alignment, the offset must be zero and the
+ * length a multiple of the PAGE_SIZE.
+ */
+ error = -EINVAL;
+ if (aligned && (off || len & ~PAGE_MASK))
+ break;
+
npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
if (npages > PIPE_BUFFERS - buffers)
npages = PIPE_BUFFERS - buffers;
@@ -1228,7 +1221,8 @@
else if (unlikely(!nr_segs))
return 0;
- spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial);
+ spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial,
+ flags & SPLICE_F_GIFT);
if (spd.nr_pages <= 0)
return spd.nr_pages;
@@ -1336,6 +1330,12 @@
obuf = opipe->bufs + nbuf;
*obuf = *ibuf;
+ /*
+ * Don't inherit the gift flag, we need to
+ * prevent multiple steals of this page.
+ */
+ obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
+
if (obuf->len > len)
obuf->len = len;
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index f431d8b0..7cfcff3 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -117,6 +117,7 @@
struct list_head list;
struct list_head sched_list;
int number;
+ int nid;
u32 isrc;
u32 node;
u64 flags;
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index 1e19cd0..87362a0 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -4,6 +4,9 @@
#include <linux/config.h>
+struct sys_device;
+struct device_node;
+
#ifdef CONFIG_NUMA
#include <asm/mmzone.h>
@@ -27,6 +30,8 @@
return first_cpu(tmp);
}
+int of_node_to_nid(struct device_node *device);
+
#define pcibus_to_node(node) (-1)
#define pcibus_to_cpumask(bus) (cpu_online_map)
@@ -57,10 +62,29 @@
extern void __init dump_numa_cpu_topology(void);
+extern int sysfs_add_device_to_node(struct sys_device *dev, int nid);
+extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid);
+
#else
+static inline int of_node_to_nid(struct device_node *device)
+{
+ return 0;
+}
+
static inline void dump_numa_cpu_topology(void) {}
+static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid)
+{
+ return 0;
+}
+
+static inline void sysfs_remove_device_from_node(struct sys_device *dev,
+ int nid)
+{
+}
+
+
#include <asm-generic/topology.h>
#endif /* CONFIG_NUMA */
diff --git a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h
index 9ad5d9c..e3a7c45 100644
--- a/include/asm-sparc64/tlbflush.h
+++ b/include/asm-sparc64/tlbflush.h
@@ -22,8 +22,6 @@
/* Local cpu only. */
extern void __flush_tlb_all(void);
-extern void __flush_tlb_page(unsigned long context, unsigned long page, unsigned long r);
-
extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end);
#ifndef CONFIG_SMP
diff --git a/include/linux/input.h b/include/linux/input.h
index b0e612d..50e338d 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -12,8 +12,6 @@
#ifdef __KERNEL__
#include <linux/time.h>
#include <linux/list.h>
-#include <linux/device.h>
-#include <linux/mod_devicetable.h>
#else
#include <sys/time.h>
#include <sys/ioctl.h>
@@ -58,6 +56,8 @@
#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
+#define EVIOCGREP _IOR('E', 0x03, int[2]) /* get repeat settings */
+#define EVIOCSREP _IOW('E', 0x03, int[2]) /* set repeat settings */
#define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */
#define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */
@@ -577,15 +577,15 @@
* Switch events
*/
-#define SW_0 0x00
-#define SW_1 0x01
-#define SW_2 0x02
-#define SW_3 0x03
-#define SW_4 0x04
-#define SW_5 0x05
-#define SW_6 0x06
-#define SW_7 0x07
-#define SW_MAX 0x0f
+#define SW_0 0x00
+#define SW_1 0x01
+#define SW_2 0x02
+#define SW_3 0x03
+#define SW_4 0x04
+#define SW_5 0x05
+#define SW_6 0x06
+#define SW_7 0x07
+#define SW_MAX 0x0f
/*
* Misc events
@@ -805,52 +805,16 @@
#define FF_MAX 0x7f
-struct input_device_id {
-
- kernel_ulong_t flags;
-
- struct input_id id;
-
- kernel_ulong_t evbit[EV_MAX/BITS_PER_LONG+1];
- kernel_ulong_t keybit[KEY_MAX/BITS_PER_LONG+1];
- kernel_ulong_t relbit[REL_MAX/BITS_PER_LONG+1];
- kernel_ulong_t absbit[ABS_MAX/BITS_PER_LONG+1];
- kernel_ulong_t mscbit[MSC_MAX/BITS_PER_LONG+1];
- kernel_ulong_t ledbit[LED_MAX/BITS_PER_LONG+1];
- kernel_ulong_t sndbit[SND_MAX/BITS_PER_LONG+1];
- kernel_ulong_t ffbit[FF_MAX/BITS_PER_LONG+1];
- kernel_ulong_t swbit[SW_MAX/BITS_PER_LONG+1];
-
- kernel_ulong_t driver_info;
-};
-
-/*
- * Structure for hotplug & device<->driver matching.
- */
-
-#define INPUT_DEVICE_ID_MATCH_BUS 1
-#define INPUT_DEVICE_ID_MATCH_VENDOR 2
-#define INPUT_DEVICE_ID_MATCH_PRODUCT 4
-#define INPUT_DEVICE_ID_MATCH_VERSION 8
-
-#define INPUT_DEVICE_ID_MATCH_EVBIT 0x010
-#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020
-#define INPUT_DEVICE_ID_MATCH_RELBIT 0x040
-#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080
-#define INPUT_DEVICE_ID_MATCH_MSCIT 0x100
-#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200
-#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400
-#define INPUT_DEVICE_ID_MATCH_FFBIT 0x800
-#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000
-
#ifdef __KERNEL__
/*
* In-kernel definitions.
*/
+#include <linux/device.h>
#include <linux/fs.h>
#include <linux/timer.h>
+#include <linux/mod_devicetable.h>
#define NBITS(x) (((x)/BITS_PER_LONG)+1)
#define BIT(x) (1UL<<((x)%BITS_PER_LONG))
@@ -951,9 +915,49 @@
};
#define to_input_dev(d) container_of(d, struct input_dev, cdev)
-#define INPUT_DEVICE_ID_MATCH_DEVICE\
+/*
+ * Verify that we are in sync with input_device_id mod_devicetable.h #defines
+ */
+
+#if EV_MAX != INPUT_DEVICE_ID_EV_MAX
+#error "EV_MAX and INPUT_DEVICE_ID_EV_MAX do not match"
+#endif
+
+#if KEY_MAX != INPUT_DEVICE_ID_KEY_MAX
+#error "KEY_MAX and INPUT_DEVICE_ID_KEY_MAX do not match"
+#endif
+
+#if REL_MAX != INPUT_DEVICE_ID_REL_MAX
+#error "REL_MAX and INPUT_DEVICE_ID_REL_MAX do not match"
+#endif
+
+#if ABS_MAX != INPUT_DEVICE_ID_ABS_MAX
+#error "ABS_MAX and INPUT_DEVICE_ID_ABS_MAX do not match"
+#endif
+
+#if MSC_MAX != INPUT_DEVICE_ID_MSC_MAX
+#error "MSC_MAX and INPUT_DEVICE_ID_MSC_MAX do not match"
+#endif
+
+#if LED_MAX != INPUT_DEVICE_ID_LED_MAX
+#error "LED_MAX and INPUT_DEVICE_ID_LED_MAX do not match"
+#endif
+
+#if SND_MAX != INPUT_DEVICE_ID_SND_MAX
+#error "SND_MAX and INPUT_DEVICE_ID_SND_MAX do not match"
+#endif
+
+#if FF_MAX != INPUT_DEVICE_ID_FF_MAX
+#error "FF_MAX and INPUT_DEVICE_ID_FF_MAX do not match"
+#endif
+
+#if SW_MAX != INPUT_DEVICE_ID_SW_MAX
+#error "SW_MAX and INPUT_DEVICE_ID_SW_MAX do not match"
+#endif
+
+#define INPUT_DEVICE_ID_MATCH_DEVICE \
(INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT)
-#define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\
+#define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION \
(INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION)
struct input_handle;
@@ -1016,7 +1020,8 @@
static inline void input_free_device(struct input_dev *dev)
{
- input_put_device(dev);
+ if (dev)
+ input_put_device(dev);
}
int input_register_device(struct input_dev *);
diff --git a/include/linux/list.h b/include/linux/list.h
index 67258b4..76f0571 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -619,7 +619,7 @@
static inline void hlist_del_init(struct hlist_node *n)
{
- if (n->pprev) {
+ if (!hlist_unhashed(n)) {
__hlist_del(n);
INIT_HLIST_NODE(n);
}
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 7b08c11..f697770 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -249,4 +249,52 @@
__u16 id;
};
+/* Input */
+#define INPUT_DEVICE_ID_EV_MAX 0x1f
+#define INPUT_DEVICE_ID_KEY_MAX 0x1ff
+#define INPUT_DEVICE_ID_REL_MAX 0x0f
+#define INPUT_DEVICE_ID_ABS_MAX 0x3f
+#define INPUT_DEVICE_ID_MSC_MAX 0x07
+#define INPUT_DEVICE_ID_LED_MAX 0x0f
+#define INPUT_DEVICE_ID_SND_MAX 0x07
+#define INPUT_DEVICE_ID_FF_MAX 0x7f
+#define INPUT_DEVICE_ID_SW_MAX 0x0f
+
+#define INPUT_DEVICE_ID_MATCH_BUS 1
+#define INPUT_DEVICE_ID_MATCH_VENDOR 2
+#define INPUT_DEVICE_ID_MATCH_PRODUCT 4
+#define INPUT_DEVICE_ID_MATCH_VERSION 8
+
+#define INPUT_DEVICE_ID_MATCH_EVBIT 0x0010
+#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x0020
+#define INPUT_DEVICE_ID_MATCH_RELBIT 0x0040
+#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x0080
+#define INPUT_DEVICE_ID_MATCH_MSCIT 0x0100
+#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x0200
+#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x0400
+#define INPUT_DEVICE_ID_MATCH_FFBIT 0x0800
+#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000
+
+struct input_device_id {
+
+ kernel_ulong_t flags;
+
+ __u16 bustype;
+ __u16 vendor;
+ __u16 product;
+ __u16 version;
+
+ kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1];
+
+ kernel_ulong_t driver_info;
+};
+
#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 3870145..48cc32d 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -337,6 +337,10 @@
char name[XT_FUNCTION_MAXNAMELEN - 1];
u_int8_t revision;
} user;
+ struct {
+ u_int16_t match_size;
+ compat_uptr_t match;
+ } kernel;
u_int16_t match_size;
} u;
unsigned char data[0];
@@ -350,6 +354,10 @@
char name[XT_FUNCTION_MAXNAMELEN - 1];
u_int8_t revision;
} user;
+ struct {
+ u_int16_t target_size;
+ compat_uptr_t target;
+ } kernel;
u_int16_t target_size;
} u;
unsigned char data[0];
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 0008d4b..df4d3fa 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -5,8 +5,9 @@
#define PIPE_BUFFERS (16)
-#define PIPE_BUF_FLAG_STOLEN 0x01
-#define PIPE_BUF_FLAG_LRU 0x02
+#define PIPE_BUF_FLAG_LRU 0x01 /* page is on the LRU */
+#define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */
+#define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */
struct pipe_buffer {
struct page *page;
@@ -15,10 +16,23 @@
unsigned int flags;
};
+/*
+ * Note on the nesting of these functions:
+ *
+ * ->pin()
+ * ->steal()
+ * ...
+ * ->map()
+ * ...
+ * ->unmap()
+ *
+ * That is, ->map() must be called on a pinned buffer, same goes for ->steal().
+ */
struct pipe_buf_operations {
int can_merge;
- void * (*map)(struct file *, struct pipe_inode_info *, struct pipe_buffer *);
- void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *);
+ void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int);
+ void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *);
+ int (*pin)(struct pipe_inode_info *, struct pipe_buffer *);
void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
@@ -51,6 +65,12 @@
void free_pipe_info(struct inode * inode);
void __free_pipe_info(struct pipe_inode_info *);
+/* Generic pipe buffer ops functions */
+void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int);
+void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *);
+void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
+int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *);
+
/*
* splice is tied to pipes as a transport (at least for now), so we'll just
* add the splice flags here.
@@ -60,6 +80,7 @@
/* we may still block on the fd we splice */
/* from/to, of course */
#define SPLICE_F_MORE (0x04) /* expect more data */
+#define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */
/*
* Passed to the actors
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h
index 72261e0f..adb3daf 100644
--- a/include/linux/spi/ads7846.h
+++ b/include/linux/spi/ads7846.h
@@ -14,5 +14,12 @@
u16 x_min, x_max;
u16 y_min, y_max;
u16 pressure_min, pressure_max;
+
+ u16 debounce_max; /* max number of additional readings
+ * per sample */
+ u16 debounce_tol; /* tolerance used for filtering */
+ u16 debounce_rep; /* additional consecutive good readings
+ * required after the first two */
+ int (*get_pendown_state)(void);
};
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 1da294c..e837f98 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -150,7 +150,7 @@
static inline int inet_twsk_dead_hashed(const struct inet_timewait_sock *tw)
{
- return tw->tw_death_node.pprev != NULL;
+ return !hlist_unhashed(&tw->tw_death_node);
}
static inline void inet_twsk_dead_node_init(struct inet_timewait_sock *tw)
diff --git a/include/net/sock.h b/include/net/sock.h
index ff8b0da..c9fad6f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -279,7 +279,7 @@
static inline int sk_hashed(const struct sock *sk)
{
- return sk->sk_node.pprev != NULL;
+ return !sk_unhashed(sk);
}
static __inline__ void sk_node_init(struct hlist_node *node)
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index df70e75..3734258 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -374,12 +374,14 @@
/* -- OSS things -- */
struct snd_pcm_oss_substream oss;
#endif
+#ifdef CONFIG_SND_VERBOSE_PROCFS
struct snd_info_entry *proc_root;
struct snd_info_entry *proc_info_entry;
struct snd_info_entry *proc_hw_params_entry;
struct snd_info_entry *proc_sw_params_entry;
struct snd_info_entry *proc_status_entry;
struct snd_info_entry *proc_prealloc_entry;
+#endif
/* misc flags */
unsigned int no_mmap_ctrl: 1;
unsigned int hw_opened: 1;
@@ -400,12 +402,14 @@
struct snd_pcm_oss_stream oss;
#endif
struct snd_pcm_file *files;
+#ifdef CONFIG_SND_VERBOSE_PROCFS
struct snd_info_entry *proc_root;
struct snd_info_entry *proc_info_entry;
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
unsigned int xrun_debug; /* 0 = disabled, 1 = verbose, 2 = stacktrace */
struct snd_info_entry *proc_xrun_debug_entry;
#endif
+#endif
};
struct snd_pcm {
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index 39df2ba..c854647 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -75,7 +75,9 @@
struct snd_pcm_oss_stream {
struct snd_pcm_oss_setup *setup_list; /* setup list */
struct mutex setup_mutex;
+#ifdef CONFIG_SND_VERBOSE_PROCFS
struct snd_info_entry *proc_entry;
+#endif
};
struct snd_pcm_oss {
diff --git a/init/main.c b/init/main.c
index 4a2f089..f715b9b 100644
--- a/init/main.c
+++ b/init/main.c
@@ -582,7 +582,7 @@
result = (*call)();
- if (result && (result != -ENODEV || initcall_debug)) {
+ if (result && result != -ENODEV && initcall_debug) {
sprintf(msgbuf, "error code %d", result);
msg = msgbuf;
}
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 1fe76d9..1ae2b2c 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -69,12 +69,16 @@
for (i = 0; i < nr_pages; i += PAGES_PER_SECTION) {
err = __add_section(zone, phys_start_pfn + i);
- if (err)
+ /* We want to keep adding the rest of the
+ * sections if the first ones already exist
+ */
+ if (err && (err != -EEXIST))
break;
}
return err;
}
+EXPORT_SYMBOL_GPL(__add_pages);
static void grow_zone_span(struct zone *zone,
unsigned long start_pfn, unsigned long end_pfn)
diff --git a/mm/migrate.c b/mm/migrate.c
index d444229..1c25040 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -439,6 +439,17 @@
goto unlock_both;
}
+ /* Make sure the dirty bit is up to date */
+ if (try_to_unmap(page, 1) == SWAP_FAIL) {
+ rc = -EPERM;
+ goto unlock_both;
+ }
+
+ if (page_mapcount(page)) {
+ rc = -EAGAIN;
+ goto unlock_both;
+ }
+
/*
* Default handling if a filesystem does not provide
* a migration function. We can only migrate clean
diff --git a/mm/sparse.c b/mm/sparse.c
index 0a51f36..d7c32de 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -32,7 +32,10 @@
unsigned long array_size = SECTIONS_PER_ROOT *
sizeof(struct mem_section);
- section = alloc_bootmem_node(NODE_DATA(nid), array_size);
+ if (system_state == SYSTEM_RUNNING)
+ section = kmalloc_node(array_size, GFP_KERNEL, nid);
+ else
+ section = alloc_bootmem_node(NODE_DATA(nid), array_size);
if (section)
memset(section, 0, array_size);
@@ -281,9 +284,9 @@
ret = sparse_init_one_section(ms, section_nr, memmap);
- if (ret <= 0)
- __kfree_section_memmap(memmap, nr_pages);
out:
pgdat_resize_unlock(pgdat, &flags);
+ if (ret <= 0)
+ __kfree_section_memmap(memmap, nr_pages);
return ret;
}
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index dc206f1..0a27745 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1257,7 +1257,7 @@
goto out;
}
-module_init(inet_init);
+fs_initcall(inet_init);
/* ------------------------------------------------------------------------ */
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index d25ac8b..6d1c115 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -956,15 +956,16 @@
compat_int_t verdict;
};
-#define IPT_ST_OFFSET (sizeof(struct ipt_standard_target) - \
- sizeof(struct compat_ipt_standard_target))
-
struct compat_ipt_standard
{
struct compat_ipt_entry entry;
struct compat_ipt_standard_target target;
};
+#define IPT_ST_LEN XT_ALIGN(sizeof(struct ipt_standard_target))
+#define IPT_ST_COMPAT_LEN COMPAT_XT_ALIGN(sizeof(struct compat_ipt_standard_target))
+#define IPT_ST_OFFSET (IPT_ST_LEN - IPT_ST_COMPAT_LEN)
+
static int compat_ipt_standard_fn(void *target,
void **dstptr, int *size, int convert)
{
@@ -975,35 +976,29 @@
ret = 0;
switch (convert) {
case COMPAT_TO_USER:
- pst = (struct ipt_standard_target *)target;
+ pst = target;
memcpy(&compat_st.target, &pst->target,
- sizeof(struct ipt_entry_target));
+ sizeof(compat_st.target));
compat_st.verdict = pst->verdict;
if (compat_st.verdict > 0)
compat_st.verdict -=
compat_calc_jump(compat_st.verdict);
- compat_st.target.u.user.target_size =
- sizeof(struct compat_ipt_standard_target);
- if (__copy_to_user(*dstptr, &compat_st,
- sizeof(struct compat_ipt_standard_target)))
+ compat_st.target.u.user.target_size = IPT_ST_COMPAT_LEN;
+ if (copy_to_user(*dstptr, &compat_st, IPT_ST_COMPAT_LEN))
ret = -EFAULT;
*size -= IPT_ST_OFFSET;
- *dstptr += sizeof(struct compat_ipt_standard_target);
+ *dstptr += IPT_ST_COMPAT_LEN;
break;
case COMPAT_FROM_USER:
- pcompat_st =
- (struct compat_ipt_standard_target *)target;
- memcpy(&st.target, &pcompat_st->target,
- sizeof(struct ipt_entry_target));
+ pcompat_st = target;
+ memcpy(&st.target, &pcompat_st->target, IPT_ST_COMPAT_LEN);
st.verdict = pcompat_st->verdict;
if (st.verdict > 0)
st.verdict += compat_calc_jump(st.verdict);
- st.target.u.user.target_size =
- sizeof(struct ipt_standard_target);
- memcpy(*dstptr, &st,
- sizeof(struct ipt_standard_target));
+ st.target.u.user.target_size = IPT_ST_LEN;
+ memcpy(*dstptr, &st, IPT_ST_LEN);
*size += IPT_ST_OFFSET;
- *dstptr += sizeof(struct ipt_standard_target);
+ *dstptr += IPT_ST_LEN;
break;
case COMPAT_CALC_SIZE:
*size += IPT_ST_OFFSET;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index a28ae59..743016b 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -465,7 +465,7 @@
TCP_INC_STATS(TCP_MIB_OUTSEGS);
err = icsk->icsk_af_ops->queue_xmit(skb, 0);
- if (unlikely(err <= 0))
+ if (likely(err <= 0))
return err;
tcp_enter_cwr(sk);
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 32ad229..4ef8efa 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -62,7 +62,7 @@
top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
0 : (iph->frag_off & htons(IP_DF));
if (!top_iph->frag_off)
- __ip_select_ident(top_iph, dst, 0);
+ __ip_select_ident(top_iph, dst->child, 0);
top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 7907874..0190e39 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -317,7 +317,7 @@
__FUNCTION__, head, head ? *head : NULL, oif);
for (rt = rt0, metric = rt0->rt6i_metric;
- rt && rt->rt6i_metric == metric;
+ rt && rt->rt6i_metric == metric && (!last || rt != rt0);
rt = rt->u.next) {
int m;
@@ -343,9 +343,12 @@
(strict & RT6_SELECT_F_REACHABLE) &&
last && last != rt0) {
/* no entries matched; do round-robin */
+ static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+ spin_lock(&lock);
*head = rt0->u.next;
rt0->u.next = last->u.next;
last->u.next = rt0;
+ spin_unlock(&lock);
}
RT6_TRACE("%s() => %p, score=%d\n",
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 09fbc4b..3862e73 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -62,7 +62,6 @@
#include <net/scm.h>
#include <net/netlink.h>
-#define Nprintk(a...)
#define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8)
struct netlink_sock {
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 7228d30..5a4a4d0 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -167,7 +167,7 @@
if (count == 0) {
sch->qstats.drops++;
kfree_skb(skb);
- return NET_XMIT_DROP;
+ return NET_XMIT_BYPASS;
}
/*
diff --git a/net/x25/x25_timer.c b/net/x25/x25_timer.c
index 0a92e1d..71ff308 100644
--- a/net/x25/x25_timer.c
+++ b/net/x25/x25_timer.c
@@ -114,8 +114,9 @@
if (sock_flag(sk, SOCK_DESTROY) ||
(sk->sk_state == TCP_LISTEN &&
sock_flag(sk, SOCK_DEAD))) {
+ bh_unlock_sock(sk);
x25_destroy_socket(sk);
- goto unlock;
+ return;
}
break;
@@ -128,7 +129,6 @@
}
restart_heartbeat:
x25_start_heartbeat(sk);
-unlock:
bh_unlock_sock(sk);
}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index c3725fe..b469c8b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -57,12 +57,12 @@
return -EAFNOSUPPORT;
typemap = afinfo->type_map;
- write_lock(&typemap->lock);
+ write_lock_bh(&typemap->lock);
if (likely(typemap->map[type->proto] == NULL))
typemap->map[type->proto] = type;
else
err = -EEXIST;
- write_unlock(&typemap->lock);
+ write_unlock_bh(&typemap->lock);
xfrm_policy_put_afinfo(afinfo);
return err;
}
@@ -78,12 +78,12 @@
return -EAFNOSUPPORT;
typemap = afinfo->type_map;
- write_lock(&typemap->lock);
+ write_lock_bh(&typemap->lock);
if (unlikely(typemap->map[type->proto] != type))
err = -ENOENT;
else
typemap->map[type->proto] = NULL;
- write_unlock(&typemap->lock);
+ write_unlock_bh(&typemap->lock);
xfrm_policy_put_afinfo(afinfo);
return err;
}
@@ -1251,7 +1251,7 @@
return -EINVAL;
if (unlikely(afinfo->family >= NPROTO))
return -EAFNOSUPPORT;
- write_lock(&xfrm_policy_afinfo_lock);
+ write_lock_bh(&xfrm_policy_afinfo_lock);
if (unlikely(xfrm_policy_afinfo[afinfo->family] != NULL))
err = -ENOBUFS;
else {
@@ -1268,7 +1268,7 @@
afinfo->garbage_collect = __xfrm_garbage_collect;
xfrm_policy_afinfo[afinfo->family] = afinfo;
}
- write_unlock(&xfrm_policy_afinfo_lock);
+ write_unlock_bh(&xfrm_policy_afinfo_lock);
return err;
}
EXPORT_SYMBOL(xfrm_policy_register_afinfo);
@@ -1280,7 +1280,7 @@
return -EINVAL;
if (unlikely(afinfo->family >= NPROTO))
return -EAFNOSUPPORT;
- write_lock(&xfrm_policy_afinfo_lock);
+ write_lock_bh(&xfrm_policy_afinfo_lock);
if (likely(xfrm_policy_afinfo[afinfo->family] != NULL)) {
if (unlikely(xfrm_policy_afinfo[afinfo->family] != afinfo))
err = -EINVAL;
@@ -1294,7 +1294,7 @@
afinfo->garbage_collect = NULL;
}
}
- write_unlock(&xfrm_policy_afinfo_lock);
+ write_unlock_bh(&xfrm_policy_afinfo_lock);
return err;
}
EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 3dc3e1f..93a2f36 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1061,7 +1061,7 @@
return -EINVAL;
if (unlikely(afinfo->family >= NPROTO))
return -EAFNOSUPPORT;
- write_lock(&xfrm_state_afinfo_lock);
+ write_lock_bh(&xfrm_state_afinfo_lock);
if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL))
err = -ENOBUFS;
else {
@@ -1069,7 +1069,7 @@
afinfo->state_byspi = xfrm_state_byspi;
xfrm_state_afinfo[afinfo->family] = afinfo;
}
- write_unlock(&xfrm_state_afinfo_lock);
+ write_unlock_bh(&xfrm_state_afinfo_lock);
return err;
}
EXPORT_SYMBOL(xfrm_state_register_afinfo);
@@ -1081,7 +1081,7 @@
return -EINVAL;
if (unlikely(afinfo->family >= NPROTO))
return -EAFNOSUPPORT;
- write_lock(&xfrm_state_afinfo_lock);
+ write_lock_bh(&xfrm_state_afinfo_lock);
if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) {
if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo))
err = -EINVAL;
@@ -1091,7 +1091,7 @@
afinfo->state_bydst = NULL;
}
}
- write_unlock(&xfrm_state_afinfo_lock);
+ write_unlock_bh(&xfrm_state_afinfo_lock);
return err;
}
EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 84e2120..37f67c2 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -374,10 +374,10 @@
kernel_ulong_t *arr, unsigned int min, unsigned int max)
{
unsigned int i;
- for (i = min; i < max; i++) {
- if (arr[i/BITS_PER_LONG] & (1 << (i%BITS_PER_LONG)))
- sprintf(alias+strlen(alias), "%X,*", i);
- }
+
+ for (i = min; i < max; i++)
+ if (arr[i / BITS_PER_LONG] & (1 << (i%BITS_PER_LONG)))
+ sprintf(alias + strlen(alias), "%X,*", i);
}
/* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */
@@ -386,39 +386,37 @@
{
sprintf(alias, "input:");
- ADD(alias, "b", id->flags&INPUT_DEVICE_ID_MATCH_BUS, id->id.bustype);
- ADD(alias, "v", id->flags&INPUT_DEVICE_ID_MATCH_VENDOR, id->id.vendor);
- ADD(alias, "p", id->flags&INPUT_DEVICE_ID_MATCH_PRODUCT,
- id->id.product);
- ADD(alias, "e", id->flags&INPUT_DEVICE_ID_MATCH_VERSION,
- id->id.version);
+ ADD(alias, "b", id->flags & INPUT_DEVICE_ID_MATCH_BUS, id->bustype);
+ ADD(alias, "v", id->flags & INPUT_DEVICE_ID_MATCH_VENDOR, id->vendor);
+ ADD(alias, "p", id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT, id->product);
+ ADD(alias, "e", id->flags & INPUT_DEVICE_ID_MATCH_VERSION, id->version);
sprintf(alias + strlen(alias), "-e*");
- if (id->flags&INPUT_DEVICE_ID_MATCH_EVBIT)
+ if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT)
do_input(alias, id->evbit, 0, EV_MAX);
sprintf(alias + strlen(alias), "k*");
- if (id->flags&INPUT_DEVICE_ID_MATCH_KEYBIT)
+ if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT)
do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
sprintf(alias + strlen(alias), "r*");
- if (id->flags&INPUT_DEVICE_ID_MATCH_RELBIT)
+ if (id->flags & INPUT_DEVICE_ID_MATCH_RELBIT)
do_input(alias, id->relbit, 0, REL_MAX);
sprintf(alias + strlen(alias), "a*");
- if (id->flags&INPUT_DEVICE_ID_MATCH_ABSBIT)
+ if (id->flags & INPUT_DEVICE_ID_MATCH_ABSBIT)
do_input(alias, id->absbit, 0, ABS_MAX);
sprintf(alias + strlen(alias), "m*");
- if (id->flags&INPUT_DEVICE_ID_MATCH_MSCIT)
+ if (id->flags & INPUT_DEVICE_ID_MATCH_MSCIT)
do_input(alias, id->mscbit, 0, MSC_MAX);
sprintf(alias + strlen(alias), "l*");
- if (id->flags&INPUT_DEVICE_ID_MATCH_LEDBIT)
+ if (id->flags & INPUT_DEVICE_ID_MATCH_LEDBIT)
do_input(alias, id->ledbit, 0, LED_MAX);
sprintf(alias + strlen(alias), "s*");
- if (id->flags&INPUT_DEVICE_ID_MATCH_SNDBIT)
+ if (id->flags & INPUT_DEVICE_ID_MATCH_SNDBIT)
do_input(alias, id->sndbit, 0, SND_MAX);
sprintf(alias + strlen(alias), "f*");
- if (id->flags&INPUT_DEVICE_ID_MATCH_FFBIT)
+ if (id->flags & INPUT_DEVICE_ID_MATCH_FFBIT)
do_input(alias, id->ffbit, 0, FF_MAX);
sprintf(alias + strlen(alias), "w*");
- if (id->flags&INPUT_DEVICE_ID_MATCH_SWBIT)
+ if (id->flags & INPUT_DEVICE_ID_MATCH_SWBIT)
do_input(alias, id->swbit, 0, SW_MAX);
return 1;
}
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 8efc1b1..4262a1c 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -142,7 +142,7 @@
config SND_VERBOSE_PROCFS
bool "Verbose procfs contents"
- depends on SND
+ depends on SND && PROC_FS
default y
help
Say Y here to include code for verbose procfs contents (provides
@@ -171,3 +171,13 @@
help
Say Y here to enable extra-verbose log messages printed when
detecting devices.
+
+config SND_PCM_XRUN_DEBUG
+ bool "Enable PCM ring buffer overrun/underrun debugging"
+ default n
+ depends on SND_DEBUG && SND_VERBOSE_PROCFS
+ help
+ Say Y to enable the PCM ring buffer overrun/underrun debugging.
+ It is usually not required, but if you have trouble with
+ sound clicking when system is loaded, it may help to determine
+ the process or driver which causes the scheduling gaps.
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index c5978d6..ac990bf 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1242,6 +1242,8 @@
if (format != AFMT_QUERY) {
formats = snd_pcm_oss_get_formats(pcm_oss_file);
+ if (formats < 0)
+ return formats;
if (!(formats & format))
format = AFMT_U8;
for (idx = 1; idx >= 0; --idx) {
@@ -2212,7 +2214,7 @@
return 0;
}
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SND_VERBOSE_PROCFS
/*
* /proc interface
*/
@@ -2366,10 +2368,10 @@
}
}
}
-#else /* !CONFIG_PROC_FS */
+#else /* !CONFIG_SND_VERBOSE_PROCFS */
#define snd_pcm_oss_proc_init(pcm)
#define snd_pcm_oss_proc_done(pcm)
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_SND_VERBOSE_PROCFS */
/*
* ENTRY functions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 122e10a..84b0003 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -142,7 +142,7 @@
return -ENOIOCTLCMD;
}
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS)
+#ifdef CONFIG_SND_VERBOSE_PROCFS
#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
@@ -436,7 +436,7 @@
snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr);
}
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
@@ -480,7 +480,7 @@
}
pstr->proc_info_entry = entry;
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
pstr->proc_root)) != NULL) {
entry->c.text.read_size = 64;
@@ -501,7 +501,7 @@
static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr)
{
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if (pstr->proc_xrun_debug_entry) {
snd_info_unregister(pstr->proc_xrun_debug_entry);
pstr->proc_xrun_debug_entry = NULL;
@@ -599,12 +599,12 @@
}
return 0;
}
-#else /* !CONFIG_PROC_FS */
+#else /* !CONFIG_SND_VERBOSE_PROCFS */
static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }
static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }
static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }
static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; }
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_SND_VERBOSE_PROCFS */
/**
* snd_pcm_new_stream - create a new PCM stream
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 230a940..eedc6cb 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -130,7 +130,7 @@
static void xrun(struct snd_pcm_substream *substream)
{
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if (substream->pstr->xrun_debug) {
snd_printd(KERN_DEBUG "XRUN: pcmC%dD%d%c\n",
substream->pcm->card->number,
@@ -204,7 +204,7 @@
delta = hw_ptr_interrupt - new_hw_ptr;
if (delta > 0) {
if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) {
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if (runtime->periods > 1 && substream->pstr->xrun_debug) {
snd_printd(KERN_ERR "Unexpected hw_pointer value [1] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2);
if (substream->pstr->xrun_debug > 1)
@@ -249,7 +249,7 @@
delta = old_hw_ptr - new_hw_ptr;
if (delta > 0) {
if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) {
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if (runtime->periods > 2 && substream->pstr->xrun_debug) {
snd_printd(KERN_ERR "Unexpected hw_pointer value [2] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2);
if (substream->pstr->xrun_debug > 1)
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index a0119ae..428f8c1 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -100,8 +100,10 @@
int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream)
{
snd_pcm_lib_preallocate_dma_free(substream);
+#ifdef CONFIG_SND_VERBOSE_PROCFS
snd_info_unregister(substream->proc_prealloc_entry);
substream->proc_prealloc_entry = NULL;
+#endif
return 0;
}
@@ -124,7 +126,7 @@
return 0;
}
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SND_VERBOSE_PROCFS
/*
* read callback for prealloc proc file
*
@@ -203,9 +205,9 @@
substream->proc_prealloc_entry = entry;
}
-#else /* !CONFIG_PROC_FS */
+#else /* !CONFIG_SND_VERBOSE_PROCFS */
#define preallocate_info_init(s)
-#endif
+#endif /* CONFIG_SND_VERBOSE_PROCFS */
/*
* pre-allocate the buffer and create a proc file for the substream
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index e35fd57..ae0df54 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -675,10 +675,8 @@
continue;
device = platform_device_register_simple(SND_DUMMY_DRIVER,
i, NULL, 0);
- if (IS_ERR(device)) {
- err = PTR_ERR(device);
- goto errout;
- }
+ if (IS_ERR(device))
+ continue;
devices[i] = device;
cards++;
}
@@ -686,14 +684,10 @@
#ifdef MODULE
printk(KERN_ERR "Dummy soundcard not found or device busy\n");
#endif
- err = -ENODEV;
- goto errout;
+ snd_dummy_unregister_all();
+ return -ENODEV;
}
return 0;
-
- errout:
- snd_dummy_unregister_all();
- return err;
}
static void __exit alsa_card_dummy_exit(void)
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 9ea3059..da7ef26 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -251,10 +251,8 @@
#endif
device = platform_device_register_simple(SND_MPU401_DRIVER,
i, NULL, 0);
- if (IS_ERR(device)) {
- err = PTR_ERR(device);
- goto errout;
- }
+ if (IS_ERR(device))
+ continue;
platform_devices[i] = device;
snd_mpu401_devices++;
}
@@ -266,14 +264,10 @@
#ifdef MODULE
printk(KERN_ERR "MPU-401 device not found or device busy\n");
#endif
- err = -ENODEV;
- goto errout;
+ snd_mpu401_unregister_all();
+ return -ENODEV;
}
return 0;
-
- errout:
- snd_mpu401_unregister_all();
- return err;
}
static void __exit alsa_card_mpu401_exit(void)
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 1a7fbef..c01b4c5 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -996,10 +996,8 @@
continue;
device = platform_device_register_simple(SND_SERIAL_DRIVER,
i, NULL, 0);
- if (IS_ERR(device)) {
- err = PTR_ERR(device);
- goto errout;
- }
+ if (IS_ERR(device))
+ continue;
devices[i] = device;
cards++;
}
@@ -1007,14 +1005,10 @@
#ifdef MODULE
printk(KERN_ERR "serial midi soundcard not found or device busy\n");
#endif
- err = -ENODEV;
- goto errout;
+ snd_serial_unregister_all();
+ return -ENODEV;
}
return 0;
-
- errout:
- snd_serial_unregister_all();
- return err;
}
static void __exit alsa_card_serial_exit(void)
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index a3ee306..26eb249 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -169,10 +169,8 @@
continue;
device = platform_device_register_simple(SND_VIRMIDI_DRIVER,
i, NULL, 0);
- if (IS_ERR(device)) {
- err = PTR_ERR(device);
- goto errout;
- }
+ if (IS_ERR(device))
+ continue;
devices[i] = device;
cards++;
}
@@ -180,14 +178,10 @@
#ifdef MODULE
printk(KERN_ERR "Card-VirMIDI soundcard not found or device busy\n");
#endif
- err = -ENODEV;
- goto errout;
+ snd_virmidi_unregister_all();
+ return -ENODEV;
}
return 0;
-
- errout:
- snd_virmidi_unregister_all();
- return err;
}
static void __exit alsa_card_virmidi_exit(void)
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 83d64bc..e6bfcf7 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -1179,20 +1179,17 @@
/* force ACI into a known state */
for (i = 0; i < 3; i++)
if (aci_cmd(miro, ACI_ERROR_OP, -1, -1) < 0) {
- snd_card_free(card);
snd_printk(KERN_ERR "can't force aci into known state.\n");
return -ENXIO;
}
if ((miro->aci_vendor=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0 ||
(miro->aci_product=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0) {
- snd_card_free(card);
snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n", miro->aci_port);
return -ENXIO;
}
if ((miro->aci_version=aci_cmd(miro, ACI_READ_VERSION, -1, -1)) < 0) {
- snd_card_free(card);
snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n",
miro->aci_port);
return -ENXIO;
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index c6c8333..eece1c7 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -39,7 +39,6 @@
#include <linux/interrupt.h>
#include <linux/compiler.h>
#include <linux/delay.h>
-#include <linux/dma-mapping.h>
#include <sound/driver.h>
#include <sound/core.h>
@@ -1052,7 +1051,7 @@
pci_set_drvdata(pci, NULL);
}
-static struct pci_device_id snd_ad1889_ids[] = {
+static struct pci_device_id snd_ad1889_ids[] __devinitdata = {
{ PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
{ 0, },
};
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index fc92b68..e2dbc21 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -279,7 +279,7 @@
#endif
};
-static struct pci_device_id snd_ali_ids[] = {
+static struct pci_device_id snd_ali_ids[] __devinitdata = {
{PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0},
{0, }
};
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 91899f8..901b08a 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -146,7 +146,7 @@
int block_counter_register;
};
-static struct pci_device_id snd_als300_ids[] = {
+static struct pci_device_id snd_als300_ids[] __devinitdata = {
{ 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 },
{ 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS },
{ 0, }
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 100d812..60423b1 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -116,7 +116,7 @@
#endif
};
-static struct pci_device_id snd_als4000_ids[] = {
+static struct pci_device_id snd_als4000_ids[] __devinitdata = {
{ 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */
{ 0, }
};
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 12e6188..d0f759d 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -284,7 +284,7 @@
/*
*/
-static struct pci_device_id snd_atiixp_ids[] = {
+static struct pci_device_id snd_atiixp_ids[] __devinitdata = {
{ 0x1002, 0x4341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */
{ 0x1002, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB300 */
{ 0x1002, 0x4370, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 1d37660..12a34c3 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -262,7 +262,7 @@
/*
*/
-static struct pci_device_id snd_atiixp_ids[] = {
+static struct pci_device_id snd_atiixp_ids[] __devinitdata = {
{ 0x1002, 0x434d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */
{ 0x1002, 0x4378, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */
{ 0, }
diff --git a/sound/pci/au88x0/au8810.c b/sound/pci/au88x0/au8810.c
index fce22c7..bd33529 100644
--- a/sound/pci/au88x0/au8810.c
+++ b/sound/pci/au88x0/au8810.c
@@ -1,6 +1,6 @@
#include "au8810.h"
#include "au88x0.h"
-static struct pci_device_id snd_vortex_ids[] = {
+static struct pci_device_id snd_vortex_ids[] __devinitdata = {
{PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1,},
{0,}
diff --git a/sound/pci/au88x0/au8820.c b/sound/pci/au88x0/au8820.c
index d1fbcce..7e3fd83 100644
--- a/sound/pci/au88x0/au8820.c
+++ b/sound/pci/au88x0/au8820.c
@@ -1,6 +1,6 @@
#include "au8820.h"
#include "au88x0.h"
-static struct pci_device_id snd_vortex_ids[] = {
+static struct pci_device_id snd_vortex_ids[] __devinitdata = {
{PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
{0,}
diff --git a/sound/pci/au88x0/au8830.c b/sound/pci/au88x0/au8830.c
index d4f2717..b840f66 100644
--- a/sound/pci/au88x0/au8830.c
+++ b/sound/pci/au88x0/au8830.c
@@ -1,6 +1,6 @@
#include "au8830.h"
#include "au88x0.h"
-static struct pci_device_id snd_vortex_ids[] = {
+static struct pci_device_id snd_vortex_ids[] __devinitdata = {
{PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
{0,}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 680077e..52a3645 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -216,7 +216,7 @@
int irq;
};
-static const struct pci_device_id snd_azf3328_ids[] = {
+static const struct pci_device_id snd_azf3328_ids[] __devinitdata = {
{ 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
{ 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
{ 0, }
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 7b44a8d..9ee07d4 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -774,7 +774,7 @@
.driver_data = rate }
/* driver_data is the default digital_rate value for that device */
-static struct pci_device_id snd_bt87x_ids[] = {
+static struct pci_device_id snd_bt87x_ids[] __devinitdata = {
/* Hauppauge WinTV series */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000),
/* Hauppauge WinTV series */
@@ -911,7 +911,7 @@
/* default entries for all Bt87x cards - it's not exported */
/* driver_data is set to 0 to call detection */
-static struct pci_device_id snd_bt87x_default_ids[] = {
+static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = {
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, 0),
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, 0),
{ }
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 9477838..fd8bfeb 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1561,7 +1561,7 @@
}
// PCI IDs
-static struct pci_device_id snd_ca0106_ids[] = {
+static struct pci_device_id snd_ca0106_ids[] __devinitdata = {
{ 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */
{ 0, }
};
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 2ecbddb..e5ce2da 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -2609,7 +2609,7 @@
#endif
-static struct pci_device_id snd_cmipci_ids[] = {
+static struct pci_device_id snd_cmipci_ids[] __devinitdata = {
{PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index ac4e73f..b3c94d8 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -494,7 +494,7 @@
static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static struct pci_device_id snd_cs4281_ids[] = {
+static struct pci_device_id snd_cs4281_ids[] __devinitdata = {
{ 0x1013, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4281 */
{ 0, }
};
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index c590602..848d772 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -65,7 +65,7 @@
module_param_array(mmap_valid, bool, NULL, 0444);
MODULE_PARM_DESC(mmap_valid, "Support OSS mmap.");
-static struct pci_device_id snd_cs46xx_ids[] = {
+static struct pci_device_id snd_cs46xx_ids[] __devinitdata = {
{ 0x1013, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4280 */
{ 0x1013, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4612 */
{ 0x1013, 0x6004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4615 */
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 9fc7f38..2c1213a 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -45,7 +45,7 @@
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static struct pci_device_id snd_cs5535audio_ids[] = {
+static struct pci_device_id snd_cs5535audio_ids[] __devinitdata = {
{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 2dfa932..42b11ba 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -77,7 +77,7 @@
/*
* Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
*/
-static struct pci_device_id snd_emu10k1_ids[] = {
+static struct pci_device_id snd_emu10k1_ids[] __devinitdata = {
{ 0x1102, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* EMU10K1 */
{ 0x1102, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy */
{ 0x1102, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy 2 Value SB0400 */
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 3e332f3..d51290c 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -36,7 +36,6 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
@@ -1596,7 +1595,7 @@
}
// PCI IDs
-static struct pci_device_id snd_emu10k1x_ids[] = {
+static struct pci_device_id snd_emu10k1x_ids[] __devinitdata = {
{ 0x1102, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Dell OEM version (EMU10K1) */
{ 0, }
};
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index a5533c8..ca9e34e 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -446,7 +446,7 @@
static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static struct pci_device_id snd_audiopci_ids[] = {
+static struct pci_device_id snd_audiopci_ids[] __devinitdata = {
#ifdef CHIP1370
{ 0x1274, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1370 */
#endif
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 4d62fe4..6f9094c 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -242,7 +242,7 @@
static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static struct pci_device_id snd_es1938_ids[] = {
+static struct pci_device_id snd_es1938_ids[] __devinitdata = {
{ 0x125d, 0x1969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Solo-1 */
{ 0, }
};
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index e3ad17f..5ff4175 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -104,7 +104,6 @@
#include <linux/slab.h>
#include <linux/gameport.h>
#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
#include <linux/mutex.h>
#include <sound/core.h>
@@ -593,7 +592,7 @@
static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static struct pci_device_id snd_es1968_ids[] = {
+static struct pci_device_id snd_es1968_ids[] __devinitdata = {
/* Maestro 1 */
{ 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO },
/* Maestro 2 */
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 6ab4aef..d72fc28 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -199,7 +199,7 @@
#endif
};
-static struct pci_device_id snd_fm801_ids[] = {
+static struct pci_device_id snd_fm801_ids[] __devinitdata = {
{ 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */
{ 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */
{ 0, }
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 0ad60ae..e821d65 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1614,7 +1614,7 @@
}
/* PCI IDs */
-static struct pci_device_id azx_ids[] = {
+static struct pci_device_id azx_ids[] __devinitdata = {
{ 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH6 */
{ 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH7 */
{ 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ESB2 */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index bcfca15..40f000b 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -799,10 +799,14 @@
{ .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD },
{ .pci_subvendor = 0x144d, .pci_subdevice = 0xc024,
.config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */
+ { .pci_subvendor = 0x1043, .pci_subdevice = 0x1153,
+ .config = AD1986A_LAPTOP_EAPD }, /* ASUS M9 */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1213,
.config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x11f7,
.config = AD1986A_LAPTOP_EAPD }, /* ASUS U5A */
+ { .pci_subvendor = 0x1043, .pci_subdevice = 0x1297,
+ .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */
{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30af,
.config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */
{}
@@ -1330,12 +1334,8 @@
static struct hda_board_config ad1981_cfg_tbl[] = {
{ .modelname = "hp", .config = AD1981_HP },
- { .pci_subvendor = 0x103c, .pci_subdevice = 0x30aa,
- .config = AD1981_HP }, /* HP nx6320 */
- { .pci_subvendor = 0x103c, .pci_subdevice = 0x309f,
- .config = AD1981_HP }, /* HP nx9420 AngelFire */
- { .pci_subvendor = 0x103c, .pci_subdevice = 0x30a2,
- .config = AD1981_HP }, /* HP nx9420 AngelFire */
+ /* All HP models */
+ { .pci_subvendor = 0x103c, .config = AD1981_HP },
{ .modelname = "basic", .config = AD1981_BASIC },
{}
};
@@ -2623,5 +2623,6 @@
{ .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
{ .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
{ .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
+ { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
{} /* terminator */
};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 66bbdb6..f0e9a9c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2148,6 +2148,7 @@
{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG },
{ .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */
{ .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */
+ { .pci_subvendor = 0x1695, .pci_subdevice = 0x4012, .config = ALC880_5ST_DIG }, /* Epox EP-5LDA+ GLi */
{ .modelname = "asus", .config = ALC880_ASUS },
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7152607..8c440fb 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1212,8 +1212,8 @@
static struct hda_input_mux vaio_mux = {
.num_items = 2,
.items = {
- /* { "HP", 0x0 },
- { "Unknown", 0x1 }, */
+ /* { "HP", 0x0 }, */
+ { "Line", 0x1 },
{ "Mic", 0x2 },
{ "PCM", 0x3 },
}
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 32f8415..c56793b 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -56,7 +56,6 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
#include <linux/mutex.h>
#include <sound/core.h>
@@ -108,7 +107,7 @@
MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE.");
-static struct pci_device_id snd_ice1712_ids[] = {
+static struct pci_device_id snd_ice1712_ids[] __devinitdata = {
{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */
{ 0, }
};
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index fce616c..b1c007e 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -86,7 +86,7 @@
/* Both VT1720 and VT1724 have the same PCI IDs */
-static struct pci_device_id snd_vt1724_ids[] = {
+static struct pci_device_id snd_vt1724_ids[] __devinitdata = {
{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, }
};
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index ebbf2cf..0df7602 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -413,7 +413,7 @@
u32 int_sta_mask; /* interrupt status mask */
};
-static struct pci_device_id snd_intel8x0_ids[] = {
+static struct pci_device_id snd_intel8x0_ids[] __devinitdata = {
{ 0x8086, 0x2415, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */
{ 0x8086, 0x2425, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */
{ 0x8086, 0x2445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */
@@ -1293,6 +1293,7 @@
return 0;
}
+#if 0 // NYI
static int snd_intel8x0_ali_spdifin_open(struct snd_pcm_substream *substream)
{
struct intel8x0 *chip = snd_pcm_substream_chip(substream);
@@ -1308,7 +1309,6 @@
return 0;
}
-#if 0 // NYI
static int snd_intel8x0_ali_spdifout_open(struct snd_pcm_substream *substream)
{
struct intel8x0 *chip = snd_pcm_substream_chip(substream);
@@ -1435,6 +1435,7 @@
.pointer = snd_intel8x0_pcm_pointer,
};
+#if 0 // NYI
static struct snd_pcm_ops snd_intel8x0_ali_spdifin_ops = {
.open = snd_intel8x0_ali_spdifin_open,
.close = snd_intel8x0_ali_spdifin_close,
@@ -1446,7 +1447,6 @@
.pointer = snd_intel8x0_pcm_pointer,
};
-#if 0 // NYI
static struct snd_pcm_ops snd_intel8x0_ali_spdifout_ops = {
.open = snd_intel8x0_ali_spdifout_open,
.close = snd_intel8x0_ali_spdifout_close,
@@ -1582,7 +1582,7 @@
{
.suffix = "IEC958",
.playback_ops = &snd_intel8x0_ali_ac97spdifout_ops,
- .capture_ops = &snd_intel8x0_ali_spdifin_ops,
+ /* .capture_ops = &snd_intel8x0_ali_spdifin_ops, */
.prealloc_size = 64 * 1024,
.prealloc_max_size = 128 * 1024,
.ac97_idx = ALID_AC97SPDIFOUT,
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 47e26aa..720635f 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -224,7 +224,7 @@
unsigned int pcm_pos_shift;
};
-static struct pci_device_id snd_intel8x0m_ids[] = {
+static struct pci_device_id snd_intel8x0m_ids[] __devinitdata = {
{ 0x8086, 0x2416, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */
{ 0x8086, 0x2426, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */
{ 0x8086, 0x2446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 4721c09..e39fad1 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -424,7 +424,7 @@
MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard.");
MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");
-static struct pci_device_id snd_korg1212_ids[] = {
+static struct pci_device_id snd_korg1212_ids[] __devinitdata = {
{
.vendor = 0x10b5,
.device = 0x906d,
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 9c90d90..1928e06 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -41,7 +41,6 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
@@ -870,7 +869,7 @@
/*
* pci ids
*/
-static struct pci_device_id snd_m3_ids[] = {
+static struct pci_device_id snd_m3_ids[] __devinitdata = {
{PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
{PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID,
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index b5a0950..09cc078 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -28,7 +28,6 @@
#include <linux/dma-mapping.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
-#include <linux/dma-mapping.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -62,7 +61,7 @@
/*
*/
-static struct pci_device_id snd_mixart_ids[] = {
+static struct pci_device_id snd_mixart_ids[] __devinitdata = {
{ 0x1057, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* MC8240 */
{ 0, }
};
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index cc297ab..b92d660 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -263,7 +263,7 @@
/*
* PCI ids
*/
-static struct pci_device_id snd_nm256_ids[] = {
+static struct pci_device_id snd_nm256_ids[] __devinitdata = {
{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 35875c8..dafa223 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -30,7 +30,6 @@
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
-#include <linux/dma-mapping.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -74,7 +73,7 @@
PCI_ID_LAST
};
-static struct pci_device_id pcxhr_ids[] = {
+static struct pci_device_id pcxhr_ids[] __devinitdata = {
{ 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, }, /* VX882HR */
{ 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, }, /* PCX882HR */
{ 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, }, /* VX881HR */
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index 03517c1..369c19f 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -385,8 +385,8 @@
fw.size = dsp->length;
fw.data = vmalloc(fw.size);
if (! fw.data) {
- snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%d bytes)\n",
- fw.size);
+ snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%lu bytes)\n",
+ (unsigned long)fw.size);
return -ENOMEM;
}
if (copy_from_user(fw.data, dsp->image, dsp->length)) {
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index f148ee4..d8cc985 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -506,7 +506,7 @@
/*
*/
-static struct pci_device_id snd_riptide_ids[] = {
+static struct pci_device_id snd_riptide_ids[] __devinitdata = {
{
.vendor = 0x127a,.device = 0x4310,
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
@@ -527,7 +527,7 @@
};
#ifdef SUPPORT_JOYSTICK
-static struct pci_device_id snd_riptide_joystick_ids[] = {
+static struct pci_device_id snd_riptide_joystick_ids[] __devinitdata = {
{
.vendor = 0x127a,.device = 0x4312,
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index ab78544..55b1d48 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -227,7 +227,7 @@
struct snd_kcontrol *spdif_ctl;
};
-static struct pci_device_id snd_rme32_ids[] = {
+static struct pci_device_id snd_rme32_ids[] __devinitdata = {
{PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
{PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8,
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 6c2a9f4..3c1bc53 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -232,7 +232,7 @@
struct snd_kcontrol *spdif_ctl;
};
-static struct pci_device_id snd_rme96_ids[] = {
+static struct pci_device_id snd_rme96_ids[] __devinitdata = {
{ PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
{ PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8,
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index ebf7a2b..61f82f0 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -568,7 +568,7 @@
}
-static struct pci_device_id snd_hdsp_ids[] = {
+static struct pci_device_id snd_hdsp_ids[] __devinitdata = {
{
.vendor = PCI_VENDOR_ID_XILINX,
.device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP,
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index b5538ef..722b9e6 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -426,7 +426,7 @@
};
-static struct pci_device_id snd_hdspm_ids[] = {
+static struct pci_device_id snd_hdspm_ids[] __devinitdata = {
{
.vendor = PCI_VENDOR_ID_XILINX,
.device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI,
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index a687eb6..75d6406 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -315,7 +315,7 @@
}
-static struct pci_device_id snd_rme9652_ids[] = {
+static struct pci_device_id snd_rme9652_ids[] __devinitdata = {
{
.vendor = 0x10ee,
.device = 0x3fc4,
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 2d66a09..91f8bf3 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -243,7 +243,7 @@
#endif
};
-static struct pci_device_id snd_sonic_ids[] = {
+static struct pci_device_id snd_sonic_ids[] __devinitdata = {
{ 0x5333, 0xca00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
{ 0, }
};
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index b453804..9624a5f 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -63,7 +63,7 @@
module_param_array(wavetable_size, int, NULL, 0444);
MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth.");
-static struct pci_device_id snd_trident_ids[] = {
+static struct pci_device_id snd_trident_ids[] __devinitdata = {
{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX),
PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX),
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 0f171dd..39daf62 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -123,6 +123,7 @@
#define VIA_REV_8233A 0x40 /* 1 rec, 1 multi-pb, spdf */
#define VIA_REV_8235 0x50 /* 2 rec, 4 pb, 1 multi-pb, spdif */
#define VIA_REV_8237 0x60
+#define VIA_REV_8251 0x70
/*
* Direct registers
@@ -395,7 +396,7 @@
#endif
};
-static struct pci_device_id snd_via82xx_ids[] = {
+static struct pci_device_id snd_via82xx_ids[] __devinitdata = {
/* 0x1106, 0x3058 */
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */
/* 0x1106, 0x3059 */
@@ -862,6 +863,11 @@
if (!status)
status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
+ /* An apparent bug in the 8251 is worked around by sending a
+ * REG_CTRL_START. */
+ if (chip->revision == VIA_REV_8251 && (status & VIA_REG_STAT_EOL))
+ snd_via82xx_pcm_trigger(substream, SNDRV_PCM_TRIGGER_START);
+
if (!(status & VIA_REG_STAT_ACTIVE)) {
res = 0;
goto unlock;
@@ -2313,6 +2319,7 @@
{ VIA_REV_8233A, "VIA 8233A", TYPE_VIA8233A },
{ VIA_REV_8235, "VIA 8235", TYPE_VIA8233 },
{ VIA_REV_8237, "VIA 8237", TYPE_VIA8233 },
+ { VIA_REV_8251, "VIA 8251", TYPE_VIA8233 },
};
/*
@@ -2325,7 +2332,7 @@
short action; /* new dxs_support value */
};
-static int __devinit check_dxs_list(struct pci_dev *pci)
+static int __devinit check_dxs_list(struct pci_dev *pci, int revision)
{
static struct dxs_whitelist whitelist[] = {
{ .subvendor = 0x1005, .subdevice = 0x4710, .action = VIA_DXS_ENABLE }, /* Avance Logic Mobo */
@@ -2342,6 +2349,7 @@
{ .subvendor = 0x1043, .subdevice = 0x810d, .action = VIA_DXS_SRC }, /* ASUS */
{ .subvendor = 0x1043, .subdevice = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */
{ .subvendor = 0x1043, .subdevice = 0x8174, .action = VIA_DXS_SRC }, /* ASUS */
+ { .subvendor = 0x1043, .subdevice = 0x81b9, .action = VIA_DXS_SRC }, /* ASUS A8V-MX */
{ .subvendor = 0x1071, .subdevice = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
{ .subvendor = 0x1071, .subdevice = 0x8399, .action = VIA_DXS_NO_VRA }, /* Umax AB 595T (VIA K8N800A - VT8237) */
{ .subvendor = 0x10cf, .subdevice = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
@@ -2405,6 +2413,10 @@
}
}
+ /* for newer revision, default to DXS_SRC */
+ if (revision >= VIA_REV_8235)
+ return VIA_DXS_SRC;
+
/*
* not detected, try 48k rate only to be sure.
*/
@@ -2449,7 +2461,7 @@
}
if (chip_type != TYPE_VIA8233A) {
if (dxs_support == VIA_DXS_AUTO)
- dxs_support = check_dxs_list(pci);
+ dxs_support = check_dxs_list(pci, revision);
/* force to use VIA8233 or 8233A model according to
* dxs_support module option
*/
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 22ce4d3..ef97e50 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -261,7 +261,7 @@
struct snd_info_entry *proc_entry;
};
-static struct pci_device_id snd_via82xx_modem_ids[] = {
+static struct pci_device_id snd_via82xx_modem_ids[] __devinitdata = {
{ 0x1106, 0x3068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA82XX_MODEM, },
{ 0, }
};
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index c816ddf..0f1ebb0 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -60,7 +60,7 @@
VX_PCI_VX222_NEW
};
-static struct pci_device_id snd_vx222_ids[] = {
+static struct pci_device_id snd_vx222_ids[] __devinitdata = {
{ 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */
{ 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */
{ 0, }
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index db57ce9..65ebf5f 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -70,7 +70,7 @@
module_param_array(rear_swap, bool, NULL, 0444);
MODULE_PARM_DESC(rear_swap, "Swap rear channels (must be enabled for correct IEC958 (S/PDIF)) output");
-static struct pci_device_id snd_ymfpci_ids[] = {
+static struct pci_device_id snd_ymfpci_ids[] __devinitdata = {
{ 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */
{ 0x1073, 0x000d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724F */
{ 0x1073, 0x000a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF740 */
diff --git a/sound/pcmcia/Kconfig b/sound/pcmcia/Kconfig
index 5d1b0b7..c9fa1a2 100644
--- a/sound/pcmcia/Kconfig
+++ b/sound/pcmcia/Kconfig
@@ -5,7 +5,7 @@
config SND_VXPOCKET
tristate "Digigram VXpocket"
- depends on SND && PCMCIA && ISA
+ depends on SND && PCMCIA
select SND_VX_LIB
help
Say Y here to include support for Digigram VXpocket and
@@ -16,7 +16,7 @@
config SND_PDAUDIOCF
tristate "Sound Core PDAudioCF"
- depends on SND && PCMCIA && ISA
+ depends on SND && PCMCIA
select SND_PCM
help
Say Y here to include support for Sound Core PDAudioCF
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 0992a09..9351846 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -1531,6 +1531,15 @@
}
},
{
+ USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0014),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ .vendor_name = "TerraTec",
+ .product_name = "PHASE 26",
+ .ifnum = 3,
+ .type = QUIRK_MIDI_STANDARD_INTERFACE
+ }
+},
+{
USB_DEVICE(0x0ccd, 0x0035),
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
.vendor_name = "Miditech",