1 /* 2 * Xen para-virtual input device 3 * 4 * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com> 5 * Copyright (C) 2006-2008 Red Hat, Inc., Markus Armbruster <armbru@redhat.com> 6 * 7 * Based on linux/drivers/input/mouse/sermouse.c 8 * 9 * This file is subject to the terms and conditions of the GNU General Public 10 * License. See the file COPYING in the main directory of this archive for 11 * more details. 12 */ 13 14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15 16 #include <linux/kernel.h> 17 #include <linux/errno.h> 18 #include <linux/module.h> 19 #include <linux/input.h> 20 #include <linux/slab.h> 21 22 #include <asm/xen/hypervisor.h> 23 24 #include <xen/xen.h> 25 #include <xen/events.h> 26 #include <xen/page.h> 27 #include <xen/grant_table.h> 28 #include <xen/interface/grant_table.h> 29 #include <xen/interface/io/fbif.h> 30 #include <xen/interface/io/kbdif.h> 31 #include <xen/xenbus.h> 32 #include <xen/platform_pci.h> 33 34 struct xenkbd_info { 35 struct input_dev *kbd; 36 struct input_dev *ptr; 37 struct xenkbd_page *page; 38 int gref; 39 int irq; 40 struct xenbus_device *xbdev; 41 char phys[32]; 42 }; 43 44 enum { KPARAM_X, KPARAM_Y, KPARAM_CNT }; 45 static int ptr_size[KPARAM_CNT] = { XENFB_WIDTH, XENFB_HEIGHT }; 46 module_param_array(ptr_size, int, NULL, 0444); 47 MODULE_PARM_DESC(ptr_size, 48 "Pointing device width, height in pixels (default 800,600)"); 49 50 static int xenkbd_remove(struct xenbus_device *); 51 static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info *); 52 static void xenkbd_disconnect_backend(struct xenkbd_info *); 53 54 /* 55 * Note: if you need to send out events, see xenfb_do_update() for how 56 * to do that. 57 */ 58 59 static irqreturn_t input_handler(int rq, void *dev_id) 60 { 61 struct xenkbd_info *info = dev_id; 62 struct xenkbd_page *page = info->page; 63 __u32 cons, prod; 64 65 prod = page->in_prod; 66 if (prod == page->in_cons) 67 return IRQ_HANDLED; 68 rmb(); /* ensure we see ring contents up to prod */ 69 for (cons = page->in_cons; cons != prod; cons++) { 70 union xenkbd_in_event *event; 71 struct input_dev *dev; 72 event = &XENKBD_IN_RING_REF(page, cons); 73 74 dev = info->ptr; 75 switch (event->type) { 76 case XENKBD_TYPE_MOTION: 77 input_report_rel(dev, REL_X, event->motion.rel_x); 78 input_report_rel(dev, REL_Y, event->motion.rel_y); 79 if (event->motion.rel_z) 80 input_report_rel(dev, REL_WHEEL, 81 -event->motion.rel_z); 82 break; 83 case XENKBD_TYPE_KEY: 84 dev = NULL; 85 if (test_bit(event->key.keycode, info->kbd->keybit)) 86 dev = info->kbd; 87 if (test_bit(event->key.keycode, info->ptr->keybit)) 88 dev = info->ptr; 89 if (dev) 90 input_report_key(dev, event->key.keycode, 91 event->key.pressed); 92 else 93 pr_warn("unhandled keycode 0x%x\n", 94 event->key.keycode); 95 break; 96 case XENKBD_TYPE_POS: 97 input_report_abs(dev, ABS_X, event->pos.abs_x); 98 input_report_abs(dev, ABS_Y, event->pos.abs_y); 99 if (event->pos.rel_z) 100 input_report_rel(dev, REL_WHEEL, 101 -event->pos.rel_z); 102 break; 103 } 104 if (dev) 105 input_sync(dev); 106 } 107 mb(); /* ensure we got ring contents */ 108 page->in_cons = cons; 109 notify_remote_via_irq(info->irq); 110 111 return IRQ_HANDLED; 112 } 113 114 static int xenkbd_probe(struct xenbus_device *dev, 115 const struct xenbus_device_id *id) 116 { 117 int ret, i; 118 unsigned int abs; 119 struct xenkbd_info *info; 120 struct input_dev *kbd, *ptr; 121 122 info = kzalloc(sizeof(*info), GFP_KERNEL); 123 if (!info) { 124 xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); 125 return -ENOMEM; 126 } 127 dev_set_drvdata(&dev->dev, info); 128 info->xbdev = dev; 129 info->irq = -1; 130 info->gref = -1; 131 snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename); 132 133 info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); 134 if (!info->page) 135 goto error_nomem; 136 137 /* Set input abs params to match backend screen res */ 138 abs = xenbus_read_unsigned(dev->otherend, "feature-abs-pointer", 0); 139 ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend, "width", 140 ptr_size[KPARAM_X]); 141 ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend, "height", 142 ptr_size[KPARAM_Y]); 143 if (abs) { 144 ret = xenbus_write(XBT_NIL, dev->nodename, 145 "request-abs-pointer", "1"); 146 if (ret) { 147 pr_warn("xenkbd: can't request abs-pointer\n"); 148 abs = 0; 149 } 150 } 151 152 /* keyboard */ 153 kbd = input_allocate_device(); 154 if (!kbd) 155 goto error_nomem; 156 kbd->name = "Xen Virtual Keyboard"; 157 kbd->phys = info->phys; 158 kbd->id.bustype = BUS_PCI; 159 kbd->id.vendor = 0x5853; 160 kbd->id.product = 0xffff; 161 162 __set_bit(EV_KEY, kbd->evbit); 163 for (i = KEY_ESC; i < KEY_UNKNOWN; i++) 164 __set_bit(i, kbd->keybit); 165 for (i = KEY_OK; i < KEY_MAX; i++) 166 __set_bit(i, kbd->keybit); 167 168 ret = input_register_device(kbd); 169 if (ret) { 170 input_free_device(kbd); 171 xenbus_dev_fatal(dev, ret, "input_register_device(kbd)"); 172 goto error; 173 } 174 info->kbd = kbd; 175 176 /* pointing device */ 177 ptr = input_allocate_device(); 178 if (!ptr) 179 goto error_nomem; 180 ptr->name = "Xen Virtual Pointer"; 181 ptr->phys = info->phys; 182 ptr->id.bustype = BUS_PCI; 183 ptr->id.vendor = 0x5853; 184 ptr->id.product = 0xfffe; 185 186 if (abs) { 187 __set_bit(EV_ABS, ptr->evbit); 188 input_set_abs_params(ptr, ABS_X, 0, ptr_size[KPARAM_X], 0, 0); 189 input_set_abs_params(ptr, ABS_Y, 0, ptr_size[KPARAM_Y], 0, 0); 190 } else { 191 input_set_capability(ptr, EV_REL, REL_X); 192 input_set_capability(ptr, EV_REL, REL_Y); 193 } 194 input_set_capability(ptr, EV_REL, REL_WHEEL); 195 196 __set_bit(EV_KEY, ptr->evbit); 197 for (i = BTN_LEFT; i <= BTN_TASK; i++) 198 __set_bit(i, ptr->keybit); 199 200 ret = input_register_device(ptr); 201 if (ret) { 202 input_free_device(ptr); 203 xenbus_dev_fatal(dev, ret, "input_register_device(ptr)"); 204 goto error; 205 } 206 info->ptr = ptr; 207 208 ret = xenkbd_connect_backend(dev, info); 209 if (ret < 0) 210 goto error; 211 212 return 0; 213 214 error_nomem: 215 ret = -ENOMEM; 216 xenbus_dev_fatal(dev, ret, "allocating device memory"); 217 error: 218 xenkbd_remove(dev); 219 return ret; 220 } 221 222 static int xenkbd_resume(struct xenbus_device *dev) 223 { 224 struct xenkbd_info *info = dev_get_drvdata(&dev->dev); 225 226 xenkbd_disconnect_backend(info); 227 memset(info->page, 0, PAGE_SIZE); 228 return xenkbd_connect_backend(dev, info); 229 } 230 231 static int xenkbd_remove(struct xenbus_device *dev) 232 { 233 struct xenkbd_info *info = dev_get_drvdata(&dev->dev); 234 235 xenkbd_disconnect_backend(info); 236 if (info->kbd) 237 input_unregister_device(info->kbd); 238 if (info->ptr) 239 input_unregister_device(info->ptr); 240 free_page((unsigned long)info->page); 241 kfree(info); 242 return 0; 243 } 244 245 static int xenkbd_connect_backend(struct xenbus_device *dev, 246 struct xenkbd_info *info) 247 { 248 int ret, evtchn; 249 struct xenbus_transaction xbt; 250 251 ret = gnttab_grant_foreign_access(dev->otherend_id, 252 virt_to_gfn(info->page), 0); 253 if (ret < 0) 254 return ret; 255 info->gref = ret; 256 257 ret = xenbus_alloc_evtchn(dev, &evtchn); 258 if (ret) 259 goto error_grant; 260 ret = bind_evtchn_to_irqhandler(evtchn, input_handler, 261 0, dev->devicetype, info); 262 if (ret < 0) { 263 xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); 264 goto error_evtchan; 265 } 266 info->irq = ret; 267 268 again: 269 ret = xenbus_transaction_start(&xbt); 270 if (ret) { 271 xenbus_dev_fatal(dev, ret, "starting transaction"); 272 goto error_irqh; 273 } 274 ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", 275 virt_to_gfn(info->page)); 276 if (ret) 277 goto error_xenbus; 278 ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", info->gref); 279 if (ret) 280 goto error_xenbus; 281 ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", 282 evtchn); 283 if (ret) 284 goto error_xenbus; 285 ret = xenbus_transaction_end(xbt, 0); 286 if (ret) { 287 if (ret == -EAGAIN) 288 goto again; 289 xenbus_dev_fatal(dev, ret, "completing transaction"); 290 goto error_irqh; 291 } 292 293 xenbus_switch_state(dev, XenbusStateInitialised); 294 return 0; 295 296 error_xenbus: 297 xenbus_transaction_end(xbt, 1); 298 xenbus_dev_fatal(dev, ret, "writing xenstore"); 299 error_irqh: 300 unbind_from_irqhandler(info->irq, info); 301 info->irq = -1; 302 error_evtchan: 303 xenbus_free_evtchn(dev, evtchn); 304 error_grant: 305 gnttab_end_foreign_access(info->gref, 0, 0UL); 306 info->gref = -1; 307 return ret; 308 } 309 310 static void xenkbd_disconnect_backend(struct xenkbd_info *info) 311 { 312 if (info->irq >= 0) 313 unbind_from_irqhandler(info->irq, info); 314 info->irq = -1; 315 if (info->gref >= 0) 316 gnttab_end_foreign_access(info->gref, 0, 0UL); 317 info->gref = -1; 318 } 319 320 static void xenkbd_backend_changed(struct xenbus_device *dev, 321 enum xenbus_state backend_state) 322 { 323 switch (backend_state) { 324 case XenbusStateInitialising: 325 case XenbusStateInitialised: 326 case XenbusStateReconfiguring: 327 case XenbusStateReconfigured: 328 case XenbusStateUnknown: 329 break; 330 331 case XenbusStateInitWait: 332 xenbus_switch_state(dev, XenbusStateConnected); 333 break; 334 335 case XenbusStateConnected: 336 /* 337 * Work around xenbus race condition: If backend goes 338 * through InitWait to Connected fast enough, we can 339 * get Connected twice here. 340 */ 341 if (dev->state != XenbusStateConnected) 342 xenbus_switch_state(dev, XenbusStateConnected); 343 break; 344 345 case XenbusStateClosed: 346 if (dev->state == XenbusStateClosed) 347 break; 348 /* Missed the backend's CLOSING state -- fallthrough */ 349 case XenbusStateClosing: 350 xenbus_frontend_closed(dev); 351 break; 352 } 353 } 354 355 static const struct xenbus_device_id xenkbd_ids[] = { 356 { "vkbd" }, 357 { "" } 358 }; 359 360 static struct xenbus_driver xenkbd_driver = { 361 .ids = xenkbd_ids, 362 .probe = xenkbd_probe, 363 .remove = xenkbd_remove, 364 .resume = xenkbd_resume, 365 .otherend_changed = xenkbd_backend_changed, 366 }; 367 368 static int __init xenkbd_init(void) 369 { 370 if (!xen_domain()) 371 return -ENODEV; 372 373 /* Nothing to do if running in dom0. */ 374 if (xen_initial_domain()) 375 return -ENODEV; 376 377 if (!xen_has_pv_devices()) 378 return -ENODEV; 379 380 return xenbus_register_frontend(&xenkbd_driver); 381 } 382 383 static void __exit xenkbd_cleanup(void) 384 { 385 xenbus_unregister_driver(&xenkbd_driver); 386 } 387 388 module_init(xenkbd_init); 389 module_exit(xenkbd_cleanup); 390 391 MODULE_DESCRIPTION("Xen virtual keyboard/pointer device frontend"); 392 MODULE_LICENSE("GPL"); 393 MODULE_ALIAS("xen:vkbd"); 394