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

« back to all changes in this revision

Viewing changes to lib/entity.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:
145
145
    ipmi_domain_id_t domain_id;
146
146
    long             seq;
147
147
 
 
148
    dlr_ref_t key;
 
149
 
148
150
    /* Lock used for protecting misc data. */
149
 
    ipmi_lock_t *lock;
 
151
    ipmi_lock_t *elock;
150
152
 
151
153
    int usecount;
152
154
 
201
203
    int           presence_possibly_changed;
202
204
    unsigned int  presence_event_count; /* Changed when presence
203
205
                                           events are reported. */
 
206
    /* Only allow one presence check at a time. */
 
207
    int           in_presence_check;
204
208
 
205
209
    /* If the presence changes while the entity is in use, we store it
206
210
       in here and the count instead of actually changing it.  Then we
297
301
    locked_list_t         *entities;
298
302
};
299
303
 
300
 
static void call_fru_handlers(ipmi_entity_t *ent, enum ipmi_update_e op);
 
304
#define ent_lock(e) ipmi_lock(e->elock)
 
305
#define ent_unlock(e) ipmi_unlock(e->elock)
 
306
 
301
307
static void entity_mc_active(ipmi_mc_t *mc, int active, void *cb_data);
302
 
static int call_presence_handlers(ipmi_entity_t *ent, int present,
303
 
                                  int handled, ipmi_event_t **event);
 
308
static void call_presence_handlers(ipmi_entity_t *ent, int present);
304
309
 
305
310
/***********************************************************************
306
311
 *
518
523
    entity_destroy_timer(ent->hot_swap_deact_info);
519
524
 
520
525
    if (ent->frudev_present) {
 
526
        _ipmi_domain_mc_lock(ent->domain);
 
527
        _ipmi_mc_get(ent->frudev_mc);
 
528
        _ipmi_domain_mc_unlock(ent->domain);
521
529
        ipmi_mc_remove_active_handler(ent->frudev_mc, entity_mc_active, ent);
522
530
        _ipmi_mc_release(ent->frudev_mc);
 
531
        _ipmi_mc_put(ent->frudev_mc);
523
532
    }
524
533
 
525
534
    if (ent->oem_info_cleanup_handler)
541
550
    locked_list_destroy(ent->control_handlers);
542
551
    locked_list_destroy(ent->sensor_handlers);
543
552
 
544
 
    ipmi_destroy_lock(ent->lock);
 
553
    ipmi_destroy_lock(ent->elock);
545
554
 
546
555
    ipmi_mem_free(ent);
547
556
 
652
661
{
653
662
    int length = sizeof(entity->name);
654
663
 
655
 
    ipmi_lock(entity->lock);
 
664
    ent_lock(entity);
656
665
    length = ipmi_domain_get_name(entity->domain, entity->name, length);
657
666
    entity->name[length] = '(';
658
667
    length++;
659
 
    if (entity->info.entity_instance >= 0x60) {
 
668
    if (entity->key.entity_instance >= 0x60) {
660
669
        length += snprintf(entity->name+length, IPMI_ENTITY_NAME_LEN-length-3,
661
670
                           "r%d.%d.%d.%d",
662
 
                           entity->info.device_num.channel,
663
 
                           entity->info.device_num.address,
664
 
                           entity->info.entity_id,
665
 
                           entity->info.entity_instance - 0x60);
 
671
                           entity->key.device_num.channel,
 
672
                           entity->key.device_num.address,
 
673
                           entity->key.entity_id,
 
674
                           entity->key.entity_instance - 0x60);
666
675
    } else {
667
676
        length += snprintf(entity->name+length, IPMI_ENTITY_NAME_LEN-length-3,
668
 
                           "%d.%d", entity->info.entity_id,
669
 
                           entity->info.entity_instance);
 
677
                           "%d.%d", entity->key.entity_id,
 
678
                           entity->key.entity_instance);
670
679
    }
671
680
    entity->name[length] = ')';
672
681
    length++;
674
683
    length++;
675
684
    entity->name[length] = '\0';
676
685
    length++;
677
 
    ipmi_unlock(entity->lock);
 
686
    ent_unlock(entity);
678
687
}
679
688
 
680
689
const char *
745
754
_ipmi_entity_put(ipmi_entity_t *ent)
746
755
{
747
756
    ipmi_domain_t *domain = ent->domain;
 
757
    int           entity_fru_fetch = 0;
748
758
    _ipmi_domain_entity_lock(domain);
749
759
 retry:
750
760
    if (ent->usecount == 1) {
753
763
            ent->info = ent->pending_info;
754
764
            /* If the entity became a fru and is present, get its fru info. */
755
765
            if (!was_fru && ipmi_entity_get_is_fru(ent) && ent->present)
756
 
                ipmi_entity_fetch_frus(ent);
 
766
                entity_fru_fetch = 1;
757
767
            entity_set_name(ent);
758
768
            ent->pending_info_ready = 0;
759
769
        }
784
794
                goto out;
785
795
        }
786
796
 
 
797
        if (ent->presence_possibly_changed) {
 
798
            _ipmi_domain_entity_unlock(domain);
 
799
            ipmi_detect_entity_presence_change(ent, 0);
 
800
            _ipmi_domain_entity_lock(domain);
 
801
 
 
802
            if (ent->usecount != 1)
 
803
                goto out;
 
804
        }
 
805
 
787
806
        while (ent->present_change_count) {
788
807
            int present;
789
808
            ent->present = !ent->present;
790
809
            present = ent->present;
791
810
            ent->present_change_count--;
792
811
            _ipmi_domain_entity_unlock(domain);
793
 
            call_presence_handlers(ent, present, IPMI_EVENT_NOT_HANDLED, NULL);
 
812
            call_presence_handlers(ent, present);
794
813
            _ipmi_domain_entity_lock(domain);
795
814
 
796
815
            /* Something grabbed the entity while the lock wasn't
814
833
 out:
815
834
    ent->usecount--;
816
835
 out2:
 
836
    /* Wait till here to start fetching FRUs, as we want to report the
 
837
       entity first before we start the fetch. */
 
838
    if (entity_fru_fetch) {
 
839
        ent->usecount++;
 
840
        ipmi_entity_fetch_frus(ent);
 
841
        ent->usecount--;
 
842
    }
817
843
    _ipmi_domain_entity_unlock(domain);
818
844
}
819
845
 
820
846
int
821
847
_ipmi_entity_add_ref(ipmi_entity_t *ent)
822
848
{
823
 
    ipmi_lock(ent->lock);
 
849
    ent_lock(ent);
824
850
    ent->ref_count++;
825
 
    ipmi_unlock(ent->lock);
 
851
    ent_unlock(ent);
826
852
    return 0;
827
853
}
828
854
 
829
855
int
830
856
_ipmi_entity_remove_ref(ipmi_entity_t *ent)
831
857
{
832
 
    ipmi_lock(ent->lock);
 
858
    ent_lock(ent);
833
859
    ent->ref_count--;
834
 
    ipmi_unlock(ent->lock);
 
860
    ent_unlock(ent);
835
861
    return 0;
836
862
}
837
863
 
858
884
}
859
885
 
860
886
typedef struct search_info_s {
861
 
    ipmi_device_num_t device_num;
862
 
    uint8_t           entity_id;
863
 
    uint8_t           entity_instance;
 
887
    dlr_ref_t         key;
864
888
    ipmi_entity_t     *ent;
865
889
} search_info_t;
866
890
 
871
895
    search_info_t *info = (search_info_t *) cb_data;
872
896
    int           same;
873
897
 
874
 
    same = ((ent->info.device_num.channel == info->device_num.channel)
875
 
            && (ent->info.device_num.address == info->device_num.address)
876
 
            && (ent->info.entity_id == info->entity_id)
877
 
            && (ent->info.entity_instance == info->entity_instance));
 
898
    same = ((ent->key.device_num.channel == info->key.device_num.channel)
 
899
            && (ent->key.device_num.address == info->key.device_num.address)
 
900
            && (ent->key.entity_id == info->key.entity_id)
 
901
            && (ent->key.entity_instance == info->key.entity_instance));
878
902
    if (same) {
879
903
        info->ent = ent;
880
904
        return LOCKED_LIST_ITER_STOP;
889
913
            int                entity_instance,
890
914
            ipmi_entity_t      **found_ent)
891
915
{
892
 
    search_info_t info = {device_num, entity_id, entity_instance, NULL};
 
916
    search_info_t info = { {device_num, entity_id, entity_instance}, NULL};
893
917
    int           rv = 0;
894
918
 
895
919
    locked_list_iterate_nolock(ents->entities, search_entity, &info);
1030
1054
    if (!ent->control_handlers)
1031
1055
        goto out_err;
1032
1056
 
1033
 
    rv = ipmi_create_lock(ent->domain, &ent->lock);
 
1057
    rv = ipmi_create_lock(ent->domain, &ent->elock);
1034
1058
    if (rv)
1035
1059
        goto out_err;
1036
1060
 
1053
1077
    ent->ents = ents;
1054
1078
 
1055
1079
    ent->info.type = IPMI_ENTITY_UNKNOWN;
1056
 
    ent->info.device_num = device_num;
1057
 
    ent->info.entity_id = entity_id;
1058
 
    ent->info.entity_instance = entity_instance;
 
1080
    ent->key.device_num = device_num;
 
1081
    ent->key.entity_id = entity_id;
 
1082
    ent->key.entity_instance = entity_instance;
1059
1083
    ent->info.id_type = IPMI_ASCII_STR;
1060
1084
 
1061
1085
    ent->entity_id_string = ipmi_get_entity_id_string(entity_id);
1083
1107
        entity_destroy_timer(ent->hot_swap_act_info);
1084
1108
    if (ent->hot_swap_deact_info)
1085
1109
        entity_destroy_timer(ent->hot_swap_deact_info);
1086
 
    if (ent->lock)
1087
 
        ipmi_destroy_lock(ent->lock);
 
1110
    if (ent->elock)
 
1111
        ipmi_destroy_lock(ent->elock);
1088
1112
    if (ent->presence_handlers)
1089
1113
        locked_list_destroy(ent->presence_handlers);
1090
1114
    if (ent->waitq)
1354
1378
{
1355
1379
    ipmi_entity_t             *ent;
1356
1380
    int                       present;
1357
 
    ipmi_event_t              *event;
1358
 
    int                       handled;
1359
1381
} presence_handler_info_t;
1360
1382
 
1361
1383
static int
1363
1385
{
1364
1386
    presence_handler_info_t        *info = cb_data;
1365
1387
    ipmi_entity_presence_change_cb handler = item1;
1366
 
    int                            handled;
1367
1388
 
1368
 
    handled = handler(info->ent, info->present, item2, info->event);
1369
 
    if (handled == IPMI_EVENT_HANDLED) {
1370
 
        info->handled = handled;
1371
 
        info->event = NULL;
1372
 
    }
 
1389
    handler(info->ent, info->present, item2, NULL);
1373
1390
    return LOCKED_LIST_ITER_CONTINUE;
1374
1391
}
1375
1392
 
1376
 
static int
1377
 
call_presence_handlers(ipmi_entity_t *ent, int present,
1378
 
                       int handled, ipmi_event_t **event)
 
1393
static void
 
1394
call_presence_handlers(ipmi_entity_t *ent, int present)
1379
1395
{
1380
1396
    presence_handler_info_t info;
1381
1397
 
1382
1398
    info.ent = ent;
1383
1399
    info.present = present;
1384
 
    if (!event)
1385
 
        info.event = NULL;
1386
 
    else
1387
 
        info.event = *event;
1388
 
    info.handled = handled;
1389
 
    ipmi_lock(ent->lock);
 
1400
    ent_lock(ent);
1390
1401
    if (ent->cruft_presence_handler) {
1391
1402
        ipmi_entity_presence_nd_cb handler = ent->cruft_presence_handler;
1392
1403
        void                       *cb_data = ent->cruft_presence_cb_data;
1393
 
        ipmi_unlock(ent->lock);
1394
 
        handler(ent, info.present, cb_data, info.event);
1395
 
        info.handled = IPMI_EVENT_HANDLED;
 
1404
        ent_unlock(ent);
 
1405
        handler(ent, info.present, cb_data, NULL);
1396
1406
    } else
1397
 
        ipmi_unlock(ent->lock);
 
1407
        ent_unlock(ent);
1398
1408
    locked_list_iterate(ent->presence_handlers, call_presence_handler,
1399
1409
                        &info);
1400
 
    if (event)
1401
 
        *event = info.event;
1402
 
    return info.handled;
1403
1410
}
1404
1411
 
1405
1412
/* This is for iterating the parents when a sensor's presence changes.
1417
1424
}
1418
1425
 
1419
1426
static void
1420
 
presence_changed(ipmi_entity_t *ent,
1421
 
                 int           present,
1422
 
                 ipmi_event_t  *event)
 
1427
presence_changed(ipmi_entity_t *ent, int present)
1423
1428
{
1424
 
    int                     handled = IPMI_EVENT_NOT_HANDLED;
1425
1429
    ipmi_fru_t              *fru;
1426
1430
    ipmi_domain_t           *domain = ent->domain;
1427
1431
 
1435
1439
        {
1436
1440
            /* Do internal presence handling if we have the internal
1437
1441
               hot-swap machine installed. */
1438
 
            handled = handle_hot_swap_presence(ent, present, event);
 
1442
            handle_hot_swap_presence(ent, present, NULL);
1439
1443
        }
1440
1444
 
1441
1445
        /* When the entity becomes present or absent, fetch or destroy
1448
1452
                ent->fru = NULL;
1449
1453
                ipmi_fru_destroy_internal(fru, NULL, NULL);
1450
1454
 
1451
 
                call_fru_handlers(ent, IPMI_DELETED);
 
1455
                _ipmi_entity_call_fru_handlers(ent, IPMI_DELETED);
1452
1456
            }
1453
1457
        }
1454
1458
 
1459
1463
        if (ent->usecount == 1) {
1460
1464
            ent->present = !ent->present;
1461
1465
            _ipmi_domain_entity_unlock(domain);
1462
 
            handled = call_presence_handlers(ent, present, handled, &event);
 
1466
            call_presence_handlers(ent, present);
1463
1467
            _ipmi_domain_entity_lock(domain);
1464
1468
            while ((ent->usecount == 1) && (ent->present_change_count)) {
1465
1469
                ent->present = !ent->present;
1466
1470
                present = ent->present;
1467
1471
                ent->present_change_count--;
1468
1472
                _ipmi_domain_entity_unlock(domain);
1469
 
                call_presence_handlers(ent, present, handled, NULL);
 
1473
                call_presence_handlers(ent, present);
1470
1474
                _ipmi_domain_entity_lock(domain);
1471
1475
            }
1472
1476
        } else {
1478
1482
           rescan them. */
1479
1483
        ipmi_entity_iterate_parents(ent, presence_parent_handler, NULL);
1480
1484
    }
1481
 
 
1482
 
    if (event && (handled == IPMI_EVENT_NOT_HANDLED))
1483
 
        ipmi_handle_unhandled_event(domain, event);
1484
1485
}
1485
1486
 
1486
1487
static void
1489
1490
                       void          *cb_data)
1490
1491
{
1491
1492
    int *present = cb_data;
 
1493
    int p = child->present;
1492
1494
 
1493
 
    if (child->present)
1494
 
        *present = 1;
 
1495
    if (ent->present_change_count % 2)
 
1496
        p = !p;
 
1497
    if (p)
 
1498
        *present = p;
1495
1499
}
1496
1500
 
1497
1501
static int
1508
1512
    /* zero offset is the "present" offset, 1 or 2 means it absent or
1509
1513
       disabled, coupled with the assertion/deassertion. */
1510
1514
    if (dir == IPMI_ASSERTION)
1511
 
        presence_changed(ent, offset == 0, event);
 
1515
        presence_changed(ent, offset == 0);
1512
1516
    else if (dir == IPMI_DEASSERTION)
1513
 
        presence_changed(ent, offset != 0, event);
 
1517
        presence_changed(ent, offset != 0);
1514
1518
    return IPMI_EVENT_NOT_HANDLED;
1515
1519
}
1516
1520
 
1530
1534
 
1531
1535
    /* Assertion means present. */
1532
1536
    if (dir == IPMI_ASSERTION)
1533
 
        presence_changed(ent, 1, event);
 
1537
        presence_changed(ent, 1);
1534
1538
    else if (dir == IPMI_DEASSERTION)
1535
 
        presence_changed(ent, 0, event);
 
1539
        presence_changed(ent, 0);
1536
1540
    return IPMI_EVENT_NOT_HANDLED;
1537
1541
}
1538
1542
 
1553
1557
} ent_active_detect_t;
1554
1558
 
1555
1559
static void
1556
 
detect_cleanup(ent_active_detect_t *info, ipmi_domain_t *domain)
 
1560
detect_cleanup(ent_active_detect_t *info, ipmi_entity_t *ent,
 
1561
               ipmi_domain_t *domain)
1557
1562
{
1558
1563
    ipmi_unlock(info->lock);
1559
1564
    ipmi_destroy_lock(info->lock);
1560
1565
    ipmi_mem_free(info);
1561
 
    _ipmi_put_domain_fully_up(domain);
 
1566
    if (ent)
 
1567
        ent->in_presence_check = 0;
 
1568
    _ipmi_put_domain_fully_up(domain, "detect_cleanup");
1562
1569
}
1563
1570
 
1564
1571
static void
1565
1572
detect_done(ipmi_entity_t *ent, ent_active_detect_t *info)
1566
1573
{
1567
1574
    ipmi_unlock(info->lock);
1568
 
    presence_changed(ent, info->present, NULL);
 
1575
    presence_changed(ent, info->present);
1569
1576
    ipmi_destroy_lock(info->lock);
1570
1577
    ipmi_mem_free(info);
1571
 
    _ipmi_put_domain_fully_up(ent->domain);
 
1578
    ent->in_presence_check = 0;
 
1579
    _ipmi_put_domain_fully_up(ent->domain, "detect_done");
1572
1580
}
1573
1581
 
1574
1582
static void
1583
1591
           set present and we detect it as not present.  However, it
1584
1592
           is not possible to detect it as present and for something
1585
1593
           else to set it not present. */
1586
 
        detect_cleanup(info, ent->domain);
 
1594
        detect_cleanup(info, ent, ent->domain);
1587
1595
        return;
1588
1596
    }
1589
1597
 
1600
1608
{
1601
1609
    ent_active_detect_t *info = rsp_data;
1602
1610
 
1603
 
    _ipmi_mc_put(mc);
1604
1611
    ipmi_lock(info->lock);
1605
1612
    info->msg = rsp;
1606
1613
    if (ipmi_entity_pointer_cb(info->ent_id, detect_frudev_handler, info))
1607
 
        detect_cleanup(info, ipmi_mc_get_domain(mc));
 
1614
        /* We cheat and pull the domain from the entity id.  The domain
 
1615
         * still has to be around in the place, but we can't rely on the
 
1616
         * MC as it may have gone away if it failed or the domain is in
 
1617
         * shutdown. */
 
1618
        detect_cleanup(info, NULL, info->ent_id.domain_id.domain);
1608
1619
}
1609
1620
 
1610
1621
/* This is the end of the line on checks.  We have to report something
1631
1642
 
1632
1643
    /* Send a message to the FRU device and see if we can get some
1633
1644
       data. */
 
1645
    _ipmi_domain_mc_lock(ent->domain);
1634
1646
    _ipmi_mc_get(ent->frudev_mc);
 
1647
    _ipmi_domain_mc_unlock(ent->domain);
1635
1648
    rv = ipmi_mc_send_command(ent->frudev_mc, ent->info.lun, &msg,
1636
1649
                              detect_frudev, info);
1637
 
    if (rv) {
1638
 
        _ipmi_mc_put(ent->frudev_mc);
 
1650
    _ipmi_mc_put(ent->frudev_mc);
 
1651
    if (rv)
1639
1652
        detect_done(ent, info);
1640
 
    }else
 
1653
    else
1641
1654
        ipmi_unlock(info->lock);
1642
1655
}
1643
1656
 
1665
1678
           set present and we detect it as not present.  However, it
1666
1679
           is not possible to detect it as present and for something
1667
1680
           else to set it not present. */
1668
 
        detect_cleanup(info, ent->domain);
 
1681
        detect_cleanup(info, ent, ent->domain);
1669
1682
        return;
1670
1683
    }
1671
1684
 
1696
1709
    info->done_count++;
1697
1710
    if (info->try_count == info->done_count) {
1698
1711
        if (ipmi_entity_pointer_cb(info->ent_id, control_detect_handler, info))
1699
 
            detect_cleanup(info, ipmi_control_get_domain(control));
 
1712
            detect_cleanup(info, NULL, ipmi_control_get_domain(control));
1700
1713
    } else
1701
1714
        ipmi_unlock(info->lock);
1702
1715
}
1716
1729
    info->done_count++;
1717
1730
    if (info->try_count == info->done_count) {
1718
1731
        if (ipmi_entity_pointer_cb(info->ent_id, control_detect_handler, info))
1719
 
            detect_cleanup(info, ipmi_control_get_domain(control));
 
1732
            detect_cleanup(info, NULL, ipmi_control_get_domain(control));
1720
1733
    } else
1721
1734
        ipmi_unlock(info->lock);
1722
1735
}
1737
1750
    info->done_count++;
1738
1751
    if (info->try_count == info->done_count) {
1739
1752
        if (ipmi_entity_pointer_cb(info->ent_id, control_detect_handler, info))
1740
 
            detect_cleanup(info, ipmi_control_get_domain(control));
 
1753
            detect_cleanup(info, NULL, ipmi_control_get_domain(control));
1741
1754
    } else
1742
1755
        ipmi_unlock(info->lock);
1743
1756
}
1758
1771
    info->done_count++;
1759
1772
    if (info->try_count == info->done_count) {
1760
1773
        if (ipmi_entity_pointer_cb(info->ent_id, control_detect_handler, info))
1761
 
            detect_cleanup(info, ipmi_control_get_domain(control));
 
1774
            detect_cleanup(info, NULL, ipmi_control_get_domain(control));
1762
1775
    } else
1763
1776
        ipmi_unlock(info->lock);
1764
1777
}
1805
1818
    info->done_count = 0;
1806
1819
    ipmi_entity_iterate_controls(ent, control_detect_send, info);
1807
1820
 
1808
 
    /* I couldn't message any sensors, go on. */
 
1821
    /* I couldn't message any controls, go on. */
1809
1822
    if (info->try_count == 1)
1810
1823
        return ENOSYS;
1811
1824
    info->done_count++;
1829
1842
           set present and we detect it as not present.  However, it
1830
1843
           is not possible to detect it as present and for something
1831
1844
           else to set it not present. */
1832
 
        detect_cleanup(info, ent->domain);
 
1845
        detect_cleanup(info, ent, ent->domain);
1833
1846
        return;
1834
1847
    }
1835
1848
 
1862
1875
    info->done_count++;
1863
1876
    if (info->try_count == info->done_count) {
1864
1877
        if (ipmi_entity_pointer_cb(info->ent_id, sensor_detect_handler, info))
1865
 
            detect_cleanup(info, ipmi_sensor_get_domain(sensor));
 
1878
            detect_cleanup(info, NULL, ipmi_sensor_get_domain(sensor));
1866
1879
    } else
1867
1880
        ipmi_unlock(info->lock);
1868
1881
}
1885
1898
    info->done_count++;
1886
1899
    if (info->try_count == info->done_count) {
1887
1900
        if (ipmi_entity_pointer_cb(info->ent_id, sensor_detect_handler, info))
1888
 
            detect_cleanup(info, ipmi_sensor_get_domain(sensor));
 
1901
            detect_cleanup(info, NULL, ipmi_sensor_get_domain(sensor));
1889
1902
    } else
1890
1903
        ipmi_unlock(info->lock);
1891
1904
}
1947
1960
 
1948
1961
    detect = ipmi_mem_alloc(sizeof(*detect));
1949
1962
    if (!detect) {
1950
 
        _ipmi_put_domain_fully_up(ent->domain);
 
1963
        ent->in_presence_check = 0;
 
1964
        _ipmi_put_domain_fully_up(ent->domain,
 
1965
                                  "detect_no_presence_sensor_presence");
1951
1966
        return;
1952
1967
    }
1953
1968
    rv = ipmi_create_lock(ent->domain, &detect->lock);
1954
1969
    if (rv) {
1955
 
        _ipmi_put_domain_fully_up(ent->domain);
 
1970
        ent->in_presence_check = 0;
 
1971
        _ipmi_put_domain_fully_up(ent->domain,
 
1972
                                  "detect_no_presence_sensor_presence(2)");
1956
1973
        ipmi_mem_free(detect);
1957
1974
        return;
1958
1975
    }
1989
2006
    int           rv;
1990
2007
 
1991
2008
    if (err) {
 
2009
        _ipmi_domain_entity_lock(ent->domain);
 
2010
        _ipmi_entity_get(ent);
 
2011
        _ipmi_domain_entity_unlock(ent->domain);
1992
2012
        detect_no_presence_sensor_presence(ent);
 
2013
        _ipmi_entity_put(ent);
1993
2014
        return;
1994
2015
    }
1995
2016
 
2001
2022
        /* The present bit is supported. */
2002
2023
        present = ipmi_is_state_set(states, 0);
2003
2024
 
2004
 
    presence_changed(ent, present, NULL);
2005
 
    _ipmi_put_domain_fully_up(ipmi_sensor_get_domain(sensor));
 
2025
    presence_changed(ent, present);
 
2026
    ent->in_presence_check = 0;
 
2027
    _ipmi_put_domain_fully_up(ipmi_sensor_get_domain(sensor), "states_read");
2006
2028
}
2007
2029
 
2008
2030
static void
2015
2037
    ipmi_entity_t *ent = cb_data;
2016
2038
 
2017
2039
    if (err) {
 
2040
        _ipmi_domain_entity_lock(ent->domain);
 
2041
        _ipmi_entity_get(ent);
 
2042
        _ipmi_domain_entity_unlock(ent->domain);
2018
2043
        detect_no_presence_sensor_presence(ent);
 
2044
        _ipmi_entity_put(ent);
2019
2045
        return;
2020
2046
    }
2021
2047
 
2022
2048
    present = ipmi_is_state_set(states, ent->presence_bit_offset);
2023
 
    presence_changed(ent, present, NULL);
2024
 
    _ipmi_put_domain_fully_up(ipmi_sensor_get_domain(sensor));
 
2049
    presence_changed(ent, present);
 
2050
    ent->in_presence_check = 0;
 
2051
    _ipmi_put_domain_fully_up(ipmi_sensor_get_domain(sensor),
 
2052
                              "states_bit_read");
2025
2053
}
2026
2054
 
2027
2055
static void
2030
2058
    ent_detect_info_t   *info = cb_data;
2031
2059
    int                 rv;
2032
2060
 
2033
 
    if ((!info->force) && (! ent->presence_possibly_changed))
 
2061
    ent_lock(ent);
 
2062
    if (ent->in_presence_check
 
2063
        || ((!info->force) && (! ent->presence_possibly_changed)))
 
2064
    {
 
2065
        ent_unlock(ent);
2034
2066
        return;
 
2067
    }
2035
2068
    ent->presence_possibly_changed = 0;
 
2069
    ent->in_presence_check = 1;
2036
2070
 
2037
 
    if (ent->hot_swappable)
 
2071
    if (ent->hot_swappable) {
 
2072
        ent_unlock(ent);
2038
2073
        ipmi_entity_check_hot_swap_state(ent);
 
2074
        ent_lock(ent);
 
2075
    }
2039
2076
 
2040
 
    _ipmi_get_domain_fully_up(ent->domain);
 
2077
    _ipmi_get_domain_fully_up(ent->domain, "ent_detect_presence");
2041
2078
    if (ent->presence_sensor) {
2042
2079
        /* Presence sensor overrides everything. */
2043
 
        rv = ipmi_sensor_id_get_states(ent->presence_sensor_id,
2044
 
                                       states_read, ent);
2045
 
        if (rv)
2046
 
            _ipmi_put_domain_fully_up(ent->domain);
 
2080
        ipmi_sensor_id_t psi = ent->presence_sensor_id;
 
2081
        ent_unlock(ent);
 
2082
        rv = ipmi_sensor_id_get_states(psi, states_read, ent);
 
2083
        if (rv) {
 
2084
            ent->in_presence_check = 0;
 
2085
            _ipmi_put_domain_fully_up(ent->domain, "ent_detect_presence(2)");
 
2086
        }
2047
2087
    } else if (ent->presence_bit_sensor) {
2048
2088
        /* Presence bit sensor overrides everything but a presence sensor. */
2049
 
        rv = ipmi_sensor_id_get_states(ent->presence_bit_sensor_id,
2050
 
                                       states_bit_read, ent);
2051
 
        if (rv)
2052
 
            _ipmi_put_domain_fully_up(ent->domain);
 
2089
        ipmi_sensor_id_t psi = ent->presence_bit_sensor_id;
 
2090
        ent_unlock(ent);
 
2091
        rv = ipmi_sensor_id_get_states(psi, states_bit_read, ent);
 
2092
        if (rv) {
 
2093
            ent->in_presence_check = 0;
 
2094
            _ipmi_put_domain_fully_up(ent->domain, "ent_detect_presence(3)");
 
2095
        }
2053
2096
    } else {
 
2097
        ent_unlock(ent);
2054
2098
        detect_no_presence_sensor_presence(ent);
2055
2099
    }
2056
2100
}
2081
2125
    ipmi_entity_t *ent = cb_data;
2082
2126
    int           rv;
2083
2127
 
 
2128
    _ipmi_domain_entity_lock(ent->domain);
2084
2129
    rv = _ipmi_entity_get(ent);
 
2130
    _ipmi_domain_entity_unlock(ent->domain);
2085
2131
    if (rv)
2086
2132
        return;
2087
2133
 
2100
2146
    _ipmi_entity_put(ent);
2101
2147
}
2102
2148
 
 
2149
/* Must be called with the entity lock held.  May release and reclaim it. */
2103
2150
static void
2104
2151
handle_new_presence_sensor(ipmi_entity_t *ent, ipmi_sensor_t *sensor)
2105
2152
{
2109
2156
    int                val;
2110
2157
 
2111
2158
    ent->presence_sensor_id = ipmi_sensor_convert_to_id(sensor);
 
2159
    ent->presence_sensor = sensor;
2112
2160
 
2113
2161
    /* If we have a presence sensor, remove the presence bit sensor. */
2114
2162
    if (ent->presence_bit_sensor) {
 
2163
        ent->presence_bit_sensor = NULL;
2115
2164
        ipmi_sensor_remove_discrete_event_handler(ent->presence_bit_sensor,
2116
2165
                                                  presence_sensor_changed,
2117
2166
                                                  ent);
2118
 
        ent->presence_bit_sensor = NULL;
2119
2167
    }
2120
2168
 
2121
2169
    event_support = ipmi_sensor_get_event_support(sensor);
2154
2202
            ipmi_discrete_event_set(&events, 1, IPMI_DEASSERTION);
2155
2203
    }
2156
2204
 
 
2205
    ent_unlock(ent);
2157
2206
    ipmi_sensor_set_event_enables(sensor, &events, NULL, NULL);
 
2207
    ent_lock(ent);
2158
2208
 
2159
2209
 out:
2160
2210
    ent->presence_possibly_changed = 1;
2167
2217
    }
2168
2218
}
2169
2219
 
 
2220
/* Must be called with the entity lock held.  May release and reclaim it. */
2170
2221
static void
2171
 
handle_new_presence_bit_sensor(ipmi_entity_t *ent, ipmi_sensor_t *sensor)
 
2222
handle_new_presence_bit_sensor(ipmi_entity_t *ent, ipmi_sensor_t *sensor,
 
2223
                               int bit)
2172
2224
{
2173
2225
    ipmi_event_state_t events;
2174
2226
    int                event_support;
2175
2227
 
 
2228
    ent->presence_bit_sensor = sensor;
 
2229
    ent->presence_bit_offset = bit;
2176
2230
    ent->presence_bit_sensor_id = ipmi_sensor_convert_to_id(sensor);
2177
2231
 
2178
2232
    event_support = ipmi_sensor_get_event_support(sensor);
2207
2261
                                    IPMI_DEASSERTION);
2208
2262
    }
2209
2263
 
 
2264
    ent_unlock(ent);
2210
2265
    ipmi_sensor_enable_events(sensor, &events, NULL, NULL);
 
2266
    ent_lock(ent);
2211
2267
 
2212
2268
 out:
2213
2269
    ent->presence_possibly_changed = 1;
2484
2540
 
2485
2541
    CHECK_ENTITY_LOCK(ent);
2486
2542
 
 
2543
    ent_lock(ent);
2487
2544
    if (is_presence_sensor(sensor) && (ent->presence_sensor == NULL)
2488
2545
        && (ent->presence_bit_sensor == NULL))
2489
2546
    {
2490
2547
        /* It's the presence sensor and we don't already have one.  We
2491
2548
           keep this special. */
2492
 
        ent->presence_sensor = sensor;
2493
2549
        handle_new_presence_sensor(ent, sensor);
2494
2550
    } else if ((ent->presence_sensor == NULL)
2495
2551
               && (ent->presence_bit_sensor == NULL)
2496
2552
               && is_presence_bit_sensor(sensor, &bit))
2497
2553
    {
2498
2554
        /* If it's a sensor with a presence bit, we use it. */
2499
 
        ent->presence_bit_sensor = sensor;
2500
 
        ent->presence_bit_offset = bit;
2501
 
        handle_new_presence_bit_sensor(ent, sensor);
 
2555
        handle_new_presence_bit_sensor(ent, sensor, bit);
2502
2556
    }
2503
2557
 
2504
2558
    if (is_hot_swap_requester(sensor) && (ent->hot_swap_requester == NULL)) {
2505
2559
        handle_new_hot_swap_requester(ent, sensor);
2506
2560
    }
 
2561
    ent_unlock(ent);
2507
2562
 
2508
2563
    locked_list_add_entry(ent->sensors, sensor, NULL, link);
2509
2564
        
2533
2588
    info->is_presence = is_presence_sensor(sensor);
2534
2589
    if (info->is_presence) {
2535
2590
        info->sensor = sensor;
2536
 
        ent->presence_sensor = sensor;
2537
2591
        handle_new_presence_sensor(ent, sensor);
2538
2592
    }
2539
2593
}
2553
2607
    info->is_presence = is_presence_bit_sensor(sensor, &info->bit);
2554
2608
    if (info->is_presence) {
2555
2609
        info->sensor = sensor;
2556
 
        ent->presence_bit_sensor = sensor;
2557
 
        ent->presence_bit_offset = info->bit;
2558
 
        handle_new_presence_bit_sensor(ent, sensor);
 
2610
        handle_new_presence_bit_sensor(ent, sensor, info->bit);
2559
2611
    }
2560
2612
}
2561
2613
 
 
2614
/* Must be called with the entity lock held.  May release and reclaim it. */
2562
2615
static void
2563
2616
check_for_another_presence_sensor(ipmi_entity_t *ent, ipmi_sensor_t *old)
2564
2617
{
2590
2643
 
2591
2644
    CHECK_ENTITY_LOCK(ent);
2592
2645
 
 
2646
    ent_lock(ent);
2593
2647
    if (sensor == ent->presence_sensor) {
2594
2648
        ent->presence_sensor = NULL;
2595
2649
        ent->presence_possibly_changed = 1;
2602
2656
    if (sensor == ent->hot_swap_requester) {
2603
2657
        ent->hot_swap_requester = NULL;
2604
2658
    }
 
2659
    ent_unlock(ent);
2605
2660
 
2606
2661
    if (! locked_list_remove(ent->sensors, sensor, NULL)) {
2607
2662
        ipmi_log(IPMI_LOG_WARNING,
2620
2675
{
2621
2676
    CHECK_ENTITY_LOCK(ent);
2622
2677
 
 
2678
    ent_lock(ent);
2623
2679
    if (is_hot_swap_power(control))
2624
2680
        handle_new_hot_swap_power(ent, control);
2625
2681
    if (is_hot_swap_indicator(control))
2626
2682
        handle_new_hot_swap_indicator(ent, control);
 
2683
    ent_unlock(ent);
2627
2684
 
2628
2685
    locked_list_add_entry(ent->controls, control, NULL, link);
2629
2686
    ent->presence_possibly_changed = 1;
2639
2696
 
2640
2697
    CHECK_ENTITY_LOCK(ent);
2641
2698
 
 
2699
    ent_lock(ent);
2642
2700
    if (control == ent->hot_swap_power) {
2643
2701
        /* If don't have power control, we can't manage hot-swap. */
2644
2702
        ipmi_entity_set_supports_managed_hot_swap(ent, 0);
2647
2705
    }
2648
2706
    if (control == ent->hot_swap_indicator)
2649
2707
        ent->hot_swap_indicator = NULL;
 
2708
    ent_unlock(ent);
2650
2709
 
2651
2710
    if (! locked_list_remove(ent->controls, control, NULL)) {
2652
2711
        ipmi_log(IPMI_LOG_WARNING,
2674
2733
    ipmi_sensor_t         *sensor = item1;
2675
2734
    int                   rv;
2676
2735
    ipmi_mc_t             *mc = ipmi_sensor_get_mc(sensor);
 
2736
    ipmi_domain_t         *domain;
2677
2737
 
2678
2738
    if (!mc)
2679
2739
        goto out_err;
 
2740
    domain = ipmi_mc_get_domain(mc);
 
2741
    _ipmi_domain_mc_lock(domain);
2680
2742
    rv = _ipmi_mc_get(mc);
 
2743
    _ipmi_domain_mc_unlock(domain);
2681
2744
    if (rv)
2682
2745
        goto out_err;
2683
2746
    rv = _ipmi_sensor_get(sensor);
2738
2801
    ipmi_control_t         *control = item1;
2739
2802
    int                   rv;
2740
2803
    ipmi_mc_t             *mc = ipmi_control_get_mc(control);
 
2804
    ipmi_domain_t         *domain = ipmi_mc_get_domain(mc);
2741
2805
 
2742
2806
    if (!mc)
2743
2807
        goto out_err;
 
2808
    _ipmi_domain_mc_lock(domain);
2744
2809
    rv = _ipmi_mc_get(mc);
 
2810
    _ipmi_domain_mc_unlock(domain);
2745
2811
    if (rv)
2746
2812
        goto out_err;
2747
2813
    rv = _ipmi_control_get(control);
2857
2923
static int
2858
2924
gdlr_output(ipmi_entity_t *ent, ipmi_sdr_info_t *sdrs, void *cb_data)
2859
2925
{
2860
 
    ipmi_sdr_t sdr;
2861
 
    int        len;
2862
 
    dlr_info_t *info = &ent->info;
 
2926
    ipmi_sdr_t   sdr;
 
2927
    unsigned int len;
 
2928
    dlr_info_t  *info = &ent->info;
2863
2929
 
2864
2930
    memset(&sdr, 0, sizeof(sdr));
2865
2931
 
2895
2961
            dlr_info_t         *info)
2896
2962
{
2897
2963
    unsigned char *str;
 
2964
    int           rv;
2898
2965
 
2899
2966
    info->type = IPMI_ENTITY_GENERIC;
2900
2967
    info->output_handler = gdlr_output;
2921
2988
    info->entity_instance = sdr->data[8];
2922
2989
    info->oem = sdr->data[9];
2923
2990
    str = sdr->data + 10;
2924
 
    info->id_len = ipmi_get_device_string(&str, sdr->length-10,
2925
 
                                          info->id, IPMI_STR_SDR_SEMANTICS, 0,
2926
 
                                          &info->id_type, ENTITY_ID_LEN);
 
2991
    rv = ipmi_get_device_string(&str, sdr->length-10,
 
2992
                                info->id, IPMI_STR_SDR_SEMANTICS, 0,
 
2993
                                &info->id_type, ENTITY_ID_LEN, &info->id_len);
2927
2994
 
2928
 
    return 0;
 
2995
    return rv;
2929
2996
}
2930
2997
 
2931
2998
static int
2932
2999
frudlr_output(ipmi_entity_t *ent, ipmi_sdr_info_t *sdrs, void *cb_data)
2933
3000
{
2934
 
    ipmi_sdr_t sdr;
2935
 
    int        len;
2936
 
    dlr_info_t *info = &ent->info;
 
3001
    ipmi_sdr_t   sdr;
 
3002
    unsigned int len;
 
3003
    dlr_info_t   *info = &ent->info;
2937
3004
 
2938
3005
    memset(&sdr, 0, sizeof(sdr));
2939
3006
 
2968
3035
              dlr_info_t         *info)
2969
3036
{
2970
3037
    unsigned char *str;
 
3038
    int           rv;
2971
3039
 
2972
3040
    info->type = IPMI_ENTITY_FRU;
2973
3041
    info->output_handler = frudlr_output;
2992
3060
    info->entity_id = sdr->data[7];
2993
3061
    info->entity_instance = sdr->data[8];
2994
3062
    str = sdr->data + 10;
2995
 
    info->id_len = ipmi_get_device_string(&str,
2996
 
                                          sdr->length-10,
2997
 
                                          info->id, IPMI_STR_SDR_SEMANTICS, 0,
2998
 
                                          &info->id_type, ENTITY_ID_LEN);
 
3063
    rv = ipmi_get_device_string(&str,
 
3064
                                sdr->length-10,
 
3065
                                info->id, IPMI_STR_SDR_SEMANTICS, 0,
 
3066
                                &info->id_type, ENTITY_ID_LEN, &info->id_len);
2999
3067
 
3000
 
    return 0;
 
3068
    return rv;
3001
3069
}
3002
3070
 
3003
3071
static int
3004
3072
mcdlr_output(ipmi_entity_t *ent, ipmi_sdr_info_t *sdrs, void *cb_data)
3005
3073
{
3006
 
    ipmi_sdr_t sdr;
3007
 
    int        len;
3008
 
    dlr_info_t *info = &ent->info;
 
3074
    ipmi_sdr_t   sdr;
 
3075
    unsigned int len;
 
3076
    dlr_info_t   *info = &ent->info;
3009
3077
 
3010
3078
    memset(&sdr, 0, sizeof(sdr));
3011
3079
 
3031
3099
    sdr.data[4] = 0;
3032
3100
    sdr.data[5] = 0;
3033
3101
    sdr.data[6] = 0;
3034
 
    sdr.data[7] = ent->info.entity_id;
3035
 
    sdr.data[8] = ent->info.entity_instance;
 
3102
    sdr.data[7] = ent->key.entity_id;
 
3103
    sdr.data[8] = ent->key.entity_instance;
3036
3104
    sdr.data[9] = info->oem;
3037
3105
    len = 16;
3038
3106
    ipmi_set_device_string(info->id,
3050
3118
{
3051
3119
    unsigned char *data;
3052
3120
    unsigned char *str;
 
3121
    int           rv;
3053
3122
 
3054
3123
 
3055
3124
    info->type = IPMI_ENTITY_MC;
3099
3168
 
3100
3169
    info->oem = sdr->data[9];
3101
3170
    str = sdr->data + 10;
3102
 
    info->id_len = ipmi_get_device_string(&str,
3103
 
                                          sdr->length-10,
3104
 
                                          info->id, IPMI_STR_SDR_SEMANTICS, 0,
3105
 
                                          &info->id_type, ENTITY_ID_LEN);
 
3171
    rv = ipmi_get_device_string(&str,
 
3172
                                sdr->length-10,
 
3173
                                info->id, IPMI_STR_SDR_SEMANTICS, 0,
 
3174
                                &info->id_type, ENTITY_ID_LEN, &info->id_len);
3106
3175
 
3107
3176
 
3108
3177
    /* Make sure the FRU fetch stuff works. */
3111
3180
    info->is_logical_fru = 1;
3112
3181
    info->private_bus_id = 0;
3113
3182
 
3114
 
    return 0;
 
3183
    return rv;
3115
3184
}
3116
3185
 
3117
3186
typedef struct entity_found_s
3178
3247
static void
3179
3248
destroy_sdr_info(entity_sdr_info_t *infos)
3180
3249
{
3181
 
    int i;
 
3250
    unsigned int i;
3182
3251
 
3183
3252
    if (infos->dlrs) {
3184
3253
        for (i=0; i<infos->next; i++) {
3195
3264
static void
3196
3265
cleanup_sdr_info(entity_sdr_info_t *infos)
3197
3266
{
3198
 
    int i;
 
3267
    unsigned int i;
3199
3268
 
3200
3269
    if (infos->dlrs) {
3201
3270
        for (i=0; i<infos->next; i++) {
3242
3311
                 entity_sdr_info_t   *infos)
3243
3312
{
3244
3313
    entity_found_t      *found;
3245
 
    int                 i, j;
 
3314
    unsigned int        i, j;
3246
3315
    int                 rv;
3247
3316
    ipmi_entity_t       *child;
3248
3317
    ipmi_entity_t       *ent;
3280
3349
        j = i - 1;
3281
3350
        ent = found->ent;
3282
3351
        while ((j > 0) && (ent == (infos->found+j)->ent)) {
3283
 
            j--;
3284
3352
            if ((infos->found+j)->found)
3285
 
                continue;
 
3353
                goto next_ent;
3286
3354
            if ((infos->dlrs[j]->type != IPMI_ENTITY_EAR)
3287
3355
                && (infos->dlrs[j]->type != IPMI_ENTITY_DREAR))
3288
 
                continue;
 
3356
                goto next_ent;
3289
3357
            found = infos->found+j;
3290
3358
 
3291
3359
            /* Since this is an EAR and we are putting it's entries in
3292
3360
               another place, ignore this one. */
3293
3361
            (infos->found+i)->found = 1;
 
3362
        next_ent:
 
3363
            j--;
3294
3364
        }
3295
3365
 
3296
3366
        if (infos->dlrs[i]->is_ranges) {
3344
3414
put_entities(entity_sdr_info_t *infos)
3345
3415
{
3346
3416
    entity_found_t      *found;
3347
 
    int                 i, j;
 
3417
    unsigned int        i, j;
3348
3418
 
3349
3419
    for (i=0; i<infos->next; i++) {
3350
3420
        found = infos->found+i;
3351
3421
 
3352
 
        if (found->found)
3353
 
            continue;
3354
 
 
3355
3422
        if (found->ent)
3356
3423
            _ipmi_entity_put(found->ent);
3357
3424
 
 
3425
        /* Still put the entity even if found, as it was refcounted by
 
3426
           looking it up. */
 
3427
        if (found->found)
 
3428
            continue;
 
3429
 
3358
3430
        for (j=0; j<found->cent_next; j++)
3359
3431
            _ipmi_entity_put(found->cent[j]);
3360
3432
    }
3396
3468
                      ipmi_sdr_info_t    *sdrs)
3397
3469
{
3398
3470
    unsigned int        count;
3399
 
    int                 i, j;
 
3471
    unsigned int        i, j;
3400
3472
    int                 rv;
3401
3473
    entity_sdr_info_t   infos;
3402
3474
    entity_sdr_info_t   *old_infos;
3716
3788
{
3717
3789
    entity_sdr_info_t   *infos = info;
3718
3790
    entity_found_t      *found;
3719
 
    int                 i, j;
 
3791
    unsigned int        i, j;
3720
3792
    int                 rv;
3721
3793
    ipmi_entity_t       *ent, *child;
3722
3794
 
3789
3861
                    _ipmi_entity_put(child);
3790
3862
                }
3791
3863
            }
 
3864
            ipmi_detect_entity_presence_change(ent, 0);
3792
3865
        }
3793
 
        ipmi_detect_entity_presence_change(ent, 0);
3794
3866
        _ipmi_entity_put(ent);
3795
3867
    }
3796
3868
 
4103
4175
}
4104
4176
 
4105
4177
int
 
4178
ipmi_entity_get_mc_id(ipmi_entity_t *ent, ipmi_mcid_t *mc_id)
 
4179
{
 
4180
    ipmi_ipmb_addr_t sa;
 
4181
    ipmi_mc_t        *mc;
 
4182
 
 
4183
    if ((ent->info.type != IPMI_ENTITY_MC)
 
4184
        && (ent->info.type != IPMI_ENTITY_GENERIC))
 
4185
    {
 
4186
        return ENOSYS;
 
4187
    }
 
4188
 
 
4189
    sa.addr_type = IPMI_IPMB_ADDR_TYPE;
 
4190
    sa.channel = ent->info.channel;
 
4191
    sa.slave_addr = ent->info.slave_address;
 
4192
    sa.lun = ent->info.lun;
 
4193
 
 
4194
    mc = _ipmi_find_mc_by_addr(ent->domain, (ipmi_addr_t *) &sa, sizeof(sa));
 
4195
    if (!mc)
 
4196
        return ENODEV;
 
4197
 
 
4198
    *mc_id = ipmi_mc_convert_to_id(mc);
 
4199
    _ipmi_mc_put(mc);
 
4200
 
 
4201
    return 0;
 
4202
}
 
4203
 
 
4204
int
4106
4205
ipmi_entity_get_lun(ipmi_entity_t *ent)
4107
4206
{
4108
4207
    CHECK_ENTITY_LOCK(ent);
4172
4271
    int rv = 0;
4173
4272
    CHECK_ENTITY_LOCK(ent);
4174
4273
 
4175
 
    ipmi_lock(ent->lock);
 
4274
    ent_lock(ent);
4176
4275
    if (ent->info.type == IPMI_ENTITY_FRU)
4177
4276
        rv = 1;
4178
4277
    if ((ent->info.type == IPMI_ENTITY_MC) && (ent->info.FRU_inventory_device))
4179
4278
        rv = 1;
4180
 
    ipmi_unlock(ent->lock);
 
4279
    ent_unlock(ent);
4181
4280
    return rv;
4182
4281
}
4183
4282
 
4210
4309
{
4211
4310
    CHECK_ENTITY_LOCK(ent);
4212
4311
 
4213
 
    return ent->info.entity_id;
 
4312
    return ent->key.entity_id;
4214
4313
}
4215
4314
 
4216
4315
int
4218
4317
{
4219
4318
    CHECK_ENTITY_LOCK(ent);
4220
4319
 
4221
 
    return ent->info.entity_instance;
 
4320
    return ent->key.entity_instance;
4222
4321
}
4223
4322
 
4224
4323
int
4226
4325
{
4227
4326
    CHECK_ENTITY_LOCK(ent);
4228
4327
 
4229
 
    return ent->info.device_num.channel;
 
4328
    return ent->key.device_num.channel;
4230
4329
}
4231
4330
 
4232
4331
int
4234
4333
{
4235
4334
    CHECK_ENTITY_LOCK(ent);
4236
4335
 
4237
 
    return ent->info.device_num.address;
 
4336
    return ent->key.device_num.address;
4238
4337
}
4239
4338
 
4240
4339
int
4327
4426
 
4328
4427
    CHECK_ENTITY_LOCK(ent);
4329
4428
 
4330
 
    ipmi_lock(ent->lock);
4331
 
    if (ent->info.id_len > length)
 
4429
    ent_lock(ent);
 
4430
    if ((int)ent->info.id_len > length)
4332
4431
        clen = length;
4333
4432
    else
4334
4433
        clen = ent->info.id_len;
4341
4440
 
4342
4441
        id[clen] = '\0';
4343
4442
    }
4344
 
    ipmi_unlock(ent->lock);
 
4443
    ent_unlock(ent);
4345
4444
 
4346
4445
    return clen;
4347
4446
}
4355
4454
    if (length > ENTITY_ID_LEN)
4356
4455
        length = ENTITY_ID_LEN;
4357
4456
    
4358
 
    ipmi_lock(ent->lock);
 
4457
    ent_lock(ent);
4359
4458
    memcpy(ent->info.id, id, length);
4360
4459
    ent->info.id_type = type;
4361
4460
    ent->info.id_len = length;
4362
 
    ipmi_unlock(ent->lock);
 
4461
    ent_unlock(ent);
4363
4462
    entity_set_name(ent);
4364
4463
}
4365
4464
 
4695
4794
    CHECK_ENTITY_LOCK(ent);
4696
4795
 
4697
4796
    val.domain_id = ent->domain_id;
4698
 
    val.entity_id = ent->info.entity_id;
4699
 
    val.entity_instance = ent->info.entity_instance;
4700
 
    val.channel = ent->info.device_num.channel;
4701
 
    val.address = ent->info.device_num.address;
 
4797
    val.entity_id = ent->key.entity_id;
 
4798
    val.entity_instance = ent->key.entity_instance;
 
4799
    val.channel = ent->key.device_num.channel;
 
4800
    val.address = ent->key.device_num.address;
4702
4801
    val.seq = ent->seq;
4703
4802
 
4704
4803
    return val;
4922
5021
    return LOCKED_LIST_ITER_CONTINUE;
4923
5022
}
4924
5023
 
4925
 
static void
4926
 
call_fru_handlers(ipmi_entity_t *ent, enum ipmi_update_e op)
 
5024
void
 
5025
_ipmi_entity_call_fru_handlers(ipmi_entity_t *ent, enum ipmi_update_e op)
4927
5026
{
4928
5027
    fru_handler_t info;
4929
5028
 
4954
5053
        }
4955
5054
        ent->fru = info->fru;
4956
5055
 
4957
 
        call_fru_handlers(ent, op);
 
5056
        _ipmi_entity_call_fru_handlers(ent, op);
4958
5057
    } else {
4959
5058
        ipmi_log(IPMI_LOG_WARNING,
4960
5059
                 "%sentity.c(fru_fetched_ent_cb):"
4961
5060
                 "Error fetching entity %d.%d FRU: %x",
4962
5061
                 ENTITY_NAME(ent),
4963
 
                 ent->info.entity_id, ent->info.entity_instance, info->err);
 
5062
                 ent->key.entity_id, ent->key.entity_instance, info->err);
4964
5063
        if ((ent->fru) && (info->fru))
4965
5064
            /* Keep the old FRU on errors. */
4966
5065
            ipmi_fru_destroy_internal(info->fru, NULL, NULL);
4968
5067
            /* Keep it if we got it, it might have some useful
4969
5068
               information. */
4970
5069
            ent->fru = info->fru;
4971
 
        call_fru_handlers(ent, IPMI_CHANGED);
 
5070
        _ipmi_entity_call_fru_handlers(ent, IPMI_CHANGED);
4972
5071
    }
4973
5072
}
4974
5073
 
4989
5088
        ipmi_fru_destroy_internal(fru, NULL, NULL);
4990
5089
 
4991
5090
    ipmi_mem_free(ent_id);
4992
 
    _ipmi_put_domain_fully_up(domain);
 
5091
    if (domain)
 
5092
        _ipmi_put_domain_fully_up(domain, "fru_fetched_handler");
4993
5093
}
4994
5094
 
4995
5095
int
5026
5126
                 " Unable to allocate the FRU: %x",
5027
5127
                 ENTITY_NAME(ent), rv);
5028
5128
    } else
5029
 
        _ipmi_get_domain_fully_up(ent->domain);
 
5129
        _ipmi_get_domain_fully_up(ent->domain, "ipmi_entity_fetch_frus");
5030
5130
 
5031
5131
    return rv;
5032
5132
}
5039
5139
    return ent->fru;
5040
5140
}
5041
5141
 
 
5142
void
 
5143
_ipmi_entity_set_fru(ipmi_entity_t *ent, ipmi_fru_t *fru)
 
5144
{
 
5145
    CHECK_ENTITY_LOCK(ent);
 
5146
 
 
5147
    if (ent->fru)
 
5148
        ipmi_fru_destroy_internal(ent->fru, NULL, NULL);
 
5149
    ent->fru = fru;
 
5150
}
 
5151
 
5042
5152
/***************************************************************************
5043
5153
 *
5044
5154
 * Hot swap
5132
5242
 
5133
5243
    handled = handler(info->ent, info->last_state, info->curr_state,
5134
5244
                      item2, *(info->event));
5135
 
    if (handled == IPMI_EVENT_HANDLED) {
5136
 
        info->handled = handled;
5137
 
        *(info->event) = NULL;
 
5245
    if (handled != IPMI_EVENT_NOT_HANDLED) {
 
5246
        if (info->handled != IPMI_EVENT_HANDLED)
 
5247
            /* Allow handled to override handled_pass, but not the
 
5248
               other way. */
 
5249
            info->handled = handled;
 
5250
        if (handled == IPMI_EVENT_HANDLED)
 
5251
            *(info->event) = NULL;
5138
5252
    }
5139
5253
    return LOCKED_LIST_ITER_CONTINUE;
5140
5254
}
5152
5266
    info.last_state = last_state;
5153
5267
    info.curr_state = curr_state;
5154
5268
    info.event = event;
5155
 
    info.handled = IPMI_EVENT_NOT_HANDLED;
 
5269
    if (handled)
 
5270
        info.handled = *handled;
 
5271
    else
 
5272
        info.handled = IPMI_EVENT_NOT_HANDLED;
5156
5273
    locked_list_iterate(ent->hot_swap_handlers, call_hot_swap_handler, &info);
5157
5274
    if (handled)
5158
5275
        *handled = info.handled;
5171
5288
}
5172
5289
 
5173
5290
int
 
5291
ipmi_entity_supports_auto_activate_time(ipmi_entity_t *ent)
 
5292
{
 
5293
    return (ent->hot_swappable && ent->hs_cb.get_auto_activate);
 
5294
}
 
5295
 
 
5296
int
5174
5297
ipmi_entity_set_auto_activate_time(ipmi_entity_t  *ent,
5175
5298
                                   ipmi_timeout_t auto_act,
5176
5299
                                   ipmi_entity_cb done,
5196
5319
}
5197
5320
 
5198
5321
int
 
5322
ipmi_entity_supports_auto_deactivate_time(ipmi_entity_t *ent)
 
5323
{
 
5324
    return (ent->hot_swappable && ent->hs_cb.get_auto_activate);
 
5325
}
 
5326
 
 
5327
int
5199
5328
ipmi_entity_set_auto_deactivate_time(ipmi_entity_t  *ent,
5200
5329
                                     ipmi_timeout_t auto_deact,
5201
5330
                                     ipmi_entity_cb done,
5534
5663
                 " Unable to set the hot swap power: %x",
5535
5664
                 CONTROL_NAME(control), err);
5536
5665
    } else {
5537
 
        ipmi_lock(ent->lock);
 
5666
        ent_lock(ent);
5538
5667
        set_hot_swap_state(ent, IPMI_HOT_SWAP_ACTIVE, NULL);
5539
 
        ipmi_unlock(ent->lock);
 
5668
        ent_unlock(ent);
5540
5669
    }
5541
5670
}
5542
5671
 
5551
5680
                 " Unable to set the hot swap power: %x",
5552
5681
                 CONTROL_NAME(control), err);
5553
5682
    } else {
5554
 
        ipmi_lock(ent->lock);
 
5683
        ent_lock(ent);
5555
5684
        set_hot_swap_state(ent, IPMI_HOT_SWAP_INACTIVE, NULL);
5556
 
        ipmi_unlock(ent->lock);
 
5685
        ent_unlock(ent);
5557
5686
    }
5558
5687
}
5559
5688
 
5576
5705
                 " Unable to set the hot swap power: %x",
5577
5706
                 CONTROL_NAME(control), err);
5578
5707
    } else {
5579
 
        ipmi_lock(ent->lock);
 
5708
        ent_lock(ent);
5580
5709
        set_hot_swap_state(ent, IPMI_HOT_SWAP_ACTIVE, NULL);
5581
 
        ipmi_unlock(ent->lock);
 
5710
        ent_unlock(ent);
5582
5711
    }
5583
5712
 
5584
5713
    if (info->handler)
5598
5727
                 " Unable to set the hot swap power: %x",
5599
5728
                 CONTROL_NAME(control), err);
5600
5729
    } else {
5601
 
        ipmi_lock(ent->lock);
 
5730
        ent_lock(ent);
5602
5731
        set_hot_swap_state(ent, IPMI_HOT_SWAP_INACTIVE, NULL);
5603
 
        ipmi_unlock(ent->lock);
 
5732
        ent_unlock(ent);
5604
5733
    }
5605
5734
 
5606
5735
    if (info->handler)
5626
5755
    ipmi_control_op_cb cb;
5627
5756
    power_cb_info_t    *info = NULL;
5628
5757
 
5629
 
    ipmi_lock(ent->lock);
 
5758
    ent_lock(ent);
5630
5759
    if (ent->hot_swap_state == IPMI_HOT_SWAP_ACTIVATION_REQUESTED) {
5631
5760
        if (ent->hot_swap_power) {
5632
5761
            if (handler == NULL) {
5646
5775
            }
5647
5776
 
5648
5777
            val = 1;
 
5778
            ent_unlock(ent);
5649
5779
            rv = ipmi_control_id_set_val(ent->hot_swap_power_id,
5650
5780
                                         &val,
5651
5781
                                         cb,
5652
5782
                                         cb_data);
 
5783
            ent_lock(ent);
5653
5784
            if (!rv)
5654
5785
                set_hot_swap_state(ent, IPMI_HOT_SWAP_ACTIVATION_IN_PROGRESS,
5655
5786
                                   NULL);
5660
5791
        rv = EAGAIN;
5661
5792
    }
5662
5793
 out:
5663
 
    ipmi_unlock(ent->lock);
 
5794
    ent_unlock(ent);
5664
5795
 
5665
5796
    return rv;
5666
5797
}
5706
5837
    ipmi_control_op_cb cb;
5707
5838
    power_cb_info_t    *info;
5708
5839
 
5709
 
    ipmi_lock(ent->lock);
 
5840
    ent_lock(ent);
5710
5841
    if (ent->hot_swap_state == IPMI_HOT_SWAP_DEACTIVATION_REQUESTED) {
5711
5842
        if (ent->hot_swap_power) {
5712
5843
            if (handler == NULL) {
5726
5857
            }
5727
5858
 
5728
5859
            val = 0;
 
5860
            ent_unlock(ent);
5729
5861
            rv = ipmi_control_id_set_val(ent->hot_swap_power_id,
5730
5862
                                         &val,
5731
5863
                                         cb,
5732
5864
                                         cb_data);
 
5865
            ent_lock(ent);
5733
5866
            if (!rv)
5734
5867
                set_hot_swap_state(ent, IPMI_HOT_SWAP_DEACTIVATION_IN_PROGRESS,
5735
5868
                                   NULL);
5738
5871
        rv = EAGAIN;
5739
5872
    }
5740
5873
 out:
5741
 
    ipmi_unlock(ent->lock);
 
5874
    ent_unlock(ent);
5742
5875
 
5743
5876
    return rv;
5744
5877
}
5837
5970
 
5838
5971
    if (old_state != state) {
5839
5972
        ent->hot_swap_state = state;
5840
 
        ipmi_unlock(ent->lock);
 
5973
        ent_unlock(ent);
5841
5974
        ipmi_entity_call_hot_swap_handlers(ent, old_state, state, &event,
5842
5975
                                           &handled);
5843
 
        ipmi_lock(ent->lock);
 
5976
        ent_lock(ent);
5844
5977
    }
5845
5978
 
5846
5979
    return handled;
5858
5991
    ipmi_entity_t *ent = cb_data;
5859
5992
    int           handled = IPMI_EVENT_NOT_HANDLED;
5860
5993
 
5861
 
    ipmi_lock(ent->lock);
 
5994
    ent_lock(ent);
5862
5995
    if (offset != ent->hot_swap_offset)
5863
5996
        goto out;
5864
5997
 
5915
6048
    }
5916
6049
 
5917
6050
 out:
5918
 
    ipmi_unlock(ent->lock);
5919
 
    return 0;
 
6051
    ent_unlock(ent);
 
6052
    return handled;
5920
6053
}
5921
6054
 
5922
6055
static void power_checked(ipmi_control_t *control,
5932
6065
                       ipmi_event_t   *event)
5933
6066
{
5934
6067
    ipmi_entity_t *ent = cb_data;
5935
 
    int           handled = IPMI_EVENT_NOT_HANDLED;
5936
6068
 
5937
6069
    if (!valid_vals[0])
5938
6070
        return IPMI_EVENT_NOT_HANDLED;
5940
6072
    if (ent->present)
5941
6073
        power_checked(control, 0, vals, ent);
5942
6074
    
5943
 
    return handled;
 
6075
    return IPMI_EVENT_NOT_HANDLED;
5944
6076
}
5945
6077
 
5946
6078
static void
5955
6087
                                       &ent->hot_swap_ind_req_deact,
5956
6088
                                       &ent->hot_swap_ind_inact);
5957
6089
 
5958
 
    ipmi_lock(ent->lock);
5959
6090
    ent->hot_swap_indicator_id = ipmi_control_convert_to_id(control);
5960
6091
    ent->hot_swap_indicator = control;
5961
6092
    switch (ent->hot_swap_state)
5982
6113
        val = ent->hot_swap_ind_inact;
5983
6114
        break;
5984
6115
    }
5985
 
    ipmi_unlock(ent->lock);
5986
6116
        
 
6117
    ent_unlock(ent);
5987
6118
    rv = ipmi_control_set_val(control, &val, NULL, NULL);
 
6119
    ent_lock(ent);
5988
6120
    if (rv)
5989
6121
        ipmi_log(IPMI_LOG_SEVERE,
5990
6122
                 "%sentity.c(handle_new_hot_swap_indicator): Unable to"
6008
6140
        return;
6009
6141
    }
6010
6142
 
6011
 
    ipmi_lock(ent->lock);
 
6143
    ent_lock(ent);
6012
6144
    if (ipmi_is_state_set(states, ent->hot_swap_offset)
6013
6145
        == ent->hot_swap_requesting_val)
6014
6146
    {
6021
6153
            set_hot_swap_state(ent, IPMI_HOT_SWAP_ACTIVATION_REQUESTED,
6022
6154
                               NULL);
6023
6155
    }
6024
 
    ipmi_unlock(ent->lock);
 
6156
    ent_unlock(ent);
6025
6157
}
6026
6158
 
6027
6159
static void
6041
6173
        return;
6042
6174
    }
6043
6175
 
6044
 
    ipmi_lock(ent->lock);
 
6176
    ent_lock(ent);
6045
6177
    if (val[0])
6046
6178
        set_hot_swap_state(ent, IPMI_HOT_SWAP_ACTIVE, NULL);
6047
6179
    else
6048
6180
        set_hot_swap_state(ent, IPMI_HOT_SWAP_INACTIVE, NULL);
6049
6181
 
6050
6182
    if (ent->hot_swap_requester) {
6051
 
        rv = ipmi_sensor_id_get_states(ent->hot_swap_requester_id,
6052
 
                                       requester_checked,
6053
 
                                       ent);
 
6183
        ipmi_sensor_id_t hsr = ent->hot_swap_requester_id;
 
6184
        ent_unlock(ent);
 
6185
        rv = ipmi_sensor_id_get_states(hsr, requester_checked, ent);
6054
6186
        if (rv) {
6055
6187
            ipmi_log(IPMI_LOG_SEVERE,
6056
6188
                     "%sentity.c(power_checked): Unable to"
6057
6189
                     " request requester status, error %x",
6058
6190
                     SENSOR_NAME(ent->hot_swap_requester), rv);
6059
6191
        }
6060
 
    }
6061
 
    ipmi_unlock(ent->lock);
 
6192
    } else
 
6193
        ent_unlock(ent);
6062
6194
}
6063
6195
 
6064
6196
static void
6066
6198
{
6067
6199
    int rv;
6068
6200
  
6069
 
    ipmi_lock(ent->lock);
6070
6201
    /* Add our own event handler. */
6071
6202
    rv = ipmi_control_add_val_event_handler(control,
6072
6203
                                            hot_swap_power_changed,
6086
6217
    ipmi_entity_set_supports_managed_hot_swap(ent, 1);
6087
6218
 
6088
6219
    if (ent->hot_swappable) {
 
6220
        ent_unlock(ent);
6089
6221
        rv = ipmi_control_get_val(control, power_checked, ent);
 
6222
        ent_lock(ent);
6090
6223
        if (rv) {
6091
6224
            ipmi_log(IPMI_LOG_SEVERE,
6092
6225
                     "%sentity.c(handle_new_hot_swap_power): Unable to"
6095
6228
        }
6096
6229
    }
6097
6230
 out:
6098
 
    ipmi_unlock(ent->lock);
 
6231
    return;
6099
6232
}
6100
6233
 
 
6234
/* Must be called with the entity lock held.  May release and reclaim it. */
6101
6235
static void
6102
6236
handle_new_hot_swap_requester(ipmi_entity_t *ent, ipmi_sensor_t *sensor)
6103
6237
{
6106
6240
    int                rv;
6107
6241
    int                val;
6108
6242
 
6109
 
    ipmi_lock(ent->lock);
6110
6243
    ent->hot_swap_requester_id = ipmi_sensor_convert_to_id(sensor);
6111
6244
 
6112
6245
    ipmi_sensor_is_hot_swap_requester(sensor,
6158
6291
                                    IPMI_DEASSERTION);
6159
6292
    }
6160
6293
 
 
6294
    ent_unlock(ent);
6161
6295
    ipmi_sensor_set_event_enables(sensor, &events, NULL, NULL);
 
6296
    ent_lock(ent);
6162
6297
 
6163
6298
    if (ent->hot_swappable) {
6164
 
        rv = ipmi_sensor_id_get_states(ent->hot_swap_requester_id,
6165
 
                                       requester_checked,
6166
 
                                       ent);
 
6299
        ipmi_sensor_id_t hsr = ent->hot_swap_requester_id;
 
6300
        ent_unlock(ent);
 
6301
        rv = ipmi_sensor_id_get_states(hsr, requester_checked, ent);
 
6302
        ent_lock(ent);
6167
6303
        if (rv) {
6168
6304
            ipmi_log(IPMI_LOG_SEVERE,
6169
6305
                     "%sentity.c(handle_new_hot_swap_requester): Unable to"
6173
6309
    }
6174
6310
 
6175
6311
 out:
6176
 
    ipmi_unlock(ent->lock);
6177
6312
    return;
6178
6313
}
6179
6314
 
6185
6320
    int handled = IPMI_EVENT_NOT_HANDLED;
6186
6321
    int rv;
6187
6322
 
6188
 
    ipmi_lock(ent->lock);
 
6323
    ent_lock(ent);
6189
6324
    if (present) {
6190
6325
        if ((!ent->hot_swap_power)
6191
6326
            || (hot_swap_act_timeout == IPMI_TIMEOUT_NOW))
6193
6328
            /* No power control or immediate timeout, it goes straight
6194
6329
               to active. */
6195
6330
            handled = set_hot_swap_state(ent, IPMI_HOT_SWAP_ACTIVE, event);
 
6331
            ent_unlock(ent);
6196
6332
        } else {
6197
 
            rv = ipmi_control_id_get_val(ent->hot_swap_power_id, power_checked,
6198
 
                                         ent);
 
6333
            ipmi_control_id_t hsp = ent->hot_swap_power_id;
 
6334
            ent_unlock(ent);
 
6335
            rv = ipmi_control_id_get_val(hsp, power_checked, ent);
6199
6336
            if (rv) {
6200
6337
                ipmi_log(IPMI_LOG_SEVERE,
6201
6338
                         "%sentity.c(handle_hot_swap_presence): Unable to"
6205
6342
        }
6206
6343
    } else {
6207
6344
        handled = set_hot_swap_state(ent, IPMI_HOT_SWAP_NOT_PRESENT, event);
 
6345
        ent_unlock(ent);
6208
6346
    }
6209
 
    ipmi_unlock(ent->lock);
6210
6347
 
6211
6348
    return handled;
6212
6349
}
6229
6366
{
6230
6367
    int rv = 0;
6231
6368
 
6232
 
    ipmi_lock(ent->lock);
 
6369
    ent_lock(ent);
6233
6370
    if (!ent->hot_swap_power)
6234
6371
        rv = ENOSYS;
6235
6372
    else
6236
6373
        ent->hot_swap_act_timeout = auto_act;
6237
 
    ipmi_unlock(ent->lock);
 
6374
    ent_unlock(ent);
6238
6375
 
6239
6376
    if ((!rv) && (done))
6240
6377
        done(ent, 0, cb_data);
6250
6387
    int            rv = 0;
6251
6388
    ipmi_timeout_t time = 0;
6252
6389
 
6253
 
    ipmi_lock(ent->lock);
 
6390
    ent_lock(ent);
6254
6391
    if (!ent->hot_swap_power)
6255
6392
        rv = ENOSYS;
6256
6393
    else
6257
6394
        time = ent->hot_swap_act_timeout;
6258
 
    ipmi_unlock(ent->lock);
 
6395
    ent_unlock(ent);
6259
6396
 
6260
6397
    if ((!rv) && (handler))
6261
6398
        handler(ent, 0, time, cb_data);
6271
6408
{
6272
6409
    int rv = 0;
6273
6410
    
6274
 
    ipmi_lock(ent->lock);
 
6411
    ent_lock(ent);
6275
6412
    if (!ent->hot_swap_power)
6276
6413
        rv = ENOSYS;
6277
6414
    else
6278
6415
        ent->hot_swap_deact_timeout = auto_act;
6279
 
    ipmi_unlock(ent->lock);
 
6416
    ent_unlock(ent);
6280
6417
 
6281
6418
    if ((!rv) && (done))
6282
6419
        done(ent, 0, cb_data);
6292
6429
    int            rv = 0;
6293
6430
    ipmi_timeout_t time = 0;
6294
6431
 
6295
 
    ipmi_lock(ent->lock);
 
6432
    ent_lock(ent);
6296
6433
    if (!ent->hot_swap_power)
6297
6434
        rv = ENOSYS;
6298
6435
    else
6299
6436
        time = ent->hot_swap_deact_timeout;
6300
 
    ipmi_unlock(ent->lock);
 
6437
    ent_unlock(ent);
6301
6438
 
6302
6439
    if ((!rv) && (handler))
6303
6440
        handler(ent, 0, time, cb_data);
6352
6489
    int                 rv;
6353
6490
    ipmi_control_id_t   id;
6354
6491
 
6355
 
    ipmi_lock(ent->lock);
 
6492
    ent_lock(ent);
6356
6493
    if (! ent->hot_swap_indicator) {
6357
 
        ipmi_unlock(ent->lock);
 
6494
        ent_unlock(ent);
6358
6495
        return ENOSYS;
6359
6496
    }
6360
6497
    id = ent->hot_swap_indicator_id;
6361
 
    ipmi_unlock(ent->lock);
 
6498
    ent_unlock(ent);
6362
6499
 
6363
6500
    info = ipmi_mem_alloc(sizeof(*info));
6364
6501
    if (!info)
6400
6537
    int                     rv;
6401
6538
    ipmi_control_id_t       id;
6402
6539
 
6403
 
    ipmi_lock(ent->lock);
 
6540
    ent_lock(ent);
6404
6541
    if (! ent->hot_swap_indicator) {
6405
 
        ipmi_unlock(ent->lock);
 
6542
        ent_unlock(ent);
6406
6543
        return ENOSYS;
6407
6544
    }
6408
6545
    id = ent->hot_swap_indicator_id;
6409
 
    ipmi_unlock(ent->lock);
 
6546
    ent_unlock(ent);
6410
6547
 
6411
6548
    info = ipmi_mem_alloc(sizeof(*info));
6412
6549
    if (!info)
6431
6568
    int                 val = 0;
6432
6569
 
6433
6570
    if (!err) {
6434
 
        ipmi_lock(info->ent->lock);
 
6571
        ent_lock(info->ent);
6435
6572
        if (ipmi_is_state_set(states, info->ent->hot_swap_offset)
6436
6573
            == info->ent->hot_swap_requesting_val)
6437
6574
        {
6438
6575
            val = 1;
6439
6576
        }
6440
 
        ipmi_unlock(info->ent->lock);
 
6577
        ent_unlock(info->ent);
6441
6578
    }
6442
6579
    info->handler(info->ent, err, val, info->cb_data);
6443
6580
    ipmi_mem_free(info);
6452
6589
    int                 rv;
6453
6590
    ipmi_sensor_id_t    id;
6454
6591
 
6455
 
    ipmi_lock(ent->lock);
 
6592
    ent_lock(ent);
6456
6593
    if (! ent->hot_swap_requester) {
6457
 
        ipmi_unlock(ent->lock);
 
6594
        ent_unlock(ent);
6458
6595
        return ENOSYS;
6459
6596
    }
6460
6597
    id = ent->hot_swap_requester_id;
6461
 
    ipmi_unlock(ent->lock);
 
6598
    ent_unlock(ent);
6462
6599
 
6463
6600
    info = ipmi_mem_alloc(sizeof(*info));
6464
6601
    if (!info)
6496
6633
        goto out;
6497
6634
    }
6498
6635
 
6499
 
    ipmi_lock(ent->lock);
 
6636
    ent_lock(ent);
6500
6637
    if (ipmi_is_state_set(states, ent->hot_swap_offset)
6501
6638
        == ent->hot_swap_requesting_val)
6502
6639
    {
6513
6650
            set_hot_swap_state(ent, IPMI_HOT_SWAP_ACTIVATION_REQUESTED,
6514
6651
                               NULL);
6515
6652
    }
6516
 
    ipmi_unlock(ent->lock);
 
6653
    ent_unlock(ent);
6517
6654
 
6518
6655
 out:
6519
6656
    ipmi_mem_free(info);
6531
6668
 
6532
6669
    if (err) {
6533
6670
        ipmi_log(IPMI_LOG_SEVERE,
6534
 
                 "%sentity.c(power_chedked): Unable to"
 
6671
                 "%sentity.c(check_power): Unable to"
6535
6672
                 " get power value, error %x",
6536
6673
                 CONTROL_NAME(control), err);
6537
6674
        ipmi_mem_free(info);
6540
6677
 
6541
6678
    info->power = val[0];
6542
6679
 
6543
 
    ipmi_lock(ent->lock);
 
6680
    ent_lock(ent);
6544
6681
    if (ent->hot_swap_requester) {
6545
 
        rv = ipmi_sensor_id_get_states(ent->hot_swap_requester_id,
6546
 
                                       check_requester,
6547
 
                                       info);
 
6682
        ipmi_sensor_id_t hsr = ent->hot_swap_requester_id;
 
6683
        ent_unlock(ent);
 
6684
        rv = ipmi_sensor_id_get_states(hsr, check_requester, info);
6548
6685
        if (rv) {
6549
6686
            ipmi_log(IPMI_LOG_SEVERE,
6550
 
                     "%sentity.c(power_checked): Unable to"
 
6687
                     "%sentity.c(check_power): Unable to"
6551
6688
                     " request requester status, error %x",
6552
6689
                     SENSOR_NAME(ent->hot_swap_requester), rv);
6553
6690
            ipmi_mem_free(info);
6557
6694
            set_hot_swap_state(ent, IPMI_HOT_SWAP_ACTIVE, NULL);
6558
6695
        else
6559
6696
            set_hot_swap_state(ent, IPMI_HOT_SWAP_INACTIVE, NULL);
 
6697
        ent_unlock(ent);
6560
6698
        ipmi_mem_free(info);
6561
6699
    }
6562
 
    ipmi_unlock(ent->lock);
6563
6700
}
6564
6701
 
6565
6702
static int
6566
6703
e_check_hot_swap_state(ipmi_entity_t *ent)
6567
6704
{
6568
6705
    hs_check_t *info;
 
6706
    int        rv = 0;
6569
6707
 
6570
6708
    info = ipmi_mem_alloc(sizeof(*info));
6571
6709
    if (!info)
6574
6712
    info->entity = ent;
6575
6713
    info->power = 1; /* Assume power is on if no power control. */
6576
6714
 
6577
 
    ipmi_lock(ent->lock);
6578
 
    if (ent->hot_swap_power)
6579
 
        ipmi_control_id_get_val(ent->hot_swap_power_id, check_power, info);
6580
 
    else if (ent->hot_swap_requester)
6581
 
        ipmi_sensor_id_get_states(ent->hot_swap_requester_id, check_requester,
6582
 
                                  info);
6583
 
    else
6584
 
        ipmi_mem_free(info);
6585
 
    ipmi_unlock(ent->lock);
 
6715
    ent_lock(ent);
 
6716
    if (ent->hot_swap_power) {
 
6717
        ipmi_control_id_t hsp = ent->hot_swap_power_id;
 
6718
        ent_unlock(ent);
 
6719
        rv = ipmi_control_id_get_val(hsp, check_power, info);
 
6720
    } else if (ent->hot_swap_requester) {
 
6721
        ipmi_sensor_id_t hsr = ent->hot_swap_requester_id;
 
6722
        ent_unlock(ent);
 
6723
        rv = ipmi_sensor_id_get_states(hsr, check_requester, info);
 
6724
    } else {
 
6725
        ent_unlock(ent);
 
6726
        ipmi_mem_free(info);
 
6727
    }
 
6728
        
 
6729
    if (info && rv)
 
6730
        ipmi_mem_free(info);
6586
6731
 
6587
 
    return 0;
 
6732
    return rv;
6588
6733
}
6589
6734
 
6590
6735
 
6746
6891
        info->__handler(entity, 0, info->__cb_data);
6747
6892
}
6748
6893
 
6749
 
static void
 
6894
static int
6750
6895
entity_opq_ready(void *cb_data, int shutdown)
6751
6896
{
6752
6897
    ipmi_entity_op_info_t *info = cb_data;
6760
6905
                 ENTITY_NAME(info->__entity));
6761
6906
        if (info->__handler)
6762
6907
            info->__handler(info->__entity, ECANCELED, info->__cb_data);
6763
 
        return;
 
6908
        return OPQ_HANDLER_STARTED;
6764
6909
    }
6765
6910
 
6766
6911
    rv = ipmi_entity_pointer_cb(info->__entity_id, entity_opq_ready2, info);
6773
6918
        if (info->__handler)
6774
6919
            info->__handler(info->__entity, rv, info->__cb_data);
6775
6920
    }
 
6921
 
 
6922
    return OPQ_HANDLER_STARTED;
6776
6923
}
6777
6924
 
6778
6925
int
6837
6984
                 "Could not convert entity id to a pointer, entity was"
6838
6985
                 " probably destroyed while operation was in progress",
6839
6986
                 MC_NAME(mc));
6840
 
        if (info->__rsp_handler)
 
6987
        if (info->__rsp_handler) {
 
6988
            _ipmi_domain_entity_lock(info->__entity->domain);
 
6989
            info->__entity->usecount++;
 
6990
            _ipmi_domain_entity_unlock(info->__entity->domain);
6841
6991
            info->__rsp_handler(info->__entity, rv, NULL, info->__cb_data);
 
6992
            _ipmi_entity_put(info->__entity);
 
6993
        }
6842
6994
    }
6843
6995
}
6844
6996
 
6894
7046
{
6895
7047
    CHECK_ENTITY_LOCK(ent);
6896
7048
 
6897
 
    ipmi_lock(ent->lock);
 
7049
    ent_lock(ent);
6898
7050
    ent->cruft_presence_handler = handler;
6899
7051
    ent->cruft_presence_cb_data = cb_data;
6900
 
    ipmi_unlock(ent->lock);
 
7052
    ent_unlock(ent);
6901
7053
    return 0;
6902
7054
}
6903
7055
 
6910
7062
 
6911
7063
    CHECK_ENTITY_LOCK(ent);
6912
7064
 
6913
 
    ipmi_lock(ent->lock);
 
7065
    ent_lock(ent);
6914
7066
    if (ent->cruft_sensor_handler)
6915
7067
        ipmi_entity_remove_sensor_update_handler
6916
7068
            (ent,
6921
7073
    ent->cruft_sensor_cb_data = cb_data;
6922
7074
    if (handler)
6923
7075
        rv = ipmi_entity_add_sensor_update_handler(ent, handler, cb_data);
6924
 
    ipmi_unlock(ent->lock);
 
7076
    ent_unlock(ent);
6925
7077
    return rv;
6926
7078
}
6927
7079
 
6934
7086
 
6935
7087
    CHECK_ENTITY_LOCK(ent);
6936
7088
 
6937
 
    ipmi_lock(ent->lock);
 
7089
    ent_lock(ent);
6938
7090
    if (ent->cruft_control_handler)
6939
7091
        ipmi_entity_remove_control_update_handler
6940
7092
            (ent,
6945
7097
    ent->cruft_control_cb_data = cb_data;
6946
7098
    if (handler)
6947
7099
        rv = ipmi_entity_add_control_update_handler(ent, handler, cb_data);
6948
 
    ipmi_unlock(ent->lock);
 
7100
    ent_unlock(ent);
6949
7101
    return rv;
6950
7102
}
6951
7103
 
6958
7110
 
6959
7111
    CHECK_ENTITY_LOCK(ent);
6960
7112
 
6961
 
    ipmi_lock(ent->lock);
 
7113
    ent_lock(ent);
6962
7114
    if (ent->cruft_fru_handler)
6963
7115
        ipmi_entity_remove_fru_update_handler
6964
7116
            (ent,
6969
7121
    ent->cruft_fru_cb_data = cb_data;
6970
7122
    if (handler)
6971
7123
        rv = ipmi_entity_add_fru_update_handler(ent, handler, cb_data);
6972
 
    ipmi_unlock(ent->lock);
 
7124
    ent_unlock(ent);
6973
7125
    return rv;
6974
7126
}
6975
7127