From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1Ov6Vv-0007aX-Ug for mharc-grub-devel@gnu.org; Mon, 13 Sep 2010 06:43:55 -0400 Received: from [140.186.70.92] (port=36554 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ov6Vs-0007YX-Pg for grub-devel@gnu.org; Mon, 13 Sep 2010 06:43:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1Ov6Vr-0007bO-G4 for grub-devel@gnu.org; Mon, 13 Sep 2010 06:43:52 -0400 Received: from smtp-out4.iol.cz ([194.228.2.92]:34630) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Ov6Vr-0007aN-0o for grub-devel@gnu.org; Mon, 13 Sep 2010 06:43:51 -0400 Received: from antivir6.iol.cz (unknown [192.168.30.215]) by smtp-out4.iol.cz (Postfix) with ESMTP id 9B623CE4E9C for ; Mon, 13 Sep 2010 10:43:48 +0000 (UTC) Received: from localhost (antivir6.iol.cz [127.0.0.1]) by antivir6.iol.cz (Postfix) with ESMTP id 3A822720088 for ; Mon, 13 Sep 2010 12:43:48 +0200 (CEST) X-Virus-Scanned: amavisd-new at iol.cz Received: from antivir6.iol.cz ([127.0.0.1]) by localhost (antivir6.iol.cz [127.0.0.1]) (amavisd-new, port 10224) with LMTP id Kp0X-cuPagJU for ; Mon, 13 Sep 2010 12:43:48 +0200 (CEST) Received: from port4.iol.cz (unknown [192.168.30.94]) by antivir6.iol.cz (Postfix) with ESMTP id DB69E72005E for ; Mon, 13 Sep 2010 12:43:37 +0200 (CEST) X-SBRS: None X-SBRS-none: None X-RECVLIST: MTA-OUT-IOL X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjcMABOdjUxVRnXk/2dsb2JhbAAHgxOBActIkQmETHQE Received: from 228.117.broadband3.iol.cz (HELO [192.168.6.160]) ([85.70.117.228]) by port4.iol.cz with ESMTP; 13 Sep 2010 12:43:37 +0200 From: =?UTF-8?Q?Ale=C5=A1?= Nesrsta To: The development of GNU GRUB In-Reply-To: <1284312512.5714.83.camel@pracovna> References: <4C7519E8.90907@gmail.com> <20100826230527.GA26246@pina.cat> <4C76F58D.6020304@gmail.com> <1282995082.14285.4.camel@pracovna> <4C7AF2BB.2040606@gmail.com> <4C7AF7E1.7020204@gmail.com> <1283551348.27688.89.camel@pracovna> <1283621655.4824.25.camel@pracovna> <1284312512.5714.83.camel@pracovna> Content-Type: multipart/mixed; boundary="=-kvxFvIDjbqhEM6w3a+WK" Date: Mon, 13 Sep 2010 12:43:34 +0200 Message-Id: <1284374614.13334.8.camel@pracovna> Mime-Version: 1.0 X-Mailer: Evolution 2.22.3.1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Subject: [PATCH] usb_keyboard.c problems (USB issues - kbdlayouts branch) X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Sep 2010 10:43:54 -0000 --=-kvxFvIDjbqhEM6w3a+WK Content-Type: text/plain Content-Transfer-Encoding: 7bit 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 --=-kvxFvIDjbqhEM6w3a+WK Content-Disposition: attachment; filename=usb_keyboard_patch_100913_0 Content-Type: text/x-patch; name=usb_keyboard_patch_100913_0; charset=UTF-8 Content-Transfer-Encoding: 7bit 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 --=-kvxFvIDjbqhEM6w3a+WK--