static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
{
	struct fru_multirec_oem_header *h;
	int guid_count;
	int offset = off;
	int start_offset = off;
	int i;

	h = (struct fru_multirec_oem_header *) &fru_data[offset];
	offset += sizeof(struct fru_multirec_oem_header);

	switch (h->record_id)
	{
		case FRU_PICMG_BACKPLANE_P2P:
		{
			uint8_t index;
			unsigned int data;
			struct fru_picmgext_slot_desc *slot_d;

			slot_d =
				(struct fru_picmgext_slot_desc*)&fru_data[offset];
			offset += sizeof(struct fru_picmgext_slot_desc);
			printf("    FRU_PICMG_BACKPLANE_P2P\n");

			while (offset <= (start_offset+length)) {
				printf("\n");
				printf("    Channel Type:  ");
				switch (slot_d->chan_type)
				{
					case 0x00:
					case 0x07:
						printf("PICMG 2.9\n");
						break;
					case 0x08:
						printf("Single Port Fabric IF\n");
						break;
					case 0x09:
						printf("Double Port Fabric IF\n");
						break;
					case 0x0a:
						printf("Full Channel Fabric IF\n");
						break;
					case 0x0b:
						printf("Base IF\n");
						break;
					case 0x0c:
						printf("Update Channel IF\n");
						break;
					case 0x0d:
						printf("ShMC Cross Connect\n");
						break;
					default:
						printf("Unknown IF (0x%x)\n",
								slot_d->chan_type);
						break;
				}
				printf("    Slot Addr.   : %02x\n",
						slot_d->slot_addr );
				printf("    Channel Count: %i\n",
						slot_d->chn_count);

				for (index = 0;
						index < (slot_d->chn_count);
						index++) {
					struct fru_picmgext_chn_desc *d;
					data = (fru_data[offset+0]) |
						(fru_data[offset+1] << 8) |
						(fru_data[offset+2] << 16);
					d = (struct fru_picmgext_chn_desc *)&data;
					if (verbose) {
						printf( "       "
								"Chn: %02x  ->  "
								"Chn: %02x in "
								"Slot: %02x\n",
								d->local_chn,
								d->remote_chn,
								d->remote_slot);
					}
					offset += FRU_PICMGEXT_CHN_DESC_RECORD_SIZE;
				}
				slot_d = (struct fru_picmgext_slot_desc*)&fru_data[offset];
				offset += sizeof(struct fru_picmgext_slot_desc);
			}
		}
		break;

		case FRU_PICMG_ADDRESS_TABLE:
		{
			unsigned int hwaddr;
			unsigned int sitetype;
			unsigned int sitenum;
			unsigned int entries;
			unsigned int i;
			char *picmg_site_type_strings[] = {
					"AdvancedTCA Board",
					"Power Entry",
					"Shelf FRU Information",
					"Dedicated ShMC",
					"Fan Tray",
					"Fan Filter Tray",
					"Alarm",
					"AdvancedMC Module",
					"PMC",
					"Rear Transition Module"};


			printf("    FRU_PICMG_ADDRESS_TABLE\n");
			printf("      Type/Len:  0x%02x\n", fru_data[offset++]);
			printf("      Shelf Addr: ");
			for (i=0;i<20;i++) {
				printf("0x%02x ", fru_data[offset++]);
			}
			printf("\n");

			entries = fru_data[offset++];
			printf("      Addr Table Entries: 0x%02x\n", entries);

			for (i=0; i<entries; i++) {
				hwaddr = fru_data[offset];
				sitenum = fru_data[offset + 1];
				sitetype = fru_data[offset + 2];
				printf(
						"        HWAddr: 0x%02x (0x%02x) SiteNum: %d SiteType: 0x%02x %s\n",
						hwaddr, hwaddr * 2,
						sitenum, sitetype,
						(sitetype < 0xa) ?
						picmg_site_type_strings[sitetype] :
						"Reserved");
				offset += 3;
			}
		}
		break;

		case FRU_PICMG_SHELF_POWER_DIST:
		{
			unsigned int entries;
			unsigned int feeds;
			unsigned int hwaddr;
			unsigned int i;
			unsigned int id;
			unsigned int j;
			unsigned int maxext;
			unsigned int maxint;
			unsigned int minexp;

			printf("    FRU_PICMG_SHELF_POWER_DIST\n");

			feeds = fru_data[offset++];
			printf("      Number of Power Feeds:   0x%02x\n",
					feeds);

			for (i=0; i<feeds; i++) {
				printf("    Feed %d:\n", i);
				maxext = fru_data[offset] |
					(fru_data[offset+1] << 8);
				offset += 2;
				maxint = fru_data[offset] |
					(fru_data[offset+1] << 8);
				offset += 2;
				minexp = fru_data[offset];
				offset += 1;
				entries = fru_data[offset];
				offset += 1;

				printf(
						"      Max External Current:   %d.%d Amps (0x%04x)\n",
						maxext / 10, maxext % 10, maxext);
				if (maxint < 0xffff) {
					printf(
							"      Max Internal Current:   %d.%d Amps (0x%04x)\n",
							maxint / 10, maxint % 10,
							maxint);
				} else {
					printf(
							"      Max Internal Current:   Not Specified\n");
				}

				if (minexp >= 0x48 && minexp <= 0x90) {
					printf(
							"      Min Expected Voltage:   -%02d.%dV\n",
							minexp / 2, (minexp % 2) * 5);
				} else {
					printf(
							"      Min Expected Voltage:   -%dV (actual invalid value 0x%x)\n",
							36, minexp);
				}
				for (j=0; j < entries; j++) {
					hwaddr = fru_data[offset++];
					id = fru_data[offset++];
					printf(
							"        FRU HW Addr: 0x%02x (0x%02x)",
							hwaddr, hwaddr * 2);
					printf(
							"   FRU ID: 0x%02x\n",
							id);
				}
			}
		}
		break;

		case FRU_PICMG_SHELF_ACTIVATION:
		{
			unsigned int i;
			unsigned int count = 0;

			printf("    FRU_PICMG_SHELF_ACTIVATION\n");
			printf(
					"      Allowance for FRU Act Readiness:   0x%02x\n",
					fru_data[offset++]);

			count = fru_data[offset++];
			printf(
					"      FRU activation and Power Desc Cnt: 0x%02x\n",
					count);

			for (i=0; i<count; i++) {
				printf("         HW Addr: 0x%02x ",
						fru_data[offset++]);
				printf("         FRU ID: 0x%02x ",
						fru_data[offset++]);
				printf("         Max FRU Power: 0x%04x ",
						fru_data[offset+0] |
						(fru_data[offset+1]<<8));
				offset += 2;
				printf("         Config: 0x%02x \n",
						fru_data[offset++]);
			}
		}
		break;

		case FRU_PICMG_SHMC_IP_CONN:
			printf("    FRU_PICMG_SHMC_IP_CONN\n");
			break;

		case FRU_PICMG_BOARD_P2P:
			printf("    FRU_PICMG_BOARD_P2P\n");

			guid_count = fru_data[offset++];
			printf("      GUID count: %2d\n", guid_count);
			for (i = 0 ; i < guid_count; i++ ) {
				int j;
				printf("        GUID [%2d]: 0x", i);

				for (j=0; j < sizeof(struct fru_picmgext_guid);
						j++) {
					printf("%02x", fru_data[offset+j]);
				}

				printf("\n");
				offset += sizeof(struct fru_picmgext_guid);
			}
			printf("\n");

			for (; offset < off + length;
					offset += sizeof(struct fru_picmgext_link_desc)) {

				/* to solve little endian /big endian problem */
				struct fru_picmgext_link_desc *d;
				unsigned int data = (fru_data[offset+0]) |
					(fru_data[offset+1] << 8) |
					(fru_data[offset+2] << 16) |
					(fru_data[offset+3] << 24);
				d = (struct fru_picmgext_link_desc *) &data;

				printf("      Link Grouping ID:     0x%02x\n",
						d->grouping);
				printf("      Link Type Extension:  0x%02x - ",
						d->ext);
				if (d->type == FRU_PICMGEXT_LINK_TYPE_BASE) {
					switch (d->ext) {
						case 0:
							printf("10/100/1000BASE-T Link (four-pair)\n");
							break;
						case 1:
							printf("ShMC Cross-connect (two-pair)\n");
							break;
						default:
							printf("Unknown\n");
							break;
					}
				} else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET) {
					switch (d->ext) {
						case 0:
							printf("1000Base-BX\n");
							break;
						case 1:
							printf("10GBase-BX4 [XAUI]\n");
							break;
						case 2:
							printf("FC-PI\n");
							break;
						case 3:
							printf("1000Base-KX\n");
							break;
						case 4:
							printf("10GBase-KX4\n");
							break;
						default:
							printf("Unknown\n");
							break;
					}
				} else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET_10GBD) {
					switch (d->ext) {
						case 0:
							printf("10GBase-KR\n");
							break;
						case 1:
							printf("40GBase-KR4\n");
							break;
						default:
							printf("Unknown\n");
							break;
					}
				} else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND) {
					printf("Unknown\n");
				} else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR) {
					printf("Unknown\n");
				} else if (d->type == FRU_PICMGEXT_LINK_TYPE_PCIE) {
					printf("Unknown\n");
				} else {
					printf("Unknown\n");
				}

				printf("      Link Type:            0x%02x - ",
						d->type);
				switch (d->type) {
					case FRU_PICMGEXT_LINK_TYPE_BASE:
						printf("PICMG 3.0 Base Interface 10/100/1000\n");
						break;
					case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET:
						printf("PICMG 3.1 Ethernet Fabric Interface\n");
						printf("                                   Base signaling Link Class\n");
						break;
					case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND:
						printf("PICMG 3.2 Infiniband Fabric Interface\n");
						break;
					case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR:
						printf("PICMG 3.3 Star Fabric Interface\n");
						break;
					case  FRU_PICMGEXT_LINK_TYPE_PCIE:
						printf("PICMG 3.4 PCI Express Fabric Interface\n");
						break;
					case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET_10GBD:
						printf("PICMG 3.1 Ethernet Fabric Interface\n");
						printf("                                   10.3125Gbd signaling Link Class\n");
						break;
					default:
						if (d->type == 0 || d->type == 0xff) {
							printf("Reserved\n");
						} else if (d->type >= 0x06 && d->type <= 0xef) {
							printf("Reserved\n");
						} else if (d->type >= 0xf0 && d->type <= 0xfe) {
							printf("OEM GUID Definition\n");
						} else {
							printf("Invalid\n");
						}
						break;
				}
				printf("      Link Designator: \n");
				printf("        Port Flag:            0x%02x\n",
						d->desig_port);
				printf("        Interface:            0x%02x - ",
						d->desig_if);
				switch (d->desig_if) {
					case FRU_PICMGEXT_DESIGN_IF_BASE:
						printf("Base Interface\n");
						break;
					case FRU_PICMGEXT_DESIGN_IF_FABRIC:
						printf("Fabric Interface\n");
						break;
					case FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL:
						printf("Update Channel\n");
						break;
					case FRU_PICMGEXT_DESIGN_IF_RESERVED:
						printf("Reserved\n");
						break;
					default:
						printf("Invalid");
						break;
				}
				printf("        Channel Number:       0x%02x\n",
						d->desig_channel);
				printf("\n");
			}

			break;

		case FRU_AMC_CURRENT:
		{
			unsigned char current;
			printf("    FRU_AMC_CURRENT\n");

			current = fru_data[offset];
			printf("      Current draw(@12V): %.2f A [ %.2f Watt ]\n",
					(float)current / 10.0f,
					(float)current / 10.0f * 12.0f);
			printf("\n");
		}
		break;

		case FRU_AMC_ACTIVATION:
			printf("    FRU_AMC_ACTIVATION\n");
			{
				uint16_t max_current;

				max_current = fru_data[offset];
				max_current |= fru_data[++offset]<<8;
				printf("      Maximum Internal Current(@12V): %.2f A [ %.2f Watt ]\n",
						(float)max_current / 10.0f,
						(float)max_current / 10.0f * 12.0f);

				printf("      Module Activation Readiness:    %i sec.\n", fru_data[++offset]);
				printf("      Descriptor Count: %i\n", fru_data[++offset]);
				printf("\n");

				for(++offset; offset < off + length;
						offset += sizeof(struct fru_picmgext_activation_record))
				{
					struct fru_picmgext_activation_record *a;
					a = (struct fru_picmgext_activation_record *)&fru_data[offset];
					printf("        IPMB-Address:         0x%x\n",
							a->ibmb_addr);
					printf("        Max. Module Current:  %.2f A\n",
							(float)a->max_module_curr / 10.0f);
					printf("\n");
				}
			}
			break;

		case FRU_AMC_CARRIER_P2P:
			{
				uint16_t index;
				printf("    FRU_CARRIER_P2P\n");
				for(; offset < off + length; ) {
					struct fru_picmgext_carrier_p2p_record * h =
						(struct fru_picmgext_carrier_p2p_record *)&fru_data[offset];
					printf("\n");
					printf("      Resource ID:      %i",
							(h->resource_id & 0x07));
						printf("  Type: ");
					if ((h->resource_id>>7) == 1) {
						printf("AMC\n");
					} else {
						printf("Local\n");
					}
					printf("      Descriptor Count: %i\n",
							h->p2p_count);
					offset += sizeof(struct fru_picmgext_carrier_p2p_record);
					for (index = 0; index < h->p2p_count; index++) {
						/* to solve little endian /big endian problem */
						unsigned char data[3];
						struct fru_picmgext_carrier_p2p_descriptor * desc;
# ifndef WORDS_BIGENDIAN
						data[0] = fru_data[offset+0];
						data[1] = fru_data[offset+1];
						data[2] = fru_data[offset+2];
# else
						data[0] = fru_data[offset+2];
						data[1] = fru_data[offset+1];
						data[2] = fru_data[offset+0];
# endif
						desc = (struct fru_picmgext_carrier_p2p_descriptor*)&data;
						printf("        Port: %02d\t->  Remote Port: %02d\t",
								desc->local_port, desc->remote_port);
						if ((desc->remote_resource_id >> 7) == 1) {
							printf("[ AMC   ID: %02d ]\n",
									desc->remote_resource_id & 0x0F);
						} else {
							printf("[ local ID: %02d ]\n",
									desc->remote_resource_id & 0x0F);
						}
						offset += sizeof(struct fru_picmgext_carrier_p2p_descriptor);
					}
				}
			}
			break;

		case FRU_AMC_P2P:
			{
				unsigned int index;
				unsigned char channel_count;
				struct fru_picmgext_amc_p2p_record * h;
				printf("    FRU_AMC_P2P\n");
				guid_count = fru_data[offset];
				printf("      GUID count: %2d\n", guid_count);
				for (i = 0 ; i < guid_count; i++) {
					int j;
					printf("        GUID %2d: ", i);
					for (j=0; j < sizeof(struct fru_picmgext_guid);
							j++) {
						printf("%02x", fru_data[offset+j]);
						offset += sizeof(struct fru_picmgext_guid);
						printf("\n");
					}
					h = (struct fru_picmgext_amc_p2p_record *)&fru_data[++offset];
					printf("      %s",
							(h->record_type ?
							 "AMC Module:" : "On-Carrier Device"));
					printf("   Resource ID: %i\n", h->resource_id);
					offset += sizeof(struct fru_picmgext_amc_p2p_record);
					channel_count = fru_data[offset++];
					printf("       Descriptor Count: %i\n",
							channel_count);
					for (index = 0; index < channel_count; index++) {
						unsigned int data;
						struct fru_picmgext_amc_channel_desc_record *d;
						/* pack the data in little endian format.
						 * Stupid intel...
						 */
						data = fru_data[offset] |
							(fru_data[offset + 1] << 8) |
							(fru_data[offset + 2] << 16);
						d = (struct fru_picmgext_amc_channel_desc_record *)&data;
						printf("        Lane 0 Port: %i\n",
								d->lane0port);
						printf("        Lane 1 Port: %i\n",
								d->lane1port);
						printf("        Lane 2 Port: %i\n",
								d->lane2port);
						printf("        Lane 3 Port: %i\n\n",
								d->lane3port);
						offset += FRU_PICMGEXT_AMC_CHANNEL_DESC_RECORD_SIZE;
					}
					for (; offset < off + length;) {
						unsigned int data[2];
						struct fru_picmgext_amc_link_desc_record *l;
						l = (struct fru_picmgext_amc_link_desc_record *)&data[0];
						data[0] = fru_data[offset] |
							(fru_data[offset + 1] << 8) |
							(fru_data[offset + 2] << 16) |
							(fru_data[offset + 3] << 24);
						data[1] = fru_data[offset + 4];
						printf( "      Link Designator:  Channel ID: %i\n"
								"            Port Flag 0: %s%s%s%s\n",
								l->channel_id,
								(l->port_flag_0)?"o":"-",
								(l->port_flag_1)?"o":"-",
								(l->port_flag_2)?"o":"-",
								(l->port_flag_3)?"o":"-"  );
						switch (l->type) {
							case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE:
								/* AMC.1 */
								printf( "        Link Type:       %02x - "
										"AMC.1 PCI Express\n", l->type);
								switch (l->type_ext) {
									case AMC_LINK_TYPE_EXT_PCIE_G1_NSSC:
										printf( "        Link Type Ext:   %i - "
												" Gen 1 capable - non SSC\n",
												l->type_ext);
									break;
									case AMC_LINK_TYPE_EXT_PCIE_G1_SSC:
										printf( "        Link Type Ext:   %i - "
												" Gen 1 capable - SSC\n",
												l->type_ext);
										break;
									case AMC_LINK_TYPE_EXT_PCIE_G2_NSSC:
										printf( "        Link Type Ext:   %i - "
												" Gen 2 capable - non SSC\n",
												l->type_ext);
										break;
									case AMC_LINK_TYPE_EXT_PCIE_G2_SSC:
										printf( "        Link Type Ext:   %i - "
												" Gen 2 capable - SSC\n",
												l->type_ext);
										break;
									default:
										printf( "        Link Type Ext:   %i - "
												" Invalid\n",
												l->type_ext);
										break;
								}
								break;

							case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE_AS1:
							case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE_AS2:
								/* AMC.1 */
								printf( "        Link Type:       %02x - "
										"AMC.1 PCI Express Advanced Switching\n",
										l->type);
								printf("        Link Type Ext:   %i\n",
										l->type_ext);
								break;

							case FRU_PICMGEXT_AMC_LINK_TYPE_ETHERNET:
								/* AMC.2 */
								printf( "        Link Type:       %02x - "
										"AMC.2 Ethernet\n",
										l->type);
								switch (l->type_ext) {
									case AMC_LINK_TYPE_EXT_ETH_1000_BX:
										printf( "        Link Type Ext:   %i - "
												" 1000Base-Bx (SerDES Gigabit) Ethernet Link\n",
												l->type_ext);
										break;

									case AMC_LINK_TYPE_EXT_ETH_10G_XAUI:
										printf( "        Link Type Ext:   %i - "
												" 10Gbit XAUI Ethernet Link\n",
										l->type_ext);
										break;

									default:
										printf( "        Link Type Ext:   %i - "
												" Invalid\n",
												l->type_ext);
										break;
								}
								break;

							case FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE:
								/* AMC.3 */
								printf( "        Link Type:       %02x - "
										"AMC.3 Storage\n",
										l->type);
								switch (l->type_ext) {
									case AMC_LINK_TYPE_EXT_STORAGE_FC:
										printf( "        Link Type Ext:   %i - "
												" Fibre Channel\n",
												l->type_ext);
										break;

									case AMC_LINK_TYPE_EXT_STORAGE_SATA:
										printf( "        Link Type Ext:   %i - "
												" Serial ATA\n",
												l->type_ext);
										break;

									case AMC_LINK_TYPE_EXT_STORAGE_SAS:
										printf( "        Link Type Ext:   %i - "
												" Serial Attached SCSI\n",
												l->type_ext);
										break;

									default:
										printf( "        Link Type Ext:   %i - "
												" Invalid\n",
												l->type_ext);
										break;
								}
								break;

							case FRU_PICMGEXT_AMC_LINK_TYPE_RAPIDIO:
								/* AMC.4 */
								printf( "        Link Type:       %02x - "
										"AMC.4 Serial Rapid IO\n",
										l->type);
								printf("        Link Type Ext:   %i\n",
										l->type_ext);
								break;

							default:
								printf( "        Link Type:       %02x - "
										"reserved or OEM GUID",
										l->type);
								printf("        Link Type Ext:   %i\n",
										l->type_ext);
								break;
						}

						printf("        Link group Id:   %i\n",
								l->group_id);
						printf("        Link Asym Match: %i\n\n",
								l->asym_match);
						offset += FRU_PICMGEXT_AMC_LINK_DESC_RECORD_SIZE;
					}
				}
			}
			break;

		case FRU_AMC_CARRIER_INFO:
		{
			unsigned char extVersion;
			unsigned char siteCount;

			printf("    FRU_CARRIER_INFO\n");

			extVersion = fru_data[offset++];
			siteCount  = fru_data[offset++];

			printf("      AMC.0 extension version: R%d.%d\n",
					(extVersion >> 0)& 0x0F,
					(extVersion >> 4)& 0x0F );
			printf("      Carrier Sie Number Cnt: %d\n", siteCount);

			for (i = 0 ; i < siteCount; i++ ){
				printf("       Site ID: %i \n", fru_data[offset++]);
			}
			printf("\n");
		}
		break;
		case FRU_PICMG_CLK_CARRIER_P2P:
		{
			unsigned char desc_count;
			int i,j;

			printf("    FRU_PICMG_CLK_CARRIER_P2P\n");

			desc_count = fru_data[offset++];

			for(i=0; i<desc_count; i++){
				unsigned char resource_id;
				unsigned char channel_count;

				resource_id   = fru_data[offset++];
				channel_count = fru_data[offset++];

				printf("\n");
				printf("      Clock Resource ID: 0x%02x  Type: ", resource_id);
				if((resource_id & 0xC0)>>6 == 0) {printf("On-Carrier-Device\n");}
				else if((resource_id & 0xC0)>>6 == 1) {printf("AMC slot\n");}
				else if((resource_id & 0xC0)>>6 == 2) {printf("Backplane\n");}
				else{ printf("reserved\n");}
				printf("      Channel Count: 0x%02x\n", channel_count);

				for(j=0; j<channel_count; j++){
					unsigned char loc_channel, rem_channel, rem_resource;

					loc_channel  = fru_data[offset++];
					rem_channel  = fru_data[offset++];
					rem_resource = fru_data[offset++];

					printf("        CLK-ID: 0x%02x    ->", loc_channel);
					printf(" remote CLKID: 0x%02x   ", rem_channel);
					if((rem_resource & 0xC0)>>6 == 0) {printf("[ Carrier-Dev");}
					else if((rem_resource & 0xC0)>>6 == 1) {printf("[ AMC slot   ");}
					else if((rem_resource & 0xC0)>>6 == 2) {printf("[ Backplane  ");}
					else{ printf("reserved         ");}
					printf(" 0x%02x ]\n", rem_resource&0xF);
				}
			}
			printf("\n");
		}
		break;
		case FRU_PICMG_CLK_CONFIG:
		{
			unsigned char resource_id, descr_count;
			int i,j;

			printf("    FRU_PICMG_CLK_CONFIG\n");

			resource_id = fru_data[offset++];
			descr_count = fru_data[offset++];

			printf("\n");
			printf("      Clock Resource ID: 0x%02x\n", resource_id);
			printf("      Descr. Count:      0x%02x\n", descr_count);

			for(i=0; i<descr_count; i++){
				unsigned char channel_id, control;
				unsigned char indirect_cnt, direct_cnt;

				channel_id = fru_data[offset++];
				control    = fru_data[offset++];
				printf("        CLK-ID: 0x%02x  -  ", channel_id);
				printf("CTRL 0x%02x [ %12s ]\n",
									control,
									((control&0x1)==0)?"Carrier IPMC":"Application");

				indirect_cnt = fru_data[offset++];
				direct_cnt   = fru_data[offset++];
				printf("         Cnt: Indirect 0x%02x  /  Direct 0x%02x\n",
						indirect_cnt,
						direct_cnt);

				/* indirect desc */
				for(j=0; j<indirect_cnt; j++){
					unsigned char feature;
					unsigned char dep_chn_id;

					feature    = fru_data[offset++];
					dep_chn_id = fru_data[offset++];

					printf("          Feature: 0x%02x [%8s] - ", feature, (feature&0x1)==1?"Source":"Receiver");
					printf("          Dep. CLK-ID: 0x%02x\n", dep_chn_id);
				}

				/* direct desc */
				for(j=0; j<direct_cnt; j++){
					unsigned char feature, family, accuracy;
					unsigned int freq, min_freq, max_freq;

					feature  = fru_data[offset++];
					family   = fru_data[offset++];
					accuracy = fru_data[offset++];
					freq     = (fru_data[offset+0] << 0 ) | (fru_data[offset+1] << 8 )
								| (fru_data[offset+2] << 16) | (fru_data[offset+3] << 24);
					offset += 4;
					min_freq = (fru_data[offset+0] << 0 ) | (fru_data[offset+1] << 8 )
								| (fru_data[offset+2] << 16) | (fru_data[offset+3] << 24);
					offset += 4;
					max_freq = (fru_data[offset+0] << 0 ) | (fru_data[offset+1] << 8 )
								| (fru_data[offset+2] << 16) | (fru_data[offset+3] << 24);
					offset += 4;

					printf("          - Feature: 0x%02x  - PLL: %x / Asym: %s\n",
							feature,
							(feature > 1) & 1,
							(feature&1)?"Source":"Receiver");
					printf("            Family:  0x%02x  - AccLVL: 0x%02x\n", family, accuracy);
					printf("            FRQ: %-9ld - min: %-9ld - max: %-9ld\n",
							freq, min_freq, max_freq);
				}
				printf("\n");
			}
			printf("\n");
		}
		break;

		case FRU_UTCA_FRU_INFO_TABLE:
		case FRU_UTCA_CARRIER_MNG_IP:
		case FRU_UTCA_CARRIER_INFO:
		case FRU_UTCA_CARRIER_LOCATION:
		case FRU_UTCA_SHMC_IP_LINK:
		case FRU_UTCA_POWER_POLICY:
		case FRU_UTCA_ACTIVATION:
		case FRU_UTCA_PM_CAPABILTY:
		case FRU_UTCA_FAN_GEOGRAPHY:
		case FRU_UTCA_CLOCK_MAPPING:
		case FRU_UTCA_MSG_BRIDGE_POLICY:
		case FRU_UTCA_OEM_MODULE_DESC:
			printf("    Not implemented yet. uTCA specific record found!!\n");
			printf("     - Record ID: 0x%02x\n", h->record_id);
		break;

		default:
			printf("    Unknown OEM Extension Record ID: %x\n", h->record_id);
		break;

	}
}