xref: /openbmc/qemu/hw/char/parallel.c (revision 3d9569b8)
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 
26 #include "qemu/osdep.h"
27 #include "qapi/error.h"
28 #include "qemu/module.h"
29 #include "hw/hw.h"
30 #include "chardev/char-parallel.h"
31 #include "chardev/char-fe.h"
32 #include "hw/isa/isa.h"
33 #include "hw/char/parallel.h"
34 #include "sysemu/sysemu.h"
35 #include "trace.h"
36 
37 //#define DEBUG_PARALLEL
38 
39 #ifdef DEBUG_PARALLEL
40 #define pdebug(fmt, ...) printf("pp: " fmt, ## __VA_ARGS__)
41 #else
42 #define pdebug(fmt, ...) ((void)0)
43 #endif
44 
45 #define PARA_REG_DATA 0
46 #define PARA_REG_STS 1
47 #define PARA_REG_CTR 2
48 #define PARA_REG_EPP_ADDR 3
49 #define PARA_REG_EPP_DATA 4
50 
51 /*
52  * These are the definitions for the Printer Status Register
53  */
54 #define PARA_STS_BUSY	0x80	/* Busy complement */
55 #define PARA_STS_ACK	0x40	/* Acknowledge */
56 #define PARA_STS_PAPER	0x20	/* Out of paper */
57 #define PARA_STS_ONLINE	0x10	/* Online */
58 #define PARA_STS_ERROR	0x08	/* Error complement */
59 #define PARA_STS_TMOUT	0x01	/* EPP timeout */
60 
61 /*
62  * These are the definitions for the Printer Control Register
63  */
64 #define PARA_CTR_DIR	0x20	/* Direction (1=read, 0=write) */
65 #define PARA_CTR_INTEN	0x10	/* IRQ Enable */
66 #define PARA_CTR_SELECT	0x08	/* Select In complement */
67 #define PARA_CTR_INIT	0x04	/* Initialize Printer complement */
68 #define PARA_CTR_AUTOLF	0x02	/* Auto linefeed complement */
69 #define PARA_CTR_STROBE	0x01	/* Strobe complement */
70 
71 #define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
72 
73 typedef struct ParallelState {
74     MemoryRegion iomem;
75     uint8_t dataw;
76     uint8_t datar;
77     uint8_t status;
78     uint8_t control;
79     qemu_irq irq;
80     int irq_pending;
81     CharBackend chr;
82     int hw_driver;
83     int epp_timeout;
84     uint32_t last_read_offset; /* For debugging */
85     /* Memory-mapped interface */
86     int it_shift;
87     PortioList portio_list;
88 } ParallelState;
89 
90 #define TYPE_ISA_PARALLEL "isa-parallel"
91 #define ISA_PARALLEL(obj) \
92     OBJECT_CHECK(ISAParallelState, (obj), TYPE_ISA_PARALLEL)
93 
94 typedef struct ISAParallelState {
95     ISADevice parent_obj;
96 
97     uint32_t index;
98     uint32_t iobase;
99     uint32_t isairq;
100     ParallelState state;
101 } ISAParallelState;
102 
103 static void parallel_update_irq(ParallelState *s)
104 {
105     if (s->irq_pending)
106         qemu_irq_raise(s->irq);
107     else
108         qemu_irq_lower(s->irq);
109 }
110 
111 static void
112 parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
113 {
114     ParallelState *s = opaque;
115 
116     addr &= 7;
117     trace_parallel_ioport_write("SW", addr, val);
118     switch(addr) {
119     case PARA_REG_DATA:
120         s->dataw = val;
121         parallel_update_irq(s);
122         break;
123     case PARA_REG_CTR:
124         val |= 0xc0;
125         if ((val & PARA_CTR_INIT) == 0 ) {
126             s->status = PARA_STS_BUSY;
127             s->status |= PARA_STS_ACK;
128             s->status |= PARA_STS_ONLINE;
129             s->status |= PARA_STS_ERROR;
130         }
131         else if (val & PARA_CTR_SELECT) {
132             if (val & PARA_CTR_STROBE) {
133                 s->status &= ~PARA_STS_BUSY;
134                 if ((s->control & PARA_CTR_STROBE) == 0)
135                     /* XXX this blocks entire thread. Rewrite to use
136                      * qemu_chr_fe_write and background I/O callbacks */
137                     qemu_chr_fe_write_all(&s->chr, &s->dataw, 1);
138             } else {
139                 if (s->control & PARA_CTR_INTEN) {
140                     s->irq_pending = 1;
141                 }
142             }
143         }
144         parallel_update_irq(s);
145         s->control = val;
146         break;
147     }
148 }
149 
150 static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
151 {
152     ParallelState *s = opaque;
153     uint8_t parm = val;
154     int dir;
155 
156     /* Sometimes programs do several writes for timing purposes on old
157        HW. Take care not to waste time on writes that do nothing. */
158 
159     s->last_read_offset = ~0U;
160 
161     addr &= 7;
162     trace_parallel_ioport_write("HW", addr, val);
163     switch(addr) {
164     case PARA_REG_DATA:
165         if (s->dataw == val)
166             return;
167         pdebug("wd%02x\n", val);
168         qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
169         s->dataw = val;
170         break;
171     case PARA_REG_STS:
172         pdebug("ws%02x\n", val);
173         if (val & PARA_STS_TMOUT)
174             s->epp_timeout = 0;
175         break;
176     case PARA_REG_CTR:
177         val |= 0xc0;
178         if (s->control == val)
179             return;
180         pdebug("wc%02x\n", val);
181 
182         if ((val & PARA_CTR_DIR) != (s->control & PARA_CTR_DIR)) {
183             if (val & PARA_CTR_DIR) {
184                 dir = 1;
185             } else {
186                 dir = 0;
187             }
188             qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
189             parm &= ~PARA_CTR_DIR;
190         }
191 
192         qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
193         s->control = val;
194         break;
195     case PARA_REG_EPP_ADDR:
196         if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
197             /* Controls not correct for EPP address cycle, so do nothing */
198             pdebug("wa%02x s\n", val);
199         else {
200             struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
201             if (qemu_chr_fe_ioctl(&s->chr,
202                                   CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
203                 s->epp_timeout = 1;
204                 pdebug("wa%02x t\n", val);
205             }
206             else
207                 pdebug("wa%02x\n", val);
208         }
209         break;
210     case PARA_REG_EPP_DATA:
211         if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
212             /* Controls not correct for EPP data cycle, so do nothing */
213             pdebug("we%02x s\n", val);
214         else {
215             struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
216             if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
217                 s->epp_timeout = 1;
218                 pdebug("we%02x t\n", val);
219             }
220             else
221                 pdebug("we%02x\n", val);
222         }
223         break;
224     }
225 }
226 
227 static void
228 parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
229 {
230     ParallelState *s = opaque;
231     uint16_t eppdata = cpu_to_le16(val);
232     int err;
233     struct ParallelIOArg ioarg = {
234         .buffer = &eppdata, .count = sizeof(eppdata)
235     };
236 
237     trace_parallel_ioport_write("EPP", addr, val);
238     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
239         /* Controls not correct for EPP data cycle, so do nothing */
240         pdebug("we%04x s\n", val);
241         return;
242     }
243     err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
244     if (err) {
245         s->epp_timeout = 1;
246         pdebug("we%04x t\n", val);
247     }
248     else
249         pdebug("we%04x\n", val);
250 }
251 
252 static void
253 parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
254 {
255     ParallelState *s = opaque;
256     uint32_t eppdata = cpu_to_le32(val);
257     int err;
258     struct ParallelIOArg ioarg = {
259         .buffer = &eppdata, .count = sizeof(eppdata)
260     };
261 
262     trace_parallel_ioport_write("EPP", addr, val);
263     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
264         /* Controls not correct for EPP data cycle, so do nothing */
265         pdebug("we%08x s\n", val);
266         return;
267     }
268     err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
269     if (err) {
270         s->epp_timeout = 1;
271         pdebug("we%08x t\n", val);
272     }
273     else
274         pdebug("we%08x\n", val);
275 }
276 
277 static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
278 {
279     ParallelState *s = opaque;
280     uint32_t ret = 0xff;
281 
282     addr &= 7;
283     switch(addr) {
284     case PARA_REG_DATA:
285         if (s->control & PARA_CTR_DIR)
286             ret = s->datar;
287         else
288             ret = s->dataw;
289         break;
290     case PARA_REG_STS:
291         ret = s->status;
292         s->irq_pending = 0;
293         if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
294             /* XXX Fixme: wait 5 microseconds */
295             if (s->status & PARA_STS_ACK)
296                 s->status &= ~PARA_STS_ACK;
297             else {
298                 /* XXX Fixme: wait 5 microseconds */
299                 s->status |= PARA_STS_ACK;
300                 s->status |= PARA_STS_BUSY;
301             }
302         }
303         parallel_update_irq(s);
304         break;
305     case PARA_REG_CTR:
306         ret = s->control;
307         break;
308     }
309     trace_parallel_ioport_read("SW", addr, ret);
310     return ret;
311 }
312 
313 static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
314 {
315     ParallelState *s = opaque;
316     uint8_t ret = 0xff;
317     addr &= 7;
318     switch(addr) {
319     case PARA_REG_DATA:
320         qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
321         if (s->last_read_offset != addr || s->datar != ret)
322             pdebug("rd%02x\n", ret);
323         s->datar = ret;
324         break;
325     case PARA_REG_STS:
326         qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
327         ret &= ~PARA_STS_TMOUT;
328         if (s->epp_timeout)
329             ret |= PARA_STS_TMOUT;
330         if (s->last_read_offset != addr || s->status != ret)
331             pdebug("rs%02x\n", ret);
332         s->status = ret;
333         break;
334     case PARA_REG_CTR:
335         /* s->control has some bits fixed to 1. It is zero only when
336            it has not been yet written to.  */
337         if (s->control == 0) {
338             qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
339             if (s->last_read_offset != addr)
340                 pdebug("rc%02x\n", ret);
341             s->control = ret;
342         }
343         else {
344             ret = s->control;
345             if (s->last_read_offset != addr)
346                 pdebug("rc%02x\n", ret);
347         }
348         break;
349     case PARA_REG_EPP_ADDR:
350         if ((s->control & (PARA_CTR_DIR | PARA_CTR_SIGNAL)) !=
351             (PARA_CTR_DIR | PARA_CTR_INIT))
352             /* Controls not correct for EPP addr cycle, so do nothing */
353             pdebug("ra%02x s\n", ret);
354         else {
355             struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
356             if (qemu_chr_fe_ioctl(&s->chr,
357                                   CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
358                 s->epp_timeout = 1;
359                 pdebug("ra%02x t\n", ret);
360             }
361             else
362                 pdebug("ra%02x\n", ret);
363         }
364         break;
365     case PARA_REG_EPP_DATA:
366         if ((s->control & (PARA_CTR_DIR | PARA_CTR_SIGNAL)) !=
367             (PARA_CTR_DIR | PARA_CTR_INIT))
368             /* Controls not correct for EPP data cycle, so do nothing */
369             pdebug("re%02x s\n", ret);
370         else {
371             struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
372             if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
373                 s->epp_timeout = 1;
374                 pdebug("re%02x t\n", ret);
375             }
376             else
377                 pdebug("re%02x\n", ret);
378         }
379         break;
380     }
381     trace_parallel_ioport_read("HW", addr, ret);
382     s->last_read_offset = addr;
383     return ret;
384 }
385 
386 static uint32_t
387 parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
388 {
389     ParallelState *s = opaque;
390     uint32_t ret;
391     uint16_t eppdata = ~0;
392     int err;
393     struct ParallelIOArg ioarg = {
394         .buffer = &eppdata, .count = sizeof(eppdata)
395     };
396     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
397         /* Controls not correct for EPP data cycle, so do nothing */
398         pdebug("re%04x s\n", eppdata);
399         return eppdata;
400     }
401     err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
402     ret = le16_to_cpu(eppdata);
403 
404     if (err) {
405         s->epp_timeout = 1;
406         pdebug("re%04x t\n", ret);
407     }
408     else
409         pdebug("re%04x\n", ret);
410     trace_parallel_ioport_read("EPP", addr, ret);
411     return ret;
412 }
413 
414 static uint32_t
415 parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
416 {
417     ParallelState *s = opaque;
418     uint32_t ret;
419     uint32_t eppdata = ~0U;
420     int err;
421     struct ParallelIOArg ioarg = {
422         .buffer = &eppdata, .count = sizeof(eppdata)
423     };
424     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
425         /* Controls not correct for EPP data cycle, so do nothing */
426         pdebug("re%08x s\n", eppdata);
427         return eppdata;
428     }
429     err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
430     ret = le32_to_cpu(eppdata);
431 
432     if (err) {
433         s->epp_timeout = 1;
434         pdebug("re%08x t\n", ret);
435     }
436     else
437         pdebug("re%08x\n", ret);
438     trace_parallel_ioport_read("EPP", addr, ret);
439     return ret;
440 }
441 
442 static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
443 {
444     trace_parallel_ioport_write("ECP", addr & 7, val);
445     pdebug("wecp%d=%02x\n", addr & 7, val);
446 }
447 
448 static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
449 {
450     uint8_t ret = 0xff;
451 
452     trace_parallel_ioport_read("ECP", addr & 7, ret);
453     pdebug("recp%d:%02x\n", addr & 7, ret);
454     return ret;
455 }
456 
457 static void parallel_reset(void *opaque)
458 {
459     ParallelState *s = opaque;
460 
461     s->datar = ~0;
462     s->dataw = ~0;
463     s->status = PARA_STS_BUSY;
464     s->status |= PARA_STS_ACK;
465     s->status |= PARA_STS_ONLINE;
466     s->status |= PARA_STS_ERROR;
467     s->status |= PARA_STS_TMOUT;
468     s->control = PARA_CTR_SELECT;
469     s->control |= PARA_CTR_INIT;
470     s->control |= 0xc0;
471     s->irq_pending = 0;
472     s->hw_driver = 0;
473     s->epp_timeout = 0;
474     s->last_read_offset = ~0U;
475 }
476 
477 static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
478 
479 static const MemoryRegionPortio isa_parallel_portio_hw_list[] = {
480     { 0, 8, 1,
481       .read = parallel_ioport_read_hw,
482       .write = parallel_ioport_write_hw },
483     { 4, 1, 2,
484       .read = parallel_ioport_eppdata_read_hw2,
485       .write = parallel_ioport_eppdata_write_hw2 },
486     { 4, 1, 4,
487       .read = parallel_ioport_eppdata_read_hw4,
488       .write = parallel_ioport_eppdata_write_hw4 },
489     { 0x400, 8, 1,
490       .read = parallel_ioport_ecp_read,
491       .write = parallel_ioport_ecp_write },
492     PORTIO_END_OF_LIST(),
493 };
494 
495 static const MemoryRegionPortio isa_parallel_portio_sw_list[] = {
496     { 0, 8, 1,
497       .read = parallel_ioport_read_sw,
498       .write = parallel_ioport_write_sw },
499     PORTIO_END_OF_LIST(),
500 };
501 
502 
503 static const VMStateDescription vmstate_parallel_isa = {
504     .name = "parallel_isa",
505     .version_id = 1,
506     .minimum_version_id = 1,
507     .fields      = (VMStateField[]) {
508         VMSTATE_UINT8(state.dataw, ISAParallelState),
509         VMSTATE_UINT8(state.datar, ISAParallelState),
510         VMSTATE_UINT8(state.status, ISAParallelState),
511         VMSTATE_UINT8(state.control, ISAParallelState),
512         VMSTATE_INT32(state.irq_pending, ISAParallelState),
513         VMSTATE_INT32(state.epp_timeout, ISAParallelState),
514         VMSTATE_END_OF_LIST()
515     }
516 };
517 
518 static int parallel_can_receive(void *opaque)
519 {
520      return 1;
521 }
522 
523 static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
524 {
525     static int index;
526     ISADevice *isadev = ISA_DEVICE(dev);
527     ISAParallelState *isa = ISA_PARALLEL(dev);
528     ParallelState *s = &isa->state;
529     int base;
530     uint8_t dummy;
531 
532     if (!qemu_chr_fe_backend_connected(&s->chr)) {
533         error_setg(errp, "Can't create parallel device, empty char device");
534         return;
535     }
536 
537     if (isa->index == -1) {
538         isa->index = index;
539     }
540     if (isa->index >= MAX_PARALLEL_PORTS) {
541         error_setg(errp, "Max. supported number of parallel ports is %d.",
542                    MAX_PARALLEL_PORTS);
543         return;
544     }
545     if (isa->iobase == -1) {
546         isa->iobase = isa_parallel_io[isa->index];
547     }
548     index++;
549 
550     base = isa->iobase;
551     isa_init_irq(isadev, &s->irq, isa->isairq);
552     qemu_register_reset(parallel_reset, s);
553 
554     qemu_chr_fe_set_handlers(&s->chr, parallel_can_receive, NULL,
555                              NULL, NULL, s, NULL, true);
556     if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
557         s->hw_driver = 1;
558         s->status = dummy;
559     }
560 
561     isa_register_portio_list(isadev, &s->portio_list, base,
562                              (s->hw_driver
563                               ? &isa_parallel_portio_hw_list[0]
564                               : &isa_parallel_portio_sw_list[0]),
565                              s, "parallel");
566 }
567 
568 /* Memory mapped interface */
569 static uint64_t parallel_mm_readfn(void *opaque, hwaddr addr, unsigned size)
570 {
571     ParallelState *s = opaque;
572 
573     return parallel_ioport_read_sw(s, addr >> s->it_shift) &
574         MAKE_64BIT_MASK(0, size * 8);
575 }
576 
577 static void parallel_mm_writefn(void *opaque, hwaddr addr,
578                                 uint64_t value, unsigned size)
579 {
580     ParallelState *s = opaque;
581 
582     parallel_ioport_write_sw(s, addr >> s->it_shift,
583                              value & MAKE_64BIT_MASK(0, size * 8));
584 }
585 
586 static const MemoryRegionOps parallel_mm_ops = {
587     .read = parallel_mm_readfn,
588     .write = parallel_mm_writefn,
589     .valid.min_access_size = 1,
590     .valid.max_access_size = 4,
591     .endianness = DEVICE_NATIVE_ENDIAN,
592 };
593 
594 /* If fd is zero, it means that the parallel device uses the console */
595 bool parallel_mm_init(MemoryRegion *address_space,
596                       hwaddr base, int it_shift, qemu_irq irq,
597                       Chardev *chr)
598 {
599     ParallelState *s;
600 
601     s = g_malloc0(sizeof(ParallelState));
602     s->irq = irq;
603     qemu_chr_fe_init(&s->chr, chr, &error_abort);
604     s->it_shift = it_shift;
605     qemu_register_reset(parallel_reset, s);
606 
607     memory_region_init_io(&s->iomem, NULL, &parallel_mm_ops, s,
608                           "parallel", 8 << it_shift);
609     memory_region_add_subregion(address_space, base, &s->iomem);
610     return true;
611 }
612 
613 static Property parallel_isa_properties[] = {
614     DEFINE_PROP_UINT32("index", ISAParallelState, index,   -1),
615     DEFINE_PROP_UINT32("iobase", ISAParallelState, iobase,  -1),
616     DEFINE_PROP_UINT32("irq",   ISAParallelState, isairq,  7),
617     DEFINE_PROP_CHR("chardev",  ISAParallelState, state.chr),
618     DEFINE_PROP_END_OF_LIST(),
619 };
620 
621 static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
622 {
623     DeviceClass *dc = DEVICE_CLASS(klass);
624 
625     dc->realize = parallel_isa_realizefn;
626     dc->vmsd = &vmstate_parallel_isa;
627     dc->props = parallel_isa_properties;
628     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
629 }
630 
631 static const TypeInfo parallel_isa_info = {
632     .name          = TYPE_ISA_PARALLEL,
633     .parent        = TYPE_ISA_DEVICE,
634     .instance_size = sizeof(ISAParallelState),
635     .class_init    = parallel_isa_class_initfn,
636 };
637 
638 static void parallel_register_types(void)
639 {
640     type_register_static(&parallel_isa_info);
641 }
642 
643 type_init(parallel_register_types)
644