0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009
0010 #include <linux/moduleparam.h>
0011 #include <linux/init.h>
0012 #include <linux/list.h>
0013 #include <linux/vmalloc.h>
0014 #include <linux/workqueue.h>
0015 #include <xen/xenbus.h>
0016 #include <xen/events.h>
0017 #include <xen/pci.h>
0018 #include "pciback.h"
0019
0020 #define INVALID_EVTCHN_IRQ (-1)
0021
0022 static bool __read_mostly passthrough;
0023 module_param(passthrough, bool, S_IRUGO);
0024 MODULE_PARM_DESC(passthrough,
0025 "Option to specify how to export PCI topology to guest:\n"\
0026 " 0 - (default) Hide the true PCI topology and makes the frontend\n"\
0027 " there is a single PCI bus with only the exported devices on it.\n"\
0028 " For example, a device at 03:05.0 will be re-assigned to 00:00.0\n"\
0029 " while second device at 02:1a.1 will be re-assigned to 00:01.1.\n"\
0030 " 1 - Passthrough provides a real view of the PCI topology to the\n"\
0031 " frontend (for example, a device at 06:01.b will still appear at\n"\
0032 " 06:01.b to the frontend). This is similar to how Xen 2.0.x\n"\
0033 " exposed PCI devices to its driver domains. This may be required\n"\
0034 " for drivers which depend on finding their hardward in certain\n"\
0035 " bus/slot locations.");
0036
0037 static struct xen_pcibk_device *alloc_pdev(struct xenbus_device *xdev)
0038 {
0039 struct xen_pcibk_device *pdev;
0040
0041 pdev = kzalloc(sizeof(struct xen_pcibk_device), GFP_KERNEL);
0042 if (pdev == NULL)
0043 goto out;
0044 dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev);
0045
0046 pdev->xdev = xdev;
0047
0048 mutex_init(&pdev->dev_lock);
0049
0050 pdev->sh_info = NULL;
0051 pdev->evtchn_irq = INVALID_EVTCHN_IRQ;
0052 pdev->be_watching = 0;
0053
0054 INIT_WORK(&pdev->op_work, xen_pcibk_do_op);
0055
0056 if (xen_pcibk_init_devices(pdev)) {
0057 kfree(pdev);
0058 pdev = NULL;
0059 }
0060
0061 dev_set_drvdata(&xdev->dev, pdev);
0062
0063 out:
0064 return pdev;
0065 }
0066
0067 static void xen_pcibk_disconnect(struct xen_pcibk_device *pdev)
0068 {
0069 mutex_lock(&pdev->dev_lock);
0070
0071 if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ) {
0072 unbind_from_irqhandler(pdev->evtchn_irq, pdev);
0073 pdev->evtchn_irq = INVALID_EVTCHN_IRQ;
0074 }
0075
0076
0077
0078
0079 flush_work(&pdev->op_work);
0080
0081 if (pdev->sh_info != NULL) {
0082 xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_info);
0083 pdev->sh_info = NULL;
0084 }
0085 mutex_unlock(&pdev->dev_lock);
0086 }
0087
0088 static void free_pdev(struct xen_pcibk_device *pdev)
0089 {
0090 if (pdev->be_watching) {
0091 unregister_xenbus_watch(&pdev->be_watch);
0092 pdev->be_watching = 0;
0093 }
0094
0095 xen_pcibk_disconnect(pdev);
0096
0097
0098
0099 xen_pcibk_release_devices(pdev);
0100
0101 dev_set_drvdata(&pdev->xdev->dev, NULL);
0102 pdev->xdev = NULL;
0103
0104 kfree(pdev);
0105 }
0106
0107 static int xen_pcibk_do_attach(struct xen_pcibk_device *pdev, int gnt_ref,
0108 evtchn_port_t remote_evtchn)
0109 {
0110 int err = 0;
0111 void *vaddr;
0112
0113 dev_dbg(&pdev->xdev->dev,
0114 "Attaching to frontend resources - gnt_ref=%d evtchn=%u\n",
0115 gnt_ref, remote_evtchn);
0116
0117 err = xenbus_map_ring_valloc(pdev->xdev, &gnt_ref, 1, &vaddr);
0118 if (err < 0) {
0119 xenbus_dev_fatal(pdev->xdev, err,
0120 "Error mapping other domain page in ours.");
0121 goto out;
0122 }
0123
0124 pdev->sh_info = vaddr;
0125
0126 err = bind_interdomain_evtchn_to_irqhandler_lateeoi(
0127 pdev->xdev, remote_evtchn, xen_pcibk_handle_event,
0128 0, DRV_NAME, pdev);
0129 if (err < 0) {
0130 xenbus_dev_fatal(pdev->xdev, err,
0131 "Error binding event channel to IRQ");
0132 goto out;
0133 }
0134 pdev->evtchn_irq = err;
0135 err = 0;
0136
0137 dev_dbg(&pdev->xdev->dev, "Attached!\n");
0138 out:
0139 return err;
0140 }
0141
0142 static int xen_pcibk_attach(struct xen_pcibk_device *pdev)
0143 {
0144 int err = 0;
0145 int gnt_ref;
0146 evtchn_port_t remote_evtchn;
0147 char *magic = NULL;
0148
0149
0150 mutex_lock(&pdev->dev_lock);
0151
0152 if (xenbus_read_driver_state(pdev->xdev->nodename) !=
0153 XenbusStateInitialised)
0154 goto out;
0155
0156
0157 if (xenbus_read_driver_state(pdev->xdev->otherend) !=
0158 XenbusStateInitialised)
0159 goto out;
0160
0161 dev_dbg(&pdev->xdev->dev, "Reading frontend config\n");
0162
0163 err = xenbus_gather(XBT_NIL, pdev->xdev->otherend,
0164 "pci-op-ref", "%u", &gnt_ref,
0165 "event-channel", "%u", &remote_evtchn,
0166 "magic", NULL, &magic, NULL);
0167 if (err) {
0168
0169 xenbus_dev_fatal(pdev->xdev, err,
0170 "Error reading configuration from frontend");
0171 goto out;
0172 }
0173
0174 if (magic == NULL || strcmp(magic, XEN_PCI_MAGIC) != 0) {
0175 xenbus_dev_fatal(pdev->xdev, -EFAULT,
0176 "version mismatch (%s/%s) with pcifront - "
0177 "halting " DRV_NAME,
0178 magic, XEN_PCI_MAGIC);
0179 err = -EFAULT;
0180 goto out;
0181 }
0182
0183 err = xen_pcibk_do_attach(pdev, gnt_ref, remote_evtchn);
0184 if (err)
0185 goto out;
0186
0187 dev_dbg(&pdev->xdev->dev, "Connecting...\n");
0188
0189 err = xenbus_switch_state(pdev->xdev, XenbusStateConnected);
0190 if (err)
0191 xenbus_dev_fatal(pdev->xdev, err,
0192 "Error switching to connected state!");
0193
0194 dev_dbg(&pdev->xdev->dev, "Connected? %d\n", err);
0195 out:
0196 mutex_unlock(&pdev->dev_lock);
0197
0198 kfree(magic);
0199
0200 return err;
0201 }
0202
0203 static int xen_pcibk_publish_pci_dev(struct xen_pcibk_device *pdev,
0204 unsigned int domain, unsigned int bus,
0205 unsigned int devfn, unsigned int devid)
0206 {
0207 int err;
0208 int len;
0209 char str[64];
0210
0211 len = snprintf(str, sizeof(str), "vdev-%d", devid);
0212 if (unlikely(len >= (sizeof(str) - 1))) {
0213 err = -ENOMEM;
0214 goto out;
0215 }
0216
0217
0218 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
0219 "%04x:%02x:%02x.%02x", domain, bus,
0220 PCI_SLOT(devfn), PCI_FUNC(devfn));
0221
0222 out:
0223 return err;
0224 }
0225
0226 static int xen_pcibk_export_device(struct xen_pcibk_device *pdev,
0227 int domain, int bus, int slot, int func,
0228 int devid)
0229 {
0230 struct pci_dev *dev;
0231 int err = 0;
0232
0233 dev_dbg(&pdev->xdev->dev, "exporting dom %x bus %x slot %x func %x\n",
0234 domain, bus, slot, func);
0235
0236 dev = pcistub_get_pci_dev_by_slot(pdev, domain, bus, slot, func);
0237 if (!dev) {
0238 err = -EINVAL;
0239 xenbus_dev_fatal(pdev->xdev, err,
0240 "Couldn't locate PCI device "
0241 "(%04x:%02x:%02x.%d)! "
0242 "perhaps already in-use?",
0243 domain, bus, slot, func);
0244 goto out;
0245 }
0246
0247 err = xen_pcibk_add_pci_dev(pdev, dev, devid,
0248 xen_pcibk_publish_pci_dev);
0249 if (err)
0250 goto out;
0251
0252 dev_info(&dev->dev, "registering for %d\n", pdev->xdev->otherend_id);
0253 if (xen_register_device_domain_owner(dev,
0254 pdev->xdev->otherend_id) != 0) {
0255 dev_err(&dev->dev, "Stealing ownership from dom%d.\n",
0256 xen_find_device_domain_owner(dev));
0257 xen_unregister_device_domain_owner(dev);
0258 xen_register_device_domain_owner(dev, pdev->xdev->otherend_id);
0259 }
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 out:
0270 return err;
0271 }
0272
0273 static int xen_pcibk_remove_device(struct xen_pcibk_device *pdev,
0274 int domain, int bus, int slot, int func)
0275 {
0276 int err = 0;
0277 struct pci_dev *dev;
0278
0279 dev_dbg(&pdev->xdev->dev, "removing dom %x bus %x slot %x func %x\n",
0280 domain, bus, slot, func);
0281
0282 dev = xen_pcibk_get_pci_dev(pdev, domain, bus, PCI_DEVFN(slot, func));
0283 if (!dev) {
0284 err = -EINVAL;
0285 dev_dbg(&pdev->xdev->dev, "Couldn't locate PCI device "
0286 "(%04x:%02x:%02x.%d)! not owned by this domain\n",
0287 domain, bus, slot, func);
0288 goto out;
0289 }
0290
0291 dev_dbg(&dev->dev, "unregistering for %d\n", pdev->xdev->otherend_id);
0292 xen_unregister_device_domain_owner(dev);
0293
0294
0295
0296 xen_pcibk_release_pci_dev(pdev, dev, true );
0297
0298 out:
0299 return err;
0300 }
0301
0302 static int xen_pcibk_publish_pci_root(struct xen_pcibk_device *pdev,
0303 unsigned int domain, unsigned int bus)
0304 {
0305 unsigned int d, b;
0306 int i, root_num, len, err;
0307 char str[64];
0308
0309 dev_dbg(&pdev->xdev->dev, "Publishing pci roots\n");
0310
0311 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
0312 "root_num", "%d", &root_num);
0313 if (err == 0 || err == -ENOENT)
0314 root_num = 0;
0315 else if (err < 0)
0316 goto out;
0317
0318
0319 for (i = 0; i < root_num; i++) {
0320 len = snprintf(str, sizeof(str), "root-%d", i);
0321 if (unlikely(len >= (sizeof(str) - 1))) {
0322 err = -ENOMEM;
0323 goto out;
0324 }
0325
0326 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
0327 str, "%x:%x", &d, &b);
0328 if (err < 0)
0329 goto out;
0330 if (err != 2) {
0331 err = -EINVAL;
0332 goto out;
0333 }
0334
0335 if (d == domain && b == bus) {
0336 err = 0;
0337 goto out;
0338 }
0339 }
0340
0341 len = snprintf(str, sizeof(str), "root-%d", root_num);
0342 if (unlikely(len >= (sizeof(str) - 1))) {
0343 err = -ENOMEM;
0344 goto out;
0345 }
0346
0347 dev_dbg(&pdev->xdev->dev, "writing root %d at %04x:%02x\n",
0348 root_num, domain, bus);
0349
0350 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
0351 "%04x:%02x", domain, bus);
0352 if (err)
0353 goto out;
0354
0355 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename,
0356 "root_num", "%d", (root_num + 1));
0357
0358 out:
0359 return err;
0360 }
0361
0362 static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev,
0363 enum xenbus_state state)
0364 {
0365 int err = 0;
0366 int num_devs;
0367 int domain, bus, slot, func;
0368 unsigned int substate;
0369 int i, len;
0370 char state_str[64];
0371 char dev_str[64];
0372
0373
0374 dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n");
0375
0376 mutex_lock(&pdev->dev_lock);
0377 if (xenbus_read_driver_state(pdev->xdev->nodename) != state)
0378 goto out;
0379
0380 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",
0381 &num_devs);
0382 if (err != 1) {
0383 if (err >= 0)
0384 err = -EINVAL;
0385 xenbus_dev_fatal(pdev->xdev, err,
0386 "Error reading number of devices");
0387 goto out;
0388 }
0389
0390 for (i = 0; i < num_devs; i++) {
0391 len = snprintf(state_str, sizeof(state_str), "state-%d", i);
0392 if (unlikely(len >= (sizeof(state_str) - 1))) {
0393 err = -ENOMEM;
0394 xenbus_dev_fatal(pdev->xdev, err,
0395 "String overflow while reading "
0396 "configuration");
0397 goto out;
0398 }
0399 substate = xenbus_read_unsigned(pdev->xdev->nodename, state_str,
0400 XenbusStateUnknown);
0401
0402 switch (substate) {
0403 case XenbusStateInitialising:
0404 dev_dbg(&pdev->xdev->dev, "Attaching dev-%d ...\n", i);
0405
0406 len = snprintf(dev_str, sizeof(dev_str), "dev-%d", i);
0407 if (unlikely(len >= (sizeof(dev_str) - 1))) {
0408 err = -ENOMEM;
0409 xenbus_dev_fatal(pdev->xdev, err,
0410 "String overflow while "
0411 "reading configuration");
0412 goto out;
0413 }
0414 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
0415 dev_str, "%x:%x:%x.%x",
0416 &domain, &bus, &slot, &func);
0417 if (err < 0) {
0418 xenbus_dev_fatal(pdev->xdev, err,
0419 "Error reading device "
0420 "configuration");
0421 goto out;
0422 }
0423 if (err != 4) {
0424 err = -EINVAL;
0425 xenbus_dev_fatal(pdev->xdev, err,
0426 "Error parsing pci device "
0427 "configuration");
0428 goto out;
0429 }
0430
0431 err = xen_pcibk_export_device(pdev, domain, bus, slot,
0432 func, i);
0433 if (err)
0434 goto out;
0435
0436
0437 err = xen_pcibk_publish_pci_roots(pdev,
0438 xen_pcibk_publish_pci_root);
0439 if (err) {
0440 xenbus_dev_fatal(pdev->xdev, err,
0441 "Error while publish PCI root"
0442 "buses for frontend");
0443 goto out;
0444 }
0445
0446 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename,
0447 state_str, "%d",
0448 XenbusStateInitialised);
0449 if (err) {
0450 xenbus_dev_fatal(pdev->xdev, err,
0451 "Error switching substate of "
0452 "dev-%d\n", i);
0453 goto out;
0454 }
0455 break;
0456
0457 case XenbusStateClosing:
0458 dev_dbg(&pdev->xdev->dev, "Detaching dev-%d ...\n", i);
0459
0460 len = snprintf(dev_str, sizeof(dev_str), "vdev-%d", i);
0461 if (unlikely(len >= (sizeof(dev_str) - 1))) {
0462 err = -ENOMEM;
0463 xenbus_dev_fatal(pdev->xdev, err,
0464 "String overflow while "
0465 "reading configuration");
0466 goto out;
0467 }
0468 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
0469 dev_str, "%x:%x:%x.%x",
0470 &domain, &bus, &slot, &func);
0471 if (err < 0) {
0472 xenbus_dev_fatal(pdev->xdev, err,
0473 "Error reading device "
0474 "configuration");
0475 goto out;
0476 }
0477 if (err != 4) {
0478 err = -EINVAL;
0479 xenbus_dev_fatal(pdev->xdev, err,
0480 "Error parsing pci device "
0481 "configuration");
0482 goto out;
0483 }
0484
0485 err = xen_pcibk_remove_device(pdev, domain, bus, slot,
0486 func);
0487 if (err)
0488 goto out;
0489
0490
0491
0492
0493
0494
0495 break;
0496
0497 default:
0498 break;
0499 }
0500 }
0501
0502 if (state != XenbusStateReconfiguring)
0503
0504 goto out;
0505
0506 err = xenbus_switch_state(pdev->xdev, XenbusStateReconfigured);
0507 if (err) {
0508 xenbus_dev_fatal(pdev->xdev, err,
0509 "Error switching to reconfigured state!");
0510 goto out;
0511 }
0512
0513 out:
0514 mutex_unlock(&pdev->dev_lock);
0515 return 0;
0516 }
0517
0518 static void xen_pcibk_frontend_changed(struct xenbus_device *xdev,
0519 enum xenbus_state fe_state)
0520 {
0521 struct xen_pcibk_device *pdev = dev_get_drvdata(&xdev->dev);
0522
0523 dev_dbg(&xdev->dev, "fe state changed %d\n", fe_state);
0524
0525 switch (fe_state) {
0526 case XenbusStateInitialised:
0527 xen_pcibk_attach(pdev);
0528 break;
0529
0530 case XenbusStateReconfiguring:
0531 xen_pcibk_reconfigure(pdev, XenbusStateReconfiguring);
0532 break;
0533
0534 case XenbusStateConnected:
0535
0536
0537
0538 xenbus_switch_state(xdev, XenbusStateConnected);
0539 break;
0540
0541 case XenbusStateClosing:
0542 xen_pcibk_disconnect(pdev);
0543 xenbus_switch_state(xdev, XenbusStateClosing);
0544 break;
0545
0546 case XenbusStateClosed:
0547 xen_pcibk_disconnect(pdev);
0548 xenbus_switch_state(xdev, XenbusStateClosed);
0549 if (xenbus_dev_is_online(xdev))
0550 break;
0551 fallthrough;
0552 case XenbusStateUnknown:
0553 dev_dbg(&xdev->dev, "frontend is gone! unregister device\n");
0554 device_unregister(&xdev->dev);
0555 break;
0556
0557 default:
0558 break;
0559 }
0560 }
0561
0562 static int xen_pcibk_setup_backend(struct xen_pcibk_device *pdev)
0563 {
0564
0565 int domain, bus, slot, func;
0566 int err = 0;
0567 int i, num_devs;
0568 char dev_str[64];
0569 char state_str[64];
0570
0571 mutex_lock(&pdev->dev_lock);
0572
0573
0574
0575 if (xenbus_read_driver_state(pdev->xdev->nodename) !=
0576 XenbusStateInitWait)
0577 goto out;
0578
0579 dev_dbg(&pdev->xdev->dev, "getting be setup\n");
0580
0581 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",
0582 &num_devs);
0583 if (err != 1) {
0584 if (err >= 0)
0585 err = -EINVAL;
0586 xenbus_dev_fatal(pdev->xdev, err,
0587 "Error reading number of devices");
0588 goto out;
0589 }
0590
0591 for (i = 0; i < num_devs; i++) {
0592 int l = snprintf(dev_str, sizeof(dev_str), "dev-%d", i);
0593 if (unlikely(l >= (sizeof(dev_str) - 1))) {
0594 err = -ENOMEM;
0595 xenbus_dev_fatal(pdev->xdev, err,
0596 "String overflow while reading "
0597 "configuration");
0598 goto out;
0599 }
0600
0601 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, dev_str,
0602 "%x:%x:%x.%x", &domain, &bus, &slot, &func);
0603 if (err < 0) {
0604 xenbus_dev_fatal(pdev->xdev, err,
0605 "Error reading device configuration");
0606 goto out;
0607 }
0608 if (err != 4) {
0609 err = -EINVAL;
0610 xenbus_dev_fatal(pdev->xdev, err,
0611 "Error parsing pci device "
0612 "configuration");
0613 goto out;
0614 }
0615
0616 err = xen_pcibk_export_device(pdev, domain, bus, slot, func, i);
0617 if (err)
0618 goto out;
0619
0620
0621 l = snprintf(state_str, sizeof(state_str), "state-%d", i);
0622 if (unlikely(l >= (sizeof(state_str) - 1))) {
0623 err = -ENOMEM;
0624 xenbus_dev_fatal(pdev->xdev, err,
0625 "String overflow while reading "
0626 "configuration");
0627 goto out;
0628 }
0629 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, state_str,
0630 "%d", XenbusStateInitialised);
0631 if (err) {
0632 xenbus_dev_fatal(pdev->xdev, err, "Error switching "
0633 "substate of dev-%d\n", i);
0634 goto out;
0635 }
0636 }
0637
0638 err = xen_pcibk_publish_pci_roots(pdev, xen_pcibk_publish_pci_root);
0639 if (err) {
0640 xenbus_dev_fatal(pdev->xdev, err,
0641 "Error while publish PCI root buses "
0642 "for frontend");
0643 goto out;
0644 }
0645
0646 err = xenbus_switch_state(pdev->xdev, XenbusStateInitialised);
0647 if (err)
0648 xenbus_dev_fatal(pdev->xdev, err,
0649 "Error switching to initialised state!");
0650
0651 out:
0652 mutex_unlock(&pdev->dev_lock);
0653 if (!err)
0654
0655 xen_pcibk_attach(pdev);
0656 return err;
0657 }
0658
0659 static void xen_pcibk_be_watch(struct xenbus_watch *watch,
0660 const char *path, const char *token)
0661 {
0662 struct xen_pcibk_device *pdev =
0663 container_of(watch, struct xen_pcibk_device, be_watch);
0664
0665 switch (xenbus_read_driver_state(pdev->xdev->nodename)) {
0666 case XenbusStateInitWait:
0667 xen_pcibk_setup_backend(pdev);
0668 break;
0669
0670 case XenbusStateInitialised:
0671
0672
0673
0674
0675
0676 xen_pcibk_reconfigure(pdev, XenbusStateInitialised);
0677 break;
0678
0679 default:
0680 break;
0681 }
0682 }
0683
0684 static int xen_pcibk_xenbus_probe(struct xenbus_device *dev,
0685 const struct xenbus_device_id *id)
0686 {
0687 int err = 0;
0688 struct xen_pcibk_device *pdev = alloc_pdev(dev);
0689
0690 if (pdev == NULL) {
0691 err = -ENOMEM;
0692 xenbus_dev_fatal(dev, err,
0693 "Error allocating xen_pcibk_device struct");
0694 goto out;
0695 }
0696
0697
0698 err = xenbus_switch_state(dev, XenbusStateInitWait);
0699 if (err)
0700 goto out;
0701
0702
0703 err = xenbus_watch_path(dev, dev->nodename, &pdev->be_watch,
0704 NULL, xen_pcibk_be_watch);
0705 if (err)
0706 goto out;
0707
0708 pdev->be_watching = 1;
0709
0710
0711
0712
0713 xen_pcibk_be_watch(&pdev->be_watch, NULL, NULL);
0714
0715 out:
0716 return err;
0717 }
0718
0719 static int xen_pcibk_xenbus_remove(struct xenbus_device *dev)
0720 {
0721 struct xen_pcibk_device *pdev = dev_get_drvdata(&dev->dev);
0722
0723 if (pdev != NULL)
0724 free_pdev(pdev);
0725
0726 return 0;
0727 }
0728
0729 static const struct xenbus_device_id xen_pcibk_ids[] = {
0730 {"pci"},
0731 {""},
0732 };
0733
0734 static struct xenbus_driver xen_pcibk_driver = {
0735 .name = DRV_NAME,
0736 .ids = xen_pcibk_ids,
0737 .probe = xen_pcibk_xenbus_probe,
0738 .remove = xen_pcibk_xenbus_remove,
0739 .otherend_changed = xen_pcibk_frontend_changed,
0740 };
0741
0742 const struct xen_pcibk_backend *__read_mostly xen_pcibk_backend;
0743
0744 int __init xen_pcibk_xenbus_register(void)
0745 {
0746 if (!xen_pcibk_pv_support())
0747 return 0;
0748
0749 xen_pcibk_backend = &xen_pcibk_vpci_backend;
0750 if (passthrough)
0751 xen_pcibk_backend = &xen_pcibk_passthrough_backend;
0752 pr_info("backend is %s\n", xen_pcibk_backend->name);
0753 return xenbus_register_backend(&xen_pcibk_driver);
0754 }
0755
0756 void __exit xen_pcibk_xenbus_unregister(void)
0757 {
0758 if (xen_pcibk_pv_support())
0759 xenbus_unregister_driver(&xen_pcibk_driver);
0760 }