Commit 624cf5b5 authored by Finn Thain's avatar Finn Thain Committed by Michael Ellerman

macintosh/via-macii: Handle poll replies correctly

Userspace applications may use /dev/adb to send Talk requests. Such
requests always have req->reply_expected == 1. The same is true of Talk
requests sent by the kernel, except for poll requests queued internally
by the via-macii driver. Those requests have req->reply_expected == 0.

Consequently, poll reply packets get treated like autopoll reply packets.
(It doesn't make sense to try to distinguish them.) Always enter 'reading'
state after a poll request, so that the reply gets collected and passed
to adb_input(), and none go missing.

All Talk replies passed to adb_input() come from polling or autopolling,
so call adb_input() with the autopoll parameter set to 1.

Fixes: d95fd5fc ("m68k: Mac II ADB fixes") # v5.0+
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Tested-by: default avatarStan Johnson <userm57@yahoo.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/754cddfa045e5bfa53e5da199831de02e7d2f27f.1593318192.git.fthain@telegraphics.com.au
parent b16b6768
...@@ -463,6 +463,21 @@ static irqreturn_t macii_interrupt(int irq, void *arg) ...@@ -463,6 +463,21 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
via[ACR] &= ~SR_OUT; via[ACR] &= ~SR_OUT;
x = via[SR]; x = via[SR];
} else if ((req->data[1] & OP_MASK) == TALK) {
macii_state = reading;
reading_reply = 0;
reply_ptr = reply_buf;
*reply_ptr = req->data[1];
reply_len = 1;
via[ACR] &= ~SR_OUT;
x = via[SR];
req->complete = 1;
current_req = req->next;
if (req->done)
(*req->done)(req);
} else { } else {
macii_state = idle; macii_state = idle;
...@@ -510,8 +525,9 @@ static irqreturn_t macii_interrupt(int irq, void *arg) ...@@ -510,8 +525,9 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
current_req = req->next; current_req = req->next;
if (req->done) if (req->done)
(*req->done)(req); (*req->done)(req);
} else if (reply_len && autopoll_devs) { } else if (reply_len && autopoll_devs &&
adb_input(reply_buf, reply_len, 0); reply_buf[0] == last_poll_cmd) {
adb_input(reply_buf, reply_len, 1);
} }
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment