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