xen-kbdfront.c 14 KB

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