Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.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 };