aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_smic_sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_smic_sm.c')
-rw-r--r--drivers/char/ipmi/ipmi_smic_sm.c149
1 files changed, 71 insertions, 78 deletions
diff --git a/drivers/char/ipmi/ipmi_smic_sm.c b/drivers/char/ipmi/ipmi_smic_sm.c
index e64ea7d25d24..faed92971907 100644
--- a/drivers/char/ipmi/ipmi_smic_sm.c
+++ b/drivers/char/ipmi/ipmi_smic_sm.c
@@ -85,6 +85,7 @@ enum smic_states {
85/* SMIC Flags Register Bits */ 85/* SMIC Flags Register Bits */
86#define SMIC_RX_DATA_READY 0x80 86#define SMIC_RX_DATA_READY 0x80
87#define SMIC_TX_DATA_READY 0x40 87#define SMIC_TX_DATA_READY 0x40
88
88/* 89/*
89 * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by 90 * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by
90 * a few systems, and then only by Systems Management 91 * a few systems, and then only by Systems Management
@@ -104,23 +105,22 @@ enum smic_states {
104#define EC_ILLEGAL_COMMAND 0x04 105#define EC_ILLEGAL_COMMAND 0x04
105#define EC_BUFFER_FULL 0x05 106#define EC_BUFFER_FULL 0x05
106 107
107struct si_sm_data 108struct si_sm_data {
108{
109 enum smic_states state; 109 enum smic_states state;
110 struct si_sm_io *io; 110 struct si_sm_io *io;
111 unsigned char write_data[MAX_SMIC_WRITE_SIZE]; 111 unsigned char write_data[MAX_SMIC_WRITE_SIZE];
112 int write_pos; 112 int write_pos;
113 int write_count; 113 int write_count;
114 int orig_write_count; 114 int orig_write_count;
115 unsigned char read_data[MAX_SMIC_READ_SIZE]; 115 unsigned char read_data[MAX_SMIC_READ_SIZE];
116 int read_pos; 116 int read_pos;
117 int truncated; 117 int truncated;
118 unsigned int error_retries; 118 unsigned int error_retries;
119 long smic_timeout; 119 long smic_timeout;
120}; 120};
121 121
122static unsigned int init_smic_data (struct si_sm_data *smic, 122static unsigned int init_smic_data(struct si_sm_data *smic,
123 struct si_sm_io *io) 123 struct si_sm_io *io)
124{ 124{
125 smic->state = SMIC_IDLE; 125 smic->state = SMIC_IDLE;
126 smic->io = io; 126 smic->io = io;
@@ -150,11 +150,10 @@ static int start_smic_transaction(struct si_sm_data *smic,
150 return IPMI_NOT_IN_MY_STATE_ERR; 150 return IPMI_NOT_IN_MY_STATE_ERR;
151 151
152 if (smic_debug & SMIC_DEBUG_MSG) { 152 if (smic_debug & SMIC_DEBUG_MSG) {
153 printk(KERN_INFO "start_smic_transaction -"); 153 printk(KERN_DEBUG "start_smic_transaction -");
154 for (i = 0; i < size; i ++) { 154 for (i = 0; i < size; i++)
155 printk (" %02x", (unsigned char) (data [i])); 155 printk(" %02x", (unsigned char) data[i]);
156 } 156 printk("\n");
157 printk ("\n");
158 } 157 }
159 smic->error_retries = 0; 158 smic->error_retries = 0;
160 memcpy(smic->write_data, data, size); 159 memcpy(smic->write_data, data, size);
@@ -173,11 +172,10 @@ static int smic_get_result(struct si_sm_data *smic,
173 int i; 172 int i;
174 173
175 if (smic_debug & SMIC_DEBUG_MSG) { 174 if (smic_debug & SMIC_DEBUG_MSG) {
176 printk (KERN_INFO "smic_get result -"); 175 printk(KERN_DEBUG "smic_get result -");
177 for (i = 0; i < smic->read_pos; i ++) { 176 for (i = 0; i < smic->read_pos; i++)
178 printk (" %02x", (smic->read_data [i])); 177 printk(" %02x", smic->read_data[i]);
179 } 178 printk("\n");
180 printk ("\n");
181 } 179 }
182 if (length < smic->read_pos) { 180 if (length < smic->read_pos) {
183 smic->read_pos = length; 181 smic->read_pos = length;
@@ -223,8 +221,8 @@ static inline void write_smic_control(struct si_sm_data *smic,
223 smic->io->outputb(smic->io, 1, control); 221 smic->io->outputb(smic->io, 1, control);
224} 222}
225 223
226static inline void write_si_sm_data (struct si_sm_data *smic, 224static inline void write_si_sm_data(struct si_sm_data *smic,
227 unsigned char data) 225 unsigned char data)
228{ 226{
229 smic->io->outputb(smic->io, 0, data); 227 smic->io->outputb(smic->io, 0, data);
230} 228}
@@ -233,10 +231,9 @@ static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
233{ 231{
234 (smic->error_retries)++; 232 (smic->error_retries)++;
235 if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) { 233 if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {
236 if (smic_debug & SMIC_DEBUG_ENABLE) { 234 if (smic_debug & SMIC_DEBUG_ENABLE)
237 printk(KERN_WARNING 235 printk(KERN_WARNING
238 "ipmi_smic_drv: smic hosed: %s\n", reason); 236 "ipmi_smic_drv: smic hosed: %s\n", reason);
239 }
240 smic->state = SMIC_HOSED; 237 smic->state = SMIC_HOSED;
241 } else { 238 } else {
242 smic->write_count = smic->orig_write_count; 239 smic->write_count = smic->orig_write_count;
@@ -254,14 +251,14 @@ static inline void write_next_byte(struct si_sm_data *smic)
254 (smic->write_count)--; 251 (smic->write_count)--;
255} 252}
256 253
257static inline void read_next_byte (struct si_sm_data *smic) 254static inline void read_next_byte(struct si_sm_data *smic)
258{ 255{
259 if (smic->read_pos >= MAX_SMIC_READ_SIZE) { 256 if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
260 read_smic_data (smic); 257 read_smic_data(smic);
261 smic->truncated = 1; 258 smic->truncated = 1;
262 } else { 259 } else {
263 smic->read_data[smic->read_pos] = read_smic_data(smic); 260 smic->read_data[smic->read_pos] = read_smic_data(smic);
264 (smic->read_pos)++; 261 smic->read_pos++;
265 } 262 }
266} 263}
267 264
@@ -336,7 +333,7 @@ static inline void read_next_byte (struct si_sm_data *smic)
336 SMIC_SC_SMS_RD_END 0xC6 333 SMIC_SC_SMS_RD_END 0xC6
337*/ 334*/
338 335
339static enum si_sm_result smic_event (struct si_sm_data *smic, long time) 336static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
340{ 337{
341 unsigned char status; 338 unsigned char status;
342 unsigned char flags; 339 unsigned char flags;
@@ -347,13 +344,15 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
347 return SI_SM_HOSED; 344 return SI_SM_HOSED;
348 } 345 }
349 if (smic->state != SMIC_IDLE) { 346 if (smic->state != SMIC_IDLE) {
350 if (smic_debug & SMIC_DEBUG_STATES) { 347 if (smic_debug & SMIC_DEBUG_STATES)
351 printk(KERN_INFO 348 printk(KERN_DEBUG
352 "smic_event - smic->smic_timeout = %ld," 349 "smic_event - smic->smic_timeout = %ld,"
353 " time = %ld\n", 350 " time = %ld\n",
354 smic->smic_timeout, time); 351 smic->smic_timeout, time);
355 } 352 /*
356/* FIXME: smic_event is sometimes called with time > SMIC_RETRY_TIMEOUT */ 353 * FIXME: smic_event is sometimes called with time >
354 * SMIC_RETRY_TIMEOUT
355 */
357 if (time < SMIC_RETRY_TIMEOUT) { 356 if (time < SMIC_RETRY_TIMEOUT) {
358 smic->smic_timeout -= time; 357 smic->smic_timeout -= time;
359 if (smic->smic_timeout < 0) { 358 if (smic->smic_timeout < 0) {
@@ -366,9 +365,9 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
366 if (flags & SMIC_FLAG_BSY) 365 if (flags & SMIC_FLAG_BSY)
367 return SI_SM_CALL_WITH_DELAY; 366 return SI_SM_CALL_WITH_DELAY;
368 367
369 status = read_smic_status (smic); 368 status = read_smic_status(smic);
370 if (smic_debug & SMIC_DEBUG_STATES) 369 if (smic_debug & SMIC_DEBUG_STATES)
371 printk(KERN_INFO 370 printk(KERN_DEBUG
372 "smic_event - state = %d, flags = 0x%02x," 371 "smic_event - state = %d, flags = 0x%02x,"
373 " status = 0x%02x\n", 372 " status = 0x%02x\n",
374 smic->state, flags, status); 373 smic->state, flags, status);
@@ -377,9 +376,7 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
377 case SMIC_IDLE: 376 case SMIC_IDLE:
378 /* in IDLE we check for available messages */ 377 /* in IDLE we check for available messages */
379 if (flags & SMIC_SMS_DATA_AVAIL) 378 if (flags & SMIC_SMS_DATA_AVAIL)
380 {
381 return SI_SM_ATTN; 379 return SI_SM_ATTN;
382 }
383 return SI_SM_IDLE; 380 return SI_SM_IDLE;
384 381
385 case SMIC_START_OP: 382 case SMIC_START_OP:
@@ -391,7 +388,7 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
391 388
392 case SMIC_OP_OK: 389 case SMIC_OP_OK:
393 if (status != SMIC_SC_SMS_READY) { 390 if (status != SMIC_SC_SMS_READY) {
394 /* this should not happen */ 391 /* this should not happen */
395 start_error_recovery(smic, 392 start_error_recovery(smic,
396 "state = SMIC_OP_OK," 393 "state = SMIC_OP_OK,"
397 " status != SMIC_SC_SMS_READY"); 394 " status != SMIC_SC_SMS_READY");
@@ -411,8 +408,10 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
411 "status != SMIC_SC_SMS_WR_START"); 408 "status != SMIC_SC_SMS_WR_START");
412 return SI_SM_CALL_WITH_DELAY; 409 return SI_SM_CALL_WITH_DELAY;
413 } 410 }
414 /* we must not issue WR_(NEXT|END) unless 411 /*
415 TX_DATA_READY is set */ 412 * we must not issue WR_(NEXT|END) unless
413 * TX_DATA_READY is set
414 * */
416 if (flags & SMIC_TX_DATA_READY) { 415 if (flags & SMIC_TX_DATA_READY) {
417 if (smic->write_count == 1) { 416 if (smic->write_count == 1) {
418 /* last byte */ 417 /* last byte */
@@ -424,10 +423,8 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
424 } 423 }
425 write_next_byte(smic); 424 write_next_byte(smic);
426 write_smic_flags(smic, flags | SMIC_FLAG_BSY); 425 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
427 } 426 } else
428 else {
429 return SI_SM_CALL_WITH_DELAY; 427 return SI_SM_CALL_WITH_DELAY;
430 }
431 break; 428 break;
432 429
433 case SMIC_WRITE_NEXT: 430 case SMIC_WRITE_NEXT:
@@ -442,52 +439,48 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
442 if (smic->write_count == 1) { 439 if (smic->write_count == 1) {
443 write_smic_control(smic, SMIC_CC_SMS_WR_END); 440 write_smic_control(smic, SMIC_CC_SMS_WR_END);
444 smic->state = SMIC_WRITE_END; 441 smic->state = SMIC_WRITE_END;
445 } 442 } else {
446 else {
447 write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); 443 write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
448 smic->state = SMIC_WRITE_NEXT; 444 smic->state = SMIC_WRITE_NEXT;
449 } 445 }
450 write_next_byte(smic); 446 write_next_byte(smic);
451 write_smic_flags(smic, flags | SMIC_FLAG_BSY); 447 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
452 } 448 } else
453 else {
454 return SI_SM_CALL_WITH_DELAY; 449 return SI_SM_CALL_WITH_DELAY;
455 }
456 break; 450 break;
457 451
458 case SMIC_WRITE_END: 452 case SMIC_WRITE_END:
459 if (status != SMIC_SC_SMS_WR_END) { 453 if (status != SMIC_SC_SMS_WR_END) {
460 start_error_recovery (smic, 454 start_error_recovery(smic,
461 "state = SMIC_WRITE_END, " 455 "state = SMIC_WRITE_END, "
462 "status != SMIC_SC_SMS_WR_END"); 456 "status != SMIC_SC_SMS_WR_END");
463 return SI_SM_CALL_WITH_DELAY; 457 return SI_SM_CALL_WITH_DELAY;
464 } 458 }
465 /* data register holds an error code */ 459 /* data register holds an error code */
466 data = read_smic_data(smic); 460 data = read_smic_data(smic);
467 if (data != 0) { 461 if (data != 0) {
468 if (smic_debug & SMIC_DEBUG_ENABLE) { 462 if (smic_debug & SMIC_DEBUG_ENABLE)
469 printk(KERN_INFO 463 printk(KERN_DEBUG
470 "SMIC_WRITE_END: data = %02x\n", data); 464 "SMIC_WRITE_END: data = %02x\n", data);
471 }
472 start_error_recovery(smic, 465 start_error_recovery(smic,
473 "state = SMIC_WRITE_END, " 466 "state = SMIC_WRITE_END, "
474 "data != SUCCESS"); 467 "data != SUCCESS");
475 return SI_SM_CALL_WITH_DELAY; 468 return SI_SM_CALL_WITH_DELAY;
476 } else { 469 } else
477 smic->state = SMIC_WRITE2READ; 470 smic->state = SMIC_WRITE2READ;
478 }
479 break; 471 break;
480 472
481 case SMIC_WRITE2READ: 473 case SMIC_WRITE2READ:
482 /* we must wait for RX_DATA_READY to be set before we 474 /*
483 can continue */ 475 * we must wait for RX_DATA_READY to be set before we
476 * can continue
477 */
484 if (flags & SMIC_RX_DATA_READY) { 478 if (flags & SMIC_RX_DATA_READY) {
485 write_smic_control(smic, SMIC_CC_SMS_RD_START); 479 write_smic_control(smic, SMIC_CC_SMS_RD_START);
486 write_smic_flags(smic, flags | SMIC_FLAG_BSY); 480 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
487 smic->state = SMIC_READ_START; 481 smic->state = SMIC_READ_START;
488 } else { 482 } else
489 return SI_SM_CALL_WITH_DELAY; 483 return SI_SM_CALL_WITH_DELAY;
490 }
491 break; 484 break;
492 485
493 case SMIC_READ_START: 486 case SMIC_READ_START:
@@ -502,15 +495,16 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
502 write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); 495 write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
503 write_smic_flags(smic, flags | SMIC_FLAG_BSY); 496 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
504 smic->state = SMIC_READ_NEXT; 497 smic->state = SMIC_READ_NEXT;
505 } else { 498 } else
506 return SI_SM_CALL_WITH_DELAY; 499 return SI_SM_CALL_WITH_DELAY;
507 }
508 break; 500 break;
509 501
510 case SMIC_READ_NEXT: 502 case SMIC_READ_NEXT:
511 switch (status) { 503 switch (status) {
512 /* smic tells us that this is the last byte to be read 504 /*
513 --> clean up */ 505 * smic tells us that this is the last byte to be read
506 * --> clean up
507 */
514 case SMIC_SC_SMS_RD_END: 508 case SMIC_SC_SMS_RD_END:
515 read_next_byte(smic); 509 read_next_byte(smic);
516 write_smic_control(smic, SMIC_CC_SMS_RD_END); 510 write_smic_control(smic, SMIC_CC_SMS_RD_END);
@@ -523,9 +517,8 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
523 write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); 517 write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
524 write_smic_flags(smic, flags | SMIC_FLAG_BSY); 518 write_smic_flags(smic, flags | SMIC_FLAG_BSY);
525 smic->state = SMIC_READ_NEXT; 519 smic->state = SMIC_READ_NEXT;
526 } else { 520 } else
527 return SI_SM_CALL_WITH_DELAY; 521 return SI_SM_CALL_WITH_DELAY;
528 }
529 break; 522 break;
530 default: 523 default:
531 start_error_recovery( 524 start_error_recovery(
@@ -546,10 +539,9 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
546 data = read_smic_data(smic); 539 data = read_smic_data(smic);
547 /* data register holds an error code */ 540 /* data register holds an error code */
548 if (data != 0) { 541 if (data != 0) {
549 if (smic_debug & SMIC_DEBUG_ENABLE) { 542 if (smic_debug & SMIC_DEBUG_ENABLE)
550 printk(KERN_INFO 543 printk(KERN_DEBUG
551 "SMIC_READ_END: data = %02x\n", data); 544 "SMIC_READ_END: data = %02x\n", data);
552 }
553 start_error_recovery(smic, 545 start_error_recovery(smic,
554 "state = SMIC_READ_END, " 546 "state = SMIC_READ_END, "
555 "data != SUCCESS"); 547 "data != SUCCESS");
@@ -565,7 +557,7 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
565 557
566 default: 558 default:
567 if (smic_debug & SMIC_DEBUG_ENABLE) { 559 if (smic_debug & SMIC_DEBUG_ENABLE) {
568 printk(KERN_WARNING "smic->state = %d\n", smic->state); 560 printk(KERN_DEBUG "smic->state = %d\n", smic->state);
569 start_error_recovery(smic, "state = UNKNOWN"); 561 start_error_recovery(smic, "state = UNKNOWN");
570 return SI_SM_CALL_WITH_DELAY; 562 return SI_SM_CALL_WITH_DELAY;
571 } 563 }
@@ -576,10 +568,12 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
576 568
577static int smic_detect(struct si_sm_data *smic) 569static int smic_detect(struct si_sm_data *smic)
578{ 570{
579 /* It's impossible for the SMIC fnags register to be all 1's, 571 /*
580 (assuming a properly functioning, self-initialized BMC) 572 * It's impossible for the SMIC fnags register to be all 1's,
581 but that's what you get from reading a bogus address, so we 573 * (assuming a properly functioning, self-initialized BMC)
582 test that first. */ 574 * but that's what you get from reading a bogus address, so we
575 * test that first.
576 */
583 if (read_smic_flags(smic) == 0xff) 577 if (read_smic_flags(smic) == 0xff)
584 return 1; 578 return 1;
585 579
@@ -595,8 +589,7 @@ static int smic_size(void)
595 return sizeof(struct si_sm_data); 589 return sizeof(struct si_sm_data);
596} 590}
597 591
598struct si_sm_handlers smic_smi_handlers = 592struct si_sm_handlers smic_smi_handlers = {
599{
600 .init_data = init_smic_data, 593 .init_data = init_smic_data,
601 .start_transaction = start_smic_transaction, 594 .start_transaction = start_smic_transaction,
602 .get_result = smic_get_result, 595 .get_result = smic_get_result,