VirtualBox

source: vbox/trunk/src/VBox/Devices/Serial/serial.c@ 1

Last change on this file since 1 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
File size: 20.0 KB
Line 
1#ifdef VBOX
2/** @file
3 *
4 * VBox serial device:
5 * Serial communication port driver
6 */
7
8/*
9 * Copyright (C) 2006 InnoTek Systemberatung GmbH
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License as published by the Free Software Foundation,
15 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
16 * distribution. VirtualBox OSE is distributed in the hope that it will
17 * be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * If you received this file as part of a commercial VirtualBox
20 * distribution, then only the terms of your commercial VirtualBox
21 * license agreement apply instead of the previous paragraph.
22 *
23 * --------------------------------------------------------------------
24 *
25 * This code is based on:
26 *
27 * QEMU 16450 UART emulation
28 *
29 * Copyright (c) 2003-2004 Fabrice Bellard
30 *
31 * Permission is hereby granted, free of charge, to any person obtaining a copy
32 * of this software and associated documentation files (the "Software"), to deal
33 * in the Software without restriction, including without limitation the rights
34 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35 * copies of the Software, and to permit persons to whom the Software is
36 * furnished to do so, subject to the following conditions:
37 *
38 * The above copyright notice and this permission notice shall be included in
39 * all copies or substantial portions of the Software.
40 *
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47 * THE SOFTWARE.
48 *
49 */
50
51
52/*******************************************************************************
53* Header Files *
54*******************************************************************************/
55#define LOG_GROUP LOG_GROUP_DEV_SERIAL
56#include <VBox/pdm.h>
57#include <VBox/err.h>
58
59#include <VBox/log.h>
60#include <iprt/assert.h>
61#include <iprt/uuid.h>
62#include <iprt/string.h>
63
64#include "Builtins.h"
65#include "../vl_vbox.h"
66
67#endif /* VBOX */
68
69#ifndef VBOX
70#include "vl.h"
71#endif
72
73//#define DEBUG_SERIAL
74
75#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
76
77#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
78#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
79#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
80#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
81
82#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
83#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
84
85#define UART_IIR_MSI 0x00 /* Modem status interrupt */
86#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
87#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
88#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
89
90/*
91 * These are the definitions for the Modem Control Register
92 */
93#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
94#define UART_MCR_OUT2 0x08 /* Out2 complement */
95#define UART_MCR_OUT1 0x04 /* Out1 complement */
96#define UART_MCR_RTS 0x02 /* RTS complement */
97#define UART_MCR_DTR 0x01 /* DTR complement */
98
99/*
100 * These are the definitions for the Modem Status Register
101 */
102#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
103#define UART_MSR_RI 0x40 /* Ring Indicator */
104#define UART_MSR_DSR 0x20 /* Data Set Ready */
105#define UART_MSR_CTS 0x10 /* Clear to Send */
106#define UART_MSR_DDCD 0x08 /* Delta DCD */
107#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
108#define UART_MSR_DDSR 0x02 /* Delta DSR */
109#define UART_MSR_DCTS 0x01 /* Delta CTS */
110#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
111
112#define UART_LSR_TEMT 0x40 /* Transmitter empty */
113#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
114#define UART_LSR_BI 0x10 /* Break interrupt indicator */
115#define UART_LSR_FE 0x08 /* Frame error indicator */
116#define UART_LSR_PE 0x04 /* Parity error indicator */
117#define UART_LSR_OE 0x02 /* Overrun error indicator */
118#define UART_LSR_DR 0x01 /* Receiver data ready */
119
120struct SerialState {
121 uint8_t divider;
122 uint8_t rbr; /* receive register */
123 uint8_t ier;
124 uint8_t iir; /* read only */
125 uint8_t lcr;
126 uint8_t mcr;
127 uint8_t lsr; /* read only */
128 uint8_t msr; /* read only */
129 uint8_t scr;
130 /* NOTE: this hidden state is necessary for tx irq generation as
131 it can be reset while reading iir */
132 int thr_ipending;
133 SetIRQFunc *set_irq;
134 void *irq_opaque;
135 int irq;
136#ifdef VBOX
137 /* Be careful with pointers in the structure; load just gets the whole structure from the saved state */
138 PPDMDEVINS pDevIns;
139#else
140 CharDriverState *chr;
141#endif
142 int last_break_enable;
143 target_ulong base;
144 int it_shift;
145};
146
147static void serial_update_irq(SerialState *s)
148{
149 if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
150 s->iir = UART_IIR_RDI;
151 } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
152 s->iir = UART_IIR_THRI;
153 } else {
154 s->iir = UART_IIR_NO_INT;
155 }
156 if (s->iir != UART_IIR_NO_INT) {
157#ifdef VBOX
158 s->pDevIns->pDevHlp->pfnISASetIrq (s->pDevIns, s->irq, 1);
159#else
160 s->set_irq(s->irq_opaque, s->irq, 1);
161#endif
162 } else {
163#ifdef VBOX
164 s->pDevIns->pDevHlp->pfnISASetIrq (s->pDevIns, s->irq, 0);
165#else
166 s->set_irq(s->irq_opaque, s->irq, 0);
167#endif
168 }
169}
170
171static void serial_update_parameters(SerialState *s)
172{
173 int speed, parity, data_bits, stop_bits;
174 QEMUSerialSetParams ssp;
175
176 if (s->lcr & 0x08) {
177 if (s->lcr & 0x10)
178 parity = 'E';
179 else
180 parity = 'O';
181 } else {
182 parity = 'N';
183 }
184 if (s->lcr & 0x04)
185 stop_bits = 2;
186 else
187 stop_bits = 1;
188 data_bits = (s->lcr & 0x03) + 5;
189 if (s->divider == 0)
190 return;
191 speed = 115200 / s->divider;
192 ssp.speed = speed;
193 ssp.parity = parity;
194 ssp.data_bits = data_bits;
195 ssp.stop_bits = stop_bits;
196#ifndef VBOX
197 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
198#endif
199#if 0
200 printf("speed=%d parity=%c data=%d stop=%d\n",
201 speed, parity, data_bits, stop_bits);
202#endif
203}
204
205static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
206{
207 SerialState *s = opaque;
208 unsigned char ch;
209
210 addr &= 7;
211#ifdef DEBUG_SERIAL
212 printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
213#endif
214 switch(addr) {
215 default:
216 case 0:
217 if (s->lcr & UART_LCR_DLAB) {
218 s->divider = (s->divider & 0xff00) | val;
219 serial_update_parameters(s);
220 } else {
221 s->thr_ipending = 0;
222 s->lsr &= ~UART_LSR_THRE;
223 serial_update_irq(s);
224 ch = val;
225#ifndef VBOX
226 qemu_chr_write(s->chr, &ch, 1);
227#endif
228 s->thr_ipending = 1;
229 s->lsr |= UART_LSR_THRE;
230 s->lsr |= UART_LSR_TEMT;
231 serial_update_irq(s);
232 }
233 break;
234 case 1:
235 if (s->lcr & UART_LCR_DLAB) {
236 s->divider = (s->divider & 0x00ff) | (val << 8);
237 serial_update_parameters(s);
238 } else {
239 s->ier = val & 0x0f;
240 if (s->lsr & UART_LSR_THRE) {
241 s->thr_ipending = 1;
242 }
243 serial_update_irq(s);
244 }
245 break;
246 case 2:
247 break;
248 case 3:
249 {
250 int break_enable;
251 s->lcr = val;
252 serial_update_parameters(s);
253 break_enable = (val >> 6) & 1;
254 if (break_enable != s->last_break_enable) {
255 s->last_break_enable = break_enable;
256#ifndef VBOX
257 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
258 &break_enable);
259#endif
260 }
261 }
262 break;
263 case 4:
264 s->mcr = val & 0x1f;
265 break;
266 case 5:
267 break;
268 case 6:
269 break;
270 case 7:
271 s->scr = val;
272 break;
273 }
274}
275
276static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
277{
278 SerialState *s = opaque;
279 uint32_t ret;
280
281 addr &= 7;
282 switch(addr) {
283 default:
284 case 0:
285 if (s->lcr & UART_LCR_DLAB) {
286 ret = s->divider & 0xff;
287 } else {
288 ret = s->rbr;
289 s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
290 serial_update_irq(s);
291 }
292 break;
293 case 1:
294 if (s->lcr & UART_LCR_DLAB) {
295 ret = (s->divider >> 8) & 0xff;
296 } else {
297 ret = s->ier;
298 }
299 break;
300 case 2:
301 ret = s->iir;
302 /* reset THR pending bit */
303 if ((ret & 0x7) == UART_IIR_THRI)
304 s->thr_ipending = 0;
305 serial_update_irq(s);
306 break;
307 case 3:
308 ret = s->lcr;
309 break;
310 case 4:
311 ret = s->mcr;
312 break;
313 case 5:
314 ret = s->lsr;
315 break;
316 case 6:
317 if (s->mcr & UART_MCR_LOOP) {
318 /* in loopback, the modem output pins are connected to the
319 inputs */
320 ret = (s->mcr & 0x0c) << 4;
321 ret |= (s->mcr & 0x02) << 3;
322 ret |= (s->mcr & 0x01) << 5;
323 } else {
324 ret = s->msr;
325 }
326 break;
327 case 7:
328 ret = s->scr;
329 break;
330 }
331#ifdef DEBUG_SERIAL
332 printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
333#endif
334 return ret;
335}
336
337#ifndef VBOX
338static int serial_can_receive(SerialState *s)
339{
340 return !(s->lsr & UART_LSR_DR);
341}
342
343static void serial_receive_byte(SerialState *s, int ch)
344{
345 s->rbr = ch;
346 s->lsr |= UART_LSR_DR;
347 serial_update_irq(s);
348}
349
350static void serial_receive_break(SerialState *s)
351{
352 s->rbr = 0;
353 s->lsr |= UART_LSR_BI | UART_LSR_DR;
354 serial_update_irq(s);
355}
356
357static int serial_can_receive1(void *opaque)
358{
359 SerialState *s = opaque;
360 return serial_can_receive(s);
361}
362
363static void serial_receive1(void *opaque, const uint8_t *buf, int size)
364{
365 SerialState *s = opaque;
366 serial_receive_byte(s, buf[0]);
367}
368
369static void serial_event(void *opaque, int event)
370{
371 SerialState *s = opaque;
372 if (event == CHR_EVENT_BREAK)
373 serial_receive_break(s);
374}
375
376static void serial_save(QEMUFile *f, void *opaque)
377{
378 SerialState *s = opaque;
379
380 qemu_put_8s(f,&s->divider);
381 qemu_put_8s(f,&s->rbr);
382 qemu_put_8s(f,&s->ier);
383 qemu_put_8s(f,&s->iir);
384 qemu_put_8s(f,&s->lcr);
385 qemu_put_8s(f,&s->mcr);
386 qemu_put_8s(f,&s->lsr);
387 qemu_put_8s(f,&s->msr);
388 qemu_put_8s(f,&s->scr);
389}
390
391static int serial_load(QEMUFile *f, void *opaque, int version_id)
392{
393 SerialState *s = opaque;
394
395 if(version_id != 1)
396 return -EINVAL;
397
398 qemu_get_8s(f,&s->divider);
399 qemu_get_8s(f,&s->rbr);
400 qemu_get_8s(f,&s->ier);
401 qemu_get_8s(f,&s->iir);
402 qemu_get_8s(f,&s->lcr);
403 qemu_get_8s(f,&s->mcr);
404 qemu_get_8s(f,&s->lsr);
405 qemu_get_8s(f,&s->msr);
406 qemu_get_8s(f,&s->scr);
407
408 return 0;
409}
410
411/* If fd is zero, it means that the serial device uses the console */
412SerialState *serial_init(SetIRQFunc *set_irq, void *opaque,
413 int base, int irq, CharDriverState *chr)
414{
415 SerialState *s;
416
417 s = qemu_mallocz(sizeof(SerialState));
418 if (!s)
419 return NULL;
420 s->set_irq = set_irq;
421 s->irq_opaque = opaque;
422 s->irq = irq;
423 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
424 s->iir = UART_IIR_NO_INT;
425 s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
426
427 register_savevm("serial", base, 1, serial_save, serial_load, s);
428
429 register_ioport_write(base, 8, 1, serial_ioport_write, s);
430 register_ioport_read(base, 8, 1, serial_ioport_read, s);
431 s->chr = chr;
432 qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
433 qemu_chr_add_event_handler(chr, serial_event);
434 return s;
435}
436
437/* Memory mapped interface */
438static uint32_t serial_mm_readb (void *opaque, target_phys_addr_t addr)
439{
440 SerialState *s = opaque;
441
442 return serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFF;
443}
444
445static void serial_mm_writeb (void *opaque,
446 target_phys_addr_t addr, uint32_t value)
447{
448 SerialState *s = opaque;
449
450 serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFF);
451}
452
453static uint32_t serial_mm_readw (void *opaque, target_phys_addr_t addr)
454{
455 SerialState *s = opaque;
456
457 return serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
458}
459
460static void serial_mm_writew (void *opaque,
461 target_phys_addr_t addr, uint32_t value)
462{
463 SerialState *s = opaque;
464
465 serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
466}
467
468static uint32_t serial_mm_readl (void *opaque, target_phys_addr_t addr)
469{
470 SerialState *s = opaque;
471
472 return serial_ioport_read(s, (addr - s->base) >> s->it_shift);
473}
474
475static void serial_mm_writel (void *opaque,
476 target_phys_addr_t addr, uint32_t value)
477{
478 SerialState *s = opaque;
479
480 serial_ioport_write(s, (addr - s->base) >> s->it_shift, value);
481}
482
483static CPUReadMemoryFunc *serial_mm_read[] = {
484 &serial_mm_readb,
485 &serial_mm_readw,
486 &serial_mm_readl,
487};
488
489static CPUWriteMemoryFunc *serial_mm_write[] = {
490 &serial_mm_writeb,
491 &serial_mm_writew,
492 &serial_mm_writel,
493};
494
495SerialState *serial_mm_init (SetIRQFunc *set_irq, void *opaque,
496 target_ulong base, int it_shift,
497 int irq, CharDriverState *chr)
498{
499 SerialState *s;
500 int s_io_memory;
501
502 s = qemu_mallocz(sizeof(SerialState));
503 if (!s)
504 return NULL;
505 s->set_irq = set_irq;
506 s->irq_opaque = opaque;
507 s->irq = irq;
508 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
509 s->iir = UART_IIR_NO_INT;
510 s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
511 s->base = base;
512 s->it_shift = it_shift;
513
514 register_savevm("serial", base, 1, serial_save, serial_load, s);
515
516 s_io_memory = cpu_register_io_memory(0, serial_mm_read,
517 serial_mm_write, s);
518 cpu_register_physical_memory(base, 8 << it_shift, s_io_memory);
519 s->chr = chr;
520 qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
521 qemu_chr_add_event_handler(chr, serial_event);
522 return s;
523}
524
525#else
526
527static DECLCALLBACK(int) serial_io_write (PPDMDEVINS pDevIns,
528 void *pvUser,
529 RTIOPORT Port,
530 uint32_t u32,
531 unsigned cb)
532{
533 if (cb == 1) {
534 serial_ioport_write (pvUser, Port, u32);
535 }
536 else {
537 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
538 }
539 return VINF_SUCCESS;
540}
541
542static DECLCALLBACK(int) serial_io_read (PPDMDEVINS pDevIns,
543 void *pvUser,
544 RTIOPORT Port,
545 uint32_t *pu32,
546 unsigned cb)
547{
548 if (cb == 1) {
549 *pu32 = serial_ioport_read (pvUser, Port);
550 return VINF_SUCCESS;
551 }
552 else {
553 return VERR_IOM_IOPORT_UNUSED;
554 }
555}
556
557static DECLCALLBACK(int) SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
558{
559 SerialState *s = PDMINS2DATA (pDevIns, SerialState *);
560 SSMR3PutMem(pSSMHandle, s, sizeof(*s));
561 return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
562}
563
564static DECLCALLBACK(int) LoadExec (PPDMDEVINS pDevIns,
565 PSSMHANDLE pSSMHandle,
566 uint32_t u32Version)
567{
568 int rc;
569 uint32_t u32;
570 SerialState *s = PDMINS2DATA (pDevIns, SerialState *);
571
572 if (u32Version != 1) {
573 AssertMsgFailed(("u32Version=%d\n", u32Version));
574 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
575 }
576
577 rc = SSMR3GetMem(pSSMHandle, s, sizeof(*s));
578 if (VBOX_FAILURE(rc))
579 return rc;
580
581 rc = SSMR3GetU32(pSSMHandle, &u32);
582 if (VBOX_FAILURE(rc))
583 return rc;
584
585 if (u32 != ~0U) {
586 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
587 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
588 }
589 /* Be careful with pointers in the structure; load just gets the whole structure from the saved state */
590 s->pDevIns = pDevIns;
591 return VINF_SUCCESS;
592}
593
594
595/**
596 * Construct a device instance for a VM.
597 *
598 * @returns VBox status.
599 * @param pDevIns The device instance data.
600 * If the registration structure is needed, pDevIns->pDevReg points to it.
601 * @param iInstance Instance number. Use this to figure out which registers and such to use.
602 * The device number is also found in pDevIns->iInstance, but since it's
603 * likely to be freqently used PDM passes it as parameter.
604 * @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
605 * of the device instance. It's also found in pDevIns->pCfgHandle, but like
606 * iInstance it's expected to be used a bit in this function.
607 */
608static DECLCALLBACK(int) serialConstruct(PPDMDEVINS pDevIns,
609 int iInstance,
610 PCFGMNODE pCfgHandle)
611{
612 int rc;
613 SerialState *s = PDMINS2DATA(pDevIns, SerialState*);
614 uint16_t io_base;
615 uint8_t irq_lvl;
616
617 Assert(iInstance < 2);
618
619 s->pDevIns = pDevIns;
620 /*
621 * Validate configuration.
622 */
623 if (!CFGMR3AreValuesValid(pCfgHandle, "IRQ\0IOBase\0")) {
624 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
625 }
626
627
628/** @todo r=bird: Check for VERR_CFGM_VALUE_NOT_FOUND and provide sensible defaults.
629 * Also do AssertMsgFailed(("Configuration error:....)) in the failure cases of CFGMR3Query*()
630 * and CFGR3AreValuesValid() like we're doing in the other devices. */
631 rc = CFGMR3QueryU8 (pCfgHandle, "IRQ", &irq_lvl);
632 if (VBOX_FAILURE (rc)) {
633 return rc;
634 }
635
636 rc = CFGMR3QueryU16 (pCfgHandle, "IOBase", &io_base);
637 if (VBOX_FAILURE (rc)) {
638 return rc;
639 }
640
641 Log(("serialConstruct instance %d iobase=%04x irq=%d\n", iInstance, io_base, irq_lvl));
642
643 s->irq = irq_lvl;
644 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
645 s->iir = UART_IIR_NO_INT;
646
647 rc = pDevIns->pDevHlp->pfnIOPortRegister (
648 pDevIns,
649 io_base,
650 8,
651 s,
652 serial_io_write,
653 serial_io_read,
654 NULL, NULL,
655 "SERIAL"
656 );
657 if (VBOX_FAILURE (rc)) {
658 return rc;
659 }
660
661 rc = pDevIns->pDevHlp->pfnSSMRegister (
662 pDevIns, /* pDevIns */
663 pDevIns->pDevReg->szDeviceName, /* pszName */
664 iInstance, /* u32Instance */
665 1 /* u32Version */,
666 sizeof (*s), /* cbGuess */
667 NULL, /* pfnSavePrep */
668 SaveExec, /* pfnSaveExec */
669 NULL, /* pfnSaveDone */
670 NULL, /* pfnLoadPrep */
671 LoadExec, /* pfnLoadExec */
672 NULL /* pfnLoadDone */
673 );
674 if (VBOX_FAILURE(rc))
675 return rc;
676
677 return VINF_SUCCESS;
678}
679
680/**
681 * The device registration structure.
682 */
683const PDMDEVREG g_DeviceSerialPort =
684{
685 /* u32Version */
686 PDM_DEVREG_VERSION,
687 /* szDeviceName */
688 "serial",
689 /* szGCMod */
690 "",
691 /* szR0Mod */
692 "",
693 /* pszDescription */
694 "Serial Communication Port",
695 /* fFlags */
696 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
697 /* fClass */
698 PDM_DEVREG_CLASS_SERIAL_PORT,
699 /* cMaxInstances */
700 1,
701 /* cbInstance */
702 sizeof(SerialState),
703 /* pfnConstruct */
704 serialConstruct,
705 /* pfnDestruct */
706 NULL,
707 /* pfnRelocate */
708 NULL,
709 /* pfnIOCtl */
710 NULL,
711 /* pfnPowerOn */
712 NULL,
713 /* pfnReset */
714 NULL,
715 /* pfnSuspend */
716 NULL,
717 /* pfnResume */
718 NULL,
719 /* pfnAttach */
720 NULL,
721 /* pfnDetach */
722 NULL,
723 /* pfnQueryInterface. */
724 NULL
725};
726#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette