~ubuntu-branches/ubuntu/vivid/openipmi/vivid

« back to all changes in this revision

Viewing changes to lib/event.c

  • Committer: Bazaar Package Importer
  • Author(s): Noèl Köthe
  • Date: 2006-09-15 17:56:24 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 etch)
  • Revision ID: james.westby@ubuntu.com-20060915175624-ljk0mg3xtcm65tvm
Tags: 2.0.7-1
* new upstream release from 2006-06-08
  Thanks to John Wright <john.wright hp.com> for initial work
  (closes: Bug#380149)
* updated Standards Version
* new binaries openipmicmd, openipmish, rmcp_ping

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include <OpenIPMI/internal/ipmi_event.h>
40
40
#include <OpenIPMI/internal/ipmi_int.h>
41
41
#include <OpenIPMI/internal/ipmi_mc.h>
 
42
#include <OpenIPMI/internal/ipmi_domain.h>
42
43
 
43
44
struct ipmi_event_s
44
45
{
240
241
 
241
242
    return rv;
242
243
}
 
244
 
 
245
ipmi_mc_t *
 
246
_ipmi_event_get_generating_mc(ipmi_domain_t      *domain,
 
247
                              ipmi_mc_t          *sel_mc,
 
248
                              const ipmi_event_t *event)
 
249
{
 
250
    ipmi_ipmb_addr_t    addr;
 
251
    const unsigned char *data;
 
252
    unsigned int        type = ipmi_event_get_type(event);
 
253
 
 
254
    if (type != 0x02)
 
255
        /* It's not a standard IPMI event. */
 
256
        return NULL;
 
257
 
 
258
    data = ipmi_event_get_data_ptr(event);
 
259
    addr.addr_type = IPMI_IPMB_ADDR_TYPE;
 
260
    /* See if the MC has an OEM handler for this. */
 
261
    if (data[6] == 0x03) {
 
262
        addr.channel = 0;
 
263
    } else {
 
264
        addr.channel = data[5] >> 4;
 
265
    }
 
266
    if ((data[4] & 0x01) == 0) {
 
267
        addr.slave_addr = data[4];
 
268
    } else if (sel_mc) {
 
269
        /* A software ID, assume it comes from the MC where we go it. */
 
270
        ipmi_addr_t iaddr;
 
271
 
 
272
        ipmi_mc_get_ipmi_address(sel_mc, &iaddr, NULL);
 
273
        addr.slave_addr = ipmi_addr_get_slave_addr(&iaddr);
 
274
        if (addr.slave_addr == 0)
 
275
            /* A system interface, just assume it's the BMC. */
 
276
            addr.slave_addr = 0x20;
 
277
    } else {
 
278
        return NULL;
 
279
    }
 
280
    addr.lun = 0;
 
281
 
 
282
    return _ipmi_find_mc_by_addr(domain, (ipmi_addr_t *) &addr, sizeof(addr));
 
283
}
 
284
 
 
285
ipmi_sensor_id_t
 
286
ipmi_event_get_generating_sensor_id(ipmi_domain_t       *domain,
 
287
                                    ipmi_mc_t           *sel_mc,
 
288
                                    const ipmi_event_t  *event)
 
289
{
 
290
    ipmi_sensor_id_t    id;
 
291
    ipmi_mc_t           *mc;
 
292
    const unsigned char *data;
 
293
    unsigned int        type = ipmi_event_get_type(event);
 
294
 
 
295
 
 
296
    if (type != 0x02)
 
297
        /* It's not a standard IPMI event. */
 
298
        goto out_invalid;
 
299
 
 
300
    mc = _ipmi_event_get_generating_mc(domain, sel_mc, event);
 
301
    if (!mc)
 
302
        goto out_invalid;
 
303
 
 
304
    data = ipmi_event_get_data_ptr(event);
 
305
    id.mcid = ipmi_mc_convert_to_id(mc);
 
306
    id.lun = data[5] & 0x3;
 
307
    id.sensor_num = data[8];
 
308
 
 
309
    _ipmi_mc_put(mc);
 
310
 
 
311
    return id;
 
312
 
 
313
 out_invalid:
 
314
    ipmi_sensor_id_set_invalid(&id);
 
315
    return id;
 
316
}
 
317
 
 
318
struct ipmi_event_handlers_s
 
319
{
 
320
    ipmi_sensor_threshold_event_cb threshold;
 
321
    ipmi_sensor_discrete_event_cb  discrete;
 
322
};
 
323
 
 
324
ipmi_event_handlers_t *
 
325
ipmi_event_handlers_alloc(void)
 
326
{
 
327
    ipmi_event_handlers_t *rv;
 
328
    rv = ipmi_mem_alloc(sizeof(*rv));
 
329
    if (!rv)
 
330
        return NULL;
 
331
    memset(rv, 0, sizeof(*rv));
 
332
    return rv;
 
333
}
 
334
 
 
335
void
 
336
ipmi_event_handlers_free(ipmi_event_handlers_t *handlers)
 
337
{
 
338
    ipmi_mem_free(handlers);
 
339
}
 
340
 
 
341
void
 
342
ipmi_event_handlers_set_threshold(ipmi_event_handlers_t         *handlers,
 
343
                                  ipmi_sensor_threshold_event_cb handler)
 
344
{
 
345
    handlers->threshold = handler;
 
346
}
 
347
 
 
348
void
 
349
ipmi_event_handlers_set_discrete(ipmi_event_handlers_t         *handlers,
 
350
                                 ipmi_sensor_discrete_event_cb handler)
 
351
{
 
352
    handlers->discrete = handler;
 
353
}
 
354
 
 
355
typedef struct event_call_handlers_s
 
356
{
 
357
    ipmi_domain_t         *domain;
 
358
    ipmi_event_handlers_t *handlers;
 
359
    ipmi_event_t          *event;
 
360
    int                   rv;
 
361
    void                  *cb_data;
 
362
} event_call_handlers_t;
 
363
 
 
364
static void
 
365
sensor_event_call(ipmi_sensor_t *sensor, void *cb_data)
 
366
{
 
367
    event_call_handlers_t *info = cb_data;
 
368
    int                   rv;
 
369
 
 
370
    if (ipmi_sensor_get_event_reading_type(sensor)
 
371
        == IPMI_EVENT_READING_TYPE_THRESHOLD)
 
372
    {
 
373
        enum ipmi_event_dir_e       dir;
 
374
        enum ipmi_thresh_e          threshold;
 
375
        enum ipmi_event_value_dir_e high_low;
 
376
        enum ipmi_value_present_e   value_present;
 
377
        unsigned int                raw_value;
 
378
        double                      value;
 
379
        const unsigned char         *data;
 
380
 
 
381
        data = ipmi_event_get_data_ptr(info->event);
 
382
        dir = data[9] >> 7;
 
383
        threshold = (data[10] >> 1) & 0x07;
 
384
        high_low = data[10] & 1;
 
385
        raw_value = data[11];
 
386
        value = 0.0;
 
387
 
 
388
        if ((data[10] >> 6) == 2) {
 
389
            rv = ipmi_sensor_convert_from_raw(sensor, raw_value, &value);
 
390
            if (!rv)
 
391
                value_present = IPMI_RAW_VALUE_PRESENT;
 
392
            else
 
393
                value_present = IPMI_BOTH_VALUES_PRESENT;
 
394
        } else {
 
395
            value_present = IPMI_NO_VALUES_PRESENT;
 
396
        }
 
397
        if (info->handlers->threshold)
 
398
            info->handlers->threshold(sensor, dir,
 
399
                                      threshold,
 
400
                                      high_low,
 
401
                                      value_present,
 
402
                                      raw_value, value,
 
403
                                      info->cb_data,
 
404
                                      info->event);
 
405
 
 
406
        else
 
407
            info->rv = EAGAIN;
 
408
    } else {
 
409
        enum ipmi_event_dir_e dir;
 
410
        int                   offset;
 
411
        int                   severity = 0;
 
412
        int                   prev_severity = 0;
 
413
        const unsigned char   *data;
 
414
 
 
415
        data = ipmi_event_get_data_ptr(info->event);
 
416
        dir = data[9] >> 7;
 
417
        offset = data[10] & 0x0f;
 
418
        if ((data[10] >> 6) == 2) {
 
419
            severity = data[11] >> 4;
 
420
            prev_severity = data[11] & 0xf;
 
421
            if (severity == 0xf)
 
422
                severity = -1;
 
423
            if (prev_severity == 0xf)
 
424
                prev_severity = -1;
 
425
        }
 
426
 
 
427
        if (info->handlers->discrete)
 
428
            info->handlers->discrete(sensor, dir, offset,
 
429
                                     severity,
 
430
                                     prev_severity,
 
431
                                     info->cb_data,
 
432
                                     info->event);
 
433
        else
 
434
            info->rv = EAGAIN;
 
435
    }
 
436
}
 
437
 
 
438
static void
 
439
sel_mc_handler(ipmi_mc_t *mc, void *cb_data)
 
440
{
 
441
    ipmi_sensor_id_t      sensor_id;
 
442
    event_call_handlers_t *info = cb_data;
 
443
    int                   rv;
 
444
 
 
445
    sensor_id = ipmi_event_get_generating_sensor_id(info->domain, mc,
 
446
                                                    info->event);
 
447
    rv = ipmi_sensor_pointer_cb(sensor_id, sensor_event_call, info);
 
448
    if (rv)
 
449
        info->rv = rv;
 
450
}
 
451
 
 
452
int
 
453
ipmi_event_call_handler(ipmi_domain_t         *domain,
 
454
                        ipmi_event_handlers_t *handlers,
 
455
                        ipmi_event_t          *event,
 
456
                        void                  *cb_data)
 
457
{
 
458
 
 
459
 
 
460
    ipmi_sensor_id_t      sensor_id;
 
461
    event_call_handlers_t info;
 
462
    int                   rv = 0;
 
463
    ipmi_mcid_t           mc_id;
 
464
 
 
465
    info.domain = domain;
 
466
    info.handlers = handlers;
 
467
    info.event = event;
 
468
    info.rv = 0;
 
469
    info.cb_data = cb_data;
 
470
 
 
471
    /* We try first to get the MC the event is stored in.  If that
 
472
       doesn't work, then just attempt to do the sensor without an MC. */
 
473
    mc_id = ipmi_event_get_mcid(event);
 
474
    if (ipmi_mc_pointer_cb(mc_id, sel_mc_handler, &info) != 0) {
 
475
        sensor_id = ipmi_event_get_generating_sensor_id(domain, NULL, event);
 
476
        rv = ipmi_sensor_pointer_cb(sensor_id, sensor_event_call, &info);
 
477
    }
 
478
    if (!rv)
 
479
        rv = info.rv;
 
480
    return rv;
 
481
}