1e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* 2e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * Copyright (C) 2012 CERN (www.cern.ch) 3e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * Author: Alessandro Rubini <rubini@gnudd.com> 4e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * 5e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * Released according to the GNU GPL, version 2 or any later version. 6e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * 7e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * This work is part of the White Rabbit project, a research effort led 8e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * by CERN, the European Institute for Nuclear Research. 9e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini */ 10e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini#ifndef __LINUX_IPMI_FRU_H__ 11e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini#define __LINUX_IPMI_FRU_H__ 12e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini#ifdef __KERNEL__ 13e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini# include <linux/types.h> 14e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini# include <linux/string.h> 15e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini#else 16e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini# include <stdint.h> 17e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini# include <string.h> 18e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini#endif 19e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 20e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* 21e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * These structures match the unaligned crap we have in FRU1011.pdf 22e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * (http://download.intel.com/design/servers/ipmi/FRU1011.pdf) 23e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini */ 24e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 25e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* chapter 8, page 5 */ 26e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinistruct fru_common_header { 27e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t format; /* 0x01 */ 28e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t internal_use_off; /* multiple of 8 bytes */ 29e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t chassis_info_off; /* multiple of 8 bytes */ 30e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t board_area_off; /* multiple of 8 bytes */ 31e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t product_area_off; /* multiple of 8 bytes */ 32e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t multirecord_off; /* multiple of 8 bytes */ 33e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t pad; /* must be 0 */ 34e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t checksum; /* sum modulo 256 must be 0 */ 35e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini}; 36e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 37e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* chapter 9, page 5 -- internal_use: not used by us */ 38e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 39e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* chapter 10, page 6 -- chassis info: not used by us */ 40e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 41e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* chapter 13, page 9 -- used by board_info_area below */ 42e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinistruct fru_type_length { 43e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t type_length; 44e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t data[0]; 45e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini}; 46e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 47e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* chapter 11, page 7 */ 48e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinistruct fru_board_info_area { 49e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t format; /* 0x01 */ 50e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t area_len; /* multiple of 8 bytes */ 51e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t language; /* I hope it's 0 */ 52e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini uint8_t mfg_date[3]; /* LSB, minutes since 1996-01-01 */ 53e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini struct fru_type_length tl[0]; /* type-length stuff follows */ 54e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 55e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini /* 56e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * the TL there are in order: 57e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * Board Manufacturer 58e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * Board Product Name 59e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * Board Serial Number 60e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * Board Part Number 61e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * FRU File ID (may be null) 62e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * more manufacturer-specific stuff 63e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * 0xc1 as a terminator 64e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * 0x00 pad to a multiple of 8 bytes - 1 65e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * checksum (sum of all stuff module 256 must be zero) 66e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini */ 67e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini}; 68e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 69e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinienum fru_type { 70e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini FRU_TYPE_BINARY = 0x00, 71e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini FRU_TYPE_BCDPLUS = 0x40, 72e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini FRU_TYPE_ASCII6 = 0x80, 73e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini FRU_TYPE_ASCII = 0xc0, /* not ascii: depends on language */ 74e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini}; 75e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 76e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* 77e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * some helpers 78e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini */ 79e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinistatic inline struct fru_board_info_area *fru_get_board_area( 80e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini const struct fru_common_header *header) 81e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini{ 82e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini /* we know for sure that the header is 8 bytes in size */ 83e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini return (struct fru_board_info_area *)(header + header->board_area_off); 84e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini} 85e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 86e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinistatic inline int fru_type(struct fru_type_length *tl) 87e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini{ 88e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini return tl->type_length & 0xc0; 89e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini} 90e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 91e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinistatic inline int fru_length(struct fru_type_length *tl) 92e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini{ 93e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini return (tl->type_length & 0x3f) + 1; /* len of whole record */ 94e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini} 95e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 96e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* assume ascii-latin1 encoding */ 97e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinistatic inline int fru_strlen(struct fru_type_length *tl) 98e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini{ 99e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini return fru_length(tl) - 1; 100e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini} 101e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 102e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinistatic inline char *fru_strcpy(char *dest, struct fru_type_length *tl) 103e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini{ 104e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini int len = fru_strlen(tl); 105e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini memcpy(dest, tl->data, len); 106e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini dest[len] = '\0'; 107e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini return dest; 108e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini} 109e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 110e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinistatic inline struct fru_type_length *fru_next_tl(struct fru_type_length *tl) 111e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini{ 112e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini return tl + fru_length(tl); 113e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini} 114e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 115e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubinistatic inline int fru_is_eof(struct fru_type_length *tl) 116e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini{ 117e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini return tl->type_length == 0xc1; 118e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini} 119e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 120e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* 121e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini * External functions defined in fru-parse.c. 122e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini */ 123e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubiniextern int fru_header_cksum_ok(struct fru_common_header *header); 124e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubiniextern int fru_bia_cksum_ok(struct fru_board_info_area *bia); 125e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 126e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* All these 4 return allocated strings by calling fru_alloc() */ 127e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubiniextern char *fru_get_board_manufacturer(struct fru_common_header *header); 128e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubiniextern char *fru_get_product_name(struct fru_common_header *header); 129e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubiniextern char *fru_get_serial_number(struct fru_common_header *header); 130e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubiniextern char *fru_get_part_number(struct fru_common_header *header); 131e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 132e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini/* This must be defined by the caller of the above functions */ 133e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubiniextern void *fru_alloc(size_t size); 134e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini 135e34fae7841b12d77f2621bd28fd41929879ef951Alessandro Rubini#endif /* __LINUX_IMPI_FRU_H__ */ 136