in master/mipi-i3c-hci/pio.c [473:540]
static void hci_pio_err(struct i3c_hci *hci, struct hci_pio_data *pio,
u32 status);
static bool hci_pio_process_resp(struct i3c_hci *hci, struct hci_pio_data *pio)
{
while (pio->curr_resp &&
(pio_reg_read(INTR_STATUS) & STAT_RESP_READY)) {
struct hci_xfer *xfer = pio->curr_resp;
u32 resp = pio_reg_read(RESPONSE_QUEUE_PORT);
unsigned int tid = RESP_TID(resp);
DBG("resp = 0x%08x", resp);
if (tid != xfer->cmd_tid) {
dev_err(&hci->master.dev,
"response tid=%d when expecting %d\n",
tid, xfer->cmd_tid);
/* let's pretend it is a prog error... any of them */
hci_pio_err(hci, pio, STAT_PROG_ERRORS);
return false;
}
xfer->response = resp;
if (pio->curr_rx == xfer) {
/*
* Response availability implies RX completion.
* Retrieve trailing RX data if any.
* Note that short reads are possible.
*/
unsigned int received, expected, to_keep;
received = xfer->data_len - xfer->data_left;
expected = RESP_DATA_LENGTH(xfer->response);
if (expected > received) {
hci_pio_do_trailing_rx(hci, pio,
expected - received);
} else if (received > expected) {
/* we consumed data meant for next xfer */
to_keep = DIV_ROUND_UP(expected, 4);
hci_pio_push_to_next_rx(hci, xfer, to_keep);
}
/* then process the RX list pointer */
if (hci_pio_process_rx(hci, pio))
pio->enabled_irqs &= ~STAT_RX_THLD;
}
/*
* We're about to give back ownership of the xfer structure
* to the waiting instance. Make sure no reference to it
* still exists.
*/
if (pio->curr_rx == xfer) {
DBG("short RX ?");
pio->curr_rx = pio->curr_rx->next_data;
} else if (pio->curr_tx == xfer) {
DBG("short TX ?");
pio->curr_tx = pio->curr_tx->next_data;
} else if (xfer->data_left) {
DBG("PIO xfer count = %d after response",
xfer->data_left);
}
pio->curr_resp = xfer->next_resp;
if (xfer->completion)
complete(xfer->completion);
}
return !pio->curr_resp;
}