commit-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[1998] 2009-02-21 Robert Millan <address@hidden>


From: Robert Millan
Subject: [1998] 2009-02-21 Robert Millan <address@hidden>
Date: Sat, 21 Feb 2009 14:55:07 +0000

Revision: 1998
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=1998
Author:   robertmh
Date:     2009-02-21 14:55:06 +0000 (Sat, 21 Feb 2009)

Log Message:
-----------
2009-02-21  Robert Millan  <address@hidden>

        Implement USB keyboard support (based on patch by Marco Gerards)

        * conf/i386-pc.rmk (pkglib_MODULES): Add `usb_keyboard.mod'.
        (usb_keyboard_mod_SOURCES, usb_keyboard_mod_CFLAGS)
        (usb_keyboard_mod_LDFLAGS): New variables.

        * term/usb_keyboard.c: New file.

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/DISTLIST
    trunk/grub2/conf/i386-pc.mk
    trunk/grub2/conf/i386-pc.rmk

Added Paths:
-----------
    trunk/grub2/term/usb_keyboard.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog       2009-02-21 12:41:18 UTC (rev 1997)
+++ trunk/grub2/ChangeLog       2009-02-21 14:55:06 UTC (rev 1998)
@@ -1,3 +1,13 @@
+2009-02-21  Robert Millan  <address@hidden>
+
+       Implement USB keyboard support (based on patch by Marco Gerards)
+
+       * conf/i386-pc.rmk (pkglib_MODULES): Add `usb_keyboard.mod'.
+       (usb_keyboard_mod_SOURCES, usb_keyboard_mod_CFLAGS)
+       (usb_keyboard_mod_LDFLAGS): New variables.
+
+       * term/usb_keyboard.c: New file.
+
 2009-02-14  Vladimir Serbinenko  <address@hidden>
 
        Corrected wrong declaration

Modified: trunk/grub2/DISTLIST
===================================================================
--- trunk/grub2/DISTLIST        2009-02-21 12:41:18 UTC (rev 1997)
+++ trunk/grub2/DISTLIST        2009-02-21 14:55:06 UTC (rev 1998)
@@ -425,6 +425,7 @@
 term/gfxterm.c
 term/terminfo.c
 term/tparm.c
+term/usb_keyboard.c
 term/efi/console.c
 term/i386/vga_common.c
 term/i386/pc/at_keyboard.c

Modified: trunk/grub2/conf/i386-pc.mk
===================================================================
--- trunk/grub2/conf/i386-pc.mk 2009-02-21 12:41:18 UTC (rev 1997)
+++ trunk/grub2/conf/i386-pc.mk 2009-02-21 14:55:06 UTC (rev 1998)
@@ -980,7 +980,7 @@
        ata.mod vga.mod memdisk.mod pci.mod lspci.mod \
        aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
        datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \
-       usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod
+       usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod
 
 # For biosdisk.mod.
 biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
@@ -3054,6 +3054,63 @@
 usbms_mod_CFLAGS = $(COMMON_CFLAGS)
 usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For usb_keyboard.mod
+usb_keyboard_mod_SOURCES = term/usb_keyboard.c
+CLEANFILES += usb_keyboard.mod mod-usb_keyboard.o mod-usb_keyboard.c 
pre-usb_keyboard.o usb_keyboard_mod-term_usb_keyboard.o und-usb_keyboard.lst
+ifneq ($(usb_keyboard_mod_EXPORTS),no)
+CLEANFILES += def-usb_keyboard.lst
+DEFSYMFILES += def-usb_keyboard.lst
+endif
+MOSTLYCLEANFILES += usb_keyboard_mod-term_usb_keyboard.d
+UNDSYMFILES += und-usb_keyboard.lst
+
+usb_keyboard.mod: pre-usb_keyboard.o mod-usb_keyboard.o $(TARGET_OBJ2ELF)
+       -rm -f $@
+       $(TARGET_CC) $(usb_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) 
$(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-usb_keyboard.o mod-usb_keyboard.o
+       if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f 
$@; exit 1); fi
+       $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K 
_grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+
+pre-usb_keyboard.o: $(usb_keyboard_mod_DEPENDENCIES) 
usb_keyboard_mod-term_usb_keyboard.o
+       -rm -f $@
+       $(TARGET_CC) $(usb_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o 
$@ usb_keyboard_mod-term_usb_keyboard.o
+
+mod-usb_keyboard.o: mod-usb_keyboard.c
+       $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) 
$(usb_keyboard_mod_CFLAGS) -c -o $@ $<
+
+mod-usb_keyboard.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+       sh $(srcdir)/genmodsrc.sh 'usb_keyboard' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(usb_keyboard_mod_EXPORTS),no)
+def-usb_keyboard.lst: pre-usb_keyboard.o
+       $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 
usb_keyboard/' > $@
+endif
+
+und-usb_keyboard.lst: pre-usb_keyboard.o
+       echo 'usb_keyboard' > $@
+       $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+usb_keyboard_mod-term_usb_keyboard.o: term/usb_keyboard.c 
$(term/usb_keyboard.c_DEPENDENCIES)
+       $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  
$(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -MD -c -o $@ $<
+-include usb_keyboard_mod-term_usb_keyboard.d
+
+CLEANFILES += cmd-usb_keyboard_mod-term_usb_keyboard.lst 
fs-usb_keyboard_mod-term_usb_keyboard.lst 
partmap-usb_keyboard_mod-term_usb_keyboard.lst
+COMMANDFILES += cmd-usb_keyboard_mod-term_usb_keyboard.lst
+FSFILES += fs-usb_keyboard_mod-term_usb_keyboard.lst
+PARTMAPFILES += partmap-usb_keyboard_mod-term_usb_keyboard.lst
+
+cmd-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c 
$(term/usb_keyboard.c_DEPENDENCIES) gencmdlist.sh
+       set -e;           $(TARGET_CC) -Iterm -I$(srcdir)/term 
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $<       | sh 
$(srcdir)/gencmdlist.sh usb_keyboard > $@ || (rm -f $@; exit 1)
+
+fs-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c 
$(term/usb_keyboard.c_DEPENDENCIES) genfslist.sh
+       set -e;           $(TARGET_CC) -Iterm -I$(srcdir)/term 
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $<       | sh 
$(srcdir)/genfslist.sh usb_keyboard > $@ || (rm -f $@; exit 1)
+
+partmap-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c 
$(term/usb_keyboard.c_DEPENDENCIES) genpartmaplist.sh
+       set -e;           $(TARGET_CC) -Iterm -I$(srcdir)/term 
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $<       | sh 
$(srcdir)/genpartmaplist.sh usb_keyboard > $@ || (rm -f $@; exit 1)
+
+
+usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For pxe.mod
 pxe_mod_SOURCES = fs/i386/pc/pxe.c
 CLEANFILES += pxe.mod mod-pxe.o mod-pxe.c pre-pxe.o pxe_mod-fs_i386_pc_pxe.o 
und-pxe.lst

Modified: trunk/grub2/conf/i386-pc.rmk
===================================================================
--- trunk/grub2/conf/i386-pc.rmk        2009-02-21 12:41:18 UTC (rev 1997)
+++ trunk/grub2/conf/i386-pc.rmk        2009-02-21 14:55:06 UTC (rev 1998)
@@ -173,7 +173,7 @@
        ata.mod vga.mod memdisk.mod pci.mod lspci.mod \
        aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
        datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \
-       usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod
+       usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod
 
 # For biosdisk.mod.
 biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
@@ -335,6 +335,11 @@
 usbms_mod_CFLAGS = $(COMMON_CFLAGS)
 usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For usb_keyboard.mod
+usb_keyboard_mod_SOURCES = term/usb_keyboard.c
+usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For pxe.mod
 pxe_mod_SOURCES = fs/i386/pc/pxe.c
 pxe_mod_CFLAGS = $(COMMON_CFLAGS)

Added: trunk/grub2/term/usb_keyboard.c
===================================================================
--- trunk/grub2/term/usb_keyboard.c                             (rev 0)
+++ trunk/grub2/term/usb_keyboard.c     2009-02-21 14:55:06 UTC (rev 1998)
@@ -0,0 +1,257 @@
+/* Support for the HID Boot Protocol.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/machine/machine.h>
+#include <grub/machine/console.h>
+#include <grub/time.h>
+#include <grub/cpu/io.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/usb.h>
+#include <grub/dl.h>
+#include <grub/time.h>
+
+
+static char keyboard_map[128] =
+  {
+    '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd',
+    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+    'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+    'u', 'v', 'w', 'x', 'y', 'z', '1', '2',
+    '3', '4', '5', '6', '7', '8', '9', '0',
+    '\n', GRUB_TERM_ESC, GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, ' ', '-', '=', 
'[',
+    ']', '\\', '#', ';', '\'', '`', ',', '.',
+    '/', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', GRUB_TERM_HOME, GRUB_TERM_PPAGE, GRUB_TERM_DC, GRUB_TERM_END, 
GRUB_TERM_NPAGE, GRUB_TERM_RIGHT,
+    GRUB_TERM_LEFT, GRUB_TERM_DOWN, GRUB_TERM_UP
+  };
+
+static char keyboard_map_shift[128] =
+  {
+    '\0', '\0', '\0', '\0', 'A', 'B', 'C', 'D',
+    'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+    'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+    'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@',
+    '#', '$', '%', '^', '&', '*', '(', ')',
+    '\n', '\0', '\0', '\0', ' ', '_', '+', '{',
+    '}', '|', '#', ':', '"', '`', '<', '>',
+    '?'
+  };
+
+static grub_usb_device_t usbdev;
+
+static void
+grub_usb_hid (void)
+{
+  struct grub_usb_desc_device *descdev;
+
+  auto int usb_iterate (grub_usb_device_t dev);
+  int usb_iterate (grub_usb_device_t dev)
+    {
+      descdev = &dev->descdev;
+      
+      grub_dprintf ("usb_keyboard", "%x %x %x\n",
+                  descdev->class, descdev->subclass, descdev->protocol);
+
+#if 0
+      if (descdev->class != 0x09
+         || descdev->subclass == 0x01
+         || descdev->protocol != 0x02)
+       return 0;
+#endif
+
+      if (descdev->class != 0 || descdev->subclass != 0 || descdev->protocol 
!= 0)
+       return 0;
+
+      grub_printf ("HID found!\n");
+
+      usbdev = dev;
+
+      return 1;
+    }
+  grub_usb_iterate (usb_iterate);
+
+  /* Place the device in boot mode.  */
+  grub_usb_control_msg (usbdev, 0x21, 0x0B, 0, 0, 0, 0);
+
+  /* Reports everytime an event occurs and not more often than that.  */
+  grub_usb_control_msg (usbdev, 0x21, 0x0A, 0<<8, 0, 0, 0);
+}
+
+static grub_err_t
+grub_usb_keyboard_getreport (grub_usb_device_t dev, unsigned char *report)
+{
+  return grub_usb_control_msg (dev, (1 << 7) | (1 << 5) | 1, 0x01, 0, 0,
+                              8, (char *) report);
+}
+
+
+
+static int
+grub_usb_keyboard_checkkey (void)
+{
+  unsigned char data[8];
+  int key;
+  int i;
+  grub_err_t err;
+
+  data[2] = 0;
+  for (i = 0; i < 50; i++)
+    {
+      /* Get_Report.  */
+      err = grub_usb_keyboard_getreport (usbdev, data);
+
+      if (! err && data[2])
+       break;
+    }
+
+  if (err || !data[2])
+    return -1;
+
+  grub_dprintf ("usb_keyboard",
+               "report: 0x%02x 0x%02x 0x%02x 0x%02x"
+               " 0x%02x 0x%02x 0x%02x 0x%02x\n",
+               data[0], data[1], data[2], data[3],
+               data[4], data[5], data[6], data[7]);
+
+  /* Check if the Control or Shift key was pressed.  */
+  if (data[0] & 0x01 || data[0] & 0x10)
+    key = keyboard_map[data[2]] - 'a' + 1;
+  else if (data[0] & 0x02 || data[0] & 0x20)
+    key = keyboard_map_shift[data[2]];
+  else
+    key = keyboard_map[data[2]];
+
+  if (key == 0)
+    grub_printf ("Unknown key 0x%x detected\n", data[2]);
+
+#if 0
+  /* Wait until the key is released.  */
+  while (!err && data[2])
+    {
+      err = grub_usb_control_msg (usbdev, (1 << 7) | (1 << 5) | 1, 0x01, 0, 0,
+                                 sizeof (data), (char *) data);
+      grub_dprintf ("usb_keyboard",
+                   "report2: 0x%02x 0x%02x 0x%02x 0x%02x"
+                   " 0x%02x 0x%02x 0x%02x 0x%02x\n",
+                   data[0], data[1], data[2], data[3],
+                   data[4], data[5], data[6], data[7]);
+    }
+#endif
+
+  grub_errno = GRUB_ERR_NONE;
+
+  return key;
+}
+
+typedef enum
+{
+  GRUB_HIDBOOT_REPEAT_NONE,
+  GRUB_HIDBOOT_REPEAT_FIRST,
+  GRUB_HIDBOOT_REPEAT
+} grub_usb_keyboard_repeat_t;
+
+static int
+grub_usb_keyboard_getkey (void)
+{
+  int key;
+  int key_release;
+  grub_err_t err;
+  unsigned char data[8];
+  grub_uint64_t currtime;
+  int timeout;
+  static grub_usb_keyboard_repeat_t repeat = GRUB_HIDBOOT_REPEAT_NONE;
+
+ again:
+
+  do
+    {
+      key = grub_usb_keyboard_checkkey ();
+    } while (key == -1);
+
+  data[2] = !0; /* Or whatever.  */
+  err = 0;
+
+  switch (repeat)
+    {
+    case GRUB_HIDBOOT_REPEAT_NONE:
+      timeout = 100;
+      break;
+    case GRUB_HIDBOOT_REPEAT_FIRST:
+      timeout = 500;
+      break;
+    case GRUB_HIDBOOT_REPEAT:
+      timeout = 50;
+      break;
+    }
+
+  /* Wait until the key is released.  */
+  currtime = grub_get_time_ms ();
+  while (!err && data[2])
+    {
+      /* Implement a timeout.  */
+      if (grub_get_time_ms () > currtime + timeout)
+       {
+         if (repeat == 0)
+           repeat = 1;
+         else
+           repeat = 2;
+
+         grub_errno = GRUB_ERR_NONE;
+         return key;
+       }
+
+      err = grub_usb_keyboard_getreport (usbdev, data);
+    }
+
+  if (repeat)
+    {
+      repeat = 0;
+      goto again;
+    }
+
+  repeat = 0;
+
+  grub_errno = GRUB_ERR_NONE;
+
+  return key;
+}
+
+static struct grub_term_input grub_usb_keyboard_term =
+  {
+    .name = "usb_keyboard",
+    .checkkey = grub_usb_keyboard_checkkey,
+    .getkey = grub_usb_keyboard_getkey,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(usb_keyboard)
+{
+  (void) mod;                  /* To stop warning. */
+
+  grub_usb_hid ();
+  grub_term_register_input (&grub_usb_keyboard_term);
+}
+
+GRUB_MOD_FINI(usb_keyboard)
+{
+  grub_term_unregister_input (&grub_usb_keyboard_term);
+}






reply via email to

[Prev in Thread] Current Thread [Next in Thread]