All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mchehab@redhat.com>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Jon Smirl <jonsmirl@gmail.com>, Pavel Machek <pavel@ucw.cz>,
	Krzysztof Halasa <khc@pm.waw.pl>,
	hermann pitton <hermann-pitton@arcor.de>,
	Christoph Bartelmus <lirc@bartelmus.de>,
	awalls@radix.net, j@jannau.net, jarod@redhat.com,
	jarod@wilsonet.com, kraxel@redhat.com,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-media@vger.kernel.org, superm1@ubuntu.com
Subject: Re: [RFC] What are the goals for the architecture of an in-kernel IR system?
Date: Sun, 28 Mar 2010 20:22:31 -0300	[thread overview]
Message-ID: <4BAFE4B7.2030204@redhat.com> (raw)
In-Reply-To: <20100326160150.GA28804@core.coreip.homeip.net>

Dmitry Torokhov wrote:
> On Fri, Mar 26, 2010 at 11:40:41AM -0300, Mauro Carvalho Chehab wrote:
>> David Härdeman wrote:
>>> On Thu, Mar 25, 2010 at 11:42:33AM -0300, Mauro Carvalho Chehab wrote:
>>>>>        10) extend keycode table replacement to support big/variable 
>>>>>        sized scancodes;
>>>> Pending.
>>>>
>>>> The current limit here is the scancode ioctl's are defined as:
>>>>
>>>> #define EVIOCGKEYCODE           _IOR('E', 0x04, int[2])                 /* get keycode */
>>>> #define EVIOCSKEYCODE           _IOW('E', 0x04, int[2])                 /* set keycode */
>>>>
>>>> As int size is 32 bits, and we must pass both 64 (or even bigger) scancodes, associated
>>>> with a keycode, there's not enough bits there for IR.
>>>>
>>>> The better approach seems to create an struct with an arbitrary long size, like:
>>>>
>>>> struct keycode_table_entry {
>>>> 	unsigned keycode;
>>>> 	char scancode[32];	/* 32 is just an arbitrary long array - maybe shorter */
>>>> 	int len;
>>>> }
>>>>
>>>> and re-define the ioctls. For example we might be doing:
>>>>
>>>> #define EVIOCGKEYCODEBIG           _IOR('E', 0x04, struct keycode_table_entry)
>>>> #define EVIOCSKEYCODEBIG           _IOW('E', 0x04, struct keycode_table_entry)
>>>> #define EVIOCLEARKEYCODEBIG        _IOR('E', 0x04, void)
>>>>
>>>> Provided that the size for struct keycode_table_entry is different, _IO will generate
>>>> a different magic number for those.
>>>>
>>>> Or, instead of using 0x04, just use another sequential number at the 'E' namespace.
>>>>
>>>> An specific function to clear the table is needed with big scancode space,
>>>> as already discussed.
>>>>
>>> I'd suggest:
>>>
>>> struct keycode_table_entry {
>>> 	unsigned keycode;
>>> 	unsigned index;
>>> 	unsigned len;
>>> 	char scancode[];
>>> };
>>>
>>> Use index in EVIOCGKEYCODEBIG to look up a keycode (all other fields are 
>>> ignored), that way no special function to clear the table is necessary, 
>>> instead you do a loop with:
>>>
>>> EVIOCGKEYCODEBIG (with index 0)
>>> EVIOCSKEYCODEBIG (with the returned struct from EVIOCGKEYCODEBIG and
>>> 		  keycode = KEY_RESERVED)
>>>
>>> until EVIOCGKEYCODEBIG returns an error.
>> Makes sense.
> 
> Yes, I think so too. Just need a nice way to handle transition, I'd
> like in the end to have drivers implement only the improved methods and
> map legacy methods in evdev.

See the attached RFC barely tested patch. 

On this patch, I'm using the following definitions for the ioctl:

struct keycode_table_entry {
	__u32 keycode;		/* e.g. KEY_A */
	__u32 index;		/* Index for the given scan/key table */
	__u32 len;		/* Lenght of the scancode */
	__u32 reserved[2];	/* Reserved for future usage */
	char *scancode;		/* scancode, in machine-endian */
};

#define EVIOCGKEYCODEBIG	_IOR('E', 0x04, struct keycode_table_entry) /* get keycode */
#define EVIOCSKEYCODEBIG	_IOW('E', 0x04, struct keycode_table_entry) /* set keycode */


I tried to do the compat backport on a nice way, on both directions, e. g.:

1) an userspace app using EVIO[CS]GKEYCODEBIG to work with a legacy driver.
2) a driver implementing the new methods to accept the legacy EVIO[CS]GKEYCODE;

For the test of (1), I implemented the following clear keytable code:

	struct keycode_table_entry      kt;
        uint32_t                        scancode, i;

        memset(&kt, 0, sizeof(kt));
        kt.len = sizeof(scancode);
        kt.scancode = (char *)&scancode;

        for (i = 0; rc == 0; i++) {
        	kt.index = i;
        	kt.keycode = KEY_RESERVED;
                rc = ioctl(fd, EVIOCSKEYCODEBIG, &kt);
        }
        fprintf(stderr, "Cleaned %i keycode(s)\n", i - 1);

It worked properly. I didn't test (2) yet.

The read keytable would also be trivial. However, there are some troubles when
implementing the code to add/replace a value at the table, in a way that it
would allow the legacy drivers to work:

- With a real CODEBIG support, the index number will be different than the
scancode number. So, let's say that this is the driver table:

index	scancode keycode
------------------------
0	0x1e00	 KEY_0
1	0x1e01	 KEY_1
2	0x1e02	 KEY_2
3	0x1e03	 KEY_3
4	0x1e04	 KEY_4
5	0x1e05	 KEY_5
6	0x1e06	 KEY_6
7	0x1e07	 KEY_7
8	0x1e08	 KEY_8
9	0x1e09	 KEY_9

Let's suppose that the user wants to overwrite the entry 5, attributing a new scancode/keycode
to entry 5 (for example, associating 0x1e0a with KEY-A).

A valid EVIOCSKEYCODEBIG call to change this code would be:

	kt->index = 5;
	*(uint32_t *)kt->scancode = 0x1e0a;
	*(uint32_t *)kt->keycode = KEY_A;
	rc = ioctl(fd, EVIOCSKEYCODEBIG, &kt);

With EVIOCSKEYCODE, this requires two separate operations:

	int codes[2];
	code[0] = 0x1e05;
	code[1] = KEY_RESERVED;
	rc = ioctl(fd, EVIOCSKEYCODE, &codes];

	code[0] = 0x1e0a;
	code[1] = KEY_A;
	rc = ioctl(fd, EVIOCSKEYCODE, &codes];


In the case of EVIOCSKEYCODEBIG call, the driver will need to:

1) Check If the scancode is not being used yet on any entry different than index=5.
If it is in use, it should return an error. 
If not, replace the scancode/keycode.

2) Check if index is equal to the length of the array + 1. If so, create a new entry.

3) check if the index is bigger than length + 1 and return an error, if so.

For the EVIOSKEYCODE emulation by an EVIOCSKEYCODEBIG driver, index=5 won't work.
The driver will need to use the scancode. However, if we do this way, the
cleanup logic will break, as scancode is equal to zero.

So, I think that having an index here is not a good idea: it will just create some
implementation troubles. We can archive the same result without the index, and having
a fast clean_table code by just reading the used scancodes and associating them
with KEY_RESERVED.

So, I'll be working on another patch with this different implementation.

I also noticed another problem: kernel should have some way to report the expected
size of the scancode to userspace, especially if we want to have the compatibility
code (since, with compat, a scancode maximum size need to be 32 bits, otherwise
the code won't work).

I'll likely adding another control that returns the size of the scancode.

Comments?

Cheers,
Mauro


---


This is the RFC patch I wrote here for my tests.

commit 6bf412eedaa05f28d5ce50795d3ac64ec41c3031
Author: Mauro Carvalho Chehab <mchehab@redhat.com>
Date:   Sun Mar 28 04:02:36 2010 -0300

    input: Add support for EVIO[CS]GKEYCODEBIG
    
    Several devices use a high number of bits for scancodes. One important
    group is the Remote Controllers. Some new protocols like RC-6 define a
    scancode space of 64 bits.
    
    The current EVIO[CS]GKEYCODE ioctls allow replace the scancode/keycode
    translation tables, but it is limited to up to 32 bits for scancode.
    
    Also, if userspace wants to clean the existing table, replacing it by
    a new one, it needs to run a loop calling the old ioctls, over the
    entire sparsed scancode userspace.
    
    To solve those problems, this patch introduces two new ioctls:
    	EVIOCGKEYCODEBIG - reads a scancode from the translation table;
    	EVIOSGKEYCODEBIG - writes a scancode into the translation table.
    
    The EVIOSGKEYCODEBIG can also be used to cleanup the translation entries
    by associating KEY_RESERVED to a scancode.
    
    By default, kernel will implement a default handler that will work with
    both EVIO[CS]GKEYCODEBIG and the legacy EVIO[CS]GKEYCODE ioctls.
    
    Compatibility code were also added to allow drivers that implement
    only the ops handler for EVIO[CS]GKEYCODE to keep working.
    
    Userspace compatibility for EVIO[CS]GKEYCODE is also granted: the evdev/input
    ioctl handler will automatically map those ioctls with the new
    getkeycodebig()/setkeycodebig() operations to handle a request using the
    legacy API.
    
    So, new drivers should only implement the EVIO[CS]GKEYCODEBIG operation
    handlers: getkeycodebig()/setkeycodebig().
    
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 258c639..aed5acc 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -513,6 +513,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 	struct input_absinfo abs;
 	struct ff_effect effect;
 	int __user *ip = (int __user *)p;
+	struct keycode_table_entry __user *kt = p;
 	int i, t, u, v;
 	int error;
 
@@ -567,6 +568,25 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 
 		return input_set_keycode(dev, t, v);
 
+	case EVIOCGKEYCODEBIG:
+		if (copy_from_user(kt, &dev->id, _IOC_SIZE(cmd)))
+			return -EFAULT;
+
+		error = input_get_keycode_big(dev, kt);
+		if (error)
+			return error;
+
+		if (copy_to_user(kt, &dev->id, _IOC_SIZE(cmd)))
+			return -EFAULT;
+
+		return 0;
+
+	case EVIOCSKEYCODEBIG:
+		if (copy_from_user(p, &dev->id, _IOC_SIZE(cmd)))
+			return -EFAULT;
+
+		return input_set_keycode_big(dev, kt);
+
 	case EVIOCRMFF:
 		return input_ff_erase(dev, (int)(unsigned long) p, file);
 
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 86cb2d2..0437c75 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -551,6 +551,11 @@ static void input_disconnect_device(struct input_dev *dev)
 	spin_unlock_irq(&dev->event_lock);
 }
 
+/*
+ * Those routines handle the default case where no [gs]etkeycode() is
+ * defined. In this case, an array indexed by the scancode is used.
+ */
+
 static int input_fetch_keycode(struct input_dev *dev, int scancode)
 {
 	switch (dev->keycodesize) {
@@ -566,57 +571,88 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode)
 }
 
 static int input_default_getkeycode(struct input_dev *dev,
-				    int scancode, int *keycode)
+				    struct keycode_table_entry *kt_entry)
 {
 	if (!dev->keycodesize)
 		return -EINVAL;
 
-	if (scancode >= dev->keycodemax)
+	if (kt_entry->index >= dev->keycodemax)
 		return -EINVAL;
 
-	*keycode = input_fetch_keycode(dev, scancode);
+	/*
+	 * Supports only 8, 16 and 32 bit scancodes. It wouldn't be that
+	 * hard to write some machine-endian logic to support 24 bit scancodes,
+	 * but it seemed overkill. It should also be noticed that, since there
+	 * are, in general, less than 256 scancodes sparsed into the scancode
+	 * space, even with 16 bits, the codespace is sparsed, with leads into
+	 * memory and code ineficiency, when retrieving the entire scancode
+	 * space.
+	 * So, it is highly recommended to implement getkeycodebig/setkeycodebig
+	 * instead of using a normal table approach, when more than 8 bits is
+	 * needed for the scancode.
+	 *
+	 */
+	switch (kt_entry->len) {
+	case 1:
+		if (kt_entry->index > ((1 << 8) - 1))
+			return -EINVAL;
+		*((u8 *)kt_entry->scancode) = (u8)kt_entry->index;
+		break;
+	case 2:
+		if (kt_entry->index > ((1 << 16) - 1))
+			return -EINVAL;
+		*((u16 *)kt_entry->scancode) = (u16)kt_entry->index;
+		break;
+	case 4:
+		*((u32 *)kt_entry->scancode) = kt_entry->index;
+		break;
+	default:
+		return -EINVAL;
+	}
+	kt_entry->keycode = input_fetch_keycode(dev, kt_entry->index);
 
 	return 0;
 }
 
 static int input_default_setkeycode(struct input_dev *dev,
-				    int scancode, int keycode)
+				    struct keycode_table_entry *kt_entry)
 {
 	int old_keycode;
 	int i;
 
-	if (scancode >= dev->keycodemax)
+	if (kt_entry->index >= dev->keycodemax)
 		return -EINVAL;
 
 	if (!dev->keycodesize)
 		return -EINVAL;
 
-	if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
+	if (dev->keycodesize < sizeof(dev->keycode) &&
+	    (kt_entry->keycode >> (dev->keycodesize * 8)))
 		return -EINVAL;
 
 	switch (dev->keycodesize) {
 		case 1: {
 			u8 *k = (u8 *)dev->keycode;
-			old_keycode = k[scancode];
-			k[scancode] = keycode;
+			old_keycode = k[kt_entry->index];
+			k[kt_entry->index] = kt_entry->keycode;
 			break;
 		}
 		case 2: {
 			u16 *k = (u16 *)dev->keycode;
-			old_keycode = k[scancode];
-			k[scancode] = keycode;
+			old_keycode = k[kt_entry->index];
+			k[kt_entry->index] = kt_entry->keycode;
 			break;
 		}
 		default: {
 			u32 *k = (u32 *)dev->keycode;
-			old_keycode = k[scancode];
-			k[scancode] = keycode;
+			old_keycode = k[kt_entry->index];
+			k[kt_entry->index] = kt_entry->keycode;
 			break;
 		}
 	}
 
 	clear_bit(old_keycode, dev->keybit);
-	set_bit(keycode, dev->keybit);
+	set_bit(kt_entry->keycode, dev->keybit);
 
 	for (i = 0; i < dev->keycodemax; i++) {
 		if (input_fetch_keycode(dev, i) == old_keycode) {
@@ -629,6 +665,103 @@ static int input_default_setkeycode(struct input_dev *dev,
 }
 
 /**
+ * input_get_keycode_big - retrieve keycode currently mapped to a given scancode
+ * @dev: input device which keymap is being queried
+ * @kt_entry: keytable entry
+ *
+ * This function should be called by anyone interested in retrieving current
+ * keymap. Presently evdev handlers use it.
+ */
+int input_get_keycode_big(struct input_dev *dev,
+			  struct keycode_table_entry *kt_entry)
+{
+	if (dev->getkeycode) {
+		/*
+		 * Support for legacy drivers, that don't implement the new
+		 * ioctls: use index=scancode, just like the default methods
+		 */
+		return dev->getkeycode(dev, kt_entry->index,
+				       &kt_entry->keycode);
+	} else
+		return dev->getkeycodebig(dev, kt_entry);
+}
+EXPORT_SYMBOL(input_get_keycode_big);
+
+/**
+ * input_set_keycode_big - attribute a keycode to a given scancode
+ * @dev: input device which keymap is being queried
+ * @kt_entry: keytable entry
+ *
+ * This function should be called by anyone needing to update current
+ * keymap. Presently keyboard and evdev handlers use it.
+ */
+int input_set_keycode_big(struct input_dev *dev,
+			  struct keycode_table_entry *kt_entry)
+{
+	unsigned long flags;
+	int new_keycode, old_keycode;
+	int retval = -EINVAL;
+
+	if (kt_entry->keycode < 0 || kt_entry->keycode > KEY_MAX)
+		return -EINVAL;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	new_keycode = kt_entry->keycode;
+
+	/*
+	 * We need to know the old scancode, in order to generate a
+	 * keyup effect, if the set operation happens successfully
+	 */
+	if (dev->getkeycode) {
+		/*
+		 * Support for legacy drivers, that don't implement the new
+		 * ioctls: use index=scancode, just like the default methods
+		 * If setkeycode is not defined, just return.
+		 */
+		if (!dev->setkeycode)
+			goto out;
+
+		retval = dev->getkeycode(dev, kt_entry->index,
+					 &kt_entry->keycode);
+	} else
+		retval = dev->getkeycodebig(dev, kt_entry);
+
+	old_keycode = kt_entry->keycode;
+	kt_entry->keycode = new_keycode;
+
+	if (retval)
+		goto out;
+
+	if (dev->getkeycode)
+		retval = dev->setkeycode(dev, kt_entry->index,
+					 kt_entry->keycode);
+	else
+		retval = dev->setkeycodebig(dev, kt_entry);
+	if (retval)
+		goto out;
+
+	/*
+	 * Simulate keyup event if keycode is not present
+	 * in the keymap anymore
+	 */
+	if (test_bit(EV_KEY, dev->evbit) &&
+	    !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
+	    __test_and_clear_bit(old_keycode, dev->key)) {
+
+		input_pass_event(dev, EV_KEY, old_keycode, 0);
+		if (dev->sync)
+			input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+	}
+
+ out:
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	return retval;
+}
+EXPORT_SYMBOL(input_set_keycode_big);
+
+/**
  * input_get_keycode - retrieve keycode currently mapped to a given scancode
  * @dev: input device which keymap is being queried
  * @scancode: scancode (or its equivalent for device in question) for which
@@ -640,10 +773,33 @@ static int input_default_setkeycode(struct input_dev *dev,
  */
 int input_get_keycode(struct input_dev *dev, int scancode, int *keycode)
 {
-	if (scancode < 0)
-		return -EINVAL;
+	if (dev->getkeycode) {
+		/*
+		 * Use the legacy calls
+		 */
+		return dev->getkeycode(dev, scancode, keycode);
+	} else {
+		int retval;
+		char char_scan[4];
+		struct keycode_table_entry kt_entry;
+
+		/*
+		 * Userspace is using a legacy call with a driver ported
+		 * to the new way. This is a bad idea with long sparsed
+		 * tables, since lots of the retrieved values will be in
+		 * blank. Also, it makes sense only if the table size is
+		 * lower than 2^32.
+		 */
+		memset(&kt_entry, 0, sizeof(kt_entry));
+		kt_entry.len = 32;
+		kt_entry.index = scancode;
+		kt_entry.scancode = char_scan;
+
+		retval = dev->getkeycodebig(dev, &kt_entry);
 
-	return dev->getkeycode(dev, scancode, keycode);
+		*keycode = kt_entry.keycode;
+		return retval;
+	}
 }
 EXPORT_SYMBOL(input_get_keycode);
 
@@ -662,21 +818,48 @@ int input_set_keycode(struct input_dev *dev, int scancode, int keycode)
 	int old_keycode;
 	int retval;
 
-	if (scancode < 0)
-		return -EINVAL;
-
 	if (keycode < 0 || keycode > KEY_MAX)
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev->event_lock, flags);
 
-	retval = dev->getkeycode(dev, scancode, &old_keycode);
-	if (retval)
-		goto out;
+	if (dev->getkeycode) {
+		/*
+		 * Use the legacy calls
+		 */
+		retval = dev->getkeycode(dev, scancode, &old_keycode);
+		if (retval)
+			goto out;
 
-	retval = dev->setkeycode(dev, scancode, keycode);
-	if (retval)
-		goto out;
+		retval = dev->setkeycode(dev, scancode, keycode);
+		if (retval)
+			goto out;
+	} else {
+		char char_scan[4];
+		struct keycode_table_entry kt_entry;
+
+		/*
+		 * Userspace is using a legacy call with a driver ported
+		 * to the new way. This is a bad idea with long sparsed
+		 * tables, since lots of the retrieved values will be in
+		 * blank. Also, it makes sense only if the table size is
+		 * lower than 2^32.
+		 */
+		memset(&kt_entry, 0, sizeof(kt_entry));
+		kt_entry.len = 32;
+		kt_entry.index = scancode;
+		kt_entry.scancode = char_scan;
+
+		retval = dev->getkeycodebig(dev, &kt_entry);
+		if (retval)
+			goto out;
+
+		kt_entry.keycode = keycode;
+
+		retval = dev->setkeycodebig(dev, &kt_entry);
+		if (retval)
+			goto out;
+	}
 
 	/*
 	 * Simulate keyup event if keycode is not present
@@ -1585,11 +1768,11 @@ int input_register_device(struct input_dev *dev)
 		dev->rep[REP_PERIOD] = 33;
 	}
 
-	if (!dev->getkeycode)
-		dev->getkeycode = input_default_getkeycode;
+	if (!dev->getkeycodebig)
+		dev->getkeycodebig = input_default_getkeycode;
 
-	if (!dev->setkeycode)
-		dev->setkeycode = input_default_setkeycode;
+	if (!dev->setkeycodebig)
+		dev->setkeycodebig = input_default_setkeycode;
 
 	dev_set_name(&dev->dev, "input%ld",
 		     (unsigned long) atomic_inc_return(&input_no) - 1);
diff --git a/include/linux/input.h b/include/linux/input.h
index 663208a..1f86f70 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -34,7 +34,7 @@ struct input_event {
  * Protocol version.
  */
 
-#define EV_VERSION		0x010000
+#define EV_VERSION		0x010001
 
 /*
  * IOCTLs (0x00 - 0x7f)
@@ -56,12 +56,22 @@ struct input_absinfo {
 	__s32 resolution;
 };
 
+struct keycode_table_entry {
+	__u32 keycode;	/* e.g. KEY_A */
+	__u32 index;		/* Index for the given scan/key table */
+	__u32 len;		/* Lenght of the scancode */
+	__u32 reserved[2];	/* Reserved for future usage */
+	char *scancode;		/* scancode, in machine-endian */
+};
+
 #define EVIOCGVERSION		_IOR('E', 0x01, int)			/* get driver version */
 #define EVIOCGID		_IOR('E', 0x02, struct input_id)	/* get device ID */
 #define EVIOCGREP		_IOR('E', 0x03, int[2])			/* get repeat settings */
 #define EVIOCSREP		_IOW('E', 0x03, int[2])			/* set repeat settings */
 #define EVIOCGKEYCODE		_IOR('E', 0x04, int[2])			/* get keycode */
 #define EVIOCSKEYCODE		_IOW('E', 0x04, int[2])			/* set keycode */
+#define EVIOCGKEYCODEBIG	_IOR('E', 0x04, struct keycode_table_entry) /* get keycode */
+#define EVIOCSKEYCODEBIG	_IOW('E', 0x04, struct keycode_table_entry) /* set keycode */
 
 #define EVIOCGNAME(len)		_IOC(_IOC_READ, 'E', 0x06, len)		/* get device name */
 #define EVIOCGPHYS(len)		_IOC(_IOC_READ, 'E', 0x07, len)		/* get physical location */
@@ -1022,11 +1032,15 @@ struct ff_effect {
  * @keycodemax: size of keycode table
  * @keycodesize: size of elements in keycode table
  * @keycode: map of scancodes to keycodes for this device
- * @setkeycode: optional method to alter current keymap, used to implement
+ * @setkeycode: optional legacy method to alter current keymap, used to
+ *	implement sparse keymaps. Shouldn't be used on new drivers
+ * @getkeycode: optional legacy method to retrieve current keymap.
+ *	Shouldn't be used on new drivers.
+ * @setkeycodebig: optional method to alter current keymap, used to implement
  *	sparse keymaps. If not supplied default mechanism will be used.
  *	The method is being called while holding event_lock and thus must
  *	not sleep
- * @getkeycode: optional method to retrieve current keymap. If not supplied
+ * @getkeycodebig: optional method to retrieve current keymap. If not supplied
  *	default mechanism will be used. The method is being called while
  *	holding event_lock and thus must not sleep
  * @ff: force feedback structure associated with the device if device
@@ -1101,6 +1115,10 @@ struct input_dev {
 	void *keycode;
 	int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
 	int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);
+	int (*setkeycodebig)(struct input_dev *dev,
+			     struct keycode_table_entry *kt_entry);
+	int (*getkeycodebig)(struct input_dev *dev,
+			     struct keycode_table_entry *kt_entry);
 
 	struct ff_device *ff;
 
@@ -1366,6 +1384,11 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
 
 int input_get_keycode(struct input_dev *dev, int scancode, int *keycode);
 int input_set_keycode(struct input_dev *dev, int scancode, int keycode);
+int input_get_keycode_big(struct input_dev *dev,
+			  struct keycode_table_entry *kt_entry);
+int input_set_keycode_big(struct input_dev *dev,
+			  struct keycode_table_entry *kt_entry);
+
 
 extern struct class input_class;
 

WARNING: multiple messages have this Message-ID (diff)
From: Mauro Carvalho Chehab <mchehab@redhat.com>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Jon Smirl <jonsmirl@gmail.com>, Pavel Machek <pavel@ucw.cz>,
	Krzysztof Halasa <khc@pm.waw.pl>,
	hermann pitton <hermann-pitton@arcor.de>,
	Christoph Bartelmus <lirc@bartelmus.de>,
	awalls@radix.net, j@jannau.net, jarod@redhat.com,
	jarod@wilsonet.com, kraxel@redhat.com,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-media@vger.kernel.org, superm1@ubuntu.com
Subject: Re: [RFC] What are the goals for the architecture of an in-kernel IR system?
Date: Sun, 28 Mar 2010 20:22:31 -0300	[thread overview]
Message-ID: <4BAFE4B7.2030204@redhat.com> (raw)
In-Reply-To: <20100326160150.GA28804@core.coreip.homeip.net>

Dmitry Torokhov wrote:
> On Fri, Mar 26, 2010 at 11:40:41AM -0300, Mauro Carvalho Chehab wrote:
>> David Härdeman wrote:
>>> On Thu, Mar 25, 2010 at 11:42:33AM -0300, Mauro Carvalho Chehab wrote:
>>>>>        10) extend keycode table replacement to support big/variable 
>>>>>        sized scancodes;
>>>> Pending.
>>>>
>>>> The current limit here is the scancode ioctl's are defined as:
>>>>
>>>> #define EVIOCGKEYCODE           _IOR('E', 0x04, int[2])                 /* get keycode */
>>>> #define EVIOCSKEYCODE           _IOW('E', 0x04, int[2])                 /* set keycode */
>>>>
>>>> As int size is 32 bits, and we must pass both 64 (or even bigger) scancodes, associated
>>>> with a keycode, there's not enough bits there for IR.
>>>>
>>>> The better approach seems to create an struct with an arbitrary long size, like:
>>>>
>>>> struct keycode_table_entry {
>>>> 	unsigned keycode;
>>>> 	char scancode[32];	/* 32 is just an arbitrary long array - maybe shorter */
>>>> 	int len;
>>>> }
>>>>
>>>> and re-define the ioctls. For example we might be doing:
>>>>
>>>> #define EVIOCGKEYCODEBIG           _IOR('E', 0x04, struct keycode_table_entry)
>>>> #define EVIOCSKEYCODEBIG           _IOW('E', 0x04, struct keycode_table_entry)
>>>> #define EVIOCLEARKEYCODEBIG        _IOR('E', 0x04, void)
>>>>
>>>> Provided that the size for struct keycode_table_entry is different, _IO will generate
>>>> a different magic number for those.
>>>>
>>>> Or, instead of using 0x04, just use another sequential number at the 'E' namespace.
>>>>
>>>> An specific function to clear the table is needed with big scancode space,
>>>> as already discussed.
>>>>
>>> I'd suggest:
>>>
>>> struct keycode_table_entry {
>>> 	unsigned keycode;
>>> 	unsigned index;
>>> 	unsigned len;
>>> 	char scancode[];
>>> };
>>>
>>> Use index in EVIOCGKEYCODEBIG to look up a keycode (all other fields are 
>>> ignored), that way no special function to clear the table is necessary, 
>>> instead you do a loop with:
>>>
>>> EVIOCGKEYCODEBIG (with index 0)
>>> EVIOCSKEYCODEBIG (with the returned struct from EVIOCGKEYCODEBIG and
>>> 		  keycode = KEY_RESERVED)
>>>
>>> until EVIOCGKEYCODEBIG returns an error.
>> Makes sense.
> 
> Yes, I think so too. Just need a nice way to handle transition, I'd
> like in the end to have drivers implement only the improved methods and
> map legacy methods in evdev.

See the attached RFC barely tested patch. 

On this patch, I'm using the following definitions for the ioctl:

struct keycode_table_entry {
	__u32 keycode;		/* e.g. KEY_A */
	__u32 index;		/* Index for the given scan/key table */
	__u32 len;		/* Lenght of the scancode */
	__u32 reserved[2];	/* Reserved for future usage */
	char *scancode;		/* scancode, in machine-endian */
};

#define EVIOCGKEYCODEBIG	_IOR('E', 0x04, struct keycode_table_entry) /* get keycode */
#define EVIOCSKEYCODEBIG	_IOW('E', 0x04, struct keycode_table_entry) /* set keycode */


I tried to do the compat backport on a nice way, on both directions, e. g.:

1) an userspace app using EVIO[CS]GKEYCODEBIG to work with a legacy driver.
2) a driver implementing the new methods to accept the legacy EVIO[CS]GKEYCODE;

For the test of (1), I implemented the following clear keytable code:

	struct keycode_table_entry      kt;
        uint32_t                        scancode, i;

        memset(&kt, 0, sizeof(kt));
        kt.len = sizeof(scancode);
        kt.scancode = (char *)&scancode;

        for (i = 0; rc == 0; i++) {
        	kt.index = i;
        	kt.keycode = KEY_RESERVED;
                rc = ioctl(fd, EVIOCSKEYCODEBIG, &kt);
        }
        fprintf(stderr, "Cleaned %i keycode(s)\n", i - 1);

It worked properly. I didn't test (2) yet.

The read keytable would also be trivial. However, there are some troubles when
implementing the code to add/replace a value at the table, in a way that it
would allow the legacy drivers to work:

- With a real CODEBIG support, the index number will be different than the
scancode number. So, let's say that this is the driver table:

index	scancode keycode
------------------------
0	0x1e00	 KEY_0
1	0x1e01	 KEY_1
2	0x1e02	 KEY_2
3	0x1e03	 KEY_3
4	0x1e04	 KEY_4
5	0x1e05	 KEY_5
6	0x1e06	 KEY_6
7	0x1e07	 KEY_7
8	0x1e08	 KEY_8
9	0x1e09	 KEY_9

Let's suppose that the user wants to overwrite the entry 5, attributing a new scancode/keycode
to entry 5 (for example, associating 0x1e0a with KEY-A).

A valid EVIOCSKEYCODEBIG call to change this code would be:

	kt->index = 5;
	*(uint32_t *)kt->scancode = 0x1e0a;
	*(uint32_t *)kt->keycode = KEY_A;
	rc = ioctl(fd, EVIOCSKEYCODEBIG, &kt);

With EVIOCSKEYCODE, this requires two separate operations:

	int codes[2];
	code[0] = 0x1e05;
	code[1] = KEY_RESERVED;
	rc = ioctl(fd, EVIOCSKEYCODE, &codes];

	code[0] = 0x1e0a;
	code[1] = KEY_A;
	rc = ioctl(fd, EVIOCSKEYCODE, &codes];


In the case of EVIOCSKEYCODEBIG call, the driver will need to:

1) Check If the scancode is not being used yet on any entry different than index=5.
If it is in use, it should return an error. 
If not, replace the scancode/keycode.

2) Check if index is equal to the length of the array + 1. If so, create a new entry.

3) check if the index is bigger than length + 1 and return an error, if so.

For the EVIOSKEYCODE emulation by an EVIOCSKEYCODEBIG driver, index=5 won't work.
The driver will need to use the scancode. However, if we do this way, the
cleanup logic will break, as scancode is equal to zero.

So, I think that having an index here is not a good idea: it will just create some
implementation troubles. We can archive the same result without the index, and having
a fast clean_table code by just reading the used scancodes and associating them
with KEY_RESERVED.

So, I'll be working on another patch with this different implementation.

I also noticed another problem: kernel should have some way to report the expected
size of the scancode to userspace, especially if we want to have the compatibility
code (since, with compat, a scancode maximum size need to be 32 bits, otherwise
the code won't work).

I'll likely adding another control that returns the size of the scancode.

Comments?

Cheers,
Mauro


---


This is the RFC patch I wrote here for my tests.

commit 6bf412eedaa05f28d5ce50795d3ac64ec41c3031
Author: Mauro Carvalho Chehab <mchehab@redhat.com>
Date:   Sun Mar 28 04:02:36 2010 -0300

    input: Add support for EVIO[CS]GKEYCODEBIG
    
    Several devices use a high number of bits for scancodes. One important
    group is the Remote Controllers. Some new protocols like RC-6 define a
    scancode space of 64 bits.
    
    The current EVIO[CS]GKEYCODE ioctls allow replace the scancode/keycode
    translation tables, but it is limited to up to 32 bits for scancode.
    
    Also, if userspace wants to clean the existing table, replacing it by
    a new one, it needs to run a loop calling the old ioctls, over the
    entire sparsed scancode userspace.
    
    To solve those problems, this patch introduces two new ioctls:
    	EVIOCGKEYCODEBIG - reads a scancode from the translation table;
    	EVIOSGKEYCODEBIG - writes a scancode into the translation table.
    
    The EVIOSGKEYCODEBIG can also be used to cleanup the translation entries
    by associating KEY_RESERVED to a scancode.
    
    By default, kernel will implement a default handler that will work with
    both EVIO[CS]GKEYCODEBIG and the legacy EVIO[CS]GKEYCODE ioctls.
    
    Compatibility code were also added to allow drivers that implement
    only the ops handler for EVIO[CS]GKEYCODE to keep working.
    
    Userspace compatibility for EVIO[CS]GKEYCODE is also granted: the evdev/input
    ioctl handler will automatically map those ioctls with the new
    getkeycodebig()/setkeycodebig() operations to handle a request using the
    legacy API.
    
    So, new drivers should only implement the EVIO[CS]GKEYCODEBIG operation
    handlers: getkeycodebig()/setkeycodebig().
    
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 258c639..aed5acc 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -513,6 +513,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 	struct input_absinfo abs;
 	struct ff_effect effect;
 	int __user *ip = (int __user *)p;
+	struct keycode_table_entry __user *kt = p;
 	int i, t, u, v;
 	int error;
 
@@ -567,6 +568,25 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 
 		return input_set_keycode(dev, t, v);
 
+	case EVIOCGKEYCODEBIG:
+		if (copy_from_user(kt, &dev->id, _IOC_SIZE(cmd)))
+			return -EFAULT;
+
+		error = input_get_keycode_big(dev, kt);
+		if (error)
+			return error;
+
+		if (copy_to_user(kt, &dev->id, _IOC_SIZE(cmd)))
+			return -EFAULT;
+
+		return 0;
+
+	case EVIOCSKEYCODEBIG:
+		if (copy_from_user(p, &dev->id, _IOC_SIZE(cmd)))
+			return -EFAULT;
+
+		return input_set_keycode_big(dev, kt);
+
 	case EVIOCRMFF:
 		return input_ff_erase(dev, (int)(unsigned long) p, file);
 
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 86cb2d2..0437c75 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -551,6 +551,11 @@ static void input_disconnect_device(struct input_dev *dev)
 	spin_unlock_irq(&dev->event_lock);
 }
 
+/*
+ * Those routines handle the default case where no [gs]etkeycode() is
+ * defined. In this case, an array indexed by the scancode is used.
+ */
+
 static int input_fetch_keycode(struct input_dev *dev, int scancode)
 {
 	switch (dev->keycodesize) {
@@ -566,57 +571,88 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode)
 }
 
 static int input_default_getkeycode(struct input_dev *dev,
-				    int scancode, int *keycode)
+				    struct keycode_table_entry *kt_entry)
 {
 	if (!dev->keycodesize)
 		return -EINVAL;
 
-	if (scancode >= dev->keycodemax)
+	if (kt_entry->index >= dev->keycodemax)
 		return -EINVAL;
 
-	*keycode = input_fetch_keycode(dev, scancode);
+	/*
+	 * Supports only 8, 16 and 32 bit scancodes. It wouldn't be that
+	 * hard to write some machine-endian logic to support 24 bit scancodes,
+	 * but it seemed overkill. It should also be noticed that, since there
+	 * are, in general, less than 256 scancodes sparsed into the scancode
+	 * space, even with 16 bits, the codespace is sparsed, with leads into
+	 * memory and code ineficiency, when retrieving the entire scancode
+	 * space.
+	 * So, it is highly recommended to implement getkeycodebig/setkeycodebig
+	 * instead of using a normal table approach, when more than 8 bits is
+	 * needed for the scancode.
+	 *
+	 */
+	switch (kt_entry->len) {
+	case 1:
+		if (kt_entry->index > ((1 << 8) - 1))
+			return -EINVAL;
+		*((u8 *)kt_entry->scancode) = (u8)kt_entry->index;
+		break;
+	case 2:
+		if (kt_entry->index > ((1 << 16) - 1))
+			return -EINVAL;
+		*((u16 *)kt_entry->scancode) = (u16)kt_entry->index;
+		break;
+	case 4:
+		*((u32 *)kt_entry->scancode) = kt_entry->index;
+		break;
+	default:
+		return -EINVAL;
+	}
+	kt_entry->keycode = input_fetch_keycode(dev, kt_entry->index);
 
 	return 0;
 }
 
 static int input_default_setkeycode(struct input_dev *dev,
-				    int scancode, int keycode)
+				    struct keycode_table_entry *kt_entry)
 {
 	int old_keycode;
 	int i;
 
-	if (scancode >= dev->keycodemax)
+	if (kt_entry->index >= dev->keycodemax)
 		return -EINVAL;
 
 	if (!dev->keycodesize)
 		return -EINVAL;
 
-	if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
+	if (dev->keycodesize < sizeof(dev->keycode) &&
+	    (kt_entry->keycode >> (dev->keycodesize * 8)))
 		return -EINVAL;
 
 	switch (dev->keycodesize) {
 		case 1: {
 			u8 *k = (u8 *)dev->keycode;
-			old_keycode = k[scancode];
-			k[scancode] = keycode;
+			old_keycode = k[kt_entry->index];
+			k[kt_entry->index] = kt_entry->keycode;
 			break;
 		}
 		case 2: {
 			u16 *k = (u16 *)dev->keycode;
-			old_keycode = k[scancode];
-			k[scancode] = keycode;
+			old_keycode = k[kt_entry->index];
+			k[kt_entry->index] = kt_entry->keycode;
 			break;
 		}
 		default: {
 			u32 *k = (u32 *)dev->keycode;
-			old_keycode = k[scancode];
-			k[scancode] = keycode;
+			old_keycode = k[kt_entry->index];
+			k[kt_entry->index] = kt_entry->keycode;
 			break;
 		}
 	}
 
 	clear_bit(old_keycode, dev->keybit);
-	set_bit(keycode, dev->keybit);
+	set_bit(kt_entry->keycode, dev->keybit);
 
 	for (i = 0; i < dev->keycodemax; i++) {
 		if (input_fetch_keycode(dev, i) == old_keycode) {
@@ -629,6 +665,103 @@ static int input_default_setkeycode(struct input_dev *dev,
 }
 
 /**
+ * input_get_keycode_big - retrieve keycode currently mapped to a given scancode
+ * @dev: input device which keymap is being queried
+ * @kt_entry: keytable entry
+ *
+ * This function should be called by anyone interested in retrieving current
+ * keymap. Presently evdev handlers use it.
+ */
+int input_get_keycode_big(struct input_dev *dev,
+			  struct keycode_table_entry *kt_entry)
+{
+	if (dev->getkeycode) {
+		/*
+		 * Support for legacy drivers, that don't implement the new
+		 * ioctls: use index=scancode, just like the default methods
+		 */
+		return dev->getkeycode(dev, kt_entry->index,
+				       &kt_entry->keycode);
+	} else
+		return dev->getkeycodebig(dev, kt_entry);
+}
+EXPORT_SYMBOL(input_get_keycode_big);
+
+/**
+ * input_set_keycode_big - attribute a keycode to a given scancode
+ * @dev: input device which keymap is being queried
+ * @kt_entry: keytable entry
+ *
+ * This function should be called by anyone needing to update current
+ * keymap. Presently keyboard and evdev handlers use it.
+ */
+int input_set_keycode_big(struct input_dev *dev,
+			  struct keycode_table_entry *kt_entry)
+{
+	unsigned long flags;
+	int new_keycode, old_keycode;
+	int retval = -EINVAL;
+
+	if (kt_entry->keycode < 0 || kt_entry->keycode > KEY_MAX)
+		return -EINVAL;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	new_keycode = kt_entry->keycode;
+
+	/*
+	 * We need to know the old scancode, in order to generate a
+	 * keyup effect, if the set operation happens successfully
+	 */
+	if (dev->getkeycode) {
+		/*
+		 * Support for legacy drivers, that don't implement the new
+		 * ioctls: use index=scancode, just like the default methods
+		 * If setkeycode is not defined, just return.
+		 */
+		if (!dev->setkeycode)
+			goto out;
+
+		retval = dev->getkeycode(dev, kt_entry->index,
+					 &kt_entry->keycode);
+	} else
+		retval = dev->getkeycodebig(dev, kt_entry);
+
+	old_keycode = kt_entry->keycode;
+	kt_entry->keycode = new_keycode;
+
+	if (retval)
+		goto out;
+
+	if (dev->getkeycode)
+		retval = dev->setkeycode(dev, kt_entry->index,
+					 kt_entry->keycode);
+	else
+		retval = dev->setkeycodebig(dev, kt_entry);
+	if (retval)
+		goto out;
+
+	/*
+	 * Simulate keyup event if keycode is not present
+	 * in the keymap anymore
+	 */
+	if (test_bit(EV_KEY, dev->evbit) &&
+	    !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
+	    __test_and_clear_bit(old_keycode, dev->key)) {
+
+		input_pass_event(dev, EV_KEY, old_keycode, 0);
+		if (dev->sync)
+			input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+	}
+
+ out:
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	return retval;
+}
+EXPORT_SYMBOL(input_set_keycode_big);
+
+/**
  * input_get_keycode - retrieve keycode currently mapped to a given scancode
  * @dev: input device which keymap is being queried
  * @scancode: scancode (or its equivalent for device in question) for which
@@ -640,10 +773,33 @@ static int input_default_setkeycode(struct input_dev *dev,
  */
 int input_get_keycode(struct input_dev *dev, int scancode, int *keycode)
 {
-	if (scancode < 0)
-		return -EINVAL;
+	if (dev->getkeycode) {
+		/*
+		 * Use the legacy calls
+		 */
+		return dev->getkeycode(dev, scancode, keycode);
+	} else {
+		int retval;
+		char char_scan[4];
+		struct keycode_table_entry kt_entry;
+
+		/*
+		 * Userspace is using a legacy call with a driver ported
+		 * to the new way. This is a bad idea with long sparsed
+		 * tables, since lots of the retrieved values will be in
+		 * blank. Also, it makes sense only if the table size is
+		 * lower than 2^32.
+		 */
+		memset(&kt_entry, 0, sizeof(kt_entry));
+		kt_entry.len = 32;
+		kt_entry.index = scancode;
+		kt_entry.scancode = char_scan;
+
+		retval = dev->getkeycodebig(dev, &kt_entry);
 
-	return dev->getkeycode(dev, scancode, keycode);
+		*keycode = kt_entry.keycode;
+		return retval;
+	}
 }
 EXPORT_SYMBOL(input_get_keycode);
 
@@ -662,21 +818,48 @@ int input_set_keycode(struct input_dev *dev, int scancode, int keycode)
 	int old_keycode;
 	int retval;
 
-	if (scancode < 0)
-		return -EINVAL;
-
 	if (keycode < 0 || keycode > KEY_MAX)
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev->event_lock, flags);
 
-	retval = dev->getkeycode(dev, scancode, &old_keycode);
-	if (retval)
-		goto out;
+	if (dev->getkeycode) {
+		/*
+		 * Use the legacy calls
+		 */
+		retval = dev->getkeycode(dev, scancode, &old_keycode);
+		if (retval)
+			goto out;
 
-	retval = dev->setkeycode(dev, scancode, keycode);
-	if (retval)
-		goto out;
+		retval = dev->setkeycode(dev, scancode, keycode);
+		if (retval)
+			goto out;
+	} else {
+		char char_scan[4];
+		struct keycode_table_entry kt_entry;
+
+		/*
+		 * Userspace is using a legacy call with a driver ported
+		 * to the new way. This is a bad idea with long sparsed
+		 * tables, since lots of the retrieved values will be in
+		 * blank. Also, it makes sense only if the table size is
+		 * lower than 2^32.
+		 */
+		memset(&kt_entry, 0, sizeof(kt_entry));
+		kt_entry.len = 32;
+		kt_entry.index = scancode;
+		kt_entry.scancode = char_scan;
+
+		retval = dev->getkeycodebig(dev, &kt_entry);
+		if (retval)
+			goto out;
+
+		kt_entry.keycode = keycode;
+
+		retval = dev->setkeycodebig(dev, &kt_entry);
+		if (retval)
+			goto out;
+	}
 
 	/*
 	 * Simulate keyup event if keycode is not present
@@ -1585,11 +1768,11 @@ int input_register_device(struct input_dev *dev)
 		dev->rep[REP_PERIOD] = 33;
 	}
 
-	if (!dev->getkeycode)
-		dev->getkeycode = input_default_getkeycode;
+	if (!dev->getkeycodebig)
+		dev->getkeycodebig = input_default_getkeycode;
 
-	if (!dev->setkeycode)
-		dev->setkeycode = input_default_setkeycode;
+	if (!dev->setkeycodebig)
+		dev->setkeycodebig = input_default_setkeycode;
 
 	dev_set_name(&dev->dev, "input%ld",
 		     (unsigned long) atomic_inc_return(&input_no) - 1);
diff --git a/include/linux/input.h b/include/linux/input.h
index 663208a..1f86f70 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -34,7 +34,7 @@ struct input_event {
  * Protocol version.
  */
 
-#define EV_VERSION		0x010000
+#define EV_VERSION		0x010001
 
 /*
  * IOCTLs (0x00 - 0x7f)
@@ -56,12 +56,22 @@ struct input_absinfo {
 	__s32 resolution;
 };
 
+struct keycode_table_entry {
+	__u32 keycode;	/* e.g. KEY_A */
+	__u32 index;		/* Index for the given scan/key table */
+	__u32 len;		/* Lenght of the scancode */
+	__u32 reserved[2];	/* Reserved for future usage */
+	char *scancode;		/* scancode, in machine-endian */
+};
+
 #define EVIOCGVERSION		_IOR('E', 0x01, int)			/* get driver version */
 #define EVIOCGID		_IOR('E', 0x02, struct input_id)	/* get device ID */
 #define EVIOCGREP		_IOR('E', 0x03, int[2])			/* get repeat settings */
 #define EVIOCSREP		_IOW('E', 0x03, int[2])			/* set repeat settings */
 #define EVIOCGKEYCODE		_IOR('E', 0x04, int[2])			/* get keycode */
 #define EVIOCSKEYCODE		_IOW('E', 0x04, int[2])			/* set keycode */
+#define EVIOCGKEYCODEBIG	_IOR('E', 0x04, struct keycode_table_entry) /* get keycode */
+#define EVIOCSKEYCODEBIG	_IOW('E', 0x04, struct keycode_table_entry) /* set keycode */
 
 #define EVIOCGNAME(len)		_IOC(_IOC_READ, 'E', 0x06, len)		/* get device name */
 #define EVIOCGPHYS(len)		_IOC(_IOC_READ, 'E', 0x07, len)		/* get physical location */
@@ -1022,11 +1032,15 @@ struct ff_effect {
  * @keycodemax: size of keycode table
  * @keycodesize: size of elements in keycode table
  * @keycode: map of scancodes to keycodes for this device
- * @setkeycode: optional method to alter current keymap, used to implement
+ * @setkeycode: optional legacy method to alter current keymap, used to
+ *	implement sparse keymaps. Shouldn't be used on new drivers
+ * @getkeycode: optional legacy method to retrieve current keymap.
+ *	Shouldn't be used on new drivers.
+ * @setkeycodebig: optional method to alter current keymap, used to implement
  *	sparse keymaps. If not supplied default mechanism will be used.
  *	The method is being called while holding event_lock and thus must
  *	not sleep
- * @getkeycode: optional method to retrieve current keymap. If not supplied
+ * @getkeycodebig: optional method to retrieve current keymap. If not supplied
  *	default mechanism will be used. The method is being called while
  *	holding event_lock and thus must not sleep
  * @ff: force feedback structure associated with the device if device
@@ -1101,6 +1115,10 @@ struct input_dev {
 	void *keycode;
 	int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
 	int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);
+	int (*setkeycodebig)(struct input_dev *dev,
+			     struct keycode_table_entry *kt_entry);
+	int (*getkeycodebig)(struct input_dev *dev,
+			     struct keycode_table_entry *kt_entry);
 
 	struct ff_device *ff;
 
@@ -1366,6 +1384,11 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
 
 int input_get_keycode(struct input_dev *dev, int scancode, int *keycode);
 int input_set_keycode(struct input_dev *dev, int scancode, int keycode);
+int input_get_keycode_big(struct input_dev *dev,
+			  struct keycode_table_entry *kt_entry);
+int input_set_keycode_big(struct input_dev *dev,
+			  struct keycode_table_entry *kt_entry);
+
 
 extern struct class input_class;
 
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2010-03-28 23:23 UTC|newest]

Thread overview: 358+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-27 15:57 [RFC] What are the goals for the architecture of an in-kernel IR system? Jon Smirl
2009-11-27 15:57 ` Jon Smirl
2009-11-27 16:57 ` Andy Walls
2009-11-27 17:29 ` Christoph Bartelmus
2009-11-27 17:29   ` Christoph Bartelmus
2009-11-27 17:49   ` Jon Smirl
2009-11-27 17:49     ` Jon Smirl
2009-11-27 19:03     ` Ferenc Wagner
2009-11-27 19:21       ` Jon Smirl
2009-11-27 19:21         ` Jon Smirl
2009-11-28  1:34         ` Dmitry Torokhov
2009-11-29 12:01     ` Christoph Bartelmus
2009-11-29 12:01       ` Christoph Bartelmus
2009-11-30 10:41       ` Mauro Carvalho Chehab
2009-11-30 19:49         ` Krzysztof Halasa
2009-11-30 21:35       ` Jon Smirl
2009-11-30 21:35         ` Jon Smirl
2009-12-01  7:45         ` Christoph Bartelmus
2009-12-01  7:45           ` Christoph Bartelmus
2009-12-01 11:38           ` Andy Walls
2009-12-01 14:10             ` Maxim Levitsky
2009-12-03 17:31           ` Krzysztof Halasa
2009-12-03 17:31             ` Krzysztof Halasa
2009-11-28  9:04   ` Simon Kenyon
2009-11-28  9:04     ` Simon Kenyon
2009-11-28  9:04     ` Simon Kenyon
2009-11-28 11:21   ` Mauro Carvalho Chehab
2009-11-29 11:50     ` Christoph Bartelmus
2009-11-29 11:50       ` Christoph Bartelmus
2009-11-30 12:34       ` Mauro Carvalho Chehab
2009-12-01  9:52         ` Gerd Hoffmann
2009-12-01 13:11           ` Mauro Carvalho Chehab
2009-12-01 14:32           ` Jarod Wilson
2009-12-01 10:20       ` Gerd Hoffmann
2009-12-01 14:14         ` Mauro Carvalho Chehab
2009-12-01 15:28           ` Gerd Hoffmann
2009-12-03  4:29             ` Jarod Wilson
2009-12-03 12:09               ` Gerd Hoffmann
2009-12-03 17:55                 ` Dmitry Torokhov
2009-12-03 18:33                   ` Mauro Carvalho Chehab
2009-12-04 10:06                     ` Dmitry Torokhov
2009-12-04 14:12                       ` Mauro Carvalho Chehab
2009-12-04 15:42                         ` Jon Smirl
2009-12-04 15:42                           ` Jon Smirl
2009-12-06  7:09                         ` Dmitry Torokhov
2009-12-06 11:03                           ` Mauro Carvalho Chehab
2009-12-06 20:19                             ` Krzysztof Halasa
2009-12-08  0:00                               ` Mauro Carvalho Chehab
2009-12-08 14:06                                 ` Krzysztof Halasa
2009-12-07  7:48                             ` Dmitry Torokhov
2009-12-07 15:34                               ` Mauro Carvalho Chehab
2009-12-07 18:34                                 ` Dmitry Torokhov
2009-12-07 23:01                                   ` Mauro Carvalho Chehab
2009-12-06  7:14                         ` Dmitry Torokhov
2009-12-06 11:23                           ` Mauro Carvalho Chehab
2009-12-03 18:56                   ` Jon Smirl
2009-12-03 18:56                     ` Jon Smirl
2009-12-03 18:56                     ` Jon Smirl
2009-12-03 21:10                 ` Mauro Carvalho Chehab
2009-12-03 21:51                   ` Christoph Bartelmus
2009-12-03 21:51                     ` Christoph Bartelmus
2009-12-03 22:12                     ` Dmitry Torokhov
2009-12-04  7:37                       ` Christoph Bartelmus
2009-12-04  7:37                         ` Christoph Bartelmus
2009-12-04 14:33                         ` Mauro Carvalho Chehab
2009-12-04 21:46                           ` Christoph Bartelmus
2009-12-04 21:46                             ` Christoph Bartelmus
2009-12-04 22:07                             ` Dmitry Torokhov
2009-12-04 23:01                               ` Christoph Bartelmus
2009-12-04 23:01                                 ` Christoph Bartelmus
2009-12-04 23:15                                 ` Dmitry Torokhov
2009-12-06 11:58                                   ` Christoph Bartelmus
2009-12-06 11:58                                     ` Christoph Bartelmus
2009-12-07  7:51                                     ` Dmitry Torokhov
2009-12-08 22:27                                       ` Christoph Bartelmus
2009-12-08 22:27                                         ` Christoph Bartelmus
2009-12-05  0:28                                 ` Jon Smirl
2009-12-05  0:28                                   ` Jon Smirl
2009-12-05  1:48                                   ` Andy Walls
2009-12-05  2:10                                     ` Andy Walls
2009-12-05  3:45                                     ` Jon Smirl
2009-12-05  3:45                                       ` Jon Smirl
2009-12-06  2:30                                       ` Andy Walls
2009-12-06 17:26                                         ` Krzysztof Halasa
2009-12-12 22:52                                           ` david
2009-12-06  3:36                                   ` hermann pitton
2009-12-06  6:55                                     ` Dmitry Torokhov
2009-12-06 11:46                                       ` Mauro Carvalho Chehab
2009-12-06 17:48                                         ` Krzysztof Halasa
2009-12-06 17:52                                           ` Jon Smirl
2009-12-06 17:52                                             ` Jon Smirl
2009-12-06 20:34                                             ` Krzysztof Halasa
2009-12-06 21:23                                               ` Jon Smirl
2009-12-06 21:23                                                 ` Jon Smirl
2009-12-07 23:44                                                 ` Mauro Carvalho Chehab
2009-12-08  0:28                                                   ` Jon Smirl
2009-12-08  0:28                                                     ` Jon Smirl
2009-12-08  0:28                                                     ` Jon Smirl
2009-12-08 11:17                                                     ` Mauro Carvalho Chehab
2009-12-08 13:34                                                       ` Jon Smirl
2009-12-08 13:34                                                         ` Jon Smirl
2009-12-08 13:34                                                         ` Jon Smirl
2009-12-08 14:56                                                         ` Mauro Carvalho Chehab
2009-12-08 22:25                                                         ` Christoph Bartelmus
2009-12-08 22:25                                                           ` Christoph Bartelmus
2009-12-08 17:04                                                       ` Dmitry Torokhov
2009-12-08 13:54                                                     ` Krzysztof Halasa
2009-12-08  4:23                                                   ` Dmitry Torokhov
2009-12-08 11:58                                                     ` Mauro Carvalho Chehab
2009-12-08 14:01                                                       ` Krzysztof Halasa
2009-12-08 14:13                                                         ` Mauro Carvalho Chehab
2009-12-08 15:26                                                           ` Krzysztof Halasa
2009-12-08 15:41                                                             ` Mauro Carvalho Chehab
2009-12-08 17:12                                                       ` Dmitry Torokhov
2009-12-08 13:57                                                     ` Krzysztof Halasa
2009-12-08 17:25                                                       ` Dmitry Torokhov
2009-12-08 13:52                                                   ` Krzysztof Halasa
2009-12-08 14:07                                                     ` Mauro Carvalho Chehab
2009-12-08 14:51                                                       ` Jon Smirl
2009-12-08 14:51                                                         ` Jon Smirl
2009-12-08 15:29                                                       ` Krzysztof Halasa
2009-12-08 15:49                                                         ` Mauro Carvalho Chehab
2009-12-08 16:26                                                           ` Jon Smirl
2009-12-08 16:26                                                             ` Jon Smirl
2009-12-08  4:10                                                 ` Andy Walls
2009-12-08 22:30                                                   ` Christoph Bartelmus
2009-12-08 22:30                                                     ` Christoph Bartelmus
2009-12-09  2:21                                                     ` Andy Walls
2009-12-07 18:41                                               ` Dmitry Torokhov
2009-12-07 20:08                                                 ` Krzysztof Halasa
2009-12-07 21:38                                                   ` Dmitry Torokhov
2009-12-08 15:24                                                     ` Krzysztof Halasa
2009-12-08  0:44                                                 ` Jon Smirl
2009-12-08  0:44                                                   ` Jon Smirl
2009-12-08 11:23                                                   ` Mauro Carvalho Chehab
2009-12-13 12:14                                                 ` Mauro Carvalho Chehab
2009-12-15 11:50                                                   ` Pavel Machek
2009-12-15 13:33                                                     ` Mauro Carvalho Chehab
2009-12-15 13:43                                                       ` Jon Smirl
2009-12-15 13:43                                                         ` Jon Smirl
2009-12-15 13:43                                                         ` Jon Smirl
2009-12-15 14:19                                                         ` Mauro Carvalho Chehab
2009-12-15 19:58                                                       ` Pavel Machek
2009-12-15 20:14                                                         ` Jon Smirl
2009-12-15 20:14                                                           ` Jon Smirl
2009-12-15 20:19                                                           ` Pavel Machek
2009-12-15 20:19                                                             ` Pavel Machek
2009-12-15 20:29                                                             ` Jon Smirl
2009-12-15 20:29                                                               ` Jon Smirl
2009-12-15 20:33                                                               ` Pavel Machek
2009-12-15 20:45                                                                 ` Jon Smirl
2009-12-15 20:45                                                                   ` Jon Smirl
2009-12-15 20:45                                                                   ` Jon Smirl
2009-12-15 21:05                                                                   ` Pavel Machek
2009-12-15 21:05                                                                     ` Pavel Machek
2009-12-15 21:38                                                                   ` Jon Smirl
2009-12-15 21:38                                                                     ` Jon Smirl
2010-03-25 14:42                                                                     ` Mauro Carvalho Chehab
2010-03-25 18:32                                                                       ` Pavel Machek
2010-03-25 19:00                                                                         ` Mauro Carvalho Chehab
2010-03-26 11:04                                                                         ` David Härdeman
2010-03-26 11:04                                                                           ` David Härdeman
2010-03-26 11:27                                                                       ` David Härdeman
2010-03-26 11:27                                                                         ` David Härdeman
2010-03-26 14:40                                                                         ` Mauro Carvalho Chehab
2010-03-26 14:40                                                                           ` Mauro Carvalho Chehab
2010-03-26 16:01                                                                           ` Dmitry Torokhov
2010-03-26 16:01                                                                             ` Dmitry Torokhov
2010-03-26 17:22                                                                             ` Mauro Carvalho Chehab
2010-03-26 19:07                                                                               ` David Härdeman
2010-03-26 19:07                                                                                 ` David Härdeman
2010-03-26 22:37                                                                               ` Jon Smirl
2010-03-26 22:37                                                                                 ` Jon Smirl
2010-03-26 22:37                                                                                 ` Jon Smirl
2010-03-27  8:27                                                                                 ` David Härdeman
2010-03-28 23:22                                                                             ` Mauro Carvalho Chehab [this message]
2010-03-28 23:22                                                                               ` Mauro Carvalho Chehab
2010-03-29  0:51                                                                               ` Mauro Carvalho Chehab
2010-03-30 11:01                                                                                 ` David Härdeman
2010-03-31  6:01                                                                                   ` Mauro Carvalho Chehab
2010-03-31  6:01                                                                                     ` Mauro Carvalho Chehab
2010-03-30 11:09                                                                               ` David Härdeman
2010-03-30 11:09                                                                                 ` David Härdeman
2010-03-30 12:43                                                                                 ` Mauro Carvalho Chehab
2010-03-30 12:43                                                                                 ` Mauro Carvalho Chehab
2010-03-26 12:23                                                                       ` David Härdeman
2010-03-26 15:17                                                                         ` Mauro Carvalho Chehab
2010-03-26 15:17                                                                           ` Mauro Carvalho Chehab
2010-03-26 19:21                                                                           ` David Härdeman
2010-03-26 19:21                                                                             ` David Härdeman
2010-03-27  5:56                                                                             ` Pavel Machek
2010-03-27  5:56                                                                               ` Pavel Machek
2010-04-09  7:21                                                                       ` James Hogan
2010-04-09 10:50                                                                         ` Andy Walls
2010-04-09 12:58                                                                           ` Jarod Wilson
2010-04-09 13:02                                                                             ` Jon Smirl
2010-04-09 13:02                                                                               ` Jon Smirl
2010-04-09 13:02                                                                               ` Jon Smirl
2010-04-09 13:01                                                                           ` Mauro Carvalho Chehab
2010-04-09 21:42                                                                             ` James Hogan
2010-04-09 21:55                                                                             ` Devin Heitmueller
2010-04-09 21:55                                                                               ` Devin Heitmueller
2010-04-09 22:14                                                                               ` Andy Walls
2010-04-09 23:32                                                                                 ` Mauro Carvalho Chehab
2010-04-10  0:18                                                                                   ` Jon Smirl
2010-04-10  0:18                                                                                     ` Jon Smirl
2010-04-10  1:01                                                                                     ` Mauro Carvalho Chehab
2010-04-10  0:38                                                                                   ` hermann pitton
2009-12-07 15:36                                             ` Mauro Carvalho Chehab
2009-12-06 11:59                                       ` Christoph Bartelmus
2009-12-06 11:59                                         ` Christoph Bartelmus
2009-12-15 11:47                                         ` Pavel Machek
2009-12-06 12:12                                   ` Christoph Bartelmus
2009-12-06 12:12                                     ` Christoph Bartelmus
2009-12-06 16:38                                     ` Jon Smirl
2009-12-06 16:38                                       ` Jon Smirl
2009-12-06 16:38                                       ` Jon Smirl
2009-12-06 20:22                                       ` Krzysztof Halasa
2009-12-07 23:50                                     ` Mauro Carvalho Chehab
2009-12-03 23:45                   ` Andy Walls
2009-12-03 17:47             ` Krzysztof Halasa
2009-11-27 21:49 ` Stefan Richter
2009-11-28  1:08   ` Maxim Levitsky
2009-11-28 11:20     ` Krzysztof Halasa
2009-11-28 14:42       ` Maxim Levitsky
2009-11-28 15:25         ` Krzysztof Halasa
2009-11-28 15:35           ` Maxim Levitsky
2009-11-28 15:44             ` Krzysztof Halasa
2009-11-28 16:26               ` Maxim Levitsky
2009-11-28 16:44                 ` Krzysztof Halasa
2009-11-28 16:47               ` Christoph Bartelmus
2009-11-28 16:47                 ` Christoph Bartelmus
2009-11-28 17:06                 ` Jon Smirl
2009-11-28 17:06                   ` Jon Smirl
2009-11-28 17:35                   ` Krzysztof Halasa
2009-11-28 17:37                     ` Jon Smirl
2009-11-28 17:37                       ` Jon Smirl
2009-11-28 17:37                       ` Jon Smirl
2009-11-28 17:40                       ` Krzysztof Halasa
2009-11-28 17:40                         ` Krzysztof Halasa
2009-11-28 23:26                       ` Andy Walls
2009-11-29  4:58                         ` Dmitry Torokhov
2009-11-29 20:27                         ` Krzysztof Halasa
2009-11-29 20:44                           ` Jon Smirl
2009-11-29 20:44                             ` Jon Smirl
2009-11-29 20:44                             ` Jon Smirl
2009-11-29 21:29                             ` Dmitry Torokhov
2009-11-29 21:47                               ` Jon Smirl
2009-11-29 21:47                                 ` Jon Smirl
2009-11-29 22:48                                 ` Dmitry Torokhov
2009-11-29 21:31                           ` Dmitry Torokhov
2009-11-30  4:50                             ` Jarod Wilson
2009-11-30  0:48                           ` Andy Walls
2009-12-01 10:46                             ` Gerd Hoffmann
2009-12-01 11:49                               ` Andy Walls
2009-12-01 14:02                                 ` Gerd Hoffmann
2009-12-01 14:18                                   ` Mauro Carvalho Chehab
2009-11-30 17:45                         ` Lennart Sorensen
2009-11-29  4:32                       ` Andy Walls
2009-11-29  4:50                         ` Dmitry Torokhov
2009-11-29 12:40                         ` Alan Cox
2009-11-29 17:28                           ` Maxim Levitsky
2009-11-29 17:49                             ` Ray Lee
2009-11-29 17:49                               ` Ray Lee
2009-11-29 18:13                               ` Alan Cox
2009-11-29 18:52                                 ` Ray Lee
2009-11-29 18:52                                   ` Ray Lee
2009-11-29 19:04                                   ` Alan Cox
2009-11-29 19:16                                     ` Jon Smirl
2009-11-29 19:16                                       ` Jon Smirl
2009-11-29 19:29                                       ` Alan Cox
2009-11-29 19:49                                       ` Christoph Bartelmus
2009-11-29 19:49                                         ` Christoph Bartelmus
2009-11-30  0:05                                         ` Andy Walls
2009-11-29 23:35                               ` Andy Walls
2009-11-30  2:15                                 ` Ray Lee
2009-11-30  2:15                                   ` Ray Lee
2009-11-30  2:15                                   ` Ray Lee
2009-11-30  9:58                                   ` Artur Skawina
2009-11-30 11:56                                 ` Mauro Carvalho Chehab
2009-11-30 12:57                                   ` Andy Walls
2009-11-30 13:23                                     ` Jon Smirl
2009-11-30 13:23                                       ` Jon Smirl
2009-11-30 13:23                                       ` Jon Smirl
2009-11-30 13:24                                     ` Mauro Carvalho Chehab
2009-11-30 16:14                                       ` kevin granade
2009-11-30 16:14                                         ` kevin granade
2009-11-30 17:33                                         ` Mauro Carvalho Chehab
2009-11-30 18:02                                           ` Dmitry Torokhov
2009-11-30 18:27                                             ` Mauro Carvalho Chehab
2009-11-30 19:07                                               ` Dmitry Torokhov
2009-11-30 20:07                                         ` Krzysztof Halasa
2009-11-30 13:43                                     ` Maxim Levitsky
2009-11-30 14:01                                       ` Jon Smirl
2009-11-30 14:01                                         ` Jon Smirl
2009-11-30 15:04                                         ` Maxim Levitsky
2009-11-30 16:19                                     ` Mauro Carvalho Chehab
2009-11-30 20:03                                     ` Krzysztof Halasa
2009-11-29 18:19                           ` Jon Smirl
2009-11-29 18:19                             ` Jon Smirl
2009-11-29 19:00                             ` Alan Cox
2009-11-30  9:57                               ` Mauro Carvalho Chehab
2009-11-28 18:17                   ` Stefan Richter
2009-11-28 18:58                     ` Jon Smirl
2009-11-28 18:58                       ` Jon Smirl
2009-11-28 18:58                       ` Jon Smirl
2009-11-28 19:45                       ` Stefan Richter
2009-11-28 20:08                         ` Jon Smirl
2009-11-28 20:08                           ` Jon Smirl
2009-11-28 20:08                           ` Jon Smirl
2009-11-28 20:21                           ` Krzysztof Halasa
2009-12-12 19:33                             ` Pavel Machek
2009-11-28 20:29                           ` Stefan Richter
2009-11-28 20:34                             ` Stefan Richter
2009-11-28 20:46                             ` Jon Smirl
2009-11-28 20:46                               ` Jon Smirl
2009-11-28 20:46                               ` Jon Smirl
2009-11-28 21:46                               ` Stefan Richter
2009-11-28 22:10                                 ` Jon Smirl
2009-11-28 22:10                                   ` Jon Smirl
2009-11-28 22:10                                   ` Jon Smirl
2009-11-28 22:18                                   ` Jon Smirl
2009-11-28 22:18                                     ` Jon Smirl
2009-11-29  4:59                                     ` Dmitry Torokhov
2009-11-29 16:01                                     ` Mauro Carvalho Chehab
2009-11-29 16:18                                   ` Mauro Carvalho Chehab
2009-11-29 11:24                             ` Christoph Bartelmus
2009-11-29 11:24                               ` Christoph Bartelmus
2009-11-29 16:01                           ` Mauro Carvalho Chehab
2009-11-28 19:55                       ` Krzysztof Halasa
2009-11-28 20:14                         ` Jon Smirl
2009-11-28 20:14                           ` Jon Smirl
2009-11-28 20:29                           ` Krzysztof Halasa
2009-11-28 17:21                 ` Krzysztof Halasa
2009-11-28 17:21                   ` Krzysztof Halasa
2009-11-29 11:07                   ` Christoph Bartelmus
2009-11-29 11:07                     ` Christoph Bartelmus
2009-11-28 16:45             ` Jon Smirl
2009-11-28 16:45               ` Jon Smirl
2009-11-28 18:45               ` Maxim Levitsky
2009-11-28 18:56                 ` Jon Smirl
2009-11-28 18:56                   ` Jon Smirl
2009-11-28 19:16                   ` Maxim Levitsky
2009-11-28 19:30                   ` Stefan Richter
2009-11-28 19:32                     ` Jon Smirl
2009-11-28 19:32                       ` Jon Smirl
2009-11-28 19:48                       ` Stefan Richter
2009-11-29  2:47 ` Mike Lampard
2009-11-29  4:55   ` Dmitry Torokhov
2009-11-29  5:31     ` Mike Lampard
2009-11-29  7:14       ` Dmitry Torokhov
2009-11-29 21:59   ` Artur Skawina
2009-11-30 12:13 ` Mauro Carvalho Chehab
2009-12-07 17:53 Emmanuel Fusté
2009-12-07 23:16 ` Mauro Carvalho Chehab
2009-12-07 17:54 Emmanuel Fusté
2009-12-07 18:24 ` Dmitry Torokhov
2009-12-08  9:31   ` Emmanuel Fusté

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4BAFE4B7.2030204@redhat.com \
    --to=mchehab@redhat.com \
    --cc=awalls@radix.net \
    --cc=dmitry.torokhov@gmail.com \
    --cc=hermann-pitton@arcor.de \
    --cc=j@jannau.net \
    --cc=jarod@redhat.com \
    --cc=jarod@wilsonet.com \
    --cc=jonsmirl@gmail.com \
    --cc=khc@pm.waw.pl \
    --cc=kraxel@redhat.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=lirc@bartelmus.de \
    --cc=pavel@ucw.cz \
    --cc=superm1@ubuntu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.