in fsi-master-gpio.c [334:395]
static int read_one_response(struct fsi_master_gpio *master,
uint8_t data_size, struct fsi_gpio_msg *msgp, uint8_t *tagp)
{
struct fsi_gpio_msg msg;
unsigned long flags;
uint32_t crc;
uint8_t tag;
int i;
local_irq_save(flags);
/* wait for the start bit */
for (i = 0; i < FSI_MASTER_MTOE_COUNT; i++) {
msg.bits = 0;
msg.msg = 0;
serial_in(master, &msg, 1);
if (msg.msg)
break;
}
if (i == FSI_MASTER_MTOE_COUNT) {
dev_dbg(master->dev,
"Master time out waiting for response\n");
local_irq_restore(flags);
return -ETIMEDOUT;
}
msg.bits = 0;
msg.msg = 0;
/* Read slave ID & response tag */
serial_in(master, &msg, 4);
tag = msg.msg & 0x3;
/* If we have an ACK and we're expecting data, clock the data in too */
if (tag == FSI_RESP_ACK && data_size)
serial_in(master, &msg, data_size * 8);
/* read CRC */
serial_in(master, &msg, FSI_CRC_SIZE);
local_irq_restore(flags);
/* we have a whole message now; check CRC */
crc = crc4(0, 1, 1);
crc = crc4(crc, msg.msg, msg.bits);
if (crc) {
/* Check if it's all 1's, that probably means the host is off */
if (((~msg.msg) & ((1ull << msg.bits) - 1)) == 0)
return -ENODEV;
dev_dbg(master->dev, "ERR response CRC msg: 0x%016llx (%d bits)\n",
msg.msg, msg.bits);
return -EAGAIN;
}
if (msgp)
*msgp = msg;
if (tagp)
*tagp = tag;
return 0;
}