18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu_file.h"
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-char.h"
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "goldfish_device.h"
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectenum {
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TTY_PUT_CHAR       = 0x00,
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TTY_BYTES_READY    = 0x04,
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TTY_CMD            = 0x08,
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TTY_DATA_PTR       = 0x10,
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TTY_DATA_LEN       = 0x14,
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TTY_CMD_INT_DISABLE    = 0,
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TTY_CMD_INT_ENABLE     = 1,
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TTY_CMD_WRITE_BUFFER   = 2,
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TTY_CMD_READ_BUFFER    = 3,
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct tty_state {
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct goldfish_device dev;
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CharDriverState *cs;
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t ptr;
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t ptr_len;
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t ready;
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t data[128];
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t data_count;
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  GOLDFISH_TTY_SAVE_VERSION  1
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void  goldfish_tty_save(QEMUFile*  f, void*  opaque)
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct tty_state*  s = opaque;
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_put_be32( f, s->ptr );
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_put_be32( f, s->ptr_len );
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_put_byte( f, s->ready );
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_put_byte( f, s->data_count );
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_put_buffer( f, s->data, s->data_count );
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int  goldfish_tty_load(QEMUFile*  f, void*  opaque, int  version_id)
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct tty_state*  s = opaque;
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (version_id != GOLDFISH_TTY_SAVE_VERSION)
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->ptr        = qemu_get_be32(f);
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->ptr_len    = qemu_get_be32(f);
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->ready      = qemu_get_byte(f);
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->data_count = qemu_get_byte(f);
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_get_buffer(f, s->data, s->data_count);
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t goldfish_tty_read(void *opaque, target_phys_addr_t offset)
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct tty_state *s = (struct tty_state *)opaque;
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    //printf("goldfish_tty_read %x %x\n", offset, size);
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (offset) {
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TTY_BYTES_READY:
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return s->data_count;
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_abort (cpu_single_env, "goldfish_tty_read: Bad offset %x\n", offset);
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void goldfish_tty_write(void *opaque, target_phys_addr_t offset, uint32_t value)
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct tty_state *s = (struct tty_state *)opaque;
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    //printf("goldfish_tty_read %x %x %x\n", offset, value, size);
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch(offset) {
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TTY_PUT_CHAR: {
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint8_t ch = value;
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if(s->cs)
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                qemu_chr_write(s->cs, &ch, 1);
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } break;
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TTY_CMD:
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch(value) {
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case TTY_CMD_INT_DISABLE:
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if(s->ready) {
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if(s->data_count > 0)
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            goldfish_device_set_irq(&s->dev, 0, 0);
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        s->ready = 0;
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case TTY_CMD_INT_ENABLE:
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if(!s->ready) {
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if(s->data_count > 0)
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            goldfish_device_set_irq(&s->dev, 0, 1);
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        s->ready = 1;
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case TTY_CMD_WRITE_BUFFER:
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if(s->cs) {
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        int len;
1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        target_phys_addr_t  buf;
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        buf = s->ptr;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        len = s->ptr_len;
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        while (len) {
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            char   temp[64];
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            int    to_write = sizeof(temp);
1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            if (to_write > len)
1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                to_write = len;
1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            cpu_memory_rw_debug(cpu_single_env, buf, temp, to_write, 0);
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            qemu_chr_write(s->cs, temp, to_write);
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            buf += to_write;
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            len -= to_write;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        //printf("goldfish_tty_write: got %d bytes from %x\n", s->ptr_len, s->ptr);
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case TTY_CMD_READ_BUFFER:
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if(s->ptr_len > s->data_count)
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        cpu_abort (cpu_single_env, "goldfish_tty_write: reading more data than available %d %d\n", s->ptr_len, s->data_count);
1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cpu_memory_rw_debug(cpu_single_env,s->ptr, s->data, s->ptr_len,1);
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    //printf("goldfish_tty_write: read %d bytes to %x\n", s->ptr_len, s->ptr);
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if(s->data_count > s->ptr_len)
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        memmove(s->data, s->data + s->ptr_len, s->data_count - s->ptr_len);
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->data_count -= s->ptr_len;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if(s->data_count == 0 && s->ready)
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        goldfish_device_set_irq(&s->dev, 0, 0);
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                default:
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_abort (cpu_single_env, "goldfish_tty_write: Bad command %x\n", value);
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            };
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TTY_DATA_PTR:
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->ptr = value;
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TTY_DATA_LEN:
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->ptr_len = value;
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            cpu_abort (cpu_single_env, "goldfish_tty_write: Bad offset %x\n", offset);
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int tty_can_receive(void *opaque)
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct tty_state *s = opaque;
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (sizeof(s->data) - s->data_count);
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tty_receive(void *opaque, const uint8_t *buf, int size)
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct tty_state *s = opaque;
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy(s->data + s->data_count, buf, size);
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->data_count += size;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(s->data_count > 0 && s->ready)
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goldfish_device_set_irq(&s->dev, 0, 1);
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CPUReadMemoryFunc *goldfish_tty_readfn[] = {
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goldfish_tty_read,
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goldfish_tty_read,
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goldfish_tty_read
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CPUWriteMemoryFunc *goldfish_tty_writefn[] = {
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goldfish_tty_write,
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goldfish_tty_write,
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goldfish_tty_write
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint goldfish_tty_add(CharDriverState *cs, int id, uint32_t base, int irq)
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct tty_state *s;
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static int  instance_id = 0;
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = qemu_mallocz(sizeof(*s));
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.name = "goldfish_tty";
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.id = id;
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.base = base;
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.size = 0x1000;
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.irq = irq;
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.irq_count = 1;
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->cs = cs;
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(cs) {
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        qemu_chr_add_handlers(cs, tty_can_receive, tty_receive, NULL, s);
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = goldfish_device_add(&s->dev, goldfish_tty_readfn, goldfish_tty_writefn, s);
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(ret) {
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        qemu_free(s);
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        register_savevm( "goldfish_tty", instance_id++, GOLDFISH_TTY_SAVE_VERSION,
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         goldfish_tty_save, goldfish_tty_load, s);
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
226