Skip to content

Commit 6e4dc3d

Browse files
committed
Merge tag 'for-linus-5.10-1' of git://github.com/cminyard/linux-ipmi
Pull IPMI updates from Corey Minyard: "Some minor bug fixes, return values, cleanups of prints, conversion of tasklets to the new API. The biggest change is retrying the initial information fetch from the management controller. If that fails, the iterface is not operational, and one group was having trouble with the management controller not being ready when the OS started up. So a retry was added" * tag 'for-linus-5.10-1' of git://github.com/cminyard/linux-ipmi: ipmi_si: Fix wrong return value in try_smi_init() ipmi: msghandler: Fix a signedness bug ipmi: add retry in try_get_dev_id() ipmi: Clean up some printks ipmi:msghandler: retry to get device id on an error ipmi:sm: Print current state when the state is invalid ipmi: Reset response handler when failing to send the command ipmi: add a newline when printing parameter 'panic_op' by sysfs char: ipmi: convert tasklets to use new tasklet_setup() API
2 parents 2f6c6d0 + 8fe7990 commit 6e4dc3d

File tree

7 files changed

+93
-36
lines changed

7 files changed

+93
-36
lines changed

drivers/char/ipmi/ipmi_bt_sm.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,10 @@ static int bt_start_transaction(struct si_sm_data *bt,
213213
if (bt->state == BT_STATE_LONG_BUSY)
214214
return IPMI_NODE_BUSY_ERR;
215215

216-
if (bt->state != BT_STATE_IDLE)
216+
if (bt->state != BT_STATE_IDLE) {
217+
dev_warn(bt->io->dev, "BT in invalid state %d\n", bt->state);
217218
return IPMI_NOT_IN_MY_STATE_ERR;
219+
}
218220

219221
if (bt_debug & BT_DEBUG_MSG) {
220222
dev_dbg(bt->io->dev, "+++++++++++++++++ New command\n");

drivers/char/ipmi/ipmi_kcs_sm.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
* that document.
1818
*/
1919

20+
#define DEBUG /* So dev_dbg() is always available. */
21+
2022
#include <linux/kernel.h> /* For printk. */
2123
#include <linux/module.h>
2224
#include <linux/moduleparam.h>
@@ -187,8 +189,8 @@ static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)
187189
(kcs->error_retries)++;
188190
if (kcs->error_retries > MAX_ERROR_RETRIES) {
189191
if (kcs_debug & KCS_DEBUG_ENABLE)
190-
printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n",
191-
reason);
192+
dev_dbg(kcs->io->dev, "ipmi_kcs_sm: kcs hosed: %s\n",
193+
reason);
192194
kcs->state = KCS_HOSED;
193195
} else {
194196
kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES;
@@ -268,11 +270,13 @@ static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
268270
if (size > MAX_KCS_WRITE_SIZE)
269271
return IPMI_REQ_LEN_EXCEEDED_ERR;
270272

271-
if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED))
273+
if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
274+
dev_warn(kcs->io->dev, "KCS in invalid state %d\n", kcs->state);
272275
return IPMI_NOT_IN_MY_STATE_ERR;
276+
}
273277

274278
if (kcs_debug & KCS_DEBUG_MSG) {
275-
printk(KERN_DEBUG "start_kcs_transaction -");
279+
dev_dbg(kcs->io->dev, "%s -", __func__);
276280
for (i = 0; i < size; i++)
277281
pr_cont(" %02x", data[i]);
278282
pr_cont("\n");
@@ -331,7 +335,8 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
331335
status = read_status(kcs);
332336

333337
if (kcs_debug & KCS_DEBUG_STATES)
334-
printk(KERN_DEBUG "KCS: State = %d, %x\n", kcs->state, status);
338+
dev_dbg(kcs->io->dev,
339+
"KCS: State = %d, %x\n", kcs->state, status);
335340

336341
/* All states wait for ibf, so just do it here. */
337342
if (!check_ibf(kcs, status, time))

drivers/char/ipmi/ipmi_msghandler.c

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,13 @@
3434
#include <linux/uuid.h>
3535
#include <linux/nospec.h>
3636
#include <linux/vmalloc.h>
37+
#include <linux/delay.h>
3738

3839
#define IPMI_DRIVER_VERSION "39.2"
3940

4041
static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
4142
static int ipmi_init_msghandler(void);
42-
static void smi_recv_tasklet(unsigned long);
43+
static void smi_recv_tasklet(struct tasklet_struct *t);
4344
static void handle_new_recv_msgs(struct ipmi_smi *intf);
4445
static void need_waiter(struct ipmi_smi *intf);
4546
static int handle_one_recv_msg(struct ipmi_smi *intf,
@@ -60,6 +61,7 @@ enum ipmi_panic_event_op {
6061
#else
6162
#define IPMI_PANIC_DEFAULT IPMI_SEND_PANIC_EVENT_NONE
6263
#endif
64+
6365
static enum ipmi_panic_event_op ipmi_send_panic_event = IPMI_PANIC_DEFAULT;
6466

6567
static int panic_op_write_handler(const char *val,
@@ -89,19 +91,19 @@ static int panic_op_read_handler(char *buffer, const struct kernel_param *kp)
8991
{
9092
switch (ipmi_send_panic_event) {
9193
case IPMI_SEND_PANIC_EVENT_NONE:
92-
strcpy(buffer, "none");
94+
strcpy(buffer, "none\n");
9395
break;
9496

9597
case IPMI_SEND_PANIC_EVENT:
96-
strcpy(buffer, "event");
98+
strcpy(buffer, "event\n");
9799
break;
98100

99101
case IPMI_SEND_PANIC_EVENT_STRING:
100-
strcpy(buffer, "string");
102+
strcpy(buffer, "string\n");
101103
break;
102104

103105
default:
104-
strcpy(buffer, "???");
106+
strcpy(buffer, "???\n");
105107
break;
106108
}
107109

@@ -317,6 +319,7 @@ struct bmc_device {
317319
int dyn_guid_set;
318320
struct kref usecount;
319321
struct work_struct remove_work;
322+
unsigned char cc; /* completion code */
320323
};
321324
#define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev)
322325

@@ -2381,6 +2384,8 @@ static void bmc_device_id_handler(struct ipmi_smi *intf,
23812384
msg->msg.data, msg->msg.data_len, &intf->bmc->fetch_id);
23822385
if (rv) {
23832386
dev_warn(intf->si_dev, "device id demangle failed: %d\n", rv);
2387+
/* record completion code when error */
2388+
intf->bmc->cc = msg->msg.data[0];
23842389
intf->bmc->dyn_id_set = 0;
23852390
} else {
23862391
/*
@@ -2426,23 +2431,39 @@ send_get_device_id_cmd(struct ipmi_smi *intf)
24262431
static int __get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc)
24272432
{
24282433
int rv;
2429-
2430-
bmc->dyn_id_set = 2;
2434+
unsigned int retry_count = 0;
24312435

24322436
intf->null_user_handler = bmc_device_id_handler;
24332437

2438+
retry:
2439+
bmc->cc = 0;
2440+
bmc->dyn_id_set = 2;
2441+
24342442
rv = send_get_device_id_cmd(intf);
24352443
if (rv)
2436-
return rv;
2444+
goto out_reset_handler;
24372445

24382446
wait_event(intf->waitq, bmc->dyn_id_set != 2);
24392447

2440-
if (!bmc->dyn_id_set)
2448+
if (!bmc->dyn_id_set) {
2449+
if ((bmc->cc == IPMI_DEVICE_IN_FW_UPDATE_ERR
2450+
|| bmc->cc == IPMI_DEVICE_IN_INIT_ERR
2451+
|| bmc->cc == IPMI_NOT_IN_MY_STATE_ERR)
2452+
&& ++retry_count <= GET_DEVICE_ID_MAX_RETRY) {
2453+
msleep(500);
2454+
dev_warn(intf->si_dev,
2455+
"BMC returned 0x%2.2x, retry get bmc device id\n",
2456+
bmc->cc);
2457+
goto retry;
2458+
}
2459+
24412460
rv = -EIO; /* Something went wrong in the fetch. */
2461+
}
24422462

24432463
/* dyn_id_set makes the id data available. */
24442464
smp_rmb();
24452465

2466+
out_reset_handler:
24462467
intf->null_user_handler = NULL;
24472468

24482469
return rv;
@@ -3245,7 +3266,6 @@ channel_handler(struct ipmi_smi *intf, struct ipmi_recv_msg *msg)
32453266
/* It's the one we want */
32463267
if (msg->msg.data[0] != 0) {
32473268
/* Got an error from the channel, just go on. */
3248-
32493269
if (msg->msg.data[0] == IPMI_INVALID_COMMAND_ERR) {
32503270
/*
32513271
* If the MC does not support this
@@ -3329,6 +3349,7 @@ static int __scan_channels(struct ipmi_smi *intf, struct ipmi_device_id *id)
33293349
dev_warn(intf->si_dev,
33303350
"Error sending channel information for channel 0, %d\n",
33313351
rv);
3352+
intf->null_user_handler = NULL;
33323353
return -EIO;
33333354
}
33343355

@@ -3430,9 +3451,8 @@ int ipmi_add_smi(struct module *owner,
34303451
intf->curr_seq = 0;
34313452
spin_lock_init(&intf->waiting_rcv_msgs_lock);
34323453
INIT_LIST_HEAD(&intf->waiting_rcv_msgs);
3433-
tasklet_init(&intf->recv_tasklet,
3434-
smi_recv_tasklet,
3435-
(unsigned long) intf);
3454+
tasklet_setup(&intf->recv_tasklet,
3455+
smi_recv_tasklet);
34363456
atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0);
34373457
spin_lock_init(&intf->xmit_msgs_lock);
34383458
INIT_LIST_HEAD(&intf->xmit_msgs);
@@ -4467,10 +4487,10 @@ static void handle_new_recv_msgs(struct ipmi_smi *intf)
44674487
}
44684488
}
44694489

4470-
static void smi_recv_tasklet(unsigned long val)
4490+
static void smi_recv_tasklet(struct tasklet_struct *t)
44714491
{
44724492
unsigned long flags = 0; /* keep us warning-free. */
4473-
struct ipmi_smi *intf = (struct ipmi_smi *) val;
4493+
struct ipmi_smi *intf = from_tasklet(intf, t, recv_tasklet);
44744494
int run_to_completion = intf->run_to_completion;
44754495
struct ipmi_smi_msg *newmsg = NULL;
44764496

@@ -4542,7 +4562,7 @@ void ipmi_smi_msg_received(struct ipmi_smi *intf,
45424562
spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags);
45434563

45444564
if (run_to_completion)
4545-
smi_recv_tasklet((unsigned long) intf);
4565+
smi_recv_tasklet(&intf->recv_tasklet);
45464566
else
45474567
tasklet_schedule(&intf->recv_tasklet);
45484568
}

drivers/char/ipmi/ipmi_si_intf.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,7 @@ static int try_get_dev_id(struct smi_info *smi_info)
13161316
unsigned char *resp;
13171317
unsigned long resp_len;
13181318
int rv = 0;
1319+
unsigned int retry_count = 0;
13191320

13201321
resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
13211322
if (!resp)
@@ -1327,6 +1328,8 @@ static int try_get_dev_id(struct smi_info *smi_info)
13271328
*/
13281329
msg[0] = IPMI_NETFN_APP_REQUEST << 2;
13291330
msg[1] = IPMI_GET_DEVICE_ID_CMD;
1331+
1332+
retry:
13301333
smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
13311334

13321335
rv = wait_for_msg_done(smi_info);
@@ -1339,6 +1342,20 @@ static int try_get_dev_id(struct smi_info *smi_info)
13391342
/* Check and record info from the get device id, in case we need it. */
13401343
rv = ipmi_demangle_device_id(resp[0] >> 2, resp[1],
13411344
resp + 2, resp_len - 2, &smi_info->device_id);
1345+
if (rv) {
1346+
/* record completion code */
1347+
unsigned char cc = *(resp + 2);
1348+
1349+
if ((cc == IPMI_DEVICE_IN_FW_UPDATE_ERR
1350+
|| cc == IPMI_DEVICE_IN_INIT_ERR
1351+
|| cc == IPMI_NOT_IN_MY_STATE_ERR)
1352+
&& ++retry_count <= GET_DEVICE_ID_MAX_RETRY) {
1353+
dev_warn(smi_info->io.dev,
1354+
"BMC returned 0x%2.2x, retry get bmc device id\n",
1355+
cc);
1356+
goto retry;
1357+
}
1358+
}
13421359

13431360
out:
13441361
kfree(resp);
@@ -1963,7 +1980,7 @@ static int try_smi_init(struct smi_info *new_smi)
19631980
/* Do this early so it's available for logs. */
19641981
if (!new_smi->io.dev) {
19651982
pr_err("IPMI interface added with no device\n");
1966-
rv = EIO;
1983+
rv = -EIO;
19671984
goto out_err;
19681985
}
19691986

drivers/char/ipmi/ipmi_smic_sm.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
* 2001 Hewlett-Packard Company
2222
*/
2323

24+
#define DEBUG /* So dev_dbg() is always available. */
25+
2426
#include <linux/kernel.h> /* For printk. */
2527
#include <linux/string.h>
2628
#include <linux/module.h>
@@ -126,11 +128,14 @@ static int start_smic_transaction(struct si_sm_data *smic,
126128
if (size > MAX_SMIC_WRITE_SIZE)
127129
return IPMI_REQ_LEN_EXCEEDED_ERR;
128130

129-
if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED))
131+
if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {
132+
dev_warn(smic->io->dev,
133+
"SMIC in invalid state %d\n", smic->state);
130134
return IPMI_NOT_IN_MY_STATE_ERR;
135+
}
131136

132137
if (smic_debug & SMIC_DEBUG_MSG) {
133-
printk(KERN_DEBUG "start_smic_transaction -");
138+
dev_dbg(smic->io->dev, "%s -", __func__);
134139
for (i = 0; i < size; i++)
135140
pr_cont(" %02x", data[i]);
136141
pr_cont("\n");
@@ -152,7 +157,7 @@ static int smic_get_result(struct si_sm_data *smic,
152157
int i;
153158

154159
if (smic_debug & SMIC_DEBUG_MSG) {
155-
printk(KERN_DEBUG "smic_get result -");
160+
dev_dbg(smic->io->dev, "smic_get result -");
156161
for (i = 0; i < smic->read_pos; i++)
157162
pr_cont(" %02x", smic->read_data[i]);
158163
pr_cont("\n");
@@ -324,9 +329,9 @@ static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
324329
}
325330
if (smic->state != SMIC_IDLE) {
326331
if (smic_debug & SMIC_DEBUG_STATES)
327-
printk(KERN_DEBUG
328-
"smic_event - smic->smic_timeout = %ld, time = %ld\n",
329-
smic->smic_timeout, time);
332+
dev_dbg(smic->io->dev,
333+
"%s - smic->smic_timeout = %ld, time = %ld\n",
334+
__func__, smic->smic_timeout, time);
330335
/*
331336
* FIXME: smic_event is sometimes called with time >
332337
* SMIC_RETRY_TIMEOUT
@@ -345,8 +350,9 @@ static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
345350

346351
status = read_smic_status(smic);
347352
if (smic_debug & SMIC_DEBUG_STATES)
348-
printk(KERN_DEBUG "smic_event - state = %d, flags = 0x%02x, status = 0x%02x\n",
349-
smic->state, flags, status);
353+
dev_dbg(smic->io->dev,
354+
"%s - state = %d, flags = 0x%02x, status = 0x%02x\n",
355+
__func__, smic->state, flags, status);
350356

351357
switch (smic->state) {
352358
case SMIC_IDLE:
@@ -436,8 +442,9 @@ static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
436442
data = read_smic_data(smic);
437443
if (data != 0) {
438444
if (smic_debug & SMIC_DEBUG_ENABLE)
439-
printk(KERN_DEBUG "SMIC_WRITE_END: data = %02x\n",
440-
data);
445+
dev_dbg(smic->io->dev,
446+
"SMIC_WRITE_END: data = %02x\n",
447+
data);
441448
start_error_recovery(smic,
442449
"state = SMIC_WRITE_END, "
443450
"data != SUCCESS");
@@ -516,8 +523,9 @@ static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
516523
/* data register holds an error code */
517524
if (data != 0) {
518525
if (smic_debug & SMIC_DEBUG_ENABLE)
519-
printk(KERN_DEBUG "SMIC_READ_END: data = %02x\n",
520-
data);
526+
dev_dbg(smic->io->dev,
527+
"SMIC_READ_END: data = %02x\n",
528+
data);
521529
start_error_recovery(smic,
522530
"state = SMIC_READ_END, "
523531
"data != SUCCESS");
@@ -533,7 +541,8 @@ static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
533541

534542
default:
535543
if (smic_debug & SMIC_DEBUG_ENABLE) {
536-
printk(KERN_DEBUG "smic->state = %d\n", smic->state);
544+
dev_dbg(smic->io->dev,
545+
"smic->state = %d\n", smic->state);
537546
start_error_recovery(smic, "state = UNKNOWN");
538547
return SI_SM_CALL_WITH_DELAY;
539548
}

include/linux/ipmi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,4 +333,6 @@ struct ipmi_smi_info {
333333
/* This is to get the private info of struct ipmi_smi */
334334
extern int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data);
335335

336+
#define GET_DEVICE_ID_MAX_RETRY 5
337+
336338
#endif /* __LINUX_IPMI_H */

include/uapi/linux/ipmi_msgdefs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
#define IPMI_ERR_MSG_TRUNCATED 0xc6
7070
#define IPMI_REQ_LEN_INVALID_ERR 0xc7
7171
#define IPMI_REQ_LEN_EXCEEDED_ERR 0xc8
72+
#define IPMI_DEVICE_IN_FW_UPDATE_ERR 0xd1
73+
#define IPMI_DEVICE_IN_INIT_ERR 0xd2
7274
#define IPMI_NOT_IN_MY_STATE_ERR 0xd5 /* IPMI 2.0 */
7375
#define IPMI_LOST_ARBITRATION_ERR 0x81
7476
#define IPMI_BUS_ERR 0x82

0 commit comments

Comments
 (0)