ipmi_sdr_find_sdr_byentity(struct ipmi_intf *intf, struct entity_id *entity)
{
	struct sdr_get_rs *header;
	struct sdr_record_list *e;
	struct sdr_record_list *head;

	if (!sdr_list_itr) {
		sdr_list_itr = ipmi_sdr_start(intf, 0);
		if (!sdr_list_itr) {
			lprintf(LOG_ERR, "Unable to open SDR for reading");
			return NULL;
		}
	}

	head = malloc(sizeof (struct sdr_record_list));
	if (!head) {
		lprintf(LOG_ERR, "ipmitool: malloc failure");
		return NULL;
	}
	memset(head, 0, sizeof (struct sdr_record_list));

	/* check what we've already read */
	for (e = sdr_list_head; e; e = e->next) {
		switch (e->type) {
		case SDR_RECORD_TYPE_FULL_SENSOR:
		case SDR_RECORD_TYPE_COMPACT_SENSOR:
			if (e->record.common->entity.id == entity->id &&
			    (entity->instance == 0x7f ||
			     e->record.common->entity.instance ==
			     entity->instance))
				__sdr_list_add(head, e);
			break;
		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
			if (e->record.eventonly->entity.id == entity->id &&
			    (entity->instance == 0x7f ||
			     e->record.eventonly->entity.instance ==
			     entity->instance))
				__sdr_list_add(head, e);
			break;
		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
			if (e->record.genloc->entity.id == entity->id &&
			    (entity->instance == 0x7f ||
			     e->record.genloc->entity.instance ==
			     entity->instance))
				__sdr_list_add(head, e);
			break;
		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
			if (e->record.fruloc->entity.id == entity->id &&
			    (entity->instance == 0x7f ||
			     e->record.fruloc->entity.instance ==
			     entity->instance))
				__sdr_list_add(head, e);
			break;
		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
			if (e->record.mcloc->entity.id == entity->id &&
			    (entity->instance == 0x7f ||
			     e->record.mcloc->entity.instance ==
			     entity->instance))
				__sdr_list_add(head, e);
			break;
		case SDR_RECORD_TYPE_ENTITY_ASSOC:
			if (e->record.entassoc->entity.id == entity->id &&
			    (entity->instance == 0x7f ||
			     e->record.entassoc->entity.instance ==
			     entity->instance))
				__sdr_list_add(head, e);
			break;
		}
	}

	/* now keep looking */
	while ((header = ipmi_sdr_get_next_header(intf, sdr_list_itr))) {
		uint8_t *rec;
		struct sdr_record_list *sdrr;

		sdrr = malloc(sizeof (struct sdr_record_list));
		if (!sdrr) {
			lprintf(LOG_ERR, "ipmitool: malloc failure");
			break;
		}
		memset(sdrr, 0, sizeof (struct sdr_record_list));
		sdrr->id = header->id;
		sdrr->type = header->type;

		rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
		if (!rec) {
			if (sdrr) {
				free(sdrr);
				sdrr = NULL;
			}
			continue;
		}

		switch (header->type) {
		case SDR_RECORD_TYPE_FULL_SENSOR:
		case SDR_RECORD_TYPE_COMPACT_SENSOR:
			sdrr->record.common =
			    (struct sdr_record_common_sensor *) rec;
			if (sdrr->record.common->entity.id == entity->id
			    && (entity->instance == 0x7f
				|| sdrr->record.common->entity.instance ==
				entity->instance))
				__sdr_list_add(head, sdrr);
			break;
		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
			sdrr->record.eventonly =
			    (struct sdr_record_eventonly_sensor *) rec;
			if (sdrr->record.eventonly->entity.id == entity->id
			    && (entity->instance == 0x7f
				|| sdrr->record.eventonly->entity.instance ==
				entity->instance))
				__sdr_list_add(head, sdrr);
			break;
		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
			sdrr->record.genloc =
			    (struct sdr_record_generic_locator *) rec;
			if (sdrr->record.genloc->entity.id == entity->id
			    && (entity->instance == 0x7f
				|| sdrr->record.genloc->entity.instance ==
				entity->instance))
				__sdr_list_add(head, sdrr);
			break;
		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
			sdrr->record.fruloc =
			    (struct sdr_record_fru_locator *) rec;
			if (sdrr->record.fruloc->entity.id == entity->id
			    && (entity->instance == 0x7f
				|| sdrr->record.fruloc->entity.instance ==
				entity->instance))
				__sdr_list_add(head, sdrr);
			break;
		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
			sdrr->record.mcloc =
			    (struct sdr_record_mc_locator *) rec;
			if (sdrr->record.mcloc->entity.id == entity->id
			    && (entity->instance == 0x7f
				|| sdrr->record.mcloc->entity.instance ==
				entity->instance))
				__sdr_list_add(head, sdrr);
			break;
		case SDR_RECORD_TYPE_ENTITY_ASSOC:
			sdrr->record.entassoc =
			    (struct sdr_record_entity_assoc *) rec;
			if (sdrr->record.entassoc->entity.id == entity->id
			    && (entity->instance == 0x7f
				|| sdrr->record.entassoc->entity.instance ==
				entity->instance))
				__sdr_list_add(head, sdrr);
			break;
		default:
			free(rec);
			rec = NULL;
			if (sdrr) {
				free(sdrr);
				sdrr = NULL;
			}
			continue;
		}

		/* add to global record list */
		if (!sdr_list_head)
			sdr_list_head = sdrr;
		else
			sdr_list_tail->next = sdrr;

		sdr_list_tail = sdrr;
	}

	return head;
}