All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pete Zaitcev <zaitcev@redhat.com>
To: linux-input@vger.kernel.org
Cc: dmitry.torokhov@gmail.com, zaitcev@redhat.com
Subject: Zeroing the report before setting fields
Date: Thu, 4 Mar 2010 14:33:49 -0700	[thread overview]
Message-ID: <20100304143349.2d861ec6@redhat.com> (raw)

Hi, Dmitry et. al.:

I was looking at the way unused bits of report are being zeroed, and
it seems like there must be a bug. Currently, the zeroing is done in
hid_output_field and it covers any bits between the last used bit and
the end of the byte. But in case of, say, my keyboard, NumLock is mask
0x01 and CapsLock is 0x02. Invoking hid_output_field for NumLock
definitely zeroes across CapsLock. The only reason this works is that
the fields are sorted by the offset.

I am not sure it's safe at all times, so why don't we pull the
zeroing outside and do it once per report? Please see the attached.
I tested it with various keyboards (including those that blow up
on RHEL 5), and it works, but the question is, do we want it?

Cheers,
-- Pete

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index eabe5f8..14b45b1 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -929,6 +929,15 @@ exit:
 	kfree(value);
 }
 
+static unsigned int hid_field_length(struct hid_field *field)
+{
+	unsigned count = field->report_count;
+	unsigned offset = field->report_offset;
+	unsigned size = field->report_size;
+
+	return offset + count * size;
+}
+
 /*
  * Output the field into the report.
  */
@@ -938,13 +947,8 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
 	unsigned count = field->report_count;
 	unsigned offset = field->report_offset;
 	unsigned size = field->report_size;
-	unsigned bitsused = offset + count * size;
 	unsigned n;
 
-	/* make sure the unused bits in the last byte are zeros */
-	if (count > 0 && size > 0 && (bitsused % 8) != 0)
-		data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1;
-
 	for (n = 0; n < count; n++) {
 		if (field->logical_minimum < 0)	/* signed values */
 			implement(data, offset + n * size, size, s32ton(field->value[n], size));
@@ -960,10 +964,19 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
 void hid_output_report(struct hid_report *report, __u8 *data)
 {
 	unsigned n;
+	unsigned length, bitsused;
 
 	if (report->id > 0)
 		*data++ = report->id;
 
+	length = 0;
+	for (n = 0; n < report->maxfield; n++) {
+		bitsused = hid_field_length(report->field[n]);
+		if (bitsused > length)
+			length = bitsused;
+	}
+	memset(data, 0, (length + 7) / 8);
+
 	for (n = 0; n < report->maxfield; n++)
 		hid_output_field(report->field[n], data);
 }

             reply	other threads:[~2010-03-04 21:33 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-04 21:33 Pete Zaitcev [this message]
2010-03-05  8:29 ` Zeroing the report before setting fields Dmitry Torokhov
2010-03-09 12:41   ` Jiri Kosina
2010-03-09 23:26     ` Pete Zaitcev
2010-03-13 22:25       ` Jiri Kosina
2010-03-22  5:09         ` Pete Zaitcev
2010-03-22 16:30           ` Jiri Kosina
2010-03-22 22:22             ` Pete Zaitcev
2010-04-12 16:08               ` Jiri Kosina

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=20100304143349.2d861ec6@redhat.com \
    --to=zaitcev@redhat.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    /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.