Skip to contentSkip to conversation

ir-core: raw decoder framework changes

PATCH In review David Härdeman 5 participants 13 messages Jun 13, 2010 – Sep 15, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover ir-core: raw decoder framework changes

The following two patches implement the same ir raw decoder centralization changes I've proposed before, but now with some changes (client register and unregister callbacks have been fixed wrt. module load order and kept around) for lirc "decoding"...

---

David Härdeman (2):
ir-core: centralize sysfs raw decoder enabling/disabling
ir-core: move decoding state to ir_raw_event_ctrl

 drivers/media/IR/ir-core-priv.h    |   41 ++++++
 drivers/media/IR/ir-jvc-decoder.c  |  152 +---------------------
 drivers/media/IR/ir-nec-decoder.c  |  151 +---------------------
 drivers/media/IR/ir-raw-event.c    |  166 +++++++++++++-----------
 drivers/media/IR/ir-rc5-decoder.c  |  165 ++----------------------
 drivers/media/IR/ir-rc6-decoder.c  |  154 +---------------------
 drivers/media/IR/ir-sony-decoder.c |  155 ++--------------------
 drivers/media/IR/ir-sysfs.c        |  252 +++++++++++++++++++++---------------
 8 files changed, 334 insertions(+), 902 deletions(-)
Signature · 5 lines
David Härdeman
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#1 lore raw

PATCH 1/2 ir-core: centralize sysfs raw decoder enabling/disabling

With the current logic, each raw decoder needs to add a copy of the exact same sysfs code. This is both unnecessary and also means that (re)loading an IR driver after raw decoder modules have been loaded won't work as expected.

This patch moves that logic into ir-raw-event and adds a single sysfs file per device.

Reading that file returns something like:

	"rc5 [rc6] nec jvc [sony]"

(with enabled protocols in [] brackets)

Writing either "+protocol" or "-protocol" to that file will enable or disable the according protocol decoder.

An additional benefit is that the disabling of a decoder will be remembered across module removal/insertion so a previously disabled decoder won't suddenly be activated again. The default setting is to enable all decoders.

This is also necessary for the next patch which moves even more decoder state into the central raw decoding structs.

---
 drivers/media/IR/ir-core-priv.h    |    3 
 drivers/media/IR/ir-jvc-decoder.c  |   64 ---------
 drivers/media/IR/ir-nec-decoder.c  |   64 ---------
 drivers/media/IR/ir-raw-event.c    |  112 +++++++++-------
 drivers/media/IR/ir-rc5-decoder.c  |   64 ---------
 drivers/media/IR/ir-rc6-decoder.c  |   64 ---------
 drivers/media/IR/ir-sony-decoder.c |   64 ---------
 drivers/media/IR/ir-sysfs.c        |  252 +++++++++++++++++++++---------------
 8 files changed, 231 insertions(+), 456 deletions(-)
drivers/media/IR/ir-core-priv.h +3 -0
index b79446f..3072e55 100644
@@ -21,6 +21,7 @@
 struct ir_raw_handler {
 	struct list_head list;
 
+	u64 protocols; /* which are handled by this handler */
 	int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
 	int (*raw_register)(struct input_dev *input_dev);
 	int (*raw_unregister)(struct input_dev *input_dev);
@@ -32,6 +33,7 @@ struct ir_raw_event_ctrl {
 	ktime_t				last_event;	/* when last event occurred */
 	enum raw_event_type		last_type;	/* last event type */
 	struct input_dev		*input_dev;	/* pointer to the parent input_dev */
+	u64				enabled_protocols; /* enabled raw protocol decoders */
 };
 
 /* macros for IR decoders */
@@ -73,6 +75,7 @@ void ir_unregister_class(struct input_dev *input_dev);
 /*
  * Routines from ir-raw-event.c to be used internally and by decoders
  */
+u64 ir_raw_get_allowed_protocols(void);
 int ir_raw_event_register(struct input_dev *input_dev);
 void ir_raw_event_unregister(struct input_dev *input_dev);
 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
drivers/media/IR/ir-jvc-decoder.c +3 -61

105 lines not on this page · raw message

drivers/media/IR/ir-nec-decoder.c +3 -61

105 lines not on this page · raw message

drivers/media/IR/ir-raw-event.c +65 -47

144 lines not on this page · raw message

drivers/media/IR/ir-rc5-decoder.c +3 -61

105 lines not on this page · raw message

drivers/media/IR/ir-rc6-decoder.c +3 -61

105 lines not on this page · raw message

drivers/media/IR/ir-sony-decoder.c +3 -61

105 lines not on this page · raw message

drivers/media/IR/ir-sysfs.c +148 -104

322 lines not on this page · raw message

Acked-by Tested-by on v1 1/2
#2 lore raw

Re: [PATCH 1/2] ir-core: centralize sysfs raw decoder enabling/disabling

Quoted 22 lines · David Härdeman

With the current logic, each raw decoder needs to add a copy of the exact same sysfs code. This is both unnecessary and also means that (re)loading an IR driver after raw decoder modules have been loaded won't work as expected.

This patch moves that logic into ir-raw-event and adds a single sysfs file per device.

Reading that file returns something like:

       "rc5 [rc6] nec jvc [sony]"

(with enabled protocols in [] brackets)

Writing either "+protocol" or "-protocol" to that file will enable or disable the according protocol decoder.

An additional benefit is that the disabling of a decoder will be remembered across module removal/insertion so a previously disabled decoder won't suddenly be activated again. The default setting is to enable all decoders.

Quoted 4 lines

This is also necessary for the next patch which moves even more decoder state into the central raw decoding structs.

Note that I was running a version rebased atop the linuxtv staging/rc branch though.

Signature · 6 lines
Jarod Wilson
[email protected]
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#3 lore raw

Re: [PATCH 1/2] ir-core: centralize sysfs raw decoder enabling/disabling

Quoted 26 lines · Jarod Wilson
Quoted 25 lines · David Härdeman

With the current logic, each raw decoder needs to add a copy of the exact same sysfs code. This is both unnecessary and also means that (re)loading an IR driver after raw decoder modules have been loaded won't work as expected.

This patch moves that logic into ir-raw-event and adds a single sysfs file per device.

Reading that file returns something like:

       "rc5 [rc6] nec jvc [sony]"

(with enabled protocols in [] brackets)

Writing either "+protocol" or "-protocol" to that file will enable or disable the according protocol decoder.

An additional benefit is that the disabling of a decoder will be remembered across module removal/insertion so a previously disabled decoder won't suddenly be activated again. The default setting is to enable all decoders.

This is also necessary for the next patch which moves even more decoder state into the central raw decoding structs.

Quoted 7 lines
Quoted 1 line

Note that I was running a version rebased atop the linuxtv staging/rc branch though.

Found here:

http://git.wilsonet.com//linux-2.6-ir-wip.git?a=commitdiff;h=e4166a6c70c4f9a06644ce8b4e9beeea7c336d90

Signature · 6 lines
Jarod Wilson
[email protected]
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#4 lore raw

Re: [PATCH 1/2] ir-core: centralize sysfs raw decoder enabling/disabling

In reply to David Härdeman

Em 13-06-2010 17:29, David Härdeman escreveu:

Quoted 39 lines

With the current logic, each raw decoder needs to add a copy of the exact same sysfs code. This is both unnecessary and also means that (re)loading an IR driver after raw decoder modules have been loaded won't work as expected.

This patch moves that logic into ir-raw-event and adds a single sysfs file per device.

Reading that file returns something like:

	"rc5 [rc6] nec jvc [sony]"

(with enabled protocols in [] brackets)

Writing either "+protocol" or "-protocol" to that file will enable or disable the according protocol decoder.

An additional benefit is that the disabling of a decoder will be remembered across module removal/insertion so a previously disabled decoder won't suddenly be activated again. The default setting is to enable all decoders.

This is also necessary for the next patch which moves even more decoder state into the central raw decoding structs.

drivers/media/IR/ir-sysfs.c +12 -0
+	if (!strncasecmp(tmp, "unknown", 7)) {
+		tmp += 7;
+		mask = IR_TYPE_UNKNOWN;
+	} else if (!strncasecmp(tmp, "rc5", 3)) {
+		tmp += 3;
+		mask = IR_TYPE_RC5;
+	} else if (!strncasecmp(tmp, "nec", 3)) {
+		tmp += 3;
+		mask = IR_TYPE_NEC;
+	} else if (!strncasecmp(tmp, "rc6", 3)) {
+		tmp += 3;
+		mask = IR_TYPE_RC6;

drivers/media/IR/ir-sysfs.c static struct class ir_input_class = { · line 165

Quoted 10 lines
drivers/media/IR/ir-sysfs.c +7 -0
+	} else if (!strncasecmp(tmp, "jvc", 3)) {
+		tmp += 3;
+		mask = IR_TYPE_JVC;
+	} else if (!strncasecmp(tmp, "sony", 4)) {
+		tmp += 4;
+		mask = IR_TYPE_SONY;
+	} else {
 		IR_dprintk(1, "Unknown protocol\n");
 		return -EINVAL;
 	}

Those "magic" sizes at the strcasecmp are ugly. Also, you didn't send a patch for the ir-keytable userspace tool (part of v4l-utils.git tree).

Also, this allows some undocumented (and problematic) ways to set protocols. For example, if someone writes: something like "rc5necjvcsony" (on this exact order and without spaces), it will accept it as just "sony", without complaining.

As I found some time during the weekend to add support for the new /protocols way at the userspace tool, I'll be applying this patch as-is, plus a few patches after it fixing the problems I found and adding some additional features that will be needed, in order to make userspace stuff easier, like supporting multiple protocols specs without needing to close/open the sysfs node for each protocol.

Btw, we should start writing some docs about the sysfs interface at the media specs (at Documentation/DocBoook).

Cheers,
Mauro
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#5 lore raw

Re: [PATCH 1/2] ir-core: centralize sysfs raw decoder enabling/disabling

In reply to David Härdeman
Quoted 42 lines · David Härdeman
drivers/media/IR/ir-sysfs.c +7 -20
index daf33c1..7ae5662 100644
@@ -33,122 +33,178 @@ static struct class ir_input_class = {
  };
 
  /**
- * show_protocol() - shows the current IR protocol
+ * show_protocols() - shows the current IR protocol(s)
   * @d:		the device descriptor
   * @mattr:	the device attribute struct (unused)
   * @buf:	a pointer to the output buffer
   *
- * This routine is a callback routine for input read the IR protocol type.
- * it is trigged by reading /sys/class/rc/rc?/current_protocol.
- * It returns the protocol name, as understood by the driver.
+ * This routine is a callback routine for input read the IR protocol type(s).
+ * it is trigged by reading /sys/class/rc/rc?/protocols.
+ * It returns the protocol names of supported protocols.
+ * Enabled protocols are printed in brackets.
   */
-static ssize_t show_protocol(struct device *d,
-			     struct device_attribute *mattr, char *buf)
+static ssize_t show_protocols(struct device *d,
+			      struct device_attribute *mattr, char *buf)
  {
-	char *s;
  	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-	u64 ir_type = ir_dev->rc_tab.ir_type;
-
-	IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type);
-
-	/* FIXME: doesn't support multiple protocols at the same time */
-	if (ir_type == IR_TYPE_UNKNOWN)
-		s = "Unknown";
-	else if (ir_type == IR_TYPE_RC5)
-		s = "rc-5";
-	else if (ir_type == IR_TYPE_NEC)
-		s = "nec";
-	else if (ir_type == IR_TYPE_RC6)
-		s = "rc6";

drivers/media/IR/ir-sysfs.c static struct class ir_input_class = { · line 53

Quoted 10 lines
drivers/media/IR/ir-sysfs.c +4 -6
-	else if (ir_type == IR_TYPE_JVC)
-		s = "jvc";
-	else if (ir_type == IR_TYPE_SONY)
-		s = "sony";
-	else
-		s = "other";
+	u64 allowed, enabled;
+	char *tmp = buf;
+
+	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {

This change introduced an oops for me. On my saa7134 MSI TV Anywhere Plus, ir_dev->props is null, so dereferencing it causes the following while attempting to read /sys/devices/virtual/rc/rc0/protocols:

[  601.632041] BUG: unable to handle kernel NULL pointer dereference at (null)
[  601.632061] IP: [<ffffffffa00f43b5>] show_protocols+0x25/0x120 [ir_core]
[  601.632079] PGD 7b181067 PUD 7bafe067 PMD 0
[  601.632093] Oops: 0000 [#1] SMP
[  601.632103] last sysfs file: /sys/devices/virtual/rc/rc0/protocols
[  601.632111] CPU 0
[  601.632115] Modules linked in: binfmt_misc rfcomm parport_pc ppdev sco bnep l2cap saa7134_alsa arc4 rc_msi_tvanywhere_plus ir_kbd_i2c advantechwdt tda827x rt2500pci rt2x00pci rt2x00lib snd_intel8x0 tda8290 snd_ac97_codec led_class ac97_bus tuner snd_seq_midi snd_rawmidi ir_lirc_codec lirc_dev mac80211 cfg80211 snd_seq_midi_event ir_sony_decoder ir_jvc_decoder saa7134 v4l2_common videodev v4l1_compat v4l2_compat_ioctl32 psmouse serio_raw ir_rc6_decoder snd_pcm snd_seq lp shpchp eeprom_93cx6 btusb snd_timer snd_seq_device videobuf_dma_sg ir_rc5_decoder snd videobuf_core ir_nec_decoder ir_common ir_core tveeprom soundcore edac_core bluetooth snd_page_alloc parport i2c_nforce2 k8temp edac_mce_amd usbhid hid btrfs zlib_deflate crc32c libcrc32c sata_nv forcedeth pata_amd
[  601.632319]
[  601.632335] Pid: 2928, comm: cat Not tainted 2.6.36-rc3-00185-gd56557a #2 KN9 Series(NF-CK804)/Unknow
[  601.632368] RIP: 0010:[<ffffffffa00f43b5>]  [<ffffffffa00f43b5>] show_protocols+0x25/0x120 [ir_core]
[  601.632404] RSP: 0018:ffff88007bb93e38  EFLAGS: 00010282
[  601.632423] RAX: ffff88007bb6e000 RBX: ffffffffa00f5ee0 RCX: ffffffffa00f4390
[  601.632444] RDX: 0000000000000000 RSI: ffffffffa00f5ee0 RDI: ffff88007bb6e000
[  601.632465] RBP: ffff88007bb93e68 R08: ffff88007bb6e010 R09: ffffffff8164ab40
[  601.632486] R10: 0000000000000000 R11: 0000000000000246 R12: ffff88007c928000
[  601.632507] R13: 0000000000008000 R14: 000000000246d000 R15: ffff88007c8798a0
[  601.632529] FS:  00007fe7aa26c700(0000) GS:ffff880001e00000(0000) knlGS:0000000000000000
[  601.632561] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  601.632580] CR2: 0000000000000000 CR3: 000000007b19f000 CR4: 00000000000006f0
[  601.632601] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  601.632623] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  601.632644] Process cat (pid: 2928, threadinfo ffff88007bb92000, task ffff88007bcd2dc0)
[  601.632675] Stack:
[  601.632689]  0000000000000000 ffffffffa00f5ee0 ffff88007bb93f48 0000000000008000
[  601.632713] <0> 000000000246d000 ffff88007c8798a0 ffff88007bb93e98 ffffffff813816e7
[  601.632750] <0> ffff88007bb93e88 ffffffff8110681e ffff88007bb93e98 ffff88007c8798c0
[  601.632797] Call Trace:
[  601.632819]  [<ffffffff813816e7>] dev_attr_show+0x27/0x50
[  601.632842]  [<ffffffff8110681e>] ? __get_free_pages+0xe/0x50
[  601.632864]  [<ffffffff811bf5b1>] sysfs_read_file+0xd1/0x1c0
[  601.632886]  [<ffffffff81152f15>] vfs_read+0xc5/0x190
[  601.632906]  [<ffffffff81153551>] sys_read+0x51/0x90
[  601.632928]  [<ffffffff8100b072>] system_call_fastpath+0x16/0x1b
[  601.632947] Code: eb 04 90 90 90 90 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 08 0f 1f 44 00 00 49 89 d4 e8 12 0e 29 e1 48 8b 90 90 02 00 00 <44> 8b 0a 45 85 c9 0f 85 af 00 00 00 4c 8b a8 70 02 00 00 48 8b
[  601.633112] RIP  [<ffffffffa00f43b5>] show_protocols+0x25/0x120 [ir_core]
[  601.633136]  RSP <ffff88007bb93e38>
[  601.633152] CR2: 0000000000000000
[  601.633448] ---[ end trace 0dbd0f2ee839a90b ]---

A similar problem exists in store_protocols and makes lircd oops and die at startup.

drivers/media/IR/ir-sysfs.c static struct class ir_input_class = { · line 57

Quoted 4 lines
drivers/media/IR/ir-sysfs.c +4 -0
+		enabled = ir_dev->rc_tab.ir_type;
+		allowed = ir_dev->props->allowed_protos;
+	} else {
+		enabled = ir_dev->raw->enabled_protocols;

ir_dev->raw is also null. If I check these pointers before using them, and bail out if both are null, then I get a working lircd, but of course the file /sys/devices/virtual/rc/rc0/protocols no longer does anything. On 2.6.35.4, the system never creates the /sys/class/rc/rc0/current_protocol file. Is it the case that the 'protocols' file should never appear, because my card can't support this feature?

Brian

#6 lore raw

Re: [PATCH 1/2] ir-core: centralize sysfs raw decoder enabling/disabling

Quoted 132 lines · Brian Rogers
Quoted 42 lines · David Härdeman
drivers/media/IR/ir-sysfs.c +7 -20
index daf33c1..7ae5662 100644
@@ -33,122 +33,178 @@ static struct class ir_input_class = {
 };
 
 /**
- * show_protocol() - shows the current IR protocol
+ * show_protocols() - shows the current IR protocol(s)
  * @d:		the device descriptor
  * @mattr:	the device attribute struct (unused)
  * @buf:	a pointer to the output buffer
  *
- * This routine is a callback routine for input read the IR protocol type.
- * it is trigged by reading /sys/class/rc/rc?/current_protocol.
- * It returns the protocol name, as understood by the driver.
+ * This routine is a callback routine for input read the IR protocol type(s).
+ * it is trigged by reading /sys/class/rc/rc?/protocols.
+ * It returns the protocol names of supported protocols.
+ * Enabled protocols are printed in brackets.
  */
-static ssize_t show_protocol(struct device *d,
-			     struct device_attribute *mattr, char *buf)
+static ssize_t show_protocols(struct device *d,
+			      struct device_attribute *mattr, char *buf)
 {
-	char *s;
 	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
-	u64 ir_type = ir_dev->rc_tab.ir_type;
-
-	IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type);
-
-	/* FIXME: doesn't support multiple protocols at the same time */
-	if (ir_type == IR_TYPE_UNKNOWN)
-		s = "Unknown";
-	else if (ir_type == IR_TYPE_RC5)
-		s = "rc-5";
-	else if (ir_type == IR_TYPE_NEC)
-		s = "nec";
-	else if (ir_type == IR_TYPE_RC6)
-		s = "rc6";

drivers/media/IR/ir-sysfs.c static struct class ir_input_class = { · line 53

Quoted 10 lines
drivers/media/IR/ir-sysfs.c +4 -6
-	else if (ir_type == IR_TYPE_JVC)
-		s = "jvc";
-	else if (ir_type == IR_TYPE_SONY)
-		s = "sony";
-	else
-		s = "other";
+	u64 allowed, enabled;
+	char *tmp = buf;
+
+	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {

This change introduced an oops for me. On my saa7134 MSI TV Anywhere Plus, ir_dev->props is null, so dereferencing it causes the following while attempting to read /sys/devices/virtual/rc/rc0/protocols:

[  601.632041] BUG: unable to handle kernel NULL pointer dereference
at (null)
[  601.632061] IP: [<ffffffffa00f43b5>] show_protocols+0x25/0x120 [ir_core]
[  601.632079] PGD 7b181067 PUD 7bafe067 PMD 0
[  601.632093] Oops: 0000 [#1] SMP
[  601.632103] last sysfs file: /sys/devices/virtual/rc/rc0/protocols
[  601.632111] CPU 0
[  601.632115] Modules linked in: binfmt_misc rfcomm parport_pc

ppdev sco bnep l2cap saa7134_alsa arc4 rc_msi_tvanywhere_plus ir_kbd_i2c advantechwdt tda827x rt2500pci rt2x00pci rt2x00lib snd_intel8x0 tda8290 snd_ac97_codec led_class ac97_bus tuner snd_seq_midi snd_rawmidi ir_lirc_codec lirc_dev mac80211 cfg80211 snd_seq_midi_event ir_sony_decoder ir_jvc_decoder saa7134 v4l2_common videodev v4l1_compat v4l2_compat_ioctl32 psmouse serio_raw ir_rc6_decoder snd_pcm snd_seq lp shpchp eeprom_93cx6 btusb snd_timer snd_seq_device videobuf_dma_sg ir_rc5_decoder snd videobuf_core ir_nec_decoder ir_common ir_core tveeprom soundcore edac_core bluetooth snd_page_alloc parport i2c_nforce2 k8temp edac_mce_amd usbhid hid btrfs zlib_deflate crc32c libcrc32c sata_nv forcedeth pata_amd

[  601.632319]
[  601.632335] Pid: 2928, comm: cat Not tainted
2.6.36-rc3-00185-gd56557a #2 KN9 Series(NF-CK804)/Unknow
[  601.632368] RIP: 0010:[<ffffffffa00f43b5>]  [<ffffffffa00f43b5>]
show_protocols+0x25/0x120 [ir_core]
[  601.632404] RSP: 0018:ffff88007bb93e38  EFLAGS: 00010282
[  601.632423] RAX: ffff88007bb6e000 RBX: ffffffffa00f5ee0 RCX:
ffffffffa00f4390
[  601.632444] RDX: 0000000000000000 RSI: ffffffffa00f5ee0 RDI:
ffff88007bb6e000
[  601.632465] RBP: ffff88007bb93e68 R08: ffff88007bb6e010 R09:
ffffffff8164ab40
[  601.632486] R10: 0000000000000000 R11: 0000000000000246 R12:
ffff88007c928000
[  601.632507] R13: 0000000000008000 R14: 000000000246d000 R15:
ffff88007c8798a0
[  601.632529] FS:  00007fe7aa26c700(0000) GS:ffff880001e00000(0000)
knlGS:0000000000000000
[  601.632561] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  601.632580] CR2: 0000000000000000 CR3: 000000007b19f000 CR4:
00000000000006f0
[  601.632601] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[  601.632623] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7:
0000000000000400
[  601.632644] Process cat (pid: 2928, threadinfo ffff88007bb92000,
task ffff88007bcd2dc0)
[  601.632675] Stack:
[  601.632689]  0000000000000000 ffffffffa00f5ee0 ffff88007bb93f48
0000000000008000
[  601.632713] <0> 000000000246d000 ffff88007c8798a0
ffff88007bb93e98 ffffffff813816e7
[  601.632750] <0> ffff88007bb93e88 ffffffff8110681e
ffff88007bb93e98 ffff88007c8798c0
[  601.632797] Call Trace:
[  601.632819]  [<ffffffff813816e7>] dev_attr_show+0x27/0x50
[  601.632842]  [<ffffffff8110681e>] ? __get_free_pages+0xe/0x50
[  601.632864]  [<ffffffff811bf5b1>] sysfs_read_file+0xd1/0x1c0
[  601.632886]  [<ffffffff81152f15>] vfs_read+0xc5/0x190
[  601.632906]  [<ffffffff81153551>] sys_read+0x51/0x90
[  601.632928]  [<ffffffff8100b072>] system_call_fastpath+0x16/0x1b
[  601.632947] Code: eb 04 90 90 90 90 55 48 89 e5 41 57 41 56 41 55
41 54 53 48 83 ec 08 0f 1f 44 00 00 49 89 d4 e8 12 0e 29 e1 48 8b 90
90 02 00 00 <44> 8b 0a 45 85 c9 0f 85 af 00 00 00 4c 8b a8 70 02 00
00 48 8b
[  601.633112] RIP  [<ffffffffa00f43b5>] show_protocols+0x25/0x120 [ir_core]
[  601.633136]  RSP <ffff88007bb93e38>
[  601.633152] CR2: 0000000000000000
[  601.633448] ---[ end trace 0dbd0f2ee839a90b ]---

A similar problem exists in store_protocols and makes lircd oops and die at startup.

Quoted 12 lines

drivers/media/IR/ir-sysfs.c static struct class ir_input_class = { · line 57

Quoted 4 lines
drivers/media/IR/ir-sysfs.c +4 -0
+		enabled = ir_dev->rc_tab.ir_type;
+		allowed = ir_dev->props->allowed_protos;
+	} else {
+		enabled = ir_dev->raw->enabled_protocols;

ir_dev->raw is also null. If I check these pointers before using them, and bail out if both are null, then I get a working lircd, but of course the file /sys/devices/virtual/rc/rc0/protocols no longer does anything. On 2.6.35.4, the system never creates the /sys/class/rc/rc0/current_protocol file. Is it the case that the 'protocols' file should never appear, because my card can't support this feature?

Hm... So protocols is indeed intended for hardware that handles raw IR, as its a list of raw IR decoders available/enabled/disabled for the receiver. But some devices that do onboard decoding and deal with scancodes still need to support changing protocols, as they can be told "decode rc5" or "decode nec", etc... My memory is currently foggy on how it was exactly that it was supposed to be donee though. :) (Yet another reason I really need to poke at the imon driver code again).

Signature · 2 lines
Jarod Wilson
[email protected]
#7 lore raw

Re: [PATCH 1/2] ir-core: centralize sysfs raw decoder enabling/disabling

Quoted 9 lines · Jarod Wilson
Quoted 7 lines · Brian Rogers

ir_dev->raw is also null. If I check these pointers before using them, and bail out if both are null, then I get a working lircd, but of course the file /sys/devices/virtual/rc/rc0/protocols no longer does anything. On 2.6.35.4, the system never creates the /sys/class/rc/rc0/current_protocol file. Is it the case that the 'protocols' file should never appear, because my card can't support this feature?

Quoted 7 lines

Hm... So protocols is indeed intended for hardware that handles raw IR, as its a list of raw IR decoders available/enabled/disabled for the receiver. But some devices that do onboard decoding and deal with scancodes still need to support changing protocols, as they can be told "decode rc5" or "decode nec", etc... My memory is currently foggy on how it was exactly that it was supposed to be donee though. :) (Yet another reason I really need to poke at the imon driver code again).

This, and a raft of similar bugreports was one of the reasons I wrote the rc_dev patch (which gets rid of ir_dev->props, the source of many oopses by now).

Hardware decoders should work with the same sysfs file, the driver should set ir_dev->props->change_protocol (current) or rc->change_protocol (future) and it'll get notified when userspace interacts with the sysfs file and the hardware can then react accordingly. So the answer is yes - all hardware should have the file.

Signature · 5 lines
David Härdeman
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#8 lore raw

PATCH 1/1 ir-core: Fix null dereferences in the protocols sysfs interface

In reply to Jarod Wilson
Quoted 8 lines · Jarod Wilson
Quoted 7 lines · Brian Rogers

ir_dev->raw is also null. If I check these pointers before using them, and bail out if both are null, then I get a working lircd, but of course the file /sys/devices/virtual/rc/rc0/protocols no longer does anything. On 2.6.35.4, the system never creates the /sys/class/rc/rc0/current_protocol file. Is it the case that the 'protocols' file should never appear, because my card can't support this feature?

Quoted 7 lines

Hm... So protocols is indeed intended for hardware that handles raw IR, as its a list of raw IR decoders available/enabled/disabled for the receiver. But some devices that do onboard decoding and deal with scancodes still need to support changing protocols, as they can be told "decode rc5" or "decode nec", etc... My memory is currently foggy on how it was exactly that it was supposed to be donee though. :) (Yet another reason I really need to poke at the imon driver code again).

How about the attached patch? Does this look like a reasonable solution for 2.6.36?

Brian

Quoted 1 line

From 7937051c5e2c8b5b0410172d48e62d54bd1906ee Mon Sep 17 00:00:00 2001

From: Brian Rogers <[email protected]>
Date: Wed, 8 Sep 2010 05:33:34 -0700
Subject: [PATCH] ir-core: Fix null dereferences in the protocols sysfs interface

For some cards, ir_dev->props and ir_dev->raw are both NULL. These cards are using built-in IR decoding instead of raw, and can't easily be made to switch protocols.

So upon reading /sys/class/rc/rc?/protocols on such a card, return 'builtin' as the supported and enabled protocol. Return -EINVAL on any attempts to change the protocol. And most important of all, don't crash.

---
 drivers/media/IR/ir-sysfs.c |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)
drivers/media/IR/ir-sysfs.c +11 -6
index 96dafc4..46d4246 100644
@@ -67,13 +67,14 @@ static ssize_t show_protocols(struct device *d,
 	char *tmp = buf;
 	int i;
 
-	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
+	if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
 		enabled = ir_dev->rc_tab.ir_type;
 		allowed = ir_dev->props->allowed_protos;
-	} else {
+	} else if (ir_dev->raw) {
 		enabled = ir_dev->raw->enabled_protocols;
 		allowed = ir_raw_get_allowed_protocols();
-	}
+	} else
+		return sprintf(tmp, "[builtin]\n");
 
 	IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
 		   (long long)allowed,
@@ -121,10 +122,14 @@ static ssize_t store_protocols(struct device *d,
 	int rc, i, count = 0;
 	unsigned long flags;
 
-	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
+	if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
 		type = ir_dev->rc_tab.ir_type;
-	else
+	else if (ir_dev->raw)
 		type = ir_dev->raw->enabled_protocols;
+	else {
+		IR_dprintk(1, "Protocol switching not supported\n");
+		return -EINVAL;
+	}
 
 	while ((tmp = strsep((char **) &data, " \n")) != NULL) {
 		if (!*tmp)
@@ -185,7 +190,7 @@ static ssize_t store_protocols(struct device *d,
 		}
 	}
 
-	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
+	if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
 		spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
 		ir_dev->rc_tab.ir_type = type;
 		spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
Signature · 1 line
1.7.1
Acked-by on v1 1/1
#9 lore raw

Re: [PATCH] ir-core: Fix null dereferences in the protocols sysfs interface

Quoted 32 lines · Brian Rogers
Quoted 8 lines · Jarod Wilson
Quoted 7 lines · Brian Rogers

ir_dev->raw is also null. If I check these pointers before using them, and bail out if both are null, then I get a working lircd, but of course the file /sys/devices/virtual/rc/rc0/protocols no longer does anything. On 2.6.35.4, the system never creates the /sys/class/rc/rc0/current_protocol file. Is it the case that the 'protocols' file should never appear, because my card can't support this feature?

Quoted 7 lines

Hm... So protocols is indeed intended for hardware that handles raw IR, as its a list of raw IR decoders available/enabled/disabled for the receiver. But some devices that do onboard decoding and deal with scancodes still need to support changing protocols, as they can be told "decode rc5" or "decode nec", etc... My memory is currently foggy on how it was exactly that it was supposed to be donee though. :) (Yet another reason I really need to poke at the imon driver code again).

How about the attached patch? Does this look like a reasonable solution for 2.6.36?

Brian

From 7937051c5e2c8b5b0410172d48e62d54bd1906ee Mon Sep 17 00:00:00 2001
From: Brian Rogers <[email protected]>
Date: Wed, 8 Sep 2010 05:33:34 -0700
Subject: [PATCH] ir-core: Fix null dereferences in the protocols sysfs interface

For some cards, ir_dev->props and ir_dev->raw are both NULL. These cards are using built-in IR decoding instead of raw, and can't easily be made to switch protocols.

Quoted 8 lines

So upon reading /sys/class/rc/rc?/protocols on such a card, return 'builtin' as the supported and enabled protocol. Return -EINVAL on any attempts to change the protocol. And most important of all, don't crash.

---
 drivers/media/IR/ir-sysfs.c |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

Yeah, this looks pretty sane for 2.6.36, would just be a short-lived panic preventer until David's interface changes get merged after 2.6.37-rc1.

Signature · 2 lines
Jarod Wilson
[email protected]
#10 lore raw

PATCH 2/2 ir-core: move decoding state to ir_raw_event_ctrl

In reply to David Härdeman

This patch moves the state from each raw decoder into the ir_raw_event_ctrl struct.

This allows the removal of code like this:

        spin_lock(&decoder_lock);
        list_for_each_entry(data, &decoder_list, list) {
                if (data->ir_dev == ir_dev)
                        break;
        }
        spin_unlock(&decoder_lock);
        return data;

which is currently run for each decoder on each event in order to get the client-specific decoding state data.

In addition, ir decoding modules and ir driver module load order is now independent. Centralizing the data also allows for a nice code reduction of about 30% per raw decoder as client lists and client registration callbacks are no longer necessary (but still kept around for the benefit of the lirc decoder).

Out-of-tree modules can still use a similar trick to what the raw decoders did before this patch until they are merged.

---
 drivers/media/IR/ir-core-priv.h    |   38 +++++++++++++
 drivers/media/IR/ir-jvc-decoder.c  |   90 ++-----------------------------
 drivers/media/IR/ir-nec-decoder.c  |   89 +++----------------------------
 drivers/media/IR/ir-raw-event.c    |   74 +++++++++++++-------------
 drivers/media/IR/ir-rc5-decoder.c  |  103 +++++-------------------------------
 drivers/media/IR/ir-rc6-decoder.c  |   92 ++------------------------------
 drivers/media/IR/ir-sony-decoder.c |   93 +++------------------------------
 7 files changed, 118 insertions(+), 461 deletions(-)
drivers/media/IR/ir-core-priv.h +38 -0
index 3072e55..9994af4 100644
@@ -23,17 +23,55 @@ struct ir_raw_handler {
 
 	u64 protocols; /* which are handled by this handler */
 	int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
+
+	/* These two should only be used by the lirc decoder */
 	int (*raw_register)(struct input_dev *input_dev);
 	int (*raw_unregister)(struct input_dev *input_dev);
 };
 
 struct ir_raw_event_ctrl {
+	struct list_head		list;		/* to keep track of raw clients */
 	struct work_struct		rx_work;	/* for the rx decoding workqueue */
 	struct kfifo			kfifo;		/* fifo for the pulse/space durations */
 	ktime_t				last_event;	/* when last event occurred */
 	enum raw_event_type		last_type;	/* last event type */
 	struct input_dev		*input_dev;	/* pointer to the parent input_dev */
 	u64				enabled_protocols; /* enabled raw protocol decoders */
+
+	/* raw decoder state follows */
+	struct ir_raw_event prev_ev;
+	struct nec_dec {
+		int state;
+		unsigned count;
+		u32 bits;
+	} nec;
+	struct rc5_dec {
+		int state;
+		u32 bits;
+		unsigned count;
+		unsigned wanted_bits;
+	} rc5;
+	struct rc6_dec {
+		int state;
+		u8 header;
+		u32 body;
+		bool toggle;
+		unsigned count;
+		unsigned wanted_bits;
+	} rc6;
+	struct sony_dec {
+		int state;
+		u32 bits;
+		unsigned count;
+	} sony;
+	struct jvc_dec {
+		int state;
+		u16 bits;
+		u16 old_bits;
+		unsigned count;
+		bool first;
+		bool toggle;
+	} jvc;
 };
 
 /* macros for IR decoders */
drivers/media/IR/ir-jvc-decoder.c +7 -83

134 lines not on this page · raw message

drivers/media/IR/ir-nec-decoder.c +8 -81

136 lines not on this page · raw message

drivers/media/IR/ir-raw-event.c +37 -37

133 lines not on this page · raw message

drivers/media/IR/ir-rc5-decoder.c +13 -90

158 lines not on this page · raw message

drivers/media/IR/ir-rc6-decoder.c +5 -87

159 lines not on this page · raw message

drivers/media/IR/ir-sony-decoder.c +10 -83

143 lines not on this page · raw message

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Acked-by Tested-by on v1 2/2
#11 lore raw

Re: [PATCH 2/2] ir-core: move decoding state to ir_raw_event_ctrl

Quoted 23 lines · David Härdeman

This patch moves the state from each raw decoder into the ir_raw_event_ctrl struct.

This allows the removal of code like this:

       spin_lock(&decoder_lock); list_for_each_entry(data, &decoder_list, list) { if (data->ir_dev == ir_dev) break;
       }
       spin_unlock(&decoder_lock);
       return data;

which is currently run for each decoder on each event in order to get the client-specific decoding state data.

In addition, ir decoding modules and ir driver module load order is now independent. Centralizing the data also allows for a nice code reduction of about 30% per raw decoder as client lists and client registration callbacks are no longer necessary (but still kept around for the benefit of the lirc decoder).

Quoted 4 lines

Out-of-tree modules can still use a similar trick to what the raw decoders did before this patch until they are merged.

Note that I was running a version rebased atop the linuxtv staging/rc branch though.

Signature · 6 lines
Jarod Wilson
[email protected]
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#12 lore raw

Re: [PATCH 2/2] ir-core: move decoding state to ir_raw_event_ctrl

Quoted 27 lines · Jarod Wilson
Quoted 26 lines · David Härdeman

This patch moves the state from each raw decoder into the ir_raw_event_ctrl struct.

This allows the removal of code like this:

       spin_lock(&decoder_lock); list_for_each_entry(data, &decoder_list, list) { if (data->ir_dev == ir_dev) break;
       }
       spin_unlock(&decoder_lock);
       return data;

which is currently run for each decoder on each event in order to get the client-specific decoding state data.

In addition, ir decoding modules and ir driver module load order is now independent. Centralizing the data also allows for a nice code reduction of about 30% per raw decoder as client lists and client registration callbacks are no longer necessary (but still kept around for the benefit of the lirc decoder).

Out-of-tree modules can still use a similar trick to what the raw decoders did before this patch until they are merged.

Quoted 7 lines
Quoted 1 line

Note that I was running a version rebased atop the linuxtv staging/rc branch though.

Which can be seen here:

http://git.wilsonet.com//linux-2.6-ir-wip.git?a=commitdiff;h=faee132179abe884a6e995acb1f5106cb2d5afa2

Signature · 6 lines
Jarod Wilson
[email protected]
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html