static int __devinit xenkbd_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { int ret, i, abs; struct xenkbd_info *info; struct input_dev *kbd, *ptr; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); return -ENOMEM; } dev_set_drvdata(&dev->dev, info); info->xbdev = dev; info->irq = -1; snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename); info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); if (!info->page) goto error_nomem; if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-abs-pointer", "%d", &abs) < 0) abs = 0; if (abs) xenbus_printf(XBT_NIL, dev->nodename, "request-abs-pointer", "1"); /* keyboard */ kbd = input_allocate_device(); if (!kbd) goto error_nomem; kbd->name = "Xen Virtual Keyboard"; kbd->phys = info->phys; kbd->id.bustype = BUS_PCI; kbd->id.vendor = 0x5853; kbd->id.product = 0xffff; __set_bit(EV_KEY, kbd->evbit); for (i = KEY_ESC; i < KEY_UNKNOWN; i++) __set_bit(i, kbd->keybit); for (i = KEY_OK; i < KEY_MAX; i++) __set_bit(i, kbd->keybit); ret = input_register_device(kbd); if (ret) { input_free_device(kbd); xenbus_dev_fatal(dev, ret, "input_register_device(kbd)"); goto error; } info->kbd = kbd; /* pointing device */ ptr = input_allocate_device(); if (!ptr) goto error_nomem; ptr->name = "Xen Virtual Pointer"; ptr->phys = info->phys; ptr->id.bustype = BUS_PCI; ptr->id.vendor = 0x5853; ptr->id.product = 0xfffe; if (abs) { __set_bit(EV_ABS, ptr->evbit); input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0); input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0); } else { input_set_capability(ptr, EV_REL, REL_X); input_set_capability(ptr, EV_REL, REL_Y); } input_set_capability(ptr, EV_REL, REL_WHEEL); __set_bit(EV_KEY, ptr->evbit); for (i = BTN_LEFT; i <= BTN_TASK; i++) __set_bit(i, ptr->keybit); ret = input_register_device(ptr); if (ret) { input_free_device(ptr); xenbus_dev_fatal(dev, ret, "input_register_device(ptr)"); goto error; } info->ptr = ptr; ret = xenkbd_connect_backend(dev, info); if (ret < 0) goto error; return 0; error_nomem: ret = -ENOMEM; xenbus_dev_fatal(dev, ret, "allocating device memory"); error: xenkbd_remove(dev); return ret; }
int __devinit xenkbd_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { int ret, i; struct xenkbd_info *info; struct input_dev *kbd, *ptr; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); return -ENOMEM; } dev_set_drvdata(&dev->dev, info); info->xbdev = dev; snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename); info->page = (void *)__get_free_page(GFP_KERNEL); if (!info->page) goto error_nomem; info->page->in_cons = info->page->in_prod = 0; info->page->out_cons = info->page->out_prod = 0; /* keyboard */ kbd = input_allocate_device(); if (!kbd) goto error_nomem; kbd->name = "Xen Virtual Keyboard"; kbd->phys = info->phys; kbd->id.bustype = BUS_PCI; kbd->id.vendor = 0x5853; kbd->id.product = 0xffff; kbd->evbit[0] = BIT(EV_KEY); for (i = KEY_ESC; i < KEY_UNKNOWN; i++) set_bit(i, kbd->keybit); for (i = KEY_OK; i < KEY_MAX; i++) set_bit(i, kbd->keybit); ret = input_register_device(kbd); if (ret) { input_free_device(kbd); xenbus_dev_fatal(dev, ret, "input_register_device(kbd)"); goto error; } info->kbd = kbd; /* pointing device */ ptr = input_allocate_device(); if (!ptr) goto error_nomem; ptr->name = "Xen Virtual Pointer"; ptr->phys = info->phys; ptr->id.bustype = BUS_PCI; ptr->id.vendor = 0x5853; ptr->id.product = 0xfffe; ptr->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); for (i = BTN_LEFT; i <= BTN_TASK; i++) set_bit(i, ptr->keybit); ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL); input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0); input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0); ret = input_register_device(ptr); if (ret) { input_free_device(ptr); xenbus_dev_fatal(dev, ret, "input_register_device(ptr)"); goto error; } info->ptr = ptr; ret = xenkbd_connect_backend(dev, info); if (ret < 0) goto error; return 0; error_nomem: ret = -ENOMEM; xenbus_dev_fatal(dev, ret, "allocating device memory"); error: xenkbd_remove(dev); return ret; }