fru_area_print_multirec(struct ipmi_intf * intf, struct fru_info * fru,
			uint8_t id, uint32_t offset)
{
	uint8_t * fru_data;
	struct fru_multirec_header * h;
	struct fru_multirec_powersupply * ps;
	struct fru_multirec_dcoutput * dc;
	struct fru_multirec_dcload * dl;
	uint16_t peak_capacity;
	uint8_t peak_hold_up_time;
	uint32_t last_off;

	last_off = offset;

	fru_data = malloc(FRU_MULTIREC_CHUNK_SIZE);
	if (!fru_data) {
		lprintf(LOG_ERR, "ipmitool: malloc failure");
		return;
	}

	memset(fru_data, 0, FRU_MULTIREC_CHUNK_SIZE);

	h = (struct fru_multirec_header *) (fru_data);

	do {
		if (read_fru_area(intf, fru, id, last_off, sizeof(*h), fru_data) < 0) {
			break;
		}

		if (h->len && read_fru_area(intf, fru, id,
				last_off + sizeof(*h), h->len, fru_data + sizeof(*h)) < 0) {
			break;
		}

		last_off += h->len + sizeof(*h);

		switch (h->type) {
		case FRU_RECORD_TYPE_POWER_SUPPLY_INFORMATION:
			ps = (struct fru_multirec_powersupply *)
				(fru_data + sizeof(struct fru_multirec_header));

#if WORDS_BIGENDIAN
			ps->capacity      = BSWAP_16(ps->capacity);
			ps->peak_va    = BSWAP_16(ps->peak_va);
			ps->lowend_input1 = BSWAP_16(ps->lowend_input1);
			ps->highend_input1   = BSWAP_16(ps->highend_input1);
			ps->lowend_input2 = BSWAP_16(ps->lowend_input2);
			ps->highend_input2   = BSWAP_16(ps->highend_input2);
			ps->combined_capacity   = BSWAP_16(ps->combined_capacity);
			ps->peak_cap_ht      = BSWAP_16(ps->peak_cap_ht);
#endif
			peak_hold_up_time = (ps->peak_cap_ht & 0xf000) >> 12;
			peak_capacity     = ps->peak_cap_ht & 0x0fff;

			printf (" Power Supply Record\n");
			printf ("  Capacity                   : %d W\n",
				ps->capacity);
			printf ("  Peak VA                    : %d VA\n",
				ps->peak_va);
			printf ("  Inrush Current             : %d A\n",
				ps->inrush_current);
			printf ("  Inrush Interval            : %d ms\n",
				ps->inrush_interval);
			printf ("  Input Voltage Range 1      : %d-%d V\n",
				ps->lowend_input1 / 100, ps->highend_input1 / 100);
			printf ("  Input Voltage Range 2      : %d-%d V\n",
				ps->lowend_input2 / 100, ps->highend_input2 / 100);
			printf ("  Input Frequency Range      : %d-%d Hz\n",
				ps->lowend_freq, ps->highend_freq);
			printf ("  A/C Dropout Tolerance      : %d ms\n",
				ps->dropout_tolerance);
			printf ("  Flags                      : %s%s%s%s%s\n",
				ps->predictive_fail ? "'Predictive fail' " : "",
				ps->pfc ? "'Power factor correction' " : "",
				ps->autoswitch ? "'Autoswitch voltage' " : "",
				ps->hotswap ? "'Hot swap' " : "",
				ps->predictive_fail ? ps->rps_threshold ?
				ps->tach ? "'Two pulses per rotation'" : "'One pulse per rotation'" :
				ps->tach ? "'Failure on pin de-assertion'" : "'Failure on pin assertion'" : "");
			printf ("  Peak capacity              : %d W\n",
				peak_capacity);
			printf ("  Peak capacity holdup       : %d s\n",
				peak_hold_up_time);
			if (ps->combined_capacity == 0)
				printf ("  Combined capacity          : not specified\n");
			else
				printf ("  Combined capacity          : %d W (%s and %s)\n",
					ps->combined_capacity,
					combined_voltage_desc [ps->combined_voltage1],
					combined_voltage_desc [ps->combined_voltage2]);
			if (ps->predictive_fail)
				printf ("  Fan lower threshold        : %d RPS\n",
					ps->rps_threshold);
			break;

		case FRU_RECORD_TYPE_DC_OUTPUT:
			dc = (struct fru_multirec_dcoutput *)
				(fru_data + sizeof(struct fru_multirec_header));

#if WORDS_BIGENDIAN
			dc->nominal_voltage  = BSWAP_16(dc->nominal_voltage);
			dc->max_neg_dev      = BSWAP_16(dc->max_neg_dev);
			dc->max_pos_dev      = BSWAP_16(dc->max_pos_dev);
			dc->ripple_and_noise = BSWAP_16(dc->ripple_and_noise);
			dc->min_current      = BSWAP_16(dc->min_current);
			dc->max_current      = BSWAP_16(dc->max_current);
#endif

			printf (" DC Output Record\n");
			printf ("  Output Number              : %d\n",
				dc->output_number);
			printf ("  Standby power              : %s\n",
				dc->standby ? "Yes" : "No");
			printf ("  Nominal voltage            : %.2f V\n",
				(double) dc->nominal_voltage / 100);
			printf ("  Max negative deviation     : %.2f V\n",
				(double) dc->max_neg_dev / 100);
			printf ("  Max positive deviation     : %.2f V\n",
				(double) dc->max_pos_dev / 100);
			printf ("  Ripple and noise pk-pk     : %d mV\n",
				dc->ripple_and_noise);
			printf ("  Minimum current draw       : %.3f A\n",
				(double) dc->min_current / 1000);
			printf ("  Maximum current draw       : %.3f A\n",
				(double) dc->max_current / 1000);
			break;

		case FRU_RECORD_TYPE_DC_LOAD:
			dl = (struct fru_multirec_dcload *)
				(fru_data + sizeof(struct fru_multirec_header));

#if WORDS_BIGENDIAN
			dl->nominal_voltage  = BSWAP_16(dl->nominal_voltage);
			dl->min_voltage      = BSWAP_16(dl->min_voltage);
			dl->max_voltage      = BSWAP_16(dl->max_voltage);
			dl->ripple_and_noise = BSWAP_16(dl->ripple_and_noise);
			dl->min_current      = BSWAP_16(dl->min_current);
			dl->max_current      = BSWAP_16(dl->max_current);
#endif

			printf (" DC Load Record\n");
			printf ("  Output Number              : %d\n",
				dl->output_number);
			printf ("  Nominal voltage            : %.2f V\n",
				(double) dl->nominal_voltage / 100);
			printf ("  Min voltage allowed        : %.2f V\n",
				(double) dl->min_voltage / 100);
			printf ("  Max voltage allowed        : %.2f V\n",
				(double) dl->max_voltage / 100);
			printf ("  Ripple and noise pk-pk     : %d mV\n",
				dl->ripple_and_noise);
			printf ("  Minimum current load       : %.3f A\n",
				(double) dl->min_current / 1000);
			printf ("  Maximum current load       : %.3f A\n",
				(double) dl->max_current / 1000);
			break;
		case FRU_RECORD_TYPE_OEM_EXTENSION:
			{
				struct fru_multirec_oem_header *oh=(struct fru_multirec_oem_header *)
										&fru_data[sizeof(struct fru_multirec_header)];
				uint32_t iana = oh->mfg_id[0] | oh->mfg_id[1]<<8 | oh->mfg_id[2]<<16;

				/* Now makes sure this is really PICMG record */

				if( iana == IPMI_OEM_PICMG ){
					printf("  PICMG Extension Record\n");
					ipmi_fru_picmg_ext_print(fru_data,
													sizeof(struct fru_multirec_header),
													h->len);
				}
				/* FIXME: Add OEM record support here */
				else{
					printf("  OEM (%s) Record\n", val2str( iana, ipmi_oem_info));
				}
			}
			break;
		}
	} while (!(h->format & 0x80));

	lprintf(LOG_DEBUG ,"Multi-Record area ends at: %i (%xh)", last_off, last_off);

	free_n(&fru_data);
}
fru_area_print_multirec(struct ipmi_intf * intf, struct fru_info * fru,
			uint8_t id, uint32_t offset)
{
	uint8_t * fru_data;
	struct fru_multirec_header * h;
	struct fru_multirec_powersupply * ps;
	struct fru_multirec_dcoutput * dc;
	struct fru_multirec_dcload * dl;
	uint16_t peak_capacity;
	uint8_t peak_hold_up_time;
	uint32_t last_off;

	last_off = offset;

	fru_data = malloc(FRU_MULTIREC_CHUNK_SIZE);
	if (!fru_data) {
		lprintf(LOG_ERR, "ipmitool: malloc failure");
		return;
	}

	memset(fru_data, 0, FRU_MULTIREC_CHUNK_SIZE);

	h = (struct fru_multirec_header *) (fru_data);

	do {
		if (read_fru_area(intf, fru, id, last_off, sizeof(*h), fru_data) < 0) {
			break;
		}

		if (h->len && read_fru_area(intf, fru, id,
				last_off + sizeof(*h), h->len, fru_data + sizeof(*h)) < 0) {
			break;
		}

		last_off += h->len + sizeof(*h);

		switch (h->type) {
		case FRU_RECORD_TYPE_POWER_SUPPLY_INFORMATION:
			ps = (struct fru_multirec_powersupply *)
				(fru_data + sizeof(struct fru_multirec_header));

#if WORDS_BIGENDIAN
			ps->capacity      = BSWAP_16(ps->capacity);
			ps->peak_va    = BSWAP_16(ps->peak_va);
			ps->lowend_input1 = BSWAP_16(ps->lowend_input1);
			ps->highend_input1   = BSWAP_16(ps->highend_input1);
			ps->lowend_input2 = BSWAP_16(ps->lowend_input2);
			ps->highend_input2   = BSWAP_16(ps->highend_input2);
			ps->combined_capacity   = BSWAP_16(ps->combined_capacity);
			ps->peak_cap_ht      = BSWAP_16(ps->peak_cap_ht);
#endif
			peak_hold_up_time = (ps->peak_cap_ht & 0xf000) >> 12;
			peak_capacity     = ps->peak_cap_ht & 0x0fff;

			printf (" Power Supply Record\n");
			printf ("  Capacity                   : %d W\n",
				ps->capacity);
			printf ("  Peak VA                    : %d VA\n",
				ps->peak_va);
			printf ("  Inrush Current             : %d A\n",
				ps->inrush_current);
			printf ("  Inrush Interval            : %d ms\n",
				ps->inrush_interval);
			printf ("  Input Voltage Range 1      : %d-%d V\n",
				ps->lowend_input1 / 100, ps->highend_input1 / 100);
			printf ("  Input Voltage Range 2      : %d-%d V\n",
				ps->lowend_input2 / 100, ps->highend_input2 / 100);
			printf ("  Input Frequency Range      : %d-%d Hz\n",
				ps->lowend_freq, ps->highend_freq);
			printf ("  A/C Dropout Tolerance      : %d ms\n",
				ps->dropout_tolerance);
			printf ("  Flags                      : %s%s%s%s%s\n",
				ps->predictive_fail ? "'Predictive fail' " : "",
				ps->pfc ? "'Power factor correction' " : "",
				ps->autoswitch ? "'Autoswitch voltage' " : "",
				ps->hotswap ? "'Hot swap' " : "",
				ps->predictive_fail ? ps->rps_threshold ?
				ps->tach ? "'Two pulses per rotation'" : "'One pulse per rotation'" :
				ps->tach ? "'Failure on pin de-assertion'" : "'Failure on pin assertion'" : "");
			printf ("  Peak capacity              : %d W\n",
				peak_capacity);
			printf ("  Peak capacity holdup       : %d s\n",
				peak_hold_up_time);
			if (ps->combined_capacity == 0)
				printf ("  Combined capacity          : not specified\n");
			else
				printf ("  Combined capacity          : %d W (%s and %s)\n",
					ps->combined_capacity,
					combined_voltage_desc [ps->combined_voltage1],
					combined_voltage_desc [ps->combined_voltage2]);
			if (ps->predictive_fail)
				printf ("  Fan lower threshold        : %d RPS\n",
					ps->rps_threshold);
			break;

		case FRU_RECORD_TYPE_DC_OUTPUT:
			dc = (struct fru_multirec_dcoutput *)
				(fru_data + sizeof(struct fru_multirec_header));

#if WORDS_BIGENDIAN
			dc->nominal_voltage  = BSWAP_16(dc->nominal_voltage);
			dc->max_neg_dev      = BSWAP_16(dc->max_neg_dev);
			dc->max_pos_dev      = BSWAP_16(dc->max_pos_dev);
			dc->ripple_and_noise = BSWAP_16(dc->ripple_and_noise);
			dc->min_current      = BSWAP_16(dc->min_current);
			dc->max_current      = BSWAP_16(dc->max_current);
#endif

			printf (" DC Output Record\n");
			printf ("  Output Number              : %d\n",
				dc->output_number);
			printf ("  Standby power              : %s\n",
				dc->standby ? "Yes" : "No");
			printf ("  Nominal voltage            : %.2f V\n",
				(double) dc->nominal_voltage / 100);
			printf ("  Max negative deviation     : %.2f V\n",
				(double) dc->max_neg_dev / 100);
			printf ("  Max positive deviation     : %.2f V\n",
				(double) dc->max_pos_dev / 100);
			printf ("  Ripple and noise pk-pk     : %d mV\n",
				dc->ripple_and_noise);
			printf ("  Minimum current draw       : %.3f A\n",
				(double) dc->min_current / 1000);
			printf ("  Maximum current draw       : %.3f A\n",
				(double) dc->max_current / 1000);
			break;

		case FRU_RECORD_TYPE_DC_LOAD:
			dl = (struct fru_multirec_dcload *)
				(fru_data + sizeof(struct fru_multirec_header));

#if WORDS_BIGENDIAN
			dl->nominal_voltage  = BSWAP_16(dl->nominal_voltage);
			dl->min_voltage      = BSWAP_16(dl->min_voltage);
			dl->max_voltage      = BSWAP_16(dl->max_voltage);
			dl->ripple_and_noise = BSWAP_16(dl->ripple_and_noise);
			dl->min_current      = BSWAP_16(dl->min_current);
			dl->max_current      = BSWAP_16(dl->max_current);
#endif

			printf (" DC Load Record\n");
			printf ("  Output Number              : %d\n",
				dl->output_number);
			printf ("  Nominal voltage            : %.2f V\n",
				(double) dl->nominal_voltage / 100);
			printf ("  Min voltage allowed        : %.2f V\n",
				(double) dl->min_voltage / 100);
			printf ("  Max voltage allowed        : %.2f V\n",
				(double) dl->max_voltage / 100);
			printf ("  Ripple and noise pk-pk     : %d mV\n",
				dl->ripple_and_noise);
			printf ("  Minimum current load       : %.3f A\n",
				(double) dl->min_current / 1000);
			printf ("  Maximum current load       : %.3f A\n",
				(double) dl->max_current / 1000);
			break;
		case FRU_RECORD_TYPE_OEM_EXTENSION:
			{
				struct fru_multirec_oem_header *oh=(struct fru_multirec_oem_header *)
										&fru_data[sizeof(struct fru_multirec_header)];
				uint32_t iana = oh->mfg_id[0] | oh->mfg_id[1]<<8 | oh->mfg_id[2]<<16;

				 

				if( iana == IPMI_OEM_PICMG ){
					printf("  PICMG Extension Record\n");
					ipmi_fru_picmg_ext_print(fru_data,
													sizeof(struct fru_multirec_header),
													h->len);
				}
				 
				else{
					printf("  OEM (%s) Record\n", val2str( iana, ipmi_oem_info));
				}
			}
			break;
		}
	} while (!(h->format & 0x80));

	lprintf(LOG_DEBUG ,"Multi-Record area ends at: %i (%xh)", last_off, last_off);

	free_n(&fru_data);
}