aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_bt_sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_bt_sm.c')
-rw-r--r--drivers/char/ipmi/ipmi_bt_sm.c66
1 files changed, 44 insertions, 22 deletions
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index 64c9afa50c13..33862670e285 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -161,7 +161,8 @@ static int bt_start_transaction(struct si_sm_data *bt,
161{ 161{
162 unsigned int i; 162 unsigned int i;
163 163
164 if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH)) return -1; 164 if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH))
165 return -1;
165 166
166 if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED)) 167 if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED))
167 return -2; 168 return -2;
@@ -169,7 +170,8 @@ static int bt_start_transaction(struct si_sm_data *bt,
169 if (bt_debug & BT_DEBUG_MSG) { 170 if (bt_debug & BT_DEBUG_MSG) {
170 printk(KERN_WARNING "+++++++++++++++++++++++++++++++++++++\n"); 171 printk(KERN_WARNING "+++++++++++++++++++++++++++++++++++++\n");
171 printk(KERN_WARNING "BT: write seq=0x%02X:", bt->seq); 172 printk(KERN_WARNING "BT: write seq=0x%02X:", bt->seq);
172 for (i = 0; i < size; i ++) printk (" %02x", data[i]); 173 for (i = 0; i < size; i ++)
174 printk (" %02x", data[i]);
173 printk("\n"); 175 printk("\n");
174 } 176 }
175 bt->write_data[0] = size + 1; /* all data plus seq byte */ 177 bt->write_data[0] = size + 1; /* all data plus seq byte */
@@ -208,15 +210,18 @@ static int bt_get_result(struct si_sm_data *bt,
208 } else { 210 } else {
209 data[0] = bt->read_data[1]; 211 data[0] = bt->read_data[1];
210 data[1] = bt->read_data[3]; 212 data[1] = bt->read_data[3];
211 if (length < msg_len) bt->truncated = 1; 213 if (length < msg_len)
214 bt->truncated = 1;
212 if (bt->truncated) { /* can be set in read_all_bytes() */ 215 if (bt->truncated) { /* can be set in read_all_bytes() */
213 data[2] = IPMI_ERR_MSG_TRUNCATED; 216 data[2] = IPMI_ERR_MSG_TRUNCATED;
214 msg_len = 3; 217 msg_len = 3;
215 } else memcpy(data + 2, bt->read_data + 4, msg_len - 2); 218 } else
219 memcpy(data + 2, bt->read_data + 4, msg_len - 2);
216 220
217 if (bt_debug & BT_DEBUG_MSG) { 221 if (bt_debug & BT_DEBUG_MSG) {
218 printk (KERN_WARNING "BT: res (raw)"); 222 printk (KERN_WARNING "BT: res (raw)");
219 for (i = 0; i < msg_len; i++) printk(" %02x", data[i]); 223 for (i = 0; i < msg_len; i++)
224 printk(" %02x", data[i]);
220 printk ("\n"); 225 printk ("\n");
221 } 226 }
222 } 227 }
@@ -229,8 +234,10 @@ static int bt_get_result(struct si_sm_data *bt,
229 234
230static void reset_flags(struct si_sm_data *bt) 235static void reset_flags(struct si_sm_data *bt)
231{ 236{
232 if (BT_STATUS & BT_H_BUSY) BT_CONTROL(BT_H_BUSY); 237 if (BT_STATUS & BT_H_BUSY)
233 if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY); 238 BT_CONTROL(BT_H_BUSY);
239 if (BT_STATUS & BT_B_BUSY)
240 BT_CONTROL(BT_B_BUSY);
234 BT_CONTROL(BT_CLR_WR_PTR); 241 BT_CONTROL(BT_CLR_WR_PTR);
235 BT_CONTROL(BT_SMS_ATN); 242 BT_CONTROL(BT_SMS_ATN);
236#ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION 243#ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
@@ -239,7 +246,8 @@ static void reset_flags(struct si_sm_data *bt)
239 BT_CONTROL(BT_H_BUSY); 246 BT_CONTROL(BT_H_BUSY);
240 BT_CONTROL(BT_B2H_ATN); 247 BT_CONTROL(BT_B2H_ATN);
241 BT_CONTROL(BT_CLR_RD_PTR); 248 BT_CONTROL(BT_CLR_RD_PTR);
242 for (i = 0; i < IPMI_MAX_MSG_LENGTH + 2; i++) BMC2HOST; 249 for (i = 0; i < IPMI_MAX_MSG_LENGTH + 2; i++)
250 BMC2HOST;
243 BT_CONTROL(BT_H_BUSY); 251 BT_CONTROL(BT_H_BUSY);
244 } 252 }
245#endif 253#endif
@@ -256,7 +264,8 @@ static inline void write_all_bytes(struct si_sm_data *bt)
256 printk (" %02x", bt->write_data[i]); 264 printk (" %02x", bt->write_data[i]);
257 printk ("\n"); 265 printk ("\n");
258 } 266 }
259 for (i = 0; i < bt->write_count; i++) HOST2BMC(bt->write_data[i]); 267 for (i = 0; i < bt->write_count; i++)
268 HOST2BMC(bt->write_data[i]);
260} 269}
261 270
262static inline int read_all_bytes(struct si_sm_data *bt) 271static inline int read_all_bytes(struct si_sm_data *bt)
@@ -276,7 +285,8 @@ static inline int read_all_bytes(struct si_sm_data *bt)
276 bt->truncated = 1; 285 bt->truncated = 1;
277 return 1; /* let next XACTION START clean it up */ 286 return 1; /* let next XACTION START clean it up */
278 } 287 }
279 for (i = 1; i <= bt->read_count; i++) bt->read_data[i] = BMC2HOST; 288 for (i = 1; i <= bt->read_count; i++)
289 bt->read_data[i] = BMC2HOST;
280 bt->read_count++; /* account for the length byte */ 290 bt->read_count++; /* account for the length byte */
281 291
282 if (bt_debug & BT_DEBUG_MSG) { 292 if (bt_debug & BT_DEBUG_MSG) {
@@ -293,7 +303,8 @@ static inline int read_all_bytes(struct si_sm_data *bt)
293 ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8))) 303 ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
294 return 1; 304 return 1;
295 305
296 if (bt_debug & BT_DEBUG_MSG) printk(KERN_WARNING "BT: bad packet: " 306 if (bt_debug & BT_DEBUG_MSG)
307 printk(KERN_WARNING "BT: bad packet: "
297 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n", 308 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
298 bt->write_data[1], bt->write_data[2], bt->write_data[3], 309 bt->write_data[1], bt->write_data[2], bt->write_data[3],
299 bt->read_data[1], bt->read_data[2], bt->read_data[3]); 310 bt->read_data[1], bt->read_data[2], bt->read_data[3]);
@@ -357,7 +368,8 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
357 time); 368 time);
358 bt->last_state = bt->state; 369 bt->last_state = bt->state;
359 370
360 if (bt->state == BT_STATE_HOSED) return SI_SM_HOSED; 371 if (bt->state == BT_STATE_HOSED)
372 return SI_SM_HOSED;
361 373
362 if (bt->state != BT_STATE_IDLE) { /* do timeout test */ 374 if (bt->state != BT_STATE_IDLE) { /* do timeout test */
363 375
@@ -369,7 +381,8 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
369 /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT 381 /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
370 (noticed in ipmi_smic_sm.c January 2004) */ 382 (noticed in ipmi_smic_sm.c January 2004) */
371 383
372 if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT)) time = 100; 384 if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT))
385 time = 100;
373 bt->timeout -= time; 386 bt->timeout -= time;
374 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) { 387 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
375 error_recovery(bt, "timed out"); 388 error_recovery(bt, "timed out");
@@ -391,12 +404,14 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
391 BT_CONTROL(BT_H_BUSY); 404 BT_CONTROL(BT_H_BUSY);
392 break; 405 break;
393 } 406 }
394 if (status & BT_B2H_ATN) break; 407 if (status & BT_B2H_ATN)
408 break;
395 bt->state = BT_STATE_WRITE_BYTES; 409 bt->state = BT_STATE_WRITE_BYTES;
396 return SI_SM_CALL_WITHOUT_DELAY; /* for logging */ 410 return SI_SM_CALL_WITHOUT_DELAY; /* for logging */
397 411
398 case BT_STATE_WRITE_BYTES: 412 case BT_STATE_WRITE_BYTES:
399 if (status & (BT_B_BUSY | BT_H2B_ATN)) break; 413 if (status & (BT_B_BUSY | BT_H2B_ATN))
414 break;
400 BT_CONTROL(BT_CLR_WR_PTR); 415 BT_CONTROL(BT_CLR_WR_PTR);
401 write_all_bytes(bt); 416 write_all_bytes(bt);
402 BT_CONTROL(BT_H2B_ATN); /* clears too fast to catch? */ 417 BT_CONTROL(BT_H2B_ATN); /* clears too fast to catch? */
@@ -404,7 +419,8 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
404 return SI_SM_CALL_WITHOUT_DELAY; /* it MIGHT sail through */ 419 return SI_SM_CALL_WITHOUT_DELAY; /* it MIGHT sail through */
405 420
406 case BT_STATE_WRITE_CONSUME: /* BMCs usually blow right thru here */ 421 case BT_STATE_WRITE_CONSUME: /* BMCs usually blow right thru here */
407 if (status & (BT_H2B_ATN | BT_B_BUSY)) break; 422 if (status & (BT_H2B_ATN | BT_B_BUSY))
423 break;
408 bt->state = BT_STATE_B2H_WAIT; 424 bt->state = BT_STATE_B2H_WAIT;
409 /* fall through with status */ 425 /* fall through with status */
410 426
@@ -413,15 +429,18 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
413 generation of B2H_ATN so ALWAYS return CALL_WITH_DELAY. */ 429 generation of B2H_ATN so ALWAYS return CALL_WITH_DELAY. */
414 430
415 case BT_STATE_B2H_WAIT: 431 case BT_STATE_B2H_WAIT:
416 if (!(status & BT_B2H_ATN)) break; 432 if (!(status & BT_B2H_ATN))
433 break;
417 434
418 /* Assume ordered, uncached writes: no need to wait */ 435 /* Assume ordered, uncached writes: no need to wait */
419 if (!(status & BT_H_BUSY)) BT_CONTROL(BT_H_BUSY); /* set */ 436 if (!(status & BT_H_BUSY))
437 BT_CONTROL(BT_H_BUSY); /* set */
420 BT_CONTROL(BT_B2H_ATN); /* clear it, ACK to the BMC */ 438 BT_CONTROL(BT_B2H_ATN); /* clear it, ACK to the BMC */
421 BT_CONTROL(BT_CLR_RD_PTR); /* reset the queue */ 439 BT_CONTROL(BT_CLR_RD_PTR); /* reset the queue */
422 i = read_all_bytes(bt); 440 i = read_all_bytes(bt);
423 BT_CONTROL(BT_H_BUSY); /* clear */ 441 BT_CONTROL(BT_H_BUSY); /* clear */
424 if (!i) break; /* Try this state again */ 442 if (!i) /* Try this state again */
443 break;
425 bt->state = BT_STATE_READ_END; 444 bt->state = BT_STATE_READ_END;
426 return SI_SM_CALL_WITHOUT_DELAY; /* for logging */ 445 return SI_SM_CALL_WITHOUT_DELAY; /* for logging */
427 446
@@ -434,7 +453,8 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
434 453
435#ifdef MAKE_THIS_TRUE_IF_NECESSARY 454#ifdef MAKE_THIS_TRUE_IF_NECESSARY
436 455
437 if (status & BT_H_BUSY) break; 456 if (status & BT_H_BUSY)
457 break;
438#endif 458#endif
439 bt->seq++; 459 bt->seq++;
440 bt->state = BT_STATE_IDLE; 460 bt->state = BT_STATE_IDLE;
@@ -457,7 +477,8 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
457 break; 477 break;
458 478
459 case BT_STATE_RESET3: 479 case BT_STATE_RESET3:
460 if (bt->timeout > 0) return SI_SM_CALL_WITH_DELAY; 480 if (bt->timeout > 0)
481 return SI_SM_CALL_WITH_DELAY;
461 bt->state = BT_STATE_RESTART; /* printk in debug modes */ 482 bt->state = BT_STATE_RESTART; /* printk in debug modes */
462 break; 483 break;
463 484
@@ -483,7 +504,8 @@ static int bt_detect(struct si_sm_data *bt)
483 but that's what you get from reading a bogus address, so we 504 but that's what you get from reading a bogus address, so we
484 test that first. The calling routine uses negative logic. */ 505 test that first. The calling routine uses negative logic. */
485 506
486 if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF)) return 1; 507 if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
508 return 1;
487 reset_flags(bt); 509 reset_flags(bt);
488 return 0; 510 return 0;
489} 511}