ipmi: style fixes in the base code
[deliverable/linux.git] / drivers / char / ipmi / ipmi_bt_sm.c
CommitLineData
1da177e4
LT
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>
c4edff1c
CM
31#include <linux/module.h>
32#include <linux/moduleparam.h>
1da177e4
LT
33#include <linux/ipmi_msgdefs.h> /* for completion codes */
34#include "ipmi_si_sm.h"
35
4d7cbac7
CM
36#define BT_DEBUG_OFF 0 /* Used in production */
37#define BT_DEBUG_ENABLE 1 /* Generic messages */
38#define BT_DEBUG_MSG 2 /* Prints all request/response buffers */
39#define BT_DEBUG_STATES 4 /* Verbose look at state changes */
0c8204b3
RD
40/* BT_DEBUG_OFF must be zero to correspond to the default uninitialized
41 value */
4d7cbac7 42
0c8204b3 43static int bt_debug; /* 0 == BT_DEBUG_OFF */
1da177e4 44
c4edff1c
CM
45module_param(bt_debug, int, 0644);
46MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
1da177e4
LT
47
48/* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
49 and 64 byte buffers. However, one HP implementation wants 255 bytes of
50 buffer (with a documented message of 160 bytes) so go for the max.
51 Since the Open IPMI architecture is single-message oriented at this
52 stage, the queue depth of BT is of no concern. */
53
4d7cbac7
CM
54#define BT_NORMAL_TIMEOUT 5 /* seconds */
55#define BT_NORMAL_RETRY_LIMIT 2
56#define BT_RESET_DELAY 6 /* seconds after warm reset */
57
58/* States are written in chronological order and usually cover
59 multiple rows of the state table discussion in the IPMI spec. */
1da177e4
LT
60
61enum bt_states {
4d7cbac7 62 BT_STATE_IDLE = 0, /* Order is critical in this list */
1da177e4
LT
63 BT_STATE_XACTION_START,
64 BT_STATE_WRITE_BYTES,
1da177e4 65 BT_STATE_WRITE_CONSUME,
4d7cbac7
CM
66 BT_STATE_READ_WAIT,
67 BT_STATE_CLEAR_B2H,
68 BT_STATE_READ_BYTES,
69 BT_STATE_RESET1, /* These must come last */
1da177e4
LT
70 BT_STATE_RESET2,
71 BT_STATE_RESET3,
72 BT_STATE_RESTART,
4d7cbac7
CM
73 BT_STATE_PRINTME,
74 BT_STATE_CAPABILITIES_BEGIN,
75 BT_STATE_CAPABILITIES_END,
76 BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */
1da177e4
LT
77};
78
4d7cbac7
CM
79/* Macros seen at the end of state "case" blocks. They help with legibility
80 and debugging. */
81
82#define BT_STATE_CHANGE(X,Y) { bt->state = X; return Y; }
83
84#define BT_SI_SM_RETURN(Y) { last_printed = BT_STATE_PRINTME; return Y; }
85
1da177e4
LT
86struct si_sm_data {
87 enum bt_states state;
1da177e4
LT
88 unsigned char seq; /* BT sequence number */
89 struct si_sm_io *io;
4d7cbac7
CM
90 unsigned char write_data[IPMI_MAX_MSG_LENGTH];
91 int write_count;
92 unsigned char read_data[IPMI_MAX_MSG_LENGTH];
93 int read_count;
94 int truncated;
95 long timeout; /* microseconds countdown */
96 int error_retries; /* end of "common" fields */
1da177e4 97 int nonzero_status; /* hung BMCs stay all 0 */
4d7cbac7
CM
98 enum bt_states complete; /* to divert the state machine */
99 int BT_CAP_outreqs;
100 long BT_CAP_req2rsp;
101 int BT_CAP_retries; /* Recommended retries */
1da177e4
LT
102};
103
104#define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */
105#define BT_CLR_RD_PTR 0x02
106#define BT_H2B_ATN 0x04
107#define BT_B2H_ATN 0x08
108#define BT_SMS_ATN 0x10
109#define BT_OEM0 0x20
110#define BT_H_BUSY 0x40
111#define BT_B_BUSY 0x80
112
113/* Some bits are toggled on each write: write once to set it, once
114 more to clear it; writing a zero does nothing. To absolutely
115 clear it, check its state and write if set. This avoids the "get
116 current then use as mask" scheme to modify one bit. Note that the
117 variable "bt" is hardcoded into these macros. */
118
119#define BT_STATUS bt->io->inputb(bt->io, 0)
120#define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x)
121
122#define BMC2HOST bt->io->inputb(bt->io, 1)
123#define HOST2BMC(x) bt->io->outputb(bt->io, 1, x)
124
125#define BT_INTMASK_R bt->io->inputb(bt->io, 2)
126#define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x)
127
128/* Convenience routines for debugging. These are not multi-open safe!
129 Note the macros have hardcoded variables in them. */
130
131static char *state2txt(unsigned char state)
132{
133 switch (state) {
4d7cbac7
CM
134 case BT_STATE_IDLE: return("IDLE");
135 case BT_STATE_XACTION_START: return("XACTION");
136 case BT_STATE_WRITE_BYTES: return("WR_BYTES");
137 case BT_STATE_WRITE_CONSUME: return("WR_CONSUME");
138 case BT_STATE_READ_WAIT: return("RD_WAIT");
139 case BT_STATE_CLEAR_B2H: return("CLEAR_B2H");
140 case BT_STATE_READ_BYTES: return("RD_BYTES");
141 case BT_STATE_RESET1: return("RESET1");
142 case BT_STATE_RESET2: return("RESET2");
143 case BT_STATE_RESET3: return("RESET3");
144 case BT_STATE_RESTART: return("RESTART");
145 case BT_STATE_LONG_BUSY: return("LONG_BUSY");
146 case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN");
147 case BT_STATE_CAPABILITIES_END: return("CAP_END");
1da177e4
LT
148 }
149 return("BAD STATE");
150}
151#define STATE2TXT state2txt(bt->state)
152
4d7cbac7 153static char *status2txt(unsigned char status)
1da177e4 154{
4d7cbac7
CM
155 /*
156 * This cannot be called by two threads at the same time and
157 * the buffer is always consumed immediately, so the static is
158 * safe to use.
159 */
160 static char buf[40];
161
1da177e4 162 strcpy(buf, "[ ");
4d7cbac7
CM
163 if (status & BT_B_BUSY)
164 strcat(buf, "B_BUSY ");
165 if (status & BT_H_BUSY)
166 strcat(buf, "H_BUSY ");
167 if (status & BT_OEM0)
168 strcat(buf, "OEM0 ");
169 if (status & BT_SMS_ATN)
170 strcat(buf, "SMS ");
171 if (status & BT_B2H_ATN)
172 strcat(buf, "B2H ");
173 if (status & BT_H2B_ATN)
174 strcat(buf, "H2B ");
1da177e4
LT
175 strcat(buf, "]");
176 return buf;
177}
4d7cbac7
CM
178#define STATUS2TXT status2txt(status)
179
180/* called externally at insmod time, and internally on cleanup */
1da177e4 181
1da177e4
LT
182static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
183{
4d7cbac7
CM
184 memset(bt, 0, sizeof(struct si_sm_data));
185 if (bt->io != io) { /* external: one-time only things */
186 bt->io = io;
187 bt->seq = 0;
188 }
189 bt->state = BT_STATE_IDLE; /* start here */
190 bt->complete = BT_STATE_IDLE; /* end here */
191 bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * 1000000;
192 bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT;
193 /* BT_CAP_outreqs == zero is a flag to read BT Capabilities */
1da177e4
LT
194 return 3; /* We claim 3 bytes of space; ought to check SPMI table */
195}
196
4d7cbac7
CM
197/* Jam a completion code (probably an error) into a response */
198
199static void force_result(struct si_sm_data *bt, unsigned char completion_code)
200{
201 bt->read_data[0] = 4; /* # following bytes */
202 bt->read_data[1] = bt->write_data[1] | 4; /* Odd NetFn/LUN */
203 bt->read_data[2] = bt->write_data[2]; /* seq (ignored) */
204 bt->read_data[3] = bt->write_data[3]; /* Command */
205 bt->read_data[4] = completion_code;
206 bt->read_count = 5;
207}
208
209/* The upper state machine starts here */
210
1da177e4
LT
211static int bt_start_transaction(struct si_sm_data *bt,
212 unsigned char *data,
213 unsigned int size)
214{
215 unsigned int i;
216
4d7cbac7
CM
217 if (size < 2)
218 return IPMI_REQ_LEN_INVALID_ERR;
219 if (size > IPMI_MAX_MSG_LENGTH)
220 return IPMI_REQ_LEN_EXCEEDED_ERR;
1da177e4 221
4d7cbac7
CM
222 if (bt->state == BT_STATE_LONG_BUSY)
223 return IPMI_NODE_BUSY_ERR;
224
225 if (bt->state != BT_STATE_IDLE)
226 return IPMI_NOT_IN_MY_STATE_ERR;
1da177e4
LT
227
228 if (bt_debug & BT_DEBUG_MSG) {
4d7cbac7
CM
229 printk(KERN_WARNING "BT: +++++++++++++++++ New command\n");
230 printk(KERN_WARNING "BT: NetFn/LUN CMD [%d data]:", size - 2);
e8b33617 231 for (i = 0; i < size; i ++)
4d7cbac7 232 printk (" %02x", data[i]);
1da177e4
LT
233 printk("\n");
234 }
235 bt->write_data[0] = size + 1; /* all data plus seq byte */
236 bt->write_data[1] = *data; /* NetFn/LUN */
4d7cbac7 237 bt->write_data[2] = bt->seq++;
1da177e4
LT
238 memcpy(bt->write_data + 3, data + 1, size - 1);
239 bt->write_count = size + 2;
1da177e4
LT
240 bt->error_retries = 0;
241 bt->nonzero_status = 0;
1da177e4
LT
242 bt->truncated = 0;
243 bt->state = BT_STATE_XACTION_START;
4d7cbac7
CM
244 bt->timeout = bt->BT_CAP_req2rsp;
245 force_result(bt, IPMI_ERR_UNSPECIFIED);
1da177e4
LT
246 return 0;
247}
248
249/* After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE
250 it calls this. Strip out the length and seq bytes. */
251
252static int bt_get_result(struct si_sm_data *bt,
4d7cbac7
CM
253 unsigned char *data,
254 unsigned int length)
1da177e4
LT
255{
256 int i, msg_len;
257
258 msg_len = bt->read_count - 2; /* account for length & seq */
1da177e4 259 if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
4d7cbac7 260 force_result(bt, IPMI_ERR_UNSPECIFIED);
1da177e4 261 msg_len = 3;
4d7cbac7
CM
262 }
263 data[0] = bt->read_data[1];
264 data[1] = bt->read_data[3];
265 if (length < msg_len || bt->truncated) {
266 data[2] = IPMI_ERR_MSG_TRUNCATED;
267 msg_len = 3;
268 } else
269 memcpy(data + 2, bt->read_data + 4, msg_len - 2);
1da177e4 270
4d7cbac7
CM
271 if (bt_debug & BT_DEBUG_MSG) {
272 printk (KERN_WARNING "BT: result %d bytes:", msg_len);
273 for (i = 0; i < msg_len; i++)
274 printk(" %02x", data[i]);
275 printk ("\n");
1da177e4 276 }
1da177e4
LT
277 return msg_len;
278}
279
280/* This bit's functionality is optional */
281#define BT_BMC_HWRST 0x80
282
283static void reset_flags(struct si_sm_data *bt)
284{
4d7cbac7
CM
285 if (bt_debug)
286 printk(KERN_WARNING "IPMI BT: flag reset %s\n",
287 status2txt(BT_STATUS));
e8b33617 288 if (BT_STATUS & BT_H_BUSY)
4d7cbac7
CM
289 BT_CONTROL(BT_H_BUSY); /* force clear */
290 BT_CONTROL(BT_CLR_WR_PTR); /* always reset */
291 BT_CONTROL(BT_SMS_ATN); /* always clear */
292 BT_INTMASK_W(BT_BMC_HWRST);
293}
294
295/* Get rid of an unwanted/stale response. This should only be needed for
296 BMCs that support multiple outstanding requests. */
297
298static void drain_BMC2HOST(struct si_sm_data *bt)
299{
300 int i, size;
301
302 if (!(BT_STATUS & BT_B2H_ATN)) /* Not signalling a response */
303 return;
304
305 BT_CONTROL(BT_H_BUSY); /* now set */
306 BT_CONTROL(BT_B2H_ATN); /* always clear */
307 BT_STATUS; /* pause */
308 BT_CONTROL(BT_B2H_ATN); /* some BMCs are stubborn */
309 BT_CONTROL(BT_CLR_RD_PTR); /* always reset */
310 if (bt_debug)
311 printk(KERN_WARNING "IPMI BT: stale response %s; ",
312 status2txt(BT_STATUS));
313 size = BMC2HOST;
314 for (i = 0; i < size ; i++)
315 BMC2HOST;
316 BT_CONTROL(BT_H_BUSY); /* now clear */
317 if (bt_debug)
318 printk("drained %d bytes\n", size + 1);
1da177e4
LT
319}
320
321static inline void write_all_bytes(struct si_sm_data *bt)
322{
323 int i;
324
325 if (bt_debug & BT_DEBUG_MSG) {
4d7cbac7 326 printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
1da177e4
LT
327 bt->write_count, bt->seq);
328 for (i = 0; i < bt->write_count; i++)
329 printk (" %02x", bt->write_data[i]);
330 printk ("\n");
331 }
e8b33617 332 for (i = 0; i < bt->write_count; i++)
4d7cbac7 333 HOST2BMC(bt->write_data[i]);
1da177e4
LT
334}
335
336static inline int read_all_bytes(struct si_sm_data *bt)
337{
338 unsigned char i;
339
4d7cbac7
CM
340 /* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
341 Keep layout of first four bytes aligned with write_data[] */
342
1da177e4
LT
343 bt->read_data[0] = BMC2HOST;
344 bt->read_count = bt->read_data[0];
1da177e4 345
1da177e4
LT
346 if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) {
347 if (bt_debug & BT_DEBUG_MSG)
4d7cbac7
CM
348 printk(KERN_WARNING "BT: bad raw rsp len=%d\n",
349 bt->read_count);
1da177e4
LT
350 bt->truncated = 1;
351 return 1; /* let next XACTION START clean it up */
352 }
e8b33617 353 for (i = 1; i <= bt->read_count; i++)
4d7cbac7
CM
354 bt->read_data[i] = BMC2HOST;
355 bt->read_count++; /* Account internally for length byte */
1da177e4
LT
356
357 if (bt_debug & BT_DEBUG_MSG) {
4d7cbac7
CM
358 int max = bt->read_count;
359
360 printk(KERN_WARNING "BT: got %d bytes seq=0x%02X",
361 max, bt->read_data[2]);
362 if (max > 16)
363 max = 16;
364 for (i = 0; i < max; i++)
1da177e4 365 printk (" %02x", bt->read_data[i]);
4d7cbac7 366 printk ("%s\n", bt->read_count == max ? "" : " ...");
1da177e4 367 }
1da177e4 368
4d7cbac7
CM
369 /* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */
370 if ((bt->read_data[3] == bt->write_data[3]) &&
371 (bt->read_data[2] == bt->write_data[2]) &&
372 ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
1da177e4
LT
373 return 1;
374
e8b33617 375 if (bt_debug & BT_DEBUG_MSG)
4d7cbac7 376 printk(KERN_WARNING "IPMI BT: bad packet: "
1da177e4 377 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
4d7cbac7 378 bt->write_data[1] | 0x04, bt->write_data[2], bt->write_data[3],
1da177e4
LT
379 bt->read_data[1], bt->read_data[2], bt->read_data[3]);
380 return 0;
381}
382
4d7cbac7 383/* Restart if retries are left, or return an error completion code */
1da177e4 384
4d7cbac7
CM
385static enum si_sm_result error_recovery(struct si_sm_data *bt,
386 unsigned char status,
387 unsigned char cCode)
1da177e4 388{
4d7cbac7 389 char *reason;
1da177e4 390
4d7cbac7 391 bt->timeout = bt->BT_CAP_req2rsp;
1da177e4 392
4d7cbac7
CM
393 switch (cCode) {
394 case IPMI_TIMEOUT_ERR:
395 reason = "timeout";
396 break;
397 default:
398 reason = "internal error";
399 break;
400 }
401
402 printk(KERN_WARNING "IPMI BT: %s in %s %s ", /* open-ended line */
403 reason, STATE2TXT, STATUS2TXT);
1da177e4 404
4d7cbac7
CM
405 /* Per the IPMI spec, retries are based on the sequence number
406 known only to this module, so manage a restart here. */
1da177e4 407 (bt->error_retries)++;
4d7cbac7
CM
408 if (bt->error_retries < bt->BT_CAP_retries) {
409 printk("%d retries left\n",
410 bt->BT_CAP_retries - bt->error_retries);
411 bt->state = BT_STATE_RESTART;
412 return SI_SM_CALL_WITHOUT_DELAY;
1da177e4
LT
413 }
414
4d7cbac7
CM
415 printk("failed %d retries, sending error response\n",
416 bt->BT_CAP_retries);
417 if (!bt->nonzero_status)
418 printk(KERN_ERR "IPMI BT: stuck, try power cycle\n");
419
420 /* this is most likely during insmod */
421 else if (bt->seq <= (unsigned char)(bt->BT_CAP_retries & 0xFF)) {
422 printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
423 bt->state = BT_STATE_RESET1;
424 return SI_SM_CALL_WITHOUT_DELAY;
1da177e4
LT
425 }
426
4d7cbac7
CM
427 /* Concoct a useful error message, set up the next state, and
428 be done with this sequence. */
429
430 bt->state = BT_STATE_IDLE;
431 switch (cCode) {
432 case IPMI_TIMEOUT_ERR:
433 if (status & BT_B_BUSY) {
434 cCode = IPMI_NODE_BUSY_ERR;
435 bt->state = BT_STATE_LONG_BUSY;
436 }
437 break;
438 default:
439 break;
440 }
441 force_result(bt, cCode);
442 return SI_SM_TRANSACTION_COMPLETE;
1da177e4
LT
443}
444
4d7cbac7 445/* Check status and (usually) take action and change this state machine. */
1da177e4
LT
446
447static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
448{
4d7cbac7
CM
449 unsigned char status, BT_CAP[8];
450 static enum bt_states last_printed = BT_STATE_PRINTME;
1da177e4
LT
451 int i;
452
453 status = BT_STATUS;
454 bt->nonzero_status |= status;
4d7cbac7 455 if ((bt_debug & BT_DEBUG_STATES) && (bt->state != last_printed)) {
1da177e4
LT
456 printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n",
457 STATE2TXT,
4d7cbac7 458 STATUS2TXT,
1da177e4
LT
459 bt->timeout,
460 time);
4d7cbac7
CM
461 last_printed = bt->state;
462 }
1da177e4 463
4d7cbac7
CM
464 /* Commands that time out may still (eventually) provide a response.
465 This stale response will get in the way of a new response so remove
466 it if possible (hopefully during IDLE). Even if it comes up later
467 it will be rejected by its (now-forgotten) seq number. */
468
469 if ((bt->state < BT_STATE_WRITE_BYTES) && (status & BT_B2H_ATN)) {
470 drain_BMC2HOST(bt);
471 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
472 }
1da177e4 473
4d7cbac7
CM
474 if ((bt->state != BT_STATE_IDLE) &&
475 (bt->state < BT_STATE_PRINTME)) { /* check timeout */
1da177e4 476 bt->timeout -= time;
4d7cbac7
CM
477 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1))
478 return error_recovery(bt,
479 status,
480 IPMI_TIMEOUT_ERR);
1da177e4
LT
481 }
482
483 switch (bt->state) {
484
4d7cbac7
CM
485 /* Idle state first checks for asynchronous messages from another
486 channel, then does some opportunistic housekeeping. */
487
488 case BT_STATE_IDLE:
1da177e4
LT
489 if (status & BT_SMS_ATN) {
490 BT_CONTROL(BT_SMS_ATN); /* clear it */
491 return SI_SM_ATTN;
492 }
1da177e4 493
4d7cbac7 494 if (status & BT_H_BUSY) /* clear a leftover H_BUSY */
1da177e4 495 BT_CONTROL(BT_H_BUSY);
1da177e4 496
4d7cbac7
CM
497 /* Read BT capabilities if it hasn't been done yet */
498 if (!bt->BT_CAP_outreqs)
499 BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN,
500 SI_SM_CALL_WITHOUT_DELAY);
501 bt->timeout = bt->BT_CAP_req2rsp;
502 BT_SI_SM_RETURN(SI_SM_IDLE);
503
504 case BT_STATE_XACTION_START:
e8b33617 505 if (status & (BT_B_BUSY | BT_H2B_ATN))
4d7cbac7
CM
506 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
507 if (BT_STATUS & BT_H_BUSY)
508 BT_CONTROL(BT_H_BUSY); /* force clear */
509 BT_STATE_CHANGE(BT_STATE_WRITE_BYTES,
510 SI_SM_CALL_WITHOUT_DELAY);
511
512 case BT_STATE_WRITE_BYTES:
513 if (status & BT_H_BUSY)
514 BT_CONTROL(BT_H_BUSY); /* clear */
1da177e4
LT
515 BT_CONTROL(BT_CLR_WR_PTR);
516 write_all_bytes(bt);
4d7cbac7
CM
517 BT_CONTROL(BT_H2B_ATN); /* can clear too fast to catch */
518 BT_STATE_CHANGE(BT_STATE_WRITE_CONSUME,
519 SI_SM_CALL_WITHOUT_DELAY);
1da177e4 520
4d7cbac7
CM
521 case BT_STATE_WRITE_CONSUME:
522 if (status & (BT_B_BUSY | BT_H2B_ATN))
523 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
524 BT_STATE_CHANGE(BT_STATE_READ_WAIT,
525 SI_SM_CALL_WITHOUT_DELAY);
526
527 /* Spinning hard can suppress B2H_ATN and force a timeout */
528
529 case BT_STATE_READ_WAIT:
530 if (!(status & BT_B2H_ATN))
531 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
532 BT_CONTROL(BT_H_BUSY); /* set */
533
534 /* Uncached, ordered writes should just proceeed serially but
535 some BMCs don't clear B2H_ATN with one hit. Fast-path a
536 workaround without too much penalty to the general case. */
537
538 BT_CONTROL(BT_B2H_ATN); /* clear it to ACK the BMC */
539 BT_STATE_CHANGE(BT_STATE_CLEAR_B2H,
540 SI_SM_CALL_WITHOUT_DELAY);
541
542 case BT_STATE_CLEAR_B2H:
543 if (status & BT_B2H_ATN) { /* keep hitting it */
544 BT_CONTROL(BT_B2H_ATN);
545 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
546 }
547 BT_STATE_CHANGE(BT_STATE_READ_BYTES,
548 SI_SM_CALL_WITHOUT_DELAY);
549
550 case BT_STATE_READ_BYTES:
551 if (!(status & BT_H_BUSY)) /* check in case of retry */
552 BT_CONTROL(BT_H_BUSY);
553 BT_CONTROL(BT_CLR_RD_PTR); /* start of BMC2HOST buffer */
554 i = read_all_bytes(bt); /* true == packet seq match */
555 BT_CONTROL(BT_H_BUSY); /* NOW clear */
556 if (!i) /* Not my message */
557 BT_STATE_CHANGE(BT_STATE_READ_WAIT,
558 SI_SM_CALL_WITHOUT_DELAY);
559 bt->state = bt->complete;
560 return bt->state == BT_STATE_IDLE ? /* where to next? */
561 SI_SM_TRANSACTION_COMPLETE : /* normal */
562 SI_SM_CALL_WITHOUT_DELAY; /* Startup magic */
563
564 case BT_STATE_LONG_BUSY: /* For example: after FW update */
565 if (!(status & BT_B_BUSY)) {
566 reset_flags(bt); /* next state is now IDLE */
567 bt_init_data(bt, bt->io);
568 }
569 return SI_SM_CALL_WITH_DELAY; /* No repeat printing */
1da177e4
LT
570
571 case BT_STATE_RESET1:
4d7cbac7
CM
572 reset_flags(bt);
573 drain_BMC2HOST(bt);
574 BT_STATE_CHANGE(BT_STATE_RESET2,
575 SI_SM_CALL_WITH_DELAY);
1da177e4
LT
576
577 case BT_STATE_RESET2: /* Send a soft reset */
578 BT_CONTROL(BT_CLR_WR_PTR);
579 HOST2BMC(3); /* number of bytes following */
580 HOST2BMC(0x18); /* NetFn/LUN == Application, LUN 0 */
581 HOST2BMC(42); /* Sequence number */
582 HOST2BMC(3); /* Cmd == Soft reset */
583 BT_CONTROL(BT_H2B_ATN);
4d7cbac7
CM
584 bt->timeout = BT_RESET_DELAY * 1000000;
585 BT_STATE_CHANGE(BT_STATE_RESET3,
586 SI_SM_CALL_WITH_DELAY);
1da177e4 587
4d7cbac7 588 case BT_STATE_RESET3: /* Hold off everything for a bit */
e8b33617 589 if (bt->timeout > 0)
4d7cbac7
CM
590 return SI_SM_CALL_WITH_DELAY;
591 drain_BMC2HOST(bt);
592 BT_STATE_CHANGE(BT_STATE_RESTART,
593 SI_SM_CALL_WITH_DELAY);
1da177e4 594
4d7cbac7 595 case BT_STATE_RESTART: /* don't reset retries or seq! */
1da177e4
LT
596 bt->read_count = 0;
597 bt->nonzero_status = 0;
4d7cbac7
CM
598 bt->timeout = bt->BT_CAP_req2rsp;
599 BT_STATE_CHANGE(BT_STATE_XACTION_START,
600 SI_SM_CALL_WITH_DELAY);
601
602 /* Get BT Capabilities, using timing of upper level state machine.
603 Set outreqs to prevent infinite loop on timeout. */
604 case BT_STATE_CAPABILITIES_BEGIN:
605 bt->BT_CAP_outreqs = 1;
606 {
607 unsigned char GetBT_CAP[] = { 0x18, 0x36 };
608 bt->state = BT_STATE_IDLE;
609 bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
610 }
611 bt->complete = BT_STATE_CAPABILITIES_END;
612 BT_STATE_CHANGE(BT_STATE_XACTION_START,
613 SI_SM_CALL_WITH_DELAY);
614
615 case BT_STATE_CAPABILITIES_END:
616 i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
617 bt_init_data(bt, bt->io);
618 if ((i == 8) && !BT_CAP[2]) {
619 bt->BT_CAP_outreqs = BT_CAP[3];
620 bt->BT_CAP_req2rsp = BT_CAP[6] * 1000000;
621 bt->BT_CAP_retries = BT_CAP[7];
622 } else
623 printk(KERN_WARNING "IPMI BT: using default values\n");
624 if (!bt->BT_CAP_outreqs)
625 bt->BT_CAP_outreqs = 1;
626 printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n",
627 bt->BT_CAP_req2rsp / 1000000L, bt->BT_CAP_retries);
628 bt->timeout = bt->BT_CAP_req2rsp;
629 return SI_SM_CALL_WITHOUT_DELAY;
630
631 default: /* should never occur */
632 return error_recovery(bt,
633 status,
634 IPMI_ERR_UNSPECIFIED);
635 }
636 return SI_SM_CALL_WITH_DELAY;
1da177e4
LT
637}
638
639static int bt_detect(struct si_sm_data *bt)
640{
641 /* It's impossible for the BT status and interrupt registers to be
642 all 1's, (assuming a properly functioning, self-initialized BMC)
643 but that's what you get from reading a bogus address, so we
644 test that first. The calling routine uses negative logic. */
645
e8b33617 646 if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
4d7cbac7 647 return 1;
1da177e4
LT
648 reset_flags(bt);
649 return 0;
650}
651
652static void bt_cleanup(struct si_sm_data *bt)
653{
654}
655
656static int bt_size(void)
657{
658 return sizeof(struct si_sm_data);
659}
660
661struct si_sm_handlers bt_smi_handlers =
662{
4d7cbac7
CM
663 .init_data = bt_init_data,
664 .start_transaction = bt_start_transaction,
665 .get_result = bt_get_result,
666 .event = bt_event,
667 .detect = bt_detect,
668 .cleanup = bt_cleanup,
669 .size = bt_size,
1da177e4 670};
This page took 0.421696 seconds and 5 git commands to generate.