1 /* Copyright (C) 2007-2008 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 #include "sysemu/char.h" 13 #include "android/cbuffer.h" 14 #include "android/qemu-debug.h" 15 16 #define xxDEBUG 17 18 #ifdef DEBUG 19 # include <stdio.h> 20 # define D(...) ( fprintf( stderr, __VA_ARGS__ ), fprintf(stderr, "\n") ) 21 #else 22 # define D(...) ((void)0) 23 #endif 24 25 /* we want to implement a bi-directionnal communication channel 26 * between two QEMU character drivers that merge well into the 27 * QEMU event loop. 28 * 29 * each half of the channel has its own object and buffer, and 30 * we implement communication through charpipe_poll() which 31 * must be called by the main event loop after its call to select() 32 * 33 */ 34 35 #define BIP_BUFFER_SIZE 512 36 37 typedef struct BipBuffer { 38 struct BipBuffer* next; 39 CBuffer cb[1]; 40 char buff[ BIP_BUFFER_SIZE ]; 41 } BipBuffer; 42 43 static BipBuffer* _free_bip_buffers; 44 45 static BipBuffer* 46 bip_buffer_alloc( void ) 47 { 48 BipBuffer* bip = _free_bip_buffers; 49 if (bip != NULL) { 50 _free_bip_buffers = bip->next; 51 } else { 52 bip = malloc( sizeof(*bip) ); 53 if (bip == NULL) { 54 derror( "%s: not enough memory", __FUNCTION__ ); 55 exit(1); 56 } 57 } 58 bip->next = NULL; 59 cbuffer_reset( bip->cb, bip->buff, sizeof(bip->buff) ); 60 return bip; 61 } 62 63 static void 64 bip_buffer_free( BipBuffer* bip ) 65 { 66 bip->next = _free_bip_buffers; 67 _free_bip_buffers = bip; 68 } 69 70 /* this models each half of the charpipe */ 71 typedef struct CharPipeHalf { 72 CharDriverState cs[1]; 73 BipBuffer* bip_first; 74 BipBuffer* bip_last; 75 struct CharPipeHalf* peer; /* NULL if closed */ 76 } CharPipeHalf; 77 78 79 80 static void 81 charpipehalf_close( CharDriverState* cs ) 82 { 83 CharPipeHalf* ph = cs->opaque; 84 85 while (ph->bip_first) { 86 BipBuffer* bip = ph->bip_first; 87 ph->bip_first = bip->next; 88 bip_buffer_free(bip); 89 } 90 ph->bip_last = NULL; 91 ph->peer = NULL; 92 } 93 94 95 static int 96 charpipehalf_write( CharDriverState* cs, const uint8_t* buf, int len ) 97 { 98 CharPipeHalf* ph = cs->opaque; 99 CharPipeHalf* peer = ph->peer; 100 BipBuffer* bip = ph->bip_last; 101 int ret = 0; 102 103 D("%s: writing %d bytes to %p: '%s'", __FUNCTION__, 104 len, ph, quote_bytes( buf, len )); 105 106 if (bip == NULL && peer != NULL && peer->cs->chr_read != NULL) { 107 /* no buffered data, try to write directly to the peer */ 108 while (len > 0) { 109 int size; 110 111 if (peer->cs->chr_can_read) { 112 size = qemu_chr_can_read( peer->cs ); 113 if (size == 0) 114 break; 115 116 if (size > len) 117 size = len; 118 } else 119 size = len; 120 121 qemu_chr_read( peer->cs, (uint8_t*)buf, size ); 122 buf += size; 123 len -= size; 124 ret += size; 125 } 126 } 127 128 if (len == 0) 129 return ret; 130 131 /* buffer the remaining data */ 132 if (bip == NULL) { 133 bip = bip_buffer_alloc(); 134 ph->bip_first = ph->bip_last = bip; 135 } 136 137 while (len > 0) { 138 int len2 = cbuffer_write( bip->cb, buf, len ); 139 140 buf += len2; 141 ret += len2; 142 len -= len2; 143 if (len == 0) 144 break; 145 146 /* ok, we need another buffer */ 147 ph->bip_last = bip_buffer_alloc(); 148 bip->next = ph->bip_last; 149 bip = ph->bip_last; 150 } 151 return ret; 152 } 153 154 155 static void 156 charpipehalf_poll( CharPipeHalf* ph ) 157 { 158 CharPipeHalf* peer = ph->peer; 159 int size; 160 161 if (peer == NULL || peer->cs->chr_read == NULL) 162 return; 163 164 while (1) { 165 BipBuffer* bip = ph->bip_first; 166 uint8_t* base; 167 int avail; 168 169 if (bip == NULL) 170 break; 171 172 size = cbuffer_read_avail(bip->cb); 173 if (size == 0) { 174 ph->bip_first = bip->next; 175 if (ph->bip_first == NULL) 176 ph->bip_last = NULL; 177 bip_buffer_free(bip); 178 continue; 179 } 180 181 if (ph->cs->chr_can_read) { 182 int size2 = qemu_chr_can_read(peer->cs); 183 184 if (size2 == 0) 185 break; 186 187 if (size > size2) 188 size = size2; 189 } 190 191 avail = cbuffer_read_peek( bip->cb, &base ); 192 if (avail > size) 193 avail = size; 194 D("%s: sending %d bytes from %p: '%s'", __FUNCTION__, 195 avail, ph, quote_bytes( base, avail )); 196 197 qemu_chr_read( peer->cs, base, avail ); 198 cbuffer_read_step( bip->cb, avail ); 199 } 200 } 201 202 203 static void 204 charpipehalf_init( CharPipeHalf* ph, CharPipeHalf* peer ) 205 { 206 CharDriverState* cs = ph->cs; 207 208 ph->bip_first = NULL; 209 ph->bip_last = NULL; 210 ph->peer = peer; 211 212 cs->chr_write = charpipehalf_write; 213 cs->chr_ioctl = NULL; 214 cs->chr_send_event = NULL; 215 cs->chr_close = charpipehalf_close; 216 cs->opaque = ph; 217 } 218 219 220 typedef struct CharPipeState { 221 CharPipeHalf a[1]; 222 CharPipeHalf b[1]; 223 } CharPipeState; 224 225 226 227 #define MAX_CHAR_PIPES 8 228 229 static CharPipeState _s_charpipes[ MAX_CHAR_PIPES ]; 230 231 int 232 qemu_chr_open_charpipe( CharDriverState* *pfirst, CharDriverState* *psecond ) 233 { 234 CharPipeState* cp = _s_charpipes; 235 CharPipeState* cp_end = cp + MAX_CHAR_PIPES; 236 237 for ( ; cp < cp_end; cp++ ) { 238 if ( cp->a->peer == NULL && cp->b->peer == NULL ) 239 break; 240 } 241 242 if (cp == cp_end) { /* can't allocate one */ 243 *pfirst = NULL; 244 *psecond = NULL; 245 return -1; 246 } 247 248 charpipehalf_init( cp->a, cp->b ); 249 charpipehalf_init( cp->b, cp->a ); 250 251 *pfirst = cp->a->cs; 252 *psecond = cp->b->cs; 253 return 0; 254 } 255 256 /** This models a charbuffer, an object used to buffer 257 ** the data that is sent to a given endpoint CharDriverState 258 ** object. 259 ** 260 ** On the other hand, any can_read() / read() request performed 261 ** by the endpoint will be passed to the CharBuffer's corresponding 262 ** handlers. 263 **/ 264 265 typedef struct CharBuffer { 266 CharDriverState cs[1]; 267 BipBuffer* bip_first; 268 BipBuffer* bip_last; 269 CharDriverState* endpoint; /* NULL if closed */ 270 char closing; 271 } CharBuffer; 272 273 274 static void 275 charbuffer_close( CharDriverState* cs ) 276 { 277 CharBuffer* cbuf = cs->opaque; 278 279 while (cbuf->bip_first) { 280 BipBuffer* bip = cbuf->bip_first; 281 cbuf->bip_first = bip->next; 282 bip_buffer_free(bip); 283 } 284 cbuf->bip_last = NULL; 285 cbuf->endpoint = NULL; 286 287 if (cbuf->endpoint != NULL) { 288 qemu_chr_close(cbuf->endpoint); 289 cbuf->endpoint = NULL; 290 } 291 } 292 293 static int 294 charbuffer_write( CharDriverState* cs, const uint8_t* buf, int len ) 295 { 296 CharBuffer* cbuf = cs->opaque; 297 CharDriverState* peer = cbuf->endpoint; 298 BipBuffer* bip = cbuf->bip_last; 299 int ret = 0; 300 301 D("%s: writing %d bytes to %p: '%s'", __FUNCTION__, 302 len, cbuf, quote_bytes( buf, len )); 303 304 if (bip == NULL && peer != NULL) { 305 /* no buffered data, try to write directly to the peer */ 306 int size = qemu_chr_write(peer, buf, len); 307 308 if (size < 0) /* just to be safe */ 309 size = 0; 310 else if (size > len) 311 size = len; 312 313 buf += size; 314 ret += size; 315 len -= size; 316 } 317 318 if (len == 0) 319 return ret; 320 321 /* buffer the remaining data */ 322 if (bip == NULL) { 323 bip = bip_buffer_alloc(); 324 cbuf->bip_first = cbuf->bip_last = bip; 325 } 326 327 while (len > 0) { 328 int len2 = cbuffer_write( bip->cb, buf, len ); 329 330 buf += len2; 331 ret += len2; 332 len -= len2; 333 if (len == 0) 334 break; 335 336 /* ok, we need another buffer */ 337 cbuf->bip_last = bip_buffer_alloc(); 338 bip->next = cbuf->bip_last; 339 bip = cbuf->bip_last; 340 } 341 return ret; 342 } 343 344 345 static void 346 charbuffer_poll( CharBuffer* cbuf ) 347 { 348 CharDriverState* peer = cbuf->endpoint; 349 350 if (peer == NULL) 351 return; 352 353 while (1) { 354 BipBuffer* bip = cbuf->bip_first; 355 uint8_t* base; 356 int avail; 357 int size; 358 359 if (bip == NULL) 360 break; 361 362 avail = cbuffer_read_peek( bip->cb, &base ); 363 if (avail == 0) { 364 cbuf->bip_first = bip->next; 365 if (cbuf->bip_first == NULL) 366 cbuf->bip_last = NULL; 367 bip_buffer_free(bip); 368 continue; 369 } 370 371 size = qemu_chr_write( peer, base, avail ); 372 373 if (size < 0) /* just to be safe */ 374 size = 0; 375 else if (size > avail) 376 size = avail; 377 378 cbuffer_read_step( bip->cb, size ); 379 380 if (size < avail) 381 break; 382 } 383 } 384 385 386 static void 387 charbuffer_update_handlers( CharDriverState* cs ) 388 { 389 CharBuffer* cbuf = cs->opaque; 390 391 qemu_chr_add_handlers( cbuf->endpoint, 392 cs->chr_can_read, 393 cs->chr_read, 394 cs->chr_event, 395 cs->handler_opaque ); 396 } 397 398 399 static void 400 charbuffer_init( CharBuffer* cbuf, CharDriverState* endpoint ) 401 { 402 CharDriverState* cs = cbuf->cs; 403 404 cbuf->bip_first = NULL; 405 cbuf->bip_last = NULL; 406 cbuf->endpoint = endpoint; 407 408 cs->chr_write = charbuffer_write; 409 cs->chr_ioctl = NULL; 410 cs->chr_send_event = NULL; 411 cs->chr_close = charbuffer_close; 412 cs->chr_update_read_handler = charbuffer_update_handlers; 413 cs->opaque = cbuf; 414 } 415 416 #define MAX_CHAR_BUFFERS 8 417 418 static CharBuffer _s_charbuffers[ MAX_CHAR_BUFFERS ]; 419 420 CharDriverState* 421 qemu_chr_open_buffer( CharDriverState* endpoint ) 422 { 423 CharBuffer* cbuf = _s_charbuffers; 424 CharBuffer* cbuf_end = cbuf + MAX_CHAR_BUFFERS; 425 426 if (endpoint == NULL) 427 return NULL; 428 429 for ( ; cbuf < cbuf_end; cbuf++ ) { 430 if (cbuf->endpoint == NULL) 431 break; 432 } 433 434 if (cbuf == cbuf_end) 435 return NULL; 436 437 charbuffer_init(cbuf, endpoint); 438 return cbuf->cs; 439 } 440 441 442 void 443 charpipe_poll( void ) 444 { 445 CharPipeState* cp = _s_charpipes; 446 CharPipeState* cp_end = cp + MAX_CHAR_PIPES; 447 448 CharBuffer* cb = _s_charbuffers; 449 CharBuffer* cb_end = cb + MAX_CHAR_BUFFERS; 450 451 /* poll the charpipes */ 452 for ( ; cp < cp_end; cp++ ) { 453 CharPipeHalf* half; 454 455 half = cp->a; 456 if (half->peer != NULL) 457 charpipehalf_poll(half); 458 459 half = cp->b; 460 if (half->peer != NULL) 461 charpipehalf_poll(half); 462 } 463 464 /* poll the charbuffers */ 465 for ( ; cb < cb_end; cb++ ) { 466 if (cb->endpoint != NULL) 467 charbuffer_poll(cb); 468 } 469 } 470