]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/char/ipmi/ipmi_bt_sm.c
Linux-2.6.12-rc2
[mirror_ubuntu-artful-kernel.git] / drivers / char / ipmi / ipmi_bt_sm.c
1 /*
2 * ipmi_bt_sm.c
3 *
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
6 *
7 * Author: Rocky Craig <first.last@hp.com>
8 *
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.
13 *
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.
24 *
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. */
28
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"
33
34 #define IPMI_BT_VERSION "v33"
35
36 static int bt_debug = 0x00; /* Production value 0, see following flags */
37
38 #define BT_DEBUG_ENABLE 1
39 #define BT_DEBUG_MSG 2
40 #define BT_DEBUG_STATES 4
41
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. */
47
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 */
51
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
65 };
66
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 */
80 };
81
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
90
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. */
96
97 #define BT_STATUS bt->io->inputb(bt->io, 0)
98 #define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x)
99
100 #define BMC2HOST bt->io->inputb(bt->io, 1)
101 #define HOST2BMC(x) bt->io->outputb(bt->io, 1, x)
102
103 #define BT_INTMASK_R bt->io->inputb(bt->io, 2)
104 #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x)
105
106 /* Convenience routines for debugging. These are not multi-open safe!
107 Note the macros have hardcoded variables in them. */
108
109 static char *state2txt(unsigned char state)
110 {
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");
124 }
125 return("BAD STATE");
126 }
127 #define STATE2TXT state2txt(bt->state)
128
129 static char *status2txt(unsigned char status, char *buf)
130 {
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;
140 }
141 #define STATUS2TXT(buf) status2txt(status, buf)
142
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)
146 {
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 */
158 }
159
160 static int bt_start_transaction(struct si_sm_data *bt,
161 unsigned char *data,
162 unsigned int size)
163 {
164 unsigned int i;
165
166 if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH)) return -1;
167
168 if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED))
169 return -2;
170
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");
176 }
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;
182
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;
191 }
192
193 /* After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE
194 it calls this. Strip out the length and seq bytes. */
195
196 static int bt_get_result(struct si_sm_data *bt,
197 unsigned char *data,
198 unsigned int length)
199 {
200 int i, msg_len;
201
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);
218
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");
223 }
224 }
225 bt->read_count = 0; /* paranoia */
226 return msg_len;
227 }
228
229 /* This bit's functionality is optional */
230 #define BT_BMC_HWRST 0x80
231
232 static void reset_flags(struct si_sm_data *bt)
233 {
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 BT_INTMASK_W(BT_BMC_HWRST);
239 #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
240 if (BT_STATUS & BT_B2H_ATN) {
241 int i;
242 BT_CONTROL(BT_H_BUSY);
243 BT_CONTROL(BT_B2H_ATN);
244 BT_CONTROL(BT_CLR_RD_PTR);
245 for (i = 0; i < IPMI_MAX_MSG_LENGTH + 2; i++) BMC2HOST;
246 BT_CONTROL(BT_H_BUSY);
247 }
248 #endif
249 }
250
251 static inline void write_all_bytes(struct si_sm_data *bt)
252 {
253 int i;
254
255 if (bt_debug & BT_DEBUG_MSG) {
256 printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
257 bt->write_count, bt->seq);
258 for (i = 0; i < bt->write_count; i++)
259 printk (" %02x", bt->write_data[i]);
260 printk ("\n");
261 }
262 for (i = 0; i < bt->write_count; i++) HOST2BMC(bt->write_data[i]);
263 }
264
265 static inline int read_all_bytes(struct si_sm_data *bt)
266 {
267 unsigned char i;
268
269 bt->read_data[0] = BMC2HOST;
270 bt->read_count = bt->read_data[0];
271 if (bt_debug & BT_DEBUG_MSG)
272 printk(KERN_WARNING "BT: read %d bytes:", bt->read_count);
273
274 /* minimum: length, NetFn, Seq, Cmd, cCode == 5 total, or 4 more
275 following the length byte. */
276 if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) {
277 if (bt_debug & BT_DEBUG_MSG)
278 printk("bad length %d\n", bt->read_count);
279 bt->truncated = 1;
280 return 1; /* let next XACTION START clean it up */
281 }
282 for (i = 1; i <= bt->read_count; i++) bt->read_data[i] = BMC2HOST;
283 bt->read_count++; /* account for the length byte */
284
285 if (bt_debug & BT_DEBUG_MSG) {
286 for (i = 0; i < bt->read_count; i++)
287 printk (" %02x", bt->read_data[i]);
288 printk ("\n");
289 }
290 if (bt->seq != bt->write_data[2]) /* idiot check */
291 printk(KERN_WARNING "BT: internal error: sequence mismatch\n");
292
293 /* per the spec, the (NetFn, Seq, Cmd) tuples should match */
294 if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */
295 (bt->read_data[2] == bt->write_data[2]) && /* Sequence */
296 ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
297 return 1;
298
299 if (bt_debug & BT_DEBUG_MSG) printk(KERN_WARNING "BT: bad packet: "
300 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
301 bt->write_data[1], bt->write_data[2], bt->write_data[3],
302 bt->read_data[1], bt->read_data[2], bt->read_data[3]);
303 return 0;
304 }
305
306 /* Modifies bt->state appropriately, need to get into the bt_event() switch */
307
308 static void error_recovery(struct si_sm_data *bt, char *reason)
309 {
310 unsigned char status;
311 char buf[40]; /* For getting status */
312
313 bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
314
315 status = BT_STATUS;
316 printk(KERN_WARNING "BT: %s in %s %s ", reason, STATE2TXT,
317 STATUS2TXT(buf));
318
319 (bt->error_retries)++;
320 if (bt->error_retries > BT_RETRY_LIMIT) {
321 printk("retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
322 bt->state = BT_STATE_HOSED;
323 if (!bt->nonzero_status)
324 printk(KERN_ERR "IPMI: BT stuck, try power cycle\n");
325 else if (bt->seq == FIRST_SEQ + BT_RETRY_LIMIT) {
326 /* most likely during insmod */
327 printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
328 bt->state = BT_STATE_RESET1;
329 }
330 return;
331 }
332
333 /* Sometimes the BMC queues get in an "off-by-one" state...*/
334 if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) {
335 printk("retry B2H_WAIT\n");
336 return;
337 }
338
339 printk("restart command\n");
340 bt->state = BT_STATE_RESTART;
341 }
342
343 /* Check the status and (possibly) advance the BT state machine. The
344 default return is SI_SM_CALL_WITH_DELAY. */
345
346 static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
347 {
348 unsigned char status;
349 char buf[40]; /* For getting status */
350 int i;
351
352 status = BT_STATUS;
353 bt->nonzero_status |= status;
354
355 if ((bt_debug & BT_DEBUG_STATES) && (bt->state != bt->last_state))
356 printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n",
357 STATE2TXT,
358 STATUS2TXT(buf),
359 bt->timeout,
360 time);
361 bt->last_state = bt->state;
362
363 if (bt->state == BT_STATE_HOSED) return SI_SM_HOSED;
364
365 if (bt->state != BT_STATE_IDLE) { /* do timeout test */
366
367 /* Certain states, on error conditions, can lock up a CPU
368 because they are effectively in an infinite loop with
369 CALL_WITHOUT_DELAY (right back here with time == 0).
370 Prevent infinite lockup by ALWAYS decrementing timeout. */
371
372 /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
373 (noticed in ipmi_smic_sm.c January 2004) */
374
375 if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT)) time = 100;
376 bt->timeout -= time;
377 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
378 error_recovery(bt, "timed out");
379 return SI_SM_CALL_WITHOUT_DELAY;
380 }
381 }
382
383 switch (bt->state) {
384
385 case BT_STATE_IDLE: /* check for asynchronous messages */
386 if (status & BT_SMS_ATN) {
387 BT_CONTROL(BT_SMS_ATN); /* clear it */
388 return SI_SM_ATTN;
389 }
390 return SI_SM_IDLE;
391
392 case BT_STATE_XACTION_START:
393 if (status & BT_H_BUSY) {
394 BT_CONTROL(BT_H_BUSY);
395 break;
396 }
397 if (status & BT_B2H_ATN) break;
398 bt->state = BT_STATE_WRITE_BYTES;
399 return SI_SM_CALL_WITHOUT_DELAY; /* for logging */
400
401 case BT_STATE_WRITE_BYTES:
402 if (status & (BT_B_BUSY | BT_H2B_ATN)) break;
403 BT_CONTROL(BT_CLR_WR_PTR);
404 write_all_bytes(bt);
405 BT_CONTROL(BT_H2B_ATN); /* clears too fast to catch? */
406 bt->state = BT_STATE_WRITE_CONSUME;
407 return SI_SM_CALL_WITHOUT_DELAY; /* it MIGHT sail through */
408
409 case BT_STATE_WRITE_CONSUME: /* BMCs usually blow right thru here */
410 if (status & (BT_H2B_ATN | BT_B_BUSY)) break;
411 bt->state = BT_STATE_B2H_WAIT;
412 /* fall through with status */
413
414 /* Stay in BT_STATE_B2H_WAIT until a packet matches. However, spinning
415 hard here, constantly reading status, seems to hold off the
416 generation of B2H_ATN so ALWAYS return CALL_WITH_DELAY. */
417
418 case BT_STATE_B2H_WAIT:
419 if (!(status & BT_B2H_ATN)) break;
420
421 /* Assume ordered, uncached writes: no need to wait */
422 if (!(status & BT_H_BUSY)) BT_CONTROL(BT_H_BUSY); /* set */
423 BT_CONTROL(BT_B2H_ATN); /* clear it, ACK to the BMC */
424 BT_CONTROL(BT_CLR_RD_PTR); /* reset the queue */
425 i = read_all_bytes(bt);
426 BT_CONTROL(BT_H_BUSY); /* clear */
427 if (!i) break; /* Try this state again */
428 bt->state = BT_STATE_READ_END;
429 return SI_SM_CALL_WITHOUT_DELAY; /* for logging */
430
431 case BT_STATE_READ_END:
432
433 /* I could wait on BT_H_BUSY to go clear for a truly clean
434 exit. However, this is already done in XACTION_START
435 and the (possible) extra loop/status/possible wait affects
436 performance. So, as long as it works, just ignore H_BUSY */
437
438 #ifdef MAKE_THIS_TRUE_IF_NECESSARY
439
440 if (status & BT_H_BUSY) break;
441 #endif
442 bt->seq++;
443 bt->state = BT_STATE_IDLE;
444 return SI_SM_TRANSACTION_COMPLETE;
445
446 case BT_STATE_RESET1:
447 reset_flags(bt);
448 bt->timeout = BT_RESET_DELAY;
449 bt->state = BT_STATE_RESET2;
450 break;
451
452 case BT_STATE_RESET2: /* Send a soft reset */
453 BT_CONTROL(BT_CLR_WR_PTR);
454 HOST2BMC(3); /* number of bytes following */
455 HOST2BMC(0x18); /* NetFn/LUN == Application, LUN 0 */
456 HOST2BMC(42); /* Sequence number */
457 HOST2BMC(3); /* Cmd == Soft reset */
458 BT_CONTROL(BT_H2B_ATN);
459 bt->state = BT_STATE_RESET3;
460 break;
461
462 case BT_STATE_RESET3:
463 if (bt->timeout > 0) return SI_SM_CALL_WITH_DELAY;
464 bt->state = BT_STATE_RESTART; /* printk in debug modes */
465 break;
466
467 case BT_STATE_RESTART: /* don't reset retries! */
468 bt->write_data[2] = ++bt->seq;
469 bt->read_count = 0;
470 bt->nonzero_status = 0;
471 bt->timeout = BT_NORMAL_TIMEOUT;
472 bt->state = BT_STATE_XACTION_START;
473 break;
474
475 default: /* HOSED is supposed to be caught much earlier */
476 error_recovery(bt, "internal logic error");
477 break;
478 }
479 return SI_SM_CALL_WITH_DELAY;
480 }
481
482 static int bt_detect(struct si_sm_data *bt)
483 {
484 /* It's impossible for the BT status and interrupt registers to be
485 all 1's, (assuming a properly functioning, self-initialized BMC)
486 but that's what you get from reading a bogus address, so we
487 test that first. The calling routine uses negative logic. */
488
489 if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF)) return 1;
490 reset_flags(bt);
491 return 0;
492 }
493
494 static void bt_cleanup(struct si_sm_data *bt)
495 {
496 }
497
498 static int bt_size(void)
499 {
500 return sizeof(struct si_sm_data);
501 }
502
503 struct si_sm_handlers bt_smi_handlers =
504 {
505 .version = IPMI_BT_VERSION,
506 .init_data = bt_init_data,
507 .start_transaction = bt_start_transaction,
508 .get_result = bt_get_result,
509 .event = bt_event,
510 .detect = bt_detect,
511 .cleanup = bt_cleanup,
512 .size = bt_size,
513 };