Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: env-seeprom.c | |
5 | * | |
6 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
7 | * | |
8 | * - Do no alter or remove copyright notices | |
9 | * | |
10 | * - Redistribution and use of this software in source and binary forms, with | |
11 | * or without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistribution of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * - Redistribution in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the name of Sun Microsystems, Inc. or the names of contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * This software is provided "AS IS," without a warranty of any kind. | |
26 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
27 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
28 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
29 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
30 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
31 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
32 | * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
33 | * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
34 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
35 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
36 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
37 | * | |
38 | * You acknowledge that this software is not designed, licensed or | |
39 | * intended for use in the design, construction, operation or maintenance of | |
40 | * any nuclear facility. | |
41 | * | |
42 | * ========== Copyright Header End ============================================ | |
43 | */ | |
44 | /* | |
45 | * id: @(#)env-seeprom.c 1.3 03/06/11 | |
46 | * purpose: | |
47 | * copyright: Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved | |
48 | * copyright: Use is subject to license terms. | |
49 | */ | |
50 | ||
51 | #include <stdio.h> | |
52 | #include <stdlib.h> | |
53 | #include <strings.h> | |
54 | #include "gen-seeprom.h" | |
55 | #include "prototypes.h" | |
56 | #include "env-seeprom.h" | |
57 | ||
58 | int processing_env = 0, processing_fan = 0; | |
59 | int running_offset = VER_SIZE; | |
60 | struct env_table_entry *env_table = NULL; | |
61 | struct env_table_entry *cur_env_table; | |
62 | struct fan_table_entry *fan_table = NULL; | |
63 | struct fan_table_entry *cur_fan_table; | |
64 | struct id_header_data id_header; | |
65 | int current_correction = 0, current_fan_pair = 0; | |
66 | int num_corrections = 0, num_fan_ctl_pairs = 0; | |
67 | int id_num = 0, fan_id_num = 0, env_version = 0; | |
68 | ||
69 | void | |
70 | set_env_ver(void *data) | |
71 | { | |
72 | env_version = (int)data; | |
73 | } | |
74 | ||
75 | /* | |
76 | * allocate memory for the id-offset block | |
77 | */ | |
78 | ||
79 | void | |
80 | set_num_sensors(void *data) | |
81 | { | |
82 | id_header.num_sensors = (int)data; | |
83 | running_offset += NUM_SEN_SIZE + | |
84 | (id_header.num_sensors * SENSOR_BLOCK_SIZE); | |
85 | id_header.id_block = malloc(id_header.num_sensors * SENSOR_BLOCK_SIZE); | |
86 | } | |
87 | ||
88 | ||
89 | /* | |
90 | * "version" , "num-sensors" , "num-fans" will only show up once in a properly | |
91 | * configured environmental segment | |
92 | */ | |
93 | ||
94 | struct fixed_seeprom env_seeprom_data[] = { | |
95 | /* name size type value */ | |
96 | { "version", VER_SIZE, NUM, 0, set_env_ver}, | |
97 | { "num-sensors", NUM_SEN_SIZE, NUM, 0, set_num_sensors}, | |
98 | { NULL, 0, 0, 0, NULL}, | |
99 | }; | |
100 | ||
101 | ||
102 | int | |
103 | not_byte_range(int value) | |
104 | { | |
105 | return (value > 255 || value < 0); | |
106 | } | |
107 | ||
108 | int | |
109 | not_sbyte_range(int value) | |
110 | { | |
111 | return (value > 127 || value < -128); | |
112 | } | |
113 | ||
114 | correction_scan(char *line, unsigned int *input_val) | |
115 | { | |
116 | char temp[MAXNAMESIZE]; | |
117 | char input_one[MAXNAMESIZE]; | |
118 | char input_two[MAXNAMESIZE]; | |
119 | unsigned int temp_val; | |
120 | int retval = NO_ERROR; | |
121 | ||
122 | if (sscanf(line, "%s %s %s", temp, input_one, input_two) != 3) { | |
123 | retval = ERROR; | |
124 | } | |
125 | ||
126 | strip_val(input_one, input_val); | |
127 | strip_val(input_two, &temp_val); | |
128 | ||
129 | if (not_sbyte_range(*input_val) || not_sbyte_range(temp_val)) | |
130 | retval = ERROR; | |
131 | ||
132 | *input_val = (*input_val & 0xff) << 8; | |
133 | *input_val += (temp_val & 0xff); | |
134 | ||
135 | if (retval == ERROR) { | |
136 | printf("Correction table entries must be entered as a "); | |
137 | printf("pair of signed bytes\n"); | |
138 | } | |
139 | return (retval); | |
140 | } | |
141 | ||
142 | fan_min_range_scan(char *line, unsigned int *input_val) | |
143 | { | |
144 | char temp[MAXNAMESIZE]; | |
145 | char input_one[MAXNAMESIZE]; | |
146 | char input_two[MAXNAMESIZE]; | |
147 | unsigned int temp_val; | |
148 | int retval = NO_ERROR; | |
149 | ||
150 | if (sscanf(line, "%s %s %s", temp, input_one, input_two) != 3) { | |
151 | retval = ERROR; | |
152 | } | |
153 | ||
154 | strip_val(input_one, input_val); | |
155 | strip_val(input_two, &temp_val); | |
156 | ||
157 | if (not_sbyte_range(*input_val) || not_byte_range(temp_val)) | |
158 | retval = ERROR; | |
159 | ||
160 | *input_val = (*input_val & 0xff) << 8; | |
161 | *input_val += (temp_val & 0xff); | |
162 | ||
163 | if (retval == ERROR) { | |
164 | printf("Fan min/range table entries must be entered as a "); | |
165 | printf("signed, unsigned byte pair.\n"); | |
166 | } | |
167 | return (retval); | |
168 | } | |
169 | ||
170 | int | |
171 | update_env_table(char *parameter, char *line) | |
172 | { | |
173 | int i = 0, offset = 0; | |
174 | unsigned int input_val; | |
175 | int size; | |
176 | unsigned char *data_ptr; | |
177 | ||
178 | while (strcmp(env_parameters[i].name, parameter)) { | |
179 | offset += env_parameters[i++].size; | |
180 | if (env_parameters[i].name == NULL) { | |
181 | fprintf(stderr, | |
182 | "%s is not a valid env parameter\n", parameter); | |
183 | return (ERROR); | |
184 | } | |
185 | } | |
186 | size = env_parameters[i].size; | |
187 | data_ptr = cur_env_table->env_data; | |
188 | ||
189 | if (strcmp(parameter, "correction") == 0) { | |
190 | offset = COR_SIZE * current_correction; | |
191 | current_correction++; | |
192 | size = COR_SIZE; | |
193 | data_ptr = cur_env_table->correction_data; | |
194 | if ((correction_scan(line, &input_val) == ERROR)) | |
195 | return (ERROR); | |
196 | } else if ((scan_line(line, &input_val) == ERROR)) | |
197 | return (ERROR); | |
198 | ||
199 | ||
200 | if (strcmp(parameter, "num-corrections") == 0) { | |
201 | num_corrections = input_val; | |
202 | cur_env_table->correction_data = | |
203 | (unsigned char *) malloc(COR_SIZE * num_corrections); | |
204 | cur_env_table->correction_size = num_corrections * COR_SIZE; | |
205 | } | |
206 | ||
207 | write_bytes(input_val, size, offset, data_ptr); | |
208 | ||
209 | return (NO_ERROR); | |
210 | } | |
211 | ||
212 | int | |
213 | update_fan_table(char *parameter, char *line) | |
214 | { | |
215 | int i = 0, offset = 0; | |
216 | unsigned int input_val; | |
217 | int size; | |
218 | unsigned char *data_ptr; | |
219 | ||
220 | while (strcmp(fan_parameters[i].name, parameter)) { | |
221 | offset += fan_parameters[i++].size; | |
222 | if (fan_parameters[i].name == NULL) { | |
223 | fprintf(stderr, | |
224 | "%s is not a valid fan parameter\n", parameter); | |
225 | return (ERROR); | |
226 | } | |
227 | } | |
228 | size = fan_parameters[i].size; | |
229 | data_ptr = cur_fan_table->fan_data; | |
230 | ||
231 | if (strcmp(parameter, "fan-min-range") == 0) { | |
232 | offset = FAN_MIN_RANGE_SZ * current_fan_pair; | |
233 | current_fan_pair++; | |
234 | data_ptr = cur_fan_table->fan_ctl_data; | |
235 | if ((fan_min_range_scan(line, &input_val) == ERROR)) | |
236 | return (ERROR); | |
237 | } else if ((scan_line(line, &input_val) == ERROR)) | |
238 | return (ERROR); | |
239 | ||
240 | ||
241 | if (strcmp(parameter, "num-ctl-pairs") == 0) { | |
242 | num_fan_ctl_pairs = input_val; | |
243 | cur_fan_table->fan_ctl_data = | |
244 | (unsigned char *) malloc(FAN_MIN_RANGE_SZ * | |
245 | num_fan_ctl_pairs); | |
246 | cur_fan_table->fan_pair_size = num_fan_ctl_pairs * | |
247 | FAN_MIN_RANGE_SZ; | |
248 | } | |
249 | ||
250 | write_bytes(input_val, size, offset, data_ptr); | |
251 | ||
252 | return (NO_ERROR); | |
253 | } | |
254 | ||
255 | int | |
256 | set_num_fans(char *line) | |
257 | { | |
258 | unsigned int input_val; | |
259 | ||
260 | if (id_header.num_fans == 0) { | |
261 | if (scan_line(line, &input_val) == ERROR) | |
262 | return (ERROR); | |
263 | id_header.num_fans = input_val; | |
264 | running_offset += NUM_FAN_SIZE + | |
265 | (id_header.num_fans * FAN_BLOCK_SIZE); | |
266 | id_header.fan_block = malloc(id_header.num_fans * | |
267 | FAN_BLOCK_SIZE); | |
268 | return (NO_ERROR); | |
269 | } else { | |
270 | printf("ERROR: Already initialized num_fans\n"); | |
271 | return (ERROR); | |
272 | } | |
273 | } | |
274 | ||
275 | /* | |
276 | * fill the id-offset block with id numbers and their respective data | |
277 | * offsets as they are presented in the cfg file. | |
278 | */ | |
279 | ||
280 | int | |
281 | parse_id(char *line) | |
282 | { | |
283 | unsigned int input_val, offset, i; | |
284 | ||
285 | offset = id_num * SENSOR_BLOCK_SIZE; | |
286 | id_num++; | |
287 | if (scan_line(line, &input_val) == ERROR) | |
288 | return (ERROR); | |
289 | ||
290 | for (i = 0; i < id_num-1; i++) { | |
291 | if (!memcmp(&input_val, &id_header.id_block[i*SENSOR_BLOCK_SIZE], | |
292 | ID_SIZE)) { | |
293 | printf("ERROR: Two sensors with id = %x\n", input_val); | |
294 | return (ERROR); | |
295 | } | |
296 | } | |
297 | write_bytes(input_val, ID_SIZE, offset, id_header.id_block); | |
298 | offset += ID_SIZE; | |
299 | write_bytes(running_offset, OFFSET_SIZE, offset, id_header.id_block); | |
300 | ||
301 | return (NO_ERROR); | |
302 | } | |
303 | ||
304 | int | |
305 | parse_fan_id(char *line) | |
306 | { | |
307 | unsigned int input_val, offset, i; | |
308 | ||
309 | offset = fan_id_num * FAN_BLOCK_SIZE; | |
310 | fan_id_num++; | |
311 | if (scan_line(line, &input_val) == ERROR) | |
312 | return (ERROR); | |
313 | for (i = 0; i < fan_id_num-1; i++) { | |
314 | if (!memcmp(&input_val, &id_header.fan_block[i*FAN_BLOCK_SIZE], | |
315 | FAN_ID_SIZE)) { | |
316 | printf("ERROR: Two fans with id = %x\n", input_val); | |
317 | return (ERROR); | |
318 | } | |
319 | } | |
320 | write_bytes(input_val, FAN_ID_SIZE, offset, id_header.fan_block); | |
321 | offset += FAN_ID_SIZE; | |
322 | write_bytes(running_offset, FAN_OFF_SIZE, offset, id_header.fan_block); | |
323 | ||
324 | return (NO_ERROR); | |
325 | } | |
326 | ||
327 | /* | |
328 | * The sensor data blocks are marked by sensor-data-start and sensor-data-end | |
329 | * tokens. sensor data blocks should only be presented between these two tokens | |
330 | */ | |
331 | ||
332 | int | |
333 | env_dynamic(char *parameter, char *line) | |
334 | { | |
335 | int retval = NO_ERROR; | |
336 | ||
337 | if (strcmp(parameter, "sensor-data-start") == 0) { | |
338 | if (processing_fan) { | |
339 | printf("ERROR, fan data cannot contain"); | |
340 | printf(" sensor-data-start\n"); | |
341 | return (ERROR); | |
342 | } | |
343 | if (!processing_env) { | |
344 | if (env_table == NULL) { | |
345 | env_table = malloc( | |
346 | sizeof (struct env_table_entry)); | |
347 | cur_env_table = env_table; | |
348 | cur_env_table->next = NULL; | |
349 | } else { | |
350 | cur_env_table->next = malloc( | |
351 | sizeof (struct env_table_entry)); | |
352 | cur_env_table = cur_env_table->next; | |
353 | cur_env_table->next = NULL; | |
354 | } | |
355 | processing_env = 1; | |
356 | } else { | |
357 | printf("ERROR, consecutive sensor-data-start tokens"); | |
358 | printf(" without sensor-data-end\n"); | |
359 | retval = ERROR; | |
360 | } | |
361 | } else if (strcmp(parameter, "sensor-data-end") == 0) { | |
362 | if (processing_fan) { | |
363 | printf("ERROR, fan data cannot contain"); | |
364 | printf(" sensor-data-end\n"); | |
365 | return (ERROR); | |
366 | } | |
367 | if (!processing_env) { | |
368 | fprintf(stderr, "Missing env_table_start\n"); | |
369 | retval = ERROR; | |
370 | } else { | |
371 | if (current_correction != num_corrections) { | |
372 | printf("ERROR, missing correction entries\n"); | |
373 | retval = ERROR; | |
374 | } | |
375 | running_offset += ENV_ENTRY_SIZE + | |
376 | (num_corrections * COR_SIZE); | |
377 | processing_env = 0; | |
378 | num_corrections = 0; | |
379 | current_correction = 0; | |
380 | } | |
381 | } else if (strcmp(parameter, "id") == 0) { | |
382 | if (processing_env) { | |
383 | retval = parse_id(line); | |
384 | } else { | |
385 | retval = UNKNOWN; | |
386 | } | |
387 | } else if (strcmp(parameter, "fan-data-start") == 0) { | |
388 | if (processing_env) { | |
389 | printf("ERROR, sensor data cannot contain"); | |
390 | printf(" fan-data-start\n"); | |
391 | return (ERROR); | |
392 | } | |
393 | if (!processing_fan) { | |
394 | if (fan_table == NULL) { | |
395 | fan_table = malloc( | |
396 | sizeof (struct fan_table_entry)); | |
397 | memset(fan_table, 0, | |
398 | sizeof (struct fan_table_entry)); | |
399 | cur_fan_table = fan_table; | |
400 | cur_fan_table->next = NULL; | |
401 | } else { | |
402 | cur_fan_table->next = malloc( | |
403 | sizeof (struct fan_table_entry)); | |
404 | memset(cur_fan_table->next, 0, | |
405 | sizeof (struct fan_table_entry)); | |
406 | cur_fan_table = cur_fan_table->next; | |
407 | cur_fan_table->next = NULL; | |
408 | } | |
409 | processing_fan = 1; | |
410 | } else { | |
411 | printf("ERROR, consecutive fan-data-start tokens"); | |
412 | printf(" without fan-data-end\n"); | |
413 | retval = ERROR; | |
414 | } | |
415 | } else if (strcmp(parameter, "fan-data-end") == 0) { | |
416 | if (processing_env) { | |
417 | printf("ERROR, sensor data cannot contain"); | |
418 | printf(" fan-data-end\n"); | |
419 | return (ERROR); | |
420 | } | |
421 | if (!processing_fan) { | |
422 | fprintf(stderr, "Missing fan_table_start\n"); | |
423 | retval = ERROR; | |
424 | } else { | |
425 | if (current_fan_pair != num_fan_ctl_pairs) { | |
426 | printf("ERROR, missing fan-min-range"); | |
427 | printf(" entries\n"); | |
428 | retval = ERROR; | |
429 | } | |
430 | running_offset += ENV_FAN_ENTRY_SIZE + | |
431 | (num_fan_ctl_pairs * FAN_MIN_RANGE_SZ); | |
432 | processing_fan = 0; | |
433 | num_fan_ctl_pairs = 0; | |
434 | current_fan_pair = 0; | |
435 | } | |
436 | } else if (strcmp(parameter, "fan-id") == 0) { | |
437 | if (processing_fan) { | |
438 | retval = parse_fan_id(line); | |
439 | } else { | |
440 | retval = UNKNOWN; | |
441 | } | |
442 | } else if (strcmp(parameter, "num-fans") == 0) { | |
443 | if (env_version == 2) { | |
444 | set_num_fans(line); | |
445 | } else { | |
446 | printf("ERROR, num_fans is not a valid parameter"); | |
447 | printf(" for this version of the cfg file\n"); | |
448 | retval = ERROR; | |
449 | } | |
450 | } else { | |
451 | if (processing_env) { | |
452 | retval = update_env_table(parameter, line); | |
453 | } else if (processing_fan) { | |
454 | retval = update_fan_table(parameter, line); | |
455 | } else { | |
456 | retval = UNKNOWN; | |
457 | } | |
458 | } | |
459 | return (retval); | |
460 | } | |
461 | ||
462 | /* | |
463 | * the number of sensor ids must match the number-sensors token value | |
464 | */ | |
465 | ||
466 | int | |
467 | check_env() | |
468 | { | |
469 | int retval = NO_ERROR; | |
470 | if (id_num != id_header.num_sensors) { | |
471 | printf("ERROR, number of id fields does not match number "); | |
472 | printf("of sensors\n"); | |
473 | retval = ERROR; | |
474 | } | |
475 | if (fan_id_num != id_header.num_fans) { | |
476 | printf("ERROR, number of fan_id fields does not match number "); | |
477 | printf("of fans\n"); | |
478 | retval = ERROR; | |
479 | } | |
480 | return (retval); | |
481 | } | |
482 | ||
483 | int | |
484 | reg_env(char *s1, data_reg **reg) | |
485 | { | |
486 | return (NO_ERROR); | |
487 | } | |
488 | ||
489 | /* | |
490 | * version and num-sensors have already been added by the gen-seeprom tool. | |
491 | * First add the id-offset table, and then the sensor table data | |
492 | */ | |
493 | ||
494 | void | |
495 | write_env(unsigned char **ptr) | |
496 | { | |
497 | struct env_table_entry *table_ptr; | |
498 | struct fan_table_entry *fan_table_ptr; | |
499 | ||
500 | store_chars((id_header.num_sensors * SENSOR_BLOCK_SIZE), | |
501 | id_header.id_block, ptr); | |
502 | if (env_version > 1) { | |
503 | store_bytes(NUM_FAN_SIZE, | |
504 | (unsigned long long) id_header.num_fans, ptr); | |
505 | store_chars((id_header.num_fans * FAN_BLOCK_SIZE), | |
506 | id_header.fan_block, ptr); | |
507 | } | |
508 | ||
509 | ||
510 | table_ptr = env_table; | |
511 | while (table_ptr != NULL) { | |
512 | store_chars(ENV_ENTRY_SIZE, table_ptr->env_data, ptr); | |
513 | store_chars(table_ptr->correction_size, | |
514 | table_ptr->correction_data, ptr); | |
515 | table_ptr = table_ptr->next; | |
516 | } | |
517 | ||
518 | fan_table_ptr = fan_table; | |
519 | while (fan_table_ptr != NULL) { | |
520 | store_chars(ENV_FAN_ENTRY_SIZE, fan_table_ptr->fan_data, ptr); | |
521 | store_chars(fan_table_ptr->fan_pair_size, | |
522 | fan_table_ptr->fan_ctl_data, ptr); | |
523 | fan_table_ptr = fan_table_ptr->next; | |
524 | } | |
525 | ||
526 | } | |
527 | ||
528 | void | |
529 | dump_env() | |
530 | { | |
531 | } |