Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 294665
b: refs/heads/master
c: 8f30d41
h: refs/heads/master
i:
  294663: d54d169
v: v3
  • Loading branch information
Andrei Warkentin authored and Jason Wessel committed Mar 22, 2012
1 parent e221365 commit ddd75ec
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2366e047840e33928803c0442176fb3991423da8
refs/heads/master: 8f30d411767351656ea62c9e7612120f9b870b59
95 changes: 73 additions & 22 deletions trunk/kernel/debug/kdb/kdb_keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */

static int kbd_exists;
static int kbd_last_ret;

/*
* Check if the keyboard controller has a keypress for us.
Expand Down Expand Up @@ -90,8 +91,11 @@ int kdb_get_kbd_char(void)
return -1;
}

if ((scancode & 0x80) != 0)
if ((scancode & 0x80) != 0) {
if (scancode == 0x9c)
kbd_last_ret = 0;
return -1;
}

scancode &= 0x7f;

Expand Down Expand Up @@ -178,35 +182,82 @@ int kdb_get_kbd_char(void)
return -1; /* ignore unprintables */
}

if ((scancode & 0x7f) == 0x1c) {
/*
* enter key. All done. Absorb the release scancode.
*/
if (scancode == 0x1c) {
kbd_last_ret = 1;
return 13;
}

return keychar & 0xff;
}
EXPORT_SYMBOL_GPL(kdb_get_kbd_char);

/*
* Best effort cleanup of ENTER break codes on leaving KDB. Called on
* exiting KDB, when we know we processed an ENTER or KP ENTER scan
* code.
*/
void kdb_kbd_cleanup_state(void)
{
int scancode, scanstatus;

/*
* Nothing to clean up, since either
* ENTER was never pressed, or has already
* gotten cleaned up.
*/
if (!kbd_last_ret)
return;

kbd_last_ret = 0;
/*
* Enter key. Need to absorb the break code here, lest it gets
* leaked out if we exit KDB as the result of processing 'g'.
*
* This has several interesting implications:
* + Need to handle KP ENTER, which has break code 0xe0 0x9c.
* + Need to handle repeat ENTER and repeat KP ENTER. Repeats
* only get a break code at the end of the repeated
* sequence. This means we can't propagate the repeated key
* press, and must swallow it away.
* + Need to handle possible PS/2 mouse input.
* + Need to handle mashed keys.
*/

while (1) {
while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
;
cpu_relax();

/*
* Fetch the scancode
* Fetch the scancode.
*/
scancode = inb(KBD_DATA_REG);
scanstatus = inb(KBD_STATUS_REG);

while (scanstatus & KBD_STAT_MOUSE_OBF) {
scancode = inb(KBD_DATA_REG);
scanstatus = inb(KBD_STATUS_REG);
}
/*
* Skip mouse input.
*/
if (scanstatus & KBD_STAT_MOUSE_OBF)
continue;

if (scancode != 0x9c) {
/*
* Wasn't an enter-release, why not?
*/
kdb_printf("kdb: expected enter got 0x%x status 0x%x\n",
scancode, scanstatus);
}
/*
* If we see 0xe0, this is either a break code for KP
* ENTER, or a repeat make for KP ENTER. Either way,
* since the second byte is equivalent to an ENTER,
* skip the 0xe0 and try again.
*
* If we see 0x1c, this must be a repeat ENTER or KP
* ENTER (and we swallowed 0xe0 before). Try again.
*
* We can also see make and break codes for other keys
* mashed before or after pressing ENTER. Thus, if we
* see anything other than 0x9c, we have to try again.
*
* Note, if you held some key as ENTER was depressed,
* that break code would get leaked out.
*/
if (scancode != 0x9c)
continue;

return 13;
return;
}

return keychar & 0xff;
}
EXPORT_SYMBOL_GPL(kdb_get_kbd_char);
3 changes: 3 additions & 0 deletions trunk/kernel/debug/kdb/kdb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,9 @@ int kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,
if (KDB_STATE(DOING_SS))
KDB_STATE_CLEAR(SSBPT);

/* Clean up any keyboard devices before leaving */
kdb_kbd_cleanup_state();

return result;
}

Expand Down
7 changes: 7 additions & 0 deletions trunk/kernel/debug/kdb/kdb_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,13 @@ extern void debug_kusage(void);

extern void kdb_set_current_task(struct task_struct *);
extern struct task_struct *kdb_current_task;

#ifdef CONFIG_KDB_KEYBOARD
extern void kdb_kbd_cleanup_state(void);
#else /* ! CONFIG_KDB_KEYBOARD */
#define kdb_kbd_cleanup_state()
#endif /* ! CONFIG_KDB_KEYBOARD */

#ifdef CONFIG_MODULES
extern struct list_head *kdb_modules;
#endif /* CONFIG_MODULES */
Expand Down

0 comments on commit ddd75ec

Please sign in to comment.