Statistics
| Branch: | Revision:

root / hw / parallel.c @ 927d4878

History | View | Annotate | Download (17.9 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.h"
26
#include "char/char.h"
27
#include "isa.h"
28
#include "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
typedef struct ISAParallelState {
84
    ISADevice dev;
85
    uint32_t index;
86
    uint32_t iobase;
87
    uint32_t isairq;
88
    ParallelState state;
89
} ISAParallelState;
90

    
91
static void parallel_update_irq(ParallelState *s)
92
{
93
    if (s->irq_pending)
94
        qemu_irq_raise(s->irq);
95
    else
96
        qemu_irq_lower(s->irq);
97
}
98

    
99
static void
100
parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
101
{
102
    ParallelState *s = opaque;
103

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

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

    
137
static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
138
{
139
    ParallelState *s = opaque;
140
    uint8_t parm = val;
141
    int dir;
142

    
143
    /* Sometimes programs do several writes for timing purposes on old
144
       HW. Take care not to waste time on writes that do nothing. */
145

    
146
    s->last_read_offset = ~0U;
147

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

    
168
        if ((val & PARA_CTR_DIR) != (s->control & PARA_CTR_DIR)) {
169
            if (val & PARA_CTR_DIR) {
170
                dir = 1;
171
            } else {
172
                dir = 0;
173
            }
174
            qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
175
            parm &= ~PARA_CTR_DIR;
176
        }
177

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

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

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

    
258
static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
259
{
260
    ParallelState *s = opaque;
261
    uint32_t ret = 0xff;
262

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

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

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

    
381
    if (err) {
382
        s->epp_timeout = 1;
383
        pdebug("re%04x t\n", ret);
384
    }
385
    else
386
        pdebug("re%04x\n", ret);
387
    return ret;
388
}
389

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

    
408
    if (err) {
409
        s->epp_timeout = 1;
410
        pdebug("re%08x t\n", ret);
411
    }
412
    else
413
        pdebug("re%08x\n", ret);
414
    return ret;
415
}
416

    
417
static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
418
{
419
    pdebug("wecp%d=%02x\n", addr & 7, val);
420
}
421

    
422
static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
423
{
424
    uint8_t ret = 0xff;
425

    
426
    pdebug("recp%d:%02x\n", addr & 7, ret);
427
    return ret;
428
}
429

    
430
static void parallel_reset(void *opaque)
431
{
432
    ParallelState *s = opaque;
433

    
434
    s->datar = ~0;
435
    s->dataw = ~0;
436
    s->status = PARA_STS_BUSY;
437
    s->status |= PARA_STS_ACK;
438
    s->status |= PARA_STS_ONLINE;
439
    s->status |= PARA_STS_ERROR;
440
    s->status |= PARA_STS_TMOUT;
441
    s->control = PARA_CTR_SELECT;
442
    s->control |= PARA_CTR_INIT;
443
    s->control |= 0xc0;
444
    s->irq_pending = 0;
445
    s->hw_driver = 0;
446
    s->epp_timeout = 0;
447
    s->last_read_offset = ~0U;
448
}
449

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

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

    
468
static const MemoryRegionPortio isa_parallel_portio_sw_list[] = {
469
    { 0, 8, 1,
470
      .read = parallel_ioport_read_sw,
471
      .write = parallel_ioport_write_sw },
472
    PORTIO_END_OF_LIST(),
473
};
474

    
475
static int parallel_isa_initfn(ISADevice *dev)
476
{
477
    static int index;
478
    ISAParallelState *isa = DO_UPCAST(ISAParallelState, dev, dev);
479
    ParallelState *s = &isa->state;
480
    int base;
481
    uint8_t dummy;
482

    
483
    if (!s->chr) {
484
        fprintf(stderr, "Can't create parallel device, empty char device\n");
485
        exit(1);
486
    }
487

    
488
    if (isa->index == -1)
489
        isa->index = index;
490
    if (isa->index >= MAX_PARALLEL_PORTS)
491
        return -1;
492
    if (isa->iobase == -1)
493
        isa->iobase = isa_parallel_io[isa->index];
494
    index++;
495

    
496
    base = isa->iobase;
497
    isa_init_irq(dev, &s->irq, isa->isairq);
498
    qemu_register_reset(parallel_reset, s);
499

    
500
    if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
501
        s->hw_driver = 1;
502
        s->status = dummy;
503
    }
504

    
505
    isa_register_portio_list(dev, base,
506
                             (s->hw_driver
507
                              ? &isa_parallel_portio_hw_list[0]
508
                              : &isa_parallel_portio_sw_list[0]),
509
                             s, "parallel");
510
    return 0;
511
}
512

    
513
/* Memory mapped interface */
514
static uint32_t parallel_mm_readb (void *opaque, hwaddr addr)
515
{
516
    ParallelState *s = opaque;
517

    
518
    return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFF;
519
}
520

    
521
static void parallel_mm_writeb (void *opaque,
522
                                hwaddr addr, uint32_t value)
523
{
524
    ParallelState *s = opaque;
525

    
526
    parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFF);
527
}
528

    
529
static uint32_t parallel_mm_readw (void *opaque, hwaddr addr)
530
{
531
    ParallelState *s = opaque;
532

    
533
    return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFFFF;
534
}
535

    
536
static void parallel_mm_writew (void *opaque,
537
                                hwaddr addr, uint32_t value)
538
{
539
    ParallelState *s = opaque;
540

    
541
    parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFFFF);
542
}
543

    
544
static uint32_t parallel_mm_readl (void *opaque, hwaddr addr)
545
{
546
    ParallelState *s = opaque;
547

    
548
    return parallel_ioport_read_sw(s, addr >> s->it_shift);
549
}
550

    
551
static void parallel_mm_writel (void *opaque,
552
                                hwaddr addr, uint32_t value)
553
{
554
    ParallelState *s = opaque;
555

    
556
    parallel_ioport_write_sw(s, addr >> s->it_shift, value);
557
}
558

    
559
static const MemoryRegionOps parallel_mm_ops = {
560
    .old_mmio = {
561
        .read = { parallel_mm_readb, parallel_mm_readw, parallel_mm_readl },
562
        .write = { parallel_mm_writeb, parallel_mm_writew, parallel_mm_writel },
563
    },
564
    .endianness = DEVICE_NATIVE_ENDIAN,
565
};
566

    
567
/* If fd is zero, it means that the parallel device uses the console */
568
bool parallel_mm_init(MemoryRegion *address_space,
569
                      hwaddr base, int it_shift, qemu_irq irq,
570
                      CharDriverState *chr)
571
{
572
    ParallelState *s;
573

    
574
    s = g_malloc0(sizeof(ParallelState));
575
    s->irq = irq;
576
    s->chr = chr;
577
    s->it_shift = it_shift;
578
    qemu_register_reset(parallel_reset, s);
579

    
580
    memory_region_init_io(&s->iomem, &parallel_mm_ops, s,
581
                          "parallel", 8 << it_shift);
582
    memory_region_add_subregion(address_space, base, &s->iomem);
583
    return true;
584
}
585

    
586
static Property parallel_isa_properties[] = {
587
    DEFINE_PROP_UINT32("index", ISAParallelState, index,   -1),
588
    DEFINE_PROP_HEX32("iobase", ISAParallelState, iobase,  -1),
589
    DEFINE_PROP_UINT32("irq",   ISAParallelState, isairq,  7),
590
    DEFINE_PROP_CHR("chardev",  ISAParallelState, state.chr),
591
    DEFINE_PROP_END_OF_LIST(),
592
};
593

    
594
static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
595
{
596
    DeviceClass *dc = DEVICE_CLASS(klass);
597
    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
598
    ic->init = parallel_isa_initfn;
599
    dc->props = parallel_isa_properties;
600
}
601

    
602
static TypeInfo parallel_isa_info = {
603
    .name          = "isa-parallel",
604
    .parent        = TYPE_ISA_DEVICE,
605
    .instance_size = sizeof(ISAParallelState),
606
    .class_init    = parallel_isa_class_initfn,
607
};
608

    
609
static void parallel_register_types(void)
610
{
611
    type_register_static(&parallel_isa_info);
612
}
613

    
614
type_init(parallel_register_types)