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: d95fd5fce88f0 ("m68k: Mac II ADB fixes") # v5.0+
Tested-by: Stan Johnson <user...@yahoo.com>
Signed-off-by: Finn Thain <fth...@telegraphics.com.au>
---
 drivers/macintosh/via-macii.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index d29c87943ca46..8d5ef77b4a435 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -463,6 +463,21 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
 
                                via[ACR] &= ~SR_OUT;
                                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 {
                                macii_state = idle;
 
@@ -510,8 +525,9 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
                                        current_req = req->next;
                                        if (req->done)
                                                (*req->done)(req);
-                               } else if (reply_len && autopoll_devs) {
-                                       adb_input(reply_buf, reply_len, 0);
+                               } else if (reply_len && autopoll_devs &&
+                                          reply_buf[0] == last_poll_cmd) {
+                                       adb_input(reply_buf, reply_len, 1);
                                }
                                break;
                        }
-- 
2.26.2

Reply via email to