----- Original Message ----- > Hi all, I've tested with WinXp guest, the multifunction hotplug works. > After reading the pci driver code, I found a problem. > > There is a list for each slot, (slot->funcs) > it will be inited in acpiphp_glue.c:register_slot() before hotpluging > device, > and only one entry(func 0) will be added to it, > no new entry will be added to the list when hotpluging devices to the > slot. > > When we release the device, there are only _one_ entry in the > list(slot->funcs). This list (slot->funcs) is designed to restore the func entries, But it only restore the func 0. I changed the #0000 to #ffff in seabios: src/acpi-dsdt.dsl mf hotplug of Windows doesn't work. linux guest will only remove the last func, func 0~6 still exist in guest. it seems a bug of Linux pci driver (not calling pci_remove_bus_device() for func 1~7). --- a/src/acpi-dsdt.dsl +++ b/src/acpi-dsdt.dsl @@ -130,7 +130,7 @@ DefinitionBlock ( #define hotplug_slot(name, nr) \ Device (S##name) { \ - Name (_ADR, nr##0000) \ + Name (_ADR, nr##ffff) \ Method (_EJ0,1) { \ Store(ShiftLeft(1, nr), B0EJ) \ Return (0x0) \ @@ -462,7 +462,7 @@ DefinitionBlock ( #define gen_pci_device(name, nr) \ Device(SL##name) { \ - Name (_ADR, nr##0000) \ + Name (_ADR, nr##ffff) \ Method (_RMV) { \ ============== I try to add new entries in acpiphp_glue.c:enable_device() for each func, but it doesn't work. > acpiphp_glue.c:disable_device() > list_for_each_entry(func, &slot->funcs, sibling) { > pdev = pci_get_slot(slot->bridge->pci_bus, > PCI_DEVFN(slot->device, func->function)); > ...release code... // those code can only be executed one time (func > 0) > pci_remove_bus_device(pdev); > } > > bus.c:pci_bus_add_device() is called for each func device in > acpiphp_glue.c:enable_device(). > bus.c:pci_remove_bus_device(pdev) is only called for func 0 in > acpiphp_glue.c:disable_device(). > > > Resolution: (I've tested it, success) > enumerate all the funcs when disable device. > > list_for_each_entry(func, &slot->funcs, sibling) { > for (i=0; i<8; i++) { > pdev = pci_get_slot(slot->bridge->pci_bus, > PCI_DEVFN(slot->device, i)); > ...release code... > pci_remove_bus_device(pdev); > > } > } -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html