* ========== Copyright Header Begin ==========================================
* Hypervisor Software File: env-seeprom.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* - Do no alter or remove copyright notices
* - Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* - Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of Sun Microsystems, Inc. or the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* You acknowledge that this software is not designed, licensed or
* intended for use in the design, construction, operation or maintenance of
* ========== Copyright Header End ============================================
* id: @(#)env-seeprom.c 1.3 03/06/11
* copyright: Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved
* copyright: Use is subject to license terms.
int processing_env
= 0, processing_fan
= 0;
int running_offset
= VER_SIZE
;
struct env_table_entry
*env_table
= NULL
;
struct env_table_entry
*cur_env_table
;
struct fan_table_entry
*fan_table
= NULL
;
struct fan_table_entry
*cur_fan_table
;
struct id_header_data id_header
;
int current_correction
= 0, current_fan_pair
= 0;
int num_corrections
= 0, num_fan_ctl_pairs
= 0;
int id_num
= 0, fan_id_num
= 0, env_version
= 0;
* allocate memory for the id-offset block
set_num_sensors(void *data
)
id_header
.num_sensors
= (int)data
;
running_offset
+= NUM_SEN_SIZE
+
(id_header
.num_sensors
* SENSOR_BLOCK_SIZE
);
id_header
.id_block
= malloc(id_header
.num_sensors
* SENSOR_BLOCK_SIZE
);
* "version" , "num-sensors" , "num-fans" will only show up once in a properly
* configured environmental segment
struct fixed_seeprom env_seeprom_data
[] = {
/* name size type value */
{ "version", VER_SIZE
, NUM
, 0, set_env_ver
},
{ "num-sensors", NUM_SEN_SIZE
, NUM
, 0, set_num_sensors
},
not_byte_range(int value
)
return (value
> 255 || value
< 0);
not_sbyte_range(int value
)
return (value
> 127 || value
< -128);
correction_scan(char *line
, unsigned int *input_val
)
char input_one
[MAXNAMESIZE
];
char input_two
[MAXNAMESIZE
];
if (sscanf(line
, "%s %s %s", temp
, input_one
, input_two
) != 3) {
strip_val(input_one
, input_val
);
strip_val(input_two
, &temp_val
);
if (not_sbyte_range(*input_val
) || not_sbyte_range(temp_val
))
*input_val
= (*input_val
& 0xff) << 8;
*input_val
+= (temp_val
& 0xff);
printf("Correction table entries must be entered as a ");
printf("pair of signed bytes\n");
fan_min_range_scan(char *line
, unsigned int *input_val
)
char input_one
[MAXNAMESIZE
];
char input_two
[MAXNAMESIZE
];
if (sscanf(line
, "%s %s %s", temp
, input_one
, input_two
) != 3) {
strip_val(input_one
, input_val
);
strip_val(input_two
, &temp_val
);
if (not_sbyte_range(*input_val
) || not_byte_range(temp_val
))
*input_val
= (*input_val
& 0xff) << 8;
*input_val
+= (temp_val
& 0xff);
printf("Fan min/range table entries must be entered as a ");
printf("signed, unsigned byte pair.\n");
update_env_table(char *parameter
, char *line
)
while (strcmp(env_parameters
[i
].name
, parameter
)) {
offset
+= env_parameters
[i
++].size
;
if (env_parameters
[i
].name
== NULL
) {
"%s is not a valid env parameter\n", parameter
);
size
= env_parameters
[i
].size
;
data_ptr
= cur_env_table
->env_data
;
if (strcmp(parameter
, "correction") == 0) {
offset
= COR_SIZE
* current_correction
;
data_ptr
= cur_env_table
->correction_data
;
if ((correction_scan(line
, &input_val
) == ERROR
))
} else if ((scan_line(line
, &input_val
) == ERROR
))
if (strcmp(parameter
, "num-corrections") == 0) {
num_corrections
= input_val
;
cur_env_table
->correction_data
=
(unsigned char *) malloc(COR_SIZE
* num_corrections
);
cur_env_table
->correction_size
= num_corrections
* COR_SIZE
;
write_bytes(input_val
, size
, offset
, data_ptr
);
update_fan_table(char *parameter
, char *line
)
while (strcmp(fan_parameters
[i
].name
, parameter
)) {
offset
+= fan_parameters
[i
++].size
;
if (fan_parameters
[i
].name
== NULL
) {
"%s is not a valid fan parameter\n", parameter
);
size
= fan_parameters
[i
].size
;
data_ptr
= cur_fan_table
->fan_data
;
if (strcmp(parameter
, "fan-min-range") == 0) {
offset
= FAN_MIN_RANGE_SZ
* current_fan_pair
;
data_ptr
= cur_fan_table
->fan_ctl_data
;
if ((fan_min_range_scan(line
, &input_val
) == ERROR
))
} else if ((scan_line(line
, &input_val
) == ERROR
))
if (strcmp(parameter
, "num-ctl-pairs") == 0) {
num_fan_ctl_pairs
= input_val
;
cur_fan_table
->fan_ctl_data
=
(unsigned char *) malloc(FAN_MIN_RANGE_SZ
*
cur_fan_table
->fan_pair_size
= num_fan_ctl_pairs
*
write_bytes(input_val
, size
, offset
, data_ptr
);
if (id_header
.num_fans
== 0) {
if (scan_line(line
, &input_val
) == ERROR
)
id_header
.num_fans
= input_val
;
running_offset
+= NUM_FAN_SIZE
+
(id_header
.num_fans
* FAN_BLOCK_SIZE
);
id_header
.fan_block
= malloc(id_header
.num_fans
*
printf("ERROR: Already initialized num_fans\n");
* fill the id-offset block with id numbers and their respective data
* offsets as they are presented in the cfg file.
unsigned int input_val
, offset
, i
;
offset
= id_num
* SENSOR_BLOCK_SIZE
;
if (scan_line(line
, &input_val
) == ERROR
)
for (i
= 0; i
< id_num
-1; i
++) {
if (!memcmp(&input_val
, &id_header
.id_block
[i
*SENSOR_BLOCK_SIZE
],
printf("ERROR: Two sensors with id = %x\n", input_val
);
write_bytes(input_val
, ID_SIZE
, offset
, id_header
.id_block
);
write_bytes(running_offset
, OFFSET_SIZE
, offset
, id_header
.id_block
);
unsigned int input_val
, offset
, i
;
offset
= fan_id_num
* FAN_BLOCK_SIZE
;
if (scan_line(line
, &input_val
) == ERROR
)
for (i
= 0; i
< fan_id_num
-1; i
++) {
if (!memcmp(&input_val
, &id_header
.fan_block
[i
*FAN_BLOCK_SIZE
],
printf("ERROR: Two fans with id = %x\n", input_val
);
write_bytes(input_val
, FAN_ID_SIZE
, offset
, id_header
.fan_block
);
write_bytes(running_offset
, FAN_OFF_SIZE
, offset
, id_header
.fan_block
);
* The sensor data blocks are marked by sensor-data-start and sensor-data-end
* tokens. sensor data blocks should only be presented between these two tokens
env_dynamic(char *parameter
, char *line
)
if (strcmp(parameter
, "sensor-data-start") == 0) {
printf("ERROR, fan data cannot contain");
printf(" sensor-data-start\n");
sizeof (struct env_table_entry
));
cur_env_table
= env_table
;
cur_env_table
->next
= NULL
;
cur_env_table
->next
= malloc(
sizeof (struct env_table_entry
));
cur_env_table
= cur_env_table
->next
;
cur_env_table
->next
= NULL
;
printf("ERROR, consecutive sensor-data-start tokens");
printf(" without sensor-data-end\n");
} else if (strcmp(parameter
, "sensor-data-end") == 0) {
printf("ERROR, fan data cannot contain");
printf(" sensor-data-end\n");
fprintf(stderr
, "Missing env_table_start\n");
if (current_correction
!= num_corrections
) {
printf("ERROR, missing correction entries\n");
running_offset
+= ENV_ENTRY_SIZE
+
(num_corrections
* COR_SIZE
);
} else if (strcmp(parameter
, "id") == 0) {
} else if (strcmp(parameter
, "fan-data-start") == 0) {
printf("ERROR, sensor data cannot contain");
printf(" fan-data-start\n");
sizeof (struct fan_table_entry
));
sizeof (struct fan_table_entry
));
cur_fan_table
= fan_table
;
cur_fan_table
->next
= NULL
;
cur_fan_table
->next
= malloc(
sizeof (struct fan_table_entry
));
memset(cur_fan_table
->next
, 0,
sizeof (struct fan_table_entry
));
cur_fan_table
= cur_fan_table
->next
;
cur_fan_table
->next
= NULL
;
printf("ERROR, consecutive fan-data-start tokens");
printf(" without fan-data-end\n");
} else if (strcmp(parameter
, "fan-data-end") == 0) {
printf("ERROR, sensor data cannot contain");
printf(" fan-data-end\n");
fprintf(stderr
, "Missing fan_table_start\n");
if (current_fan_pair
!= num_fan_ctl_pairs
) {
printf("ERROR, missing fan-min-range");
running_offset
+= ENV_FAN_ENTRY_SIZE
+
(num_fan_ctl_pairs
* FAN_MIN_RANGE_SZ
);
} else if (strcmp(parameter
, "fan-id") == 0) {
retval
= parse_fan_id(line
);
} else if (strcmp(parameter
, "num-fans") == 0) {
printf("ERROR, num_fans is not a valid parameter");
printf(" for this version of the cfg file\n");
retval
= update_env_table(parameter
, line
);
} else if (processing_fan
) {
retval
= update_fan_table(parameter
, line
);
* the number of sensor ids must match the number-sensors token value
if (id_num
!= id_header
.num_sensors
) {
printf("ERROR, number of id fields does not match number ");
if (fan_id_num
!= id_header
.num_fans
) {
printf("ERROR, number of fan_id fields does not match number ");
reg_env(char *s1
, data_reg
**reg
)
* version and num-sensors have already been added by the gen-seeprom tool.
* First add the id-offset table, and then the sensor table data
write_env(unsigned char **ptr
)
struct env_table_entry
*table_ptr
;
struct fan_table_entry
*fan_table_ptr
;
store_chars((id_header
.num_sensors
* SENSOR_BLOCK_SIZE
),
id_header
.id_block
, ptr
);
store_bytes(NUM_FAN_SIZE
,
(unsigned long long) id_header
.num_fans
, ptr
);
store_chars((id_header
.num_fans
* FAN_BLOCK_SIZE
),
id_header
.fan_block
, ptr
);
while (table_ptr
!= NULL
) {
store_chars(ENV_ENTRY_SIZE
, table_ptr
->env_data
, ptr
);
store_chars(table_ptr
->correction_size
,
table_ptr
->correction_data
, ptr
);
table_ptr
= table_ptr
->next
;
fan_table_ptr
= fan_table
;
while (fan_table_ptr
!= NULL
) {
store_chars(ENV_FAN_ENTRY_SIZE
, fan_table_ptr
->fan_data
, ptr
);
store_chars(fan_table_ptr
->fan_pair_size
,
fan_table_ptr
->fan_ctl_data
, ptr
);
fan_table_ptr
= fan_table_ptr
->next
;