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"); |