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