goto cleanup;
if (pciDeviceGetManaged(dev) &&
- pciDettachDevice(dev) < 0)
+ pciDettachDevice(dev, driver->activePciHostdevs) < 0)
goto cleanup;
}
static void
-qemudReattachManagedDevice(pciDevice *dev)
+qemudReattachManagedDevice(pciDevice *dev, struct qemud_driver *driver)
{
int retries = 100;
usleep(100*1000);
retries--;
}
- if (pciReAttachDevice(dev) < 0) {
+ if (pciReAttachDevice(dev, driver->activePciHostdevs) < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to re-attach PCI device: %s"),
err ? err->message : _("unknown error"));
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
pciDevice *dev = pciDeviceListGet(pcidevs, i);
- qemudReattachManagedDevice(dev);
+ qemudReattachManagedDevice(dev, driver);
}
pciDeviceListFree(pcidevs);
return -1;
if (!pciDeviceIsAssignable(pci, !driver->relaxedACS) ||
- (hostdev->managed && pciDettachDevice(pci) < 0) ||
+ (hostdev->managed && pciDettachDevice(pci, driver->activePciHostdevs) < 0) ||
pciResetDevice(pci, driver->activePciHostdevs) < 0) {
pciFreeDevice(pci);
return -1;
if (pciResetDevice(pci, driver->activePciHostdevs) < 0)
VIR_WARN0("Unable to reset PCI device after assign failure");
else if (hostdev->managed &&
- pciReAttachDevice(pci) < 0)
+ pciReAttachDevice(pci, driver->activePciHostdevs) < 0)
VIR_WARN0("Unable to re-attach PCI device after assign failure");
pciFreeDevice(pci);
pciDeviceListDel(driver->activePciHostdevs, pci);
if (pciResetDevice(pci, driver->activePciHostdevs) < 0)
ret = -1;
- qemudReattachManagedDevice(pci);
+ qemudReattachManagedDevice(pci, driver);
pciFreeDevice(pci);
}
static int
qemudNodeDeviceDettach (virNodeDevicePtr dev)
{
+ struct qemud_driver *driver = dev->conn->privateData;
pciDevice *pci;
unsigned domain, bus, slot, function;
int ret = -1;
if (!pci)
return -1;
- if (pciDettachDevice(pci) < 0)
+ qemuDriverLock(driver);
+ if (pciDettachDevice(pci, driver->activePciHostdevs) < 0)
goto out;
ret = 0;
out:
+ qemuDriverUnlock(driver);
pciFreeDevice(pci);
return ret;
}
static int
qemudNodeDeviceReAttach (virNodeDevicePtr dev)
{
+ struct qemud_driver *driver = dev->conn->privateData;
pciDevice *pci;
unsigned domain, bus, slot, function;
int ret = -1;
if (!pci)
return -1;
- if (pciReAttachDevice(pci) < 0)
+ qemuDriverLock(driver);
+ if (pciReAttachDevice(pci, driver->activePciHostdevs) < 0)
goto out;
ret = 0;
out:
+ qemuDriverUnlock(driver);
pciFreeDevice(pci);
return ret;
}
}
int
-pciDettachDevice(pciDevice *dev)
+pciDettachDevice(pciDevice *dev, pciDeviceList *activeDevs)
{
const char *driver = pciFindStubDriver();
if (!driver) {
return -1;
}
+ if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
+ pciReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Not detaching active device %s"), dev->name);
+ return -1;
+ }
+
return pciBindDeviceToStub(dev, driver);
}
}
int
-pciReAttachDevice(pciDevice *dev)
+pciReAttachDevice(pciDevice *dev, pciDeviceList *activeDevs)
{
const char *driver = pciFindStubDriver();
if (!driver) {
return -1;
}
+ if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
+ pciReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Not reattaching active device %s"), dev->name);
+ return -1;
+ }
+
return pciUnBindDeviceFromStub(dev, driver);
}
unsigned slot,
unsigned function);
void pciFreeDevice (pciDevice *dev);
-int pciDettachDevice (pciDevice *dev);
-int pciReAttachDevice (pciDevice *dev);
+int pciDettachDevice (pciDevice *dev, pciDeviceList *activeDevs);
+int pciReAttachDevice (pciDevice *dev, pciDeviceList *activeDevs);
int pciResetDevice (pciDevice *dev,
pciDeviceList *activeDevs);
void pciDeviceSetManaged(pciDevice *dev,