Update to 3.3-rc4
aufs: Update to aufs3.x-rcN-20120123 rt: Disable until it is updated for Linux 3.3 or later svn path=/dists/trunk/linux-2.6/; revision=18703
This commit is contained in:
parent
6ae5f75c0f
commit
b1e98ddaba
|
@ -1,3 +1,13 @@
|
|||
linux-2.6 (3.3~rc4-1~experimental.1) UNRELEASED; urgency=low
|
||||
|
||||
* New upstream release candidate
|
||||
|
||||
[ Ben Hutchings ]
|
||||
* aufs: Update to aufs3.x-rcN-20120123
|
||||
* rt: Disable until it is updated for Linux 3.3 or later
|
||||
|
||||
-- Ben Hutchings <ben@decadent.org.uk> Sun, 19 Feb 2012 20:52:21 +0000
|
||||
|
||||
linux-2.6 (3.2.6-1) unstable; urgency=low
|
||||
|
||||
* New upstream stable update:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[base]
|
||||
featuresets:
|
||||
rt
|
||||
# rt
|
||||
flavours:
|
||||
amd64
|
||||
kernel-arch: x86
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[base]
|
||||
featuresets:
|
||||
rt
|
||||
# rt
|
||||
flavours:
|
||||
486
|
||||
686-pae
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Wed, 16 Nov 2011 01:49:41 -0300
|
||||
Subject: [PATCH 1/5] [media] staging: lirc_serial: Fix init/exit order
|
||||
|
||||
commit 9105b8b200410383d0854bbe237ee385d7d33ba6 upstream.
|
||||
|
||||
Currently the module init function registers a platform_device and
|
||||
only then allocates its IRQ and I/O region. This allows allocation to
|
||||
race with the device's suspend() function. Instead, allocate
|
||||
resources in the platform driver's probe() function and free them in
|
||||
the remove() function.
|
||||
|
||||
The module exit function removes the platform device before the
|
||||
character device that provides access to it. Change it to reverse the
|
||||
order of initialisation.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
---
|
||||
drivers/staging/media/lirc/lirc_serial.c | 56 +++++++++++------------------
|
||||
1 files changed, 21 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
|
||||
index 8a060a8..8637631 100644
|
||||
--- a/drivers/staging/media/lirc/lirc_serial.c
|
||||
+++ b/drivers/staging/media/lirc/lirc_serial.c
|
||||
@@ -836,7 +836,7 @@ static int hardware_init_port(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int init_port(void)
|
||||
+static int __devinit lirc_serial_probe(struct platform_device *dev)
|
||||
{
|
||||
int i, nlow, nhigh, result;
|
||||
|
||||
@@ -913,6 +913,18 @@ static int init_port(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int __devexit lirc_serial_remove(struct platform_device *dev)
|
||||
+{
|
||||
+ free_irq(irq, (void *)&hardware);
|
||||
+
|
||||
+ if (iommap != 0)
|
||||
+ release_mem_region(iommap, 8 << ioshift);
|
||||
+ else
|
||||
+ release_region(io, 8);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int set_use_inc(void *data)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -1076,16 +1088,6 @@ static struct lirc_driver driver = {
|
||||
|
||||
static struct platform_device *lirc_serial_dev;
|
||||
|
||||
-static int __devinit lirc_serial_probe(struct platform_device *dev)
|
||||
-{
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int __devexit lirc_serial_remove(struct platform_device *dev)
|
||||
-{
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static int lirc_serial_suspend(struct platform_device *dev,
|
||||
pm_message_t state)
|
||||
{
|
||||
@@ -1188,10 +1190,6 @@ static int __init lirc_serial_init_module(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
- result = lirc_serial_init();
|
||||
- if (result)
|
||||
- return result;
|
||||
-
|
||||
switch (type) {
|
||||
case LIRC_HOMEBREW:
|
||||
case LIRC_IRDEO:
|
||||
@@ -1211,8 +1209,7 @@ static int __init lirc_serial_init_module(void)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
- result = -EINVAL;
|
||||
- goto exit_serial_exit;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
if (!softcarrier) {
|
||||
switch (type) {
|
||||
@@ -1228,37 +1225,26 @@ static int __init lirc_serial_init_module(void)
|
||||
}
|
||||
}
|
||||
|
||||
- result = init_port();
|
||||
- if (result < 0)
|
||||
- goto exit_serial_exit;
|
||||
+ result = lirc_serial_init();
|
||||
+ if (result)
|
||||
+ return result;
|
||||
+
|
||||
driver.features = hardware[type].features;
|
||||
driver.dev = &lirc_serial_dev->dev;
|
||||
driver.minor = lirc_register_driver(&driver);
|
||||
if (driver.minor < 0) {
|
||||
printk(KERN_ERR LIRC_DRIVER_NAME
|
||||
": register_chrdev failed!\n");
|
||||
- result = -EIO;
|
||||
- goto exit_release;
|
||||
+ lirc_serial_exit();
|
||||
+ return -EIO;
|
||||
}
|
||||
return 0;
|
||||
-exit_release:
|
||||
- release_region(io, 8);
|
||||
-exit_serial_exit:
|
||||
- lirc_serial_exit();
|
||||
- return result;
|
||||
}
|
||||
|
||||
static void __exit lirc_serial_exit_module(void)
|
||||
{
|
||||
- lirc_serial_exit();
|
||||
-
|
||||
- free_irq(irq, (void *)&hardware);
|
||||
-
|
||||
- if (iommap != 0)
|
||||
- release_mem_region(iommap, 8 << ioshift);
|
||||
- else
|
||||
- release_region(io, 8);
|
||||
lirc_unregister_driver(driver.minor);
|
||||
+ lirc_serial_exit();
|
||||
dprintk("cleaned up module\n");
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.3
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Wed, 16 Nov 2011 01:52:11 -0300
|
||||
Subject: [PATCH 2/5] [media] staging: lirc_serial: Free resources on failure
|
||||
paths of lirc_serial_probe()
|
||||
|
||||
commit c8e57e1b766c2321aa76ee5e6878c69bd2313d62 upstream.
|
||||
|
||||
Failure to allocate the I/O region leaves the IRQ allocated.
|
||||
A later failure leaves them both allocated.
|
||||
|
||||
Reported-by: Torsten Crass <torsten.crass@eBiology.de>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
---
|
||||
drivers/staging/media/lirc/lirc_serial.c | 19 ++++++++++++++++---
|
||||
1 files changed, 16 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
|
||||
index 8637631..d833772 100644
|
||||
--- a/drivers/staging/media/lirc/lirc_serial.c
|
||||
+++ b/drivers/staging/media/lirc/lirc_serial.c
|
||||
@@ -875,11 +875,14 @@ static int __devinit lirc_serial_probe(struct platform_device *dev)
|
||||
": or compile the serial port driver as module and\n");
|
||||
printk(KERN_WARNING LIRC_DRIVER_NAME
|
||||
": make sure this module is loaded first\n");
|
||||
- return -EBUSY;
|
||||
+ result = -EBUSY;
|
||||
+ goto exit_free_irq;
|
||||
}
|
||||
|
||||
- if (hardware_init_port() < 0)
|
||||
- return -EINVAL;
|
||||
+ if (hardware_init_port() < 0) {
|
||||
+ result = -EINVAL;
|
||||
+ goto exit_release_region;
|
||||
+ }
|
||||
|
||||
/* Initialize pulse/space widths */
|
||||
init_timing_params(duty_cycle, freq);
|
||||
@@ -911,6 +914,16 @@ static int __devinit lirc_serial_probe(struct platform_device *dev)
|
||||
|
||||
dprintk("Interrupt %d, port %04x obtained\n", irq, io);
|
||||
return 0;
|
||||
+
|
||||
+exit_release_region:
|
||||
+ if (iommap != 0)
|
||||
+ release_mem_region(iommap, 8 << ioshift);
|
||||
+ else
|
||||
+ release_region(io, 8);
|
||||
+exit_free_irq:
|
||||
+ free_irq(irq, (void *)&hardware);
|
||||
+
|
||||
+ return result;
|
||||
}
|
||||
|
||||
static int __devexit lirc_serial_remove(struct platform_device *dev)
|
||||
--
|
||||
1.7.7.3
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Wed, 16 Nov 2011 01:53:25 -0300
|
||||
Subject: [PATCH 3/5] [media] staging: lirc_serial: Fix deadlock on resume
|
||||
failure
|
||||
|
||||
commit 1ff1d88e862948ae5bfe490248c023ff8ac2855d upstream.
|
||||
|
||||
A resume function cannot remove the device it is resuming!
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
---
|
||||
drivers/staging/media/lirc/lirc_serial.c | 4 +---
|
||||
1 files changed, 1 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
|
||||
index d833772..befe626 100644
|
||||
--- a/drivers/staging/media/lirc/lirc_serial.c
|
||||
+++ b/drivers/staging/media/lirc/lirc_serial.c
|
||||
@@ -1127,10 +1127,8 @@ static int lirc_serial_resume(struct platform_device *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
- if (hardware_init_port() < 0) {
|
||||
- lirc_serial_exit();
|
||||
+ if (hardware_init_port() < 0)
|
||||
return -EINVAL;
|
||||
- }
|
||||
|
||||
spin_lock_irqsave(&hardware[type].lock, flags);
|
||||
/* Enable Interrupt */
|
||||
--
|
||||
1.7.7.3
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Wed, 16 Nov 2011 01:53:35 -0300
|
||||
Subject: [PATCH 4/5] [media] staging: lirc_serial: Fix bogus error codes
|
||||
|
||||
commit 9b98d60679711753e548be15c6bef5239db6ed64 upstream.
|
||||
|
||||
Device not found? ENODEV, not EINVAL.
|
||||
Write to read-only device? EPERM, not EBADF.
|
||||
Invalid argument? EINVAL, not ENOSYS.
|
||||
Unsupported ioctl? ENOIOCTLCMD, not ENOSYS.
|
||||
Another function returned an error code? Use that, don't replace it.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
---
|
||||
drivers/staging/media/lirc/lirc_serial.c | 23 ++++++++++++-----------
|
||||
1 files changed, 12 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
|
||||
index befe626..6f5257e 100644
|
||||
--- a/drivers/staging/media/lirc/lirc_serial.c
|
||||
+++ b/drivers/staging/media/lirc/lirc_serial.c
|
||||
@@ -773,7 +773,7 @@ static int hardware_init_port(void)
|
||||
/* we fail, there's nothing here */
|
||||
printk(KERN_ERR LIRC_DRIVER_NAME ": port existence test "
|
||||
"failed, cannot continue\n");
|
||||
- return -EINVAL;
|
||||
+ return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
@@ -879,10 +879,9 @@ static int __devinit lirc_serial_probe(struct platform_device *dev)
|
||||
goto exit_free_irq;
|
||||
}
|
||||
|
||||
- if (hardware_init_port() < 0) {
|
||||
- result = -EINVAL;
|
||||
+ result = hardware_init_port();
|
||||
+ if (result < 0)
|
||||
goto exit_release_region;
|
||||
- }
|
||||
|
||||
/* Initialize pulse/space widths */
|
||||
init_timing_params(duty_cycle, freq);
|
||||
@@ -980,7 +979,7 @@ static ssize_t lirc_write(struct file *file, const char *buf,
|
||||
int *wbuf;
|
||||
|
||||
if (!(hardware[type].features & LIRC_CAN_SEND_PULSE))
|
||||
- return -EBADF;
|
||||
+ return -EPERM;
|
||||
|
||||
count = n / sizeof(int);
|
||||
if (n % sizeof(int) || count % 2 == 0)
|
||||
@@ -1031,11 +1030,11 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
return result;
|
||||
/* only LIRC_MODE_PULSE supported */
|
||||
if (value != LIRC_MODE_PULSE)
|
||||
- return -ENOSYS;
|
||||
+ return -EINVAL;
|
||||
break;
|
||||
|
||||
case LIRC_GET_LENGTH:
|
||||
- return -ENOSYS;
|
||||
+ return -ENOIOCTLCMD;
|
||||
break;
|
||||
|
||||
case LIRC_SET_SEND_DUTY_CYCLE:
|
||||
@@ -1126,9 +1125,11 @@ static void lirc_serial_exit(void);
|
||||
static int lirc_serial_resume(struct platform_device *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
+ int result;
|
||||
|
||||
- if (hardware_init_port() < 0)
|
||||
- return -EINVAL;
|
||||
+ result = hardware_init_port();
|
||||
+ if (result < 0)
|
||||
+ return result;
|
||||
|
||||
spin_lock_irqsave(&hardware[type].lock, flags);
|
||||
/* Enable Interrupt */
|
||||
@@ -1161,7 +1162,7 @@ static int __init lirc_serial_init(void)
|
||||
/* Init read buffer. */
|
||||
result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
|
||||
if (result < 0)
|
||||
- return -ENOMEM;
|
||||
+ return result;
|
||||
|
||||
result = platform_driver_register(&lirc_serial_driver);
|
||||
if (result) {
|
||||
@@ -1247,7 +1248,7 @@ static int __init lirc_serial_init_module(void)
|
||||
printk(KERN_ERR LIRC_DRIVER_NAME
|
||||
": register_chrdev failed!\n");
|
||||
lirc_serial_exit();
|
||||
- return -EIO;
|
||||
+ return driver.minor;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
1.7.7.3
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Wed, 16 Nov 2011 01:54:04 -0300
|
||||
Subject: [PATCH 5/5] [media] staging: lirc_serial: Do not assume error codes
|
||||
returned by request_irq()
|
||||
|
||||
commit affc9a0d59ac49bd304e2137bd5e4ffdd6fdfa52 upstream.
|
||||
|
||||
lirc_serial_probe() must fail if request_irq() returns an error, even if
|
||||
it isn't EBUSY or EINVAL,
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
---
|
||||
drivers/staging/media/lirc/lirc_serial.c | 21 +++++++++------------
|
||||
1 files changed, 9 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
|
||||
index 6f5257e..0ca308a 100644
|
||||
--- a/drivers/staging/media/lirc/lirc_serial.c
|
||||
+++ b/drivers/staging/media/lirc/lirc_serial.c
|
||||
@@ -843,18 +843,15 @@ static int __devinit lirc_serial_probe(struct platform_device *dev)
|
||||
result = request_irq(irq, irq_handler,
|
||||
(share_irq ? IRQF_SHARED : 0),
|
||||
LIRC_DRIVER_NAME, (void *)&hardware);
|
||||
-
|
||||
- switch (result) {
|
||||
- case -EBUSY:
|
||||
- printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq);
|
||||
- return -EBUSY;
|
||||
- case -EINVAL:
|
||||
- printk(KERN_ERR LIRC_DRIVER_NAME
|
||||
- ": Bad irq number or handler\n");
|
||||
- return -EINVAL;
|
||||
- default:
|
||||
- break;
|
||||
- };
|
||||
+ if (result < 0) {
|
||||
+ if (result == -EBUSY)
|
||||
+ printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n",
|
||||
+ irq);
|
||||
+ else if (result == -EINVAL)
|
||||
+ printk(KERN_ERR LIRC_DRIVER_NAME
|
||||
+ ": Bad irq number or handler\n");
|
||||
+ return result;
|
||||
+ }
|
||||
|
||||
/* Reserve io region. */
|
||||
/*
|
||||
--
|
||||
1.7.7.3
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
From f88373fa47f3ce6590fdfaa742d0ddacc2ae017f Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sun, 5 Feb 2012 21:15:17 +0100
|
||||
Subject: ath9k: fix a WEP crypto related regression
|
||||
|
||||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
commit f88373fa47f3ce6590fdfaa742d0ddacc2ae017f upstream.
|
||||
|
||||
commit b4a82a0 "ath9k_hw: fix interpretation of the rx KeyMiss flag"
|
||||
fixed the interpretation of the KeyMiss flag for keycache based lookups,
|
||||
however WEP encryption uses a static index, so KeyMiss is always asserted
|
||||
for it, even though frames are decrypted properly.
|
||||
Fix this by clearing the ATH9K_RXERR_KEYMISS flag if no keycache based
|
||||
lookup was performed.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
Reported-by: Laurent Bonnans <bonnans.l@gmail.com>
|
||||
Reported-by: Jurica Vukadin <u.ra604@googlemail.com>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
---
|
||||
drivers/net/wireless/ath/ath9k/recv.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/recv.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/recv.c
|
||||
@@ -824,6 +824,14 @@ static bool ath9k_rx_accept(struct ath_c
|
||||
(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
|
||||
ATH9K_RXERR_KEYMISS));
|
||||
|
||||
+ /*
|
||||
+ * Key miss events are only relevant for pairwise keys where the
|
||||
+ * descriptor does contain a valid key index. This has been observed
|
||||
+ * mostly with CCMP encryption.
|
||||
+ */
|
||||
+ if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID)
|
||||
+ rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
|
||||
+
|
||||
if (!rx_stats->rs_datalen)
|
||||
return false;
|
||||
/*
|
|
@ -1,63 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Tue, 10 Jan 2012 02:59:49 +0000
|
||||
Subject: [PATCH 1/2] cpu: Do not return errors from cpu_dev_init() which will
|
||||
be ignored
|
||||
|
||||
commit 024f78462c3da710642a54939888a92e28704653 upstream.
|
||||
|
||||
cpu_dev_init() is only called from driver_init(), which does not check
|
||||
its return value. Therefore make cpu_dev_init() return void.
|
||||
|
||||
We must register the CPU subsystem, so panic if this fails.
|
||||
|
||||
If sched_create_sysfs_power_savings_entries() fails, the damage is
|
||||
contained, so ignore this (as before).
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
[bwh: Backport to 3.2]
|
||||
---
|
||||
--- a/drivers/base/base.h
|
||||
+++ b/drivers/base/base.h
|
||||
@@ -95,7 +95,7 @@ extern int hypervisor_init(void);
|
||||
#endif
|
||||
extern int platform_bus_init(void);
|
||||
extern int system_bus_init(void);
|
||||
-extern int cpu_dev_init(void);
|
||||
+extern void cpu_dev_init(void);
|
||||
|
||||
extern int bus_add_device(struct device *dev);
|
||||
extern void bus_probe_device(struct device *dev);
|
||||
--- a/drivers/base/cpu.c
|
||||
+++ b/drivers/base/cpu.c
|
||||
@@ -2,6 +2,7 @@
|
||||
* drivers/base/cpu.c - basic CPU class support
|
||||
*/
|
||||
|
||||
+#include <linux/kernel.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
@@ -247,17 +248,14 @@ bool cpu_is_hotpluggable(unsigned cpu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_cpu_sysdev);
|
||||
|
||||
-int __init cpu_dev_init(void)
|
||||
+void __init cpu_dev_init(void)
|
||||
{
|
||||
- int err;
|
||||
-
|
||||
- err = sysdev_class_register(&cpu_sysdev_class);
|
||||
+ if (sysdev_class_register(&cpu_sysdev_class))
|
||||
+ panic("Failed to register CPU subsystem");
|
||||
+
|
||||
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
|
||||
- if (!err)
|
||||
- err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
|
||||
+ sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
|
||||
#endif
|
||||
-
|
||||
- return err;
|
||||
}
|
||||
|
||||
static struct sysdev_class_attribute *cpu_sysdev_class_attrs[] = {
|
|
@ -1,152 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Tue, 10 Jan 2012 03:04:32 +0000
|
||||
Subject: [PATCH 2/2] cpu: Register a generic CPU device on architectures that
|
||||
currently do not
|
||||
|
||||
commit 9f13a1fd452f11c18004ba2422a6384b424ec8a9 upstream.
|
||||
|
||||
frv, h8300, m68k, microblaze, openrisc, score, um and xtensa currently
|
||||
do not register a CPU device. Add the config option GENERIC_CPU_DEVICES
|
||||
which causes a generic CPU device to be registered for each present CPU,
|
||||
and make all these architectures select it.
|
||||
|
||||
Richard Weinberger <richard@nod.at> covered UML and suggested using
|
||||
per_cpu.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
[bwh: Backport to 3.2]
|
||||
---
|
||||
--- a/arch/frv/Kconfig
|
||||
+++ b/arch/frv/Kconfig
|
||||
@@ -8,6 +8,7 @@ config FRV
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select GENERIC_IRQ_SHOW
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||
+ select GENERIC_CPU_DEVICES
|
||||
|
||||
config ZONE_DMA
|
||||
bool
|
||||
--- a/arch/h8300/Kconfig
|
||||
+++ b/arch/h8300/Kconfig
|
||||
@@ -4,6 +4,7 @@ config H8300
|
||||
select HAVE_IDE
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select GENERIC_IRQ_SHOW
|
||||
+ select GENERIC_CPU_DEVICES
|
||||
|
||||
config SYMBOL_PREFIX
|
||||
string
|
||||
--- a/arch/m68k/Kconfig
|
||||
+++ b/arch/m68k/Kconfig
|
||||
@@ -6,6 +6,7 @@ config M68K
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select GENERIC_IRQ_SHOW
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
|
||||
+ select GENERIC_CPU_DEVICES
|
||||
|
||||
config RWSEM_GENERIC_SPINLOCK
|
||||
bool
|
||||
--- a/arch/microblaze/Kconfig
|
||||
+++ b/arch/microblaze/Kconfig
|
||||
@@ -17,6 +17,7 @@ config MICROBLAZE
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select GENERIC_IRQ_PROBE
|
||||
select GENERIC_IRQ_SHOW
|
||||
+ select GENERIC_CPU_DEVICES
|
||||
|
||||
config SWAP
|
||||
def_bool n
|
||||
--- a/arch/openrisc/Kconfig
|
||||
+++ b/arch/openrisc/Kconfig
|
||||
@@ -15,6 +15,7 @@ config OPENRISC
|
||||
select GENERIC_IRQ_PROBE
|
||||
select GENERIC_IRQ_SHOW
|
||||
select GENERIC_IOMAP
|
||||
+ select GENERIC_CPU_DEVICES
|
||||
|
||||
config MMU
|
||||
def_bool y
|
||||
--- a/arch/score/Kconfig
|
||||
+++ b/arch/score/Kconfig
|
||||
@@ -4,6 +4,7 @@ config SCORE
|
||||
def_bool y
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select GENERIC_IRQ_SHOW
|
||||
+ select GENERIC_CPU_DEVICES
|
||||
|
||||
choice
|
||||
prompt "System type"
|
||||
--- a/arch/um/Kconfig.common
|
||||
+++ b/arch/um/Kconfig.common
|
||||
@@ -8,6 +8,7 @@ config UML
|
||||
default y
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select GENERIC_IRQ_SHOW
|
||||
+ select GENERIC_CPU_DEVICES
|
||||
|
||||
config MMU
|
||||
bool
|
||||
--- a/arch/xtensa/Kconfig
|
||||
+++ b/arch/xtensa/Kconfig
|
||||
@@ -9,6 +9,7 @@ config XTENSA
|
||||
select HAVE_IDE
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select GENERIC_IRQ_SHOW
|
||||
+ select GENERIC_CPU_DEVICES
|
||||
help
|
||||
Xtensa processors are 32-bit RISC machines designed by Tensilica
|
||||
primarily for embedded systems. These processors are both
|
||||
--- a/drivers/base/Kconfig
|
||||
+++ b/drivers/base/Kconfig
|
||||
@@ -172,6 +172,10 @@ config SYS_HYPERVISOR
|
||||
bool
|
||||
default n
|
||||
|
||||
+config GENERIC_CPU_DEVICES
|
||||
+ bool
|
||||
+ default n
|
||||
+
|
||||
source "drivers/base/regmap/Kconfig"
|
||||
|
||||
config DMA_SHARED_BUFFER
|
||||
--- a/drivers/base/cpu.c
|
||||
+++ b/drivers/base/cpu.c
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/node.h>
|
||||
#include <linux/gfp.h>
|
||||
+#include <linux/percpu.h>
|
||||
|
||||
#include "base.h"
|
||||
|
||||
@@ -248,11 +249,29 @@ bool cpu_is_hotpluggable(unsigned cpu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_cpu_sysdev);
|
||||
|
||||
+#ifdef CONFIG_GENERIC_CPU_DEVICES
|
||||
+static DEFINE_PER_CPU(struct cpu, cpu_devices);
|
||||
+#endif
|
||||
+
|
||||
+static void __init cpu_dev_register_generic(void)
|
||||
+{
|
||||
+#ifdef CONFIG_GENERIC_CPU_DEVICES
|
||||
+ int i;
|
||||
+
|
||||
+ for_each_possible_cpu(i) {
|
||||
+ if (register_cpu(&per_cpu(cpu_devices, i), i))
|
||||
+ panic("Failed to register CPU device");
|
||||
+ }
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
void __init cpu_dev_init(void)
|
||||
{
|
||||
if (sysdev_class_register(&cpu_sysdev_class))
|
||||
panic("Failed to register CPU subsystem");
|
||||
|
||||
+ cpu_dev_register_generic();
|
||||
+
|
||||
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
|
||||
sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
|
||||
#endif
|
|
@ -1,48 +0,0 @@
|
|||
From f6302f1bcd75a042df69866d98b8d775a668f8f1 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Date: Fri, 10 Feb 2012 09:03:58 +0100
|
||||
Subject: relay: prevent integer overflow in relay_open()
|
||||
|
||||
From: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
|
||||
commit f6302f1bcd75a042df69866d98b8d775a668f8f1 upstream.
|
||||
|
||||
"subbuf_size" and "n_subbufs" come from the user and they need to be
|
||||
capped to prevent an integer overflow.
|
||||
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
---
|
||||
kernel/relay.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/kernel/relay.c
|
||||
+++ b/kernel/relay.c
|
||||
@@ -164,10 +164,14 @@ depopulate:
|
||||
*/
|
||||
static struct rchan_buf *relay_create_buf(struct rchan *chan)
|
||||
{
|
||||
- struct rchan_buf *buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
|
||||
- if (!buf)
|
||||
+ struct rchan_buf *buf;
|
||||
+
|
||||
+ if (chan->n_subbufs > UINT_MAX / sizeof(size_t *))
|
||||
return NULL;
|
||||
|
||||
+ buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
|
||||
+ if (!buf)
|
||||
+ return NULL;
|
||||
buf->padding = kmalloc(chan->n_subbufs * sizeof(size_t *), GFP_KERNEL);
|
||||
if (!buf->padding)
|
||||
goto free_buf;
|
||||
@@ -574,6 +578,8 @@ struct rchan *relay_open(const char *bas
|
||||
|
||||
if (!(subbuf_size && n_subbufs))
|
||||
return NULL;
|
||||
+ if (subbuf_size > UINT_MAX / n_subbufs)
|
||||
+ return NULL;
|
||||
|
||||
chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
|
||||
if (!chan)
|
|
@ -1,102 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Tue, 27 Dec 2011 20:42:09 +0100
|
||||
Subject: [PATCH] snapshot: Implement compat_ioctl
|
||||
|
||||
References: http://bugs.debian.org/502816
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
kernel/power/user.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 64 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kernel/power/user.c b/kernel/power/user.c
|
||||
index 6d8f535..d86e5a7 100644
|
||||
--- a/kernel/power/user.c
|
||||
+++ b/kernel/power/user.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/swapops.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/fs.h>
|
||||
+#include <linux/compat.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/freezer.h>
|
||||
@@ -464,6 +465,66 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
|
||||
return error;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+
|
||||
+struct compat_resume_swap_area {
|
||||
+ compat_loff_t offset;
|
||||
+ u32 dev;
|
||||
+} __packed;
|
||||
+
|
||||
+static long
|
||||
+snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
+{
|
||||
+ BUILD_BUG_ON(sizeof(loff_t) != sizeof(compat_loff_t));
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case SNAPSHOT_GET_IMAGE_SIZE:
|
||||
+ case SNAPSHOT_AVAIL_SWAP_SIZE:
|
||||
+ case SNAPSHOT_ALLOC_SWAP_PAGE: {
|
||||
+ compat_loff_t __user *uoffset = compat_ptr(arg);
|
||||
+ loff_t offset;
|
||||
+ mm_segment_t old_fs;
|
||||
+ int err;
|
||||
+
|
||||
+ old_fs = get_fs();
|
||||
+ set_fs(KERNEL_DS);
|
||||
+ err = snapshot_ioctl(file, cmd, (unsigned long) &offset);
|
||||
+ set_fs(old_fs);
|
||||
+ if (!err && put_user(offset, uoffset))
|
||||
+ err = -EFAULT;
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ case SNAPSHOT_CREATE_IMAGE:
|
||||
+ return snapshot_ioctl(file, cmd,
|
||||
+ (unsigned long) compat_ptr(arg));
|
||||
+
|
||||
+ case SNAPSHOT_SET_SWAP_AREA: {
|
||||
+ struct compat_resume_swap_area __user *u_swap_area =
|
||||
+ compat_ptr(arg);
|
||||
+ struct resume_swap_area swap_area;
|
||||
+ mm_segment_t old_fs;
|
||||
+ int err;
|
||||
+
|
||||
+ err = get_user(swap_area.offset, &u_swap_area->offset);
|
||||
+ err |= get_user(swap_area.dev, &u_swap_area->dev);
|
||||
+ if (err)
|
||||
+ return -EFAULT;
|
||||
+ old_fs = get_fs();
|
||||
+ set_fs(KERNEL_DS);
|
||||
+ err = snapshot_ioctl(file, SNAPSHOT_SET_SWAP_AREA,
|
||||
+ (unsigned long) &swap_area);
|
||||
+ set_fs(old_fs);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ default:
|
||||
+ return snapshot_ioctl(file, cmd, arg);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#endif /* CONFIG_COMPAT */
|
||||
+
|
||||
static const struct file_operations snapshot_fops = {
|
||||
.open = snapshot_open,
|
||||
.release = snapshot_release,
|
||||
@@ -471,6 +532,9 @@ static const struct file_operations snapshot_fops = {
|
||||
.write = snapshot_write,
|
||||
.llseek = no_llseek,
|
||||
.unlocked_ioctl = snapshot_ioctl,
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ .compat_ioctl = snapshot_compat_ioctl,
|
||||
+#endif
|
||||
};
|
||||
|
||||
static struct miscdevice snapshot_device = {
|
||||
--
|
||||
1.7.7.3
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
http://ftp.arm.linux.org.uk/git/gitweb.cgi?p=linux-2.6-arm.git;a=commit;h=7dbaa466780a754154531b44c2086f6618cee3a8
|
||||
|
||||
From 7dbaa466780a754154531b44c2086f6618cee3a8 Mon Sep 17 00:00:00 2001
|
||||
From: Rob Herring <rob.herring@calxeda.com>
|
||||
Date: Tue, 22 Nov 2011 04:01:07 +0100
|
||||
Subject: [PATCH] ARM: 7169/1: topdown mmap support
|
||||
|
||||
Similar to other architectures, this adds topdown mmap support in user
|
||||
process address space allocation policy. This allows mmap sizes greater
|
||||
than 2GB. This support is largely copied from MIPS and the generic
|
||||
implementations.
|
||||
|
||||
The address space randomization is moved into arch_pick_mmap_layout.
|
||||
|
||||
Tested on V-Express with ubuntu and a mmap test from here:
|
||||
https://bugs.launchpad.net/bugs/861296
|
||||
|
||||
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
|
||||
Acked-by: Nicolas Pitre <nico@linaro.org>
|
||||
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
---
|
||||
arch/arm/include/asm/pgtable.h | 1 +
|
||||
arch/arm/include/asm/processor.h | 2 +
|
||||
arch/arm/mm/mmap.c | 173 ++++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 171 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
|
||||
index 9451dce..2f659e2 100644
|
||||
--- a/arch/arm/include/asm/pgtable.h
|
||||
+++ b/arch/arm/include/asm/pgtable.h
|
||||
@@ -336,6 +336,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
* We provide our own arch_get_unmapped_area to cope with VIPT caches.
|
||||
*/
|
||||
#define HAVE_ARCH_UNMAPPED_AREA
|
||||
+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
|
||||
|
||||
/*
|
||||
* remap a physical page `pfn' of size `size' with page protection `prot'
|
||||
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
|
||||
index b2d9df5..ce280b8 100644
|
||||
--- a/arch/arm/include/asm/processor.h
|
||||
+++ b/arch/arm/include/asm/processor.h
|
||||
@@ -123,6 +123,8 @@ static inline void prefetch(const void *ptr)
|
||||
|
||||
#endif
|
||||
|
||||
+#define HAVE_ARCH_PICK_MMAP_LAYOUT
|
||||
+
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_ARM_PROCESSOR_H */
|
||||
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
|
||||
index 44b628e..ce8cb19 100644
|
||||
--- a/arch/arm/mm/mmap.c
|
||||
+++ b/arch/arm/mm/mmap.c
|
||||
@@ -11,10 +11,49 @@
|
||||
#include <linux/random.h>
|
||||
#include <asm/cachetype.h>
|
||||
|
||||
+static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr,
|
||||
+ unsigned long pgoff)
|
||||
+{
|
||||
+ unsigned long base = addr & ~(SHMLBA-1);
|
||||
+ unsigned long off = (pgoff << PAGE_SHIFT) & (SHMLBA-1);
|
||||
+
|
||||
+ if (base + off <= addr)
|
||||
+ return base + off;
|
||||
+
|
||||
+ return base - off;
|
||||
+}
|
||||
+
|
||||
#define COLOUR_ALIGN(addr,pgoff) \
|
||||
((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \
|
||||
(((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
|
||||
|
||||
+/* gap between mmap and stack */
|
||||
+#define MIN_GAP (128*1024*1024UL)
|
||||
+#define MAX_GAP ((TASK_SIZE)/6*5)
|
||||
+
|
||||
+static int mmap_is_legacy(void)
|
||||
+{
|
||||
+ if (current->personality & ADDR_COMPAT_LAYOUT)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
|
||||
+ return 1;
|
||||
+
|
||||
+ return sysctl_legacy_va_layout;
|
||||
+}
|
||||
+
|
||||
+static unsigned long mmap_base(unsigned long rnd)
|
||||
+{
|
||||
+ unsigned long gap = rlimit(RLIMIT_STACK);
|
||||
+
|
||||
+ if (gap < MIN_GAP)
|
||||
+ gap = MIN_GAP;
|
||||
+ else if (gap > MAX_GAP)
|
||||
+ gap = MAX_GAP;
|
||||
+
|
||||
+ return PAGE_ALIGN(TASK_SIZE - gap - rnd);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* We need to ensure that shared mappings are correctly aligned to
|
||||
* avoid aliasing issues with VIPT caches. We need to ensure that
|
||||
@@ -68,13 +107,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||
if (len > mm->cached_hole_size) {
|
||||
start_addr = addr = mm->free_area_cache;
|
||||
} else {
|
||||
- start_addr = addr = TASK_UNMAPPED_BASE;
|
||||
+ start_addr = addr = mm->mmap_base;
|
||||
mm->cached_hole_size = 0;
|
||||
}
|
||||
- /* 8 bits of randomness in 20 address space bits */
|
||||
- if ((current->flags & PF_RANDOMIZE) &&
|
||||
- !(current->personality & ADDR_NO_RANDOMIZE))
|
||||
- addr += (get_random_int() % (1 << 8)) << PAGE_SHIFT;
|
||||
|
||||
full_search:
|
||||
if (do_align)
|
||||
@@ -111,6 +146,134 @@ full_search:
|
||||
}
|
||||
}
|
||||
|
||||
+unsigned long
|
||||
+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
||||
+ const unsigned long len, const unsigned long pgoff,
|
||||
+ const unsigned long flags)
|
||||
+{
|
||||
+ struct vm_area_struct *vma;
|
||||
+ struct mm_struct *mm = current->mm;
|
||||
+ unsigned long addr = addr0;
|
||||
+ int do_align = 0;
|
||||
+ int aliasing = cache_is_vipt_aliasing();
|
||||
+
|
||||
+ /*
|
||||
+ * We only need to do colour alignment if either the I or D
|
||||
+ * caches alias.
|
||||
+ */
|
||||
+ if (aliasing)
|
||||
+ do_align = filp || (flags & MAP_SHARED);
|
||||
+
|
||||
+ /* requested length too big for entire address space */
|
||||
+ if (len > TASK_SIZE)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (flags & MAP_FIXED) {
|
||||
+ if (aliasing && flags & MAP_SHARED &&
|
||||
+ (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
|
||||
+ return -EINVAL;
|
||||
+ return addr;
|
||||
+ }
|
||||
+
|
||||
+ /* requesting a specific address */
|
||||
+ if (addr) {
|
||||
+ if (do_align)
|
||||
+ addr = COLOUR_ALIGN(addr, pgoff);
|
||||
+ else
|
||||
+ addr = PAGE_ALIGN(addr);
|
||||
+ vma = find_vma(mm, addr);
|
||||
+ if (TASK_SIZE - len >= addr &&
|
||||
+ (!vma || addr + len <= vma->vm_start))
|
||||
+ return addr;
|
||||
+ }
|
||||
+
|
||||
+ /* check if free_area_cache is useful for us */
|
||||
+ if (len <= mm->cached_hole_size) {
|
||||
+ mm->cached_hole_size = 0;
|
||||
+ mm->free_area_cache = mm->mmap_base;
|
||||
+ }
|
||||
+
|
||||
+ /* either no address requested or can't fit in requested address hole */
|
||||
+ addr = mm->free_area_cache;
|
||||
+ if (do_align) {
|
||||
+ unsigned long base = COLOUR_ALIGN_DOWN(addr - len, pgoff);
|
||||
+ addr = base + len;
|
||||
+ }
|
||||
+
|
||||
+ /* make sure it can fit in the remaining address space */
|
||||
+ if (addr > len) {
|
||||
+ vma = find_vma(mm, addr-len);
|
||||
+ if (!vma || addr <= vma->vm_start)
|
||||
+ /* remember the address as a hint for next time */
|
||||
+ return (mm->free_area_cache = addr-len);
|
||||
+ }
|
||||
+
|
||||
+ if (mm->mmap_base < len)
|
||||
+ goto bottomup;
|
||||
+
|
||||
+ addr = mm->mmap_base - len;
|
||||
+ if (do_align)
|
||||
+ addr = COLOUR_ALIGN_DOWN(addr, pgoff);
|
||||
+
|
||||
+ do {
|
||||
+ /*
|
||||
+ * Lookup failure means no vma is above this address,
|
||||
+ * else if new region fits below vma->vm_start,
|
||||
+ * return with success:
|
||||
+ */
|
||||
+ vma = find_vma(mm, addr);
|
||||
+ if (!vma || addr+len <= vma->vm_start)
|
||||
+ /* remember the address as a hint for next time */
|
||||
+ return (mm->free_area_cache = addr);
|
||||
+
|
||||
+ /* remember the largest hole we saw so far */
|
||||
+ if (addr + mm->cached_hole_size < vma->vm_start)
|
||||
+ mm->cached_hole_size = vma->vm_start - addr;
|
||||
+
|
||||
+ /* try just below the current vma->vm_start */
|
||||
+ addr = vma->vm_start - len;
|
||||
+ if (do_align)
|
||||
+ addr = COLOUR_ALIGN_DOWN(addr, pgoff);
|
||||
+ } while (len < vma->vm_start);
|
||||
+
|
||||
+bottomup:
|
||||
+ /*
|
||||
+ * A failed mmap() very likely causes application failure,
|
||||
+ * so fall back to the bottom-up function here. This scenario
|
||||
+ * can happen with large stack limits and large mmap()
|
||||
+ * allocations.
|
||||
+ */
|
||||
+ mm->cached_hole_size = ~0UL;
|
||||
+ mm->free_area_cache = TASK_UNMAPPED_BASE;
|
||||
+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
|
||||
+ /*
|
||||
+ * Restore the topdown base:
|
||||
+ */
|
||||
+ mm->free_area_cache = mm->mmap_base;
|
||||
+ mm->cached_hole_size = ~0UL;
|
||||
+
|
||||
+ return addr;
|
||||
+}
|
||||
+
|
||||
+void arch_pick_mmap_layout(struct mm_struct *mm)
|
||||
+{
|
||||
+ unsigned long random_factor = 0UL;
|
||||
+
|
||||
+ /* 8 bits of randomness in 20 address space bits */
|
||||
+ if ((current->flags & PF_RANDOMIZE) &&
|
||||
+ !(current->personality & ADDR_NO_RANDOMIZE))
|
||||
+ random_factor = (get_random_int() % (1 << 8)) << PAGE_SHIFT;
|
||||
+
|
||||
+ if (mmap_is_legacy()) {
|
||||
+ mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
|
||||
+ mm->get_unmapped_area = arch_get_unmapped_area;
|
||||
+ mm->unmap_area = arch_unmap_area;
|
||||
+ } else {
|
||||
+ mm->mmap_base = mmap_base(random_factor);
|
||||
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown;
|
||||
+ mm->unmap_area = arch_unmap_area_topdown;
|
||||
+ }
|
||||
+}
|
||||
|
||||
/*
|
||||
* You really shouldn't be using read() or write() on /dev/mem. This
|
||||
--
|
||||
1.7.4.4
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
From: Émeric Maschino <emeric.maschino@gmail.com>
|
||||
Date: Mon, 9 Jan 2012 12:55:10 -0800
|
||||
Subject: [PATCH] ia64: Add accept4() syscall
|
||||
|
||||
commit 65cc21b4523e94d5640542a818748cd3be8cd6b4 upstream.
|
||||
|
||||
While debugging udev > 170 failure on Debian Wheezy
|
||||
(http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=648325), it appears
|
||||
that the issue was in fact due to missing accept4() in ia64.
|
||||
|
||||
This patch simply adds accept4() to ia64.
|
||||
|
||||
Signed-off-by: Émeric Maschino <emeric.maschino@gmail.com>
|
||||
Signed-off-by: Tony Luck <tony.luck@intel.com>
|
||||
---
|
||||
arch/ia64/include/asm/unistd.h | 3 ++-
|
||||
arch/ia64/kernel/entry.S | 1 +
|
||||
2 files changed, 3 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
|
||||
index 7617248..7a3bd25 100644
|
||||
--- a/arch/ia64/include/asm/unistd.h
|
||||
+++ b/arch/ia64/include/asm/unistd.h
|
||||
@@ -323,11 +323,12 @@
|
||||
#define __NR_sendmmsg 1331
|
||||
#define __NR_process_vm_readv 1332
|
||||
#define __NR_process_vm_writev 1333
|
||||
+#define __NR_accept4 1334
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
|
||||
-#define NR_syscalls 310 /* length of syscall table */
|
||||
+#define NR_syscalls 311 /* length of syscall table */
|
||||
|
||||
/*
|
||||
* The following defines stop scripts/checksyscalls.sh from complaining about
|
||||
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
|
||||
index 5b31d46..1ccbe12 100644
|
||||
--- a/arch/ia64/kernel/entry.S
|
||||
+++ b/arch/ia64/kernel/entry.S
|
||||
@@ -1779,6 +1779,7 @@ sys_call_table:
|
||||
data8 sys_sendmmsg
|
||||
data8 sys_process_vm_readv
|
||||
data8 sys_process_vm_writev
|
||||
+ data8 sys_accept4
|
||||
|
||||
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
|
||||
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
|
||||
--
|
||||
1.7.8.2
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
From: Nadav Har'El <nyh@il.ibm.com>
|
||||
Date: Thu, 22 Sep 2011 13:52:56 +0300
|
||||
Subject: [PATCH 1/2] KVM: nVMX: Add KVM_REQ_IMMEDIATE_EXIT
|
||||
|
||||
commit d6185f20a0efbf175e12831d0de330e4f21725aa upstream.
|
||||
|
||||
This patch adds a new vcpu->requests bit, KVM_REQ_IMMEDIATE_EXIT.
|
||||
This bit requests that when next entering the guest, we should run it only
|
||||
for as little as possible, and exit again.
|
||||
|
||||
We use this new option in nested VMX: When L1 launches L2, but L0 wishes L1
|
||||
to continue running so it can inject an event to it, we unfortunately cannot
|
||||
just pretend to have run L2 for a little while - We must really launch L2,
|
||||
otherwise certain one-off vmcs12 parameters (namely, L1 injection into L2)
|
||||
will be lost. So the existing code runs L2 in this case.
|
||||
But L2 could potentially run for a long time until it exits, and the
|
||||
injection into L1 will be delayed. The new KVM_REQ_IMMEDIATE_EXIT allows us
|
||||
to request that L2 will be entered, as necessary, but will exit as soon as
|
||||
possible after entry.
|
||||
|
||||
Our implementation of this request uses smp_send_reschedule() to send a
|
||||
self-IPI, with interrupts disabled. The interrupts remain disabled until the
|
||||
guest is entered, and then, after the entry is complete (often including
|
||||
processing an injection and jumping to the relevant handler), the physical
|
||||
interrupt is noticed and causes an exit.
|
||||
|
||||
On recent Intel processors, we could have achieved the same goal by using
|
||||
MTF instead of a self-IPI. Another technique worth considering in the future
|
||||
is to use VM_EXIT_ACK_INTR_ON_EXIT and a highest-priority vector IPI - to
|
||||
slightly improve performance by avoiding the useless interrupt handler
|
||||
which ends up being called when smp_send_reschedule() is used.
|
||||
|
||||
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
|
||||
Signed-off-by: Avi Kivity <avi@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/vmx.c | 11 +++++++----
|
||||
arch/x86/kvm/x86.c | 7 ++++++-
|
||||
include/linux/kvm_host.h | 1 +
|
||||
3 files changed, 14 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
||||
index 579a0b5..d75d914 100644
|
||||
--- a/arch/x86/kvm/vmx.c
|
||||
+++ b/arch/x86/kvm/vmx.c
|
||||
@@ -3945,12 +3945,15 @@ static bool nested_exit_on_intr(struct kvm_vcpu *vcpu)
|
||||
static void enable_irq_window(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u32 cpu_based_vm_exec_control;
|
||||
- if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu))
|
||||
- /* We can get here when nested_run_pending caused
|
||||
- * vmx_interrupt_allowed() to return false. In this case, do
|
||||
- * nothing - the interrupt will be injected later.
|
||||
+ if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) {
|
||||
+ /*
|
||||
+ * We get here if vmx_interrupt_allowed() said we can't
|
||||
+ * inject to L1 now because L2 must run. Ask L2 to exit
|
||||
+ * right after entry, so we can inject to L1 more promptly.
|
||||
*/
|
||||
+ kvm_make_request(KVM_REQ_IMMEDIATE_EXIT, vcpu);
|
||||
return;
|
||||
+ }
|
||||
|
||||
cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
|
||||
cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
|
||||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
||||
index 4c938da..e24edbc 100644
|
||||
--- a/arch/x86/kvm/x86.c
|
||||
+++ b/arch/x86/kvm/x86.c
|
||||
@@ -5648,6 +5648,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
|
||||
int r;
|
||||
bool req_int_win = !irqchip_in_kernel(vcpu->kvm) &&
|
||||
vcpu->run->request_interrupt_window;
|
||||
+ bool req_immediate_exit = 0;
|
||||
|
||||
if (vcpu->requests) {
|
||||
if (kvm_check_request(KVM_REQ_MMU_RELOAD, vcpu))
|
||||
@@ -5687,7 +5688,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
|
||||
record_steal_time(vcpu);
|
||||
if (kvm_check_request(KVM_REQ_NMI, vcpu))
|
||||
process_nmi(vcpu);
|
||||
-
|
||||
+ req_immediate_exit =
|
||||
+ kvm_check_request(KVM_REQ_IMMEDIATE_EXIT, vcpu);
|
||||
}
|
||||
|
||||
r = kvm_mmu_reload(vcpu);
|
||||
@@ -5738,6 +5740,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
|
||||
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
|
||||
|
||||
+ if (req_immediate_exit)
|
||||
+ smp_send_reschedule(vcpu->cpu);
|
||||
+
|
||||
kvm_guest_enter();
|
||||
|
||||
if (unlikely(vcpu->arch.switch_db_regs)) {
|
||||
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
|
||||
index d526231..9fedeb3 100644
|
||||
--- a/include/linux/kvm_host.h
|
||||
+++ b/include/linux/kvm_host.h
|
||||
@@ -50,6 +50,7 @@
|
||||
#define KVM_REQ_APF_HALT 12
|
||||
#define KVM_REQ_STEAL_UPDATE 13
|
||||
#define KVM_REQ_NMI 14
|
||||
+#define KVM_REQ_IMMEDIATE_EXIT 15
|
||||
|
||||
#define KVM_USERSPACE_IRQ_SOURCE_ID 0
|
||||
|
||||
--
|
||||
1.7.8.3
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
From: Nadav Har'El <nyh@il.ibm.com>
|
||||
Date: Thu, 22 Sep 2011 13:53:26 +0300
|
||||
Subject: [PATCH 2/2] KVM: nVMX: Fix warning-causing idt-vectoring-info
|
||||
behavior
|
||||
|
||||
commit 51cfe38ea50aa631f58ed8c340ed6f0143c325a8 upstream.
|
||||
|
||||
When L0 wishes to inject an interrupt while L2 is running, it emulates an exit
|
||||
to L1 with EXIT_REASON_EXTERNAL_INTERRUPT. This was explained in the original
|
||||
nVMX patch 23, titled "Correct handling of interrupt injection".
|
||||
|
||||
Unfortunately, it is possible (though rare) that at this point there is valid
|
||||
idt_vectoring_info in vmcs02. For example, L1 injected some interrupt to L2,
|
||||
and when L2 tried to run this interrupt's handler, it got a page fault - so
|
||||
it returns the original interrupt vector in idt_vectoring_info. The problem
|
||||
is that if this is the case, we cannot exit to L1 with EXTERNAL_INTERRUPT
|
||||
like we wished to, because the VMX spec guarantees that idt_vectoring_info
|
||||
and exit_reason_external_interrupt can never happen together. This is not
|
||||
just specified in the spec - a KVM L1 actually prints a kernel warning
|
||||
"unexpected, valid vectoring info" if we violate this guarantee, and some
|
||||
users noticed these warnings in L1's logs.
|
||||
|
||||
In order to better emulate a processor, which would never return the external
|
||||
interrupt and the idt-vectoring-info together, we need to separate the two
|
||||
injection steps: First, complete L1's injection into L2 (i.e., enter L2,
|
||||
injecting to it the idt-vectoring-info); Second, after entry into L2 succeeds
|
||||
and it exits back to L0, exit to L1 with the EXIT_REASON_EXTERNAL_INTERRUPT.
|
||||
Most of this is already in the code - the only change we need is to remain
|
||||
in L2 (and not exit to L1) in this case.
|
||||
|
||||
Note that the previous patch ensures (by using KVM_REQ_IMMEDIATE_EXIT) that
|
||||
although we do enter L2 first, it will exit immediately after processing its
|
||||
injection, allowing us to promptly inject to L1.
|
||||
|
||||
Note how we test vmcs12->idt_vectoring_info_field; This isn't really the
|
||||
vmcs12 value (we haven't exited to L1 yet, so vmcs12 hasn't been updated),
|
||||
but rather the place we save, at the end of vmx_vcpu_run, the vmcs02 value
|
||||
of this field. This was explained in patch 25 ("Correct handling of idt
|
||||
vectoring info") of the original nVMX patch series.
|
||||
|
||||
Thanks to Dave Allan and to Federico Simoncelli for reporting this bug,
|
||||
to Abel Gordon for helping me figure out the solution, and to Avi Kivity
|
||||
for helping to improve it.
|
||||
|
||||
Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
|
||||
Signed-off-by: Avi Kivity <avi@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/vmx.c | 7 ++++---
|
||||
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
||||
index d75d914..6e28d58 100644
|
||||
--- a/arch/x86/kvm/vmx.c
|
||||
+++ b/arch/x86/kvm/vmx.c
|
||||
@@ -4080,11 +4080,12 @@ static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
|
||||
static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) {
|
||||
- struct vmcs12 *vmcs12;
|
||||
- if (to_vmx(vcpu)->nested.nested_run_pending)
|
||||
+ struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
||||
+ if (to_vmx(vcpu)->nested.nested_run_pending ||
|
||||
+ (vmcs12->idt_vectoring_info_field &
|
||||
+ VECTORING_INFO_VALID_MASK))
|
||||
return 0;
|
||||
nested_vmx_vmexit(vcpu);
|
||||
- vmcs12 = get_vmcs12(vcpu);
|
||||
vmcs12->vm_exit_reason = EXIT_REASON_EXTERNAL_INTERRUPT;
|
||||
vmcs12->vm_exit_intr_info = 0;
|
||||
/* fall through to normal code, but now in L1, not L2 */
|
||||
--
|
||||
1.7.8.3
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
From: =?utf8?q?Stephan=20B=C3=A4rwolf?= <stephan.baerwolf@tu-ilmenau.de>
|
||||
Date: Thu, 12 Jan 2012 16:43:03 +0100
|
||||
Subject: [PATCH] KVM: x86: extend "struct x86_emulate_ops" with "get_cpuid"
|
||||
|
||||
commit 0769c5de24621141c953fbe1f943582d37cb4244 upstream.
|
||||
|
||||
In order to be able to proceed checks on CPU-specific properties
|
||||
within the emulator, function "get_cpuid" is introduced.
|
||||
With "get_cpuid" it is possible to virtually call the guests
|
||||
"cpuid"-opcode without changing the VM's context.
|
||||
|
||||
[mtosatti: cleanup/beautify code]
|
||||
|
||||
Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
|
||||
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
|
||||
---
|
||||
arch/x86/include/asm/kvm_emulate.h | 3 +++
|
||||
arch/x86/kvm/x86.c | 23 +++++++++++++++++++++++
|
||||
2 files changed, 26 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
|
||||
index ab4092e..c8b2868 100644
|
||||
--- a/arch/x86/include/asm/kvm_emulate.h
|
||||
+++ b/arch/x86/include/asm/kvm_emulate.h
|
||||
@@ -190,6 +190,9 @@ struct x86_emulate_ops {
|
||||
int (*intercept)(struct x86_emulate_ctxt *ctxt,
|
||||
struct x86_instruction_info *info,
|
||||
enum x86_intercept_stage stage);
|
||||
+
|
||||
+ bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
|
||||
+ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
|
||||
};
|
||||
|
||||
typedef u32 __attribute__((vector_size(16))) sse128_t;
|
||||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
||||
index f0fa3fb..c95ca2d 100644
|
||||
--- a/arch/x86/kvm/x86.c
|
||||
+++ b/arch/x86/kvm/x86.c
|
||||
@@ -4205,6 +4205,28 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
|
||||
return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
|
||||
}
|
||||
|
||||
+static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
|
||||
+ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
|
||||
+{
|
||||
+ struct kvm_cpuid_entry2 *cpuid = NULL;
|
||||
+
|
||||
+ if (eax && ecx)
|
||||
+ cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt),
|
||||
+ *eax, *ecx);
|
||||
+
|
||||
+ if (cpuid) {
|
||||
+ *eax = cpuid->eax;
|
||||
+ *ecx = cpuid->ecx;
|
||||
+ if (ebx)
|
||||
+ *ebx = cpuid->ebx;
|
||||
+ if (edx)
|
||||
+ *edx = cpuid->edx;
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static struct x86_emulate_ops emulate_ops = {
|
||||
.read_std = kvm_read_guest_virt_system,
|
||||
.write_std = kvm_write_guest_virt_system,
|
||||
@@ -4236,6 +4258,7 @@ static struct x86_emulate_ops emulate_ops = {
|
||||
.get_fpu = emulator_get_fpu,
|
||||
.put_fpu = emulator_put_fpu,
|
||||
.intercept = emulator_intercept,
|
||||
+ .get_cpuid = emulator_get_cpuid,
|
||||
};
|
||||
|
||||
static void cache_all_regs(struct kvm_vcpu *vcpu)
|
||||
--
|
||||
1.7.6.5
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
From: =?utf8?q?Stephan=20B=C3=A4rwolf?= <stephan.baerwolf@tu-ilmenau.de>
|
||||
Date: Thu, 12 Jan 2012 16:43:04 +0100
|
||||
Subject: [PATCH] KVM: x86: fix missing checks in syscall emulation
|
||||
|
||||
commit e28ba7bb020f07193bc000453c8775e9d2c0dda7 upstream.
|
||||
|
||||
On hosts without this patch, 32bit guests will crash (and 64bit guests
|
||||
may behave in a wrong way) for example by simply executing following
|
||||
nasm-demo-application:
|
||||
|
||||
[bits 32]
|
||||
global _start
|
||||
SECTION .text
|
||||
_start: syscall
|
||||
|
||||
(I tested it with winxp and linux - both always crashed)
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00000000 <_start>:
|
||||
0: 0f 05 syscall
|
||||
|
||||
The reason seems a missing "invalid opcode"-trap (int6) for the
|
||||
syscall opcode "0f05", which is not available on Intel CPUs
|
||||
within non-longmodes, as also on some AMD CPUs within legacy-mode.
|
||||
(depending on CPU vendor, MSR_EFER and cpuid)
|
||||
|
||||
Because previous mentioned OSs may not engage corresponding
|
||||
syscall target-registers (STAR, LSTAR, CSTAR), they remain
|
||||
NULL and (non trapping) syscalls are leading to multiple
|
||||
faults and finally crashs.
|
||||
|
||||
Depending on the architecture (AMD or Intel) pretended by
|
||||
guests, various checks according to vendor's documentation
|
||||
are implemented to overcome the current issue and behave
|
||||
like the CPUs physical counterparts.
|
||||
|
||||
[mtosatti: cleanup/beautify code]
|
||||
|
||||
Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
|
||||
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
|
||||
---
|
||||
arch/x86/include/asm/kvm_emulate.h | 13 +++++++++
|
||||
arch/x86/kvm/emulate.c | 51 ++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 64 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
|
||||
index c8b2868..7b9cfc4 100644
|
||||
--- a/arch/x86/include/asm/kvm_emulate.h
|
||||
+++ b/arch/x86/include/asm/kvm_emulate.h
|
||||
@@ -301,6 +301,19 @@ struct x86_emulate_ctxt {
|
||||
#define X86EMUL_MODE_PROT (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \
|
||||
X86EMUL_MODE_PROT64)
|
||||
|
||||
+/* CPUID vendors */
|
||||
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541
|
||||
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163
|
||||
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65
|
||||
+
|
||||
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41
|
||||
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574
|
||||
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273
|
||||
+
|
||||
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547
|
||||
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e
|
||||
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69
|
||||
+
|
||||
enum x86_intercept_stage {
|
||||
X86_ICTP_NONE = 0, /* Allow zero-init to not match anything */
|
||||
X86_ICPT_PRE_EXCEPT,
|
||||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
||||
index 05a562b..0982507 100644
|
||||
--- a/arch/x86/kvm/emulate.c
|
||||
+++ b/arch/x86/kvm/emulate.c
|
||||
@@ -1891,6 +1891,51 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
|
||||
ss->p = 1;
|
||||
}
|
||||
|
||||
+static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
|
||||
+{
|
||||
+ struct x86_emulate_ops *ops = ctxt->ops;
|
||||
+ u32 eax, ebx, ecx, edx;
|
||||
+
|
||||
+ /*
|
||||
+ * syscall should always be enabled in longmode - so only become
|
||||
+ * vendor specific (cpuid) if other modes are active...
|
||||
+ */
|
||||
+ if (ctxt->mode == X86EMUL_MODE_PROT64)
|
||||
+ return true;
|
||||
+
|
||||
+ eax = 0x00000000;
|
||||
+ ecx = 0x00000000;
|
||||
+ if (ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx)) {
|
||||
+ /*
|
||||
+ * Intel ("GenuineIntel")
|
||||
+ * remark: Intel CPUs only support "syscall" in 64bit
|
||||
+ * longmode. Also an 64bit guest with a
|
||||
+ * 32bit compat-app running will #UD !! While this
|
||||
+ * behaviour can be fixed (by emulating) into AMD
|
||||
+ * response - CPUs of AMD can't behave like Intel.
|
||||
+ */
|
||||
+ if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx &&
|
||||
+ ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx &&
|
||||
+ edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx)
|
||||
+ return false;
|
||||
+
|
||||
+ /* AMD ("AuthenticAMD") */
|
||||
+ if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx &&
|
||||
+ ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx &&
|
||||
+ edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx)
|
||||
+ return true;
|
||||
+
|
||||
+ /* AMD ("AMDisbetter!") */
|
||||
+ if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx &&
|
||||
+ ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx &&
|
||||
+ edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ /* default: (not Intel, not AMD), apply Intel's stricter rules... */
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static int em_syscall(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
struct x86_emulate_ops *ops = ctxt->ops;
|
||||
@@ -1904,9 +1949,15 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
|
||||
ctxt->mode == X86EMUL_MODE_VM86)
|
||||
return emulate_ud(ctxt);
|
||||
|
||||
+ if (!(em_syscall_is_enabled(ctxt)))
|
||||
+ return emulate_ud(ctxt);
|
||||
+
|
||||
ops->get_msr(ctxt, MSR_EFER, &efer);
|
||||
setup_syscalls_segments(ctxt, &cs, &ss);
|
||||
|
||||
+ if (!(efer & EFER_SCE))
|
||||
+ return emulate_ud(ctxt);
|
||||
+
|
||||
ops->get_msr(ctxt, MSR_STAR, &msr_data);
|
||||
msr_data >>= 32;
|
||||
cs_sel = (u16)(msr_data & 0xfffc);
|
||||
--
|
||||
1.7.6.5
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Mon, 2 Jan 2012 02:50:42 +0000
|
||||
Subject: [PATCH] ARM: Remove use of possibly-undefined BUILD_BUG_ON in
|
||||
<asm/bug.h>
|
||||
|
||||
<asm/bug.h> may be included by either <linux/bug.h> or
|
||||
<linux/kernel.h> but only the latter will define BUILD_BUG_ON.
|
||||
Bodge it until there is a proper upstream fix.
|
||||
---
|
||||
arch/arm/include/asm/bug.h | 1 -
|
||||
1 files changed, 0 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
|
||||
index 9abe7a0..fac79dc 100644
|
||||
--- a/arch/arm/include/asm/bug.h
|
||||
+++ b/arch/arm/include/asm/bug.h
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#define __BUG(__file, __line, __value) \
|
||||
do { \
|
||||
- BUILD_BUG_ON(sizeof(struct bug_entry) != 12); \
|
||||
asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \
|
||||
".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
|
||||
"2:\t.asciz " #__file "\n" \
|
||||
--
|
||||
1.7.7.3
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Thu, 24 Nov 2011 07:45:52 +0000
|
||||
Subject: [PATCH] bcma: Do not claim PCI device IDs also claimed by brcmsmac
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
drivers/bcma/host_pci.c | 4 +++-
|
||||
drivers/net/wireless/brcm80211/Kconfig | 1 -
|
||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
|
||||
index 1b51d8b..1f43cd4 100644
|
||||
--- a/drivers/bcma/host_pci.c
|
||||
+++ b/drivers/bcma/host_pci.c
|
||||
@@ -225,11 +225,13 @@ static void bcma_host_pci_remove(struct pci_dev *dev)
|
||||
}
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
|
||||
+#if !IS_ENABLED(CONFIG_BRCMSMAC)
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
|
||||
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
|
||||
+#endif
|
||||
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
|
||||
{ 0, },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
|
||||
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
|
||||
index 2069fc8..d5784ee 100644
|
||||
--- a/drivers/net/wireless/brcm80211/Kconfig
|
||||
+++ b/drivers/net/wireless/brcm80211/Kconfig
|
||||
@@ -5,7 +5,6 @@ config BRCMSMAC
|
||||
tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
|
||||
depends on PCI
|
||||
depends on MAC80211
|
||||
- depends on BCMA=n
|
||||
select BRCMUTIL
|
||||
select FW_LOADER
|
||||
select CRC_CCITT
|
||||
--
|
||||
1.7.7.3
|
||||
|
|
@ -1,20 +1,13 @@
|
|||
From 969e4dd0b5c715b239c765b870f2abf81c57e878 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Sun, 30 May 2010 22:47:01 +0100
|
||||
Subject: [PATCH 2/2] cgroups: Document the Debian memory resource controller
|
||||
config change
|
||||
|
||||
---
|
||||
Documentation/cgroups/memory.txt | 4 ++++
|
||||
1 files changed, 4 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
|
||||
index 7c16347..684f70d 100644
|
||||
--- a/Documentation/cgroups/memory.txt
|
||||
+++ b/Documentation/cgroups/memory.txt
|
||||
@@ -47,6 +47,10 @@ Features:
|
||||
Kernel memory and Hugepages are not under control yet. We just manage
|
||||
pages on LRU. To add more controls, we have to take care of performance.
|
||||
Kernel memory support is work in progress, and the current version provides
|
||||
basically functionality. (See Section 2.7)
|
||||
|
||||
+NOTE: In Debian kernel packages, the memory resource controller is
|
||||
+included but disabled by default. Use the kernel parameter
|
||||
|
@ -23,6 +16,3 @@ index 7c16347..684f70d 100644
|
|||
Brief summary of control files.
|
||||
|
||||
tasks # attach a task(thread) and show list of threads
|
||||
--
|
||||
1.7.4.4
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ rm drivers/staging/ft1000/ft1000-*/*.img
|
|||
|
||||
rm drivers/staging/keucr/init.h
|
||||
|
||||
unifdef drivers/staging/rtl8192e/r8192E_hwimg.c -UREMOVE_DFSG
|
||||
unifdef drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c -UREMOVE_DFSG
|
||||
|
||||
rm drivers/staging/wlags49_h2/ap_*.c
|
||||
rm drivers/staging/wlags49_h2/sta_*.c
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
diff --git a/drivers/staging/rtl8192e/r8192E_firmware.c b/drivers/staging/rtl8192e/r8192E_firmware.c
|
||||
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c
|
||||
index 3771985..b073208 100644
|
||||
--- a/drivers/staging/rtl8192e/r8192E_firmware.c
|
||||
+++ b/drivers/staging/rtl8192e/r8192E_firmware.c
|
||||
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c
|
||||
+++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c
|
||||
@@ -228,13 +228,6 @@ bool init_firmware(struct net_device *dev)
|
||||
struct r8192_priv *priv = rtllib_priv(dev);
|
||||
bool rt_status = true;
|
||||
|
@ -31,10 +31,10 @@ index 3771985..b073208 100644
|
|||
|
||||
default:
|
||||
break;
|
||||
diff --git a/drivers/staging/rtl8192e/r8192E_hwimg.c b/drivers/staging/rtl8192e/r8192E_hwimg.c
|
||||
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c
|
||||
index 08e7dbb..e760397 100644
|
||||
--- a/drivers/staging/rtl8192e/r8192E_hwimg.c
|
||||
+++ b/drivers/staging/rtl8192e/r8192E_hwimg.c
|
||||
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c
|
||||
+++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "r8192E_hwimg.h"
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
diff --git a/kernel/sched_autogroup.c b/kernel/sched_autogroup.c
|
||||
index 9fb6562..96abaaf 100644
|
||||
--- a/kernel/sched_autogroup.c
|
||||
+++ b/kernel/sched_autogroup.c
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/utsname.h>
|
||||
--- a/kernel/sched/auto_group.c
|
||||
+++ b/kernel/sched/auto_group.c
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <linux/security.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
-unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1;
|
||||
+unsigned int __read_mostly sysctl_sched_autogroup_enabled = 0;
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
From: Seth Forshee <seth.forshee@canonical.com>
|
||||
Date: Mon, 7 Nov 2011 19:53:24 -0800
|
||||
Subject: [PATCH 2/5] Input: ALPS - add protocol version field in
|
||||
alps_model_info
|
||||
|
||||
commit fa629ef5222193214da9a2b3c94369f79353bec9 upstream.
|
||||
|
||||
In preparation for adding support for more ALPS protocol versions,
|
||||
add a field for the protocol version to the model info instead of
|
||||
using a field in the flags. OLDPROTO and !OLDPROTO are now called
|
||||
version 1 and version 2, repsectively.
|
||||
|
||||
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
|
||||
Acked-by: Chase Douglas <chase.douglas@canonical.com>
|
||||
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
|
||||
|
||||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
|
||||
index 19d0943..77b776d 100644
|
||||
--- a/drivers/input/mouse/alps.c
|
||||
+++ b/drivers/input/mouse/alps.c
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "psmouse.h"
|
||||
#include "alps.h"
|
||||
|
||||
-#define ALPS_OLDPROTO 0x01 /* old style input */
|
||||
#define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */
|
||||
#define ALPS_PASS 0x04 /* device has a pass-through port */
|
||||
|
||||
@@ -35,30 +34,30 @@
|
||||
6-byte ALPS packet */
|
||||
|
||||
static const struct alps_model_info alps_model_data[] = {
|
||||
- { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
|
||||
- { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */
|
||||
- { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
|
||||
- { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
|
||||
- { { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 }, /* HP ze1115 */
|
||||
- { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
|
||||
- { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
|
||||
- { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
|
||||
- { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
|
||||
- { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
|
||||
- { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 },
|
||||
- { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */
|
||||
- { { 0x73, 0x00, 0x0a }, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */
|
||||
- { { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
|
||||
- { { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
|
||||
- { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
|
||||
- { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
|
||||
- { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
|
||||
+ { { 0x32, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
|
||||
+ { { 0x33, 0x02, 0x0a }, ALPS_PROTO_V1, 0x88, 0xf8, 0 }, /* UMAX-530T */
|
||||
+ { { 0x53, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x53, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x60, 0x03, 0xc8 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, /* HP ze1115 */
|
||||
+ { { 0x63, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x63, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x63, 0x02, 0x28 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
|
||||
+ { { 0x63, 0x02, 0x3c }, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
|
||||
+ { { 0x63, 0x02, 0x50 }, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
|
||||
+ { { 0x63, 0x02, 0x64 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x63, 0x03, 0xc8 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */
|
||||
+ { { 0x73, 0x00, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */
|
||||
+ { { 0x73, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x73, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
|
||||
+ { { 0x20, 0x02, 0x0e }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
|
||||
+ { { 0x22, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
|
||||
+ { { 0x22, 0x02, 0x14 }, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
|
||||
/* Dell Latitude E5500, E6400, E6500, Precision M4400 */
|
||||
- { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
|
||||
+ { { 0x62, 0x02, 0x14 }, ALPS_PROTO_V2, 0xcf, 0xcf,
|
||||
ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
|
||||
- { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
|
||||
- { { 0x52, 0x01, 0x14 }, 0xff, 0xff,
|
||||
- ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
|
||||
+ { { 0x73, 0x02, 0x50 }, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
|
||||
+ { { 0x52, 0x01, 0x14 }, ALPS_PROTO_V2, 0xff, 0xff,
|
||||
+ ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -112,7 +111,7 @@ static void alps_process_packet(struct psmouse *psmouse)
|
||||
int x, y, z, ges, fin, left, right, middle;
|
||||
int back = 0, forward = 0;
|
||||
|
||||
- if (model->flags & ALPS_OLDPROTO) {
|
||||
+ if (model->proto_version == ALPS_PROTO_V1) {
|
||||
left = packet[2] & 0x10;
|
||||
right = packet[2] & 0x08;
|
||||
middle = 0;
|
||||
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
|
||||
index 904ed8b..4ce9bba 100644
|
||||
--- a/drivers/input/mouse/alps.h
|
||||
+++ b/drivers/input/mouse/alps.h
|
||||
@@ -12,8 +12,12 @@
|
||||
#ifndef _ALPS_H
|
||||
#define _ALPS_H
|
||||
|
||||
+#define ALPS_PROTO_V1 0
|
||||
+#define ALPS_PROTO_V2 1
|
||||
+
|
||||
struct alps_model_info {
|
||||
unsigned char signature[3];
|
||||
+ unsigned char proto_version;
|
||||
unsigned char byte0, mask0;
|
||||
unsigned char flags;
|
||||
};
|
||||
--
|
||||
1.7.8.2
|
||||
|
|
@ -1,333 +0,0 @@
|
|||
From: Seth Forshee <seth.forshee@canonical.com>
|
||||
Date: Mon, 7 Nov 2011 19:54:13 -0800
|
||||
Subject: [PATCH 5/5] Input: ALPS - add semi-MT support for v3 protocol
|
||||
|
||||
commit 01ce661fc83005947dc958a5739c153843af8a73 upstream.
|
||||
|
||||
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
|
||||
Acked-by: Chase Douglas <chase.douglas@canonical.com>
|
||||
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
|
||||
|
||||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
|
||||
index a0248fd..bd87380 100644
|
||||
--- a/drivers/input/mouse/alps.c
|
||||
+++ b/drivers/input/mouse/alps.c
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/input.h>
|
||||
+#include <linux/input/mt.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/libps2.h>
|
||||
|
||||
@@ -26,6 +27,12 @@
|
||||
/*
|
||||
* Definitions for ALPS version 3 and 4 command mode protocol
|
||||
*/
|
||||
+#define ALPS_V3_X_MAX 2000
|
||||
+#define ALPS_V3_Y_MAX 1400
|
||||
+
|
||||
+#define ALPS_BITMAP_X_BITS 15
|
||||
+#define ALPS_BITMAP_Y_BITS 11
|
||||
+
|
||||
#define ALPS_CMD_NIBBLE_10 0x01f2
|
||||
|
||||
static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
|
||||
@@ -250,6 +257,137 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
|
||||
input_sync(dev);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Process bitmap data from v3 and v4 protocols. Returns the number of
|
||||
+ * fingers detected. A return value of 0 means at least one of the
|
||||
+ * bitmaps was empty.
|
||||
+ *
|
||||
+ * The bitmaps don't have enough data to track fingers, so this function
|
||||
+ * only generates points representing a bounding box of all contacts.
|
||||
+ * These points are returned in x1, y1, x2, and y2 when the return value
|
||||
+ * is greater than 0.
|
||||
+ */
|
||||
+static int alps_process_bitmap(unsigned int x_map, unsigned int y_map,
|
||||
+ int *x1, int *y1, int *x2, int *y2)
|
||||
+{
|
||||
+ struct alps_bitmap_point {
|
||||
+ int start_bit;
|
||||
+ int num_bits;
|
||||
+ };
|
||||
+
|
||||
+ int fingers_x = 0, fingers_y = 0, fingers;
|
||||
+ int i, bit, prev_bit;
|
||||
+ struct alps_bitmap_point x_low = {0,}, x_high = {0,};
|
||||
+ struct alps_bitmap_point y_low = {0,}, y_high = {0,};
|
||||
+ struct alps_bitmap_point *point;
|
||||
+
|
||||
+ if (!x_map || !y_map)
|
||||
+ return 0;
|
||||
+
|
||||
+ *x1 = *y1 = *x2 = *y2 = 0;
|
||||
+
|
||||
+ prev_bit = 0;
|
||||
+ point = &x_low;
|
||||
+ for (i = 0; x_map != 0; i++, x_map >>= 1) {
|
||||
+ bit = x_map & 1;
|
||||
+ if (bit) {
|
||||
+ if (!prev_bit) {
|
||||
+ point->start_bit = i;
|
||||
+ fingers_x++;
|
||||
+ }
|
||||
+ point->num_bits++;
|
||||
+ } else {
|
||||
+ if (prev_bit)
|
||||
+ point = &x_high;
|
||||
+ else
|
||||
+ point->num_bits = 0;
|
||||
+ }
|
||||
+ prev_bit = bit;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * y bitmap is reversed for what we need (lower positions are in
|
||||
+ * higher bits), so we process from the top end.
|
||||
+ */
|
||||
+ y_map = y_map << (sizeof(y_map) * BITS_PER_BYTE - ALPS_BITMAP_Y_BITS);
|
||||
+ prev_bit = 0;
|
||||
+ point = &y_low;
|
||||
+ for (i = 0; y_map != 0; i++, y_map <<= 1) {
|
||||
+ bit = y_map & (1 << (sizeof(y_map) * BITS_PER_BYTE - 1));
|
||||
+ if (bit) {
|
||||
+ if (!prev_bit) {
|
||||
+ point->start_bit = i;
|
||||
+ fingers_y++;
|
||||
+ }
|
||||
+ point->num_bits++;
|
||||
+ } else {
|
||||
+ if (prev_bit)
|
||||
+ point = &y_high;
|
||||
+ else
|
||||
+ point->num_bits = 0;
|
||||
+ }
|
||||
+ prev_bit = bit;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Fingers can overlap, so we use the maximum count of fingers
|
||||
+ * on either axis as the finger count.
|
||||
+ */
|
||||
+ fingers = max(fingers_x, fingers_y);
|
||||
+
|
||||
+ /*
|
||||
+ * If total fingers is > 1 but either axis reports only a single
|
||||
+ * contact, we have overlapping or adjacent fingers. For the
|
||||
+ * purposes of creating a bounding box, divide the single contact
|
||||
+ * (roughly) equally between the two points.
|
||||
+ */
|
||||
+ if (fingers > 1) {
|
||||
+ if (fingers_x == 1) {
|
||||
+ i = x_low.num_bits / 2;
|
||||
+ x_low.num_bits = x_low.num_bits - i;
|
||||
+ x_high.start_bit = x_low.start_bit + i;
|
||||
+ x_high.num_bits = max(i, 1);
|
||||
+ } else if (fingers_y == 1) {
|
||||
+ i = y_low.num_bits / 2;
|
||||
+ y_low.num_bits = y_low.num_bits - i;
|
||||
+ y_high.start_bit = y_low.start_bit + i;
|
||||
+ y_high.num_bits = max(i, 1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *x1 = (ALPS_V3_X_MAX * (2 * x_low.start_bit + x_low.num_bits - 1)) /
|
||||
+ (2 * (ALPS_BITMAP_X_BITS - 1));
|
||||
+ *y1 = (ALPS_V3_Y_MAX * (2 * y_low.start_bit + y_low.num_bits - 1)) /
|
||||
+ (2 * (ALPS_BITMAP_Y_BITS - 1));
|
||||
+
|
||||
+ if (fingers > 1) {
|
||||
+ *x2 = (ALPS_V3_X_MAX * (2 * x_high.start_bit + x_high.num_bits - 1)) /
|
||||
+ (2 * (ALPS_BITMAP_X_BITS - 1));
|
||||
+ *y2 = (ALPS_V3_Y_MAX * (2 * y_high.start_bit + y_high.num_bits - 1)) /
|
||||
+ (2 * (ALPS_BITMAP_Y_BITS - 1));
|
||||
+ }
|
||||
+
|
||||
+ return fingers;
|
||||
+}
|
||||
+
|
||||
+static void alps_set_slot(struct input_dev *dev, int slot, bool active,
|
||||
+ int x, int y)
|
||||
+{
|
||||
+ input_mt_slot(dev, slot);
|
||||
+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
|
||||
+ if (active) {
|
||||
+ input_report_abs(dev, ABS_MT_POSITION_X, x);
|
||||
+ input_report_abs(dev, ABS_MT_POSITION_Y, y);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void alps_report_semi_mt_data(struct input_dev *dev, int num_fingers,
|
||||
+ int x1, int y1, int x2, int y2)
|
||||
+{
|
||||
+ alps_set_slot(dev, 0, num_fingers != 0, x1, y1);
|
||||
+ alps_set_slot(dev, 1, num_fingers == 2, x2, y2);
|
||||
+}
|
||||
+
|
||||
static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
|
||||
{
|
||||
struct alps_data *priv = psmouse->private;
|
||||
@@ -318,16 +456,17 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
|
||||
struct input_dev *dev2 = priv->dev2;
|
||||
int x, y, z;
|
||||
int left, right, middle;
|
||||
+ int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||
+ int fingers = 0, bmap_fingers;
|
||||
+ unsigned int x_bitmap, y_bitmap;
|
||||
|
||||
/*
|
||||
- * There's no single feature of touchpad position and bitmap
|
||||
- * packets that can be used to distinguish between them. We
|
||||
- * rely on the fact that a bitmap packet should always follow
|
||||
- * a position packet with bit 6 of packet[4] set.
|
||||
+ * There's no single feature of touchpad position and bitmap packets
|
||||
+ * that can be used to distinguish between them. We rely on the fact
|
||||
+ * that a bitmap packet should always follow a position packet with
|
||||
+ * bit 6 of packet[4] set.
|
||||
*/
|
||||
if (priv->multi_packet) {
|
||||
- priv->multi_packet = 0;
|
||||
-
|
||||
/*
|
||||
* Sometimes a position packet will indicate a multi-packet
|
||||
* sequence, but then what follows is another position
|
||||
@@ -335,18 +474,49 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
|
||||
* position packet as usual.
|
||||
*/
|
||||
if (packet[0] & 0x40) {
|
||||
+ fingers = (packet[5] & 0x3) + 1;
|
||||
+ x_bitmap = ((packet[4] & 0x7e) << 8) |
|
||||
+ ((packet[1] & 0x7f) << 2) |
|
||||
+ ((packet[0] & 0x30) >> 4);
|
||||
+ y_bitmap = ((packet[3] & 0x70) << 4) |
|
||||
+ ((packet[2] & 0x7f) << 1) |
|
||||
+ (packet[4] & 0x01);
|
||||
+
|
||||
+ bmap_fingers = alps_process_bitmap(x_bitmap, y_bitmap,
|
||||
+ &x1, &y1, &x2, &y2);
|
||||
+
|
||||
/*
|
||||
- * Bitmap packets are not yet supported, so for now
|
||||
- * just ignore them.
|
||||
+ * We shouldn't report more than one finger if
|
||||
+ * we don't have two coordinates.
|
||||
*/
|
||||
- return;
|
||||
+ if (fingers > 1 && bmap_fingers < 2)
|
||||
+ fingers = bmap_fingers;
|
||||
+
|
||||
+ /* Now process position packet */
|
||||
+ packet = priv->multi_data;
|
||||
+ } else {
|
||||
+ priv->multi_packet = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- if (!priv->multi_packet && (packet[4] & 0x40))
|
||||
+ /*
|
||||
+ * Bit 6 of byte 0 is not usually set in position packets. The only
|
||||
+ * times it seems to be set is in situations where the data is
|
||||
+ * suspect anyway, e.g. a palm resting flat on the touchpad. Given
|
||||
+ * this combined with the fact that this bit is useful for filtering
|
||||
+ * out misidentified bitmap packets, we reject anything with this
|
||||
+ * bit set.
|
||||
+ */
|
||||
+ if (packet[0] & 0x40)
|
||||
+ return;
|
||||
+
|
||||
+ if (!priv->multi_packet && (packet[4] & 0x40)) {
|
||||
priv->multi_packet = 1;
|
||||
- else
|
||||
- priv->multi_packet = 0;
|
||||
+ memcpy(priv->multi_data, packet, sizeof(priv->multi_data));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ priv->multi_packet = 0;
|
||||
|
||||
left = packet[3] & 0x01;
|
||||
right = packet[3] & 0x02;
|
||||
@@ -366,22 +536,38 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
|
||||
if (x && y && !z)
|
||||
return;
|
||||
|
||||
+ /*
|
||||
+ * If we don't have MT data or the bitmaps were empty, we have
|
||||
+ * to rely on ST data.
|
||||
+ */
|
||||
+ if (!fingers) {
|
||||
+ x1 = x;
|
||||
+ y1 = y;
|
||||
+ fingers = z > 0 ? 1 : 0;
|
||||
+ }
|
||||
+
|
||||
if (z >= 64)
|
||||
input_report_key(dev, BTN_TOUCH, 1);
|
||||
else
|
||||
input_report_key(dev, BTN_TOUCH, 0);
|
||||
|
||||
+ alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
|
||||
+
|
||||
+ input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
|
||||
+ input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
|
||||
+ input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
|
||||
+ input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4);
|
||||
+
|
||||
+ input_report_key(dev, BTN_LEFT, left);
|
||||
+ input_report_key(dev, BTN_RIGHT, right);
|
||||
+ input_report_key(dev, BTN_MIDDLE, middle);
|
||||
+
|
||||
if (z > 0) {
|
||||
input_report_abs(dev, ABS_X, x);
|
||||
input_report_abs(dev, ABS_Y, y);
|
||||
}
|
||||
input_report_abs(dev, ABS_PRESSURE, z);
|
||||
|
||||
- input_report_key(dev, BTN_TOOL_FINGER, z > 0);
|
||||
- input_report_key(dev, BTN_LEFT, left);
|
||||
- input_report_key(dev, BTN_RIGHT, right);
|
||||
- input_report_key(dev, BTN_MIDDLE, middle);
|
||||
-
|
||||
input_sync(dev);
|
||||
|
||||
if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) {
|
||||
@@ -1368,9 +1554,18 @@ int alps_init(struct psmouse *psmouse)
|
||||
input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
|
||||
break;
|
||||
case ALPS_PROTO_V3:
|
||||
+ set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
|
||||
+ input_mt_init_slots(dev1, 2);
|
||||
+ input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0);
|
||||
+ input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0);
|
||||
+
|
||||
+ set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit);
|
||||
+ set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
|
||||
+ set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
|
||||
+ /* fall through */
|
||||
case ALPS_PROTO_V4:
|
||||
- input_set_abs_params(dev1, ABS_X, 0, 2000, 0, 0);
|
||||
- input_set_abs_params(dev1, ABS_Y, 0, 1400, 0, 0);
|
||||
+ input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0);
|
||||
+ input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
|
||||
index 62db7f4..a00a4ab 100644
|
||||
--- a/drivers/input/mouse/alps.h
|
||||
+++ b/drivers/input/mouse/alps.h
|
||||
@@ -38,6 +38,7 @@ struct alps_data {
|
||||
int addr_command; /* Command to set register address */
|
||||
int prev_fin; /* Finger bit from previous packet */
|
||||
int multi_packet; /* Multi-packet data in progress */
|
||||
+ unsigned char multi_data[6]; /* Saved multi-packet data */
|
||||
u8 quirks;
|
||||
struct timer_list timer;
|
||||
};
|
||||
--
|
||||
1.7.8.2
|
||||
|
|
@ -1,998 +0,0 @@
|
|||
From: Seth Forshee <seth.forshee@canonical.com>
|
||||
Date: Mon, 7 Nov 2011 19:53:36 -0800
|
||||
Subject: [PATCH 4/5] Input: ALPS - add support for protocol versions 3 and 4
|
||||
|
||||
commit 25bded7cd60fa460e520e9f819bd06f4c5cb53f0 upstream.
|
||||
|
||||
This patch adds support for two ALPS touchpad protocols not
|
||||
supported currently by the driver, which I am arbitrarily naming
|
||||
version 3 and version 4. Support is single-touch only at this time,
|
||||
although both protocols are capable of limited multitouch support.
|
||||
|
||||
Thanks to Andrew Skalski, who did the initial reverse-engineering
|
||||
of the v3 protocol.
|
||||
|
||||
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
|
||||
Acked-by: Chase Douglas <chase.douglas@canonical.com>
|
||||
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
|
||||
|
||||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
|
||||
index 44a0a71..a0248fd 100644
|
||||
--- a/drivers/input/mouse/alps.c
|
||||
+++ b/drivers/input/mouse/alps.c
|
||||
@@ -23,6 +23,50 @@
|
||||
#include "psmouse.h"
|
||||
#include "alps.h"
|
||||
|
||||
+/*
|
||||
+ * Definitions for ALPS version 3 and 4 command mode protocol
|
||||
+ */
|
||||
+#define ALPS_CMD_NIBBLE_10 0x01f2
|
||||
+
|
||||
+static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
|
||||
+ { PSMOUSE_CMD_SETPOLL, 0x00 }, /* 0 */
|
||||
+ { PSMOUSE_CMD_RESET_DIS, 0x00 }, /* 1 */
|
||||
+ { PSMOUSE_CMD_SETSCALE21, 0x00 }, /* 2 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x0a }, /* 3 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x14 }, /* 4 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x28 }, /* 5 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x3c }, /* 6 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x50 }, /* 7 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x64 }, /* 8 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0xc8 }, /* 9 */
|
||||
+ { ALPS_CMD_NIBBLE_10, 0x00 }, /* a */
|
||||
+ { PSMOUSE_CMD_SETRES, 0x00 }, /* b */
|
||||
+ { PSMOUSE_CMD_SETRES, 0x01 }, /* c */
|
||||
+ { PSMOUSE_CMD_SETRES, 0x02 }, /* d */
|
||||
+ { PSMOUSE_CMD_SETRES, 0x03 }, /* e */
|
||||
+ { PSMOUSE_CMD_SETSCALE11, 0x00 }, /* f */
|
||||
+};
|
||||
+
|
||||
+static const struct alps_nibble_commands alps_v4_nibble_commands[] = {
|
||||
+ { PSMOUSE_CMD_ENABLE, 0x00 }, /* 0 */
|
||||
+ { PSMOUSE_CMD_RESET_DIS, 0x00 }, /* 1 */
|
||||
+ { PSMOUSE_CMD_SETSCALE21, 0x00 }, /* 2 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x0a }, /* 3 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x14 }, /* 4 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x28 }, /* 5 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x3c }, /* 6 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x50 }, /* 7 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0x64 }, /* 8 */
|
||||
+ { PSMOUSE_CMD_SETRATE, 0xc8 }, /* 9 */
|
||||
+ { ALPS_CMD_NIBBLE_10, 0x00 }, /* a */
|
||||
+ { PSMOUSE_CMD_SETRES, 0x00 }, /* b */
|
||||
+ { PSMOUSE_CMD_SETRES, 0x01 }, /* c */
|
||||
+ { PSMOUSE_CMD_SETRES, 0x02 }, /* d */
|
||||
+ { PSMOUSE_CMD_SETRES, 0x03 }, /* e */
|
||||
+ { PSMOUSE_CMD_SETSCALE11, 0x00 }, /* f */
|
||||
+};
|
||||
+
|
||||
+
|
||||
#define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */
|
||||
#define ALPS_PASS 0x04 /* device has a pass-through port */
|
||||
|
||||
@@ -34,30 +78,33 @@
|
||||
6-byte ALPS packet */
|
||||
|
||||
static const struct alps_model_info alps_model_data[] = {
|
||||
- { { 0x32, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
|
||||
- { { 0x33, 0x02, 0x0a }, ALPS_PROTO_V1, 0x88, 0xf8, 0 }, /* UMAX-530T */
|
||||
- { { 0x53, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
- { { 0x53, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
- { { 0x60, 0x03, 0xc8 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, /* HP ze1115 */
|
||||
- { { 0x63, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
- { { 0x63, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
- { { 0x63, 0x02, 0x28 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
|
||||
- { { 0x63, 0x02, 0x3c }, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
|
||||
- { { 0x63, 0x02, 0x50 }, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
|
||||
- { { 0x63, 0x02, 0x64 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
- { { 0x63, 0x03, 0xc8 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */
|
||||
- { { 0x73, 0x00, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */
|
||||
- { { 0x73, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
- { { 0x73, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
|
||||
- { { 0x20, 0x02, 0x0e }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
|
||||
- { { 0x22, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
|
||||
- { { 0x22, 0x02, 0x14 }, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
|
||||
+ { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
|
||||
+ { { 0x33, 0x02, 0x0a }, 0x00, ALPS_PROTO_V1, 0x88, 0xf8, 0 }, /* UMAX-530T */
|
||||
+ { { 0x53, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x53, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x60, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, /* HP ze1115 */
|
||||
+ { { 0x63, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x63, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x63, 0x02, 0x28 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
|
||||
+ { { 0x63, 0x02, 0x3c }, 0x00, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
|
||||
+ { { 0x63, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
|
||||
+ { { 0x63, 0x02, 0x64 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x63, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */
|
||||
+ { { 0x73, 0x00, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */
|
||||
+ { { 0x73, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
+ { { 0x73, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
|
||||
+ { { 0x20, 0x02, 0x0e }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
|
||||
+ { { 0x22, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
|
||||
+ { { 0x22, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
|
||||
/* Dell Latitude E5500, E6400, E6500, Precision M4400 */
|
||||
- { { 0x62, 0x02, 0x14 }, ALPS_PROTO_V2, 0xcf, 0xcf,
|
||||
+ { { 0x62, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf,
|
||||
ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
|
||||
- { { 0x73, 0x02, 0x50 }, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
|
||||
- { { 0x52, 0x01, 0x14 }, ALPS_PROTO_V2, 0xff, 0xff,
|
||||
- ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
|
||||
+ { { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
|
||||
+ { { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff,
|
||||
+ ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
|
||||
+ { { 0x73, 0x02, 0x64 }, 0x9b, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT },
|
||||
+ { { 0x73, 0x02, 0x64 }, 0x9d, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT },
|
||||
+ { { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 },
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -101,7 +148,7 @@ static void alps_report_buttons(struct psmouse *psmouse,
|
||||
input_sync(dev2);
|
||||
}
|
||||
|
||||
-static void alps_process_packet(struct psmouse *psmouse)
|
||||
+static void alps_process_packet_v1_v2(struct psmouse *psmouse)
|
||||
{
|
||||
struct alps_data *priv = psmouse->private;
|
||||
const struct alps_model_info *model = priv->i;
|
||||
@@ -203,6 +250,224 @@ static void alps_process_packet(struct psmouse *psmouse)
|
||||
input_sync(dev);
|
||||
}
|
||||
|
||||
+static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct alps_data *priv = psmouse->private;
|
||||
+ unsigned char *packet = psmouse->packet;
|
||||
+ struct input_dev *dev = priv->dev2;
|
||||
+ int x, y, z, left, right, middle;
|
||||
+
|
||||
+ /* Sanity check packet */
|
||||
+ if (!(packet[0] & 0x40)) {
|
||||
+ psmouse_dbg(psmouse, "Bad trackstick packet, discarding\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * There's a special packet that seems to indicate the end
|
||||
+ * of a stream of trackstick data. Filter these out.
|
||||
+ */
|
||||
+ if (packet[1] == 0x7f && packet[2] == 0x7f && packet[4] == 0x7f)
|
||||
+ return;
|
||||
+
|
||||
+ x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f));
|
||||
+ y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f));
|
||||
+ z = (packet[4] & 0x7c) >> 2;
|
||||
+
|
||||
+ /*
|
||||
+ * The x and y values tend to be quite large, and when used
|
||||
+ * alone the trackstick is difficult to use. Scale them down
|
||||
+ * to compensate.
|
||||
+ */
|
||||
+ x /= 8;
|
||||
+ y /= 8;
|
||||
+
|
||||
+ input_report_rel(dev, REL_X, x);
|
||||
+ input_report_rel(dev, REL_Y, -y);
|
||||
+
|
||||
+ /*
|
||||
+ * Most ALPS models report the trackstick buttons in the touchpad
|
||||
+ * packets, but a few report them here. No reliable way has been
|
||||
+ * found to differentiate between the models upfront, so we enable
|
||||
+ * the quirk in response to seeing a button press in the trackstick
|
||||
+ * packet.
|
||||
+ */
|
||||
+ left = packet[3] & 0x01;
|
||||
+ right = packet[3] & 0x02;
|
||||
+ middle = packet[3] & 0x04;
|
||||
+
|
||||
+ if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) &&
|
||||
+ (left || right || middle))
|
||||
+ priv->quirks |= ALPS_QUIRK_TRACKSTICK_BUTTONS;
|
||||
+
|
||||
+ if (priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) {
|
||||
+ input_report_key(dev, BTN_LEFT, left);
|
||||
+ input_report_key(dev, BTN_RIGHT, right);
|
||||
+ input_report_key(dev, BTN_MIDDLE, middle);
|
||||
+ }
|
||||
+
|
||||
+ input_sync(dev);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct alps_data *priv = psmouse->private;
|
||||
+ unsigned char *packet = psmouse->packet;
|
||||
+ struct input_dev *dev = psmouse->dev;
|
||||
+ struct input_dev *dev2 = priv->dev2;
|
||||
+ int x, y, z;
|
||||
+ int left, right, middle;
|
||||
+
|
||||
+ /*
|
||||
+ * There's no single feature of touchpad position and bitmap
|
||||
+ * packets that can be used to distinguish between them. We
|
||||
+ * rely on the fact that a bitmap packet should always follow
|
||||
+ * a position packet with bit 6 of packet[4] set.
|
||||
+ */
|
||||
+ if (priv->multi_packet) {
|
||||
+ priv->multi_packet = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * Sometimes a position packet will indicate a multi-packet
|
||||
+ * sequence, but then what follows is another position
|
||||
+ * packet. Check for this, and when it happens process the
|
||||
+ * position packet as usual.
|
||||
+ */
|
||||
+ if (packet[0] & 0x40) {
|
||||
+ /*
|
||||
+ * Bitmap packets are not yet supported, so for now
|
||||
+ * just ignore them.
|
||||
+ */
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!priv->multi_packet && (packet[4] & 0x40))
|
||||
+ priv->multi_packet = 1;
|
||||
+ else
|
||||
+ priv->multi_packet = 0;
|
||||
+
|
||||
+ left = packet[3] & 0x01;
|
||||
+ right = packet[3] & 0x02;
|
||||
+ middle = packet[3] & 0x04;
|
||||
+
|
||||
+ x = ((packet[1] & 0x7f) << 4) | ((packet[4] & 0x30) >> 2) |
|
||||
+ ((packet[0] & 0x30) >> 4);
|
||||
+ y = ((packet[2] & 0x7f) << 4) | (packet[4] & 0x0f);
|
||||
+ z = packet[5] & 0x7f;
|
||||
+
|
||||
+ /*
|
||||
+ * Sometimes the hardware sends a single packet with z = 0
|
||||
+ * in the middle of a stream. Real releases generate packets
|
||||
+ * with x, y, and z all zero, so these seem to be flukes.
|
||||
+ * Ignore them.
|
||||
+ */
|
||||
+ if (x && y && !z)
|
||||
+ return;
|
||||
+
|
||||
+ if (z >= 64)
|
||||
+ input_report_key(dev, BTN_TOUCH, 1);
|
||||
+ else
|
||||
+ input_report_key(dev, BTN_TOUCH, 0);
|
||||
+
|
||||
+ if (z > 0) {
|
||||
+ input_report_abs(dev, ABS_X, x);
|
||||
+ input_report_abs(dev, ABS_Y, y);
|
||||
+ }
|
||||
+ input_report_abs(dev, ABS_PRESSURE, z);
|
||||
+
|
||||
+ input_report_key(dev, BTN_TOOL_FINGER, z > 0);
|
||||
+ input_report_key(dev, BTN_LEFT, left);
|
||||
+ input_report_key(dev, BTN_RIGHT, right);
|
||||
+ input_report_key(dev, BTN_MIDDLE, middle);
|
||||
+
|
||||
+ input_sync(dev);
|
||||
+
|
||||
+ if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) {
|
||||
+ left = packet[3] & 0x10;
|
||||
+ right = packet[3] & 0x20;
|
||||
+ middle = packet[3] & 0x40;
|
||||
+
|
||||
+ input_report_key(dev2, BTN_LEFT, left);
|
||||
+ input_report_key(dev2, BTN_RIGHT, right);
|
||||
+ input_report_key(dev2, BTN_MIDDLE, middle);
|
||||
+ input_sync(dev2);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void alps_process_packet_v3(struct psmouse *psmouse)
|
||||
+{
|
||||
+ unsigned char *packet = psmouse->packet;
|
||||
+
|
||||
+ /*
|
||||
+ * v3 protocol packets come in three types, two representing
|
||||
+ * touchpad data and one representing trackstick data.
|
||||
+ * Trackstick packets seem to be distinguished by always
|
||||
+ * having 0x3f in the last byte. This value has never been
|
||||
+ * observed in the last byte of either of the other types
|
||||
+ * of packets.
|
||||
+ */
|
||||
+ if (packet[5] == 0x3f) {
|
||||
+ alps_process_trackstick_packet_v3(psmouse);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ alps_process_touchpad_packet_v3(psmouse);
|
||||
+}
|
||||
+
|
||||
+static void alps_process_packet_v4(struct psmouse *psmouse)
|
||||
+{
|
||||
+ unsigned char *packet = psmouse->packet;
|
||||
+ struct input_dev *dev = psmouse->dev;
|
||||
+ int x, y, z;
|
||||
+ int left, right;
|
||||
+
|
||||
+ left = packet[4] & 0x01;
|
||||
+ right = packet[4] & 0x02;
|
||||
+
|
||||
+ x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) |
|
||||
+ ((packet[0] & 0x30) >> 4);
|
||||
+ y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f);
|
||||
+ z = packet[5] & 0x7f;
|
||||
+
|
||||
+ if (z >= 64)
|
||||
+ input_report_key(dev, BTN_TOUCH, 1);
|
||||
+ else
|
||||
+ input_report_key(dev, BTN_TOUCH, 0);
|
||||
+
|
||||
+ if (z > 0) {
|
||||
+ input_report_abs(dev, ABS_X, x);
|
||||
+ input_report_abs(dev, ABS_Y, y);
|
||||
+ }
|
||||
+ input_report_abs(dev, ABS_PRESSURE, z);
|
||||
+
|
||||
+ input_report_key(dev, BTN_TOOL_FINGER, z > 0);
|
||||
+ input_report_key(dev, BTN_LEFT, left);
|
||||
+ input_report_key(dev, BTN_RIGHT, right);
|
||||
+
|
||||
+ input_sync(dev);
|
||||
+}
|
||||
+
|
||||
+static void alps_process_packet(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct alps_data *priv = psmouse->private;
|
||||
+ const struct alps_model_info *model = priv->i;
|
||||
+
|
||||
+ switch (model->proto_version) {
|
||||
+ case ALPS_PROTO_V1:
|
||||
+ case ALPS_PROTO_V2:
|
||||
+ alps_process_packet_v1_v2(psmouse);
|
||||
+ break;
|
||||
+ case ALPS_PROTO_V3:
|
||||
+ alps_process_packet_v3(psmouse);
|
||||
+ break;
|
||||
+ case ALPS_PROTO_V4:
|
||||
+ alps_process_packet_v4(psmouse);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
|
||||
unsigned char packet[],
|
||||
bool report_buttons)
|
||||
@@ -376,11 +641,127 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
|
||||
return PSMOUSE_GOOD_DATA;
|
||||
}
|
||||
|
||||
+static int alps_command_mode_send_nibble(struct psmouse *psmouse, int nibble)
|
||||
+{
|
||||
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
+ struct alps_data *priv = psmouse->private;
|
||||
+ int command;
|
||||
+ unsigned char *param;
|
||||
+ unsigned char dummy[4];
|
||||
+
|
||||
+ BUG_ON(nibble > 0xf);
|
||||
+
|
||||
+ command = priv->nibble_commands[nibble].command;
|
||||
+ param = (command & 0x0f00) ?
|
||||
+ dummy : (unsigned char *)&priv->nibble_commands[nibble].data;
|
||||
+
|
||||
+ if (ps2_command(ps2dev, param, command))
|
||||
+ return -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int alps_command_mode_set_addr(struct psmouse *psmouse, int addr)
|
||||
+{
|
||||
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
+ struct alps_data *priv = psmouse->private;
|
||||
+ int i, nibble;
|
||||
+
|
||||
+ if (ps2_command(ps2dev, NULL, priv->addr_command))
|
||||
+ return -1;
|
||||
+
|
||||
+ for (i = 12; i >= 0; i -= 4) {
|
||||
+ nibble = (addr >> i) & 0xf;
|
||||
+ if (alps_command_mode_send_nibble(psmouse, nibble))
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __alps_command_mode_read_reg(struct psmouse *psmouse, int addr)
|
||||
+{
|
||||
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
+ unsigned char param[4];
|
||||
+
|
||||
+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
|
||||
+ return -1;
|
||||
+
|
||||
+ /*
|
||||
+ * The address being read is returned in the first two bytes
|
||||
+ * of the result. Check that this address matches the expected
|
||||
+ * address.
|
||||
+ */
|
||||
+ if (addr != ((param[0] << 8) | param[1]))
|
||||
+ return -1;
|
||||
+
|
||||
+ return param[2];
|
||||
+}
|
||||
+
|
||||
+static int alps_command_mode_read_reg(struct psmouse *psmouse, int addr)
|
||||
+{
|
||||
+ if (alps_command_mode_set_addr(psmouse, addr))
|
||||
+ return -1;
|
||||
+ return __alps_command_mode_read_reg(psmouse, addr);
|
||||
+}
|
||||
+
|
||||
+static int __alps_command_mode_write_reg(struct psmouse *psmouse, u8 value)
|
||||
+{
|
||||
+ if (alps_command_mode_send_nibble(psmouse, (value >> 4) & 0xf))
|
||||
+ return -1;
|
||||
+ if (alps_command_mode_send_nibble(psmouse, value & 0xf))
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int alps_command_mode_write_reg(struct psmouse *psmouse, int addr,
|
||||
+ u8 value)
|
||||
+{
|
||||
+ if (alps_command_mode_set_addr(psmouse, addr))
|
||||
+ return -1;
|
||||
+ return __alps_command_mode_write_reg(psmouse, value);
|
||||
+}
|
||||
+
|
||||
+static int alps_enter_command_mode(struct psmouse *psmouse,
|
||||
+ unsigned char *resp)
|
||||
+{
|
||||
+ unsigned char param[4];
|
||||
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
+
|
||||
+ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
|
||||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
|
||||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
|
||||
+ ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
|
||||
+ psmouse_err(psmouse, "failed to enter command mode\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (param[0] != 0x88 && param[1] != 0x07) {
|
||||
+ psmouse_dbg(psmouse,
|
||||
+ "unknown response while entering command mode: %2.2x %2.2x %2.2x\n",
|
||||
+ param[0], param[1], param[2]);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (resp)
|
||||
+ *resp = param[2];
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int alps_exit_command_mode(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
+ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM))
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
|
||||
{
|
||||
struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
|
||||
unsigned char param[4];
|
||||
+ const struct alps_model_info *model = NULL;
|
||||
int i;
|
||||
|
||||
/*
|
||||
@@ -428,12 +809,41 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
|
||||
*version = (param[0] << 8) | (param[1] << 4) | i;
|
||||
}
|
||||
|
||||
- for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
|
||||
+ for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
|
||||
if (!memcmp(param, alps_model_data[i].signature,
|
||||
- sizeof(alps_model_data[i].signature)))
|
||||
- return alps_model_data + i;
|
||||
+ sizeof(alps_model_data[i].signature))) {
|
||||
+ model = alps_model_data + i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- return NULL;
|
||||
+ if (model && model->proto_version > ALPS_PROTO_V2) {
|
||||
+ /*
|
||||
+ * Need to check command mode response to identify
|
||||
+ * model
|
||||
+ */
|
||||
+ model = NULL;
|
||||
+ if (alps_enter_command_mode(psmouse, param)) {
|
||||
+ psmouse_warn(psmouse,
|
||||
+ "touchpad failed to enter command mode\n");
|
||||
+ } else {
|
||||
+ for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
|
||||
+ if (alps_model_data[i].proto_version > ALPS_PROTO_V2 &&
|
||||
+ alps_model_data[i].command_mode_resp == param[0]) {
|
||||
+ model = alps_model_data + i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ alps_exit_command_mode(psmouse);
|
||||
+
|
||||
+ if (!model)
|
||||
+ psmouse_dbg(psmouse,
|
||||
+ "Unknown command mode response %2.2x\n",
|
||||
+ param[0]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return model;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -441,7 +851,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
|
||||
* subsequent commands. It looks like glidepad is behind stickpointer,
|
||||
* I'd thought it would be other way around...
|
||||
*/
|
||||
-static int alps_passthrough_mode(struct psmouse *psmouse, bool enable)
|
||||
+static int alps_passthrough_mode_v2(struct psmouse *psmouse, bool enable)
|
||||
{
|
||||
struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
|
||||
@@ -458,7 +868,7 @@ static int alps_passthrough_mode(struct psmouse *psmouse, bool enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int alps_absolute_mode(struct psmouse *psmouse)
|
||||
+static int alps_absolute_mode_v1_v2(struct psmouse *psmouse)
|
||||
{
|
||||
struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
|
||||
@@ -533,13 +943,13 @@ static int alps_poll(struct psmouse *psmouse)
|
||||
bool poll_failed;
|
||||
|
||||
if (priv->i->flags & ALPS_PASS)
|
||||
- alps_passthrough_mode(psmouse, true);
|
||||
+ alps_passthrough_mode_v2(psmouse, true);
|
||||
|
||||
poll_failed = ps2_command(&psmouse->ps2dev, buf,
|
||||
PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
|
||||
|
||||
if (priv->i->flags & ALPS_PASS)
|
||||
- alps_passthrough_mode(psmouse, false);
|
||||
+ alps_passthrough_mode_v2(psmouse, false);
|
||||
|
||||
if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
|
||||
return -1;
|
||||
@@ -556,13 +966,13 @@ static int alps_poll(struct psmouse *psmouse)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int alps_hw_init(struct psmouse *psmouse)
|
||||
+static int alps_hw_init_v1_v2(struct psmouse *psmouse)
|
||||
{
|
||||
struct alps_data *priv = psmouse->private;
|
||||
const struct alps_model_info *model = priv->i;
|
||||
|
||||
if ((model->flags & ALPS_PASS) &&
|
||||
- alps_passthrough_mode(psmouse, true)) {
|
||||
+ alps_passthrough_mode_v2(psmouse, true)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -571,13 +981,13 @@ static int alps_hw_init(struct psmouse *psmouse)
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (alps_absolute_mode(psmouse)) {
|
||||
+ if (alps_absolute_mode_v1_v2(psmouse)) {
|
||||
psmouse_err(psmouse, "Failed to enable absolute mode\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((model->flags & ALPS_PASS) &&
|
||||
- alps_passthrough_mode(psmouse, false)) {
|
||||
+ alps_passthrough_mode_v2(psmouse, false)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -590,6 +1000,297 @@ static int alps_hw_init(struct psmouse *psmouse)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Enable or disable passthrough mode to the trackstick. Must be in
|
||||
+ * command mode when calling this function.
|
||||
+ */
|
||||
+static int alps_passthrough_mode_v3(struct psmouse *psmouse, bool enable)
|
||||
+{
|
||||
+ int reg_val;
|
||||
+
|
||||
+ reg_val = alps_command_mode_read_reg(psmouse, 0x0008);
|
||||
+ if (reg_val == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (enable)
|
||||
+ reg_val |= 0x01;
|
||||
+ else
|
||||
+ reg_val &= ~0x01;
|
||||
+
|
||||
+ if (__alps_command_mode_write_reg(psmouse, reg_val))
|
||||
+ return -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Must be in command mode when calling this function */
|
||||
+static int alps_absolute_mode_v3(struct psmouse *psmouse)
|
||||
+{
|
||||
+ int reg_val;
|
||||
+
|
||||
+ reg_val = alps_command_mode_read_reg(psmouse, 0x0004);
|
||||
+ if (reg_val == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ reg_val |= 0x06;
|
||||
+ if (__alps_command_mode_write_reg(psmouse, reg_val))
|
||||
+ return -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int alps_hw_init_v3(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct alps_data *priv = psmouse->private;
|
||||
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
+ int reg_val;
|
||||
+ unsigned char param[4];
|
||||
+
|
||||
+ priv->nibble_commands = alps_v3_nibble_commands;
|
||||
+ priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
|
||||
+
|
||||
+ if (alps_enter_command_mode(psmouse, NULL))
|
||||
+ goto error;
|
||||
+
|
||||
+ /* Check for trackstick */
|
||||
+ reg_val = alps_command_mode_read_reg(psmouse, 0x0008);
|
||||
+ if (reg_val == -1)
|
||||
+ goto error;
|
||||
+ if (reg_val & 0x80) {
|
||||
+ if (alps_passthrough_mode_v3(psmouse, true))
|
||||
+ goto error;
|
||||
+ if (alps_exit_command_mode(psmouse))
|
||||
+ goto error;
|
||||
+
|
||||
+ /*
|
||||
+ * E7 report for the trackstick
|
||||
+ *
|
||||
+ * There have been reports of failures to seem to trace back
|
||||
+ * to the above trackstick check failing. When these occur
|
||||
+ * this E7 report fails, so when that happens we continue
|
||||
+ * with the assumption that there isn't a trackstick after
|
||||
+ * all.
|
||||
+ */
|
||||
+ param[0] = 0x64;
|
||||
+ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
|
||||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
|
||||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
|
||||
+ ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
|
||||
+ psmouse_warn(psmouse, "trackstick E7 report failed\n");
|
||||
+ } else {
|
||||
+ psmouse_dbg(psmouse,
|
||||
+ "trackstick E7 report: %2.2x %2.2x %2.2x\n",
|
||||
+ param[0], param[1], param[2]);
|
||||
+
|
||||
+ /*
|
||||
+ * Not sure what this does, but it is absolutely
|
||||
+ * essential. Without it, the touchpad does not
|
||||
+ * work at all and the trackstick just emits normal
|
||||
+ * PS/2 packets.
|
||||
+ */
|
||||
+ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
|
||||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
|
||||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
|
||||
+ alps_command_mode_send_nibble(psmouse, 0x9) ||
|
||||
+ alps_command_mode_send_nibble(psmouse, 0x4)) {
|
||||
+ psmouse_err(psmouse,
|
||||
+ "Error sending magic E6 sequence\n");
|
||||
+ goto error_passthrough;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (alps_enter_command_mode(psmouse, NULL))
|
||||
+ goto error_passthrough;
|
||||
+ if (alps_passthrough_mode_v3(psmouse, false))
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (alps_absolute_mode_v3(psmouse)) {
|
||||
+ psmouse_err(psmouse, "Failed to enter absolute mode\n");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ reg_val = alps_command_mode_read_reg(psmouse, 0x0006);
|
||||
+ if (reg_val == -1)
|
||||
+ goto error;
|
||||
+ if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01))
|
||||
+ goto error;
|
||||
+
|
||||
+ reg_val = alps_command_mode_read_reg(psmouse, 0x0007);
|
||||
+ if (reg_val == -1)
|
||||
+ goto error;
|
||||
+ if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_read_reg(psmouse, 0x0144) == -1)
|
||||
+ goto error;
|
||||
+ if (__alps_command_mode_write_reg(psmouse, 0x04))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_read_reg(psmouse, 0x0159) == -1)
|
||||
+ goto error;
|
||||
+ if (__alps_command_mode_write_reg(psmouse, 0x03))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_read_reg(psmouse, 0x0163) == -1)
|
||||
+ goto error;
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x0163, 0x03))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_read_reg(psmouse, 0x0162) == -1)
|
||||
+ goto error;
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x0162, 0x04))
|
||||
+ goto error;
|
||||
+
|
||||
+ /*
|
||||
+ * This ensures the trackstick packets are in the format
|
||||
+ * supported by this driver. If bit 1 isn't set the packet
|
||||
+ * format is different.
|
||||
+ */
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x0008, 0x82))
|
||||
+ goto error;
|
||||
+
|
||||
+ alps_exit_command_mode(psmouse);
|
||||
+
|
||||
+ /* Set rate and enable data reporting */
|
||||
+ param[0] = 0x64;
|
||||
+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) ||
|
||||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
|
||||
+ psmouse_err(psmouse, "Failed to enable data reporting\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+error_passthrough:
|
||||
+ /* Something failed while in passthrough mode, so try to get out */
|
||||
+ if (!alps_enter_command_mode(psmouse, NULL))
|
||||
+ alps_passthrough_mode_v3(psmouse, false);
|
||||
+error:
|
||||
+ /*
|
||||
+ * Leaving the touchpad in command mode will essentially render
|
||||
+ * it unusable until the machine reboots, so exit it here just
|
||||
+ * to be safe
|
||||
+ */
|
||||
+ alps_exit_command_mode(psmouse);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+/* Must be in command mode when calling this function */
|
||||
+static int alps_absolute_mode_v4(struct psmouse *psmouse)
|
||||
+{
|
||||
+ int reg_val;
|
||||
+
|
||||
+ reg_val = alps_command_mode_read_reg(psmouse, 0x0004);
|
||||
+ if (reg_val == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ reg_val |= 0x02;
|
||||
+ if (__alps_command_mode_write_reg(psmouse, reg_val))
|
||||
+ return -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int alps_hw_init_v4(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct alps_data *priv = psmouse->private;
|
||||
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
+ unsigned char param[4];
|
||||
+
|
||||
+ priv->nibble_commands = alps_v4_nibble_commands;
|
||||
+ priv->addr_command = PSMOUSE_CMD_DISABLE;
|
||||
+
|
||||
+ if (alps_enter_command_mode(psmouse, NULL))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_absolute_mode_v4(psmouse)) {
|
||||
+ psmouse_err(psmouse, "Failed to enter absolute mode\n");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x0007, 0x8c))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x0149, 0x03))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x0160, 0x03))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x017f, 0x15))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x0151, 0x01))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x0168, 0x03))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x014a, 0x03))
|
||||
+ goto error;
|
||||
+
|
||||
+ if (alps_command_mode_write_reg(psmouse, 0x0161, 0x03))
|
||||
+ goto error;
|
||||
+
|
||||
+ alps_exit_command_mode(psmouse);
|
||||
+
|
||||
+ /*
|
||||
+ * This sequence changes the output from a 9-byte to an
|
||||
+ * 8-byte format. All the same data seems to be present,
|
||||
+ * just in a more compact format.
|
||||
+ */
|
||||
+ param[0] = 0xc8;
|
||||
+ param[1] = 0x64;
|
||||
+ param[2] = 0x50;
|
||||
+ if (ps2_command(ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE) ||
|
||||
+ ps2_command(ps2dev, ¶m[1], PSMOUSE_CMD_SETRATE) ||
|
||||
+ ps2_command(ps2dev, ¶m[2], PSMOUSE_CMD_SETRATE) ||
|
||||
+ ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
|
||||
+ return -1;
|
||||
+
|
||||
+ /* Set rate and enable data reporting */
|
||||
+ param[0] = 0x64;
|
||||
+ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) ||
|
||||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
|
||||
+ psmouse_err(psmouse, "Failed to enable data reporting\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+error:
|
||||
+ /*
|
||||
+ * Leaving the touchpad in command mode will essentially render
|
||||
+ * it unusable until the machine reboots, so exit it here just
|
||||
+ * to be safe
|
||||
+ */
|
||||
+ alps_exit_command_mode(psmouse);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static int alps_hw_init(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct alps_data *priv = psmouse->private;
|
||||
+ const struct alps_model_info *model = priv->i;
|
||||
+ int ret = -1;
|
||||
+
|
||||
+ switch (model->proto_version) {
|
||||
+ case ALPS_PROTO_V1:
|
||||
+ case ALPS_PROTO_V2:
|
||||
+ ret = alps_hw_init_v1_v2(psmouse);
|
||||
+ break;
|
||||
+ case ALPS_PROTO_V3:
|
||||
+ ret = alps_hw_init_v3(psmouse);
|
||||
+ break;
|
||||
+ case ALPS_PROTO_V4:
|
||||
+ ret = alps_hw_init_v4(psmouse);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int alps_reconnect(struct psmouse *psmouse)
|
||||
{
|
||||
const struct alps_model_info *model;
|
||||
@@ -630,6 +1331,8 @@ int alps_init(struct psmouse *psmouse)
|
||||
|
||||
psmouse->private = priv;
|
||||
|
||||
+ psmouse_reset(psmouse);
|
||||
+
|
||||
model = alps_get_model(psmouse, &version);
|
||||
if (!model)
|
||||
goto init_fail;
|
||||
@@ -657,8 +1360,20 @@ int alps_init(struct psmouse *psmouse)
|
||||
BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
|
||||
|
||||
dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
|
||||
- input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
|
||||
- input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
|
||||
+
|
||||
+ switch (model->proto_version) {
|
||||
+ case ALPS_PROTO_V1:
|
||||
+ case ALPS_PROTO_V2:
|
||||
+ input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
|
||||
+ input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
|
||||
+ break;
|
||||
+ case ALPS_PROTO_V3:
|
||||
+ case ALPS_PROTO_V4:
|
||||
+ input_set_abs_params(dev1, ABS_X, 0, 2000, 0, 0);
|
||||
+ input_set_abs_params(dev1, ABS_Y, 0, 1400, 0, 0);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
|
||||
|
||||
if (model->flags & ALPS_WHEEL) {
|
||||
@@ -701,7 +1416,7 @@ int alps_init(struct psmouse *psmouse)
|
||||
psmouse->poll = alps_poll;
|
||||
psmouse->disconnect = alps_disconnect;
|
||||
psmouse->reconnect = alps_reconnect;
|
||||
- psmouse->pktsize = 6;
|
||||
+ psmouse->pktsize = model->proto_version == ALPS_PROTO_V4 ? 8 : 6;
|
||||
|
||||
/* We are having trouble resyncing ALPS touchpads so disable it for now */
|
||||
psmouse->resync_time = 0;
|
||||
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
|
||||
index 4ce9bba..62db7f4 100644
|
||||
--- a/drivers/input/mouse/alps.h
|
||||
+++ b/drivers/input/mouse/alps.h
|
||||
@@ -14,22 +14,36 @@
|
||||
|
||||
#define ALPS_PROTO_V1 0
|
||||
#define ALPS_PROTO_V2 1
|
||||
+#define ALPS_PROTO_V3 2
|
||||
+#define ALPS_PROTO_V4 3
|
||||
|
||||
struct alps_model_info {
|
||||
unsigned char signature[3];
|
||||
+ unsigned char command_mode_resp; /* v3/v4 only */
|
||||
unsigned char proto_version;
|
||||
unsigned char byte0, mask0;
|
||||
unsigned char flags;
|
||||
};
|
||||
|
||||
+struct alps_nibble_commands {
|
||||
+ int command;
|
||||
+ unsigned char data;
|
||||
+};
|
||||
+
|
||||
struct alps_data {
|
||||
struct input_dev *dev2; /* Relative device */
|
||||
char phys[32]; /* Phys */
|
||||
const struct alps_model_info *i;/* Info */
|
||||
+ const struct alps_nibble_commands *nibble_commands;
|
||||
+ int addr_command; /* Command to set register address */
|
||||
int prev_fin; /* Finger bit from previous packet */
|
||||
+ int multi_packet; /* Multi-packet data in progress */
|
||||
+ u8 quirks;
|
||||
struct timer_list timer;
|
||||
};
|
||||
|
||||
+#define ALPS_QUIRK_TRACKSTICK_BUTTONS 1 /* trakcstick buttons in trackstick packet */
|
||||
+
|
||||
#ifdef CONFIG_MOUSE_PS2_ALPS
|
||||
int alps_detect(struct psmouse *psmouse, bool set_properties);
|
||||
int alps_init(struct psmouse *psmouse);
|
||||
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
|
||||
index 9b84b0c..11a9c6c 100644
|
||||
--- a/drivers/input/mouse/psmouse.h
|
||||
+++ b/drivers/input/mouse/psmouse.h
|
||||
@@ -8,6 +8,7 @@
|
||||
#define PSMOUSE_CMD_SETSTREAM 0x00ea
|
||||
#define PSMOUSE_CMD_SETPOLL 0x00f0
|
||||
#define PSMOUSE_CMD_POLL 0x00eb /* caller sets number of bytes to receive */
|
||||
+#define PSMOUSE_CMD_RESET_WRAP 0x00ec
|
||||
#define PSMOUSE_CMD_GETID 0x02f2
|
||||
#define PSMOUSE_CMD_SETRATE 0x10f3
|
||||
#define PSMOUSE_CMD_ENABLE 0x00f4
|
||||
--
|
||||
1.7.8.2
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
From: Seth Forshee <seth.forshee@canonical.com>
|
||||
Date: Mon, 7 Nov 2011 19:53:15 -0800
|
||||
Subject: [PATCH 1/5] Input: ALPS - move protocol information to Documentation
|
||||
|
||||
commit d4b347b29b4d14647c7394f7167bf6785dc98e50 upstream.
|
||||
|
||||
In preparation for new protocol support, move the protocol
|
||||
information currently documented in alps.c to
|
||||
Documentation/input/alps.txt, where it can be expanded without
|
||||
cluttering up the driver.
|
||||
|
||||
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
|
||||
Acked-by: Chase Douglas <chase.douglas@canonical.com>
|
||||
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
|
||||
|
||||
diff --git a/Documentation/input/alps.txt b/Documentation/input/alps.txt
|
||||
new file mode 100644
|
||||
index 0000000..ab5478f
|
||||
--- /dev/null
|
||||
+++ b/Documentation/input/alps.txt
|
||||
@@ -0,0 +1,75 @@
|
||||
+ALPS Touchpad Protocol
|
||||
+----------------------
|
||||
+
|
||||
+Introduction
|
||||
+------------
|
||||
+
|
||||
+Currently the ALPS touchpad driver supports two protocol versions in use by
|
||||
+ALPS touchpads, the "old" and "new" protocol versions. Fundamentally these
|
||||
+differ only in the format of their event packets (in reality many features may
|
||||
+be found on new protocol devices that aren't found on the old protocol
|
||||
+devices, but these are handled transparently as feature differences rather
|
||||
+than protocol differences).
|
||||
+
|
||||
+Detection
|
||||
+---------
|
||||
+
|
||||
+All ALPS touchpads should respond to the "E6 report" command sequence:
|
||||
+E8-E6-E6-E6-E9. An ALPS touchpad should respond with either 00-00-0A or
|
||||
+00-00-64.
|
||||
+
|
||||
+If the E6 report is successful, the touchpad model is identified using the "E7
|
||||
+report" sequence: E8-E7-E7-E7-E9. The response is the model signature and is
|
||||
+matched against known models in the alps_model_data_array.
|
||||
+
|
||||
+Packet Format
|
||||
+-------------
|
||||
+
|
||||
+In the following tables, the following notation us used.
|
||||
+
|
||||
+ CAPITALS = stick, miniscules = touchpad
|
||||
+
|
||||
+?'s can have different meanings on different models, such as wheel rotation,
|
||||
+extra buttons, stick buttons on a dualpoint, etc.
|
||||
+
|
||||
+PS/2 packet format
|
||||
+------------------
|
||||
+
|
||||
+ byte 0: 0 0 YSGN XSGN 1 M R L
|
||||
+ byte 1: X7 X6 X5 X4 X3 X2 X1 X0
|
||||
+ byte 2: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
|
||||
+
|
||||
+Note that the device never signals overflow condition.
|
||||
+
|
||||
+ALPS Absolute Mode - Old Format
|
||||
+-------------------------------
|
||||
+
|
||||
+ byte 0: 1 0 0 0 1 x9 x8 x7
|
||||
+ byte 1: 0 x6 x5 x4 x3 x2 x1 x0
|
||||
+ byte 2: 0 ? ? l r ? fin ges
|
||||
+ byte 3: 0 ? ? ? ? y9 y8 y7
|
||||
+ byte 4: 0 y6 y5 y4 y3 y2 y1 y0
|
||||
+ byte 5: 0 z6 z5 z4 z3 z2 z1 z0
|
||||
+
|
||||
+ALPS Absolute Mode - New Format
|
||||
+-------------------------------
|
||||
+
|
||||
+ byte 0: 1 ? ? ? 1 ? ? ?
|
||||
+ byte 1: 0 x6 x5 x4 x3 x2 x1 x0
|
||||
+ byte 2: 0 x10 x9 x8 x7 ? fin ges
|
||||
+ byte 3: 0 y9 y8 y7 1 M R L
|
||||
+ byte 4: 0 y6 y5 y4 y3 y2 y1 y0
|
||||
+ byte 5: 0 z6 z5 z4 z3 z2 z1 z0
|
||||
+
|
||||
+Dualpoint device -- interleaved packet format
|
||||
+---------------------------------------------
|
||||
+
|
||||
+ byte 0: 1 1 0 0 1 1 1 1
|
||||
+ byte 1: 0 x6 x5 x4 x3 x2 x1 x0
|
||||
+ byte 2: 0 x10 x9 x8 x7 0 fin ges
|
||||
+ byte 3: 0 0 YSGN XSGN 1 1 1 1
|
||||
+ byte 4: X7 X6 X5 X4 X3 X2 X1 X0
|
||||
+ byte 5: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
|
||||
+ byte 6: 0 y9 y8 y7 1 m r l
|
||||
+ byte 7: 0 y6 y5 y4 y3 y2 y1 y0
|
||||
+ byte 8: 0 z6 z5 z4 z3 z2 z1 z0
|
||||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
|
||||
index 003587c..19d0943 100644
|
||||
--- a/drivers/input/mouse/alps.c
|
||||
+++ b/drivers/input/mouse/alps.c
|
||||
@@ -67,42 +67,7 @@ static const struct alps_model_info alps_model_data[] = {
|
||||
* isn't valid per PS/2 spec.
|
||||
*/
|
||||
|
||||
-/*
|
||||
- * PS/2 packet format
|
||||
- *
|
||||
- * byte 0: 0 0 YSGN XSGN 1 M R L
|
||||
- * byte 1: X7 X6 X5 X4 X3 X2 X1 X0
|
||||
- * byte 2: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
|
||||
- *
|
||||
- * Note that the device never signals overflow condition.
|
||||
- *
|
||||
- * ALPS absolute Mode - new format
|
||||
- *
|
||||
- * byte 0: 1 ? ? ? 1 ? ? ?
|
||||
- * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
|
||||
- * byte 2: 0 x10 x9 x8 x7 ? fin ges
|
||||
- * byte 3: 0 y9 y8 y7 1 M R L
|
||||
- * byte 4: 0 y6 y5 y4 y3 y2 y1 y0
|
||||
- * byte 5: 0 z6 z5 z4 z3 z2 z1 z0
|
||||
- *
|
||||
- * Dualpoint device -- interleaved packet format
|
||||
- *
|
||||
- * byte 0: 1 1 0 0 1 1 1 1
|
||||
- * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
|
||||
- * byte 2: 0 x10 x9 x8 x7 0 fin ges
|
||||
- * byte 3: 0 0 YSGN XSGN 1 1 1 1
|
||||
- * byte 4: X7 X6 X5 X4 X3 X2 X1 X0
|
||||
- * byte 5: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
|
||||
- * byte 6: 0 y9 y8 y7 1 m r l
|
||||
- * byte 7: 0 y6 y5 y4 y3 y2 y1 y0
|
||||
- * byte 8: 0 z6 z5 z4 z3 z2 z1 z0
|
||||
- *
|
||||
- * CAPITALS = stick, miniscules = touchpad
|
||||
- *
|
||||
- * ?'s can have different meanings on different models,
|
||||
- * such as wheel rotation, extra buttons, stick buttons
|
||||
- * on a dualpoint, etc.
|
||||
- */
|
||||
+/* Packet formats are described in Documentation/input/alps.txt */
|
||||
|
||||
static bool alps_is_valid_first_byte(const struct alps_model_info *model,
|
||||
unsigned char data)
|
||||
--
|
||||
1.7.8.2
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
From: Seth Forshee <seth.forshee@canonical.com>
|
||||
Date: Mon, 7 Nov 2011 19:53:30 -0800
|
||||
Subject: [PATCH 3/5] Input: ALPS - remove assumptions about packet size
|
||||
|
||||
commit b46615fe9215214ac00e26d35fc54dbe1c510803 upstream.
|
||||
|
||||
In preparation for version 4 protocol support, which has 8-byte
|
||||
data packets, remove all hard-coded assumptions about packet size
|
||||
and use psmouse->pktsize instead.
|
||||
|
||||
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
|
||||
Acked-by: Chase Douglas <chase.douglas@canonical.com>
|
||||
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
|
||||
|
||||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
|
||||
index 77b776d..44a0a71 100644
|
||||
--- a/drivers/input/mouse/alps.c
|
||||
+++ b/drivers/input/mouse/alps.c
|
||||
@@ -308,7 +308,7 @@ static void alps_flush_packet(unsigned long data)
|
||||
|
||||
serio_pause_rx(psmouse->ps2dev.serio);
|
||||
|
||||
- if (psmouse->pktcnt == 6) {
|
||||
+ if (psmouse->pktcnt == psmouse->pktsize) {
|
||||
|
||||
/*
|
||||
* We did not any more data in reasonable amount of time.
|
||||
@@ -359,8 +359,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
|
||||
return PSMOUSE_BAD_DATA;
|
||||
}
|
||||
|
||||
- /* Bytes 2 - 6 should have 0 in the highest bit */
|
||||
- if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 &&
|
||||
+ /* Bytes 2 - pktsize should have 0 in the highest bit */
|
||||
+ if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
|
||||
(psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
|
||||
psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
|
||||
psmouse->pktcnt - 1,
|
||||
@@ -368,7 +368,7 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
|
||||
return PSMOUSE_BAD_DATA;
|
||||
}
|
||||
|
||||
- if (psmouse->pktcnt == 6) {
|
||||
+ if (psmouse->pktcnt == psmouse->pktsize) {
|
||||
alps_process_packet(psmouse);
|
||||
return PSMOUSE_FULL_PACKET;
|
||||
}
|
||||
@@ -529,7 +529,7 @@ static int alps_tap_mode(struct psmouse *psmouse, int enable)
|
||||
static int alps_poll(struct psmouse *psmouse)
|
||||
{
|
||||
struct alps_data *priv = psmouse->private;
|
||||
- unsigned char buf[6];
|
||||
+ unsigned char buf[sizeof(psmouse->packet)];
|
||||
bool poll_failed;
|
||||
|
||||
if (priv->i->flags & ALPS_PASS)
|
||||
--
|
||||
1.7.8.2
|
||||
|
|
@ -1759,8 +1759,8 @@
|
|||
+
|
||||
+-include ${srctree}/${src}/conf_priv.mk
|
||||
--- a/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/fs/aufs/cpup.c 2012-01-10 02:15:56.545455955 +0000
|
||||
@@ -0,0 +1,1079 @@
|
||||
+++ b/fs/aufs/cpup.c 2012-02-19 21:12:26.542426948 +0000
|
||||
@@ -0,0 +1,1084 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
+ *
|
||||
|
@ -1821,7 +1821,12 @@
|
|||
+ && au_plink_test(inode))
|
||||
+ return;
|
||||
+
|
||||
+ set_nlink(inode, h_inode->i_nlink);
|
||||
+ /*
|
||||
+ * 0 can happen in revalidating.
|
||||
+ * h_inode->i_mutex is not held, but it is harmless since once i_nlink
|
||||
+ * reaches 0, it will never become positive.
|
||||
+ */
|
||||
+ vfsub_set_nlink(inode, h_inode->i_nlink);
|
||||
+
|
||||
+ /*
|
||||
+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
|
||||
|
@ -6324,8 +6329,8 @@
|
|||
+ return -1;
|
||||
+}
|
||||
--- a/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/fs/aufs/dir.c 2012-01-10 02:15:56.549455982 +0000
|
||||
@@ -0,0 +1,634 @@
|
||||
+++ b/fs/aufs/dir.c 2012-02-19 21:12:26.566427085 +0000
|
||||
@@ -0,0 +1,636 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
+ *
|
||||
|
@ -6361,7 +6366,8 @@
|
|||
+ nlink += h_dir->i_nlink - 2;
|
||||
+ if (h_dir->i_nlink < 2)
|
||||
+ nlink += 2;
|
||||
+ set_nlink(dir, nlink);
|
||||
+ /* 0 can happen in revaliding */
|
||||
+ vfsub_set_nlink(dir, nlink);
|
||||
+}
|
||||
+
|
||||
+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
|
||||
|
@ -6374,6 +6380,7 @@
|
|||
+ nlink -= h_dir->i_nlink - 2;
|
||||
+ if (h_dir->i_nlink < 2)
|
||||
+ nlink -= 2;
|
||||
+ /* no vfsub version. nlink == 0 means the branch-fs is broken */
|
||||
+ set_nlink(dir, nlink);
|
||||
+}
|
||||
+
|
||||
|
@ -7560,8 +7567,8 @@
|
|||
+#endif /* __KERNEL__ */
|
||||
+#endif /* __AUFS_DYNOP_H__ */
|
||||
--- a/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/fs/aufs/export.c 2012-01-10 02:15:56.549455982 +0000
|
||||
@@ -0,0 +1,804 @@
|
||||
+++ b/fs/aufs/export.c 2012-02-19 21:12:26.566427085 +0000
|
||||
@@ -0,0 +1,803 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
+ *
|
||||
|
@ -7585,11 +7592,12 @@
|
|||
+ */
|
||||
+
|
||||
+#include <linux/exportfs.h>
|
||||
+#include <linux/mnt_namespace.h>
|
||||
+#include <linux/fs_struct.h>
|
||||
+#include <linux/namei.h>
|
||||
+#include <linux/nsproxy.h>
|
||||
+#include <linux/random.h>
|
||||
+#include <linux/writeback.h>
|
||||
+#include "../fs/mount.h"
|
||||
+#include "aufs.h"
|
||||
+
|
||||
+union conv {
|
||||
|
@ -7843,18 +7851,16 @@
|
|||
+static struct vfsmount *au_mnt_get(struct super_block *sb)
|
||||
+{
|
||||
+ int err;
|
||||
+ struct path root;
|
||||
+ struct au_compare_mnt_args args = {
|
||||
+ .sb = sb
|
||||
+ };
|
||||
+ struct mnt_namespace *ns;
|
||||
+
|
||||
+ get_fs_root(current->fs, &root);
|
||||
+ br_read_lock(vfsmount_lock);
|
||||
+ /* no get/put ?? */
|
||||
+ AuDebugOn(!current->nsproxy);
|
||||
+ ns = current->nsproxy->mnt_ns;
|
||||
+ AuDebugOn(!ns);
|
||||
+ err = iterate_mounts(au_compare_mnt, &args, ns->root);
|
||||
+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
|
||||
+ br_read_unlock(vfsmount_lock);
|
||||
+ path_put(&root);
|
||||
+ AuDebugOn(!err);
|
||||
+ AuDebugOn(!args.mnt);
|
||||
+ return args.mnt;
|
||||
|
@ -9400,8 +9406,8 @@
|
|||
+ return ret;
|
||||
+}
|
||||
--- a/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/fs/aufs/file.c 2012-01-10 02:15:56.549455982 +0000
|
||||
@@ -0,0 +1,673 @@
|
||||
+++ b/fs/aufs/file.c 2012-02-19 21:12:26.570427095 +0000
|
||||
@@ -0,0 +1,676 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
+ *
|
||||
|
@ -9424,6 +9430,9 @@
|
|||
+ * handling file/dir, and address_space operation
|
||||
+ */
|
||||
+
|
||||
+#ifdef CONFIG_AUFS_DEBUG
|
||||
+#include <linux/migrate.h>
|
||||
+#endif
|
||||
+#include <linux/pagemap.h>
|
||||
+#include "aufs.h"
|
||||
+
|
||||
|
@ -10042,7 +10051,7 @@
|
|||
+static int aufs_releasepage(struct page *page, gfp_t gfp)
|
||||
+{ AuUnsupport(); return 0; }
|
||||
+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
|
||||
+ struct page *page)
|
||||
+ struct page *page, enum migrate_mode mode)
|
||||
+{ AuUnsupport(); return 0; }
|
||||
+static int aufs_launder_page(struct page *page)
|
||||
+{ AuUnsupport(); return 0; }
|
||||
|
@ -12060,7 +12069,7 @@
|
|||
+ au_hn_destroy_cache();
|
||||
+}
|
||||
--- a/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/fs/aufs/i_op.c 2012-01-10 02:15:56.553455997 +0000
|
||||
+++ b/fs/aufs/i_op.c 2012-02-19 21:12:26.570427095 +0000
|
||||
@@ -0,0 +1,992 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
|
@ -12761,8 +12770,7 @@
|
|||
+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
|
||||
+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
|
||||
+ == (ATTR_MODE | ATTR_CTIME)) {
|
||||
+ err = security_path_chmod(a->h_path.dentry, a->h_path.mnt,
|
||||
+ ia->ia_mode);
|
||||
+ err = security_path_chmod(&a->h_path, ia->ia_mode);
|
||||
+ if (unlikely(err))
|
||||
+ goto out_unlock;
|
||||
+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
|
||||
|
@ -12828,7 +12836,8 @@
|
|||
+ n = inode->i_nlink;
|
||||
+ n -= nlink;
|
||||
+ n += st->nlink;
|
||||
+ set_nlink(inode, n);
|
||||
+ /* 0 can happen */
|
||||
+ vfsub_set_nlink(inode, n);
|
||||
+ }
|
||||
+
|
||||
+ spin_lock(&inode->i_lock);
|
||||
|
@ -13055,7 +13064,7 @@
|
|||
+ .truncate_range = aufs_truncate_range
|
||||
+};
|
||||
--- a/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/fs/aufs/i_op_add.c 2012-01-10 02:15:56.553455997 +0000
|
||||
+++ b/fs/aufs/i_op_add.c 2012-02-19 21:12:26.570427095 +0000
|
||||
@@ -0,0 +1,711 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
|
@ -13274,14 +13283,14 @@
|
|||
+ int type;
|
||||
+ union {
|
||||
+ struct {
|
||||
+ int mode;
|
||||
+ umode_t mode;
|
||||
+ struct nameidata *nd;
|
||||
+ } c;
|
||||
+ struct {
|
||||
+ const char *symname;
|
||||
+ } s;
|
||||
+ struct {
|
||||
+ int mode;
|
||||
+ umode_t mode;
|
||||
+ dev_t dev;
|
||||
+ } m;
|
||||
+ } u;
|
||||
|
@ -13368,7 +13377,7 @@
|
|||
+ return err;
|
||||
+}
|
||||
+
|
||||
+int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
|
||||
+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
|
||||
+{
|
||||
+ struct simple_arg arg = {
|
||||
+ .type = Mknod,
|
||||
|
@ -13389,7 +13398,7 @@
|
|||
+ return add_simple(dir, dentry, &arg);
|
||||
+}
|
||||
+
|
||||
+int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
|
||||
+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
+ struct nameidata *nd)
|
||||
+{
|
||||
+ struct simple_arg arg = {
|
||||
|
@ -13661,7 +13670,7 @@
|
|||
+ return err;
|
||||
+}
|
||||
+
|
||||
+int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
+{
|
||||
+ int err, rerr;
|
||||
+ aufs_bindex_t bindex;
|
||||
|
@ -16011,7 +16020,7 @@
|
|||
+ return au_test_h_perm(h_inode, mask);
|
||||
+}
|
||||
--- a/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/fs/aufs/inode.h 2012-01-10 02:15:56.557456016 +0000
|
||||
+++ b/fs/aufs/inode.h 2012-02-19 21:12:26.570427095 +0000
|
||||
@@ -0,0 +1,554 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
|
@ -16173,13 +16182,13 @@
|
|||
+/* i_op_add.c */
|
||||
+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
|
||||
+ struct dentry *h_parent, int isdir);
|
||||
+int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
|
||||
+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev);
|
||||
+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
|
||||
+int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
|
||||
+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
+ struct nameidata *nd);
|
||||
+int aufs_link(struct dentry *src_dentry, struct inode *dir,
|
||||
+ struct dentry *dentry);
|
||||
+int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
|
||||
+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
|
||||
+
|
||||
+/* i_op_del.c */
|
||||
+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
|
||||
|
@ -20951,8 +20960,8 @@
|
|||
+#endif /* __KERNEL__ */
|
||||
+#endif /* __AUFS_SPL_H__ */
|
||||
--- a/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/fs/aufs/super.c 2012-01-10 02:15:56.569456073 +0000
|
||||
@@ -0,0 +1,938 @@
|
||||
+++ b/fs/aufs/super.c 2012-02-19 21:12:26.570427095 +0000
|
||||
@@ -0,0 +1,936 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
+ *
|
||||
|
@ -21118,7 +21127,7 @@
|
|||
+ }
|
||||
+}
|
||||
+
|
||||
+static int au_show_xino(struct seq_file *seq, struct vfsmount *mnt)
|
||||
+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
|
||||
+{
|
||||
+#ifdef CONFIG_SYSFS
|
||||
+ return 0;
|
||||
|
@ -21126,7 +21135,6 @@
|
|||
+ int err;
|
||||
+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
|
||||
+ aufs_bindex_t bindex, brid;
|
||||
+ struct super_block *sb;
|
||||
+ struct qstr *name;
|
||||
+ struct file *f;
|
||||
+ struct dentry *d, *h_root;
|
||||
|
@ -21135,7 +21143,6 @@
|
|||
+ AuRwMustAnyLock(&sbinfo->si_rwsem);
|
||||
+
|
||||
+ err = 0;
|
||||
+ sb = mnt->mnt_sb;
|
||||
+ f = au_sbi(sb)->si_xib;
|
||||
+ if (!f)
|
||||
+ goto out;
|
||||
|
@ -21165,7 +21172,7 @@
|
|||
+}
|
||||
+
|
||||
+/* seq_file will re-call me in case of too long string */
|
||||
+static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt)
|
||||
+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
|
||||
+{
|
||||
+ int err;
|
||||
+ unsigned int mnt_flags, v;
|
||||
|
@ -21190,14 +21197,14 @@
|
|||
+} while (0)
|
||||
+
|
||||
+ /* lock free root dinfo */
|
||||
+ sb = mnt->mnt_sb;
|
||||
+ sb = dentry->d_sb;
|
||||
+ si_noflush_read_lock(sb);
|
||||
+ sbinfo = au_sbi(sb);
|
||||
+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
|
||||
+
|
||||
+ mnt_flags = au_mntflags(sb);
|
||||
+ if (au_opt_test(mnt_flags, XINO)) {
|
||||
+ err = au_show_xino(m, mnt);
|
||||
+ err = au_show_xino(m, sb);
|
||||
+ if (unlikely(err))
|
||||
+ goto out;
|
||||
+ } else
|
||||
|
@ -24793,8 +24800,8 @@
|
|||
+ return err;
|
||||
+}
|
||||
--- a/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/fs/aufs/vfsub.h 2012-01-10 02:15:56.569456073 +0000
|
||||
@@ -0,0 +1,232 @@
|
||||
+++ b/fs/aufs/vfsub.h 2012-02-19 21:12:26.574427108 +0000
|
||||
@@ -0,0 +1,240 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
+ *
|
||||
|
@ -24897,6 +24904,14 @@
|
|||
+ clear_nlink(inode);
|
||||
+}
|
||||
+
|
||||
+static inline void vfsub_set_nlink(struct inode *inode, unsigned int nlink)
|
||||
+{
|
||||
+ if (nlink)
|
||||
+ set_nlink(inode, nlink);
|
||||
+ else
|
||||
+ clear_nlink(inode);
|
||||
+}
|
||||
+
|
||||
+/* ---------------------------------------------------------------------- */
|
||||
+
|
||||
+int vfsub_update_h_iattr(struct path *h_path, int *did);
|
||||
|
@ -28453,7 +28468,7 @@
|
|||
+ return err;
|
||||
+}
|
||||
--- a/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/include/linux/aufs_type.h 2012-01-10 02:15:56.573456100 +0000
|
||||
+++ b/include/linux/aufs_type.h 2012-02-19 21:12:26.574427108 +0000
|
||||
@@ -0,0 +1,233 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2005-2012 Junjiro R. Okajima
|
||||
|
@ -28496,7 +28511,7 @@
|
|||
+
|
||||
+#include <linux/limits.h>
|
||||
+
|
||||
+#define AUFS_VERSION "3.2-20120109"
|
||||
+#define AUFS_VERSION "3.x-rcN-20120123"
|
||||
+
|
||||
+/* todo? move this to linux-2.6.19/include/magic.h */
|
||||
+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
aufs3.2 base patch
|
||||
aufs3.x-rcN base patch
|
||||
|
||||
diff --git a/fs/namei.c b/fs/namei.c
|
||||
index 5008f01..4cc94cf 100644
|
||||
index c283a1e..586eccd 100644
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -1753,7 +1753,7 @@ static struct dentry *__lookup_hash(struct qstr *name,
|
||||
@@ -1756,7 +1756,7 @@ static struct dentry *__lookup_hash(struct qstr *name,
|
||||
* needs parent already locked. Doesn't follow mounts.
|
||||
* SMP-safe.
|
||||
*/
|
||||
|
@ -14,10 +14,10 @@ index 5008f01..4cc94cf 100644
|
|||
return __lookup_hash(&nd->last, nd->path.dentry, nd);
|
||||
}
|
||||
diff --git a/fs/splice.c b/fs/splice.c
|
||||
index fa2defa..e3569b0 100644
|
||||
index 1ec0493..c599f73 100644
|
||||
--- a/fs/splice.c
|
||||
+++ b/fs/splice.c
|
||||
@@ -1085,8 +1085,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
|
||||
@@ -1084,8 +1084,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
|
||||
/*
|
||||
* Attempt to initiate a splice from pipe to file.
|
||||
*/
|
||||
|
@ -28,7 +28,7 @@ index fa2defa..e3569b0 100644
|
|||
{
|
||||
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
|
||||
loff_t *, size_t, unsigned int);
|
||||
@@ -1113,9 +1113,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
|
||||
@@ -1112,9 +1112,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
|
||||
/*
|
||||
* Attempt to initiate a splice from a file to a pipe.
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
aufs3.2 kbuild patch
|
||||
aufs3.x-rcN kbuild patch
|
||||
|
||||
diff --git a/fs/Kconfig b/fs/Kconfig
|
||||
index 5f4c45d..357a8a6 100644
|
||||
index d621f02..9b9694c 100644
|
||||
--- a/fs/Kconfig
|
||||
+++ b/fs/Kconfig
|
||||
@@ -215,6 +215,7 @@ source "fs/pstore/Kconfig"
|
||||
|
@ -13,16 +13,16 @@ index 5f4c45d..357a8a6 100644
|
|||
endif # MISC_FILESYSTEMS
|
||||
|
||||
diff --git a/fs/Makefile b/fs/Makefile
|
||||
index d2c3353..680ad8a 100644
|
||||
index 93804d4..cf3dcb9 100644
|
||||
--- a/fs/Makefile
|
||||
+++ b/fs/Makefile
|
||||
@@ -123,3 +123,4 @@ obj-$(CONFIG_GFS2_FS) += gfs2/
|
||||
@@ -124,3 +124,4 @@ obj-$(CONFIG_GFS2_FS) += gfs2/
|
||||
obj-y += exofs/ # Multiple modules
|
||||
obj-$(CONFIG_CEPH_FS) += ceph/
|
||||
obj-$(CONFIG_PSTORE) += pstore/
|
||||
+obj-$(CONFIG_AUFS_FS) += aufs/
|
||||
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
|
||||
index 619b565..29f386b 100644
|
||||
index c94e717..fccb9df 100644
|
||||
--- a/include/linux/Kbuild
|
||||
+++ b/include/linux/Kbuild
|
||||
@@ -65,6 +65,7 @@ header-y += atmppp.h
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
aufs3.2 standalone patch
|
||||
aufs3.x-rcN standalone patch
|
||||
|
||||
diff --git a/fs/file_table.c b/fs/file_table.c
|
||||
index c322794..2aad244 100644
|
||||
index 20002e3..6d792ad 100644
|
||||
--- a/fs/file_table.c
|
||||
+++ b/fs/file_table.c
|
||||
@@ -443,6 +443,8 @@ void file_sb_list_del(struct file *file)
|
||||
|
@ -14,10 +14,10 @@ index c322794..2aad244 100644
|
|||
|
||||
/*
|
||||
diff --git a/fs/inode.c b/fs/inode.c
|
||||
index ee4e66b..728042b 100644
|
||||
index 4fa4f09..f07a146 100644
|
||||
--- a/fs/inode.c
|
||||
+++ b/fs/inode.c
|
||||
@@ -65,6 +65,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
|
||||
@@ -66,6 +66,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
|
||||
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
|
||||
|
||||
__cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
|
||||
|
@ -26,10 +26,10 @@ index ee4e66b..728042b 100644
|
|||
/*
|
||||
* Empty aops. Can be used for the cases where the user does not
|
||||
diff --git a/fs/namei.c b/fs/namei.c
|
||||
index 4cc94cf..af19e30 100644
|
||||
index 586eccd..62dd0a8 100644
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -1757,6 +1757,7 @@ struct dentry *lookup_hash(struct nameidata *nd)
|
||||
@@ -1760,6 +1760,7 @@ struct dentry *lookup_hash(struct nameidata *nd)
|
||||
{
|
||||
return __lookup_hash(&nd->last, nd->path.dentry, nd);
|
||||
}
|
||||
|
@ -38,16 +38,16 @@ index 4cc94cf..af19e30 100644
|
|||
/**
|
||||
* lookup_one_len - filesystem helper to lookup single pathname component
|
||||
diff --git a/fs/namespace.c b/fs/namespace.c
|
||||
index cfc6d44..173d15a 100644
|
||||
index e608199..38fcc2e 100644
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -1506,6 +1506,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
|
||||
@@ -1339,6 +1339,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(iterate_mounts);
|
||||
|
||||
static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end)
|
||||
static void cleanup_group_ids(struct mount *mnt, struct mount *end)
|
||||
{
|
||||
diff --git a/fs/notify/group.c b/fs/notify/group.c
|
||||
index 63fc294..6f4adca 100644
|
||||
|
@ -75,7 +75,7 @@ index 63fc294..6f4adca 100644
|
|||
}
|
||||
+EXPORT_SYMBOL_GPL(fsnotify_alloc_group);
|
||||
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
|
||||
index e14587d..be6533b 100644
|
||||
index f104d56..54f36db 100644
|
||||
--- a/fs/notify/mark.c
|
||||
+++ b/fs/notify/mark.c
|
||||
@@ -112,6 +112,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
|
||||
|
@ -86,7 +86,7 @@ index e14587d..be6533b 100644
|
|||
|
||||
/*
|
||||
* Any time a mark is getting freed we end up here.
|
||||
@@ -189,6 +190,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
|
||||
@@ -191,6 +192,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
|
||||
if (unlikely(atomic_dec_and_test(&group->num_marks)))
|
||||
fsnotify_final_destroy_group(group);
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ index e14587d..be6533b 100644
|
|||
|
||||
void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
|
||||
{
|
||||
@@ -276,6 +278,7 @@ err:
|
||||
@@ -278,6 +280,7 @@ err:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ index e14587d..be6533b 100644
|
|||
|
||||
/*
|
||||
* clear any marks in a group in which mark->flags & flags is true
|
||||
@@ -331,6 +334,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
|
||||
@@ -333,6 +336,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
|
||||
atomic_set(&mark->refcnt, 1);
|
||||
mark->free_mark = free_mark;
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ index e14587d..be6533b 100644
|
|||
static int fsnotify_mark_destroy(void *ignored)
|
||||
{
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 22c41b5..33b4033 100644
|
||||
index 77becc0..f634f02 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -60,6 +60,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
|
||||
|
@ -123,10 +123,10 @@ index 22c41b5..33b4033 100644
|
|||
static long do_sys_truncate(const char __user *pathname, loff_t length)
|
||||
{
|
||||
diff --git a/fs/splice.c b/fs/splice.c
|
||||
index e3569b0..9dc07b7 100644
|
||||
index c599f73..00303ba 100644
|
||||
--- a/fs/splice.c
|
||||
+++ b/fs/splice.c
|
||||
@@ -1109,6 +1109,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
|
||||
@@ -1108,6 +1108,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
|
||||
|
||||
return splice_write(pipe, out, ppos, len, flags);
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ index e3569b0..9dc07b7 100644
|
|||
|
||||
/*
|
||||
* Attempt to initiate a splice from a file to a pipe.
|
||||
@@ -1135,6 +1136,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
|
||||
@@ -1134,6 +1135,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
|
||||
|
||||
return splice_read(in, ppos, pipe, len, flags);
|
||||
}
|
||||
|
@ -143,16 +143,16 @@ index e3569b0..9dc07b7 100644
|
|||
/**
|
||||
* splice_direct_to_actor - splices data directly between two non-pipes
|
||||
diff --git a/security/commoncap.c b/security/commoncap.c
|
||||
index ee4f848..611fd70 100644
|
||||
index 7ce191e..19a95be 100644
|
||||
--- a/security/commoncap.c
|
||||
+++ b/security/commoncap.c
|
||||
@@ -975,3 +975,4 @@ int cap_file_mmap(struct file *file, unsigned long reqprot,
|
||||
@@ -965,3 +965,4 @@ int cap_file_mmap(struct file *file, unsigned long reqprot,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(cap_file_mmap);
|
||||
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
|
||||
index 4450fbe..bc94175 100644
|
||||
index 8b5b5d8..911850c 100644
|
||||
--- a/security/device_cgroup.c
|
||||
+++ b/security/device_cgroup.c
|
||||
@@ -7,6 +7,7 @@
|
||||
|
@ -163,7 +163,7 @@ index 4450fbe..bc94175 100644
|
|||
#include <linux/list.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/seq_file.h>
|
||||
@@ -500,6 +501,7 @@ found:
|
||||
@@ -501,6 +502,7 @@ found:
|
||||
|
||||
return -EPERM;
|
||||
}
|
||||
|
@ -172,10 +172,10 @@ index 4450fbe..bc94175 100644
|
|||
int devcgroup_inode_mknod(int mode, dev_t dev)
|
||||
{
|
||||
diff --git a/security/security.c b/security/security.c
|
||||
index e2f684a..892000c 100644
|
||||
index d754249..1aa6154 100644
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -411,6 +411,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
|
||||
@@ -392,6 +392,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
|
||||
return 0;
|
||||
return security_ops->path_rmdir(dir, dentry);
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ index e2f684a..892000c 100644
|
|||
|
||||
int security_path_unlink(struct path *dir, struct dentry *dentry)
|
||||
{
|
||||
@@ -427,6 +428,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
|
||||
@@ -408,6 +409,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
|
||||
return 0;
|
||||
return security_ops->path_symlink(dir, dentry, old_name);
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ index e2f684a..892000c 100644
|
|||
|
||||
int security_path_link(struct dentry *old_dentry, struct path *new_dir,
|
||||
struct dentry *new_dentry)
|
||||
@@ -435,6 +437,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
|
||||
@@ -416,6 +418,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
|
||||
return 0;
|
||||
return security_ops->path_link(old_dentry, new_dir, new_dentry);
|
||||
}
|
||||
|
@ -199,23 +199,23 @@ index e2f684a..892000c 100644
|
|||
|
||||
int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
|
||||
struct path *new_dir, struct dentry *new_dentry)
|
||||
@@ -453,6 +456,7 @@ int security_path_truncate(struct path *path)
|
||||
@@ -434,6 +437,7 @@ int security_path_truncate(struct path *path)
|
||||
return 0;
|
||||
return security_ops->path_truncate(path);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(security_path_truncate);
|
||||
|
||||
int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
|
||||
mode_t mode)
|
||||
@@ -461,6 +465,7 @@ int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
|
||||
int security_path_chmod(struct path *path, umode_t mode)
|
||||
{
|
||||
@@ -441,6 +445,7 @@ int security_path_chmod(struct path *path, umode_t mode)
|
||||
return 0;
|
||||
return security_ops->path_chmod(dentry, mnt, mode);
|
||||
return security_ops->path_chmod(path, mode);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(security_path_chmod);
|
||||
|
||||
int security_path_chown(struct path *path, uid_t uid, gid_t gid)
|
||||
{
|
||||
@@ -468,6 +473,7 @@ int security_path_chown(struct path *path, uid_t uid, gid_t gid)
|
||||
@@ -448,6 +453,7 @@ int security_path_chown(struct path *path, uid_t uid, gid_t gid)
|
||||
return 0;
|
||||
return security_ops->path_chown(path, uid, gid);
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ index e2f684a..892000c 100644
|
|||
|
||||
int security_path_chroot(struct path *path)
|
||||
{
|
||||
@@ -544,6 +550,7 @@ int security_inode_readlink(struct dentry *dentry)
|
||||
@@ -524,6 +530,7 @@ int security_inode_readlink(struct dentry *dentry)
|
||||
return 0;
|
||||
return security_ops->inode_readlink(dentry);
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ index e2f684a..892000c 100644
|
|||
|
||||
int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
|
||||
{
|
||||
@@ -558,6 +565,7 @@ int security_inode_permission(struct inode *inode, int mask)
|
||||
@@ -538,6 +545,7 @@ int security_inode_permission(struct inode *inode, int mask)
|
||||
return 0;
|
||||
return security_ops->inode_permission(inode, mask);
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ index e2f684a..892000c 100644
|
|||
|
||||
int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
{
|
||||
@@ -673,6 +681,7 @@ int security_file_permission(struct file *file, int mask)
|
||||
@@ -653,6 +661,7 @@ int security_file_permission(struct file *file, int mask)
|
||||
|
||||
return fsnotify_perm(file, mask);
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ index e2f684a..892000c 100644
|
|||
|
||||
int security_file_alloc(struct file *file)
|
||||
{
|
||||
@@ -700,6 +709,7 @@ int security_file_mmap(struct file *file, unsigned long reqprot,
|
||||
@@ -680,6 +689,7 @@ int security_file_mmap(struct file *file, unsigned long reqprot,
|
||||
return ret;
|
||||
return ima_file_mmap(file, prot);
|
||||
}
|
||||
|
|
|
@ -1,270 +0,0 @@
|
|||
From: Jean Delvare <khali@linux-fr.org>
|
||||
Date: Mon, 16 Jan 2012 22:51:48 +0100
|
||||
Subject: [PATCH] hwmon: (it87) Add IT8728F support
|
||||
|
||||
commit 16b5dda22e3798e61bb008d2329d4f4d90ef764e upstream.
|
||||
|
||||
Until we get a datasheet for the IT8728F, treat it as fully compatible
|
||||
with the IT8721F, as it seems to work reasonably well.
|
||||
|
||||
This closes kernel bug #27262.
|
||||
|
||||
Signed-off-by: Jean Delvare <khali@linux-fr.org>
|
||||
Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
|
||||
---
|
||||
Documentation/hwmon/it87 | 13 +++++++--
|
||||
drivers/hwmon/Kconfig | 4 +-
|
||||
drivers/hwmon/it87.c | 61 ++++++++++++++++++++++++++++++++++-----------
|
||||
3 files changed, 58 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
|
||||
index 6f496a5..23b7def 100644
|
||||
--- a/Documentation/hwmon/it87
|
||||
+++ b/Documentation/hwmon/it87
|
||||
@@ -26,6 +26,10 @@ Supported chips:
|
||||
Prefix: 'it8721'
|
||||
Addresses scanned: from Super I/O config space (8 I/O ports)
|
||||
Datasheet: Not publicly available
|
||||
+ * IT8728F
|
||||
+ Prefix: 'it8728'
|
||||
+ Addresses scanned: from Super I/O config space (8 I/O ports)
|
||||
+ Datasheet: Not publicly available
|
||||
* SiS950 [clone of IT8705F]
|
||||
Prefix: 'it87'
|
||||
Addresses scanned: from Super I/O config space (8 I/O ports)
|
||||
@@ -71,7 +75,7 @@ Description
|
||||
-----------
|
||||
|
||||
This driver implements support for the IT8705F, IT8712F, IT8716F,
|
||||
-IT8718F, IT8720F, IT8721F, IT8726F, IT8758E and SiS950 chips.
|
||||
+IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E and SiS950 chips.
|
||||
|
||||
These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
|
||||
joysticks and other miscellaneous stuff. For hardware monitoring, they
|
||||
@@ -105,6 +109,9 @@ The IT8726F is just bit enhanced IT8716F with additional hardware
|
||||
for AMD power sequencing. Therefore the chip will appear as IT8716F
|
||||
to userspace applications.
|
||||
|
||||
+The IT8728F is considered compatible with the IT8721F, until a datasheet
|
||||
+becomes available (hopefully.)
|
||||
+
|
||||
Temperatures are measured in degrees Celsius. An alarm is triggered once
|
||||
when the Overtemperature Shutdown limit is crossed.
|
||||
|
||||
@@ -121,8 +128,8 @@ alarm is triggered if the voltage has crossed a programmable minimum or
|
||||
maximum limit. Note that minimum in this case always means 'closest to
|
||||
zero'; this is important for negative voltage measurements. All voltage
|
||||
inputs can measure voltages between 0 and 4.08 volts, with a resolution of
|
||||
-0.016 volt (except IT8721F/IT8758E: 0.012 volt.) The battery voltage in8 does
|
||||
-not have limit registers.
|
||||
+0.016 volt (except IT8721F/IT8758E and IT8728F: 0.012 volt.) The battery
|
||||
+voltage in8 does not have limit registers.
|
||||
|
||||
On the IT8721F/IT8758E, some voltage inputs are internal and scaled inside
|
||||
the chip (in7, in8 and optionally in3). The driver handles this transparently
|
||||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
|
||||
index f468bbb..0226040 100644
|
||||
--- a/drivers/hwmon/Kconfig
|
||||
+++ b/drivers/hwmon/Kconfig
|
||||
@@ -474,8 +474,8 @@ config SENSORS_IT87
|
||||
select HWMON_VID
|
||||
help
|
||||
If you say yes here you get support for ITE IT8705F, IT8712F,
|
||||
- IT8716F, IT8718F, IT8720F, IT8721F, IT8726F and IT8758E sensor
|
||||
- chips, and the SiS960 clone.
|
||||
+ IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F and IT8758E
|
||||
+ sensor chips, and the SiS960 clone.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called it87.
|
||||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
|
||||
index 603ef2a..0054d6f 100644
|
||||
--- a/drivers/hwmon/it87.c
|
||||
+++ b/drivers/hwmon/it87.c
|
||||
@@ -17,6 +17,7 @@
|
||||
* IT8720F Super I/O chip w/LPC interface
|
||||
* IT8721F Super I/O chip w/LPC interface
|
||||
* IT8726F Super I/O chip w/LPC interface
|
||||
+ * IT8728F Super I/O chip w/LPC interface
|
||||
* IT8758E Super I/O chip w/LPC interface
|
||||
* Sis950 A clone of the IT8705F
|
||||
*
|
||||
@@ -58,7 +59,7 @@
|
||||
|
||||
#define DRVNAME "it87"
|
||||
|
||||
-enum chips { it87, it8712, it8716, it8718, it8720, it8721 };
|
||||
+enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728 };
|
||||
|
||||
static unsigned short force_id;
|
||||
module_param(force_id, ushort, 0);
|
||||
@@ -135,6 +136,7 @@ static inline void superio_exit(void)
|
||||
#define IT8720F_DEVID 0x8720
|
||||
#define IT8721F_DEVID 0x8721
|
||||
#define IT8726F_DEVID 0x8726
|
||||
+#define IT8728F_DEVID 0x8728
|
||||
#define IT87_ACT_REG 0x30
|
||||
#define IT87_BASE_REG 0x60
|
||||
|
||||
@@ -274,11 +276,31 @@ struct it87_data {
|
||||
s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */
|
||||
};
|
||||
|
||||
+static inline int has_12mv_adc(const struct it87_data *data)
|
||||
+{
|
||||
+ /*
|
||||
+ * IT8721F and later have a 12 mV ADC, also with internal scaling
|
||||
+ * on selected inputs.
|
||||
+ */
|
||||
+ return data->type == it8721
|
||||
+ || data->type == it8728;
|
||||
+}
|
||||
+
|
||||
+static inline int has_newer_autopwm(const struct it87_data *data)
|
||||
+{
|
||||
+ /*
|
||||
+ * IT8721F and later have separate registers for the temperature
|
||||
+ * mapping and the manual duty cycle.
|
||||
+ */
|
||||
+ return data->type == it8721
|
||||
+ || data->type == it8728;
|
||||
+}
|
||||
+
|
||||
static u8 in_to_reg(const struct it87_data *data, int nr, long val)
|
||||
{
|
||||
long lsb;
|
||||
|
||||
- if (data->type == it8721) {
|
||||
+ if (has_12mv_adc(data)) {
|
||||
if (data->in_scaled & (1 << nr))
|
||||
lsb = 24;
|
||||
else
|
||||
@@ -292,7 +314,7 @@ static u8 in_to_reg(const struct it87_data *data, int nr, long val)
|
||||
|
||||
static int in_from_reg(const struct it87_data *data, int nr, int val)
|
||||
{
|
||||
- if (data->type == it8721) {
|
||||
+ if (has_12mv_adc(data)) {
|
||||
if (data->in_scaled & (1 << nr))
|
||||
return val * 24;
|
||||
else
|
||||
@@ -329,7 +351,7 @@ static inline u16 FAN16_TO_REG(long rpm)
|
||||
|
||||
static u8 pwm_to_reg(const struct it87_data *data, long val)
|
||||
{
|
||||
- if (data->type == it8721)
|
||||
+ if (has_newer_autopwm(data))
|
||||
return val;
|
||||
else
|
||||
return val >> 1;
|
||||
@@ -337,7 +359,7 @@ static u8 pwm_to_reg(const struct it87_data *data, long val)
|
||||
|
||||
static int pwm_from_reg(const struct it87_data *data, u8 reg)
|
||||
{
|
||||
- if (data->type == it8721)
|
||||
+ if (has_newer_autopwm(data))
|
||||
return reg;
|
||||
else
|
||||
return (reg & 0x7f) << 1;
|
||||
@@ -374,7 +396,8 @@ static inline int has_16bit_fans(const struct it87_data *data)
|
||||
|| data->type == it8716
|
||||
|| data->type == it8718
|
||||
|| data->type == it8720
|
||||
- || data->type == it8721;
|
||||
+ || data->type == it8721
|
||||
+ || data->type == it8728;
|
||||
}
|
||||
|
||||
static inline int has_old_autopwm(const struct it87_data *data)
|
||||
@@ -842,7 +865,7 @@ static ssize_t set_pwm_enable(struct device *dev,
|
||||
data->fan_main_ctrl);
|
||||
} else {
|
||||
if (val == 1) /* Manual mode */
|
||||
- data->pwm_ctrl[nr] = data->type == it8721 ?
|
||||
+ data->pwm_ctrl[nr] = has_newer_autopwm(data) ?
|
||||
data->pwm_temp_map[nr] :
|
||||
data->pwm_duty[nr];
|
||||
else /* Automatic mode */
|
||||
@@ -870,7 +893,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
- if (data->type == it8721) {
|
||||
+ if (has_newer_autopwm(data)) {
|
||||
/* If we are in automatic mode, the PWM duty cycle register
|
||||
* is read-only so we can't write the value */
|
||||
if (data->pwm_ctrl[nr] & 0x80) {
|
||||
@@ -1311,8 +1334,8 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr,
|
||||
struct it87_data *data = dev_get_drvdata(dev);
|
||||
int nr = to_sensor_dev_attr(attr)->index;
|
||||
|
||||
- return sprintf(buf, "%s\n", data->type == it8721 ? labels_it8721[nr]
|
||||
- : labels[nr]);
|
||||
+ return sprintf(buf, "%s\n", has_12mv_adc(data) ? labels_it8721[nr]
|
||||
+ : labels[nr]);
|
||||
}
|
||||
static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
|
||||
@@ -1605,6 +1628,9 @@ static int __init it87_find(unsigned short *address,
|
||||
case IT8721F_DEVID:
|
||||
sio_data->type = it8721;
|
||||
break;
|
||||
+ case IT8728F_DEVID:
|
||||
+ sio_data->type = it8728;
|
||||
+ break;
|
||||
case 0xffff: /* No device at all */
|
||||
goto exit;
|
||||
default:
|
||||
@@ -1646,8 +1672,11 @@ static int __init it87_find(unsigned short *address,
|
||||
superio_select(GPIO);
|
||||
|
||||
reg = superio_inb(IT87_SIO_GPIO3_REG);
|
||||
- if (sio_data->type == it8721) {
|
||||
- /* The IT8721F/IT8758E doesn't have VID pins at all */
|
||||
+ if (sio_data->type == it8721 || sio_data->type == it8728) {
|
||||
+ /*
|
||||
+ * The IT8721F/IT8758E doesn't have VID pins at all,
|
||||
+ * not sure about the IT8728F.
|
||||
+ */
|
||||
sio_data->skip_vid = 1;
|
||||
} else {
|
||||
/* We need at least 4 VID pins */
|
||||
@@ -1692,7 +1721,8 @@ static int __init it87_find(unsigned short *address,
|
||||
}
|
||||
if (reg & (1 << 0))
|
||||
sio_data->internal |= (1 << 0);
|
||||
- if ((reg & (1 << 1)) || sio_data->type == it8721)
|
||||
+ if ((reg & (1 << 1)) || sio_data->type == it8721 ||
|
||||
+ sio_data->type == it8728)
|
||||
sio_data->internal |= (1 << 1);
|
||||
|
||||
sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
|
||||
@@ -1770,6 +1800,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
|
||||
"it8718",
|
||||
"it8720",
|
||||
"it8721",
|
||||
+ "it8728",
|
||||
};
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
@@ -1807,7 +1838,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
|
||||
enable_pwm_interface = it87_check_pwm(dev);
|
||||
|
||||
/* Starting with IT8721F, we handle scaling of internal voltages */
|
||||
- if (data->type == it8721) {
|
||||
+ if (has_12mv_adc(data)) {
|
||||
if (sio_data->internal & (1 << 0))
|
||||
data->in_scaled |= (1 << 3); /* in3 is AVCC */
|
||||
if (sio_data->internal & (1 << 1))
|
||||
@@ -2093,7 +2124,7 @@ static void __devinit it87_init_device(struct platform_device *pdev)
|
||||
static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
|
||||
{
|
||||
data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
|
||||
- if (data->type == it8721) {
|
||||
+ if (has_newer_autopwm(data)) {
|
||||
data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
|
||||
data->pwm_duty[nr] = it87_read_value(data,
|
||||
IT87_REG_PWM_DUTY(nr));
|
||||
--
|
||||
1.7.9
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Thu, 24 Nov 2011 07:04:39 +0000
|
||||
Subject: [PATCH] topology: Provide CPU topology in sysfs in !SMP
|
||||
configurations
|
||||
|
||||
commit ccbc60d3e19a1b6ae66ca0d89b3da02dde62088b upstream.
|
||||
|
||||
We should provide topology information to userland even if it's not
|
||||
very interesting. The current code appears to work properly for !SMP
|
||||
(tested on i386).
|
||||
|
||||
Reference: http://bugs.debian.org/649216
|
||||
Reported-by: Marcus Osdoba <marcus.osdoba@googlemail.com>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/base/Makefile | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
|
||||
index 99a375a..1334d89 100644
|
||||
--- a/drivers/base/Makefile
|
||||
+++ b/drivers/base/Makefile
|
||||
@@ -3,7 +3,8 @@
|
||||
obj-y := core.o sys.o bus.o dd.o syscore.o \
|
||||
driver.o class.o platform.o \
|
||||
cpu.o firmware.o init.o map.o devres.o \
|
||||
- attribute_container.o transport_class.o
|
||||
+ attribute_container.o transport_class.o \
|
||||
+ topology.o
|
||||
obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
|
||||
obj-y += power/
|
||||
obj-$(CONFIG_HAS_DMA) += dma-mapping.o
|
||||
@@ -12,7 +13,6 @@ obj-$(CONFIG_ISA) += isa.o
|
||||
obj-$(CONFIG_FW_LOADER) += firmware_class.o
|
||||
obj-$(CONFIG_NUMA) += node.o
|
||||
obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
|
||||
-obj-$(CONFIG_SMP) += topology.o
|
||||
ifeq ($(CONFIG_SYSFS),y)
|
||||
obj-$(CONFIG_MODULES) += module.o
|
||||
endif
|
||||
--
|
||||
1.7.7.3
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
commit a87d89e74f0a4b56eaee8c3ef74bce69277b780f
|
||||
Author: Martin Michlmayr <tbm@cyrius.com>
|
||||
Date: Thu Nov 3 12:57:43 2011 +0000
|
||||
|
||||
ARM: Kirkwood: Recognize A1 revision of 6282 chip
|
||||
|
||||
Recognize the Kirkwood 6282 revision A1 chip since products using
|
||||
this chip are shipping now, such as the QNAP TS-x19P II devices.
|
||||
|
||||
Signed-off-by: Martin Michlmayr <tbm@cyrius.com>
|
||||
Acked-by: Lennert Buytenhek <buytenh@wantstofly.org>
|
||||
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
|
||||
|
||||
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
|
||||
index f3248cf..b9632ee 100644
|
||||
--- a/arch/arm/mach-kirkwood/common.c
|
||||
+++ b/arch/arm/mach-kirkwood/common.c
|
||||
@@ -430,6 +430,8 @@ static char * __init kirkwood_id(void)
|
||||
} else if (dev == MV88F6282_DEV_ID) {
|
||||
if (rev == MV88F6282_REV_A0)
|
||||
return "MV88F6282-Rev-A0";
|
||||
+ else if (rev == MV88F6282_REV_A1)
|
||||
+ return "MV88F6282-Rev-A1";
|
||||
else
|
||||
return "MV88F6282-Rev-Unsupported";
|
||||
} else {
|
||||
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
|
||||
index 010bdeb..fede3d5 100644
|
||||
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
|
||||
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
|
||||
@@ -135,4 +135,5 @@
|
||||
|
||||
#define MV88F6282_DEV_ID 0x6282
|
||||
#define MV88F6282_REV_A0 0
|
||||
+#define MV88F6282_REV_A1 1
|
||||
#endif
|
|
@ -42,41 +42,10 @@
|
|||
+ debian/cgroups-Document-the-Debian-memory-resource-controll.patch
|
||||
+ bugfix/ia64/nouveau-ACPI-support-is-dependent-on-X86.patch
|
||||
+ features/x86/x86-Add-amilo-rfkill-driver-for-some-Fujitsu-Siemens.patch
|
||||
|
||||
+ bugfix/ia64/ia64-Add-accept4-syscall.patch
|
||||
+ bugfix/arm/ixp4xx_iobe.patch
|
||||
|
||||
+ debian/bcma-Do-not-claim-PCI-device-IDs-also-claimed-by-brc.patch
|
||||
|
||||
+ bugfix/all/0001-media-staging-lirc_serial-Fix-init-exit-order.patch
|
||||
+ bugfix/all/0002-media-staging-lirc_serial-Free-resources-on-failure-.patch
|
||||
+ bugfix/all/0003-media-staging-lirc_serial-Fix-deadlock-on-resume-fai.patch
|
||||
+ bugfix/all/0004-media-staging-lirc_serial-Fix-bogus-error-codes.patch
|
||||
+ bugfix/all/0005-media-staging-lirc_serial-Do-not-assume-error-codes-.patch
|
||||
|
||||
+ features/all/topology-Provide-CPU-topology-in-sysfs-in-SMP-configura.patch
|
||||
+ bugfix/all/cpu-Do-not-return-errors-from-cpu_dev_init-which-wil.patch
|
||||
+ bugfix/all/cpu-Register-a-generic-CPU-device-on-architectures-t.patch
|
||||
+ debian/x86-memtest-WARN-if-bad-RAM-found.patch
|
||||
+ bugfix/all/snapshot-Implement-compat_ioctl.patch
|
||||
+ debian/ARM-Remove-use-of-possibly-undefined-BUILD_BUG_ON-in.patch
|
||||
+ bugfix/arm/ARM-ixp4xx-gpiolib-support.patch
|
||||
+ bugfix/arm/ARM-topdown-mmap.patch
|
||||
+ bugfix/alpha/alpha-add-io-read-write-16-32-be-functions.patch
|
||||
+ features/arm/ARM-kirkwood-6282A1.patch
|
||||
+ features/all/Input-ALPS-move-protocol-information-to-Documentatio.patch
|
||||
+ features/all/Input-ALPS-add-protocol-version-field-in-alps_model_.patch
|
||||
+ features/all/Input-ALPS-remove-assumptions-about-packet-size.patch
|
||||
+ features/all/Input-ALPS-add-support-for-protocol-versions-3-and-4.patch
|
||||
+ features/all/Input-ALPS-add-semi-MT-support-for-v3-protocol.patch
|
||||
+ bugfix/x86/KVM-nVMX-Add-KVM_REQ_IMMEDIATE_EXIT.patch
|
||||
+ bugfix/x86/KVM-nVMX-Fix-warning-causing-idt-vectoring-info-beha.patch
|
||||
+ bugfix/x86/KVM-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch
|
||||
+ bugfix/x86/KVM-x86-fix-missing-checks-in-syscall-emulation.patch
|
||||
|
||||
+ features/all/hwmon-it87-Add-IT8728F-support.patch
|
||||
+ bugfix/arm/ARM-ixp4xx-mtd-oops.patch
|
||||
|
||||
+ bugfix/all/relay-prevent-integer-overflow-in-relay_open.patch
|
||||
+ bugfix/all/builddeb-Don-t-create-files-in-tmp-with-predictable-.patch
|
||||
+ bugfix/all/ath9k-fix-a-wep-crypto-related-regression.patch
|
||||
|
||||
|
|
Loading…
Reference in New Issue