xen-pcifront.c (51c71a3bbaca868043cc45b3ad3786dd48a90235) xen-pcifront.c (a83919e0940f6eb8f77ab1d602a063f8a6703117)
1/*
2 * Xen PCI Frontend.
3 *
4 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
5 */
6#include <linux/module.h>
7#include <linux/init.h>
8#include <linux/mm.h>

--- 6 unchanged lines hidden (view full) ---

15#include <linux/msi.h>
16#include <xen/interface/io/pciif.h>
17#include <asm/xen/pci.h>
18#include <linux/interrupt.h>
19#include <linux/atomic.h>
20#include <linux/workqueue.h>
21#include <linux/bitops.h>
22#include <linux/time.h>
1/*
2 * Xen PCI Frontend.
3 *
4 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
5 */
6#include <linux/module.h>
7#include <linux/init.h>
8#include <linux/mm.h>

--- 6 unchanged lines hidden (view full) ---

15#include <linux/msi.h>
16#include <xen/interface/io/pciif.h>
17#include <asm/xen/pci.h>
18#include <linux/interrupt.h>
19#include <linux/atomic.h>
20#include <linux/workqueue.h>
21#include <linux/bitops.h>
22#include <linux/time.h>
23#include <xen/platform_pci.h>
24
25#include <asm/xen/swiotlb-xen.h>
26#define INVALID_GRANT_REF (0)
27#define INVALID_EVTCHN (-1)
28
29struct pci_bus_entry {
30 struct list_head list;
31 struct pci_bus *bus;

--- 435 unchanged lines hidden (view full) ---

467 bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
468 sd = kmalloc(sizeof(*sd), GFP_KERNEL);
469 if (!bus_entry || !sd) {
470 err = -ENOMEM;
471 goto err_out;
472 }
473 pcifront_init_sd(sd, domain, bus, pdev);
474
23
24#include <asm/xen/swiotlb-xen.h>
25#define INVALID_GRANT_REF (0)
26#define INVALID_EVTCHN (-1)
27
28struct pci_bus_entry {
29 struct list_head list;
30 struct pci_bus *bus;

--- 435 unchanged lines hidden (view full) ---

466 bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
467 sd = kmalloc(sizeof(*sd), GFP_KERNEL);
468 if (!bus_entry || !sd) {
469 err = -ENOMEM;
470 goto err_out;
471 }
472 pcifront_init_sd(sd, domain, bus, pdev);
473
474 pci_lock_rescan_remove();
475
475 b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
476 &pcifront_bus_ops, sd);
477 if (!b) {
478 dev_err(&pdev->xdev->dev,
479 "Error creating PCI Frontend Bus!\n");
480 err = -ENOMEM;
476 b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
477 &pcifront_bus_ops, sd);
478 if (!b) {
479 dev_err(&pdev->xdev->dev,
480 "Error creating PCI Frontend Bus!\n");
481 err = -ENOMEM;
482 pci_unlock_rescan_remove();
481 goto err_out;
482 }
483
484 bus_entry->bus = b;
485
486 list_add(&bus_entry->list, &pdev->root_buses);
487
488 /* pci_scan_bus_parented skips devices which do not have a have
489 * devfn==0. The pcifront_scan_bus enumerates all devfn. */
490 err = pcifront_scan_bus(pdev, domain, bus, b);
491
492 /* Claim resources before going "live" with our devices */
493 pci_walk_bus(b, pcifront_claim_resource, pdev);
494
495 /* Create SysFS and notify udev of the devices. Aka: "going live" */
496 pci_bus_add_devices(b);
497
483 goto err_out;
484 }
485
486 bus_entry->bus = b;
487
488 list_add(&bus_entry->list, &pdev->root_buses);
489
490 /* pci_scan_bus_parented skips devices which do not have a have
491 * devfn==0. The pcifront_scan_bus enumerates all devfn. */
492 err = pcifront_scan_bus(pdev, domain, bus, b);
493
494 /* Claim resources before going "live" with our devices */
495 pci_walk_bus(b, pcifront_claim_resource, pdev);
496
497 /* Create SysFS and notify udev of the devices. Aka: "going live" */
498 pci_bus_add_devices(b);
499
500 pci_unlock_rescan_remove();
498 return err;
499
500err_out:
501 kfree(bus_entry);
502 kfree(sd);
503
504 return err;
505}

--- 46 unchanged lines hidden (view full) ---

552}
553
554static void pcifront_free_roots(struct pcifront_device *pdev)
555{
556 struct pci_bus_entry *bus_entry, *t;
557
558 dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
559
501 return err;
502
503err_out:
504 kfree(bus_entry);
505 kfree(sd);
506
507 return err;
508}

--- 46 unchanged lines hidden (view full) ---

555}
556
557static void pcifront_free_roots(struct pcifront_device *pdev)
558{
559 struct pci_bus_entry *bus_entry, *t;
560
561 dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
562
563 pci_lock_rescan_remove();
560 list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
561 list_del(&bus_entry->list);
562
563 free_root_bus_devs(bus_entry->bus);
564
565 kfree(bus_entry->bus->sysdata);
566
567 device_unregister(bus_entry->bus->bridge);
568 pci_remove_bus(bus_entry->bus);
569
570 kfree(bus_entry);
571 }
564 list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
565 list_del(&bus_entry->list);
566
567 free_root_bus_devs(bus_entry->bus);
568
569 kfree(bus_entry->bus->sysdata);
570
571 device_unregister(bus_entry->bus->bridge);
572 pci_remove_bus(bus_entry->bus);
573
574 kfree(bus_entry);
575 }
576 pci_unlock_rescan_remove();
572}
573
574static pci_ers_result_t pcifront_common_process(int cmd,
575 struct pcifront_device *pdev,
576 pci_channel_state_t state)
577{
578 pci_ers_result_t result;
579 struct pci_driver *pdrv;

--- 459 unchanged lines hidden (view full) ---

1039 pci_dev = pci_get_domain_bus_and_slot(domain, bus,
1040 PCI_DEVFN(slot, func));
1041 if (!pci_dev) {
1042 dev_dbg(&pdev->xdev->dev,
1043 "Cannot get PCI device %04x:%02x:%02x.%d\n",
1044 domain, bus, slot, func);
1045 continue;
1046 }
577}
578
579static pci_ers_result_t pcifront_common_process(int cmd,
580 struct pcifront_device *pdev,
581 pci_channel_state_t state)
582{
583 pci_ers_result_t result;
584 struct pci_driver *pdrv;

--- 459 unchanged lines hidden (view full) ---

1044 pci_dev = pci_get_domain_bus_and_slot(domain, bus,
1045 PCI_DEVFN(slot, func));
1046 if (!pci_dev) {
1047 dev_dbg(&pdev->xdev->dev,
1048 "Cannot get PCI device %04x:%02x:%02x.%d\n",
1049 domain, bus, slot, func);
1050 continue;
1051 }
1052 pci_lock_rescan_remove();
1047 pci_stop_and_remove_bus_device(pci_dev);
1048 pci_dev_put(pci_dev);
1053 pci_stop_and_remove_bus_device(pci_dev);
1054 pci_dev_put(pci_dev);
1055 pci_unlock_rescan_remove();
1049
1050 dev_dbg(&pdev->xdev->dev,
1051 "PCI device %04x:%02x:%02x.%d removed.\n",
1052 domain, bus, slot, func);
1053 }
1054
1055 err = xenbus_switch_state(pdev->xdev, XenbusStateReconfiguring);
1056

--- 77 unchanged lines hidden (view full) ---

1134 .otherend_changed = pcifront_backend_changed,
1135);
1136
1137static int __init pcifront_init(void)
1138{
1139 if (!xen_pv_domain() || xen_initial_domain())
1140 return -ENODEV;
1141
1056
1057 dev_dbg(&pdev->xdev->dev,
1058 "PCI device %04x:%02x:%02x.%d removed.\n",
1059 domain, bus, slot, func);
1060 }
1061
1062 err = xenbus_switch_state(pdev->xdev, XenbusStateReconfiguring);
1063

--- 77 unchanged lines hidden (view full) ---

1141 .otherend_changed = pcifront_backend_changed,
1142);
1143
1144static int __init pcifront_init(void)
1145{
1146 if (!xen_pv_domain() || xen_initial_domain())
1147 return -ENODEV;
1148
1142 if (!xen_has_pv_devices())
1143 return -ENODEV;
1144
1145 pci_frontend_registrar(1 /* enable */);
1146
1147 return xenbus_register_frontend(&xenpci_driver);
1148}
1149
1150static void __exit pcifront_cleanup(void)
1151{
1152 xenbus_unregister_driver(&xenpci_driver);
1153 pci_frontend_registrar(0 /* disable */);
1154}
1155module_init(pcifront_init);
1156module_exit(pcifront_cleanup);
1157
1158MODULE_DESCRIPTION("Xen PCI passthrough frontend.");
1159MODULE_LICENSE("GPL");
1160MODULE_ALIAS("xen:pci");
1149 pci_frontend_registrar(1 /* enable */);
1150
1151 return xenbus_register_frontend(&xenpci_driver);
1152}
1153
1154static void __exit pcifront_cleanup(void)
1155{
1156 xenbus_unregister_driver(&xenpci_driver);
1157 pci_frontend_registrar(0 /* disable */);
1158}
1159module_init(pcifront_init);
1160module_exit(pcifront_cleanup);
1161
1162MODULE_DESCRIPTION("Xen PCI passthrough frontend.");
1163MODULE_LICENSE("GPL");
1164MODULE_ALIAS("xen:pci");