Statistics
| Branch: | Revision:

root / hw / char / parallel.c @ 2c9b15ca

History | View | Annotate | Download (18.2 kB)

1
/*
2
 * QEMU Parallel PORT emulation
3
 *
4
 * Copyright (c) 2003-2005 Fabrice Bellard
5
 * Copyright (c) 2007 Marko Kohtala
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25
#include "hw/hw.h"
26
#include "sysemu/char.h"
27
#include "hw/isa/isa.h"
28
#include "hw/i386/pc.h"
29
#include "sysemu/sysemu.h"
30

    
31
//#define DEBUG_PARALLEL
32

    
33
#ifdef DEBUG_PARALLEL
34
#define pdebug(fmt, ...) printf("pp: " fmt, ## __VA_ARGS__)
35
#else
36
#define pdebug(fmt, ...) ((void)0)
37
#endif
38

    
39
#define PARA_REG_DATA 0
40
#define PARA_REG_STS 1
41
#define PARA_REG_CTR 2
42
#define PARA_REG_EPP_ADDR 3
43
#define PARA_REG_EPP_DATA 4
44

    
45
/*
46
 * These are the definitions for the Printer Status Register
47
 */
48
#define PARA_STS_BUSY        0x80        /* Busy complement */
49
#define PARA_STS_ACK        0x40        /* Acknowledge */
50
#define PARA_STS_PAPER        0x20        /* Out of paper */
51
#define PARA_STS_ONLINE        0x10        /* Online */
52
#define PARA_STS_ERROR        0x08        /* Error complement */
53
#define PARA_STS_TMOUT        0x01        /* EPP timeout */
54

    
55
/*
56
 * These are the definitions for the Printer Control Register
57
 */
58
#define PARA_CTR_DIR        0x20        /* Direction (1=read, 0=write) */
59
#define PARA_CTR_INTEN        0x10        /* IRQ Enable */
60
#define PARA_CTR_SELECT        0x08        /* Select In complement */
61
#define PARA_CTR_INIT        0x04        /* Initialize Printer complement */
62
#define PARA_CTR_AUTOLF        0x02        /* Auto linefeed complement */
63
#define PARA_CTR_STROBE        0x01        /* Strobe complement */
64

    
65
#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
66

    
67
typedef struct ParallelState {
68
    MemoryRegion iomem;
69
    uint8_t dataw;
70
    uint8_t datar;
71
    uint8_t status;
72
    uint8_t control;
73
    qemu_irq irq;
74
    int irq_pending;
75
    CharDriverState *chr;
76
    int hw_driver;
77
    int epp_timeout;
78
    uint32_t last_read_offset; /* For debugging */
79
    /* Memory-mapped interface */
80
    int it_shift;
81
} ParallelState;
82

    
83
#define TYPE_ISA_PARALLEL "isa-parallel"
84
#define ISA_PARALLEL(obj) \
85
    OBJECT_CHECK(ISAParallelState, (obj), TYPE_ISA_PARALLEL)
86

    
87
typedef struct ISAParallelState {
88
    ISADevice parent_obj;
89

    
90
    uint32_t index;
91
    uint32_t iobase;
92
    uint32_t isairq;
93
    ParallelState state;
94
} ISAParallelState;
95

    
96
static void parallel_update_irq(ParallelState *s)
97
{
98
    if (s->irq_pending)
99
        qemu_irq_raise(s->irq);
100
    else
101
        qemu_irq_lower(s->irq);
102
}
103

    
104
static void
105
parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
106
{
107
    ParallelState *s = opaque;
108

    
109
    pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
110

    
111
    addr &= 7;
112
    switch(addr) {
113
    case PARA_REG_DATA:
114
        s->dataw = val;
115
        parallel_update_irq(s);
116
        break;
117
    case PARA_REG_CTR:
118
        val |= 0xc0;
119
        if ((val & PARA_CTR_INIT) == 0 ) {
120
            s->status = PARA_STS_BUSY;
121
            s->status |= PARA_STS_ACK;
122
            s->status |= PARA_STS_ONLINE;
123
            s->status |= PARA_STS_ERROR;
124
        }
125
        else if (val & PARA_CTR_SELECT) {
126
            if (val & PARA_CTR_STROBE) {
127
                s->status &= ~PARA_STS_BUSY;
128
                if ((s->control & PARA_CTR_STROBE) == 0)
129
                    qemu_chr_fe_write(s->chr, &s->dataw, 1);
130
            } else {
131
                if (s->control & PARA_CTR_INTEN) {
132
                    s->irq_pending = 1;
133
                }
134
            }
135
        }
136
        parallel_update_irq(s);
137
        s->control = val;
138
        break;
139
    }
140
}
141

    
142
static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
143
{
144
    ParallelState *s = opaque;
145
    uint8_t parm = val;
146
    int dir;
147

    
148
    /* Sometimes programs do several writes for timing purposes on old
149
       HW. Take care not to waste time on writes that do nothing. */
150

    
151
    s->last_read_offset = ~0U;
152

    
153
    addr &= 7;
154
    switch(addr) {
155
    case PARA_REG_DATA:
156
        if (s->dataw == val)
157
            return;
158
        pdebug("wd%02x\n", val);
159
        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
160
        s->dataw = val;
161
        break;
162
    case PARA_REG_STS:
163
        pdebug("ws%02x\n", val);
164
        if (val & PARA_STS_TMOUT)
165
            s->epp_timeout = 0;
166
        break;
167
    case PARA_REG_CTR:
168
        val |= 0xc0;
169
        if (s->control == val)
170
            return;
171
        pdebug("wc%02x\n", val);
172

    
173
        if ((val & PARA_CTR_DIR) != (s->control & PARA_CTR_DIR)) {
174
            if (val & PARA_CTR_DIR) {
175
                dir = 1;
176
            } else {
177
                dir = 0;
178
            }
179
            qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
180
            parm &= ~PARA_CTR_DIR;
181
        }
182

    
183
        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
184
        s->control = val;
185
        break;
186
    case PARA_REG_EPP_ADDR:
187
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
188
            /* Controls not correct for EPP address cycle, so do nothing */
189
            pdebug("wa%02x s\n", val);
190
        else {
191
            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
192
            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
193
                s->epp_timeout = 1;
194
                pdebug("wa%02x t\n", val);
195
            }
196
            else
197
                pdebug("wa%02x\n", val);
198
        }
199
        break;
200
    case PARA_REG_EPP_DATA:
201
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
202
            /* Controls not correct for EPP data cycle, so do nothing */
203
            pdebug("we%02x s\n", val);
204
        else {
205
            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
206
            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
207
                s->epp_timeout = 1;
208
                pdebug("we%02x t\n", val);
209
            }
210
            else
211
                pdebug("we%02x\n", val);
212
        }
213
        break;
214
    }
215
}
216

    
217
static void
218
parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
219
{
220
    ParallelState *s = opaque;
221
    uint16_t eppdata = cpu_to_le16(val);
222
    int err;
223
    struct ParallelIOArg ioarg = {
224
        .buffer = &eppdata, .count = sizeof(eppdata)
225
    };
226
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
227
        /* Controls not correct for EPP data cycle, so do nothing */
228
        pdebug("we%04x s\n", val);
229
        return;
230
    }
231
    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
232
    if (err) {
233
        s->epp_timeout = 1;
234
        pdebug("we%04x t\n", val);
235
    }
236
    else
237
        pdebug("we%04x\n", val);
238
}
239

    
240
static void
241
parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
242
{
243
    ParallelState *s = opaque;
244
    uint32_t eppdata = cpu_to_le32(val);
245
    int err;
246
    struct ParallelIOArg ioarg = {
247
        .buffer = &eppdata, .count = sizeof(eppdata)
248
    };
249
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
250
        /* Controls not correct for EPP data cycle, so do nothing */
251
        pdebug("we%08x s\n", val);
252
        return;
253
    }
254
    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
255
    if (err) {
256
        s->epp_timeout = 1;
257
        pdebug("we%08x t\n", val);
258
    }
259
    else
260
        pdebug("we%08x\n", val);
261
}
262

    
263
static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
264
{
265
    ParallelState *s = opaque;
266
    uint32_t ret = 0xff;
267

    
268
    addr &= 7;
269
    switch(addr) {
270
    case PARA_REG_DATA:
271
        if (s->control & PARA_CTR_DIR)
272
            ret = s->datar;
273
        else
274
            ret = s->dataw;
275
        break;
276
    case PARA_REG_STS:
277
        ret = s->status;
278
        s->irq_pending = 0;
279
        if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
280
            /* XXX Fixme: wait 5 microseconds */
281
            if (s->status & PARA_STS_ACK)
282
                s->status &= ~PARA_STS_ACK;
283
            else {
284
                /* XXX Fixme: wait 5 microseconds */
285
                s->status |= PARA_STS_ACK;
286
                s->status |= PARA_STS_BUSY;
287
            }
288
        }
289
        parallel_update_irq(s);
290
        break;
291
    case PARA_REG_CTR:
292
        ret = s->control;
293
        break;
294
    }
295
    pdebug("read addr=0x%02x val=0x%02x\n", addr, ret);
296
    return ret;
297
}
298

    
299
static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
300
{
301
    ParallelState *s = opaque;
302
    uint8_t ret = 0xff;
303
    addr &= 7;
304
    switch(addr) {
305
    case PARA_REG_DATA:
306
        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
307
        if (s->last_read_offset != addr || s->datar != ret)
308
            pdebug("rd%02x\n", ret);
309
        s->datar = ret;
310
        break;
311
    case PARA_REG_STS:
312
        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
313
        ret &= ~PARA_STS_TMOUT;
314
        if (s->epp_timeout)
315
            ret |= PARA_STS_TMOUT;
316
        if (s->last_read_offset != addr || s->status != ret)
317
            pdebug("rs%02x\n", ret);
318
        s->status = ret;
319
        break;
320
    case PARA_REG_CTR:
321
        /* s->control has some bits fixed to 1. It is zero only when
322
           it has not been yet written to.  */
323
        if (s->control == 0) {
324
            qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
325
            if (s->last_read_offset != addr)
326
                pdebug("rc%02x\n", ret);
327
            s->control = ret;
328
        }
329
        else {
330
            ret = s->control;
331
            if (s->last_read_offset != addr)
332
                pdebug("rc%02x\n", ret);
333
        }
334
        break;
335
    case PARA_REG_EPP_ADDR:
336
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
337
            /* Controls not correct for EPP addr cycle, so do nothing */
338
            pdebug("ra%02x s\n", ret);
339
        else {
340
            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
341
            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
342
                s->epp_timeout = 1;
343
                pdebug("ra%02x t\n", ret);
344
            }
345
            else
346
                pdebug("ra%02x\n", ret);
347
        }
348
        break;
349
    case PARA_REG_EPP_DATA:
350
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
351
            /* Controls not correct for EPP data cycle, so do nothing */
352
            pdebug("re%02x s\n", ret);
353
        else {
354
            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
355
            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
356
                s->epp_timeout = 1;
357
                pdebug("re%02x t\n", ret);
358
            }
359
            else
360
                pdebug("re%02x\n", ret);
361
        }
362
        break;
363
    }
364
    s->last_read_offset = addr;
365
    return ret;
366
}
367

    
368
static uint32_t
369
parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
370
{
371
    ParallelState *s = opaque;
372
    uint32_t ret;
373
    uint16_t eppdata = ~0;
374
    int err;
375
    struct ParallelIOArg ioarg = {
376
        .buffer = &eppdata, .count = sizeof(eppdata)
377
    };
378
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
379
        /* Controls not correct for EPP data cycle, so do nothing */
380
        pdebug("re%04x s\n", eppdata);
381
        return eppdata;
382
    }
383
    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
384
    ret = le16_to_cpu(eppdata);
385

    
386
    if (err) {
387
        s->epp_timeout = 1;
388
        pdebug("re%04x t\n", ret);
389
    }
390
    else
391
        pdebug("re%04x\n", ret);
392
    return ret;
393
}
394

    
395
static uint32_t
396
parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
397
{
398
    ParallelState *s = opaque;
399
    uint32_t ret;
400
    uint32_t eppdata = ~0U;
401
    int err;
402
    struct ParallelIOArg ioarg = {
403
        .buffer = &eppdata, .count = sizeof(eppdata)
404
    };
405
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
406
        /* Controls not correct for EPP data cycle, so do nothing */
407
        pdebug("re%08x s\n", eppdata);
408
        return eppdata;
409
    }
410
    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
411
    ret = le32_to_cpu(eppdata);
412

    
413
    if (err) {
414
        s->epp_timeout = 1;
415
        pdebug("re%08x t\n", ret);
416
    }
417
    else
418
        pdebug("re%08x\n", ret);
419
    return ret;
420
}
421

    
422
static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
423
{
424
    pdebug("wecp%d=%02x\n", addr & 7, val);
425
}
426

    
427
static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
428
{
429
    uint8_t ret = 0xff;
430

    
431
    pdebug("recp%d:%02x\n", addr & 7, ret);
432
    return ret;
433
}
434

    
435
static void parallel_reset(void *opaque)
436
{
437
    ParallelState *s = opaque;
438

    
439
    s->datar = ~0;
440
    s->dataw = ~0;
441
    s->status = PARA_STS_BUSY;
442
    s->status |= PARA_STS_ACK;
443
    s->status |= PARA_STS_ONLINE;
444
    s->status |= PARA_STS_ERROR;
445
    s->status |= PARA_STS_TMOUT;
446
    s->control = PARA_CTR_SELECT;
447
    s->control |= PARA_CTR_INIT;
448
    s->control |= 0xc0;
449
    s->irq_pending = 0;
450
    s->hw_driver = 0;
451
    s->epp_timeout = 0;
452
    s->last_read_offset = ~0U;
453
}
454

    
455
static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
456

    
457
static const MemoryRegionPortio isa_parallel_portio_hw_list[] = {
458
    { 0, 8, 1,
459
      .read = parallel_ioport_read_hw,
460
      .write = parallel_ioport_write_hw },
461
    { 4, 1, 2,
462
      .read = parallel_ioport_eppdata_read_hw2,
463
      .write = parallel_ioport_eppdata_write_hw2 },
464
    { 4, 1, 4,
465
      .read = parallel_ioport_eppdata_read_hw4,
466
      .write = parallel_ioport_eppdata_write_hw4 },
467
    { 0x400, 8, 1,
468
      .read = parallel_ioport_ecp_read,
469
      .write = parallel_ioport_ecp_write },
470
    PORTIO_END_OF_LIST(),
471
};
472

    
473
static const MemoryRegionPortio isa_parallel_portio_sw_list[] = {
474
    { 0, 8, 1,
475
      .read = parallel_ioport_read_sw,
476
      .write = parallel_ioport_write_sw },
477
    PORTIO_END_OF_LIST(),
478
};
479

    
480
static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
481
{
482
    static int index;
483
    ISADevice *isadev = ISA_DEVICE(dev);
484
    ISAParallelState *isa = ISA_PARALLEL(dev);
485
    ParallelState *s = &isa->state;
486
    int base;
487
    uint8_t dummy;
488

    
489
    if (!s->chr) {
490
        error_setg(errp, "Can't create parallel device, empty char device");
491
        return;
492
    }
493

    
494
    if (isa->index == -1) {
495
        isa->index = index;
496
    }
497
    if (isa->index >= MAX_PARALLEL_PORTS) {
498
        error_setg(errp, "Max. supported number of parallel ports is %d.",
499
                   MAX_PARALLEL_PORTS);
500
        return;
501
    }
502
    if (isa->iobase == -1) {
503
        isa->iobase = isa_parallel_io[isa->index];
504
    }
505
    index++;
506

    
507
    base = isa->iobase;
508
    isa_init_irq(isadev, &s->irq, isa->isairq);
509
    qemu_register_reset(parallel_reset, s);
510

    
511
    if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
512
        s->hw_driver = 1;
513
        s->status = dummy;
514
    }
515

    
516
    isa_register_portio_list(isadev, base,
517
                             (s->hw_driver
518
                              ? &isa_parallel_portio_hw_list[0]
519
                              : &isa_parallel_portio_sw_list[0]),
520
                             s, "parallel");
521
}
522

    
523
/* Memory mapped interface */
524
static uint32_t parallel_mm_readb (void *opaque, hwaddr addr)
525
{
526
    ParallelState *s = opaque;
527

    
528
    return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFF;
529
}
530

    
531
static void parallel_mm_writeb (void *opaque,
532
                                hwaddr addr, uint32_t value)
533
{
534
    ParallelState *s = opaque;
535

    
536
    parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFF);
537
}
538

    
539
static uint32_t parallel_mm_readw (void *opaque, hwaddr addr)
540
{
541
    ParallelState *s = opaque;
542

    
543
    return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFFFF;
544
}
545

    
546
static void parallel_mm_writew (void *opaque,
547
                                hwaddr addr, uint32_t value)
548
{
549
    ParallelState *s = opaque;
550

    
551
    parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFFFF);
552
}
553

    
554
static uint32_t parallel_mm_readl (void *opaque, hwaddr addr)
555
{
556
    ParallelState *s = opaque;
557

    
558
    return parallel_ioport_read_sw(s, addr >> s->it_shift);
559
}
560

    
561
static void parallel_mm_writel (void *opaque,
562
                                hwaddr addr, uint32_t value)
563
{
564
    ParallelState *s = opaque;
565

    
566
    parallel_ioport_write_sw(s, addr >> s->it_shift, value);
567
}
568

    
569
static const MemoryRegionOps parallel_mm_ops = {
570
    .old_mmio = {
571
        .read = { parallel_mm_readb, parallel_mm_readw, parallel_mm_readl },
572
        .write = { parallel_mm_writeb, parallel_mm_writew, parallel_mm_writel },
573
    },
574
    .endianness = DEVICE_NATIVE_ENDIAN,
575
};
576

    
577
/* If fd is zero, it means that the parallel device uses the console */
578
bool parallel_mm_init(MemoryRegion *address_space,
579
                      hwaddr base, int it_shift, qemu_irq irq,
580
                      CharDriverState *chr)
581
{
582
    ParallelState *s;
583

    
584
    s = g_malloc0(sizeof(ParallelState));
585
    s->irq = irq;
586
    s->chr = chr;
587
    s->it_shift = it_shift;
588
    qemu_register_reset(parallel_reset, s);
589

    
590
    memory_region_init_io(&s->iomem, NULL, &parallel_mm_ops, s,
591
                          "parallel", 8 << it_shift);
592
    memory_region_add_subregion(address_space, base, &s->iomem);
593
    return true;
594
}
595

    
596
static Property parallel_isa_properties[] = {
597
    DEFINE_PROP_UINT32("index", ISAParallelState, index,   -1),
598
    DEFINE_PROP_HEX32("iobase", ISAParallelState, iobase,  -1),
599
    DEFINE_PROP_UINT32("irq",   ISAParallelState, isairq,  7),
600
    DEFINE_PROP_CHR("chardev",  ISAParallelState, state.chr),
601
    DEFINE_PROP_END_OF_LIST(),
602
};
603

    
604
static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
605
{
606
    DeviceClass *dc = DEVICE_CLASS(klass);
607

    
608
    dc->realize = parallel_isa_realizefn;
609
    dc->props = parallel_isa_properties;
610
}
611

    
612
static const TypeInfo parallel_isa_info = {
613
    .name          = TYPE_ISA_PARALLEL,
614
    .parent        = TYPE_ISA_DEVICE,
615
    .instance_size = sizeof(ISAParallelState),
616
    .class_init    = parallel_isa_class_initfn,
617
};
618

    
619
static void parallel_register_types(void)
620
{
621
    type_register_static(&parallel_isa_info);
622
}
623

    
624
type_init(parallel_register_types)