~ubuntu-branches/ubuntu/gutsy/openipmi/gutsy

« back to all changes in this revision

Viewing changes to lib/sensor.c

  • Committer: Bazaar Package Importer
  • Author(s): Noèl Köthe
  • Date: 2007-06-21 19:48:32 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070621194832-nqtxvxn4pu3ha3gh
Tags: 2.0.11-1
* new upstream release from 2007-02-25
  (closes: Bug#392788)
* added patch parts from Philipp Matthias Hahn <pmhahn@debian.org>
  Thank you!

Show diffs side-by-side

added added

removed removed

Lines of Context:
109
109
    unsigned char entity_id;
110
110
    unsigned char entity_instance;
111
111
 
112
 
    unsigned char entity_instance_logical : 1;
 
112
    /* Can the sensor be read?  Event-only sensors and sensors with
 
113
       software ID owners cannot be read.  */
 
114
    unsigned int  readable : 1;
 
115
 
 
116
    unsigned int  entity_instance_logical : 1;
113
117
    unsigned int  sensor_init_scanning : 1;
114
118
    unsigned int  sensor_init_events : 1;
115
119
    unsigned int  sensor_init_thresholds : 1;
820
824
 
821
825
    sensor->hot_swap_requester = -1;
822
826
    sensor->usecount = 1;
 
827
    sensor->readable = 1;
823
828
 
824
829
    *new_sensor = sensor;
825
830
    return 0;
839
844
    ipmi_domain_t      *domain;
840
845
    os_handler_t       *os_hnd;
841
846
    void               *link;
 
847
    int                err;
 
848
    unsigned int       i;
842
849
 
843
850
    CHECK_MC_LOCK(mc);
844
851
    CHECK_ENTITY_LOCK(ent);
846
853
    domain = ipmi_mc_get_domain(mc);
847
854
    os_hnd = ipmi_domain_get_os_hnd(domain);
848
855
 
849
 
    if (num >= 256)
 
856
    if ((num >= 256) && (num != UINT_MAX))
850
857
        return EINVAL;
851
858
 
852
859
    _ipmi_domain_entity_lock(domain);
853
860
    ipmi_lock(sensors->idx_lock);
854
861
 
 
862
    if (num == UINT_MAX){
 
863
        for (i=0; i<sensors->idx_size[4]; i++) {
 
864
            if (! sensors->sensors_by_idx[4][i])
 
865
                break;
 
866
        }
 
867
        num = i;
 
868
        if (num >= 256) {
 
869
            err = EAGAIN;
 
870
            goto out_err;
 
871
        }
 
872
    }
 
873
 
855
874
    if (num >= sensors->idx_size[4]) {
856
875
        ipmi_sensor_t **new_array;
857
876
        unsigned int  new_size;
861
880
           too much). */
862
881
        new_size = ((num / 16) * 16) + 16;
863
882
        new_array = ipmi_mem_alloc(sizeof(*new_array) * new_size);
864
 
        if (!new_array)
865
 
            return ENOMEM;
 
883
        if (!new_array) {
 
884
            err = ENOMEM;
 
885
            goto out_err;
 
886
        }
866
887
        if (sensors->sensors_by_idx[4]) {
867
888
            memcpy(new_array, sensors->sensors_by_idx[4],
868
889
                   sizeof(*new_array) * (sensors->idx_size[4]));
875
896
    }
876
897
 
877
898
    sensor->waitq = opq_alloc(os_hnd);
878
 
    if (! sensor->waitq)
879
 
        return ENOMEM;
 
899
    if (! sensor->waitq) {
 
900
        err = ENOMEM;
 
901
        goto out_err;
 
902
    }
880
903
 
881
904
    sensor->handler_list = locked_list_alloc(os_hnd);
882
905
    if (! sensor->handler_list) {
883
906
        opq_destroy(sensor->waitq);
884
 
        return ENOMEM;
 
907
        err = ENOMEM;
 
908
        goto out_err;
885
909
    }
886
910
 
887
911
    link = locked_list_alloc_entry();
890
914
        sensor->waitq = NULL;
891
915
        locked_list_destroy(sensor->handler_list);
892
916
        sensor->handler_list = NULL;
893
 
        return ENOMEM;
 
917
        err = ENOMEM;
 
918
        goto out_err;
894
919
    }
895
920
 
896
921
    sensor->domain = domain;
920
945
    sensor->add_pending = 1;
921
946
 
922
947
    return 0;
 
948
 
 
949
 out_err:
 
950
    ipmi_unlock(sensors->idx_lock);
 
951
    _ipmi_domain_entity_unlock(domain);
 
952
    return err;
923
953
}
924
954
 
925
955
static void
933
963
    if (sensor->destroy_handler)
934
964
        sensor->destroy_handler(sensor, sensor->destroy_handler_cb_data);
935
965
 
936
 
    if (sensor->oem_info_cleanup_handler)
937
 
        sensor->oem_info_cleanup_handler(sensor, sensor->oem_info);
938
 
 
939
966
    if (sensor->waitq)
940
967
        opq_destroy(sensor->waitq);
941
968
 
945
972
    if (sensor->entity)
946
973
        ipmi_entity_remove_sensor(sensor->entity, sensor);
947
974
 
 
975
    if (sensor->oem_info_cleanup_handler)
 
976
        sensor->oem_info_cleanup_handler(sensor, sensor->oem_info);
 
977
 
948
978
    _ipmi_entity_put(sensor->entity);
949
979
    ipmi_mem_free(sensor);
950
980
}
961
991
    sensors = _ipmi_mc_get_sensors(sensor->mc);
962
992
 
963
993
    ipmi_lock(sensors->idx_lock);
964
 
    if (sensor != sensors->sensors_by_idx[sensor->lun][sensor->num]) {
965
 
        ipmi_unlock(sensors->idx_lock);
966
 
        _ipmi_mc_put(sensor->mc);
967
 
        return EINVAL;
 
994
    if (sensor == sensors->sensors_by_idx[sensor->lun][sensor->num]) {
 
995
        sensors->sensor_count--;
 
996
        sensors->sensors_by_idx[sensor->lun][sensor->num] = NULL;
968
997
    }
969
998
 
970
999
    _ipmi_sensor_get(sensor);
972
1001
    if (sensor->source_array)
973
1002
        sensor->source_array[sensor->source_idx] = NULL;
974
1003
 
975
 
    sensors->sensor_count--;
976
 
    sensors->sensors_by_idx[sensor->lun][sensor->num] = NULL;
977
1004
    ipmi_unlock(sensors->idx_lock);
978
1005
 
979
1006
    sensor->destroyed = 1;
1083
1110
    int           entity_instance_incr;
1084
1111
    int           id_string_modifier_offset;
1085
1112
    unsigned char *str;
1086
 
 
 
1113
    unsigned int  str_len;
1087
1114
    
1088
1115
 
1089
1116
    rv = ipmi_get_sdr_count(sdrs, &count);
1090
 
    if (rv)
 
1117
    if (rv) {
 
1118
        ipmi_log(IPMI_LOG_WARNING,
 
1119
                 "%ssensor.c(get_sensors_from_sdrs):"
 
1120
                 " Could not fetch SDR count fron the SDR record.",
 
1121
                 MC_NAME(source_mc));
1091
1122
        goto out_err;
1092
 
 
 
1123
    }
 
1124
    
1093
1125
    /* Get a real count on the number of sensors, since a single SDR can
1094
1126
       contain multiple sensors. */
1095
1127
    p = 0;
1098
1130
        int lun;
1099
1131
 
1100
1132
        rv = ipmi_get_sdr_by_index(sdrs, i, &sdr);
1101
 
        if (rv)
 
1133
        if (rv) {
 
1134
            ipmi_log(IPMI_LOG_WARNING,
 
1135
                     "%ssensor.c(get_sensors_from_sdrs):"
 
1136
                     " SDR record %d could not be fetched from the SDR"
 
1137
                     " record: %d",
 
1138
                     MC_NAME(source_mc), i, rv);
1102
1139
            goto out_err;
 
1140
        }
1103
1141
 
1104
1142
        lun = sdr.data[1] & 0x03;
1105
1143
        if (sdr.type == 1) {
1122
1160
 
1123
1161
    /* Setup memory to hold the sensors. */
1124
1162
    s = ipmi_mem_alloc(sizeof(*s) * p);
1125
 
    if (!s) {
1126
 
        rv = ENOMEM;
1127
 
        goto out_err;
1128
 
    }
 
1163
    if (!s)
 
1164
        goto out_err_enomem;
1129
1165
    s_size = p;
1130
1166
    memset(s, 0, sizeof(*s) * p);
1131
1167
 
1132
1168
    p = 0;
1133
1169
    for (i=0; i<count; i++) {
1134
1170
        rv = ipmi_get_sdr_by_index(sdrs, i, &sdr);
1135
 
        if (rv)
 
1171
        if (rv) {
 
1172
            ipmi_log(IPMI_LOG_WARNING,
 
1173
                     "%ssensor.c(get_sensors_from_sdrs):"
 
1174
                     " SDR record %d could not be fetched from the SDR"
 
1175
                     " record: %d (2)",
 
1176
                     MC_NAME(source_mc), i, rv);
1136
1177
            goto out_err;
 
1178
        }
1137
1179
 
1138
1180
        if ((sdr.type != 1) && (sdr.type != 2) && (sdr.type != 3))
1139
1181
            continue;
1140
1182
 
1141
1183
        s[p] = ipmi_mem_alloc(sizeof(*s[p]));
1142
 
        if (!s[p]) {
1143
 
            rv = ENOMEM;
1144
 
            goto out_err;
1145
 
        }
 
1184
        if (!s[p])
 
1185
            goto out_err_enomem;
1146
1186
        memset(s[p], 0, sizeof(*s[p]));
1147
1187
 
1148
1188
        s[p]->source_recid = sdr.record_id;
1149
1189
        s[p]->hot_swap_requester = -1;
1150
1190
 
1151
1191
        s[p]->waitq = opq_alloc(ipmi_domain_get_os_hnd(domain));
1152
 
        if (!s[p]->waitq) {
1153
 
            rv = ENOMEM;
1154
 
            goto out_err;
1155
 
        }
 
1192
        if (!s[p]->waitq)
 
1193
            goto out_err_enomem;
1156
1194
 
1157
1195
        s[p]->handler_list = locked_list_alloc(ipmi_domain_get_os_hnd(domain));
1158
1196
        if (! s[p]->handler_list) {
1159
1197
            opq_destroy(s[p]->waitq);
1160
 
            rv = ENOMEM;
1161
 
            goto out_err;
 
1198
            goto out_err_enomem;
1162
1199
        }
1163
1200
 
1164
1201
        s[p]->destroyed = 0;
1168
1205
                                                   sdr.data[1] >> 4,
1169
1206
                                                   sdr.data[0],
1170
1207
                                                   &(s[p]->mc));
1171
 
        if (rv)
 
1208
        if (rv) {
 
1209
            ipmi_log(IPMI_LOG_WARNING,
 
1210
                     "%ssensor.c(get_sensors_from_sdrs):"
 
1211
                     " Could not create MC for SDR record %d, channel %d"
 
1212
                     " owner 0x%x: %d",
 
1213
                     MC_NAME(source_mc), i, sdr.data[1] >> 4, sdr.data[0], rv);
1172
1214
            goto out_err;
 
1215
        }
1173
1216
 
1174
1217
        share_count = 0;
1175
1218
        id_string_mod_type = 0;
1190
1233
        s[p]->entity_instance_logical = sdr.data[4] >> 7;
1191
1234
        s[p]->entity_instance = sdr.data[4] & 0x7f;
1192
1235
        if ((sdr.type == 1) || (sdr.type == 2)) {
 
1236
            /* If the lower bit is set, the owner is a system software
 
1237
               id and it cannot be read. */
 
1238
            s[p]->readable = (sdr.data[0] & 1) != 1;
 
1239
 
1193
1240
            s[p]->sensor_init_scanning = (sdr.data[5] >> 6) & 1;
1194
1241
            s[p]->sensor_init_events = (sdr.data[5] >> 5) & 1;
1195
1242
            s[p]->sensor_init_thresholds = (sdr.data[5] >> 4) & 1;
1254
1301
            s[p]->oem1 = sdr.data[41];
1255
1302
 
1256
1303
            str = sdr.data + 42;
1257
 
            rv = ipmi_get_device_string(&str, sdr.length-42,
1258
 
                                        s[p]->id, IPMI_STR_SDR_SEMANTICS, 0,
1259
 
                                        &s[p]->id_type, SENSOR_ID_LEN,
1260
 
                                        &s[p]->id_len);
1261
 
            if (rv)
1262
 
                goto out_err;
 
1304
            str_len = sdr.length - 42;
 
1305
 
1263
1306
            if (s[p]->entity)
1264
1307
                sensor_set_name(s[p]);
1265
1308
        } else if (sdr.type == 2) {
1274
1317
            s[p]->oem1 = sdr.data[25];
1275
1318
 
1276
1319
            str = sdr.data + 26;
1277
 
            rv = ipmi_get_device_string(&str, sdr.length-26,
1278
 
                                        s[p]->id, IPMI_STR_SDR_SEMANTICS, 0,
1279
 
                                        &s[p]->id_type, SENSOR_ID_LEN,
1280
 
                                        &s[p]->id_len);
1281
 
            if (rv)
1282
 
                goto out_err;
 
1320
            str_len = sdr.length - 26;
1283
1321
 
1284
1322
            share_count = sdr.data[18] & 0x0f;
1285
1323
            if (share_count == 0)
1288
1326
            entity_instance_incr = (sdr.data[19] >> 7) & 0x01;
1289
1327
            id_string_modifier_offset = sdr.data[19] & 0x7f;
1290
1328
        } else {
1291
 
            /* Event-only sensor */
 
1329
            /* Event-only sensor.  It is not readable. */
1292
1330
 
1293
1331
            s[p]->sensor_type = sdr.data[5];
1294
1332
            s[p]->event_reading_type = sdr.data[6];
1295
 
            s[p]->oem1 = sdr.data[10];
 
1333
            s[p]->oem1 = sdr.data[9];
1296
1334
 
1297
 
            str = sdr.data + 11;
1298
 
            rv = ipmi_get_device_string(&str, sdr.length-11,
1299
 
                                        s[p]->id, IPMI_STR_SDR_SEMANTICS, 0,
1300
 
                                        &s[p]->id_type, SENSOR_ID_LEN,
1301
 
                                        &s[p]->id_len);
1302
 
            if (rv)
1303
 
                goto out_err;
 
1335
            str = sdr.data + 10;
 
1336
            str_len = sdr.length - 10;
1304
1337
 
1305
1338
            share_count = sdr.data[7] & 0x0f;
1306
1339
            if (share_count == 0)
1310
1343
            id_string_modifier_offset = sdr.data[8] & 0x7f;
1311
1344
        }
1312
1345
 
 
1346
        rv = ipmi_get_device_string(&str, str_len,
 
1347
                                    s[p]->id, IPMI_STR_SDR_SEMANTICS, 0,
 
1348
                                    &s[p]->id_type, SENSOR_ID_LEN,
 
1349
                                    &s[p]->id_len);
 
1350
        if (rv) {
 
1351
            ipmi_log(IPMI_LOG_WARNING,
 
1352
                     "%ssensor.c(get_sensors_from_sdrs):"
 
1353
                     " Error getting device ID string from SDR record %d: %d",
 
1354
                     MC_NAME(source_mc), i, rv);
 
1355
            goto out_err;
 
1356
        }
 
1357
 
1313
1358
        if (share_count) {
1314
1359
            /* Duplicate the sensor records for each instance.  Go
1315
1360
               backwards to avoid destroying the first one until we
1323
1368
                       not necessary.  We still have to iterate the
1324
1369
                       first one to set its string name, though. */
1325
1370
                    s[p+j] = ipmi_mem_alloc(sizeof(ipmi_sensor_t));
1326
 
                    if (!s[p+j]) {
1327
 
                        rv = ENOMEM;
1328
 
                        goto out_err;
1329
 
                    }
 
1371
                    if (!s[p+j])
 
1372
                        goto out_err_enomem;
1330
1373
                    memcpy(s[p+j], s[p], sizeof(ipmi_sensor_t));
1331
1374
                    
1332
1375
                    /* In case of error */
1342
1385
                                                          &(s[p+j]->mc));
1343
1386
 
1344
1387
                    s[p+j]->waitq = opq_alloc(ipmi_domain_get_os_hnd(domain));
1345
 
                    if (!s[p+j]->waitq) {
1346
 
                        rv = ENOMEM;
1347
 
                        goto out_err;
1348
 
                    }
 
1388
                    if (!s[p+j]->waitq)
 
1389
                        goto out_err_enomem;
1349
1390
 
1350
1391
                    s[p+j]->handler_list
1351
1392
                        = locked_list_alloc(ipmi_domain_get_os_hnd(domain));
1352
 
                    if (! s[p+j]->handler_list) {
1353
 
                        rv = ENOMEM;
1354
 
                        goto out_err;
1355
 
                    }
 
1393
                    if (! s[p+j]->handler_list)
 
1394
                        goto out_err_enomem;
1356
1395
 
1357
1396
                    s[p+j]->num += j;
1358
1397
 
1406
1445
    *sensor_count = s_size;
1407
1446
    return 0;
1408
1447
 
 
1448
 out_err_enomem:
 
1449
    rv = ENOMEM;
 
1450
    ipmi_log(IPMI_LOG_WARNING,
 
1451
             "%ssensor.c(get_sensors_from_sdrs):"
 
1452
             " Out of memory while processing the SDRS.",
 
1453
             MC_NAME(source_mc));
1409
1454
 out_err:
1410
1455
    if (s) {
1411
1456
        for (i=0; i<s_size; i++)
2541
2586
}
2542
2587
 
2543
2588
int
 
2589
ipmi_sensor_get_is_readable(ipmi_sensor_t *sensor)
 
2590
{
 
2591
    CHECK_SENSOR_LOCK(sensor);
 
2592
 
 
2593
    return sensor->readable;
 
2594
}
 
2595
 
 
2596
int
2544
2597
ipmi_sensor_get_analog_data_format(ipmi_sensor_t *sensor)
2545
2598
{
2546
2599
    CHECK_SENSOR_LOCK(sensor);
2915
2968
}
2916
2969
 
2917
2970
void
 
2971
ipmi_sensor_set_is_readable(ipmi_sensor_t *sensor,
 
2972
                            int           readable)
 
2973
{
 
2974
    sensor->readable = readable != 0;
 
2975
}
 
2976
 
 
2977
void
2918
2978
ipmi_sensor_set_analog_data_format(ipmi_sensor_t *sensor,
2919
2979
                                   int           analog_data_format)
2920
2980
{
4636
4696
    if (sensor->event_reading_type != IPMI_EVENT_READING_TYPE_THRESHOLD)
4637
4697
        /* Not a threshold sensor, it doesn't have readings. */
4638
4698
        return ENOSYS;
 
4699
    if (!sensor->readable)
 
4700
        return ENOSYS;
4639
4701
 
4640
4702
    info = ipmi_mem_alloc(sizeof(*info));
4641
4703
    if (!info)
4738
4800
    if (sensor->event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD)
4739
4801
        /* A threshold sensor, it doesn't have states. */
4740
4802
        return ENOSYS;
 
4803
    if (!sensor->readable)
 
4804
        return ENOSYS;
4741
4805
 
4742
4806
    info = ipmi_mem_alloc(sizeof(*info));
4743
4807
    if (!info)