aboutsummaryrefslogtreecommitdiff
path: root/hdata/i2c.c
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2017-05-24 18:09:12 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-05-26 16:00:18 +1000
commit41dc3eb4495c451a405974570f604622a3f829ef (patch)
tree31e9f165230383d8388085f764d4f9ccf8c5885c /hdata/i2c.c
parent3bb3f137d0b92e5f7ec596a07acd5eada0c09cc3 (diff)
downloadskiboot-41dc3eb4495c451a405974570f604622a3f829ef.zip
skiboot-41dc3eb4495c451a405974570f604622a3f829ef.tar.gz
skiboot-41dc3eb4495c451a405974570f604622a3f829ef.tar.bz2
hdata: Check the Host I2C devices array version
Currently this is not populated on FSP machines which causes some obnoxious errors to appear in the boot log. We also only want to parse version 1 of this structure since future versions will completely change the array item format. Cc: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com> [stewart@linux.vnet.ibm.com: return -1 on error rather than 1] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hdata/i2c.c')
-rw-r--r--hdata/i2c.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/hdata/i2c.c b/hdata/i2c.c
index f5c5baf..62933e6 100644
--- a/hdata/i2c.c
+++ b/hdata/i2c.c
@@ -149,6 +149,11 @@ static bool is_zeros(const void *p, size_t size)
return true;
}
+struct host_i2c_hdr {
+ const struct HDIF_array_hdr hdr;
+ __be32 version;
+};
+
int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index,
struct dt_node *xscom)
{
@@ -156,7 +161,9 @@ int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index,
const struct hdat_i2c_type *type;
const struct i2c_dev *dev;
const char *label, *name, *compat;
+ const struct host_i2c_hdr *ahdr;
uint32_t i2c_addr;
+ uint32_t version;
uint32_t size;
int i, count;
@@ -166,6 +173,32 @@ int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index,
*/
assert(proc_gen == proc_gen_p9);
+ /*
+ * Emit an error if we get a newer version. This is an interim measure
+ * until the new version format is finalised.
+ */
+ ahdr = HDIF_get_idata(hdr, idata_index, &size);
+ if (!ahdr || !size)
+ return -1;
+
+ /*
+ * Some hostboots don't correctly fill the version field. On these
+ * the offset from the start of the header to the start of the array
+ * is 16 bytes.
+ */
+ if (be32_to_cpu(ahdr->hdr.offset) == 16) {
+ version = 1;
+ prerror("I2C: HDAT device array has no version! Assuming v1\n");
+ } else {
+ version = be32_to_cpu(hdr->version);
+ }
+
+ if (version != 1) {
+ prerror("I2C: HDAT version %d not supported! THIS IS A BUG\n",
+ version);
+ return -1;
+ }
+
count = HDIF_get_iarray_size(hdr, idata_index);
for (i = 0; i < count; i++) {
dev = HDIF_get_iarray_item(hdr, idata_index, i, &size);