[coreboot] New patch to review for coreboot: 31e7318 libpayload: Make USB HID support multiple keyboards

Nico Huber (nico.huber@secunet.com) gerrit at coreboot.org
Fri Nov 23 15:01:04 CET 2012


Nico Huber (nico.huber at secunet.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1907

-gerrit

commit 31e73184bca37955a6cd40fe7ace331d31f8b351
Author: Nico Huber <nico.huber at secunet.com>
Date:   Fri Nov 23 13:18:13 2012 +0100

    libpayload: Make USB HID support multiple keyboards
    
    The USB HID driver had some static variables with keyboard state. This
    moves them to the driver's instance, so multiple attached keyboards
    don't effect each other.
    
    Change-Id: I3f1ccfdea95062b443cebe510abf2f72fdeb1916
    Signed-off-by: Nico Huber <nico.huber at secunet.com>
---
 payloads/libpayload/drivers/usb/usbhid.c | 58 ++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 26 deletions(-)

diff --git a/payloads/libpayload/drivers/usb/usbhid.c b/payloads/libpayload/drivers/usb/usbhid.c
index 496fbaa..9464680 100644
--- a/payloads/libpayload/drivers/usb/usbhid.c
+++ b/payloads/libpayload/drivers/usb/usbhid.c
@@ -42,9 +42,22 @@ enum { GET_REPORT = 0x1, GET_IDLE = 0x2, GET_PROTOCOL = 0x3, SET_REPORT =
 		0x9, SET_IDLE = 0xa, SET_PROTOCOL = 0xb
 };
 
+typedef union {
+	struct {
+		u8 modifiers;
+		u8 repeats;
+		u8 keys[6];
+	};
+	u8 buffer[8];
+} usb_hid_keyboard_event_t;
+
 typedef struct {
 	void* queue;
 	hid_descriptor_t *descriptor;
+
+	usb_hid_keyboard_event_t previous;
+	int lastkeypress;
+	int repeat_delay;
 } usbhid_inst_t;
 
 #define HID_INST(dev) ((usbhid_inst_t*)(dev)->data)
@@ -241,25 +254,17 @@ static void usb_hid_keyboard_queue(int ch) {
 		keybuffer[keycount++] = ch;
 }
 
-typedef union {
-	struct {
-		u8 modifiers;
-		u8 repeats;
-		u8 keys[6];
-	};
-	u8 buffer[8];
-} usb_hid_keyboard_event_t;
-
 #define KEYBOARD_REPEAT_MS	30
 #define INITIAL_REPEAT_DELAY	10
 #define REPEAT_DELAY		 2
 
 static void
-usb_hid_process_keyboard_event(usb_hid_keyboard_event_t *current,
-		usb_hid_keyboard_event_t *previous)
+usb_hid_process_keyboard_event(usbhid_inst_t *const inst,
+		const usb_hid_keyboard_event_t *const current)
 {
+	const usb_hid_keyboard_event_t *const previous = &inst->previous;
+
 	int i, keypress = 0, modifiers = 0;
-	static int lastkeypress = 0, repeat_delay = INITIAL_REPEAT_DELAY;
 
 	if (current->modifiers & 0x01) /* Left-Ctrl */   modifiers |= MOD_CTRL;
 	if (current->modifiers & 0x02) /* Left-Shift */  modifiers |= MOD_SHIFT;
@@ -278,19 +283,20 @@ usb_hid_process_keyboard_event(usb_hid_keyboard_event_t *current,
 	}
 
 	/* Did the event change at all? */
-	if (lastkeypress && !memcmp(current, previous, sizeof(usb_hid_keyboard_event_t))) {
+	if (inst->lastkeypress &&
+			!memcmp(current, previous, sizeof(*current))) {
 		/* No. Then it's a key repeat event. */
-		if (repeat_delay) {
-			repeat_delay--;
+		if (inst->repeat_delay) {
+			inst->repeat_delay--;
 		} else {
-			usb_hid_keyboard_queue(lastkeypress);
-			repeat_delay = REPEAT_DELAY;
+			usb_hid_keyboard_queue(inst->lastkeypress);
+			inst->repeat_delay = REPEAT_DELAY;
 		}
 
 		return;
 	}
 
-	lastkeypress = 0;
+	inst->lastkeypress = 0;
 
 	for (i=0; i<6; i++) {
 		int j;
@@ -337,8 +343,8 @@ usb_hid_process_keyboard_event(usb_hid_keyboard_event_t *current,
 		usb_hid_keyboard_queue(keypress);
 
 		/* Remember for authentic key repeat */
-		lastkeypress = keypress;
-		repeat_delay = INITIAL_REPEAT_DELAY;
+		inst->lastkeypress = keypress;
+		inst->repeat_delay = INITIAL_REPEAT_DELAY;
 	}
 }
 
@@ -346,14 +352,12 @@ static void
 usb_hid_poll (usbdev_t *dev)
 {
 	usb_hid_keyboard_event_t current;
-	static usb_hid_keyboard_event_t previous = {
-		.buffer = { 0, 0, 0, 0, 0, 0, 0, 0}
-	};
-	u8* buf;
+	const u8 *buf;
+
 	while ((buf=dev->controller->poll_intr_queue (HID_INST(dev)->queue))) {
 		memcpy(&current.buffer, buf, 8);
-		usb_hid_process_keyboard_event(&current, &previous);
-		previous = current;
+		usb_hid_process_keyboard_event(HID_INST(dev), &current);
+		HID_INST(dev)->previous = current;
 	}
 }
 
@@ -437,6 +441,8 @@ usb_hid_init (usbdev_t *dev)
 			dev->data = malloc (sizeof (usbhid_inst_t));
 			if (!dev->data)
 				fatal("Not enough memory for USB HID device.\n");
+			memset(&HID_INST(dev)->previous, 0x00,
+			       sizeof(HID_INST(dev)->previous));
 			usb_debug ("  configuring...\n");
 			usb_hid_set_protocol(dev, interface, hid_proto_boot);
 			usb_hid_set_idle(dev, interface, KEYBOARD_REPEAT_MS);




More information about the coreboot mailing list