Discussion:
[PATCH resend] [media] rc-core: fix protocol_change regression in ir_raw_event_register
Tomas Melin
2014-10-09 18:30:36 UTC
Permalink
IR reciever using nuvoton-cir and lirc was not working anymore after
upgrade from kernel 3.16 to 3.17-rcX.
Bisected regression to commit da6e162d6a4607362f8478c715c797d84d449f8b
("[media] rc-core: simplify sysfs code").

The regression comes from adding function change_protocol in
ir-raw.c. During registration, ir_raw_event_register enables all protocols
by default. Later, rc_register_device also tests dev->change_protocol and
changes the enabled protocols based on rc_map type. However, rc_map type
only defines a single specific protocol, so in the case of a more generic
driver, this disables all protocols but the one defined by the map.

Changed back to original behaviour by removing empty function
change_protocol in ir-raw.c. Instead only calling change_protocol for
drivers that actually have the function set up.

Signed-off-by: Tomas Melin <***@iki.fi>
---
drivers/media/rc/rc-ir-raw.c | 7 -------
drivers/media/rc/rc-main.c | 19 ++++++++-----------
2 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index e8fff2a..a118539 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -240,12 +240,6 @@ ir_raw_get_allowed_protocols(void)
return protocols;
}

-static int change_protocol(struct rc_dev *dev, u64 *rc_type)
-{
- /* the caller will update dev->enabled_protocols */
- return 0;
-}
-
/*
* Used to (un)register raw event clients
*/
@@ -263,7 +257,6 @@ int ir_raw_event_register(struct rc_dev *dev)

dev->raw->dev = dev;
dev->enabled_protocols = ~0;
- dev->change_protocol = change_protocol;
rc = kfifo_alloc(&dev->raw->kfifo,
sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE,
GFP_KERNEL);
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index a7991c7..633c682 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1001,11 +1001,6 @@ static ssize_t store_protocols(struct device *device,
set_filter = dev->s_wakeup_filter;
}

- if (!change_protocol) {
- IR_dprintk(1, "Protocol switching not supported\n");
- return -EINVAL;
- }
-
mutex_lock(&dev->lock);

old_protocols = *current_protocols;
@@ -1013,12 +1008,14 @@ static ssize_t store_protocols(struct device *device,
rc = parse_protocol_change(&new_protocols, buf);
if (rc < 0)
goto out;
-
- rc = change_protocol(dev, &new_protocols);
- if (rc < 0) {
- IR_dprintk(1, "Error setting protocols to 0x%llx\n",
- (long long)new_protocols);
- goto out;
+ /* Only if protocol change set up in driver */
+ if (change_protocol) {
+ rc = change_protocol(dev, &new_protocols);
+ if (rc < 0) {
+ IR_dprintk(1, "Error setting protocols to 0x%llx\n",
+ (long long)new_protocols);
+ goto out;
+ }
}

if (new_protocols == old_protocols) {
--
1.7.10.4
David Härdeman
2014-10-16 20:49:20 UTC
Permalink
Post by Tomas Melin
IR reciever using nuvoton-cir and lirc was not working anymore after
upgrade from kernel 3.16 to 3.17-rcX.
Bisected regression to commit da6e162d6a4607362f8478c715c797d84d449f8b
("[media] rc-core: simplify sysfs code").
The regression comes from adding function change_protocol in
ir-raw.c. During registration, ir_raw_event_register enables all protocols
by default. Later, rc_register_device also tests dev->change_protocol and
changes the enabled protocols based on rc_map type. However, rc_map type
only defines a single specific protocol, so in the case of a more generic
driver, this disables all protocols but the one defined by the map.
Changed back to original behaviour by removing empty function
change_protocol in ir-raw.c. Instead only calling change_protocol for
drivers that actually have the function set up.
I think this is already addressed in this thread:
http://www.spinics.net/lists/linux-media/msg79865.html
Tomas Melin
2014-10-18 10:10:01 UTC
Permalink
Post by David Härdeman
http://www.spinics.net/lists/linux-media/msg79865.html
The patch in that thread would have broken things since the
store_protocol function is not changed at the same time. The patch I
sent also takes that into account.

My concern is still that user space behaviour changes.
In my case, lirc simply does not work anymore. More generically,
anyone now using e.g. nuvoton-cir with anything other than RC6_MCE
will not get their devices working without first explictly enabling
the correct protocol from sysfs or with ir-keytable.

Correct me if I'm wrong but the change_protocol function in struct
rc_dev is meant for changing hardware decoder protocols which means
only a few drivers actually use it. So the added empty function
change_protocol into rc-ir-raw.c doesnt really make sense in the first
place.

Tomas
Mauro Carvalho Chehab
2014-10-18 18:18:56 UTC
Permalink
Em Sat, 18 Oct 2014 13:10:01 +0300
Post by Tomas Melin
Post by David Härdeman
http://www.spinics.net/lists/linux-media/msg79865.html
The patch in that thread would have broken things since the
store_protocol function is not changed at the same time. The patch I
sent also takes that into account.
=20
My concern is still that user space behaviour changes.
In my case, lirc simply does not work anymore.
Yeah, lirc should be enabled by default.
Post by Tomas Melin
More generically,
anyone now using e.g. nuvoton-cir with anything other than RC6_MCE
will not get their devices working without first explictly enabling
the correct protocol from sysfs or with ir-keytable.
The right behavior here is to enable the protocol as soon as the
new keycode table is written by userspace.

Except for LIRC and the protocol of the current table enabled is
not a good idea because:

1) It misread the code from some other IR;
2) It will be just spending power without need, running
several tasks (one for each IR type) with no reason, as the
keytable won't match the codes for other IRs (and if it is
currently matching, then this is a bad behavior).
Post by Tomas Melin
Correct me if I'm wrong but the change_protocol function in struct
rc_dev is meant for changing hardware decoder protocols which means
only a few drivers actually use it.
Actually, most drivers are for hardware decoders.
Post by Tomas Melin
So the added empty function
change_protocol into rc-ir-raw.c doesnt really make sense in the firs=
t
Post by Tomas Melin
place.
=20
Tomas
--=20

Cheers,
Mauro
Tomas Melin
2014-10-19 10:14:11 UTC
Permalink
On Sat, Oct 18, 2014 at 9:18 PM, Mauro Carvalho Chehab
Post by Mauro Carvalho Chehab
The right behavior here is to enable the protocol as soon as the
new keycode table is written by userspace.
Except for LIRC and the protocol of the current table enabled is
1) It misread the code from some other IR;
2) It will be just spending power without need, running
several tasks (one for each IR type) with no reason, as the
keytable won't match the codes for other IRs (and if it is
currently matching, then this is a bad behavior).
I agree, it sounds overkill to have all protocols enabled by default.
I'll make a new patch that enables lirc but disables other protocols
during registration.

Tomas

Loading...