int vpci_bus_init(void) { struct pci_dev *pcidev = NULL; sysdata = kzalloc(sizeof(void *), GFP_KERNEL); vbus = pci_scan_bus_parented(NULL, 2, & vpci_ops, sysdata); //vbus = pci_create_root_bus(NULL,i,& vpci_ops, sysdata,NULL); //if (vbus != NULL) //break; memset(sysdata, 0, sizeof(void *)); if (vbus == NULL) { kfree(sysdata); return -EINVAL; } if (pci_register_driver(& vpci_vdev_driver) < 0) { pci_remove_bus(vbus); vbus = NULL; return -EINVAL; } pcidev = pci_scan_single_device(vbus, 0); if (pcidev == NULL) return 0; else pci_dev_get(pcidev); pci_bus_add_devices(vbus); return 0; }
void vpci_bus_remove(void) { if (vbus) { pci_unregister_driver(&vpci_vdev_driver); device_unregister(vbus->bridge); pci_remove_bus(vbus); kfree(sysdata); vbus = NULL; } }
static void pci_remove_bus_device(struct pci_dev *dev) { struct pci_bus *bus = dev->subordinate; struct pci_dev *child, *tmp; if (bus) { list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) pci_remove_bus_device(child); pci_remove_bus(bus); dev->subordinate = NULL; } pci_destroy_dev(dev); }
void pci_remove_root_bus(struct pci_bus *bus) { struct pci_dev *child, *tmp; struct pci_host_bridge *host_bridge; if (!pci_is_root_bus(bus)) return; host_bridge = to_pci_host_bridge(bus->bridge); list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) pci_remove_bus_device(child); pci_remove_bus(bus); host_bridge->bus = NULL; /* remove the host bridge */ device_unregister(&host_bridge->dev); }