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 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.