VirtualBox

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

Last change on this file since 61 was 61, checked in by vboxsync, 18 years ago

Sync with qemu -- fixed sizeof(divider).

  • Property svn:eol-style set to native
File size: 20.1 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 uint16_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_be16s(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 > 2)
396 return -EINVAL;
397
398 if (version_id >= 2)
399 qemu_get_be16s(f, &s->divider);
400 else
401 s->divider = qemu_get_byte(f);
402 qemu_get_8s(f,&s->rbr);
403 qemu_get_8s(f,&s->ier);
404 qemu_get_8s(f,&s->iir);
405 qemu_get_8s(f,&s->lcr);
406 qemu_get_8s(f,&s->mcr);
407 qemu_get_8s(f,&s->lsr);
408 qemu_get_8s(f,&s->msr);
409 qemu_get_8s(f,&s->scr);
410
411 return 0;
412}
413
414/* If fd is zero, it means that the serial device uses the console */
415SerialState *serial_init(SetIRQFunc *set_irq, void *opaque,
416 int base, int irq, CharDriverState *chr)
417{
418 SerialState *s;
419
420 s = qemu_mallocz(sizeof(SerialState));
421 if (!s)
422 return NULL;
423 s->set_irq = set_irq;
424 s->irq_opaque = opaque;
425 s->irq = irq;
426 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
427 s->iir = UART_IIR_NO_INT;
428 s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
429
430 register_savevm("serial", base, 2, serial_save, serial_load, s);
431
432 register_ioport_write(base, 8, 1, serial_ioport_write, s);
433 register_ioport_read(base, 8, 1, serial_ioport_read, s);
434 s->chr = chr;
435 qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
436 qemu_chr_add_event_handler(chr, serial_event);
437 return s;
438}
439
440/* Memory mapped interface */
441static uint32_t serial_mm_readb (void *opaque, target_phys_addr_t addr)
442{
443 SerialState *s = opaque;
444
445 return serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFF;
446}
447
448static void serial_mm_writeb (void *opaque,
449 target_phys_addr_t addr, uint32_t value)
450{
451 SerialState *s = opaque;
452
453 serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFF);
454}
455
456static uint32_t serial_mm_readw (void *opaque, target_phys_addr_t addr)
457{
458 SerialState *s = opaque;
459
460 return serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
461}
462
463static void serial_mm_writew (void *opaque,
464 target_phys_addr_t addr, uint32_t value)
465{
466 SerialState *s = opaque;
467
468 serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
469}
470
471static uint32_t serial_mm_readl (void *opaque, target_phys_addr_t addr)
472{
473 SerialState *s = opaque;
474
475 return serial_ioport_read(s, (addr - s->base) >> s->it_shift);
476}
477
478static void serial_mm_writel (void *opaque,
479 target_phys_addr_t addr, uint32_t value)
480{
481 SerialState *s = opaque;
482
483 serial_ioport_write(s, (addr - s->base) >> s->it_shift, value);
484}
485
486static CPUReadMemoryFunc *serial_mm_read[] = {
487 &serial_mm_readb,
488 &serial_mm_readw,
489 &serial_mm_readl,
490};
491
492static CPUWriteMemoryFunc *serial_mm_write[] = {
493 &serial_mm_writeb,
494 &serial_mm_writew,
495 &serial_mm_writel,
496};
497
498SerialState *serial_mm_init (SetIRQFunc *set_irq, void *opaque,
499 target_ulong base, int it_shift,
500 int irq, CharDriverState *chr)
501{
502 SerialState *s;
503 int s_io_memory;
504
505 s = qemu_mallocz(sizeof(SerialState));
506 if (!s)
507 return NULL;
508 s->set_irq = set_irq;
509 s->irq_opaque = opaque;
510 s->irq = irq;
511 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
512 s->iir = UART_IIR_NO_INT;
513 s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
514 s->base = base;
515 s->it_shift = it_shift;
516
517 register_savevm("serial", base, 2, serial_save, serial_load, s);
518
519 s_io_memory = cpu_register_io_memory(0, serial_mm_read,
520 serial_mm_write, s);
521 cpu_register_physical_memory(base, 8 << it_shift, s_io_memory);
522 s->chr = chr;
523 qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
524 qemu_chr_add_event_handler(chr, serial_event);
525 return s;
526}
527
528#else
529
530static DECLCALLBACK(int) serial_io_write (PPDMDEVINS pDevIns,
531 void *pvUser,
532 RTIOPORT Port,
533 uint32_t u32,
534 unsigned cb)
535{
536 if (cb == 1) {
537 serial_ioport_write (pvUser, Port, u32);
538 }
539 else {
540 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
541 }
542 return VINF_SUCCESS;
543}
544
545static DECLCALLBACK(int) serial_io_read (PPDMDEVINS pDevIns,
546 void *pvUser,
547 RTIOPORT Port,
548 uint32_t *pu32,
549 unsigned cb)
550{
551 if (cb == 1) {
552 *pu32 = serial_ioport_read (pvUser, Port);
553 return VINF_SUCCESS;
554 }
555 else {
556 return VERR_IOM_IOPORT_UNUSED;
557 }
558}
559
560static DECLCALLBACK(int) SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
561{
562 SerialState *s = PDMINS2DATA (pDevIns, SerialState *);
563 SSMR3PutMem(pSSMHandle, s, sizeof(*s));
564 return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
565}
566
567static DECLCALLBACK(int) LoadExec (PPDMDEVINS pDevIns,
568 PSSMHANDLE pSSMHandle,
569 uint32_t u32Version)
570{
571 int rc;
572 uint32_t u32;
573 SerialState *s = PDMINS2DATA (pDevIns, SerialState *);
574
575 if (u32Version != 2) {
576 AssertMsgFailed(("u32Version=%d\n", u32Version));
577 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
578 }
579
580 rc = SSMR3GetMem(pSSMHandle, s, sizeof(*s));
581 if (VBOX_FAILURE(rc))
582 return rc;
583
584 rc = SSMR3GetU32(pSSMHandle, &u32);
585 if (VBOX_FAILURE(rc))
586 return rc;
587
588 if (u32 != ~0U) {
589 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
590 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
591 }
592 /* Be careful with pointers in the structure; load just gets the whole structure from the saved state */
593 s->pDevIns = pDevIns;
594 return VINF_SUCCESS;
595}
596
597
598/**
599 * Construct a device instance for a VM.
600 *
601 * @returns VBox status.
602 * @param pDevIns The device instance data.
603 * If the registration structure is needed, pDevIns->pDevReg points to it.
604 * @param iInstance Instance number. Use this to figure out which registers and such to use.
605 * The device number is also found in pDevIns->iInstance, but since it's
606 * likely to be freqently used PDM passes it as parameter.
607 * @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
608 * of the device instance. It's also found in pDevIns->pCfgHandle, but like
609 * iInstance it's expected to be used a bit in this function.
610 */
611static DECLCALLBACK(int) serialConstruct(PPDMDEVINS pDevIns,
612 int iInstance,
613 PCFGMNODE pCfgHandle)
614{
615 int rc;
616 SerialState *s = PDMINS2DATA(pDevIns, SerialState*);
617 uint16_t io_base;
618 uint8_t irq_lvl;
619
620 Assert(iInstance < 2);
621
622 s->pDevIns = pDevIns;
623 /*
624 * Validate configuration.
625 */
626 if (!CFGMR3AreValuesValid(pCfgHandle, "IRQ\0IOBase\0")) {
627 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
628 }
629
630
631/** @todo r=bird: Check for VERR_CFGM_VALUE_NOT_FOUND and provide sensible defaults.
632 * Also do AssertMsgFailed(("Configuration error:....)) in the failure cases of CFGMR3Query*()
633 * and CFGR3AreValuesValid() like we're doing in the other devices. */
634 rc = CFGMR3QueryU8 (pCfgHandle, "IRQ", &irq_lvl);
635 if (VBOX_FAILURE (rc)) {
636 return rc;
637 }
638
639 rc = CFGMR3QueryU16 (pCfgHandle, "IOBase", &io_base);
640 if (VBOX_FAILURE (rc)) {
641 return rc;
642 }
643
644 Log(("serialConstruct instance %d iobase=%04x irq=%d\n", iInstance, io_base, irq_lvl));
645
646 s->irq = irq_lvl;
647 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
648 s->iir = UART_IIR_NO_INT;
649
650 rc = pDevIns->pDevHlp->pfnIOPortRegister (
651 pDevIns,
652 io_base,
653 8,
654 s,
655 serial_io_write,
656 serial_io_read,
657 NULL, NULL,
658 "SERIAL"
659 );
660 if (VBOX_FAILURE (rc)) {
661 return rc;
662 }
663
664 rc = pDevIns->pDevHlp->pfnSSMRegister (
665 pDevIns, /* pDevIns */
666 pDevIns->pDevReg->szDeviceName, /* pszName */
667 iInstance, /* u32Instance */
668 2 /* u32Version */,
669 sizeof (*s), /* cbGuess */
670 NULL, /* pfnSavePrep */
671 SaveExec, /* pfnSaveExec */
672 NULL, /* pfnSaveDone */
673 NULL, /* pfnLoadPrep */
674 LoadExec, /* pfnLoadExec */
675 NULL /* pfnLoadDone */
676 );
677 if (VBOX_FAILURE(rc))
678 return rc;
679
680 return VINF_SUCCESS;
681}
682
683/**
684 * The device registration structure.
685 */
686const PDMDEVREG g_DeviceSerialPort =
687{
688 /* u32Version */
689 PDM_DEVREG_VERSION,
690 /* szDeviceName */
691 "serial",
692 /* szGCMod */
693 "",
694 /* szR0Mod */
695 "",
696 /* pszDescription */
697 "Serial Communication Port",
698 /* fFlags */
699 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
700 /* fClass */
701 PDM_DEVREG_CLASS_SERIAL_PORT,
702 /* cMaxInstances */
703 1,
704 /* cbInstance */
705 sizeof(SerialState),
706 /* pfnConstruct */
707 serialConstruct,
708 /* pfnDestruct */
709 NULL,
710 /* pfnRelocate */
711 NULL,
712 /* pfnIOCtl */
713 NULL,
714 /* pfnPowerOn */
715 NULL,
716 /* pfnReset */
717 NULL,
718 /* pfnSuspend */
719 NULL,
720 /* pfnResume */
721 NULL,
722 /* pfnAttach */
723 NULL,
724 /* pfnDetach */
725 NULL,
726 /* pfnQueryInterface. */
727 NULL
728};
729#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