| From a0c04cf2b222d45b6906c6eae4ce0d2ea95a841f Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 30 Sep 2025 15:42:38 +0800 |
| Subject: ipmi: Fix __scan_channels() failing to rescan channels |
| |
| From: Jinhui Guo <guojinhui.liam@bytedance.com> |
| |
| [ Upstream commit 6bd30d8fc523fb880b4be548e8501bc0fe8f42d4 ] |
| |
| channel_handler() sets intf->channels_ready to true but never |
| clears it, so __scan_channels() skips any rescan. When the BMC |
| firmware changes a rescan is required. Allow it by clearing |
| the flag before starting a new scan. |
| |
| Signed-off-by: Jinhui Guo <guojinhui.liam@bytedance.com> |
| Message-ID: <20250930074239.2353-3-guojinhui.liam@bytedance.com> |
| Signed-off-by: Corey Minyard <corey@minyard.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/char/ipmi/ipmi_msghandler.c | 18 +++++++++++++----- |
| 1 file changed, 13 insertions(+), 5 deletions(-) |
| |
| diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c |
| index 117454a5603b..a72cd57dd8a5 100644 |
| --- a/drivers/char/ipmi/ipmi_msghandler.c |
| +++ b/drivers/char/ipmi/ipmi_msghandler.c |
| @@ -605,7 +605,8 @@ static void __ipmi_bmc_unregister(struct ipmi_smi *intf); |
| static int __ipmi_bmc_register(struct ipmi_smi *intf, |
| struct ipmi_device_id *id, |
| bool guid_set, guid_t *guid, int intf_num); |
| -static int __scan_channels(struct ipmi_smi *intf, struct ipmi_device_id *id); |
| +static int __scan_channels(struct ipmi_smi *intf, |
| + struct ipmi_device_id *id, bool rescan); |
| |
| |
| /** |
| @@ -2556,7 +2557,7 @@ static int __bmc_get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc, |
| if (__ipmi_bmc_register(intf, &id, guid_set, &guid, intf_num)) |
| need_waiter(intf); /* Retry later on an error. */ |
| else |
| - __scan_channels(intf, &id); |
| + __scan_channels(intf, &id, false); |
| |
| |
| if (!intf_set) { |
| @@ -2576,7 +2577,7 @@ static int __bmc_get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc, |
| goto out_noprocessing; |
| } else if (memcmp(&bmc->fetch_id, &bmc->id, sizeof(bmc->id))) |
| /* Version info changes, scan the channels again. */ |
| - __scan_channels(intf, &bmc->fetch_id); |
| + __scan_channels(intf, &bmc->fetch_id, true); |
| |
| bmc->dyn_id_expiry = jiffies + IPMI_DYN_DEV_ID_EXPIRY; |
| |
| @@ -3326,10 +3327,17 @@ channel_handler(struct ipmi_smi *intf, struct ipmi_recv_msg *msg) |
| /* |
| * Must be holding intf->bmc_reg_mutex to call this. |
| */ |
| -static int __scan_channels(struct ipmi_smi *intf, struct ipmi_device_id *id) |
| +static int __scan_channels(struct ipmi_smi *intf, |
| + struct ipmi_device_id *id, |
| + bool rescan) |
| { |
| int rv; |
| |
| + if (rescan) { |
| + /* Clear channels_ready to force channels rescan. */ |
| + intf->channels_ready = false; |
| + } |
| + |
| if (ipmi_version_major(id) > 1 |
| || (ipmi_version_major(id) == 1 |
| && ipmi_version_minor(id) >= 5)) { |
| @@ -3501,7 +3509,7 @@ int ipmi_add_smi(struct module *owner, |
| } |
| |
| mutex_lock(&intf->bmc_reg_mutex); |
| - rv = __scan_channels(intf, &id); |
| + rv = __scan_channels(intf, &id, false); |
| mutex_unlock(&intf->bmc_reg_mutex); |
| if (rv) |
| goto out_err_bmc_reg; |
| -- |
| 2.51.0 |
| |