This source file includes following definitions.
- init_kcs_data
- read_status
- read_data
- write_cmd
- write_data
- write_next_byte
- start_error_recovery
- read_next_byte
- check_ibf
- check_obf
- clear_obf
- restart_kcs_transaction
- start_kcs_transaction
- get_kcs_result
- kcs_event
- kcs_size
- kcs_detect
- kcs_cleanup
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
37 static int kcs_debug;
38 module_param(kcs_debug, int, 0644);
39 MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
40
41
42 enum 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
106 struct 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
123 static 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
141 static inline unsigned char read_status(struct si_sm_data *kcs)
142 {
143 return kcs->io->inputb(kcs->io, 1);
144 }
145
146 static inline unsigned char read_data(struct si_sm_data *kcs)
147 {
148 return kcs->io->inputb(kcs->io, 0);
149 }
150
151 static inline void write_cmd(struct si_sm_data *kcs, unsigned char data)
152 {
153 kcs->io->outputb(kcs->io, 1, data);
154 }
155
156 static 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
178 static 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
185 static 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
199 static 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
212 static 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
228 static 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
244 static void clear_obf(struct si_sm_data *kcs, unsigned char status)
245 {
246 if (GET_STATUS_OBF(status))
247 read_data(kcs);
248 }
249
250 static 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
261 static 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 pr_cont(" %02x", data[i]);
278 pr_cont("\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
292 static 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
326 static 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
500 static int kcs_size(void)
501 {
502 return sizeof(struct si_sm_data);
503 }
504
505 static 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
519 static void kcs_cleanup(struct si_sm_data *kcs)
520 {
521 }
522
523 const 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 };