[TG3]: Set minimal hw interrupt mitigation.
[linux-2.6/verdex.git] / drivers / char / ipmi / ipmi_bt_sm.c
blob5ce9c62690334cdf50ada526ec2c2a123b087849
1 /*
2 * ipmi_bt_sm.c
4 * The state machine for an Open IPMI BT sub-driver under ipmi_si.c, part
5 * of the driver architecture at http://sourceforge.net/project/openipmi
7 * Author: Rocky Craig <first.last@hp.com>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
20 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA. */
29 #include <linux/kernel.h> /* For printk. */
30 #include <linux/string.h>
31 #include <linux/ipmi_msgdefs.h> /* for completion codes */
32 #include "ipmi_si_sm.h"
34 #define IPMI_BT_VERSION "v33"
36 static int bt_debug = 0x00; /* Production value 0, see following flags */
38 #define BT_DEBUG_ENABLE 1
39 #define BT_DEBUG_MSG 2
40 #define BT_DEBUG_STATES 4
42 /* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
43 and 64 byte buffers. However, one HP implementation wants 255 bytes of
44 buffer (with a documented message of 160 bytes) so go for the max.
45 Since the Open IPMI architecture is single-message oriented at this
46 stage, the queue depth of BT is of no concern. */
48 #define BT_NORMAL_TIMEOUT 2000000 /* seconds in microseconds */
49 #define BT_RETRY_LIMIT 2
50 #define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */
52 enum bt_states {
53 BT_STATE_IDLE,
54 BT_STATE_XACTION_START,
55 BT_STATE_WRITE_BYTES,
56 BT_STATE_WRITE_END,
57 BT_STATE_WRITE_CONSUME,
58 BT_STATE_B2H_WAIT,
59 BT_STATE_READ_END,
60 BT_STATE_RESET1, /* These must come last */
61 BT_STATE_RESET2,
62 BT_STATE_RESET3,
63 BT_STATE_RESTART,
64 BT_STATE_HOSED
67 struct si_sm_data {
68 enum bt_states state;
69 enum bt_states last_state; /* assist printing and resets */
70 unsigned char seq; /* BT sequence number */
71 struct si_sm_io *io;
72 unsigned char write_data[IPMI_MAX_MSG_LENGTH];
73 int write_count;
74 unsigned char read_data[IPMI_MAX_MSG_LENGTH];
75 int read_count;
76 int truncated;
77 long timeout;
78 unsigned int error_retries; /* end of "common" fields */
79 int nonzero_status; /* hung BMCs stay all 0 */
82 #define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */
83 #define BT_CLR_RD_PTR 0x02
84 #define BT_H2B_ATN 0x04
85 #define BT_B2H_ATN 0x08
86 #define BT_SMS_ATN 0x10
87 #define BT_OEM0 0x20
88 #define BT_H_BUSY 0x40
89 #define BT_B_BUSY 0x80
91 /* Some bits are toggled on each write: write once to set it, once
92 more to clear it; writing a zero does nothing. To absolutely
93 clear it, check its state and write if set. This avoids the "get
94 current then use as mask" scheme to modify one bit. Note that the
95 variable "bt" is hardcoded into these macros. */
97 #define BT_STATUS bt->io->inputb(bt->io, 0)
98 #define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x)
100 #define BMC2HOST bt->io->inputb(bt->io, 1)
101 #define HOST2BMC(x) bt->io->outputb(bt->io, 1, x)
103 #define BT_INTMASK_R bt->io->inputb(bt->io, 2)
104 #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x)
106 /* Convenience routines for debugging. These are not multi-open safe!
107 Note the macros have hardcoded variables in them. */
109 static char *state2txt(unsigned char state)
111 switch (state) {
112 case BT_STATE_IDLE: return("IDLE");
113 case BT_STATE_XACTION_START: return("XACTION");
114 case BT_STATE_WRITE_BYTES: return("WR_BYTES");
115 case BT_STATE_WRITE_END: return("WR_END");
116 case BT_STATE_WRITE_CONSUME: return("WR_CONSUME");
117 case BT_STATE_B2H_WAIT: return("B2H_WAIT");
118 case BT_STATE_READ_END: return("RD_END");
119 case BT_STATE_RESET1: return("RESET1");
120 case BT_STATE_RESET2: return("RESET2");
121 case BT_STATE_RESET3: return("RESET3");
122 case BT_STATE_RESTART: return("RESTART");
123 case BT_STATE_HOSED: return("HOSED");
125 return("BAD STATE");
127 #define STATE2TXT state2txt(bt->state)
129 static char *status2txt(unsigned char status, char *buf)
131 strcpy(buf, "[ ");
132 if (status & BT_B_BUSY) strcat(buf, "B_BUSY ");
133 if (status & BT_H_BUSY) strcat(buf, "H_BUSY ");
134 if (status & BT_OEM0) strcat(buf, "OEM0 ");
135 if (status & BT_SMS_ATN) strcat(buf, "SMS ");
136 if (status & BT_B2H_ATN) strcat(buf, "B2H ");
137 if (status & BT_H2B_ATN) strcat(buf, "H2B ");
138 strcat(buf, "]");
139 return buf;
141 #define STATUS2TXT(buf) status2txt(status, buf)
143 /* This will be called from within this module on a hosed condition */
144 #define FIRST_SEQ 0
145 static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
147 bt->state = BT_STATE_IDLE;
148 bt->last_state = BT_STATE_IDLE;
149 bt->seq = FIRST_SEQ;
150 bt->io = io;
151 bt->write_count = 0;
152 bt->read_count = 0;
153 bt->error_retries = 0;
154 bt->nonzero_status = 0;
155 bt->truncated = 0;
156 bt->timeout = BT_NORMAL_TIMEOUT;
157 return 3; /* We claim 3 bytes of space; ought to check SPMI table */
160 static int bt_start_transaction(struct si_sm_data *bt,
161 unsigned char *data,
162 unsigned int size)
164 unsigned int i;
166 if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH)) return -1;
168 if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED))
169 return -2;
171 if (bt_debug & BT_DEBUG_MSG) {
172 printk(KERN_WARNING "+++++++++++++++++++++++++++++++++++++\n");
173 printk(KERN_WARNING "BT: write seq=0x%02X:", bt->seq);
174 for (i = 0; i < size; i ++) printk (" %02x", data[i]);
175 printk("\n");
177 bt->write_data[0] = size + 1; /* all data plus seq byte */
178 bt->write_data[1] = *data; /* NetFn/LUN */
179 bt->write_data[2] = bt->seq;
180 memcpy(bt->write_data + 3, data + 1, size - 1);
181 bt->write_count = size + 2;
183 bt->error_retries = 0;
184 bt->nonzero_status = 0;
185 bt->read_count = 0;
186 bt->truncated = 0;
187 bt->state = BT_STATE_XACTION_START;
188 bt->last_state = BT_STATE_IDLE;
189 bt->timeout = BT_NORMAL_TIMEOUT;
190 return 0;
193 /* After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE
194 it calls this. Strip out the length and seq bytes. */
196 static int bt_get_result(struct si_sm_data *bt,
197 unsigned char *data,
198 unsigned int length)
200 int i, msg_len;
202 msg_len = bt->read_count - 2; /* account for length & seq */
203 /* Always NetFn, Cmd, cCode */
204 if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
205 printk(KERN_WARNING "BT results: bad msg_len = %d\n", msg_len);
206 data[0] = bt->write_data[1] | 0x4; /* Kludge a response */
207 data[1] = bt->write_data[3];
208 data[2] = IPMI_ERR_UNSPECIFIED;
209 msg_len = 3;
210 } else {
211 data[0] = bt->read_data[1];
212 data[1] = bt->read_data[3];
213 if (length < msg_len) bt->truncated = 1;
214 if (bt->truncated) { /* can be set in read_all_bytes() */
215 data[2] = IPMI_ERR_MSG_TRUNCATED;
216 msg_len = 3;
217 } else memcpy(data + 2, bt->read_data + 4, msg_len - 2);
219 if (bt_debug & BT_DEBUG_MSG) {
220 printk (KERN_WARNING "BT: res (raw)");
221 for (i = 0; i < msg_len; i++) printk(" %02x", data[i]);
222 printk ("\n");
225 bt->read_count = 0; /* paranoia */
226 return msg_len;
229 /* This bit's functionality is optional */
230 #define BT_BMC_HWRST 0x80
232 static void reset_flags(struct si_sm_data *bt)
234 if (BT_STATUS & BT_H_BUSY) BT_CONTROL(BT_H_BUSY);
235 if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY);
236 BT_CONTROL(BT_CLR_WR_PTR);
237 BT_CONTROL(BT_SMS_ATN);
238 #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
239 if (BT_STATUS & BT_B2H_ATN) {
240 int i;
241 BT_CONTROL(BT_H_BUSY);
242 BT_CONTROL(BT_B2H_ATN);
243 BT_CONTROL(BT_CLR_RD_PTR);
244 for (i = 0; i < IPMI_MAX_MSG_LENGTH + 2; i++) BMC2HOST;
245 BT_CONTROL(BT_H_BUSY);
247 #endif
250 static inline void write_all_bytes(struct si_sm_data *bt)
252 int i;
254 if (bt_debug & BT_DEBUG_MSG) {
255 printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
256 bt->write_count, bt->seq);
257 for (i = 0; i < bt->write_count; i++)
258 printk (" %02x", bt->write_data[i]);
259 printk ("\n");
261 for (i = 0; i < bt->write_count; i++) HOST2BMC(bt->write_data[i]);
264 static inline int read_all_bytes(struct si_sm_data *bt)
266 unsigned char i;
268 bt->read_data[0] = BMC2HOST;
269 bt->read_count = bt->read_data[0];
270 if (bt_debug & BT_DEBUG_MSG)
271 printk(KERN_WARNING "BT: read %d bytes:", bt->read_count);
273 /* minimum: length, NetFn, Seq, Cmd, cCode == 5 total, or 4 more
274 following the length byte. */
275 if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) {
276 if (bt_debug & BT_DEBUG_MSG)
277 printk("bad length %d\n", bt->read_count);
278 bt->truncated = 1;
279 return 1; /* let next XACTION START clean it up */
281 for (i = 1; i <= bt->read_count; i++) bt->read_data[i] = BMC2HOST;
282 bt->read_count++; /* account for the length byte */
284 if (bt_debug & BT_DEBUG_MSG) {
285 for (i = 0; i < bt->read_count; i++)
286 printk (" %02x", bt->read_data[i]);
287 printk ("\n");
289 if (bt->seq != bt->write_data[2]) /* idiot check */
290 printk(KERN_WARNING "BT: internal error: sequence mismatch\n");
292 /* per the spec, the (NetFn, Seq, Cmd) tuples should match */
293 if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */
294 (bt->read_data[2] == bt->write_data[2]) && /* Sequence */
295 ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
296 return 1;
298 if (bt_debug & BT_DEBUG_MSG) printk(KERN_WARNING "BT: bad packet: "
299 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
300 bt->write_data[1], bt->write_data[2], bt->write_data[3],
301 bt->read_data[1], bt->read_data[2], bt->read_data[3]);
302 return 0;
305 /* Modifies bt->state appropriately, need to get into the bt_event() switch */
307 static void error_recovery(struct si_sm_data *bt, char *reason)
309 unsigned char status;
310 char buf[40]; /* For getting status */
312 bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
314 status = BT_STATUS;
315 printk(KERN_WARNING "BT: %s in %s %s ", reason, STATE2TXT,
316 STATUS2TXT(buf));
318 (bt->error_retries)++;
319 if (bt->error_retries > BT_RETRY_LIMIT) {
320 printk("retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
321 bt->state = BT_STATE_HOSED;
322 if (!bt->nonzero_status)
323 printk(KERN_ERR "IPMI: BT stuck, try power cycle\n");
324 else if (bt->seq == FIRST_SEQ + BT_RETRY_LIMIT) {
325 /* most likely during insmod */
326 printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
327 bt->state = BT_STATE_RESET1;
329 return;
332 /* Sometimes the BMC queues get in an "off-by-one" state...*/
333 if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) {
334 printk("retry B2H_WAIT\n");
335 return;
338 printk("restart command\n");
339 bt->state = BT_STATE_RESTART;
342 /* Check the status and (possibly) advance the BT state machine. The
343 default return is SI_SM_CALL_WITH_DELAY. */
345 static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
347 unsigned char status;
348 char buf[40]; /* For getting status */
349 int i;
351 status = BT_STATUS;
352 bt->nonzero_status |= status;
354 if ((bt_debug & BT_DEBUG_STATES) && (bt->state != bt->last_state))
355 printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n",
356 STATE2TXT,
357 STATUS2TXT(buf),
358 bt->timeout,
359 time);
360 bt->last_state = bt->state;
362 if (bt->state == BT_STATE_HOSED) return SI_SM_HOSED;
364 if (bt->state != BT_STATE_IDLE) { /* do timeout test */
366 /* Certain states, on error conditions, can lock up a CPU
367 because they are effectively in an infinite loop with
368 CALL_WITHOUT_DELAY (right back here with time == 0).
369 Prevent infinite lockup by ALWAYS decrementing timeout. */
371 /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
372 (noticed in ipmi_smic_sm.c January 2004) */
374 if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT)) time = 100;
375 bt->timeout -= time;
376 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
377 error_recovery(bt, "timed out");
378 return SI_SM_CALL_WITHOUT_DELAY;
382 switch (bt->state) {
384 case BT_STATE_IDLE: /* check for asynchronous messages */
385 if (status & BT_SMS_ATN) {
386 BT_CONTROL(BT_SMS_ATN); /* clear it */
387 return SI_SM_ATTN;
389 return SI_SM_IDLE;
391 case BT_STATE_XACTION_START:
392 if (status & BT_H_BUSY) {
393 BT_CONTROL(BT_H_BUSY);
394 break;
396 if (status & BT_B2H_ATN) break;
397 bt->state = BT_STATE_WRITE_BYTES;
398 return SI_SM_CALL_WITHOUT_DELAY; /* for logging */
400 case BT_STATE_WRITE_BYTES:
401 if (status & (BT_B_BUSY | BT_H2B_ATN)) break;
402 BT_CONTROL(BT_CLR_WR_PTR);
403 write_all_bytes(bt);
404 BT_CONTROL(BT_H2B_ATN); /* clears too fast to catch? */
405 bt->state = BT_STATE_WRITE_CONSUME;
406 return SI_SM_CALL_WITHOUT_DELAY; /* it MIGHT sail through */
408 case BT_STATE_WRITE_CONSUME: /* BMCs usually blow right thru here */
409 if (status & (BT_H2B_ATN | BT_B_BUSY)) break;
410 bt->state = BT_STATE_B2H_WAIT;
411 /* fall through with status */
413 /* Stay in BT_STATE_B2H_WAIT until a packet matches. However, spinning
414 hard here, constantly reading status, seems to hold off the
415 generation of B2H_ATN so ALWAYS return CALL_WITH_DELAY. */
417 case BT_STATE_B2H_WAIT:
418 if (!(status & BT_B2H_ATN)) break;
420 /* Assume ordered, uncached writes: no need to wait */
421 if (!(status & BT_H_BUSY)) BT_CONTROL(BT_H_BUSY); /* set */
422 BT_CONTROL(BT_B2H_ATN); /* clear it, ACK to the BMC */
423 BT_CONTROL(BT_CLR_RD_PTR); /* reset the queue */
424 i = read_all_bytes(bt);
425 BT_CONTROL(BT_H_BUSY); /* clear */
426 if (!i) break; /* Try this state again */
427 bt->state = BT_STATE_READ_END;
428 return SI_SM_CALL_WITHOUT_DELAY; /* for logging */
430 case BT_STATE_READ_END:
432 /* I could wait on BT_H_BUSY to go clear for a truly clean
433 exit. However, this is already done in XACTION_START
434 and the (possible) extra loop/status/possible wait affects
435 performance. So, as long as it works, just ignore H_BUSY */
437 #ifdef MAKE_THIS_TRUE_IF_NECESSARY
439 if (status & BT_H_BUSY) break;
440 #endif
441 bt->seq++;
442 bt->state = BT_STATE_IDLE;
443 return SI_SM_TRANSACTION_COMPLETE;
445 case BT_STATE_RESET1:
446 reset_flags(bt);
447 bt->timeout = BT_RESET_DELAY;
448 bt->state = BT_STATE_RESET2;
449 break;
451 case BT_STATE_RESET2: /* Send a soft reset */
452 BT_CONTROL(BT_CLR_WR_PTR);
453 HOST2BMC(3); /* number of bytes following */
454 HOST2BMC(0x18); /* NetFn/LUN == Application, LUN 0 */
455 HOST2BMC(42); /* Sequence number */
456 HOST2BMC(3); /* Cmd == Soft reset */
457 BT_CONTROL(BT_H2B_ATN);
458 bt->state = BT_STATE_RESET3;
459 break;
461 case BT_STATE_RESET3:
462 if (bt->timeout > 0) return SI_SM_CALL_WITH_DELAY;
463 bt->state = BT_STATE_RESTART; /* printk in debug modes */
464 break;
466 case BT_STATE_RESTART: /* don't reset retries! */
467 bt->write_data[2] = ++bt->seq;
468 bt->read_count = 0;
469 bt->nonzero_status = 0;
470 bt->timeout = BT_NORMAL_TIMEOUT;
471 bt->state = BT_STATE_XACTION_START;
472 break;
474 default: /* HOSED is supposed to be caught much earlier */
475 error_recovery(bt, "internal logic error");
476 break;
478 return SI_SM_CALL_WITH_DELAY;
481 static int bt_detect(struct si_sm_data *bt)
483 /* It's impossible for the BT status and interrupt registers to be
484 all 1's, (assuming a properly functioning, self-initialized BMC)
485 but that's what you get from reading a bogus address, so we
486 test that first. The calling routine uses negative logic. */
488 if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF)) return 1;
489 reset_flags(bt);
490 return 0;
493 static void bt_cleanup(struct si_sm_data *bt)
497 static int bt_size(void)
499 return sizeof(struct si_sm_data);
502 struct si_sm_handlers bt_smi_handlers =
504 .version = IPMI_BT_VERSION,
505 .init_data = bt_init_data,
506 .start_transaction = bt_start_transaction,
507 .get_result = bt_get_result,
508 .event = bt_event,
509 .detect = bt_detect,
510 .cleanup = bt_cleanup,
511 .size = bt_size,