0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #define DEBUG
0025
0026 #include <linux/kernel.h> /* For printk. */
0027 #include <linux/string.h>
0028 #include <linux/module.h>
0029 #include <linux/moduleparam.h>
0030 #include <linux/ipmi_msgdefs.h> /* for completion codes */
0031 #include "ipmi_si_sm.h"
0032
0033
0034
0035
0036
0037
0038 #define SMIC_DEBUG_STATES 4
0039 #define SMIC_DEBUG_MSG 2
0040 #define SMIC_DEBUG_ENABLE 1
0041
0042 static int smic_debug = 1;
0043 module_param(smic_debug, int, 0644);
0044 MODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
0045
0046 enum smic_states {
0047 SMIC_IDLE,
0048 SMIC_START_OP,
0049 SMIC_OP_OK,
0050 SMIC_WRITE_START,
0051 SMIC_WRITE_NEXT,
0052 SMIC_WRITE_END,
0053 SMIC_WRITE2READ,
0054 SMIC_READ_START,
0055 SMIC_READ_NEXT,
0056 SMIC_READ_END,
0057 SMIC_HOSED
0058 };
0059
0060 #define MAX_SMIC_READ_SIZE 80
0061 #define MAX_SMIC_WRITE_SIZE 80
0062 #define SMIC_MAX_ERROR_RETRIES 3
0063
0064
0065 #define SMIC_RETRY_TIMEOUT (2*USEC_PER_SEC)
0066
0067
0068 #define SMIC_RX_DATA_READY 0x80
0069 #define SMIC_TX_DATA_READY 0x40
0070
0071
0072
0073
0074
0075
0076
0077 #define SMIC_SMI 0x10
0078 #define SMIC_EVM_DATA_AVAIL 0x08
0079 #define SMIC_SMS_DATA_AVAIL 0x04
0080 #define SMIC_FLAG_BSY 0x01
0081
0082
0083 #define EC_NO_ERROR 0x00
0084 #define EC_ABORTED 0x01
0085 #define EC_ILLEGAL_CONTROL 0x02
0086 #define EC_NO_RESPONSE 0x03
0087 #define EC_ILLEGAL_COMMAND 0x04
0088 #define EC_BUFFER_FULL 0x05
0089
0090 struct si_sm_data {
0091 enum smic_states state;
0092 struct si_sm_io *io;
0093 unsigned char write_data[MAX_SMIC_WRITE_SIZE];
0094 int write_pos;
0095 int write_count;
0096 int orig_write_count;
0097 unsigned char read_data[MAX_SMIC_READ_SIZE];
0098 int read_pos;
0099 int truncated;
0100 unsigned int error_retries;
0101 long smic_timeout;
0102 };
0103
0104 static unsigned int init_smic_data(struct si_sm_data *smic,
0105 struct si_sm_io *io)
0106 {
0107 smic->state = SMIC_IDLE;
0108 smic->io = io;
0109 smic->write_pos = 0;
0110 smic->write_count = 0;
0111 smic->orig_write_count = 0;
0112 smic->read_pos = 0;
0113 smic->error_retries = 0;
0114 smic->truncated = 0;
0115 smic->smic_timeout = SMIC_RETRY_TIMEOUT;
0116
0117
0118 return 3;
0119 }
0120
0121 static int start_smic_transaction(struct si_sm_data *smic,
0122 unsigned char *data, unsigned int size)
0123 {
0124 unsigned int i;
0125
0126 if (size < 2)
0127 return IPMI_REQ_LEN_INVALID_ERR;
0128 if (size > MAX_SMIC_WRITE_SIZE)
0129 return IPMI_REQ_LEN_EXCEEDED_ERR;
0130
0131 if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {
0132 dev_warn(smic->io->dev,
0133 "SMIC in invalid state %d\n", smic->state);
0134 return IPMI_NOT_IN_MY_STATE_ERR;
0135 }
0136
0137 if (smic_debug & SMIC_DEBUG_MSG) {
0138 dev_dbg(smic->io->dev, "%s -", __func__);
0139 for (i = 0; i < size; i++)
0140 pr_cont(" %02x", data[i]);
0141 pr_cont("\n");
0142 }
0143 smic->error_retries = 0;
0144 memcpy(smic->write_data, data, size);
0145 smic->write_count = size;
0146 smic->orig_write_count = size;
0147 smic->write_pos = 0;
0148 smic->read_pos = 0;
0149 smic->state = SMIC_START_OP;
0150 smic->smic_timeout = SMIC_RETRY_TIMEOUT;
0151 return 0;
0152 }
0153
0154 static int smic_get_result(struct si_sm_data *smic,
0155 unsigned char *data, unsigned int length)
0156 {
0157 int i;
0158
0159 if (smic_debug & SMIC_DEBUG_MSG) {
0160 dev_dbg(smic->io->dev, "smic_get result -");
0161 for (i = 0; i < smic->read_pos; i++)
0162 pr_cont(" %02x", smic->read_data[i]);
0163 pr_cont("\n");
0164 }
0165 if (length < smic->read_pos) {
0166 smic->read_pos = length;
0167 smic->truncated = 1;
0168 }
0169 memcpy(data, smic->read_data, smic->read_pos);
0170
0171 if ((length >= 3) && (smic->read_pos < 3)) {
0172 data[2] = IPMI_ERR_UNSPECIFIED;
0173 smic->read_pos = 3;
0174 }
0175 if (smic->truncated) {
0176 data[2] = IPMI_ERR_MSG_TRUNCATED;
0177 smic->truncated = 0;
0178 }
0179 return smic->read_pos;
0180 }
0181
0182 static inline unsigned char read_smic_flags(struct si_sm_data *smic)
0183 {
0184 return smic->io->inputb(smic->io, 2);
0185 }
0186
0187 static inline unsigned char read_smic_status(struct si_sm_data *smic)
0188 {
0189 return smic->io->inputb(smic->io, 1);
0190 }
0191
0192 static inline unsigned char read_smic_data(struct si_sm_data *smic)
0193 {
0194 return smic->io->inputb(smic->io, 0);
0195 }
0196
0197 static inline void write_smic_flags(struct si_sm_data *smic,
0198 unsigned char flags)
0199 {
0200 smic->io->outputb(smic->io, 2, flags);
0201 }
0202
0203 static inline void write_smic_control(struct si_sm_data *smic,
0204 unsigned char control)
0205 {
0206 smic->io->outputb(smic->io, 1, control);
0207 }
0208
0209 static inline void write_si_sm_data(struct si_sm_data *smic,
0210 unsigned char data)
0211 {
0212 smic->io->outputb(smic->io, 0, data);
0213 }
0214
0215 static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
0216 {
0217 (smic->error_retries)++;
0218 if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {
0219 if (smic_debug & SMIC_DEBUG_ENABLE)
0220 pr_warn("ipmi_smic_drv: smic hosed: %s\n", reason);
0221 smic->state = SMIC_HOSED;
0222 } else {
0223 smic->write_count = smic->orig_write_count;
0224 smic->write_pos = 0;
0225 smic->read_pos = 0;
0226 smic->state = SMIC_START_OP;
0227 smic->smic_timeout = SMIC_RETRY_TIMEOUT;
0228 }
0229 }
0230
0231 static inline void write_next_byte(struct si_sm_data *smic)
0232 {
0233 write_si_sm_data(smic, smic->write_data[smic->write_pos]);
0234 (smic->write_pos)++;
0235 (smic->write_count)--;
0236 }
0237
0238 static inline void read_next_byte(struct si_sm_data *smic)
0239 {
0240 if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
0241 read_smic_data(smic);
0242 smic->truncated = 1;
0243 } else {
0244 smic->read_data[smic->read_pos] = read_smic_data(smic);
0245 smic->read_pos++;
0246 }
0247 }
0248
0249
0250 #define SMIC_GET_STATUS 0x00
0251 #define SMIC_READY 0x00
0252 #define SMIC_WR_START 0x01
0253 #define SMIC_WR_NEXT 0x02
0254 #define SMIC_WR_END 0x03
0255 #define SMIC_RD_START 0x04
0256 #define SMIC_RD_NEXT 0x05
0257 #define SMIC_RD_END 0x06
0258 #define SMIC_CODE_MASK 0x0f
0259
0260 #define SMIC_CONTROL 0x00
0261 #define SMIC_STATUS 0x80
0262 #define SMIC_CS_MASK 0x80
0263
0264 #define SMIC_SMS 0x40
0265 #define SMIC_SMM 0x60
0266 #define SMIC_STREAM_MASK 0x60
0267
0268
0269 #define SMIC_CC_SMS_GET_STATUS (SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)
0270 #define SMIC_CC_SMS_WR_START (SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)
0271 #define SMIC_CC_SMS_WR_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)
0272 #define SMIC_CC_SMS_WR_END (SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)
0273 #define SMIC_CC_SMS_RD_START (SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)
0274 #define SMIC_CC_SMS_RD_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)
0275 #define SMIC_CC_SMS_RD_END (SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)
0276
0277 #define SMIC_CC_SMM_GET_STATUS (SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)
0278 #define SMIC_CC_SMM_WR_START (SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)
0279 #define SMIC_CC_SMM_WR_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)
0280 #define SMIC_CC_SMM_WR_END (SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)
0281 #define SMIC_CC_SMM_RD_START (SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)
0282 #define SMIC_CC_SMM_RD_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)
0283 #define SMIC_CC_SMM_RD_END (SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)
0284
0285
0286 #define SMIC_SC_SMS_READY (SMIC_STATUS|SMIC_SMS|SMIC_READY)
0287 #define SMIC_SC_SMS_WR_START (SMIC_STATUS|SMIC_SMS|SMIC_WR_START)
0288 #define SMIC_SC_SMS_WR_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT)
0289 #define SMIC_SC_SMS_WR_END (SMIC_STATUS|SMIC_SMS|SMIC_WR_END)
0290 #define SMIC_SC_SMS_RD_START (SMIC_STATUS|SMIC_SMS|SMIC_RD_START)
0291 #define SMIC_SC_SMS_RD_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT)
0292 #define SMIC_SC_SMS_RD_END (SMIC_STATUS|SMIC_SMS|SMIC_RD_END)
0293
0294 #define SMIC_SC_SMM_READY (SMIC_STATUS|SMIC_SMM|SMIC_READY)
0295 #define SMIC_SC_SMM_WR_START (SMIC_STATUS|SMIC_SMM|SMIC_WR_START)
0296 #define SMIC_SC_SMM_WR_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT)
0297 #define SMIC_SC_SMM_WR_END (SMIC_STATUS|SMIC_SMM|SMIC_WR_END)
0298 #define SMIC_SC_SMM_RD_START (SMIC_STATUS|SMIC_SMM|SMIC_RD_START)
0299 #define SMIC_SC_SMM_RD_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT)
0300 #define SMIC_SC_SMM_RD_END (SMIC_STATUS|SMIC_SMM|SMIC_RD_END)
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320 static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
0321 {
0322 unsigned char status;
0323 unsigned char flags;
0324 unsigned char data;
0325
0326 if (smic->state == SMIC_HOSED) {
0327 init_smic_data(smic, smic->io);
0328 return SI_SM_HOSED;
0329 }
0330 if (smic->state != SMIC_IDLE) {
0331 if (smic_debug & SMIC_DEBUG_STATES)
0332 dev_dbg(smic->io->dev,
0333 "%s - smic->smic_timeout = %ld, time = %ld\n",
0334 __func__, smic->smic_timeout, time);
0335
0336
0337
0338
0339 if (time < SMIC_RETRY_TIMEOUT) {
0340 smic->smic_timeout -= time;
0341 if (smic->smic_timeout < 0) {
0342 start_error_recovery(smic, "smic timed out.");
0343 return SI_SM_CALL_WITH_DELAY;
0344 }
0345 }
0346 }
0347 flags = read_smic_flags(smic);
0348 if (flags & SMIC_FLAG_BSY)
0349 return SI_SM_CALL_WITH_DELAY;
0350
0351 status = read_smic_status(smic);
0352 if (smic_debug & SMIC_DEBUG_STATES)
0353 dev_dbg(smic->io->dev,
0354 "%s - state = %d, flags = 0x%02x, status = 0x%02x\n",
0355 __func__, smic->state, flags, status);
0356
0357 switch (smic->state) {
0358 case SMIC_IDLE:
0359
0360 if (flags & SMIC_SMS_DATA_AVAIL)
0361 return SI_SM_ATTN;
0362 return SI_SM_IDLE;
0363
0364 case SMIC_START_OP:
0365
0366 write_smic_control(smic, SMIC_CC_SMS_GET_STATUS);
0367 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
0368 smic->state = SMIC_OP_OK;
0369 break;
0370
0371 case SMIC_OP_OK:
0372 if (status != SMIC_SC_SMS_READY) {
0373
0374 start_error_recovery(smic,
0375 "state = SMIC_OP_OK,"
0376 " status != SMIC_SC_SMS_READY");
0377 return SI_SM_CALL_WITH_DELAY;
0378 }
0379
0380 write_smic_control(smic, SMIC_CC_SMS_WR_START);
0381 write_next_byte(smic);
0382 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
0383 smic->state = SMIC_WRITE_START;
0384 break;
0385
0386 case SMIC_WRITE_START:
0387 if (status != SMIC_SC_SMS_WR_START) {
0388 start_error_recovery(smic,
0389 "state = SMIC_WRITE_START, "
0390 "status != SMIC_SC_SMS_WR_START");
0391 return SI_SM_CALL_WITH_DELAY;
0392 }
0393
0394
0395
0396
0397 if (flags & SMIC_TX_DATA_READY) {
0398 if (smic->write_count == 1) {
0399
0400 write_smic_control(smic, SMIC_CC_SMS_WR_END);
0401 smic->state = SMIC_WRITE_END;
0402 } else {
0403 write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
0404 smic->state = SMIC_WRITE_NEXT;
0405 }
0406 write_next_byte(smic);
0407 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
0408 } else
0409 return SI_SM_CALL_WITH_DELAY;
0410 break;
0411
0412 case SMIC_WRITE_NEXT:
0413 if (status != SMIC_SC_SMS_WR_NEXT) {
0414 start_error_recovery(smic,
0415 "state = SMIC_WRITE_NEXT, "
0416 "status != SMIC_SC_SMS_WR_NEXT");
0417 return SI_SM_CALL_WITH_DELAY;
0418 }
0419
0420 if (flags & SMIC_TX_DATA_READY) {
0421 if (smic->write_count == 1) {
0422 write_smic_control(smic, SMIC_CC_SMS_WR_END);
0423 smic->state = SMIC_WRITE_END;
0424 } else {
0425 write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
0426 smic->state = SMIC_WRITE_NEXT;
0427 }
0428 write_next_byte(smic);
0429 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
0430 } else
0431 return SI_SM_CALL_WITH_DELAY;
0432 break;
0433
0434 case SMIC_WRITE_END:
0435 if (status != SMIC_SC_SMS_WR_END) {
0436 start_error_recovery(smic,
0437 "state = SMIC_WRITE_END, "
0438 "status != SMIC_SC_SMS_WR_END");
0439 return SI_SM_CALL_WITH_DELAY;
0440 }
0441
0442 data = read_smic_data(smic);
0443 if (data != 0) {
0444 if (smic_debug & SMIC_DEBUG_ENABLE)
0445 dev_dbg(smic->io->dev,
0446 "SMIC_WRITE_END: data = %02x\n",
0447 data);
0448 start_error_recovery(smic,
0449 "state = SMIC_WRITE_END, "
0450 "data != SUCCESS");
0451 return SI_SM_CALL_WITH_DELAY;
0452 } else
0453 smic->state = SMIC_WRITE2READ;
0454 break;
0455
0456 case SMIC_WRITE2READ:
0457
0458
0459
0460
0461 if (flags & SMIC_RX_DATA_READY) {
0462 write_smic_control(smic, SMIC_CC_SMS_RD_START);
0463 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
0464 smic->state = SMIC_READ_START;
0465 } else
0466 return SI_SM_CALL_WITH_DELAY;
0467 break;
0468
0469 case SMIC_READ_START:
0470 if (status != SMIC_SC_SMS_RD_START) {
0471 start_error_recovery(smic,
0472 "state = SMIC_READ_START, "
0473 "status != SMIC_SC_SMS_RD_START");
0474 return SI_SM_CALL_WITH_DELAY;
0475 }
0476 if (flags & SMIC_RX_DATA_READY) {
0477 read_next_byte(smic);
0478 write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
0479 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
0480 smic->state = SMIC_READ_NEXT;
0481 } else
0482 return SI_SM_CALL_WITH_DELAY;
0483 break;
0484
0485 case SMIC_READ_NEXT:
0486 switch (status) {
0487
0488
0489
0490
0491 case SMIC_SC_SMS_RD_END:
0492 read_next_byte(smic);
0493 write_smic_control(smic, SMIC_CC_SMS_RD_END);
0494 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
0495 smic->state = SMIC_READ_END;
0496 break;
0497 case SMIC_SC_SMS_RD_NEXT:
0498 if (flags & SMIC_RX_DATA_READY) {
0499 read_next_byte(smic);
0500 write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
0501 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
0502 smic->state = SMIC_READ_NEXT;
0503 } else
0504 return SI_SM_CALL_WITH_DELAY;
0505 break;
0506 default:
0507 start_error_recovery(
0508 smic,
0509 "state = SMIC_READ_NEXT, "
0510 "status != SMIC_SC_SMS_RD_(NEXT|END)");
0511 return SI_SM_CALL_WITH_DELAY;
0512 }
0513 break;
0514
0515 case SMIC_READ_END:
0516 if (status != SMIC_SC_SMS_READY) {
0517 start_error_recovery(smic,
0518 "state = SMIC_READ_END, "
0519 "status != SMIC_SC_SMS_READY");
0520 return SI_SM_CALL_WITH_DELAY;
0521 }
0522 data = read_smic_data(smic);
0523
0524 if (data != 0) {
0525 if (smic_debug & SMIC_DEBUG_ENABLE)
0526 dev_dbg(smic->io->dev,
0527 "SMIC_READ_END: data = %02x\n",
0528 data);
0529 start_error_recovery(smic,
0530 "state = SMIC_READ_END, "
0531 "data != SUCCESS");
0532 return SI_SM_CALL_WITH_DELAY;
0533 } else {
0534 smic->state = SMIC_IDLE;
0535 return SI_SM_TRANSACTION_COMPLETE;
0536 }
0537
0538 case SMIC_HOSED:
0539 init_smic_data(smic, smic->io);
0540 return SI_SM_HOSED;
0541
0542 default:
0543 if (smic_debug & SMIC_DEBUG_ENABLE) {
0544 dev_dbg(smic->io->dev,
0545 "smic->state = %d\n", smic->state);
0546 start_error_recovery(smic, "state = UNKNOWN");
0547 return SI_SM_CALL_WITH_DELAY;
0548 }
0549 }
0550 smic->smic_timeout = SMIC_RETRY_TIMEOUT;
0551 return SI_SM_CALL_WITHOUT_DELAY;
0552 }
0553
0554 static int smic_detect(struct si_sm_data *smic)
0555 {
0556
0557
0558
0559
0560
0561
0562 if (read_smic_flags(smic) == 0xff)
0563 return 1;
0564
0565 return 0;
0566 }
0567
0568 static void smic_cleanup(struct si_sm_data *kcs)
0569 {
0570 }
0571
0572 static int smic_size(void)
0573 {
0574 return sizeof(struct si_sm_data);
0575 }
0576
0577 const struct si_sm_handlers smic_smi_handlers = {
0578 .init_data = init_smic_data,
0579 .start_transaction = start_smic_transaction,
0580 .get_result = smic_get_result,
0581 .event = smic_event,
0582 .detect = smic_detect,
0583 .cleanup = smic_cleanup,
0584 .size = smic_size,
0585 };