/* -*- linux-c -*- * * (C) Copyright IBM Corp. 2003, 2005 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This * file and program are licensed under a BSD style license. See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Author(s): * Renier Morales */ #include #include #include typedef struct { SaHpiRptEntryT rpt_entry; int owndata; void *data; /* private data for the owner of the RPTable */ SaHpiUint32T update_count; /* RDR Update counter */ GSList *rdrlist; /* Contains RDRecords for sequence lookups */ GHashTable *rdrtable; /* Contains RDRecords for fast RecordId lookups */ } RPTEntry; typedef struct { SaHpiRdrT rdr; int owndata; void *data; /* private data for the owner of the rpt entry. */ } RDRecord; static RPTEntry *get_rptentry_by_rid(RPTable *table, SaHpiResourceIdT rid) { GSList *rptnode = NULL; RPTEntry *rptentry = NULL; if (!table) { return NULL; } if (!(table->rptlist)) { /*DBG("Info: RPT is empty.");*/ return NULL; } if (rid == SAHPI_FIRST_ENTRY) { rptentry = (RPTEntry *) (table->rptlist->data); } else { rptnode = (GSList *)g_hash_table_lookup(table->rptable, &rid); rptentry = rptnode ? (RPTEntry *)rptnode->data : NULL; } return rptentry; } static GSList *get_rptnode_by_rid(RPTable *table, SaHpiResourceIdT rid) { GSList *rptnode = NULL; if (!table) { return NULL; } if (!(table->rptlist)) { /*DBG("Info: RPT is empty.");*/ return NULL; } if (rid == SAHPI_FIRST_ENTRY) { rptnode = (GSList *) (table->rptlist); } else { rptnode = (GSList *)g_hash_table_lookup(table->rptable, &rid); } return rptnode; } static RDRecord *get_rdrecord_by_id(RPTEntry *rptentry, SaHpiEntryIdT id) { GSList *rdrnode = NULL; RDRecord *rdrecord = NULL; if (!rptentry) { return NULL; } if (!rptentry->rdrlist) { /*DBG("Info: RDR repository is empty.");*/ return NULL; } if (id == SAHPI_FIRST_ENTRY) { rdrecord = (RDRecord *) (rptentry->rdrlist->data); } else { rdrnode = (GSList *)g_hash_table_lookup(rptentry->rdrtable, &id); rdrecord = rdrnode ? (RDRecord *)rdrnode->data : NULL; } return rdrecord; } static GSList *get_rdrnode_by_id(RPTEntry *rptentry, SaHpiEntryIdT id) { GSList *rdrnode = NULL; if (!rptentry) { return NULL; } if (!rptentry->rdrlist) { /*DBG("Info: RPT is empty.");*/ return NULL; } if (id == SAHPI_FIRST_ENTRY) { rdrnode = (GSList *) (rptentry->rdrlist); } else { rdrnode = (GSList *)g_hash_table_lookup(rptentry->rdrtable, &id); } return rdrnode; } static int check_instrument_id(SaHpiRptEntryT *rptentry, SaHpiRdrT *rdr) { int result = 0; static const SaHpiInstrumentIdT SENSOR_AGGREGATE_MAX = 0x0000010F; switch (rdr->RdrType) { case SAHPI_SENSOR_RDR: if (rdr->RdrTypeUnion.SensorRec.Num >= SAHPI_STANDARD_SENSOR_MIN && rdr->RdrTypeUnion.SensorRec.Num <= SAHPI_STANDARD_SENSOR_MAX) { if (rdr->RdrTypeUnion.SensorRec.Num > SENSOR_AGGREGATE_MAX) { result = -1; } else if (rptentry->ResourceCapabilities & SAHPI_CAPABILITY_AGGREGATE_STATUS) { result = 0; } else { result = -1; } } else { result = 0; } break; default: result = 0; } return result; } static void update_rptable(RPTable *table) { if (!table) { return; } oh_gettimeofday(&table->update_timestamp); table->update_count++; } /** * oh_get_rdr_uid * @type: type of rdr * @num: id number of the RDR unique withing the RDR type for that resource * * Helper function to derive the Record id of an rdr from its @type and @num * * Returns: a derived Record Id used to identify RDRs within Resources */ SaHpiEntryIdT oh_get_rdr_uid(SaHpiRdrTypeT type, SaHpiInstrumentIdT num) { SaHpiEntryIdT uid; uid = ((SaHpiEntryIdT)type) << 16; uid = uid + (SaHpiEntryIdT)num; return uid; } SaHpiInstrumentIdT oh_get_rdr_num(SaHpiEntryIdT rdrid) { return rdrid & 0x0000ffff; } /** * oh_get_instrument_id * @rdr: RDR * * Helper function to derive the Instrument Id of the rdr * * Returns: an instrument id or zero */ SaHpiInstrumentIdT oh_get_instrument_id(const SaHpiRdrT *rdr) { SaHpiInstrumentIdT num = 0; switch (rdr->RdrType) { case SAHPI_CTRL_RDR: num = rdr->RdrTypeUnion.CtrlRec.Num; break; case SAHPI_SENSOR_RDR: num = rdr->RdrTypeUnion.SensorRec.Num; break; case SAHPI_INVENTORY_RDR: num = rdr->RdrTypeUnion.InventoryRec.IdrId; break; case SAHPI_WATCHDOG_RDR: num = rdr->RdrTypeUnion.WatchdogRec.WatchdogNum; break; case SAHPI_ANNUNCIATOR_RDR: num = rdr->RdrTypeUnion.AnnunciatorRec.AnnunciatorNum; break; case SAHPI_DIMI_RDR: num = rdr->RdrTypeUnion.DimiRec.DimiNum; break; case SAHPI_FUMI_RDR: num = rdr->RdrTypeUnion.FumiRec.Num; break; default: num = 0; } return num; } /** * General RPT calls **/ /** * oh_init_rpt * @table: Pointer to RPTable structure to be initialized. * * * Returns: SA_OK on success Or minus SA_OK on error. **/ SaErrorT oh_init_rpt(RPTable *table) { if (!table) { return SA_ERR_HPI_INVALID_PARAMS; } table->update_timestamp = SAHPI_TIME_UNSPECIFIED; table->update_count = 0; table->rptlist = NULL; table->rptable = NULL; return SA_OK; } /** * oh_flush_rpt * @table: Pointer to the RPT to flush. * * Cleans RPT from all entries and RDRs and frees the memory * associated with them. * * Returns: SA_OK on success Or minus SA_OK on error. **/ SaErrorT oh_flush_rpt(RPTable *table) { SaHpiRptEntryT *tmp_entry; while ((tmp_entry = oh_get_resource_by_id(table, SAHPI_FIRST_ENTRY)) != NULL) { oh_remove_resource(table, SAHPI_FIRST_ENTRY); } return SA_OK; } /** * rpt_diff * @cur_rpt: IN. Pointer to RPTable that represents the current state of resources * and rdrs. * @new_rpt: IN. Pointer to RPTable that contains rpt entries and rdrs just recently * discovered. * @res_new: OUT. List of new or changed rpt entries * @rdr_new: OUT. List of new or changed rdrs * @res_gone: OUT. List of old and not present resources. * @rdr_gone: OUT. List of old and not present rdrs. * * Extracts from current the resources and rdrs that are not found * in new and puts them in res_gone and rdr_gone. Also, puts in res_new and rdr_new * the resources and rdrs that are not already in current Or that are not identical * to the ones in current. * * Returns: SA_ERR_HPI_INVALID_PARAMS if any argument is NULL, otherwise SA_OK. **/ SaErrorT rpt_diff(RPTable *cur_rpt, RPTable *new_rpt, GSList **res_new, GSList **rdr_new, GSList **res_gone, GSList **rdr_gone) { SaHpiRptEntryT *res = NULL; if (!cur_rpt || !new_rpt || !res_new || !rdr_new || !res_gone || !rdr_gone) return SA_ERR_HPI_INVALID_PARAMS; /* Look for absent resources and rdrs */ for (res = oh_get_resource_by_id(cur_rpt, SAHPI_FIRST_ENTRY); res != NULL; res = oh_get_resource_next(cur_rpt, res->ResourceId)) { SaHpiRptEntryT *tmp_res = oh_get_resource_by_id(new_rpt, res->ResourceId); if (tmp_res == NULL) *res_gone = g_slist_append(*res_gone, (gpointer)res); else { SaHpiRdrT *rdr = NULL; for (rdr = oh_get_rdr_by_id(cur_rpt, res->ResourceId, SAHPI_FIRST_ENTRY); rdr != NULL; rdr = oh_get_rdr_next(cur_rpt, res->ResourceId, rdr->RecordId)) { SaHpiRdrT *tmp_rdr = oh_get_rdr_by_id(new_rpt, res->ResourceId, rdr->RecordId); if (tmp_rdr == NULL) *rdr_gone = g_slist_append(*rdr_gone, (gpointer)rdr); } } } /* Look for new resources and rdrs*/ for (res = oh_get_resource_by_id(new_rpt, SAHPI_FIRST_ENTRY); res != NULL; res = oh_get_resource_next(new_rpt, res->ResourceId)) { SaHpiRptEntryT *tmp_res = oh_get_resource_by_id(cur_rpt, res->ResourceId); SaHpiRdrT *rdr = NULL; if (tmp_res == NULL || memcmp(res, tmp_res, sizeof(SaHpiRptEntryT))) { *res_new = g_slist_append(*res_new, (gpointer)res); } for (rdr = oh_get_rdr_by_id(new_rpt, res->ResourceId, SAHPI_FIRST_ENTRY); rdr != NULL; rdr = oh_get_rdr_next(new_rpt, res->ResourceId, rdr->RecordId)) { SaHpiRdrT *tmp_rdr = NULL; if (tmp_res != NULL) tmp_rdr = oh_get_rdr_by_id(cur_rpt, res->ResourceId, rdr->RecordId); if (tmp_rdr == NULL || memcmp(rdr, tmp_rdr, sizeof(SaHpiRdrT))) *rdr_new = g_slist_append(*rdr_new, (gpointer)rdr); } } return SA_OK; } /** * oh_get_rpt_info * @table: pointer to RPT * @update_count: pointer of where to place the rpt's update count * @update_timestamp: pointer of where to place the rpt's update timestamp * * Returns: SA_OK on success Or minus SA_OK on error. **/ SaErrorT oh_get_rpt_info(RPTable *table, SaHpiUint32T *update_count, SaHpiTimeT *update_timestamp) { if (!table || !update_count || !update_timestamp) { return SA_ERR_HPI_INVALID_PARAMS; } *update_count = table->update_count; *update_timestamp = table->update_timestamp; return SA_OK; } /** * Resource interface functions */ /** * oh_add_resource * @table: Pointer to the RPT to which the RPT entry will be added. * @entry: The RPT entry (resource) to be added to the RPT. * @data: Pointer to private data for storing along with the RPT entry. * @owndata: boolean flag. true (%KEEP_RPT_DATA) to tell the interface *not* * to free the data when the resource is removed. false (%FREE_RPT_DATA) to tell * the interface to free the data when the resource is removed. * * Add a RPT entry to the RPT along with some private data. * If an RPT entry with the same resource id exists int the RPT, it will be * overlayed with the new RPT entry. Also, this function will assign the * resource id as its entry id since it is expected to be unique for the table. * The update count and timestamp will not be updated if the entry being added * already existed in the table and was the same. * * Returns: SA_OK on success Or minus SA_OK on error. SA_ERR_HPI_INVALID_PARAMS will * be returned if @table is NULL, @entry is NULL, ResourceId in @entry equals * SAHPI_FIRST_ENTRY, ResourceId in @entry equals SAHPI_UNSPECIFIED_RESOURCE_ID, * or ResourceEntity in @entry has a malformed entity path (look at the * entity path utils documentation). **/ SaErrorT oh_add_resource(RPTable *table, SaHpiRptEntryT *entry, void *data, int owndata) { RPTEntry *rptentry; int update_info = 0; if (!table) { return SA_ERR_HPI_INVALID_PARAMS; } else if (!entry) { return SA_ERR_HPI_INVALID_PARAMS; } else if (entry->ResourceId == SAHPI_FIRST_ENTRY) { return SA_ERR_HPI_INVALID_PARAMS; } else if (entry->ResourceId == SAHPI_UNSPECIFIED_RESOURCE_ID) { return SA_ERR_HPI_INVALID_PARAMS; } else if (!oh_valid_ep(&(entry->ResourceEntity))) { return SA_ERR_HPI_INVALID_PARAMS; } entry->EntryId = entry->ResourceId; /* Check to see if the entry is in the RPTable already */ rptentry = get_rptentry_by_rid(table, entry->ResourceId); /* If not, create new RPTEntry */ if (!rptentry) { rptentry = g_new0(RPTEntry, 1); if (!rptentry) { return SA_ERR_HPI_OUT_OF_MEMORY; } update_info = 1; /* Have a new changed entry */ /* Put new RPTEntry in RPTable */ table->rptlist = g_slist_append(table->rptlist, (gpointer)rptentry); /* Add to rpt hash table */ if (!table->rptable) /* Create hash table if it doesn't exist */ table->rptable = g_hash_table_new(g_int_hash, g_int_equal); rptentry->rpt_entry.EntryId = entry->ResourceId; g_hash_table_insert(table->rptable, &(rptentry->rpt_entry.EntryId), g_slist_last(table->rptlist)); } /* Else, modify existing RPTEntry */ if (rptentry->data && rptentry->data != data && !rptentry->owndata) g_free(rptentry->data); rptentry->data = data; rptentry->owndata = owndata; /* Check if we really have a new/changed entry */ if (update_info || memcmp(entry, &(rptentry->rpt_entry), sizeof(SaHpiRptEntryT))) { update_info = 1; rptentry->rpt_entry = *entry; } if (update_info) update_rptable(table); return SA_OK; } /** * oh_remove_resource * @table: Pointer to the RPT from which an RPT entry will be removed. * @rid: Resource id of the RPT entry to be removed. * * Remove a resource from the RPT. If the @rid is * %SAHPI_FIRST_ENTRY, the first RPT entry in the table will be removed. * The void data will be freed if @owndata was false (%FREE_RPT_DATA) when adding * the resource, otherwise if @owndata was true (%KEEP_RPT_DATA) it will not be freed. * * Returns: SA_OK on success Or minus SA_OK on error. **/ SaErrorT oh_remove_resource(RPTable *table, SaHpiResourceIdT rid) { RPTEntry *rptentry; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { return SA_ERR_HPI_NOT_PRESENT; } else { SaHpiRdrT *tmp_rdr; /* Remove all RDRs for the resource first */ while ((tmp_rdr = oh_get_rdr_by_id(table, rid, SAHPI_FIRST_ENTRY)) != NULL) { oh_remove_rdr(table, rid, SAHPI_FIRST_ENTRY); } /* then remove the resource itself. */ table->rptlist = g_slist_remove(table->rptlist, (gpointer)rptentry); if (!rptentry->owndata) g_free(rptentry->data); g_hash_table_remove(table->rptable, &(rptentry->rpt_entry.EntryId)); g_free((gpointer)rptentry); if (!table->rptlist) { g_hash_table_destroy(table->rptable); table->rptable = NULL; } } update_rptable(table); return SA_OK; } /** * oh_get_resource_data * @table: Pointer to the RPT for looking up the RPT entry's private data. * @rid: Resource id of the RPT entry that holds the private data. * * Get the private data for a RPT entry. If the @rid is * %SAHPI_FIRST_ENTRY, the first RPT entry's data in the table will be returned. * * Returns: A void pointer to the private data for the RPT entry requested, or NULL * if the RPT entry was not found or the table was a NULL pointer. **/ void *oh_get_resource_data(RPTable *table, SaHpiResourceIdT rid) { RPTEntry *rptentry; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { /*DBG("Warning: RPT entry not found. Returning NULL.");*/ return NULL; } return rptentry->data; } /** * oh_get_resource_by_id * @table: Pointer to the RPT for looking up the RPT entry. * @rid: Resource id of the RPT entry to be looked up. * * Get a RPT entry from the RPT by using the resource id. * If @rid is %SAHPI_FIRST_ENTRY, the first RPT entry in the table will be returned. * * Returns: * Pointer to the RPT entry found or NULL if an RPT entry by that * id was not found or the table was a NULL pointer. **/ SaHpiRptEntryT *oh_get_resource_by_id(RPTable *table, SaHpiResourceIdT rid) { RPTEntry *rptentry; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { /*DBG("Warning: RPT entry not found. Returning NULL.");*/ return NULL; } return &(rptentry->rpt_entry); } /** * oh_get_resource_by_ep * @table: Pointer to the RPT for looking up the RPT entry. * @ep: Entity path of the RPT entry to be looked up. * * Get a RPT entry from the RPT by using the entity path. * * Returns: * Pointer to the RPT entry found or NULL if an RPT entry by that * entity path was not found or the table was a NULL pointer. **/ SaHpiRptEntryT *oh_get_resource_by_ep(RPTable *table, SaHpiEntityPathT *ep) { RPTEntry *rptentry = NULL; GSList *node = NULL; SaHpiResourceIdT rid = 0; if (!table) { return NULL; } /* Check the uid database first */ rid = oh_uid_is_initialized() ? oh_uid_lookup(ep) : 0; if (rid > 0) { /* Found it in uid database */ return oh_get_resource_by_id(table, rid); } else { DBG("Didn't find the EP in the Uid table so " "looking manually in the RPTable"); } for (node = table->rptlist; node != NULL; node = node->next) { rptentry = (RPTEntry *) node->data; if (oh_cmp_ep(&(rptentry->rpt_entry.ResourceEntity), ep)) break; else rptentry = NULL; } if (!rptentry) { /*DBG("Warning: RPT entry not found. Returning NULL.");*/ return NULL; } return &(rptentry->rpt_entry); } /** * oh_get_resource_next * @table: Pointer to the RPT for looking up the RPT entry. * @rid_prev: Resource id of the RPT entry previous to the one being looked up. * * Get the RPT entry next to the specified RPT entry * from the RPT. If @rid_prev is %SAHPI_FIRST_ENTRY, the first RPT entry * in the table will be returned. * * Returns: * Pointer to the RPT entry found or NULL if the previous RPT entry by that * id was not found or the table was a NULL pointer. **/ SaHpiRptEntryT *oh_get_resource_next(RPTable *table, SaHpiResourceIdT rid_prev) { RPTEntry *rptentry = NULL; GSList *rptnode = NULL; if (rid_prev == SAHPI_FIRST_ENTRY) { rptentry = get_rptentry_by_rid(table, rid_prev); } else { rptnode = get_rptnode_by_rid(table, rid_prev); if (rptnode && rptnode->next) { rptentry = (RPTEntry *)rptnode->next->data; } } return rptentry ? &(rptentry->rpt_entry) : NULL; } /** * oh_get_rdr_update_count * @table: Pointer to the RPT for looking up the RPT entry. * @rid: Resource id of the RPT entry to be looked up. * @update_count: pointer of where to place the rdr update count * * Get a RDR Repository Update Counter for the resource using the resource id. * * Returns: * Returns: SA_OK on success. * Will return SA_ERR_HPI_INVALID_PARAMS if update_count is NULL. * Will return SA_ERR_HPI_NOT_PRESENT if there is no resource * with specified rid in RPT. **/ SaErrorT oh_get_rdr_update_count(RPTable *table, SaHpiResourceIdT rid, SaHpiUint32T *update_count) { RPTEntry *rptentry = get_rptentry_by_rid(table, rid); if ( !rptentry ) { return SA_ERR_HPI_NOT_PRESENT; } if ( !update_count ) { return SA_ERR_HPI_INVALID_PARAMS; } *update_count = rptentry->update_count; return SA_OK; } /** * RDR interface functions */ /** * oh_add_rdr * @table: Pointer to RPT table containig the RPT entry to which the RDR will belong. * @rid: Id of the RPT entry that will own the RDR to be added. * @rdr: RDR to be added to an RPT entry's RDR repository. * @data: Pointer to private data belonging to the RDR that is being added. * @owndata: boolean flag. true (%KEEP_RPT_DATA) to tell the interface *not* * to free the data when the rdr is removed. false (%FREE_RPT_DATA) to tell * the interface to free the data when the rdr is removed. * * Add an RDR to a RPT entry's RDR repository. * If an RDR is found with the same record id as the one being added, the RDR being * added will overlay the existing one. Also, a unique record id will be assigned * to it based on the RDR type and its type's numeric id. * All rdr interface funtions, except oh_add_rdr() will act in the context of * the first RPT entry in the table, if @rid is %SAHPI_FIRST_ENTRY. * * Returns: SA_OK on success Or minus SA_OK on error. Will return * SA_ERR_HPI_INVALID_PARAMS if instrument id is invalid. An invalid * intrument id for a sensor is in the range of 0x100-0x1FF. An aggregate type * of sensor can have its instrument id in the range of 0x100-0x10F, but * the resource must have the aggregate sensor capabilitiy bit set. **/ SaErrorT oh_add_rdr(RPTable *table, SaHpiResourceIdT rid, SaHpiRdrT *rdr, void *data, int owndata) { RPTEntry *rptentry; RDRecord *rdrecord; SaHpiInstrumentIdT instr_id; if (!rdr) { return SA_ERR_HPI_INVALID_PARAMS; } rptentry = get_rptentry_by_rid(table, rid); if (!rptentry){ return SA_ERR_HPI_NOT_PRESENT; } if (check_instrument_id(&(rptentry->rpt_entry), rdr)) { CRIT("Invalid instrument id found in RDR."); return SA_ERR_HPI_INVALID_PARAMS; } instr_id = oh_get_instrument_id(rdr); /* Form correct RecordId. */ rdr->RecordId = oh_get_rdr_uid(rdr->RdrType, instr_id); /* Check if record exists */ rdrecord = get_rdrecord_by_id(rptentry, rdr->RecordId); /* If not, create new rdr */ if (!rdrecord) { rdrecord = g_new0(RDRecord, 1); if (!rdrecord) { return SA_ERR_HPI_OUT_OF_MEMORY; } /* Put new rdrecord in rdr repository */ rptentry->rdrlist = g_slist_append(rptentry->rdrlist, (gpointer)rdrecord); /* Create rdr hash table if first rdr here */ if (!rptentry->rdrtable) rptentry->rdrtable = g_hash_table_new(g_int_hash, g_int_equal); rdrecord->rdr.RecordId = rdr->RecordId; g_hash_table_insert(rptentry->rdrtable, &(rdrecord->rdr.RecordId), g_slist_last(rptentry->rdrlist)); } /* Else, modify existing rdrecord */ if (rdrecord->data && rdrecord->data != data && !rdrecord->owndata) g_free(rdrecord->data); rdrecord->data = data; rdrecord->owndata = owndata; rdrecord->rdr = *rdr; ++rptentry->update_count; return SA_OK; } /** * oh_remove_rdr * @table: Pointer to RPT table containig the RPT entry from which the RDR will * be removed. * @rid: Id of the RPT entry from which the RDR will be removed. * @rdrid: Record id of the RDR to remove. * * * Remove an RDR from a RPT entry's RDR repository. * If @rdrid is %SAHPI_FIRST_ENTRY, the first RDR in the repository will be removed. * If @owndata was set to false (%FREE_RPT_DATA) on the rdr when it was added, * the data will be freed, otherwise if it was set to true (%KEEP_RPT_DATA), * it will not be freed. * All rdr interface funtions, except oh_add_rdr() will act in the context of * the first RPT entry in the table, if @rid is %SAHPI_FIRST_ENTRY. * * Returns: SA_OK on success Or minus SA_OK on error. **/ SaErrorT oh_remove_rdr(RPTable *table, SaHpiResourceIdT rid, SaHpiEntryIdT rdrid) { RPTEntry *rptentry; RDRecord *rdrecord; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { return SA_ERR_HPI_NOT_PRESENT; } rdrecord = get_rdrecord_by_id(rptentry, rdrid); if (!rdrecord) { return SA_ERR_HPI_NOT_PRESENT; } else { rptentry->rdrlist = g_slist_remove(rptentry->rdrlist, (gpointer)rdrecord); if (!rdrecord->owndata) g_free(rdrecord->data); g_hash_table_remove(rptentry->rdrtable, &(rdrecord->rdr.RecordId)); g_free((gpointer)rdrecord); if (!rptentry->rdrlist) { g_hash_table_destroy(rptentry->rdrtable); rptentry->rdrtable = NULL; } ++rptentry->update_count; } return SA_OK; } /** * oh_get_rdr_data * @table: Pointer to RPT table containig the RPT entry from which the RDR's data * will be read. * @rid: Id of the RPT entry from which the RDR's data will be read. * @rdrid: Record id of the RDR to read data from. * * * Get the private data associated to an RDR. * If @rdrid is %SAHPI_FIRST_ENTRY, the first RDR's data in the repository will be returned. * All rdr interface funtions, except oh_add_rdr() will act in the context of * the first RPT entry in the table, if @rid is %SAHPI_FIRST_ENTRY. * * Returns: A void pointer to the RDR data, or NULL if no data for that RDR was found or * the table pointer is NULL. **/ void *oh_get_rdr_data(RPTable *table, SaHpiResourceIdT rid, SaHpiEntryIdT rdrid) { RPTEntry *rptentry; RDRecord *rdrecord; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { return NULL; /* No resource found by that id */ } rdrecord = get_rdrecord_by_id(rptentry, rdrid); if (!rdrecord) { /*DBG("Warning: RDR not found. Returning NULL.");*/ return NULL; } return rdrecord->data; } /** * oh_get_rdr_by_id * @table: Pointer to RPT table containig the RPT entry tha has the RDR * being looked up. * @rid: Id of the RPT entry containing the RDR being looked up. * @rdrid: Record id of the RDR being looked up. * * Get a reference to an RDR by its record id. * If @rdrid is %SAHPI_FIRST_ENTRY, the first RDR in the repository will be returned. * All rdr interface funtions, except oh_add_rdr() will act in the context of * the first RPT entry in the table, if @rid is %SAHPI_FIRST_ENTRY. * * Returns: * Reference to the RDR looked up or NULL if no RDR was found. **/ SaHpiRdrT *oh_get_rdr_by_id(RPTable *table, SaHpiResourceIdT rid, SaHpiEntryIdT rdrid) { RPTEntry *rptentry; RDRecord *rdrecord; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { return NULL; /* No resource found by that id */ } rdrecord = get_rdrecord_by_id(rptentry, rdrid); if (!rdrecord) { /*DBG("Warning: RDR not found. Returning NULL.");*/ return NULL; } return &(rdrecord->rdr); } /** * oh_get_rdr_by_type * @table: Pointer to RPT table containig the RPT entry tha has the RDR * being looked up. * @rid: Id of the RPT entry containing the RDR being looked up. * @type: RDR Type of the RDR being looked up. * @num: RDR id within the RDR type for the specified RPT entry. * * Get a reference to an RDR by its type and number. * All rdr interface funtions, except oh_add_rdr() will act in the context of * the first RPT entry in the table, if @rid is %SAHPI_FIRST_ENTRY. * * Returns: * Reference to the RDR looked up or NULL if no RDR was found. **/ SaHpiRdrT *oh_get_rdr_by_type(RPTable *table, SaHpiResourceIdT rid, SaHpiRdrTypeT type, SaHpiInstrumentIdT num) { RPTEntry *rptentry = NULL; RDRecord *rdrecord = NULL; SaHpiEntryIdT rdr_uid; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { return NULL; /* No resource found by that id */ } /* Get rdr_uid from type/num combination */ rdr_uid = oh_get_rdr_uid(type, num); rdrecord = get_rdrecord_by_id(rptentry, rdr_uid); if (!rdrecord) { /*DBG("Warning: RDR not found. Returning NULL.");*/ return NULL; } return &(rdrecord->rdr); } /** * oh_get_rdr_next * @table: Pointer to the RPT containing the RPT entry to look up the RDR in. * @rid: Id of the RPT entry containing the RDR being looked up. * @rdrid_prev: Record id of the RDR previous to the one being looked up, relative * to the specified RPT entry. * * Get the RDR next to the specified RDR in the specified * RPT entry's repository. If @rdrid_prev is %SAHPI_FIRST_ENTRY, the first RDR * in the repository will be returned. * All rdr interface funtions, except oh_add_rdr() will act in the context of * the first RPT entry in the table, if @rid is %SAHPI_FIRST_ENTRY. * * Returns: * Pointer to the RDR found or NULL if the previous RDR by that * id was not found. If the @rdrid_prev was %SAHPI_FIRST_ENTRY, the first RDR in the list * will be returned. **/ SaHpiRdrT *oh_get_rdr_next(RPTable *table, SaHpiResourceIdT rid, SaHpiEntryIdT rdrid_prev) { RPTEntry *rptentry = NULL; RDRecord *rdrecord = NULL; GSList *rdrnode = NULL; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { return NULL; /* No resource found by that id */ } if (rdrid_prev == SAHPI_FIRST_ENTRY) { rdrecord = get_rdrecord_by_id(rptentry, rdrid_prev); } else { rdrnode = get_rdrnode_by_id(rptentry, rdrid_prev); if (rdrnode && rdrnode->next) { rdrecord = (RDRecord *)rdrnode->next->data; } } return rdrecord ? &(rdrecord->rdr) : NULL; } SaHpiRdrT *oh_get_rdr_by_type_first(RPTable *table, SaHpiResourceIdT rid, SaHpiRdrTypeT type) { RPTEntry *rptentry = NULL; RDRecord *rdrecord = NULL; GSList *node = NULL; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { return NULL; /* No resource found by that id */ } /* Get first RDR matching the type */ for (node = rptentry->rdrlist; node; node = node->next) { RDRecord *temp = (RDRecord *)node->data; if (temp->rdr.RdrType == type) { rdrecord = temp; break; } } if (!rdrecord) return NULL; return &(rdrecord->rdr); } SaHpiRdrT *oh_get_rdr_by_type_next(RPTable *table, SaHpiResourceIdT rid, SaHpiRdrTypeT type, SaHpiInstrumentIdT num) { RPTEntry *rptentry = NULL; RDRecord *rdrecord = NULL; GSList *node = NULL; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { return NULL; /* No resource found by that id */ } /* Get rdr_uid from type/num combination */ node = get_rdrnode_by_id(rptentry, oh_get_rdr_uid(type, num)); if (!node) return NULL; for (node = node->next; node; node = node->next) { RDRecord *temp = (RDRecord *)node->data; if (temp->rdr.RdrType == type) { rdrecord = temp; break; } } if (!rdrecord) return NULL; return &(rdrecord->rdr); }