ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
			   struct sdr_record_common_sensor    *sensor,
			   uint8_t sdr_record_type)
{
	char sval[16];
	unsigned int i = 0;
	uint8_t target, lun, channel;
	struct sensor_reading *sr;


	sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 2);

	if (!sr)
		return -1;

	target = sensor->keys.owner_id;
	lun = sensor->keys.lun;
	channel = sensor->keys.channel;

	/*
	 * CSV OUTPUT
	 */

	if (csv_output) {
		/*
		 * print sensor name, reading, unit, state
		 */
		printf("%s,", sr->s_id);
		if (!IS_THRESHOLD_SENSOR(sensor)) {
			/* Discrete/Non-Threshold */
			print_csv_discrete(intf, sensor, sr);
			printf("\n");
		}
		else {
			/* Threshold Analog & Discrete*/
			if (sr->s_reading_valid) {
				if (sr->s_has_analog_value) {
					/* Analog/Threshold */
					printf("%.*f,", (sr->s_a_val ==
					(int) sr->s_a_val) ? 0 : 3,
					sr->s_a_val);
					printf("%s,%s", sr->s_a_units,
					       ipmi_sdr_get_thresh_status(sr, "ns"));
				} else { /* Discrete/Threshold */
					print_csv_discrete(intf, sensor, sr);
				}
			} else {
				printf(",,ns");
			}

			if (verbose) {
				printf(",%d.%d,%s,%s,",
					sensor->entity.id, sensor->entity.instance,
					val2str(sensor->entity.id, entity_id_vals),
					ipmi_get_sensor_type(intf, sensor->sensor.type));

				if (sr->full) {
					SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.nominal_read,
						sr->full->nominal_read);
					SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.normal_min,
						sr->full->normal_min);
					SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.normal_max,
						     sr->full->normal_max);
					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.unr,
						sr->full->threshold.upper.non_recover);
					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.ucr,
						sr->full->threshold.upper.critical);
					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.unc,
						sr->full->threshold.upper.non_critical);
					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lnr,
						sr->full->threshold.lower.non_recover);
					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lcr,
						sr->full->threshold.lower.critical);
					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lnc,
						sr->full->threshold.lower.non_critical);

					if (UNITS_ARE_DISCRETE(sensor)) {
						printf("0x%02X,0x%02X", sr->full->sensor_min, sr->full->sensor_max);
					}
					else {
						printf("%.3f,%.3f",
						       sdr_convert_sensor_reading(sr->full,
									      sr->full->sensor_min),
						       sdr_convert_sensor_reading(sr->full,
									      sr->full->sensor_max));
					}
				} else {
					printf(",,,,,,,,,,");
				}
			}
			printf("\n");
		}

		return 0;	/* done */
	}

	/*
	 * NORMAL OUTPUT
	 */

	if (verbose == 0 && sdr_extended == 0) {
		/*
		 * print sensor name, reading, state
		 */
		printf("%-16s | ", sr->s_id);

		memset(sval, 0, sizeof (sval));

		if (sr->s_reading_valid) {
			if( sr->s_has_analog_value ) {
				snprintf(sval, sizeof (sval), "%s %s",
						      sr->s_a_str,
						      sr->s_a_units);
			} else /* Discrete */
				snprintf(sval, sizeof(sval),
					"0x%02x", sr->s_reading);
		}
		else if (sr->s_scanning_disabled)
			snprintf(sval, sizeof (sval), sr->full ? "disabled"   : "Not Readable");
		else
			snprintf(sval, sizeof (sval), sr->full ? "no reading" : "Not Readable");

		printf("%s", sval);

		for (i = strlen(sval); i <= sizeof (sval); i++)
			printf(" ");
		printf(" | ");

		if (IS_THRESHOLD_SENSOR(sensor)) {
			printf("%s", ipmi_sdr_get_thresh_status(sr, "ns"));
		}
		else {
			printf("%s", sr->s_reading_valid ? "ok" : "ns");
		}

		printf("\n");

		return 0;	/* done */
	} else if (verbose == 0 && sdr_extended == 1) {
		/*
		 * print sensor name, number, state, entity, reading
		 */
		printf("%-16s | %02Xh | ",
		       sr->s_id, sensor->keys.sensor_num);

		if (IS_THRESHOLD_SENSOR(sensor)) {
			/* Threshold Analog & Discrete */
			printf("%-3s | %2d.%1d | ",
			   ipmi_sdr_get_thresh_status(sr, "ns"),
		           sensor->entity.id, sensor->entity.instance);
		}
		else {
			/* Non Threshold Analog & Discrete */
			printf("%-3s | %2d.%1d | ",
			       (sr->s_reading_valid ? "ok" : "ns"),
			       sensor->entity.id, sensor->entity.instance);
		}

		memset(sval, 0, sizeof (sval));

		if (sr->s_reading_valid) {
			if (IS_THRESHOLD_SENSOR(sensor) &&
				sr->s_has_analog_value ) {
				/* Threshold Analog */
					snprintf(sval, sizeof (sval), "%s %s",
						      sr->s_a_str,
						      sr->s_a_units);
			} else {
				/* Analog & Discrete & Threshold/Discrete */
				char *header = NULL;
				if (sr->s_has_analog_value) { /* Sensor has an analog value */
					printf("%s %s", sr->s_a_str, sr->s_a_units);
					header = ", ";
				}
				ipmi_sdr_print_discrete_state_mini(intf, header, ", ",
								   sensor->sensor.type,
								   sensor->event_type,
								   sr->s_data2,
								   sr->s_data3);
			}
		}
		else if (sr->s_scanning_disabled)
			snprintf(sval, sizeof (sval), "Disabled");
		else
			snprintf(sval, sizeof (sval), "No Reading");

		printf("%s\n", sval);
		return 0;	/* done */
	}
	/*
	 * VERBOSE OUTPUT
	 */

	printf("Sensor ID              : %s (0x%x)\n",
	       sr->s_id, sensor->keys.sensor_num);
	printf(" Entity ID             : %d.%d (%s)\n",
	       sensor->entity.id, sensor->entity.instance,
	       val2str(sensor->entity.id, entity_id_vals));

	if (!IS_THRESHOLD_SENSOR(sensor)) {
		/* Discrete */
		printf(" Sensor Type (Discrete): %s (0x%02x)\n",
				ipmi_get_sensor_type(intf, sensor->sensor.type),
				sensor->sensor.type);
		lprintf(LOG_DEBUG, " Event Type Code       : 0x%02x",
			sensor->event_type);

		printf(" Sensor Reading        : ");
		if (sr->s_reading_valid) {
			if (sr->s_has_analog_value) { /* Sensor has an analog value */
				printf("%s %s\n", sr->s_a_str, sr->s_a_units);
			} else {
				printf("%xh\n", sr->s_reading);
			}
		}
		else if (sr->s_scanning_disabled)
			printf("Disabled\n");
		else {
			/* Used to be 'Not Reading' */
			printf("No Reading\n");
		}

		printf(" Event Message Control : ");
		switch (sensor->sensor.capabilities.event_msg) {
		case 0:
			printf("Per-threshold\n");
			break;
		case 1:
			printf("Entire Sensor Only\n");
			break;
		case 2:
			printf("Global Disable Only\n");
			break;
		case 3:
			printf("No Events From Sensor\n");
			break;
		}

		ipmi_sdr_print_discrete_state(intf, "States Asserted",
					      sensor->sensor.type,
					      sensor->event_type,
					      sr->s_data2,
					      sr->s_data3);
		ipmi_sdr_print_sensor_mask(intf, &sensor->mask, sensor->sensor.type,
					   sensor->event_type, DISCRETE_SENSOR);
		ipmi_sdr_print_sensor_event_status(intf,
						   sensor->keys.sensor_num,
						   sensor->sensor.type,
						   sensor->event_type,
						   DISCRETE_SENSOR,
						   target,
						   lun, channel);
		ipmi_sdr_print_sensor_event_enable(intf,
						   sensor->keys.sensor_num,
						   sensor->sensor.type,
						   sensor->event_type,
						   DISCRETE_SENSOR,
						   target,
						   lun, channel);
		printf(" OEM                   : %X\n",
					sr->full ? sr->full->oem : sr->compact->oem);
		printf("\n");

		return 0;	/* done */
	}
	printf(" Sensor Type (Threshold)  : %s (0x%02x)\n",
		ipmi_get_sensor_type(intf, sensor->sensor.type),
		sensor->sensor.type);

	printf(" Sensor Reading        : ");
	if (sr->s_reading_valid) {
		if (sr->full) {
			uint16_t raw_tol = __TO_TOL(sr->full->mtol);
			if (UNITS_ARE_DISCRETE(sensor)) {
				printf("0x%02X (+/- 0x%02X) %s\n",
				sr->s_reading, raw_tol, sr->s_a_units);
			}
			else {
				double tol = sdr_convert_sensor_tolerance(sr->full, raw_tol);
				printf("%.*f (+/- %.*f) %s\n",
				       (sr->s_a_val == (int) sr->s_a_val) ? 0 : 3,
				       sr->s_a_val, (tol == (int) tol) ? 0 :
				       3, tol, sr->s_a_units);
			}
		} else {
			printf("0x%02X %s\n", sr->s_reading, sr->s_a_units);
		}
	} else if (sr->s_scanning_disabled)
		printf("Disabled\n");
	else
		printf("No Reading\n");

	printf(" Status                : %s\n",
	       ipmi_sdr_get_thresh_status(sr, "Not Available"));

	if(sr->full) {
		SENSOR_PRINT_NORMAL(sr->full, "Nominal Reading", nominal_read);
		SENSOR_PRINT_NORMAL(sr->full, "Normal Minimum", normal_min);
		SENSOR_PRINT_NORMAL(sr->full, "Normal Maximum", normal_max);

		SENSOR_PRINT_THRESH(sr->full, "Upper non-recoverable", upper.non_recover, unr);
		SENSOR_PRINT_THRESH(sr->full, "Upper critical", upper.critical, ucr);
		SENSOR_PRINT_THRESH(sr->full, "Upper non-critical", upper.non_critical, unc);
		SENSOR_PRINT_THRESH(sr->full, "Lower non-recoverable", lower.non_recover, lnr);
		SENSOR_PRINT_THRESH(sr->full, "Lower critical", lower.critical, lcr);
		SENSOR_PRINT_THRESH(sr->full, "Lower non-critical", lower.non_critical, lnc);
	}
	ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
		sr->full ? sr->full->threshold.hysteresis.positive :
		sr->compact->threshold.hysteresis.positive, "Positive Hysteresis");

	ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
		sr->full ? sr->full->threshold.hysteresis.negative :
		sr->compact->threshold.hysteresis.negative, "Negative Hysteresis");

	print_sensor_min_max(sr->full);

	printf(" Event Message Control : ");
	switch (sensor->sensor.capabilities.event_msg) {
	case 0:
		printf("Per-threshold\n");
		break;
	case 1:
		printf("Entire Sensor Only\n");
		break;
	case 2:
		printf("Global Disable Only\n");
		break;
	case 3:
		printf("No Events From Sensor\n");
		break;
	}

	printf(" Readable Thresholds   : ");
	switch (sensor->sensor.capabilities.threshold) {
	case 0:
		printf("No Thresholds\n");
		break;
	case 1:		/* readable according to mask */
	case 2:		/* readable and settable according to mask */
		if (sensor->mask.type.threshold.read.lnr)
			printf("lnr ");
		if (sensor->mask.type.threshold.read.lcr)
			printf("lcr ");
		if (sensor->mask.type.threshold.read.lnc)
			printf("lnc ");
		if (sensor->mask.type.threshold.read.unc)
			printf("unc ");
		if (sensor->mask.type.threshold.read.ucr)
			printf("ucr ");
		if (sensor->mask.type.threshold.read.unr)
			printf("unr ");
		printf("\n");
		break;
	case 3:
		printf("Thresholds Fixed\n");
		break;
	}

	printf(" Settable Thresholds   : ");
	switch (sensor->sensor.capabilities.threshold) {
	case 0:
		printf("No Thresholds\n");
		break;
	case 1:		/* readable according to mask */
	case 2:		/* readable and settable according to mask */
		if (sensor->mask.type.threshold.set.lnr)
			printf("lnr ");
		if (sensor->mask.type.threshold.set.lcr)
			printf("lcr ");
		if (sensor->mask.type.threshold.set.lnc)
			printf("lnc ");
		if (sensor->mask.type.threshold.set.unc)
			printf("unc ");
		if (sensor->mask.type.threshold.set.ucr)
			printf("ucr ");
		if (sensor->mask.type.threshold.set.unr)
			printf("unr ");
		printf("\n");
		break;
	case 3:
		printf("Thresholds Fixed\n");
		break;
	}

	if (sensor->mask.type.threshold.status_lnr ||
	    sensor->mask.type.threshold.status_lcr ||
	    sensor->mask.type.threshold.status_lnc ||
	    sensor->mask.type.threshold.status_unc ||
	    sensor->mask.type.threshold.status_ucr ||
	    sensor->mask.type.threshold.status_unr) {
		printf(" Threshold Read Mask   : ");
		if (sensor->mask.type.threshold.status_lnr)
			printf("lnr ");
		if (sensor->mask.type.threshold.status_lcr)
			printf("lcr ");
		if (sensor->mask.type.threshold.status_lnc)
			printf("lnc ");
		if (sensor->mask.type.threshold.status_unc)
			printf("unc ");
		if (sensor->mask.type.threshold.status_ucr)
			printf("ucr ");
		if (sensor->mask.type.threshold.status_unr)
			printf("unr ");
		printf("\n");
	}

	ipmi_sdr_print_sensor_mask(intf, &sensor->mask,
				   sensor->sensor.type,
				   sensor->event_type, ANALOG_SENSOR);
	ipmi_sdr_print_sensor_event_status(intf,
					   sensor->keys.sensor_num,
					   sensor->sensor.type,
					   sensor->event_type, ANALOG_SENSOR,
					   target,
					   lun, channel);

	ipmi_sdr_print_sensor_event_enable(intf,
					   sensor->keys.sensor_num,
					   sensor->sensor.type,
					   sensor->event_type, ANALOG_SENSOR,
					   target,
					   lun, channel);

	printf("\n");
	return 0;
}