CMD_A0_ROC | CMD_A0_TOC;
xfer->cmd_desc[1] = 0;
xfer->completion = &done;
- hci->io->queue_xfer(hci, xfer, 1);
- if (!wait_for_completion_timeout(&done, HZ) &&
- hci->io->dequeue_xfer(hci, xfer, 1)) {
- ret = -ETIMEDOUT;
+ xfer->timeout = HZ;
+ ret = i3c_hci_process_xfer(hci, xfer, 1);
+ if (ret)
break;
- }
if ((RESP_STATUS(xfer->response) == RESP_ERR_ADDR_HEADER ||
RESP_STATUS(xfer->response) == RESP_ERR_NACK) &&
RESP_DATA_LENGTH(xfer->response) == 1) {
xfer[0].rnw = true;
xfer[0].cmd_desc[1] = CMD_A1_DATA_LENGTH(8);
xfer[1].completion = &done;
+ xfer[1].timeout = HZ;
for (;;) {
ret = i3c_master_get_free_addr(&hci->master, next_addr);
CMD_A0_ASSIGN_ADDRESS(next_addr) |
CMD_A0_ROC |
CMD_A0_TOC;
- hci->io->queue_xfer(hci, xfer, 2);
- if (!wait_for_completion_timeout(&done, HZ) &&
- hci->io->dequeue_xfer(hci, xfer, 2)) {
- ret = -ETIMEDOUT;
+ ret = i3c_hci_process_xfer(hci, xfer, 2);
+ if (ret)
break;
- }
if (RESP_STATUS(xfer[0].response) != RESP_SUCCESS) {
ret = 0; /* no more devices to be assigned */
break;
reg_write(DCT_SECTION, FIELD_PREP(DCT_TABLE_INDEX, 0));
}
+int i3c_hci_process_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n)
+{
+ struct completion *done = xfer[n - 1].completion;
+ unsigned long timeout = xfer[n - 1].timeout;
+ int ret;
+
+ ret = hci->io->queue_xfer(hci, xfer, n);
+ if (ret)
+ return ret;
+
+ if (!wait_for_completion_timeout(done, timeout) &&
+ hci->io->dequeue_xfer(hci, xfer, n)) {
+ dev_err(&hci->master.dev, "%s: timeout error\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
static int i3c_hci_send_ccc_cmd(struct i3c_master_controller *m,
struct i3c_ccc_cmd *ccc)
{
last = i - 1;
xfer[last].cmd_desc[0] |= CMD_0_TOC;
xfer[last].completion = &done;
+ xfer[last].timeout = HZ;
if (prefixed)
xfer--;
- ret = hci->io->queue_xfer(hci, xfer, nxfers);
+ ret = i3c_hci_process_xfer(hci, xfer, nxfers);
if (ret)
goto out;
- if (!wait_for_completion_timeout(&done, HZ) &&
- hci->io->dequeue_xfer(hci, xfer, nxfers)) {
- ret = -ETIMEDOUT;
- goto out;
- }
for (i = prefixed; i < nxfers; i++) {
if (ccc->rnw)
ccc->dests[i - prefixed].payload.len =
last = i - 1;
xfer[last].cmd_desc[0] |= CMD_0_TOC;
xfer[last].completion = &done;
+ xfer[last].timeout = HZ;
- ret = hci->io->queue_xfer(hci, xfer, nxfers);
+ ret = i3c_hci_process_xfer(hci, xfer, nxfers);
if (ret)
goto out;
- if (!wait_for_completion_timeout(&done, HZ) &&
- hci->io->dequeue_xfer(hci, xfer, nxfers)) {
- ret = -ETIMEDOUT;
- goto out;
- }
for (i = 0; i < nxfers; i++) {
if (i3c_xfers[i].rnw)
i3c_xfers[i].len = RESP_DATA_LENGTH(xfer[i].response);
last = i - 1;
xfer[last].cmd_desc[0] |= CMD_0_TOC;
xfer[last].completion = &done;
+ xfer[last].timeout = m->i2c.timeout;
- ret = hci->io->queue_xfer(hci, xfer, nxfers);
+ ret = i3c_hci_process_xfer(hci, xfer, nxfers);
if (ret)
goto out;
- if (!wait_for_completion_timeout(&done, m->i2c.timeout) &&
- hci->io->dequeue_xfer(hci, xfer, nxfers)) {
- ret = -ETIMEDOUT;
- goto out;
- }
for (i = 0; i < nxfers; i++) {
if (RESP_STATUS(xfer[i].response) != RESP_SUCCESS) {
ret = -EIO;