Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/char/ipmi/ipmi_smic_sm.c
26282 views
1
// SPDX-License-Identifier: GPL-2.0+
2
/*
3
* ipmi_smic_sm.c
4
*
5
* The state-machine driver for an IPMI SMIC driver
6
*
7
* It started as a copy of Corey Minyard's driver for the KSC interface
8
* and the kernel patch "mmcdev-patch-245" by HP
9
*
10
* modified by: Hannes Schulz <[email protected]>
11
* [email protected]
12
*
13
*
14
* Corey Minyard's driver for the KSC interface has the following
15
* copyright notice:
16
* Copyright 2002 MontaVista Software Inc.
17
*
18
* the kernel patch "mmcdev-patch-245" by HP has the following
19
* copyright notice:
20
* (c) Copyright 2001 Grant Grundler (c) Copyright
21
* 2001 Hewlett-Packard Company
22
*/
23
24
#define DEBUG /* So dev_dbg() is always available. */
25
26
#include <linux/kernel.h> /* For printk. */
27
#include <linux/string.h>
28
#include <linux/module.h>
29
#include <linux/moduleparam.h>
30
#include <linux/ipmi_msgdefs.h> /* for completion codes */
31
#include "ipmi_si_sm.h"
32
33
/* smic_debug is a bit-field
34
* SMIC_DEBUG_ENABLE - turned on for now
35
* SMIC_DEBUG_MSG - commands and their responses
36
* SMIC_DEBUG_STATES - state machine
37
*/
38
#define SMIC_DEBUG_STATES 4
39
#define SMIC_DEBUG_MSG 2
40
#define SMIC_DEBUG_ENABLE 1
41
42
static int smic_debug = 1;
43
module_param(smic_debug, int, 0644);
44
MODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
45
46
enum smic_states {
47
SMIC_IDLE,
48
SMIC_START_OP,
49
SMIC_OP_OK,
50
SMIC_WRITE_START,
51
SMIC_WRITE_NEXT,
52
SMIC_WRITE_END,
53
SMIC_WRITE2READ,
54
SMIC_READ_START,
55
SMIC_READ_NEXT,
56
SMIC_READ_END,
57
SMIC_HOSED
58
};
59
60
#define MAX_SMIC_READ_SIZE 80
61
#define MAX_SMIC_WRITE_SIZE 80
62
#define SMIC_MAX_ERROR_RETRIES 3
63
64
/* Timeouts in microseconds. */
65
#define SMIC_RETRY_TIMEOUT (2*USEC_PER_SEC)
66
67
/* SMIC Flags Register Bits */
68
#define SMIC_RX_DATA_READY 0x80
69
#define SMIC_TX_DATA_READY 0x40
70
71
/*
72
* SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by
73
* a few systems, and then only by Systems Management
74
* Interrupts, not by the OS. Always ignore these bits.
75
*
76
*/
77
#define SMIC_SMI 0x10
78
#define SMIC_EVM_DATA_AVAIL 0x08
79
#define SMIC_SMS_DATA_AVAIL 0x04
80
#define SMIC_FLAG_BSY 0x01
81
82
/* SMIC Error Codes */
83
#define EC_NO_ERROR 0x00
84
#define EC_ABORTED 0x01
85
#define EC_ILLEGAL_CONTROL 0x02
86
#define EC_NO_RESPONSE 0x03
87
#define EC_ILLEGAL_COMMAND 0x04
88
#define EC_BUFFER_FULL 0x05
89
90
struct si_sm_data {
91
enum smic_states state;
92
struct si_sm_io *io;
93
unsigned char write_data[MAX_SMIC_WRITE_SIZE];
94
int write_pos;
95
int write_count;
96
int orig_write_count;
97
unsigned char read_data[MAX_SMIC_READ_SIZE];
98
int read_pos;
99
int truncated;
100
unsigned int error_retries;
101
long smic_timeout;
102
};
103
104
static unsigned int init_smic_data(struct si_sm_data *smic,
105
struct si_sm_io *io)
106
{
107
smic->state = SMIC_IDLE;
108
smic->io = io;
109
smic->write_pos = 0;
110
smic->write_count = 0;
111
smic->orig_write_count = 0;
112
smic->read_pos = 0;
113
smic->error_retries = 0;
114
smic->truncated = 0;
115
smic->smic_timeout = SMIC_RETRY_TIMEOUT;
116
117
/* We use 3 bytes of I/O. */
118
return 3;
119
}
120
121
static int start_smic_transaction(struct si_sm_data *smic,
122
unsigned char *data, unsigned int size)
123
{
124
unsigned int i;
125
126
if (size < 2)
127
return IPMI_REQ_LEN_INVALID_ERR;
128
if (size > MAX_SMIC_WRITE_SIZE)
129
return IPMI_REQ_LEN_EXCEEDED_ERR;
130
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);
134
return IPMI_NOT_IN_MY_STATE_ERR;
135
}
136
137
if (smic_debug & SMIC_DEBUG_MSG) {
138
dev_dbg(smic->io->dev, "%s -", __func__);
139
for (i = 0; i < size; i++)
140
pr_cont(" %02x", data[i]);
141
pr_cont("\n");
142
}
143
smic->error_retries = 0;
144
memcpy(smic->write_data, data, size);
145
smic->write_count = size;
146
smic->orig_write_count = size;
147
smic->write_pos = 0;
148
smic->read_pos = 0;
149
smic->state = SMIC_START_OP;
150
smic->smic_timeout = SMIC_RETRY_TIMEOUT;
151
return 0;
152
}
153
154
static int smic_get_result(struct si_sm_data *smic,
155
unsigned char *data, unsigned int length)
156
{
157
int i;
158
159
if (smic_debug & SMIC_DEBUG_MSG) {
160
dev_dbg(smic->io->dev, "smic_get result -");
161
for (i = 0; i < smic->read_pos; i++)
162
pr_cont(" %02x", smic->read_data[i]);
163
pr_cont("\n");
164
}
165
if (length < smic->read_pos) {
166
smic->read_pos = length;
167
smic->truncated = 1;
168
}
169
memcpy(data, smic->read_data, smic->read_pos);
170
171
if ((length >= 3) && (smic->read_pos < 3)) {
172
data[2] = IPMI_ERR_UNSPECIFIED;
173
smic->read_pos = 3;
174
}
175
if (smic->truncated) {
176
data[2] = IPMI_ERR_MSG_TRUNCATED;
177
smic->truncated = 0;
178
}
179
return smic->read_pos;
180
}
181
182
static inline unsigned char read_smic_flags(struct si_sm_data *smic)
183
{
184
return smic->io->inputb(smic->io, 2);
185
}
186
187
static inline unsigned char read_smic_status(struct si_sm_data *smic)
188
{
189
return smic->io->inputb(smic->io, 1);
190
}
191
192
static inline unsigned char read_smic_data(struct si_sm_data *smic)
193
{
194
return smic->io->inputb(smic->io, 0);
195
}
196
197
static inline void write_smic_flags(struct si_sm_data *smic,
198
unsigned char flags)
199
{
200
smic->io->outputb(smic->io, 2, flags);
201
}
202
203
static inline void write_smic_control(struct si_sm_data *smic,
204
unsigned char control)
205
{
206
smic->io->outputb(smic->io, 1, control);
207
}
208
209
static inline void write_si_sm_data(struct si_sm_data *smic,
210
unsigned char data)
211
{
212
smic->io->outputb(smic->io, 0, data);
213
}
214
215
static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
216
{
217
(smic->error_retries)++;
218
if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {
219
if (smic_debug & SMIC_DEBUG_ENABLE)
220
pr_warn("ipmi_smic_drv: smic hosed: %s\n", reason);
221
smic->state = SMIC_HOSED;
222
} else {
223
smic->write_count = smic->orig_write_count;
224
smic->write_pos = 0;
225
smic->read_pos = 0;
226
smic->state = SMIC_START_OP;
227
smic->smic_timeout = SMIC_RETRY_TIMEOUT;
228
}
229
}
230
231
static inline void write_next_byte(struct si_sm_data *smic)
232
{
233
write_si_sm_data(smic, smic->write_data[smic->write_pos]);
234
(smic->write_pos)++;
235
(smic->write_count)--;
236
}
237
238
static inline void read_next_byte(struct si_sm_data *smic)
239
{
240
if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
241
read_smic_data(smic);
242
smic->truncated = 1;
243
} else {
244
smic->read_data[smic->read_pos] = read_smic_data(smic);
245
smic->read_pos++;
246
}
247
}
248
249
/* SMIC Control/Status Code Components */
250
#define SMIC_GET_STATUS 0x00 /* Control form's name */
251
#define SMIC_READY 0x00 /* Status form's name */
252
#define SMIC_WR_START 0x01 /* Unified Control/Status names... */
253
#define SMIC_WR_NEXT 0x02
254
#define SMIC_WR_END 0x03
255
#define SMIC_RD_START 0x04
256
#define SMIC_RD_NEXT 0x05
257
#define SMIC_RD_END 0x06
258
#define SMIC_CODE_MASK 0x0f
259
260
#define SMIC_CONTROL 0x00
261
#define SMIC_STATUS 0x80
262
#define SMIC_CS_MASK 0x80
263
264
#define SMIC_SMS 0x40
265
#define SMIC_SMM 0x60
266
#define SMIC_STREAM_MASK 0x60
267
268
/* SMIC Control Codes */
269
#define SMIC_CC_SMS_GET_STATUS (SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)
270
#define SMIC_CC_SMS_WR_START (SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)
271
#define SMIC_CC_SMS_WR_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)
272
#define SMIC_CC_SMS_WR_END (SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)
273
#define SMIC_CC_SMS_RD_START (SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)
274
#define SMIC_CC_SMS_RD_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)
275
#define SMIC_CC_SMS_RD_END (SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)
276
277
#define SMIC_CC_SMM_GET_STATUS (SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)
278
#define SMIC_CC_SMM_WR_START (SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)
279
#define SMIC_CC_SMM_WR_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)
280
#define SMIC_CC_SMM_WR_END (SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)
281
#define SMIC_CC_SMM_RD_START (SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)
282
#define SMIC_CC_SMM_RD_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)
283
#define SMIC_CC_SMM_RD_END (SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)
284
285
/* SMIC Status Codes */
286
#define SMIC_SC_SMS_READY (SMIC_STATUS|SMIC_SMS|SMIC_READY)
287
#define SMIC_SC_SMS_WR_START (SMIC_STATUS|SMIC_SMS|SMIC_WR_START)
288
#define SMIC_SC_SMS_WR_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT)
289
#define SMIC_SC_SMS_WR_END (SMIC_STATUS|SMIC_SMS|SMIC_WR_END)
290
#define SMIC_SC_SMS_RD_START (SMIC_STATUS|SMIC_SMS|SMIC_RD_START)
291
#define SMIC_SC_SMS_RD_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT)
292
#define SMIC_SC_SMS_RD_END (SMIC_STATUS|SMIC_SMS|SMIC_RD_END)
293
294
#define SMIC_SC_SMM_READY (SMIC_STATUS|SMIC_SMM|SMIC_READY)
295
#define SMIC_SC_SMM_WR_START (SMIC_STATUS|SMIC_SMM|SMIC_WR_START)
296
#define SMIC_SC_SMM_WR_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT)
297
#define SMIC_SC_SMM_WR_END (SMIC_STATUS|SMIC_SMM|SMIC_WR_END)
298
#define SMIC_SC_SMM_RD_START (SMIC_STATUS|SMIC_SMM|SMIC_RD_START)
299
#define SMIC_SC_SMM_RD_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT)
300
#define SMIC_SC_SMM_RD_END (SMIC_STATUS|SMIC_SMM|SMIC_RD_END)
301
302
/* these are the control/status codes we actually use
303
SMIC_CC_SMS_GET_STATUS 0x40
304
SMIC_CC_SMS_WR_START 0x41
305
SMIC_CC_SMS_WR_NEXT 0x42
306
SMIC_CC_SMS_WR_END 0x43
307
SMIC_CC_SMS_RD_START 0x44
308
SMIC_CC_SMS_RD_NEXT 0x45
309
SMIC_CC_SMS_RD_END 0x46
310
311
SMIC_SC_SMS_READY 0xC0
312
SMIC_SC_SMS_WR_START 0xC1
313
SMIC_SC_SMS_WR_NEXT 0xC2
314
SMIC_SC_SMS_WR_END 0xC3
315
SMIC_SC_SMS_RD_START 0xC4
316
SMIC_SC_SMS_RD_NEXT 0xC5
317
SMIC_SC_SMS_RD_END 0xC6
318
*/
319
320
static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
321
{
322
unsigned char status;
323
unsigned char flags;
324
unsigned char data;
325
326
if (smic->state == SMIC_HOSED) {
327
init_smic_data(smic, smic->io);
328
return SI_SM_HOSED;
329
}
330
if (smic->state != SMIC_IDLE) {
331
if (smic_debug & SMIC_DEBUG_STATES)
332
dev_dbg(smic->io->dev,
333
"%s - smic->smic_timeout = %ld, time = %ld\n",
334
__func__, smic->smic_timeout, time);
335
/*
336
* FIXME: smic_event is sometimes called with time >
337
* SMIC_RETRY_TIMEOUT
338
*/
339
if (time < SMIC_RETRY_TIMEOUT) {
340
smic->smic_timeout -= time;
341
if (smic->smic_timeout < 0) {
342
start_error_recovery(smic, "smic timed out.");
343
return SI_SM_CALL_WITH_DELAY;
344
}
345
}
346
}
347
flags = read_smic_flags(smic);
348
if (flags & SMIC_FLAG_BSY)
349
return SI_SM_CALL_WITH_DELAY;
350
351
status = read_smic_status(smic);
352
if (smic_debug & SMIC_DEBUG_STATES)
353
dev_dbg(smic->io->dev,
354
"%s - state = %d, flags = 0x%02x, status = 0x%02x\n",
355
__func__, smic->state, flags, status);
356
357
switch (smic->state) {
358
case SMIC_IDLE:
359
/* in IDLE we check for available messages */
360
if (flags & SMIC_SMS_DATA_AVAIL)
361
return SI_SM_ATTN;
362
return SI_SM_IDLE;
363
364
case SMIC_START_OP:
365
/* sanity check whether smic is really idle */
366
write_smic_control(smic, SMIC_CC_SMS_GET_STATUS);
367
write_smic_flags(smic, flags | SMIC_FLAG_BSY);
368
smic->state = SMIC_OP_OK;
369
break;
370
371
case SMIC_OP_OK:
372
if (status != SMIC_SC_SMS_READY) {
373
/* this should not happen */
374
start_error_recovery(smic,
375
"state = SMIC_OP_OK,"
376
" status != SMIC_SC_SMS_READY");
377
return SI_SM_CALL_WITH_DELAY;
378
}
379
/* OK so far; smic is idle let us start ... */
380
write_smic_control(smic, SMIC_CC_SMS_WR_START);
381
write_next_byte(smic);
382
write_smic_flags(smic, flags | SMIC_FLAG_BSY);
383
smic->state = SMIC_WRITE_START;
384
break;
385
386
case SMIC_WRITE_START:
387
if (status != SMIC_SC_SMS_WR_START) {
388
start_error_recovery(smic,
389
"state = SMIC_WRITE_START, "
390
"status != SMIC_SC_SMS_WR_START");
391
return SI_SM_CALL_WITH_DELAY;
392
}
393
/*
394
* we must not issue WR_(NEXT|END) unless
395
* TX_DATA_READY is set
396
* */
397
if (flags & SMIC_TX_DATA_READY) {
398
if (smic->write_count == 1) {
399
/* last byte */
400
write_smic_control(smic, SMIC_CC_SMS_WR_END);
401
smic->state = SMIC_WRITE_END;
402
} else {
403
write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
404
smic->state = SMIC_WRITE_NEXT;
405
}
406
write_next_byte(smic);
407
write_smic_flags(smic, flags | SMIC_FLAG_BSY);
408
} else
409
return SI_SM_CALL_WITH_DELAY;
410
break;
411
412
case SMIC_WRITE_NEXT:
413
if (status != SMIC_SC_SMS_WR_NEXT) {
414
start_error_recovery(smic,
415
"state = SMIC_WRITE_NEXT, "
416
"status != SMIC_SC_SMS_WR_NEXT");
417
return SI_SM_CALL_WITH_DELAY;
418
}
419
/* this is the same code as in SMIC_WRITE_START */
420
if (flags & SMIC_TX_DATA_READY) {
421
if (smic->write_count == 1) {
422
write_smic_control(smic, SMIC_CC_SMS_WR_END);
423
smic->state = SMIC_WRITE_END;
424
} else {
425
write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
426
smic->state = SMIC_WRITE_NEXT;
427
}
428
write_next_byte(smic);
429
write_smic_flags(smic, flags | SMIC_FLAG_BSY);
430
} else
431
return SI_SM_CALL_WITH_DELAY;
432
break;
433
434
case SMIC_WRITE_END:
435
if (status != SMIC_SC_SMS_WR_END) {
436
start_error_recovery(smic,
437
"state = SMIC_WRITE_END, "
438
"status != SMIC_SC_SMS_WR_END");
439
return SI_SM_CALL_WITH_DELAY;
440
}
441
/* data register holds an error code */
442
data = read_smic_data(smic);
443
if (data != 0) {
444
if (smic_debug & SMIC_DEBUG_ENABLE)
445
dev_dbg(smic->io->dev,
446
"SMIC_WRITE_END: data = %02x\n",
447
data);
448
start_error_recovery(smic,
449
"state = SMIC_WRITE_END, "
450
"data != SUCCESS");
451
return SI_SM_CALL_WITH_DELAY;
452
} else
453
smic->state = SMIC_WRITE2READ;
454
break;
455
456
case SMIC_WRITE2READ:
457
/*
458
* we must wait for RX_DATA_READY to be set before we
459
* can continue
460
*/
461
if (flags & SMIC_RX_DATA_READY) {
462
write_smic_control(smic, SMIC_CC_SMS_RD_START);
463
write_smic_flags(smic, flags | SMIC_FLAG_BSY);
464
smic->state = SMIC_READ_START;
465
} else
466
return SI_SM_CALL_WITH_DELAY;
467
break;
468
469
case SMIC_READ_START:
470
if (status != SMIC_SC_SMS_RD_START) {
471
start_error_recovery(smic,
472
"state = SMIC_READ_START, "
473
"status != SMIC_SC_SMS_RD_START");
474
return SI_SM_CALL_WITH_DELAY;
475
}
476
if (flags & SMIC_RX_DATA_READY) {
477
read_next_byte(smic);
478
write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
479
write_smic_flags(smic, flags | SMIC_FLAG_BSY);
480
smic->state = SMIC_READ_NEXT;
481
} else
482
return SI_SM_CALL_WITH_DELAY;
483
break;
484
485
case SMIC_READ_NEXT:
486
switch (status) {
487
/*
488
* smic tells us that this is the last byte to be read
489
* --> clean up
490
*/
491
case SMIC_SC_SMS_RD_END:
492
read_next_byte(smic);
493
write_smic_control(smic, SMIC_CC_SMS_RD_END);
494
write_smic_flags(smic, flags | SMIC_FLAG_BSY);
495
smic->state = SMIC_READ_END;
496
break;
497
case SMIC_SC_SMS_RD_NEXT:
498
if (flags & SMIC_RX_DATA_READY) {
499
read_next_byte(smic);
500
write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
501
write_smic_flags(smic, flags | SMIC_FLAG_BSY);
502
smic->state = SMIC_READ_NEXT;
503
} else
504
return SI_SM_CALL_WITH_DELAY;
505
break;
506
default:
507
start_error_recovery(
508
smic,
509
"state = SMIC_READ_NEXT, "
510
"status != SMIC_SC_SMS_RD_(NEXT|END)");
511
return SI_SM_CALL_WITH_DELAY;
512
}
513
break;
514
515
case SMIC_READ_END:
516
if (status != SMIC_SC_SMS_READY) {
517
start_error_recovery(smic,
518
"state = SMIC_READ_END, "
519
"status != SMIC_SC_SMS_READY");
520
return SI_SM_CALL_WITH_DELAY;
521
}
522
data = read_smic_data(smic);
523
/* data register holds an error code */
524
if (data != 0) {
525
if (smic_debug & SMIC_DEBUG_ENABLE)
526
dev_dbg(smic->io->dev,
527
"SMIC_READ_END: data = %02x\n",
528
data);
529
start_error_recovery(smic,
530
"state = SMIC_READ_END, "
531
"data != SUCCESS");
532
return SI_SM_CALL_WITH_DELAY;
533
} else {
534
smic->state = SMIC_IDLE;
535
return SI_SM_TRANSACTION_COMPLETE;
536
}
537
538
case SMIC_HOSED:
539
init_smic_data(smic, smic->io);
540
return SI_SM_HOSED;
541
542
default:
543
if (smic_debug & SMIC_DEBUG_ENABLE) {
544
dev_dbg(smic->io->dev,
545
"smic->state = %d\n", smic->state);
546
start_error_recovery(smic, "state = UNKNOWN");
547
return SI_SM_CALL_WITH_DELAY;
548
}
549
}
550
smic->smic_timeout = SMIC_RETRY_TIMEOUT;
551
return SI_SM_CALL_WITHOUT_DELAY;
552
}
553
554
static int smic_detect(struct si_sm_data *smic)
555
{
556
/*
557
* It's impossible for the SMIC fnags register to be all 1's,
558
* (assuming a properly functioning, self-initialized BMC)
559
* but that's what you get from reading a bogus address, so we
560
* test that first.
561
*/
562
if (read_smic_flags(smic) == 0xff)
563
return 1;
564
565
return 0;
566
}
567
568
static void smic_cleanup(struct si_sm_data *kcs)
569
{
570
}
571
572
static int smic_size(void)
573
{
574
return sizeof(struct si_sm_data);
575
}
576
577
const struct si_sm_handlers smic_smi_handlers = {
578
.init_data = init_smic_data,
579
.start_transaction = start_smic_transaction,
580
.get_result = smic_get_result,
581
.event = smic_event,
582
.detect = smic_detect,
583
.cleanup = smic_cleanup,
584
.size = smic_size,
585
};
586
587