Skip to content

Commit 28f26ac

Browse files
committed
ipmi: Dynamically fetch GUID periodically
This will catch if the GUID changes. Signed-off-by: Corey Minyard <[email protected]>
1 parent 39d3fb4 commit 28f26ac

File tree

1 file changed

+42
-19
lines changed

1 file changed

+42
-19
lines changed

drivers/char/ipmi/ipmi_msghandler.c

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@ struct bmc_device {
274274
unsigned long dyn_id_expiry;
275275
struct mutex dyn_mutex; /* protects id & dyn* fields */
276276
u8 guid[16];
277-
int guid_set;
277+
u8 fetch_guid[16];
278+
int dyn_guid_set;
278279
struct kref usecount;
279280
};
280281
#define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev)
@@ -538,6 +539,8 @@ struct ipmi_smi {
538539
};
539540
#define to_si_intf_from_dev(device) container_of(device, struct ipmi_smi, dev)
540541

542+
static void __get_guid(ipmi_smi_t intf);
543+
541544
/**
542545
* The driver model view of the IPMI messaging driver.
543546
*/
@@ -2198,7 +2201,7 @@ static int bmc_get_device_id(ipmi_smi_t intf, struct bmc_device *bmc,
21982201
bool *guid_set, u8 *guid)
21992202
{
22002203
int rv = 0;
2201-
int prev_dyn_id_set;
2204+
int prev_dyn_id_set, prev_guid_set;
22022205

22032206
if (!intf) {
22042207
mutex_lock(&bmc->dyn_mutex);
@@ -2230,8 +2233,19 @@ static int bmc_get_device_id(ipmi_smi_t intf, struct bmc_device *bmc,
22302233
if (bmc->dyn_id_set && time_is_after_jiffies(bmc->dyn_id_expiry))
22312234
goto out;
22322235

2233-
prev_dyn_id_set = bmc->dyn_id_set;
2236+
prev_guid_set = bmc->dyn_guid_set;
2237+
__get_guid(intf);
2238+
2239+
if (bmc->dyn_guid_set)
2240+
memcpy(bmc->guid, bmc->fetch_guid, 16);
2241+
else if (prev_guid_set)
2242+
/*
2243+
* The guid used to be valid and it failed to fetch,
2244+
* just use the cached value.
2245+
*/
2246+
bmc->dyn_guid_set = prev_guid_set;
22342247

2248+
prev_dyn_id_set = bmc->dyn_id_set;
22352249
rv = __get_device_id(intf, bmc);
22362250
if (rv)
22372251
goto out;
@@ -2250,9 +2264,9 @@ static int bmc_get_device_id(ipmi_smi_t intf, struct bmc_device *bmc,
22502264
*id = bmc->id;
22512265

22522266
if (guid_set)
2253-
*guid_set = bmc->guid_set;
2267+
*guid_set = bmc->dyn_guid_set;
22542268

2255-
if (guid && bmc->guid_set)
2269+
if (guid && bmc->dyn_guid_set)
22562270
memcpy(guid, bmc->guid, 16);
22572271

22582272
mutex_unlock(&bmc->dyn_mutex);
@@ -2845,7 +2859,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum)
28452859
* representing the interfaced BMC already
28462860
*/
28472861
mutex_lock(&ipmidriver_mutex);
2848-
if (bmc->guid_set)
2862+
if (bmc->dyn_guid_set)
28492863
old_bmc = ipmi_find_bmc_guid(&ipmidriver.driver, bmc->guid);
28502864
else
28512865
old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver.driver,
@@ -2997,9 +3011,10 @@ send_guid_cmd(ipmi_smi_t intf, int chan)
29973011
-1, 0);
29983012
}
29993013

3000-
static void
3001-
guid_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
3014+
static void guid_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
30023015
{
3016+
struct bmc_device *bmc = intf->bmc;
3017+
30033018
if ((msg->addr.addr_type != IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
30043019
|| (msg->msg.netfn != IPMI_NETFN_APP_RESPONSE)
30053020
|| (msg->msg.cmd != IPMI_GET_DEVICE_GUID_CMD))
@@ -3008,12 +3023,12 @@ guid_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
30083023

30093024
if (msg->msg.data[0] != 0) {
30103025
/* Error from getting the GUID, the BMC doesn't have one. */
3011-
intf->bmc->guid_set = 0;
3026+
bmc->dyn_guid_set = 0;
30123027
goto out;
30133028
}
30143029

30153030
if (msg->msg.data_len < 17) {
3016-
intf->bmc->guid_set = 0;
3031+
bmc->dyn_guid_set = 0;
30173032
printk(KERN_WARNING PFX
30183033
"guid_handler: The GUID response from the BMC was too"
30193034
" short, it was %d but should have been 17. Assuming"
@@ -3022,24 +3037,34 @@ guid_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
30223037
goto out;
30233038
}
30243039

3025-
memcpy(intf->bmc->guid, msg->msg.data + 1, 16);
3026-
intf->bmc->guid_set = 1;
3040+
memcpy(bmc->fetch_guid, msg->msg.data + 1, 16);
3041+
/*
3042+
* Make sure the guid data is available before setting
3043+
* dyn_guid_set.
3044+
*/
3045+
smp_wmb();
3046+
bmc->dyn_guid_set = 1;
30273047
out:
30283048
wake_up(&intf->waitq);
30293049
}
30303050

3031-
static void
3032-
get_guid(ipmi_smi_t intf)
3051+
static void __get_guid(ipmi_smi_t intf)
30333052
{
30343053
int rv;
3054+
struct bmc_device *bmc = intf->bmc;
30353055

3036-
intf->bmc->guid_set = 0x2;
3056+
bmc->dyn_guid_set = 2;
30373057
intf->null_user_handler = guid_handler;
30383058
rv = send_guid_cmd(intf, 0);
30393059
if (rv)
30403060
/* Send failed, no GUID available. */
3041-
intf->bmc->guid_set = 0;
3042-
wait_event(intf->waitq, intf->bmc->guid_set != 2);
3061+
bmc->dyn_guid_set = 0;
3062+
3063+
wait_event(intf->waitq, bmc->dyn_guid_set != 2);
3064+
3065+
/* dyn_guid_set makes the guid data available. */
3066+
smp_rmb();
3067+
30433068
intf->null_user_handler = NULL;
30443069
}
30453070

@@ -3254,8 +3279,6 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
32543279
if (rv)
32553280
goto out;
32563281

3257-
get_guid(intf);
3258-
32593282
rv = bmc_get_device_id(intf, NULL, &id, NULL, NULL);
32603283
if (rv) {
32613284
dev_err(si_dev, "Unable to get the device id: %d\n", rv);

0 commit comments

Comments
 (0)