Merge /spare/repo/linux-2.6/
[linux-2.6] / 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 static int bt_debug = 0x00;     /* Production value 0, see following flags */
35
36 #define BT_DEBUG_ENABLE 1
37 #define BT_DEBUG_MSG    2
38 #define BT_DEBUG_STATES 4
39
40 /* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
41    and 64 byte buffers.  However, one HP implementation wants 255 bytes of
42    buffer (with a documented message of 160 bytes) so go for the max.
43    Since the Open IPMI architecture is single-message oriented at this
44    stage, the queue depth of BT is of no concern. */
45
46 #define BT_NORMAL_TIMEOUT       2000000 /* seconds in microseconds */
47 #define BT_RETRY_LIMIT          2
48 #define BT_RESET_DELAY          6000000 /* 6 seconds after warm reset */
49
50 enum bt_states {
51         BT_STATE_IDLE,
52         BT_STATE_XACTION_START,
53         BT_STATE_WRITE_BYTES,
54         BT_STATE_WRITE_END,
55         BT_STATE_WRITE_CONSUME,
56         BT_STATE_B2H_WAIT,
57         BT_STATE_READ_END,
58         BT_STATE_RESET1,                /* These must come last */
59         BT_STATE_RESET2,
60         BT_STATE_RESET3,
61         BT_STATE_RESTART,
62         BT_STATE_HOSED
63 };
64
65 struct si_sm_data {
66         enum bt_states  state;
67         enum bt_states  last_state;     /* assist printing and resets */
68         unsigned char   seq;            /* BT sequence number */
69         struct si_sm_io *io;
70         unsigned char   write_data[IPMI_MAX_MSG_LENGTH];
71         int             write_count;
72         unsigned char   read_data[IPMI_MAX_MSG_LENGTH];
73         int             read_count;
74         int             truncated;
75         long            timeout;
76         unsigned int    error_retries;  /* end of "common" fields */
77         int             nonzero_status; /* hung BMCs stay all 0 */
78 };
79
80 #define BT_CLR_WR_PTR   0x01    /* See IPMI 1.5 table 11.6.4 */
81 #define BT_CLR_RD_PTR   0x02
82 #define BT_H2B_ATN      0x04
83 #define BT_B2H_ATN      0x08
84 #define BT_SMS_ATN      0x10
85 #define BT_OEM0         0x20
86 #define BT_H_BUSY       0x40
87 #define BT_B_BUSY       0x80
88
89 /* Some bits are toggled on each write: write once to set it, once
90    more to clear it; writing a zero does nothing.  To absolutely
91    clear it, check its state and write if set.  This avoids the "get
92    current then use as mask" scheme to modify one bit.  Note that the
93    variable "bt" is hardcoded into these macros. */
94
95 #define BT_STATUS       bt->io->inputb(bt->io, 0)
96 #define BT_CONTROL(x)   bt->io->outputb(bt->io, 0, x)
97
98 #define BMC2HOST        bt->io->inputb(bt->io, 1)
99 #define HOST2BMC(x)     bt->io->outputb(bt->io, 1, x)
100
101 #define BT_INTMASK_R    bt->io->inputb(bt->io, 2)
102 #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x)
103
104 /* Convenience routines for debugging.  These are not multi-open safe!
105    Note the macros have hardcoded variables in them. */
106
107 static char *state2txt(unsigned char state)
108 {
109         switch (state) {
110                 case BT_STATE_IDLE:             return("IDLE");
111                 case BT_STATE_XACTION_START:    return("XACTION");
112                 case BT_STATE_WRITE_BYTES:      return("WR_BYTES");
113                 case BT_STATE_WRITE_END:        return("WR_END");
114                 case BT_STATE_WRITE_CONSUME:    return("WR_CONSUME");
115                 case BT_STATE_B2H_WAIT:         return("B2H_WAIT");
116                 case BT_STATE_READ_END:         return("RD_END");
117                 case BT_STATE_RESET1:           return("RESET1");
118                 case BT_STATE_RESET2:           return("RESET2");
119                 case BT_STATE_RESET3:           return("RESET3");
120                 case BT_STATE_RESTART:          return("RESTART");
121                 case BT_STATE_HOSED:            return("HOSED");
122         }
123         return("BAD STATE");
124 }
125 #define STATE2TXT state2txt(bt->state)
126
127 static char *status2txt(unsigned char status, char *buf)
128 {
129         strcpy(buf, "[ ");
130         if (status & BT_B_BUSY) strcat(buf, "B_BUSY ");
131         if (status & BT_H_BUSY) strcat(buf, "H_BUSY ");
132         if (status & BT_OEM0) strcat(buf, "OEM0 ");
133         if (status & BT_SMS_ATN) strcat(buf, "SMS ");
134         if (status & BT_B2H_ATN) strcat(buf, "B2H ");
135         if (status & BT_H2B_ATN) strcat(buf, "H2B ");
136         strcat(buf, "]");
137         return buf;
138 }
139 #define STATUS2TXT(buf) status2txt(status, buf)
140
141 /* This will be called from within this module on a hosed condition */
142 #define FIRST_SEQ       0
143 static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
144 {
145         bt->state = BT_STATE_IDLE;
146         bt->last_state = BT_STATE_IDLE;
147         bt->seq = FIRST_SEQ;
148         bt->io = io;
149         bt->write_count = 0;
150         bt->read_count = 0;
151         bt->error_retries = 0;
152         bt->nonzero_status = 0;
153         bt->truncated = 0;
154         bt->timeout = BT_NORMAL_TIMEOUT;
155         return 3; /* We claim 3 bytes of space; ought to check SPMI table */
156 }
157
158 static int bt_start_transaction(struct si_sm_data *bt,
159                                 unsigned char *data,
160                                 unsigned int size)
161 {
162         unsigned int i;
163
164         if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH))
165                return -1;
166
167         if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED))
168                 return -2;
169
170         if (bt_debug & BT_DEBUG_MSG) {
171                 printk(KERN_WARNING "+++++++++++++++++++++++++++++++++++++\n");
172                 printk(KERN_WARNING "BT: write seq=0x%02X:", bt->seq);
173                 for (i = 0; i < size; i ++)
174                        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)
214                        bt->truncated = 1;
215                 if (bt->truncated) {    /* can be set in read_all_bytes() */
216                         data[2] = IPMI_ERR_MSG_TRUNCATED;
217                         msg_len = 3;
218                 } else
219                        memcpy(data + 2, bt->read_data + 4, msg_len - 2);
220
221                 if (bt_debug & BT_DEBUG_MSG) {
222                         printk (KERN_WARNING "BT: res (raw)");
223                         for (i = 0; i < msg_len; i++)
224                                printk(" %02x", data[i]);
225                         printk ("\n");
226                 }
227         }
228         bt->read_count = 0;     /* paranoia */
229         return msg_len;
230 }
231
232 /* This bit's functionality is optional */
233 #define BT_BMC_HWRST    0x80
234
235 static void reset_flags(struct si_sm_data *bt)
236 {
237         if (BT_STATUS & BT_H_BUSY)
238                BT_CONTROL(BT_H_BUSY);
239         if (BT_STATUS & BT_B_BUSY)
240                BT_CONTROL(BT_B_BUSY);
241         BT_CONTROL(BT_CLR_WR_PTR);
242         BT_CONTROL(BT_SMS_ATN);
243 #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
244         if (BT_STATUS & BT_B2H_ATN) {
245                 int i;
246                 BT_CONTROL(BT_H_BUSY);
247                 BT_CONTROL(BT_B2H_ATN);
248                 BT_CONTROL(BT_CLR_RD_PTR);
249                 for (i = 0; i < IPMI_MAX_MSG_LENGTH + 2; i++)
250                        BMC2HOST;
251                 BT_CONTROL(BT_H_BUSY);
252         }
253 #endif
254 }
255
256 static inline void write_all_bytes(struct si_sm_data *bt)
257 {
258         int i;
259
260         if (bt_debug & BT_DEBUG_MSG) {
261                 printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
262                         bt->write_count, bt->seq);
263                 for (i = 0; i < bt->write_count; i++)
264                         printk (" %02x", bt->write_data[i]);
265                 printk ("\n");
266         }
267         for (i = 0; i < bt->write_count; i++)
268                HOST2BMC(bt->write_data[i]);
269 }
270
271 static inline int read_all_bytes(struct si_sm_data *bt)
272 {
273         unsigned char i;
274
275         bt->read_data[0] = BMC2HOST;
276         bt->read_count = bt->read_data[0];
277         if (bt_debug & BT_DEBUG_MSG)
278                 printk(KERN_WARNING "BT: read %d bytes:", bt->read_count);
279
280         /* minimum: length, NetFn, Seq, Cmd, cCode == 5 total, or 4 more
281            following the length byte. */
282         if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) {
283                 if (bt_debug & BT_DEBUG_MSG)
284                         printk("bad length %d\n", bt->read_count);
285                 bt->truncated = 1;
286                 return 1;       /* let next XACTION START clean it up */
287         }
288         for (i = 1; i <= bt->read_count; i++)
289                bt->read_data[i] = BMC2HOST;
290         bt->read_count++;       /* account for the length byte */
291
292         if (bt_debug & BT_DEBUG_MSG) {
293                 for (i = 0; i < bt->read_count; i++)
294                         printk (" %02x", bt->read_data[i]);
295                 printk ("\n");
296         }
297         if (bt->seq != bt->write_data[2])       /* idiot check */
298                 printk(KERN_WARNING "BT: internal error: sequence mismatch\n");
299
300         /* per the spec, the (NetFn, Seq, Cmd) tuples should match */
301         if ((bt->read_data[3] == bt->write_data[3]) &&          /* Cmd */
302                 (bt->read_data[2] == bt->write_data[2]) &&      /* Sequence */
303                 ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
304                         return 1;
305
306         if (bt_debug & BT_DEBUG_MSG)
307                printk(KERN_WARNING "BT: bad packet: "
308                 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
309                 bt->write_data[1], bt->write_data[2], bt->write_data[3],
310                 bt->read_data[1],  bt->read_data[2],  bt->read_data[3]);
311         return 0;
312 }
313
314 /* Modifies bt->state appropriately, need to get into the bt_event() switch */
315
316 static void error_recovery(struct si_sm_data *bt, char *reason)
317 {
318         unsigned char status;
319         char buf[40]; /* For getting status */
320
321         bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
322
323         status = BT_STATUS;
324         printk(KERN_WARNING "BT: %s in %s %s ", reason, STATE2TXT,
325                STATUS2TXT(buf));
326
327         (bt->error_retries)++;
328         if (bt->error_retries > BT_RETRY_LIMIT) {
329                 printk("retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
330                 bt->state = BT_STATE_HOSED;
331                 if (!bt->nonzero_status)
332                         printk(KERN_ERR "IPMI: BT stuck, try power cycle\n");
333                 else if (bt->seq == FIRST_SEQ + BT_RETRY_LIMIT) {
334                         /* most likely during insmod */
335                         printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
336                         bt->state = BT_STATE_RESET1;
337                 }
338         return;
339         }
340
341         /* Sometimes the BMC queues get in an "off-by-one" state...*/
342         if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) {
343                 printk("retry B2H_WAIT\n");
344                 return;
345         }
346
347         printk("restart command\n");
348         bt->state = BT_STATE_RESTART;
349 }
350
351 /* Check the status and (possibly) advance the BT state machine.  The
352    default return is SI_SM_CALL_WITH_DELAY. */
353
354 static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
355 {
356         unsigned char status;
357         char buf[40]; /* For getting status */
358         int i;
359
360         status = BT_STATUS;
361         bt->nonzero_status |= status;
362
363         if ((bt_debug & BT_DEBUG_STATES) && (bt->state != bt->last_state))
364                 printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n",
365                         STATE2TXT,
366                         STATUS2TXT(buf),
367                         bt->timeout,
368                         time);
369         bt->last_state = bt->state;
370
371         if (bt->state == BT_STATE_HOSED)
372                return SI_SM_HOSED;
373
374         if (bt->state != BT_STATE_IDLE) {       /* do timeout test */
375
376                 /* Certain states, on error conditions, can lock up a CPU
377                    because they are effectively in an infinite loop with
378                    CALL_WITHOUT_DELAY (right back here with time == 0).
379                    Prevent infinite lockup by ALWAYS decrementing timeout. */
380
381         /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
382               (noticed in ipmi_smic_sm.c January 2004) */
383
384                 if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT))
385                        time = 100;
386                 bt->timeout -= time;
387                 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
388                         error_recovery(bt, "timed out");
389                         return SI_SM_CALL_WITHOUT_DELAY;
390                 }
391         }
392
393         switch (bt->state) {
394
395         case BT_STATE_IDLE:     /* check for asynchronous messages */
396                 if (status & BT_SMS_ATN) {
397                         BT_CONTROL(BT_SMS_ATN); /* clear it */
398                         return SI_SM_ATTN;
399                 }
400                 return SI_SM_IDLE;
401
402         case BT_STATE_XACTION_START:
403                 if (status & BT_H_BUSY) {
404                         BT_CONTROL(BT_H_BUSY);
405                         break;
406                 }
407                 if (status & BT_B2H_ATN)
408                        break;
409                 bt->state = BT_STATE_WRITE_BYTES;
410                 return SI_SM_CALL_WITHOUT_DELAY;        /* for logging */
411
412         case BT_STATE_WRITE_BYTES:
413                 if (status & (BT_B_BUSY | BT_H2B_ATN))
414                        break;
415                 BT_CONTROL(BT_CLR_WR_PTR);
416                 write_all_bytes(bt);
417                 BT_CONTROL(BT_H2B_ATN); /* clears too fast to catch? */
418                 bt->state = BT_STATE_WRITE_CONSUME;
419                 return SI_SM_CALL_WITHOUT_DELAY; /* it MIGHT sail through */
420
421         case BT_STATE_WRITE_CONSUME: /* BMCs usually blow right thru here */
422                 if (status & (BT_H2B_ATN | BT_B_BUSY))
423                        break;
424                 bt->state = BT_STATE_B2H_WAIT;
425                 /* fall through with status */
426
427         /* Stay in BT_STATE_B2H_WAIT until a packet matches.  However, spinning
428            hard here, constantly reading status, seems to hold off the
429            generation of B2H_ATN so ALWAYS return CALL_WITH_DELAY. */
430
431         case BT_STATE_B2H_WAIT:
432                 if (!(status & BT_B2H_ATN))
433                        break;
434
435                 /* Assume ordered, uncached writes: no need to wait */
436                 if (!(status & BT_H_BUSY))
437                        BT_CONTROL(BT_H_BUSY); /* set */
438                 BT_CONTROL(BT_B2H_ATN);         /* clear it, ACK to the BMC */
439                 BT_CONTROL(BT_CLR_RD_PTR);      /* reset the queue */
440                 i = read_all_bytes(bt);
441                 BT_CONTROL(BT_H_BUSY);          /* clear */
442                 if (!i)                         /* Try this state again */
443                        break;
444                 bt->state = BT_STATE_READ_END;
445                 return SI_SM_CALL_WITHOUT_DELAY;        /* for logging */
446
447         case BT_STATE_READ_END:
448
449                 /* I could wait on BT_H_BUSY to go clear for a truly clean
450                    exit.  However, this is already done in XACTION_START
451                    and the (possible) extra loop/status/possible wait affects
452                    performance.  So, as long as it works, just ignore H_BUSY */
453
454 #ifdef MAKE_THIS_TRUE_IF_NECESSARY
455
456                 if (status & BT_H_BUSY)
457                        break;
458 #endif
459                 bt->seq++;
460                 bt->state = BT_STATE_IDLE;
461                 return SI_SM_TRANSACTION_COMPLETE;
462
463         case BT_STATE_RESET1:
464                 reset_flags(bt);
465                 bt->timeout = BT_RESET_DELAY;
466                 bt->state = BT_STATE_RESET2;
467                 break;
468
469         case BT_STATE_RESET2:           /* Send a soft reset */
470                 BT_CONTROL(BT_CLR_WR_PTR);
471                 HOST2BMC(3);            /* number of bytes following */
472                 HOST2BMC(0x18);         /* NetFn/LUN == Application, LUN 0 */
473                 HOST2BMC(42);           /* Sequence number */
474                 HOST2BMC(3);            /* Cmd == Soft reset */
475                 BT_CONTROL(BT_H2B_ATN);
476                 bt->state = BT_STATE_RESET3;
477                 break;
478
479         case BT_STATE_RESET3:
480                 if (bt->timeout > 0)
481                        return SI_SM_CALL_WITH_DELAY;
482                 bt->state = BT_STATE_RESTART;   /* printk in debug modes */
483                 break;
484
485         case BT_STATE_RESTART:          /* don't reset retries! */
486                 bt->write_data[2] = ++bt->seq;
487                 bt->read_count = 0;
488                 bt->nonzero_status = 0;
489                 bt->timeout = BT_NORMAL_TIMEOUT;
490                 bt->state = BT_STATE_XACTION_START;
491                 break;
492
493         default:        /* HOSED is supposed to be caught much earlier */
494                 error_recovery(bt, "internal logic error");
495                 break;
496         }
497         return SI_SM_CALL_WITH_DELAY;
498 }
499
500 static int bt_detect(struct si_sm_data *bt)
501 {
502         /* It's impossible for the BT status and interrupt registers to be
503            all 1's, (assuming a properly functioning, self-initialized BMC)
504            but that's what you get from reading a bogus address, so we
505            test that first.  The calling routine uses negative logic. */
506
507         if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
508                return 1;
509         reset_flags(bt);
510         return 0;
511 }
512
513 static void bt_cleanup(struct si_sm_data *bt)
514 {
515 }
516
517 static int bt_size(void)
518 {
519         return sizeof(struct si_sm_data);
520 }
521
522 struct si_sm_handlers bt_smi_handlers =
523 {
524         .init_data         = bt_init_data,
525         .start_transaction = bt_start_transaction,
526         .get_result        = bt_get_result,
527         .event             = bt_event,
528         .detect            = bt_detect,
529         .cleanup           = bt_cleanup,
530         .size              = bt_size,
531 };