From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:55174) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R3Tuz-0005vA-Nw for qemu-devel@nongnu.org; Tue, 13 Sep 2011 10:25:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R3Tun-0003iO-IL for qemu-devel@nongnu.org; Tue, 13 Sep 2011 10:24:57 -0400 Received: from mx4-phx2.redhat.com ([209.132.183.25]:53133) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R3Tun-0003hn-8z for qemu-devel@nongnu.org; Tue, 13 Sep 2011 10:24:45 -0400 Date: Tue, 13 Sep 2011 10:24:43 -0400 (EDT) From: Amos Kong Message-ID: <1559006108.649056.1315923882976.JavaMail.root@zmail05.collab.prod.int.phx2.redhat.com> In-Reply-To: <1117934480.646073.1315916609192.JavaMail.root@zmail05.collab.prod.int.phx2.redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] About hotplug multifunction List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Michael S. Tsirkin" Cc: kvm@vger.kernel.org, Marcelo Tosatti , qemu-devel@nongnu.org, blauwirbel@gmail.com, yamahata@valinux.co.jp, Alex Williamson ----- 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); > > } > }