1 /*
2 * sensor.c
3 *
4 * MontaVista IPMI code for handling sensors
5 *
6 * Author: MontaVista Software, Inc.
7 * Corey Minyard <minyard@mvista.com>
8 * source@mvista.com
9 *
10 * Copyright 2002,2003 MontaVista Software Inc.
11 *
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.
16 *
17 *
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.
28 *
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.
32 */
33
34 #include <string.h>
35 #include <stdio.h>
36 #include <math.h>
37
38 #include <OpenIPMI/ipmiif.h>
39 #include <OpenIPMI/ipmi_sdr.h>
40 #include <OpenIPMI/ipmi_msgbits.h>
41 #include <OpenIPMI/ipmi_err.h>
42
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>
51
52 struct ipmi_sensor_info_s
53 {
54 int destroyed;
55
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. */
60 unsigned int idx_size[5];
61 /* In the above two, the 5th index is for non-standard sensors. */
62
63 ipmi_lock_t *idx_lock;
64
65 /* Total number of sensors we have in this. */
66 unsigned int sensor_count;
67 };
68
69 #define SENSOR_ID_LEN 32 /* 16 bytes are allowed for a sensor. */
70 struct ipmi_sensor_s
71 {
72 unsigned int usecount;
73
74 ipmi_domain_t *domain; /* Domain I am in. */
75
76 ipmi_mc_t *mc; /* My owner, NOT the SMI mc (unless that
77 happens to be my direct owner). */
78
79 ipmi_mc_t *source_mc; /* If the sensor came from the main SDR,
80 this will be NULL. Otherwise, it
81 will be the MC that owned the device
82 SDR this came from. */
83 int source_idx; /* The index into the source array where
84 this is stored. This will be -1 if
85 it does not have a source index (ie
86 it's a non-standard sensor) */
87 int source_recid; /* The SDR record ID the sensor came from. */
88 ipmi_sensor_t **source_array; /* This is the source array where
89 the sensor is stored. */
90
91 int destroyed;
92
93 /* After the sensor is added, it will not be reported immediately.
94 Instead, it will wait until the usecount goes to zero before
95 being reported. This marks that the add report is pending */
96 int add_pending;
97
98 unsigned char owner;
99 unsigned char channel;
100 unsigned char lun;
101 unsigned char num;
102
103 /* For OEM sensors, the sending LUN might be different that the
104 LUN we use for storage. */
105 unsigned char send_lun;
106
107 ipmi_entity_t *entity;
108
109 unsigned char entity_id;
110 unsigned char entity_instance;
111
112 /* Can the sensor be read? Event-only sensors cannot be read. */
113 unsigned int readable : 1;
114
115 unsigned int 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;
128
129 unsigned int sensor_direction : 2;
130
131 unsigned int ignore_for_presence : 1;
132
133 int hot_swap_requester;
134 int hot_swap_requester_val;
135
136 unsigned char sensor_type;
137
138 unsigned char event_reading_type;
139
140 #define IPMI_SENSOR_GET_MASK_BIT(mask, bit) (((mask) >> (bit)) & 1)
141 #define IPMI_SENSOR_SET_MASK_BIT(mask, bit, v) \
142 (mask) = v ? (mask) | (1 << (bit)) : (mask) & ~(1 << (bit))
143 uint16_t mask1;
144 uint16_t mask2;
145 uint16_t mask3;
146
147 unsigned int analog_data_format : 2;
148
149 unsigned int rate_unit : 3;
150
151 unsigned int modifier_unit_use : 2;
152
153 unsigned int percentage : 1;
154
155 unsigned char base_unit;
156 unsigned char modifier_unit;
157
158 unsigned char linearization;
159
160 struct {
161 int m : 10;
162 unsigned int tolerance : 6;
163 int b : 10;
164 int r_exp : 4;
165 unsigned int accuracy_exp : 2;
166 int accuracy : 10;
167 int b_exp : 4;
168 } conv[256];
169
170 unsigned int normal_min_specified : 1;
171 unsigned int normal_max_specified : 1;
172 unsigned int nominal_reading_specified : 1;
173
174 unsigned char nominal_reading;
175 unsigned char normal_max;
176 unsigned char normal_min;
177 unsigned char sensor_max;
178 unsigned char sensor_min;
179 unsigned char default_thresholds[6];
180 unsigned char positive_going_threshold_hysteresis;
181 unsigned char negative_going_threshold_hysteresis;
182
183
184 unsigned char oem1;
185
186 /* Note that the ID is *not* nil terminated. */
187 enum ipmi_str_type_e id_type;
188 unsigned int id_len;
189 char id[SENSOR_ID_LEN]; /* The ID from the device SDR. */
190
191 const char *sensor_type_string;
192 const char *event_reading_type_string;
193 const char *rate_unit_string;
194 const char *base_unit_string;
195 const char *modifier_unit_string;
196
197 /* A list of handlers to call when an event for the sensor comes
198 in. */
199 locked_list_t *handler_list, *handler_list_cl;
200
201 opq_t *waitq;
202 ipmi_event_state_t event_state;
203
204 /* Polymorphic functions. */
205 ipmi_sensor_cbs_t cbs;
206
207 /* OEM info */
208 void *oem_info;
209 ipmi_sensor_cleanup_oem_info_cb oem_info_cleanup_handler;
210
211 ipmi_sensor_destroy_cb destroy_handler;
212 void *destroy_handler_cb_data;
213
214 /* Name we use for reporting. We add a ' ' onto the end, thus
215 the +1. */
216 char name[IPMI_SENSOR_NAME_LEN+1];
217
218 /* Used for temporary linking. */
219 ipmi_sensor_t *tlink;
220
221 /* Cruft. */
222 ipmi_sensor_threshold_event_handler_nd_cb threshold_event_handler;
223 ipmi_sensor_discrete_event_handler_nd_cb discrete_event_handler;
224 void *cb_data;
225 };
226
227 static void sensor_final_destroy(ipmi_sensor_t *sensor);
228
229 /***********************************************************************
230 *
231 * Sensor ID handling.
232 *
233 **********************************************************************/
234
235 /* Must be called with the domain entity lock held. */
236 int
i_ipmi_sensor_get(ipmi_sensor_t * sensor)237 i_ipmi_sensor_get(ipmi_sensor_t *sensor)
238 {
239 if (sensor->destroyed)
240 return EINVAL;
241 sensor->usecount++;
242 return 0;
243 }
244
245 void
i_ipmi_sensor_put(ipmi_sensor_t * sensor)246 i_ipmi_sensor_put(ipmi_sensor_t *sensor)
247 {
248 ipmi_domain_t *domain = sensor->domain;
249 i_ipmi_domain_entity_lock(domain);
250 if (sensor->usecount == 1) {
251 if (sensor->add_pending) {
252 sensor->add_pending = 0;
253 i_ipmi_domain_entity_unlock(sensor->domain);
254 i_ipmi_entity_call_sensor_handlers(sensor->entity,
255 sensor, IPMI_ADDED);
256 i_ipmi_domain_entity_lock(sensor->domain);
257 }
258 if (sensor->destroyed
259 && (!sensor->waitq
260 || (!opq_stuff_in_progress(sensor->waitq))))
261 {
262 i_ipmi_domain_entity_unlock(domain);
263 sensor_final_destroy(sensor);
264 return;
265 }
266 }
267 sensor->usecount--;
268 i_ipmi_domain_entity_unlock(domain);
269 }
270
271 ipmi_sensor_id_t
ipmi_sensor_convert_to_id(ipmi_sensor_t * sensor)272 ipmi_sensor_convert_to_id(ipmi_sensor_t *sensor)
273 {
274 ipmi_sensor_id_t val;
275
276 CHECK_SENSOR_LOCK(sensor);
277
278 val.mcid = ipmi_mc_convert_to_id(sensor->mc);
279 val.lun = sensor->lun;
280 val.sensor_num = sensor->num;
281
282 return val;
283 }
284
285 int
ipmi_cmp_sensor_id(ipmi_sensor_id_t id1,ipmi_sensor_id_t id2)286 ipmi_cmp_sensor_id(ipmi_sensor_id_t id1, ipmi_sensor_id_t id2)
287 {
288 int rv;
289
290 rv = ipmi_cmp_mc_id(id1.mcid, id2.mcid);
291 if (rv)
292 return rv;
293 if (id1.lun > id2.lun)
294 return 1;
295 if (id1.lun < id2.lun)
296 return -1;
297 if (id1.sensor_num > id2.sensor_num)
298 return 1;
299 if (id1.sensor_num < id2.sensor_num)
300 return -1;
301 return 0;
302 }
303
304 void
ipmi_sensor_id_set_invalid(ipmi_sensor_id_t * id)305 ipmi_sensor_id_set_invalid(ipmi_sensor_id_t *id)
306 {
307 memset(id, 0, sizeof(*id));
308 }
309
310 int
ipmi_sensor_id_is_invalid(const ipmi_sensor_id_t * id)311 ipmi_sensor_id_is_invalid(const ipmi_sensor_id_t *id)
312 {
313 return (id->mcid.domain_id.domain == NULL);
314 }
315
316 typedef struct mc_cb_info_s
317 {
318 ipmi_sensor_ptr_cb handler;
319 void *cb_data;
320 ipmi_sensor_id_t id;
321 int err;
322 } mc_cb_info_t;
323
324 static void
mc_cb(ipmi_mc_t * mc,void * cb_data)325 mc_cb(ipmi_mc_t *mc, void *cb_data)
326 {
327 mc_cb_info_t *info = cb_data;
328 ipmi_sensor_info_t *sensors;
329 ipmi_domain_t *domain = ipmi_mc_get_domain(mc);
330 ipmi_sensor_t *sensor;
331 ipmi_entity_t *entity = NULL;
332
333 sensors = i_ipmi_mc_get_sensors(mc);
334 i_ipmi_domain_entity_lock(domain);
335 if (info->id.lun > 4) {
336 info->err = EINVAL;
337 goto out_unlock;
338 }
339
340 if (info->id.sensor_num >= sensors->idx_size[info->id.lun]) {
341 info->err = EINVAL;
342 goto out_unlock;
343 }
344
345 sensor = sensors->sensors_by_idx[info->id.lun][info->id.sensor_num];
346 if (!sensor) {
347 info->err = EINVAL;
348 goto out_unlock;
349 }
350
351 info->err = i_ipmi_entity_get(sensor->entity);
352 if (info->err)
353 goto out_unlock;
354 entity = sensor->entity;
355
356 info->err = i_ipmi_sensor_get(sensor);
357 if (info->err)
358 goto out_unlock;
359
360 i_ipmi_domain_entity_unlock(domain);
361
362 info->handler(sensor, info->cb_data);
363
364 i_ipmi_sensor_put(sensor);
365 i_ipmi_entity_put(entity);
366 return;
367
368 out_unlock:
369 i_ipmi_domain_entity_unlock(domain);
370 if (entity)
371 i_ipmi_entity_put(entity);
372 }
373
374 int
ipmi_sensor_pointer_cb(ipmi_sensor_id_t id,ipmi_sensor_ptr_cb handler,void * cb_data)375 ipmi_sensor_pointer_cb(ipmi_sensor_id_t id,
376 ipmi_sensor_ptr_cb handler,
377 void *cb_data)
378 {
379 int rv;
380 mc_cb_info_t info;
381
382 if (id.lun >= 5)
383 return EINVAL;
384
385 info.handler = handler;
386 info.cb_data = cb_data;
387 info.id = id;
388 info.err = 0;
389
390 rv = ipmi_mc_pointer_cb(id.mcid, mc_cb, &info);
391 if (!rv)
392 rv = info.err;
393
394 return rv;
395 }
396
397 int
ipmi_sensor_pointer_noseq_cb(ipmi_sensor_id_t id,ipmi_sensor_ptr_cb handler,void * cb_data)398 ipmi_sensor_pointer_noseq_cb(ipmi_sensor_id_t id,
399 ipmi_sensor_ptr_cb handler,
400 void *cb_data)
401 {
402 int rv;
403 mc_cb_info_t info;
404
405 if (id.lun >= 5)
406 return EINVAL;
407
408 info.handler = handler;
409 info.cb_data = cb_data;
410 info.id = id;
411 info.err = 0;
412
413 rv = ipmi_mc_pointer_noseq_cb(id.mcid, mc_cb, &info);
414 if (!rv)
415 rv = info.err;
416
417 return rv;
418 }
419
420 typedef struct sensor_find_info_s
421 {
422 ipmi_sensor_id_t id;
423 char *id_name;
424 int rv;
425 } sensor_find_info_t;
426
427 static void
sensor_search_cmp(ipmi_entity_t * entity,ipmi_sensor_t * sensor,void * cb_data)428 sensor_search_cmp(ipmi_entity_t *entity, ipmi_sensor_t *sensor, void *cb_data)
429 {
430 sensor_find_info_t *info = cb_data;
431 char id[33];
432 int rv;
433
434 rv = ipmi_sensor_get_id(sensor, id, 33);
435 if (rv)
436 return;
437 if (strcmp(info->id_name, id) == 0) {
438 info->id = ipmi_sensor_convert_to_id(sensor);
439 info->rv = 0;
440 }
441 }
442
443 static void
sensor_search(ipmi_entity_t * entity,void * cb_data)444 sensor_search(ipmi_entity_t *entity, void *cb_data)
445 {
446 sensor_find_info_t *info = cb_data;
447
448 ipmi_entity_iterate_sensors(entity, sensor_search_cmp, info);
449 }
450
451 int
ipmi_sensor_find_id(ipmi_domain_id_t domain_id,int entity_id,int entity_instance,int channel,int slave_address,char * id_name,ipmi_sensor_id_t * id)452 ipmi_sensor_find_id(ipmi_domain_id_t domain_id,
453 int entity_id, int entity_instance,
454 int channel, int slave_address,
455 char *id_name,
456 ipmi_sensor_id_t *id)
457 {
458 int rv;
459 ipmi_entity_id_t entity;
460 sensor_find_info_t info;
461
462 rv = ipmi_entity_find_id(domain_id, entity_id, entity_instance,
463 channel, slave_address, &entity);
464 if (rv)
465 return rv;
466
467 info.id_name = id_name;
468 info.rv = EINVAL;
469
470 rv = ipmi_entity_pointer_cb(entity, sensor_search, &info);
471 if (!rv)
472 rv = info.rv;
473 if (!rv)
474 *id = info.id;
475
476 return rv;
477 }
478
479 /***********************************************************************
480 *
481 * Various sensor allocation/deallocation/opq/etc.
482 *
483 **********************************************************************/
484
485 static int
sensor_ok_to_use(ipmi_sensor_t * sensor)486 sensor_ok_to_use(ipmi_sensor_t *sensor)
487 {
488 return ( !sensor->destroyed
489 && !i_ipmi_domain_in_shutdown(sensor->domain));
490 }
491
492 static void sensor_set_name(ipmi_sensor_t *sensor);
493
494 static void
sensor_opq_ready2(ipmi_sensor_t * sensor,void * cb_data)495 sensor_opq_ready2(ipmi_sensor_t *sensor, void *cb_data)
496 {
497 ipmi_sensor_op_info_t *info = cb_data;
498 if (info->__handler)
499 info->__handler(sensor, 0, info->__cb_data);
500 }
501
502 static int
sensor_opq_ready(void * cb_data,int shutdown)503 sensor_opq_ready(void *cb_data, int shutdown)
504 {
505 ipmi_sensor_op_info_t *info = cb_data;
506 int rv;
507
508 if (shutdown) {
509 if (info->__handler)
510 info->__handler(info->__sensor, ECANCELED, info->__cb_data);
511 return OPQ_HANDLER_STARTED;
512 }
513
514 rv = ipmi_sensor_pointer_cb(info->__sensor_id, sensor_opq_ready2, info);
515 if (rv)
516 if (info->__handler)
517 info->__handler(info->__sensor, rv, info->__cb_data);
518 return OPQ_HANDLER_STARTED;
519 }
520
521 int
ipmi_sensor_add_opq(ipmi_sensor_t * sensor,ipmi_sensor_op_cb handler,ipmi_sensor_op_info_t * info,void * cb_data)522 ipmi_sensor_add_opq(ipmi_sensor_t *sensor,
523 ipmi_sensor_op_cb handler,
524 ipmi_sensor_op_info_t *info,
525 void *cb_data)
526 {
527 if (sensor->destroyed)
528 return EINVAL;
529
530 info->__sensor = sensor;
531 info->__sensor_id = ipmi_sensor_convert_to_id(sensor);
532 info->__cb_data = cb_data;
533 info->__handler = handler;
534 if (!opq_new_op(sensor->waitq, sensor_opq_ready, info, 0))
535 return ENOMEM;
536 return 0;
537 }
538
539 static void
sensor_id_add_opq_cb(ipmi_sensor_t * sensor,void * cb_data)540 sensor_id_add_opq_cb(ipmi_sensor_t *sensor, void *cb_data)
541 {
542 ipmi_sensor_op_info_t *info = cb_data;
543
544 info->__sensor = sensor;
545 if (!opq_new_op(sensor->waitq, sensor_opq_ready, info, 0))
546 info->__err = ENOMEM;
547 }
548
549 int
ipmi_sensor_id_add_opq(ipmi_sensor_id_t sensor_id,ipmi_sensor_op_cb handler,ipmi_sensor_op_info_t * info,void * cb_data)550 ipmi_sensor_id_add_opq(ipmi_sensor_id_t sensor_id,
551 ipmi_sensor_op_cb handler,
552 ipmi_sensor_op_info_t *info,
553 void *cb_data)
554 {
555 int rv;
556
557 info->__sensor_id = sensor_id;
558 info->__cb_data = cb_data;
559 info->__handler = handler;
560 info->__err = 0;
561 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_add_opq_cb, info);
562 if (!rv)
563 rv = info->__err;
564 return rv;
565 }
566
567 void
ipmi_sensor_opq_done(ipmi_sensor_t * sensor)568 ipmi_sensor_opq_done(ipmi_sensor_t *sensor)
569 {
570 /* Protect myself from NULL sensors. This way, it doesn't have to
571 be done in each call. */
572 if (!sensor)
573 return;
574
575 /* This gets called on ECANCELLED error cases, if the sensor is
576 already destroyed we need to clear out the opq. */
577 if (sensor->destroyed) {
578 if (sensor->waitq) {
579 opq_destroy(sensor->waitq);
580 sensor->waitq = NULL;
581 }
582 return;
583 }
584
585 /* No check for the sensor lock. It will sometimes fail at
586 destruction time. */
587
588 opq_op_done(sensor->waitq);
589 }
590
591 static void
sensor_rsp_handler2(ipmi_sensor_t * sensor,void * cb_data)592 sensor_rsp_handler2(ipmi_sensor_t *sensor, void *cb_data)
593 {
594 ipmi_sensor_op_info_t *info = cb_data;
595
596 if (info->__rsp_handler)
597 info->__rsp_handler(sensor, 0, info->__rsp, info->__cb_data);
598 }
599
600 static void
sensor_rsp_handler(ipmi_mc_t * mc,ipmi_msg_t * rsp,void * rsp_data)601 sensor_rsp_handler(ipmi_mc_t *mc,
602 ipmi_msg_t *rsp,
603 void *rsp_data)
604 {
605 ipmi_sensor_op_info_t *info = rsp_data;
606 int rv;
607 ipmi_sensor_t *sensor = info->__sensor;
608 ipmi_entity_t *entity = NULL;
609
610 if (sensor->destroyed) {
611 i_ipmi_domain_entity_lock(sensor->domain);
612 sensor->usecount++;
613 rv = i_ipmi_entity_get(sensor->entity);
614 if (! rv)
615 entity = sensor->entity;
616 i_ipmi_domain_entity_unlock(sensor->domain);
617
618 if (info->__rsp_handler)
619 info->__rsp_handler(sensor, ECANCELED, NULL, info->__cb_data);
620
621 i_ipmi_sensor_put(sensor);
622 if (entity)
623 i_ipmi_entity_put(entity);
624 return;
625 }
626
627 if (!mc) {
628 i_ipmi_domain_entity_lock(sensor->domain);
629 sensor->usecount++;
630 rv = i_ipmi_entity_get(sensor->entity);
631 if (! rv)
632 entity = sensor->entity;
633 i_ipmi_domain_entity_unlock(sensor->domain);
634
635 if (info->__rsp_handler)
636 info->__rsp_handler(sensor, ECANCELED, rsp, info->__cb_data);
637
638 i_ipmi_sensor_put(sensor);
639 if (entity)
640 i_ipmi_entity_put(entity);
641 return;
642 }
643
644 /* Call the next stage with the lock held. */
645 info->__rsp = rsp;
646 rv = ipmi_sensor_pointer_cb(info->__sensor_id,
647 sensor_rsp_handler2,
648 info);
649 if (rv) {
650 int nrv;
651
652 ipmi_log(IPMI_LOG_ERR_INFO,
653 "%ssensor.c(sensor_rsp_handler):"
654 " Could not convert sensor id to a pointer",
655 MC_NAME(mc));
656
657 i_ipmi_domain_entity_lock(sensor->domain);
658 sensor->usecount++;
659 nrv = i_ipmi_entity_get(sensor->entity);
660 if (! nrv)
661 entity = sensor->entity;
662 i_ipmi_domain_entity_unlock(sensor->domain);
663
664 if (info->__rsp_handler)
665 info->__rsp_handler(sensor, rv, NULL, info->__cb_data);
666
667 i_ipmi_sensor_put(sensor);
668 if (entity)
669 i_ipmi_entity_put(entity);
670 }
671 }
672
673 int
ipmi_sensor_send_command(ipmi_sensor_t * sensor,ipmi_mc_t * mc,unsigned int lun,ipmi_msg_t * msg,ipmi_sensor_rsp_cb handler,ipmi_sensor_op_info_t * info,void * cb_data)674 ipmi_sensor_send_command(ipmi_sensor_t *sensor,
675 ipmi_mc_t *mc,
676 unsigned int lun,
677 ipmi_msg_t *msg,
678 ipmi_sensor_rsp_cb handler,
679 ipmi_sensor_op_info_t *info,
680 void *cb_data)
681 {
682 int rv;
683
684 CHECK_MC_LOCK(mc);
685 CHECK_SENSOR_LOCK(sensor);
686
687 if (sensor->destroyed)
688 return EINVAL;
689
690 info->__sensor = sensor;
691 info->__sensor_id = ipmi_sensor_convert_to_id(sensor);
692 info->__cb_data = cb_data;
693 info->__rsp_handler = handler;
694 rv = ipmi_mc_send_command(mc, lun, msg, sensor_rsp_handler, info);
695 return rv;
696 }
697
698 static int
sensor_addr_response_handler(ipmi_domain_t * domain,ipmi_msgi_t * rspi)699 sensor_addr_response_handler(ipmi_domain_t *domain, ipmi_msgi_t *rspi)
700 {
701 ipmi_msg_t *msg = &rspi->msg;
702 ipmi_sensor_op_info_t *info = rspi->data1;
703 int rv;
704 ipmi_sensor_t *sensor = info->__sensor;
705
706 if (sensor->destroyed) {
707 if (info->__rsp_handler) {
708 i_ipmi_domain_mc_lock(sensor->domain);
709 i_ipmi_mc_get(sensor->mc);
710 i_ipmi_domain_mc_unlock(sensor->domain);
711 i_ipmi_domain_entity_lock(sensor->domain);
712 i_ipmi_entity_get(sensor->entity);
713 sensor->usecount++;
714 i_ipmi_domain_entity_unlock(sensor->domain);
715 info->__rsp_handler(NULL, ECANCELED, NULL, info->__cb_data);
716 i_ipmi_sensor_put(sensor);
717 i_ipmi_mc_put(sensor->mc);
718 i_ipmi_entity_put(sensor->entity);
719 }
720 return IPMI_MSG_ITEM_NOT_USED;
721 }
722
723 /* Call the next stage with the lock held. */
724 info->__rsp = msg;
725 rv = ipmi_sensor_pointer_cb(info->__sensor_id,
726 sensor_rsp_handler2,
727 info);
728 if (rv) {
729 ipmi_log(IPMI_LOG_ERR_INFO,
730 "%ssensor.c(sensor_addr_rsp_handler):"
731 " Could not convert sensor id to a pointer",
732 DOMAIN_NAME(domain));
733 if (info->__rsp_handler) {
734 i_ipmi_domain_mc_lock(sensor->domain);
735 i_ipmi_mc_get(sensor->mc);
736 i_ipmi_domain_mc_unlock(sensor->domain);
737 i_ipmi_domain_entity_lock(sensor->domain);
738 i_ipmi_entity_get(sensor->entity);
739 sensor->usecount++;
740 i_ipmi_domain_entity_unlock(sensor->domain);
741 info->__rsp_handler(sensor, rv, NULL, info->__cb_data);
742 i_ipmi_sensor_put(sensor);
743 i_ipmi_mc_put(sensor->mc);
744 i_ipmi_entity_put(sensor->entity);
745 }
746 }
747 return IPMI_MSG_ITEM_NOT_USED;
748 }
749
750 int
ipmi_sensor_send_command_addr(ipmi_domain_t * domain,ipmi_sensor_t * sensor,ipmi_addr_t * addr,unsigned int addr_len,ipmi_msg_t * msg,ipmi_sensor_rsp_cb handler,ipmi_sensor_op_info_t * info,void * cb_data)751 ipmi_sensor_send_command_addr(ipmi_domain_t *domain,
752 ipmi_sensor_t *sensor,
753 ipmi_addr_t *addr,
754 unsigned int addr_len,
755 ipmi_msg_t *msg,
756 ipmi_sensor_rsp_cb handler,
757 ipmi_sensor_op_info_t *info,
758 void *cb_data)
759 {
760 int rv;
761
762 CHECK_SENSOR_LOCK(sensor);
763 CHECK_MC_LOCK(sensor->mc);
764
765 info->__sensor = sensor;
766 info->__sensor_id = ipmi_sensor_convert_to_id(sensor);
767 info->__cb_data = cb_data;
768 info->__rsp_handler = handler;
769 rv = ipmi_send_command_addr(domain, addr, addr_len,
770 msg, sensor_addr_response_handler, info, NULL);
771 return rv;
772 }
773
774 int
ipmi_sensors_alloc(ipmi_mc_t * mc,ipmi_sensor_info_t ** new_sensors)775 ipmi_sensors_alloc(ipmi_mc_t *mc, ipmi_sensor_info_t **new_sensors)
776 {
777 ipmi_sensor_info_t *sensors;
778 ipmi_domain_t *domain;
779 os_handler_t *os_hnd;
780 int i;
781 int rv;
782
783 CHECK_MC_LOCK(mc);
784
785 domain = ipmi_mc_get_domain(mc);
786 os_hnd = ipmi_domain_get_os_hnd(domain);
787
788 sensors = ipmi_mem_alloc(sizeof(*sensors));
789 if (!sensors)
790 return ENOMEM;
791
792 rv = ipmi_create_lock_os_hnd(os_hnd, &sensors->idx_lock);
793 if (rv) {
794 ipmi_mem_free(sensors);
795 return rv;
796 }
797
798 sensors->destroyed = 0;
799 sensors->sensor_count = 0;
800 for (i=0; i<5; i++) {
801 sensors->sensors_by_idx[i] = NULL;
802 sensors->idx_size[i] = 0;
803 }
804
805 *new_sensors = sensors;
806 return 0;
807 }
808
809 unsigned int
ipmi_sensors_get_count(ipmi_sensor_info_t * sensors)810 ipmi_sensors_get_count(ipmi_sensor_info_t *sensors)
811 {
812 return sensors->sensor_count;
813 }
814
815 int
ipmi_sensor_alloc_nonstandard(ipmi_sensor_t ** new_sensor)816 ipmi_sensor_alloc_nonstandard(ipmi_sensor_t **new_sensor)
817 {
818 ipmi_sensor_t *sensor;
819
820 sensor = ipmi_mem_alloc(sizeof(*sensor));
821 if (!sensor)
822 return ENOMEM;
823
824 memset(sensor, 0, sizeof(*sensor));
825
826 sensor->hot_swap_requester = -1;
827 sensor->usecount = 1;
828 sensor->readable = 1;
829
830 *new_sensor = sensor;
831 return 0;
832 }
833
834 int
ipmi_sensor_add_nonstandard(ipmi_mc_t * mc,ipmi_mc_t * source_mc,ipmi_sensor_t * sensor,unsigned int num,unsigned int send_lun,ipmi_entity_t * ent,ipmi_sensor_destroy_cb destroy_handler,void * destroy_handler_cb_data)835 ipmi_sensor_add_nonstandard(ipmi_mc_t *mc,
836 ipmi_mc_t *source_mc,
837 ipmi_sensor_t *sensor,
838 unsigned int num,
839 unsigned int send_lun,
840 ipmi_entity_t *ent,
841 ipmi_sensor_destroy_cb destroy_handler,
842 void *destroy_handler_cb_data)
843 {
844 ipmi_sensor_info_t *sensors = i_ipmi_mc_get_sensors(mc);
845 ipmi_domain_t *domain;
846 os_handler_t *os_hnd;
847 void *link;
848 int err;
849 unsigned int i;
850
851 CHECK_MC_LOCK(mc);
852 CHECK_ENTITY_LOCK(ent);
853
854 domain = ipmi_mc_get_domain(mc);
855 os_hnd = ipmi_domain_get_os_hnd(domain);
856
857 if ((num >= 256) && (num != UINT_MAX))
858 return EINVAL;
859
860 i_ipmi_domain_entity_lock(domain);
861 ipmi_lock(sensors->idx_lock);
862
863 if (num == UINT_MAX){
864 for (i=0; i<sensors->idx_size[4]; i++) {
865 if (! sensors->sensors_by_idx[4][i])
866 break;
867 }
868 num = i;
869 if (num >= 256) {
870 err = EAGAIN;
871 goto out_err;
872 }
873 }
874
875 if (num >= sensors->idx_size[4]) {
876 ipmi_sensor_t **new_array;
877 unsigned int new_size;
878 unsigned int i;
879
880 /* Allocate the array in multiples of 16 (to avoid thrashing malloc
881 too much). */
882 new_size = ((num / 16) * 16) + 16;
883 new_array = ipmi_mem_alloc(sizeof(*new_array) * new_size);
884 if (!new_array) {
885 err = ENOMEM;
886 goto out_err;
887 }
888 if (sensors->sensors_by_idx[4]) {
889 memcpy(new_array, sensors->sensors_by_idx[4],
890 sizeof(*new_array) * (sensors->idx_size[4]));
891 ipmi_mem_free(sensors->sensors_by_idx[4]);
892 }
893 for (i=sensors->idx_size[4]; i<new_size; i++)
894 new_array[i] = NULL;
895 sensors->sensors_by_idx[4] = new_array;
896 sensors->idx_size[4] = new_size;
897 }
898
899 sensor->waitq = opq_alloc(os_hnd);
900 if (! sensor->waitq) {
901 err = ENOMEM;
902 goto out_err;
903 }
904
905 sensor->handler_list = locked_list_alloc(os_hnd);
906 if (! sensor->handler_list) {
907 opq_destroy(sensor->waitq);
908 err = ENOMEM;
909 goto out_err;
910 }
911
912 sensor->handler_list_cl = locked_list_alloc(os_hnd);
913 if (! sensor->handler_list_cl) {
914 locked_list_destroy(sensor->handler_list);
915 opq_destroy(sensor->waitq);
916 err = ENOMEM;
917 goto out_err;
918 }
919
920 link = locked_list_alloc_entry();
921 if (!link) {
922 opq_destroy(sensor->waitq);
923 sensor->waitq = NULL;
924 locked_list_destroy(sensor->handler_list);
925 locked_list_destroy(sensor->handler_list_cl);
926 sensor->handler_list = NULL;
927 err = ENOMEM;
928 goto out_err;
929 }
930
931 sensor->domain = domain;
932 sensor->mc = mc;
933 sensor->source_mc = source_mc;
934 sensor->lun = 4;
935 sensor->send_lun = send_lun;
936 sensor->num = num;
937 sensor->source_idx = -1;
938 sensor->source_array = NULL;
939 if (!sensors->sensors_by_idx[4][num])
940 sensors->sensor_count++;
941 sensors->sensors_by_idx[4][num] = sensor;
942 sensor->entity = ent;
943 sensor->entity_id = ipmi_entity_get_entity_id(ent);
944 sensor->entity_instance = ipmi_entity_get_entity_instance(ent);
945 sensor->destroy_handler = destroy_handler;
946 sensor->destroy_handler_cb_data = destroy_handler_cb_data;
947 sensor_set_name(sensor);
948
949 ipmi_unlock(sensors->idx_lock);
950
951 i_ipmi_domain_entity_unlock(domain);
952
953 ipmi_entity_add_sensor(ent, sensor, link);
954
955 sensor->add_pending = 1;
956
957 return 0;
958
959 out_err:
960 ipmi_unlock(sensors->idx_lock);
961 i_ipmi_domain_entity_unlock(domain);
962 return err;
963 }
964
965 typedef struct threshold_handler_cl_info_s
966 {
967 ipmi_sensor_threshold_event_cb handler;
968 void *handler_data;
969 } threshold_handler_cl_info_t;
970
971 static int
iterate_threshold_handler_cl(void * cb_data,void * item1,void * item2)972 iterate_threshold_handler_cl(void *cb_data, void *item1, void *item2)
973 {
974 threshold_handler_cl_info_t *info = cb_data;
975 ipmi_sensor_threshold_event_cl_cb handler = item1;
976
977 handler(info->handler, info->handler_data, item2);
978 return LOCKED_LIST_ITER_CONTINUE;
979 }
980
981 typedef struct discrete_handler_cl_info_s
982 {
983 ipmi_sensor_discrete_event_cb handler;
984 void *handler_data;
985 } discrete_handler_cl_info_t;
986
987 static int
iterate_discrete_handler_cl(void * cb_data,void * item1,void * item2)988 iterate_discrete_handler_cl(void *cb_data, void *item1, void *item2)
989 {
990 discrete_handler_cl_info_t *info = cb_data;
991 ipmi_sensor_discrete_event_cl_cb handler = item1;
992
993 handler(info->handler, info->handler_data, item2);
994 return LOCKED_LIST_ITER_CONTINUE;
995 }
996
997 static int
handler_list_cleanup(void * cb_data,void * item1,void * item2)998 handler_list_cleanup(void *cb_data, void *item1, void *item2)
999 {
1000 ipmi_sensor_t *sensor = cb_data;
1001
1002 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD) {
1003 threshold_handler_cl_info_t info;
1004 info.handler = item1;
1005 info.handler_data = item2;
1006 locked_list_iterate(sensor->handler_list_cl,
1007 iterate_threshold_handler_cl,
1008 &info);
1009 } else {
1010 discrete_handler_cl_info_t info;
1011 info.handler = item1;
1012 info.handler_data = item2;
1013 locked_list_iterate(sensor->handler_list_cl,
1014 iterate_discrete_handler_cl,
1015 &info);
1016 }
1017 return LOCKED_LIST_ITER_CONTINUE;
1018 }
1019
1020 static void
sensor_final_destroy(ipmi_sensor_t * sensor)1021 sensor_final_destroy(ipmi_sensor_t *sensor)
1022 {
1023 i_ipmi_entity_get(sensor->entity);
1024 i_ipmi_entity_call_sensor_handlers(sensor->entity, sensor, IPMI_DELETED);
1025
1026 sensor->mc = NULL;
1027
1028 if (sensor->destroy_handler)
1029 sensor->destroy_handler(sensor, sensor->destroy_handler_cb_data);
1030
1031 if (sensor->waitq)
1032 opq_destroy(sensor->waitq);
1033
1034 if (sensor->handler_list) {
1035 locked_list_iterate(sensor->handler_list, handler_list_cleanup,
1036 sensor);
1037 locked_list_destroy(sensor->handler_list);
1038 }
1039
1040 if (sensor->handler_list_cl)
1041 locked_list_destroy(sensor->handler_list_cl);
1042
1043 ipmi_entity_remove_sensor(sensor->entity, sensor);
1044
1045 if (sensor->oem_info_cleanup_handler)
1046 sensor->oem_info_cleanup_handler(sensor, sensor->oem_info);
1047
1048 i_ipmi_entity_put(sensor->entity);
1049 ipmi_mem_free(sensor);
1050 }
1051
1052 int
ipmi_sensor_destroy(ipmi_sensor_t * sensor)1053 ipmi_sensor_destroy(ipmi_sensor_t *sensor)
1054 {
1055 ipmi_sensor_info_t *sensors;
1056 ipmi_mc_t *mc = sensor->mc;
1057
1058 i_ipmi_domain_mc_lock(sensor->domain);
1059 i_ipmi_mc_get(mc);
1060 i_ipmi_domain_mc_unlock(sensor->domain);
1061 sensors = i_ipmi_mc_get_sensors(sensor->mc);
1062
1063 ipmi_lock(sensors->idx_lock);
1064 if (sensor == sensors->sensors_by_idx[sensor->lun][sensor->num]) {
1065 sensors->sensor_count--;
1066 sensors->sensors_by_idx[sensor->lun][sensor->num] = NULL;
1067 }
1068
1069 i_ipmi_sensor_get(sensor);
1070
1071 if (sensor->source_array)
1072 sensor->source_array[sensor->source_idx] = NULL;
1073
1074 ipmi_unlock(sensors->idx_lock);
1075
1076 sensor->destroyed = 1;
1077 i_ipmi_sensor_put(sensor);
1078 i_ipmi_mc_put(mc);
1079 return 0;
1080 }
1081
1082 int
ipmi_sensors_destroy(ipmi_sensor_info_t * sensors)1083 ipmi_sensors_destroy(ipmi_sensor_info_t *sensors)
1084 {
1085 unsigned int i, j;
1086
1087 if (sensors->destroyed)
1088 return EINVAL;
1089
1090 sensors->destroyed = 1;
1091 for (i=0; i<=4; i++) {
1092 for (j=0; j<sensors->idx_size[i]; j++) {
1093 if (sensors->sensors_by_idx[i][j]) {
1094 ipmi_sensor_destroy(sensors->sensors_by_idx[i][j]);
1095 }
1096 }
1097 if (sensors->sensors_by_idx[i])
1098 ipmi_mem_free(sensors->sensors_by_idx[i]);
1099 }
1100 if (sensors->idx_lock)
1101 ipmi_destroy_lock(sensors->idx_lock);
1102 ipmi_mem_free(sensors);
1103 return 0;
1104 }
1105
1106 static void
sensor_set_name(ipmi_sensor_t * sensor)1107 sensor_set_name(ipmi_sensor_t *sensor)
1108 {
1109 int length;
1110
1111 length = ipmi_entity_get_name(sensor->entity, sensor->name,
1112 sizeof(sensor->name)-2);
1113 sensor->name[length] = '.';
1114 length++;
1115 length += snprintf(sensor->name+length, IPMI_SENSOR_NAME_LEN-length-2,
1116 "%s", sensor->id);
1117 sensor->name[length] = ' ';
1118 length++;
1119 sensor->name[length] = '\0';
1120 length++;
1121 }
1122
1123 const char *
i_ipmi_sensor_name(const ipmi_sensor_t * sensor)1124 i_ipmi_sensor_name(const ipmi_sensor_t *sensor)
1125 {
1126 return sensor->name;
1127 }
1128
1129 int
ipmi_sensor_get_name(ipmi_sensor_t * sensor,char * name,int length)1130 ipmi_sensor_get_name(ipmi_sensor_t *sensor, char *name, int length)
1131 {
1132 int slen;
1133
1134 if (length <= 0)
1135 return 0;
1136
1137 /* Never changes, no lock needed. */
1138 slen = strlen(sensor->name);
1139 if (slen == 0) {
1140 if (name)
1141 *name = '\0';
1142 goto out;
1143 }
1144
1145 slen -= 1; /* Remove the trailing ' ' */
1146 if (slen >= length)
1147 slen = length - 1;
1148
1149 if (name) {
1150 memcpy(name, sensor->name, slen);
1151 name[slen] = '\0';
1152 }
1153 out:
1154 return slen;
1155 }
1156
1157 /***********************************************************************
1158 *
1159 * Sensor SDR handling
1160 *
1161 **********************************************************************/
1162
1163 static int
get_sensors_from_sdrs(ipmi_domain_t * domain,ipmi_mc_t * source_mc,ipmi_sdr_info_t * sdrs,ipmi_sensor_t *** sensors,unsigned int * sensor_count)1164 get_sensors_from_sdrs(ipmi_domain_t *domain,
1165 ipmi_mc_t *source_mc,
1166 ipmi_sdr_info_t *sdrs,
1167 ipmi_sensor_t ***sensors,
1168 unsigned int *sensor_count)
1169 {
1170 ipmi_sdr_t sdr;
1171 unsigned int count;
1172 ipmi_sensor_t **s = NULL;
1173 unsigned int p, s_size = 0;
1174 int val;
1175 int rv;
1176 unsigned int i;
1177 int j;
1178 int share_count;
1179 int id_string_mod_type;
1180 int entity_instance_incr;
1181 int id_string_modifier_offset;
1182 unsigned char *str;
1183 unsigned int str_len;
1184
1185
1186 rv = ipmi_get_sdr_count(sdrs, &count);
1187 if (rv) {
1188 ipmi_log(IPMI_LOG_WARNING,
1189 "%ssensor.c(get_sensors_from_sdrs):"
1190 " Could not fetch SDR count fron the SDR record.",
1191 MC_NAME(source_mc));
1192 goto out_err;
1193 }
1194
1195 /* Get a real count on the number of sensors, since a single SDR can
1196 contain multiple sensors. */
1197 p = 0;
1198 for (i=0; i<count; i++) {
1199 int incr;
1200
1201 rv = ipmi_get_sdr_by_index(sdrs, i, &sdr);
1202 if (rv) {
1203 ipmi_log(IPMI_LOG_WARNING,
1204 "%ssensor.c(get_sensors_from_sdrs):"
1205 " SDR record %d could not be fetched from the SDR"
1206 " record: %d",
1207 MC_NAME(source_mc), i, rv);
1208 goto out_err;
1209 }
1210
1211 if (sdr.type == 1) {
1212 incr = 1;
1213 } else if (sdr.type == 2) {
1214 if (sdr.data[18] & 0x0f)
1215 incr = sdr.data[18] & 0x0f;
1216 else
1217 incr = 1;
1218 } else if (sdr.type == 3) {
1219 if (sdr.data[7] & 0x0f)
1220 incr = sdr.data[7] & 0x0f;
1221 else
1222 incr = 1;
1223 } else
1224 continue;
1225
1226 p += incr;
1227 }
1228 if (!p)
1229 return 0;
1230
1231 /* Setup memory to hold the sensors. */
1232 s = ipmi_mem_alloc(sizeof(*s) * p);
1233 if (!s)
1234 goto out_err_enomem;
1235 s_size = p;
1236 memset(s, 0, sizeof(*s) * p);
1237
1238 p = 0;
1239 for (i=0; i<count; i++) {
1240 rv = ipmi_get_sdr_by_index(sdrs, i, &sdr);
1241 if (rv) {
1242 ipmi_log(IPMI_LOG_WARNING,
1243 "%ssensor.c(get_sensors_from_sdrs):"
1244 " SDR record %d could not be fetched from the SDR"
1245 " record index: %d (2)",
1246 MC_NAME(source_mc), i, rv);
1247 goto out_err;
1248 }
1249
1250 if ((sdr.type != 1) && (sdr.type != 2) && (sdr.type != 3))
1251 continue;
1252
1253 s[p] = ipmi_mem_alloc(sizeof(*s[p]));
1254 if (!s[p])
1255 goto out_err_enomem;
1256 memset(s[p], 0, sizeof(*s[p]));
1257
1258 s[p]->source_recid = sdr.record_id;
1259 s[p]->hot_swap_requester = -1;
1260
1261 s[p]->waitq = opq_alloc(ipmi_domain_get_os_hnd(domain));
1262 if (!s[p]->waitq)
1263 goto out_err_enomem;
1264
1265 s[p]->handler_list_cl
1266 = locked_list_alloc(ipmi_domain_get_os_hnd(domain));
1267 if (! s[p]->handler_list_cl) {
1268 opq_destroy(s[p]->waitq);
1269 goto out_err_enomem;
1270 }
1271
1272 s[p]->handler_list = locked_list_alloc(ipmi_domain_get_os_hnd(domain));
1273 if (! s[p]->handler_list) {
1274 locked_list_destroy(s[i]->handler_list_cl);
1275 opq_destroy(s[p]->waitq);
1276 goto out_err_enomem;
1277 }
1278
1279 s[p]->destroyed = 0;
1280 s[p]->destroy_handler = NULL;
1281
1282 rv = i_ipmi_find_or_create_mc_by_slave_addr(domain,
1283 sdr.data[1] >> 4,
1284 sdr.data[0],
1285 &(s[p]->mc));
1286 if (rv) {
1287 ipmi_log(IPMI_LOG_WARNING,
1288 "%ssensor.c(get_sensors_from_sdrs):"
1289 " Could not create MC for SDR record %d, channel %d"
1290 " owner 0x%x: %d",
1291 MC_NAME(source_mc), i, sdr.data[1] >> 4, sdr.data[0], rv);
1292 goto out_err;
1293 }
1294
1295 share_count = 0;
1296 id_string_mod_type = 0;
1297 entity_instance_incr = 0;
1298 id_string_modifier_offset = 0;
1299
1300 s[p]->usecount = 1;
1301 s[p]->domain = domain;
1302 s[p]->source_mc = source_mc;
1303 s[p]->source_idx = p;
1304 s[p]->source_array = s;
1305 s[p]->owner = sdr.data[0];
1306 s[p]->channel = sdr.data[1] >> 4;
1307 s[p]->lun = sdr.data[1] & 0x03;
1308 s[p]->send_lun = s[p]->lun;
1309 s[p]->num = sdr.data[2];
1310 s[p]->entity_id = sdr.data[3];
1311 s[p]->entity_instance_logical = sdr.data[4] >> 7;
1312 s[p]->entity_instance = sdr.data[4] & 0x7f;
1313 if ((sdr.type == 1) || (sdr.type == 2)) {
1314 s[p]->readable = 1;
1315
1316 s[p]->sensor_init_scanning = (sdr.data[5] >> 6) & 1;
1317 s[p]->sensor_init_events = (sdr.data[5] >> 5) & 1;
1318 s[p]->sensor_init_thresholds = (sdr.data[5] >> 4) & 1;
1319 s[p]->sensor_init_hysteresis = (sdr.data[5] >> 3) & 1;
1320 s[p]->sensor_init_type = (sdr.data[5] >> 2) & 1;
1321 s[p]->sensor_init_pu_events = (sdr.data[5] >> 1) & 1;
1322 s[p]->sensor_init_pu_scanning = (sdr.data[5] >> 0) & 1;
1323 s[p]->ignore_if_no_entity = (sdr.data[6] >> 7) & 1;
1324 s[p]->supports_auto_rearm = (sdr.data[6] >> 6) & 1 ;
1325 s[p]->hysteresis_support = (sdr.data[6] >> 4) & 3;
1326 s[p]->threshold_access = (sdr.data[6] >> 2) & 3;
1327 s[p]->event_support = sdr.data[6] & 3;
1328 s[p]->sensor_type = sdr.data[7];
1329 s[p]->event_reading_type = sdr.data[8];
1330
1331 s[p]->mask1 = ipmi_get_uint16(sdr.data+9);
1332 s[p]->mask2 = ipmi_get_uint16(sdr.data+11);
1333 s[p]->mask3 = ipmi_get_uint16(sdr.data+13);
1334
1335 s[p]->analog_data_format = (sdr.data[15] >> 6) & 3;
1336 s[p]->rate_unit = (sdr.data[15] >> 3) & 7;
1337 s[p]->modifier_unit_use = (sdr.data[15] >> 1) & 3;
1338 s[p]->percentage = sdr.data[15] & 1;
1339 s[p]->base_unit = sdr.data[16];
1340 s[p]->modifier_unit = sdr.data[17];
1341 }
1342
1343 if (sdr.type == 1) {
1344 /* A full sensor record. */
1345 s[p]->linearization = sdr.data[18] & 0x7f;
1346
1347 if (s[p]->linearization <= 11) {
1348 for (j=0; j<256; j++) {
1349 s[p]->conv[j].m = sdr.data[19] | ((sdr.data[20] & 0xc0) << 2);
1350 s[p]->conv[j].tolerance = sdr.data[20] & 0x3f;
1351 s[p]->conv[j].b = sdr.data[21] | ((sdr.data[22] & 0xc0) << 2);
1352 s[p]->conv[j].accuracy = ((sdr.data[22] & 0x3f)
1353 | ((sdr.data[23] & 0xf0) << 2));
1354 s[p]->conv[j].accuracy_exp = (sdr.data[23] >> 2) & 0x3;
1355 s[p]->conv[j].r_exp = (sdr.data[24] >> 4) & 0xf;
1356 s[p]->conv[j].b_exp = sdr.data[24] & 0xf;
1357 }
1358 }
1359
1360 s[p]->sensor_direction = sdr.data[23] & 0x3;
1361 s[p]->normal_min_specified = (sdr.data[25] >> 2) & 1;
1362 s[p]->normal_max_specified = (sdr.data[25] >> 1) & 1;
1363 s[p]->nominal_reading_specified = sdr.data[25] & 1;
1364 s[p]->nominal_reading = sdr.data[26];
1365 s[p]->normal_max = sdr.data[27];
1366 s[p]->normal_min = sdr.data[28];
1367 s[p]->sensor_max = sdr.data[29];
1368 s[p]->sensor_min = sdr.data[30];
1369 s[p]->default_thresholds[IPMI_UPPER_NON_RECOVERABLE]= sdr.data[31];
1370 s[p]->default_thresholds[IPMI_UPPER_CRITICAL] = sdr.data[32];
1371 s[p]->default_thresholds[IPMI_UPPER_NON_CRITICAL] = sdr.data[33];
1372 s[p]->default_thresholds[IPMI_LOWER_NON_RECOVERABLE] = sdr.data[34];
1373 s[p]->default_thresholds[IPMI_LOWER_CRITICAL] = sdr.data[35];
1374 s[p]->default_thresholds[IPMI_LOWER_NON_CRITICAL] = sdr.data[36];
1375 s[p]->positive_going_threshold_hysteresis = sdr.data[37];
1376 s[p]->negative_going_threshold_hysteresis = sdr.data[38];
1377 s[p]->oem1 = sdr.data[41];
1378
1379 str = sdr.data + 42;
1380 str_len = sdr.length - 42;
1381
1382 if (s[p]->entity)
1383 sensor_set_name(s[p]);
1384 } else if (sdr.type == 2) {
1385 /* FIXME - make sure this is not a threshold sensor. The
1386 question is, what do I do if it is? */
1387 /* A short sensor record. */
1388
1389 s[p]->sensor_direction = (sdr.data[18] >> 6) & 0x3;
1390
1391 s[p]->positive_going_threshold_hysteresis = sdr.data[20];
1392 s[p]->negative_going_threshold_hysteresis = sdr.data[21];
1393 s[p]->oem1 = sdr.data[25];
1394
1395 str = sdr.data + 26;
1396 str_len = sdr.length - 26;
1397
1398 share_count = sdr.data[18] & 0x0f;
1399 if (share_count == 0)
1400 share_count = 1;
1401 id_string_mod_type = (sdr.data[18] >> 4) & 0x3;
1402 entity_instance_incr = (sdr.data[19] >> 7) & 0x01;
1403 id_string_modifier_offset = sdr.data[19] & 0x7f;
1404 } else {
1405 /* Event-only sensor. It is not readable. */
1406
1407 s[p]->sensor_type = sdr.data[5];
1408 s[p]->event_reading_type = sdr.data[6];
1409 s[p]->oem1 = sdr.data[9];
1410
1411 str = sdr.data + 10;
1412 str_len = sdr.length - 10;
1413
1414 share_count = sdr.data[7] & 0x0f;
1415 if (share_count == 0)
1416 share_count = 1;
1417 id_string_mod_type = (sdr.data[7] >> 4) & 0x3;
1418 entity_instance_incr = (sdr.data[8] >> 7) & 0x01;
1419 id_string_modifier_offset = sdr.data[8] & 0x7f;
1420 }
1421
1422 rv = ipmi_get_device_string(&str, str_len,
1423 s[p]->id, IPMI_STR_SDR_SEMANTICS, 0,
1424 &s[p]->id_type, SENSOR_ID_LEN,
1425 &s[p]->id_len);
1426 if (rv) {
1427 ipmi_log(IPMI_LOG_WARNING,
1428 "%ssensor.c(get_sensors_from_sdrs):"
1429 " Error getting device ID string from SDR record %d: %d,"
1430 " this sensor will be named **INVALID**",
1431 MC_NAME(source_mc), sdr.record_id, rv);
1432 strncpy(s[p]->id, "**INVALID**", sizeof(s[p]->id));
1433 s[p]->id_len = strlen(s[p]->id);
1434 s[p]->id_type = IPMI_ASCII_STR;
1435 }
1436
1437 if (share_count > 1) {
1438 /* Duplicate the sensor records for each instance. Go
1439 backwards to avoid destroying the first one until we
1440 finish the others. */
1441 for (j=share_count-1; j>=0; j--) {
1442 int len;
1443
1444 if (j != 0) {
1445 /* The first one is already allocated, we are
1446 using it to copy to the other ones, so this is
1447 not necessary. We still have to iterate the
1448 first one to set its string name, though. */
1449 s[p+j] = ipmi_mem_alloc(sizeof(ipmi_sensor_t));
1450 if (!s[p+j])
1451 goto out_err_enomem;
1452 memcpy(s[p+j], s[p], sizeof(ipmi_sensor_t));
1453
1454 /* In case of error */
1455 s[p+j]->handler_list = NULL;
1456
1457 /* For every sensor except the first, increment the usage
1458 count for the MC so that it will decrement properly.
1459 This cannot fail because we have already gotten it
1460 before. */
1461 i_ipmi_find_or_create_mc_by_slave_addr(domain,
1462 s[p+j]->channel,
1463 s[p+j]->owner,
1464 &(s[p+j]->mc));
1465
1466 s[p+j]->waitq = opq_alloc(ipmi_domain_get_os_hnd(domain));
1467 if (!s[p+j]->waitq)
1468 goto out_err_enomem;
1469
1470 s[p+j]->handler_list_cl
1471 = locked_list_alloc(ipmi_domain_get_os_hnd(domain));
1472 if (! s[p+j]->handler_list_cl)
1473 goto out_err_enomem;
1474
1475 s[p+j]->handler_list
1476 = locked_list_alloc(ipmi_domain_get_os_hnd(domain));
1477 if (! s[p+j]->handler_list)
1478 goto out_err_enomem;
1479
1480 s[p+j]->num += j;
1481
1482 if (entity_instance_incr & 0x80) {
1483 s[p+j]->entity_instance += j;
1484 }
1485
1486 s[p+j]->source_idx += j;
1487 }
1488
1489 val = id_string_modifier_offset + j;
1490 len = s[p+j]->id_len;
1491 switch (id_string_mod_type) {
1492 case 0: /* Numeric */
1493 if ((val / 10) > 0) {
1494 if (len < SENSOR_ID_LEN) {
1495 s[p+j]->id[len] = (val/10) + '0';
1496 len++;
1497 }
1498 }
1499 if (len < SENSOR_ID_LEN) {
1500 s[p+j]->id[len] = (val%10) + '0';
1501 len++;
1502 }
1503 break;
1504 case 1: /* Alpha */
1505 if ((val / 26) > 0) {
1506 if (len < SENSOR_ID_LEN) {
1507 s[p+j]->id[len] = (val/26) + 'A';
1508 len++;
1509 }
1510 }
1511 if (len < SENSOR_ID_LEN) {
1512 s[p+j]->id[len] = (val%26) + 'A';
1513 len++;
1514 }
1515 break;
1516 /* FIXME - unicode handling? */
1517 }
1518 s[p+j]->id_len = len;
1519 if (s[p+j]->entity)
1520 sensor_set_name(s[p+j]);
1521 }
1522
1523 p += share_count;
1524 } else
1525 p++;
1526 }
1527
1528 *sensors = s;
1529 *sensor_count = s_size;
1530 return 0;
1531
1532 out_err_enomem:
1533 rv = ENOMEM;
1534 ipmi_log(IPMI_LOG_WARNING,
1535 "%ssensor.c(get_sensors_from_sdrs):"
1536 " Out of memory while processing the SDRS.",
1537 MC_NAME(source_mc));
1538 out_err:
1539 if (s) {
1540 for (i=0; i<s_size; i++)
1541 if (s[i]) {
1542 if (s[i]->mc)
1543 i_ipmi_mc_put(s[i]->mc);
1544 if (s[i]->waitq)
1545 opq_destroy(s[i]->waitq);
1546 if (s[i]->handler_list)
1547 locked_list_destroy(s[i]->handler_list);
1548 if (s[i]->handler_list_cl)
1549 locked_list_destroy(s[i]->handler_list_cl);
1550 ipmi_mem_free(s[i]);
1551 }
1552 ipmi_mem_free(s);
1553 }
1554 return rv;
1555 }
1556
1557 static void
handle_new_sensor(ipmi_domain_t * domain,ipmi_sensor_t * sensor,void * link)1558 handle_new_sensor(ipmi_domain_t *domain,
1559 ipmi_sensor_t *sensor,
1560 void *link)
1561 {
1562 /* Call this before the OEM call so the OEM call can replace it. */
1563 sensor->cbs = ipmi_standard_sensor_cb;
1564 sensor->sensor_type_string
1565 = ipmi_get_sensor_type_string(sensor->sensor_type);
1566 sensor->event_reading_type_string
1567 = ipmi_get_event_reading_type_string(sensor->event_reading_type);
1568 sensor->rate_unit_string
1569 = ipmi_get_rate_unit_string(sensor->rate_unit);
1570 sensor->base_unit_string
1571 = ipmi_get_unit_type_string(sensor->base_unit);
1572 sensor->modifier_unit_string
1573 = ipmi_get_unit_type_string(sensor->modifier_unit);
1574
1575 sensor_set_name(sensor);
1576
1577 if ((sensor->source_mc)
1578 && (i_ipmi_mc_new_sensor(sensor->source_mc, sensor->entity,
1579 sensor, link)))
1580 {
1581 /* Nothing to do, OEM code handled the sensor. */
1582 } else {
1583 ipmi_entity_add_sensor(sensor->entity, sensor, link);
1584 }
1585
1586 i_call_new_sensor_handlers(domain, sensor);
1587 }
1588
cmp_sensor(ipmi_sensor_t * s1,ipmi_sensor_t * s2)1589 static int cmp_sensor(ipmi_sensor_t *s1,
1590 ipmi_sensor_t *s2)
1591 {
1592 int i;
1593
1594 if (s1->entity_instance_logical != s2->entity_instance_logical) return 0;
1595 if (s1->sensor_init_scanning != s2->sensor_init_scanning) return 0;
1596 if (s1->sensor_init_events != s2->sensor_init_events) return 0;
1597 if (s1->sensor_init_thresholds != s2->sensor_init_thresholds) return 0;
1598 if (s1->sensor_init_hysteresis != s2->sensor_init_hysteresis) return 0;
1599 if (s1->sensor_init_type != s2->sensor_init_type) return 0;
1600 if (s1->sensor_init_pu_events != s2->sensor_init_pu_events) return 0;
1601 if (s1->sensor_init_pu_scanning != s2->sensor_init_pu_scanning) return 0;
1602 if (s1->ignore_if_no_entity != s2->ignore_if_no_entity) return 0;
1603 if (s1->supports_auto_rearm != s2->supports_auto_rearm) return 0;
1604 if (s1->hysteresis_support != s2->hysteresis_support) return 0;
1605 if (s1->threshold_access != s2->threshold_access) return 0;
1606 if (s1->event_support != s2->event_support) return 0;
1607 if (s1->sensor_type != s2->sensor_type) return 0;
1608 if (s1->event_reading_type != s2->event_reading_type) return 0;
1609
1610 if (s1->mask1 != s2->mask1) return 0;
1611 if (s1->mask2 != s2->mask2) return 0;
1612 if (s1->mask3 != s2->mask3) return 0;
1613
1614 if (s1->analog_data_format != s2->analog_data_format) return 0;
1615 if (s1->rate_unit != s2->rate_unit) return 0;
1616 if (s1->modifier_unit_use != s2->modifier_unit_use) return 0;
1617 if (s1->percentage != s2->percentage) return 0;
1618 if (s1->base_unit != s2->base_unit) return 0;
1619 if (s1->modifier_unit != s2->modifier_unit) return 0;
1620 if (s1->linearization != s2->linearization) return 0;
1621 if (s1->linearization <= 11) {
1622 if (s1->conv[0].m != s2->conv[0].m) return 0;
1623 if (s1->conv[0].tolerance != s2->conv[0].tolerance) return 0;
1624 if (s1->conv[0].b != s2->conv[0].b) return 0;
1625 if (s1->conv[0].accuracy != s2->conv[0].accuracy) return 0;
1626 if (s1->conv[0].accuracy_exp != s2->conv[0].accuracy_exp) return 0;
1627 if (s1->conv[0].r_exp != s2->conv[0].r_exp) return 0;
1628 if (s1->conv[0].b_exp != s2->conv[0].b_exp) return 0;
1629 }
1630 if (s1->normal_min_specified != s2->normal_min_specified) return 0;
1631 if (s1->normal_max_specified != s2->normal_max_specified) return 0;
1632 if (s1->nominal_reading_specified != s2->nominal_reading_specified) return 0;
1633 if (s1->nominal_reading != s2->nominal_reading) return 0;
1634 if (s1->normal_max != s2->normal_max) return 0;
1635 if (s1->normal_min != s2->normal_min) return 0;
1636 if (s1->sensor_max != s2->sensor_max) return 0;
1637 if (s1->sensor_min != s2->sensor_min) return 0;
1638 for (i=0; i<6; i++) {
1639 if (s1->default_thresholds[i] != s2->default_thresholds[i])
1640 return 0;
1641 }
1642 if (s1->positive_going_threshold_hysteresis
1643 != s2->positive_going_threshold_hysteresis)
1644 return 0;
1645 if (s1->negative_going_threshold_hysteresis
1646 != s2->negative_going_threshold_hysteresis)
1647 return 0;
1648 if (s1->oem1 != s2->oem1) return 0;
1649
1650 if (s1->id_type != s2->id_type) return 0;
1651 if (s1->id_len != s2->id_len) return 0;
1652 if (memcmp(s1->id, s2->id, s1->id_len) != 0) return 0;
1653
1654 return 1;
1655 }
1656
1657 enum entity_list_op { ENT_LIST_OLD, ENT_LIST_NEW, ENT_LIST_DUP };
1658 typedef struct entity_list_s
1659 {
1660 ipmi_entity_t *ent;
1661 ipmi_sensor_t *sensor;
1662 ipmi_sensor_t *osensor;
1663 ipmi_mc_t *mc;
1664 enum entity_list_op op;
1665 struct entity_list_s *next;
1666 } entity_list_t;
1667
1668 /* Assume it has enough space for one pointer. */
1669 struct locked_list_entry_s
1670 {
1671 locked_list_entry_t *next;
1672 };
1673
1674 int
ipmi_sensor_handle_sdrs(ipmi_domain_t * domain,ipmi_mc_t * source_mc,ipmi_sdr_info_t * sdrs)1675 ipmi_sensor_handle_sdrs(ipmi_domain_t *domain,
1676 ipmi_mc_t *source_mc,
1677 ipmi_sdr_info_t *sdrs)
1678 {
1679 int rv;
1680 unsigned int i, j;
1681 ipmi_sensor_t **sdr_sensors = NULL;
1682 ipmi_sensor_t **old_sdr_sensors;
1683 unsigned int old_count;
1684 unsigned int count = 0;
1685 ipmi_entity_info_t *ents;
1686 ipmi_entity_t *ent;
1687 entity_list_t *new_sensors = NULL;
1688 entity_list_t *del_sensors = NULL;
1689 entity_list_t *ent_item;
1690 entity_list_t *new_ent_item;
1691 locked_list_entry_t *link, *links = NULL;
1692 ipmi_sensor_t **sens_tmp;
1693
1694
1695 CHECK_DOMAIN_LOCK(domain);
1696 if (source_mc)
1697 CHECK_MC_LOCK(source_mc);
1698
1699 rv = get_sensors_from_sdrs(domain, source_mc, sdrs, &sdr_sensors, &count);
1700 if (rv)
1701 goto out_err;
1702
1703 ents = ipmi_domain_get_entities(domain);
1704
1705 /* Pre-allocate all the links we will need for registering sensors
1706 with the entities, and we make sure all the entities exist. */
1707 for (i=0; i<count; i++) {
1708 ipmi_sensor_t *nsensor = sdr_sensors[i];
1709
1710 ent = NULL;
1711
1712 if (nsensor != NULL) {
1713 ipmi_sensor_info_t *sensors;
1714
1715 /* Make sure the entity exists for ALL sensors in the
1716 new list. This way, if a sensor has changed
1717 entities, the new entity will exist. */
1718 rv = ipmi_entity_add(ents,
1719 domain,
1720 ipmi_mc_get_channel(nsensor->mc),
1721 ipmi_mc_get_address(nsensor->mc),
1722 i,
1723 nsensor->entity_id,
1724 nsensor->entity_instance,
1725 "",
1726 IPMI_ASCII_STR,
1727 0,
1728 NULL,
1729 NULL,
1730 &ent);
1731 if (rv)
1732 goto out_err_free;
1733
1734 nsensor->entity = ent;
1735
1736 sensors = i_ipmi_mc_get_sensors(nsensor->mc);
1737
1738 ipmi_lock(sensors->idx_lock);
1739 if (nsensor->num >= sensors->idx_size[nsensor->lun]) {
1740 /* There's not enough room in the sensor repository
1741 for the new item, so expand the array. */
1742 ipmi_sensor_t **new_by_idx;
1743 unsigned int new_size = nsensor->num+10;
1744 new_by_idx = ipmi_mem_alloc(sizeof(ipmi_sensor_t *) * new_size);
1745 if (!new_by_idx) {
1746 ipmi_unlock(sensors->idx_lock);
1747 rv = ENOMEM;
1748 i_ipmi_entity_put(ent);
1749 goto out_err_free;
1750 }
1751 if (sensors->sensors_by_idx[nsensor->lun]) {
1752 memcpy(new_by_idx,
1753 sensors->sensors_by_idx[nsensor->lun],
1754 (sensors->idx_size[nsensor->lun]
1755 * sizeof(ipmi_sensor_t *)));
1756 ipmi_mem_free(sensors->sensors_by_idx[nsensor->lun]);
1757 }
1758 for (j=sensors->idx_size[nsensor->lun]; j<new_size; j++)
1759 new_by_idx[j] = NULL;
1760 sensors->sensors_by_idx[nsensor->lun] = new_by_idx;
1761 sensors->idx_size[nsensor->lun] = new_size;
1762 }
1763 ipmi_unlock(sensors->idx_lock);
1764
1765 /* Keep track of each entity/sensor pair. */
1766 new_ent_item = ipmi_mem_alloc(sizeof(*new_ent_item));
1767 if (!new_ent_item) {
1768 i_ipmi_entity_put(ent);
1769 goto out_err_free;
1770 }
1771 new_ent_item->ent = ent;
1772 new_ent_item->sensor = nsensor;
1773 new_ent_item->osensor = NULL;
1774 new_ent_item->mc = nsensor->mc;
1775 new_ent_item->op = ENT_LIST_OLD;
1776 new_ent_item->next = new_sensors;
1777 new_sensors = new_ent_item;
1778
1779 /* Pre-allocate link entries for putting the sensor into
1780 the entity. */
1781 link = locked_list_alloc_entry();
1782 if (!link)
1783 goto out_err_free;
1784 link->next = links;
1785 links = link;
1786 }
1787 }
1788
1789 /* Check for duplicate sensor numbers in the new sensor set. */
1790 sens_tmp = ipmi_mem_alloc(256 * sizeof(ipmi_sensor_t **));
1791 if (!sens_tmp) {
1792 rv = ENOMEM;
1793 goto out_err_free;
1794 }
1795 memset(sens_tmp, 0, 256 * sizeof(ipmi_sensor_t **));
1796 ent_item = new_sensors;
1797 while (ent_item) {
1798 ipmi_sensor_t *nsensor = ent_item->sensor;
1799 ipmi_sensor_t *csensor;
1800
1801 if ((!ent_item->ent) || (!nsensor)) {
1802 ent_item = ent_item->next;
1803 continue;
1804 }
1805
1806 csensor = sens_tmp[nsensor->num];
1807 while (csensor) {
1808 if ((csensor->lun == nsensor->lun)
1809 && (csensor->num == nsensor->num)
1810 && (csensor->mc == nsensor->mc))
1811 {
1812 break;
1813 }
1814 csensor = csensor->tlink;
1815 }
1816 if (csensor) {
1817 ipmi_log(IPMI_LOG_WARNING,
1818 "%ssensor.c(ipmi_sensor_handle_sdrs):"
1819 " SDR record %d has the same sensor number as record"
1820 " %d in the repository. Ignoring second sensor."
1821 " Fix your SDRs!",
1822 SENSOR_NAME(nsensor),
1823 csensor->source_recid,
1824 nsensor->source_recid);
1825 ent_item->op = ENT_LIST_DUP;
1826 ent_item->osensor = NULL;
1827 } else {
1828 nsensor->tlink = sens_tmp[nsensor->num];
1829 sens_tmp[nsensor->num] = nsensor;
1830 }
1831 ent_item = ent_item->next;
1832 }
1833 ipmi_mem_free(sens_tmp);
1834
1835 i_ipmi_domain_entity_lock(domain);
1836
1837 i_ipmi_get_sdr_sensors(domain, source_mc,
1838 &old_sdr_sensors, &old_count);
1839
1840 ent_item = new_sensors;
1841 while (ent_item) {
1842 ipmi_sensor_t *nsensor = ent_item->sensor;
1843 ipmi_sensor_info_t *sensors;
1844
1845 if ((!ent_item->ent) || (!nsensor) || (ent_item->op == ENT_LIST_DUP)) {
1846 ent_item = ent_item->next;
1847 continue;
1848 }
1849
1850 sensors = i_ipmi_mc_get_sensors(nsensor->mc);
1851 ipmi_lock(sensors->idx_lock);
1852 if (sensors->sensors_by_idx[nsensor->lun]
1853 && (nsensor->num < sensors->idx_size[nsensor->lun])
1854 && sensors->sensors_by_idx[nsensor->lun][nsensor->num])
1855 {
1856 /* A sensor is already there. */
1857 ipmi_sensor_t *osensor
1858 = sensors->sensors_by_idx[nsensor->lun][nsensor->num];
1859
1860 if (cmp_sensor(nsensor, osensor)) {
1861 /* Since the data is the same, there is no need to get
1862 the old sensor entity or mc, since they are already
1863 gotten by the new sensor. */
1864 ent_item->op = ENT_LIST_DUP;
1865 ent_item->osensor = osensor;
1866 } else {
1867 /* We have to delete the old sensor. */
1868 new_ent_item = ipmi_mem_alloc(sizeof(*new_ent_item));
1869 if (!new_ent_item) {
1870 ipmi_unlock(sensors->idx_lock);
1871 rv = ENOMEM;
1872 goto out_err_free_unlock;
1873 }
1874 /* It's possible this can fail, but that means that
1875 the MC is currently being destroyed. No big deal,
1876 just ignore it. */
1877 new_ent_item->mc = NULL;
1878 i_ipmi_find_or_create_mc_by_slave_addr(domain,
1879 osensor->channel,
1880 osensor->owner,
1881 &new_ent_item->mc);
1882 i_ipmi_entity_get(osensor->entity);
1883 i_ipmi_sensor_get(osensor);
1884 new_ent_item->ent = osensor->entity;
1885 new_ent_item->sensor = osensor;
1886 new_ent_item->next = del_sensors;
1887 del_sensors = new_ent_item;
1888 ent_item->op = ENT_LIST_NEW;
1889 }
1890 } else {
1891 ent_item->op = ENT_LIST_NEW;
1892 }
1893 ipmi_unlock(sensors->idx_lock);
1894
1895 ent_item = ent_item->next;
1896 }
1897
1898 i_ipmi_domain_entity_unlock(domain);
1899
1900 /* After this point, the operation cannot fail. Nothing above
1901 this actually changes anything, it just gets it ready. Now we
1902 put into place all the changes. */
1903
1904 /* First delete the sensors that we are replacing. */
1905 ent_item = del_sensors;
1906 while (ent_item) {
1907 ipmi_sensor_t *osensor = ent_item->sensor;
1908
1909 if (osensor->source_array) {
1910 osensor->source_array[osensor->source_idx] = NULL;
1911 osensor->source_array = NULL;
1912 }
1913 /* Note that the actual destroy is deferred until we put the
1914 sensor. */
1915 ipmi_sensor_destroy(osensor);
1916
1917 ent_item = ent_item->next;
1918 }
1919
1920 ent_item = new_sensors;
1921 while (ent_item) {
1922 ipmi_sensor_t *nsensor = ent_item->sensor;
1923 ipmi_sensor_t *osensor = ent_item->osensor;
1924 ipmi_sensor_info_t *sensors;
1925
1926 if ((!ent_item->ent) || (!nsensor)) {
1927 ent_item = ent_item->next;
1928 continue;
1929 }
1930
1931 sensors = i_ipmi_mc_get_sensors(nsensor->mc);
1932 ipmi_lock(sensors->idx_lock);
1933 switch (ent_item->op) {
1934 case ENT_LIST_NEW:
1935 sensors->sensors_by_idx[nsensor->lun][nsensor->num] = nsensor;
1936 sensors->sensor_count++;
1937 link = links;
1938 links = link->next;
1939 handle_new_sensor(domain, nsensor, link);
1940 break;
1941
1942 case ENT_LIST_OLD:
1943 break;
1944
1945 case ENT_LIST_DUP:
1946 /* They compare, prefer to keep the old data. */
1947 i = nsensor->source_idx;
1948 opq_destroy(nsensor->waitq);
1949 locked_list_destroy(nsensor->handler_list);
1950 locked_list_destroy(nsensor->handler_list_cl);
1951 ipmi_mem_free(nsensor);
1952 ent_item->sensor = NULL;
1953 sdr_sensors[i] = osensor;
1954 if (osensor) {
1955 if (osensor->source_array)
1956 osensor->source_array[osensor->source_idx] = NULL;
1957 osensor->source_idx = i;
1958 osensor->source_array = sdr_sensors;
1959 }
1960 break;
1961 }
1962 ipmi_unlock(sensors->idx_lock);
1963 ent_item = ent_item->next;
1964 }
1965
1966 i_ipmi_set_sdr_sensors(domain, source_mc, sdr_sensors, count);
1967
1968 if (old_sdr_sensors) {
1969 for (i=0; i<old_count; i++) {
1970 ipmi_sensor_t *osensor = old_sdr_sensors[i];
1971 if (osensor != NULL) {
1972 /* This sensor was not in the new repository, so it must
1973 have been deleted. */
1974 i_ipmi_domain_entity_lock(domain);
1975 i_ipmi_sensor_get(osensor);
1976 i_ipmi_domain_entity_unlock(domain);
1977 ipmi_sensor_destroy(osensor);
1978 }
1979 }
1980 }
1981
1982 if (old_sdr_sensors) {
1983 for (i=0; i<old_count; i++) {
1984 ipmi_sensor_t *osensor = old_sdr_sensors[i];
1985 if (osensor != NULL) {
1986 i_ipmi_sensor_put(osensor);
1987 }
1988 }
1989 ipmi_mem_free(old_sdr_sensors);
1990 }
1991
1992 /* Free up all the deleted sensors. */
1993 while (del_sensors) {
1994 ent_item = del_sensors;
1995 del_sensors = del_sensors->next;
1996 if (ent_item->sensor)
1997 i_ipmi_sensor_put(ent_item->sensor);
1998 if (ent_item->ent)
1999 i_ipmi_entity_put(ent_item->ent);
2000 if (ent_item->mc)
2001 i_ipmi_mc_put(ent_item->mc);
2002 ipmi_mem_free(ent_item);
2003 }
2004
2005 /* Report then free up all the new sensors. */
2006 while (new_sensors) {
2007 ent_item = new_sensors;
2008 new_sensors = new_sensors->next;
2009
2010 if (ent_item->ent && ent_item->sensor)
2011 ent_item->sensor->add_pending = 1;
2012 if (ent_item->sensor)
2013 i_ipmi_sensor_put(ent_item->sensor);
2014 if (ent_item->ent)
2015 i_ipmi_entity_put(ent_item->ent);
2016 if (ent_item->mc)
2017 i_ipmi_mc_put(ent_item->mc);
2018 ipmi_mem_free(ent_item);
2019 }
2020
2021 out:
2022 /* Cleanup unused links. */
2023 while (links) {
2024 link = links;
2025 links = link->next;
2026 locked_list_free_entry(link);
2027 }
2028
2029 return rv;
2030
2031 out_err:
2032 /* Release all the entities, sensors, etc. */
2033 while (del_sensors) {
2034 ent_item = del_sensors;
2035 del_sensors = del_sensors->next;
2036 if (ent_item->sensor)
2037 i_ipmi_sensor_put(ent_item->sensor);
2038 if (ent_item->ent)
2039 i_ipmi_entity_put(ent_item->ent);
2040 if (ent_item->mc)
2041 i_ipmi_mc_put(ent_item->mc);
2042 ipmi_mem_free(ent_item);
2043 }
2044 while (new_sensors) {
2045 ent_item = new_sensors;
2046 new_sensors = new_sensors->next;
2047 if (ent_item->sensor)
2048 i_ipmi_sensor_put(ent_item->sensor);
2049 if (ent_item->ent)
2050 i_ipmi_entity_put(ent_item->ent);
2051 if (ent_item->mc)
2052 i_ipmi_mc_put(ent_item->mc);
2053 ipmi_mem_free(ent_item);
2054 }
2055 goto out;
2056
2057 out_err_free_unlock:
2058 i_ipmi_domain_entity_unlock(domain);
2059 out_err_free:
2060 /* Free up the usecounts on all the MCs we got. */
2061 for (i=0; i<count; i++) {
2062 ipmi_sensor_t *nsensor = sdr_sensors[i];
2063
2064 if ((nsensor) && (nsensor->mc))
2065 i_ipmi_mc_put(nsensor->mc);
2066 }
2067 goto out_err;
2068 }
2069
2070 /***********************************************************************
2071 *
2072 * Get/set various local information about a sensor.
2073 *
2074 **********************************************************************/
2075
2076 int
ipmi_sensor_get_nominal_reading(ipmi_sensor_t * sensor,double * nominal_reading)2077 ipmi_sensor_get_nominal_reading(ipmi_sensor_t *sensor,
2078 double *nominal_reading)
2079 {
2080 CHECK_SENSOR_LOCK(sensor);
2081
2082 if (!sensor->nominal_reading_specified)
2083 return ENOSYS;
2084
2085 return (ipmi_sensor_convert_from_raw(sensor,
2086 sensor->nominal_reading,
2087 nominal_reading));
2088 }
2089
2090 int
ipmi_sensor_get_normal_max(ipmi_sensor_t * sensor,double * normal_max)2091 ipmi_sensor_get_normal_max(ipmi_sensor_t *sensor, double *normal_max)
2092 {
2093 CHECK_SENSOR_LOCK(sensor);
2094
2095 if (!sensor->normal_max_specified)
2096 return ENOSYS;
2097
2098 return (ipmi_sensor_convert_from_raw(sensor,
2099 sensor->normal_max,
2100 normal_max));
2101 }
2102
2103 int
ipmi_sensor_get_normal_min(ipmi_sensor_t * sensor,double * normal_min)2104 ipmi_sensor_get_normal_min(ipmi_sensor_t *sensor, double *normal_min)
2105 {
2106 CHECK_SENSOR_LOCK(sensor);
2107
2108 if (!sensor->normal_min_specified)
2109 return ENOSYS;
2110
2111 return (ipmi_sensor_convert_from_raw(sensor,
2112 sensor->normal_min,
2113 normal_min));
2114 }
2115
2116 int
ipmi_sensor_get_sensor_max(ipmi_sensor_t * sensor,double * sensor_max)2117 ipmi_sensor_get_sensor_max(ipmi_sensor_t *sensor, double *sensor_max)
2118 {
2119 CHECK_SENSOR_LOCK(sensor);
2120
2121 return (ipmi_sensor_convert_from_raw(sensor,
2122 sensor->sensor_max,
2123 sensor_max));
2124 }
2125
2126 int
ipmi_sensor_get_sensor_min(ipmi_sensor_t * sensor,double * sensor_min)2127 ipmi_sensor_get_sensor_min(ipmi_sensor_t *sensor, double *sensor_min)
2128 {
2129 CHECK_SENSOR_LOCK(sensor);
2130
2131 return (ipmi_sensor_convert_from_raw(sensor,
2132 sensor->sensor_min,
2133 sensor_min));
2134 }
2135
ipmi_sensor_set_raw_default_threshold(ipmi_sensor_t * sensor,int threshold,int val)2136 int ipmi_sensor_set_raw_default_threshold(ipmi_sensor_t *sensor,
2137 int threshold,
2138 int val)
2139 {
2140 if ((threshold < 0) || (threshold > 5))
2141 return EINVAL;
2142
2143 sensor->default_thresholds[threshold] = val;
2144 return 0;
2145 }
2146
ipmi_sensor_get_default_threshold_raw(ipmi_sensor_t * sensor,int threshold,int * raw)2147 int ipmi_sensor_get_default_threshold_raw(ipmi_sensor_t *sensor,
2148 int threshold,
2149 int *raw)
2150 {
2151 int rv;
2152 int val;
2153
2154 CHECK_SENSOR_LOCK(sensor);
2155
2156 if ((threshold < 0) || (threshold > 5))
2157 return EINVAL;
2158
2159 rv = ipmi_sensor_threshold_settable(sensor, threshold, &val);
2160 if (rv)
2161 return rv;
2162
2163 if (!val)
2164 return ENOSYS;
2165
2166 if (!ipmi_sensor_get_sensor_init_thresholds(sensor))
2167 return ENOSYS;
2168
2169 *raw = sensor->default_thresholds[threshold];
2170 return 0;
2171 }
2172
ipmi_sensor_get_default_threshold_cooked(ipmi_sensor_t * sensor,int threshold,double * cooked)2173 int ipmi_sensor_get_default_threshold_cooked(ipmi_sensor_t *sensor,
2174 int threshold,
2175 double *cooked)
2176 {
2177 int rv;
2178 int val;
2179
2180 CHECK_SENSOR_LOCK(sensor);
2181
2182 if ((threshold < 0) || (threshold > 5))
2183 return EINVAL;
2184
2185 rv = ipmi_sensor_threshold_settable(sensor, threshold, &val);
2186 if (rv)
2187 return rv;
2188
2189 if (!val)
2190 return ENOSYS;
2191
2192 if (!ipmi_sensor_get_sensor_init_thresholds(sensor))
2193 return ENOSYS;
2194
2195 return (ipmi_sensor_convert_from_raw(sensor,
2196 sensor->default_thresholds[threshold],
2197 cooked));
2198 }
2199
2200 ipmi_mc_t *
ipmi_sensor_get_mc(ipmi_sensor_t * sensor)2201 ipmi_sensor_get_mc(ipmi_sensor_t *sensor)
2202 {
2203 return sensor->mc;
2204 }
2205
2206 ipmi_mc_t *
ipmi_sensor_get_source_mc(ipmi_sensor_t * sensor)2207 ipmi_sensor_get_source_mc(ipmi_sensor_t *sensor)
2208 {
2209 CHECK_SENSOR_LOCK(sensor);
2210
2211 return sensor->source_mc;
2212 }
2213
2214 int
ipmi_sensor_get_num(ipmi_sensor_t * sensor,int * lun,int * num)2215 ipmi_sensor_get_num(ipmi_sensor_t *sensor,
2216 int *lun,
2217 int *num)
2218 {
2219 CHECK_SENSOR_LOCK(sensor);
2220
2221 if (lun)
2222 *lun = sensor->lun;
2223 if (num)
2224 *num = sensor->num;
2225 return 0;
2226 }
2227
2228 static void
ipmi_sensor_get_event_masks(ipmi_sensor_t * sensor,uint16_t * mask1,uint16_t * mask2)2229 ipmi_sensor_get_event_masks(ipmi_sensor_t *sensor,
2230 uint16_t *mask1,
2231 uint16_t *mask2)
2232 {
2233 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD) {
2234 /* Remove the reading mask, as that is not part of the event
2235 values allowed. */
2236 *mask1 = sensor->mask1 & 0x0fff;
2237 *mask2 = sensor->mask2 & 0x0fff;
2238 } else {
2239 /* Cannot set bit 15 */
2240 *mask1 = sensor->mask1 & 0x7fff;
2241 *mask2 = sensor->mask2 & 0x7fff;
2242 }
2243 }
2244
2245 int
ipmi_sensor_threshold_event_supported(ipmi_sensor_t * sensor,enum ipmi_thresh_e event,enum ipmi_event_value_dir_e value_dir,enum ipmi_event_dir_e dir,int * val)2246 ipmi_sensor_threshold_event_supported(ipmi_sensor_t *sensor,
2247 enum ipmi_thresh_e event,
2248 enum ipmi_event_value_dir_e value_dir,
2249 enum ipmi_event_dir_e dir,
2250 int *val)
2251 {
2252 int idx;
2253 uint16_t mask;
2254
2255 CHECK_SENSOR_LOCK(sensor);
2256
2257 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2258 /* Not a threshold sensor, it doesn't have readings. */
2259 return ENOSYS;
2260 if (sensor->threshold_access == IPMI_THRESHOLD_ACCESS_SUPPORT_NONE) {
2261 /* No thresholds supported. */
2262 *val = 0;
2263 return 0;
2264 }
2265
2266 if (dir == IPMI_ASSERTION)
2267 mask = sensor->mask1;
2268 else if (dir == IPMI_DEASSERTION)
2269 mask = sensor->mask2;
2270 else
2271 return EINVAL;
2272
2273 idx = (event * 2) + value_dir;
2274 if (idx > 11)
2275 return EINVAL;
2276
2277 *val = IPMI_SENSOR_GET_MASK_BIT(mask, idx);
2278 return 0;
2279 }
2280
2281 void
ipmi_sensor_set_threshold_assertion_event_supported(ipmi_sensor_t * sensor,enum ipmi_thresh_e event,enum ipmi_event_value_dir_e dir,int val)2282 ipmi_sensor_set_threshold_assertion_event_supported(
2283 ipmi_sensor_t *sensor,
2284 enum ipmi_thresh_e event,
2285 enum ipmi_event_value_dir_e dir,
2286 int val)
2287 {
2288 int idx;
2289
2290 idx = (event * 2) + dir;
2291 if (idx > 11)
2292 return;
2293
2294 IPMI_SENSOR_SET_MASK_BIT(sensor->mask1, idx, val);
2295 }
2296
2297 void
ipmi_sensor_set_threshold_deassertion_event_supported(ipmi_sensor_t * sensor,enum ipmi_thresh_e event,enum ipmi_event_value_dir_e dir,int val)2298 ipmi_sensor_set_threshold_deassertion_event_supported(
2299 ipmi_sensor_t *sensor,
2300 enum ipmi_thresh_e event,
2301 enum ipmi_event_value_dir_e dir,
2302 int val)
2303 {
2304 int idx;
2305
2306 idx = (event * 2) + dir;
2307 if (idx > 11)
2308 return;
2309
2310 IPMI_SENSOR_SET_MASK_BIT(sensor->mask2, idx, val);
2311 }
2312
2313 int
ipmi_sensor_threshold_reading_supported(ipmi_sensor_t * sensor,enum ipmi_thresh_e thresh,int * val)2314 ipmi_sensor_threshold_reading_supported(ipmi_sensor_t *sensor,
2315 enum ipmi_thresh_e thresh,
2316 int *val)
2317 {
2318 CHECK_SENSOR_LOCK(sensor);
2319
2320 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2321 /* Not a threshold sensor, it doesn't have readings. */
2322 return ENOSYS;
2323
2324 switch(thresh) {
2325 case IPMI_LOWER_NON_CRITICAL:
2326 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask1, 12);
2327 break;
2328 case IPMI_LOWER_CRITICAL:
2329 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask1, 13);
2330 break;
2331 case IPMI_LOWER_NON_RECOVERABLE:
2332 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask1, 14);
2333 break;
2334 case IPMI_UPPER_NON_CRITICAL:
2335 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask2, 12);
2336 break;
2337 case IPMI_UPPER_CRITICAL:
2338 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask2, 13);
2339 break;
2340 case IPMI_UPPER_NON_RECOVERABLE:
2341 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask2, 14);
2342 break;
2343 default:
2344 return EINVAL;
2345 }
2346 return 0;
2347 }
2348
2349 int
ipmi_sensor_threshold_settable(ipmi_sensor_t * sensor,enum ipmi_thresh_e event,int * val)2350 ipmi_sensor_threshold_settable(ipmi_sensor_t *sensor,
2351 enum ipmi_thresh_e event,
2352 int *val)
2353 {
2354 CHECK_SENSOR_LOCK(sensor);
2355
2356 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2357 /* Not a threshold sensor, it doesn't have readings. */
2358 return ENOSYS;
2359 if (sensor->threshold_access != IPMI_THRESHOLD_ACCESS_SUPPORT_SETTABLE) {
2360 /* Threshold setting not supported for any thresholds. */
2361 *val = 0;
2362 return 0;
2363 }
2364
2365 if (event > IPMI_UPPER_NON_RECOVERABLE)
2366 return EINVAL;
2367
2368 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask3, event + 8);
2369 return 0;
2370 }
2371
2372 void
ipmi_sensor_threshold_set_settable(ipmi_sensor_t * sensor,enum ipmi_thresh_e event,int val)2373 ipmi_sensor_threshold_set_settable(ipmi_sensor_t *sensor,
2374 enum ipmi_thresh_e event,
2375 int val)
2376 {
2377 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2378 /* Not a threshold sensor, it doesn't have readings. */
2379 return;
2380
2381 if (event > IPMI_UPPER_NON_RECOVERABLE)
2382 return;
2383
2384 IPMI_SENSOR_SET_MASK_BIT(sensor->mask3, event + 8, val);
2385 }
2386
2387 int
ipmi_sensor_threshold_readable(ipmi_sensor_t * sensor,enum ipmi_thresh_e event,int * val)2388 ipmi_sensor_threshold_readable(ipmi_sensor_t *sensor,
2389 enum ipmi_thresh_e event,
2390 int *val)
2391 {
2392 CHECK_SENSOR_LOCK(sensor);
2393
2394 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2395 /* Not a threshold sensor, it doesn't have readings. */
2396 return ENOSYS;
2397 if ((sensor->threshold_access == IPMI_THRESHOLD_ACCESS_SUPPORT_NONE)
2398 || (sensor->threshold_access == IPMI_THRESHOLD_ACCESS_SUPPORT_FIXED))
2399 {
2400 /* Threshold reading not supported for any thresholds. */
2401 *val = 0;
2402 return 0;
2403 }
2404
2405 if (event > IPMI_UPPER_NON_RECOVERABLE)
2406 return EINVAL;
2407
2408 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask3, event);
2409 return 0;
2410 }
2411
2412 void
ipmi_sensor_threshold_set_readable(ipmi_sensor_t * sensor,enum ipmi_thresh_e event,int val)2413 ipmi_sensor_threshold_set_readable(ipmi_sensor_t *sensor,
2414 enum ipmi_thresh_e event,
2415 int val)
2416 {
2417 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
2418 /* Not a threshold sensor, it doesn't have readings. */
2419 return;
2420
2421 if (event > IPMI_UPPER_NON_RECOVERABLE)
2422 return;
2423
2424 IPMI_SENSOR_SET_MASK_BIT(sensor->mask3, event, val);
2425 }
2426
2427 int
ipmi_sensor_discrete_event_supported(ipmi_sensor_t * sensor,int event,enum ipmi_event_dir_e dir,int * val)2428 ipmi_sensor_discrete_event_supported(ipmi_sensor_t *sensor,
2429 int event,
2430 enum ipmi_event_dir_e dir,
2431 int *val)
2432 {
2433 uint16_t mask;
2434
2435 CHECK_SENSOR_LOCK(sensor);
2436
2437 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
2438 /* A threshold sensor, it doesn't have events. */
2439 return ENOSYS;
2440
2441 if (dir == IPMI_ASSERTION)
2442 mask = sensor->mask1;
2443 else if (dir == IPMI_DEASSERTION)
2444 mask = sensor->mask2;
2445 else
2446 return EINVAL;
2447
2448 if (event > 14)
2449 return EINVAL;
2450
2451 *val = IPMI_SENSOR_GET_MASK_BIT(mask, event);
2452 return 0;
2453 }
2454
2455 void
ipmi_sensor_set_discrete_assertion_event_supported(ipmi_sensor_t * sensor,int event,int val)2456 ipmi_sensor_set_discrete_assertion_event_supported(ipmi_sensor_t *sensor,
2457 int event,
2458 int val)
2459 {
2460 if (event > 14)
2461 return;
2462
2463 IPMI_SENSOR_SET_MASK_BIT(sensor->mask1, event, val);
2464 }
2465
2466 void
ipmi_sensor_set_discrete_deassertion_event_supported(ipmi_sensor_t * sensor,int event,int val)2467 ipmi_sensor_set_discrete_deassertion_event_supported(ipmi_sensor_t *sensor,
2468 int event,
2469 int val)
2470 {
2471 if (event > 14)
2472 return;
2473
2474 IPMI_SENSOR_SET_MASK_BIT(sensor->mask2, event, val);
2475 }
2476
2477 int
ipmi_sensor_discrete_event_readable(ipmi_sensor_t * sensor,int event,int * val)2478 ipmi_sensor_discrete_event_readable(ipmi_sensor_t *sensor,
2479 int event,
2480 int *val)
2481 {
2482 CHECK_SENSOR_LOCK(sensor);
2483
2484 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
2485 /* A threshold sensor, it doesn't have events. */
2486 return ENOSYS;
2487
2488 if (event > 14)
2489 return EINVAL;
2490
2491 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask3, event);
2492 return 0;
2493 }
2494
2495 void
ipmi_sensor_discrete_set_event_readable(ipmi_sensor_t * sensor,int event,int val)2496 ipmi_sensor_discrete_set_event_readable(ipmi_sensor_t *sensor,
2497 int event,
2498 int val)
2499 {
2500 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
2501 /* A threshold sensor, it doesn't have events. */
2502 return;
2503
2504 if (event > 14)
2505 return;
2506
2507 IPMI_SENSOR_SET_MASK_BIT(sensor->mask3, event, val);
2508 }
2509
2510 int
ipmi_sensor_get_owner(ipmi_sensor_t * sensor)2511 ipmi_sensor_get_owner(ipmi_sensor_t *sensor)
2512 {
2513 CHECK_SENSOR_LOCK(sensor);
2514
2515 return sensor->owner;
2516 }
2517
2518 int
ipmi_sensor_get_channel(ipmi_sensor_t * sensor)2519 ipmi_sensor_get_channel(ipmi_sensor_t *sensor)
2520 {
2521 CHECK_SENSOR_LOCK(sensor);
2522
2523 return sensor->channel;
2524 }
2525
2526 int
ipmi_sensor_get_entity_id(ipmi_sensor_t * sensor)2527 ipmi_sensor_get_entity_id(ipmi_sensor_t *sensor)
2528 {
2529 CHECK_SENSOR_LOCK(sensor);
2530
2531 return sensor->entity_id;
2532 }
2533
2534 int
ipmi_sensor_get_entity_instance(ipmi_sensor_t * sensor)2535 ipmi_sensor_get_entity_instance(ipmi_sensor_t *sensor)
2536 {
2537 CHECK_SENSOR_LOCK(sensor);
2538
2539 return sensor->entity_instance;
2540 }
2541
2542 int
ipmi_sensor_get_entity_instance_logical(ipmi_sensor_t * sensor)2543 ipmi_sensor_get_entity_instance_logical(ipmi_sensor_t *sensor)
2544 {
2545 CHECK_SENSOR_LOCK(sensor);
2546
2547 return sensor->entity_instance_logical;
2548 }
2549
2550 int
ipmi_sensor_get_sensor_init_scanning(ipmi_sensor_t * sensor)2551 ipmi_sensor_get_sensor_init_scanning(ipmi_sensor_t *sensor)
2552 {
2553 CHECK_SENSOR_LOCK(sensor);
2554
2555 return sensor->sensor_init_scanning;
2556 }
2557
2558 int
ipmi_sensor_get_sensor_init_events(ipmi_sensor_t * sensor)2559 ipmi_sensor_get_sensor_init_events(ipmi_sensor_t *sensor)
2560 {
2561 CHECK_SENSOR_LOCK(sensor);
2562
2563 return sensor->sensor_init_events;
2564 }
2565
2566 int
ipmi_sensor_get_sensor_init_thresholds(ipmi_sensor_t * sensor)2567 ipmi_sensor_get_sensor_init_thresholds(ipmi_sensor_t *sensor)
2568 {
2569 CHECK_SENSOR_LOCK(sensor);
2570
2571 return sensor->sensor_init_thresholds;
2572 }
2573
2574 int
ipmi_sensor_get_sensor_init_hysteresis(ipmi_sensor_t * sensor)2575 ipmi_sensor_get_sensor_init_hysteresis(ipmi_sensor_t *sensor)
2576 {
2577 CHECK_SENSOR_LOCK(sensor);
2578
2579 return sensor->sensor_init_hysteresis;
2580 }
2581
2582 int
ipmi_sensor_get_sensor_init_type(ipmi_sensor_t * sensor)2583 ipmi_sensor_get_sensor_init_type(ipmi_sensor_t *sensor)
2584 {
2585 CHECK_SENSOR_LOCK(sensor);
2586
2587 return sensor->sensor_init_type;
2588 }
2589
2590 int
ipmi_sensor_get_sensor_init_pu_events(ipmi_sensor_t * sensor)2591 ipmi_sensor_get_sensor_init_pu_events(ipmi_sensor_t *sensor)
2592 {
2593 CHECK_SENSOR_LOCK(sensor);
2594
2595 return sensor->sensor_init_pu_events;
2596 }
2597
2598 int
ipmi_sensor_get_sensor_init_pu_scanning(ipmi_sensor_t * sensor)2599 ipmi_sensor_get_sensor_init_pu_scanning(ipmi_sensor_t *sensor)
2600 {
2601 CHECK_SENSOR_LOCK(sensor);
2602
2603 return sensor->sensor_init_pu_scanning;
2604 }
2605
2606 int
ipmi_sensor_get_ignore_if_no_entity(ipmi_sensor_t * sensor)2607 ipmi_sensor_get_ignore_if_no_entity(ipmi_sensor_t *sensor)
2608 {
2609 CHECK_SENSOR_LOCK(sensor);
2610
2611 return sensor->ignore_if_no_entity;
2612 }
2613
2614 int
ipmi_sensor_get_ignore_for_presence(ipmi_sensor_t * sensor)2615 ipmi_sensor_get_ignore_for_presence(ipmi_sensor_t *sensor)
2616 {
2617 CHECK_SENSOR_LOCK(sensor);
2618
2619 return sensor->ignore_for_presence;
2620 }
2621
2622 int
ipmi_sensor_get_supports_auto_rearm(ipmi_sensor_t * sensor)2623 ipmi_sensor_get_supports_auto_rearm(ipmi_sensor_t *sensor)
2624 {
2625 CHECK_SENSOR_LOCK(sensor);
2626
2627 return sensor->supports_auto_rearm;
2628 }
2629
2630 int
ipmi_sensor_get_hysteresis_support(ipmi_sensor_t * sensor)2631 ipmi_sensor_get_hysteresis_support(ipmi_sensor_t *sensor)
2632 {
2633 CHECK_SENSOR_LOCK(sensor);
2634
2635 return sensor->hysteresis_support;
2636 }
2637
2638 int
ipmi_sensor_get_threshold_access(ipmi_sensor_t * sensor)2639 ipmi_sensor_get_threshold_access(ipmi_sensor_t *sensor)
2640 {
2641 CHECK_SENSOR_LOCK(sensor);
2642
2643 return sensor->threshold_access;
2644 }
2645
2646 int
ipmi_sensor_get_event_support(ipmi_sensor_t * sensor)2647 ipmi_sensor_get_event_support(ipmi_sensor_t *sensor)
2648 {
2649 CHECK_SENSOR_LOCK(sensor);
2650
2651 return sensor->event_support;
2652 }
2653
2654 int
ipmi_sensor_get_sensor_type(ipmi_sensor_t * sensor)2655 ipmi_sensor_get_sensor_type(ipmi_sensor_t *sensor)
2656 {
2657 CHECK_SENSOR_LOCK(sensor);
2658
2659 return sensor->sensor_type;
2660 }
2661
2662 int
ipmi_sensor_get_event_reading_type(ipmi_sensor_t * sensor)2663 ipmi_sensor_get_event_reading_type(ipmi_sensor_t *sensor)
2664 {
2665 CHECK_SENSOR_LOCK(sensor);
2666
2667 return sensor->event_reading_type;
2668 }
2669
2670 int
ipmi_sensor_get_sensor_direction(ipmi_sensor_t * sensor)2671 ipmi_sensor_get_sensor_direction(ipmi_sensor_t *sensor)
2672 {
2673 CHECK_SENSOR_LOCK(sensor);
2674
2675 return sensor->sensor_direction;
2676 }
2677
2678 int
ipmi_sensor_get_is_readable(ipmi_sensor_t * sensor)2679 ipmi_sensor_get_is_readable(ipmi_sensor_t *sensor)
2680 {
2681 CHECK_SENSOR_LOCK(sensor);
2682
2683 return sensor->readable;
2684 }
2685
2686 int
ipmi_sensor_get_analog_data_format(ipmi_sensor_t * sensor)2687 ipmi_sensor_get_analog_data_format(ipmi_sensor_t *sensor)
2688 {
2689 CHECK_SENSOR_LOCK(sensor);
2690
2691 return sensor->analog_data_format;
2692 }
2693
2694 enum ipmi_rate_unit_e
ipmi_sensor_get_rate_unit(ipmi_sensor_t * sensor)2695 ipmi_sensor_get_rate_unit(ipmi_sensor_t *sensor)
2696 {
2697 CHECK_SENSOR_LOCK(sensor);
2698
2699 return sensor->rate_unit;
2700 }
2701
2702 enum ipmi_modifier_unit_use_e
ipmi_sensor_get_modifier_unit_use(ipmi_sensor_t * sensor)2703 ipmi_sensor_get_modifier_unit_use(ipmi_sensor_t *sensor)
2704 {
2705 CHECK_SENSOR_LOCK(sensor);
2706
2707 return sensor->modifier_unit_use;
2708 }
2709
2710 int
ipmi_sensor_get_percentage(ipmi_sensor_t * sensor)2711 ipmi_sensor_get_percentage(ipmi_sensor_t *sensor)
2712 {
2713 CHECK_SENSOR_LOCK(sensor);
2714
2715 return sensor->percentage;
2716 }
2717
2718 enum ipmi_unit_type_e
ipmi_sensor_get_base_unit(ipmi_sensor_t * sensor)2719 ipmi_sensor_get_base_unit(ipmi_sensor_t *sensor)
2720 {
2721 CHECK_SENSOR_LOCK(sensor);
2722
2723 return sensor->base_unit;
2724 }
2725
2726 enum ipmi_unit_type_e
ipmi_sensor_get_modifier_unit(ipmi_sensor_t * sensor)2727 ipmi_sensor_get_modifier_unit(ipmi_sensor_t *sensor)
2728 {
2729 CHECK_SENSOR_LOCK(sensor);
2730
2731 return sensor->modifier_unit;
2732 }
2733
2734 int
ipmi_sensor_get_linearization(ipmi_sensor_t * sensor)2735 ipmi_sensor_get_linearization(ipmi_sensor_t *sensor)
2736 {
2737 CHECK_SENSOR_LOCK(sensor);
2738
2739 return sensor->linearization;
2740 }
2741
2742 int
ipmi_sensor_get_raw_m(ipmi_sensor_t * sensor,int val)2743 ipmi_sensor_get_raw_m(ipmi_sensor_t *sensor, int val)
2744 {
2745 CHECK_SENSOR_LOCK(sensor);
2746
2747 return sensor->conv[val].m;
2748 }
2749
2750 int
ipmi_sensor_get_raw_tolerance(ipmi_sensor_t * sensor,int val)2751 ipmi_sensor_get_raw_tolerance(ipmi_sensor_t *sensor, int val)
2752 {
2753 CHECK_SENSOR_LOCK(sensor);
2754
2755 return sensor->conv[val].tolerance;
2756 }
2757
2758 int
ipmi_sensor_get_raw_b(ipmi_sensor_t * sensor,int val)2759 ipmi_sensor_get_raw_b(ipmi_sensor_t *sensor, int val)
2760 {
2761 CHECK_SENSOR_LOCK(sensor);
2762
2763 return sensor->conv[val].b;
2764 }
2765
2766 int
ipmi_sensor_get_raw_accuracy(ipmi_sensor_t * sensor,int val)2767 ipmi_sensor_get_raw_accuracy(ipmi_sensor_t *sensor, int val)
2768 {
2769 CHECK_SENSOR_LOCK(sensor);
2770
2771 return sensor->conv[val].accuracy;
2772 }
2773
2774 int
ipmi_sensor_get_raw_accuracy_exp(ipmi_sensor_t * sensor,int val)2775 ipmi_sensor_get_raw_accuracy_exp(ipmi_sensor_t *sensor, int val)
2776 {
2777 CHECK_SENSOR_LOCK(sensor);
2778
2779 return sensor->conv[val].accuracy_exp;
2780 }
2781
2782 int
ipmi_sensor_get_raw_r_exp(ipmi_sensor_t * sensor,int val)2783 ipmi_sensor_get_raw_r_exp(ipmi_sensor_t *sensor, int val)
2784 {
2785 CHECK_SENSOR_LOCK(sensor);
2786
2787 return sensor->conv[val].r_exp;
2788 }
2789
2790 int
ipmi_sensor_get_raw_b_exp(ipmi_sensor_t * sensor,int val)2791 ipmi_sensor_get_raw_b_exp(ipmi_sensor_t *sensor, int val)
2792 {
2793 CHECK_SENSOR_LOCK(sensor);
2794
2795 return sensor->conv[val].b_exp;
2796 }
2797
2798 int
ipmi_sensor_get_normal_min_specified(ipmi_sensor_t * sensor)2799 ipmi_sensor_get_normal_min_specified(ipmi_sensor_t *sensor)
2800 {
2801 CHECK_SENSOR_LOCK(sensor);
2802
2803 return sensor->normal_min_specified;
2804 }
2805
2806 int
ipmi_sensor_get_normal_max_specified(ipmi_sensor_t * sensor)2807 ipmi_sensor_get_normal_max_specified(ipmi_sensor_t *sensor)
2808 {
2809 CHECK_SENSOR_LOCK(sensor);
2810
2811 return sensor->normal_max_specified;
2812 }
2813
2814 int
ipmi_sensor_get_nominal_reading_specified(ipmi_sensor_t * sensor)2815 ipmi_sensor_get_nominal_reading_specified(ipmi_sensor_t *sensor)
2816 {
2817 CHECK_SENSOR_LOCK(sensor);
2818
2819 return sensor->nominal_reading_specified;
2820 }
2821
2822 int
ipmi_sensor_get_raw_nominal_reading(ipmi_sensor_t * sensor)2823 ipmi_sensor_get_raw_nominal_reading(ipmi_sensor_t *sensor)
2824 {
2825 CHECK_SENSOR_LOCK(sensor);
2826
2827 return sensor->nominal_reading;
2828 }
2829
2830 int
ipmi_sensor_get_raw_normal_max(ipmi_sensor_t * sensor)2831 ipmi_sensor_get_raw_normal_max(ipmi_sensor_t *sensor)
2832 {
2833 CHECK_SENSOR_LOCK(sensor);
2834
2835 return sensor->normal_max;
2836 }
2837
2838 int
ipmi_sensor_get_raw_normal_min(ipmi_sensor_t * sensor)2839 ipmi_sensor_get_raw_normal_min(ipmi_sensor_t *sensor)
2840 {
2841 CHECK_SENSOR_LOCK(sensor);
2842
2843 return sensor->normal_min;
2844 }
2845
2846 int
ipmi_sensor_get_raw_sensor_max(ipmi_sensor_t * sensor)2847 ipmi_sensor_get_raw_sensor_max(ipmi_sensor_t *sensor)
2848 {
2849 CHECK_SENSOR_LOCK(sensor);
2850
2851 return sensor->sensor_max;
2852 }
2853
2854 int
ipmi_sensor_get_raw_sensor_min(ipmi_sensor_t * sensor)2855 ipmi_sensor_get_raw_sensor_min(ipmi_sensor_t *sensor)
2856 {
2857 CHECK_SENSOR_LOCK(sensor);
2858
2859 return sensor->sensor_min;
2860 }
2861
2862 int
ipmi_sensor_get_positive_going_threshold_hysteresis(ipmi_sensor_t * sensor)2863 ipmi_sensor_get_positive_going_threshold_hysteresis(ipmi_sensor_t *sensor)
2864 {
2865 CHECK_SENSOR_LOCK(sensor);
2866
2867 return sensor->positive_going_threshold_hysteresis;
2868 }
2869
2870 int
ipmi_sensor_get_negative_going_threshold_hysteresis(ipmi_sensor_t * sensor)2871 ipmi_sensor_get_negative_going_threshold_hysteresis(ipmi_sensor_t *sensor)
2872 {
2873 CHECK_SENSOR_LOCK(sensor);
2874
2875 return sensor->negative_going_threshold_hysteresis;
2876 }
2877
2878 int
ipmi_sensor_get_oem1(ipmi_sensor_t * sensor)2879 ipmi_sensor_get_oem1(ipmi_sensor_t *sensor)
2880 {
2881 CHECK_SENSOR_LOCK(sensor);
2882
2883 return sensor->oem1;
2884 }
2885
2886 int
ipmi_sensor_get_id_length(ipmi_sensor_t * sensor)2887 ipmi_sensor_get_id_length(ipmi_sensor_t *sensor)
2888 {
2889 CHECK_SENSOR_LOCK(sensor);
2890
2891 if (sensor->id_type == IPMI_ASCII_STR)
2892 return sensor->id_len+1;
2893 else
2894 return sensor->id_len;
2895 }
2896
2897 enum ipmi_str_type_e
ipmi_sensor_get_id_type(ipmi_sensor_t * sensor)2898 ipmi_sensor_get_id_type(ipmi_sensor_t *sensor)
2899 {
2900 CHECK_SENSOR_LOCK(sensor);
2901
2902 return sensor->id_type;
2903 }
2904
2905 int
ipmi_sensor_get_id(ipmi_sensor_t * sensor,char * id,int length)2906 ipmi_sensor_get_id(ipmi_sensor_t *sensor, char *id, int length)
2907 {
2908 int clen;
2909
2910 CHECK_SENSOR_LOCK(sensor);
2911
2912 if ((int) sensor->id_len > length)
2913 clen = length;
2914 else
2915 clen = sensor->id_len;
2916 memcpy(id, sensor->id, clen);
2917
2918 if (sensor->id_type == IPMI_ASCII_STR) {
2919 /* NIL terminate the ASCII string. */
2920 if (clen == length)
2921 clen--;
2922
2923 id[clen] = '\0';
2924 }
2925
2926 return clen;
2927 }
2928
2929 void
ipmi_sensor_set_owner(ipmi_sensor_t * sensor,int owner)2930 ipmi_sensor_set_owner(ipmi_sensor_t *sensor, int owner)
2931 {
2932 sensor->owner = owner;
2933 }
2934
2935 void
ipmi_sensor_set_channel(ipmi_sensor_t * sensor,int channel)2936 ipmi_sensor_set_channel(ipmi_sensor_t *sensor, int channel)
2937 {
2938 sensor->channel = channel;
2939 }
2940
2941 void
ipmi_sensor_set_entity_id(ipmi_sensor_t * sensor,int entity_id)2942 ipmi_sensor_set_entity_id(ipmi_sensor_t *sensor, int entity_id)
2943 {
2944 sensor->entity_id = entity_id;
2945 }
2946
2947 void
ipmi_sensor_set_entity_instance(ipmi_sensor_t * sensor,int entity_instance)2948 ipmi_sensor_set_entity_instance(ipmi_sensor_t *sensor, int entity_instance)
2949 {
2950 sensor->entity_instance = entity_instance;
2951 }
2952
2953 void
ipmi_sensor_set_entity_instance_logical(ipmi_sensor_t * sensor,int entity_instance_logical)2954 ipmi_sensor_set_entity_instance_logical(ipmi_sensor_t *sensor,
2955 int entity_instance_logical)
2956 {
2957 sensor->entity_instance_logical = entity_instance_logical;
2958 }
2959
2960 void
ipmi_sensor_set_sensor_init_scanning(ipmi_sensor_t * sensor,int sensor_init_scanning)2961 ipmi_sensor_set_sensor_init_scanning(ipmi_sensor_t *sensor,
2962 int sensor_init_scanning)
2963 {
2964 sensor->sensor_init_scanning = sensor_init_scanning;
2965 }
2966
2967 void
ipmi_sensor_set_sensor_init_events(ipmi_sensor_t * sensor,int sensor_init_events)2968 ipmi_sensor_set_sensor_init_events(ipmi_sensor_t *sensor,
2969 int sensor_init_events)
2970 {
2971 sensor->sensor_init_events = sensor_init_events;
2972 }
2973
2974 void
ipmi_sensor_set_sensor_init_thresholds(ipmi_sensor_t * sensor,int sensor_init_thresholds)2975 ipmi_sensor_set_sensor_init_thresholds(ipmi_sensor_t *sensor,
2976 int sensor_init_thresholds)
2977 {
2978 sensor->sensor_init_thresholds = sensor_init_thresholds;
2979 }
2980
2981 void
ipmi_sensor_set_sensor_init_hysteresis(ipmi_sensor_t * sensor,int sensor_init_hysteresis)2982 ipmi_sensor_set_sensor_init_hysteresis(ipmi_sensor_t *sensor,
2983 int sensor_init_hysteresis)
2984 {
2985 sensor->sensor_init_hysteresis = sensor_init_hysteresis;
2986 }
2987
2988 void
ipmi_sensor_set_sensor_init_type(ipmi_sensor_t * sensor,int sensor_init_type)2989 ipmi_sensor_set_sensor_init_type(ipmi_sensor_t *sensor, int sensor_init_type)
2990 {
2991 sensor->sensor_init_type = sensor_init_type;
2992 }
2993
2994 void
ipmi_sensor_set_sensor_init_pu_events(ipmi_sensor_t * sensor,int sensor_init_pu_events)2995 ipmi_sensor_set_sensor_init_pu_events(ipmi_sensor_t *sensor,
2996 int sensor_init_pu_events)
2997 {
2998 sensor->sensor_init_pu_events = sensor_init_pu_events;
2999 }
3000
3001 void
ipmi_sensor_set_sensor_init_pu_scanning(ipmi_sensor_t * sensor,int sensor_init_pu_scanning)3002 ipmi_sensor_set_sensor_init_pu_scanning(ipmi_sensor_t *sensor,
3003 int sensor_init_pu_scanning)
3004 {
3005 sensor->sensor_init_pu_scanning = sensor_init_pu_scanning;
3006 }
3007
3008 void
ipmi_sensor_set_ignore_if_no_entity(ipmi_sensor_t * sensor,int ignore_if_no_entity)3009 ipmi_sensor_set_ignore_if_no_entity(ipmi_sensor_t *sensor,
3010 int ignore_if_no_entity)
3011 {
3012 sensor->ignore_if_no_entity = ignore_if_no_entity;
3013 }
3014
3015 void
ipmi_sensor_set_ignore_for_presence(ipmi_sensor_t * sensor,int ignore)3016 ipmi_sensor_set_ignore_for_presence(ipmi_sensor_t *sensor, int ignore)
3017 {
3018 sensor->ignore_for_presence = ignore;
3019 }
3020
3021 void
ipmi_sensor_set_supports_auto_rearm(ipmi_sensor_t * sensor,int val)3022 ipmi_sensor_set_supports_auto_rearm(ipmi_sensor_t *sensor, int val)
3023 {
3024 sensor->supports_auto_rearm = val;
3025 }
3026
3027 void
ipmi_sensor_set_hysteresis_support(ipmi_sensor_t * sensor,int hysteresis_support)3028 ipmi_sensor_set_hysteresis_support(ipmi_sensor_t *sensor,
3029 int hysteresis_support)
3030 {
3031 sensor->hysteresis_support = hysteresis_support;
3032 }
3033
3034 void
ipmi_sensor_set_threshold_access(ipmi_sensor_t * sensor,int threshold_access)3035 ipmi_sensor_set_threshold_access(ipmi_sensor_t *sensor, int threshold_access)
3036 {
3037 sensor->threshold_access = threshold_access;
3038 }
3039
3040 void
ipmi_sensor_set_event_support(ipmi_sensor_t * sensor,int event_support)3041 ipmi_sensor_set_event_support(ipmi_sensor_t *sensor, int event_support)
3042 {
3043 sensor->event_support = event_support;
3044 }
3045
3046 void
ipmi_sensor_set_sensor_type(ipmi_sensor_t * sensor,int sensor_type)3047 ipmi_sensor_set_sensor_type(ipmi_sensor_t *sensor, int sensor_type)
3048 {
3049 sensor->sensor_type = sensor_type;
3050 }
3051
3052 void
ipmi_sensor_set_event_reading_type(ipmi_sensor_t * sensor,int event_reading_type)3053 ipmi_sensor_set_event_reading_type(ipmi_sensor_t *sensor,
3054 int event_reading_type)
3055 {
3056 sensor->event_reading_type = event_reading_type;
3057 }
3058
3059 void
ipmi_sensor_set_direction(ipmi_sensor_t * sensor,int direction)3060 ipmi_sensor_set_direction(ipmi_sensor_t *sensor,
3061 int direction)
3062 {
3063 sensor->sensor_direction = direction;
3064 }
3065
3066 void
ipmi_sensor_set_is_readable(ipmi_sensor_t * sensor,int readable)3067 ipmi_sensor_set_is_readable(ipmi_sensor_t *sensor,
3068 int readable)
3069 {
3070 sensor->readable = readable != 0;
3071 }
3072
3073 void
ipmi_sensor_set_analog_data_format(ipmi_sensor_t * sensor,int analog_data_format)3074 ipmi_sensor_set_analog_data_format(ipmi_sensor_t *sensor,
3075 int analog_data_format)
3076 {
3077 sensor->analog_data_format = analog_data_format;
3078 }
3079
3080 void
ipmi_sensor_set_rate_unit(ipmi_sensor_t * sensor,int rate_unit)3081 ipmi_sensor_set_rate_unit(ipmi_sensor_t *sensor, int rate_unit)
3082 {
3083 sensor->rate_unit = rate_unit;
3084 }
3085
3086 void
ipmi_sensor_set_modifier_unit_use(ipmi_sensor_t * sensor,int modifier_unit_use)3087 ipmi_sensor_set_modifier_unit_use(ipmi_sensor_t *sensor, int modifier_unit_use)
3088 {
3089 sensor->modifier_unit_use = modifier_unit_use;
3090 }
3091
3092 void
ipmi_sensor_set_percentage(ipmi_sensor_t * sensor,int percentage)3093 ipmi_sensor_set_percentage(ipmi_sensor_t *sensor, int percentage)
3094 {
3095 sensor->percentage = percentage;
3096 }
3097
3098 void
ipmi_sensor_set_base_unit(ipmi_sensor_t * sensor,int base_unit)3099 ipmi_sensor_set_base_unit(ipmi_sensor_t *sensor, int base_unit)
3100 {
3101 sensor->base_unit = base_unit;
3102 }
3103
3104 void
ipmi_sensor_set_modifier_unit(ipmi_sensor_t * sensor,int modifier_unit)3105 ipmi_sensor_set_modifier_unit(ipmi_sensor_t *sensor, int modifier_unit)
3106 {
3107 sensor->modifier_unit = modifier_unit;
3108 }
3109
3110 void
ipmi_sensor_set_linearization(ipmi_sensor_t * sensor,int linearization)3111 ipmi_sensor_set_linearization(ipmi_sensor_t *sensor, int linearization)
3112 {
3113 sensor->linearization = linearization;
3114 }
3115
3116 void
ipmi_sensor_set_raw_m(ipmi_sensor_t * sensor,int idx,int val)3117 ipmi_sensor_set_raw_m(ipmi_sensor_t *sensor, int idx, int val)
3118 {
3119 sensor->conv[idx].m = val;
3120 }
3121
3122 void
ipmi_sensor_set_raw_tolerance(ipmi_sensor_t * sensor,int idx,int val)3123 ipmi_sensor_set_raw_tolerance(ipmi_sensor_t *sensor, int idx, int val)
3124 {
3125 sensor->conv[idx].tolerance = val;
3126 }
3127
3128 void
ipmi_sensor_set_raw_b(ipmi_sensor_t * sensor,int idx,int val)3129 ipmi_sensor_set_raw_b(ipmi_sensor_t *sensor, int idx, int val)
3130 {
3131 sensor->conv[idx].b = val;
3132 }
3133
3134 void
ipmi_sensor_set_raw_accuracy(ipmi_sensor_t * sensor,int idx,int val)3135 ipmi_sensor_set_raw_accuracy(ipmi_sensor_t *sensor, int idx, int val)
3136 {
3137 sensor->conv[idx].accuracy = val;
3138 }
3139
3140 void
ipmi_sensor_set_raw_accuracy_exp(ipmi_sensor_t * sensor,int idx,int val)3141 ipmi_sensor_set_raw_accuracy_exp(ipmi_sensor_t *sensor, int idx, int val)
3142 {
3143 sensor->conv[idx].accuracy_exp = val;
3144 }
3145
3146 void
ipmi_sensor_set_raw_r_exp(ipmi_sensor_t * sensor,int idx,int val)3147 ipmi_sensor_set_raw_r_exp(ipmi_sensor_t *sensor, int idx, int val)
3148 {
3149 sensor->conv[idx].r_exp = val;
3150 }
3151
3152 void
ipmi_sensor_set_raw_b_exp(ipmi_sensor_t * sensor,int idx,int val)3153 ipmi_sensor_set_raw_b_exp(ipmi_sensor_t *sensor, int idx, int val)
3154 {
3155 sensor->conv[idx].b_exp = val;
3156 }
3157
3158 void
ipmi_sensor_set_normal_min_specified(ipmi_sensor_t * sensor,int normal_min_specified)3159 ipmi_sensor_set_normal_min_specified(ipmi_sensor_t *sensor,
3160 int normal_min_specified)
3161 {
3162 sensor->normal_min_specified = normal_min_specified;
3163 }
3164
3165 void
ipmi_sensor_set_normal_max_specified(ipmi_sensor_t * sensor,int normal_max_specified)3166 ipmi_sensor_set_normal_max_specified(ipmi_sensor_t *sensor,
3167 int normal_max_specified)
3168 {
3169 sensor->normal_max_specified = normal_max_specified;
3170 }
3171
3172 void
ipmi_sensor_set_nominal_reading_specified(ipmi_sensor_t * sensor,int nominal_reading_specified)3173 ipmi_sensor_set_nominal_reading_specified(
3174 ipmi_sensor_t *sensor,
3175 int nominal_reading_specified)
3176 {
3177 sensor->nominal_reading_specified = nominal_reading_specified;
3178 }
3179
3180 void
ipmi_sensor_set_raw_nominal_reading(ipmi_sensor_t * sensor,int raw_nominal_reading)3181 ipmi_sensor_set_raw_nominal_reading(ipmi_sensor_t *sensor,
3182 int raw_nominal_reading)
3183 {
3184 sensor->nominal_reading = raw_nominal_reading;
3185 }
3186
3187 void
ipmi_sensor_set_raw_normal_max(ipmi_sensor_t * sensor,int raw_normal_max)3188 ipmi_sensor_set_raw_normal_max(ipmi_sensor_t *sensor, int raw_normal_max)
3189 {
3190 sensor->normal_max = raw_normal_max;
3191 }
3192
3193 void
ipmi_sensor_set_raw_normal_min(ipmi_sensor_t * sensor,int raw_normal_min)3194 ipmi_sensor_set_raw_normal_min(ipmi_sensor_t *sensor, int raw_normal_min)
3195 {
3196 sensor->normal_min = raw_normal_min;
3197 }
3198
3199 void
ipmi_sensor_set_raw_sensor_max(ipmi_sensor_t * sensor,int raw_sensor_max)3200 ipmi_sensor_set_raw_sensor_max(ipmi_sensor_t *sensor, int raw_sensor_max)
3201 {
3202 sensor->sensor_max = raw_sensor_max;
3203 }
3204
3205 void
ipmi_sensor_set_raw_sensor_min(ipmi_sensor_t * sensor,int raw_sensor_min)3206 ipmi_sensor_set_raw_sensor_min(ipmi_sensor_t *sensor, int raw_sensor_min)
3207 {
3208 sensor->sensor_min = raw_sensor_min;
3209 }
3210
3211 void
ipmi_sensor_set_positive_going_threshold_hysteresis(ipmi_sensor_t * sensor,int positive_going_threshold_hysteresis)3212 ipmi_sensor_set_positive_going_threshold_hysteresis(
3213 ipmi_sensor_t *sensor,
3214 int positive_going_threshold_hysteresis)
3215 {
3216 sensor->positive_going_threshold_hysteresis
3217 = positive_going_threshold_hysteresis;
3218 }
3219
3220 void
ipmi_sensor_set_negative_going_threshold_hysteresis(ipmi_sensor_t * sensor,int negative_going_threshold_hysteresis)3221 ipmi_sensor_set_negative_going_threshold_hysteresis(
3222 ipmi_sensor_t *sensor,
3223 int negative_going_threshold_hysteresis)
3224 {
3225 sensor->negative_going_threshold_hysteresis
3226 = negative_going_threshold_hysteresis;
3227 }
3228
3229 void
ipmi_sensor_set_oem1(ipmi_sensor_t * sensor,int oem1)3230 ipmi_sensor_set_oem1(ipmi_sensor_t *sensor, int oem1)
3231 {
3232 sensor->oem1 = oem1;
3233 }
3234
3235 void
ipmi_sensor_set_id(ipmi_sensor_t * sensor,char * id,enum ipmi_str_type_e type,int length)3236 ipmi_sensor_set_id(ipmi_sensor_t *sensor, char *id,
3237 enum ipmi_str_type_e type, int length)
3238 {
3239 if (length > SENSOR_ID_LEN)
3240 length = SENSOR_ID_LEN;
3241
3242 memcpy(sensor->id, id, length);
3243 sensor->id_type = type;
3244 sensor->id_len = length;
3245 if (sensor->entity)
3246 sensor_set_name(sensor);
3247 }
3248
3249 void
ipmi_sensor_set_oem_info(ipmi_sensor_t * sensor,void * oem_info,ipmi_sensor_cleanup_oem_info_cb cleanup_handler)3250 ipmi_sensor_set_oem_info(ipmi_sensor_t *sensor, void *oem_info,
3251 ipmi_sensor_cleanup_oem_info_cb cleanup_handler)
3252 {
3253 sensor->oem_info = oem_info;
3254 sensor->oem_info_cleanup_handler = cleanup_handler;
3255 }
3256
3257 void *
ipmi_sensor_get_oem_info(ipmi_sensor_t * sensor)3258 ipmi_sensor_get_oem_info(ipmi_sensor_t *sensor)
3259 {
3260 CHECK_SENSOR_LOCK(sensor);
3261
3262 return sensor->oem_info;
3263 }
3264
3265 const char *
ipmi_sensor_get_sensor_type_string(ipmi_sensor_t * sensor)3266 ipmi_sensor_get_sensor_type_string(ipmi_sensor_t *sensor)
3267 {
3268 CHECK_SENSOR_LOCK(sensor);
3269
3270 return sensor->sensor_type_string;
3271 }
3272
3273 void
ipmi_sensor_set_sensor_type_string(ipmi_sensor_t * sensor,const char * str)3274 ipmi_sensor_set_sensor_type_string(ipmi_sensor_t *sensor, const char *str)
3275 {
3276 sensor->sensor_type_string = str;
3277 }
3278
3279 const char *
ipmi_sensor_get_event_reading_type_string(ipmi_sensor_t * sensor)3280 ipmi_sensor_get_event_reading_type_string(ipmi_sensor_t *sensor)
3281 {
3282 CHECK_SENSOR_LOCK(sensor);
3283
3284 return sensor->event_reading_type_string;
3285 }
3286
3287 void
ipmi_sensor_set_event_reading_type_string(ipmi_sensor_t * sensor,const char * str)3288 ipmi_sensor_set_event_reading_type_string(ipmi_sensor_t *sensor,
3289 const char *str)
3290 {
3291 sensor->event_reading_type_string = str;
3292 }
3293
3294 const char *
ipmi_sensor_get_rate_unit_string(ipmi_sensor_t * sensor)3295 ipmi_sensor_get_rate_unit_string(ipmi_sensor_t *sensor)
3296 {
3297 CHECK_SENSOR_LOCK(sensor);
3298
3299 return sensor->rate_unit_string;
3300 }
3301
3302 void
ipmi_sensor_set_rate_unit_string(ipmi_sensor_t * sensor,const char * str)3303 ipmi_sensor_set_rate_unit_string(ipmi_sensor_t *sensor,
3304 const char *str)
3305 {
3306 sensor->rate_unit_string = str;
3307 }
3308
3309 const char *
ipmi_sensor_get_base_unit_string(ipmi_sensor_t * sensor)3310 ipmi_sensor_get_base_unit_string(ipmi_sensor_t *sensor)
3311 {
3312 CHECK_SENSOR_LOCK(sensor);
3313
3314 return sensor->base_unit_string;
3315 }
3316
3317 void
ipmi_sensor_set_base_unit_string(ipmi_sensor_t * sensor,const char * str)3318 ipmi_sensor_set_base_unit_string(ipmi_sensor_t *sensor, const char *str)
3319 {
3320 sensor->base_unit_string = str;
3321 }
3322
3323 const char *
ipmi_sensor_get_modifier_unit_string(ipmi_sensor_t * sensor)3324 ipmi_sensor_get_modifier_unit_string(ipmi_sensor_t *sensor)
3325 {
3326 CHECK_SENSOR_LOCK(sensor);
3327
3328 return sensor->modifier_unit_string;
3329 }
3330
3331 void
ipmi_sensor_set_modifier_unit_string(ipmi_sensor_t * sensor,const char * str)3332 ipmi_sensor_set_modifier_unit_string(ipmi_sensor_t *sensor, const char *str)
3333 {
3334 sensor->modifier_unit_string = str;
3335 }
3336
3337 void
ipmi_sensor_set_hot_swap_requester(ipmi_sensor_t * sensor,int offset,int val_when_requesting)3338 ipmi_sensor_set_hot_swap_requester(ipmi_sensor_t *sensor,
3339 int offset,
3340 int val_when_requesting)
3341 {
3342 sensor->hot_swap_requester = offset;
3343 sensor->hot_swap_requester_val = val_when_requesting;
3344 }
3345
3346 int
ipmi_sensor_is_hot_swap_requester(ipmi_sensor_t * sensor,int * offset,int * val_when_requesting)3347 ipmi_sensor_is_hot_swap_requester(ipmi_sensor_t *sensor,
3348 int *offset,
3349 int *val_when_requesting)
3350 {
3351 CHECK_SENSOR_LOCK(sensor);
3352
3353 if (sensor->hot_swap_requester != -1) {
3354 if (offset)
3355 *offset = sensor->hot_swap_requester;
3356 if (val_when_requesting)
3357 *val_when_requesting = sensor->hot_swap_requester_val;
3358 return 1;
3359 }
3360 return 0;
3361 }
3362
3363 ipmi_domain_t *
ipmi_sensor_get_domain(ipmi_sensor_t * sensor)3364 ipmi_sensor_get_domain(ipmi_sensor_t *sensor)
3365 {
3366 return sensor->domain;
3367 }
3368
3369 ipmi_entity_t *
ipmi_sensor_get_entity(ipmi_sensor_t * sensor)3370 ipmi_sensor_get_entity(ipmi_sensor_t *sensor)
3371 {
3372 return sensor->entity;
3373 }
3374
3375
3376 /***********************************************************************
3377 *
3378 * Incoming event handling for sensors.
3379 *
3380 **********************************************************************/
3381
3382 int
ipmi_sensor_threshold_set_event_handler(ipmi_sensor_t * sensor,ipmi_sensor_threshold_event_handler_nd_cb handler,void * cb_data)3383 ipmi_sensor_threshold_set_event_handler(
3384 ipmi_sensor_t *sensor,
3385 ipmi_sensor_threshold_event_handler_nd_cb handler,
3386 void *cb_data)
3387 {
3388 CHECK_SENSOR_LOCK(sensor);
3389
3390 sensor->threshold_event_handler = handler;
3391 sensor->cb_data = cb_data;
3392 return 0;
3393 }
3394
3395 int
ipmi_sensor_add_threshold_event_handler(ipmi_sensor_t * sensor,ipmi_sensor_threshold_event_cb handler,void * cb_data)3396 ipmi_sensor_add_threshold_event_handler(
3397 ipmi_sensor_t *sensor,
3398 ipmi_sensor_threshold_event_cb handler,
3399 void *cb_data)
3400 {
3401 CHECK_SENSOR_LOCK(sensor);
3402
3403 if (! locked_list_add(sensor->handler_list, handler, cb_data))
3404 return ENOMEM;
3405
3406 return 0;
3407 }
3408
3409 int
ipmi_sensor_remove_threshold_event_handler(ipmi_sensor_t * sensor,ipmi_sensor_threshold_event_cb handler,void * cb_data)3410 ipmi_sensor_remove_threshold_event_handler(
3411 ipmi_sensor_t *sensor,
3412 ipmi_sensor_threshold_event_cb handler,
3413 void *cb_data)
3414 {
3415 CHECK_SENSOR_LOCK(sensor);
3416
3417 if (! locked_list_remove(sensor->handler_list, handler, cb_data))
3418 return ENOENT;
3419
3420 return 0;
3421 }
3422
3423 int
ipmi_sensor_add_threshold_event_handler_cl(ipmi_sensor_t * sensor,ipmi_sensor_threshold_event_cl_cb handler,void * cb_data)3424 ipmi_sensor_add_threshold_event_handler_cl(
3425 ipmi_sensor_t *sensor,
3426 ipmi_sensor_threshold_event_cl_cb handler,
3427 void *cb_data)
3428 {
3429 CHECK_SENSOR_LOCK(sensor);
3430
3431 if (! locked_list_add(sensor->handler_list_cl, handler, cb_data))
3432 return ENOMEM;
3433
3434 return 0;
3435 }
3436
3437 int
ipmi_sensor_remove_threshold_event_handler_cl(ipmi_sensor_t * sensor,ipmi_sensor_threshold_event_cl_cb handler,void * cb_data)3438 ipmi_sensor_remove_threshold_event_handler_cl(
3439 ipmi_sensor_t *sensor,
3440 ipmi_sensor_threshold_event_cl_cb handler,
3441 void *cb_data)
3442 {
3443 CHECK_SENSOR_LOCK(sensor);
3444
3445 if (! locked_list_remove(sensor->handler_list_cl, handler, cb_data))
3446 return ENOENT;
3447
3448 return 0;
3449 }
3450
3451
3452 int
ipmi_sensor_discrete_set_event_handler(ipmi_sensor_t * sensor,ipmi_sensor_discrete_event_handler_nd_cb handler,void * cb_data)3453 ipmi_sensor_discrete_set_event_handler(
3454 ipmi_sensor_t *sensor,
3455 ipmi_sensor_discrete_event_handler_nd_cb handler,
3456 void *cb_data)
3457 {
3458 CHECK_SENSOR_LOCK(sensor);
3459
3460 sensor->discrete_event_handler = handler;
3461 sensor->cb_data = cb_data;
3462 return 0;
3463 }
3464
3465 int
ipmi_sensor_add_discrete_event_handler(ipmi_sensor_t * sensor,ipmi_sensor_discrete_event_cb handler,void * cb_data)3466 ipmi_sensor_add_discrete_event_handler(
3467 ipmi_sensor_t *sensor,
3468 ipmi_sensor_discrete_event_cb handler,
3469 void *cb_data)
3470 {
3471 CHECK_SENSOR_LOCK(sensor);
3472
3473 if (! locked_list_add(sensor->handler_list, handler, cb_data))
3474 return ENOMEM;
3475
3476 return 0;
3477 }
3478
3479 int
ipmi_sensor_remove_discrete_event_handler(ipmi_sensor_t * sensor,ipmi_sensor_discrete_event_cb handler,void * cb_data)3480 ipmi_sensor_remove_discrete_event_handler(
3481 ipmi_sensor_t *sensor,
3482 ipmi_sensor_discrete_event_cb handler,
3483 void *cb_data)
3484 {
3485 CHECK_SENSOR_LOCK(sensor);
3486
3487 if (! locked_list_remove(sensor->handler_list, handler, cb_data))
3488 return ENOENT;
3489
3490 return 0;
3491 }
3492
3493 int
ipmi_sensor_add_discrete_event_handler_cl(ipmi_sensor_t * sensor,ipmi_sensor_discrete_event_cl_cb handler,void * cb_data)3494 ipmi_sensor_add_discrete_event_handler_cl(
3495 ipmi_sensor_t *sensor,
3496 ipmi_sensor_discrete_event_cl_cb handler,
3497 void *cb_data)
3498 {
3499 CHECK_SENSOR_LOCK(sensor);
3500
3501 if (! locked_list_add(sensor->handler_list_cl, handler, cb_data))
3502 return ENOMEM;
3503
3504 return 0;
3505 }
3506
3507 int
ipmi_sensor_remove_discrete_event_handler_cl(ipmi_sensor_t * sensor,ipmi_sensor_discrete_event_cl_cb handler,void * cb_data)3508 ipmi_sensor_remove_discrete_event_handler_cl(
3509 ipmi_sensor_t *sensor,
3510 ipmi_sensor_discrete_event_cl_cb handler,
3511 void *cb_data)
3512 {
3513 CHECK_SENSOR_LOCK(sensor);
3514
3515 if (! locked_list_remove(sensor->handler_list_cl, handler, cb_data))
3516 return ENOENT;
3517
3518 return 0;
3519 }
3520
3521 typedef struct sensor_event_info_s
3522 {
3523 ipmi_sensor_t *sensor;
3524 int handled;
3525
3526 enum ipmi_event_dir_e dir;
3527 enum ipmi_thresh_e threshold;
3528 enum ipmi_event_value_dir_e high_low;
3529 enum ipmi_value_present_e value_present;
3530 unsigned int raw_value;
3531 double value;
3532
3533 int offset;
3534 int severity;
3535 int prev_severity;
3536
3537 ipmi_event_t *event;
3538 } sensor_event_info_t;
3539
3540 static int
threshold_sensor_event_call_handler(void * cb_data,void * item1,void * item2)3541 threshold_sensor_event_call_handler(void *cb_data, void *item1, void *item2)
3542 {
3543 ipmi_sensor_threshold_event_cb handler = item1;
3544 sensor_event_info_t *info = cb_data;
3545 int handled;
3546
3547 handled = handler(info->sensor, info->dir,
3548 info->threshold,
3549 info->high_low,
3550 info->value_present,
3551 info->raw_value, info->value,
3552 item2, info->event);
3553 if (handled != IPMI_EVENT_NOT_HANDLED) {
3554 if (info->handled != IPMI_EVENT_HANDLED)
3555 /* Allow handled to override handled_pass, but not the
3556 other way. */
3557 info->handled = handled;
3558 if (handled == IPMI_EVENT_HANDLED)
3559 info->event = NULL;
3560 }
3561 return LOCKED_LIST_ITER_CONTINUE;
3562 }
3563
3564 void
ipmi_sensor_call_threshold_event_handlers(ipmi_sensor_t * sensor,enum ipmi_event_dir_e dir,enum ipmi_thresh_e threshold,enum ipmi_event_value_dir_e high_low,enum ipmi_value_present_e value_present,unsigned int raw_value,double value,ipmi_event_t ** event,int * handled)3565 ipmi_sensor_call_threshold_event_handlers
3566 (ipmi_sensor_t *sensor,
3567 enum ipmi_event_dir_e dir,
3568 enum ipmi_thresh_e threshold,
3569 enum ipmi_event_value_dir_e high_low,
3570 enum ipmi_value_present_e value_present,
3571 unsigned int raw_value,
3572 double value,
3573 ipmi_event_t **event,
3574 int *handled)
3575 {
3576 sensor_event_info_t info;
3577
3578 info.sensor = sensor;
3579 info.dir = dir;
3580 info.threshold = threshold;
3581 info.high_low = high_low;
3582 info.value_present = value_present;
3583 info.raw_value = raw_value;
3584 info.value = value;
3585 info.event = *event;
3586 if (handled)
3587 info.handled = *handled;
3588 else
3589 info.handled = IPMI_EVENT_NOT_HANDLED;
3590
3591 if (sensor->threshold_event_handler) {
3592 sensor->threshold_event_handler(sensor, info.dir,
3593 info.threshold,
3594 info.high_low,
3595 info.value_present,
3596 info.raw_value, info.value,
3597 sensor->cb_data, info.event);
3598 if (info.event)
3599 info.handled = IPMI_EVENT_HANDLED;
3600 info.event = NULL;
3601 }
3602 locked_list_iterate(sensor->handler_list,
3603 threshold_sensor_event_call_handler, &info);
3604
3605 if (handled)
3606 *handled = info.handled;
3607 *event = info.event;
3608 }
3609
3610 static int
discrete_sensor_event_call_handler(void * cb_data,void * item1,void * item2)3611 discrete_sensor_event_call_handler(void *cb_data, void *item1, void *item2)
3612 {
3613 ipmi_sensor_discrete_event_cb handler = item1;
3614 sensor_event_info_t *info = cb_data;
3615 int handled;
3616
3617 handled = handler(info->sensor, info->dir, info->offset,
3618 info->severity,
3619 info->prev_severity,
3620 item2, info->event);
3621 if (handled != IPMI_EVENT_NOT_HANDLED) {
3622 if (info->handled != IPMI_EVENT_HANDLED)
3623 /* Allow handled to override handled_pass, but not the
3624 other way. */
3625 info->handled = handled;
3626 if (handled == IPMI_EVENT_HANDLED)
3627 info->event = NULL;
3628 }
3629 return LOCKED_LIST_ITER_CONTINUE;
3630 }
3631
3632 void
ipmi_sensor_call_discrete_event_handlers(ipmi_sensor_t * sensor,enum ipmi_event_dir_e dir,int offset,int severity,int prev_severity,ipmi_event_t ** event,int * handled)3633 ipmi_sensor_call_discrete_event_handlers(ipmi_sensor_t *sensor,
3634 enum ipmi_event_dir_e dir,
3635 int offset,
3636 int severity,
3637 int prev_severity,
3638 ipmi_event_t **event,
3639 int *handled)
3640 {
3641 sensor_event_info_t info;
3642
3643 info.sensor = sensor;
3644 info.dir = dir;
3645 info.offset = offset;
3646 info.severity = severity;
3647 info.prev_severity = prev_severity;
3648 info.event = *event;
3649 if (handled)
3650 info.handled = *handled;
3651 else
3652 info.handled = IPMI_EVENT_NOT_HANDLED;
3653
3654 if (sensor->discrete_event_handler) {
3655 sensor->discrete_event_handler(sensor, info.dir, info.offset,
3656 info.severity,
3657 info.prev_severity,
3658 sensor->cb_data, info.event);
3659 if (info.event)
3660 info.handled = IPMI_EVENT_HANDLED;
3661 info.event = NULL;
3662 }
3663 locked_list_iterate(sensor->handler_list,
3664 discrete_sensor_event_call_handler, &info);
3665
3666 if (handled)
3667 *handled = info.handled;
3668 *event = info.event;
3669 }
3670
3671 int
ipmi_sensor_event(ipmi_sensor_t * sensor,ipmi_event_t * event)3672 ipmi_sensor_event(ipmi_sensor_t *sensor, ipmi_event_t *event)
3673 {
3674 int rv;
3675 int handled;
3676
3677 CHECK_SENSOR_LOCK(sensor);
3678
3679 handled = IPMI_EVENT_NOT_HANDLED;
3680
3681 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD) {
3682 enum ipmi_event_dir_e dir;
3683 enum ipmi_thresh_e threshold;
3684 enum ipmi_event_value_dir_e high_low;
3685 enum ipmi_value_present_e value_present;
3686 unsigned int raw_value;
3687 double value;
3688 const unsigned char *data;
3689
3690 data = ipmi_event_get_data_ptr(event);
3691 dir = data[9] >> 7;
3692 threshold = (data[10] >> 1) & 0x07;
3693 high_low = data[10] & 1;
3694 raw_value = data[11];
3695 value = 0.0;
3696
3697 if ((data[10] >> 6) == 1) {
3698 rv = ipmi_sensor_convert_from_raw(sensor, raw_value, &value);
3699 if (rv)
3700 value_present = IPMI_RAW_VALUE_PRESENT;
3701 else
3702 value_present = IPMI_BOTH_VALUES_PRESENT;
3703 } else {
3704 value_present = IPMI_NO_VALUES_PRESENT;
3705 }
3706 ipmi_sensor_call_threshold_event_handlers(sensor, dir,
3707 threshold,
3708 high_low,
3709 value_present,
3710 raw_value, value,
3711 &event,
3712 &handled);
3713 } else {
3714 enum ipmi_event_dir_e dir;
3715 int offset;
3716 int severity = 0;
3717 int prev_severity = 0;
3718 const unsigned char *data;
3719
3720 data = ipmi_event_get_data_ptr(event);
3721 dir = data[9] >> 7;
3722 offset = data[10] & 0x0f;
3723 if ((data[10] >> 6) == 2) {
3724 severity = data[11] >> 4;
3725 prev_severity = data[11] & 0xf;
3726 if (severity == 0xf)
3727 severity = -1;
3728 if (prev_severity == 0xf)
3729 prev_severity = -1;
3730 }
3731
3732 ipmi_sensor_call_discrete_event_handlers(sensor, dir, offset,
3733 severity,
3734 prev_severity,
3735 &event,
3736 &handled);
3737 }
3738
3739 /* Make sure the caller knows if we didn't deliver the event. */
3740 if (handled == IPMI_EVENT_NOT_HANDLED)
3741 return EINVAL;
3742 return 0;
3743 }
3744
3745 /***********************************************************************
3746 *
3747 * Standard sensor messaging.
3748 *
3749 **********************************************************************/
3750
3751 typedef void (*sensor_done_handler_cb)(ipmi_sensor_t *sensor,
3752 int err,
3753 void *sinfo);
3754
3755 static int
sensor_done_check_rsp(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,unsigned int min_length,char * name,sensor_done_handler_cb done,void * sinfo)3756 sensor_done_check_rsp(ipmi_sensor_t *sensor,
3757 int err,
3758 ipmi_msg_t *rsp,
3759 unsigned int min_length,
3760 char *name,
3761 sensor_done_handler_cb done,
3762 void *sinfo)
3763 {
3764 if (err) {
3765 ipmi_log(IPMI_LOG_ERR_INFO,
3766 "%ssensor.c(%s): Got error: %x",
3767 SENSOR_NAME(sensor), name, err);
3768 done(sensor, err, sinfo);
3769 return err;
3770 }
3771
3772 if (!sensor) {
3773 /* This *should* never happen, but we check it to shake out
3774 bugs. */
3775 ipmi_log(IPMI_LOG_ERR_INFO,
3776 "%ssensor.c(%s): Sensor when away during operation",
3777 SENSOR_NAME(sensor), name);
3778 done(sensor, ECANCELED, sinfo);
3779 return ECANCELED;
3780 }
3781
3782 if (rsp && rsp->data[0]) {
3783 #if 0
3784 /* This is sometimes expected. */
3785 ipmi_log(IPMI_LOG_ERR_INFO,
3786 "%ssensor.c(%s): Got IPMI error in response: %x",
3787 SENSOR_NAME(sensor), name, rsp->data[0]);
3788 #endif
3789 done(sensor, IPMI_IPMI_ERR_VAL(rsp->data[0]), sinfo);
3790 return IPMI_IPMI_ERR_VAL(rsp->data[0]);
3791 }
3792
3793 if (rsp && (rsp->data_len < min_length)) {
3794 ipmi_log(IPMI_LOG_ERR_INFO,
3795 "%ssensor.c(%s): Response was too short, got %d, expected %d",
3796 SENSOR_NAME(sensor), name, rsp->data_len, min_length);
3797 done(sensor, EINVAL, sinfo);
3798 return EINVAL;
3799 }
3800
3801 return 0;
3802 }
3803
3804 typedef struct event_enable_info_s
3805 {
3806 ipmi_sensor_op_info_t sdata;
3807 ipmi_event_state_t state;
3808 ipmi_sensor_done_cb done;
3809 void *cb_data;
3810 int do_enable;
3811 int do_disable;
3812 } event_enable_info_t;
3813
enables_done_handler(ipmi_sensor_t * sensor,int err,void * sinfo)3814 static void enables_done_handler(ipmi_sensor_t *sensor,
3815 int err,
3816 void *sinfo)
3817 {
3818 event_enable_info_t *info = sinfo;
3819
3820 if (info->done)
3821 info->done(sensor, err, info->cb_data);
3822 ipmi_sensor_opq_done(sensor);
3823 ipmi_mem_free(info);
3824 }
3825
3826 static void
disables_set(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,void * cb_data)3827 disables_set(ipmi_sensor_t *sensor,
3828 int err,
3829 ipmi_msg_t *rsp,
3830 void *cb_data)
3831 {
3832 event_enable_info_t *info = cb_data;
3833
3834 if (sensor_done_check_rsp(sensor, err, rsp, 1, "disables_set",
3835 enables_done_handler, info))
3836 return;
3837
3838 enables_done_handler(sensor, 0, info);
3839 }
3840
3841 static void
enables_set(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,void * cb_data)3842 enables_set(ipmi_sensor_t *sensor,
3843 int err,
3844 ipmi_msg_t *rsp,
3845 void *cb_data)
3846 {
3847 event_enable_info_t *info = cb_data;
3848 unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
3849 ipmi_msg_t cmd_msg;
3850 int rv;
3851
3852 if (sensor_done_check_rsp(sensor, err, rsp, 1, "enables_set",
3853 enables_done_handler, info))
3854 return;
3855
3856 if (info->do_disable) {
3857 /* Enables were set, now disable all the other ones. Make
3858 sure we only set event bits that we support. */
3859 uint16_t val1, val2;
3860
3861 cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
3862 cmd_msg.cmd = IPMI_SET_SENSOR_EVENT_ENABLE_CMD;
3863 cmd_msg.data_len = 6;
3864 cmd_msg.data = cmd_data;
3865 cmd_data[0] = sensor->num;
3866 cmd_data[1] = (info->state.status & 0xc0) | (0x02 << 4);
3867 ipmi_sensor_get_event_masks(sensor, &val1, &val2);
3868 val1 &= ~info->state.__assertion_events;
3869 val2 &= ~info->state.__deassertion_events;
3870 ipmi_set_uint16(cmd_data+2, val1);
3871 ipmi_set_uint16(cmd_data+4, val2);
3872 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
3873 &cmd_msg, disables_set,
3874 &(info->sdata), info);
3875 if (rv) {
3876 ipmi_log(IPMI_LOG_ERR_INFO,
3877 "%ssensors.c(enables_set):"
3878 " Error sending event enable command to clear events: %x",
3879 SENSOR_NAME(sensor), rv);
3880 enables_done_handler(sensor, rv, info);
3881 }
3882 } else {
3883 /* Just doing enables, we are done. */
3884 enables_done_handler(sensor, 0, info);
3885 }
3886 }
3887
3888 static void
event_enable_set_start(ipmi_sensor_t * sensor,int err,void * cb_data)3889 event_enable_set_start(ipmi_sensor_t *sensor, int err, void *cb_data)
3890 {
3891 event_enable_info_t *info = cb_data;
3892 unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
3893 ipmi_msg_t cmd_msg;
3894 int event_support;
3895 int rv;
3896
3897 if (sensor_done_check_rsp(sensor, err, NULL, 0, "event_enable_set_start",
3898 enables_done_handler, info))
3899 return;
3900
3901 event_support = ipmi_sensor_get_event_support(sensor);
3902
3903 cmd_msg.data = cmd_data;
3904 cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
3905 cmd_msg.cmd = IPMI_SET_SENSOR_EVENT_ENABLE_CMD;
3906 cmd_msg.data = cmd_data;
3907 cmd_data[0] = sensor->num;
3908 if (event_support == IPMI_EVENT_SUPPORT_ENTIRE_SENSOR) {
3909 /* We can only turn on/off the entire sensor, just pass the
3910 status to the sensor. */
3911 cmd_data[1] = info->state.status & 0xc0;
3912 cmd_msg.data_len = 2;
3913 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
3914 &cmd_msg, disables_set, &(info->sdata),
3915 info);
3916 } else if (info->do_enable) {
3917 /* Start by first setting the enables, then set the disables
3918 in a second operation. We do this because enables and
3919 disables cannot both be set at the same time, and it's
3920 safer to first enable the new events then to disable the
3921 events we want disabled. It would be *really* nice if IPMI
3922 had a way to do this in one operation, such as using 11b in
3923 the request byte 2 bits 5:4 to say "set the events to
3924 exactly this state". */
3925 cmd_data[1] = (info->state.status & 0xc0) | (0x01 << 4);
3926 cmd_data[2] = info->state.__assertion_events & 0xff;
3927 cmd_data[3] = info->state.__assertion_events >> 8;
3928 cmd_data[4] = info->state.__deassertion_events & 0xff;
3929 cmd_data[5] = info->state.__deassertion_events >> 8;
3930 cmd_msg.data_len = 6;
3931 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
3932 &cmd_msg, enables_set, &(info->sdata),
3933 info);
3934 } else {
3935 /* We are only doing disables. */
3936 cmd_data[1] = (info->state.status & 0xc0) | (0x02 << 4);
3937 cmd_data[2] = info->state.__assertion_events & 0xff;
3938 cmd_data[3] = info->state.__assertion_events >> 8;
3939 cmd_data[4] = info->state.__deassertion_events & 0xff;
3940 cmd_data[5] = info->state.__deassertion_events >> 8;
3941 cmd_msg.data_len = 6;
3942 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
3943 &cmd_msg, disables_set,
3944 &(info->sdata), info);
3945 }
3946 if (rv) {
3947 ipmi_log(IPMI_LOG_ERR_INFO,
3948 "%ssensor.c(event_enable_set_start):"
3949 " Error sending event enable command: %x",
3950 SENSOR_NAME(sensor), rv);
3951 enables_done_handler(sensor, rv, info);
3952 }
3953 }
3954
3955 static int
check_events_capability(ipmi_sensor_t * sensor,ipmi_event_state_t * states)3956 check_events_capability(ipmi_sensor_t *sensor,
3957 ipmi_event_state_t *states)
3958 {
3959 int event_support;
3960
3961 event_support = ipmi_sensor_get_event_support(sensor);
3962 if ((event_support == IPMI_EVENT_SUPPORT_NONE)
3963 || (event_support == IPMI_EVENT_SUPPORT_GLOBAL_ENABLE))
3964 {
3965 /* We don't support setting events for this sensor. */
3966 return EINVAL;
3967 }
3968
3969 if ((event_support == IPMI_EVENT_SUPPORT_ENTIRE_SENSOR)
3970 && ((states->__assertion_events != 0)
3971 || (states->__deassertion_events != 0)))
3972 {
3973 /* This sensor does not support individual event states, but
3974 the user is trying to set them. */
3975 return EINVAL;
3976 }
3977
3978 if (event_support == IPMI_EVENT_SUPPORT_PER_STATE) {
3979 uint16_t mask1, mask2;
3980
3981 ipmi_sensor_get_event_masks(sensor, &mask1, &mask2);
3982 if (((~mask1) & states->__assertion_events)
3983 || ((~mask2) & states->__deassertion_events))
3984 {
3985 /* The user is attempting to set a state that the
3986 sensor does not support. */
3987 return EINVAL;
3988 }
3989 }
3990
3991 return 0;
3992 }
3993
3994 static int
stand_ipmi_sensor_set_event_enables(ipmi_sensor_t * sensor,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)3995 stand_ipmi_sensor_set_event_enables(ipmi_sensor_t *sensor,
3996 ipmi_event_state_t *states,
3997 ipmi_sensor_done_cb done,
3998 void *cb_data)
3999 {
4000 event_enable_info_t *info;
4001 int rv;
4002
4003 rv = check_events_capability(sensor, states);
4004 if (rv)
4005 return rv;
4006
4007 info = ipmi_mem_alloc(sizeof(*info));
4008 if (!info)
4009 return ENOMEM;
4010 info->state = *states;
4011 info->done = done;
4012 info->cb_data = cb_data;
4013 info->do_enable = 1;
4014 info->do_disable = 1;
4015 rv = ipmi_sensor_add_opq(sensor, event_enable_set_start,
4016 &(info->sdata), info);
4017 if (rv)
4018 ipmi_mem_free(info);
4019 return rv;
4020 }
4021
4022 static int
stand_ipmi_sensor_enable_events(ipmi_sensor_t * sensor,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)4023 stand_ipmi_sensor_enable_events(ipmi_sensor_t *sensor,
4024 ipmi_event_state_t *states,
4025 ipmi_sensor_done_cb done,
4026 void *cb_data)
4027 {
4028 event_enable_info_t *info;
4029 int rv;
4030
4031 rv = check_events_capability(sensor, states);
4032 if (rv)
4033 return rv;
4034
4035 info = ipmi_mem_alloc(sizeof(*info));
4036 if (!info)
4037 return ENOMEM;
4038 info->state = *states;
4039 info->done = done;
4040 info->cb_data = cb_data;
4041 info->do_enable = 1;
4042 info->do_disable = 0;
4043 rv = ipmi_sensor_add_opq(sensor, event_enable_set_start,
4044 &(info->sdata), info);
4045 if (rv)
4046 ipmi_mem_free(info);
4047 return rv;
4048 }
4049
4050 static int
stand_ipmi_sensor_disable_events(ipmi_sensor_t * sensor,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)4051 stand_ipmi_sensor_disable_events(ipmi_sensor_t *sensor,
4052 ipmi_event_state_t *states,
4053 ipmi_sensor_done_cb done,
4054 void *cb_data)
4055 {
4056 event_enable_info_t *info;
4057 int rv;
4058
4059 rv = check_events_capability(sensor, states);
4060 if (rv)
4061 return rv;
4062
4063 info = ipmi_mem_alloc(sizeof(*info));
4064 if (!info)
4065 return ENOMEM;
4066 info->state = *states;
4067 info->done = done;
4068 info->cb_data = cb_data;
4069 info->do_enable = 0;
4070 info->do_disable = 1;
4071 rv = ipmi_sensor_add_opq(sensor, event_enable_set_start,
4072 &(info->sdata), info);
4073 if (rv)
4074 ipmi_mem_free(info);
4075 return rv;
4076 }
4077
4078 typedef struct event_enable_get_info_s
4079 {
4080 ipmi_sensor_op_info_t sdata;
4081 ipmi_event_state_t state;
4082 ipmi_sensor_event_enables_cb done;
4083 void *cb_data;
4084 } event_enable_get_info_t;
4085
enables_get_done_handler(ipmi_sensor_t * sensor,int err,void * sinfo)4086 static void enables_get_done_handler(ipmi_sensor_t *sensor,
4087 int err,
4088 void *sinfo)
4089 {
4090 event_enable_get_info_t *info = sinfo;
4091
4092 if (info->done)
4093 info->done(sensor, err, &info->state, info->cb_data);
4094 ipmi_sensor_opq_done(sensor);
4095 ipmi_mem_free(info);
4096 }
4097
4098 static void
enables_get(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,void * cb_data)4099 enables_get(ipmi_sensor_t *sensor,
4100 int err,
4101 ipmi_msg_t *rsp,
4102 void *cb_data)
4103 {
4104 event_enable_get_info_t *info = cb_data;
4105
4106 if (sensor_done_check_rsp(sensor, err, rsp, 2, "enables_get",
4107 enables_get_done_handler, info))
4108 return;
4109
4110 info->state.status = rsp->data[1] & 0xc0;
4111 if (rsp->data_len >= 3)
4112 info->state.__assertion_events = rsp->data[2];
4113 if (rsp->data_len >= 4)
4114 info->state.__assertion_events |= rsp->data[3] << 8;
4115 if (rsp->data_len >= 5)
4116 info->state.__deassertion_events = rsp->data[4];
4117 if (rsp->data_len >= 6)
4118 info->state.__deassertion_events |= rsp->data[5] << 8;
4119
4120 /* Mask off reserved bits */
4121 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD) {
4122 info->state.__assertion_events &= 0x0fff;
4123 info->state.__deassertion_events &= 0x0fff;
4124 } else {
4125 info->state.__assertion_events &= 0x7fff;
4126 info->state.__deassertion_events &= 0x7fff;
4127 }
4128
4129 /* It is possible that there are events set here that are not in
4130 sensor->mask1 (assertion events) or sensor->mask2 (deassertion
4131 events). That's a bug in the sensor; it shouldn't be setting
4132 those bits. If it ever comes to the point where we need to
4133 handle that here, a simple mask operation would do it. */
4134
4135 enables_get_done_handler(sensor, 0, info);
4136 }
4137
4138 static void
event_enable_get_start(ipmi_sensor_t * sensor,int err,void * cb_data)4139 event_enable_get_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4140 {
4141 event_enable_get_info_t *info = cb_data;
4142 unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4143 ipmi_msg_t cmd_msg;
4144 int rv;
4145
4146 if (sensor_done_check_rsp(sensor, err, NULL, 0, "event_enable_get_start",
4147 enables_get_done_handler, info))
4148 return;
4149
4150 cmd_msg.data = cmd_data;
4151 cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4152 cmd_msg.cmd = IPMI_GET_SENSOR_EVENT_ENABLE_CMD;
4153 cmd_msg.data_len = 1;
4154 cmd_msg.data = cmd_data;
4155 cmd_data[0] = sensor->num;
4156 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4157 &cmd_msg, enables_get, &(info->sdata), info);
4158 if (rv) {
4159 ipmi_log(IPMI_LOG_ERR_INFO,
4160 "%ssensor.c(event_enable_get_start):"
4161 " Error sending get event enables command: %x",
4162 SENSOR_NAME(sensor), rv);
4163 enables_get_done_handler(sensor, rv, info);
4164 }
4165 }
4166
4167 static int
stand_ipmi_sensor_get_event_enables(ipmi_sensor_t * sensor,ipmi_sensor_event_enables_cb done,void * cb_data)4168 stand_ipmi_sensor_get_event_enables(ipmi_sensor_t *sensor,
4169 ipmi_sensor_event_enables_cb done,
4170 void *cb_data)
4171 {
4172 event_enable_get_info_t *info;
4173 int rv;
4174
4175 info = ipmi_mem_alloc(sizeof(*info));
4176 if (!info)
4177 return ENOMEM;
4178 memset(info, 0, sizeof(*info));
4179 info->done = done;
4180 info->cb_data = cb_data;
4181 rv = ipmi_sensor_add_opq(sensor, event_enable_get_start,
4182 &(info->sdata), info);
4183 if (rv)
4184 ipmi_mem_free(info);
4185 return rv;
4186 }
4187
4188 typedef struct sensor_rearm_info_s
4189 {
4190 ipmi_sensor_op_info_t sdata;
4191 ipmi_event_state_t state;
4192 int global_enable;
4193 ipmi_sensor_done_cb done;
4194 void *cb_data;
4195 } sensor_rearm_info_t;
4196
sensor_rearm_done_handler(ipmi_sensor_t * sensor,int err,void * sinfo)4197 static void sensor_rearm_done_handler(ipmi_sensor_t *sensor,
4198 int err,
4199 void *sinfo)
4200 {
4201 sensor_rearm_info_t *info = sinfo;
4202
4203 if (info->done)
4204 info->done(sensor, err, info->cb_data);
4205 ipmi_sensor_opq_done(sensor);
4206 ipmi_mem_free(info);
4207 }
4208
4209 static void
sensor_rearm(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,void * cb_data)4210 sensor_rearm(ipmi_sensor_t *sensor,
4211 int err,
4212 ipmi_msg_t *rsp,
4213 void *cb_data)
4214 {
4215 sensor_rearm_info_t *info = cb_data;
4216
4217 if (sensor_done_check_rsp(sensor, err, rsp, 1, "sensor_rearm",
4218 sensor_rearm_done_handler, info))
4219 return;
4220
4221 sensor_rearm_done_handler(sensor, 0, info);
4222 }
4223
4224 static void
sensor_rearm_start(ipmi_sensor_t * sensor,int err,void * cb_data)4225 sensor_rearm_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4226 {
4227 sensor_rearm_info_t *info = cb_data;
4228 unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4229 ipmi_msg_t cmd_msg;
4230 int rv;
4231
4232 if (sensor_done_check_rsp(sensor, err, NULL, 0, "sensor_rearm_start",
4233 sensor_rearm_done_handler, info))
4234 return;
4235
4236 cmd_msg.data = cmd_data;
4237 cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4238 cmd_msg.cmd = IPMI_REARM_SENSOR_EVENTS_CMD;
4239 if (info->global_enable) {
4240 cmd_msg.data_len = 2;
4241 cmd_msg.data = cmd_data;
4242 cmd_data[0] = sensor->num;
4243 cmd_data[1] = 0; /* Rearm all events. */
4244 } else {
4245 cmd_msg.data_len = 6;
4246 cmd_msg.data = cmd_data;
4247 cmd_data[0] = sensor->num;
4248 cmd_data[1] = 0x80; /* Rearm only specific sensors. */
4249 cmd_data[2] = info->state.__assertion_events & 0xff;
4250 cmd_data[3] = info->state.__assertion_events >> 8;
4251 cmd_data[4] = info->state.__deassertion_events & 0xff;
4252 cmd_data[5] = info->state.__deassertion_events >> 8;
4253 }
4254 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4255 &cmd_msg, sensor_rearm,
4256 &(info->sdata), info);
4257 if (rv) {
4258 ipmi_log(IPMI_LOG_ERR_INFO,
4259 "%ssensor.c(sensor_rearm_start):"
4260 " Error sending rearm command: %x",
4261 SENSOR_NAME(sensor), rv);
4262 sensor_rearm_done_handler(sensor, rv, info);
4263 }
4264 }
4265
4266 static int
stand_ipmi_sensor_rearm(ipmi_sensor_t * sensor,int global_enable,ipmi_event_state_t * state,ipmi_sensor_done_cb done,void * cb_data)4267 stand_ipmi_sensor_rearm(ipmi_sensor_t *sensor,
4268 int global_enable,
4269 ipmi_event_state_t *state,
4270 ipmi_sensor_done_cb done,
4271 void *cb_data)
4272 {
4273 sensor_rearm_info_t *info;
4274 int rv;
4275
4276 if (!global_enable && !state)
4277 return EINVAL;
4278
4279 info = ipmi_mem_alloc(sizeof(*info));
4280 if (!info)
4281 return ENOMEM;
4282 info->done = done;
4283 info->cb_data = cb_data;
4284 info->global_enable = global_enable;
4285 if (state)
4286 memcpy(&info->state, state, sizeof(info->state));
4287 rv = ipmi_sensor_add_opq(sensor, sensor_rearm_start, &(info->sdata), info);
4288 if (rv)
4289 ipmi_mem_free(info);
4290 return rv;
4291 }
4292
4293 typedef struct hyst_get_info_s
4294 {
4295 ipmi_sensor_op_info_t sdata;
4296 ipmi_sensor_hysteresis_cb done;
4297 void *cb_data;
4298 unsigned int positive;
4299 unsigned int negative;
4300 } hyst_get_info_t;
4301
hyst_get_done_handler(ipmi_sensor_t * sensor,int err,void * sinfo)4302 static void hyst_get_done_handler(ipmi_sensor_t *sensor,
4303 int err,
4304 void *sinfo)
4305 {
4306 hyst_get_info_t *info = sinfo;
4307
4308 if (info->done)
4309 info->done(sensor, err, info->positive, info->negative, info->cb_data);
4310 ipmi_sensor_opq_done(sensor);
4311 ipmi_mem_free(info);
4312 }
4313
4314 static void
hyst_get(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,void * cb_data)4315 hyst_get(ipmi_sensor_t *sensor,
4316 int err,
4317 ipmi_msg_t *rsp,
4318 void *cb_data)
4319 {
4320 hyst_get_info_t *info = cb_data;
4321
4322 if (sensor_done_check_rsp(sensor, err, rsp, 3, "hyst_get",
4323 hyst_get_done_handler, info))
4324 return;
4325
4326 info->positive = rsp->data[1];
4327 info->negative = rsp->data[2];
4328 hyst_get_done_handler(sensor, 0, info);
4329 }
4330
4331 static void
hyst_get_start(ipmi_sensor_t * sensor,int err,void * cb_data)4332 hyst_get_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4333 {
4334 hyst_get_info_t *info = cb_data;
4335 unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4336 ipmi_msg_t cmd_msg;
4337 int rv;
4338
4339 if (sensor_done_check_rsp(sensor, err, NULL, 0, "hyst_get_start",
4340 hyst_get_done_handler, info))
4341 return;
4342
4343 cmd_msg.data = cmd_data;
4344 cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4345 cmd_msg.cmd = IPMI_GET_SENSOR_HYSTERESIS_CMD;
4346 cmd_msg.data_len = 2;
4347 cmd_msg.data = cmd_data;
4348 cmd_data[0] = sensor->num;
4349 cmd_data[1] = 0xff;
4350 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4351 &cmd_msg, hyst_get, &(info->sdata), info);
4352 if (rv) {
4353 ipmi_log(IPMI_LOG_ERR_INFO,
4354 "%ssensor.c(hyst_get_start):"
4355 " Error sending hysteresis get command: %x",
4356 SENSOR_NAME(sensor), rv);
4357 hyst_get_done_handler(sensor, rv, info);
4358 }
4359 }
4360
4361 static int
stand_ipmi_sensor_get_hysteresis(ipmi_sensor_t * sensor,ipmi_sensor_hysteresis_cb done,void * cb_data)4362 stand_ipmi_sensor_get_hysteresis(ipmi_sensor_t *sensor,
4363 ipmi_sensor_hysteresis_cb done,
4364 void *cb_data)
4365 {
4366 hyst_get_info_t *info;
4367 int rv;
4368
4369 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4370 /* Not a threshold sensor, it doesn't have readings. */
4371 return ENOSYS;
4372
4373 if ((sensor->hysteresis_support != IPMI_HYSTERESIS_SUPPORT_READABLE)
4374 && (sensor->hysteresis_support != IPMI_HYSTERESIS_SUPPORT_SETTABLE))
4375 return ENOSYS;
4376
4377 info = ipmi_mem_alloc(sizeof(*info));
4378 if (!info)
4379 return ENOMEM;
4380 memset(info, 0, sizeof(*info));
4381 info->done = done;
4382 info->cb_data = cb_data;
4383 rv = ipmi_sensor_add_opq(sensor, hyst_get_start, &(info->sdata), info);
4384 if (rv)
4385 ipmi_mem_free(info);
4386 return rv;
4387 }
4388
4389 typedef struct hyst_set_info_s
4390 {
4391 ipmi_sensor_op_info_t sdata;
4392 unsigned int positive, negative;
4393 ipmi_sensor_done_cb done;
4394 void *cb_data;
4395 } hyst_set_info_t;
4396
hyst_set_done_handler(ipmi_sensor_t * sensor,int err,void * sinfo)4397 static void hyst_set_done_handler(ipmi_sensor_t *sensor,
4398 int err,
4399 void *sinfo)
4400 {
4401 hyst_set_info_t *info = sinfo;
4402
4403 if (info->done)
4404 info->done(sensor, err, info->cb_data);
4405 ipmi_sensor_opq_done(sensor);
4406 ipmi_mem_free(info);
4407 }
4408
4409 static void
hyst_set(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,void * cb_data)4410 hyst_set(ipmi_sensor_t *sensor,
4411 int err,
4412 ipmi_msg_t *rsp,
4413 void *cb_data)
4414 {
4415 hyst_set_info_t *info = cb_data;
4416
4417 if (sensor_done_check_rsp(sensor, err, rsp, 1, "hyst_set",
4418 hyst_set_done_handler, info))
4419 return;
4420
4421 hyst_set_done_handler(sensor, 0, info);
4422 }
4423
4424 static void
hyst_set_start(ipmi_sensor_t * sensor,int err,void * cb_data)4425 hyst_set_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4426 {
4427 hyst_set_info_t *info = cb_data;
4428 unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4429 ipmi_msg_t cmd_msg;
4430 int rv;
4431
4432 if (sensor_done_check_rsp(sensor, err, NULL, 0, "hyst_set_start",
4433 hyst_set_done_handler, info))
4434 return;
4435
4436 cmd_msg.data = cmd_data;
4437 cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4438 cmd_msg.cmd = IPMI_SET_SENSOR_HYSTERESIS_CMD;
4439 cmd_msg.data_len = 4;
4440 cmd_msg.data = cmd_data;
4441 cmd_data[0] = sensor->num;
4442 cmd_data[1] = 0xff;
4443 cmd_data[2] = info->positive;
4444 cmd_data[3] = info->negative;
4445 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4446 &cmd_msg, hyst_set, &(info->sdata), info);
4447 if (rv) {
4448 ipmi_log(IPMI_LOG_ERR_INFO,
4449 "%ssensor.c(hyst_set_start):"
4450 " Error sending hysteresis set command: %x",
4451 SENSOR_NAME(sensor), rv);
4452 hyst_set_done_handler(sensor, rv, info);
4453 }
4454 }
4455
4456 static int
stand_ipmi_sensor_set_hysteresis(ipmi_sensor_t * sensor,unsigned int positive_hysteresis,unsigned int negative_hysteresis,ipmi_sensor_done_cb done,void * cb_data)4457 stand_ipmi_sensor_set_hysteresis(ipmi_sensor_t *sensor,
4458 unsigned int positive_hysteresis,
4459 unsigned int negative_hysteresis,
4460 ipmi_sensor_done_cb done,
4461 void *cb_data)
4462 {
4463 hyst_set_info_t *info;
4464 int rv;
4465
4466 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4467 /* Not a threshold sensor, it doesn't have readings. */
4468 return ENOSYS;
4469
4470 if (sensor->hysteresis_support != IPMI_HYSTERESIS_SUPPORT_SETTABLE)
4471 return ENOSYS;
4472
4473 info = ipmi_mem_alloc(sizeof(*info));
4474 if (!info)
4475 return ENOMEM;
4476 info->positive = positive_hysteresis;
4477 info->negative = negative_hysteresis;
4478 info->done = done;
4479 info->cb_data = cb_data;
4480 rv = ipmi_sensor_add_opq(sensor, hyst_set_start, &(info->sdata), info);
4481 if (rv)
4482 ipmi_mem_free(info);
4483 return rv;
4484 }
4485
4486 typedef struct thresh_get_info_s
4487 {
4488 ipmi_sensor_op_info_t sdata;
4489 ipmi_thresholds_t th;
4490 ipmi_sensor_thresholds_cb done;
4491 void *cb_data;
4492 } thresh_get_info_t;
4493
thresh_get_done_handler(ipmi_sensor_t * sensor,int err,void * sinfo)4494 static void thresh_get_done_handler(ipmi_sensor_t *sensor,
4495 int err,
4496 void *sinfo)
4497 {
4498 thresh_get_info_t *info = sinfo;
4499
4500 if (info->done)
4501 info->done(sensor, err, &info->th, info->cb_data);
4502 ipmi_sensor_opq_done(sensor);
4503 ipmi_mem_free(info);
4504 }
4505
4506 static void
thresh_get(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,void * cb_data)4507 thresh_get(ipmi_sensor_t *sensor,
4508 int err,
4509 ipmi_msg_t *rsp,
4510 void *cb_data)
4511 {
4512 thresh_get_info_t *info = cb_data;
4513 enum ipmi_thresh_e th;
4514
4515 if (sensor_done_check_rsp(sensor, err, rsp, 8, "thresh_get",
4516 thresh_get_done_handler, info))
4517 return;
4518
4519 for (th=IPMI_LOWER_NON_CRITICAL; th<=IPMI_UPPER_NON_RECOVERABLE; th++) {
4520 int rv;
4521 if (rsp->data[1] & (1 << th)) {
4522 info->th.vals[th].status = 1;
4523 rv = ipmi_sensor_convert_from_raw(sensor,
4524 rsp->data[th+2],
4525 &(info->th.vals[th].val));
4526 if (rv) {
4527 ipmi_log(IPMI_LOG_ERR_INFO,
4528 "%ssensor.c(thresh_get):"
4529 " Could not convert raw threshold value: %x",
4530 SENSOR_NAME(sensor), rv);
4531 thresh_get_done_handler(sensor, rv, info);
4532 return;
4533 }
4534 } else {
4535 info->th.vals[th].status = 0;
4536 }
4537 }
4538
4539 thresh_get_done_handler(sensor, 0, info);
4540 }
4541
4542 int
ipmi_get_default_sensor_thresholds(ipmi_sensor_t * sensor,ipmi_thresholds_t * th)4543 ipmi_get_default_sensor_thresholds(ipmi_sensor_t *sensor,
4544 ipmi_thresholds_t *th)
4545 {
4546 enum ipmi_thresh_e thnum;
4547 int rv = 0;
4548
4549 CHECK_SENSOR_LOCK(sensor);
4550
4551 for (thnum = IPMI_LOWER_NON_CRITICAL;
4552 thnum <= IPMI_UPPER_NON_RECOVERABLE;
4553 thnum++)
4554 {
4555 th->vals[thnum].status = 1;
4556 rv = ipmi_sensor_convert_from_raw(sensor,
4557 sensor->default_thresholds[thnum],
4558 &(th->vals[thnum].val));
4559 if (rv)
4560 goto out;
4561 }
4562 out:
4563 return rv;
4564 }
4565
4566 static void
thresh_get_start(ipmi_sensor_t * sensor,int err,void * cb_data)4567 thresh_get_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4568 {
4569 thresh_get_info_t *info = cb_data;
4570 unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4571 ipmi_msg_t cmd_msg;
4572 int rv;
4573
4574 if (sensor_done_check_rsp(sensor, err, NULL, 0, "thresh_get_start",
4575 thresh_get_done_handler, info))
4576 return;
4577
4578 if (sensor->threshold_access == IPMI_THRESHOLD_ACCESS_SUPPORT_FIXED) {
4579 int thnum;
4580 /* Thresholds are fixed, they cannot be read. */
4581 for (thnum = IPMI_LOWER_NON_CRITICAL;
4582 thnum <= IPMI_UPPER_NON_RECOVERABLE;
4583 thnum++)
4584 {
4585 info->th.vals[thnum].status = 0;
4586 }
4587 thresh_get_done_handler(sensor, 0, info);
4588 return;
4589 }
4590
4591 cmd_msg.data = cmd_data;
4592 cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4593 cmd_msg.cmd = IPMI_GET_SENSOR_THRESHOLD_CMD;
4594 cmd_msg.data_len = 1;
4595 cmd_msg.data = cmd_data;
4596 cmd_data[0] = sensor->num;
4597 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4598 &cmd_msg, thresh_get, &(info->sdata), info);
4599 if (rv) {
4600 ipmi_log(IPMI_LOG_ERR_INFO,
4601 "%ssensor.c(thresh_get_start):"
4602 " Error sending threshold get command: %x",
4603 SENSOR_NAME(sensor), rv);
4604 thresh_get_done_handler(sensor, rv, info);
4605 }
4606 }
4607
4608 static int
stand_ipmi_sensor_get_thresholds(ipmi_sensor_t * sensor,ipmi_sensor_thresholds_cb done,void * cb_data)4609 stand_ipmi_sensor_get_thresholds(ipmi_sensor_t *sensor,
4610 ipmi_sensor_thresholds_cb done,
4611 void *cb_data)
4612 {
4613 thresh_get_info_t *info;
4614 int rv;
4615
4616 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4617 /* Not a threshold sensor, it doesn't have readings. */
4618 return ENOSYS;
4619
4620 if (sensor->threshold_access == IPMI_THRESHOLD_ACCESS_SUPPORT_NONE)
4621 return ENOSYS;
4622
4623 info = ipmi_mem_alloc(sizeof(*info));
4624 if (!info)
4625 return ENOMEM;
4626 info->done = done;
4627 info->cb_data = cb_data;
4628 rv = ipmi_sensor_add_opq(sensor, thresh_get_start, &(info->sdata), info);
4629 if (rv)
4630 ipmi_mem_free(info);
4631 return rv;
4632 }
4633
4634 typedef struct thresh_set_info_s
4635 {
4636 ipmi_sensor_op_info_t sdata;
4637 ipmi_thresholds_t th;
4638 ipmi_sensor_done_cb done;
4639 void *cb_data;
4640 } thresh_set_info_t;
4641
thresh_set_done_handler(ipmi_sensor_t * sensor,int err,void * sinfo)4642 static void thresh_set_done_handler(ipmi_sensor_t *sensor,
4643 int err,
4644 void *sinfo)
4645 {
4646 thresh_set_info_t *info = sinfo;
4647
4648 if (info->done)
4649 info->done(sensor, err, info->cb_data);
4650 ipmi_sensor_opq_done(sensor);
4651 ipmi_mem_free(info);
4652 }
4653
4654 static void
thresh_set(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,void * cb_data)4655 thresh_set(ipmi_sensor_t *sensor,
4656 int err,
4657 ipmi_msg_t *rsp,
4658 void *cb_data)
4659 {
4660 thresh_set_info_t *info = cb_data;
4661
4662 if (sensor_done_check_rsp(sensor, err, rsp, 1, "thresh_set",
4663 thresh_set_done_handler, info))
4664 return;
4665
4666 thresh_set_done_handler(sensor, 0, info);
4667 }
4668
4669 static void
thresh_set_start(ipmi_sensor_t * sensor,int err,void * cb_data)4670 thresh_set_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4671 {
4672 thresh_set_info_t *info = cb_data;
4673 unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4674 ipmi_msg_t cmd_msg;
4675 int rv;
4676 enum ipmi_thresh_e th;
4677
4678 if (sensor_done_check_rsp(sensor, err, NULL, 0, "thresh_set_start",
4679 thresh_set_done_handler, info))
4680 return;
4681
4682 cmd_msg.data = cmd_data;
4683 cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4684 cmd_msg.cmd = IPMI_SET_SENSOR_THRESHOLD_CMD;
4685 cmd_msg.data_len = 8;
4686 cmd_msg.data = cmd_data;
4687 cmd_data[0] = sensor->num;
4688 cmd_data[1] = 0;
4689 for (th=IPMI_LOWER_NON_CRITICAL; th<=IPMI_UPPER_NON_RECOVERABLE; th++) {
4690 int val;
4691 if (info->th.vals[th].status) {
4692 cmd_data[1] |= (1 << th);
4693 rv = ipmi_sensor_convert_to_raw(sensor,
4694 ROUND_NORMAL,
4695 info->th.vals[th].val,
4696 &val);
4697 if (rv) {
4698 ipmi_log(IPMI_LOG_ERR_INFO,
4699 "%ssensor.c(thresh_set_start):"
4700 "Error converting threshold to raw: %x",
4701 SENSOR_NAME(sensor), rv);
4702 thresh_set_done_handler(sensor, rv, info);
4703 return;
4704 }
4705 } else {
4706 val = 0;
4707 }
4708 cmd_data[th+2] = val;
4709 }
4710
4711 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4712 &cmd_msg, thresh_set, &(info->sdata), info);
4713 if (rv) {
4714 ipmi_log(IPMI_LOG_ERR_INFO,
4715 "%ssensor.c(thresh_set_start):"
4716 "Error sending thresholds set command: %x",
4717 SENSOR_NAME(sensor), rv);
4718 thresh_set_done_handler(sensor, rv, info);
4719 }
4720 }
4721
4722 static int
stand_ipmi_sensor_set_thresholds(ipmi_sensor_t * sensor,ipmi_thresholds_t * thresholds,ipmi_sensor_done_cb done,void * cb_data)4723 stand_ipmi_sensor_set_thresholds(ipmi_sensor_t *sensor,
4724 ipmi_thresholds_t *thresholds,
4725 ipmi_sensor_done_cb done,
4726 void *cb_data)
4727 {
4728 thresh_set_info_t *info;
4729 int rv;
4730
4731 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4732 /* Not a threshold sensor, it doesn't have readings. */
4733 return ENOSYS;
4734
4735 if (sensor->threshold_access != IPMI_THRESHOLD_ACCESS_SUPPORT_SETTABLE)
4736 return ENOSYS;
4737
4738 info = ipmi_mem_alloc(sizeof(*info));
4739 if (!info)
4740 return ENOMEM;
4741 info->th = *thresholds;
4742 info->done = done;
4743 info->cb_data = cb_data;
4744 rv = ipmi_sensor_add_opq(sensor, thresh_set_start, &(info->sdata), info);
4745 if (rv)
4746 ipmi_mem_free(info);
4747 return rv;
4748 }
4749
4750 typedef struct reading_get_info_s
4751 {
4752 ipmi_sensor_op_info_t sdata;
4753 ipmi_sensor_reading_cb done;
4754 void *cb_data;
4755 ipmi_states_t states;
4756 enum ipmi_value_present_e value_present;
4757 unsigned int raw_val;
4758 double cooked_val;
4759 } reading_get_info_t;
4760
reading_get_done_handler(ipmi_sensor_t * sensor,int err,void * sinfo)4761 static void reading_get_done_handler(ipmi_sensor_t *sensor,
4762 int err,
4763 void *sinfo)
4764 {
4765 reading_get_info_t *info = sinfo;
4766
4767 if (info->done)
4768 info->done(sensor, err, info->value_present,
4769 info->raw_val, info->cooked_val, &info->states,
4770 info->cb_data);
4771 ipmi_sensor_opq_done(sensor);
4772 ipmi_mem_free(info);
4773 }
4774
4775 static void
reading_get(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,void * rsp_data)4776 reading_get(ipmi_sensor_t *sensor,
4777 int err,
4778 ipmi_msg_t *rsp,
4779 void *rsp_data)
4780 {
4781 reading_get_info_t *info = rsp_data;
4782 int rv;
4783
4784 if (sensor_done_check_rsp(sensor, err, rsp, 3, "reading_get",
4785 reading_get_done_handler, info))
4786 return;
4787
4788 info->raw_val = rsp->data[1];
4789 if (sensor->analog_data_format != IPMI_ANALOG_DATA_FORMAT_NOT_ANALOG) {
4790 rv = ipmi_sensor_convert_from_raw(sensor,
4791 info->raw_val,
4792 &info->cooked_val);
4793 if (rv)
4794 info->value_present = IPMI_RAW_VALUE_PRESENT;
4795 else
4796 info->value_present = IPMI_BOTH_VALUES_PRESENT;
4797 } else {
4798 info->value_present = IPMI_NO_VALUES_PRESENT;
4799 }
4800
4801 info->states.__event_messages_enabled = (rsp->data[2] >> 7) & 1;
4802 info->states.__sensor_scanning_enabled = (rsp->data[2] >> 6) & 1;
4803 info->states.__initial_update_in_progress = (rsp->data[2] >> 5) & 1;
4804 if (rsp->data_len >= 4)
4805 info->states.__states = rsp->data[3];
4806
4807 reading_get_done_handler(sensor, 0, info);
4808 }
4809
4810 static void
reading_get_start(ipmi_sensor_t * sensor,int err,void * cb_data)4811 reading_get_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4812 {
4813 reading_get_info_t *info = cb_data;
4814 unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4815 ipmi_msg_t cmd_msg;
4816 int rv;
4817
4818 if (sensor_done_check_rsp(sensor, err, NULL, 0, "reading_get_start",
4819 reading_get_done_handler, info))
4820 return;
4821
4822 cmd_msg.data = cmd_data;
4823 cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4824 cmd_msg.cmd = IPMI_GET_SENSOR_READING_CMD;
4825 cmd_msg.data_len = 1;
4826 cmd_msg.data = cmd_data;
4827 cmd_data[0] = sensor->num;
4828 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4829 &cmd_msg, reading_get,
4830 &(info->sdata), info);
4831 if (rv) {
4832 ipmi_log(IPMI_LOG_ERR_INFO,
4833 "%ssensor.c(reading_get_start):"
4834 "Error sending reading get command: %x",
4835 SENSOR_NAME(sensor), rv);
4836 reading_get_done_handler(sensor, rv, info);
4837 }
4838 }
4839
4840 static int
stand_ipmi_sensor_get_reading(ipmi_sensor_t * sensor,ipmi_sensor_reading_cb done,void * cb_data)4841 stand_ipmi_sensor_get_reading(ipmi_sensor_t *sensor,
4842 ipmi_sensor_reading_cb done,
4843 void *cb_data)
4844 {
4845 reading_get_info_t *info;
4846 int rv;
4847
4848 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4849 /* Not a threshold sensor, it doesn't have readings. */
4850 return ENOSYS;
4851 if (!sensor->readable)
4852 return ENOSYS;
4853
4854 info = ipmi_mem_alloc(sizeof(*info));
4855 if (!info)
4856 return ENOMEM;
4857 info->done = done;
4858 info->cb_data = cb_data;
4859 info->value_present = IPMI_NO_VALUES_PRESENT;
4860 info->raw_val = 0;
4861 info->cooked_val = 0.0;
4862 ipmi_init_states(&info->states);
4863 rv = ipmi_sensor_add_opq(sensor, reading_get_start, &(info->sdata), info);
4864 if (rv)
4865 ipmi_mem_free(info);
4866 return rv;
4867 }
4868
4869
4870 typedef struct states_get_info_s
4871 {
4872 ipmi_sensor_op_info_t sdata;
4873 ipmi_sensor_states_cb done;
4874 void *cb_data;
4875 ipmi_states_t states;
4876 } states_get_info_t;
4877
states_get_done_handler(ipmi_sensor_t * sensor,int err,void * sinfo)4878 static void states_get_done_handler(ipmi_sensor_t *sensor,
4879 int err,
4880 void *sinfo)
4881 {
4882 states_get_info_t *info = sinfo;
4883
4884 if (info->done)
4885 info->done(sensor, err, &info->states, info->cb_data);
4886 ipmi_sensor_opq_done(sensor);
4887 ipmi_mem_free(info);
4888 }
4889
4890 static void
states_get(ipmi_sensor_t * sensor,int err,ipmi_msg_t * rsp,void * cb_data)4891 states_get(ipmi_sensor_t *sensor,
4892 int err,
4893 ipmi_msg_t *rsp,
4894 void *cb_data)
4895 {
4896 states_get_info_t *info = cb_data;
4897
4898 if (sensor_done_check_rsp(sensor, err, rsp, 3, "states_get",
4899 states_get_done_handler, info))
4900 return;
4901
4902 info->states.__event_messages_enabled = (rsp->data[2] >> 7) & 1;
4903 info->states.__sensor_scanning_enabled = (rsp->data[2] >> 6) & 1;
4904 info->states.__initial_update_in_progress = (rsp->data[2] >> 5) & 1;
4905
4906 if (rsp->data_len >= 4)
4907 info->states.__states |= rsp->data[3];
4908 if (rsp->data_len >= 5)
4909 info->states.__states |= rsp->data[4] << 8;
4910
4911 states_get_done_handler(sensor, 0, info);
4912 }
4913
4914 static void
states_get_start(ipmi_sensor_t * sensor,int err,void * cb_data)4915 states_get_start(ipmi_sensor_t *sensor, int err, void *cb_data)
4916 {
4917 states_get_info_t *info = cb_data;
4918 unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
4919 ipmi_msg_t cmd_msg;
4920 int rv;
4921
4922 if (sensor_done_check_rsp(sensor, err, NULL, 0, "states_get_start",
4923 states_get_done_handler, info))
4924 return;
4925
4926 cmd_msg.data = cmd_data;
4927 cmd_msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4928 cmd_msg.cmd = IPMI_GET_SENSOR_READING_CMD;
4929 cmd_msg.data_len = 1;
4930 cmd_msg.data = cmd_data;
4931 cmd_data[0] = sensor->num;
4932 rv = ipmi_sensor_send_command(sensor, sensor->mc, sensor->send_lun,
4933 &cmd_msg, states_get,
4934 &(info->sdata), info);
4935 if (rv) {
4936 ipmi_log(IPMI_LOG_ERR_INFO,
4937 "%sstates.c(states_get_start):"
4938 " Error sending states get command: %x",
4939 SENSOR_NAME(sensor), rv);
4940 states_get_done_handler(sensor, rv, info);
4941 }
4942 }
4943
4944 static int
stand_ipmi_sensor_get_states(ipmi_sensor_t * sensor,ipmi_sensor_states_cb done,void * cb_data)4945 stand_ipmi_sensor_get_states(ipmi_sensor_t *sensor,
4946 ipmi_sensor_states_cb done,
4947 void *cb_data)
4948 {
4949 states_get_info_t *info;
4950 int rv;
4951
4952 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
4953 /* A threshold sensor, it doesn't have states. */
4954 return ENOSYS;
4955 if (!sensor->readable)
4956 return ENOSYS;
4957
4958 info = ipmi_mem_alloc(sizeof(*info));
4959 if (!info)
4960 return ENOMEM;
4961 info->done = done;
4962 info->cb_data = cb_data;
4963 ipmi_init_states(&info->states);
4964 rv = ipmi_sensor_add_opq(sensor, states_get_start, &(info->sdata), info);
4965 if (rv)
4966 ipmi_mem_free(info);
4967 return rv;
4968 }
4969
4970 /***********************************************************************
4971 *
4972 * Various data conversion stuff.
4973 *
4974 **********************************************************************/
4975
c_linear(double val)4976 static double c_linear(double val)
4977 {
4978 return val;
4979 }
4980
c_log2(double val)4981 static double c_log2(double val)
4982 {
4983 return log(val) / 0.69314718 /* log(2) */;
4984 }
4985
c_exp10(double val)4986 static double c_exp10(double val)
4987 {
4988 return pow(10.0, val);
4989 }
4990
c_exp2(double val)4991 static double c_exp2(double val)
4992 {
4993 return pow(2.0, val);
4994 }
4995
c_1_over_x(double val)4996 static double c_1_over_x(double val)
4997 {
4998 return 1.0 / val;
4999 }
5000
c_sqr(double val)5001 static double c_sqr(double val)
5002 {
5003 return pow(val, 2.0);
5004 }
5005
c_cube(double val)5006 static double c_cube(double val)
5007 {
5008 return pow(val, 3.0);
5009 }
5010
c_1_over_cube(double val)5011 static double c_1_over_cube(double val)
5012 {
5013 return 1.0 / pow(val, 3.0);
5014 }
5015
5016 typedef double (*linearizer)(double val);
5017 static linearizer linearize[12] =
5018 {
5019 c_linear,
5020 log,
5021 log10,
5022 c_log2,
5023 exp,
5024 c_exp10,
5025 c_exp2,
5026 c_1_over_x,
5027 c_sqr,
5028 c_cube,
5029 sqrt,
5030 c_1_over_cube
5031 };
5032
5033 static int
sign_extend(int m,int bits)5034 sign_extend(int m, int bits)
5035 {
5036 if (m & (1 << (bits-1)))
5037 return m | (-1 << bits);
5038 else
5039 return m & (~(-1 << bits));
5040 }
5041
5042 static int
stand_ipmi_sensor_convert_from_raw(ipmi_sensor_t * sensor,int val,double * result)5043 stand_ipmi_sensor_convert_from_raw(ipmi_sensor_t *sensor,
5044 int val,
5045 double *result)
5046 {
5047 double m, b, b_exp, r_exp, fval;
5048 linearizer c_func;
5049
5050 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
5051 /* Not a threshold sensor, it doesn't have readings. */
5052 return ENOSYS;
5053
5054 if (sensor->linearization == IPMI_LINEARIZATION_NONLINEAR)
5055 c_func = c_linear;
5056 else if (sensor->linearization <= 11)
5057 c_func = linearize[sensor->linearization];
5058 else
5059 return EINVAL;
5060
5061 val &= 0xff;
5062
5063 m = sensor->conv[val].m;
5064 b = sensor->conv[val].b;
5065 r_exp = sensor->conv[val].r_exp;
5066 b_exp = sensor->conv[val].b_exp;
5067
5068 switch(sensor->analog_data_format) {
5069 case IPMI_ANALOG_DATA_FORMAT_UNSIGNED:
5070 fval = val;
5071 break;
5072 case IPMI_ANALOG_DATA_FORMAT_1_COMPL:
5073 val = sign_extend(val, 8);
5074 if (val < 0)
5075 val += 1;
5076 fval = val;
5077 break;
5078 case IPMI_ANALOG_DATA_FORMAT_2_COMPL:
5079 fval = sign_extend(val, 8);
5080 break;
5081 default:
5082 return EINVAL;
5083 }
5084
5085 *result = c_func(((m * fval) + (b * pow(10, b_exp))) * pow(10, r_exp));
5086 return 0;
5087 }
5088
5089 static int
stand_ipmi_sensor_convert_to_raw(ipmi_sensor_t * sensor,enum ipmi_round_e rounding,double val,int * result)5090 stand_ipmi_sensor_convert_to_raw(ipmi_sensor_t *sensor,
5091 enum ipmi_round_e rounding,
5092 double val,
5093 int *result)
5094 {
5095 double cval;
5096 int lowraw, highraw, raw, maxraw, minraw, next_raw;
5097 int rv;
5098
5099 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
5100 /* Not a threshold sensor, it doesn't have readings. */
5101 return ENOSYS;
5102
5103 switch(sensor->analog_data_format) {
5104 case IPMI_ANALOG_DATA_FORMAT_UNSIGNED:
5105 lowraw = 0;
5106 highraw = 255;
5107 minraw = 0;
5108 maxraw = 255;
5109 next_raw = 128;
5110 break;
5111 case IPMI_ANALOG_DATA_FORMAT_1_COMPL:
5112 lowraw = -127;
5113 highraw = 127;
5114 minraw = -127;
5115 maxraw = 127;
5116 next_raw = 0;
5117 break;
5118 case IPMI_ANALOG_DATA_FORMAT_2_COMPL:
5119 lowraw = -128;
5120 highraw = 127;
5121 minraw = -128;
5122 maxraw = 127;
5123 next_raw = 0;
5124 break;
5125 default:
5126 return EINVAL;
5127 }
5128
5129 /* We do a binary search for the right value. Yuck, but I don't
5130 have a better plan that will work with non-linear sensors. */
5131 do {
5132 raw = next_raw;
5133 rv = ipmi_sensor_convert_from_raw(sensor, raw, &cval);
5134 if (rv)
5135 return rv;
5136
5137 if (cval < val) {
5138 next_raw = ((highraw - raw) / 2) + raw;
5139 lowraw = raw;
5140 } else {
5141 next_raw = ((raw - lowraw) / 2) + lowraw;
5142 highraw = raw;
5143 }
5144 } while (raw != next_raw);
5145
5146 /* The above loop gets us to within 1 of what it should be, we
5147 have to look at rounding to make the final decision. */
5148 switch (rounding)
5149 {
5150 case ROUND_NORMAL:
5151 if (val > cval) {
5152 if (raw < maxraw) {
5153 double nval;
5154 rv = ipmi_sensor_convert_from_raw(sensor, raw+1, &nval);
5155 if (rv)
5156 return rv;
5157 nval = cval + ((nval - cval) / 2.0);
5158 if (val >= nval)
5159 raw++;
5160 }
5161 } else {
5162 if (raw > minraw) {
5163 double pval;
5164 rv = ipmi_sensor_convert_from_raw(sensor, raw-1, &pval);
5165 if (rv)
5166 return rv;
5167 pval = pval + ((cval - pval) / 2.0);
5168 if (val < pval)
5169 raw--;
5170 }
5171 }
5172 break;
5173 case ROUND_UP:
5174 if ((val > cval) && (raw < maxraw)) {
5175 raw++;
5176 }
5177 break;
5178 case ROUND_DOWN:
5179 if ((val < cval) && (raw > minraw)) {
5180 raw--;
5181 }
5182 break;
5183 }
5184
5185 if (sensor->analog_data_format == IPMI_ANALOG_DATA_FORMAT_1_COMPL) {
5186 if (raw < 0)
5187 raw -= 1;
5188 }
5189
5190 *result = raw & 0xff;
5191 return 0;
5192 }
5193
5194 static int
stand_ipmi_sensor_get_tolerance(ipmi_sensor_t * sensor,int val,double * tolerance)5195 stand_ipmi_sensor_get_tolerance(ipmi_sensor_t *sensor,
5196 int val,
5197 double *tolerance)
5198 {
5199 double m, r_exp, fval;
5200 linearizer c_func;
5201
5202 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
5203 /* Not a threshold sensor, it doesn't have readings. */
5204 return ENOSYS;
5205
5206 if (sensor->linearization == IPMI_LINEARIZATION_NONLINEAR)
5207 c_func = c_linear;
5208 else if (sensor->linearization <= 11)
5209 c_func = linearize[sensor->linearization];
5210 else
5211 return EINVAL;
5212
5213 val &= 0xff;
5214
5215 m = sensor->conv[val].m;
5216 r_exp = sensor->conv[val].r_exp;
5217
5218 fval = sign_extend(val, 8);
5219
5220 *tolerance = c_func(((m * fval) / 2.0) * pow(10, r_exp));
5221 return 0;
5222 }
5223
5224 /* Returns accuracy as a percentage value. */
5225 static int
stand_ipmi_sensor_get_accuracy(ipmi_sensor_t * sensor,int val,double * accuracy)5226 stand_ipmi_sensor_get_accuracy(ipmi_sensor_t *sensor, int val, double *accuracy)
5227 {
5228 double a, a_exp;
5229
5230 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
5231 /* Not a threshold sensor, it doesn't have readings. */
5232 return ENOSYS;
5233
5234 val &= 0xff;
5235
5236 a = sensor->conv[val].accuracy;
5237 a_exp = sensor->conv[val].r_exp;
5238
5239 *accuracy = (a * pow(10, a_exp)) / 100.0;
5240 return 0;
5241 }
5242
5243 static const char *
stand_ipmi_sensor_reading_name_string(ipmi_sensor_t * sensor,int offset)5244 stand_ipmi_sensor_reading_name_string(ipmi_sensor_t *sensor, int offset)
5245 {
5246 return ipmi_get_reading_name(sensor->event_reading_type,
5247 sensor->sensor_type,
5248 offset);
5249 }
5250
5251 /***********************************************************************
5252 *
5253 * The standard callback structure
5254 *
5255 **********************************************************************/
5256
5257 const ipmi_sensor_cbs_t ipmi_standard_sensor_cb =
5258 {
5259 .ipmi_sensor_set_event_enables = stand_ipmi_sensor_set_event_enables,
5260 .ipmi_sensor_get_event_enables = stand_ipmi_sensor_get_event_enables,
5261 .ipmi_sensor_enable_events = stand_ipmi_sensor_enable_events,
5262 .ipmi_sensor_disable_events = stand_ipmi_sensor_disable_events,
5263 .ipmi_sensor_rearm = stand_ipmi_sensor_rearm,
5264
5265 .ipmi_sensor_convert_from_raw = stand_ipmi_sensor_convert_from_raw,
5266 .ipmi_sensor_convert_to_raw = stand_ipmi_sensor_convert_to_raw,
5267 .ipmi_sensor_get_accuracy = stand_ipmi_sensor_get_accuracy,
5268 .ipmi_sensor_get_tolerance = stand_ipmi_sensor_get_tolerance,
5269 .ipmi_sensor_get_hysteresis = stand_ipmi_sensor_get_hysteresis,
5270 .ipmi_sensor_set_hysteresis = stand_ipmi_sensor_set_hysteresis,
5271 .ipmi_sensor_set_thresholds = stand_ipmi_sensor_set_thresholds,
5272 .ipmi_sensor_get_thresholds = stand_ipmi_sensor_get_thresholds,
5273 .ipmi_sensor_get_reading = stand_ipmi_sensor_get_reading,
5274
5275 .ipmi_sensor_get_states = stand_ipmi_sensor_get_states,
5276 .ipmi_sensor_reading_name_string = stand_ipmi_sensor_reading_name_string,
5277 };
5278
5279 void
ipmi_sensor_get_callbacks(ipmi_sensor_t * sensor,ipmi_sensor_cbs_t * cbs)5280 ipmi_sensor_get_callbacks(ipmi_sensor_t *sensor, ipmi_sensor_cbs_t *cbs)
5281 {
5282 *cbs = sensor->cbs;
5283 }
5284
5285 void
ipmi_sensor_set_callbacks(ipmi_sensor_t * sensor,ipmi_sensor_cbs_t * cbs)5286 ipmi_sensor_set_callbacks(ipmi_sensor_t *sensor, ipmi_sensor_cbs_t *cbs)
5287 {
5288 sensor->cbs = *cbs;
5289 }
5290
5291 /***********************************************************************
5292 *
5293 * Polymorphic calls to the callback handlers.
5294 *
5295 **********************************************************************/
5296
5297 int
ipmi_sensor_set_event_enables(ipmi_sensor_t * sensor,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)5298 ipmi_sensor_set_event_enables(ipmi_sensor_t *sensor,
5299 ipmi_event_state_t *states,
5300 ipmi_sensor_done_cb done,
5301 void *cb_data)
5302 {
5303 if (!sensor_ok_to_use(sensor))
5304 return ECANCELED;
5305
5306 CHECK_SENSOR_LOCK(sensor);
5307
5308 if (!sensor->cbs.ipmi_sensor_set_event_enables)
5309 return ENOSYS;
5310 return sensor->cbs.ipmi_sensor_set_event_enables(sensor,
5311 states,
5312 done,
5313 cb_data);
5314 }
5315
5316 int
ipmi_sensor_enable_events(ipmi_sensor_t * sensor,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)5317 ipmi_sensor_enable_events(ipmi_sensor_t *sensor,
5318 ipmi_event_state_t *states,
5319 ipmi_sensor_done_cb done,
5320 void *cb_data)
5321 {
5322 if (!sensor_ok_to_use(sensor))
5323 return ECANCELED;
5324
5325 CHECK_SENSOR_LOCK(sensor);
5326
5327 if (!sensor->cbs.ipmi_sensor_enable_events)
5328 return ENOSYS;
5329 return sensor->cbs.ipmi_sensor_enable_events(sensor,
5330 states,
5331 done,
5332 cb_data);
5333 }
5334
5335 int
ipmi_sensor_disable_events(ipmi_sensor_t * sensor,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)5336 ipmi_sensor_disable_events(ipmi_sensor_t *sensor,
5337 ipmi_event_state_t *states,
5338 ipmi_sensor_done_cb done,
5339 void *cb_data)
5340 {
5341 if (!sensor_ok_to_use(sensor))
5342 return ECANCELED;
5343
5344 CHECK_SENSOR_LOCK(sensor);
5345
5346 if (!sensor->cbs.ipmi_sensor_disable_events)
5347 return ENOSYS;
5348 return sensor->cbs.ipmi_sensor_disable_events(sensor,
5349 states,
5350 done,
5351 cb_data);
5352 }
5353
5354 int
ipmi_sensor_rearm(ipmi_sensor_t * sensor,int global_enable,ipmi_event_state_t * state,ipmi_sensor_done_cb done,void * cb_data)5355 ipmi_sensor_rearm(ipmi_sensor_t *sensor,
5356 int global_enable,
5357 ipmi_event_state_t *state,
5358 ipmi_sensor_done_cb done,
5359 void *cb_data)
5360 {
5361 if (!sensor_ok_to_use(sensor))
5362 return ECANCELED;
5363
5364 CHECK_SENSOR_LOCK(sensor);
5365
5366 if (!sensor->cbs.ipmi_sensor_rearm)
5367 return ENOSYS;
5368 return sensor->cbs.ipmi_sensor_rearm(sensor,
5369 global_enable,
5370 state,
5371 done,
5372 cb_data);
5373 }
5374
5375 int
ipmi_sensor_get_event_enables(ipmi_sensor_t * sensor,ipmi_sensor_event_enables_cb done,void * cb_data)5376 ipmi_sensor_get_event_enables(ipmi_sensor_t *sensor,
5377 ipmi_sensor_event_enables_cb done,
5378 void *cb_data)
5379 {
5380 if (!sensor_ok_to_use(sensor))
5381 return ECANCELED;
5382
5383 CHECK_SENSOR_LOCK(sensor);
5384
5385 if (!sensor->cbs.ipmi_sensor_get_event_enables)
5386 return ENOSYS;
5387 return sensor->cbs.ipmi_sensor_get_event_enables(sensor,
5388 done,
5389 cb_data);
5390 }
5391
5392 int
ipmi_sensor_get_hysteresis(ipmi_sensor_t * sensor,ipmi_sensor_hysteresis_cb done,void * cb_data)5393 ipmi_sensor_get_hysteresis(ipmi_sensor_t *sensor,
5394 ipmi_sensor_hysteresis_cb done,
5395 void *cb_data)
5396 {
5397 if (!sensor_ok_to_use(sensor))
5398 return ECANCELED;
5399
5400 CHECK_SENSOR_LOCK(sensor);
5401
5402 if (!sensor->cbs.ipmi_sensor_get_hysteresis)
5403 return ENOSYS;
5404 return sensor->cbs.ipmi_sensor_get_hysteresis(sensor,
5405 done,
5406 cb_data);
5407 }
5408
5409 int
ipmi_sensor_set_hysteresis(ipmi_sensor_t * sensor,unsigned int positive_hysteresis,unsigned int negative_hysteresis,ipmi_sensor_done_cb done,void * cb_data)5410 ipmi_sensor_set_hysteresis(ipmi_sensor_t *sensor,
5411 unsigned int positive_hysteresis,
5412 unsigned int negative_hysteresis,
5413 ipmi_sensor_done_cb done,
5414 void *cb_data)
5415 {
5416 if (!sensor_ok_to_use(sensor))
5417 return ECANCELED;
5418
5419 CHECK_SENSOR_LOCK(sensor);
5420
5421 if (!sensor->cbs.ipmi_sensor_set_hysteresis)
5422 return ENOSYS;
5423 return sensor->cbs.ipmi_sensor_set_hysteresis(sensor,
5424 positive_hysteresis,
5425 negative_hysteresis,
5426 done,
5427 cb_data);
5428 }
5429
5430 int
ipmi_sensor_get_thresholds(ipmi_sensor_t * sensor,ipmi_sensor_thresholds_cb done,void * cb_data)5431 ipmi_sensor_get_thresholds(ipmi_sensor_t *sensor,
5432 ipmi_sensor_thresholds_cb done,
5433 void *cb_data)
5434 {
5435 if (!sensor_ok_to_use(sensor))
5436 return ECANCELED;
5437
5438 CHECK_SENSOR_LOCK(sensor);
5439
5440 if (!sensor->cbs.ipmi_sensor_get_thresholds)
5441 return ENOSYS;
5442 return sensor->cbs.ipmi_sensor_get_thresholds(sensor, done, cb_data);
5443 }
5444
5445 int
ipmi_sensor_set_thresholds(ipmi_sensor_t * sensor,ipmi_thresholds_t * thresholds,ipmi_sensor_done_cb done,void * cb_data)5446 ipmi_sensor_set_thresholds(ipmi_sensor_t *sensor,
5447 ipmi_thresholds_t *thresholds,
5448 ipmi_sensor_done_cb done,
5449 void *cb_data)
5450 {
5451 if (!sensor_ok_to_use(sensor))
5452 return ECANCELED;
5453
5454 CHECK_SENSOR_LOCK(sensor);
5455
5456 if (!sensor->cbs.ipmi_sensor_set_thresholds)
5457 return ENOSYS;
5458 return sensor->cbs.ipmi_sensor_set_thresholds(sensor, thresholds,
5459 done, cb_data);
5460 }
5461
5462 int
ipmi_sensor_get_reading(ipmi_sensor_t * sensor,ipmi_sensor_reading_cb done,void * cb_data)5463 ipmi_sensor_get_reading(ipmi_sensor_t *sensor,
5464 ipmi_sensor_reading_cb done,
5465 void *cb_data)
5466 {
5467 if (!sensor_ok_to_use(sensor))
5468 return ECANCELED;
5469
5470 CHECK_SENSOR_LOCK(sensor);
5471
5472 if (!sensor->cbs.ipmi_sensor_get_reading)
5473 return ENOSYS;
5474 return sensor->cbs.ipmi_sensor_get_reading(sensor, done, cb_data);
5475 }
5476
5477 int
ipmi_sensor_get_states(ipmi_sensor_t * sensor,ipmi_sensor_states_cb done,void * cb_data)5478 ipmi_sensor_get_states(ipmi_sensor_t *sensor,
5479 ipmi_sensor_states_cb done,
5480 void *cb_data)
5481 {
5482 if (!sensor_ok_to_use(sensor))
5483 return ECANCELED;
5484
5485 CHECK_SENSOR_LOCK(sensor);
5486
5487 if (!sensor->cbs.ipmi_sensor_get_states)
5488 return ENOSYS;
5489 return sensor->cbs.ipmi_sensor_get_states(sensor, done, cb_data);
5490 }
5491
5492 const char *
ipmi_sensor_reading_name_string(ipmi_sensor_t * sensor,int offset)5493 ipmi_sensor_reading_name_string(ipmi_sensor_t *sensor, int offset)
5494 {
5495 CHECK_SENSOR_LOCK(sensor);
5496
5497 if (!sensor->cbs.ipmi_sensor_reading_name_string)
5498 return NULL;
5499 return sensor->cbs.ipmi_sensor_reading_name_string(sensor, offset);
5500 }
5501
5502 int
ipmi_sensor_convert_from_raw(ipmi_sensor_t * sensor,int val,double * result)5503 ipmi_sensor_convert_from_raw(ipmi_sensor_t *sensor,
5504 int val,
5505 double *result)
5506 {
5507 CHECK_SENSOR_LOCK(sensor);
5508
5509 if (!sensor->cbs.ipmi_sensor_convert_from_raw)
5510 return ENOSYS;
5511 return sensor->cbs.ipmi_sensor_convert_from_raw(sensor, val, result);
5512 }
5513
5514 int
ipmi_sensor_convert_to_raw(ipmi_sensor_t * sensor,enum ipmi_round_e rounding,double val,int * result)5515 ipmi_sensor_convert_to_raw(ipmi_sensor_t *sensor,
5516 enum ipmi_round_e rounding,
5517 double val,
5518 int *result)
5519 {
5520 CHECK_SENSOR_LOCK(sensor);
5521
5522 if (!sensor->cbs.ipmi_sensor_convert_to_raw)
5523 return ENOSYS;
5524 return sensor->cbs.ipmi_sensor_convert_to_raw(sensor,
5525 rounding,
5526 val,
5527 result);
5528 }
5529
5530 int
ipmi_sensor_get_tolerance(ipmi_sensor_t * sensor,int val,double * tolerance)5531 ipmi_sensor_get_tolerance(ipmi_sensor_t *sensor, int val, double *tolerance)
5532 {
5533 CHECK_SENSOR_LOCK(sensor);
5534
5535 if (!sensor->cbs.ipmi_sensor_get_tolerance)
5536 return ENOSYS;
5537 return sensor->cbs.ipmi_sensor_get_tolerance(sensor, val, tolerance);
5538 }
5539
5540 /* Returns accuracy as a percentage value. */
5541 int
ipmi_sensor_get_accuracy(ipmi_sensor_t * sensor,int val,double * accuracy)5542 ipmi_sensor_get_accuracy(ipmi_sensor_t *sensor, int val, double *accuracy)
5543 {
5544 CHECK_SENSOR_LOCK(sensor);
5545
5546 if (!sensor->cbs.ipmi_sensor_get_accuracy)
5547 return ENOSYS;
5548 return sensor->cbs.ipmi_sensor_get_accuracy(sensor, val, accuracy);
5549 }
5550
5551
5552 /***********************************************************************
5553 *
5554 * Convenience functions that take ids.
5555 *
5556 **********************************************************************/
5557
5558 typedef struct sensor_id_events_enable_set_s
5559 {
5560 ipmi_event_state_t *states;
5561 ipmi_sensor_done_cb done;
5562 void *cb_data;
5563 int rv;
5564 } sensor_id_events_enable_set_t;
5565
5566 static void
sensor_id_set_event_enables_cb(ipmi_sensor_t * sensor,void * cb_data)5567 sensor_id_set_event_enables_cb(ipmi_sensor_t *sensor, void *cb_data)
5568 {
5569 sensor_id_events_enable_set_t *info = cb_data;
5570
5571 info->rv = ipmi_sensor_set_event_enables(sensor, info->states,
5572 info->done, info->cb_data);
5573 }
5574
5575 int
ipmi_sensor_id_set_event_enables(ipmi_sensor_id_t sensor_id,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)5576 ipmi_sensor_id_set_event_enables(ipmi_sensor_id_t sensor_id,
5577 ipmi_event_state_t *states,
5578 ipmi_sensor_done_cb done,
5579 void *cb_data)
5580 {
5581 sensor_id_events_enable_set_t info;
5582 int rv;
5583
5584 info.states = states;
5585 info.done = done;
5586 info.cb_data = cb_data;
5587 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_set_event_enables_cb,
5588 &info);
5589 if (!rv)
5590 rv = info.rv;
5591 return rv;
5592 }
5593
5594 typedef struct sensor_id_events_enable_s
5595 {
5596 ipmi_event_state_t *states;
5597 ipmi_sensor_done_cb done;
5598 void *cb_data;
5599 int rv;
5600 } sensor_id_events_enable_t;
5601
5602 static void
sensor_id_enable_events_cb(ipmi_sensor_t * sensor,void * cb_data)5603 sensor_id_enable_events_cb(ipmi_sensor_t *sensor, void *cb_data)
5604 {
5605 sensor_id_events_enable_t *info = cb_data;
5606
5607 info->rv = ipmi_sensor_enable_events(sensor,
5608 info->states,
5609 info->done,
5610 info->cb_data);
5611 }
5612
5613 int
ipmi_sensor_id_enable_events(ipmi_sensor_id_t sensor_id,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)5614 ipmi_sensor_id_enable_events(ipmi_sensor_id_t sensor_id,
5615 ipmi_event_state_t *states,
5616 ipmi_sensor_done_cb done,
5617 void *cb_data)
5618 {
5619 sensor_id_events_enable_t info;
5620 int rv;
5621
5622 info.states = states;
5623 info.done = done;
5624 info.cb_data = cb_data;
5625 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_enable_events_cb, &info);
5626 if (!rv)
5627 rv = info.rv;
5628 return rv;
5629 }
5630
5631 typedef struct sensor_id_events_disable_s
5632 {
5633 ipmi_event_state_t *states;
5634 ipmi_sensor_done_cb done;
5635 void *cb_data;
5636 int rv;
5637 } sensor_id_events_disable_t;
5638
5639 static void
sensor_id_disable_events_cb(ipmi_sensor_t * sensor,void * cb_data)5640 sensor_id_disable_events_cb(ipmi_sensor_t *sensor, void *cb_data)
5641 {
5642 sensor_id_events_disable_t *info = cb_data;
5643
5644 info->rv = ipmi_sensor_disable_events(sensor,
5645 info->states,
5646 info->done,
5647 info->cb_data);
5648 }
5649
5650 int
ipmi_sensor_id_disable_events(ipmi_sensor_id_t sensor_id,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)5651 ipmi_sensor_id_disable_events(ipmi_sensor_id_t sensor_id,
5652 ipmi_event_state_t *states,
5653 ipmi_sensor_done_cb done,
5654 void *cb_data)
5655 {
5656 sensor_id_events_enable_t info;
5657 int rv;
5658
5659 info.states = states;
5660 info.done = done;
5661 info.cb_data = cb_data;
5662 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_disable_events_cb, &info);
5663 if (!rv)
5664 rv = info.rv;
5665 return rv;
5666 }
5667
5668 typedef struct sensor_id_events_enable_get_s
5669 {
5670 ipmi_sensor_event_enables_cb done;
5671 void *cb_data;
5672 int rv;
5673 } sensor_id_events_enable_get_t;
5674
5675 static void
sensor_id_get_event_enables_cb(ipmi_sensor_t * sensor,void * cb_data)5676 sensor_id_get_event_enables_cb(ipmi_sensor_t *sensor, void *cb_data)
5677 {
5678 sensor_id_events_enable_get_t *info = cb_data;
5679
5680 info->rv = ipmi_sensor_get_event_enables(sensor,
5681 info->done,
5682 info->cb_data);
5683 }
5684
5685 int
ipmi_sensor_id_get_event_enables(ipmi_sensor_id_t sensor_id,ipmi_sensor_event_enables_cb done,void * cb_data)5686 ipmi_sensor_id_get_event_enables(ipmi_sensor_id_t sensor_id,
5687 ipmi_sensor_event_enables_cb done,
5688 void *cb_data)
5689 {
5690 sensor_id_events_enable_get_t info;
5691 int rv;
5692
5693 info.done = done;
5694 info.cb_data = cb_data;
5695 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_get_event_enables_cb,
5696 &info);
5697 if (!rv)
5698 rv = info.rv;
5699 return rv;
5700 }
5701
5702 typedef struct sensor_id_rearm_s
5703 {
5704 int global_enable;
5705 ipmi_event_state_t *state;
5706 ipmi_sensor_done_cb done;
5707 void *cb_data;
5708 int rv;
5709 } sensor_id_rearm_t;
5710
5711 static void
sensor_id_rearm_cb(ipmi_sensor_t * sensor,void * cb_data)5712 sensor_id_rearm_cb(ipmi_sensor_t *sensor, void *cb_data)
5713 {
5714 sensor_id_rearm_t *info = cb_data;
5715
5716 info->rv = ipmi_sensor_rearm(sensor,
5717 info->global_enable,
5718 info->state,
5719 info->done,
5720 info->cb_data);
5721 }
5722
5723 int
ipmi_sensor_id_rearm(ipmi_sensor_id_t sensor_id,int global_enable,ipmi_event_state_t * state,ipmi_sensor_done_cb done,void * cb_data)5724 ipmi_sensor_id_rearm(ipmi_sensor_id_t sensor_id,
5725 int global_enable,
5726 ipmi_event_state_t *state,
5727 ipmi_sensor_done_cb done,
5728 void *cb_data)
5729 {
5730 sensor_id_rearm_t info;
5731 int rv;
5732
5733 info.global_enable = global_enable;
5734 info.state = state;
5735 info.done = done;
5736 info.cb_data = cb_data;
5737 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_rearm_cb, &info);
5738 if (!rv)
5739 rv = info.rv;
5740 return rv;
5741 }
5742
5743 typedef struct sensor_id_get_hysteresis_s
5744 {
5745 ipmi_sensor_hysteresis_cb done;
5746 void *cb_data;
5747 int rv;
5748 } sensor_id_get_hysteresis_t;
5749
5750 static void
sensor_id_get_hysteresis_cb(ipmi_sensor_t * sensor,void * cb_data)5751 sensor_id_get_hysteresis_cb(ipmi_sensor_t *sensor, void *cb_data)
5752 {
5753 sensor_id_get_hysteresis_t *info = cb_data;
5754
5755 info->rv = ipmi_sensor_get_hysteresis(sensor,
5756 info->done,
5757 info->cb_data);
5758 }
5759
5760 int
ipmi_sensor_id_get_hysteresis(ipmi_sensor_id_t sensor_id,ipmi_sensor_hysteresis_cb done,void * cb_data)5761 ipmi_sensor_id_get_hysteresis(ipmi_sensor_id_t sensor_id,
5762 ipmi_sensor_hysteresis_cb done,
5763 void *cb_data)
5764 {
5765 sensor_id_get_hysteresis_t info;
5766 int rv;
5767
5768 info.done = done;
5769 info.cb_data = cb_data;
5770 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_get_hysteresis_cb, &info);
5771 if (!rv)
5772 rv = info.rv;
5773 return rv;
5774 }
5775
5776 typedef struct sensor_id_set_hysteresis_s
5777 {
5778 unsigned int positive_hysteresis;
5779 unsigned int negative_hysteresis;
5780 ipmi_sensor_done_cb done;
5781 void *cb_data;
5782 int rv;
5783 } sensor_id_set_hysteresis_t;
5784
5785 static void
sensor_id_set_hysteresis_cb(ipmi_sensor_t * sensor,void * cb_data)5786 sensor_id_set_hysteresis_cb(ipmi_sensor_t *sensor, void *cb_data)
5787 {
5788 sensor_id_set_hysteresis_t *info = cb_data;
5789
5790 info->rv = ipmi_sensor_set_hysteresis(sensor,
5791 info->positive_hysteresis,
5792 info->negative_hysteresis,
5793 info->done,
5794 info->cb_data);
5795 }
5796
5797 int
ipmi_sensor_id_set_hysteresis(ipmi_sensor_id_t sensor_id,unsigned int positive_hysteresis,unsigned int negative_hysteresis,ipmi_sensor_done_cb done,void * cb_data)5798 ipmi_sensor_id_set_hysteresis(ipmi_sensor_id_t sensor_id,
5799 unsigned int positive_hysteresis,
5800 unsigned int negative_hysteresis,
5801 ipmi_sensor_done_cb done,
5802 void *cb_data)
5803 {
5804 sensor_id_set_hysteresis_t info;
5805 int rv;
5806
5807 info.positive_hysteresis = positive_hysteresis;
5808 info.negative_hysteresis = negative_hysteresis;
5809 info.done = done;
5810 info.cb_data = cb_data;
5811 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_set_hysteresis_cb, &info);
5812 if (!rv)
5813 rv = info.rv;
5814 return rv;
5815 }
5816
5817 typedef struct sensor_id_thresholds_set_s
5818 {
5819 ipmi_thresholds_t *thresholds;
5820 ipmi_sensor_done_cb done;
5821 void *cb_data;
5822 int rv;
5823 } sensor_id_thresholds_set_t;
5824
5825 static void
sensor_id_set_thresholds_cb(ipmi_sensor_t * sensor,void * cb_data)5826 sensor_id_set_thresholds_cb(ipmi_sensor_t *sensor, void *cb_data)
5827 {
5828 sensor_id_thresholds_set_t *info = cb_data;
5829
5830 info->rv = ipmi_sensor_set_thresholds(sensor,
5831 info->thresholds,
5832 info->done,
5833 info->cb_data);
5834 }
5835
5836 int
ipmi_sensor_id_set_thresholds(ipmi_sensor_id_t sensor_id,ipmi_thresholds_t * thresholds,ipmi_sensor_done_cb done,void * cb_data)5837 ipmi_sensor_id_set_thresholds(ipmi_sensor_id_t sensor_id,
5838 ipmi_thresholds_t *thresholds,
5839 ipmi_sensor_done_cb done,
5840 void *cb_data)
5841 {
5842 sensor_id_thresholds_set_t info;
5843 int rv;
5844
5845 info.thresholds = thresholds;
5846 info.done = done;
5847 info.cb_data = cb_data;
5848 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_set_thresholds_cb, &info);
5849 if (!rv)
5850 rv = info.rv;
5851 return rv;
5852 }
5853
5854 typedef struct sensor_id_thresholds_get_s
5855 {
5856 ipmi_sensor_thresholds_cb done;
5857 void *cb_data;
5858 int rv;
5859 } sensor_id_thresholds_get_t;
5860
5861 static void
sensor_id_get_thresholds_cb(ipmi_sensor_t * sensor,void * cb_data)5862 sensor_id_get_thresholds_cb(ipmi_sensor_t *sensor, void *cb_data)
5863 {
5864 sensor_id_thresholds_get_t *info = cb_data;
5865
5866 info->rv = ipmi_sensor_get_thresholds(sensor,
5867 info->done,
5868 info->cb_data);
5869 }
5870
5871 int
ipmi_sensor_id_get_thresholds(ipmi_sensor_id_t sensor_id,ipmi_sensor_thresholds_cb done,void * cb_data)5872 ipmi_sensor_id_get_thresholds(ipmi_sensor_id_t sensor_id,
5873 ipmi_sensor_thresholds_cb done,
5874 void *cb_data)
5875 {
5876 sensor_id_thresholds_get_t info;
5877 int rv;
5878
5879 info.done = done;
5880 info.cb_data = cb_data;
5881 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_get_thresholds_cb, &info);
5882 if (!rv)
5883 rv = info.rv;
5884 return rv;
5885 }
5886
5887 typedef struct sensor_id_reading_get_s
5888 {
5889 ipmi_sensor_reading_cb done;
5890 void *cb_data;
5891 int rv;
5892 } sensor_id_reading_get_t;
5893
5894 static void
sensor_id_get_reading_cb(ipmi_sensor_t * sensor,void * cb_data)5895 sensor_id_get_reading_cb(ipmi_sensor_t *sensor, void *cb_data)
5896 {
5897 sensor_id_reading_get_t *info = cb_data;
5898
5899 info->rv = ipmi_sensor_get_reading(sensor,
5900 info->done,
5901 info->cb_data);
5902 }
5903
5904 int
ipmi_sensor_id_get_reading(ipmi_sensor_id_t sensor_id,ipmi_sensor_reading_cb done,void * cb_data)5905 ipmi_sensor_id_get_reading(ipmi_sensor_id_t sensor_id,
5906 ipmi_sensor_reading_cb done,
5907 void *cb_data)
5908 {
5909 sensor_id_reading_get_t info;
5910 int rv;
5911
5912 info.done = done;
5913 info.cb_data = cb_data;
5914 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_get_reading_cb, &info);
5915 if (!rv)
5916 rv = info.rv;
5917 return rv;
5918 }
5919
5920 typedef struct sensor_id_states_get_s
5921 {
5922 ipmi_sensor_states_cb done;
5923 void *cb_data;
5924 int rv;
5925 } sensor_id_states_get_t;
5926
5927 static void
sensor_id_get_states_cb(ipmi_sensor_t * sensor,void * cb_data)5928 sensor_id_get_states_cb(ipmi_sensor_t *sensor, void *cb_data)
5929 {
5930 sensor_id_states_get_t *info = cb_data;
5931
5932 info->rv = ipmi_sensor_get_states(sensor,
5933 info->done,
5934 info->cb_data);
5935 }
5936
5937 int
ipmi_sensor_id_get_states(ipmi_sensor_id_t sensor_id,ipmi_sensor_states_cb done,void * cb_data)5938 ipmi_sensor_id_get_states(ipmi_sensor_id_t sensor_id,
5939 ipmi_sensor_states_cb done,
5940 void *cb_data)
5941 {
5942 sensor_id_states_get_t info;
5943 int rv;
5944
5945 info.done = done;
5946 info.cb_data = cb_data;
5947 rv = ipmi_sensor_pointer_cb(sensor_id, sensor_id_get_states_cb, &info);
5948 if (!rv)
5949 rv = info.rv;
5950 return rv;
5951 }
5952
5953
5954 #ifdef IPMI_CHECK_LOCKS
5955 void
i__ipmi_check_sensor_lock(const ipmi_sensor_t * sensor)5956 i__ipmi_check_sensor_lock(const ipmi_sensor_t *sensor)
5957 {
5958 if (!sensor)
5959 return;
5960
5961 if (!DEBUG_LOCKS)
5962 return;
5963
5964 CHECK_ENTITY_LOCK(sensor->entity);
5965 CHECK_MC_LOCK(sensor->mc);
5966
5967 if (sensor->usecount == 0)
5968 ipmi_report_lock_error(ipmi_domain_get_os_hnd(sensor->domain),
5969 "sensor not locked when it should have been");
5970 }
5971 #endif
5972
5973 /***********************************************************************
5974 *
5975 * Cruft
5976 *
5977 **********************************************************************/
5978
5979 int
ipmi_sensor_threshold_assertion_event_supported(ipmi_sensor_t * sensor,enum ipmi_thresh_e event,enum ipmi_event_value_dir_e dir,int * val)5980 ipmi_sensor_threshold_assertion_event_supported(
5981 ipmi_sensor_t *sensor,
5982 enum ipmi_thresh_e event,
5983 enum ipmi_event_value_dir_e dir,
5984 int *val)
5985 {
5986 int idx;
5987
5988 CHECK_SENSOR_LOCK(sensor);
5989
5990 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
5991 /* Not a threshold sensor, it doesn't have readings. */
5992 return ENOSYS;
5993
5994 idx = (event * 2) + dir;
5995 if (idx > 11)
5996 return EINVAL;
5997
5998 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask1, idx);
5999 return 0;
6000 }
6001
6002 int
ipmi_sensor_threshold_deassertion_event_supported(ipmi_sensor_t * sensor,enum ipmi_thresh_e event,enum ipmi_event_value_dir_e dir,int * val)6003 ipmi_sensor_threshold_deassertion_event_supported(
6004 ipmi_sensor_t *sensor,
6005 enum ipmi_thresh_e event,
6006 enum ipmi_event_value_dir_e dir,
6007 int *val)
6008 {
6009 int idx;
6010
6011 CHECK_SENSOR_LOCK(sensor);
6012
6013 if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
6014 /* Not a threshold sensor, it doesn't have readings. */
6015 return ENOSYS;
6016
6017 idx = (event * 2) + dir;
6018 if (idx > 11)
6019 return 0;
6020
6021 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask2, idx);
6022 return 0;
6023 }
6024
6025 int
ipmi_sensor_discrete_assertion_event_supported(ipmi_sensor_t * sensor,int event,int * val)6026 ipmi_sensor_discrete_assertion_event_supported(ipmi_sensor_t *sensor,
6027 int event,
6028 int *val)
6029 {
6030 CHECK_SENSOR_LOCK(sensor);
6031
6032 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
6033 /* A threshold sensor, it doesn't have events. */
6034 return ENOSYS;
6035
6036 if (event > 14)
6037 return EINVAL;
6038
6039 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask1, event);
6040 return 0;
6041 }
6042
6043 int
ipmi_sensor_discrete_deassertion_event_supported(ipmi_sensor_t * sensor,int event,int * val)6044 ipmi_sensor_discrete_deassertion_event_supported(ipmi_sensor_t *sensor,
6045 int event,
6046 int *val)
6047 {
6048 CHECK_SENSOR_LOCK(sensor);
6049
6050 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
6051 /* A threshold sensor, it doesn't have events. */
6052 return ENOSYS;
6053
6054 if (event > 14)
6055 return EINVAL;
6056
6057 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask2, event);
6058 return 0;
6059 }
6060
6061 int
ipmi_sensor_events_enable_get(ipmi_sensor_t * sensor,ipmi_sensor_event_enables_cb done,void * cb_data)6062 ipmi_sensor_events_enable_get(ipmi_sensor_t *sensor,
6063 ipmi_sensor_event_enables_cb done,
6064 void *cb_data)
6065 {
6066 return ipmi_sensor_get_event_enables(sensor, done, cb_data);
6067 }
6068
6069 int
ipmi_sensor_events_disable(ipmi_sensor_t * sensor,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)6070 ipmi_sensor_events_disable(ipmi_sensor_t *sensor,
6071 ipmi_event_state_t *states,
6072 ipmi_sensor_done_cb done,
6073 void *cb_data)
6074 {
6075 return ipmi_sensor_disable_events(sensor, states, done, cb_data);
6076 }
6077
6078 int
ipmi_sensor_events_enable(ipmi_sensor_t * sensor,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)6079 ipmi_sensor_events_enable(ipmi_sensor_t *sensor,
6080 ipmi_event_state_t *states,
6081 ipmi_sensor_done_cb done,
6082 void *cb_data)
6083 {
6084 return ipmi_sensor_enable_events(sensor, states, done, cb_data);
6085 }
6086
ipmi_sensor_events_enable_set(ipmi_sensor_t * sensor,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)6087 int ipmi_sensor_events_enable_set(ipmi_sensor_t *sensor,
6088 ipmi_event_state_t *states,
6089 ipmi_sensor_done_cb done,
6090 void *cb_data)
6091 {
6092 return ipmi_sensor_set_event_enables(sensor, states, done, cb_data);
6093 }
6094
6095 int
ipmi_sensor_id_events_enable_set(ipmi_sensor_id_t sensor_id,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)6096 ipmi_sensor_id_events_enable_set(ipmi_sensor_id_t sensor_id,
6097 ipmi_event_state_t *states,
6098 ipmi_sensor_done_cb done,
6099 void *cb_data)
6100 {
6101 return ipmi_sensor_id_set_event_enables(sensor_id, states, done, cb_data);
6102 }
6103
6104 int
ipmi_sensor_id_events_enable(ipmi_sensor_id_t sensor_id,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)6105 ipmi_sensor_id_events_enable(ipmi_sensor_id_t sensor_id,
6106 ipmi_event_state_t *states,
6107 ipmi_sensor_done_cb done,
6108 void *cb_data)
6109 {
6110 return ipmi_sensor_id_enable_events(sensor_id, states, done, cb_data);
6111 }
6112
6113 int
ipmi_sensor_id_events_disable(ipmi_sensor_id_t sensor_id,ipmi_event_state_t * states,ipmi_sensor_done_cb done,void * cb_data)6114 ipmi_sensor_id_events_disable(ipmi_sensor_id_t sensor_id,
6115 ipmi_event_state_t *states,
6116 ipmi_sensor_done_cb done,
6117 void *cb_data)
6118 {
6119 return ipmi_sensor_id_disable_events(sensor_id, states, done, cb_data);
6120 }
6121
6122 int
ipmi_sensor_id_events_enable_get(ipmi_sensor_id_t sensor_id,ipmi_sensor_event_enables_cb done,void * cb_data)6123 ipmi_sensor_id_events_enable_get(ipmi_sensor_id_t sensor_id,
6124 ipmi_sensor_event_enables_cb done,
6125 void *cb_data)
6126 {
6127 return ipmi_sensor_id_get_event_enables(sensor_id, done, cb_data);
6128 }
6129
6130 int
ipmi_states_get(ipmi_sensor_t * sensor,ipmi_sensor_states_cb done,void * cb_data)6131 ipmi_states_get(ipmi_sensor_t *sensor,
6132 ipmi_sensor_states_cb done,
6133 void *cb_data)
6134 {
6135 return ipmi_sensor_get_states(sensor, done, cb_data);
6136 }
6137
6138 int
ipmi_reading_get(ipmi_sensor_t * sensor,ipmi_sensor_reading_cb done,void * cb_data)6139 ipmi_reading_get(ipmi_sensor_t *sensor,
6140 ipmi_sensor_reading_cb done,
6141 void *cb_data)
6142 {
6143 return ipmi_sensor_get_reading(sensor, done, cb_data);
6144 }
6145
6146 int
ipmi_thresholds_set(ipmi_sensor_t * sensor,ipmi_thresholds_t * thresholds,ipmi_sensor_done_cb done,void * cb_data)6147 ipmi_thresholds_set(ipmi_sensor_t *sensor,
6148 ipmi_thresholds_t *thresholds,
6149 ipmi_sensor_done_cb done,
6150 void *cb_data)
6151 {
6152 return ipmi_sensor_set_thresholds(sensor, thresholds, done, cb_data);
6153 }
6154
6155 int
ipmi_thresholds_get(ipmi_sensor_t * sensor,ipmi_sensor_thresholds_cb done,void * cb_data)6156 ipmi_thresholds_get(ipmi_sensor_t *sensor,
6157 ipmi_sensor_thresholds_cb done,
6158 void *cb_data)
6159 {
6160 return ipmi_sensor_get_thresholds(sensor, done, cb_data);
6161 }
6162
6163 int
ipmi_sensor_id_thresholds_set(ipmi_sensor_id_t sensor_id,ipmi_thresholds_t * thresholds,ipmi_sensor_done_cb done,void * cb_data)6164 ipmi_sensor_id_thresholds_set(ipmi_sensor_id_t sensor_id,
6165 ipmi_thresholds_t *thresholds,
6166 ipmi_sensor_done_cb done,
6167 void *cb_data)
6168 {
6169 return ipmi_sensor_id_set_thresholds(sensor_id, thresholds, done, cb_data);
6170 }
6171
6172 int
ipmi_sensor_id_thresholds_get(ipmi_sensor_id_t sensor_id,ipmi_sensor_thresholds_cb done,void * cb_data)6173 ipmi_sensor_id_thresholds_get(ipmi_sensor_id_t sensor_id,
6174 ipmi_sensor_thresholds_cb done,
6175 void *cb_data)
6176 {
6177 return ipmi_sensor_id_get_thresholds(sensor_id, done, cb_data);
6178 }
6179
6180 int
ipmi_sensor_id_reading_get(ipmi_sensor_id_t sensor_id,ipmi_sensor_reading_cb done,void * cb_data)6181 ipmi_sensor_id_reading_get(ipmi_sensor_id_t sensor_id,
6182 ipmi_sensor_reading_cb done,
6183 void *cb_data)
6184 {
6185 return ipmi_sensor_id_get_reading(sensor_id, done, cb_data);
6186 }
6187
6188 int
ipmi_sensor_id_states_get(ipmi_sensor_id_t sensor_id,ipmi_sensor_states_cb done,void * cb_data)6189 ipmi_sensor_id_states_get(ipmi_sensor_id_t sensor_id,
6190 ipmi_sensor_states_cb done,
6191 void *cb_data)
6192 {
6193 return ipmi_sensor_id_get_states(sensor_id, done, cb_data);
6194 }
6195
6196 int
ipmi_discrete_event_readable(ipmi_sensor_t * sensor,int event,int * val)6197 ipmi_discrete_event_readable(ipmi_sensor_t *sensor,
6198 int event,
6199 int *val)
6200 {
6201 CHECK_SENSOR_LOCK(sensor);
6202
6203 if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
6204 /* A threshold sensor, it doesn't have events. */
6205 return ENOSYS;
6206
6207 if (event > 14)
6208 return EINVAL;
6209
6210 *val = IPMI_SENSOR_GET_MASK_BIT(sensor->mask3, event);
6211 return 0;
6212 }
6213