提交 d4cf72af 编写于 作者: L Laine Stump

conf: pay attention to bus minSlot/maxSlot when autoassigning PCI addresses

The function that auto-assigns PCI addresses was written with the
hardcoded assumptions that any PCI bus would have slots available
starting at 1 and ending at 31. This isn't true for many types of
controllers (some have a single slot/port at 0, some have slots/ports
from 0 to 31). This patch updates that function to remove the
hardcoded assumptions. It will properly find/assign addresses for
devices that can only connect to pcie-(root|downstream)-port (which
have minSlot/maxSlot of 0/0) or a pcie-switch-upstream-port (0/31).

It still will not auto-create a new bus of the proper kind for these
connections when one doesn't exist, that task is for another day.
上级 be6c35e4
......@@ -471,55 +471,66 @@ virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs,
virDomainPCIConnectFlags flags)
{
/* default to starting the search for a free slot from
* 0000:00:00.0
* the first slot of domain 0 bus 0...
*/
virDevicePCIAddress a = { 0, 0, 0, 0, false };
char *addrStr = NULL;
/* except if this search is for the exact same type of device as
* last time, continue the search from the previous match
*/
if (flags == addrs->lastFlags)
a = addrs->lastaddr;
if (addrs->nbuses == 0) {
virReportError(VIR_ERR_XML_ERROR, "%s", _("No PCI buses available"));
goto error;
}
/* Start the search at the last used bus and slot */
for (a.slot++; a.bus < addrs->nbuses; a.bus++) {
/* ...unless this search is for the exact same type of device as
* last time, then continue the search from the next slot after
* the previous match (the "next slot" may possibly be the first
* slot of the next bus).
*/
if (flags == addrs->lastFlags) {
a = addrs->lastaddr;
if (++a.slot > addrs->buses[a.bus].maxSlot &&
++a.bus < addrs->nbuses)
a.slot = addrs->buses[a.bus].minSlot;
} else {
a.slot = addrs->buses[0].minSlot;
}
while (a.bus < addrs->nbuses) {
VIR_FREE(addrStr);
if (!(addrStr = virDomainPCIAddressAsString(&a)))
goto error;
if (!virDomainPCIAddressFlagsCompatible(&a, addrStr,
addrs->buses[a.bus].flags,
flags, false, false)) {
VIR_FREE(addrStr);
VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device",
a.domain, a.bus);
continue;
}
for (; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) {
if (!virDomainPCIAddressSlotInUse(addrs, &a))
goto success;
} else {
while (a.slot <= addrs->buses[a.bus].maxSlot) {
if (!virDomainPCIAddressSlotInUse(addrs, &a))
goto success;
VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
a.domain, a.bus, a.slot);
VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
a.domain, a.bus, a.slot);
a.slot++;
}
}
a.slot = 1;
VIR_FREE(addrStr);
if (++a.bus < addrs->nbuses)
a.slot = addrs->buses[a.bus].minSlot;
}
/* There were no free slots after the last used one */
if (addrs->dryRun) {
/* a is already set to the first new bus and slot 1 */
/* a is already set to the first new bus */
if (virDomainPCIAddressSetGrow(addrs, &a, flags) < 0)
goto error;
/* this device will use the first slot of the new bus */
a.slot = addrs->buses[a.bus].minSlot;
goto success;
} else if (flags == addrs->lastFlags) {
/* Check the buses from 0 up to the last used one */
for (a.bus = 0; a.bus <= addrs->lastaddr.bus; a.bus++) {
addrStr = NULL;
a.slot = addrs->buses[a.bus].minSlot;
VIR_FREE(addrStr);
if (!(addrStr = virDomainPCIAddressAsString(&a)))
goto error;
if (!virDomainPCIAddressFlagsCompatible(&a, addrStr,
......@@ -527,14 +538,15 @@ virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs,
flags, false, false)) {
VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device",
a.domain, a.bus);
continue;
}
for (a.slot = 1; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) {
if (!virDomainPCIAddressSlotInUse(addrs, &a))
goto success;
VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
a.domain, a.bus, a.slot);
} else {
while (a.slot <= addrs->buses[a.bus].maxSlot) {
if (!virDomainPCIAddressSlotInUse(addrs, &a))
goto success;
VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
a.domain, a.bus, a.slot);
a.slot++;
}
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册