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/input/mt.h> 21 #include <linux/slab.h> 22 23 #include <asm/xen/hypervisor.h> 24 25 #include <xen/xen.h> 26 #include <xen/events.h> 27 #include <xen/page.h> 28 #include <xen/grant_table.h> 29 #include <xen/interface/grant_table.h> 30 #include <xen/interface/io/fbif.h> 31 #include <xen/interface/io/kbdif.h> 32 #include <xen/xenbus.h> 33 #include <xen/platform_pci.h> 34 35 struct xenkbd_info { 36 struct input_dev *kbd; 37 struct input_dev *ptr; 38 struct input_dev *mtouch; 39 struct xenkbd_page *page; 40 int gref; 41 int irq; 42 struct xenbus_device *xbdev; 43 char phys[32]; 44 /* current MT slot/contact ID we are injecting events in */ 45 int mtouch_cur_contact_id; 46 }; 47 48 enum { KPARAM_X, KPARAM_Y, KPARAM_CNT }; 49 static int ptr_size[KPARAM_CNT] = { XENFB_WIDTH, XENFB_HEIGHT }; 50 module_param_array(ptr_size, int, NULL, 0444); 51 MODULE_PARM_DESC(ptr_size, 52 "Pointing device width, height in pixels (default 800,600)"); 53 54 static int xenkbd_remove(struct xenbus_device *); 55 static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info *); 56 static void xenkbd_disconnect_backend(struct xenkbd_info *); 57 58 /* 59 * Note: if you need to send out events, see xenfb_do_update() for how 60 * to do that. 61 */ 62 63 static void xenkbd_handle_motion_event(struct xenkbd_info *info, 64 struct xenkbd_motion *motion) 65 { 66 input_report_rel(info->ptr, REL_X, motion->rel_x); 67 input_report_rel(info->ptr, REL_Y, motion->rel_y); 68 if (motion->rel_z) 69 input_report_rel(info->ptr, REL_WHEEL, -motion->rel_z); 70 input_sync(info->ptr); 71 } 72 73 static void xenkbd_handle_position_event(struct xenkbd_info *info, 74 struct xenkbd_position *pos) 75 { 76 input_report_abs(info->ptr, ABS_X, pos->abs_x); 77 input_report_abs(info->ptr, ABS_Y, pos->abs_y); 78 if (pos->rel_z) 79 input_report_rel(info->ptr, REL_WHEEL, -pos->rel_z); 80 input_sync(info->ptr); 81 } 82 83 static void xenkbd_handle_key_event(struct xenkbd_info *info, 84 struct xenkbd_key *key) 85 { 86 struct input_dev *dev; 87 88 if (test_bit(key->keycode, info->ptr->keybit)) { 89 dev = info->ptr; 90 } else if (test_bit(key->keycode, info->kbd->keybit)) { 91 dev = info->kbd; 92 } else { 93 pr_warn("unhandled keycode 0x%x\n", key->keycode); 94 return; 95 } 96 97 input_report_key(dev, key->keycode, key->pressed); 98 input_sync(dev); 99 } 100 101 static void xenkbd_handle_mt_event(struct xenkbd_info *info, 102 struct xenkbd_mtouch *mtouch) 103 { 104 if (unlikely(!info->mtouch)) 105 return; 106 107 if (mtouch->contact_id != info->mtouch_cur_contact_id) { 108 info->mtouch_cur_contact_id = mtouch->contact_id; 109 input_mt_slot(info->mtouch, mtouch->contact_id); 110 } 111 112 switch (mtouch->event_type) { 113 case XENKBD_MT_EV_DOWN: 114 input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, true); 115 /* fall through */ 116 117 case XENKBD_MT_EV_MOTION: 118 input_report_abs(info->mtouch, ABS_MT_POSITION_X, 119 mtouch->u.pos.abs_x); 120 input_report_abs(info->mtouch, ABS_MT_POSITION_Y, 121 mtouch->u.pos.abs_y); 122 break; 123 124 case XENKBD_MT_EV_SHAPE: 125 input_report_abs(info->mtouch, ABS_MT_TOUCH_MAJOR, 126 mtouch->u.shape.major); 127 input_report_abs(info->mtouch, ABS_MT_TOUCH_MINOR, 128 mtouch->u.shape.minor); 129 break; 130 131 case XENKBD_MT_EV_ORIENT: 132 input_report_abs(info->mtouch, ABS_MT_ORIENTATION, 133 mtouch->u.orientation); 134 break; 135 136 case XENKBD_MT_EV_UP: 137 input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, false); 138 break; 139 140 case XENKBD_MT_EV_SYN: 141 input_mt_sync_frame(info->mtouch); 142 input_sync(info->mtouch); 143 break; 144 } 145 } 146 147 static void xenkbd_handle_event(struct xenkbd_info *info, 148 union xenkbd_in_event *event) 149 { 150 switch (event->type) { 151 case XENKBD_TYPE_MOTION: 152 xenkbd_handle_motion_event(info, &event->motion); 153 break; 154 155 case XENKBD_TYPE_KEY: 156 xenkbd_handle_key_event(info, &event->key); 157 break; 158 159 case XENKBD_TYPE_POS: 160 xenkbd_handle_position_event(info, &event->pos); 161 break; 162 163 case XENKBD_TYPE_MTOUCH: 164 xenkbd_handle_mt_event(info, &event->mtouch); 165 break; 166 } 167 } 168 169 static irqreturn_t input_handler(int rq, void *dev_id) 170 { 171 struct xenkbd_info *info = dev_id; 172 struct xenkbd_page *page = info->page; 173 __u32 cons, prod; 174 175 prod = page->in_prod; 176 if (prod == page->in_cons) 177 return IRQ_HANDLED; 178 rmb(); /* ensure we see ring contents up to prod */ 179 for (cons = page->in_cons; cons != prod; cons++) 180 xenkbd_handle_event(info, &XENKBD_IN_RING_REF(page, cons)); 181 mb(); /* ensure we got ring contents */ 182 page->in_cons = cons; 183 notify_remote_via_irq(info->irq); 184 185 return IRQ_HANDLED; 186 } 187 188 static int xenkbd_probe(struct xenbus_device *dev, 189 const struct xenbus_device_id *id) 190 { 191 int ret, i; 192 unsigned int abs, touch; 193 struct xenkbd_info *info; 194 struct input_dev *kbd, *ptr, *mtouch; 195 196 info = kzalloc(sizeof(*info), GFP_KERNEL); 197 if (!info) { 198 xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); 199 return -ENOMEM; 200 } 201 dev_set_drvdata(&dev->dev, info); 202 info->xbdev = dev; 203 info->irq = -1; 204 info->gref = -1; 205 snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename); 206 207 info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); 208 if (!info->page) 209 goto error_nomem; 210 211 /* Set input abs params to match backend screen res */ 212 abs = xenbus_read_unsigned(dev->otherend, 213 XENKBD_FIELD_FEAT_ABS_POINTER, 0); 214 ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend, 215 XENKBD_FIELD_WIDTH, 216 ptr_size[KPARAM_X]); 217 ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend, 218 XENKBD_FIELD_HEIGHT, 219 ptr_size[KPARAM_Y]); 220 if (abs) { 221 ret = xenbus_write(XBT_NIL, dev->nodename, 222 XENKBD_FIELD_REQ_ABS_POINTER, "1"); 223 if (ret) { 224 pr_warn("xenkbd: can't request abs-pointer\n"); 225 abs = 0; 226 } 227 } 228 229 touch = xenbus_read_unsigned(dev->nodename, 230 XENKBD_FIELD_FEAT_MTOUCH, 0); 231 if (touch) { 232 ret = xenbus_write(XBT_NIL, dev->nodename, 233 XENKBD_FIELD_REQ_MTOUCH, "1"); 234 if (ret) { 235 pr_warn("xenkbd: can't request multi-touch"); 236 touch = 0; 237 } 238 } 239 240 /* keyboard */ 241 kbd = input_allocate_device(); 242 if (!kbd) 243 goto error_nomem; 244 kbd->name = "Xen Virtual Keyboard"; 245 kbd->phys = info->phys; 246 kbd->id.bustype = BUS_PCI; 247 kbd->id.vendor = 0x5853; 248 kbd->id.product = 0xffff; 249 250 __set_bit(EV_KEY, kbd->evbit); 251 for (i = KEY_ESC; i < KEY_UNKNOWN; i++) 252 __set_bit(i, kbd->keybit); 253 for (i = KEY_OK; i < KEY_MAX; i++) 254 __set_bit(i, kbd->keybit); 255 256 ret = input_register_device(kbd); 257 if (ret) { 258 input_free_device(kbd); 259 xenbus_dev_fatal(dev, ret, "input_register_device(kbd)"); 260 goto error; 261 } 262 info->kbd = kbd; 263 264 /* pointing device */ 265 ptr = input_allocate_device(); 266 if (!ptr) 267 goto error_nomem; 268 ptr->name = "Xen Virtual Pointer"; 269 ptr->phys = info->phys; 270 ptr->id.bustype = BUS_PCI; 271 ptr->id.vendor = 0x5853; 272 ptr->id.product = 0xfffe; 273 274 if (abs) { 275 __set_bit(EV_ABS, ptr->evbit); 276 input_set_abs_params(ptr, ABS_X, 0, ptr_size[KPARAM_X], 0, 0); 277 input_set_abs_params(ptr, ABS_Y, 0, ptr_size[KPARAM_Y], 0, 0); 278 } else { 279 input_set_capability(ptr, EV_REL, REL_X); 280 input_set_capability(ptr, EV_REL, REL_Y); 281 } 282 input_set_capability(ptr, EV_REL, REL_WHEEL); 283 284 __set_bit(EV_KEY, ptr->evbit); 285 for (i = BTN_LEFT; i <= BTN_TASK; i++) 286 __set_bit(i, ptr->keybit); 287 288 ret = input_register_device(ptr); 289 if (ret) { 290 input_free_device(ptr); 291 xenbus_dev_fatal(dev, ret, "input_register_device(ptr)"); 292 goto error; 293 } 294 info->ptr = ptr; 295 296 /* multi-touch device */ 297 if (touch) { 298 int num_cont, width, height; 299 300 mtouch = input_allocate_device(); 301 if (!mtouch) 302 goto error_nomem; 303 304 num_cont = xenbus_read_unsigned(info->xbdev->nodename, 305 XENKBD_FIELD_MT_NUM_CONTACTS, 306 1); 307 width = xenbus_read_unsigned(info->xbdev->nodename, 308 XENKBD_FIELD_MT_WIDTH, 309 XENFB_WIDTH); 310 height = xenbus_read_unsigned(info->xbdev->nodename, 311 XENKBD_FIELD_MT_HEIGHT, 312 XENFB_HEIGHT); 313 314 mtouch->name = "Xen Virtual Multi-touch"; 315 mtouch->phys = info->phys; 316 mtouch->id.bustype = BUS_PCI; 317 mtouch->id.vendor = 0x5853; 318 mtouch->id.product = 0xfffd; 319 320 input_set_abs_params(mtouch, ABS_MT_TOUCH_MAJOR, 321 0, 255, 0, 0); 322 input_set_abs_params(mtouch, ABS_MT_POSITION_X, 323 0, width, 0, 0); 324 input_set_abs_params(mtouch, ABS_MT_POSITION_Y, 325 0, height, 0, 0); 326 input_set_abs_params(mtouch, ABS_MT_PRESSURE, 327 0, 255, 0, 0); 328 329 ret = input_mt_init_slots(mtouch, num_cont, INPUT_MT_DIRECT); 330 if (ret) { 331 input_free_device(mtouch); 332 xenbus_dev_fatal(info->xbdev, ret, 333 "input_mt_init_slots"); 334 goto error; 335 } 336 337 ret = input_register_device(mtouch); 338 if (ret) { 339 input_free_device(mtouch); 340 xenbus_dev_fatal(info->xbdev, ret, 341 "input_register_device(mtouch)"); 342 goto error; 343 } 344 info->mtouch_cur_contact_id = -1; 345 info->mtouch = mtouch; 346 } 347 348 ret = xenkbd_connect_backend(dev, info); 349 if (ret < 0) 350 goto error; 351 352 return 0; 353 354 error_nomem: 355 ret = -ENOMEM; 356 xenbus_dev_fatal(dev, ret, "allocating device memory"); 357 error: 358 xenkbd_remove(dev); 359 return ret; 360 } 361 362 static int xenkbd_resume(struct xenbus_device *dev) 363 { 364 struct xenkbd_info *info = dev_get_drvdata(&dev->dev); 365 366 xenkbd_disconnect_backend(info); 367 memset(info->page, 0, PAGE_SIZE); 368 return xenkbd_connect_backend(dev, info); 369 } 370 371 static int xenkbd_remove(struct xenbus_device *dev) 372 { 373 struct xenkbd_info *info = dev_get_drvdata(&dev->dev); 374 375 xenkbd_disconnect_backend(info); 376 if (info->kbd) 377 input_unregister_device(info->kbd); 378 if (info->ptr) 379 input_unregister_device(info->ptr); 380 if (info->mtouch) 381 input_unregister_device(info->mtouch); 382 free_page((unsigned long)info->page); 383 kfree(info); 384 return 0; 385 } 386 387 static int xenkbd_connect_backend(struct xenbus_device *dev, 388 struct xenkbd_info *info) 389 { 390 int ret, evtchn; 391 struct xenbus_transaction xbt; 392 393 ret = gnttab_grant_foreign_access(dev->otherend_id, 394 virt_to_gfn(info->page), 0); 395 if (ret < 0) 396 return ret; 397 info->gref = ret; 398 399 ret = xenbus_alloc_evtchn(dev, &evtchn); 400 if (ret) 401 goto error_grant; 402 ret = bind_evtchn_to_irqhandler(evtchn, input_handler, 403 0, dev->devicetype, info); 404 if (ret < 0) { 405 xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); 406 goto error_evtchan; 407 } 408 info->irq = ret; 409 410 again: 411 ret = xenbus_transaction_start(&xbt); 412 if (ret) { 413 xenbus_dev_fatal(dev, ret, "starting transaction"); 414 goto error_irqh; 415 } 416 ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_REF, "%lu", 417 virt_to_gfn(info->page)); 418 if (ret) 419 goto error_xenbus; 420 ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_GREF, 421 "%u", info->gref); 422 if (ret) 423 goto error_xenbus; 424 ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_EVT_CHANNEL, "%u", 425 evtchn); 426 if (ret) 427 goto error_xenbus; 428 ret = xenbus_transaction_end(xbt, 0); 429 if (ret) { 430 if (ret == -EAGAIN) 431 goto again; 432 xenbus_dev_fatal(dev, ret, "completing transaction"); 433 goto error_irqh; 434 } 435 436 xenbus_switch_state(dev, XenbusStateInitialised); 437 return 0; 438 439 error_xenbus: 440 xenbus_transaction_end(xbt, 1); 441 xenbus_dev_fatal(dev, ret, "writing xenstore"); 442 error_irqh: 443 unbind_from_irqhandler(info->irq, info); 444 info->irq = -1; 445 error_evtchan: 446 xenbus_free_evtchn(dev, evtchn); 447 error_grant: 448 gnttab_end_foreign_access(info->gref, 0, 0UL); 449 info->gref = -1; 450 return ret; 451 } 452 453 static void xenkbd_disconnect_backend(struct xenkbd_info *info) 454 { 455 if (info->irq >= 0) 456 unbind_from_irqhandler(info->irq, info); 457 info->irq = -1; 458 if (info->gref >= 0) 459 gnttab_end_foreign_access(info->gref, 0, 0UL); 460 info->gref = -1; 461 } 462 463 static void xenkbd_backend_changed(struct xenbus_device *dev, 464 enum xenbus_state backend_state) 465 { 466 switch (backend_state) { 467 case XenbusStateInitialising: 468 case XenbusStateInitialised: 469 case XenbusStateReconfiguring: 470 case XenbusStateReconfigured: 471 case XenbusStateUnknown: 472 break; 473 474 case XenbusStateInitWait: 475 xenbus_switch_state(dev, XenbusStateConnected); 476 break; 477 478 case XenbusStateConnected: 479 /* 480 * Work around xenbus race condition: If backend goes 481 * through InitWait to Connected fast enough, we can 482 * get Connected twice here. 483 */ 484 if (dev->state != XenbusStateConnected) 485 xenbus_switch_state(dev, XenbusStateConnected); 486 break; 487 488 case XenbusStateClosed: 489 if (dev->state == XenbusStateClosed) 490 break; 491 /* Missed the backend's CLOSING state -- fallthrough */ 492 case XenbusStateClosing: 493 xenbus_frontend_closed(dev); 494 break; 495 } 496 } 497 498 static const struct xenbus_device_id xenkbd_ids[] = { 499 { XENKBD_DRIVER_NAME }, 500 { "" } 501 }; 502 503 static struct xenbus_driver xenkbd_driver = { 504 .ids = xenkbd_ids, 505 .probe = xenkbd_probe, 506 .remove = xenkbd_remove, 507 .resume = xenkbd_resume, 508 .otherend_changed = xenkbd_backend_changed, 509 }; 510 511 static int __init xenkbd_init(void) 512 { 513 if (!xen_domain()) 514 return -ENODEV; 515 516 /* Nothing to do if running in dom0. */ 517 if (xen_initial_domain()) 518 return -ENODEV; 519 520 if (!xen_has_pv_devices()) 521 return -ENODEV; 522 523 return xenbus_register_frontend(&xenkbd_driver); 524 } 525 526 static void __exit xenkbd_cleanup(void) 527 { 528 xenbus_unregister_driver(&xenkbd_driver); 529 } 530 531 module_init(xenkbd_init); 532 module_exit(xenkbd_cleanup); 533 534 MODULE_DESCRIPTION("Xen virtual keyboard/pointer device frontend"); 535 MODULE_LICENSE("GPL"); 536 MODULE_ALIAS("xen:" XENKBD_DRIVER_NAME); 537