]> nv-tegra.nvidia Code Review - linux-3.10.git/blob - drivers/char/ipmi/ipmi_bt_sm.c
[PATCH] ipmi: enable interrupts on the BT driver
[linux-3.10.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 #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);
246         }
247 #endif
248 }
249
250 static inline void write_all_bytes(struct si_sm_data *bt)
251 {
252         int i;
253
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");
260         }
261         for (i = 0; i < bt->write_count; i++) HOST2BMC(bt->write_data[i]);
262 }
263
264 static inline int read_all_bytes(struct si_sm_data *bt)
265 {
266         unsigned char i;
267
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);
272
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 */
280         }
281         for (i = 1; i <= bt->read_count; i++) bt->read_data[i] = BMC2HOST;
282         bt->read_count++;       /* account for the length byte */
283
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");
288         }
289         if (bt->seq != bt->write_data[2])       /* idiot check */
290                 printk(KERN_WARNING "BT: internal error: sequence mismatch\n");
291
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;
297
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;
303 }
304
305 /* Modifies bt->state appropriately, need to get into the bt_event() switch */
306
307 static void error_recovery(struct si_sm_data *bt, char *reason)
308 {
309         unsigned char status;
310         char buf[40]; /* For getting status */
311
312         bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
313
314         status = BT_STATUS;
315         printk(KERN_WARNING "BT: %s in %s %s ", reason, STATE2TXT,
316                STATUS2TXT(buf));
317
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;
328                 }
329         return;
330         }
331
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;
336         }
337
338         printk("restart command\n");
339         bt->state = BT_STATE_RESTART;
340 }
341
342 /* Check the status and (possibly) advance the BT state machine.  The
343    default return is SI_SM_CALL_WITH_DELAY. */
344
345 static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
346 {
347         unsigned char status;
348         char buf[40]; /* For getting status */
349         int i;
350
351         status = BT_STATUS;
352         bt->nonzero_status |= status;
353
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;
361
362         if (bt->state == BT_STATE_HOSED) return SI_SM_HOSED;
363
364         if (bt->state != BT_STATE_IDLE) {       /* do timeout test */
365
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. */
370
371         /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
372               (noticed in ipmi_smic_sm.c January 2004) */
373
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;
379                 }
380         }
381
382         switch (bt->state) {
383
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;
388                 }
389                 return SI_SM_IDLE;
390
391         case BT_STATE_XACTION_START:
392                 if (status & BT_H_BUSY) {
393                         BT_CONTROL(BT_H_BUSY);
394                         break;
395                 }
396                 if (status & BT_B2H_ATN) break;
397                 bt->state = BT_STATE_WRITE_BYTES;
398                 return SI_SM_CALL_WITHOUT_DELAY;        /* for logging */
399
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 */
407
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 */
412
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. */
416
417         case BT_STATE_B2H_WAIT:
418                 if (!(status & BT_B2H_ATN)) break;
419
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 */
429
430         case BT_STATE_READ_END:
431
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 */
436
437 #ifdef MAKE_THIS_TRUE_IF_NECESSARY
438
439                 if (status & BT_H_BUSY) break;
440 #endif
441                 bt->seq++;
442                 bt->state = BT_STATE_IDLE;
443                 return SI_SM_TRANSACTION_COMPLETE;
444
445         case BT_STATE_RESET1:
446                 reset_flags(bt);
447                 bt->timeout = BT_RESET_DELAY;
448                 bt->state = BT_STATE_RESET2;
449                 break;
450
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;
460
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;
465
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;
473
474         default:        /* HOSED is supposed to be caught much earlier */
475                 error_recovery(bt, "internal logic error");
476                 break;
477         }
478         return SI_SM_CALL_WITH_DELAY;
479 }
480
481 static int bt_detect(struct si_sm_data *bt)
482 {
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. */
487
488         if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF)) return 1;
489         reset_flags(bt);
490         return 0;
491 }
492
493 static void bt_cleanup(struct si_sm_data *bt)
494 {
495 }
496
497 static int bt_size(void)
498 {
499         return sizeof(struct si_sm_data);
500 }
501
502 struct si_sm_handlers bt_smi_handlers =
503 {
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,
512 };