aboutsummaryrefslogtreecommitdiffstats
path: root/charpipe.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:35 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:35 -0800
commitf721e3ac031f892af46f255a47d7f54a91317b30 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /charpipe.c
parentbae1bc39312d5019bd9a5b8d840a529213a69a17 (diff)
downloadexternal_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.zip
external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.gz
external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'charpipe.c')
-rw-r--r--charpipe.c273
1 files changed, 0 insertions, 273 deletions
diff --git a/charpipe.c b/charpipe.c
deleted file mode 100644
index d6b9829..0000000
--- a/charpipe.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu-char.h"
-#include "cbuffer.h"
-#include "qemu_debug.h"
-
-#define xxDEBUG
-
-#ifdef DEBUG
-# include <stdio.h>
-# define D(...) ( fprintf( stderr, __VA_ARGS__ ), fprintf(stderr, "\n") )
-#else
-# define D(...) ((void)0)
-#endif
-
-/* we want to implement a bi-directionnal communication channel
- * between two QEMU character drivers that merge well into the
- * QEMU event loop.
- *
- * each half of the channel has its own object and buffer, and
- * we implement communication through charpipe_poll() which
- * must be called by the main event loop after its call to select()
- *
- */
-
-#define BIP_BUFFER_SIZE 512
-
-typedef struct BipBuffer {
- struct BipBuffer* next;
- CBuffer cb[1];
- char buff[ BIP_BUFFER_SIZE ];
-} BipBuffer;
-
-static BipBuffer* _free_bip_buffers;
-
-static BipBuffer*
-bip_buffer_alloc( void )
-{
- BipBuffer* bip = _free_bip_buffers;
- if (bip != NULL) {
- _free_bip_buffers = bip->next;
- } else {
- bip = malloc( sizeof(*bip) );
- if (bip == NULL) {
- derror( "%s: not enough memory", __FUNCTION__ );
- exit(1);
- }
- }
- bip->next = NULL;
- cbuffer_reset( bip->cb, bip->buff, sizeof(bip->buff) );
- return bip;
-}
-
-static void
-bip_buffer_free( BipBuffer* bip )
-{
- bip->next = _free_bip_buffers;
- _free_bip_buffers = bip;
-}
-
-/* this models each half of the charpipe */
-typedef struct CharPipeHalf {
- CharDriverState cs[1];
- BipBuffer* bip_first;
- BipBuffer* bip_last;
- struct CharPipeHalf* peer; /* NULL if closed */
-} CharPipeHalf;
-
-
-
-static void
-charpipehalf_close( CharDriverState* cs )
-{
- CharPipeHalf* ph = cs->opaque;
-
- while (ph->bip_first) {
- BipBuffer* bip = ph->bip_first;
- ph->bip_first = bip->next;
- bip_buffer_free(bip);
- }
- ph->bip_last = NULL;
- ph->peer = NULL;
-}
-
-
-static int
-charpipehalf_write( CharDriverState* cs, const uint8_t* buf, int len )
-{
- CharPipeHalf* ph = cs->opaque;
- CharPipeHalf* peer = ph->peer;
- BipBuffer* bip = ph->bip_last;
- int ret = 0;
-
- D("%s: writing %d bytes to %p: '%s'", __FUNCTION__,
- len, ph, quote_bytes( buf, len ));
-
- if (bip == NULL && peer != NULL && peer->cs->chr_read != NULL) {
- /* no buffered data, try to write directly to the peer */
- while (len > 0) {
- int size;
-
- if (peer->cs->chr_can_read) {
- size = qemu_chr_can_read( peer->cs );
- if (size == 0)
- break;
-
- if (size > len)
- size = len;
- } else
- size = len;
-
- qemu_chr_read( peer->cs, (uint8_t*)buf, size );
- buf += size;
- len -= size;
- ret += size;
- }
- }
-
- if (len == 0)
- return ret;
-
- /* buffer the remaining data */
- if (bip == NULL) {
- bip = bip_buffer_alloc();
- ph->bip_first = ph->bip_last = bip;
- }
-
- while (len > 0) {
- int len2 = cbuffer_write( bip->cb, buf, len );
-
- buf += len2;
- ret += len2;
- len -= len2;
- if (len == 0)
- break;
-
- /* ok, we need another buffer */
- ph->bip_last = bip_buffer_alloc();
- bip->next = ph->bip_last;
- bip = ph->bip_last;
- }
- return ret;
-}
-
-
-static void
-charpipehalf_poll( CharPipeHalf* ph )
-{
- CharPipeHalf* peer = ph->peer;
- int size;
-
- if (peer == NULL || peer->cs->chr_read == NULL)
- return;
-
- while (1) {
- BipBuffer* bip = ph->bip_first;
- uint8_t* base;
- int avail;
-
- if (bip == NULL)
- break;
-
- size = cbuffer_read_avail(bip->cb);
- if (size == 0) {
- ph->bip_first = bip->next;
- if (ph->bip_first == NULL)
- ph->bip_last = NULL;
- bip_buffer_free(bip);
- continue;
- }
-
- if (ph->cs->chr_can_read) {
- int size2 = qemu_chr_can_read(peer->cs);
-
- if (size2 == 0)
- break;
-
- if (size > size2)
- size = size2;
- }
-
- avail = cbuffer_read_peek( bip->cb, &base );
- if (avail > size)
- avail = size;
- D("%s: sending %d bytes from %p: '%s'", __FUNCTION__,
- avail, ph, quote_bytes( base, avail ));
-
- qemu_chr_read( peer->cs, base, avail );
- cbuffer_read_step( bip->cb, avail );
- }
-}
-
-
-static void
-charpipehalf_init( CharPipeHalf* ph, CharPipeHalf* peer )
-{
- CharDriverState* cs = ph->cs;
-
- ph->bip_first = NULL;
- ph->bip_last = NULL;
- ph->peer = peer;
-
- cs->chr_write = charpipehalf_write;
- cs->chr_ioctl = NULL;
- cs->chr_send_event = NULL;
- cs->chr_close = charpipehalf_close;
- cs->opaque = ph;
-}
-
-
-typedef struct CharPipeState {
- CharPipeHalf a[1];
- CharPipeHalf b[1];
-} CharPipeState;
-
-
-
-#define MAX_CHAR_PIPES 8
-
-static CharPipeState _s_charpipes[ MAX_CHAR_PIPES ];
-
-int
-qemu_chr_open_charpipe( CharDriverState* *pfirst, CharDriverState* *psecond )
-{
- CharPipeState* cp = _s_charpipes;
- CharPipeState* cp_end = cp + MAX_CHAR_PIPES;
-
- for ( ; cp < cp_end; cp++ ) {
- if ( cp->a->peer == NULL && cp->b->peer == NULL )
- break;
- }
-
- if (cp == cp_end) { /* can't allocate one */
- *pfirst = NULL;
- *psecond = NULL;
- return -1;
- }
-
- charpipehalf_init( cp->a, cp->b );
- charpipehalf_init( cp->b, cp->a );
-
- *pfirst = cp->a->cs;
- *psecond = cp->b->cs;
- return 0;
-}
-
-void
-charpipe_poll( void )
-{
- CharPipeState* cp = _s_charpipes;
- CharPipeState* cp_end = cp + MAX_CHAR_PIPES;
-
- for ( ; cp < cp_end; cp++ ) {
- CharPipeHalf* half;
-
- half = cp->a;
- if (half->peer != NULL)
- charpipehalf_poll(half);
-
- half = cp->b;
- if (half->peer != NULL)
- charpipehalf_poll(half);
- }
-}