pcie: introduce pcie_sltctl_powered_off() helper
In pcie_cap_slot_write_config() we check for PCI_EXP_SLTCTL_PWR_OFF in a bad form. We should distinguish PCI_EXP_SLTCTL_PWR which is a "mask" and PCI_EXP_SLTCTL_PWR_OFF which is value for that mask. Better code is in pcie_cap_slot_unplug_request_cb() and in pcie_cap_update_power(). Let's use same pattern everywhere. To simplify things add also a helper. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Anton Kuchin <antonkuchin@yandex-team.ru> Message-Id: <20230216180356.156832-12-vsementsov@yandex-team.ru> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
f90d932094
commit
5aaed9caf1
@ -39,6 +39,11 @@
|
|||||||
#define PCIE_DEV_PRINTF(dev, fmt, ...) \
|
#define PCIE_DEV_PRINTF(dev, fmt, ...) \
|
||||||
PCIE_DPRINTF("%s:%x "fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__)
|
PCIE_DPRINTF("%s:%x "fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__)
|
||||||
|
|
||||||
|
static bool pcie_sltctl_powered_off(uint16_t sltctl)
|
||||||
|
{
|
||||||
|
return (sltctl & PCI_EXP_SLTCTL_PCC) == PCI_EXP_SLTCTL_PWR_OFF
|
||||||
|
&& (sltctl & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PWR_IND_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* pci express capability helper functions
|
* pci express capability helper functions
|
||||||
@ -395,6 +400,7 @@ static void pcie_cap_update_power(PCIDevice *hotplug_dev)
|
|||||||
|
|
||||||
if (sltcap & PCI_EXP_SLTCAP_PCP) {
|
if (sltcap & PCI_EXP_SLTCAP_PCP) {
|
||||||
power = (sltctl & PCI_EXP_SLTCTL_PCC) == PCI_EXP_SLTCTL_PWR_ON;
|
power = (sltctl & PCI_EXP_SLTCTL_PCC) == PCI_EXP_SLTCTL_PWR_ON;
|
||||||
|
/* Don't we need to check also (sltctl & PCI_EXP_SLTCTL_PIC) ? */
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
|
pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
|
||||||
@ -579,8 +585,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((sltctl & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PWR_IND_OFF) &&
|
if (pcie_sltctl_powered_off(sltctl)) {
|
||||||
((sltctl & PCI_EXP_SLTCTL_PCC) == PCI_EXP_SLTCTL_PWR_OFF)) {
|
|
||||||
/* slot is powered off -> unplug without round-trip to the guest */
|
/* slot is powered off -> unplug without round-trip to the guest */
|
||||||
pcie_cap_slot_do_unplug(hotplug_pdev);
|
pcie_cap_slot_do_unplug(hotplug_pdev);
|
||||||
hotplug_event_notify(hotplug_pdev);
|
hotplug_event_notify(hotplug_pdev);
|
||||||
@ -770,10 +775,9 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
|
|||||||
* this is a work around for guests that overwrite
|
* this is a work around for guests that overwrite
|
||||||
* control of powered off slots before powering them on.
|
* control of powered off slots before powering them on.
|
||||||
*/
|
*/
|
||||||
if ((sltsta & PCI_EXP_SLTSTA_PDS) && (val & PCI_EXP_SLTCTL_PCC) &&
|
if ((sltsta & PCI_EXP_SLTSTA_PDS) && pcie_sltctl_powered_off(val) &&
|
||||||
(val & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PWR_IND_OFF &&
|
!pcie_sltctl_powered_off(old_slt_ctl))
|
||||||
(!(old_slt_ctl & PCI_EXP_SLTCTL_PCC) ||
|
{
|
||||||
(old_slt_ctl & PCI_EXP_SLTCTL_PIC) != PCI_EXP_SLTCTL_PWR_IND_OFF)) {
|
|
||||||
pcie_cap_slot_do_unplug(dev);
|
pcie_cap_slot_do_unplug(dev);
|
||||||
}
|
}
|
||||||
pcie_cap_update_power(dev);
|
pcie_cap_update_power(dev);
|
||||||
|
Loading…
Reference in New Issue
Block a user