in fsi-sbefifo.c [215:255]
int sbefifo_parse_status(struct device *dev, u16 cmd, __be32 *response,
size_t resp_len, size_t *data_len)
{
u32 dh, s0, s1;
size_t ffdc_sz;
if (resp_len < 3) {
pr_debug("sbefifo: cmd %04x, response too small: %zd\n",
cmd, resp_len);
return -ENXIO;
}
dh = be32_to_cpu(response[resp_len - 1]);
if (dh > resp_len || dh < 3) {
dev_err(dev, "SBE cmd %02x:%02x status offset out of range: %d/%zd\n",
cmd >> 8, cmd & 0xff, dh, resp_len);
return -ENXIO;
}
s0 = be32_to_cpu(response[resp_len - dh]);
s1 = be32_to_cpu(response[resp_len - dh + 1]);
if (((s0 >> 16) != 0xC0DE) || ((s0 & 0xffff) != cmd)) {
dev_err(dev, "SBE cmd %02x:%02x, status signature invalid: 0x%08x 0x%08x\n",
cmd >> 8, cmd & 0xff, s0, s1);
return -ENXIO;
}
if (s1 != 0) {
ffdc_sz = dh - 3;
dev_warn(dev, "SBE error cmd %02x:%02x status=%04x:%04x\n",
cmd >> 8, cmd & 0xff, s1 >> 16, s1 & 0xffff);
if (ffdc_sz)
sbefifo_dump_ffdc(dev, &response[resp_len - dh + 2],
ffdc_sz, false);
}
if (data_len)
*data_len = resp_len - dh;
/*
* Primary status don't have the top bit set, so can't be confused with
* Linux negative error codes, so return the status word whole.
*/
return s1;
}