Fix keyboard detection bugs
[qemu] / hw / slavio_serial.c
1 /*
2  * QEMU Sparc SLAVIO serial port emulation
3  * 
4  * Copyright (c) 2003-2005 Fabrice Bellard
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "vl.h"
25 /* debug serial */
26 //#define DEBUG_SERIAL
27
28 /* debug keyboard */
29 //#define DEBUG_KBD
30
31 /* debug mouse */
32 //#define DEBUG_MOUSE
33
34 /*
35  * This is the serial port, mouse and keyboard part of chip STP2001
36  * (Slave I/O), also produced as NCR89C105. See
37  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
38  * 
39  * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
40  * mouse and keyboard ports don't implement all functions and they are
41  * only asynchronous. There is no DMA.
42  *
43  */
44
45 /*
46  * Modifications:
47  *  2006-Aug-10  Igor Kovalenko :   Renamed KBDQueue to SERIOQueue, implemented
48  *                                  serial mouse queue.
49  *                                  Implemented serial mouse protocol.
50  */
51
52 #ifdef DEBUG_SERIAL
53 #define SER_DPRINTF(fmt, args...) \
54 do { printf("SER: " fmt , ##args); } while (0)
55 #else
56 #define SER_DPRINTF(fmt, args...)
57 #endif
58 #ifdef DEBUG_KBD
59 #define KBD_DPRINTF(fmt, args...) \
60 do { printf("KBD: " fmt , ##args); } while (0)
61 #else
62 #define KBD_DPRINTF(fmt, args...)
63 #endif
64 #ifdef DEBUG_MOUSE
65 #define MS_DPRINTF(fmt, args...) \
66 do { printf("MSC: " fmt , ##args); } while (0)
67 #else
68 #define MS_DPRINTF(fmt, args...)
69 #endif
70
71 typedef enum {
72     chn_a, chn_b,
73 } chn_id_t;
74
75 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
76
77 typedef enum {
78     ser, kbd, mouse,
79 } chn_type_t;
80
81 #define SERIO_QUEUE_SIZE 256
82
83 typedef struct {
84     uint8_t data[SERIO_QUEUE_SIZE];
85     int rptr, wptr, count;
86 } SERIOQueue;
87
88 typedef struct ChannelState {
89     qemu_irq irq;
90     int reg;
91     int rxint, txint, rxint_under_svc, txint_under_svc;
92     chn_id_t chn; // this channel, A (base+4) or B (base+0)
93     chn_type_t type;
94     struct ChannelState *otherchn;
95     uint8_t rx, tx, wregs[16], rregs[16];
96     SERIOQueue queue;
97     CharDriverState *chr;
98 } ChannelState;
99
100 struct SerialState {
101     struct ChannelState chn[2];
102 };
103
104 #define SERIAL_MAXADDR 7
105
106 static void handle_kbd_command(ChannelState *s, int val);
107 static int serial_can_receive(void *opaque);
108 static void serial_receive_byte(ChannelState *s, int ch);
109 static inline void set_txint(ChannelState *s);
110
111 static void clear_queue(void *opaque)
112 {
113     ChannelState *s = opaque;
114     SERIOQueue *q = &s->queue;
115     q->rptr = q->wptr = q->count = 0;
116 }
117
118 static void put_queue(void *opaque, int b)
119 {
120     ChannelState *s = opaque;
121     SERIOQueue *q = &s->queue;
122
123     SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
124     if (q->count >= SERIO_QUEUE_SIZE)
125         return;
126     q->data[q->wptr] = b;
127     if (++q->wptr == SERIO_QUEUE_SIZE)
128         q->wptr = 0;
129     q->count++;
130     serial_receive_byte(s, 0);
131 }
132
133 static uint32_t get_queue(void *opaque)
134 {
135     ChannelState *s = opaque;
136     SERIOQueue *q = &s->queue;
137     int val;
138     
139     if (q->count == 0) {
140         return 0;
141     } else {
142         val = q->data[q->rptr];
143         if (++q->rptr == SERIO_QUEUE_SIZE)
144             q->rptr = 0;
145         q->count--;
146     }
147     SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
148     if (q->count > 0)
149         serial_receive_byte(s, 0);
150     return val;
151 }
152
153 static int slavio_serial_update_irq_chn(ChannelState *s)
154 {
155     if ((s->wregs[1] & 1) && // interrupts enabled
156         (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
157          ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
158           s->rxint == 1) || // rx ints enabled, pending
159          ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
160         return 1;
161     }
162     return 0;
163 }
164
165 static void slavio_serial_update_irq(ChannelState *s)
166 {
167     int irq;
168
169     irq = slavio_serial_update_irq_chn(s);
170     irq |= slavio_serial_update_irq_chn(s->otherchn);
171
172     SER_DPRINTF("IRQ = %d\n", irq);
173     qemu_set_irq(s->irq, irq);
174 }
175
176 static void slavio_serial_reset_chn(ChannelState *s)
177 {
178     int i;
179
180     s->reg = 0;
181     for (i = 0; i < SERIAL_MAXADDR; i++) {
182         s->rregs[i] = 0;
183         s->wregs[i] = 0;
184     }
185     s->wregs[4] = 4;
186     s->wregs[9] = 0xc0;
187     s->wregs[11] = 8;
188     s->wregs[14] = 0x30;
189     s->wregs[15] = 0xf8;
190     s->rregs[0] = 0x44;
191     s->rregs[1] = 6;
192
193     s->rx = s->tx = 0;
194     s->rxint = s->txint = 0;
195     s->rxint_under_svc = s->txint_under_svc = 0;
196     clear_queue(s);
197 }
198
199 static void slavio_serial_reset(void *opaque)
200 {
201     SerialState *s = opaque;
202     slavio_serial_reset_chn(&s->chn[0]);
203     slavio_serial_reset_chn(&s->chn[1]);
204 }
205
206 static inline void clr_rxint(ChannelState *s)
207 {
208     s->rxint = 0;
209     s->rxint_under_svc = 0;
210     if (s->chn == chn_a) {
211         if (s->wregs[9] & 0x10)
212             s->otherchn->rregs[2] = 0x60;
213         else
214             s->otherchn->rregs[2] = 0x06;
215         s->rregs[3] &= ~0x20;
216     } else {
217         if (s->wregs[9] & 0x10)
218             s->rregs[2] = 0x60;
219         else
220             s->rregs[2] = 0x06;
221         s->otherchn->rregs[3] &= ~4;
222     }
223     if (s->txint)
224         set_txint(s);
225     else
226         s->rregs[2] = 6;
227     slavio_serial_update_irq(s);
228 }
229
230 static inline void set_rxint(ChannelState *s)
231 {
232     s->rxint = 1;
233     if (!s->txint_under_svc) {
234         s->rxint_under_svc = 1;
235         if (s->chn == chn_a) {
236             if (s->wregs[9] & 0x10)
237                 s->otherchn->rregs[2] = 0x30;
238             else
239                 s->otherchn->rregs[2] = 0x0c;
240             s->rregs[3] |= 0x20;
241         } else {
242             if (s->wregs[9] & 0x10)
243                 s->rregs[2] = 0x20;
244             else
245                 s->rregs[2] = 0x04;
246             s->otherchn->rregs[3] |= 4;
247         }
248         slavio_serial_update_irq(s);
249     }
250 }
251
252 static inline void clr_txint(ChannelState *s)
253 {
254     s->txint = 0;
255     s->txint_under_svc = 0;
256     if (s->chn == chn_a)
257         s->rregs[3] &= ~0x10;
258     else
259         s->otherchn->rregs[3] &= ~2;
260     if (s->rxint)
261         set_rxint(s);
262     else
263         s->rregs[2] = 6;
264     slavio_serial_update_irq(s);
265 }
266
267 static inline void set_txint(ChannelState *s)
268 {
269     s->txint = 1;
270     if (!s->rxint_under_svc) {
271         s->txint_under_svc = 1;
272         if (s->chn == chn_a)
273             s->rregs[3] |= 0x10;
274         else
275             s->otherchn->rregs[3] |= 2;
276         s->rregs[2] = 0;
277         slavio_serial_update_irq(s);
278     }
279 }
280
281 static void slavio_serial_update_parameters(ChannelState *s)
282 {
283     int speed, parity, data_bits, stop_bits;
284     QEMUSerialSetParams ssp;
285
286     if (!s->chr || s->type != ser)
287         return;
288
289     if (s->wregs[4] & 1) {
290         if (s->wregs[4] & 2)
291             parity = 'E';
292         else
293             parity = 'O';
294     } else {
295         parity = 'N';
296     }
297     if ((s->wregs[4] & 0x0c) == 0x0c)
298         stop_bits = 2;
299     else
300         stop_bits = 1;
301     switch (s->wregs[5] & 0x60) {
302     case 0x00:
303         data_bits = 5;
304         break;
305     case 0x20:
306         data_bits = 7;
307         break;
308     case 0x40:
309         data_bits = 6;
310         break;
311     default:
312     case 0x60:
313         data_bits = 8;
314         break;
315     }
316     speed = 2457600 / ((s->wregs[12] | (s->wregs[13] << 8)) + 2);
317     switch (s->wregs[4] & 0xc0) {
318     case 0x00:
319         break;
320     case 0x40:
321         speed /= 16;
322         break;
323     case 0x80:
324         speed /= 32;
325         break;
326     default:
327     case 0xc0:
328         speed /= 64;
329         break;
330     }
331     ssp.speed = speed;
332     ssp.parity = parity;
333     ssp.data_bits = data_bits;
334     ssp.stop_bits = stop_bits;
335     SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
336                 speed, parity, data_bits, stop_bits);
337     qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
338 }
339
340 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
341 {
342     SerialState *ser = opaque;
343     ChannelState *s;
344     uint32_t saddr;
345     int newreg, channel;
346
347     val &= 0xff;
348     saddr = (addr & 3) >> 1;
349     channel = (addr & SERIAL_MAXADDR) >> 2;
350     s = &ser->chn[channel];
351     switch (saddr) {
352     case 0:
353         SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
354         newreg = 0;
355         switch (s->reg) {
356         case 0:
357             newreg = val & 7;
358             val &= 0x38;
359             switch (val) {
360             case 8:
361                 newreg |= 0x8;
362                 break;
363             case 0x28:
364                 clr_txint(s);
365                 break;
366             case 0x38:
367                 if (s->rxint_under_svc)
368                     clr_rxint(s);
369                 else if (s->txint_under_svc)
370                     clr_txint(s);
371                 break;
372             default:
373                 break;
374             }
375             break;
376         case 1 ... 3:
377         case 6 ... 8:
378         case 10 ... 11:
379         case 14 ... 15:
380             s->wregs[s->reg] = val;
381             break;
382         case 4:
383         case 5:
384         case 12:
385         case 13:
386             s->wregs[s->reg] = val;
387             slavio_serial_update_parameters(s);
388             break;
389         case 9:
390             switch (val & 0xc0) {
391             case 0:
392             default:
393                 break;
394             case 0x40:
395                 slavio_serial_reset_chn(&ser->chn[1]);
396                 return;
397             case 0x80:
398                 slavio_serial_reset_chn(&ser->chn[0]);
399                 return;
400             case 0xc0:
401                 slavio_serial_reset(ser);
402                 return;
403             }
404             break;
405         default:
406             break;
407         }
408         if (s->reg == 0)
409             s->reg = newreg;
410         else
411             s->reg = 0;
412         break;
413     case 1:
414         SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
415         if (s->wregs[5] & 8) { // tx enabled
416             s->tx = val;
417             if (s->chr)
418                 qemu_chr_write(s->chr, &s->tx, 1);
419             else if (s->type == kbd) {
420                 handle_kbd_command(s, val);
421             }
422             s->rregs[0] |= 4; // Tx buffer empty
423             s->rregs[1] |= 1; // All sent
424             set_txint(s);
425         }
426         break;
427     default:
428         break;
429     }
430 }
431
432 static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
433 {
434     SerialState *ser = opaque;
435     ChannelState *s;
436     uint32_t saddr;
437     uint32_t ret;
438     int channel;
439
440     saddr = (addr & 3) >> 1;
441     channel = (addr & SERIAL_MAXADDR) >> 2;
442     s = &ser->chn[channel];
443     switch (saddr) {
444     case 0:
445         SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
446         ret = s->rregs[s->reg];
447         s->reg = 0;
448         return ret;
449     case 1:
450         s->rregs[0] &= ~1;
451         clr_rxint(s);
452         if (s->type == kbd || s->type == mouse)
453             ret = get_queue(s);
454         else
455             ret = s->rx;
456         SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
457         return ret;
458     default:
459         break;
460     }
461     return 0;
462 }
463
464 static int serial_can_receive(void *opaque)
465 {
466     ChannelState *s = opaque;
467     int ret;
468
469     if (((s->wregs[3] & 1) == 0) // Rx not enabled
470         || ((s->rregs[0] & 1) == 1)) // char already available
471         ret = 0;
472     else
473         ret = 1;
474     //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
475     return ret;
476 }
477
478 static void serial_receive_byte(ChannelState *s, int ch)
479 {
480     SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
481     s->rregs[0] |= 1;
482     s->rx = ch;
483     set_rxint(s);
484 }
485
486 static void serial_receive_break(ChannelState *s)
487 {
488     s->rregs[0] |= 0x80;
489     slavio_serial_update_irq(s);
490 }
491
492 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
493 {
494     ChannelState *s = opaque;
495     serial_receive_byte(s, buf[0]);
496 }
497
498 static void serial_event(void *opaque, int event)
499 {
500     ChannelState *s = opaque;
501     if (event == CHR_EVENT_BREAK)
502         serial_receive_break(s);
503 }
504
505 static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
506     slavio_serial_mem_readb,
507     slavio_serial_mem_readb,
508     slavio_serial_mem_readb,
509 };
510
511 static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
512     slavio_serial_mem_writeb,
513     slavio_serial_mem_writeb,
514     slavio_serial_mem_writeb,
515 };
516
517 static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
518 {
519     int tmp;
520     tmp = 0;
521     qemu_put_be32s(f, &tmp); /* unused, was IRQ.  */
522     qemu_put_be32s(f, &s->reg);
523     qemu_put_be32s(f, &s->rxint);
524     qemu_put_be32s(f, &s->txint);
525     qemu_put_be32s(f, &s->rxint_under_svc);
526     qemu_put_be32s(f, &s->txint_under_svc);
527     qemu_put_8s(f, &s->rx);
528     qemu_put_8s(f, &s->tx);
529     qemu_put_buffer(f, s->wregs, 16);
530     qemu_put_buffer(f, s->rregs, 16);
531 }
532
533 static void slavio_serial_save(QEMUFile *f, void *opaque)
534 {
535     SerialState *s = opaque;
536
537     slavio_serial_save_chn(f, &s->chn[0]);
538     slavio_serial_save_chn(f, &s->chn[1]);
539 }
540
541 static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
542 {
543     int tmp;
544
545     if (version_id > 2)
546         return -EINVAL;
547
548     qemu_get_be32s(f, &tmp); /* unused */
549     qemu_get_be32s(f, &s->reg);
550     qemu_get_be32s(f, &s->rxint);
551     qemu_get_be32s(f, &s->txint);
552     if (version_id >= 2) {
553         qemu_get_be32s(f, &s->rxint_under_svc);
554         qemu_get_be32s(f, &s->txint_under_svc);
555     }
556     qemu_get_8s(f, &s->rx);
557     qemu_get_8s(f, &s->tx);
558     qemu_get_buffer(f, s->wregs, 16);
559     qemu_get_buffer(f, s->rregs, 16);
560     return 0;
561 }
562
563 static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
564 {
565     SerialState *s = opaque;
566     int ret;
567
568     ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
569     if (ret != 0)
570         return ret;
571     ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
572     return ret;
573
574 }
575
576 SerialState *slavio_serial_init(int base, qemu_irq irq, CharDriverState *chr1,
577                                 CharDriverState *chr2)
578 {
579     int slavio_serial_io_memory, i;
580     SerialState *s;
581
582     s = qemu_mallocz(sizeof(SerialState));
583     if (!s)
584         return NULL;
585
586     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
587     cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
588
589     s->chn[0].chr = chr1;
590     s->chn[1].chr = chr2;
591
592     for (i = 0; i < 2; i++) {
593         s->chn[i].irq = irq;
594         s->chn[i].chn = 1 - i;
595         s->chn[i].type = ser;
596         if (s->chn[i].chr) {
597             qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
598                                   serial_receive1, serial_event, &s->chn[i]);
599         }
600     }
601     s->chn[0].otherchn = &s->chn[1];
602     s->chn[1].otherchn = &s->chn[0];
603     register_savevm("slavio_serial", base, 2, slavio_serial_save, slavio_serial_load, s);
604     qemu_register_reset(slavio_serial_reset, s);
605     slavio_serial_reset(s);
606     return s;
607 }
608
609 static const uint8_t keycodes[128] = {
610     127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
611     54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
612     79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
613     104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
614     14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
615     113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
616     90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
617     0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
618 };
619
620 static void sunkbd_event(void *opaque, int ch)
621 {
622     ChannelState *s = opaque;
623     int release = ch & 0x80;
624
625     ch = keycodes[ch & 0x7f];
626     KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
627     put_queue(s, ch | release);
628 }
629
630 static void handle_kbd_command(ChannelState *s, int val)
631 {
632     KBD_DPRINTF("Command %d\n", val);
633     switch (val) {
634     case 1: // Reset, return type code
635         clear_queue(s);
636         put_queue(s, 0xff);
637         put_queue(s, 4); // Type 4
638         break;
639     case 7: // Query layout
640     case 0xf:
641         clear_queue(s);
642         put_queue(s, 0xfe);
643         put_queue(s, 19); // XXX, layout?
644         break;
645     default:
646         break;
647     }
648 }
649
650 static void sunmouse_event(void *opaque, 
651                                int dx, int dy, int dz, int buttons_state)
652 {
653     ChannelState *s = opaque;
654     int ch;
655
656     MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
657
658     ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
659
660     if (buttons_state & MOUSE_EVENT_LBUTTON)
661         ch ^= 0x4;
662     if (buttons_state & MOUSE_EVENT_MBUTTON)
663         ch ^= 0x2;
664     if (buttons_state & MOUSE_EVENT_RBUTTON)
665         ch ^= 0x1;
666
667     put_queue(s, ch);
668
669     ch = dx;
670
671     if (ch > 127)
672         ch=127;
673     else if (ch < -127)
674         ch=-127;
675
676     put_queue(s, ch & 0xff);
677
678     ch = -dy;
679
680     if (ch > 127)
681         ch=127;
682     else if (ch < -127)
683         ch=-127;
684
685     put_queue(s, ch & 0xff);
686
687     // MSC protocol specify two extra motion bytes
688
689     put_queue(s, 0);
690     put_queue(s, 0);
691 }
692
693 void slavio_serial_ms_kbd_init(int base, qemu_irq irq)
694 {
695     int slavio_serial_io_memory, i;
696     SerialState *s;
697
698     s = qemu_mallocz(sizeof(SerialState));
699     if (!s)
700         return;
701     for (i = 0; i < 2; i++) {
702         s->chn[i].irq = irq;
703         s->chn[i].chn = 1 - i;
704         s->chn[i].chr = NULL;
705     }
706     s->chn[0].otherchn = &s->chn[1];
707     s->chn[1].otherchn = &s->chn[0];
708     s->chn[0].type = mouse;
709     s->chn[1].type = kbd;
710
711     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
712     cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
713
714     qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
715     qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
716     register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save, slavio_serial_load, s);
717     qemu_register_reset(slavio_serial_reset, s);
718     slavio_serial_reset(s);
719 }