60
61
/* Holds an event in the list of events. */
61
62
typedef struct sel_event_holder_s
64
unsigned int deleted : 1;
65
unsigned int cancelled : 1;
66
unsigned int refcount;
64
67
ipmi_event_t *event;
65
68
} sel_event_holder_t;
67
#define SEL_NAME_LEN (IPMI_DOMAIN_NAME_LEN + 32)
70
static sel_event_holder_t *
71
sel_event_holder_alloc(void)
73
sel_event_holder_t *holder = ipmi_mem_alloc(sizeof(*holder));
78
holder->cancelled = 0;
85
sel_event_holder_get(sel_event_holder_t *holder)
91
sel_event_holder_put(sel_event_holder_t *holder)
94
if (holder->refcount == 0) {
95
ipmi_event_free(holder->event);
96
ipmi_mem_free(holder);
100
typedef struct sel_clear_req_s
102
ipmi_event_t *last_event;
103
struct sel_clear_req_s *next;
106
#define SEL_NAME_LEN (IPMI_MC_NAME_LEN + 32)
69
108
struct ipmi_sel_info_s
114
153
/* When fetching the data in event-driven mode, these are the
115
154
variables that track what is going on. */
155
unsigned int curr_rec_id;
156
unsigned int next_rec_id;
118
157
unsigned int reservation;
119
158
int sels_changed;
120
int fetch_retry_count;
159
unsigned int fetch_retry_count;
121
160
sel_fetch_handler_t *fetch_handlers;
162
/* When we start a fetch, we start with this id. This is the last
163
one we successfully fetches (or 0 if it is not valid) so we can
164
find the next valid id to fetch. */
165
unsigned int start_rec_id;
166
unsigned char start_rec_id_data[14];
123
168
/* A lock, primarily for handling race conditions fetching the data. */
124
169
os_hnd_lock_t *sel_lock;
258
304
memset(sel, 0, sizeof(*sel));
260
strncpy(sel->name, _ipmi_mc_name(mc), sizeof(sel->name));
306
i = ipmi_mc_get_name(mc, sel->name, sizeof(sel->name));
307
snprintf(sel->name+i, sizeof(sel->name)-i, "(sel)");
262
309
sel->events = alloc_ilist();
263
310
if (!sel->events) {
476
525
free_deleted_event(ilist_iter_t *iter, void *item, void *cb_data)
478
527
sel_event_holder_t *holder = item;
528
ipmi_sel_info_t *sel = cb_data;
480
530
if (holder->deleted) {
481
531
ilist_delete(iter);
482
ipmi_event_free(holder->event);
483
ipmi_mem_free(holder);
532
holder->cancelled = 1;
534
sel_event_holder_put(holder);
487
free_deleted_events(ilist_t *events)
539
free_deleted_events(ipmi_sel_info_t *sel)
489
ilist_iter(events, free_deleted_event, NULL);
541
ilist_iter(sel->events, free_deleted_event, sel);
613
665
"%ssel.c(handle_sel_data): "
614
666
"Too many lost reservations in SEL fetch",
616
fetch_complete(sel, EAGAIN);
668
fetch_complete(sel, EAGAIN, 1);
619
672
start_fetch(elem, 0);
623
if (rsp->data[0] != 0) {
624
if (sel->curr_rec_id != 0) {
676
if ((rsp->data[0] == 0) && (rsp->data_len < 19)) {
677
ipmi_log(IPMI_LOG_ERR_INFO,
678
"%ssel.c(handle_sel_data): "
679
"Received a short SEL data message",
681
fetch_complete(sel, EINVAL, 1);
685
if ((rsp->data[0] != 0)
686
|| ((sel->start_rec_id != 0) && (sel->start_rec_id == sel->curr_rec_id)
687
&& (memcmp(sel->start_rec_id_data, rsp->data+5, 14) != 0)))
689
/* We got an error fetching the current id, or the current
690
id's data was for our "start" record and it doesn't match
691
the one we fetched, so it has changed. We have to start
692
over or handle the error. */
693
if (sel->start_rec_id != 0) {
625
694
/* If we get a fetch error and it is not a lost
626
695
reservation, it may be that another system deleted our
627
696
"current" record. Start over from the beginning of the
698
sel->start_rec_id = 0;
629
699
sel->curr_rec_id = 0;
630
700
del_event = NULL;
631
701
goto start_request_sel_data;
636
706
"%ssel.c(handle_sel_data): "
637
707
"IPMI error from SEL fetch: %x",
638
708
sel->name, rsp->data[0]);
639
fetch_complete(sel, IPMI_IPMI_ERR_VAL(rsp->data[0]));
709
fetch_complete(sel, IPMI_IPMI_ERR_VAL(rsp->data[0]), 1);
669
739
holder = find_event(sel->events, record_id);
671
holder = ipmi_mem_alloc(sizeof(*holder));
741
holder = sel_event_holder_alloc();
673
743
ipmi_log(IPMI_LOG_ERR_INFO,
674
744
"%ssel.c(handle_sel_data): "
675
745
"Could not allocate log information for SEL",
677
fetch_complete(sel, ENOMEM);
747
fetch_complete(sel, ENOMEM, 1);
680
750
if (!ilist_add_tail(sel->events, holder, NULL)) {
720
790
/* To avoid confusion, deliver the event before we deliver fetch
722
if (event_is_new && sel->new_event_handler)
723
sel->new_event_handler(sel,
726
sel->new_event_cb_data);
792
if (event_is_new && sel->new_event_handler) {
793
ipmi_sel_new_event_handler_cb handler = sel->new_event_handler;
794
void *cb_data = sel->new_event_cb_data;
796
handler(sel, mc, del_event, cb_data);
728
800
if (sel->sel_good_scans)
729
801
ipmi_domain_stat_add(sel->sel_good_scans, 1);
739
811
happen again later if it does. */
740
812
rv = send_sel_clear(elem, mc);
742
fetch_complete(sel, 0);
814
fetch_complete(sel, 0, 1);
748
fetch_complete(sel, 0);
820
fetch_complete(sel, 0, 1);
824
sel->start_rec_id = sel->curr_rec_id;
825
memcpy(sel->start_rec_id_data, rsp->data+5, 14);
752
826
sel->curr_rec_id = sel->next_rec_id;
754
828
start_request_sel_data:
766
840
ipmi_log(IPMI_LOG_ERR_INFO,
767
841
"%ssel.c(handle_sel_clear): "
768
842
"Could not send SEL fetch command: %x", sel->name, rv);
769
fetch_complete(sel, rv);
843
fetch_complete(sel, rv, 1);
773
if (event_is_new && sel->new_event_handler)
774
sel->new_event_handler(sel, mc, del_event, sel->new_event_cb_data);
847
if (event_is_new && sel->new_event_handler) {
848
ipmi_sel_new_event_handler_cb handler = sel->new_event_handler;
849
void *cb_data = sel->new_event_cb_data;
851
handler(sel, mc, del_event, cb_data);
832
911
"%ssel.c(handle_sel_info): "
833
912
"IPMI error from SEL info fetch: %x",
834
913
sel->name, rsp->data[0]);
835
fetch_complete(sel, IPMI_IPMI_ERR_VAL(rsp->data[0]));
914
fetch_complete(sel, IPMI_IPMI_ERR_VAL(rsp->data[0]), 1);
841
920
ipmi_domain_stat_add(sel->sel_fetch_errors, 1);
842
921
ipmi_log(IPMI_LOG_ERR_INFO,
843
922
"%ssel.c(handle_sel_info): SEL info too short", sel->name);
844
fetch_complete(sel, EINVAL);
923
fetch_complete(sel, EINVAL, 1);
863
942
sel_fixups(mc, sel);
865
/* If the timestamps still match, no need to re-fetch the repository */
867
&& (add_timestamp == sel->last_addition_timestamp)
868
&& (erase_timestamp == sel->last_erase_timestamp))
944
/* If the timestamps still match, no need to re-fetch the
945
repository. Note that we only check the add timestamp. We
946
don't care if things were deleted. */
947
if (sel->fetched && (add_timestamp == sel->last_addition_timestamp)) {
870
948
/* If the operation completed successfully and everything in
871
949
our SEL is deleted, then clear it with our old reservation.
872
950
We also do the clear if the overflow flag is set; on some
878
956
happen again later if it does. */
879
957
rv = send_sel_clear(elem, mc);
881
fetch_complete(sel, 0);
959
fetch_complete(sel, 0, 1);
886
fetch_complete(sel, 0);
964
fetch_complete(sel, 0, 1);
891
/* Note that we only re-fetch from the beginning if the SEL is
892
erased. The SEL is supposed to be ordered and only have new
893
records added onto the end. So we can re-fetch from the last
894
added one to get the next event properly. Unless, of course,
895
the SEL was erased. */
896
if (sel->last_erase_timestamp != erase_timestamp) {
897
sel->curr_rec_id = 0;
900
969
sel->curr_addition_timestamp = add_timestamp;
901
970
sel->curr_erase_timestamp = erase_timestamp;
910
979
there was nothing to do. */
911
980
sel->last_addition_timestamp = sel->curr_addition_timestamp;
912
981
sel->last_erase_timestamp = sel->curr_erase_timestamp;
982
sel->start_rec_id = 0;
983
sel->curr_rec_id = 0;
914
fetch_complete(sel, 0);
985
fetch_complete(sel, 0, 1);
918
989
/* Fetch the first SEL entry. */
990
sel->curr_rec_id = sel->start_rec_id;
919
991
cmd_msg.data = cmd_data;
920
992
cmd_msg.netfn = IPMI_STORAGE_NETFN;
921
993
cmd_msg.cmd = IPMI_GET_SEL_ENTRY_CMD;
1015
send_get_sel_info(sel_fetch_handler_t *elem, ipmi_mc_t *mc)
1017
ipmi_sel_info_t *sel = elem->sel;
1020
/* Fetch the repository info. */
1021
cmd_msg.netfn = IPMI_STORAGE_NETFN;
1022
cmd_msg.cmd = IPMI_GET_SEL_INFO_CMD;
1023
cmd_msg.data = NULL;
1024
cmd_msg.data_len = 0;
1025
return ipmi_mc_send_command(mc, sel->lun, &cmd_msg, handle_sel_info, elem);
943
1029
sel_handle_reservation(ipmi_mc_t *mc,
944
1030
ipmi_msg_t *rsp,
975
1059
ipmi_log(IPMI_LOG_ERR_INFO,
976
1060
"%ssel.c(sel_handle_reservation): "
977
1061
"Failed getting reservation", sel->name);
978
fetch_complete(sel, ENOSYS);
1062
fetch_complete(sel, ENOSYS, 1);
980
1064
} else if (rsp->data_len < 3) {
981
1065
if (sel->sel_fetch_errors)
983
1067
ipmi_log(IPMI_LOG_ERR_INFO,
984
1068
"%ssel.c(sel_handle_reservation): "
985
1069
"got invalid reservation length", sel->name);
986
fetch_complete(sel, EINVAL);
1070
fetch_complete(sel, EINVAL, 1);
990
1074
sel->reservation = ipmi_get_uint16(rsp->data+1);
992
/* Fetch the repository info. */
993
cmd_msg.data = cmd_data;
994
cmd_msg.netfn = IPMI_STORAGE_NETFN;
995
cmd_msg.cmd = IPMI_GET_SEL_INFO_CMD;
996
cmd_msg.data_len = 0;
997
rv = ipmi_mc_send_command(mc, sel->lun, &cmd_msg, handle_sel_info, elem);
1076
rv = send_get_sel_info(elem, mc);
999
1078
ipmi_log(IPMI_LOG_ERR_INFO,
1000
1079
"%ssel.c(sel_handle_reservation): "
1001
1080
"Could not send SEL info command: %x", sel->name, rv);
1002
fetch_complete(sel, rv);
1081
fetch_complete(sel, rv, 1);
1005
1084
sel_unlock(sel);
1051
1129
ipmi_log(IPMI_LOG_ERR_INFO,
1052
1130
"%ssel.c(start_fetch_cb): could not send cmd: %x",
1053
1131
sel->name, rv);
1054
fetch_complete(sel, ECANCELED);
1064
1141
start_fetch(void *cb_data, int shutdown)
1066
1143
sel_fetch_handler_t *elem = cb_data;
1146
sel_lock(elem->sel);
1069
1147
if (shutdown) {
1070
1148
ipmi_log(IPMI_LOG_ERR_INFO,
1071
1149
"%ssel.c(start_fetch): "
1072
1150
"SEL info was destroyed while an operation was in progress",
1073
1151
elem->sel->name);
1074
sel_lock(elem->sel);
1075
fetch_complete(elem->sel, ECANCELED);
1152
fetch_complete(elem->sel, ECANCELED, 0);
1153
return OPQ_HANDLER_ABORTED;
1079
1156
/* The read lock must be claimed before the sel lock to avoid
1081
1158
rv = ipmi_mc_pointer_cb(elem->sel->mc, start_fetch_cb, elem);
1083
1160
ipmi_log(IPMI_LOG_ERR_INFO,
1084
1161
"%ssel.c(start_fetch): MC is not valid", elem->sel->name);
1085
sel_lock(elem->sel);
1086
fetch_complete(elem->sel, rv);
1166
fetch_complete(elem->sel, rv, 0);
1167
return OPQ_HANDLER_ABORTED;
1170
sel_unlock(elem->sel);
1172
return OPQ_HANDLER_STARTED;
1090
1175
/* We have to have this because the allocate element can go away (the
1122
1207
elem->next = NULL;
1123
1208
sel->fetch_handlers = elem;
1124
1209
sel_unlock(sel);
1125
if (!opq_new_op(sel->opq, start_fetch, elem, 0)) {
1210
/* Always put a fetch ahead of everything else. If there are
1211
deletes in progress and a clear gets done, we can complete
1213
if (!opq_new_op_prio(sel->opq, start_fetch, elem, 0, OPQ_ADD_HEAD,
1126
1216
sel->fetch_handlers = NULL;
1127
1217
info->rv = ENOMEM;
1192
1284
unsigned int lun;
1193
1285
unsigned int count;
1194
1286
ipmi_event_t *event;
1195
} sel_cb_handler_data_t;
1197
static int send_reserve_sel_for_delete(sel_cb_handler_data_t *data,
1287
sel_event_holder_t *holder;
1289
/* If true, we do a clear operation if the given record is the
1290
last record in the SEL. */
1292
} sel_del_handler_data_t;
1294
static int send_reserve_sel_for_delete(sel_del_handler_data_t *data,
1198
1295
ipmi_mc_t *mc);
1201
sel_op_done(sel_cb_handler_data_t *data,
1298
sel_op_done(sel_del_handler_data_t *data,
1204
1302
ipmi_sel_info_t *sel = data->sel;
1305
sel_event_holder_put(data->holder);
1206
1309
if (data->handler)
1207
1310
data->handler(sel, data->cb_data, rv);
1209
1314
if (sel->in_destroy) {
1210
1315
/* Nothing to do */
1211
1316
sel_unlock(sel);
1331
free_all_event(ilist_iter_t *iter, void *item, void *cb_data)
1333
sel_event_holder_t *holder = item;
1334
ipmi_sel_info_t *sel = cb_data;
1336
if (holder->deleted) {
1338
holder->cancelled = 1;
1341
sel_event_holder_put(holder);
1345
free_all_events(ipmi_sel_info_t *sel)
1347
ilist_iter(sel->events, free_all_event, sel);
1351
handle_del_sel_clear(ipmi_mc_t *mc,
1355
sel_del_handler_data_t *data = rsp_data;
1356
ipmi_sel_info_t *sel = data->sel;
1359
if (sel->destroyed) {
1360
ipmi_log(IPMI_LOG_ERR_INFO,
1361
"%ssel.c(handle_del_sel_clear): "
1362
"SEL info was destroyed while an operation was in progress",
1364
sel_op_done(data, ECANCELED, 1);
1369
ipmi_log(IPMI_LOG_ERR_INFO,
1370
"%ssel.c(handle_del_sel_clear): "
1371
"MC went away while SEL fetch was in progress",
1373
sel_op_done(data, ECANCELED, 1);
1378
ipmi_log(IPMI_LOG_ERR_INFO,
1379
"%ssel.c(handle_del_sel_clear): "
1380
"IPMI error clearing SEL: 0x%x",
1381
sel->name, rsp->data[0]);
1382
sel_op_done(data, IPMI_IPMI_ERR_VAL(rsp->data[0]), 1);
1386
free_all_events(sel);
1389
sel_op_done(data, 0, 1);
1396
send_del_clear(sel_del_handler_data_t *data, ipmi_mc_t *mc)
1398
ipmi_sel_info_t *sel = data->sel;
1399
unsigned char cmd_data[MAX_IPMI_DATA_SIZE];
1402
cmd_msg.data = cmd_data;
1403
cmd_msg.netfn = IPMI_STORAGE_NETFN;
1404
cmd_msg.cmd = IPMI_CLEAR_SEL_CMD;
1405
cmd_msg.data_len = 6;
1406
ipmi_set_uint16(cmd_msg.data, data->reservation);
1407
cmd_msg.data[2] = 'C';
1408
cmd_msg.data[3] = 'L';
1409
cmd_msg.data[4] = 'R';
1410
cmd_msg.data[5] = 0xaa;
1412
return ipmi_mc_send_command(mc, sel->lun, &cmd_msg,
1413
handle_del_sel_clear, data);
1225
1417
handle_sel_delete(ipmi_mc_t *mc,
1226
1418
ipmi_msg_t *rsp,
1227
1419
void *rsp_data)
1229
sel_cb_handler_data_t *data = (sel_cb_handler_data_t *) rsp_data;
1230
ipmi_sel_info_t *sel = data->sel;
1421
sel_del_handler_data_t *data = rsp_data;
1422
ipmi_sel_info_t *sel = data->sel;
1234
1426
if (sel->destroyed) {
1335
1526
ipmi_msg_t *rsp,
1336
1527
void *rsp_data)
1338
sel_cb_handler_data_t *data = (sel_cb_handler_data_t *) rsp_data;
1339
ipmi_sel_info_t *sel = data->sel;
1529
sel_del_handler_data_t *data = rsp_data;
1530
ipmi_sel_info_t *sel = data->sel;
1343
1534
if (sel->destroyed) {
1344
1535
ipmi_log(IPMI_LOG_ERR_INFO,
1345
1536
"%ssel.c(handle_sel_check): "
1346
"SEL info was destroyed while an operation was in progress",
1537
"SEL info was destroyed while SEL delete element was in"
1348
sel_op_done(data, ECANCELED);
1540
sel_op_done(data, ECANCELED, 1);
1353
1545
ipmi_log(IPMI_LOG_ERR_INFO,
1354
1546
"%ssel.c(handle_sel_check): "
1355
"MC went away while SEL fetch was in progress",
1547
"MC went away while SEL delete element was in progress",
1357
sel_op_done(data, ECANCELED);
1549
sel_op_done(data, ECANCELED, 1);
1361
1553
/* Special return codes. */
1362
1554
if (rsp->data[0] == IPMI_NOT_PRESENT_CC) {
1363
1555
/* The entry is already gone, so just return no error. */
1364
sel_op_done(data, 0);
1556
sel_op_done(data, 0, 1);
1366
1558
} else if (rsp->data[0]) {
1367
1559
if (sel->sel_delete_errors)
1368
1560
ipmi_domain_stat_add(sel->sel_delete_errors, 1);
1369
1561
ipmi_log(IPMI_LOG_ERR_INFO,
1370
"%ssel.c(handle_sel_check): IPMI error from SEL get: %x",
1562
"%ssel.c(handle_sel_check): IPMI error from SEL check: %x",
1371
1563
sel->name, rsp->data[0]);
1372
sel_op_done(data, IPMI_IPMI_ERR_VAL(rsp->data[0]));
1564
sel_op_done(data, IPMI_IPMI_ERR_VAL(rsp->data[0]), 1);
1375
1567
ipmi_event_t *ch_event;
1389
1581
ipmi_log(IPMI_LOG_ERR_INFO,
1390
1582
"%ssel.c(handle_sel_check): Could not allocate memory",
1392
sel_op_done(data, ENOMEM);
1584
sel_op_done(data, ENOMEM, 1);
1396
if (event_cmp(ch_event, data->event) != 0) {
1588
if (data->event && (event_cmp(ch_event, data->event) != 0)) {
1397
1589
/* The event's don't match, so just finish. */
1398
1590
ipmi_event_free(ch_event);
1399
sel_op_done(data, 0);
1591
sel_op_done(data, 0, 1);
1402
1594
ipmi_event_free(ch_event);
1404
rv = send_del_sel(data, mc);
1406
ipmi_log(IPMI_LOG_ERR_INFO,
1407
"%ssel.c(handle_sel_check): "
1408
"Could not send SEL delete command: %x",
1410
sel_op_done(data, rv);
1412
} else if (data->record_id == sel->curr_rec_id)
1413
/* We are deleting our "current" record (used for finding
1414
the next record), make sure we start again from
1415
scratch on the next fetch. */
1416
sel->curr_rec_id = 0;
1596
if (data->do_clear) {
1597
/* Make sure that there is no next event. */
1598
uint16_t next_ev = ipmi_get_uint16(rsp->data+1);
1600
if (next_ev != 0xffff) {
1601
/* A new event was added after this one. Fail the op. */
1602
ipmi_log(IPMI_LOG_ERR_INFO,
1603
"%ssel.c(handle_sel_check): "
1604
"Clear SEL failed, new events in SEL",
1606
sel_op_done(data, EAGAIN, 1);
1610
rv = send_del_clear(data, mc);
1612
ipmi_log(IPMI_LOG_ERR_INFO,
1613
"%ssel.c(handle_sel_check): "
1614
"Could not send SEL clear command: %x",
1616
sel_op_done(data, rv, 1);
1620
rv = send_del_sel(data, mc);
1622
ipmi_log(IPMI_LOG_ERR_INFO,
1623
"%ssel.c(handle_sel_check): "
1624
"Could not send SEL delete command: %x",
1626
sel_op_done(data, rv, 1);
1628
} else if (data->record_id == sel->start_rec_id)
1629
/* We are deleting our "current" record (used for finding
1630
the next record), make sure we start again from
1631
scratch on the next fetch. */
1632
sel->start_rec_id = 0;
1450
1667
ipmi_msg_t *rsp,
1451
1668
void *rsp_data)
1453
sel_cb_handler_data_t *data = rsp_data;
1454
ipmi_sel_info_t *sel = data->sel;
1670
sel_del_handler_data_t *data = rsp_data;
1671
ipmi_sel_info_t *sel = data->sel;
1458
1675
if (sel->destroyed) {
1459
1676
ipmi_log(IPMI_LOG_ERR_INFO,
1460
1677
"%ssel.c(sel_reserved_for_delete): "
1461
"SEL info was destroyed while an operation was in progress",
1678
"SEL info was destroyed while SEL delete element was in"
1463
sel_op_done(data, ECANCELED);
1681
sel_op_done(data, ECANCELED, 1);
1467
1685
ipmi_log(IPMI_LOG_ERR_INFO,
1468
1686
"%ssel.c(sel_reserved_for_delete): "
1469
"MC went away while SEL fetch was in progress", sel->name);
1470
sel_op_done(data, ECANCELED);
1687
"MC went away while SEL delete element was in progress",
1689
sel_op_done(data, ECANCELED, 1);
1478
1697
"%ssel.c(sel_reserved_for_delete): "
1479
1698
"IPMI error from SEL delete reservation: %x",
1480
1699
sel->name, rsp->data[0]);
1481
sel_op_done(data, IPMI_IPMI_ERR_VAL(rsp->data[0]));
1700
sel_op_done(data, IPMI_IPMI_ERR_VAL(rsp->data[0]), 1);
1485
1704
data->reservation = ipmi_get_uint16(rsp->data+1);
1486
rv = send_check_sel(data, mc);
1488
ipmi_log(IPMI_LOG_ERR_INFO,
1489
"%ssel.c(sel_reserved_for_delete): "
1490
"Could not send SEL get command: %x", sel->name, rv);
1491
sel_op_done(data, rv);
1705
if (!data->do_clear || data->event) {
1706
rv = send_check_sel(data, mc);
1708
ipmi_log(IPMI_LOG_ERR_INFO,
1709
"%ssel.c(sel_reserved_for_delete): "
1710
"Could not send SEL get command: %x", sel->name, rv);
1711
sel_op_done(data, rv, 1);
1715
/* We are clearing the SEL and the user didn't supply an
1716
event. Don't worry about checking anything. */
1717
rv = send_del_clear(data, mc);
1719
ipmi_log(IPMI_LOG_ERR_INFO,
1720
"%ssel.c(sel_reserved_for_delete): "
1721
"Could not send SEL clear command: %x", sel->name, rv);
1722
sel_op_done(data, rv, 1);
1495
1727
sel_unlock(sel);
1562
1794
"%ssel.c(start_del_sel): "
1563
1795
"SEL info was destroyed while an operation was in progress",
1565
sel_op_done(data, ECANCELED);
1797
sel_op_done(data, ECANCELED, 0);
1798
return OPQ_HANDLER_ABORTED;
1801
if (data->holder && data->holder->cancelled) {
1802
/* Deleted by a clear, everything is ok. */
1803
sel_op_done(data, 0, 0);
1804
return OPQ_HANDLER_ABORTED;
1569
1807
rv = ipmi_mc_pointer_cb(sel->mc, start_del_sel_cb, data);
1571
1809
ipmi_log(IPMI_LOG_ERR_INFO,
1572
1810
"%ssel.c(start_del_sel_cb): MC went away during delete",
1574
sel_op_done(data, ECANCELED);
1812
sel_op_done(data, ECANCELED, 0);
1813
return OPQ_HANDLER_ABORTED;
1816
return OPQ_HANDLER_STARTED;
1582
1819
typedef struct sel_del_event_info_s
1608
1845
goto out_unlock;
1611
ilist_init_iter(&iter, sel->events);
1612
ilist_unpositioned(&iter);
1613
real_holder = ilist_search_iter(&iter, recid_search_cmp,
1849
ilist_init_iter(&iter, sel->events);
1850
ilist_unpositioned(&iter);
1851
real_holder = ilist_search_iter(&iter, recid_search_cmp,
1614
1852
&info->record_id);
1620
if (cmp_event && (event_cmp(event, real_holder->event) != 0)) {
1625
if (real_holder->deleted) {
1630
real_holder->deleted = 1;
1636
if (sel->supports_delete_sel) {
1858
if (cmp_event && (event_cmp(event, real_holder->event) != 0)) {
1863
if (! info->do_clear) {
1864
if (real_holder->deleted) {
1869
real_holder->deleted = 1;
1873
start_fetch = (sel->num_sels == 0) && (sel->del_sels > 1);
1877
/* Note that at this point we cannot check num_sels to see if it
1878
is zero and do a bulk clear. A new event might be added to the
1879
SEL after this point, thus failing the bulk clear, and that
1880
would prevent the individual delete from happening. But we can
1881
start a fetch if the value reaches zero, which is just as
1884
if (sel->supports_delete_sel || info->do_clear) {
1885
sel_del_handler_data_t *data;
1637
1888
/* We can delete the entry immediately, just do it. */
1638
1889
data = ipmi_mem_alloc(sizeof(*data));
1640
/* We will eventually free this anyway, so no need to
1890
elem = opq_alloc_elem();
1891
if (!data || !elem) {
1892
if (! info->do_clear) {
1893
real_holder->deleted = 0;
1899
ipmi_mem_free(data);
1901
opq_free_elem(elem);
1642
1902
goto out_unlock;
1644
1905
data->sel = sel;
1645
1906
data->handler = info->handler;
1646
1907
data->cb_data = info->cb_data;
1908
data->lun = sel->lun;
1648
1909
data->record_id = info->record_id;
1649
1910
data->count = 0;
1650
1911
data->event = event;
1912
data->holder = real_holder;
1914
sel_event_holder_get(real_holder);
1915
data->do_clear = info->do_clear;
1653
/* We don't return a return code, because we don't really
1654
care. If this fails, it will just be handled later. */
1655
1918
sel_unlock(sel);
1656
if (!opq_new_op(sel->opq, start_del_sel, data, 0))
1657
ipmi_mem_free(data);
1919
opq_new_op_prio(sel->opq, start_del_sel, data, 0, OPQ_ADD_TAIL, elem);
1659
1921
sel_unlock(sel);
1660
1922
/* Don't really delete the event, but report is as done. */
1661
1923
info->handler(sel, info->cb_data, 0);
1662
1924
ipmi_event_free(event);
1928
ipmi_sel_get(sel, NULL, NULL);
1709
1976
ipmi_sel_op_done_cb_t handler,
1712
return sel_del_event(sel, NULL, record_id, handler, cb_data, 0);
1979
return sel_del_event(sel, NULL, record_id, handler, cb_data, 0, 0);
1983
ipmi_sel_clear(ipmi_sel_info_t *sel,
1984
ipmi_event_t *last_event,
1985
ipmi_sel_op_done_cb_t handler,
1988
int cmp_event = (last_event != NULL);
1989
unsigned int record_id = 0;
1991
record_id = ipmi_event_get_record_id(last_event);
1992
return sel_del_event(sel, last_event, record_id, handler, cb_data,