From patchwork Sun Apr 26 02:26:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: penghao122@sina.com X-Patchwork-Id: 464673 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 26FE41400A0 for ; Sun, 26 Apr 2015 22:36:38 +1000 (AEST) Received: from localhost ([::1]:50702 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YmLnW-0001jR-UO for incoming@patchwork.ozlabs.org; Sun, 26 Apr 2015 08:36:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36371) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YmCc9-0008DZ-8S for qemu-devel@nongnu.org; Sat, 25 Apr 2015 22:48:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YmCc5-00055X-WF for qemu-devel@nongnu.org; Sat, 25 Apr 2015 22:48:13 -0400 Received: from mail2-156.sinamail.sina.com.cn ([60.28.2.156]:40936 helo=smtp2911-210.mail.sina.com.cn) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1YmCc4-00054o-V3 for qemu-devel@nongnu.org; Sat, 25 Apr 2015 22:48:09 -0400 Received: from webmail14.fmail.tg.sinanode.com (HELO webmail.sinamail.sina.com.cn)([172.16.201.48]) by sina.com with SMTP 26 Apr 2015 10:26:27 +0800 (CST) X-Sender: penghao122@sina.com X-SMAIL-MID: 91250811294683 Received: by webmail.sinamail.sina.com.cn (Postfix, from userid 80) id DB9A647813F; Sun, 26 Apr 2015 10:26:27 +0800 (CST) Date: Sun, 26 Apr 2015 10:26:27 +0800 Received: from penghao122@sina.com([222.211.226.111]) by m0.mail.sina.com.cn via HTTP; Sun, 26 Apr 2015 10:26:27 +0800 (CST) From: To: "qemu-devel" MIME-Version: 1.0 X-Priority: 3 X-MessageID: 553c4cd321c41c8d X-Originating-IP: [172.16.201.48] X-Mailer: Sina WebMail 4.0 Message-Id: <20150426022627.DB9A647813F@webmail.sinamail.sina.com.cn> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 60.28.2.156 X-Mailman-Approved-At: Sun, 26 Apr 2015 08:36:06 -0400 Subject: [Qemu-devel] [PATCH] ps2 keyboard:fix can't use ps2 keyboard if typing many times After leaving grub and before finishing linux kernel ps2 driver initialization X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: penghao122@sina.com List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Starting a linux guest with ps2 keyboard ,if you type many times during leaving grub and into linux kernel ,then you can't use keyboard after linux initialization finished. during grub,the work method of ps2 keyboard is like this: first ,ps2 keyboard driver send command KBD_CCMD_KBD_ENABLE, second,if there is a keyboard input,then ps2 keyboard driver read data. third ,ps2 keyboard driver send command KBD_CCMD_KBD_ENABLE, ... this is diffrent method of linux kernel . After leaving grub and before finishing linux kernel ps2 driver initialization,if you type many times,the input data keep saving the ps2 queue in qemu .Before linux kernel initialize ps2 keyboard,linux call i8042_init->i8042_controller_check,if i8042_controller_check return fail,then linux kernel ps2 keyboard driver will never initialize. (linux kernel 2.6.32 i8042.c) static int i8042_controller_check(void) { if (i8042_flush() == I8042_BUFFER_SIZE) return -ENODEV; return 0; } static int i8042_flush(void) {... while (((str = i8042_read_status()) & I8042_STR_OBF) && (i < I8042_BUFFER_SIZE)) { udelay(50); data = i8042_read_data(); i++; } return i; } during calling i8042_flush it is full in qemu queue . ps_read_data: s->update_irq(s->update_arg, 0); s->update_irq(s->update_arg, q->count != 0); because q->count!=0, kbd_update_irq can set I8042_STR_OBF.Then i8042_flush() will return I8042_BUFFER_SIZE. --- ps2.c.orig 2015-04-25 09:44:38.865777168 -0400 +++ ps2.c 2015-04-25 09:48:46.385121172 -0400 @@ -150,7 +150,12 @@ q->count++; s->update_irq(s->update_arg, 1); } - +void ps2_clear_queue(void *opaque) +{ + PS2State *s = (PS2State *)opaque; + PS2Queue *q = &s->queue; + q->wptr = q->rptr = q->count = 0; +} /* keycode is expressed as follow: bit 7 - 0 key pressed, 1 = key released --- pckbd.c.orig 2015-04-25 09:36:59.960640241 -0400 +++ pckbd.c 2015-04-25 09:44:27.298562406 -0400 @@ -207,6 +207,8 @@ KBDState *s = opaque; int val; val = s->status; + if(s->write-cmd == KBD_CCMD_KBD_ENABLE) + val &= ~KBD_STAT_OBF; DPRINTF("kbd: read status=0x%02x\n", val); return val; } @@ -251,9 +253,10 @@ else val = KBD_CCMD_NO_OP; } - + s->write_cmd = 0; switch(val) { case KBD_CCMD_READ_MODE: + ps2_clear_queue(s->kbd); kbd_queue(s, s->mode, 0); break; case KBD_CCMD_WRITE_MODE: @@ -284,6 +287,7 @@ kbd_update_irq(s); break; case KBD_CCMD_KBD_ENABLE: + s->write_cmd = KBD_CCMD_KBD_ENABLE; s->mode &= ~KBD_MODE_DISABLE_KBD; kbd_update_irq(s); break;