[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 3/4][RFC] Paravirtual Framebuffer/Keyboard
# HG changeset patch # User Anthony Liguori <anthony@xxxxxxxxxxxxx> # Node ID 2b3f2e8722737cdc8931398cde598570b3250f27 # Parent 2b1f225753ed4480c9968866b5955df878eea04d Xen Virtual Keyboard/Mouse driver This driver is a pretty basic shared-memory message queue that is used to transmit input events. It probably needs some more work to be more correct for non-US keyboard layouts. Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx> diff -r 2b1f225753ed -r 2b3f2e872273 linux-2.6-xen-sparse/drivers/input/keyboard/Makefile --- /dev/null Sun Jan 15 18:08:56 2006 -0500 +++ b/linux-2.6-xen-sparse/drivers/input/keyboard/Makefile Sun Jan 15 18:10:29 2006 -0500 @@ -0,0 +1,20 @@ +# +# Makefile for the input core drivers. +# + +# Each configuration option enables a list of files. + +obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o +obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o +obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o +obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o +obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o +obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o +obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o +obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o +obj-$(CONFIG_KEYBOARD_98KBD) += 98kbd.o +obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o +obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o +obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o +obj-$(CONFIG_KEYBOARD_XENKBD) += xenkbd.o + diff -r 2b1f225753ed -r 2b3f2e872273 linux-2.6-xen-sparse/drivers/input/keyboard/xenkbd.c --- /dev/null Sun Jan 15 18:08:56 2006 -0500 +++ b/linux-2.6-xen-sparse/drivers/input/keyboard/xenkbd.c Sun Jan 15 18:10:29 2006 -0500 @@ -0,0 +1,166 @@ +/* + * linux/drivers/input/keyboard/xenkbd.c -- Xen para-virtual input device + * + * Copyright (C) 2005 + * + * Anthony Liguori <aliguori@xxxxxxxxxx> + * + * Based on linux/drivers/input/mouse/sermouse.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/module.h> +#include <linux/input.h> +#include <asm/hypervisor.h> +#include <asm-xen/evtchn.h> +#include <linux/xenkbd.h> + +struct xenkbd_device +{ + struct input_dev dev; + struct xenkbd_info *info; +}; + +static irqreturn_t input_handler(int rq, void *dev_id, struct pt_regs *regs) +{ + struct xenkbd_device *dev = dev_id; + struct xenkbd_info *info = dev ? dev->info : 0; + static int button_map[3] = { BTN_RIGHT, BTN_MIDDLE, BTN_LEFT }; + __u32 cons, prod; + + if (!info || !info->initialized) + return IRQ_NONE; + + /* FIXME barriers */ + prod = XENKBD_MASK_RING(info->in_prod, info->in); + cons = XENKBD_MASK_RING(info->in_cons, info->in); + + if (prod == cons) + return IRQ_HANDLED; + + for (; cons != prod; cons = XENKBD_MASK_RING(cons + 1, info->in)) { + union xenkbd_in_event *event; + + event = &info->in[cons]; + + switch (event->type) { + case XENKBD_TYPE_MOTION: + input_report_rel(&dev->dev, REL_X, event->motion.rel_x); + input_report_rel(&dev->dev, REL_Y, event->motion.rel_y); + break; + case XENKBD_TYPE_BUTTON: + if (event->button.button < 3) + input_report_key(&dev->dev, + button_map[event->button.button], + event->button.pressed); + break; + case XENKBD_TYPE_KEY: + input_report_key(&dev->dev, event->key.keycode, event->key.pressed); + break; + } + + notify_remote_via_evtchn(xen_start_info->kbd_evtchn); + } + input_sync(&dev->dev); + + info->in_cons = cons; + + return IRQ_HANDLED; +} + +static struct xenkbd_device *xenkbd_dev; +static int xenkbd_irq; + +int __init xenkbd_init(void) +{ + int ret = 0; + int i; + struct xenkbd_device *dev; + + if (xen_start_info->kbd_evtchn == 0) + return -ENODEV; + + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) + return -ENOMEM; + + dev->info = mfn_to_virt(xen_start_info->kbd_mfn); + dev->info->initialized = 0; + + ret = bind_evtchn_to_irqhandler(xen_start_info->kbd_evtchn, + input_handler, + 0, + "xenkbd", + dev); + if (ret <= 0) { + kfree(dev); + return ret; + } + + xenkbd_irq = ret; + + init_input_dev(&dev->dev); + dev->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + dev->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); + dev->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); + + /* FIXME */ + for (i = 0; i < 256; i++) + set_bit(i, dev->dev.keybit); + + dev->dev.name = "Xen Virtual Keyboard/Mouse"; + + input_register_device(&dev->dev); + + dev->info->in_cons = dev->info->in_prod = 0; + dev->info->out_cons = dev->info->out_prod = 0; + dev->info->initialized = 1; + + xenkbd_dev = dev; + + return ret; +} + +static void __exit xenkbd_cleanup(void) +{ + if (xenkbd_dev) { + /* FIXME how do we unbind the evtchn? */ + /* FIXME does dev->info need to be unmapped? */ + input_unregister_device(&xenkbd_dev->dev); + kfree(xenkbd_dev); + } +} + +void xenkbd_resume(void) +{ + int ret; + + if (xenkbd_dev && xen_start_info->kbd_evtchn) { +#if 0 + if (xenkbd_irq) + unbind_from_irqhandler(xenkbd_irq, NULL); +#endif + + ret = bind_evtchn_to_irqhandler(xen_start_info->kbd_evtchn, + input_handler, + 0, + "xenkbd", + xenkbd_dev); + + if (ret <= 0) + return; + + xenkbd_irq = ret; + xenkbd_dev->info = mfn_to_virt(xen_start_info->kbd_mfn); + } +} + +module_init(xenkbd_init); +module_exit(xenkbd_cleanup); + +MODULE_LICENSE("GPL"); diff -r 2b1f225753ed -r 2b3f2e872273 linux-2.6-xen-sparse/include/linux/xenkbd.h --- /dev/null Sun Jan 15 18:08:56 2006 -0500 +++ b/linux-2.6-xen-sparse/include/linux/xenkbd.h Sun Jan 15 18:10:29 2006 -0500 @@ -0,0 +1,81 @@ +/* + * linux/include/linux/xenkbd.h -- Xen virtual keyboard/mouse + * + * Copyright (C) 2005 + * + * Anthony Liguori <aliguori@xxxxxxxxxx> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#ifndef _LINUX_XENKBD_H +#define _LINUX_XENKBD_H + +#include <asm/types.h> + +/* in events */ + +#define XENKBD_TYPE_MOTION 1 /* mouse movement event */ +#define XENKBD_TYPE_BUTTON 2 /* mouse button event */ +#define XENKBD_TYPE_KEY 3 /* keyboard event */ + +struct xenkbd_motion +{ + __u8 type; /* XENKBD_TYPE_MOTION */ + __s16 rel_x; /* relative X motion */ + __s16 rel_y; /* relative Y motion */ +}; + +struct xenkbd_button +{ + __u8 type; /* XENKBD_TYPE_BUTTON */ + __u8 pressed; /* 1 if pressed; 0 otherwise */ + __u8 button; /* the button (0, 1, 2 is right, middle, left) */ +}; + +struct xenkbd_key +{ + __u8 type; /* XENKBD_TYPE_KEY */ + __u8 pressed; /* 1 if pressed; 0 otherwise */ + __u16 keycode; /* KEY_* from linux/input.h */ +}; + +union xenkbd_in_event +{ + __u8 type; + struct xenkbd_motion motion; + struct xenkbd_button button; + struct xenkbd_key key; + char _[40]; +}; + +/* out events */ + +union xenkbd_out_event +{ + __u8 type; + char _[40]; +}; + +/* shared page */ + +#define XENKBD_IN_RING_SIZE (2048 / 40) +#define XENKBD_OUT_RING_SIZE (1024 / 40) + +#define XENKBD_MASK_RING(idx, ring) ((idx)%(sizeof((ring))/sizeof((ring)[0]))) + +struct xenkbd_info +{ + __u8 initialized; + __u32 in_cons, in_prod; + __u32 out_cons, out_prod; + + union xenkbd_in_event in[XENKBD_IN_RING_SIZE]; + union xenkbd_out_event out[XENKBD_OUT_RING_SIZE]; +}; + +void xenkbd_resume(void); + +#endif _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |