Detect usb keyboard properly, support keyboard hotpluanad multiple keyboards
This commit is contained in:
parent
b92c6ff67f
commit
3a25376967
1 changed files with 82 additions and 34 deletions
|
@ -54,7 +54,6 @@ static char keyboard_map_shift[128] =
|
||||||
'?'
|
'?'
|
||||||
};
|
};
|
||||||
|
|
||||||
static grub_usb_device_t usbdev;
|
|
||||||
|
|
||||||
/* Valid values for bmRequestType. See HID definition version 1.11 section
|
/* Valid values for bmRequestType. See HID definition version 1.11 section
|
||||||
7.2. */
|
7.2. */
|
||||||
|
@ -69,36 +68,64 @@ static grub_usb_device_t usbdev;
|
||||||
#define USB_HID_SET_IDLE 0x0A
|
#define USB_HID_SET_IDLE 0x0A
|
||||||
#define USB_HID_SET_PROTOCOL 0x0B
|
#define USB_HID_SET_PROTOCOL 0x0B
|
||||||
|
|
||||||
|
static int grub_usb_keyboard_checkkey (struct grub_term_input *term);
|
||||||
|
static int grub_usb_keyboard_getkey (struct grub_term_input *term);
|
||||||
|
static int grub_usb_keyboard_getkeystatus (struct grub_term_input *term);
|
||||||
|
|
||||||
|
static struct grub_term_input grub_usb_keyboard_term =
|
||||||
|
{
|
||||||
|
.checkkey = grub_usb_keyboard_checkkey,
|
||||||
|
.getkey = grub_usb_keyboard_getkey,
|
||||||
|
.getkeystatus = grub_usb_keyboard_getkeystatus,
|
||||||
|
.next = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct grub_term_input grub_usb_keyboards[16];
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_usb_hid (void)
|
grub_usb_keyboard_detach (grub_usb_device_t usbdev,
|
||||||
|
int config __attribute__ ((unused)),
|
||||||
|
int interface __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
struct grub_usb_desc_device *descdev;
|
unsigned i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE (grub_usb_keyboards); i++)
|
||||||
|
if (grub_usb_keyboards[i].data && grub_usb_keyboards[i].data == usbdev)
|
||||||
|
{
|
||||||
|
grub_term_unregister_input (&grub_usb_keyboards[i]);
|
||||||
|
grub_free ((char *) grub_usb_keyboards[i].name);
|
||||||
|
grub_usb_keyboards[i].name = NULL;
|
||||||
|
grub_usb_keyboards[i].data = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto int usb_iterate (grub_usb_device_t dev);
|
static int
|
||||||
int usb_iterate (grub_usb_device_t dev)
|
grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno)
|
||||||
{
|
{
|
||||||
descdev = &dev->descdev;
|
unsigned curnum;
|
||||||
|
|
||||||
grub_dprintf ("usb_keyboard", "%x %x %x\n",
|
grub_dprintf ("usb_keyboard", "%x %x %x %d %d\n",
|
||||||
descdev->class, descdev->subclass, descdev->protocol);
|
usbdev->descdev.class, usbdev->descdev.subclass,
|
||||||
|
usbdev->descdev.protocol, configno, interfno);
|
||||||
|
|
||||||
|
for (curnum = 0; curnum < ARRAY_SIZE (grub_usb_keyboards); curnum++)
|
||||||
|
if (!grub_usb_keyboards[curnum].data)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (curnum == ARRAY_SIZE (grub_usb_keyboards))
|
||||||
|
return 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (descdev->class != 0x09
|
if (descdev->class != 0x09
|
||||||
|| descdev->subclass == 0x01
|
|| descdev->subclass == 0x01
|
||||||
|| descdev->protocol != 0x02)
|
|| descdev->protocol != 0x02)
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (descdev->class != 0 || descdev->subclass != 0 || descdev->protocol != 0)
|
if (usbdev->descdev.class != 0
|
||||||
return 0;
|
|| usbdev->descdev.subclass != 0 || usbdev->descdev.protocol != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
grub_printf ("HID found!\n");
|
grub_printf ("HID found!\n");
|
||||||
|
|
||||||
usbdev = dev;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
grub_usb_iterate (usb_iterate);
|
|
||||||
|
|
||||||
/* Place the device in boot mode. */
|
/* Place the device in boot mode. */
|
||||||
grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_PROTOCOL,
|
grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_PROTOCOL,
|
||||||
|
@ -107,6 +134,19 @@ grub_usb_hid (void)
|
||||||
/* Reports every time an event occurs and not more often than that. */
|
/* Reports every time an event occurs and not more often than that. */
|
||||||
grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
|
grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
|
||||||
0<<8, 0, 0, 0);
|
0<<8, 0, 0, 0);
|
||||||
|
|
||||||
|
grub_memcpy (&grub_usb_keyboards[curnum], &grub_usb_keyboard_term,
|
||||||
|
sizeof (grub_usb_keyboards[curnum]));
|
||||||
|
grub_usb_keyboards[curnum].data = usbdev;
|
||||||
|
usbdev->config[configno].interf[interfno].detach_hook
|
||||||
|
= grub_usb_keyboard_detach;
|
||||||
|
grub_usb_keyboards[curnum].name = grub_xasprintf ("usb_keyboard%d", curnum);
|
||||||
|
if (!grub_usb_keyboards[curnum].name)
|
||||||
|
return 0;
|
||||||
|
grub_term_register_input_active ("usb_keyboard", &grub_usb_keyboards[curnum]);
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -119,13 +159,14 @@ grub_usb_keyboard_getreport (grub_usb_device_t dev, grub_uint8_t *report)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused)))
|
grub_usb_keyboard_checkkey (struct grub_term_input *term)
|
||||||
{
|
{
|
||||||
grub_uint8_t data[8];
|
grub_uint8_t data[8];
|
||||||
int key;
|
int key;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
grub_uint64_t currtime;
|
grub_uint64_t currtime;
|
||||||
int timeout = 50;
|
int timeout = 50;
|
||||||
|
grub_usb_device_t usbdev = term->data;
|
||||||
|
|
||||||
data[2] = 0;
|
data[2] = 0;
|
||||||
currtime = grub_get_time_ms ();
|
currtime = grub_get_time_ms ();
|
||||||
|
@ -196,6 +237,7 @@ grub_usb_keyboard_getkey (struct grub_term_input *term)
|
||||||
grub_uint64_t currtime;
|
grub_uint64_t currtime;
|
||||||
int timeout;
|
int timeout;
|
||||||
static grub_usb_keyboard_repeat_t repeat = GRUB_HIDBOOT_REPEAT_NONE;
|
static grub_usb_keyboard_repeat_t repeat = GRUB_HIDBOOT_REPEAT_NONE;
|
||||||
|
grub_usb_device_t usbdev = term->data;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
|
|
||||||
|
@ -253,13 +295,14 @@ grub_usb_keyboard_getkey (struct grub_term_input *term)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grub_usb_keyboard_getkeystatus (struct grub_term_input *term __attribute__ ((unused)))
|
grub_usb_keyboard_getkeystatus (struct grub_term_input *term)
|
||||||
{
|
{
|
||||||
grub_uint8_t data[8];
|
grub_uint8_t data[8];
|
||||||
int mods = 0;
|
int mods = 0;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
grub_uint64_t currtime;
|
grub_uint64_t currtime;
|
||||||
int timeout = 50;
|
int timeout = 50;
|
||||||
|
grub_usb_device_t usbdev = term->data;
|
||||||
|
|
||||||
/* Set idle time to the minimum offered by the spec (4 milliseconds) so
|
/* Set idle time to the minimum offered by the spec (4 milliseconds) so
|
||||||
that we can find out the current state. */
|
that we can find out the current state. */
|
||||||
|
@ -307,22 +350,27 @@ grub_usb_keyboard_getkeystatus (struct grub_term_input *term __attribute__ ((unu
|
||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct grub_term_input grub_usb_keyboard_term =
|
struct grub_usb_attach_desc attach_hook =
|
||||||
{
|
{
|
||||||
.name = "usb_keyboard",
|
.class = GRUB_USB_CLASS_HID,
|
||||||
.checkkey = grub_usb_keyboard_checkkey,
|
.hook = grub_usb_keyboard_attach
|
||||||
.getkey = grub_usb_keyboard_getkey,
|
};
|
||||||
.getkeystatus = grub_usb_keyboard_getkeystatus,
|
|
||||||
.next = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(usb_keyboard)
|
GRUB_MOD_INIT(usb_keyboard)
|
||||||
{
|
{
|
||||||
grub_usb_hid ();
|
grub_usb_register_attach_hook_class (&attach_hook);
|
||||||
grub_term_register_input ("usb_keyboard", &grub_usb_keyboard_term);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_FINI(usb_keyboard)
|
GRUB_MOD_FINI(usb_keyboard)
|
||||||
{
|
{
|
||||||
grub_term_unregister_input (&grub_usb_keyboard_term);
|
unsigned i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE (grub_usb_keyboards); i++)
|
||||||
|
if (grub_usb_keyboards[i].data)
|
||||||
|
{
|
||||||
|
grub_term_unregister_input (&grub_usb_keyboards[i]);
|
||||||
|
grub_free ((char *) grub_usb_keyboards[i].name);
|
||||||
|
grub_usb_keyboards[i].name = NULL;
|
||||||
|
grub_usb_keyboards[i].data = 0;
|
||||||
|
}
|
||||||
|
grub_usb_unregister_attach_hook_class (&attach_hook);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue