Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openhackware / src / char.c
1 /*
2  * <char.c>
3  *
4  * Open Hack'Ware BIOS character devices drivers.
5  * 
6  *  Copyright (c) 2004-2005 Jocelyn Mayer
7  *
8  *  cuda driver: Copyright (c) 2004-2005 Fabrice Bellard
9  *
10  *   This program is free software; you can redistribute it and/or
11  *   modify it under the terms of the GNU General Public License V2
12  *   as published by the Free Software Foundation
13  *
14  *   This program is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with this program; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include "bios.h"
27 #include "adb.h"
28
29 //#define DEBUG_CHARDEV
30 //#define DEBUG_CUDA
31 //#define DEBUG_ADB
32
33 #ifdef DEBUG_CHARDEV
34 #define CHARDEV_DPRINTF(fmt, args...) \
35 do { dprintf("CHARDEV - %s: " fmt, __func__ , ##args); } while (0)
36 #else
37 #define CHARDEV_DPRINTF(fmt, args...) do { } while (0)
38 #endif
39
40 /* Generic character device API */
41 struct chardev_t {
42     chardev_t *next;
43     int type;
44     cops_t *ops;
45     void *private;
46 };
47
48 static chardev_t *char_devices;
49
50 int chardev_register (int type, cops_t *ops, void *private)
51 {
52     chardev_t *dev, **cur;
53
54     CHARDEV_DPRINTF("Register char device of type %d\n", type);
55     if (type > CHARDEV_LAST)
56         return -1;
57     dev = malloc(sizeof(chardev_t));
58     if (dev == NULL)
59         return -1;
60     dev->type = type;
61     dev->ops = ops;
62     dev->private = private;
63     for (cur = &char_devices; *cur != NULL; cur = &((*cur)->next))
64         continue;
65     *cur = dev;
66
67     return 0;
68 }
69
70 int chardev_open (chardev_t *dev)
71 {
72     if (dev->ops == NULL)
73         return -1;
74     if (dev->ops->open == NULL)
75         return 0;
76
77     return (*dev->ops->open)(dev->private);
78 }
79
80 int chardev_close (chardev_t *dev)
81 {
82     if (dev->ops == NULL)
83         return -1;
84     if (dev->ops->close == NULL)
85         return 0;
86
87     return (*dev->ops->close)(dev->private);
88 }
89
90 int chardev_read (chardev_t *dev, void *buffer, int maxlen)
91 {
92     unsigned char *p;
93     int len;
94     int c;
95
96     if (dev->ops == NULL || dev->ops->read == NULL)
97         return -1;
98
99     p = buffer;
100     for (len = 0; len < maxlen; len++) {
101         c = (*dev->ops->read)(dev->private);
102         if (c < 0)
103             break;
104         *p++ = c;
105     }
106
107     return len;
108 }
109
110 int chardev_write (chardev_t *dev, const void *buffer, int maxlen)
111 {
112     const unsigned char *p;
113     int len;
114     int c;
115
116     if (dev->ops == NULL || dev->ops->write == NULL)
117         return -1;
118
119     p = buffer;
120     for (len = 0; len < maxlen; len++) {
121         c = *p++;
122         if ((*dev->ops->write)(dev->private, c) < 0)
123             break;
124     }
125
126     return len;
127 }
128
129 int chardev_type (chardev_t *dev)
130 {
131     return dev->type;
132 }
133
134 /* Console driver */
135 static chardev_t *console_in_devs[17], *console_out_devs[17];
136 static int console_last_in;
137
138 int console_open (void)
139 {
140     chardev_t *cur;
141     int i, j, n, register_outd;
142
143     i = 0;
144     j = 0;
145     n = 0;
146     /* Check all character devices and register those which are usable
147      * as IO for the console
148      */
149     CHARDEV_DPRINTF("enter\n");
150     for (cur = char_devices; cur != NULL; cur = cur->next, n++) {
151         register_outd = 0;
152         switch (cur->type) {
153         case  CHARDEV_SERIAL:
154             CHARDEV_DPRINTF("one serial port\n");
155             register_outd = 1;
156             /* No break here */
157         case CHARDEV_KBD:
158             CHARDEV_DPRINTF("one input port %d %d\n", n, i);
159             if (i < 16 && chardev_open(cur) == 0) {
160                 console_in_devs[i++] = cur;
161             }
162             if (!register_outd)
163                 break;
164             /* No break here */
165         case CHARDEV_DISPLAY:
166             CHARDEV_DPRINTF("one output port %d %d\n", n, j);
167             if (j < 16 && chardev_open(cur) == 0) {
168                 console_out_devs[j++] = cur;
169             }
170             break;
171         default:
172             CHARDEV_DPRINTF("Skip device %d\n", n);
173             break;
174         }
175     }
176     
177     return 0;
178 }
179
180 int console_read (void *buffer, int maxlen)
181 {
182     chardev_t *cur;
183     int i, in;
184
185     CHARDEV_DPRINTF("enter\n");
186     /* Get data from the first in device responding to us */
187     cur = console_in_devs[console_last_in];
188     for (i = console_last_in;;) {
189         CHARDEV_DPRINTF("read from device %d\n", i);
190         in = chardev_read(cur, buffer, maxlen);
191         if (in > 0) {
192             console_last_in = i;
193 #if 0
194             printf("Read %d chars '%c'...\n", in, *((char *)buffer));
195 #endif
196             return in;
197         }
198         cur = console_in_devs[++i];
199         if (cur == NULL) {
200             i = 0;
201             cur = console_in_devs[0];
202         }
203         if (i == console_last_in || cur == NULL)
204             break;
205     }
206     console_last_in = i;
207     CHARDEV_DPRINTF("out\n");
208
209     return 0;
210 }
211
212 int console_write (const void *buffer, int len)
213 {
214     chardev_t *cur;
215     int i, out, max;
216
217     /* Write data to all devices */
218     max = 0;
219     for (i = 0; i < 16; i++) {
220         cur = console_out_devs[i];
221         if (cur == NULL)
222             break;
223         out = chardev_write(cur, buffer, len);
224         if (out > max)
225             max = out;
226     }
227
228     return max;
229 }
230
231 void console_close (void)
232 {
233     chardev_t *cur;
234     int i;
235
236     for (i = 0; i < 16; i++) {
237         cur = console_out_devs[i];
238         if (cur == NULL)
239             break;
240         chardev_close(cur);
241         console_out_devs[i] = NULL;
242     }
243 }
244
245 /* PC serial port "driver" */
246 #define PC_SERIAL_LSR_OFFSET (5)
247 typedef struct pc_serial_t {
248     uint16_t base;
249 } pc_serial_t;
250
251 static int pc_serial_open (unused void *private)
252 {
253     return 0;
254 }
255
256 static int pc_serial_writeb (void *private, int data)
257 {
258     pc_serial_t *serial = private;
259
260     /* Wait for the FIFO to be ready to accept more chars.
261      * Note: this is completely buggy and would never work on real hardware,
262      *       as the serial port (especialy the FIFO) has not been programmed
263      *       anywhere before !
264      */
265     if (!(inb(serial->base + PC_SERIAL_LSR_OFFSET) & 0x20))
266         usleep(100);
267     outb(serial->base, data);
268
269     return 0;
270 }
271
272 static int pc_serial_readb (void *private)
273 {
274     pc_serial_t *serial = private;
275
276     if (!(inb(serial->base + PC_SERIAL_LSR_OFFSET) & 0x01))
277         return -1;
278
279     return inb(serial->base);
280 }
281
282 static int pc_serial_close (unused void *private)
283 {
284     return 0;
285 }
286
287 static cops_t pc_serial_ops = {
288     .open = &pc_serial_open,
289     .read = &pc_serial_readb,
290     .write = &pc_serial_writeb,
291     .close = &pc_serial_close,
292 };
293
294 /* XXX: debug stuff only ! (TOFIX with a generic debug console) */
295 int serial_write (const void *buffer, int len)
296 {
297     const char *p;
298
299     for (p = buffer; len > 0; len--) {
300         if (!(inb(0x3F8 + PC_SERIAL_LSR_OFFSET) & 0x20))
301             usleep(100);
302         outb(0x3F8, *p++);
303     }
304
305     return 0;
306 }
307
308 int pc_serial_register (uint16_t base)
309 {
310     pc_serial_t *serial;
311     
312     serial = malloc(sizeof(pc_serial_t));
313     if (serial == NULL)
314         return -1;
315     serial->base = base;
316     /* XXX: TODO: initialize the serial port (FIFO, speed, ...) */
317     
318     return chardev_register(CHARDEV_SERIAL, &pc_serial_ops, serial);
319 }
320
321 /* VGA console device */
322 static int vga_cons_open (unused void *private)
323 {
324     return 0;
325 }
326
327 static int vga_cons_writeb (unused void *private, int data)
328 {
329     vga_putchar(data);
330
331     return 0;
332 }
333
334 static int vga_cons_close (unused void *private)
335 {
336     return 0;
337 }
338
339 static cops_t vga_cons_ops = {
340     .open = &vga_cons_open,
341     .read = NULL,
342     .write = &vga_cons_writeb,
343     .close = &vga_cons_close,
344 };
345
346 int vga_console_register (void)
347 {
348     return chardev_register(CHARDEV_DISPLAY, &vga_cons_ops, NULL);
349 }
350
351 /* Macintosh via-cuda driver */
352 #ifdef DEBUG_CUDA
353 #define CUDA_DPRINTF(fmt, args...) \
354 do { dprintf("CUDA - %s: " fmt, __func__ , ##args); } while (0)
355 #else
356 #define CUDA_DPRINTF(fmt, args...) do { } while (0)
357 #endif
358
359 /* VIA registers - spaced 0x200 bytes apart */
360 #define RS              0x200           /* skip between registers */
361 #define B               0               /* B-side data */
362 #define A               RS              /* A-side data */
363 #define DIRB            (2*RS)          /* B-side direction (1=output) */
364 #define DIRA            (3*RS)          /* A-side direction (1=output) */
365 #define T1CL            (4*RS)          /* Timer 1 ctr/latch (low 8 bits) */
366 #define T1CH            (5*RS)          /* Timer 1 counter (high 8 bits) */
367 #define T1LL            (6*RS)          /* Timer 1 latch (low 8 bits) */
368 #define T1LH            (7*RS)          /* Timer 1 latch (high 8 bits) */
369 #define T2CL            (8*RS)          /* Timer 2 ctr/latch (low 8 bits) */
370 #define T2CH            (9*RS)          /* Timer 2 counter (high 8 bits) */
371 #define SR              (10*RS)         /* Shift register */
372 #define ACR             (11*RS)         /* Auxiliary control register */
373 #define PCR             (12*RS)         /* Peripheral control register */
374 #define IFR             (13*RS)         /* Interrupt flag register */
375 #define IER             (14*RS)         /* Interrupt enable register */
376 #define ANH             (15*RS)         /* A-side data, no handshake */
377
378 /* Bits in B data register: all active low */
379 #define TREQ            0x08            /* Transfer request (input) */
380 #define TACK            0x10            /* Transfer acknowledge (output) */
381 #define TIP             0x20            /* Transfer in progress (output) */
382
383 /* Bits in ACR */
384 #define SR_CTRL         0x1c            /* Shift register control bits */
385 #define SR_EXT          0x0c            /* Shift on external clock */
386 #define SR_OUT          0x10            /* Shift out if 1 */
387
388 /* Bits in IFR and IER */
389 #define IER_SET         0x80            /* set bits in IER */
390 #define IER_CLR         0               /* clear bits in IER */
391 #define SR_INT          0x04            /* Shift register full/empty */
392
393 #define CUDA_BUF_SIZE 16
394
395 #define ADB_PACKET      0
396 #define CUDA_PACKET     1
397
398 struct cuda_t {
399     uint32_t base;
400     adb_bus_t *adb_bus;
401 };
402
403 static uint8_t cuda_readb (cuda_t *dev, int reg)
404 {
405     return *(volatile uint8_t *)(dev->base + reg);
406 }
407
408 static void cuda_writeb (cuda_t *dev, int reg, uint8_t val)
409 {
410     *(volatile uint8_t *)(dev->base + reg) = val;
411 }
412
413 static void cuda_wait_irq (cuda_t *dev)
414 {
415     int val;
416
417     CUDA_DPRINTF("\n");
418     for(;;) {
419         val = cuda_readb(dev, IFR);
420         cuda_writeb(dev, IFR, val & 0x7f);
421         if (val & SR_INT)
422             break;
423     }
424 }
425
426 static int cuda_request (cuda_t *dev, uint8_t pkt_type, const uint8_t *buf,
427                          int buf_len, uint8_t *obuf)
428 {
429     int i, obuf_len, val;
430
431     cuda_writeb(dev, ACR, cuda_readb(dev, ACR) | SR_OUT);
432     cuda_writeb(dev, SR, pkt_type);
433     cuda_writeb(dev, B, cuda_readb(dev, B) & ~TIP);
434     if (buf) {
435         CUDA_DPRINTF("Send buf len: %d\n", buf_len);
436         /* send 'buf' */
437         for(i = 0; i < buf_len; i++) {
438             cuda_wait_irq(dev);
439             cuda_writeb(dev, SR, buf[i]);
440             cuda_writeb(dev, B, cuda_readb(dev, B) ^ TACK);
441         }
442     }
443     cuda_wait_irq(dev);
444     cuda_writeb(dev, ACR, cuda_readb(dev, ACR) & ~SR_OUT);
445     cuda_readb(dev, SR);
446     cuda_writeb(dev, B, cuda_readb(dev, B) | TIP | TACK);
447     
448     obuf_len = 0;
449     if (obuf) {
450         cuda_wait_irq(dev);
451         cuda_readb(dev, SR);
452         cuda_writeb(dev, B, cuda_readb(dev, B) & ~TIP);
453         for(;;) {
454             cuda_wait_irq(dev);
455             val = cuda_readb(dev, SR);
456             if (obuf_len < CUDA_BUF_SIZE)
457                 obuf[obuf_len++] = val;
458             if (cuda_readb(dev, B) & TREQ)
459                 break;
460             cuda_writeb(dev, B, cuda_readb(dev, B) ^ TACK);
461         }
462         cuda_writeb(dev, B, cuda_readb(dev, B) | TIP | TACK);
463
464         cuda_wait_irq(dev);
465         cuda_readb(dev, SR);
466     }
467     CUDA_DPRINTF("Got len: %d\n", obuf_len);
468
469     return obuf_len;
470 }
471
472 #if 0
473 void cuda_test(void)
474 {
475     int keycode;
476     printf("cuda test:\n");
477     cuda_init(0x80400000 + 0x16000);
478     for(;;) {
479         keycode = adb_read_key();
480         if (keycode >= 0)
481             printf("keycode=%x\n", keycode);
482     }
483 }
484 #endif
485
486 /* Cuda ADB glue */
487 static int cuda_adb_req (void *host, const uint8_t *snd_buf, int len,
488                          uint8_t *rcv_buf)
489 {
490     uint8_t buffer[CUDA_BUF_SIZE], *pos;
491
492     CUDA_DPRINTF("len: %d %02x\n", len, snd_buf[0]);
493     len = cuda_request(host, ADB_PACKET, snd_buf, len, buffer);
494     if (len > 1 && buffer[0] == ADB_PACKET) {
495         pos = buffer + 2;
496         len -= 2;
497     } else {
498         pos = buffer + 1;
499         len = -1;
500     }
501     memcpy(rcv_buf, pos, len);
502
503     return len;
504 }
505
506 cuda_t *cuda_init (uint32_t base)
507 {
508     cuda_t *cuda;
509
510     CUDA_DPRINTF(" base=%08x\n", base);
511     cuda = malloc(sizeof(cuda_t));
512     if (cuda == NULL)
513         return NULL;
514     cuda->base = base;
515     cuda_writeb(cuda, B, cuda_readb(cuda, B) | TREQ | TIP);
516 #if 0
517     {
518         int len;
519
520         /* enable auto poll */
521         buf[0] = 0x01;
522         buf[1] = 1;
523         len = cuda_request(cuda, CUDA_PACKET, buf, 2, obuf);
524         if (len != 2 || obuf[0] != CUDA_PACKET || obuf[1] != 1) {
525             printf("cuda: invalid reply for auto poll request");
526             free(cuda);
527             return NULL;
528         }
529     }
530 #endif
531     cuda->adb_bus = adb_bus_new(cuda, &cuda_adb_req);
532     if (cuda->adb_bus == NULL) {
533         free(cuda);
534         return NULL;
535     }
536     adb_bus_init(cuda->adb_bus);
537
538     return cuda;
539 }
540
541 void cuda_reset (cuda_t *cuda)
542 {
543     adb_bus_reset(cuda->adb_bus);
544 }
545
546 /* ADB generic driver */
547 #ifdef DEBUG_ADB
548 #define ADB_DPRINTF(fmt, args...) \
549 do { dprintf("ADB - %s: " fmt, __func__ , ##args); } while (0)
550 #else
551 #define ADB_DPRINTF(fmt, args...) do { } while (0)
552 #endif
553
554 int adb_cmd (adb_dev_t *dev, uint8_t cmd, uint8_t reg,
555              uint8_t *buf, int len)
556 {
557     uint8_t adb_send[ADB_BUF_SIZE], adb_rcv[ADB_BUF_SIZE];
558     
559     ADB_DPRINTF("cmd: %d reg: %d len: %d\n", cmd, reg, len);
560     if (dev->bus == NULL || dev->bus->req == NULL) {
561         ADB_DPRINTF("ERROR: invalid bus !\n");
562         bug();
563     }
564     /* Sanity checks */
565     if (cmd != ADB_LISTEN && len != 0) {
566         /* No buffer transmitted but for LISTEN command */
567         ADB_DPRINTF("in buffer for cmd %d\n", cmd);
568         return -1;
569     }
570     if (cmd == ADB_LISTEN && ((len < 2 || len > 8) || buf == NULL)) {
571         /* Need a buffer with a regular register size for LISTEN command */
572         ADB_DPRINTF("no/invalid buffer for ADB_LISTEN (%d)\n", len);
573         return -1;
574     }
575     if ((cmd == ADB_TALK || cmd == ADB_LISTEN) && reg > 3) {
576         /* Need a valid register number for LISTEN and TALK commands */
577         ADB_DPRINTF("invalid reg for TALK/LISTEN command (%d %d)\n", cmd, reg);
578         return -1;
579     }
580     switch (cmd) {
581     case ADB_SEND_RESET:
582         adb_send[0] = ADB_SEND_RESET;
583         break;
584     case ADB_FLUSH:
585         adb_send[0] = (dev->addr << 4) | ADB_FLUSH;
586         break;
587     case ADB_LISTEN:
588         memcpy(adb_send + 1, buf, len);
589         /* No break here */
590     case ADB_TALK:
591         adb_send[0] = (dev->addr << 4) | cmd | reg;
592         break;
593     }
594     memset(adb_rcv, 0, ADB_BUF_SIZE);
595     len = (*dev->bus->req)(dev->bus->host, adb_send, len + 1, adb_rcv);
596 #ifdef DEBUG_ADB
597     printf("%x %x %x %x\n", adb_rcv[0], adb_rcv[1], adb_rcv[2], adb_rcv[3]);
598 #endif
599     switch (len) {
600     case 0:
601         /* No data */
602         break;
603     case 2 ... 8:
604         /* Register transmitted */
605         if (buf != NULL)
606             memcpy(buf, adb_rcv, len);
607         break;
608     default:
609         /* Should never happen */
610         ADB_DPRINTF("Cmd %d returned %d bytes !\n", cmd, len);
611         return -1;
612     }
613     ADB_DPRINTF("retlen: %d\n", len);
614     
615     return len;
616 }
617
618 void adb_bus_reset (adb_bus_t *bus)
619 {
620     adb_reset(bus);
621 }
622
623 adb_bus_t *adb_bus_new (void *host,
624                         int (*req)(void *host, const uint8_t *snd_buf,
625                                    int len, uint8_t *rcv_buf))
626 {
627     adb_bus_t *new;
628
629     new = malloc(sizeof(adb_bus_t));
630     if (new == NULL)
631         return NULL;
632     new->host = host;
633     new->req = req;
634
635     return new;
636 }
637
638 /* ADB */
639 void *adb_kbd_new (void *private);
640
641 static int adb_mouse_open (void *private);
642 static int adb_mouse_close (void *private);
643 static int adb_mouse_read (void *private);
644
645 static cops_t adb_mouse_ops = {
646     &adb_mouse_open,
647     &adb_mouse_close,
648     &adb_mouse_read,
649     NULL,
650 };
651
652 /* Check and relocate all ADB devices as suggested in
653  * ADB_manager Apple documentation
654  */
655 int adb_bus_init (adb_bus_t *bus)
656 {
657     uint8_t buffer[ADB_BUF_SIZE];
658     uint8_t adb_addresses[16] =
659         { 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, 0, };
660     adb_dev_t tmp_device, **cur;
661     int address;
662     int reloc = 0, next_free = 7;
663     int keep;
664
665     /* Reset the bus */
666     ADB_DPRINTF("\n");
667     adb_reset(bus);
668     cur = &bus->devices;
669     memset(&tmp_device, 0, sizeof(adb_dev_t));
670     tmp_device.bus = bus;
671     for (address = 1; address < 8 && adb_addresses[reloc] > 0;) {
672         if (address == ADB_RES) {
673             /* Reserved */
674             address++;
675             continue;
676         }
677         ADB_DPRINTF("Check device on ADB address %d\n", address);
678         tmp_device.addr = address;
679         switch (adb_reg_get(&tmp_device, 3, buffer)) {
680         case 0:
681             ADB_DPRINTF("No device on ADB address %d\n", address);
682             /* Register this address as free */
683             if (adb_addresses[next_free] != 0)
684                 adb_addresses[next_free++] = address;
685             /* Check next ADB address */
686             address++;
687             break;
688         case 2:
689             /* One device answered :
690              * make it available and relocate it to a free address
691              */
692             if (buffer[0] == ADB_CHADDR) {
693                 /* device self test failed */
694                 ADB_DPRINTF("device on ADB address %d self-test failed "
695                             "%02x %02x %02x\n", address,
696                             buffer[0], buffer[1], buffer[2]);
697                 keep = 0;
698             } else {
699                 ADB_DPRINTF("device on ADB address %d self-test OK\n",
700                             address);
701                 keep = 1;
702             }
703             ADB_DPRINTF("Relocate device on ADB address %d to %d (%d)\n",
704                         address, adb_addresses[reloc], reloc);
705             buffer[0] = ((buffer[0] & 0x40) & ~0x90) | adb_addresses[reloc];
706             if (keep == 1)
707                 buffer[0] |= 0x20;
708             buffer[1] = ADB_CHADDR_NOCOLL;
709             if (adb_reg_set(&tmp_device, 3, buffer, 2) < 0) {
710                 ADB_DPRINTF("ADB device relocation failed\n");
711                 return -1;
712             }
713             if (keep == 1) {
714                 *cur = malloc(sizeof(adb_dev_t));
715                 if (*cur == NULL) {
716                     return -1;
717                 }
718                 (*cur)->type = address;
719                 (*cur)->bus = bus;
720                 (*cur)->addr = adb_addresses[reloc++];
721                 /* Flush buffers */
722                 adb_flush(*cur);
723                 switch ((*cur)->type) {
724                 case ADB_PROTECT:
725                     ADB_DPRINTF("Found one protected device\n");
726                     break;
727                 case ADB_KEYBD:
728                     ADB_DPRINTF("Found one keyboard\n");
729                     adb_kbd_new(*cur);
730                     break;
731                 case ADB_MOUSE:
732                     ADB_DPRINTF("Found one mouse\n");
733                     chardev_register(CHARDEV_MOUSE, &adb_mouse_ops, *cur);
734                     break;
735                 case ADB_ABS:
736                     ADB_DPRINTF("Found one absolute positioning device\n");
737                     break;
738                 case ADB_MODEM:
739                     ADB_DPRINTF("Found one modem\n");
740                     break;
741                 case ADB_RES:
742                     ADB_DPRINTF("Found one ADB res device\n");
743                     break;
744                 case ADB_MISC:
745                     ADB_DPRINTF("Found one ADB misc device\n");
746                     break;
747                 }
748                 cur = &((*cur)->next);
749             }
750             break;
751         case 1:
752         case 3 ... 7:
753             /* SHOULD NOT HAPPEN : register 3 is always two bytes long */
754             ADB_DPRINTF("Invalid returned len for ADB register 3\n");
755             return -1;
756         case -1:
757             /* ADB ERROR */
758             ADB_DPRINTF("error gettting ADB register 3\n");
759             return -1;
760         }
761     }
762
763     return 0;
764 }
765
766 /* ADB mouse chardev interface (TODO) */
767 static int adb_mouse_open (unused void *private)
768 {
769     return 0;
770 }
771
772 static int adb_mouse_close (unused void *private)
773 {
774     return 0;
775 }
776
777 static int adb_mouse_read (unused void *private)
778 {
779     return -1;
780 }