4
* MontaVista IPMI code for handling sensors
6
* Author: MontaVista Software, Inc.
7
* Corey Minyard <minyard@mvista.com>
10
* Copyright 2002,2003 MontaVista Software Inc.
12
* This program is free software; you can redistribute it and/or
13
* modify it under the terms of the GNU Lesser General Public License
14
* as published by the Free Software Foundation; either version 2 of
15
* the License, or (at your option) any later version.
18
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
* You should have received a copy of the GNU Lesser General Public
30
* License along with this program; if not, write to the Free
31
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38
#include <OpenIPMI/ipmiif.h>
39
#include <OpenIPMI/ipmi_sdr.h>
40
#include <OpenIPMI/ipmi_msgbits.h>
41
#include <OpenIPMI/ipmi_err.h>
43
#include <OpenIPMI/internal/locked_list.h>
44
#include <OpenIPMI/internal/opq.h>
45
#include <OpenIPMI/internal/ipmi_int.h>
46
#include <OpenIPMI/internal/ipmi_sensor.h>
47
#include <OpenIPMI/internal/ipmi_entity.h>
48
#include <OpenIPMI/internal/ipmi_domain.h>
49
#include <OpenIPMI/internal/ipmi_mc.h>
50
#include <OpenIPMI/internal/ipmi_event.h>
52
struct ipmi_sensor_info_s
56
/* Indexed by LUN and sensor # */
57
ipmi_sensor_t **(sensors_by_idx[5]);
58
/* Size of above sensor array, per LUN. This will be 0 if the
59
LUN has no sensors. */
61
/* In the above two, the 5th index is for non-standard sensors. */
63
ipmi_lock_t *idx_lock;
65
/* Total number of sensors we have in this. */
66
unsigned int sensor_count;
72
#define SENSOR_ID_LEN 32 /* 16 bytes are allowed for a sensor. */
75
unsigned int usecount;
77
ipmi_domain_t *domain; /* Domain I am in. */
79
ipmi_mc_t *mc; /* My owner, NOT the SMI mc (unless that
80
happens to be my direct owner). */
82
ipmi_mc_t *source_mc; /* If the sensor came from the main SDR,
83
this will be NULL. Otherwise, it
84
will be the MC that owned the device
85
SDR this came from. */
86
int source_idx; /* The index into the source array where
87
this is stored. This will be -1 if
88
it does not have a source index (ie
89
it's a non-standard sensor) */
90
int source_recid; /* The SDR record ID the sensor came from. */
91
ipmi_sensor_t **source_array; /* This is the source array where
92
the sensor is stored. */
96
/* After the sensor is added, it will not be reported immediately.
97
Instead, it will wait until the usecount goes to zero before
98
being reported. This marks that the add report is pending */
102
unsigned char channel;
106
/* For OEM sensors, the sending LUN might be different that the
107
LUN we use for storage. */
108
unsigned char send_lun;
110
ipmi_entity_t *entity;
112
unsigned char entity_id;
113
unsigned char entity_instance;
115
unsigned char entity_instance_logical : 1;
116
unsigned int sensor_init_scanning : 1;
117
unsigned int sensor_init_events : 1;
118
unsigned int sensor_init_thresholds : 1;
119
unsigned int sensor_init_hysteresis : 1;
120
unsigned int sensor_init_type : 1;
121
unsigned int sensor_init_pu_events : 1;
122
unsigned int sensor_init_pu_scanning : 1;
123
unsigned int ignore_if_no_entity : 1;
124
unsigned int supports_auto_rearm : 1;
125
unsigned int hysteresis_support : 2;
126
unsigned int threshold_access : 2;
127
unsigned int event_support : 2;
129
unsigned int sensor_direction : 2;
131
int hot_swap_requester;
132
unsigned int hot_swap_requester_val;
134
unsigned char sensor_type;
136
unsigned char event_reading_type;
138
unsigned char mask1[16];
139
unsigned char mask2[16];
140
unsigned char mask3[16];
142
unsigned int analog_data_format : 2;
144
unsigned int rate_unit : 3;
146
unsigned int modifier_unit_use : 2;
148
unsigned int percentage : 1;
150
unsigned char base_unit;
151
unsigned char modifier_unit;
153
unsigned char linearization;
157
unsigned int tolerance : 6;
160
unsigned int accuracy_exp : 2;
165
unsigned int normal_min_specified : 1;
166
unsigned int normal_max_specified : 1;
167
unsigned int nominal_reading_specified : 1;
169
unsigned char nominal_reading;
170
unsigned char normal_max;
171
unsigned char normal_min;
172
unsigned char sensor_max;
173
unsigned char sensor_min;
174
unsigned char default_thresholds[6];
175
unsigned char positive_going_threshold_hysteresis;
176
unsigned char negative_going_threshold_hysteresis;
181
/* Note that the ID is *not* nil terminated. */
182
enum ipmi_str_type_e id_type;
184
char id[SENSOR_ID_LEN]; /* The ID from the device SDR. */
186
const char *sensor_type_string;
187
const char *event_reading_type_string;
188
const char *rate_unit_string;
189
const char *base_unit_string;
190
const char *modifier_unit_string;
192
/* A list of handlers to call when an event for the sensor comes
194
locked_list_t *handler_list;
197
ipmi_event_state_t event_state;
199
/* Polymorphic functions. */
200
ipmi_sensor_cbs_t cbs;
204
ipmi_sensor_cleanup_oem_info_cb oem_info_cleanup_handler;
206
ipmi_sensor_destroy_cb destroy_handler;
207
void *destroy_handler_cb_data;
209
/* Name we use for reporting. We add a ' ' onto the end, thus
211
char name[IPMI_SENSOR_NAME_LEN+1];
213
/* Used for temporary linking. */
214
ipmi_sensor_t *tlink;
217
ipmi_sensor_threshold_event_handler_nd_cb threshold_event_handler;
218
ipmi_sensor_discrete_event_handler_nd_cb discrete_event_handler;
222
static void sensor_final_destroy(ipmi_sensor_t *sensor);
224
/***********************************************************************
226
* Sensor ID handling.
228
**********************************************************************/
230
/* Must be called with the domain entity lock held. */
232
_ipmi_sensor_get(ipmi_sensor_t *sensor)
234
if (sensor->destroyed)
241
_ipmi_sensor_put(ipmi_sensor_t *sensor)
243
ipmi_domain_t *domain = sensor->domain;
244
_ipmi_domain_entity_lock(domain);
245
if (sensor->usecount == 1) {
246
if (sensor->add_pending) {
247
sensor->add_pending = 0;
248
_ipmi_domain_entity_unlock(sensor->domain);
249
_ipmi_entity_call_sensor_handlers(sensor->entity,
251
_ipmi_domain_entity_lock(sensor->domain);
253
if (sensor->destroyed
255
|| (!opq_stuff_in_progress(sensor->waitq))))
257
_ipmi_domain_entity_unlock(domain);
258
sensor_final_destroy(sensor);
263
_ipmi_domain_entity_unlock(domain);
267
ipmi_sensor_convert_to_id(ipmi_sensor_t *sensor)
269
ipmi_sensor_id_t val;
271
CHECK_SENSOR_LOCK(sensor);
273
val.mcid = ipmi_mc_convert_to_id(sensor->mc);
274
val.lun = sensor->lun;
275
val.sensor_num = sensor->num;
281
ipmi_cmp_sensor_id(ipmi_sensor_id_t id1, ipmi_sensor_id_t id2)
285
rv = ipmi_cmp_mc_id(id1.mcid, id2.mcid);
288
if (id1.lun > id2.lun)
290
if (id1.lun < id2.lun)
292
if (id1.sensor_num > id2.sensor_num)
294
if (id1.sensor_num < id2.sensor_num)
300
ipmi_sensor_id_set_invalid(ipmi_sensor_id_t *id)
302
memset(id, 0, sizeof(*id));
306
ipmi_sensor_id_is_invalid(ipmi_sensor_id_t *id)
308
return (id->mcid.domain_id.domain == NULL);
311
typedef struct mc_cb_info_s
313
ipmi_sensor_ptr_cb handler;
320
mc_cb(ipmi_mc_t *mc, void *cb_data)
322
mc_cb_info_t *info = cb_data;
323
ipmi_sensor_info_t *sensors;
324
ipmi_domain_t *domain = ipmi_mc_get_domain(mc);
325
ipmi_sensor_t *sensor;
326
ipmi_entity_t *entity = NULL;
328
sensors = _ipmi_mc_get_sensors(mc);
329
_ipmi_domain_entity_lock(domain);
330
if (info->id.lun > 4) {
335
if (info->id.sensor_num >= sensors->idx_size[info->id.lun]) {
340
sensor = sensors->sensors_by_idx[info->id.lun][info->id.sensor_num];
346
info->err = _ipmi_entity_get(sensor->entity);
349
entity = sensor->entity;
351
info->err = _ipmi_sensor_get(sensor);
355
_ipmi_domain_entity_unlock(domain);
357
info->handler(sensor, info->cb_data);
359
_ipmi_sensor_put(sensor);
360
_ipmi_entity_put(entity);
364
_ipmi_domain_entity_unlock(domain);
366
_ipmi_entity_put(entity);
370
ipmi_sensor_pointer_cb(ipmi_sensor_id_t id,
371
ipmi_sensor_ptr_cb handler,
380
info.handler = handler;
381
info.cb_data = cb_data;
385
rv = ipmi_mc_pointer_cb(id.mcid, mc_cb, &info);
393
ipmi_sensor_pointer_noseq_cb(ipmi_sensor_id_t id,
394
ipmi_sensor_ptr_cb handler,
403
info.handler = handler;
404
info.cb_data = cb_data;
408
rv = ipmi_mc_pointer_noseq_cb(id.mcid, mc_cb, &info);
415
typedef struct sensor_find_info_s
420
} sensor_find_info_t;
423
sensor_search_cmp(ipmi_entity_t *entity, ipmi_sensor_t *sensor, void *cb_data)
425
sensor_find_info_t *info = cb_data;
429
rv = ipmi_sensor_get_id(sensor, id, 33);
432
if (strcmp(info->id_name, id) == 0) {
433
info->id = ipmi_sensor_convert_to_id(sensor);
439
sensor_search(ipmi_entity_t *entity, void *cb_data)
441
sensor_find_info_t *info = cb_data;
443
ipmi_entity_iterate_sensors(entity, sensor_search_cmp, info);
447
ipmi_sensor_find_id(ipmi_domain_id_t domain_id,
448
int entity_id, int entity_instance,
449
int channel, int slave_address,
451
ipmi_sensor_id_t *id)
454
ipmi_entity_id_t entity;
455
sensor_find_info_t info;
457
rv = ipmi_entity_find_id(domain_id, entity_id, entity_instance,
458
channel, slave_address, &entity);
462
info.id_name = id_name;
465
rv = ipmi_entity_pointer_cb(entity, sensor_search, &info);
474
/***********************************************************************
476
* Various sensor allocation/deallocation/opq/etc.
478
**********************************************************************/
480
static void sensor_set_name(ipmi_sensor_t *sensor);
483
sensor_opq_ready2(ipmi_sensor_t *sensor, void *cb_data)
485
ipmi_sensor_op_info_t *info = cb_data;
487
info->__handler(sensor, 0, info->__cb_data);
491
sensor_opq_ready(void *cb_data, int shutdown)
493
ipmi_sensor_op_info_t *info = cb_data;
498
info->__handler(info->__sensor, ECANCELED, info->__cb_data);
502
rv = ipmi_sensor_pointer_cb(info->__sensor_id, sensor_opq_ready2, info);
505
info->__handler(info->__sensor, rv, info->__cb_data);
509
ipmi_sensor_add_opq(ipmi_sensor_t *sensor,
510
ipmi_sensor_op_cb handler,
511
ipmi_sensor_op_info_t *info,
514
if (sensor->destroyed)
517
info->__sensor = sensor;
518
info->__sensor_id = ipmi_sensor_convert_to_id(sensor);
519
info->__cb_data = cb_data;
520
info->__handler = handler;
521
if (!opq_new_op(sensor->waitq, sensor_opq_ready, info, 0))
527
sensor_id_add_opq_cb(ipmi_sensor_t *sensor, void *cb_data)
529
ipmi_sensor_op_info_t *info = cb_data;
531
info->__sensor = sensor;
532
if (!opq_new_op(sensor->waitq, sensor_opq_ready, info, 0))
533
info->__err = ENOMEM;
537
ipmi_sensor_id_add_opq(ipmi_sensor_id_t sensor_id,
538
ipmi_sensor_op_cb handler,
539
ipmi_sensor_op_info_t *info,
544
info->__sensor_id = sensor_id;
545
info->__cb_data = cb_data;
546
info->__handler = handler;
548
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_add_opq_cb, info);
555
ipmi_sensor_opq_done(ipmi_sensor_t *sensor)
557
/* Protect myself from NULL sensors. This way, it doesn't have to
558
be done in each call. */
562
/* This gets called on ECANCELLED error cases, if the sensor is
563
already we need to clear out the opq. */
564
if (sensor->destroyed) {
566
opq_destroy(sensor->waitq);
567
sensor->waitq = NULL;
572
/* No check for the sensor lock. It will sometimes fail at
575
opq_op_done(sensor->waitq);
579
sensor_rsp_handler2(ipmi_sensor_t *sensor, void *cb_data)
581
ipmi_sensor_op_info_t *info = cb_data;
583
if (info->__rsp_handler)
584
info->__rsp_handler(sensor, 0, info->__rsp, info->__cb_data);
588
sensor_rsp_handler(ipmi_mc_t *mc,
592
ipmi_sensor_op_info_t *info = rsp_data;
594
ipmi_sensor_t *sensor = info->__sensor;
596
if (sensor->destroyed) {
597
ipmi_entity_t *entity = NULL;
599
_ipmi_domain_entity_lock(sensor->domain);
601
_ipmi_domain_entity_unlock(sensor->domain);
603
rv = _ipmi_entity_get(sensor->entity);
605
entity = sensor->entity;
607
if (info->__rsp_handler)
608
info->__rsp_handler(sensor, ECANCELED, NULL, info->__cb_data);
610
_ipmi_sensor_put(sensor);
612
_ipmi_entity_put(entity);
617
if (info->__rsp_handler)
618
info->__rsp_handler(sensor, ECANCELED, rsp, info->__cb_data);
622
/* Call the next stage with the lock held. */
624
rv = ipmi_sensor_pointer_cb(info->__sensor_id,
628
ipmi_log(IPMI_LOG_ERR_INFO,
629
"%ssensor.c(sensor_rsp_handler):"
630
" Could not convert sensor id to a pointer",
632
if (info->__rsp_handler)
633
info->__rsp_handler(sensor, rv, NULL, info->__cb_data);
638
ipmi_sensor_send_command(ipmi_sensor_t *sensor,
642
ipmi_sensor_rsp_cb handler,
643
ipmi_sensor_op_info_t *info,
649
CHECK_SENSOR_LOCK(sensor);
651
if (sensor->destroyed)
654
info->__sensor = sensor;
655
info->__sensor_id = ipmi_sensor_convert_to_id(sensor);
656
info->__cb_data = cb_data;
657
info->__rsp_handler = handler;
658
rv = ipmi_mc_send_command(mc, lun, msg, sensor_rsp_handler, info);
663
sensor_addr_response_handler(ipmi_domain_t *domain, ipmi_msgi_t *rspi)
665
ipmi_msg_t *msg = &rspi->msg;
666
ipmi_sensor_op_info_t *info = rspi->data1;
668
ipmi_sensor_t *sensor = info->__sensor;
670
if (sensor->destroyed) {
671
if (info->__rsp_handler)
672
info->__rsp_handler(NULL, ECANCELED, NULL, info->__cb_data);
674
_ipmi_domain_entity_lock(sensor->domain);
676
_ipmi_domain_entity_unlock(sensor->domain);
677
_ipmi_sensor_put(sensor);
678
return IPMI_MSG_ITEM_NOT_USED;
681
/* Call the next stage with the lock held. */
683
rv = ipmi_sensor_pointer_cb(info->__sensor_id,
687
ipmi_log(IPMI_LOG_ERR_INFO,
688
"%ssensor.c(sensor_addr_rsp_handler):"
689
" Could not convert sensor id to a pointer",
690
DOMAIN_NAME(domain));
691
if (info->__rsp_handler)
692
info->__rsp_handler(sensor, rv, NULL, info->__cb_data);
694
return IPMI_MSG_ITEM_NOT_USED;
698
ipmi_sensor_send_command_addr(ipmi_domain_t *domain,
699
ipmi_sensor_t *sensor,
701
unsigned int addr_len,
703
ipmi_sensor_rsp_cb handler,
704
ipmi_sensor_op_info_t *info,
709
CHECK_SENSOR_LOCK(sensor);
710
CHECK_MC_LOCK(sensor->mc);
712
info->__sensor = sensor;
713
info->__sensor_id = ipmi_sensor_convert_to_id(sensor);
714
info->__cb_data = cb_data;
715
info->__rsp_handler = handler;
716
rv = ipmi_send_command_addr(domain, addr, addr_len,
717
msg, sensor_addr_response_handler, info, NULL);
722
ipmi_sensors_alloc(ipmi_mc_t *mc, ipmi_sensor_info_t **new_sensors)
724
ipmi_sensor_info_t *sensors;
725
ipmi_domain_t *domain;
726
os_handler_t *os_hnd;
732
domain = ipmi_mc_get_domain(mc);
733
os_hnd = ipmi_domain_get_os_hnd(domain);
735
sensors = ipmi_mem_alloc(sizeof(*sensors));
738
sensors->sensor_wait_q = opq_alloc(os_hnd);
739
if (! sensors->sensor_wait_q) {
740
ipmi_mem_free(sensors);
744
rv = ipmi_create_lock_os_hnd(os_hnd, &sensors->idx_lock);
746
opq_destroy(sensors->sensor_wait_q);
747
ipmi_mem_free(sensors);
751
sensors->destroyed = 0;
752
sensors->sensor_count = 0;
753
for (i=0; i<5; i++) {
754
sensors->sensors_by_idx[i] = NULL;
755
sensors->idx_size[i] = 0;
758
*new_sensors = sensors;
763
ipmi_sensors_get_count(ipmi_sensor_info_t *sensors)
765
return sensors->sensor_count;
769
_ipmi_sensors_get_waitq(ipmi_sensor_info_t *sensors)
771
return sensors->sensor_wait_q;
775
ipmi_sensor_alloc_nonstandard(ipmi_sensor_t **new_sensor)
777
ipmi_sensor_t *sensor;
779
sensor = ipmi_mem_alloc(sizeof(*sensor));
783
memset(sensor, 0, sizeof(*sensor));
785
sensor->hot_swap_requester = -1;
786
sensor->usecount = 1;
788
*new_sensor = sensor;
793
ipmi_sensor_add_nonstandard(ipmi_mc_t *mc,
794
ipmi_mc_t *source_mc,
795
ipmi_sensor_t *sensor,
797
unsigned int send_lun,
799
ipmi_sensor_destroy_cb destroy_handler,
800
void *destroy_handler_cb_data)
802
ipmi_sensor_info_t *sensors = _ipmi_mc_get_sensors(mc);
803
ipmi_domain_t *domain;
804
os_handler_t *os_hnd;
808
CHECK_ENTITY_LOCK(ent);
810
domain = ipmi_mc_get_domain(mc);
811
os_hnd = ipmi_domain_get_os_hnd(domain);
816
_ipmi_domain_entity_lock(domain);
817
ipmi_lock(sensors->idx_lock);
819
if (num >= sensors->idx_size[4]) {
820
ipmi_sensor_t **new_array;
821
unsigned int new_size;
824
/* Allocate the array in multiples of 16 (to avoid thrashing malloc
826
new_size = ((num / 16) * 16) + 16;
827
new_array = ipmi_mem_alloc(sizeof(*new_array) * new_size);
830
if (sensors->sensors_by_idx[4]) {
831
memcpy(new_array, sensors->sensors_by_idx[4],
832
sizeof(*new_array) * (sensors->idx_size[4]));
833
ipmi_mem_free(sensors->sensors_by_idx[4]);
835
for (i=sensors->idx_size[4]; i<new_size; i++)
837
sensors->sensors_by_idx[4] = new_array;
838
sensors->idx_size[4] = new_size;
841
sensor->waitq = opq_alloc(os_hnd);
845
sensor->handler_list = locked_list_alloc(os_hnd);
846
if (! sensor->handler_list) {
847
opq_destroy(sensor->waitq);
851
link = locked_list_alloc_entry();
853
opq_destroy(sensor->waitq);
854
sensor->waitq = NULL;
855
locked_list_destroy(sensor->handler_list);
856
sensor->handler_list = NULL;
860
sensor->domain = domain;
862
sensor->source_mc = source_mc;
864
sensor->send_lun = send_lun;
866
sensor->source_idx = -1;
867
sensor->source_array = NULL;
868
if (!sensors->sensors_by_idx[4][num])
869
sensors->sensor_count++;
870
sensors->sensors_by_idx[4][num] = sensor;
871
sensor->entity = ent;
872
sensor->entity_id = ipmi_entity_get_entity_id(ent);
873
sensor->entity_instance = ipmi_entity_get_entity_instance(ent);
874
sensor->destroy_handler = destroy_handler;
875
sensor->destroy_handler_cb_data = destroy_handler_cb_data;
876
sensor_set_name(sensor);
878
ipmi_unlock(sensors->idx_lock);
880
_ipmi_domain_entity_unlock(domain);
882
ipmi_entity_add_sensor(ent, sensor, link);
884
sensor->add_pending = 1;
890
sensor_final_destroy(ipmi_sensor_t *sensor)
892
_ipmi_entity_get(sensor->entity);
893
_ipmi_entity_call_sensor_handlers(sensor->entity, sensor, IPMI_DELETED);
897
if (sensor->destroy_handler)
898
sensor->destroy_handler(sensor, sensor->destroy_handler_cb_data);
900
if (sensor->oem_info_cleanup_handler)
901
sensor->oem_info_cleanup_handler(sensor, sensor->oem_info);
904
opq_destroy(sensor->waitq);
906
if (sensor->handler_list)
907
locked_list_destroy(sensor->handler_list);
910
ipmi_entity_remove_sensor(sensor->entity, sensor);
912
_ipmi_entity_put(sensor->entity);
913
ipmi_mem_free(sensor);
917
ipmi_sensor_destroy(ipmi_sensor_t *sensor)
919
ipmi_sensor_info_t *sensors = _ipmi_mc_get_sensors(sensor->mc);
921
ipmi_lock(sensors->idx_lock);
922
if (sensor != sensors->sensors_by_idx[sensor->lun][sensor->num])
925
_ipmi_sensor_get(sensor);
927
if (sensor->source_array)
928
sensor->source_array[sensor->source_idx] = NULL;
930
sensors->sensor_count--;
931
sensors->sensors_by_idx[sensor->lun][sensor->num] = NULL;
932
ipmi_unlock(sensors->idx_lock);
934
sensor->destroyed = 1;
935
_ipmi_sensor_put(sensor);
940
ipmi_sensors_destroy(ipmi_sensor_info_t *sensors)
944
if (sensors->destroyed)
947
sensors->destroyed = 1;
948
for (i=0; i<=4; i++) {
949
for (j=0; j<sensors->idx_size[i]; j++) {
950
if (sensors->sensors_by_idx[i][j]) {
951
ipmi_sensor_destroy(sensors->sensors_by_idx[i][j]);
954
if (sensors->sensors_by_idx[i])
955
ipmi_mem_free(sensors->sensors_by_idx[i]);
957
if (sensors->sensor_wait_q)
958
opq_destroy(sensors->sensor_wait_q);
959
if (sensors->idx_lock)
960
ipmi_destroy_lock(sensors->idx_lock);
961
ipmi_mem_free(sensors);
966
sensor_set_name(ipmi_sensor_t *sensor)
970
length = ipmi_entity_get_name(sensor->entity, sensor->name,
971
sizeof(sensor->name)-2);
972
sensor->name[length] = '.';
974
length += snprintf(sensor->name+length, IPMI_SENSOR_NAME_LEN-length-2,
976
sensor->name[length] = ' ';
978
sensor->name[length] = '\0';
983
_ipmi_sensor_name(ipmi_sensor_t *sensor)
989
ipmi_sensor_get_name(ipmi_sensor_t *sensor, char *name, int length)
996
/* Never changes, no lock needed. */
997
slen = strlen(sensor->name);
1004
slen -= 1; /* Remove the trailing ' ' */
1009
memcpy(name, sensor->name, slen);
1016
/***********************************************************************
1018
* Sensor SDR handling
1020
**********************************************************************/
1023
get_sensors_from_sdrs(ipmi_domain_t *domain,
1024
ipmi_mc_t *source_mc,
1025
ipmi_sdr_info_t *sdrs,
1026
ipmi_sensor_t ***sensors,
1027
unsigned int *sensor_count)
1031
ipmi_sensor_t **s = NULL;
1032
unsigned int p, s_size = 0;
1037
int id_string_mod_type;
1038
int entity_instance_incr;
1039
int id_string_modifier_offset;
1044
rv = ipmi_get_sdr_count(sdrs, &count);
1048
/* Get a real count on the number of sensors, since a single SDR can
1049
contain multiple sensors. */
1051
for (i=0; i<count; i++) {
1055
rv = ipmi_get_sdr_by_index(sdrs, i, &sdr);
1059
lun = sdr.data[1] & 0x03;
1060
if (sdr.type == 1) {
1062
} else if (sdr.type == 2) {
1063
if (sdr.data[18] & 0x0f)
1064
incr = sdr.data[18] & 0x0f;
1067
} else if (sdr.type == 3) {
1068
if (sdr.data[7] & 0x0f)
1069
incr = sdr.data[7] & 0x0f;
1078
/* Setup memory to hold the sensors. */
1079
s = ipmi_mem_alloc(sizeof(*s) * p);
1085
memset(s, 0, sizeof(*s) * p);
1088
for (i=0; i<count; i++) {
1089
rv = ipmi_get_sdr_by_index(sdrs, i, &sdr);
1093
if ((sdr.type != 1) && (sdr.type != 2) && (sdr.type != 3))
1096
s[p] = ipmi_mem_alloc(sizeof(*s[p]));
1101
memset(s[p], 0, sizeof(*s[p]));
1103
s[p]->source_recid = sdr.record_id;
1104
s[p]->hot_swap_requester = -1;
1106
s[p]->waitq = opq_alloc(ipmi_domain_get_os_hnd(domain));
1112
s[p]->handler_list = locked_list_alloc(ipmi_domain_get_os_hnd(domain));
1113
if (! s[p]->handler_list) {
1114
opq_destroy(s[p]->waitq);
1119
s[p]->destroyed = 0;
1120
s[p]->destroy_handler = NULL;
1122
rv = _ipmi_find_or_create_mc_by_slave_addr(domain,
1130
id_string_mod_type = 0;
1131
entity_instance_incr = 0;
1132
id_string_modifier_offset = 0;
1135
s[p]->domain = domain;
1136
s[p]->source_mc = source_mc;
1137
s[p]->source_idx = p;
1138
s[p]->source_array = s;
1139
s[p]->owner = sdr.data[0];
1140
s[p]->channel = sdr.data[1] >> 4;
1141
s[p]->lun = sdr.data[1] & 0x03;
1142
s[p]->send_lun = s[p]->lun;
1143
s[p]->num = sdr.data[2];
1144
s[p]->entity_id = sdr.data[3];
1145
s[p]->entity_instance_logical = sdr.data[4] >> 7;
1146
s[p]->entity_instance = sdr.data[4] & 0x7f;
1147
if ((sdr.type == 1) || (sdr.type == 2)) {
1148
s[p]->sensor_init_scanning = (sdr.data[5] >> 6) & 1;
1149
s[p]->sensor_init_events = (sdr.data[5] >> 5) & 1;
1150
s[p]->sensor_init_thresholds = (sdr.data[5] >> 4) & 1;
1151
s[p]->sensor_init_hysteresis = (sdr.data[5] >> 3) & 1;
1152
s[p]->sensor_init_type = (sdr.data[5] >> 2) & 1;
1153
s[p]->sensor_init_pu_events = (sdr.data[5] >> 1) & 1;
1154
s[p]->sensor_init_pu_scanning = (sdr.data[5] >> 0) & 1;
1155
s[p]->ignore_if_no_entity = (sdr.data[6] >> 7) & 1;
1156
s[p]->supports_auto_rearm = (sdr.data[6] >> 6) & 1 ;
1157
s[p]->hysteresis_support = (sdr.data[6] >> 4) & 3;
1158
s[p]->threshold_access = (sdr.data[6] >> 2) & 3;
1159
s[p]->event_support = sdr.data[6] & 3;
1160
s[p]->sensor_type = sdr.data[7];
1161
s[p]->event_reading_type = sdr.data[8];
1163
val = ipmi_get_uint16(sdr.data+9);
1164
for (j=0; j<16; j++) {
1165
s[p]->mask1[j] = val & 1;
1168
val = ipmi_get_uint16(sdr.data+11);
1169
for (j=0; j<16; j++) {
1170
s[p]->mask2[j] = val & 1;
1173
val = ipmi_get_uint16(sdr.data+13);
1174
for (j=0; j<16; j++) {
1175
s[p]->mask3[j] = val & 1;
1179
s[p]->analog_data_format = (sdr.data[15] >> 6) & 3;
1180
s[p]->rate_unit = (sdr.data[15] >> 3) & 7;
1181
s[p]->modifier_unit_use = (sdr.data[15] >> 1) & 3;
1182
s[p]->percentage = sdr.data[15] & 1;
1183
s[p]->base_unit = sdr.data[16];
1184
s[p]->modifier_unit = sdr.data[17];
1187
if (sdr.type == 1) {
1188
/* A full sensor record. */
1189
s[p]->linearization = sdr.data[18] & 0x7f;
1191
if (s[p]->linearization <= 11) {
1192
for (j=0; j<256; j++) {
1193
s[p]->conv[j].m = sdr.data[19] | ((sdr.data[20] & 0xc0) << 2);
1194
s[p]->conv[j].tolerance = sdr.data[20] & 0x3f;
1195
s[p]->conv[j].b = sdr.data[21] | ((sdr.data[22] & 0xc0) << 2);
1196
s[p]->conv[j].accuracy = ((sdr.data[22] & 0x3f)
1197
| ((sdr.data[23] & 0xf0) << 2));
1198
s[p]->conv[j].accuracy_exp = (sdr.data[23] >> 2) & 0x3;
1199
s[p]->conv[j].r_exp = (sdr.data[24] >> 4) & 0xf;
1200
s[p]->conv[j].b_exp = sdr.data[24] & 0xf;
1204
s[p]->sensor_direction = sdr.data[23] & 0x3;
1205
s[p]->normal_min_specified = (sdr.data[25] >> 2) & 1;
1206
s[p]->normal_max_specified = (sdr.data[25] >> 1) & 1;
1207
s[p]->nominal_reading_specified = sdr.data[25] & 1;
1208
s[p]->nominal_reading = sdr.data[26];
1209
s[p]->normal_max = sdr.data[27];
1210
s[p]->normal_min = sdr.data[28];
1211
s[p]->sensor_max = sdr.data[29];
1212
s[p]->sensor_min = sdr.data[30];
1213
s[p]->default_thresholds[IPMI_UPPER_NON_RECOVERABLE]= sdr.data[31];
1214
s[p]->default_thresholds[IPMI_UPPER_CRITICAL] = sdr.data[32];
1215
s[p]->default_thresholds[IPMI_UPPER_NON_CRITICAL] = sdr.data[33];
1216
s[p]->default_thresholds[IPMI_LOWER_NON_RECOVERABLE] = sdr.data[34];
1217
s[p]->default_thresholds[IPMI_LOWER_CRITICAL] = sdr.data[35];
1218
s[p]->default_thresholds[IPMI_LOWER_NON_CRITICAL] = sdr.data[36];
1219
s[p]->positive_going_threshold_hysteresis = sdr.data[37];
1220
s[p]->negative_going_threshold_hysteresis = sdr.data[38];
1221
s[p]->oem1 = sdr.data[41];
1223
str = sdr.data + 42;
1224
s[p]->id_len = ipmi_get_device_string(&str, sdr.length-42,
1225
s[p]->id, IPMI_STR_SDR_SEMANTICS, 0,
1226
&s[p]->id_type, SENSOR_ID_LEN);
1228
sensor_set_name(s[p]);
1229
} else if (sdr.type == 2) {
1230
/* FIXME - make sure this is not a threshold sensor. The
1231
question is, what do I do if it is? */
1232
/* A short sensor record. */
1234
s[p]->sensor_direction = (sdr.data[18] >> 6) & 0x3;
1236
s[p]->positive_going_threshold_hysteresis = sdr.data[20];
1237
s[p]->negative_going_threshold_hysteresis = sdr.data[21];
1238
s[p]->oem1 = sdr.data[25];
1240
str = sdr.data + 26;
1241
s[p]->id_len = ipmi_get_device_string(&str, sdr.length-26,
1242
s[p]->id, IPMI_STR_SDR_SEMANTICS, 0,
1243
&s[p]->id_type, SENSOR_ID_LEN);
1245
share_count = sdr.data[18] & 0x0f;
1246
if (share_count == 0)
1248
id_string_mod_type = (sdr.data[18] >> 4) & 0x3;
1249
entity_instance_incr = (sdr.data[19] >> 7) & 0x01;
1250
id_string_modifier_offset = sdr.data[19] & 0x7f;
1252
/* Event-only sensor */
1254
s[p]->sensor_type = sdr.data[5];
1255
s[p]->event_reading_type = sdr.data[6];
1256
s[p]->oem1 = sdr.data[10];
1258
str = sdr.data + 11;
1259
s[p]->id_len = ipmi_get_device_string(&str, sdr.length-11,
1260
s[p]->id, IPMI_STR_SDR_SEMANTICS, 0,
1261
&s[p]->id_type, SENSOR_ID_LEN);
1263
share_count = sdr.data[7] & 0x0f;
1264
if (share_count == 0)
1266
id_string_mod_type = (sdr.data[7] >> 4) & 0x3;
1267
entity_instance_incr = (sdr.data[8] >> 7) & 0x01;
1268
id_string_modifier_offset = sdr.data[8] & 0x7f;
1272
/* Duplicate the sensor records for each instance. Go
1273
backwards to avoid destroying the first one until we
1274
finish the others. */
1275
for (j=share_count-1; j>=0; j--) {
1279
/* The first one is already allocated, we are
1280
using it to copy to the other ones, so this is
1281
not necessary. We still have to iterate the
1282
first one to set its string name, though. */
1283
s[p+j] = ipmi_mem_alloc(sizeof(ipmi_sensor_t));
1288
memcpy(s[p+j], s[p], sizeof(ipmi_sensor_t));
1290
/* In case of error */
1291
s[p+j]->handler_list = NULL;
1293
/* For every sensor except the first, increment the usage
1294
count for the MC so that it will decrement properly.
1295
This cannot fail because we have already gotten it
1297
_ipmi_find_or_create_mc_by_slave_addr(domain,
1302
s[p+j]->waitq = opq_alloc(ipmi_domain_get_os_hnd(domain));
1303
if (!s[p+j]->waitq) {
1308
s[p+j]->handler_list
1309
= locked_list_alloc(ipmi_domain_get_os_hnd(domain));
1310
if (! s[p+j]->handler_list) {
1317
if (entity_instance_incr & 0x80) {
1318
s[p+j]->entity_instance += j;
1321
s[p+j]->source_idx += j;
1324
val = id_string_modifier_offset + j;
1325
len = s[p+j]->id_len;
1326
switch (id_string_mod_type) {
1327
case 0: /* Numeric */
1328
if ((val / 10) > 0) {
1329
if (len < SENSOR_ID_LEN) {
1330
s[p+j]->id[len] = (val/10) + '0';
1334
if (len < SENSOR_ID_LEN) {
1335
s[p+j]->id[len] = (val%10) + '0';
1340
if ((val / 26) > 0) {
1341
if (len < SENSOR_ID_LEN) {
1342
s[p+j]->id[len] = (val/26) + 'A';
1346
if (len < SENSOR_ID_LEN) {
1347
s[p+j]->id[len] = (val%26) + 'A';
1351
/* FIXME - unicode handling? */
1353
s[p+j]->id_len = len;
1355
sensor_set_name(s[p+j]);
1364
*sensor_count = s_size;
1369
for (i=0; i<s_size; i++)
1372
_ipmi_mc_put(s[i]->mc);
1374
opq_destroy(s[i]->waitq);
1375
if (s[i]->handler_list)
1376
locked_list_destroy(s[i]->handler_list);
1377
ipmi_mem_free(s[i]);
1385
handle_new_sensor(ipmi_domain_t *domain,
1386
ipmi_sensor_t *sensor,
1389
ipmi_entity_info_t *ents;
1392
/* Call this before the OEM call so the OEM call can replace it. */
1393
sensor->cbs = ipmi_standard_sensor_cb;
1394
sensor->sensor_type_string
1395
= ipmi_get_sensor_type_string(sensor->sensor_type);
1396
sensor->event_reading_type_string
1397
= ipmi_get_event_reading_type_string(sensor->event_reading_type);
1398
sensor->rate_unit_string
1399
= ipmi_get_rate_unit_string(sensor->rate_unit);
1400
sensor->base_unit_string
1401
= ipmi_get_unit_type_string(sensor->base_unit);
1402
sensor->modifier_unit_string
1403
= ipmi_get_unit_type_string(sensor->modifier_unit);
1405
ents = ipmi_domain_get_entities(domain);
1407
sensor_set_name(sensor);
1409
if ((sensor->source_mc)
1410
&& (_ipmi_mc_new_sensor(sensor->source_mc, sensor->entity,
1413
/* Nothing to do, OEM code handled the sensor. */
1415
ipmi_entity_add_sensor(sensor->entity, sensor, link);
1418
_call_new_sensor_handlers(domain, sensor);
1421
static int cmp_sensor(ipmi_sensor_t *s1,
1426
if (s1->entity_instance_logical != s2->entity_instance_logical) return 0;
1427
if (s1->sensor_init_scanning != s2->sensor_init_scanning) return 0;
1428
if (s1->sensor_init_events != s2->sensor_init_events) return 0;
1429
if (s1->sensor_init_thresholds != s2->sensor_init_thresholds) return 0;
1430
if (s1->sensor_init_hysteresis != s2->sensor_init_hysteresis) return 0;
1431
if (s1->sensor_init_type != s2->sensor_init_type) return 0;
1432
if (s1->sensor_init_pu_events != s2->sensor_init_pu_events) return 0;
1433
if (s1->sensor_init_pu_scanning != s2->sensor_init_pu_scanning) return 0;
1434
if (s1->ignore_if_no_entity != s2->ignore_if_no_entity) return 0;
1435
if (s1->supports_auto_rearm != s2->supports_auto_rearm) return 0;
1436
if (s1->hysteresis_support != s2->hysteresis_support) return 0;
1437
if (s1->threshold_access != s2->threshold_access) return 0;
1438
if (s1->event_support != s2->event_support) return 0;
1439
if (s1->sensor_type != s2->sensor_type) return 0;
1440
if (s1->event_reading_type != s2->event_reading_type) return 0;
1442
for (i=0; i<16; i++) {
1443
if (s1->mask1[i] != s2->mask1[i]) return 0;
1444
if (s1->mask2[i] != s2->mask2[i]) return 0;
1445
if (s1->mask3[i] != s2->mask3[i]) return 0;
1448
if (s1->analog_data_format != s2->analog_data_format) return 0;
1449
if (s1->rate_unit != s2->rate_unit) return 0;
1450
if (s1->modifier_unit_use != s2->modifier_unit_use) return 0;
1451
if (s1->percentage != s2->percentage) return 0;
1452
if (s1->base_unit != s2->base_unit) return 0;
1453
if (s1->modifier_unit != s2->modifier_unit) return 0;
1454
if (s1->linearization != s2->linearization) return 0;
1455
if (s1->linearization <= 11) {
1456
if (s1->conv[0].m != s2->conv[0].m) return 0;
1457
if (s1->conv[0].tolerance != s2->conv[0].tolerance) return 0;
1458
if (s1->conv[0].b != s2->conv[0].b) return 0;
1459
if (s1->conv[0].accuracy != s2->conv[0].accuracy) return 0;
1460
if (s1->conv[0].accuracy_exp != s2->conv[0].accuracy_exp) return 0;
1461
if (s1->conv[0].r_exp != s2->conv[0].r_exp) return 0;
1462
if (s1->conv[0].b_exp != s2->conv[0].b_exp) return 0;
1464
if (s1->normal_min_specified != s2->normal_min_specified) return 0;
1465
if (s1->normal_max_specified != s2->normal_max_specified) return 0;
1466
if (s1->nominal_reading_specified != s2->nominal_reading_specified) return 0;
1467
if (s1->nominal_reading != s2->nominal_reading) return 0;
1468
if (s1->normal_max != s2->normal_max) return 0;
1469
if (s1->normal_min != s2->normal_min) return 0;
1470
if (s1->sensor_max != s2->sensor_max) return 0;
1471
if (s1->sensor_min != s2->sensor_min) return 0;
1472
for (i=0; i<6; i++) {
1473
if (s1->default_thresholds[i] != s2->default_thresholds[i])
1476
if (s1->positive_going_threshold_hysteresis
1477
!= s2->positive_going_threshold_hysteresis)
1479
if (s1->negative_going_threshold_hysteresis
1480
!= s2->negative_going_threshold_hysteresis)
1482
if (s1->oem1 != s2->oem1) return 0;
1484
if (s1->id_type != s2->id_type) return 0;
1485
if (s1->id_len != s2->id_len) return 0;
1486
if (memcmp(s1->id, s2->id, s1->id_len) != 0) return 0;
1491
enum entity_list_op { ENT_LIST_OLD, ENT_LIST_NEW, ENT_LIST_DUP };
1492
typedef struct entity_list_s
1495
ipmi_sensor_t *sensor;
1496
ipmi_sensor_t *osensor;
1498
enum entity_list_op op;
1499
struct entity_list_s *next;
1502
/* Assume it has enough space for one pointer. */
1503
struct locked_list_entry_s
1505
locked_list_entry_t *next;
1509
ipmi_sensor_handle_sdrs(ipmi_domain_t *domain,
1510
ipmi_mc_t *source_mc,
1511
ipmi_sdr_info_t *sdrs)
1515
ipmi_sensor_t **sdr_sensors;
1516
ipmi_sensor_t **old_sdr_sensors;
1517
unsigned int old_count;
1519
ipmi_entity_info_t *ents;
1521
entity_list_t *new_sensors = NULL;
1522
entity_list_t *del_sensors = NULL;
1523
entity_list_t *ent_item;
1524
entity_list_t *new_ent_item;
1525
locked_list_entry_t *link, *links = NULL;
1526
ipmi_sensor_t **sens_tmp;
1529
CHECK_DOMAIN_LOCK(domain);
1531
CHECK_MC_LOCK(source_mc);
1533
rv = get_sensors_from_sdrs(domain, source_mc, sdrs, &sdr_sensors, &count);
1537
ents = ipmi_domain_get_entities(domain);
1539
/* Pre-allocate all the links we will need for registering sensors
1540
with the entities, and we make sure all the entities exist. */
1541
for (i=0; i<count; i++) {
1542
ipmi_sensor_t *nsensor = sdr_sensors[i];
1546
if (nsensor != NULL) {
1547
ipmi_sensor_info_t *sensors;
1549
/* Make sure the entity exists for ALL sensors in the
1550
new list. This way, if a sensor has changed
1551
entities, the new entity will exist. */
1552
rv = ipmi_entity_add(ents,
1554
ipmi_mc_get_channel(nsensor->mc),
1555
ipmi_mc_get_address(nsensor->mc),
1558
nsensor->entity_instance,
1568
nsensor->entity = ent;
1570
sensors = _ipmi_mc_get_sensors(nsensor->mc);
1572
ipmi_lock(sensors->idx_lock);
1573
if (nsensor->num >= sensors->idx_size[nsensor->lun]) {
1574
/* There's not enough room in the sensor repository
1575
for the new item, so expand the array. */
1576
ipmi_sensor_t **new_by_idx;
1577
unsigned int new_size = nsensor->num+10;
1578
new_by_idx = ipmi_mem_alloc(sizeof(ipmi_sensor_t *) * new_size);
1580
ipmi_unlock(sensors->idx_lock);
1582
_ipmi_entity_put(ent);
1585
if (sensors->sensors_by_idx[nsensor->lun]) {
1587
sensors->sensors_by_idx[nsensor->lun],
1588
(sensors->idx_size[nsensor->lun]
1589
* sizeof(ipmi_sensor_t *)));
1590
ipmi_mem_free(sensors->sensors_by_idx[nsensor->lun]);
1592
for (j=sensors->idx_size[nsensor->lun]; j<new_size; j++)
1593
new_by_idx[j] = NULL;
1594
sensors->sensors_by_idx[nsensor->lun] = new_by_idx;
1595
sensors->idx_size[nsensor->lun] = new_size;
1597
ipmi_unlock(sensors->idx_lock);
1599
/* Keep track of each entity/sensor pair. */
1600
new_ent_item = ipmi_mem_alloc(sizeof(*new_ent_item));
1601
if (!new_ent_item) {
1602
_ipmi_entity_put(ent);
1605
new_ent_item->ent = ent;
1606
new_ent_item->sensor = nsensor;
1607
new_ent_item->osensor = NULL;
1608
new_ent_item->mc = nsensor->mc;
1609
new_ent_item->op = ENT_LIST_OLD;
1610
new_ent_item->next = new_sensors;
1611
new_sensors = new_ent_item;
1613
/* Pre-allocate link entries for putting the sensor into
1615
link = locked_list_alloc_entry();
1623
/* Check for duplicate sensor numbers in the new sensor set. */
1624
sens_tmp = ipmi_mem_alloc(256 * sizeof(ipmi_sensor_t **));
1629
memset(sens_tmp, 0, 256 * sizeof(ipmi_sensor_t **));
1630
ent_item = new_sensors;
1632
ipmi_sensor_t *nsensor = ent_item->sensor;
1633
ipmi_sensor_t *csensor;
1635
if ((!ent_item->ent) || (!nsensor)) {
1636
ent_item = ent_item->next;
1640
csensor = sens_tmp[nsensor->num];
1642
if ((csensor->lun == nsensor->lun)
1643
&& (csensor->num == nsensor->num)
1644
&& (csensor->mc == nsensor->mc))
1648
csensor = csensor->tlink;
1651
ipmi_log(IPMI_LOG_WARNING,
1652
"%ssensor.c(ipmi_sensor_handle_sdrs):"
1653
" SDR record %d has the same sensor number as record"
1654
" %d in the repository. Ignoring second sensor."
1656
SENSOR_NAME(nsensor),
1657
csensor->source_recid,
1658
nsensor->source_recid);
1659
ent_item->op = ENT_LIST_DUP;
1660
ent_item->osensor = NULL;
1662
nsensor->tlink = sens_tmp[nsensor->num];
1663
sens_tmp[nsensor->num] = nsensor;
1665
ent_item = ent_item->next;
1667
ipmi_mem_free(sens_tmp);
1669
_ipmi_domain_entity_lock(domain);
1671
_ipmi_get_sdr_sensors(domain, source_mc,
1672
&old_sdr_sensors, &old_count);
1674
ent_item = new_sensors;
1676
ipmi_sensor_t *nsensor = ent_item->sensor;
1677
ipmi_sensor_info_t *sensors;
1679
if ((!ent_item->ent) || (!nsensor) || (ent_item->op == ENT_LIST_DUP)) {
1680
ent_item = ent_item->next;
1684
sensors = _ipmi_mc_get_sensors(nsensor->mc);
1685
ipmi_lock(sensors->idx_lock);
1686
if (sensors->sensors_by_idx[nsensor->lun]
1687
&& (nsensor->num < sensors->idx_size[nsensor->lun])
1688
&& sensors->sensors_by_idx[nsensor->lun][nsensor->num])
1690
/* A sensor is already there. */
1691
ipmi_sensor_t *osensor
1692
= sensors->sensors_by_idx[nsensor->lun][nsensor->num];
1694
if (cmp_sensor(nsensor, osensor)) {
1695
/* Since the data is the same, there is no need to get
1696
the old sensor entity or mc, since they are already
1697
gotten by the new sensor. */
1698
ent_item->op = ENT_LIST_DUP;
1699
ent_item->osensor = osensor;
1701
/* We have to delete the old sensor. */
1702
new_ent_item = ipmi_mem_alloc(sizeof(*new_ent_item));
1703
if (!new_ent_item) {
1704
ipmi_unlock(sensors->idx_lock);
1706
goto out_err_free_unlock;
1708
/* It's possible this can fail, but that means that
1709
the MC is currently being destroyed. No big deal,
1711
new_ent_item->mc = NULL;
1712
_ipmi_find_or_create_mc_by_slave_addr(domain,
1716
_ipmi_entity_get(osensor->entity);
1717
_ipmi_sensor_get(osensor);
1718
new_ent_item->ent = osensor->entity;
1719
new_ent_item->sensor = osensor;
1720
new_ent_item->next = del_sensors;
1721
del_sensors = new_ent_item;
1722
ent_item->op = ENT_LIST_NEW;
1725
ent_item->op = ENT_LIST_NEW;
1727
ipmi_unlock(sensors->idx_lock);
1729
ent_item = ent_item->next;
1732
_ipmi_domain_entity_unlock(domain);
1734
/* After this point, the operation cannot fail. Nothing above
1735
this actually changes anything, it just gets it ready. Now we
1736
put into place all the changes. */
1738
/* First delete the sensors that we are replacing. */
1739
ent_item = del_sensors;
1741
ipmi_sensor_t *osensor = ent_item->sensor;
1743
if (osensor->source_array) {
1744
osensor->source_array[osensor->source_idx] = NULL;
1745
osensor->source_array = NULL;
1747
/* Note that the actual destroy is deferred until we put the
1749
ipmi_sensor_destroy(osensor);
1751
ent_item = ent_item->next;
1754
ent_item = new_sensors;
1756
ipmi_sensor_t *nsensor = ent_item->sensor;
1757
ipmi_sensor_t *osensor = ent_item->osensor;
1758
ipmi_sensor_info_t *sensors;
1760
if ((!ent_item->ent) || (!nsensor)) {
1761
ent_item = ent_item->next;
1765
sensors = _ipmi_mc_get_sensors(nsensor->mc);
1766
ipmi_lock(sensors->idx_lock);
1767
switch (ent_item->op) {
1769
sensors->sensors_by_idx[nsensor->lun][nsensor->num] = nsensor;
1770
sensors->sensor_count++;
1773
handle_new_sensor(domain, nsensor, link);
1780
/* They compare, prefer to keep the old data. */
1781
i = nsensor->source_idx;
1782
opq_destroy(nsensor->waitq);
1783
locked_list_destroy(nsensor->handler_list);
1784
ipmi_mem_free(nsensor);
1785
ent_item->sensor = NULL;
1786
sdr_sensors[i] = osensor;
1788
if (osensor->source_array)
1789
osensor->source_array[osensor->source_idx] = NULL;
1790
osensor->source_idx = i;
1791
osensor->source_array = sdr_sensors;
1795
ipmi_unlock(sensors->idx_lock);
1796
ent_item = ent_item->next;
1799
_ipmi_set_sdr_sensors(domain, source_mc, sdr_sensors, count);
1801
if (old_sdr_sensors) {
1802
for (i=0; i<old_count; i++) {
1803
ipmi_sensor_t *osensor = old_sdr_sensors[i];
1804
if (osensor != NULL) {
1805
/* This sensor was not in the new repository, so it must
1806
have been deleted. */
1807
_ipmi_sensor_get(osensor);
1808
ipmi_sensor_destroy(osensor);
1813
if (old_sdr_sensors) {
1814
for (i=0; i<old_count; i++) {
1815
ipmi_sensor_t *osensor = old_sdr_sensors[i];
1816
if (osensor != NULL) {
1817
_ipmi_sensor_put(osensor);
1820
ipmi_mem_free(old_sdr_sensors);
1823
/* Free up all the deleted sensors. */
1824
while (del_sensors) {
1825
ent_item = del_sensors;
1826
del_sensors = del_sensors->next;
1827
if (ent_item->sensor)
1828
_ipmi_sensor_put(ent_item->sensor);
1830
_ipmi_entity_put(ent_item->ent);
1832
_ipmi_mc_put(ent_item->mc);
1833
ipmi_mem_free(ent_item);
1836
/* Report then free up all the new sensors. */
1837
while (new_sensors) {
1838
ent_item = new_sensors;
1839
new_sensors = new_sensors->next;
1841
if (ent_item->ent && ent_item->sensor)
1842
ent_item->sensor->add_pending = 1;
1843
if (ent_item->sensor)
1844
_ipmi_sensor_put(ent_item->sensor);
1846
_ipmi_entity_put(ent_item->ent);
1848
_ipmi_mc_put(ent_item->mc);
1849
ipmi_mem_free(ent_item);
1853
/* Cleanup unused links. */
1857
locked_list_free_entry(link);
1863
/* Release all the entities, sensors, etc. */
1864
while (del_sensors) {
1865
ent_item = del_sensors;
1866
del_sensors = del_sensors->next;
1867
if (ent_item->sensor)
1868
_ipmi_sensor_put(ent_item->sensor);
1870
_ipmi_entity_put(ent_item->ent);
1872
_ipmi_mc_put(ent_item->mc);
1873
ipmi_mem_free(ent_item);
1875
while (new_sensors) {
1876
ent_item = new_sensors;
1877
new_sensors = new_sensors->next;
1878
if (ent_item->sensor)
1879
_ipmi_sensor_put(ent_item->sensor);
1881
_ipmi_entity_put(ent_item->ent);
1883
_ipmi_mc_put(ent_item->mc);
1884
ipmi_mem_free(ent_item);
1888
out_err_free_unlock:
1889
_ipmi_domain_entity_unlock(domain);
1891
/* Free up the usecounts on all the MCs we got. */
1892
for (i=0; i<count; i++) {
1893
ipmi_sensor_t *nsensor = sdr_sensors[i];
1895
if ((nsensor) && (nsensor->mc))
1896
_ipmi_mc_put(nsensor->mc);
1901
/***********************************************************************
1903
* Get/set various local information about a sensor.
1905
**********************************************************************/
1908
ipmi_sensor_get_nominal_reading(ipmi_sensor_t *sensor,
1909
double *nominal_reading)
1911
CHECK_SENSOR_LOCK(sensor);
1913
if (!sensor->nominal_reading_specified)
1916
return (ipmi_sensor_convert_from_raw(sensor,
1917
sensor->nominal_reading,
1922
ipmi_sensor_get_normal_max(ipmi_sensor_t *sensor, double *normal_max)
1924
CHECK_SENSOR_LOCK(sensor);
1926
if (!sensor->normal_max_specified)
1929
return (ipmi_sensor_convert_from_raw(sensor,
1935
ipmi_sensor_get_normal_min(ipmi_sensor_t *sensor, double *normal_min)
1937
CHECK_SENSOR_LOCK(sensor);
1939
if (!sensor->normal_min_specified)
1942
return (ipmi_sensor_convert_from_raw(sensor,
1948
ipmi_sensor_get_sensor_max(ipmi_sensor_t *sensor, double *sensor_max)
1950
CHECK_SENSOR_LOCK(sensor);
1952
return (ipmi_sensor_convert_from_raw(sensor,
1958
ipmi_sensor_get_sensor_min(ipmi_sensor_t *sensor, double *sensor_min)
1960
CHECK_SENSOR_LOCK(sensor);
1962
return (ipmi_sensor_convert_from_raw(sensor,
1967
int ipmi_sensor_set_raw_default_threshold(ipmi_sensor_t *sensor,
1971
if ((threshold < 0) || (threshold > 5))
1974
sensor->default_thresholds[threshold] = val;
1978
int ipmi_sensor_get_default_threshold_raw(ipmi_sensor_t *sensor,
1985
CHECK_SENSOR_LOCK(sensor);
1987
if ((threshold < 0) || (threshold > 5))
1990
rv = ipmi_sensor_threshold_settable(sensor, threshold, &val);
1997
if (!ipmi_sensor_get_sensor_init_thresholds(sensor))
2000
*raw = sensor->default_thresholds[threshold];
2004
int ipmi_sensor_get_default_threshold_cooked(ipmi_sensor_t *sensor,
2011
CHECK_SENSOR_LOCK(sensor);
2013
if ((threshold < 0) || (threshold > 5))
2016
rv = ipmi_sensor_threshold_settable(sensor, threshold, &val);
2023
if (!ipmi_sensor_get_sensor_init_thresholds(sensor))
2026
return (ipmi_sensor_convert_from_raw(sensor,
2027
sensor->default_thresholds[threshold],
2032
ipmi_sensor_get_mc(ipmi_sensor_t *sensor)
2038
ipmi_sensor_get_source_mc(ipmi_sensor_t *sensor)
2040
CHECK_SENSOR_LOCK(sensor);
2042
return sensor->source_mc;
2046
ipmi_sensor_get_num(ipmi_sensor_t *sensor,
2050
CHECK_SENSOR_LOCK(sensor);
2060
ipmi_sensor_threshold_event_supported(ipmi_sensor_t *sensor,
2061
enum ipmi_thresh_e event,
2062
enum ipmi_event_value_dir_e value_dir,
2063
enum ipmi_event_dir_e dir,
2067
unsigned char *mask;
2069
CHECK_SENSOR_LOCK(sensor);
2071
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2072
/* Not a threshold sensor, it doesn't have readings. */
2074
if (sensor->threshold_access == IPMI_THRESHOLD_ACCESS_SUPPORT_NONE) {
2075
/* No thresholds supported. */
2080
if (dir == IPMI_ASSERTION)
2081
mask = sensor->mask1;
2082
else if (dir == IPMI_DEASSERTION)
2083
mask = sensor->mask2;
2087
idx = (event * 2) + value_dir;
2096
ipmi_sensor_set_threshold_assertion_event_supported(
2097
ipmi_sensor_t *sensor,
2098
enum ipmi_thresh_e event,
2099
enum ipmi_event_value_dir_e dir,
2104
idx = (event * 2) + dir;
2108
sensor->mask1[idx] = val;
2112
ipmi_sensor_set_threshold_deassertion_event_supported(
2113
ipmi_sensor_t *sensor,
2114
enum ipmi_thresh_e event,
2115
enum ipmi_event_value_dir_e dir,
2120
idx = (event * 2) + dir;
2124
sensor->mask2[idx] = val;
2128
ipmi_sensor_threshold_reading_supported(ipmi_sensor_t *sensor,
2129
enum ipmi_thresh_e thresh,
2132
CHECK_SENSOR_LOCK(sensor);
2134
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2135
/* Not a threshold sensor, it doesn't have readings. */
2139
case IPMI_LOWER_NON_CRITICAL:
2140
*val = sensor->mask1[12];
2142
case IPMI_LOWER_CRITICAL:
2143
*val = sensor->mask1[13];
2145
case IPMI_LOWER_NON_RECOVERABLE:
2146
*val = sensor->mask1[14];
2148
case IPMI_UPPER_NON_CRITICAL:
2149
*val = sensor->mask2[12];
2151
case IPMI_UPPER_CRITICAL:
2152
*val = sensor->mask2[13];
2154
case IPMI_UPPER_NON_RECOVERABLE:
2155
*val = sensor->mask2[14];
2164
ipmi_sensor_threshold_settable(ipmi_sensor_t *sensor,
2165
enum ipmi_thresh_e event,
2168
CHECK_SENSOR_LOCK(sensor);
2170
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2171
/* Not a threshold sensor, it doesn't have readings. */
2173
if (sensor->threshold_access != IPMI_THRESHOLD_ACCESS_SUPPORT_SETTABLE) {
2174
/* Threshold setting not supported for any thresholds. */
2179
if (event > IPMI_UPPER_NON_RECOVERABLE)
2182
*val = sensor->mask3[event + 8];
2187
ipmi_sensor_threshold_set_settable(ipmi_sensor_t *sensor,
2188
enum ipmi_thresh_e event,
2191
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2192
/* Not a threshold sensor, it doesn't have readings. */
2195
if (event > IPMI_UPPER_NON_RECOVERABLE)
2198
sensor->mask3[event + 8] = val;
2202
ipmi_sensor_threshold_readable(ipmi_sensor_t *sensor,
2203
enum ipmi_thresh_e event,
2206
CHECK_SENSOR_LOCK(sensor);
2208
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2209
/* Not a threshold sensor, it doesn't have readings. */
2211
if ((sensor->threshold_access == IPMI_THRESHOLD_ACCESS_SUPPORT_NONE)
2212
|| (sensor->threshold_access == IPMI_THRESHOLD_ACCESS_SUPPORT_FIXED))
2214
/* Threshold reading not supported for any thresholds. */
2219
if (event > IPMI_UPPER_NON_RECOVERABLE)
2222
*val = sensor->mask3[event];
2227
ipmi_sensor_threshold_set_readable(ipmi_sensor_t *sensor,
2228
enum ipmi_thresh_e event,
2231
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2232
/* Not a threshold sensor, it doesn't have readings. */
2235
if (event > IPMI_UPPER_NON_RECOVERABLE)
2238
sensor->mask3[event] = val;
2242
ipmi_sensor_discrete_event_supported(ipmi_sensor_t *sensor,
2244
enum ipmi_event_dir_e dir,
2247
unsigned char *mask;
2249
CHECK_SENSOR_LOCK(sensor);
2251
if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
2252
/* A threshold sensor, it doesn't have events. */
2255
if (dir == IPMI_ASSERTION)
2256
mask = sensor->mask1;
2257
else if (dir == IPMI_DEASSERTION)
2258
mask = sensor->mask2;
2270
ipmi_sensor_set_discrete_assertion_event_supported(ipmi_sensor_t *sensor,
2277
sensor->mask1[event] = val;
2281
ipmi_sensor_set_discrete_deassertion_event_supported(ipmi_sensor_t *sensor,
2288
sensor->mask2[event] = val;
2292
ipmi_sensor_discrete_event_readable(ipmi_sensor_t *sensor,
2296
CHECK_SENSOR_LOCK(sensor);
2298
if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
2299
/* A threshold sensor, it doesn't have events. */
2305
*val = sensor->mask3[event];
2310
ipmi_sensor_discrete_set_event_readable(ipmi_sensor_t *sensor,
2314
if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
2315
/* A threshold sensor, it doesn't have events. */
2321
sensor->mask3[event] = val;
2325
ipmi_sensor_get_owner(ipmi_sensor_t *sensor)
2327
CHECK_SENSOR_LOCK(sensor);
2329
return sensor->owner;
2333
ipmi_sensor_get_channel(ipmi_sensor_t *sensor)
2335
CHECK_SENSOR_LOCK(sensor);
2337
return sensor->channel;
2341
ipmi_sensor_get_entity_id(ipmi_sensor_t *sensor)
2343
CHECK_SENSOR_LOCK(sensor);
2345
return sensor->entity_id;
2349
ipmi_sensor_get_entity_instance(ipmi_sensor_t *sensor)
2351
CHECK_SENSOR_LOCK(sensor);
2353
return sensor->entity_instance;
2357
ipmi_sensor_get_entity_instance_logical(ipmi_sensor_t *sensor)
2359
CHECK_SENSOR_LOCK(sensor);
2361
return sensor->entity_instance_logical;
2365
ipmi_sensor_get_sensor_init_scanning(ipmi_sensor_t *sensor)
2367
CHECK_SENSOR_LOCK(sensor);
2369
return sensor->sensor_init_scanning;
2373
ipmi_sensor_get_sensor_init_events(ipmi_sensor_t *sensor)
2375
CHECK_SENSOR_LOCK(sensor);
2377
return sensor->sensor_init_events;
2381
ipmi_sensor_get_sensor_init_thresholds(ipmi_sensor_t *sensor)
2383
CHECK_SENSOR_LOCK(sensor);
2385
return sensor->sensor_init_thresholds;
2389
ipmi_sensor_get_sensor_init_hysteresis(ipmi_sensor_t *sensor)
2391
CHECK_SENSOR_LOCK(sensor);
2393
return sensor->sensor_init_hysteresis;
2397
ipmi_sensor_get_sensor_init_type(ipmi_sensor_t *sensor)
2399
CHECK_SENSOR_LOCK(sensor);
2401
return sensor->sensor_init_type;
2405
ipmi_sensor_get_sensor_init_pu_events(ipmi_sensor_t *sensor)
2407
CHECK_SENSOR_LOCK(sensor);
2409
return sensor->sensor_init_pu_events;
2413
ipmi_sensor_get_sensor_init_pu_scanning(ipmi_sensor_t *sensor)
2415
CHECK_SENSOR_LOCK(sensor);
2417
return sensor->sensor_init_pu_scanning;
2421
ipmi_sensor_get_ignore_if_no_entity(ipmi_sensor_t *sensor)
2423
CHECK_SENSOR_LOCK(sensor);
2425
return sensor->ignore_if_no_entity;
2429
ipmi_sensor_get_supports_auto_rearm(ipmi_sensor_t *sensor)
2431
CHECK_SENSOR_LOCK(sensor);
2433
return sensor->supports_auto_rearm;
2437
ipmi_sensor_get_hysteresis_support(ipmi_sensor_t *sensor)
2439
CHECK_SENSOR_LOCK(sensor);
2441
return sensor->hysteresis_support;
2445
ipmi_sensor_get_threshold_access(ipmi_sensor_t *sensor)
2447
CHECK_SENSOR_LOCK(sensor);
2449
return sensor->threshold_access;
2453
ipmi_sensor_get_event_support(ipmi_sensor_t *sensor)
2455
CHECK_SENSOR_LOCK(sensor);
2457
return sensor->event_support;
2461
ipmi_sensor_get_sensor_type(ipmi_sensor_t *sensor)
2463
CHECK_SENSOR_LOCK(sensor);
2465
return sensor->sensor_type;
2469
ipmi_sensor_get_event_reading_type(ipmi_sensor_t *sensor)
2471
CHECK_SENSOR_LOCK(sensor);
2473
return sensor->event_reading_type;
2477
ipmi_sensor_get_sensor_direction(ipmi_sensor_t *sensor)
2479
CHECK_SENSOR_LOCK(sensor);
2481
return sensor->sensor_direction;
2485
ipmi_sensor_get_analog_data_format(ipmi_sensor_t *sensor)
2487
CHECK_SENSOR_LOCK(sensor);
2489
return sensor->analog_data_format;
2492
enum ipmi_rate_unit_e
2493
ipmi_sensor_get_rate_unit(ipmi_sensor_t *sensor)
2495
CHECK_SENSOR_LOCK(sensor);
2497
return sensor->rate_unit;
2500
enum ipmi_modifier_unit_use_e
2501
ipmi_sensor_get_modifier_unit_use(ipmi_sensor_t *sensor)
2503
CHECK_SENSOR_LOCK(sensor);
2505
return sensor->modifier_unit_use;
2509
ipmi_sensor_get_percentage(ipmi_sensor_t *sensor)
2511
CHECK_SENSOR_LOCK(sensor);
2513
return sensor->percentage;
2516
enum ipmi_unit_type_e
2517
ipmi_sensor_get_base_unit(ipmi_sensor_t *sensor)
2519
CHECK_SENSOR_LOCK(sensor);
2521
return sensor->base_unit;
2524
enum ipmi_unit_type_e
2525
ipmi_sensor_get_modifier_unit(ipmi_sensor_t *sensor)
2527
CHECK_SENSOR_LOCK(sensor);
2529
return sensor->modifier_unit;
2533
ipmi_sensor_get_linearization(ipmi_sensor_t *sensor)
2535
CHECK_SENSOR_LOCK(sensor);
2537
return sensor->linearization;
2541
ipmi_sensor_get_raw_m(ipmi_sensor_t *sensor, int val)
2543
CHECK_SENSOR_LOCK(sensor);
2545
return sensor->conv[val].m;
2549
ipmi_sensor_get_raw_tolerance(ipmi_sensor_t *sensor, int val)
2551
CHECK_SENSOR_LOCK(sensor);
2553
return sensor->conv[val].tolerance;
2557
ipmi_sensor_get_raw_b(ipmi_sensor_t *sensor, int val)
2559
CHECK_SENSOR_LOCK(sensor);
2561
return sensor->conv[val].b;
2565
ipmi_sensor_get_raw_accuracy(ipmi_sensor_t *sensor, int val)
2567
CHECK_SENSOR_LOCK(sensor);
2569
return sensor->conv[val].accuracy;
2573
ipmi_sensor_get_raw_accuracy_exp(ipmi_sensor_t *sensor, int val)
2575
CHECK_SENSOR_LOCK(sensor);
2577
return sensor->conv[val].accuracy_exp;
2581
ipmi_sensor_get_raw_r_exp(ipmi_sensor_t *sensor, int val)
2583
CHECK_SENSOR_LOCK(sensor);
2585
return sensor->conv[val].r_exp;
2589
ipmi_sensor_get_raw_b_exp(ipmi_sensor_t *sensor, int val)
2591
CHECK_SENSOR_LOCK(sensor);
2593
return sensor->conv[val].b_exp;
2597
ipmi_sensor_get_normal_min_specified(ipmi_sensor_t *sensor)
2599
CHECK_SENSOR_LOCK(sensor);
2601
return sensor->normal_min_specified;
2605
ipmi_sensor_get_normal_max_specified(ipmi_sensor_t *sensor)
2607
CHECK_SENSOR_LOCK(sensor);
2609
return sensor->normal_max_specified;
2613
ipmi_sensor_get_nominal_reading_specified(ipmi_sensor_t *sensor)
2615
CHECK_SENSOR_LOCK(sensor);
2617
return sensor->nominal_reading_specified;
2621
ipmi_sensor_get_raw_nominal_reading(ipmi_sensor_t *sensor)
2623
CHECK_SENSOR_LOCK(sensor);
2625
return sensor->nominal_reading;
2629
ipmi_sensor_get_raw_normal_max(ipmi_sensor_t *sensor)
2631
CHECK_SENSOR_LOCK(sensor);
2633
return sensor->normal_max;
2637
ipmi_sensor_get_raw_normal_min(ipmi_sensor_t *sensor)
2639
CHECK_SENSOR_LOCK(sensor);
2641
return sensor->normal_min;
2645
ipmi_sensor_get_raw_sensor_max(ipmi_sensor_t *sensor)
2647
CHECK_SENSOR_LOCK(sensor);
2649
return sensor->sensor_max;
2653
ipmi_sensor_get_raw_sensor_min(ipmi_sensor_t *sensor)
2655
CHECK_SENSOR_LOCK(sensor);
2657
return sensor->sensor_min;
2661
ipmi_sensor_get_positive_going_threshold_hysteresis(ipmi_sensor_t *sensor)
2663
CHECK_SENSOR_LOCK(sensor);
2665
return sensor->positive_going_threshold_hysteresis;
2669
ipmi_sensor_get_negative_going_threshold_hysteresis(ipmi_sensor_t *sensor)
2671
CHECK_SENSOR_LOCK(sensor);
2673
return sensor->negative_going_threshold_hysteresis;
2677
ipmi_sensor_get_oem1(ipmi_sensor_t *sensor)
2679
CHECK_SENSOR_LOCK(sensor);
2681
return sensor->oem1;
2685
ipmi_sensor_get_id_length(ipmi_sensor_t *sensor)
2687
CHECK_SENSOR_LOCK(sensor);
2689
if (sensor->id_type == IPMI_ASCII_STR)
2690
return sensor->id_len+1;
2692
return sensor->id_len;
2695
enum ipmi_str_type_e
2696
ipmi_sensor_get_id_type(ipmi_sensor_t *sensor)
2698
CHECK_SENSOR_LOCK(sensor);
2700
return sensor->id_type;
2704
ipmi_sensor_get_id(ipmi_sensor_t *sensor, char *id, int length)
2708
CHECK_SENSOR_LOCK(sensor);
2710
if (sensor->id_len > length)
2713
clen = sensor->id_len;
2714
memcpy(id, sensor->id, clen);
2716
if (sensor->id_type == IPMI_ASCII_STR) {
2717
/* NIL terminate the ASCII string. */
2728
ipmi_sensor_set_owner(ipmi_sensor_t *sensor, int owner)
2730
sensor->owner = owner;
2734
ipmi_sensor_set_channel(ipmi_sensor_t *sensor, int channel)
2736
sensor->channel = channel;
2740
ipmi_sensor_set_entity_id(ipmi_sensor_t *sensor, int entity_id)
2742
sensor->entity_id = entity_id;
2746
ipmi_sensor_set_entity_instance(ipmi_sensor_t *sensor, int entity_instance)
2748
sensor->entity_instance = entity_instance;
2752
ipmi_sensor_set_entity_instance_logical(ipmi_sensor_t *sensor,
2753
int entity_instance_logical)
2755
sensor->entity_instance_logical = entity_instance_logical;
2759
ipmi_sensor_set_sensor_init_scanning(ipmi_sensor_t *sensor,
2760
int sensor_init_scanning)
2762
sensor->sensor_init_scanning = sensor_init_scanning;
2766
ipmi_sensor_set_sensor_init_events(ipmi_sensor_t *sensor,
2767
int sensor_init_events)
2769
sensor->sensor_init_events = sensor_init_events;
2773
ipmi_sensor_set_sensor_init_thresholds(ipmi_sensor_t *sensor,
2774
int sensor_init_thresholds)
2776
sensor->sensor_init_thresholds = sensor_init_thresholds;
2780
ipmi_sensor_set_sensor_init_hysteresis(ipmi_sensor_t *sensor,
2781
int sensor_init_hysteresis)
2783
sensor->sensor_init_hysteresis = sensor_init_hysteresis;
2787
ipmi_sensor_set_sensor_init_type(ipmi_sensor_t *sensor, int sensor_init_type)
2789
sensor->sensor_init_type = sensor_init_type;
2793
ipmi_sensor_set_sensor_init_pu_events(ipmi_sensor_t *sensor,
2794
int sensor_init_pu_events)
2796
sensor->sensor_init_pu_events = sensor_init_pu_events;
2800
ipmi_sensor_set_sensor_init_pu_scanning(ipmi_sensor_t *sensor,
2801
int sensor_init_pu_scanning)
2803
sensor->sensor_init_pu_scanning = sensor_init_pu_scanning;
2807
ipmi_sensor_set_ignore_if_no_entity(ipmi_sensor_t *sensor,
2808
int ignore_if_no_entity)
2810
sensor->ignore_if_no_entity = ignore_if_no_entity;
2814
ipmi_sensor_set_supports_auto_rearm(ipmi_sensor_t *sensor, int val)
2816
sensor->supports_auto_rearm = val;
2820
ipmi_sensor_set_hysteresis_support(ipmi_sensor_t *sensor,
2821
int hysteresis_support)
2823
sensor->hysteresis_support = hysteresis_support;
2827
ipmi_sensor_set_threshold_access(ipmi_sensor_t *sensor, int threshold_access)
2829
sensor->threshold_access = threshold_access;
2833
ipmi_sensor_set_event_support(ipmi_sensor_t *sensor, int event_support)
2835
sensor->event_support = event_support;
2839
ipmi_sensor_set_sensor_type(ipmi_sensor_t *sensor, int sensor_type)
2841
sensor->sensor_type = sensor_type;
2845
ipmi_sensor_set_event_reading_type(ipmi_sensor_t *sensor,
2846
int event_reading_type)
2848
sensor->event_reading_type = event_reading_type;
2852
ipmi_sensor_set_direction(ipmi_sensor_t *sensor,
2855
sensor->sensor_direction = direction;
2859
ipmi_sensor_set_analog_data_format(ipmi_sensor_t *sensor,
2860
int analog_data_format)
2862
sensor->analog_data_format = analog_data_format;
2866
ipmi_sensor_set_rate_unit(ipmi_sensor_t *sensor, int rate_unit)
2868
sensor->rate_unit = rate_unit;
2872
ipmi_sensor_set_modifier_unit_use(ipmi_sensor_t *sensor, int modifier_unit_use)
2874
sensor->modifier_unit_use = modifier_unit_use;
2878
ipmi_sensor_set_percentage(ipmi_sensor_t *sensor, int percentage)
2880
sensor->percentage = percentage;
2884
ipmi_sensor_set_base_unit(ipmi_sensor_t *sensor, int base_unit)
2886
sensor->base_unit = base_unit;
2890
ipmi_sensor_set_modifier_unit(ipmi_sensor_t *sensor, int modifier_unit)
2892
sensor->modifier_unit = modifier_unit;
2896
ipmi_sensor_set_linearization(ipmi_sensor_t *sensor, int linearization)
2898
sensor->linearization = linearization;
2902
ipmi_sensor_set_raw_m(ipmi_sensor_t *sensor, int idx, int val)
2904
sensor->conv[idx].m = val;
2908
ipmi_sensor_set_raw_tolerance(ipmi_sensor_t *sensor, int idx, int val)
2910
sensor->conv[idx].tolerance = val;
2914
ipmi_sensor_set_raw_b(ipmi_sensor_t *sensor, int idx, int val)
2916
sensor->conv[idx].b = val;
2920
ipmi_sensor_set_raw_accuracy(ipmi_sensor_t *sensor, int idx, int val)
2922
sensor->conv[idx].accuracy = val;
2926
ipmi_sensor_set_raw_accuracy_exp(ipmi_sensor_t *sensor, int idx, int val)
2928
sensor->conv[idx].accuracy_exp = val;
2932
ipmi_sensor_set_raw_r_exp(ipmi_sensor_t *sensor, int idx, int val)
2934
sensor->conv[idx].r_exp = val;
2938
ipmi_sensor_set_raw_b_exp(ipmi_sensor_t *sensor, int idx, int val)
2940
sensor->conv[idx].b_exp = val;
2944
ipmi_sensor_set_normal_min_specified(ipmi_sensor_t *sensor,
2945
int normal_min_specified)
2947
sensor->normal_min_specified = normal_min_specified;
2951
ipmi_sensor_set_normal_max_specified(ipmi_sensor_t *sensor,
2952
int normal_max_specified)
2954
sensor->normal_max_specified = normal_max_specified;
2958
ipmi_sensor_set_nominal_reading_specified(
2959
ipmi_sensor_t *sensor,
2960
int nominal_reading_specified)
2962
sensor->nominal_reading_specified = nominal_reading_specified;
2966
ipmi_sensor_set_raw_nominal_reading(ipmi_sensor_t *sensor,
2967
int raw_nominal_reading)
2969
sensor->nominal_reading = raw_nominal_reading;
2973
ipmi_sensor_set_raw_normal_max(ipmi_sensor_t *sensor, int raw_normal_max)
2975
sensor->normal_max = raw_normal_max;
2979
ipmi_sensor_set_raw_normal_min(ipmi_sensor_t *sensor, int raw_normal_min)
2981
sensor->normal_min = raw_normal_min;
2985
ipmi_sensor_set_raw_sensor_max(ipmi_sensor_t *sensor, int raw_sensor_max)
2987
sensor->sensor_max = raw_sensor_max;
2991
ipmi_sensor_set_raw_sensor_min(ipmi_sensor_t *sensor, int raw_sensor_min)
2993
sensor->sensor_min = raw_sensor_min;
2997
ipmi_sensor_set_positive_going_threshold_hysteresis(
2998
ipmi_sensor_t *sensor,
2999
int positive_going_threshold_hysteresis)
3001
sensor->positive_going_threshold_hysteresis
3002
= positive_going_threshold_hysteresis;
3006
ipmi_sensor_set_negative_going_threshold_hysteresis(
3007
ipmi_sensor_t *sensor,
3008
int negative_going_threshold_hysteresis)
3010
sensor->negative_going_threshold_hysteresis
3011
= negative_going_threshold_hysteresis;
3015
ipmi_sensor_set_oem1(ipmi_sensor_t *sensor, int oem1)
3017
sensor->oem1 = oem1;
3021
ipmi_sensor_set_id(ipmi_sensor_t *sensor, char *id,
3022
enum ipmi_str_type_e type, int length)
3024
if (length > SENSOR_ID_LEN)
3025
length = SENSOR_ID_LEN;
3027
memcpy(sensor->id, id, length);
3028
sensor->id_type = type;
3029
sensor->id_len = length;
3031
sensor_set_name(sensor);
3035
ipmi_sensor_set_oem_info(ipmi_sensor_t *sensor, void *oem_info,
3036
ipmi_sensor_cleanup_oem_info_cb cleanup_handler)
3038
sensor->oem_info = oem_info;
3039
sensor->oem_info_cleanup_handler = cleanup_handler;
3043
ipmi_sensor_get_oem_info(ipmi_sensor_t *sensor)
3045
CHECK_SENSOR_LOCK(sensor);
3047
return sensor->oem_info;
3051
ipmi_sensor_get_sensor_type_string(ipmi_sensor_t *sensor)
3053
CHECK_SENSOR_LOCK(sensor);
3055
return sensor->sensor_type_string;
3059
ipmi_sensor_set_sensor_type_string(ipmi_sensor_t *sensor, const char *str)
3061
sensor->sensor_type_string = str;
3065
ipmi_sensor_get_event_reading_type_string(ipmi_sensor_t *sensor)
3067
CHECK_SENSOR_LOCK(sensor);
3069
return sensor->event_reading_type_string;
3073
ipmi_sensor_set_event_reading_type_string(ipmi_sensor_t *sensor,
3076
sensor->event_reading_type_string = str;
3080
ipmi_sensor_get_rate_unit_string(ipmi_sensor_t *sensor)
3082
CHECK_SENSOR_LOCK(sensor);
3084
return sensor->rate_unit_string;
3088
ipmi_sensor_set_rate_unit_string(ipmi_sensor_t *sensor,
3091
sensor->rate_unit_string = str;
3095
ipmi_sensor_get_base_unit_string(ipmi_sensor_t *sensor)
3097
CHECK_SENSOR_LOCK(sensor);
3099
return sensor->base_unit_string;
3103
ipmi_sensor_set_base_unit_string(ipmi_sensor_t *sensor, const char *str)
3105
sensor->base_unit_string = str;
3109
ipmi_sensor_get_modifier_unit_string(ipmi_sensor_t *sensor)
3111
CHECK_SENSOR_LOCK(sensor);
3113
return sensor->modifier_unit_string;
3117
ipmi_sensor_set_modifier_unit_string(ipmi_sensor_t *sensor, const char *str)
3119
sensor->modifier_unit_string = str;
3123
ipmi_sensor_set_hot_swap_requester(ipmi_sensor_t *sensor,
3124
unsigned int offset,
3125
unsigned int val_when_requesting)
3127
sensor->hot_swap_requester = offset;
3128
sensor->hot_swap_requester_val = val_when_requesting;
3132
ipmi_sensor_is_hot_swap_requester(ipmi_sensor_t *sensor,
3133
unsigned int *offset,
3134
unsigned int *val_when_requesting)
3136
CHECK_SENSOR_LOCK(sensor);
3138
if (sensor->hot_swap_requester != -1) {
3140
*offset = sensor->hot_swap_requester;
3141
if (val_when_requesting)
3142
*val_when_requesting = sensor->hot_swap_requester_val;
3149
ipmi_sensor_get_domain(ipmi_sensor_t *sensor)
3151
return sensor->domain;
3155
ipmi_sensor_get_entity(ipmi_sensor_t *sensor)
3157
return sensor->entity;
3161
/***********************************************************************
3163
* Incoming event handling for sensors.
3165
**********************************************************************/
3168
ipmi_sensor_threshold_set_event_handler(
3169
ipmi_sensor_t *sensor,
3170
ipmi_sensor_threshold_event_handler_nd_cb handler,
3173
CHECK_SENSOR_LOCK(sensor);
3175
sensor->threshold_event_handler = handler;
3176
sensor->cb_data = cb_data;
3181
ipmi_sensor_add_threshold_event_handler(
3182
ipmi_sensor_t *sensor,
3183
ipmi_sensor_threshold_event_cb handler,
3186
CHECK_SENSOR_LOCK(sensor);
3188
if (! locked_list_add(sensor->handler_list, handler, cb_data))
3195
ipmi_sensor_remove_threshold_event_handler(
3196
ipmi_sensor_t *sensor,
3197
ipmi_sensor_threshold_event_cb handler,
3200
CHECK_SENSOR_LOCK(sensor);
3202
if (! locked_list_remove(sensor->handler_list, handler, cb_data))
3210
ipmi_sensor_discrete_set_event_handler(
3211
ipmi_sensor_t *sensor,
3212
ipmi_sensor_discrete_event_handler_nd_cb handler,
3215
CHECK_SENSOR_LOCK(sensor);
3217
sensor->discrete_event_handler = handler;
3218
sensor->cb_data = cb_data;
3223
ipmi_sensor_add_discrete_event_handler(
3224
ipmi_sensor_t *sensor,
3225
ipmi_sensor_discrete_event_cb handler,
3228
CHECK_SENSOR_LOCK(sensor);
3230
if (! locked_list_add(sensor->handler_list, handler, cb_data))
3237
ipmi_sensor_remove_discrete_event_handler(
3238
ipmi_sensor_t *sensor,
3239
ipmi_sensor_discrete_event_cb handler,
3242
CHECK_SENSOR_LOCK(sensor);
3244
if (! locked_list_remove(sensor->handler_list, handler, cb_data))
3250
typedef struct sensor_event_info_s
3252
ipmi_sensor_t *sensor;
3255
enum ipmi_event_dir_e dir;
3256
enum ipmi_thresh_e threshold;
3257
enum ipmi_event_value_dir_e high_low;
3258
enum ipmi_value_present_e value_present;
3259
unsigned int raw_value;
3266
ipmi_event_t *event;
3267
} sensor_event_info_t;
3270
threshold_sensor_event_call_handler(void *cb_data, void *item1, void *item2)
3272
ipmi_sensor_threshold_event_cb handler = item1;
3273
sensor_event_info_t *info = cb_data;
3276
handled = handler(info->sensor, info->dir,
3279
info->value_present,
3280
info->raw_value, info->value,
3281
item2, info->event);
3282
if (handled == IPMI_EVENT_HANDLED) {
3283
info->handled = handled;
3286
return LOCKED_LIST_ITER_CONTINUE;
3290
ipmi_sensor_call_threshold_event_handlers
3291
(ipmi_sensor_t *sensor,
3292
enum ipmi_event_dir_e dir,
3293
enum ipmi_thresh_e threshold,
3294
enum ipmi_event_value_dir_e high_low,
3295
enum ipmi_value_present_e value_present,
3296
unsigned int raw_value,
3298
ipmi_event_t **event,
3301
sensor_event_info_t info;
3303
info.sensor = sensor;
3305
info.threshold = threshold;
3306
info.high_low = high_low;
3307
info.value_present = value_present;
3308
info.raw_value = raw_value;
3310
info.event = *event;
3311
info.handled = IPMI_EVENT_NOT_HANDLED;
3313
if (sensor->threshold_event_handler) {
3314
sensor->threshold_event_handler(sensor, info.dir,
3318
info.raw_value, info.value,
3319
sensor->cb_data, info.event);
3321
info.handled = IPMI_EVENT_HANDLED;
3324
locked_list_iterate(sensor->handler_list,
3325
threshold_sensor_event_call_handler, &info);
3328
*handled = info.handled;
3329
*event = info.event;
3333
discrete_sensor_event_call_handler(void *cb_data, void *item1, void *item2)
3335
ipmi_sensor_discrete_event_cb handler = item1;
3336
sensor_event_info_t *info = cb_data;
3339
handled = handler(info->sensor, info->dir, info->offset,
3341
info->prev_severity,
3342
item2, info->event);
3343
if (handled == IPMI_EVENT_HANDLED) {
3344
info->handled = handled;
3347
return LOCKED_LIST_ITER_CONTINUE;
3351
ipmi_sensor_call_discrete_event_handlers(ipmi_sensor_t *sensor,
3352
enum ipmi_event_dir_e dir,
3356
ipmi_event_t **event,
3359
sensor_event_info_t info;
3361
info.sensor = sensor;
3363
info.offset = offset;
3364
info.severity = severity;
3365
info.prev_severity = prev_severity;
3366
info.event = *event;
3367
info.handled = IPMI_EVENT_NOT_HANDLED;
3369
if (sensor->discrete_event_handler) {
3370
sensor->discrete_event_handler(sensor, info.dir, info.offset,
3373
sensor->cb_data, info.event);
3375
info.handled = IPMI_EVENT_HANDLED;
3378
locked_list_iterate(sensor->handler_list,
3379
discrete_sensor_event_call_handler, &info);
3382
*handled = info.handled;
3383
*event = info.event;
3387
ipmi_sensor_event(ipmi_sensor_t *sensor, ipmi_event_t *event)
3392
CHECK_SENSOR_LOCK(sensor);
3396
if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD) {
3397
enum ipmi_event_dir_e dir;
3398
enum ipmi_thresh_e threshold;
3399
enum ipmi_event_value_dir_e high_low;
3400
enum ipmi_value_present_e value_present;
3401
unsigned int raw_value;
3403
unsigned char *data;
3405
data = ipmi_event_get_data_ptr(event);
3407
threshold = (data[10] >> 1) & 0x07;
3408
high_low = data[10] & 1;
3409
raw_value = data[11];
3412
if ((data[10] >> 6) == 2) {
3413
rv = ipmi_sensor_convert_from_raw(sensor, raw_value, &value);
3415
value_present = IPMI_RAW_VALUE_PRESENT;
3417
value_present = IPMI_BOTH_VALUES_PRESENT;
3419
value_present = IPMI_NO_VALUES_PRESENT;
3421
ipmi_sensor_call_threshold_event_handlers(sensor, dir,
3429
enum ipmi_event_dir_e dir;
3432
int prev_severity = 0;
3433
unsigned char *data;
3435
data = ipmi_event_get_data_ptr(event);
3437
offset = data[10] & 0x0f;
3438
if ((data[10] >> 6) == 2) {
3439
severity = data[11] >> 4;
3440
prev_severity = data[11] & 0xf;
3441
if (severity == 0xf)
3443
if (prev_severity == 0xf)
3447
ipmi_sensor_call_discrete_event_handlers(sensor, dir, offset,
3454
/* Make sure the caller knows if we didn't deliver the event. */
3455
if (handled == IPMI_EVENT_NOT_HANDLED)
3460
/***********************************************************************
3462
* Standard sensor messaging.
3464
**********************************************************************/
3466
typedef void (*sensor_done_handler_cb)(ipmi_sensor_t *sensor,
3471
sensor_done_check_rsp(ipmi_sensor_t *sensor,
3474
unsigned int min_length,
3476
sensor_done_handler_cb done,
3480
ipmi_log(IPMI_LOG_ERR_INFO,
3481
"%ssensor.c(%s): Got error: %x",
3482
SENSOR_NAME(sensor), name, err);
3483
done(sensor, err, sinfo);
3488
/* This *should* never happen, but we check it to shake out
3490
ipmi_log(IPMI_LOG_ERR_INFO,
3491
"%ssensor.c(%s): Sensor when away during operation",
3492
SENSOR_NAME(sensor), name);
3493
done(sensor, ECANCELED, sinfo);
3497
if (rsp && rsp->data[0]) {
3499
/* This is sometimes expected. */
3500
ipmi_log(IPMI_LOG_ERR_INFO,
3501
"%ssensor.c(%s): Got IPMI error in response: %x",
3502
SENSOR_NAME(sensor), name, rsp->data[0]);
3504
done(sensor, IPMI_IPMI_ERR_VAL(rsp->data[0]), sinfo);
3505
return IPMI_IPMI_ERR_VAL(rsp->data[0]);
3508
if (rsp && (rsp->data_len < min_length)) {
3509
ipmi_log(IPMI_LOG_ERR_INFO,
3510
"%ssensor.c(%s): Response was too short, got %d, expected %d",
3511
SENSOR_NAME(sensor), name, rsp->data_len, min_length);
3512
done(sensor, EINVAL, sinfo);
3519
typedef struct event_enable_info_s
3521
ipmi_sensor_op_info_t sdata;
3522
ipmi_event_state_t state;
3523
ipmi_sensor_done_cb done;
3527
} event_enable_info_t;
3529
static void enables_done_handler(ipmi_sensor_t *sensor,
3533
event_enable_info_t *info = sinfo;
3536
info->done(sensor, err, info->cb_data);
3537
ipmi_sensor_opq_done(sensor);
3538
ipmi_mem_free(info);
3542
disables_set(ipmi_sensor_t *sensor,
3547
event_enable_info_t *info = cb_data;
3549
if (sensor_done_check_rsp(sensor, err, rsp, 1, "disables_set",
3550
enables_done_handler, info))
3553
enables_done_handler(sensor, 0, info);
3557
enables_set(ipmi_sensor_t *sensor,
3562
event_enable_info_t *info = cb_data;
3563
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
3567
if (sensor_done_check_rsp(sensor, err, rsp, 1, "enables_set",
3568
enables_done_handler, info))
3571
if (info->do_disable) {
3572
/* Enables were set, now disable all the other ones. */
3573
cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
3574
cmd_msg.cmd = IPMI_SET_SENSOR_EVENT_ENABLE_CMD;
3575
cmd_msg.data_len = 6;
3576
cmd_msg.data = cmd_data;
3577
cmd_data[0] = sensor->num;
3578
cmd_data[1] = (info->state.status & 0xc0) | (0x02 << 4);
3579
cmd_data[2] = ~(info->state.__assertion_events & 0xff);
3580
cmd_data[3] = ~(info->state.__assertion_events >> 8);
3581
cmd_data[4] = ~(info->state.__deassertion_events & 0xff);
3582
cmd_data[5] = ~(info->state.__deassertion_events >> 8);
3583
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
3584
&cmd_msg, disables_set,
3585
&(info->sdata), info);
3587
ipmi_log(IPMI_LOG_ERR_INFO,
3588
"%ssensors.c(enables_set):"
3589
" Error sending event enable command to clear events: %x",
3590
SENSOR_NAME(sensor), rv);
3591
enables_done_handler(sensor, rv, info);
3594
/* Just doing enables, we are done. */
3595
enables_done_handler(sensor, 0, info);
3600
event_enable_set_start(ipmi_sensor_t *sensor, int err, void *cb_data)
3602
event_enable_info_t *info = cb_data;
3603
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
3608
if (sensor_done_check_rsp(sensor, err, NULL, 0, "event_enable_set_start",
3609
enables_done_handler, info))
3612
event_support = ipmi_sensor_get_event_support(sensor);
3614
cmd_msg.data = cmd_data;
3615
cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
3616
cmd_msg.cmd = IPMI_SET_SENSOR_EVENT_ENABLE_CMD;
3617
cmd_msg.data = cmd_data;
3618
cmd_data[0] = sensor->num;
3619
if (event_support == IPMI_EVENT_SUPPORT_ENTIRE_SENSOR) {
3620
/* We can only turn on/off the entire sensor, just pass the
3621
status to the sensor. */
3622
cmd_data[1] = info->state.status & 0xc0;
3623
cmd_msg.data_len = 2;
3624
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
3625
&cmd_msg, disables_set, &(info->sdata),
3627
} else if (info->do_enable) {
3628
/* Start by first setting the enables, then set the disables
3629
in a second operation. We do this because enables and
3630
disables cannot both be set at the same time, and it's
3631
safer to first enable the new events then to disable the
3632
events we want disabled. It would be *really* nice if IPMI
3633
had a way to do this in one operation, such as using 11b in
3634
the request byte 2 bits 5:4 to say "set the events to
3635
exactly this state". */
3636
cmd_data[1] = (info->state.status & 0xc0) | (0x01 << 4);
3637
cmd_data[2] = info->state.__assertion_events & 0xff;
3638
cmd_data[3] = info->state.__assertion_events >> 8;
3639
cmd_data[4] = info->state.__deassertion_events & 0xff;
3640
cmd_data[5] = info->state.__deassertion_events >> 8;
3641
cmd_msg.data_len = 6;
3642
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
3643
&cmd_msg, enables_set, &(info->sdata),
3646
/* We are only doing disables. */
3647
cmd_data[1] = (info->state.status & 0xc0) | (0x02 << 4);
3648
cmd_data[2] = info->state.__assertion_events & 0xff;
3649
cmd_data[3] = info->state.__assertion_events >> 8;
3650
cmd_data[4] = info->state.__deassertion_events & 0xff;
3651
cmd_data[5] = info->state.__deassertion_events >> 8;
3652
cmd_msg.data_len = 6;
3653
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
3654
&cmd_msg, disables_set,
3655
&(info->sdata), info);
3658
ipmi_log(IPMI_LOG_ERR_INFO,
3659
"%ssensor.c(event_enable_set_start):"
3660
" Error sending event enable command: %x",
3661
SENSOR_NAME(sensor), rv);
3662
enables_done_handler(sensor, rv, info);
3667
check_events_capability(ipmi_sensor_t *sensor,
3668
ipmi_event_state_t *states)
3672
event_support = ipmi_sensor_get_event_support(sensor);
3673
if ((event_support == IPMI_EVENT_SUPPORT_NONE)
3674
|| (event_support == IPMI_EVENT_SUPPORT_GLOBAL_ENABLE))
3676
/* We don't support setting events for this sensor. */
3680
if ((event_support == IPMI_EVENT_SUPPORT_ENTIRE_SENSOR)
3681
&& ((states->__assertion_events != 0)
3682
|| (states->__deassertion_events != 0)))
3684
/* This sensor does not support individual event states, but
3685
the user is trying to set them. */
3689
if (event_support == IPMI_EVENT_SUPPORT_PER_STATE) {
3691
for (i=0; i<16; i++) {
3692
unsigned int bit = 1 << i;
3694
if (((!sensor->mask1[i]) && (bit & states->__assertion_events))
3695
|| ((!sensor->mask2[i]) && (bit & states->__deassertion_events)))
3697
/* The user is attempting to set a state that the
3698
sensor does not support. */
3708
stand_ipmi_sensor_set_event_enables(ipmi_sensor_t *sensor,
3709
ipmi_event_state_t *states,
3710
ipmi_sensor_done_cb done,
3713
event_enable_info_t *info;
3716
rv = check_events_capability(sensor, states);
3720
info = ipmi_mem_alloc(sizeof(*info));
3723
info->state = *states;
3725
info->cb_data = cb_data;
3726
info->do_enable = 1;
3727
info->do_disable = 1;
3728
rv = ipmi_sensor_add_opq(sensor, event_enable_set_start,
3729
&(info->sdata), info);
3731
ipmi_mem_free(info);
3736
stand_ipmi_sensor_enable_events(ipmi_sensor_t *sensor,
3737
ipmi_event_state_t *states,
3738
ipmi_sensor_done_cb done,
3741
event_enable_info_t *info;
3744
rv = check_events_capability(sensor, states);
3748
info = ipmi_mem_alloc(sizeof(*info));
3751
info->state = *states;
3753
info->cb_data = cb_data;
3754
info->do_enable = 1;
3755
info->do_disable = 0;
3756
rv = ipmi_sensor_add_opq(sensor, event_enable_set_start,
3757
&(info->sdata), info);
3759
ipmi_mem_free(info);
3764
stand_ipmi_sensor_disable_events(ipmi_sensor_t *sensor,
3765
ipmi_event_state_t *states,
3766
ipmi_sensor_done_cb done,
3769
event_enable_info_t *info;
3772
rv = check_events_capability(sensor, states);
3776
info = ipmi_mem_alloc(sizeof(*info));
3779
info->state = *states;
3781
info->cb_data = cb_data;
3782
info->do_enable = 0;
3783
info->do_disable = 1;
3784
rv = ipmi_sensor_add_opq(sensor, event_enable_set_start,
3785
&(info->sdata), info);
3787
ipmi_mem_free(info);
3791
typedef struct event_enable_get_info_s
3793
ipmi_sensor_op_info_t sdata;
3794
ipmi_event_state_t state;
3795
ipmi_sensor_event_enables_cb done;
3797
} event_enable_get_info_t;
3799
static void enables_get_done_handler(ipmi_sensor_t *sensor,
3803
event_enable_get_info_t *info = sinfo;
3806
info->done(sensor, err, &info->state, info->cb_data);
3807
ipmi_sensor_opq_done(sensor);
3808
ipmi_mem_free(info);
3812
enables_get(ipmi_sensor_t *sensor,
3817
event_enable_get_info_t *info = cb_data;
3819
if (sensor_done_check_rsp(sensor, err, rsp, 2, "enables_get",
3820
enables_get_done_handler, info))
3823
info->state.status = rsp->data[1] & 0xc0;
3824
if (rsp->data_len >= 4)
3825
info->state.__assertion_events = (rsp->data[2]
3826
| (rsp->data[3] << 8));
3827
if (rsp->data_len >= 6)
3828
info->state.__deassertion_events = (rsp->data[4]
3829
| (rsp->data[5] << 8));
3830
enables_get_done_handler(sensor, 0, info);
3834
event_enable_get_start(ipmi_sensor_t *sensor, int err, void *cb_data)
3836
event_enable_get_info_t *info = cb_data;
3837
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
3841
if (sensor_done_check_rsp(sensor, err, NULL, 0, "event_enable_get_start",
3842
enables_get_done_handler, info))
3845
cmd_msg.data = cmd_data;
3846
cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
3847
cmd_msg.cmd = IPMI_GET_SENSOR_EVENT_ENABLE_CMD;
3848
cmd_msg.data_len = 1;
3849
cmd_msg.data = cmd_data;
3850
cmd_data[0] = sensor->num;
3851
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
3852
&cmd_msg, enables_get, &(info->sdata), info);
3854
ipmi_log(IPMI_LOG_ERR_INFO,
3855
"%ssensor.c(event_enable_get_start):"
3856
" Error sending get event enables command: %x",
3857
SENSOR_NAME(sensor), rv);
3858
enables_get_done_handler(sensor, rv, info);
3863
stand_ipmi_sensor_get_event_enables(ipmi_sensor_t *sensor,
3864
ipmi_sensor_event_enables_cb done,
3867
event_enable_get_info_t *info;
3870
info = ipmi_mem_alloc(sizeof(*info));
3873
memset(info, 0, sizeof(info));
3875
info->cb_data = cb_data;
3876
rv = ipmi_sensor_add_opq(sensor, event_enable_get_start,
3877
&(info->sdata), info);
3879
ipmi_mem_free(info);
3883
typedef struct sensor_rearm_info_s
3885
ipmi_sensor_op_info_t sdata;
3886
ipmi_event_state_t state;
3888
ipmi_sensor_done_cb done;
3890
} sensor_rearm_info_t;
3892
static void sensor_rearm_done_handler(ipmi_sensor_t *sensor,
3896
sensor_rearm_info_t *info = sinfo;
3899
info->done(sensor, err, info->cb_data);
3900
ipmi_sensor_opq_done(sensor);
3901
ipmi_mem_free(info);
3905
sensor_rearm(ipmi_sensor_t *sensor,
3910
sensor_rearm_info_t *info = cb_data;
3912
if (sensor_done_check_rsp(sensor, err, rsp, 1, "sensor_rearm",
3913
sensor_rearm_done_handler, info))
3916
sensor_rearm_done_handler(sensor, 0, info);
3920
sensor_rearm_start(ipmi_sensor_t *sensor, int err, void *cb_data)
3922
sensor_rearm_info_t *info = cb_data;
3923
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
3927
if (sensor_done_check_rsp(sensor, err, NULL, 0, "sensor_rearm_start",
3928
sensor_rearm_done_handler, info))
3931
cmd_msg.data = cmd_data;
3932
cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
3933
cmd_msg.cmd = IPMI_REARM_SENSOR_EVENTS_CMD;
3934
if (info->global_enable) {
3935
cmd_msg.data_len = 2;
3936
cmd_msg.data = cmd_data;
3937
cmd_data[0] = sensor->num;
3938
cmd_data[1] = 0; /* Rearm all events. */
3940
cmd_msg.data_len = 6;
3941
cmd_msg.data = cmd_data;
3942
cmd_data[0] = sensor->num;
3943
cmd_data[1] = 0x80; /* Rearm only specific sensors. */
3944
cmd_data[2] = info->state.__assertion_events & 0xff;
3945
cmd_data[3] = info->state.__assertion_events >> 8;
3946
cmd_data[4] = info->state.__deassertion_events & 0xff;
3947
cmd_data[5] = info->state.__deassertion_events >> 8;
3949
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
3950
&cmd_msg, sensor_rearm,
3951
&(info->sdata), info);
3953
ipmi_log(IPMI_LOG_ERR_INFO,
3954
"%ssensor.c(sensor_rearm_start):"
3955
" Error sending rearm command: %x",
3956
SENSOR_NAME(sensor), rv);
3957
sensor_rearm_done_handler(sensor, rv, info);
3962
stand_ipmi_sensor_rearm(ipmi_sensor_t *sensor,
3964
ipmi_event_state_t *state,
3965
ipmi_sensor_done_cb done,
3968
sensor_rearm_info_t *info;
3971
if (!global_enable && !state)
3974
info = ipmi_mem_alloc(sizeof(*info));
3978
info->cb_data = cb_data;
3979
info->global_enable = global_enable;
3981
memcpy(&info->state, state, sizeof(info->state));
3982
rv = ipmi_sensor_add_opq(sensor, sensor_rearm_start, &(info->sdata), info);
3984
ipmi_mem_free(info);
3988
typedef struct hyst_get_info_s
3990
ipmi_sensor_op_info_t sdata;
3991
ipmi_sensor_hysteresis_cb done;
3993
unsigned int positive;
3994
unsigned int negative;
3997
static void hyst_get_done_handler(ipmi_sensor_t *sensor,
4001
hyst_get_info_t *info = sinfo;
4004
info->done(sensor, err, info->positive, info->negative, info->cb_data);
4005
ipmi_sensor_opq_done(sensor);
4006
ipmi_mem_free(info);
4010
hyst_get(ipmi_sensor_t *sensor,
4015
hyst_get_info_t *info = cb_data;
4017
if (sensor_done_check_rsp(sensor, err, rsp, 3, "hyst_get",
4018
hyst_get_done_handler, info))
4021
info->positive = rsp->data[1];
4022
info->negative = rsp->data[2];
4023
hyst_get_done_handler(sensor, 0, info);
4027
hyst_get_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4029
hyst_get_info_t *info = cb_data;
4030
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4034
if (sensor_done_check_rsp(sensor, err, NULL, 0, "hyst_get_start",
4035
hyst_get_done_handler, info))
4038
cmd_msg.data = cmd_data;
4039
cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4040
cmd_msg.cmd = IPMI_GET_SENSOR_HYSTERESIS_CMD;
4041
cmd_msg.data_len = 2;
4042
cmd_msg.data = cmd_data;
4043
cmd_data[0] = sensor->num;
4045
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4046
&cmd_msg, hyst_get, &(info->sdata), info);
4048
ipmi_log(IPMI_LOG_ERR_INFO,
4049
"%ssensor.c(hyst_get_start):"
4050
" Error sending hysteresis get command: %x",
4051
SENSOR_NAME(sensor), rv);
4052
hyst_get_done_handler(sensor, rv, info);
4057
stand_ipmi_sensor_get_hysteresis(ipmi_sensor_t *sensor,
4058
ipmi_sensor_hysteresis_cb done,
4061
hyst_get_info_t *info;
4064
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4065
/* Not a threshold sensor, it doesn't have readings. */
4068
if ((sensor->hysteresis_support != IPMI_HYSTERESIS_SUPPORT_READABLE)
4069
&& (sensor->hysteresis_support != IPMI_HYSTERESIS_SUPPORT_SETTABLE))
4072
info = ipmi_mem_alloc(sizeof(*info));
4075
memset(info, 0, sizeof(*info));
4077
info->cb_data = cb_data;
4078
rv = ipmi_sensor_add_opq(sensor, hyst_get_start, &(info->sdata), info);
4080
ipmi_mem_free(info);
4084
typedef struct hyst_set_info_s
4086
ipmi_sensor_op_info_t sdata;
4087
unsigned int positive, negative;
4088
ipmi_sensor_done_cb done;
4092
static void hyst_set_done_handler(ipmi_sensor_t *sensor,
4096
hyst_set_info_t *info = sinfo;
4099
info->done(sensor, err, info->cb_data);
4100
ipmi_sensor_opq_done(sensor);
4101
ipmi_mem_free(info);
4105
hyst_set(ipmi_sensor_t *sensor,
4110
hyst_set_info_t *info = cb_data;
4112
if (sensor_done_check_rsp(sensor, err, rsp, 1, "hyst_set",
4113
hyst_set_done_handler, info))
4116
hyst_set_done_handler(sensor, 0, info);
4120
hyst_set_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4122
hyst_set_info_t *info = cb_data;
4123
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4127
if (sensor_done_check_rsp(sensor, err, NULL, 0, "hyst_set_start",
4128
hyst_set_done_handler, info))
4131
cmd_msg.data = cmd_data;
4132
cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4133
cmd_msg.cmd = IPMI_SET_SENSOR_HYSTERESIS_CMD;
4134
cmd_msg.data_len = 4;
4135
cmd_msg.data = cmd_data;
4136
cmd_data[0] = sensor->num;
4138
cmd_data[2] = info->positive;
4139
cmd_data[3] = info->negative;
4140
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4141
&cmd_msg, hyst_set, &(info->sdata), info);
4143
ipmi_log(IPMI_LOG_ERR_INFO,
4144
"%ssensor.c(hyst_set_start):"
4145
" Error sending hysteresis set command: %x",
4146
SENSOR_NAME(sensor), rv);
4147
hyst_set_done_handler(sensor, rv, info);
4152
stand_ipmi_sensor_set_hysteresis(ipmi_sensor_t *sensor,
4153
unsigned int positive_hysteresis,
4154
unsigned int negative_hysteresis,
4155
ipmi_sensor_done_cb done,
4158
hyst_set_info_t *info;
4161
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4162
/* Not a threshold sensor, it doesn't have readings. */
4165
if (sensor->hysteresis_support != IPMI_HYSTERESIS_SUPPORT_SETTABLE)
4168
info = ipmi_mem_alloc(sizeof(*info));
4171
info->positive = positive_hysteresis;
4172
info->negative = negative_hysteresis;
4174
info->cb_data = cb_data;
4175
rv = ipmi_sensor_add_opq(sensor, hyst_set_start, &(info->sdata), info);
4177
ipmi_mem_free(info);
4181
typedef struct thresh_get_info_s
4183
ipmi_sensor_op_info_t sdata;
4184
ipmi_thresholds_t th;
4185
ipmi_sensor_thresholds_cb done;
4187
} thresh_get_info_t;
4189
static void thresh_get_done_handler(ipmi_sensor_t *sensor,
4193
thresh_get_info_t *info = sinfo;
4196
info->done(sensor, err, &info->th, info->cb_data);
4197
ipmi_sensor_opq_done(sensor);
4198
ipmi_mem_free(info);
4202
thresh_get(ipmi_sensor_t *sensor,
4207
thresh_get_info_t *info = cb_data;
4208
enum ipmi_thresh_e th;
4210
if (sensor_done_check_rsp(sensor, err, rsp, 8, "thresh_get",
4211
thresh_get_done_handler, info))
4214
for (th=IPMI_LOWER_NON_CRITICAL; th<=IPMI_UPPER_NON_RECOVERABLE; th++) {
4216
if (rsp->data[1] & (1 << th)) {
4217
info->th.vals[th].status = 1;
4218
rv = ipmi_sensor_convert_from_raw(sensor,
4220
&(info->th.vals[th].val));
4222
ipmi_log(IPMI_LOG_ERR_INFO,
4223
"%ssensor.c(thresh_get):"
4224
" Could not convert raw threshold value: %x",
4225
SENSOR_NAME(sensor), rv);
4226
thresh_get_done_handler(sensor, rv, info);
4230
info->th.vals[th].status = 0;
4234
thresh_get_done_handler(sensor, 0, info);
4238
ipmi_get_default_sensor_thresholds(ipmi_sensor_t *sensor,
4239
ipmi_thresholds_t *th)
4241
enum ipmi_thresh_e thnum;
4244
CHECK_SENSOR_LOCK(sensor);
4246
for (thnum = IPMI_LOWER_NON_CRITICAL;
4247
thnum <= IPMI_UPPER_NON_RECOVERABLE;
4250
th->vals[thnum].status = 1;
4251
rv = ipmi_sensor_convert_from_raw(sensor,
4252
sensor->default_thresholds[thnum],
4253
&(th->vals[thnum].val));
4262
thresh_get_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4264
thresh_get_info_t *info = cb_data;
4265
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4269
if (sensor_done_check_rsp(sensor, err, NULL, 0, "thresh_get_start",
4270
thresh_get_done_handler, info))
4273
if (sensor->threshold_access == IPMI_THRESHOLD_ACCESS_SUPPORT_FIXED) {
4275
/* Thresholds are fixed, they cannot be read. */
4276
for (thnum = IPMI_LOWER_NON_CRITICAL;
4277
thnum <= IPMI_UPPER_NON_RECOVERABLE;
4280
info->th.vals[thnum].status = 0;
4282
thresh_get_done_handler(sensor, 0, info);
4286
cmd_msg.data = cmd_data;
4287
cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4288
cmd_msg.cmd = IPMI_GET_SENSOR_THRESHOLD_CMD;
4289
cmd_msg.data_len = 1;
4290
cmd_msg.data = cmd_data;
4291
cmd_data[0] = sensor->num;
4292
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4293
&cmd_msg, thresh_get, &(info->sdata), info);
4295
ipmi_log(IPMI_LOG_ERR_INFO,
4296
"%ssensor.c(thresh_get_start):"
4297
" Error sending threshold get command: %x",
4298
SENSOR_NAME(sensor), rv);
4299
thresh_get_done_handler(sensor, rv, info);
4304
stand_ipmi_sensor_get_thresholds(ipmi_sensor_t *sensor,
4305
ipmi_sensor_thresholds_cb done,
4308
thresh_get_info_t *info;
4311
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4312
/* Not a threshold sensor, it doesn't have readings. */
4315
if (sensor->threshold_access == IPMI_THRESHOLD_ACCESS_SUPPORT_NONE)
4318
info = ipmi_mem_alloc(sizeof(*info));
4322
info->cb_data = cb_data;
4323
rv = ipmi_sensor_add_opq(sensor, thresh_get_start, &(info->sdata), info);
4325
ipmi_mem_free(info);
4329
typedef struct thresh_set_info_s
4331
ipmi_sensor_op_info_t sdata;
4332
ipmi_thresholds_t th;
4333
ipmi_sensor_done_cb done;
4335
} thresh_set_info_t;
4337
static void thresh_set_done_handler(ipmi_sensor_t *sensor,
4341
thresh_set_info_t *info = sinfo;
4344
info->done(sensor, err, info->cb_data);
4345
ipmi_sensor_opq_done(sensor);
4346
ipmi_mem_free(info);
4350
thresh_set(ipmi_sensor_t *sensor,
4355
thresh_set_info_t *info = cb_data;
4357
if (sensor_done_check_rsp(sensor, err, rsp, 1, "thresh_set",
4358
thresh_set_done_handler, info))
4361
thresh_set_done_handler(sensor, 0, info);
4365
thresh_set_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4367
thresh_set_info_t *info = cb_data;
4368
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4371
enum ipmi_thresh_e th;
4373
if (sensor_done_check_rsp(sensor, err, NULL, 0, "thresh_set_start",
4374
thresh_set_done_handler, info))
4377
cmd_msg.data = cmd_data;
4378
cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4379
cmd_msg.cmd = IPMI_SET_SENSOR_THRESHOLD_CMD;
4380
cmd_msg.data_len = 8;
4381
cmd_msg.data = cmd_data;
4382
cmd_data[0] = sensor->num;
4384
for (th=IPMI_LOWER_NON_CRITICAL; th<=IPMI_UPPER_NON_RECOVERABLE; th++) {
4385
if (info->th.vals[th].status) {
4387
cmd_data[1] |= (1 << th);
4388
rv = ipmi_sensor_convert_to_raw(sensor,
4390
info->th.vals[th].val,
4393
ipmi_log(IPMI_LOG_ERR_INFO,
4394
"%ssensor.c(thresh_set_start):"
4395
"Error converting threshold to raw: %x",
4396
SENSOR_NAME(sensor), rv);
4397
thresh_set_done_handler(sensor, rv, info);
4400
cmd_data[th+2] = val;
4404
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4405
&cmd_msg, thresh_set, &(info->sdata), info);
4407
ipmi_log(IPMI_LOG_ERR_INFO,
4408
"%ssensor.c(thresh_set_start):"
4409
"Error sending thresholds set command: %x",
4410
SENSOR_NAME(sensor), rv);
4411
thresh_set_done_handler(sensor, rv, info);
4416
stand_ipmi_sensor_set_thresholds(ipmi_sensor_t *sensor,
4417
ipmi_thresholds_t *thresholds,
4418
ipmi_sensor_done_cb done,
4421
thresh_set_info_t *info;
4424
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4425
/* Not a threshold sensor, it doesn't have readings. */
4428
if (sensor->threshold_access != IPMI_THRESHOLD_ACCESS_SUPPORT_SETTABLE)
4431
info = ipmi_mem_alloc(sizeof(*info));
4434
info->th = *thresholds;
4436
info->cb_data = cb_data;
4437
rv = ipmi_sensor_add_opq(sensor, thresh_set_start, &(info->sdata), info);
4439
ipmi_mem_free(info);
4443
typedef struct reading_get_info_s
4445
ipmi_sensor_op_info_t sdata;
4446
ipmi_sensor_reading_cb done;
4448
ipmi_states_t states;
4449
enum ipmi_value_present_e value_present;
4452
} reading_get_info_t;
4454
static void reading_get_done_handler(ipmi_sensor_t *sensor,
4458
reading_get_info_t *info = sinfo;
4461
info->done(sensor, err, info->value_present,
4462
info->raw_val, info->cooked_val, &info->states,
4464
ipmi_sensor_opq_done(sensor);
4465
ipmi_mem_free(info);
4469
reading_get(ipmi_sensor_t *sensor,
4474
reading_get_info_t *info = rsp_data;
4477
if (sensor_done_check_rsp(sensor, err, rsp, 3, "reading_get",
4478
reading_get_done_handler, info))
4481
info->raw_val = rsp->data[1];
4482
if (sensor->analog_data_format != IPMI_ANALOG_DATA_FORMAT_NOT_ANALOG) {
4483
rv = ipmi_sensor_convert_from_raw(sensor,
4487
info->value_present = IPMI_RAW_VALUE_PRESENT;
4489
info->value_present = IPMI_BOTH_VALUES_PRESENT;
4491
info->value_present = IPMI_NO_VALUES_PRESENT;
4494
info->states.__event_messages_enabled = (rsp->data[2] >> 7) & 1;
4495
info->states.__sensor_scanning_enabled = (rsp->data[2] >> 6) & 1;
4496
info->states.__initial_update_in_progress = (rsp->data[2] >> 5) & 1;
4497
if (rsp->data_len >= 4)
4498
info->states.__states = rsp->data[3];
4500
reading_get_done_handler(sensor, 0, info);
4504
reading_get_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4506
reading_get_info_t *info = cb_data;
4507
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4511
if (sensor_done_check_rsp(sensor, err, NULL, 0, "reading_get_start",
4512
reading_get_done_handler, info))
4515
cmd_msg.data = cmd_data;
4516
cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4517
cmd_msg.cmd = IPMI_GET_SENSOR_READING_CMD;
4518
cmd_msg.data_len = 1;
4519
cmd_msg.data = cmd_data;
4520
cmd_data[0] = sensor->num;
4521
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4522
&cmd_msg, reading_get,
4523
&(info->sdata), info);
4525
ipmi_log(IPMI_LOG_ERR_INFO,
4526
"%ssensor.c(reading_get_start):"
4527
"Error sending reading get command: %x",
4528
SENSOR_NAME(sensor), rv);
4529
reading_get_done_handler(sensor, rv, info);
4534
stand_ipmi_sensor_get_reading(ipmi_sensor_t *sensor,
4535
ipmi_sensor_reading_cb done,
4538
reading_get_info_t *info;
4541
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4542
/* Not a threshold sensor, it doesn't have readings. */
4545
info = ipmi_mem_alloc(sizeof(*info));
4549
info->cb_data = cb_data;
4550
info->value_present = IPMI_NO_VALUES_PRESENT;
4552
info->cooked_val = 0.0;
4553
ipmi_init_states(&info->states);
4554
rv = ipmi_sensor_add_opq(sensor, reading_get_start, &(info->sdata), info);
4556
ipmi_mem_free(info);
4561
typedef struct states_get_info_s
4563
ipmi_sensor_op_info_t sdata;
4564
ipmi_sensor_states_cb done;
4566
ipmi_states_t states;
4567
} states_get_info_t;
4569
static void states_get_done_handler(ipmi_sensor_t *sensor,
4573
states_get_info_t *info = sinfo;
4576
info->done(sensor, err, &info->states, info->cb_data);
4577
ipmi_sensor_opq_done(sensor);
4578
ipmi_mem_free(info);
4582
states_get(ipmi_sensor_t *sensor,
4587
states_get_info_t *info = cb_data;
4589
if (sensor_done_check_rsp(sensor, err, rsp, 3, "states_get",
4590
states_get_done_handler, info))
4593
info->states.__event_messages_enabled = (rsp->data[2] >> 7) & 1;
4594
info->states.__sensor_scanning_enabled = (rsp->data[2] >> 6) & 1;
4595
info->states.__initial_update_in_progress = (rsp->data[2] >> 5) & 1;
4597
if (rsp->data_len >= 4)
4598
info->states.__states |= rsp->data[3];
4599
if (rsp->data_len >= 5)
4600
info->states.__states |= rsp->data[4] << 8;
4602
states_get_done_handler(sensor, 0, info);
4606
states_get_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4608
states_get_info_t *info = cb_data;
4609
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4613
if (sensor_done_check_rsp(sensor, err, NULL, 0, "states_get_start",
4614
states_get_done_handler, info))
4617
cmd_msg.data = cmd_data;
4618
cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4619
cmd_msg.cmd = IPMI_GET_SENSOR_READING_CMD;
4620
cmd_msg.data_len = 1;
4621
cmd_msg.data = cmd_data;
4622
cmd_data[0] = sensor->num;
4623
rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4624
&cmd_msg, states_get,
4625
&(info->sdata), info);
4627
ipmi_log(IPMI_LOG_ERR_INFO,
4628
"%sstates.c(states_get_start):"
4629
" Error sending states get command: %x",
4630
SENSOR_NAME(sensor), rv);
4631
states_get_done_handler(sensor, 0, info);
4636
stand_ipmi_sensor_get_states(ipmi_sensor_t *sensor,
4637
ipmi_sensor_states_cb done,
4640
states_get_info_t *info;
4643
if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
4644
/* A threshold sensor, it doesn't have states. */
4647
info = ipmi_mem_alloc(sizeof(*info));
4651
info->cb_data = cb_data;
4652
ipmi_init_states(&info->states);
4653
rv = ipmi_sensor_add_opq(sensor, states_get_start, &(info->sdata), info);
4655
ipmi_mem_free(info);
4659
/***********************************************************************
4661
* Various data conversion stuff.
4663
**********************************************************************/
4665
static double c_linear(double val)
4670
static double c_log2(double val)
4672
return log(val) / 0.69314718 /* log(2) */;
4675
static double c_exp10(double val)
4677
return pow(10.0, val);
4680
static double c_exp2(double val)
4682
return pow(2.0, val);
4685
static double c_1_over_x(double val)
4690
static double c_sqr(double val)
4692
return pow(val, 2.0);
4695
static double c_cube(double val)
4697
return pow(val, 3.0);
4700
static double c_1_over_cube(double val)
4702
return 1.0 / pow(val, 3.0);
4705
typedef double (*linearizer)(double val);
4706
static linearizer linearize[12] =
4723
sign_extend(int m, int bits)
4725
if (m & (1 << (bits-1)))
4726
return m | (-1 << bits);
4728
return m & (~(-1 << bits));
4732
stand_ipmi_sensor_convert_from_raw(ipmi_sensor_t *sensor,
4736
double m, b, b_exp, r_exp, fval;
4739
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4740
/* Not a threshold sensor, it doesn't have readings. */
4743
if (sensor->linearization == IPMI_LINEARIZATION_NONLINEAR)
4745
else if (sensor->linearization <= 11)
4746
c_func = linearize[sensor->linearization];
4752
m = sensor->conv[val].m;
4753
b = sensor->conv[val].b;
4754
r_exp = sensor->conv[val].r_exp;
4755
b_exp = sensor->conv[val].b_exp;
4757
switch(sensor->analog_data_format) {
4758
case IPMI_ANALOG_DATA_FORMAT_UNSIGNED:
4761
case IPMI_ANALOG_DATA_FORMAT_1_COMPL:
4762
val = sign_extend(val, 8);
4767
case IPMI_ANALOG_DATA_FORMAT_2_COMPL:
4768
fval = sign_extend(val, 8);
4774
*result = c_func(((m * fval) + (b * pow(10, b_exp))) * pow(10, r_exp));
4779
stand_ipmi_sensor_convert_to_raw(ipmi_sensor_t *sensor,
4780
enum ipmi_round_e rounding,
4785
int lowraw, highraw, raw, maxraw, minraw, next_raw;
4788
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4789
/* Not a threshold sensor, it doesn't have readings. */
4792
switch(sensor->analog_data_format) {
4793
case IPMI_ANALOG_DATA_FORMAT_UNSIGNED:
4800
case IPMI_ANALOG_DATA_FORMAT_1_COMPL:
4807
case IPMI_ANALOG_DATA_FORMAT_2_COMPL:
4818
/* We do a binary search for the right value. Yuck, but I don't
4819
have a better plan that will work with non-linear sensors. */
4822
rv = ipmi_sensor_convert_from_raw(sensor, raw, &cval);
4827
next_raw = ((highraw - raw) / 2) + raw;
4830
next_raw = ((raw - lowraw) / 2) + lowraw;
4833
} while (raw != next_raw);
4835
/* The above loop gets us to within 1 of what it should be, we
4836
have to look at rounding to make the final decision. */
4843
rv = ipmi_sensor_convert_from_raw(sensor, raw+1, &nval);
4846
nval = cval + ((nval - cval) / 2.0);
4853
rv = ipmi_sensor_convert_from_raw(sensor, raw-1, &pval);
4856
pval = pval + ((cval - pval) / 2.0);
4863
if ((val > cval) && (raw < maxraw)) {
4868
if ((val < cval) && (raw > minraw)) {
4874
if (sensor->analog_data_format == IPMI_ANALOG_DATA_FORMAT_1_COMPL) {
4879
*result = raw & 0xff;
4884
stand_ipmi_sensor_get_tolerance(ipmi_sensor_t *sensor,
4888
double m, r_exp, fval;
4891
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4892
/* Not a threshold sensor, it doesn't have readings. */
4895
if (sensor->linearization == IPMI_LINEARIZATION_NONLINEAR)
4897
else if (sensor->linearization <= 11)
4898
c_func = linearize[sensor->linearization];
4904
m = sensor->conv[val].m;
4905
r_exp = sensor->conv[val].r_exp;
4907
fval = sign_extend(val, 8);
4909
*tolerance = c_func(((m * fval) / 2.0) * pow(10, r_exp));
4913
/* Returns accuracy as a percentage value. */
4915
stand_ipmi_sensor_get_accuracy(ipmi_sensor_t *sensor, int val, double *accuracy)
4919
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4920
/* Not a threshold sensor, it doesn't have readings. */
4925
a = sensor->conv[val].accuracy;
4926
a_exp = sensor->conv[val].r_exp;
4928
*accuracy = (a * pow(10, a_exp)) / 100.0;
4933
stand_ipmi_sensor_reading_name_string(ipmi_sensor_t *sensor, int offset)
4935
return ipmi_get_reading_name(sensor->event_reading_type,
4936
sensor->sensor_type,
4940
/***********************************************************************
4942
* The standard callback structure
4944
**********************************************************************/
4946
const ipmi_sensor_cbs_t ipmi_standard_sensor_cb =
4948
.ipmi_sensor_set_event_enables = stand_ipmi_sensor_set_event_enables,
4949
.ipmi_sensor_get_event_enables = stand_ipmi_sensor_get_event_enables,
4950
.ipmi_sensor_enable_events = stand_ipmi_sensor_enable_events,
4951
.ipmi_sensor_disable_events = stand_ipmi_sensor_disable_events,
4952
.ipmi_sensor_rearm = stand_ipmi_sensor_rearm,
4954
.ipmi_sensor_convert_from_raw = stand_ipmi_sensor_convert_from_raw,
4955
.ipmi_sensor_convert_to_raw = stand_ipmi_sensor_convert_to_raw,
4956
.ipmi_sensor_get_accuracy = stand_ipmi_sensor_get_accuracy,
4957
.ipmi_sensor_get_tolerance = stand_ipmi_sensor_get_tolerance,
4958
.ipmi_sensor_get_hysteresis = stand_ipmi_sensor_get_hysteresis,
4959
.ipmi_sensor_set_hysteresis = stand_ipmi_sensor_set_hysteresis,
4960
.ipmi_sensor_set_thresholds = stand_ipmi_sensor_set_thresholds,
4961
.ipmi_sensor_get_thresholds = stand_ipmi_sensor_get_thresholds,
4962
.ipmi_sensor_get_reading = stand_ipmi_sensor_get_reading,
4964
.ipmi_sensor_get_states = stand_ipmi_sensor_get_states,
4965
.ipmi_sensor_reading_name_string = stand_ipmi_sensor_reading_name_string,
4969
ipmi_sensor_get_callbacks(ipmi_sensor_t *sensor, ipmi_sensor_cbs_t *cbs)
4975
ipmi_sensor_set_callbacks(ipmi_sensor_t *sensor, ipmi_sensor_cbs_t *cbs)
4980
/***********************************************************************
4982
* Polymorphic calls to the callback handlers.
4984
**********************************************************************/
4987
ipmi_sensor_set_event_enables(ipmi_sensor_t *sensor,
4988
ipmi_event_state_t *states,
4989
ipmi_sensor_done_cb done,
4992
if (sensor->destroyed)
4995
CHECK_SENSOR_LOCK(sensor);
4997
if (!sensor->cbs.ipmi_sensor_set_event_enables)
4999
return sensor->cbs.ipmi_sensor_set_event_enables(sensor,
5006
ipmi_sensor_enable_events(ipmi_sensor_t *sensor,
5007
ipmi_event_state_t *states,
5008
ipmi_sensor_done_cb done,
5011
if (sensor->destroyed)
5014
CHECK_SENSOR_LOCK(sensor);
5016
if (!sensor->cbs.ipmi_sensor_enable_events)
5018
return sensor->cbs.ipmi_sensor_enable_events(sensor,
5025
ipmi_sensor_disable_events(ipmi_sensor_t *sensor,
5026
ipmi_event_state_t *states,
5027
ipmi_sensor_done_cb done,
5030
if (sensor->destroyed)
5033
CHECK_SENSOR_LOCK(sensor);
5035
if (!sensor->cbs.ipmi_sensor_disable_events)
5037
return sensor->cbs.ipmi_sensor_disable_events(sensor,
5044
ipmi_sensor_rearm(ipmi_sensor_t *sensor,
5046
ipmi_event_state_t *state,
5047
ipmi_sensor_done_cb done,
5050
if (sensor->destroyed)
5053
CHECK_SENSOR_LOCK(sensor);
5055
if (!sensor->cbs.ipmi_sensor_rearm)
5057
return sensor->cbs.ipmi_sensor_rearm(sensor,
5065
ipmi_sensor_get_event_enables(ipmi_sensor_t *sensor,
5066
ipmi_sensor_event_enables_cb done,
5069
if (sensor->destroyed)
5072
CHECK_SENSOR_LOCK(sensor);
5074
if (!sensor->cbs.ipmi_sensor_get_event_enables)
5076
return sensor->cbs.ipmi_sensor_get_event_enables(sensor,
5082
ipmi_sensor_get_hysteresis(ipmi_sensor_t *sensor,
5083
ipmi_sensor_hysteresis_cb done,
5086
if (sensor->destroyed)
5089
CHECK_SENSOR_LOCK(sensor);
5091
if (!sensor->cbs.ipmi_sensor_get_hysteresis)
5093
return sensor->cbs.ipmi_sensor_get_hysteresis(sensor,
5099
ipmi_sensor_set_hysteresis(ipmi_sensor_t *sensor,
5100
unsigned int positive_hysteresis,
5101
unsigned int negative_hysteresis,
5102
ipmi_sensor_done_cb done,
5105
if (sensor->destroyed)
5108
CHECK_SENSOR_LOCK(sensor);
5110
if (!sensor->cbs.ipmi_sensor_set_hysteresis)
5112
return sensor->cbs.ipmi_sensor_set_hysteresis(sensor,
5113
positive_hysteresis,
5114
negative_hysteresis,
5120
ipmi_sensor_get_thresholds(ipmi_sensor_t *sensor,
5121
ipmi_sensor_thresholds_cb done,
5124
if (sensor->destroyed)
5127
CHECK_SENSOR_LOCK(sensor);
5129
if (!sensor->cbs.ipmi_sensor_get_thresholds)
5131
return sensor->cbs.ipmi_sensor_get_thresholds(sensor, done, cb_data);
5135
ipmi_sensor_set_thresholds(ipmi_sensor_t *sensor,
5136
ipmi_thresholds_t *thresholds,
5137
ipmi_sensor_done_cb done,
5140
if (sensor->destroyed)
5143
CHECK_SENSOR_LOCK(sensor);
5145
if (!sensor->cbs.ipmi_sensor_set_thresholds)
5147
return sensor->cbs.ipmi_sensor_set_thresholds(sensor, thresholds,
5152
ipmi_sensor_get_reading(ipmi_sensor_t *sensor,
5153
ipmi_sensor_reading_cb done,
5156
if (sensor->destroyed)
5159
CHECK_SENSOR_LOCK(sensor);
5161
if (!sensor->cbs.ipmi_sensor_get_reading)
5163
return sensor->cbs.ipmi_sensor_get_reading(sensor, done, cb_data);
5167
ipmi_sensor_get_states(ipmi_sensor_t *sensor,
5168
ipmi_sensor_states_cb done,
5171
if (sensor->destroyed)
5174
CHECK_SENSOR_LOCK(sensor);
5176
if (!sensor->cbs.ipmi_sensor_get_states)
5178
return sensor->cbs.ipmi_sensor_get_states(sensor, done, cb_data);
5182
ipmi_sensor_reading_name_string(ipmi_sensor_t *sensor, int offset)
5184
CHECK_SENSOR_LOCK(sensor);
5186
if (!sensor->cbs.ipmi_sensor_reading_name_string)
5188
return sensor->cbs.ipmi_sensor_reading_name_string(sensor, offset);
5192
ipmi_sensor_convert_from_raw(ipmi_sensor_t *sensor,
5196
CHECK_SENSOR_LOCK(sensor);
5198
if (!sensor->cbs.ipmi_sensor_convert_from_raw)
5200
return sensor->cbs.ipmi_sensor_convert_from_raw(sensor, val, result);
5204
ipmi_sensor_convert_to_raw(ipmi_sensor_t *sensor,
5205
enum ipmi_round_e rounding,
5209
CHECK_SENSOR_LOCK(sensor);
5211
if (!sensor->cbs.ipmi_sensor_convert_to_raw)
5213
return sensor->cbs.ipmi_sensor_convert_to_raw(sensor,
5220
ipmi_sensor_get_tolerance(ipmi_sensor_t *sensor, int val, double *tolerance)
5222
CHECK_SENSOR_LOCK(sensor);
5224
if (!sensor->cbs.ipmi_sensor_get_tolerance)
5226
return sensor->cbs.ipmi_sensor_get_tolerance(sensor, val, tolerance);
5229
/* Returns accuracy as a percentage value. */
5231
ipmi_sensor_get_accuracy(ipmi_sensor_t *sensor, int val, double *accuracy)
5233
CHECK_SENSOR_LOCK(sensor);
5235
if (!sensor->cbs.ipmi_sensor_get_accuracy)
5237
return sensor->cbs.ipmi_sensor_get_accuracy(sensor, val, accuracy);
5241
/***********************************************************************
5243
* Convenience functions that take ids.
5245
**********************************************************************/
5247
typedef struct sensor_id_events_enable_set_s
5249
ipmi_event_state_t *states;
5250
ipmi_sensor_done_cb done;
5253
} sensor_id_events_enable_set_t;
5256
sensor_id_set_event_enables_cb(ipmi_sensor_t *sensor, void *cb_data)
5258
sensor_id_events_enable_set_t *info = cb_data;
5260
info->rv = ipmi_sensor_set_event_enables(sensor, info->states,
5261
info->done, info->cb_data);
5265
ipmi_sensor_id_set_event_enables(ipmi_sensor_id_t sensor_id,
5266
ipmi_event_state_t *states,
5267
ipmi_sensor_done_cb done,
5270
sensor_id_events_enable_set_t info;
5273
info.states = states;
5275
info.cb_data = cb_data;
5276
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_set_event_enables_cb,
5283
typedef struct sensor_id_events_enable_s
5285
ipmi_event_state_t *states;
5286
ipmi_sensor_done_cb done;
5289
} sensor_id_events_enable_t;
5292
sensor_id_enable_events_cb(ipmi_sensor_t *sensor, void *cb_data)
5294
sensor_id_events_enable_t *info = cb_data;
5296
info->rv = ipmi_sensor_enable_events(sensor,
5303
ipmi_sensor_id_enable_events(ipmi_sensor_id_t sensor_id,
5304
ipmi_event_state_t *states,
5305
ipmi_sensor_done_cb done,
5308
sensor_id_events_enable_t info;
5311
info.states = states;
5313
info.cb_data = cb_data;
5314
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_enable_events_cb, &info);
5320
typedef struct sensor_id_events_disable_s
5322
ipmi_event_state_t *states;
5323
ipmi_sensor_done_cb done;
5326
} sensor_id_events_disable_t;
5329
sensor_id_disable_events_cb(ipmi_sensor_t *sensor, void *cb_data)
5331
sensor_id_events_disable_t *info = cb_data;
5333
info->rv = ipmi_sensor_disable_events(sensor,
5340
ipmi_sensor_id_disable_events(ipmi_sensor_id_t sensor_id,
5341
ipmi_event_state_t *states,
5342
ipmi_sensor_done_cb done,
5345
sensor_id_events_enable_t info;
5348
info.states = states;
5350
info.cb_data = cb_data;
5351
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_disable_events_cb, &info);
5357
typedef struct sensor_id_events_enable_get_s
5359
ipmi_sensor_event_enables_cb done;
5362
} sensor_id_events_enable_get_t;
5365
sensor_id_get_event_enables_cb(ipmi_sensor_t *sensor, void *cb_data)
5367
sensor_id_events_enable_get_t *info = cb_data;
5369
info->rv = ipmi_sensor_get_event_enables(sensor,
5375
ipmi_sensor_id_get_event_enables(ipmi_sensor_id_t sensor_id,
5376
ipmi_sensor_event_enables_cb done,
5379
sensor_id_events_enable_get_t info;
5383
info.cb_data = cb_data;
5384
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_get_event_enables_cb,
5391
typedef struct sensor_id_rearm_s
5394
ipmi_event_state_t *state;
5395
ipmi_sensor_done_cb done;
5398
} sensor_id_rearm_t;
5401
sensor_id_rearm_cb(ipmi_sensor_t *sensor, void *cb_data)
5403
sensor_id_rearm_t *info = cb_data;
5405
info->rv = ipmi_sensor_rearm(sensor,
5406
info->global_enable,
5413
ipmi_sensor_id_rearm(ipmi_sensor_id_t sensor_id,
5415
ipmi_event_state_t *state,
5416
ipmi_sensor_done_cb done,
5419
sensor_id_rearm_t info;
5422
info.global_enable = global_enable;
5425
info.cb_data = cb_data;
5426
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_rearm_cb, &info);
5432
typedef struct sensor_id_get_hysteresis_s
5434
ipmi_sensor_hysteresis_cb done;
5437
} sensor_id_get_hysteresis_t;
5440
sensor_id_get_hysteresis_cb(ipmi_sensor_t *sensor, void *cb_data)
5442
sensor_id_get_hysteresis_t *info = cb_data;
5444
info->rv = ipmi_sensor_get_hysteresis(sensor,
5450
ipmi_sensor_id_get_hysteresis(ipmi_sensor_id_t sensor_id,
5451
ipmi_sensor_hysteresis_cb done,
5454
sensor_id_get_hysteresis_t info;
5458
info.cb_data = cb_data;
5459
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_get_hysteresis_cb, &info);
5465
typedef struct sensor_id_set_hysteresis_s
5467
unsigned int positive_hysteresis;
5468
unsigned int negative_hysteresis;
5469
ipmi_sensor_done_cb done;
5472
} sensor_id_set_hysteresis_t;
5475
sensor_id_set_hysteresis_cb(ipmi_sensor_t *sensor, void *cb_data)
5477
sensor_id_set_hysteresis_t *info = cb_data;
5479
info->rv = ipmi_sensor_set_hysteresis(sensor,
5480
info->positive_hysteresis,
5481
info->negative_hysteresis,
5487
ipmi_sensor_id_set_hysteresis(ipmi_sensor_id_t sensor_id,
5488
unsigned int positive_hysteresis,
5489
unsigned int negative_hysteresis,
5490
ipmi_sensor_done_cb done,
5493
sensor_id_set_hysteresis_t info;
5496
info.positive_hysteresis = positive_hysteresis;
5497
info.negative_hysteresis = negative_hysteresis;
5499
info.cb_data = cb_data;
5500
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_set_hysteresis_cb, &info);
5506
typedef struct sensor_id_thresholds_set_s
5508
ipmi_thresholds_t *thresholds;
5509
ipmi_sensor_done_cb done;
5512
} sensor_id_thresholds_set_t;
5515
sensor_id_set_thresholds_cb(ipmi_sensor_t *sensor, void *cb_data)
5517
sensor_id_thresholds_set_t *info = cb_data;
5519
info->rv = ipmi_sensor_set_thresholds(sensor,
5526
ipmi_sensor_id_set_thresholds(ipmi_sensor_id_t sensor_id,
5527
ipmi_thresholds_t *thresholds,
5528
ipmi_sensor_done_cb done,
5531
sensor_id_thresholds_set_t info;
5534
info.thresholds = thresholds;
5536
info.cb_data = cb_data;
5537
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_set_thresholds_cb, &info);
5543
typedef struct sensor_id_thresholds_get_s
5545
ipmi_sensor_thresholds_cb done;
5548
} sensor_id_thresholds_get_t;
5551
sensor_id_get_thresholds_cb(ipmi_sensor_t *sensor, void *cb_data)
5553
sensor_id_thresholds_get_t *info = cb_data;
5555
info->rv = ipmi_sensor_get_thresholds(sensor,
5561
ipmi_sensor_id_get_thresholds(ipmi_sensor_id_t sensor_id,
5562
ipmi_sensor_thresholds_cb done,
5565
sensor_id_thresholds_get_t info;
5569
info.cb_data = cb_data;
5570
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_get_thresholds_cb, &info);
5576
typedef struct sensor_id_reading_get_s
5578
ipmi_sensor_reading_cb done;
5581
} sensor_id_reading_get_t;
5584
sensor_id_get_reading_cb(ipmi_sensor_t *sensor, void *cb_data)
5586
sensor_id_reading_get_t *info = cb_data;
5588
info->rv = ipmi_sensor_get_reading(sensor,
5594
ipmi_sensor_id_get_reading(ipmi_sensor_id_t sensor_id,
5595
ipmi_sensor_reading_cb done,
5598
sensor_id_reading_get_t info;
5602
info.cb_data = cb_data;
5603
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_get_reading_cb, &info);
5609
typedef struct sensor_id_states_get_s
5611
ipmi_sensor_states_cb done;
5614
} sensor_id_states_get_t;
5617
sensor_id_get_states_cb(ipmi_sensor_t *sensor, void *cb_data)
5619
sensor_id_states_get_t *info = cb_data;
5621
info->rv = ipmi_sensor_get_states(sensor,
5627
ipmi_sensor_id_get_states(ipmi_sensor_id_t sensor_id,
5628
ipmi_sensor_states_cb done,
5631
sensor_id_states_get_t info;
5635
info.cb_data = cb_data;
5636
rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_get_states_cb, &info);
5643
#ifdef IPMI_CHECK_LOCKS
5645
__ipmi_check_sensor_lock(ipmi_sensor_t *sensor)
5653
CHECK_ENTITY_LOCK(sensor->entity);
5654
CHECK_MC_LOCK(sensor->mc);
5656
if (sensor->usecount == 0)
5657
ipmi_report_lock_error(ipmi_domain_get_os_hnd(sensor->domain),
5658
"sensor not locked when it should have been");
5662
/***********************************************************************
5666
**********************************************************************/
5669
ipmi_sensor_threshold_assertion_event_supported(
5670
ipmi_sensor_t *sensor,
5671
enum ipmi_thresh_e event,
5672
enum ipmi_event_value_dir_e dir,
5677
CHECK_SENSOR_LOCK(sensor);
5679
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
5680
/* Not a threshold sensor, it doesn't have readings. */
5683
idx = (event * 2) + dir;
5687
*val = sensor->mask1[idx];
5692
ipmi_sensor_threshold_deassertion_event_supported(
5693
ipmi_sensor_t *sensor,
5694
enum ipmi_thresh_e event,
5695
enum ipmi_event_value_dir_e dir,
5700
CHECK_SENSOR_LOCK(sensor);
5702
if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
5703
/* Not a threshold sensor, it doesn't have readings. */
5706
idx = (event * 2) + dir;
5710
*val = sensor->mask2[idx];
5715
ipmi_sensor_discrete_assertion_event_supported(ipmi_sensor_t *sensor,
5719
CHECK_SENSOR_LOCK(sensor);
5721
if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
5722
/* A threshold sensor, it doesn't have events. */
5728
*val = sensor->mask1[event];
5733
ipmi_sensor_discrete_deassertion_event_supported(ipmi_sensor_t *sensor,
5737
CHECK_SENSOR_LOCK(sensor);
5739
if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
5740
/* A threshold sensor, it doesn't have events. */
5746
*val = sensor->mask2[event];
5751
ipmi_sensor_events_enable_get(ipmi_sensor_t *sensor,
5752
ipmi_sensor_event_enables_cb done,
5755
return ipmi_sensor_get_event_enables(sensor, done, cb_data);
5759
ipmi_sensor_events_disable(ipmi_sensor_t *sensor,
5760
ipmi_event_state_t *states,
5761
ipmi_sensor_done_cb done,
5764
return ipmi_sensor_disable_events(sensor, states, done, cb_data);
5768
ipmi_sensor_events_enable(ipmi_sensor_t *sensor,
5769
ipmi_event_state_t *states,
5770
ipmi_sensor_done_cb done,
5773
return ipmi_sensor_enable_events(sensor, states, done, cb_data);
5776
int ipmi_sensor_events_enable_set(ipmi_sensor_t *sensor,
5777
ipmi_event_state_t *states,
5778
ipmi_sensor_done_cb done,
5781
return ipmi_sensor_set_event_enables(sensor, states, done, cb_data);
5785
ipmi_sensor_id_events_enable_set(ipmi_sensor_id_t sensor_id,
5786
ipmi_event_state_t *states,
5787
ipmi_sensor_done_cb done,
5790
return ipmi_sensor_id_set_event_enables(sensor_id, states, done, cb_data);
5794
ipmi_sensor_id_events_enable(ipmi_sensor_id_t sensor_id,
5795
ipmi_event_state_t *states,
5796
ipmi_sensor_done_cb done,
5799
return ipmi_sensor_id_enable_events(sensor_id, states, done, cb_data);
5803
ipmi_sensor_id_events_disable(ipmi_sensor_id_t sensor_id,
5804
ipmi_event_state_t *states,
5805
ipmi_sensor_done_cb done,
5808
return ipmi_sensor_id_disable_events(sensor_id, states, done, cb_data);
5812
ipmi_sensor_id_events_enable_get(ipmi_sensor_id_t sensor_id,
5813
ipmi_sensor_event_enables_cb done,
5816
return ipmi_sensor_id_get_event_enables(sensor_id, done, cb_data);
5820
ipmi_states_get(ipmi_sensor_t *sensor,
5821
ipmi_sensor_states_cb done,
5824
return ipmi_sensor_get_states(sensor, done, cb_data);
5828
ipmi_reading_get(ipmi_sensor_t *sensor,
5829
ipmi_sensor_reading_cb done,
5832
return ipmi_sensor_get_reading(sensor, done, cb_data);
5836
ipmi_thresholds_set(ipmi_sensor_t *sensor,
5837
ipmi_thresholds_t *thresholds,
5838
ipmi_sensor_done_cb done,
5841
return ipmi_sensor_set_thresholds(sensor, thresholds, done, cb_data);
5845
ipmi_thresholds_get(ipmi_sensor_t *sensor,
5846
ipmi_sensor_thresholds_cb done,
5849
return ipmi_sensor_get_thresholds(sensor, done, cb_data);
5853
ipmi_sensor_id_thresholds_set(ipmi_sensor_id_t sensor_id,
5854
ipmi_thresholds_t *thresholds,
5855
ipmi_sensor_done_cb done,
5858
return ipmi_sensor_id_set_thresholds(sensor_id, thresholds, done, cb_data);
5862
ipmi_sensor_id_thresholds_get(ipmi_sensor_id_t sensor_id,
5863
ipmi_sensor_thresholds_cb done,
5866
return ipmi_sensor_id_get_thresholds(sensor_id, done, cb_data);
5870
ipmi_sensor_id_reading_get(ipmi_sensor_id_t sensor_id,
5871
ipmi_sensor_reading_cb done,
5874
return ipmi_sensor_id_get_reading(sensor_id, done, cb_data);
5878
ipmi_sensor_id_states_get(ipmi_sensor_id_t sensor_id,
5879
ipmi_sensor_states_cb done,
5882
return ipmi_sensor_id_get_states(sensor_id, done, cb_data);
5886
ipmi_discrete_event_readable(ipmi_sensor_t *sensor,
5890
CHECK_SENSOR_LOCK(sensor);
5892
if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
5893
/* A threshold sensor, it doesn't have events. */
5899
*val = sensor->mask3[event];