linux/drivers/macintosh/via-cuda.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Device driver for the Cuda and Egret system controllers found on PowerMacs
   4 * and 68k Macs.
   5 *
   6 * The Cuda or Egret is a 6805 microcontroller interfaced to the 6522 VIA.
   7 * This MCU controls system power, Parameter RAM, Real Time Clock and the
   8 * Apple Desktop Bus (ADB) that connects to the keyboard and mouse.
   9 *
  10 * Copyright (C) 1996 Paul Mackerras.
  11 */
  12#include <stdarg.h>
  13#include <linux/types.h>
  14#include <linux/errno.h>
  15#include <linux/kernel.h>
  16#include <linux/delay.h>
  17#include <linux/adb.h>
  18#include <linux/cuda.h>
  19#include <linux/spinlock.h>
  20#include <linux/interrupt.h>
  21#ifdef CONFIG_PPC
  22#include <asm/prom.h>
  23#include <asm/machdep.h>
  24#else
  25#include <asm/macintosh.h>
  26#include <asm/macints.h>
  27#include <asm/mac_via.h>
  28#endif
  29#include <asm/io.h>
  30#include <linux/init.h>
  31
  32static volatile unsigned char __iomem *via;
  33static DEFINE_SPINLOCK(cuda_lock);
  34
  35/* VIA registers - spaced 0x200 bytes apart */
  36#define RS              0x200           /* skip between registers */
  37#define B               0               /* B-side data */
  38#define A               RS              /* A-side data */
  39#define DIRB            (2*RS)          /* B-side direction (1=output) */
  40#define DIRA            (3*RS)          /* A-side direction (1=output) */
  41#define T1CL            (4*RS)          /* Timer 1 ctr/latch (low 8 bits) */
  42#define T1CH            (5*RS)          /* Timer 1 counter (high 8 bits) */
  43#define T1LL            (6*RS)          /* Timer 1 latch (low 8 bits) */
  44#define T1LH            (7*RS)          /* Timer 1 latch (high 8 bits) */
  45#define T2CL            (8*RS)          /* Timer 2 ctr/latch (low 8 bits) */
  46#define T2CH            (9*RS)          /* Timer 2 counter (high 8 bits) */
  47#define SR              (10*RS)         /* Shift register */
  48#define ACR             (11*RS)         /* Auxiliary control register */
  49#define PCR             (12*RS)         /* Peripheral control register */
  50#define IFR             (13*RS)         /* Interrupt flag register */
  51#define IER             (14*RS)         /* Interrupt enable register */
  52#define ANH             (15*RS)         /* A-side data, no handshake */
  53
  54/*
  55 * When the Cuda design replaced the Egret, some signal names and
  56 * logic sense changed. They all serve the same purposes, however.
  57 *
  58 *   VIA pin       |  Egret pin
  59 * ----------------+------------------------------------------
  60 *   PB3 (input)   |  Transceiver session   (active low)
  61 *   PB4 (output)  |  VIA full              (active high)
  62 *   PB5 (output)  |  System session        (active high)
  63 *
  64 *   VIA pin       |  Cuda pin
  65 * ----------------+------------------------------------------
  66 *   PB3 (input)   |  Transfer request      (active low)
  67 *   PB4 (output)  |  Byte acknowledge      (active low)
  68 *   PB5 (output)  |  Transfer in progress  (active low)
  69 */
  70
  71/* Bits in Port B data register */
  72#define TREQ            0x08            /* Transfer request */
  73#define TACK            0x10            /* Transfer acknowledge */
  74#define TIP             0x20            /* Transfer in progress */
  75
  76/* Bits in ACR */
  77#define SR_CTRL         0x1c            /* Shift register control bits */
  78#define SR_EXT          0x0c            /* Shift on external clock */
  79#define SR_OUT          0x10            /* Shift out if 1 */
  80
  81/* Bits in IFR and IER */
  82#define IER_SET         0x80            /* set bits in IER */
  83#define IER_CLR         0               /* clear bits in IER */
  84#define SR_INT          0x04            /* Shift register full/empty */
  85
  86/* Duration of byte acknowledgement pulse (us) */
  87#define EGRET_TACK_ASSERTED_DELAY       300
  88#define EGRET_TACK_NEGATED_DELAY        400
  89
  90/* Interval from interrupt to start of session (us) */
  91#define EGRET_SESSION_DELAY             450
  92
  93#ifdef CONFIG_PPC
  94#define mcu_is_egret    false
  95#else
  96static bool mcu_is_egret;
  97#endif
  98
  99static inline bool TREQ_asserted(u8 portb)
 100{
 101        return !(portb & TREQ);
 102}
 103
 104static inline void assert_TIP(void)
 105{
 106        if (mcu_is_egret) {
 107                udelay(EGRET_SESSION_DELAY);
 108                out_8(&via[B], in_8(&via[B]) | TIP);
 109        } else
 110                out_8(&via[B], in_8(&via[B]) & ~TIP);
 111}
 112
 113static inline void assert_TIP_and_TACK(void)
 114{
 115        if (mcu_is_egret) {
 116                udelay(EGRET_SESSION_DELAY);
 117                out_8(&via[B], in_8(&via[B]) | TIP | TACK);
 118        } else
 119                out_8(&via[B], in_8(&via[B]) & ~(TIP | TACK));
 120}
 121
 122static inline void assert_TACK(void)
 123{
 124        if (mcu_is_egret) {
 125                udelay(EGRET_TACK_NEGATED_DELAY);
 126                out_8(&via[B], in_8(&via[B]) | TACK);
 127        } else
 128                out_8(&via[B], in_8(&via[B]) & ~TACK);
 129}
 130
 131static inline void toggle_TACK(void)
 132{
 133        out_8(&via[B], in_8(&via[B]) ^ TACK);
 134}
 135
 136static inline void negate_TACK(void)
 137{
 138        if (mcu_is_egret) {
 139                udelay(EGRET_TACK_ASSERTED_DELAY);
 140                out_8(&via[B], in_8(&via[B]) & ~TACK);
 141        } else
 142                out_8(&via[B], in_8(&via[B]) | TACK);
 143}
 144
 145static inline void negate_TIP_and_TACK(void)
 146{
 147        if (mcu_is_egret) {
 148                udelay(EGRET_TACK_ASSERTED_DELAY);
 149                out_8(&via[B], in_8(&via[B]) & ~(TIP | TACK));
 150        } else
 151                out_8(&via[B], in_8(&via[B]) | TIP | TACK);
 152}
 153
 154static enum cuda_state {
 155    idle,
 156    sent_first_byte,
 157    sending,
 158    reading,
 159    read_done,
 160    awaiting_reply
 161} cuda_state;
 162
 163static struct adb_request *current_req;
 164static struct adb_request *last_req;
 165static unsigned char cuda_rbuf[16];
 166static unsigned char *reply_ptr;
 167static int reading_reply;
 168static int data_index;
 169static int cuda_irq;
 170#ifdef CONFIG_PPC
 171static struct device_node *vias;
 172#endif
 173static int cuda_fully_inited;
 174
 175#ifdef CONFIG_ADB
 176static int cuda_probe(void);
 177static int cuda_send_request(struct adb_request *req, int sync);
 178static int cuda_adb_autopoll(int devs);
 179static int cuda_reset_adb_bus(void);
 180#endif /* CONFIG_ADB */
 181
 182static int cuda_init_via(void);
 183static void cuda_start(void);
 184static irqreturn_t cuda_interrupt(int irq, void *arg);
 185static void cuda_input(unsigned char *buf, int nb);
 186void cuda_poll(void);
 187static int cuda_write(struct adb_request *req);
 188
 189int cuda_request(struct adb_request *req,
 190                 void (*done)(struct adb_request *), int nbytes, ...);
 191
 192#ifdef CONFIG_ADB
 193struct adb_driver via_cuda_driver = {
 194        .name         = "CUDA",
 195        .probe        = cuda_probe,
 196        .send_request = cuda_send_request,
 197        .autopoll     = cuda_adb_autopoll,
 198        .poll         = cuda_poll,
 199        .reset_bus    = cuda_reset_adb_bus,
 200};
 201#endif /* CONFIG_ADB */
 202
 203#ifdef CONFIG_MAC
 204int __init find_via_cuda(void)
 205{
 206    struct adb_request req;
 207    int err;
 208
 209    if (macintosh_config->adb_type != MAC_ADB_CUDA &&
 210        macintosh_config->adb_type != MAC_ADB_EGRET)
 211        return 0;
 212
 213    via = via1;
 214    cuda_state = idle;
 215    mcu_is_egret = macintosh_config->adb_type == MAC_ADB_EGRET;
 216
 217    err = cuda_init_via();
 218    if (err) {
 219        printk(KERN_ERR "cuda_init_via() failed\n");
 220        via = NULL;
 221        return 0;
 222    }
 223
 224    /* enable autopoll */
 225    cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);
 226    while (!req.complete)
 227        cuda_poll();
 228
 229    return 1;
 230}
 231#else
 232int __init find_via_cuda(void)
 233{
 234    struct adb_request req;
 235    phys_addr_t taddr;
 236    const u32 *reg;
 237    int err;
 238
 239    if (vias != 0)
 240        return 1;
 241    vias = of_find_node_by_name(NULL, "via-cuda");
 242    if (vias == 0)
 243        return 0;
 244
 245    reg = of_get_property(vias, "reg", NULL);
 246    if (reg == NULL) {
 247            printk(KERN_ERR "via-cuda: No \"reg\" property !\n");
 248            goto fail;
 249    }
 250    taddr = of_translate_address(vias, reg);
 251    if (taddr == 0) {
 252            printk(KERN_ERR "via-cuda: Can't translate address !\n");
 253            goto fail;
 254    }
 255    via = ioremap(taddr, 0x2000);
 256    if (via == NULL) {
 257            printk(KERN_ERR "via-cuda: Can't map address !\n");
 258            goto fail;
 259    }
 260
 261    cuda_state = idle;
 262    sys_ctrler = SYS_CTRLER_CUDA;
 263
 264    err = cuda_init_via();
 265    if (err) {
 266        printk(KERN_ERR "cuda_init_via() failed\n");
 267        via = NULL;
 268        return 0;
 269    }
 270
 271    /* Clear and enable interrupts, but only on PPC. On 68K it's done  */
 272    /* for us by the main VIA driver in arch/m68k/mac/via.c        */
 273
 274    out_8(&via[IFR], 0x7f);     /* clear interrupts by writing 1s */
 275    out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */
 276
 277    /* enable autopoll */
 278    cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);
 279    while (!req.complete)
 280        cuda_poll();
 281
 282    return 1;
 283
 284 fail:
 285    of_node_put(vias);
 286    vias = NULL;
 287    return 0;
 288}
 289#endif /* !defined CONFIG_MAC */
 290
 291static int __init via_cuda_start(void)
 292{
 293    if (via == NULL)
 294        return -ENODEV;
 295
 296#ifdef CONFIG_MAC
 297    cuda_irq = IRQ_MAC_ADB;
 298#else
 299    cuda_irq = irq_of_parse_and_map(vias, 0);
 300    if (!cuda_irq) {
 301        printk(KERN_ERR "via-cuda: can't map interrupts for %pOF\n",
 302               vias);
 303        return -ENODEV;
 304    }
 305#endif
 306
 307    if (request_irq(cuda_irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
 308        printk(KERN_ERR "via-cuda: can't request irq %d\n", cuda_irq);
 309        return -EAGAIN;
 310    }
 311
 312    pr_info("Macintosh Cuda and Egret driver.\n");
 313
 314    cuda_fully_inited = 1;
 315    return 0;
 316}
 317
 318device_initcall(via_cuda_start);
 319
 320#ifdef CONFIG_ADB
 321static int
 322cuda_probe(void)
 323{
 324#ifdef CONFIG_PPC
 325    if (sys_ctrler != SYS_CTRLER_CUDA)
 326        return -ENODEV;
 327#else
 328    if (macintosh_config->adb_type != MAC_ADB_CUDA &&
 329        macintosh_config->adb_type != MAC_ADB_EGRET)
 330        return -ENODEV;
 331#endif
 332    if (via == NULL)
 333        return -ENODEV;
 334    return 0;
 335}
 336#endif /* CONFIG_ADB */
 337
 338static int __init sync_egret(void)
 339{
 340        if (TREQ_asserted(in_8(&via[B]))) {
 341                /* Complete the inbound transfer */
 342                assert_TIP_and_TACK();
 343                while (1) {
 344                        negate_TACK();
 345                        mdelay(1);
 346                        (void)in_8(&via[SR]);
 347                        assert_TACK();
 348                        if (!TREQ_asserted(in_8(&via[B])))
 349                                break;
 350                }
 351                negate_TIP_and_TACK();
 352        } else if (in_8(&via[B]) & TIP) {
 353                /* Terminate the outbound transfer */
 354                negate_TACK();
 355                assert_TACK();
 356                mdelay(1);
 357                negate_TIP_and_TACK();
 358        }
 359        /* Clear shift register interrupt */
 360        if (in_8(&via[IFR]) & SR_INT)
 361                (void)in_8(&via[SR]);
 362        return 0;
 363}
 364
 365#define WAIT_FOR(cond, what)                                    \
 366    do {                                                        \
 367        int x;                                                  \
 368        for (x = 1000; !(cond); --x) {                          \
 369            if (x == 0) {                                       \
 370                pr_err("Timeout waiting for " what "\n");       \
 371                return -ENXIO;                                  \
 372            }                                                   \
 373            udelay(100);                                        \
 374        }                                                       \
 375    } while (0)
 376
 377static int
 378__init cuda_init_via(void)
 379{
 380#ifdef CONFIG_PPC
 381    out_8(&via[IER], 0x7f);                                     /* disable interrupts from VIA */
 382    (void)in_8(&via[IER]);
 383#else
 384    out_8(&via[IER], SR_INT);                                   /* disable SR interrupt from VIA */
 385#endif
 386
 387    out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ); /* TACK & TIP out */
 388    out_8(&via[ACR], (in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT);    /* SR data in */
 389    (void)in_8(&via[SR]);                                       /* clear any left-over data */
 390
 391    if (mcu_is_egret)
 392        return sync_egret();
 393
 394    negate_TIP_and_TACK();
 395
 396    /* delay 4ms and then clear any pending interrupt */
 397    mdelay(4);
 398    (void)in_8(&via[SR]);
 399    out_8(&via[IFR], SR_INT);
 400
 401    /* sync with the CUDA - assert TACK without TIP */
 402    assert_TACK();
 403
 404    /* wait for the CUDA to assert TREQ in response */
 405    WAIT_FOR(TREQ_asserted(in_8(&via[B])), "CUDA response to sync");
 406
 407    /* wait for the interrupt and then clear it */
 408    WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (2)");
 409    (void)in_8(&via[SR]);
 410    out_8(&via[IFR], SR_INT);
 411
 412    /* finish the sync by negating TACK */
 413    negate_TACK();
 414
 415    /* wait for the CUDA to negate TREQ and the corresponding interrupt */
 416    WAIT_FOR(!TREQ_asserted(in_8(&via[B])), "CUDA response to sync (3)");
 417    WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (4)");
 418    (void)in_8(&via[SR]);
 419    out_8(&via[IFR], SR_INT);
 420
 421    return 0;
 422}
 423
 424#ifdef CONFIG_ADB
 425/* Send an ADB command */
 426static int
 427cuda_send_request(struct adb_request *req, int sync)
 428{
 429    int i;
 430
 431    if ((via == NULL) || !cuda_fully_inited) {
 432        req->complete = 1;
 433        return -ENXIO;
 434    }
 435  
 436    req->reply_expected = 1;
 437
 438    i = cuda_write(req);
 439    if (i)
 440        return i;
 441
 442    if (sync) {
 443        while (!req->complete)
 444            cuda_poll();
 445    }
 446    return 0;
 447}
 448
 449
 450/* Enable/disable autopolling */
 451static int
 452cuda_adb_autopoll(int devs)
 453{
 454    struct adb_request req;
 455
 456    if ((via == NULL) || !cuda_fully_inited)
 457        return -ENXIO;
 458
 459    cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, (devs? 1: 0));
 460    while (!req.complete)
 461        cuda_poll();
 462    return 0;
 463}
 464
 465/* Reset adb bus - how do we do this?? */
 466static int
 467cuda_reset_adb_bus(void)
 468{
 469    struct adb_request req;
 470
 471    if ((via == NULL) || !cuda_fully_inited)
 472        return -ENXIO;
 473
 474    cuda_request(&req, NULL, 2, ADB_PACKET, 0);         /* maybe? */
 475    while (!req.complete)
 476        cuda_poll();
 477    return 0;
 478}
 479#endif /* CONFIG_ADB */
 480
 481/* Construct and send a cuda request */
 482int
 483cuda_request(struct adb_request *req, void (*done)(struct adb_request *),
 484             int nbytes, ...)
 485{
 486    va_list list;
 487    int i;
 488
 489    if (via == NULL) {
 490        req->complete = 1;
 491        return -ENXIO;
 492    }
 493
 494    req->nbytes = nbytes;
 495    req->done = done;
 496    va_start(list, nbytes);
 497    for (i = 0; i < nbytes; ++i)
 498        req->data[i] = va_arg(list, int);
 499    va_end(list);
 500    req->reply_expected = 1;
 501    return cuda_write(req);
 502}
 503EXPORT_SYMBOL(cuda_request);
 504
 505static int
 506cuda_write(struct adb_request *req)
 507{
 508    unsigned long flags;
 509
 510    if (req->nbytes < 2 || req->data[0] > CUDA_PACKET) {
 511        req->complete = 1;
 512        return -EINVAL;
 513    }
 514    req->next = NULL;
 515    req->sent = 0;
 516    req->complete = 0;
 517    req->reply_len = 0;
 518
 519    spin_lock_irqsave(&cuda_lock, flags);
 520    if (current_req != 0) {
 521        last_req->next = req;
 522        last_req = req;
 523    } else {
 524        current_req = req;
 525        last_req = req;
 526        if (cuda_state == idle)
 527            cuda_start();
 528    }
 529    spin_unlock_irqrestore(&cuda_lock, flags);
 530
 531    return 0;
 532}
 533
 534static void
 535cuda_start(void)
 536{
 537    /* assert cuda_state == idle */
 538    if (current_req == NULL)
 539        return;
 540    data_index = 0;
 541    if (TREQ_asserted(in_8(&via[B])))
 542        return;                 /* a byte is coming in from the CUDA */
 543
 544    /* set the shift register to shift out and send a byte */
 545    out_8(&via[ACR], in_8(&via[ACR]) | SR_OUT);
 546    out_8(&via[SR], current_req->data[data_index++]);
 547    if (mcu_is_egret)
 548        assert_TIP_and_TACK();
 549    else
 550        assert_TIP();
 551    cuda_state = sent_first_byte;
 552}
 553
 554void
 555cuda_poll(void)
 556{
 557        cuda_interrupt(0, NULL);
 558}
 559EXPORT_SYMBOL(cuda_poll);
 560
 561#define ARRAY_FULL(a, p)        ((p) - (a) == ARRAY_SIZE(a))
 562
 563static irqreturn_t
 564cuda_interrupt(int irq, void *arg)
 565{
 566    unsigned long flags;
 567    u8 status;
 568    struct adb_request *req = NULL;
 569    unsigned char ibuf[16];
 570    int ibuf_len = 0;
 571    int complete = 0;
 572    
 573    spin_lock_irqsave(&cuda_lock, flags);
 574
 575    /* On powermacs, this handler is registered for the VIA IRQ. But they use
 576     * just the shift register IRQ -- other VIA interrupt sources are disabled.
 577     * On m68k macs, the VIA IRQ sources are dispatched individually. Unless
 578     * we are polling, the shift register IRQ flag has already been cleared.
 579     */
 580
 581#ifdef CONFIG_MAC
 582    if (!arg)
 583#endif
 584    {
 585        if ((in_8(&via[IFR]) & SR_INT) == 0) {
 586            spin_unlock_irqrestore(&cuda_lock, flags);
 587            return IRQ_NONE;
 588        } else {
 589            out_8(&via[IFR], SR_INT);
 590        }
 591    }
 592
 593    status = in_8(&via[B]) & (TIP | TACK | TREQ);
 594
 595    switch (cuda_state) {
 596    case idle:
 597        /* System controller has unsolicited data for us */
 598        (void)in_8(&via[SR]);
 599idle_state:
 600        assert_TIP();
 601        cuda_state = reading;
 602        reply_ptr = cuda_rbuf;
 603        reading_reply = 0;
 604        break;
 605
 606    case awaiting_reply:
 607        /* System controller has reply data for us */
 608        (void)in_8(&via[SR]);
 609        assert_TIP();
 610        cuda_state = reading;
 611        reply_ptr = current_req->reply;
 612        reading_reply = 1;
 613        break;
 614
 615    case sent_first_byte:
 616        if (TREQ_asserted(status)) {
 617            /* collision */
 618            out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
 619            (void)in_8(&via[SR]);
 620            negate_TIP_and_TACK();
 621            cuda_state = idle;
 622            /* Egret does not raise an "aborted" interrupt */
 623            if (mcu_is_egret)
 624                goto idle_state;
 625        } else {
 626            out_8(&via[SR], current_req->data[data_index++]);
 627            toggle_TACK();
 628            if (mcu_is_egret)
 629                assert_TACK();
 630            cuda_state = sending;
 631        }
 632        break;
 633
 634    case sending:
 635        req = current_req;
 636        if (data_index >= req->nbytes) {
 637            out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
 638            (void)in_8(&via[SR]);
 639            negate_TIP_and_TACK();
 640            req->sent = 1;
 641            if (req->reply_expected) {
 642                cuda_state = awaiting_reply;
 643            } else {
 644                current_req = req->next;
 645                complete = 1;
 646                /* not sure about this */
 647                cuda_state = idle;
 648                cuda_start();
 649            }
 650        } else {
 651            out_8(&via[SR], req->data[data_index++]);
 652            toggle_TACK();
 653            if (mcu_is_egret)
 654                assert_TACK();
 655        }
 656        break;
 657
 658    case reading:
 659        if (reading_reply ? ARRAY_FULL(current_req->reply, reply_ptr)
 660                          : ARRAY_FULL(cuda_rbuf, reply_ptr))
 661            (void)in_8(&via[SR]);
 662        else
 663            *reply_ptr++ = in_8(&via[SR]);
 664        if (!TREQ_asserted(status)) {
 665            if (mcu_is_egret)
 666                assert_TACK();
 667            /* that's all folks */
 668            negate_TIP_and_TACK();
 669            cuda_state = read_done;
 670            /* Egret does not raise a "read done" interrupt */
 671            if (mcu_is_egret)
 672                goto read_done_state;
 673        } else {
 674            toggle_TACK();
 675            if (mcu_is_egret)
 676                negate_TACK();
 677        }
 678        break;
 679
 680    case read_done:
 681        (void)in_8(&via[SR]);
 682read_done_state:
 683        if (reading_reply) {
 684            req = current_req;
 685            req->reply_len = reply_ptr - req->reply;
 686            if (req->data[0] == ADB_PACKET) {
 687                /* Have to adjust the reply from ADB commands */
 688                if (req->reply_len <= 2 || (req->reply[1] & 2) != 0) {
 689                    /* the 0x2 bit indicates no response */
 690                    req->reply_len = 0;
 691                } else {
 692                    /* leave just the command and result bytes in the reply */
 693                    req->reply_len -= 2;
 694                    memmove(req->reply, req->reply + 2, req->reply_len);
 695                }
 696            }
 697            current_req = req->next;
 698            complete = 1;
 699            reading_reply = 0;
 700        } else {
 701            /* This is tricky. We must break the spinlock to call
 702             * cuda_input. However, doing so means we might get
 703             * re-entered from another CPU getting an interrupt
 704             * or calling cuda_poll(). I ended up using the stack
 705             * (it's only for 16 bytes) and moving the actual
 706             * call to cuda_input to outside of the lock.
 707             */
 708            ibuf_len = reply_ptr - cuda_rbuf;
 709            memcpy(ibuf, cuda_rbuf, ibuf_len);
 710        }
 711        reply_ptr = cuda_rbuf;
 712        cuda_state = idle;
 713        cuda_start();
 714        if (cuda_state == idle && TREQ_asserted(in_8(&via[B]))) {
 715            assert_TIP();
 716            cuda_state = reading;
 717        }
 718        break;
 719
 720    default:
 721        pr_err("cuda_interrupt: unknown cuda_state %d?\n", cuda_state);
 722    }
 723    spin_unlock_irqrestore(&cuda_lock, flags);
 724    if (complete && req) {
 725        void (*done)(struct adb_request *) = req->done;
 726        mb();
 727        req->complete = 1;
 728        /* Here, we assume that if the request has a done member, the
 729         * struct request will survive to setting req->complete to 1
 730         */
 731        if (done)
 732                (*done)(req);
 733    }
 734    if (ibuf_len)
 735        cuda_input(ibuf, ibuf_len);
 736    return IRQ_HANDLED;
 737}
 738
 739static void
 740cuda_input(unsigned char *buf, int nb)
 741{
 742    switch (buf[0]) {
 743    case ADB_PACKET:
 744#ifdef CONFIG_XMON
 745        if (nb == 5 && buf[2] == 0x2c) {
 746            extern int xmon_wants_key, xmon_adb_keycode;
 747            if (xmon_wants_key) {
 748                xmon_adb_keycode = buf[3];
 749                return;
 750            }
 751        }
 752#endif /* CONFIG_XMON */
 753#ifdef CONFIG_ADB
 754        adb_input(buf+2, nb-2, buf[1] & 0x40);
 755#endif /* CONFIG_ADB */
 756        break;
 757
 758    case TIMER_PACKET:
 759        /* Egret sends these periodically. Might be useful as a 'heartbeat'
 760         * to trigger a recovery for the VIA shift register errata.
 761         */
 762        break;
 763
 764    default:
 765        print_hex_dump(KERN_INFO, "cuda_input: ", DUMP_PREFIX_NONE, 32, 1,
 766                       buf, nb, false);
 767    }
 768}
 769