qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] About hotplug multifunction


From: Amos Kong
Subject: Re: [Qemu-devel] About hotplug multifunction
Date: Tue, 13 Sep 2011 10:24:43 -0400 (EDT)

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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]