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