in fsi-sbefifo.c [540:622]
static int sbefifo_read_response(struct sbefifo *sbefifo, struct iov_iter *response)
{
struct device *dev = &sbefifo->fsi_dev->dev;
u32 status, eot_set;
unsigned long timeout;
bool overflow = false;
__be32 data;
size_t len;
int rc;
dev_vdbg(dev, "reading response, buflen = %zd\n", iov_iter_count(response));
timeout = msecs_to_jiffies(SBEFIFO_TIMEOUT_START_RSP);
for (;;) {
/* Grab FIFO status (this will handle parity errors) */
rc = sbefifo_wait(sbefifo, false, &status, timeout);
if (rc < 0)
return rc;
timeout = msecs_to_jiffies(SBEFIFO_TIMEOUT_IN_RSP);
/* Decode status */
len = sbefifo_populated(status);
eot_set = sbefifo_eot_set(status);
dev_vdbg(dev, " chunk size %zd eot_set=0x%x\n", len, eot_set);
/* Go through the chunk */
while(len--) {
/* Read the data */
rc = sbefifo_down_read(sbefifo, &data);
if (rc < 0)
return rc;
/* Was it an EOT ? */
if (eot_set & 0x80) {
/*
* There should be nothing else in the FIFO,
* if there is, mark broken, this will force
* a reset on next use, but don't fail the
* command.
*/
if (len) {
dev_warn(dev, "FIFO read hit"
" EOT with still %zd data\n",
len);
sbefifo->broken = true;
}
/* We are done */
rc = sbefifo_regw(sbefifo,
SBEFIFO_DOWN | SBEFIFO_EOT_ACK, 0);
/*
* If that write fail, still complete the request but mark
* the fifo as broken for subsequent reset (not much else
* we can do here).
*/
if (rc) {
dev_err(dev, "FSI error %d ack'ing EOT\n", rc);
sbefifo->broken = true;
}
/* Tell whether we overflowed */
return overflow ? -EOVERFLOW : 0;
}
/* Store it if there is room */
if (iov_iter_count(response) >= sizeof(__be32)) {
if (copy_to_iter(&data, sizeof(__be32), response) < sizeof(__be32))
return -EFAULT;
} else {
dev_vdbg(dev, "Response overflowed !\n");
overflow = true;
}
/* Next EOT bit */
eot_set <<= 1;
}
}
/* Shouldn't happen */
return -EIO;
}