[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v4 04/16] pci/shpc: more generic handle hot-unplug in shpc_slot_c
From: |
Vladimir Sementsov-Ogievskiy |
Subject: |
[PATCH v4 04/16] pci/shpc: more generic handle hot-unplug in shpc_slot_command() |
Date: |
Mon, 13 Feb 2023 17:00:51 +0300 |
Free slot if both conditions (power-led = OFF and state = DISABLED)
becomes true regardless of the sequence. It is similar to how PCIe
hotplug works.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
hw/pci/shpc.c | 52 ++++++++++++++++++++++++++++++---------------------
1 file changed, 31 insertions(+), 21 deletions(-)
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index 25e4172382..959dc470f3 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -258,49 +258,59 @@ static void shpc_free_devices_in_slot(SHPCDevice *shpc,
int slot)
}
}
+static bool shpc_slot_is_off(uint8_t state, uint8_t power, uint8_t attn)
+{
+ return state == SHPC_STATE_DISABLED && power == SHPC_LED_OFF;
+}
+
static void shpc_slot_command(SHPCDevice *shpc, uint8_t target,
uint8_t state, uint8_t power, uint8_t attn)
{
- uint8_t current_state;
int slot = SHPC_LOGICAL_TO_IDX(target);
+ uint8_t old_state = shpc_get_status(shpc, slot, SHPC_SLOT_STATE_MASK);
+ uint8_t old_power = shpc_get_status(shpc, slot, SHPC_SLOT_PWR_LED_MASK);
+ uint8_t old_attn = shpc_get_status(shpc, slot, SHPC_SLOT_ATTN_LED_MASK);
+
if (target < SHPC_CMD_TRGT_MIN || slot >= shpc->nslots) {
shpc_invalid_command(shpc);
return;
}
- current_state = shpc_get_status(shpc, slot, SHPC_SLOT_STATE_MASK);
- if (current_state == SHPC_STATE_ENABLED && state == SHPC_STATE_PWRONLY) {
+
+ if (old_state == SHPC_STATE_ENABLED && state == SHPC_STATE_PWRONLY) {
shpc_invalid_command(shpc);
return;
}
- if (power != SHPC_LED_NO) {
+ if (power == SHPC_LED_NO) {
+ power = old_power;
+ } else {
/* TODO: send event to monitor */
shpc_set_status(shpc, slot, power, SHPC_SLOT_PWR_LED_MASK);
}
- if (attn != SHPC_LED_NO) {
+
+ if (attn == SHPC_LED_NO) {
+ attn = old_attn;
+ } else {
/* TODO: send event to monitor */
shpc_set_status(shpc, slot, attn, SHPC_SLOT_ATTN_LED_MASK);
}
- if (state != SHPC_STATE_NO) {
+
+ if (state == SHPC_STATE_NO) {
+ state = old_state;
+ } else {
shpc_set_status(shpc, slot, state, SHPC_SLOT_STATE_MASK);
}
- if ((current_state == SHPC_STATE_ENABLED ||
- current_state == SHPC_STATE_PWRONLY) &&
- state == SHPC_STATE_DISABLED)
+ if (!shpc_slot_is_off(old_state, old_power, old_attn) &&
+ shpc_slot_is_off(state, power, attn))
{
- power = shpc_get_status(shpc, slot, SHPC_SLOT_PWR_LED_MASK);
- /* TODO: track what monitor requested. */
- /* Look at LED to figure out whether it's ok to remove the device. */
- if (power == SHPC_LED_OFF) {
- shpc_free_devices_in_slot(shpc, slot);
- shpc_set_status(shpc, slot, 1, SHPC_SLOT_STATUS_MRL_OPEN);
- shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_EMPTY,
- SHPC_SLOT_STATUS_PRSNT_MASK);
- shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
- SHPC_SLOT_EVENT_MRL |
- SHPC_SLOT_EVENT_PRESENCE;
- }
+ shpc_free_devices_in_slot(shpc, slot);
+ shpc_set_status(shpc, slot, 1, SHPC_SLOT_STATUS_MRL_OPEN);
+ shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_EMPTY,
+ SHPC_SLOT_STATUS_PRSNT_MASK);
+ shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
+ SHPC_SLOT_EVENT_MRL |
+ SHPC_SLOT_EVENT_PRESENCE;
}
}
--
2.34.1
- Re: [PATCH v4 06/16] pci/shpc: refactor shpc_device_plug_common(), (continued)
- [PATCH v4 03/16] pci/shpc: shpc_slot_command(): handle PWRONLY -> ENABLED transition, Vladimir Sementsov-Ogievskiy, 2023/02/13
- [PATCH v4 07/16] pcie: pcie_cap_slot_write_config(): use correct macro, Vladimir Sementsov-Ogievskiy, 2023/02/13
- [PATCH v4 10/16] pcie: pcie_cap_slot_enable_power() use correct helper, Vladimir Sementsov-Ogievskiy, 2023/02/13
- [PATCH v4 01/16] pci/shpc: set attention led to OFF on reset, Vladimir Sementsov-Ogievskiy, 2023/02/13
- [PATCH v4 04/16] pci/shpc: more generic handle hot-unplug in shpc_slot_command(),
Vladimir Sementsov-Ogievskiy <=
- [PATCH v4 05/16] pci/shpc: pass PCIDevice pointer to shpc_slot_command(), Vladimir Sementsov-Ogievskiy, 2023/02/13
- [PATCH v4 14/16] qapi: deprecate "device" field of DEVICE_* events, Vladimir Sementsov-Ogievskiy, 2023/02/13
- Re: [PATCH v4 14/16] qapi: deprecate "device" field of DEVICE_* events, Daniel P . Berrangé, 2023/02/13
- Re: [PATCH v4 14/16] qapi: deprecate "device" field of DEVICE_* events, Markus Armbruster, 2023/02/14
- Re: [PATCH v4 14/16] qapi: deprecate "device" field of DEVICE_* events, Peter Krempa, 2023/02/14
- Re: [PATCH v4 14/16] qapi: deprecate "device" field of DEVICE_* events, Daniel P . Berrangé, 2023/02/14
- Re: [PATCH v4 14/16] qapi: deprecate "device" field of DEVICE_* events, Markus Armbruster, 2023/02/14
- Re: [PATCH v4 14/16] qapi: deprecate "device" field of DEVICE_* events, Philippe Mathieu-Daudé, 2023/02/14