The following patch adds support for multiple usb keyboards and mice to seabios. Maximum number of keyboards is configurable in Kconfig and defaults to 1 to keep current behavior.
Tested on: * Qemu q35 with two usb keyboards on seperate displays * Prodrive broadwell-d platform with one Dell keyboard and one virtual KVM keyboard on Aspeed AST2500.
Stef van Os (1): usb-hid: add support for multiple input devices
src/Kconfig | 14 +++++++++++ src/hw/usb-hid.c | 76 ++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 68 insertions(+), 22 deletions(-)
Add support for multiple keyboards and mice. Add a Kconfig option to set maximum number of devices.
Signed-off-by: Stef van Os stef.van.os@prodrive-technologies.com --- src/Kconfig | 14 +++++++++++ src/hw/usb-hid.c | 76 ++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 68 insertions(+), 22 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig index 55a87cb..0dbf61d 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -294,12 +294,26 @@ menu "Hardware support" default y help Support USB keyboards. + config NUM_USB_KEYBOARD + depends on USB_KEYBOARD + int "Maximum number of USB keyboards supported" + default 1 + help + Sets the maximum number of USB keyboards that can be used + at the same time. config USB_MOUSE depends on USB && MOUSE bool "USB mice" default y help Support USB mice. + config NUM_USB_MOUSE + depends on USB_MOUSE + int "Maximum number of USB mice supported" + default 1 + help + Sets the maximum number of USB mice that can be used + at the same time.
config SERIAL bool "Serial port" diff --git a/src/hw/usb-hid.c b/src/hw/usb-hid.c index fa4d9a2..8ed90e2 100644 --- a/src/hw/usb-hid.c +++ b/src/hw/usb-hid.c @@ -12,8 +12,8 @@ #include "usb-hid.h" // usb_keyboard_setup #include "util.h" // process_key
-struct usb_pipe *keyboard_pipe VARFSEG; -struct usb_pipe *mouse_pipe VARFSEG; +struct usb_pipe *keyboard_pipe[CONFIG_NUM_USB_KEYBOARD] VARFSEG = {0}; +struct usb_pipe *mouse_pipe[CONFIG_NUM_USB_MOUSE] VARFSEG = {0};
/**************************************************************** @@ -53,11 +53,22 @@ static int usb_kbd_setup(struct usbdevice_s *usbdev , struct usb_endpoint_descriptor *epdesc) { - if (! CONFIG_USB_KEYBOARD) + int kbd_idx; + + if (!CONFIG_USB_KEYBOARD || CONFIG_NUM_USB_KEYBOARD == 0) { return -1; - if (keyboard_pipe) - // XXX - this enables the first found keyboard (could be random) + } + + for (kbd_idx = 0; kbd_idx < CONFIG_NUM_USB_KEYBOARD; kbd_idx++) { + if (keyboard_pipe[kbd_idx] == NULL) { + break; + } + } + + if (kbd_idx == CONFIG_NUM_USB_KEYBOARD) { + dprintf(1, "USB keyboard %d already in use, skipping..\n", kbd_idx); return -1; + }
if (epdesc->wMaxPacketSize != 8) return -1; @@ -71,11 +82,12 @@ usb_kbd_setup(struct usbdevice_s *usbdev if (ret) return -1;
- keyboard_pipe = usb_alloc_pipe(usbdev, epdesc); - if (!keyboard_pipe) + keyboard_pipe[kbd_idx] = usb_alloc_pipe(usbdev, epdesc); + if (!keyboard_pipe[kbd_idx]) { return -1; + }
- dprintf(1, "USB keyboard initialized\n"); + dprintf(1, "USB keyboard %d initialized\n", kbd_idx); return 0; }
@@ -83,11 +95,22 @@ static int usb_mouse_setup(struct usbdevice_s *usbdev , struct usb_endpoint_descriptor *epdesc) { - if (! CONFIG_USB_MOUSE) + int mouse_idx; + + if (!CONFIG_USB_MOUSE || CONFIG_NUM_USB_MOUSE == 0) { return -1; - if (mouse_pipe) - // XXX - this enables the first found mouse (could be random) + } + + for (mouse_idx = 0; mouse_idx < CONFIG_NUM_USB_MOUSE; mouse_idx++) { + if (mouse_pipe[mouse_idx] == NULL) { + break; + } + } + + if (mouse_idx == CONFIG_NUM_USB_MOUSE) { + dprintf(1, "USB mouse %d already in use, skipping..\n", mouse_idx); return -1; + }
if (epdesc->wMaxPacketSize < 3 || epdesc->wMaxPacketSize > 8) return -1; @@ -97,11 +120,12 @@ usb_mouse_setup(struct usbdevice_s *usbdev if (ret) return -1;
- mouse_pipe = usb_alloc_pipe(usbdev, epdesc); - if (!mouse_pipe) + mouse_pipe[mouse_idx] = usb_alloc_pipe(usbdev, epdesc); + if (!mouse_pipe[mouse_idx]) { return -1; + }
- dprintf(1, "USB mouse initialized\n"); + dprintf(1, "USB mouse %d initialized\n", mouse_idx); return 0; }
@@ -300,11 +324,11 @@ handle_key(struct keyevent *data)
// Check if a USB keyboard event is pending and process it if so. static void -usb_check_key(void) +usb_check_key(int kbd_idx) { if (! CONFIG_USB_KEYBOARD) return; - struct usb_pipe *pipe = GET_GLOBAL(keyboard_pipe); + struct usb_pipe *pipe = GET_GLOBAL(keyboard_pipe[kbd_idx]); if (!pipe) return;
@@ -321,9 +345,10 @@ usb_check_key(void) inline int usb_kbd_active(void) { - if (! CONFIG_USB_KEYBOARD) + if (!CONFIG_USB_KEYBOARD || CONFIG_NUM_USB_KEYBOARD == 0) { return 0; - return GET_GLOBAL(keyboard_pipe) != NULL; + } + return GET_GLOBAL(keyboard_pipe[0]) != NULL; }
// Handle a ps2 style keyboard command. @@ -372,11 +397,11 @@ handle_mouse(struct mouseevent *data)
// Check if a USB mouse event is pending and process it if so. static void -usb_check_mouse(void) +usb_check_mouse(int mouse_idx) { if (! CONFIG_USB_MOUSE) return; - struct usb_pipe *pipe = GET_GLOBAL(mouse_pipe); + struct usb_pipe *pipe = GET_GLOBAL(mouse_pipe[mouse_idx]); if (!pipe) return;
@@ -437,6 +462,13 @@ usb_mouse_command(int command, u8 *param) void usb_check_event(void) { - usb_check_key(); - usb_check_mouse(); + int i; + + for (i = 0; i < CONFIG_NUM_USB_KEYBOARD; i++) { + usb_check_key(i); + } + + for (i = 0; i < CONFIG_NUM_USB_MOUSE; i++) { + usb_check_mouse(i); + } }
On Fri, Dec 15, 2017 at 11:09:45AM +0100, Stef van Os wrote:
The following patch adds support for multiple usb keyboards and mice to seabios. Maximum number of keyboards is configurable in Kconfig and defaults to 1 to keep current behavior.
Thanks. What's the use case for enabling multiple keyboards?
-Kevin
When I have more than 2 usb keyboards connected, SeaBIOS doesn't register keyboard input. This persists even when I get to the disk GRUB menu. I have to manually unplug my other keyboard to do any input during boot.
And by other keyboard, I just mean a separate numerical keypad.
From: SeaBIOS seabios-bounces@seabios.org on behalf of Kevin O'Connor kevin@koconnor.net Sent: 20 December 2017 08:33 To: Stef van Os Cc: seabios@seabios.org Subject: Re: [SeaBIOS] [PATCH 0/1] add multiple usb-hid support
On Fri, Dec 15, 2017 at 11:09:45AM +0100, Stef van Os wrote:
The following patch adds support for multiple usb keyboards and mice to seabios. Maximum number of keyboards is configurable in Kconfig and defaults to 1 to keep current behavior.
Thanks. What's the use case for enabling multiple keyboards?
-Kevin
Hi Kevin,
The use case is that on many boards there is a BMC emulating a keyboard/mouse device (the Aspeed AST2500 in our case). This device is always on, and enumerated first.
This meant that in our case we were never able to use both a "real" keyboard to select the boot mode in SeaBIOS, and the network KVM via the Aspeed at the same time.
With this patch (and multiple keyboards configured in Kconfig) we do not have this limitation anymore, and can use both the network KVM remote, as well as a "real" keyboard on the device to select e.g. network boot or USB install medium.
Br,
Stef
On 12/20/2017 05:33 PM, Kevin O'Connor wrote:
On Fri, Dec 15, 2017 at 11:09:45AM +0100, Stef van Os wrote:
The following patch adds support for multiple usb keyboards and mice to seabios. Maximum number of keyboards is configurable in Kconfig and defaults to 1 to keep current behavior.
Thanks. What's the use case for enabling multiple keyboards?
-Kevin
On Thu, Dec 21, 2017 at 11:47:40AM +0100, Stef van Os wrote:
Hi Kevin,
The use case is that on many boards there is a BMC emulating a keyboard/mouse device (the Aspeed AST2500 in our case). This device is always on, and enumerated first.
This meant that in our case we were never able to use both a "real" keyboard to select the boot mode in SeaBIOS, and the network KVM via the Aspeed at the same time.
With this patch (and multiple keyboards configured in Kconfig) we do not have this limitation anymore, and can use both the network KVM remote, as well as a "real" keyboard on the device to select e.g. network boot or USB install medium.
Okay, thanks. That makes sense.
I agree with Daniel that it would be preferable to do this without a kconfig option. Perhaps put all of the keyboards in a linked list? (FYI, I don't see any reason to support multiple mice, as no one uses the old dos mouse interface anyway.)
-Kevin