1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/string.h>
24#include <linux/jiffies.h>
25#include <linux/ipmi_msgdefs.h>
26#include "ipmi_si_sm.h"
27
28
29
30
31
32
33#define KCS_DEBUG_STATES 4
34#define KCS_DEBUG_MSG 2
35#define KCS_DEBUG_ENABLE 1
36
37static int kcs_debug;
38module_param(kcs_debug, int, 0644);
39MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
40
41
42enum kcs_states {
43
44 KCS_IDLE,
45
46
47
48
49
50
51
52 KCS_START_OP,
53
54
55 KCS_WAIT_WRITE_START,
56
57
58 KCS_WAIT_WRITE,
59
60
61
62
63
64 KCS_WAIT_WRITE_END,
65
66
67 KCS_WAIT_READ,
68
69
70
71
72
73 KCS_ERROR0,
74
75
76
77
78
79 KCS_ERROR1,
80
81
82
83
84
85 KCS_ERROR2,
86
87
88
89
90
91 KCS_ERROR3,
92
93
94 KCS_HOSED
95};
96
97#define MAX_KCS_READ_SIZE IPMI_MAX_MSG_LENGTH
98#define MAX_KCS_WRITE_SIZE IPMI_MAX_MSG_LENGTH
99
100
101#define IBF_RETRY_TIMEOUT (5*USEC_PER_SEC)
102#define OBF_RETRY_TIMEOUT (5*USEC_PER_SEC)
103#define MAX_ERROR_RETRIES 10
104#define ERROR0_OBF_WAIT_JIFFIES (2*HZ)
105
106struct si_sm_data {
107 enum kcs_states state;
108 struct si_sm_io *io;
109 unsigned char write_data[MAX_KCS_WRITE_SIZE];
110 int write_pos;
111 int write_count;
112 int orig_write_count;
113 unsigned char read_data[MAX_KCS_READ_SIZE];
114 int read_pos;
115 int truncated;
116
117 unsigned int error_retries;
118 long ibf_timeout;
119 long obf_timeout;
120 unsigned long error0_timeout;
121};
122
123static unsigned int init_kcs_data(struct si_sm_data *kcs,
124 struct si_sm_io *io)
125{
126 kcs->state = KCS_IDLE;
127 kcs->io = io;
128 kcs->write_pos = 0;
129 kcs->write_count = 0;
130 kcs->orig_write_count = 0;
131 kcs->read_pos = 0;
132 kcs->error_retries = 0;
133 kcs->truncated = 0;
134 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
135 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
136
137
138 return 2;
139}
140
141static inline unsigned char read_status(struct si_sm_data *kcs)
142{
143 return kcs->io->inputb(kcs->io, 1);
144}
145
146static inline unsigned char read_data(struct si_sm_data *kcs)
147{
148 return kcs->io->inputb(kcs->io, 0);
149}
150
151static inline void write_cmd(struct si_sm_data *kcs, unsigned char data)
152{
153 kcs->io->outputb(kcs->io, 1, data);
154}
155
156static inline void write_data(struct si_sm_data *kcs, unsigned char data)
157{
158 kcs->io->outputb(kcs->io, 0, data);
159}
160
161
162#define KCS_GET_STATUS_ABORT 0x60
163#define KCS_WRITE_START 0x61
164#define KCS_WRITE_END 0x62
165#define KCS_READ_BYTE 0x68
166
167
168#define GET_STATUS_STATE(status) (((status) >> 6) & 0x03)
169#define KCS_IDLE_STATE 0
170#define KCS_READ_STATE 1
171#define KCS_WRITE_STATE 2
172#define KCS_ERROR_STATE 3
173#define GET_STATUS_ATN(status) ((status) & 0x04)
174#define GET_STATUS_IBF(status) ((status) & 0x02)
175#define GET_STATUS_OBF(status) ((status) & 0x01)
176
177
178static inline void write_next_byte(struct si_sm_data *kcs)
179{
180 write_data(kcs, kcs->write_data[kcs->write_pos]);
181 (kcs->write_pos)++;
182 (kcs->write_count)--;
183}
184
185static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)
186{
187 (kcs->error_retries)++;
188 if (kcs->error_retries > MAX_ERROR_RETRIES) {
189 if (kcs_debug & KCS_DEBUG_ENABLE)
190 printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n",
191 reason);
192 kcs->state = KCS_HOSED;
193 } else {
194 kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES;
195 kcs->state = KCS_ERROR0;
196 }
197}
198
199static inline void read_next_byte(struct si_sm_data *kcs)
200{
201 if (kcs->read_pos >= MAX_KCS_READ_SIZE) {
202
203 read_data(kcs);
204 kcs->truncated = 1;
205 } else {
206 kcs->read_data[kcs->read_pos] = read_data(kcs);
207 (kcs->read_pos)++;
208 }
209 write_data(kcs, KCS_READ_BYTE);
210}
211
212static inline int check_ibf(struct si_sm_data *kcs, unsigned char status,
213 long time)
214{
215 if (GET_STATUS_IBF(status)) {
216 kcs->ibf_timeout -= time;
217 if (kcs->ibf_timeout < 0) {
218 start_error_recovery(kcs, "IBF not ready in time");
219 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
220 return 1;
221 }
222 return 0;
223 }
224 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
225 return 1;
226}
227
228static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
229 long time)
230{
231 if (!GET_STATUS_OBF(status)) {
232 kcs->obf_timeout -= time;
233 if (kcs->obf_timeout < 0) {
234 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
235 start_error_recovery(kcs, "OBF not ready in time");
236 return 1;
237 }
238 return 0;
239 }
240 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
241 return 1;
242}
243
244static void clear_obf(struct si_sm_data *kcs, unsigned char status)
245{
246 if (GET_STATUS_OBF(status))
247 read_data(kcs);
248}
249
250static void restart_kcs_transaction(struct si_sm_data *kcs)
251{
252 kcs->write_count = kcs->orig_write_count;
253 kcs->write_pos = 0;
254 kcs->read_pos = 0;
255 kcs->state = KCS_WAIT_WRITE_START;
256 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
257 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
258 write_cmd(kcs, KCS_WRITE_START);
259}
260
261static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
262 unsigned int size)
263{
264 unsigned int i;
265
266 if (size < 2)
267 return IPMI_REQ_LEN_INVALID_ERR;
268 if (size > MAX_KCS_WRITE_SIZE)
269 return IPMI_REQ_LEN_EXCEEDED_ERR;
270
271 if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED))
272 return IPMI_NOT_IN_MY_STATE_ERR;
273
274 if (kcs_debug & KCS_DEBUG_MSG) {
275 printk(KERN_DEBUG "start_kcs_transaction -");
276 for (i = 0; i < size; i++)
277 printk(" %02x", (unsigned char) (data [i]));
278 printk("\n");
279 }
280 kcs->error_retries = 0;
281 memcpy(kcs->write_data, data, size);
282 kcs->write_count = size;
283 kcs->orig_write_count = size;
284 kcs->write_pos = 0;
285 kcs->read_pos = 0;
286 kcs->state = KCS_START_OP;
287 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
288 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
289 return 0;
290}
291
292static int get_kcs_result(struct si_sm_data *kcs, unsigned char *data,
293 unsigned int length)
294{
295 if (length < kcs->read_pos) {
296 kcs->read_pos = length;
297 kcs->truncated = 1;
298 }
299
300 memcpy(data, kcs->read_data, kcs->read_pos);
301
302 if ((length >= 3) && (kcs->read_pos < 3)) {
303
304
305 data[2] = IPMI_ERR_UNSPECIFIED;
306 kcs->read_pos = 3;
307 }
308 if (kcs->truncated) {
309
310
311
312
313
314 data[2] = IPMI_ERR_MSG_TRUNCATED;
315 kcs->truncated = 0;
316 }
317
318 return kcs->read_pos;
319}
320
321
322
323
324
325
326static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
327{
328 unsigned char status;
329 unsigned char state;
330
331 status = read_status(kcs);
332
333 if (kcs_debug & KCS_DEBUG_STATES)
334 printk(KERN_DEBUG "KCS: State = %d, %x\n", kcs->state, status);
335
336
337 if (!check_ibf(kcs, status, time))
338 return SI_SM_CALL_WITH_DELAY;
339
340
341 state = GET_STATUS_STATE(status);
342
343 switch (kcs->state) {
344 case KCS_IDLE:
345
346 clear_obf(kcs, status);
347
348 if (GET_STATUS_ATN(status))
349 return SI_SM_ATTN;
350 else
351 return SI_SM_IDLE;
352
353 case KCS_START_OP:
354 if (state != KCS_IDLE_STATE) {
355 start_error_recovery(kcs,
356 "State machine not idle at start");
357 break;
358 }
359
360 clear_obf(kcs, status);
361 write_cmd(kcs, KCS_WRITE_START);
362 kcs->state = KCS_WAIT_WRITE_START;
363 break;
364
365 case KCS_WAIT_WRITE_START:
366 if (state != KCS_WRITE_STATE) {
367 start_error_recovery(
368 kcs,
369 "Not in write state at write start");
370 break;
371 }
372 read_data(kcs);
373 if (kcs->write_count == 1) {
374 write_cmd(kcs, KCS_WRITE_END);
375 kcs->state = KCS_WAIT_WRITE_END;
376 } else {
377 write_next_byte(kcs);
378 kcs->state = KCS_WAIT_WRITE;
379 }
380 break;
381
382 case KCS_WAIT_WRITE:
383 if (state != KCS_WRITE_STATE) {
384 start_error_recovery(kcs,
385 "Not in write state for write");
386 break;
387 }
388 clear_obf(kcs, status);
389 if (kcs->write_count == 1) {
390 write_cmd(kcs, KCS_WRITE_END);
391 kcs->state = KCS_WAIT_WRITE_END;
392 } else {
393 write_next_byte(kcs);
394 }
395 break;
396
397 case KCS_WAIT_WRITE_END:
398 if (state != KCS_WRITE_STATE) {
399 start_error_recovery(kcs,
400 "Not in write state"
401 " for write end");
402 break;
403 }
404 clear_obf(kcs, status);
405 write_next_byte(kcs);
406 kcs->state = KCS_WAIT_READ;
407 break;
408
409 case KCS_WAIT_READ:
410 if ((state != KCS_READ_STATE) && (state != KCS_IDLE_STATE)) {
411 start_error_recovery(
412 kcs,
413 "Not in read or idle in read state");
414 break;
415 }
416
417 if (state == KCS_READ_STATE) {
418 if (!check_obf(kcs, status, time))
419 return SI_SM_CALL_WITH_DELAY;
420 read_next_byte(kcs);
421 } else {
422
423
424
425
426
427
428
429
430
431 clear_obf(kcs, status);
432 kcs->orig_write_count = 0;
433 kcs->state = KCS_IDLE;
434 return SI_SM_TRANSACTION_COMPLETE;
435 }
436 break;
437
438 case KCS_ERROR0:
439 clear_obf(kcs, status);
440 status = read_status(kcs);
441 if (GET_STATUS_OBF(status))
442
443 if (time_before(jiffies, kcs->error0_timeout))
444 return SI_SM_CALL_WITH_TICK_DELAY;
445 write_cmd(kcs, KCS_GET_STATUS_ABORT);
446 kcs->state = KCS_ERROR1;
447 break;
448
449 case KCS_ERROR1:
450 clear_obf(kcs, status);
451 write_data(kcs, 0);
452 kcs->state = KCS_ERROR2;
453 break;
454
455 case KCS_ERROR2:
456 if (state != KCS_READ_STATE) {
457 start_error_recovery(kcs,
458 "Not in read state for error2");
459 break;
460 }
461 if (!check_obf(kcs, status, time))
462 return SI_SM_CALL_WITH_DELAY;
463
464 clear_obf(kcs, status);
465 write_data(kcs, KCS_READ_BYTE);
466 kcs->state = KCS_ERROR3;
467 break;
468
469 case KCS_ERROR3:
470 if (state != KCS_IDLE_STATE) {
471 start_error_recovery(kcs,
472 "Not in idle state for error3");
473 break;
474 }
475
476 if (!check_obf(kcs, status, time))
477 return SI_SM_CALL_WITH_DELAY;
478
479 clear_obf(kcs, status);
480 if (kcs->orig_write_count) {
481 restart_kcs_transaction(kcs);
482 } else {
483 kcs->state = KCS_IDLE;
484 return SI_SM_TRANSACTION_COMPLETE;
485 }
486 break;
487
488 case KCS_HOSED:
489 break;
490 }
491
492 if (kcs->state == KCS_HOSED) {
493 init_kcs_data(kcs, kcs->io);
494 return SI_SM_HOSED;
495 }
496
497 return SI_SM_CALL_WITHOUT_DELAY;
498}
499
500static int kcs_size(void)
501{
502 return sizeof(struct si_sm_data);
503}
504
505static int kcs_detect(struct si_sm_data *kcs)
506{
507
508
509
510
511
512
513 if (read_status(kcs) == 0xff)
514 return 1;
515
516 return 0;
517}
518
519static void kcs_cleanup(struct si_sm_data *kcs)
520{
521}
522
523const struct si_sm_handlers kcs_smi_handlers = {
524 .init_data = init_kcs_data,
525 .start_transaction = start_kcs_transaction,
526 .get_result = get_kcs_result,
527 .event = kcs_event,
528 .detect = kcs_detect,
529 .cleanup = kcs_cleanup,
530 .size = kcs_size,
531};
532