From: "Aleš Nesrsta" <starous@volny.cz>
To: The development of GNU GRUB <grub-devel@gnu.org>
Subject: [PATCH] usb_keyboard.c problems (USB issues - kbdlayouts branch)
Date: Mon, 13 Sep 2010 12:43:34 +0200 [thread overview]
Message-ID: <1284374614.13334.8.camel@pracovna> (raw)
In-Reply-To: <1284312512.5714.83.camel@pracovna>
[-- Attachment #1: Type: text/plain, Size: 447 bytes --]
Hi,
I found two problems in usb_keyboard, included patch should solve them
(I hope...):
1.
Configuration of USB device was misssing.
(Additionally, for low speed devices on UHCI should be applied patch
which I sent at Sat, 04 Sep 2010 00:02:28, subject: "Re: Plans on 1.99
release - USB issues").
2.
Received report was wrongly interpreted. It caused wrong repeating of
keys, for example when more than one key were pressed etc.
Regards
Ales
[-- Attachment #2: usb_keyboard_patch_100913_0 --]
[-- Type: text/x-patch, Size: 5544 bytes --]
diff -urB ./kbdlayouts/grub-core/term/usb_keyboard.c ./kbdlayouts_changed/grub-core/term/usb_keyboard.c
--- ./kbdlayouts/grub-core/term/usb_keyboard.c 2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/term/usb_keyboard.c 2010-09-13 12:21:50.000000000 +0200
@@ -75,6 +75,10 @@
int dead;
int last_key;
grub_uint64_t repeat_time;
+ grub_uint8_t current_report[8];
+ grub_uint8_t last_report[8];
+ int index;
+ int max_index;
};
static int grub_usb_keyboard_getkey (struct grub_term_input *term);
@@ -192,6 +196,9 @@
data->interfno = interfno;
data->endp = endp;
+ /* Configure device */
+ grub_usb_set_configuration (usbdev, configno + 1);
+
/* Place the device in boot mode. */
grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT,
USB_HID_SET_PROTOCOL, 0, interfno, 0, 0);
@@ -271,16 +278,95 @@
}
static int
+parse_keycode (struct grub_usb_keyboard_data *termdata)
+{
+ int index = termdata->index;
+ int i, keycode;
+
+ /* Sanity check */
+ if (index < 2)
+ index = 2;
+
+ for ( ; index < termdata->max_index; index++)
+ {
+ keycode = termdata->current_report[index];
+
+ if (keycode == KEY_NO_KEY
+ || keycode == KEY_ERR_BUFFER
+ || keycode == KEY_ERR_POST
+ || keycode == KEY_ERR_UNDEF)
+ {
+ /* Don't parse (rest of) this report */
+ termdata->index = 0;
+ if (keycode != KEY_NO_KEY)
+ /* Don't replace last report with current faulty report
+ * in future ! */
+ grub_memcpy (termdata->current_report,
+ termdata->last_report,
+ sizeof (termdata->report));
+ return GRUB_TERM_NO_KEY;
+ }
+
+ /* Try to find current keycode in last report. */
+ for (i = 2; i < 8; i++)
+ if (keycode == termdata->last_report[i])
+ break;
+ if (i < 8)
+ /* Keycode is in last report, it means it was not released,
+ * ignore it. */
+ continue;
+
+ if (keycode == KEY_CAPS_LOCK)
+ {
+ termdata->mods ^= GRUB_TERM_STATUS_CAPS;
+ send_leds (termdata);
+ continue;
+ }
+
+ if (keycode == KEY_NUM_LOCK)
+ {
+ termdata->mods ^= GRUB_TERM_STATUS_NUM;
+ send_leds (termdata);
+ continue;
+ }
+
+ termdata->last_key = grub_term_map_key (keycode,
+ interpret_status (termdata->current_report[0])
+ | termdata->mods);
+ termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL;
+
+ grub_errno = GRUB_ERR_NONE;
+
+ index++;
+ if (index >= termdata->max_index)
+ termdata->index = 0;
+ else
+ termdata->index = index;
+
+ return termdata->last_key;
+ }
+
+ /* All keycodes parsed */
+ termdata->index = 0;
+ return GRUB_TERM_NO_KEY;
+}
+
+static int
grub_usb_keyboard_getkey (struct grub_term_input *term)
{
grub_usb_err_t err;
struct grub_usb_keyboard_data *termdata = term->data;
- grub_uint8_t data[sizeof (termdata->report)];
grub_size_t actual;
+ int keycode = GRUB_TERM_NO_KEY;
if (termdata->dead)
return GRUB_TERM_NO_KEY;
+ if (termdata->index)
+ keycode = parse_keycode (termdata);
+ if (keycode != GRUB_TERM_NO_KEY)
+ return keycode;
+
/* Poll interrupt pipe. */
err = grub_usb_check_transfer (termdata->transfer, &actual);
@@ -296,7 +382,14 @@
return GRUB_TERM_NO_KEY;
}
- grub_memcpy (data, termdata->report, sizeof (data));
+ if (!err && (actual >= 3))
+ grub_memcpy (termdata->last_report,
+ termdata->current_report,
+ sizeof (termdata->report));
+
+ grub_memcpy (termdata->current_report,
+ termdata->report,
+ sizeof (termdata->report));
termdata->transfer = grub_usb_bulk_read_background (termdata->usbdev,
termdata->endp->endp_addr,
@@ -314,42 +407,23 @@
"err = %d, actual = %d report: 0x%02x 0x%02x 0x%02x 0x%02x"
" 0x%02x 0x%02x 0x%02x 0x%02x\n",
err, actual,
- data[0], data[1], data[2], data[3],
- data[4], data[5], data[6], data[7]);
+ termdata->current_report[0], termdata->current_report[1],
+ termdata->current_report[2], termdata->current_report[3],
+ termdata->current_report[4], termdata->current_report[5],
+ termdata->current_report[6], termdata->current_report[7]);
if (err || actual < 1)
return GRUB_TERM_NO_KEY;
- termdata->status = data[0];
+ termdata->status = termdata->current_report[0];
if (actual < 3)
return GRUB_TERM_NO_KEY;
- if (data[2] == KEY_NO_KEY || data[2] == KEY_ERR_BUFFER
- || data[2] == KEY_ERR_POST || data[2] == KEY_ERR_UNDEF)
- return GRUB_TERM_NO_KEY;
-
- if (data[2] == KEY_CAPS_LOCK)
- {
- termdata->mods ^= GRUB_TERM_STATUS_CAPS;
- send_leds (termdata);
- return GRUB_TERM_NO_KEY;
- }
-
- if (data[2] == KEY_NUM_LOCK)
- {
- termdata->mods ^= GRUB_TERM_STATUS_NUM;
- send_leds (termdata);
- return GRUB_TERM_NO_KEY;
- }
-
- termdata->last_key = grub_term_map_key (data[2], interpret_status (data[0])
- | termdata->mods);
- termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL;
-
- grub_errno = GRUB_ERR_NONE;
-
- return termdata->last_key;
+ termdata->index = 2; /* New data received. */
+ termdata->max_index = actual;
+
+ return parse_keycode (termdata);
}
static int
next prev parent reply other threads:[~2010-09-13 10:43 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-25 13:26 Plans on 1.99 release Vladimir 'φ-coder/phcoder' Serbinenko
2010-08-26 23:05 ` Carles Pina i Estany
2010-08-26 23:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-08-28 11:31 ` Aleš Nesrsta
2010-08-29 23:52 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-08-30 0:14 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-09-03 22:02 ` Plans on 1.99 release - USB issues Aleš Nesrsta
2010-09-04 17:34 ` Aleš Nesrsta
2010-09-12 17:28 ` [PATCH] USB issues - kbdlayouts branch Aleš Nesrsta
2010-09-13 10:43 ` Aleš Nesrsta [this message]
2010-09-13 11:47 ` Aleš Nesrsta
2010-09-13 18:13 ` Aleš Nesrsta
2010-09-15 5:58 ` [PATCH] USB serial - missing configuration Aleš Nesrsta
2010-09-19 11:46 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-09-21 20:18 ` Aleš Nesrsta
2010-09-23 21:13 ` Trunk: boot problem - unaligned pointer 0x Aleš Nesrsta
2010-09-26 9:58 ` Aleš Nesrsta
2010-09-30 19:37 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-09-30 20:45 ` Aleš Nesrsta
2010-09-15 5:58 ` Question: USB serial - device driver debugging Aleš Nesrsta
2010-09-30 17:53 ` [RFC - Vladimir ?] USB/RS232 converter PL2303 small problem Aleš Nesrsta
2010-10-17 11:54 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-09-18 10:08 ` Plans on 1.99 release - USB issues Vladimir 'φ-coder/phcoder' Serbinenko
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=1284374614.13334.8.camel@pracovna \
--to=starous@volny.cz \
--cc=grub-devel@gnu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).