1 /*
2 * marvel_mod.c
3 *
4 * Marvell specific modules for handling BMC and MC functions.
5 *
6 * Author: MontaVista Software, Inc.
7 * Corey Minyard <minyard@mvista.com>
8 * source@mvista.com
9 *
10 * Copyright 2012,2013 MontaVista Software Inc.
11 *
12 * This software is available to you under a choice of one of two
13 * licenses. You may choose to be licensed under the terms of the GNU
14 * Lesser General Public License (GPL) Version 2 or the modified BSD
15 * license below. The following disclamer applies to both licenses:
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
26 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * GNU Lesser General Public Licence
29 *
30 * This program is free software; you can redistribute it and/or
31 * modify it under the terms of the GNU Lesser General Public License
32 * as published by the Free Software Foundation; either version 2 of
33 * the License, or (at your option) any later version.
34 *
35 * You should have received a copy of the GNU Lesser General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38 *
39 * Modified BSD Licence
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 *
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above
48 * copyright notice, this list of conditions and the following
49 * disclaimer in the documentation and/or other materials provided
50 * with the distribution.
51 * 3. The name of the author may not be used to endorse or promote
52 * products derived from this software without specific prior
53 * written permission.
54 */
55
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <errno.h>
59 #include <string.h>
60 #include <sys/time.h>
61 #include <sys/ioctl.h>
62 #include <unistd.h>
63 #include <signal.h>
64 #include <pthread.h>
65 #include <sys/types.h>
66 #include <sys/stat.h>
67 #include <fcntl.h>
68 #include <semaphore.h>
69
70 #include <OpenIPMI/ipmi_msgbits.h>
71 #include <OpenIPMI/ipmi_bits.h>
72 #include <OpenIPMI/serv.h>
73
74 #include "wiw.h"
75
76 #define PVERSION "2.0.12"
77
78 #define NUM_BOARDS 6
79
80 #define CHASSIS_FRU_SIZE 1024
81 #define BOARD_FRU_SIZE 2048
82
83 #define BOARD_TEMP_SHUTDOWN 105
84 #define SWITCH_TEMP_SHUTDOWN 115
85 #define FRONT_TEMP_SHUTDOWN 50
86
87 #define MARVELL_SEMI_ISREAL_IANA 20495
88 #define DISABLE_NETWORK_SRVC_CMD 1
89 #define RELOAD_BOARD_FRU_CMD 2
90 #define SET_ALL_FANS_DUTY_CMD 3
91 #define GET_ALL_FANS_DUTY_CMD 4
92
93 #define BOARD_FRU_FILE "/etc/ipmi/axp_board_fru"
94 #define COLD_POWER_FILE "/var/lib/ipmi_sim_coldpower"
95 #define RESET_REASON_FILE "/var/lib/reset_reason"
96 #define RESET_REASON_UNKNOWN 0
97 #define RESET_REASON_COLD_BOOT 1
98 #define RESET_REASON_WARM_BOOT 2
99 static int init_complete;
100
101 #define GPIODIR "/sys/class/astgpio/GPIO"
102
103 #define COLD_POWER_UP_IO "/sys/class/astgpio/ColdBoot"
104 static unsigned int cold_power_up = 1;
105
106 /*
107 * Set debugging with bits:
108 * bit 0 - power
109 * bit 1 - sensor reading
110 * bit 2 - sensor writing
111 * bit 3 - fan
112 */
113 static unsigned int debug;
114
115 /* 1 second poll time */
116 static unsigned int poll_time = 2000000;
117
118 static lmc_data_t *bmc_mc;
119
120 /* Set the file to "0" to enable reset */
121 #define BOARD_RESET_ON 0
122 #define BOARD_RESET_OFF 1
123 static const char *trg_reset[NUM_BOARDS] =
124 {
125 GPIODIR "H0",
126 GPIODIR "H1",
127 GPIODIR "H2",
128 GPIODIR "H3",
129 GPIODIR "H4",
130 GPIODIR "H5"
131 };
132
133 /* Set the file to "1" to power on, "0" to power off. */
134 #define BOARD_POWER_ON 1
135 #define BOARD_POWER_OFF 0
136 static const char *trg_power[NUM_BOARDS] =
137 {
138 GPIODIR "D6",
139 GPIODIR "D7",
140 GPIODIR "B0",
141 GPIODIR "B1",
142 GPIODIR "B2",
143 GPIODIR "B3"
144 };
145
146 /* Will contain "0" if present, "1" if not present. */
147 #define BOARD_PRESENT 0
148 #define BOARD_ABSENT 1
149 static const char *trg_present[NUM_BOARDS] =
150 {
151 GPIODIR "C0",
152 GPIODIR "C1",
153 GPIODIR "C2",
154 GPIODIR "C3",
155 GPIODIR "C4",
156 GPIODIR "C5",
157 };
158
159 static int simulate_board_absent[NUM_BOARDS];
160
161 /* Set this to zero to request that the board power off. */
162 #define BOARD_OFF_REQUEST_ON 0
163 #define BOARD_OFF_REQUEST_OFF 1
164 static const char *pow_off_request[NUM_BOARDS] =
165 {
166 GPIODIR "A6",
167 GPIODIR "A7",
168 GPIODIR "I4",
169 GPIODIR "I5",
170 GPIODIR "I6",
171 GPIODIR "I7"
172 };
173
174 /* The board will set the value to 0 when it is ready to power off. */
175 #define BOARD_OFF_READY 0
176 #define BOARD_OFF_NOT_READY 1
177 static const char *pow_off_ready[NUM_BOARDS] =
178 {
179 GPIODIR "A0",
180 GPIODIR "A1",
181 GPIODIR "A2",
182 GPIODIR "A3",
183 GPIODIR "G4",
184 GPIODIR "G5"
185 };
186
187
188 #define I2CDIR "/sys/class/i2c-adapter/i2c-"
189
190 struct eeprom {
191 unsigned char addr;
192 const char *part;
193 const char *dev;
194 unsigned int size;
195 };
196
197 static struct board_i2c_info
198 {
199 const char *add_dev;
200 struct eeprom fru;
201 } const board_i2c[NUM_BOARDS] =
202 {
203 {
204 .add_dev = I2CDIR "1/new_device",
205 .fru = {
206 .addr = 0x50,
207 .part = "24c64",
208 .dev = I2CDIR "1/1-0050/at24c64",
209 .size = BOARD_FRU_SIZE
210 },
211 },
212 {
213 .add_dev = I2CDIR "2/new_device",
214 .fru = {
215 .addr = 0x50,
216 .part = "24c64",
217 .dev = I2CDIR "2/2-0050/at24c64",
218 .size = BOARD_FRU_SIZE
219 },
220 },
221 {
222 .add_dev = I2CDIR "3/new_device",
223 .fru = {
224 .addr = 0x50,
225 .part = "24c64",
226 .dev = I2CDIR "3/3-0050/at24c64",
227 .size = BOARD_FRU_SIZE
228 },
229 },
230 {
231 .add_dev = I2CDIR "4/new_device",
232 .fru = {
233 .addr = 0x50,
234 .part = "24c64",
235 .dev = I2CDIR "4/4-0050/at24c64",
236 .size = BOARD_FRU_SIZE
237 },
238 },
239 {
240 .add_dev = I2CDIR "5/new_device",
241 .fru = {
242 .addr = 0x50,
243 .part = "24c64",
244 .dev = I2CDIR "5/5-0050/at24c64",
245 .size = BOARD_FRU_SIZE
246 },
247 },
248 {
249 .add_dev = I2CDIR "6/new_device",
250 .fru = {
251 .addr = 0x50,
252 .part = "24c64",
253 .dev = I2CDIR "6/6-0050/at24c64",
254 .size = BOARD_FRU_SIZE
255 },
256 },
257 };
258
259 static struct board_i2c_info *chassis_i2c;
260
261 /* For older systems (before DVT2) */
262 static struct board_i2c_info chassis_i2c_old =
263 {
264 .add_dev = I2CDIR "7/new_device",
265 .fru = {
266 .addr = 0x54,
267 .part = "24c128",
268 .dev = I2CDIR "7/7-0054/at24c128",
269 .size = CHASSIS_FRU_SIZE
270 }
271 };
272
273 /* For newer systems (DVT2 and later) */
274 static struct board_i2c_info chassis_i2c_new =
275 {
276 .add_dev = I2CDIR "0/new_device",
277 .fru = {
278 .addr = 0x54,
279 .part = "24c128",
280 .dev = I2CDIR "0/0-0051/at24c128",
281 .size = CHASSIS_FRU_SIZE
282 }
283 };
284
285 static struct board_info {
286 sys_data_t *sys;
287
288 lmc_data_t *mc;
289 unsigned char num;
290 char present;
291 char fru_good;
292 unsigned char fru[BOARD_FRU_SIZE];
293 struct timeval button_press_time;
294 unsigned int power_off_countdown;
295 char button_pressed;
296 char waiting_power_off;
297
298 volatile char fru_data_ready_for_handling;
299
300 /*
301 * Tracks the state of the power request line, request happens
302 * on a 1->0 transition.
303 */
304 char last_power_request;
305 } boards[NUM_BOARDS];
306
307 struct timeval last_board_power_on;
308
309 static unsigned char chassis_fru[CHASSIS_FRU_SIZE];
310 static unsigned int chassis_iuse;
311 static unsigned int chassis_iuse_len;
312 static unsigned int chassis_chinfo;
313 static unsigned int chassis_chinfo_len;
314 static unsigned int chassis_brdinfo;
315 static unsigned int chassis_brdinfo_len;
316
317 /* Offset from beginning of chassis info area */
318 static unsigned int sernum_offset;
319 static unsigned int sernum_offset2;
320 static unsigned int sernum_len;
321 static unsigned int sysmac_offset;
322
323 /* Pieces of the serial number and MAC we need for generating board info */
324 static unsigned char sernum[10];
325 static unsigned char sysmac[17];
326
327 static const unsigned char board_ipmb[NUM_BOARDS] = { 1, 2, 3, 4, 5, 6 };
328
329 static int disable_wdt;
330 static int wdt_fd;
331 static ipmi_timer_t *wdt_test_timer;
332 static volatile int wdt_test_timer_ran;
333
334 static void
add_to_timeval(struct timeval * tv,unsigned int usecs)335 add_to_timeval(struct timeval *tv, unsigned int usecs)
336 {
337 while (usecs >= 1000000) {
338 tv->tv_sec += 1;
339 usecs -= 1000000;
340 }
341 tv->tv_usec += usecs;
342 while (tv->tv_usec >= 1000000) {
343 tv->tv_sec += 1;
344 tv->tv_usec -= 1000000;
345 }
346 }
347
348 static void
diff_timeval(struct timeval * result,struct timeval * tv1,struct timeval * tv2)349 diff_timeval(struct timeval *result, struct timeval *tv1, struct timeval *tv2)
350 {
351 result->tv_sec = tv1->tv_sec - tv2->tv_sec;
352 result->tv_usec = tv1->tv_usec - tv2->tv_usec;
353 while (result->tv_usec < 0) {
354 result->tv_usec += 1000000;
355 result->tv_sec -= 1;
356 }
357 }
358
359 static long
diff_timeval_ms(struct timeval * tv1,struct timeval * tv2)360 diff_timeval_ms(struct timeval *tv1, struct timeval *tv2)
361 {
362 struct timeval tv;
363 diff_timeval(&tv, tv1, tv2);
364
365 if (tv.tv_sec > 1000)
366 return 1000000;
367 if (tv.tv_sec < -1000)
368 return -1000000;
369 return (tv.tv_sec * 1000) + ((tv.tv_usec + 500) / 1000);
370 }
371
372
373 /**************************************************************************
374 * EEPROM handling
375 *************************************************************************/
376
377 static unsigned char
checksum(unsigned char * data,int size)378 checksum(unsigned char *data, int size)
379 {
380 unsigned char csum = 0;
381
382 for (; size > 0; size--, data++)
383 csum += *data;
384
385 return csum;
386 }
387
388 /*
389 * Validate that the eeprom device exists and can be opened.
390 */
391 static int
check_eeprom(sys_data_t * sys,const struct eeprom * e)392 check_eeprom(sys_data_t *sys, const struct eeprom *e)
393 {
394 int fd;
395
396 fd = open(e->dev, O_RDONLY);
397 if (fd == -1)
398 return errno;
399 close(fd);
400 return 0;
401 }
402
403 /*
404 * Write to the sysfs file to create the eeprom device. Sometimes it
405 * doesn't get automatically created, so create it here.
406 */
407 static int
create_eeprom(sys_data_t * sys,const char * add_dev,const struct eeprom * e)408 create_eeprom(sys_data_t *sys, const char *add_dev, const struct eeprom *e)
409 {
410 int fd;
411
412 fd = open(e->dev, O_RDONLY);
413 if (fd == -1) {
414 FILE *f;
415 f = fopen(add_dev, "w");
416 if (!f)
417 return errno;
418 fprintf(f, "%s %d\n", e->part, e->addr);
419 fclose(f);
420 fd = open(e->dev, O_RDONLY);
421 if (fd == -1)
422 return errno;
423 }
424 close(fd);
425 return 0;
426 }
427
428 /* Note: Data must be at least e->size */
429 static int
read_eeprom(const struct eeprom * e,unsigned char * data,unsigned int offset,int size)430 read_eeprom(const struct eeprom *e, unsigned char *data,
431 unsigned int offset, int size)
432 {
433 int rv;
434 int err = 0;
435 int fd;
436
437 if (offset + size > e->size)
438 return EINVAL;
439
440 fd = open(e->dev, O_RDONLY);
441 if (fd == -1)
442 return errno;
443 if (lseek(fd, offset, SEEK_SET) == -1) {
444 err = errno;
445 close(fd);
446 return err;
447 }
448 rv = read(fd, data, size);
449 if (rv == -1)
450 err = errno;
451 else if (rv < size)
452 err = EIO;
453 close(fd);
454 return err;
455 }
456
457 /* Note: Data must be at least e->size */
458 static int
write_eeprom(const struct eeprom * e,unsigned char * data,unsigned int offset,unsigned int size)459 write_eeprom(const struct eeprom *e, unsigned char *data,
460 unsigned int offset, unsigned int size)
461 {
462 int rv;
463 int err = 0;
464 int fd;
465
466 if (size + offset > e->size)
467 return EINVAL;
468
469 fd = open(e->dev, O_WRONLY);
470 if (fd == -1)
471 return errno;
472 if (lseek(fd, offset, SEEK_SET) == -1) {
473 close(fd);
474 return errno;
475 }
476 rv = write(fd, data, size);
477 if (rv == -1)
478 err = errno;
479 else if (rv < size)
480 err = EIO;
481 close(fd);
482 return err;
483 }
484
485
486 /**************************************************************************
487 * General file handling. These are functions that read and write
488 * sysfs files, generally.
489 *************************************************************************/
490
491 /*
492 * Convert an integer value to a string and write it to the device.
493 */
494 static int
set_intval(const char * fname,unsigned int val)495 set_intval(const char *fname, unsigned int val)
496 {
497 FILE *f;
498
499 f = fopen(fname, "w");
500 if (!f)
501 return errno;
502 fprintf(f, "%u\n", val);
503 fclose(f);
504 return 0;
505 }
506
507 /*
508 * Fetch an unsigned integer ASCII value from a file an convert it.
509 */
510 static int
get_uintval(const char * fname,unsigned int * val)511 get_uintval(const char *fname, unsigned int *val)
512 {
513 FILE *f;
514 char line[80];
515 size_t rv;
516
517 f = fopen(fname, "r");
518 if (!f)
519 return errno;
520 rv = fread(line, 1, sizeof(line), f);
521 if (rv == 0) {
522 int retval = 0;
523 if (ferror(f)) {
524 retval = errno;
525 }
526 fclose(f);
527 return retval;
528 }
529 fclose(f);
530 *val = strtoul(line, NULL, 0);
531 return 0;
532 }
533
534 /*
535 * Fetch a signed integer ASCII value from a file an convert it.
536 */
537 static int
get_intval(const char * fname,int * val)538 get_intval(const char *fname, int *val)
539 {
540 FILE *f;
541 char line[80];
542 size_t rv;
543
544 f = fopen(fname, "r");
545 if (!f)
546 return errno;
547 rv = fread(line, 1, sizeof(line), f);
548 if (rv == 0) {
549 int retval = 0;
550 if (ferror(f)) {
551 retval = errno;
552 }
553 fclose(f);
554 return retval;
555 }
556 fclose(f);
557 *val = strtol(line, NULL, 0);
558 return 0;
559 }
560
561
562 /**************************************************************************
563 * Board power handling.
564 *
565 * This is kept as a list of boards waiting to power on. Only one
566 * board may be waiting at a time, and the first thing in
567 * boards_waiting_power_on will be the next thing to power on.
568 *************************************************************************/
569
570 static ipmi_timer_t *power_timer;
571 static unsigned int boards_waiting_power_on[NUM_BOARDS];
572 static unsigned int num_boards_waiting_power_on;
573 static enum {
574 PT_NOT_RUNNING,
575 PT_RUNNING,
576 PT_WAITING_RESET
577 } power_timer_running;
578
579 /*
580 * Return true if the board is on, false if not.
581 */
582 static int
board_power_state(sys_data_t * sys,unsigned int num)583 board_power_state(sys_data_t *sys, unsigned int num)
584 {
585 int rv;
586 unsigned int rval;
587
588 rv = get_uintval(trg_power[num], &rval);
589 if (rv) {
590 sys->log(sys, OS_ERROR, NULL,
591 "Unable to read board %u power state: %s",
592 num + 1, strerror(rv));
593 return 0;
594 }
595 return rval == BOARD_POWER_ON;
596 }
597
598 /*
599 * Return true if the given board number is waiting to power on.
600 */
601 static int
board_waiting_power_on(unsigned int num)602 board_waiting_power_on(unsigned int num)
603 {
604 unsigned int i;
605
606 for (i = 0; i < num_boards_waiting_power_on; i++) {
607 if (boards_waiting_power_on[i] == num)
608 return 1;
609 }
610 return 0;
611 }
612
613 /*
614 * Start the timer to power on the board. The time will be
615 * mintime + rand[1-6].
616 */
617 static void
start_power_timer(sys_data_t * sys,unsigned int mintime)618 start_power_timer(sys_data_t *sys, unsigned int mintime)
619 {
620 struct timeval tv;
621 unsigned int to_add;
622
623 sys->gen_rand(sys, &to_add, sizeof(to_add));
624 to_add %= 5;
625 to_add += 1 + mintime;
626 tv.tv_sec = to_add;
627 tv.tv_usec = 0;
628
629 if (debug & 1)
630 sys->log(sys, DEBUG, NULL, "Starting power timer on board %u for"
631 " %u seconds",
632 boards_waiting_power_on[0] + 1, to_add);
633 sys->start_timer(power_timer, &tv);
634 power_timer_running = PT_RUNNING;
635 }
636
637 /*
638 * Set the given board number waiting to power up.
639 */
640 static void
board_add_power_wait(sys_data_t * sys,unsigned int num)641 board_add_power_wait(sys_data_t *sys, unsigned int num)
642 {
643 boards_waiting_power_on[num_boards_waiting_power_on] = num;
644 num_boards_waiting_power_on++;
645 if (num_boards_waiting_power_on == 1)
646 start_power_timer(sys, 0);
647 }
648
649 /*
650 * Remove the board from the power up wait list and start the next
651 * board, if there is one.
652 */
653 static void
board_remove_power_wait(sys_data_t * sys,unsigned int num)654 board_remove_power_wait(sys_data_t *sys, unsigned int num)
655 {
656 unsigned int i;
657
658 for (i = 0; i < num_boards_waiting_power_on; i++) {
659 if (boards_waiting_power_on[i] == num)
660 break;
661 }
662 if (i == num_boards_waiting_power_on)
663 /* Not found */
664 return;
665 for (; i < num_boards_waiting_power_on - 1; i++)
666 boards_waiting_power_on[i] = boards_waiting_power_on[i + 1];
667 num_boards_waiting_power_on--;
668
669 if (num_boards_waiting_power_on == 0) {
670 sys->stop_timer(power_timer);
671 if (!init_complete) {
672 set_intval(COLD_POWER_FILE, 0);
673 init_complete = 1;
674 }
675 } else if (power_timer_running == PT_NOT_RUNNING)
676 start_power_timer(sys, 5);
677 }
678
679 static int
set_chassis_control(lmc_data_t * mc,int op,unsigned char * val,void * cb_data)680 set_chassis_control(lmc_data_t *mc, int op, unsigned char *val, void *cb_data)
681 {
682 struct board_info *board = cb_data;
683 sys_data_t *sys = board->sys;
684 unsigned int num = board->num;
685 int wval;
686 int rv, err;
687
688 switch (op) {
689 case CHASSIS_CONTROL_POWER:
690 if (debug & 1) {
691 struct timeval now;
692 board->sys->get_real_time(board->sys, &now);
693 sys->log(sys, DEBUG, NULL, "Power request for board %d,"
694 " val=%d, wait=%d last=%ld.%ld, now=%ld.%ld",
695 board->num + 1, *val, board->waiting_power_off,
696 last_board_power_on.tv_sec, last_board_power_on.tv_sec,
697 now.tv_sec, now.tv_sec);
698 }
699 if (debug & 1 && board->waiting_power_off)
700 sys->log(sys, DEBUG, NULL, "Canceling power off wait on"
701 "board power request for board %d", board->num + 1);
702
703 /* It's going to be forced on or off soon, just disable this. */
704 board->waiting_power_off = 0;
705 set_intval(pow_off_request[num], BOARD_OFF_REQUEST_OFF);
706
707 if (*val) {
708 if (!board->present) {
709 if (debug & 1)
710 sys->log(sys, DEBUG, NULL, "Power on request while board"
711 " not present on %d", num + 1);
712 return EAGAIN;
713 }
714 if (!board_power_state(sys, num) && !board_waiting_power_on(num))
715 board_add_power_wait(sys, num);
716 else if (debug & 1)
717 sys->log(sys, DEBUG, NULL, "Power on request, but board was"
718 " alread on or waiting power up on board %d", num + 1);
719
720 /* We always delay for a power on. */
721 break;
722 }
723
724 /* We are powering off. */
725 if (board_waiting_power_on(num)) {
726 /* Don't power on later. */
727 if (debug & 1)
728 sys->log(sys, DEBUG, NULL, "Stopping board power timer"
729 " on %d", num + 1);
730 board_remove_power_wait(sys, num);
731 }
732 if (debug & 1)
733 sys->log(sys, DEBUG, NULL, "Setting board power off on %d",
734 num + 1);
735 rv = set_intval(trg_power[num], BOARD_POWER_OFF);
736 if (rv) {
737 sys->log(sys, OS_ERROR, NULL, "Warning: Unable to set power off"
738 " for board %d: %s", board->num, strerror(rv));
739 return rv;
740 }
741
742 /*
743 * We require a 0->1 transition for the power request to be
744 * honored, so start at 1 for the next time to avoid board
745 * insertion or startup issues.
746 */
747 board->last_power_request = BOARD_OFF_READY;
748 break;
749
750 case CHASSIS_CONTROL_RESET:
751 if (debug & 1)
752 sys->log(sys, DEBUG, NULL, "Resetting board %d", board->num + 1);
753 set_intval(trg_reset[num], BOARD_RESET_ON);
754 set_intval(trg_reset[num], BOARD_RESET_OFF);
755 break;
756
757 case CHASSIS_CONTROL_BOOT_INFO_ACK:
758 /* Just ignore this for now */
759 break;
760
761 case CHASSIS_CONTROL_BOOT:
762 if (debug & 1)
763 sys->log(sys, DEBUG, NULL, "Chassis control on %d present=%d, "
764 "fru_good=%d, val=%d",
765 board->num + 1, boards[num].present,
766 boards[num].fru_good, *val);
767 if (!boards[num].present)
768 return EAGAIN;
769 if (!boards[num].fru_good)
770 return EBADFD;
771 switch (*val) {
772 case 0: /* none */
773 return 0;
774
775 case 1: /* pxe */
776 wval = 1;
777 break;
778
779 case 2: /* default */
780 wval = 0;
781 break;
782
783 default:
784 return EINVAL;
785 }
786
787 rv = ipmi_mc_fru_sem_trywait(boards[num].mc, 0);
788 if (rv)
789 return rv;
790
791 boards[num].fru[11] = wval;
792 rv = write_eeprom(&board_i2c[num].fru, boards[num].fru + 11, 11, 1);
793 if (rv) {
794 sys->log(sys, OS_ERROR, NULL, "Warning: Error writing board %d"
795 " PXE boot: %s", num + 1, strerror(rv));
796 } else {
797 boards[num].fru[79] = -checksum(boards[num].fru + 8, 71);
798 rv = write_eeprom(&board_i2c[num].fru, boards[num].fru + 79, 79, 1);
799 if (rv) {
800 sys->log(sys, OS_ERROR, NULL, "Warning: Error writing"
801 " board %d"
802 " PXE boot checksum: %s", num + 1, strerror(rv));
803 rv = 0;
804 }
805 }
806 err = ipmi_mc_fru_sem_post(board->mc, 0);
807 if (err)
808 sys->log(sys, OS_ERROR, NULL,
809 "Error posting board %d semaphore: %s", num + 1,
810 strerror(err));
811 return rv;
812
813 case CHASSIS_CONTROL_GRACEFUL_SHUTDOWN:
814 if (board_waiting_power_on(num)) {
815 if (debug & 1)
816 sys->log(sys, DEBUG, NULL, "Graceful shutdown requested on %d,"
817 " shutting down power on timer", board->num + 1);
818 board_remove_power_wait(sys, num);
819 } else if (board->waiting_power_off) {
820 /* Nothing to do, already waiting. */
821 } else if (board_power_state(sys, num)) {
822 if (debug & 1)
823 sys->log(sys, DEBUG, NULL, "Graceful shutdown requested on %d,"
824 " requesting board power off", board->num + 1);
825 board->waiting_power_off = 1;
826 board->power_off_countdown = 30;
827 set_intval(pow_off_request[num], BOARD_OFF_REQUEST_ON);
828 }
829 break;
830
831 default:
832 return EINVAL;
833 }
834 return 0;
835 }
836
837 static int
get_chassis_control(lmc_data_t * mc,int op,unsigned char * val,void * cb_data)838 get_chassis_control(lmc_data_t *mc, int op, unsigned char *val, void *cb_data)
839 {
840 struct board_info *board = cb_data;
841 sys_data_t *sys = board->sys;
842 unsigned int num = board->num;
843 unsigned char cval;
844 int rv, err;
845
846 switch (op) {
847 case CHASSIS_CONTROL_POWER:
848 *val = (board_power_state(board->sys, num) ||
849 board_waiting_power_on(num));
850 break;
851
852 case CHASSIS_CONTROL_BOOT_INFO_ACK:
853 val[0] = 0;
854 val[1] = 0;
855 break;
856
857 case CHASSIS_CONTROL_BOOT:
858 rv = ipmi_mc_fru_sem_trywait(boards[num].mc, 0);
859 if (rv)
860 return rv;
861 rv = read_eeprom(&board_i2c[num].fru, &cval, 11, 1);
862 if (rv)
863 goto out_post;
864 switch(cval) {
865 case 0:
866 *val = 2; /* default disk */
867 break;
868 case 1:
869 *val = 1; /* pxe */
870 break;
871
872 default:
873 *val = 0; /* Shouldn't happen */
874 break;
875 }
876 out_post:
877 err = ipmi_mc_fru_sem_post(board->mc, 0);
878 if (err)
879 sys->log(sys, OS_ERROR, NULL,
880 "Error posting board %d semaphore: %s", num + 1,
881 strerror(err));
882 return rv;
883
884 default:
885 return EINVAL;
886 }
887 return 0;
888 }
889
890 /*
891 * Chassis control for the chassis. This will perform the operation on
892 * all boards.
893 */
894 static int
bmc_set_chassis_control(lmc_data_t * mc,int op,unsigned char * val,void * cb_data)895 bmc_set_chassis_control(lmc_data_t *mc, int op, unsigned char *val,
896 void *cb_data)
897 {
898 sys_data_t *sys = cb_data;
899 unsigned int i;
900
901 switch (op) {
902 case CHASSIS_CONTROL_POWER:
903 case CHASSIS_CONTROL_RESET:
904 case CHASSIS_CONTROL_BOOT_INFO_ACK:
905 case CHASSIS_CONTROL_BOOT:
906 case CHASSIS_CONTROL_GRACEFUL_SHUTDOWN:
907 break;
908 default:
909 return EINVAL;
910 }
911
912 if (debug & 1) {
913 struct timeval now;
914 sys->get_real_time(sys, &now);
915 sys->log(sys, DEBUG, NULL, "Power request for all boards,"
916 " val=%d, now=%ld.%ld",
917 *val, now.tv_sec, now.tv_sec);
918 }
919
920 for (i = 0; i < NUM_BOARDS; i++)
921 set_chassis_control(NULL, op, val, &boards[i]);
922
923 return 0;
924 }
925
926 /*
927 * Chassis control get for the chassis. This only works for the power
928 * control, and will return on if any board in the chassis is on, and
929 * off otherwise.
930 */
931 static int
bmc_get_chassis_control(lmc_data_t * mc,int op,unsigned char * val,void * cb_data)932 bmc_get_chassis_control(lmc_data_t *mc, int op, unsigned char *val,
933 void *cb_data)
934 {
935 unsigned int i;
936
937 if (op == CHASSIS_CONTROL_POWER) {
938 unsigned char rval = 0, tval;
939
940 /* If any board is on, report power as on. */
941 for (i = 0; i < NUM_BOARDS; i++) {
942 get_chassis_control(NULL, op, &tval, &boards[i]);
943 if (tval)
944 rval = 1;
945 }
946 *val = rval;
947 return 0;
948 }
949
950 /* This doesn't make sense for anything else. */
951 return EINVAL;
952 }
953
954 static void
board_power_timeout(void * cb_data)955 board_power_timeout(void *cb_data)
956 {
957 sys_data_t *sys = cb_data;
958 unsigned int num = boards_waiting_power_on[0];
959 struct board_info *board = &boards[num];
960 int rv;
961
962 if (num_boards_waiting_power_on == 0) {
963 sys->log(sys, SETUP_ERROR, NULL, "Warning: power timer went off"
964 " but no board waiting");
965 return;
966 }
967
968 if (power_timer_running == PT_RUNNING) {
969 struct timeval tv;
970
971 if (debug & 1)
972 sys->log(sys, DEBUG, NULL, "Powering on board %d", num + 1);
973
974 /* Hold the reset on the board for 100ms while it powers on. */
975 set_intval(trg_reset[num], BOARD_RESET_ON);
976
977 rv = set_intval(trg_power[num], BOARD_POWER_ON);
978 if (rv)
979 sys->log(sys, OS_ERROR, NULL, "Warning: Unable to set power on"
980 " for board %d: %s", num, strerror(rv));
981
982 /* Start the 100ms reset timer */
983 if (debug & 1)
984 sys->log(sys, DEBUG, NULL, "Starting reset timer on board %u",
985 num + 1);
986 power_timer_running = PT_WAITING_RESET;
987 tv.tv_sec = 0;
988 tv.tv_usec = 100000;
989 sys->start_timer(power_timer, &tv);
990 } else {
991 /* Take the board out of reset. */
992 set_intval(trg_reset[num], BOARD_RESET_OFF);
993
994 power_timer_running = PT_NOT_RUNNING;
995
996 /* Starts the next one if something is waiting. */
997 board_remove_power_wait(sys, num);
998 }
999 }
1000
1001 static void
power_down_system(sys_data_t * sys)1002 power_down_system(sys_data_t *sys)
1003 {
1004 unsigned int i;
1005 unsigned char val = 0;
1006
1007 for (i = 0; i < NUM_BOARDS; i++)
1008 set_chassis_control(NULL, CHASSIS_CONTROL_POWER, &val, &boards[i]);
1009 }
1010
1011 /*
1012 * Called at init time to make sure the board state is sane.
1013 */
1014 static void
check_chassis_state(sys_data_t * sys)1015 check_chassis_state(sys_data_t *sys)
1016 {
1017 unsigned int i;
1018
1019 /*
1020 * Make sure the reset is off on all boards. The power state will
1021 * be set later.
1022 */
1023 for (i = 0; i < NUM_BOARDS; i++)
1024 set_intval(trg_reset[i], BOARD_RESET_OFF);
1025 }
1026
1027 /**************************************************************************
1028 * Sensor handling
1029 *************************************************************************/
1030
1031 /*
1032 * The DIMM and CPU error sensors will remain set until rearmed. This
1033 * is the rearm handling to clear those bits.
1034 */
1035 struct eesense_rearm
1036 {
1037 unsigned int num;
1038 unsigned int offset;
1039 unsigned char mask;
1040 };
1041
1042 static int
rearm_eesense_sensor(void * cb_data,uint16_t assert,uint16_t deassert)1043 rearm_eesense_sensor(void *cb_data,
1044 uint16_t assert,
1045 uint16_t deassert)
1046 {
1047 struct eesense_rearm *info = cb_data;
1048 unsigned int num = info->num;
1049 unsigned int off = info->offset;
1050 unsigned char mask = info->mask;
1051 struct board_info *board = &boards[num];
1052 sys_data_t *sys = board->sys;
1053 unsigned char data[72];
1054 unsigned int i;
1055 int rv, err;
1056
1057 if (!(assert & mask))
1058 return 0;
1059
1060 rv = ipmi_mc_fru_sem_trywait(boards[num].mc, 0);
1061 if (rv)
1062 return rv;
1063
1064 rv = read_eeprom(&board_i2c[num].fru, data, 8, 72);
1065 if (rv) {
1066 sys->log(sys, OS_ERROR, NULL,
1067 "Warning: Error reading board %d fru: %s",
1068 num + 1, strerror(rv));
1069 goto out_post;
1070 }
1071
1072 if (!(data[off] & mask))
1073 goto out_post;
1074
1075 data[off] &= ~mask;
1076 data[71] = -checksum(data, 71);
1077
1078 rv = write_eeprom(&board_i2c[num].fru, data + off, 8 + off, 1);
1079 if (rv) {
1080 sys->log(sys, OS_ERROR, NULL,
1081 "Warning: Error writing board %d"
1082 " sensor data: %s", num + 1, strerror(rv));
1083 goto out_post;
1084 }
1085
1086 for (i = 0; i < 8; i++)
1087 ipmi_mc_sensor_set_bit(boards[num].mc, 0, 19 + off, i,
1088 ((data[off] >> i) & 1), 0);
1089
1090 rv = write_eeprom(&board_i2c[num].fru, data + 71, 79, 1);
1091 if (rv) {
1092 sys->log(sys, OS_ERROR, NULL,
1093 "Warning: Error writing board %d"
1094 " internal use checksum: %s", num + 1, strerror(rv));
1095 rv = 0;
1096 }
1097
1098 out_post:
1099 err = ipmi_mc_fru_sem_post(board->mc, 0);
1100 if (err)
1101 sys->log(sys, OS_ERROR, NULL,
1102 "Error posting board %d semaphore: %s", num + 1,
1103 strerror(err));
1104
1105 return rv;
1106 }
1107
1108 /*
1109 * The rearm for the power supply sensor will set the clear fault flag
1110 * for the power supply, just to be sure it is clear.
1111 */
1112 static int
rearm_power_supply_sensor(void * cb_data,uint16_t assert,uint16_t deassert)1113 rearm_power_supply_sensor(void *cb_data,
1114 uint16_t assert,
1115 uint16_t deassert)
1116 {
1117 unsigned int num = (unsigned long) cb_data;
1118 sys_data_t *sys = boards[0].sys;
1119 int rv;
1120 char fname[100];
1121
1122 if (!(assert & 2))
1123 return 0;
1124
1125 sprintf(fname, "/sys/class/wixpmbus/CLEAR_FAULT_%d", num);
1126 rv = set_intval(fname, 1);
1127 if (rv) {
1128 sys->log(sys, OS_ERROR, NULL,
1129 "Error writing ps %d clear file: %s", num, strerror(rv));
1130 return rv;
1131 }
1132 return 0;
1133 }
1134
1135
1136 /**************************************************************************
1137 * Board handling
1138 *************************************************************************/
1139
1140 /*
1141 * Read the board's FRU and update anything that needs to be updated,
1142 * like the chassis information, the board's external MAC address, etc.
1143 */
1144 static int
handle_board_fru(sys_data_t * sys,int num)1145 handle_board_fru(sys_data_t *sys, int num)
1146 {
1147 int rv;
1148 unsigned int iuse;
1149 unsigned int iuse_len;
1150 unsigned int chinfo;
1151 unsigned int chinfo_len;
1152 unsigned int brdinfo;
1153 unsigned int brdinfo_len;
1154 unsigned int mac_offset;
1155 unsigned int brdchsernum_offset;
1156 unsigned int brdsernum_offset;
1157 int modified = 0;
1158 int fruversion2 = 0;
1159 unsigned char *fru;
1160
1161 if (debug & 1)
1162 sys->log(sys, DEBUG, NULL, "Checking board FRU on board %d", num + 1);
1163
1164 /* Guilty until proven innocent */
1165 boards[num].fru_good = 0;
1166
1167 rv = read_eeprom(&board_i2c[num].fru, boards[num].fru,
1168 0, board_i2c[num].fru.size);
1169 if (rv) {
1170 sys->log(sys, SETUP_ERROR, NULL, "Can't read board %d eeprom: %s",
1171 num + 1, strerror(rv));
1172 return 0;
1173 }
1174
1175 fru = boards[num].fru;
1176
1177 if (fru[0] != 1) {
1178 sys->log(sys, SETUP_ERROR, NULL, "Invalid board %d FRU version: 0x%x",
1179 num + 1, fru[0]);
1180 return 0;
1181 }
1182
1183 if (checksum(fru + 0, 8) != 0) {
1184 sys->log(sys, SETUP_ERROR, NULL, "Warning: Board %d FRU header"
1185 " checksum fail", num + 1);
1186 }
1187
1188 iuse = fru[1] * 8;
1189 iuse_len = 80 - 8;
1190 chinfo = fru[2] * 8;
1191 chinfo_len = 256 - 80;
1192 brdinfo = fru[3] * 8;
1193 brdinfo_len = 2048 - 256;
1194 brdchsernum_offset = 42;
1195 brdsernum_offset = 74;
1196 mac_offset = 95;
1197
1198 if (iuse != 8) {
1199 sys->log(sys, SETUP_ERROR, NULL, "Warning: Board %d FRU internal use"
1200 "area is not at offset 8", num + 1);
1201 return 0;
1202 }
1203 if (chinfo != 80) {
1204 sys->log(sys, SETUP_ERROR, NULL, "Warning: Board %d FRU chassis info"
1205 "area is not at offset 80", num + 1);
1206 return 0;
1207 }
1208 if (brdinfo != 256) {
1209 sys->log(sys, SETUP_ERROR, NULL, "Warning: Board %d FRU board info"
1210 "area is not at offset 256", num + 1);
1211 return 0;
1212 }
1213 if (checksum(fru + iuse, iuse_len) != 0) {
1214 sys->log(sys, SETUP_ERROR, NULL, "Warning: Board %d FRU internal use"
1215 " checksum fail", num + 1);
1216 return 0;
1217 }
1218 if (checksum(fru + chinfo, chinfo_len) != 0) {
1219 sys->log(sys, SETUP_ERROR, NULL, "Warning: Board %d FRU chassis info"
1220 " checksum fail", num + 1);
1221 return 0;
1222 }
1223 if (checksum(fru + brdinfo, brdinfo_len) != 0) {
1224 sys->log(sys, SETUP_ERROR, NULL, "Warning: Board %d FRU board info"
1225 " checksum fail", num + 1);
1226 return 0;
1227 }
1228 boards[num].fru_good = 1;
1229
1230 /* Set the chassis information if it is not correct. */
1231 if (chassis_fru[chinfo + brdchsernum_offset] != 0xd4) {
1232 /* Try the version 2.0 of the FRU data */
1233 brdchsernum_offset = 17;
1234 }
1235 if (sernum_len == 0) {
1236 sys->log(sys, SETUP_ERROR, NULL, "Warning: FRU chassis serial number"
1237 " invalid, not setting board %d data", num + 1);
1238 } else if (chassis_chinfo == 0) {
1239 sys->log(sys, SETUP_ERROR, NULL, "Warning: Chassis chassis info FRU"
1240 "invalid, not checking board %d FRU chassis data", num + 1);
1241 } else {
1242 /*
1243 * If we have a different FRU version, or if the serial
1244 * numbers don't match, then update the chassis info area.
1245 */
1246 if ((brdchsernum_offset != sernum_offset) ||
1247 memcmp(fru + chinfo + brdchsernum_offset,
1248 chassis_fru + chassis_chinfo + sernum_offset,
1249 sernum_len) != 0) {
1250 /* The chassis serial number has changed. */
1251 sys->log(sys, INFO, NULL, "Info: Updating board %d"
1252 " chassis info area", num + 1);
1253 memcpy(fru + chinfo, chassis_fru + chassis_chinfo,
1254 chassis_chinfo_len);
1255 rv = write_eeprom(&board_i2c[num].fru, fru + chinfo, chinfo,
1256 chassis_chinfo_len);
1257 if (rv) {
1258 sys->log(sys, OS_ERROR, NULL,
1259 "Warning: Error writing board %d"
1260 " chassis info: %s", num + 1, strerror(rv));
1261 }
1262 }
1263 }
1264
1265 /* Set the board system serial number if it is not correct. */
1266 if (fru[brdinfo + brdsernum_offset] != 0xd4) {
1267 /* FRU version 2.0 */
1268 brdsernum_offset = 34;
1269 fruversion2 = 1;
1270 }
1271 if (fru[brdinfo + brdsernum_offset] != 0xd4) {
1272 sys->log(sys, SETUP_ERROR, NULL, "Warning: Board %d FRU serial num"
1273 " data invalid", num + 1);
1274 } else if (!sernum[0]) {
1275 sys->log(sys, SETUP_ERROR, NULL, "Warning: System serial num invalid,"
1276 " not checking board %d ser num", num + 1);
1277 } else {
1278 char mysernum[21];
1279
1280 if (fruversion2) {
1281 int len;
1282 len = sprintf(mysernum, "%s-%c", sernum, num + 'A');
1283 memset(mysernum + len, ' ', 20 - len);
1284 mysernum[20] = '\0';
1285 } else {
1286 memset(mysernum, 0, 21);
1287 sprintf(mysernum, "System SN %s-%c", sernum, num + 'A');
1288 }
1289
1290 if (memcmp(mysernum, fru + brdinfo + brdsernum_offset + 1, 20) != 0) {
1291 sys->log(sys, INFO, NULL, "Info: Updating board %d"
1292 " serial number", num + 1);
1293 memcpy(fru + brdinfo + brdsernum_offset + 1, mysernum, 20);
1294 rv = write_eeprom(&board_i2c[num].fru,
1295 fru + brdinfo + brdsernum_offset + 1,
1296 brdinfo + brdsernum_offset + 1,
1297 20);
1298 if (rv) {
1299 sys->log(sys, OS_ERROR, NULL,
1300 "Warning: Error writing board %d"
1301 " serial num: %s", num + 1, strerror(rv));
1302 }
1303 modified = 1;
1304 }
1305 }
1306
1307 /* Set the board MAC address if it is not correct. */
1308 if (fru[brdinfo + mac_offset] != 0xdc) {
1309 sys->log(sys, SETUP_ERROR, NULL, "Warning: Board %d FRU external MAC"
1310 " data invalid", num + 1);
1311 } else if (!sysmac[0]) {
1312 sys->log(sys, SETUP_ERROR, NULL, "Warning: System MAC invalid, not"
1313 " checking board %d MAC", num + 1);
1314 } else {
1315 char mac[29];
1316
1317 memset(mac, 0, 29);
1318 sprintf(mac, "System MAC %s%d", sysmac, num + 1);
1319 if (memcmp(mac, fru + brdinfo + mac_offset + 1, 28) != 0) {
1320 sys->log(sys, INFO, NULL, "Info: Updating board %d"
1321 " MAC address", num + 1);
1322 memcpy(fru + brdinfo + mac_offset + 1, mac, 28);
1323 rv = write_eeprom(&board_i2c[num].fru,
1324 fru + brdinfo + mac_offset + 1,
1325 brdinfo + mac_offset + 1,
1326 28);
1327 if (rv) {
1328 sys->log(sys, OS_ERROR, NULL,
1329 "Warning: Error writing board %d"
1330 " MAC address: %s", num + 1, strerror(rv));
1331 }
1332 modified = 1;
1333 }
1334 }
1335
1336 if (modified) {
1337 /* Recalculate the board checksum */
1338 fru[brdinfo + brdinfo_len - 1] = -checksum(fru + brdinfo,
1339 brdinfo_len - 1);
1340
1341 rv = write_eeprom(&board_i2c[num].fru, fru + brdinfo + brdinfo_len - 1,
1342 brdinfo + brdinfo_len - 1, 1);
1343 if (rv) {
1344 sys->log(sys, OS_ERROR, NULL, "Warning: Error writing board %d"
1345 " board info checksum: %s", num + 1, strerror(rv));
1346 }
1347 }
1348 return 0;
1349 }
1350
1351 /*
1352 * Check that the board has not changed states, and if it has then
1353 * handle the change. Called on insertion/removal events and
1354 * periodically by a timer.
1355 */
1356 static int
check_board(sys_data_t * sys,int num,unsigned int since_last,int power_up_new_board)1357 check_board(sys_data_t *sys, int num, unsigned int since_last,
1358 int power_up_new_board)
1359 {
1360 int rv;
1361 unsigned int present;
1362 unsigned int rval;
1363 unsigned char val;
1364 struct board_info *board = &boards[num];
1365
1366 if (board->present && board_power_state(sys, num)) {
1367 rv = get_uintval(pow_off_ready[num], &rval);
1368 if (rv) {
1369 sys->log(sys, OS_ERROR, NULL,
1370 "Unable to read board %u power off ready: %s",
1371 num, strerror(rv));
1372 } else {
1373 if (board->last_power_request == BOARD_OFF_NOT_READY &&
1374 rval == BOARD_OFF_READY) {
1375 if (debug & 1) {
1376 if (board->waiting_power_off)
1377 sys->log(sys, DEBUG, NULL, "Graceful power of finished"
1378 " on %d, setting power off", board->num + 1);
1379 else
1380 sys->log(sys, DEBUG, NULL, "Board %d requested power"
1381 " off, setting power off", board->num + 1);
1382 }
1383 val = 0;
1384 set_chassis_control(NULL, CHASSIS_CONTROL_POWER, &val, board);
1385 }
1386 board->last_power_request = rval;
1387 }
1388 }
1389
1390 if (board->waiting_power_off && since_last) {
1391 if (board->power_off_countdown == 0) {
1392 unsigned char val;
1393
1394 if (debug & 1)
1395 sys->log(sys, DEBUG, NULL, "Graceful power off timeout"
1396 " on %d, forcing power off", board->num + 1);
1397 val = 0;
1398 set_chassis_control(NULL, CHASSIS_CONTROL_POWER, &val, board);
1399 } else {
1400 board->power_off_countdown--;
1401 }
1402 }
1403
1404 rv = get_uintval(trg_present[num], &present);
1405 if (rv) {
1406 sys->log(sys, OS_ERROR, NULL, "Unable to read board %d presence: %s",
1407 num + 1, strerror(rv));
1408 return rv;
1409 }
1410 present = (present == BOARD_PRESENT) && !simulate_board_absent[num];
1411 if (board->present == present)
1412 return 0;
1413
1414 board->present = present;
1415 if (!present) {
1416 sys->log(sys, INFO, NULL, "Info: board %d has been removed", num + 1);
1417
1418 board->fru_good = 0;
1419
1420 /*
1421 * Turn off board power when not present, that way we can hold
1422 * off power on until we are done with messing with the board FRU
1423 * data.
1424 */
1425 val = 0;
1426 set_chassis_control(NULL, CHASSIS_CONTROL_POWER, &val, board);
1427 return 0;
1428 }
1429
1430 sys->log(sys, INFO, NULL, "Info: board %d is now present", num + 1);
1431
1432 rv = create_eeprom(sys, board_i2c[num].add_dev, &board_i2c[num].fru);
1433 if (rv) {
1434 /* Force a retry, perhaps the device hasn't been created yet */
1435 board->present = 0;
1436 sys->log(sys, SETUP_ERROR, NULL, "Can't create board %d eeprom: %s."
1437 " Will retry in a second",
1438 num + 1, strerror(rv));
1439 return 0;
1440 }
1441
1442 rv = handle_board_fru(sys, num);
1443 if (rv)
1444 return rv;
1445
1446 if (power_up_new_board) {
1447 /* If the board was not present and now it is, power it on. */
1448 val = 1;
1449 set_chassis_control(NULL, CHASSIS_CONTROL_POWER, &val, board);
1450 }
1451
1452 return 0;
1453 }
1454
1455 /*
1456 * If the board front-panel button is pressed, record the time, the
1457 * button will be handled on release.
1458 */
1459 static void
handle_button_press(sys_data_t * sys,unsigned int brdnum)1460 handle_button_press(sys_data_t *sys, unsigned int brdnum)
1461 {
1462 struct board_info *board = &boards[brdnum];
1463
1464 if (debug & 1)
1465 sys->log(sys, DEBUG, NULL, "Button press on %d", board->num + 1);
1466
1467 board->button_pressed = 1;
1468 board->sys->get_monotonic_time(board->sys, &board->button_press_time);
1469 }
1470
1471 /*
1472 * Handle the board's front-panel button.
1473 */
1474 static void
handle_button_release(sys_data_t * sys,unsigned int num)1475 handle_button_release(sys_data_t *sys, unsigned int num)
1476 {
1477 struct timeval now;
1478 unsigned char val;
1479 struct board_info *board = &boards[num];
1480 int power_state = board_power_state(sys, num);
1481
1482 if (!board->button_pressed)
1483 return;
1484
1485 if (debug & 1)
1486 sys->log(sys, DEBUG, NULL, "Button release on %d", num + 1);
1487
1488 board->button_pressed = 0;
1489
1490 board->sys->get_monotonic_time(board->sys, &now);
1491
1492 /*
1493 * If the button is pressed more than 4 seconds, start a graceful
1494 * shutdown.
1495 */
1496 if (power_state &&
1497 (diff_timeval_ms(&now, &board->button_press_time) > 4000)) {
1498 if (board_waiting_power_on(num)) {
1499 if (debug & 1)
1500 sys->log(sys, DEBUG, NULL, "Button press on %d >4sec, stop"
1501 " power on timer", board->num + 1);
1502 board_remove_power_wait(sys, num);
1503 } else {
1504 if (debug & 1)
1505 sys->log(sys, DEBUG, NULL, "Button press on %d >4sec, start"
1506 " graceful shutdown", board->num + 1);
1507 val = 0;
1508 set_chassis_control(NULL, CHASSIS_CONTROL_GRACEFUL_SHUTDOWN,
1509 &val, board);
1510 }
1511 }
1512
1513 /*
1514 * If the button is pressed less than 4 seconds, start a power up
1515 * if the board is not already on.
1516 */
1517 if (!power_state &&
1518 (diff_timeval_ms(&now, &board->button_press_time) <= 4000)) {
1519 if (debug & 1)
1520 sys->log(sys, DEBUG, NULL, "Button press on %d <4sec, power on",
1521 board->num + 1);
1522
1523 val = 1;
1524 set_chassis_control(NULL, CHASSIS_CONTROL_POWER, &val, board);
1525 }
1526 }
1527
1528 /*
1529 * Read data from the chassis FRU.
1530 */
1531 static int
init_chassis(sys_data_t * sys)1532 init_chassis(sys_data_t *sys)
1533 {
1534 int rv;
1535
1536 if (debug & 1)
1537 sys->log(sys, DEBUG, NULL, "Reading chassis eeprom info");
1538
1539 /* Detect which I2C channel to use for the chassis I2C. */
1540 rv = check_eeprom(sys, &chassis_i2c_new.fru);
1541 if (rv) {
1542 rv = check_eeprom(sys, &chassis_i2c_old.fru);
1543 if (rv) {
1544 sys->log(sys, SETUP_ERROR, NULL, "Can't find chassis eeprom: %s",
1545 strerror(rv));
1546 return rv;
1547 }
1548 chassis_i2c = &chassis_i2c_old;
1549 } else {
1550 chassis_i2c = &chassis_i2c_new;
1551 }
1552
1553 rv = read_eeprom(&chassis_i2c->fru, chassis_fru, 0, chassis_i2c->fru.size);
1554 if (rv) {
1555 sys->log(sys, SETUP_ERROR, NULL, "Can't read chassis eeprom: %s",
1556 strerror(rv));
1557 return rv;
1558 }
1559
1560 if (chassis_fru[0] != 1) {
1561 sys->log(sys, SETUP_ERROR, NULL, "Invalid Chassis FRU version: 0x%x",
1562 chassis_fru[0]);
1563 return EINVAL;
1564 }
1565
1566 if (checksum(chassis_fru + 0, 8) != 0) {
1567 sys->log(sys, SETUP_ERROR, NULL, "Warning: Chassis FRU header"
1568 " checksum fail");
1569 }
1570
1571 chassis_iuse = chassis_fru[1] * 8;
1572 chassis_iuse_len = 80 - 8;
1573 chassis_chinfo = chassis_fru[2] * 8;
1574 chassis_chinfo_len = 256 - 80;
1575 chassis_brdinfo = chassis_fru[3] * 8;
1576 chassis_brdinfo_len = 1024 - 256;
1577 sernum_offset = 42;
1578 sernum_offset2 = 11;
1579 sernum_len = 20;
1580 sysmac_offset = 74;
1581
1582 if (chassis_iuse != 8) {
1583 sys->log(sys, SETUP_ERROR, NULL, "Warning: Chassis FRU internal use"
1584 "area is not at offset 8");
1585 }
1586 if (chassis_chinfo != 80) {
1587 sys->log(sys, SETUP_ERROR, NULL, "Warning: Chassis FRU chassis info"
1588 "area is not at offset 80");
1589 }
1590 if (chassis_brdinfo != 256) {
1591 sys->log(sys, SETUP_ERROR, NULL, "Warning: Chassis FRU board info"
1592 "area is not at offset 256");
1593 }
1594 if (checksum(chassis_fru + chassis_iuse, chassis_iuse_len) != 0) {
1595 sys->log(sys, SETUP_ERROR, NULL, "Warning: Chassis FRU internal use"
1596 " checksum fail");
1597 }
1598 if (checksum(chassis_fru + chassis_chinfo, chassis_chinfo_len) != 0) {
1599 sys->log(sys, SETUP_ERROR, NULL, "Warning: Chassis FRU chassis info"
1600 " checksum fail");
1601 }
1602 if (checksum(chassis_fru + chassis_brdinfo, chassis_brdinfo_len) != 0) {
1603 sys->log(sys, SETUP_ERROR, NULL, "Warning: Chassis FRU board info"
1604 " checksum fail");
1605 }
1606
1607 if (chassis_fru[chassis_chinfo + sernum_offset] != 0xd4) {
1608 /* Try the version 2.0 of the FRU data */
1609 sernum_offset = 17;
1610 sernum_offset2 = 1;
1611 }
1612 if (chassis_fru[chassis_chinfo + sernum_offset] != 0xd4) {
1613 sys->log(sys, SETUP_ERROR, NULL,
1614 "Warning: Chassis FRU system serial"
1615 " number data invalid");
1616 sernum_len = 0;
1617 } else {
1618 memcpy(sernum, chassis_fru + chassis_chinfo + sernum_offset
1619 + sernum_offset2, 8);
1620 sernum[9] = '\0';
1621 }
1622
1623 if (chassis_fru[chassis_brdinfo + sysmac_offset] != 0xe0) {
1624 sys->log(sys, SETUP_ERROR, NULL, "Warning: Chassis FRU system MAC"
1625 " data invalid");
1626 } else {
1627 /* Don't copy the last byte, we use that for the boards. */
1628 memcpy(sysmac, chassis_fru + chassis_brdinfo + sysmac_offset + 14, 16);
1629 sysmac[16] = '\0';
1630 }
1631
1632 return 0;
1633 }
1634
1635 /**************************************************************************
1636 * Event/timer handling
1637 *************************************************************************/
1638
1639 static int ast_fd;
1640 static ipmi_io_t *ast_fd_id;
1641 static int fork_event_wait = 0;
1642
1643 static void
ast_evt(int fd,void * cb_data)1644 ast_evt(int fd, void *cb_data)
1645 {
1646 int rv;
1647 int event;
1648 sys_data_t *sys = cb_data;
1649
1650 if (!fork_event_wait) {
1651 rv = ioctl(fd, READ_WIW_NONBLOCKING, &event);
1652 if (rv == -1) {
1653 sys->log(sys, OS_ERROR, NULL, "Warning: MV: Error reading"
1654 " AST event: %s", strerror(errno));
1655 return;
1656 }
1657 } else {
1658 unsigned char c;
1659 rv = read(fd, &c, 1);
1660 if (rv != 1) {
1661 sys->log(sys, OS_ERROR, NULL, "Warning: MV: AST1300 shim"
1662 " failed: %s", strerror(errno));
1663 exit(1);
1664 }
1665 event = c;
1666 }
1667
1668 if (debug & 1)
1669 sys->log(sys, DEBUG, NULL, "Got event %d", event);
1670
1671 switch (event) {
1672 case WIW_NO_EVENT:
1673 break;
1674
1675 case WIW_NODE1_IN:
1676 case WIW_NODE1_OUT:
1677 if (debug & 1)
1678 sys->log(sys, DEBUG, NULL, "Board %s on 1",
1679 event == WIW_NODE1_IN ? "insertion" : "removal");
1680 check_board(sys, 0, 0, 1);
1681 break;
1682
1683 case WIW_NODE2_IN:
1684 case WIW_NODE2_OUT:
1685 if (debug & 1)
1686 sys->log(sys, DEBUG, NULL, "Board %s on 2",
1687 event == WIW_NODE2_IN ? "insertion" : "removal");
1688 check_board(sys, 1, 0, 1);
1689 break;
1690
1691 case WIW_NODE3_IN:
1692 case WIW_NODE3_OUT:
1693 if (debug & 1)
1694 sys->log(sys, DEBUG, NULL, "Board %s on 3",
1695 event == WIW_NODE3_IN ? "insertion" : "removal");
1696 check_board(sys, 2, 0, 1);
1697 break;
1698
1699 case WIW_NODE4_IN:
1700 case WIW_NODE4_OUT:
1701 if (debug & 1)
1702 sys->log(sys, DEBUG, NULL, "Board %s on 4",
1703 event == WIW_NODE4_IN ? "insertion" : "removal");
1704 check_board(sys, 3, 0, 1);
1705 break;
1706
1707 case WIW_NODE5_IN:
1708 case WIW_NODE5_OUT:
1709 if (debug & 1)
1710 sys->log(sys, DEBUG, NULL, "Board %s on 5",
1711 event == WIW_NODE5_IN ? "insertion" : "removal");
1712 check_board(sys, 4, 0, 1);
1713 break;
1714
1715 case WIW_NODE6_IN:
1716 case WIW_NODE6_OUT:
1717 if (debug & 1)
1718 sys->log(sys, DEBUG, NULL, "Board %s on 6",
1719 event == WIW_NODE6_IN ? "insertion" : "removal");
1720 check_board(sys, 5, 0, 1);
1721 break;
1722
1723 case WIW_NODE1_PBTN_P:
1724 handle_button_press(sys, 0);
1725 break;
1726
1727 case WIW_NODE1_PBTN_R:
1728 handle_button_release(sys, 0);
1729 break;
1730
1731 case WIW_NODE2_PBTN_P:
1732 handle_button_press(sys, 1);
1733 break;
1734
1735 case WIW_NODE2_PBTN_R:
1736 handle_button_release(sys, 1);
1737 break;
1738
1739 case WIW_NODE3_PBTN_P:
1740 handle_button_press(sys, 2);
1741 break;
1742
1743 case WIW_NODE3_PBTN_R:
1744 handle_button_release(sys, 2);
1745 break;
1746
1747 case WIW_NODE4_PBTN_P:
1748 handle_button_press(sys, 3);
1749 break;
1750
1751 case WIW_NODE4_PBTN_R:
1752 handle_button_release(sys, 3);
1753 break;
1754
1755 case WIW_NODE5_PBTN_P:
1756 handle_button_press(sys, 4);
1757 break;
1758
1759 case WIW_NODE5_PBTN_R:
1760 handle_button_release(sys, 4);
1761 break;
1762
1763 case WIW_NODE6_PBTN_P:
1764 handle_button_press(sys, 5);
1765 break;
1766
1767 case WIW_NODE6_PBTN_R:
1768 handle_button_release(sys, 5);
1769 break;
1770
1771 default:
1772 break;
1773 }
1774 }
1775
1776
1777 /*
1778 * This timer is called periodically to check the boards.
1779 */
1780 static ipmi_timer_t *mv_timer;
1781
1782 static void
mv_timeout(void * cb_data)1783 mv_timeout(void *cb_data)
1784 {
1785 int i;
1786 struct timeval tv;
1787 sys_data_t *sys = cb_data;
1788
1789 for (i = 0; i < NUM_BOARDS; i++)
1790 check_board(sys, i, 1, 1);
1791
1792 tv.tv_sec = 1;
1793 tv.tv_usec = 0;
1794 sys->start_timer(mv_timer, &tv);
1795 }
1796
1797 static void
shim_sig(int signr)1798 shim_sig(int signr)
1799 {
1800 exit(1);
1801 }
1802
1803 /*
1804 * The ast1300 device doesn't support select() in older
1805 * implementations. So add a small program that will wait for it
1806 * blocking and then feed it to the program through a pipe, which will
1807 * work as a select() device.
1808 */
1809 static void
ast1300_shim(sys_data_t * sys,int ast_fd,int writefd,int pid)1810 ast1300_shim(sys_data_t *sys, int ast_fd, int writefd, int pid)
1811 {
1812 unsigned char c;
1813 int rv;
1814 int event;
1815 struct sigaction act;
1816
1817 /*
1818 * Make sure to terminate if the main program goes away.
1819 */
1820 memset(&act, 0, sizeof(act));
1821 act.sa_handler = shim_sig;
1822 rv = sigaction(SIGCHLD, &act, NULL);
1823 if (rv == -1) {
1824 sys->log(sys, OS_ERROR, NULL, "Warning: MV: Error settint up"
1825 " signal: %s", strerror(errno));
1826 exit(1);
1827 }
1828
1829 for (;;) {
1830 rv = ioctl(ast_fd, READ_WIW_BLOCKING, &event);
1831 if (rv == -1) {
1832 sys->log(sys, OS_ERROR, NULL, "Warning: MV: Error reading"
1833 " AST event: %s", strerror(errno));
1834 exit(1);
1835 }
1836 c = event;
1837 rv = write(writefd, &c, 1);
1838 if (rv != 1) {
1839 /* Other end of the pipe went away, just shut down. */
1840 exit(0);
1841 }
1842 }
1843 }
1844
1845 /**************************************************************************
1846 * General sensor handling
1847 *************************************************************************/
1848
1849 struct sensor_info {
1850 char *filename;
1851 unsigned char sensor_number;
1852 char *create_file;
1853 char *create_data;
1854 int invalid_if_off;
1855 int mult;
1856 int div;
1857 int sub;
1858 };
1859 static struct sensor_info empty_sensors[] = { { NULL } };
1860
1861 static int all_fans_duty = 0;
1862
1863 struct fan_duty_table {
1864 int reading;
1865 int setting;
1866 };
1867
1868 struct sensor_handling {
1869 struct sensor_info *switch_s;
1870 char *switch_valids;
1871 int *switch_last_values;
1872 struct sensor_info *board;
1873 char (*board_valids)[NUM_BOARDS];
1874 int (*board_last_values)[NUM_BOARDS];
1875 struct fan_duty_table *fan_duty;
1876
1877 /* Modify the duty tables by this much. */
1878 int duty_offset;
1879 };
1880
1881 static struct sensor_info switch_temp_sensors[] =
1882 {
1883 /* Switch Temp */
1884 { "/sys/class/i2c-adapter/i2c-0/0-0058/temp2_input", 1, .div = 1000 },
1885 /* Switch CPU Temp */
1886 { "/sys/class/i2c-adapter/i2c-0/0-0058/temp3_input", 2, .div = 1000 },
1887 { NULL }
1888 };
1889 static char switch_temp_sensor_valids[2];
1890 static int switch_temp_sensor_last_values[2];
1891 static struct sensor_info board_temp_sensors[] =
1892 {
1893 /* Board CPU Temp */
1894 { "/sys/class/i2c-adapter/i2c-%d/%d-0064/temp1_input", 2, .div = 1000,
1895 .invalid_if_off = 1,
1896 .create_file = "/sys/class/i2c-adapter/i2c-%d/new_device",
1897 .create_data = "axp 0x64" },
1898 /* Board DIMM Temp */
1899 { "/sys/class/i2c-adapter/i2c-%d/%d-001e/temp1_input", 3, .div = 1000,
1900 .invalid_if_off = 1,
1901 .create_file = "/sys/class/i2c-adapter/i2c-%d/new_device",
1902 .create_data = "dimm 0x1e" },
1903 { NULL }
1904 };
1905 static char board_temp_sensor_last_oor[NUM_BOARDS];
1906 static char board_temp_sensor_valids[2][NUM_BOARDS];
1907 static int board_temp_sensor_last_values[2][NUM_BOARDS];
1908 static struct fan_duty_table main_fan_duty_table[] =
1909 {
1910 { 0, 42 },
1911 { 60, 45 },
1912 { 65, 48 },
1913 { 70, 51 },
1914 { 75, 54 },
1915 { 80, 57 },
1916 { 85, 60 },
1917 { 95, 70 },
1918 { 100, 85 },
1919 { 105, 100 },
1920 { -1 }
1921 };
1922 static struct sensor_handling main_temp =
1923 {
1924 .switch_s = switch_temp_sensors,
1925 .switch_valids = switch_temp_sensor_valids,
1926 .switch_last_values = switch_temp_sensor_last_values,
1927 .board = board_temp_sensors,
1928 .board_valids = board_temp_sensor_valids,
1929 .board_last_values = board_temp_sensor_last_values,
1930 .fan_duty = main_fan_duty_table,
1931 .duty_offset = 10
1932 };
1933
1934 static struct sensor_info board_mb_sensors[] =
1935 {
1936 /* Board MB Temp */
1937 { "/sys/class/i2c-adapter/i2c-%d/%d-004a/temp1_input", 1, .div = 1000 },
1938 { NULL }
1939 };
1940 static char board_mb_sensor_valids[1][NUM_BOARDS];
1941 static int board_mb_sensor_last_values[1][NUM_BOARDS];
1942 static struct fan_duty_table mb_fan_duty_table[] =
1943 {
1944 { 0, 42 },
1945 { 50, 45 },
1946 { 52, 48 },
1947 { 54, 51 },
1948 { 56, 54 },
1949 { 58, 57 },
1950 { 60, 60 },
1951 { -1 }
1952 };
1953 static struct sensor_handling mb_temp =
1954 {
1955 .switch_s = empty_sensors,
1956 .board = board_mb_sensors,
1957 .board_valids = board_mb_sensor_valids,
1958 .board_last_values = board_mb_sensor_last_values,
1959 .fan_duty = mb_fan_duty_table,
1960 .duty_offset = 0
1961 };
1962
1963 static struct sensor_info board_front_sensors[] =
1964 {
1965 /* Board Front Temp */
1966 { "/sys/class/i2c-adapter/i2c-%d/%d-004c/temp1_input", 4, .div = 1000 },
1967 { NULL }
1968 };
1969 static char board_front_sensor_valids[1][NUM_BOARDS];
1970 static int board_front_sensor_last_values[1][NUM_BOARDS];
1971 static struct fan_duty_table front_fan_duty_table[] =
1972 {
1973 { 0, 42 },
1974 { 37, 65 },
1975 { 39, 70 },
1976 { 41, 75 },
1977 { 43, 80 },
1978 { 45, 85 },
1979 { -1 }
1980 };
1981 static struct sensor_handling front_temp =
1982 {
1983 .switch_s = empty_sensors,
1984 .board = board_front_sensors,
1985 .board_valids = board_front_sensor_valids,
1986 .board_last_values = board_front_sensor_last_values,
1987 .fan_duty = front_fan_duty_table,
1988 .duty_offset = 0
1989 };
1990
1991 static struct sensor_info switch_sensors[] =
1992 {
1993 /* Switch 12v */
1994 { "/sys/class/i2c-adapter/i2c-0/0-0058/in11_input", 3,
1995 .mult=8, .div=125, .sub=10000 },
1996 /* Switch 3.3v */
1997 { "/sys/class/i2c-adapter/i2c-0/0-0058/in10_input", 4,
1998 .mult=8, .div=25, .sub=2900 },
1999 /* Switch 1.8v */
2000 { "/sys/class/i2c-adapter/i2c-0/0-0058/in2_input", 5,
2001 .mult=16, .div=25, .sub=1600 },
2002 /* Fans */
2003 { "/sys/class/astfan/fan1_input", 0x70, .mult = 10, .div = 392 },
2004 { "/sys/class/astfan/fan2_input", 0x71, .mult = 10, .div = 392 },
2005 { "/sys/class/astfan/fan3_input", 0x72, .mult = 10, .div = 392 },
2006 { "/sys/class/astfan/fan4_input", 0x73, .mult = 10, .div = 392 },
2007 { "/sys/class/astfan/fan5_input", 0x74, .mult = 10, .div = 392 },
2008 { "/sys/class/astfan/fan6_input", 0x75, .mult = 10, .div = 392 },
2009 { "/sys/class/astfan/fan7_input", 0x76, .mult = 10, .div = 392 },
2010 { "/sys/class/astfan/fan8_input", 0x77, .mult = 10, .div = 392 },
2011 { NULL }
2012 };
2013 static char switch_sensor_valids[11];
2014 static int switch_sensor_last_values[11];
2015 static struct sensor_info board_sensors[] =
2016 {
2017 /* Board 1.0v */
2018 { "/sys/class/i2c-adapter/i2c-%d/%d-0048/in3_input", 5,
2019 .mult=32, .div=25, .sub=900,
2020 .invalid_if_off = 1 },
2021 /* Board 1.8v */
2022 { "/sys/class/i2c-adapter/i2c-%d/%d-0048/in2_input", 6,
2023 .mult=16, .div=25, .sub=1600,
2024 .invalid_if_off = 1 },
2025 /* Board 2.5v */
2026 { "/sys/class/i2c-adapter/i2c-%d/%d-0048/in1_input", 7,
2027 .mult=32, .div=125, .sub=2000,
2028 .invalid_if_off = 1 },
2029 /* Board 3.3v */
2030 { "/sys/class/i2c-adapter/i2c-%d/%d-0048/in0_input", 8,
2031 .mult=8, .div=25, .sub=2900,
2032 .invalid_if_off = 1 },
2033 /* Board 1.05v */
2034 { "/sys/class/i2c-adapter/i2c-%d/%d-0049/in2_input", 9,
2035 .mult=16, .div=25, .sub=800,
2036 .invalid_if_off = 1 },
2037 /* Board DIMMv */
2038 { "/sys/class/i2c-adapter/i2c-%d/%d-0049/in1_input", 11,
2039 .mult=64, .div=75, .sub=1200,
2040 .invalid_if_off = 1 },
2041 /* Board 0.9v */
2042 { "/sys/class/i2c-adapter/i2c-%d/%d-0049/in0_input", 12,
2043 .mult=21, .div=50, .sub=700,
2044 .invalid_if_off = 1 },
2045 { NULL }
2046 };
2047 static char board_sensor_valids[8][NUM_BOARDS];
2048 static int board_sensor_last_values[8][NUM_BOARDS];
2049 static struct sensor_handling system_sensors =
2050 {
2051 .switch_s = switch_sensors,
2052 .switch_valids = switch_sensor_valids,
2053 .switch_last_values = switch_sensor_last_values,
2054 .board = board_sensors,
2055 .board_valids = board_sensor_valids,
2056 .board_last_values = board_sensor_last_values,
2057 };
2058
2059
2060 static int
get_readings(sys_data_t * sys,struct sensor_handling * h,int * rmax)2061 get_readings(sys_data_t *sys, struct sensor_handling *h, int *rmax)
2062 {
2063 int err;
2064 int success = 0;
2065 int max = 0;
2066 unsigned int i, j;
2067
2068 for (i = 0; h->switch_s[i].filename; i++) {
2069 int value;
2070
2071 err = get_intval(h->switch_s[i].filename, &value);
2072 if (debug & 2)
2073 sys->log(sys, DEBUG, NULL, "Read value %s: %d %d",
2074 h->switch_s[i].filename, err, value);
2075 if (err) {
2076 h->switch_valids[i] = 0;
2077 } else {
2078 success = 1;
2079 h->switch_valids[i] = 1;
2080 h->switch_last_values[i] = value;
2081 if (value > max)
2082 max = value;
2083 }
2084 }
2085
2086 for (i = 0; h->board[i].filename; i++) {
2087 for (j = 0; j < NUM_BOARDS; j++) {
2088 int value;
2089 char filename[100];
2090
2091 if (!boards[j].present ||
2092 (h->board[i].invalid_if_off && !board_power_state(sys, j))) {
2093 h->board_valids[i][j] = 0;
2094 continue;
2095 }
2096
2097 sprintf(filename, h->board[i].filename, j + 1, j + 1);
2098
2099 err = get_intval(filename, &value);
2100 if ( err && h->board[i].create_file) {
2101 /* The sysfs file doesn't exist, create it. */
2102 char cfilename[100];
2103 FILE *f;
2104
2105 sprintf(cfilename, h->board[i].create_file, j + 1);
2106 f = fopen(cfilename, "w");
2107 if (!f) {
2108 sys->log(sys, OS_ERROR, NULL, "Unable to create %s",
2109 filename);
2110 } else {
2111 fprintf(f, "%s\n", h->board[i].create_data);
2112 fclose(f);
2113 }
2114 err = get_intval(filename, &value);
2115 }
2116
2117 if (debug & 2)
2118 sys->log(sys, DEBUG, NULL, "Read value %s: %d %d",
2119 filename, err, value);
2120 if (err) {
2121 sys->log(sys, OS_ERROR, NULL, "Sensor read error of %s: %s",
2122 filename, strerror(err));
2123 h->board_valids[i][j] = 0;
2124 } else {
2125 success = 1;
2126 h->board_valids[i][j] = 1;
2127 h->board_last_values[i][j] = value;
2128 if (value > max)
2129 max = value;
2130 }
2131 }
2132 }
2133
2134 if (rmax)
2135 *rmax = max;
2136 return !success;
2137 }
2138
2139 static int
calc_duty(struct fan_duty_table * t,int duty_offset,int v,int * last_v,int * last_duty)2140 calc_duty(struct fan_duty_table *t, int duty_offset,
2141 int v, int *last_v, int *last_duty)
2142 {
2143 unsigned int i;
2144 int duty = 0;
2145
2146 /* Hysteresis when going down, and is two degress C. */
2147 if (v < *last_v)
2148 v += 2000;
2149
2150 /* Convert to degrees, rounding */
2151 v = (v + 500) / 1000;
2152
2153 for (i = 1; t[i].reading != -1; i++) {
2154 if (v < t[i].reading)
2155 break;
2156 }
2157 duty = t[i - 1].setting + duty_offset;
2158 if (duty > 100)
2159 duty = 100;
2160 if (duty < 42)
2161 duty = 42;
2162 if (duty != *last_duty) {
2163 *last_duty = duty;
2164 *last_v = v;
2165 } else if (v > *last_v) {
2166 /*
2167 * This is subtle, but is required to correctly implement
2168 * hysteresis. We don't want to get in a situation where the
2169 * temperature goes down, but is still in the hysteresis area,
2170 * then goes back up a little bit. So we only set last_v when
2171 * going up.
2172 */
2173 *last_v = v;
2174 }
2175
2176 return duty;
2177 }
2178
2179 static int last_main_v, last_mb_v, last_front_v;
2180 static int last_main_duty, last_mb_duty, last_front_duty;
2181 static int last_duty;
2182
2183 static int scan_pipe[2];
2184 static pthread_mutex_t scan_mutex = PTHREAD_MUTEX_INITIALIZER;
2185 static pthread_cond_t scan_cond = PTHREAD_COND_INITIALIZER;
2186 static pthread_t scan_thread;
2187 static ipmi_io_t *scan_fd_id;
2188
2189 static int eesense_data_ready[NUM_BOARDS];
2190 static unsigned char cpu_errors[NUM_BOARDS];
2191 static uint16_t dimm_errors[NUM_BOARDS];
2192
2193 static int ps_status_good[2];
2194 static unsigned int ps_status_word[2];
2195
2196 static void
scan_eeprom_sensors(sys_data_t * sys)2197 scan_eeprom_sensors(sys_data_t *sys)
2198 {
2199 int rv;
2200 unsigned int i;
2201
2202 for (i = 0; i < NUM_BOARDS; i++) {
2203 if (!boards[i].present) {
2204 eesense_data_ready[i] = 0;
2205 } else {
2206 unsigned char data[2];
2207
2208 rv = ipmi_mc_fru_sem_trywait(boards[i].mc, 0);
2209 if (rv)
2210 continue;
2211
2212 rv = read_eeprom(&board_i2c[i].fru, data, 9, 2);
2213 if (rv) {
2214 eesense_data_ready[i] = 0;
2215 sys->log(sys, OS_ERROR, NULL,
2216 "Error reading eeprom sensors for %d: %s",
2217 i + 1, strerror(rv));
2218 } else {
2219 eesense_data_ready[i] = 1;
2220 cpu_errors[i] = data[0];
2221 dimm_errors[i] = data[1];
2222 }
2223 rv = ipmi_mc_fru_sem_post(boards[i].mc, 0);
2224 if (rv)
2225 sys->log(sys, OS_ERROR, NULL,
2226 "Error posting board %d semaphore: %s", i + 1,
2227 strerror(rv));
2228 }
2229 }
2230 }
2231
2232 static void
scan_ps_sensors(sys_data_t * sys)2233 scan_ps_sensors(sys_data_t *sys)
2234 {
2235 int rv;
2236 unsigned int i;
2237
2238 rv = get_uintval("/sys/class/wixpmbus/STATUS_1", &i);
2239 if (rv) {
2240 /* Not present */
2241 ps_status_good[0] = 0;
2242 } else {
2243 ps_status_good[0] = 1;
2244 ps_status_word[0] = i;
2245 }
2246 rv = get_uintval("/sys/class/wixpmbus/STATUS_2", &i);
2247 if (rv) {
2248 /* Not present */
2249 ps_status_good[1] = 0;
2250 } else {
2251 ps_status_good[1] = 1;
2252 ps_status_word[1] = i;
2253 }
2254 }
2255
2256 static char *fan_fail_led[4] =
2257 {
2258 "/sys/class/astgpio/GPIOP0",
2259 "/sys/class/astgpio/GPIOP1",
2260 "/sys/class/astgpio/GPIOP2",
2261 "/sys/class/astgpio/GPIOP3",
2262 };
2263
2264 static void *
scan_sensors(void * cb_data)2265 scan_sensors(void *cb_data)
2266 {
2267 sys_data_t *sys = cb_data;
2268 int err;
2269 int duty;
2270 int max_temp = 0;
2271 int max_duty = 0;
2272 char dummy = 0;
2273 struct timeval next, now, wait;
2274 unsigned int i;
2275 char fan_fail[8];
2276
2277 for (;;) {
2278 sys->get_monotonic_time(sys, &next);
2279 add_to_timeval(&next, poll_time);
2280
2281 err = get_readings(sys, &main_temp, &max_temp);
2282 if (!err) {
2283 max_duty = calc_duty(main_temp.fan_duty, main_temp.duty_offset,
2284 max_temp, &last_main_v, &last_main_duty);
2285 }
2286 err = get_readings(sys, &mb_temp, &max_temp);
2287 if (!err) {
2288 duty = calc_duty(mb_temp.fan_duty, mb_temp.duty_offset, max_temp,
2289 &last_mb_v, &last_mb_duty);
2290 if (duty > max_duty)
2291 max_duty = duty;
2292 }
2293 err = get_readings(sys, &front_temp, &max_temp);
2294 if (!err) {
2295 duty = calc_duty(front_temp.fan_duty, front_temp.duty_offset,
2296 max_temp, &last_front_v, &last_front_duty);
2297 if (duty > max_duty)
2298 max_duty = duty;
2299 }
2300
2301 duty = 0;
2302 for (i = 1; i < 9; i++) {
2303 char filename[50];
2304 int val;
2305
2306 sprintf(filename, "/sys/class/astfan/fan%u_input", i);
2307 err = get_intval(filename, &val);
2308 if (err) {
2309 sys->log(sys, OS_ERROR, NULL,
2310 "Can't read fan speed for %s: %s", filename,
2311 strerror(err));
2312 /* Can't read fan, better safe than sorry. */
2313 duty = 90;
2314 fan_fail[i - 1] = 1;
2315 } else {
2316 /* A fan is failing. */
2317 if (val < 1000) {
2318 fan_fail[i - 1] = 1;
2319 duty = 90;
2320 } else
2321 fan_fail[i - 1] = 0;
2322 }
2323 }
2324
2325 for (i = 0; i < 4; i++) {
2326 if (fan_fail[i * 2] || fan_fail[i * 2 + 1])
2327 set_intval(fan_fail_led[i], 1);
2328 else
2329 set_intval(fan_fail_led[i], 0);
2330 }
2331
2332 if (duty > max_duty)
2333 max_duty = duty;
2334
2335 if (all_fans_duty)
2336 max_duty = all_fans_duty;
2337
2338 if (max_duty != last_duty) {
2339 if (debug & 8)
2340 sys->log(sys, DEBUG, NULL, "Setting fan duty to %d",
2341 max_duty);
2342
2343 for (i = 1; i < 5; i++) {
2344 char filename[50];
2345
2346 sprintf(filename, "/sys/class/astfan/pwm%u", i);
2347 err = set_intval(filename, max_duty * 256 / 100);
2348 if (err)
2349 sys->log(sys, OS_ERROR, NULL,
2350 "Can't set fan duty %s to %d: %s",
2351 filename, max_duty, strerror(err));
2352 }
2353 }
2354
2355 get_readings(sys, &system_sensors, NULL);
2356
2357 scan_eeprom_sensors(sys);
2358
2359 scan_ps_sensors(sys);
2360
2361 pthread_mutex_lock(&scan_mutex);
2362 write(scan_pipe[1], &dummy, 1);
2363 pthread_cond_wait(&scan_cond, &scan_mutex);
2364 pthread_mutex_unlock(&scan_mutex);
2365
2366 if (wdt_test_timer_ran) {
2367 unsigned char data = 1;
2368 err = write(wdt_fd, &data, 1);
2369 if (err == -1) {
2370 sys->log(sys, OS_ERROR, NULL,
2371 "Unable to write to watchdog timer: %s",
2372 strerror(err));
2373 }
2374 wdt_test_timer_ran = 0;
2375 }
2376
2377 /* Wait until poll_time seconds after the last scan started */
2378 sys->get_monotonic_time(sys, &now);
2379 diff_timeval(&wait, &next, &now);
2380 select(0, NULL, NULL, NULL, &wait);
2381 }
2382
2383 return NULL;
2384 }
2385
2386 static unsigned char
conv_value(struct sensor_info * info,int value)2387 conv_value(struct sensor_info *info, int value)
2388 {
2389 value -= info->sub;
2390 if (info->mult)
2391 value *= info->mult;
2392 if (info->div) {
2393 value += info->div / 2;
2394 value /= info->div;
2395 }
2396 if (value < 0)
2397 return 0;
2398 if (value > 255)
2399 return 255;
2400 return value;
2401 }
2402
2403 static void
set_sensors_from_table(sys_data_t * sys,struct sensor_handling * h)2404 set_sensors_from_table(sys_data_t *sys, struct sensor_handling *h)
2405 {
2406 unsigned int i, j;
2407
2408 for (i = 0; h->switch_s[i].filename; i++) {
2409 if (debug & 4)
2410 sys->log(sys, DEBUG, NULL, "process value %s: %d %d (%u)",
2411 h->switch_s[i].filename, h->switch_valids[i],
2412 h->switch_last_values[i],
2413 conv_value(&h->switch_s[i],
2414 h->switch_last_values[i]));
2415
2416 ipmi_mc_sensor_set_enabled(bmc_mc, 0,
2417 h->switch_s[i].sensor_number,
2418 h->switch_valids[i]);
2419 if (h->switch_valids[i]) {
2420 ipmi_mc_sensor_set_value(bmc_mc, 0,
2421 h->switch_s[i].sensor_number,
2422 conv_value(&h->switch_s[i],
2423 h->switch_last_values[i]),
2424 1);
2425 }
2426 }
2427
2428 for (i = 0; h->board[i].filename; i++) {
2429 for (j = 0; j < NUM_BOARDS; j++) {
2430 if (debug & 4)
2431 sys->log(sys, DEBUG, NULL, "process value %s (%d): %d %d (%u)",
2432 h->board[i].filename, j + 1, h->board_valids[i][j],
2433 h->board_last_values[i][j],
2434 conv_value(&h->board[i],
2435 h->board_last_values[i][j]));
2436
2437 ipmi_mc_sensor_set_enabled(boards[j].mc, 0,
2438 h->board[i].sensor_number,
2439 h->board_valids[i][j]);
2440 if (h->board_valids[i][j])
2441 ipmi_mc_sensor_set_value(boards[j].mc, 0,
2442 h->board[i].sensor_number,
2443 conv_value(&h->board[i],
2444 h->board_last_values[i][j]),
2445 1);
2446 }
2447 }
2448 }
2449
2450 static void
handle_eesense_data(sys_data_t * sys)2451 handle_eesense_data(sys_data_t *sys)
2452 {
2453 unsigned int i, j;
2454
2455 for (i = 0; i < NUM_BOARDS; i++) {
2456
2457 ipmi_mc_sensor_set_enabled(boards[i].mc, 0, 20,
2458 eesense_data_ready[i]);
2459 ipmi_mc_sensor_set_enabled(boards[i].mc, 0, 21,
2460 eesense_data_ready[i]);
2461 if (!eesense_data_ready[i])
2462 continue;
2463 for (j = 0; j < 1; j++)
2464 ipmi_mc_sensor_set_bit(boards[i].mc, 0, 20, j,
2465 ((cpu_errors[i] >> j) & 1), 1);
2466 for (j = 0; j < 8; j++)
2467 ipmi_mc_sensor_set_bit(boards[i].mc, 0, 21, j,
2468 ((dimm_errors[i] >> j) & 1), 1);
2469 }
2470 }
2471
2472 #define PMBUS_NONE_BIT (1 << 0)
2473 #define PMBUS_CML_BIT (1 << 1)
2474 #define PMBUS_TEMP_BIT (1 << 2)
2475 #define PMBUS_VIN_UV_BIT (1 << 3)
2476 #define PMBUS_IOUT_OC_BIT (1 << 4)
2477 #define PMBUS_VOUT_OV_BIT (1 << 5)
2478 #define PMBUS_OFF_BIT (1 << 6)
2479 #define PMBUS_BUSY_BIT (1 << 7)
2480 #define PMBUS_UNKNOWN_BIT (1 << 8)
2481 #define PMBUS_OTHER_BIT (1 << 9)
2482 #define PMBUS_FANS_BIT (1 << 10)
2483 #define PMBUS_NOT_POWER_GOOD_BIT (1 << 11)
2484 #define PMBUS_MRF_BIT (1 << 12)
2485 #define PMBUS_INPUT_BIT (1 << 13)
2486 #define PMBUS_I_P_OUT_BIT (1 << 14)
2487 #define PMBUS_VOUT_BIT (1 << 15)
2488
2489 /*
2490 * This is a mask to convert the PMBus status work to the IPMI power
2491 * supply status bitmask. Each entry in this array has a set of bits;
2492 * if one of those bits is set in the status work then the index of
2493 * the entry is a bit that should be set in the IPMI sensor.
2494 */
2495 static uint16_t pm_word_to_ipmi[7] =
2496 {
2497 0, /* presence is handled separately */
2498 0xffff, /* If anything is set we declare a fault */
2499 PMBUS_TEMP_BIT | PMBUS_FANS_BIT, /* Predictive failure */
2500 0, /* Input lost, nothing for this, only have "lost or out of range" */
2501 PMBUS_INPUT_BIT, /* Input lost or out of range */
2502 0, /* Out of range but present. No bit for this, just previous. */
2503 0, /* Configuration error */
2504 };
2505
2506 static void
handle_ps_status(int num)2507 handle_ps_status(int num)
2508 {
2509 uint16_t val;
2510 unsigned int i;
2511
2512 if (ps_status_good[num]) {
2513 val = 1; /* Present */
2514 for (i = 1; i < 7; i++)
2515 val |= (!!(ps_status_word[num] & pm_word_to_ipmi[i])) << i;
2516 } else {
2517 val = 0; /* Not present */
2518 }
2519
2520 for (i = 0; i < 7; i++)
2521 ipmi_mc_sensor_set_bit(bmc_mc, 0, 8 + num, i, (val >> i) & 1, 1);
2522 }
2523
2524 static void
set_sensors_from_tables(int fd,void * cb_data)2525 set_sensors_from_tables(int fd, void *cb_data)
2526 {
2527 sys_data_t *sys = cb_data;
2528 unsigned int i;
2529 int temp = 0;
2530 unsigned char dummy;
2531 int rv;
2532
2533 read(fd, &dummy, 1);
2534
2535 set_sensors_from_table(sys, &main_temp);
2536 set_sensors_from_table(sys, &mb_temp);
2537 set_sensors_from_table(sys, &front_temp);
2538 set_sensors_from_table(sys, &system_sensors);
2539 handle_eesense_data(sys);
2540 handle_ps_status(0);
2541 handle_ps_status(1);
2542
2543 /* Check for shutdown thresholds */
2544 if (switch_temp_sensor_valids[0])
2545 temp = switch_temp_sensor_last_values[0];
2546 if (switch_temp_sensor_valids[1] &&
2547 temp < switch_temp_sensor_last_values[1])
2548 temp = switch_temp_sensor_last_values[1];
2549 if (temp >= SWITCH_TEMP_SHUTDOWN * 1000) {
2550 sys->log(sys, INFO, NULL, "CRITICAL: Switch has exceeded temperature"
2551 " threshold, powering down system");
2552 power_down_system(sys);
2553 }
2554 temp = 0;
2555 for (i = 0; i < NUM_BOARDS; i++) {
2556 if (board_front_sensor_valids[0][i] &&
2557 board_front_sensor_last_values[0][i] > temp)
2558 temp = board_front_sensor_last_values[0][i];
2559 }
2560 if (temp >= FRONT_TEMP_SHUTDOWN * 1000) {
2561 sys->log(sys, INFO, NULL, "CRITICAL: External environment exceeded"
2562 " temperature threshold, raw value is %d, powering down"
2563 " system", temp);
2564 power_down_system(sys);
2565 }
2566
2567 for (i = 0; i < NUM_BOARDS; i++) {
2568 temp = 0;
2569 if (board_temp_sensor_valids[0][i])
2570 temp = board_temp_sensor_last_values[0][i];
2571 if (board_temp_sensor_valids[1][i] &&
2572 temp < board_temp_sensor_last_values[1][i])
2573 temp = board_temp_sensor_last_values[1][i];
2574 if (temp >= BOARD_TEMP_SHUTDOWN * 1000) {
2575 unsigned char val = 0;
2576 if (board_temp_sensor_last_oor[i]) {
2577 sys->log(sys, INFO, NULL, "CRITICAL: Board %d has exceeded"
2578 " temperature threshold, raw value is %d,"
2579 " powering down",
2580 i + 1, temp);
2581 set_chassis_control(NULL, CHASSIS_CONTROL_POWER, &val,
2582 &boards[i]);
2583 } else {
2584 sys->log(sys, INFO, NULL, "WARNING: Board %d has exceeded"
2585 " temperature threshold, raw value is %d,"
2586 " will check again before shutdown",
2587 i + 1, temp);
2588 board_temp_sensor_last_oor[i]++;
2589 }
2590 } else
2591 board_temp_sensor_last_oor[i] = 0;
2592
2593 if (boards[i].fru_data_ready_for_handling) {
2594 boards[i].fru_data_ready_for_handling = 0;
2595 handle_board_fru(sys, i);
2596 rv = ipmi_mc_fru_sem_post(boards[i].mc, 0);
2597 if (rv)
2598 sys->log(sys, OS_ERROR, NULL,
2599 "Error posting board %d semaphore: %s", i + 1,
2600 strerror(rv));
2601 }
2602 }
2603
2604 pthread_mutex_lock(&scan_mutex);
2605 pthread_cond_signal(&scan_cond);
2606 pthread_mutex_unlock(&scan_mutex);
2607 }
2608
2609 /**************************************************************************
2610 * Marvell OEM commands.
2611 *************************************************************************/
2612
2613 struct fru_write_data {
2614 sys_data_t *sys;
2615 unsigned int num;
2616 };
2617
2618 /*
2619 * Writing FRU data is too slow to do in the main thread, so do it in
2620 * another thread.
2621 */
2622 static void *
fru_write_thread(void * cb_data)2623 fru_write_thread(void *cb_data)
2624 {
2625 struct fru_write_data *info = cb_data;
2626 sys_data_t *sys = info->sys;
2627 unsigned int num = info->num;
2628 unsigned char board_fru_data[2048];
2629 int fd, rv;
2630
2631 pthread_detach(pthread_self());
2632
2633 free(info);
2634
2635 fd = open(BOARD_FRU_FILE, O_RDONLY);
2636 if (fd == -1) {
2637 sys->log(sys, OS_ERROR, NULL,
2638 "Unable to read board FRU file %s: %s",
2639 BOARD_FRU_FILE, strerror(errno));
2640 }
2641 rv = read(fd, board_fru_data, sizeof(board_fru_data));
2642 if (rv == -1) {
2643 sys->log(sys, OS_ERROR, NULL,
2644 "Unable to read board FRU file %s: %s",
2645 BOARD_FRU_FILE, strerror(errno));
2646 goto out_err;
2647 } else if (rv != sizeof(board_fru_data)) {
2648 sys->log(sys, OS_ERROR, NULL,
2649 "board FRU file too small %s: %d",
2650 BOARD_FRU_FILE, rv);
2651 goto out_err;
2652 }
2653 rv = write_eeprom(&board_i2c[num].fru, board_fru_data, 0,
2654 sizeof(board_fru_data));
2655 if (rv) {
2656 sys->log(sys, OS_ERROR, NULL,
2657 "Error writing board %d fru: %d", num, rv);
2658 goto out_err;
2659 }
2660
2661 boards[num].fru_data_ready_for_handling = 1;
2662 return NULL;
2663
2664 out_err:
2665 rv = ipmi_mc_fru_sem_post(boards[num].mc, 0);
2666 if (rv)
2667 sys->log(sys, OS_ERROR, NULL,
2668 "Error posting board %d semaphore: %s", num + 1, strerror(rv));
2669 return NULL;
2670 }
2671
2672 static void
handle_marvell_cmd(lmc_data_t * mc,msg_t * msg,unsigned char * rdata,unsigned int * rdata_len,void * cb_data)2673 handle_marvell_cmd(lmc_data_t *mc,
2674 msg_t *msg,
2675 unsigned char *rdata,
2676 unsigned int *rdata_len,
2677 void *cb_data)
2678 {
2679 sys_data_t *sys = cb_data;
2680 char cmd[100];
2681 int rv;
2682
2683 /*
2684 * Note that the calling function remove the IANA from the message
2685 * and inserts the IANA in the return message, we handle this like
2686 * a normal command.
2687 *
2688 * Start assuming success.
2689 */
2690 rdata[0] = 0;
2691 *rdata_len = 1;
2692
2693 switch (msg->cmd) {
2694 case DISABLE_NETWORK_SRVC_CMD:
2695 if (check_msg_length(msg, 1, rdata, rdata_len))
2696 break;
2697 snprintf(cmd, sizeof(cmd), "/etc/ipmi/netsrvc %d\n", msg->data[0]);
2698 rv = system(cmd);
2699 if (rv == -1) {
2700 rdata[0] = 0xff;
2701 rdata[1] = errno;
2702 rdata[2] = 0;
2703 *rdata_len = 3;
2704 } else if (rv) {
2705 rdata[0] = 0xff;
2706 rdata[1] = 0;
2707 rdata[2] = rv;
2708 *rdata_len = 3;
2709 }
2710 break;
2711
2712 case RELOAD_BOARD_FRU_CMD:
2713 {
2714 struct fru_write_data *info;
2715 pthread_t tid;
2716 unsigned int num;
2717
2718 if (check_msg_length(msg, 1, rdata, rdata_len))
2719 return;
2720
2721 num = msg->data[0] - 1;
2722 if (num >= NUM_BOARDS)
2723 goto out_err;
2724
2725 if (!boards[num].present)
2726 goto out_err;
2727
2728 rv = ipmi_mc_fru_sem_trywait(boards[num].mc, 0);
2729 if (rv) {
2730 if (errno == EAGAIN)
2731 /* Already in progress. */
2732 goto out_good;
2733
2734 sys->log(sys, OS_ERROR, NULL,
2735 "Unable to claim board %d FRU semaphore: %s",
2736 num + 1, strerror(errno));
2737 goto out_err;
2738 }
2739
2740 info = malloc(sizeof(*info));
2741 if (!info)
2742 goto out_err;
2743 info->sys = sys;
2744 info->num = num;
2745
2746 rv = pthread_create(&tid, NULL, fru_write_thread, info);
2747 if (rv) {
2748 sys->log(sys, OS_ERROR, NULL,
2749 "MVMOD: Unable to create fru write thread: %s",
2750 strerror(rv));
2751 free(info);
2752 goto out_err;
2753 }
2754 }
2755 break;
2756
2757 case SET_ALL_FANS_DUTY_CMD:
2758 {
2759 int duty;
2760
2761 if (check_msg_length(msg, 1, rdata, rdata_len))
2762 break;
2763
2764 duty = msg->data[0];
2765 if (duty == 0)
2766 ; /* Disable the duty by setting to zero */
2767 else if (duty < 30)
2768 duty = 30; /* Minimum allowed fan duty */
2769 else if (duty > 100)
2770 duty = 100;
2771 all_fans_duty = duty;
2772 }
2773 break;
2774
2775 case GET_ALL_FANS_DUTY_CMD:
2776 rdata[1] = all_fans_duty;
2777 *rdata_len = 2;
2778 break;
2779
2780 default:
2781 handle_invalid_cmd(mc, rdata, rdata_len);
2782 break;
2783 }
2784
2785 out_good:
2786 return;
2787
2788 out_err:
2789 rdata[0] = 0xff;
2790 }
2791
2792 int
ipmi_sim_module_print_version(sys_data_t * sys,char * initstr)2793 ipmi_sim_module_print_version(sys_data_t *sys, char *initstr)
2794 {
2795 printf("IPMI Simulator Marvell AXP module version %s\n", PVERSION);
2796 return 0;
2797 }
2798
2799 /*
2800 * An emulator command for simulating a change in the board's presence.
2801 */
simulate_board_presence(emu_out_t * out,emu_data_t * emu,lmc_data_t * mc,char ** toks)2802 static int simulate_board_presence(emu_out_t *out,
2803 emu_data_t *emu,
2804 lmc_data_t *mc,
2805 char **toks)
2806 {
2807 int rv;
2808 unsigned int board, present;
2809 const char *err;
2810
2811 rv = get_uint(toks, &board, &err);
2812 if (!rv && ((board == 0 || board > NUM_BOARDS))) {
2813 err = "board number out of range";
2814 rv = EINVAL;
2815 }
2816 if (rv) {
2817 out->printf(out, "Invalid board number: %s\n", err);
2818 return EINVAL;
2819 }
2820 board--;
2821 rv = get_bool(toks, &present, &err);
2822 if (rv) {
2823 out->printf(out, "Invalid board presence value: %s\n", err);
2824 return EINVAL;
2825 }
2826 simulate_board_absent[board] = !present;
2827 }
2828
2829
2830 /**************************************************************************
2831 * BMC reset handling
2832 *************************************************************************/
2833
2834 static void
handle_cold_reset(lmc_data_t * mc,msg_t * msg,unsigned char * rdata,unsigned int * rdata_len,void * cb_data)2835 handle_cold_reset(lmc_data_t *mc,
2836 msg_t *msg,
2837 unsigned char *rdata,
2838 unsigned int *rdata_len,
2839 void *cb_data)
2840 {
2841 sys_data_t *sys = cb_data;
2842 int rv;
2843
2844 rv = set_intval(RESET_REASON_FILE, RESET_REASON_COLD_BOOT);
2845 if (rv) {
2846 sys->log(sys, OS_ERROR, NULL,
2847 "MVMOD: Unable to write cold reset reason: %s",
2848 strerror(rv));
2849 }
2850
2851 system("reboot");
2852 }
2853
2854 static void
handle_warm_reset(lmc_data_t * mc,msg_t * msg,unsigned char * rdata,unsigned int * rdata_len,void * cb_data)2855 handle_warm_reset(lmc_data_t *mc,
2856 msg_t *msg,
2857 unsigned char *rdata,
2858 unsigned int *rdata_len,
2859 void *cb_data)
2860 {
2861 sys_data_t *sys = cb_data;
2862 int rv;
2863
2864 rv = set_intval(RESET_REASON_FILE, RESET_REASON_WARM_BOOT);
2865 if (rv) {
2866 sys->log(sys, OS_ERROR, NULL,
2867 "MVMOD: Unable to write warm reset reason: %s",
2868 strerror(rv));
2869 }
2870
2871 exit(1);
2872 }
2873
2874 /*
2875 * This is a timer that is periodically called from the main thread,
2876 * it is basically used to tell if the main thread is running.
2877 */
2878 static void
wdt_test_timeout(void * cb_data)2879 wdt_test_timeout(void *cb_data)
2880 {
2881 struct timeval tv;
2882 sys_data_t *sys = cb_data;
2883
2884 if (wdt_test_timer_ran)
2885 sys->log(sys, OS_ERROR, NULL, "MVMOD: WDT test timer not cleared");
2886
2887 wdt_test_timer_ran = 1;
2888 tv.tv_sec = 4;
2889 tv.tv_usec = 0;
2890 sys->start_timer(wdt_test_timer, &tv);
2891 }
2892
2893
2894 /**************************************************************************
2895 * Module initialization
2896 *************************************************************************/
2897
2898 int
ipmi_sim_module_init(sys_data_t * sys,const char * initstr_i)2899 ipmi_sim_module_init(sys_data_t *sys, const char *initstr_i)
2900 {
2901 unsigned int num;
2902 int rv;
2903 const char *c;
2904 char *next;
2905 int use_events = 1;
2906 struct timeval tv;
2907 int power_up_force = 0;
2908 char *initstr = strdup(initstr_i);
2909 int val;
2910
2911 printf("IPMI Simulator Marvell AXP module version %s\n", PVERSION);
2912
2913 if (!initstr) {
2914 sys->log(sys, SETUP_ERROR, NULL, "Error: MV: Out of memory");
2915 return ENOMEM;
2916 }
2917
2918 c = mystrtok(initstr, " \t\n", &next);
2919 while (c) {
2920 if (strcmp(c, "noevents") == 0) {
2921 use_events = 0;
2922 } else if (strcmp(c, "fork") == 0) {
2923 fork_event_wait = 1;
2924 } else if (strncmp(c, "debug=", 6) == 0) {
2925 debug = strtoul(c + 6, NULL, 0);
2926 } else if (strcmp(c, "forcecold") == 0) {
2927 power_up_force = 1;
2928 } else if (strcmp(c, "forcewarm") == 0) {
2929 power_up_force = 1;
2930 cold_power_up = 0;
2931 } else if (strcmp(c, "disablewdt") == 0) {
2932 disable_wdt = 1;
2933 } else if (strncmp(c, "poll_time=", 10) == 0) {
2934 poll_time = strtoul(c + 10, NULL, 0);
2935 } else {
2936 sys->log(sys, SETUP_ERROR, NULL, "Warning: MV: Unknown init"
2937 " string: %s", c);
2938 }
2939 c = mystrtok(NULL, " \t\n", &next);
2940 }
2941
2942 free(initstr);
2943
2944 check_chassis_state(sys);
2945
2946 rv = init_chassis(sys);
2947 if (rv)
2948 return rv;
2949
2950 rv = pipe(scan_pipe);
2951 if (rv == -1) {
2952 int errval = errno;
2953 sys->log(sys, SETUP_ERROR, NULL, "MVMOD: Unable to open pipe");
2954 return errval;
2955 }
2956 rv = sys->add_io_hnd(sys, scan_pipe[0], set_sensors_from_tables, sys,
2957 &scan_fd_id);
2958 if (rv) {
2959 int errval = errno;
2960 sys->log(sys, SETUP_ERROR, NULL,
2961 "MVMOD: Unable to add I/O handler");
2962 close(scan_pipe[0]);
2963 close(scan_pipe[1]);
2964 return errval;
2965 }
2966
2967 if (use_events) {
2968 ast_fd = open("/dev/event", O_RDWR);
2969 if (ast_fd == -1) {
2970 int errval = errno;
2971 sys->log(sys, SETUP_ERROR, NULL, "Unable to open /dev/event");
2972 return errval;
2973 }
2974 if (fork_event_wait) {
2975 int pipefds[2];
2976 rv = pipe(pipefds);
2977 if (rv == -1) {
2978 int errval = errno;
2979 close(ast_fd);
2980 sys->log(sys, SETUP_ERROR, NULL, "Unable to open pipe");
2981 return errval;
2982 }
2983 rv = fork();
2984 if (rv == -1) {
2985 int errval = errno;
2986 close(ast_fd);
2987 close(pipefds[0]);
2988 close(pipefds[1]);
2989 sys->log(sys, SETUP_ERROR, NULL, "Unable to fork");
2990 return errval;
2991 } else if (rv != 0) {
2992 /*
2993 * Note that the main program runs as the child and
2994 * the shim program runs as the parent. This allows
2995 * the shim program to catch the SIGCHLD and terminate
2996 * if the main program goes away. Otherwise the shim
2997 * would be stuck waiting on an event and not
2998 * terminate properly.
2999 */
3000 close(pipefds[0]);
3001 ast1300_shim(sys, ast_fd, pipefds[1], rv);
3002 }
3003 close(ast_fd);
3004 close(pipefds[1]);
3005 ast_fd = pipefds[0];
3006 }
3007
3008 rv = sys->add_io_hnd(sys, ast_fd, ast_evt, sys, &ast_fd_id);
3009 if (rv) {
3010 int errval = errno;
3011 sys->log(sys, SETUP_ERROR, NULL,
3012 "MVMOD: Unable to add I/O handler");
3013 close(ast_fd);
3014 return errval;
3015 }
3016 }
3017 rv = sys->alloc_timer(sys, mv_timeout, sys, &mv_timer);
3018 if (rv) {
3019 int errval = errno;
3020 sys->log(sys, SETUP_ERROR, NULL, "MVMOD: Unable to create timer");
3021 return errval;
3022 } else {
3023 tv.tv_sec = 1;
3024 tv.tv_usec = 0;
3025 sys->start_timer(mv_timer, &tv);
3026 }
3027
3028 rv = sys->alloc_timer(sys, board_power_timeout, sys, &power_timer);
3029 if (rv) {
3030 sys->log(sys, OS_ERROR, NULL,
3031 "Unable to allocate board power timer: %s", strerror(rv));
3032 return rv;
3033 }
3034
3035 if (!power_up_force) {
3036 rv = get_uintval(COLD_POWER_UP_IO, &cold_power_up);
3037 if (rv) {
3038 sys->log(sys, OS_ERROR, NULL, "Warning: MV: Could not read %s"
3039 " so assuming cold power up: %s", COLD_POWER_UP_IO,
3040 strerror(errno));
3041 cold_power_up = 1;
3042 } else if (cold_power_up) {
3043 /* Save the setting in case we fail in startup */
3044 set_intval(COLD_POWER_FILE, 1);
3045 } else {
3046 /*
3047 * Get the setting from the last startup. If it's not
3048 * there, no big deal.
3049 */
3050 get_uintval(COLD_POWER_FILE, &cold_power_up);
3051 }
3052 }
3053
3054 rv = ipmi_mc_alloc_unconfigured(sys, 0x20, &bmc_mc);
3055 if (rv) {
3056 sys->log(sys, OS_ERROR, NULL,
3057 "Unable to allocate an mc: %s", strerror(rv));
3058 return rv;
3059 }
3060
3061 for (num = 0; num < NUM_BOARDS; num++) {
3062 lmc_data_t *mc;
3063 unsigned int rval = 0;
3064 struct board_info *board = &boards[num];
3065
3066 board->num = num;
3067 board->sys = sys;
3068
3069 board->last_power_request = BOARD_OFF_READY;
3070 if (!cold_power_up) {
3071 /*
3072 * On a cold power up, we bring everything up that is
3073 * present. Otherwise we run this code to read the
3074 * current status and retain that.
3075 */
3076 rv = get_uintval(trg_present[num], &rval);
3077 if (rv) {
3078 sys->log(sys, OS_ERROR, NULL,
3079 "Unable to read board %u presence state: %s",
3080 num, strerror(rv));
3081 return rv;
3082 }
3083 if (rval != BOARD_PRESENT) {
3084 unsigned char val = 0;
3085 set_chassis_control(NULL, CHASSIS_CONTROL_POWER, &val, board);
3086 } else if (board_power_state(sys, num)) {
3087 /*
3088 * This looks a bit unusual, so I will explain. The
3089 * board power request is only handled on a off-to-on
3090 * transition, the raw values is not used directly.
3091 * But this presents an issue at startup: what if the
3092 * board requested a power off while this code wasn't
3093 * running? To solve that, if it is not a cold power
3094 * up, assume that the request is off and then we will
3095 * power down if the request is asserted.
3096 */
3097 board->last_power_request = BOARD_OFF_NOT_READY;
3098 }
3099 }
3100
3101 rv = ipmi_mc_alloc_unconfigured(sys, board_ipmb[num], &mc);
3102 if (rv) {
3103 sys->log(sys, OS_ERROR, NULL,
3104 "Unable to allocate an mc: %s", strerror(rv));
3105 return rv;
3106 }
3107 boards[num].mc = mc;
3108
3109 ipmi_mc_set_chassis_control_func(mc, set_chassis_control,
3110 get_chassis_control, board);
3111
3112 rv = check_board(sys, num, 0, cold_power_up);
3113 if (rv) {
3114 if (ast_fd_id)
3115 sys->remove_io_hnd(ast_fd_id);
3116 if (mv_timer)
3117 sys->free_timer(mv_timer);
3118 return rv;
3119 }
3120 }
3121
3122 ipmi_mc_set_chassis_control_func(bmc_mc, bmc_set_chassis_control,
3123 bmc_get_chassis_control, sys);
3124
3125
3126 rv = ipmi_emu_register_iana_handler(MARVELL_SEMI_ISREAL_IANA,
3127 handle_marvell_cmd, sys);
3128 if (rv) {
3129 sys->log(sys, OS_ERROR, NULL,
3130 "Unable to register Marvell IANA handler: %s", strerror(rv));
3131 }
3132
3133 rv = ipmi_emu_register_cmd_handler(IPMI_APP_NETFN, IPMI_COLD_RESET_CMD,
3134 handle_cold_reset, sys);
3135 if (rv) {
3136 sys->log(sys, OS_ERROR, NULL,
3137 "Unable to register cold reset handler: %s", strerror(rv));
3138 }
3139
3140 rv = ipmi_emu_register_cmd_handler(IPMI_APP_NETFN, IPMI_WARM_RESET_CMD,
3141 handle_warm_reset, sys);
3142 if (rv) {
3143 sys->log(sys, OS_ERROR, NULL,
3144 "Unable to register cold reset handler: %s", strerror(rv));
3145 }
3146
3147 if (!disable_wdt) {
3148 wdt_fd = open("/dev/watchdog", O_WRONLY);
3149 if (wdt_fd == -1) {
3150 sys->log(sys, OS_ERROR, NULL,
3151 "Unable to open wdt: %s", strerror(errno));
3152 return rv;
3153 }
3154
3155 rv = sys->alloc_timer(sys, wdt_test_timeout, sys, &wdt_test_timer);
3156 if (rv) {
3157 sys->log(sys, OS_ERROR, NULL,
3158 "Unable to allocate wdt test timer: %s", strerror(rv));
3159 return rv;
3160 }
3161 tv.tv_sec = 4;
3162 tv.tv_usec = 0;
3163 sys->start_timer(wdt_test_timer, &tv);
3164 }
3165
3166 if (!cold_power_up)
3167 init_complete = 1;
3168
3169 ipmi_emu_add_cmd("simulate_board_presence", NOMC, simulate_board_presence);
3170
3171 return 0;
3172 }
3173
3174 int
ipmi_sim_module_post_init(sys_data_t * sys)3175 ipmi_sim_module_post_init(sys_data_t *sys)
3176 {
3177 int rv;
3178 const char *ver = get_lanserv_version();
3179 unsigned char lver[4];
3180 unsigned char omajor, ominor, orel;
3181 unsigned int i;
3182 int val;
3183
3184 sscanf(ver, "%hhu.%hhu.%hhu", lver + 0, lver + 1, lver + 2);
3185 lver[3] = 0;
3186 sscanf(PVERSION, "%hhu.%hhu.%hhu", &omajor, &ominor, &orel);
3187 for (i = 0; i < NUM_BOARDS; i++) {
3188 ipmi_mc_set_fw_revision(boards[i].mc, omajor, ominor << 4 | orel);
3189 ipmi_mc_set_aux_fw_revision(boards[i].mc, lver);
3190 }
3191 ipmi_mc_set_fw_revision(bmc_mc, omajor, ominor << 4 | orel);
3192 ipmi_mc_set_aux_fw_revision(bmc_mc, lver);
3193
3194 /*
3195 * Set the rearm handler for the CPU and DIMM sensors to clear
3196 * them on rearm.
3197 */
3198
3199 for (i = 0; i < NUM_BOARDS; i++) {
3200 struct eesense_rearm *info;
3201
3202 info = malloc(sizeof(*info));
3203 if (!info) {
3204 sys->log(sys, OS_ERROR, NULL,
3205 "MVMOD: Unable to allocate eesense handler for board %d: "
3206 "Out of memory", i + 1);
3207 continue;
3208 }
3209 info->num = i;
3210 info->offset = 1;
3211 info->mask = 0x01;
3212 rv = ipmi_mc_sensor_add_rearm_handler(boards[i].mc, 0, 20,
3213 rearm_eesense_sensor, info);
3214 if (rv) {
3215 sys->log(sys, OS_ERROR, NULL,
3216 "MVMOD: Error adding eesense CPU rearm on %d: %s",
3217 i + 1, strerror(rv));
3218 continue;
3219 }
3220
3221 info = malloc(sizeof(*info));
3222 if (!info) {
3223 sys->log(sys, OS_ERROR, NULL,
3224 "MVMOD: Unable to allocate eesense handler for board %d: "
3225 "Out of memory", i + 1);
3226 continue;
3227 }
3228 info->num = i;
3229 info->offset = 2;
3230 info->mask = 0x87;
3231 rv = ipmi_mc_sensor_add_rearm_handler(boards[i].mc, 0, 21,
3232 rearm_eesense_sensor, info);
3233 if (rv) {
3234 sys->log(sys, OS_ERROR, NULL,
3235 "MVMOD: Error adding eesense DIMM rearm on %d: %s",
3236 i + 1, strerror(rv));
3237 }
3238 }
3239
3240 rv = ipmi_mc_sensor_add_rearm_handler(bmc_mc, 0, 8,
3241 rearm_power_supply_sensor,
3242 (void *) 1);
3243 if (rv) {
3244 sys->log(sys, OS_ERROR, NULL,
3245 "MVMOD: Error adding power supply %d rearm: %s",
3246 1, strerror(rv));
3247 }
3248
3249 rv = ipmi_mc_sensor_add_rearm_handler(bmc_mc, 0, 9,
3250 rearm_power_supply_sensor,
3251 (void *) 2);
3252 if (rv) {
3253 sys->log(sys, OS_ERROR, NULL,
3254 "MVMOD: Error adding power supply %d rearm: %s",
3255 2, strerror(rv));
3256 }
3257
3258 /* Initial state of the PSU sensor is with the present bit set */
3259 ipmi_mc_sensor_set_bit(bmc_mc, 0, 8, 0, 1, 0);
3260 ipmi_mc_sensor_set_bit(bmc_mc, 0, 9, 0, 1, 0);
3261
3262 rv = pthread_create(&scan_thread, NULL, scan_sensors, sys);
3263 if (rv) {
3264 sys->log(sys, OS_ERROR, NULL,
3265 "MVMOD: Unable to start scan thread: %s", strerror(rv));
3266 }
3267
3268 rv = get_intval(RESET_REASON_FILE, &val);
3269 if (rv || cold_power_up) {
3270 val = 0x00; /* Initiated by power up */
3271 } else if (val == RESET_REASON_COLD_BOOT ||
3272 rv || val == RESET_REASON_UNKNOWN) {
3273 val = 0x01; /* Initiated by hard reset */
3274 } else if (val == RESET_REASON_WARM_BOOT) {
3275 val = 0x02; /* Initiated by warm reset */
3276 } else {
3277 sys->log(sys, OS_ERROR, NULL, "MVMOD: known reset reason: %d", val);
3278 val = 0x01; /* Assume hard reset */
3279 }
3280 {
3281 /*
3282 * We don't have an actual sensor for this, since it is
3283 * event-only, just send the event.
3284 */
3285 unsigned char data[13];
3286 memset(data, 0, sizeof(data));
3287 data[4] = ipmi_mc_get_ipmb(bmc_mc);
3288 data[5] = 0; /* LUN */
3289 data[6] = 0x04; /* Event message revision for IPMI 1.5. */
3290 data[7] = 0x1d; /* System boot initiated. */
3291 data[8] = 20; /* Sensor num */
3292 data[9] = (IPMI_ASSERTION << 7) | 0x6f;
3293 data[10] = val;
3294 rv = mc_new_event(bmc_mc, 0x02, data);
3295 if (rv)
3296 sys->log(sys, OS_ERROR, NULL,
3297 "MVMOD: Unable to add reboot cause event: %s, "
3298 "event queue is probably full",
3299 strerror(rv));
3300
3301 }
3302
3303 rv = set_intval(RESET_REASON_FILE, 0);
3304 if (rv) {
3305 sys->log(sys, OS_ERROR, NULL,
3306 "MVMOD: Unable to clear reset reason: %s",
3307 strerror(rv));
3308 }
3309
3310 return rv;
3311 }
3312