Commit 5867c88a8256c6501c382ba421c91464dd871e3b

Authored by ths
1 parent d5d10bc3

Parport EPP support for Linux, by Marko Kohtala.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2430 c046a42c-6fe2-441c-8c8c-71466251a162
hw/parallel.c
... ... @@ -2,6 +2,7 @@
2 2 * QEMU Parallel PORT emulation
3 3 *
4 4 * Copyright (c) 2003-2005 Fabrice Bellard
  5 + * Copyright (c) 2007 Marko Kohtala
5 6 *
6 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 8 * of this software and associated documentation files (the "Software"), to deal
... ... @@ -25,6 +26,18 @@
25 26  
26 27 //#define DEBUG_PARALLEL
27 28  
  29 +#ifdef DEBUG_PARALLEL
  30 +#define pdebug(fmt, arg...) printf("pp: " fmt, ##arg)
  31 +#else
  32 +#define pdebug(fmt, arg...) ((void)0)
  33 +#endif
  34 +
  35 +#define PARA_REG_DATA 0
  36 +#define PARA_REG_STS 1
  37 +#define PARA_REG_CTR 2
  38 +#define PARA_REG_EPP_ADDR 3
  39 +#define PARA_REG_EPP_DATA 4
  40 +
28 41 /*
29 42 * These are the definitions for the Printer Status Register
30 43 */
... ... @@ -33,24 +46,31 @@
33 46 #define PARA_STS_PAPER 0x20 /* Out of paper */
34 47 #define PARA_STS_ONLINE 0x10 /* Online */
35 48 #define PARA_STS_ERROR 0x08 /* Error complement */
  49 +#define PARA_STS_TMOUT 0x01 /* EPP timeout */
36 50  
37 51 /*
38 52 * These are the definitions for the Printer Control Register
39 53 */
  54 +#define PARA_CTR_DIR 0x20 /* Direction (1=read, 0=write) */
40 55 #define PARA_CTR_INTEN 0x10 /* IRQ Enable */
41 56 #define PARA_CTR_SELECT 0x08 /* Select In complement */
42 57 #define PARA_CTR_INIT 0x04 /* Initialize Printer complement */
43 58 #define PARA_CTR_AUTOLF 0x02 /* Auto linefeed complement */
44 59 #define PARA_CTR_STROBE 0x01 /* Strobe complement */
45 60  
  61 +#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
  62 +
46 63 struct ParallelState {
47   - uint8_t data;
48   - uint8_t status; /* read only register */
  64 + uint8_t dataw;
  65 + uint8_t datar;
  66 + uint8_t status;
49 67 uint8_t control;
50 68 int irq;
51 69 int irq_pending;
52 70 CharDriverState *chr;
53 71 int hw_driver;
  72 + int epp_timeout;
  73 + uint32_t last_read_offset; /* For debugging */
54 74 };
55 75  
56 76 static void parallel_update_irq(ParallelState *s)
... ... @@ -61,96 +81,322 @@ static void parallel_update_irq(ParallelState *s)
61 81 pic_set_irq(s->irq, 0);
62 82 }
63 83  
64   -static void parallel_ioport_write(void *opaque, uint32_t addr, uint32_t val)
  84 +static void
  85 +parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
65 86 {
66 87 ParallelState *s = opaque;
67 88  
  89 + pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
  90 +
  91 + addr &= 7;
  92 + switch(addr) {
  93 + case PARA_REG_DATA:
  94 + s->dataw = val;
  95 + parallel_update_irq(s);
  96 + break;
  97 + case PARA_REG_CTR:
  98 + if ((val & PARA_CTR_INIT) == 0 ) {
  99 + s->status = PARA_STS_BUSY;
  100 + s->status |= PARA_STS_ACK;
  101 + s->status |= PARA_STS_ONLINE;
  102 + s->status |= PARA_STS_ERROR;
  103 + }
  104 + else if (val & PARA_CTR_SELECT) {
  105 + if (val & PARA_CTR_STROBE) {
  106 + s->status &= ~PARA_STS_BUSY;
  107 + if ((s->control & PARA_CTR_STROBE) == 0)
  108 + qemu_chr_write(s->chr, &s->dataw, 1);
  109 + } else {
  110 + if (s->control & PARA_CTR_INTEN) {
  111 + s->irq_pending = 1;
  112 + }
  113 + }
  114 + }
  115 + parallel_update_irq(s);
  116 + s->control = val;
  117 + break;
  118 + }
  119 +}
  120 +
  121 +static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
  122 +{
  123 + ParallelState *s = opaque;
  124 + uint8_t parm = val;
  125 +
  126 + /* Sometimes programs do several writes for timing purposes on old
  127 + HW. Take care not to waste time on writes that do nothing. */
  128 +
  129 + s->last_read_offset = ~0U;
  130 +
68 131 addr &= 7;
69   -#ifdef DEBUG_PARALLEL
70   - printf("parallel: write addr=0x%02x val=0x%02x\n", addr, val);
71   -#endif
72 132 switch(addr) {
73   - case 0:
74   - if (s->hw_driver) {
75   - s->data = val;
76   - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &s->data);
77   - } else {
78   - s->data = val;
79   - parallel_update_irq(s);
80   - }
  133 + case PARA_REG_DATA:
  134 + if (s->dataw == val)
  135 + return;
  136 + pdebug("wd%02x\n", val);
  137 + qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
  138 + s->dataw = val;
81 139 break;
82   - case 2:
83   - if (s->hw_driver) {
84   - s->control = val;
85   - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &s->control);
86   - } else {
87   - if ((val & PARA_CTR_INIT) == 0 ) {
88   - s->status = PARA_STS_BUSY;
89   - s->status |= PARA_STS_ACK;
90   - s->status |= PARA_STS_ONLINE;
91   - s->status |= PARA_STS_ERROR;
92   - }
93   - else if (val & PARA_CTR_SELECT) {
94   - if (val & PARA_CTR_STROBE) {
95   - s->status &= ~PARA_STS_BUSY;
96   - if ((s->control & PARA_CTR_STROBE) == 0)
97   - qemu_chr_write(s->chr, &s->data, 1);
98   - } else {
99   - if (s->control & PARA_CTR_INTEN) {
100   - s->irq_pending = 1;
101   - }
102   - }
103   - }
104   - parallel_update_irq(s);
105   - s->control = val;
106   - }
  140 + case PARA_REG_STS:
  141 + pdebug("ws%02x\n", val);
  142 + if (val & PARA_STS_TMOUT)
  143 + s->epp_timeout = 0;
  144 + break;
  145 + case PARA_REG_CTR:
  146 + val |= 0xc0;
  147 + if (s->control == val)
  148 + return;
  149 + pdebug("wc%02x\n", val);
  150 + qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
  151 + s->control = val;
107 152 break;
  153 + case PARA_REG_EPP_ADDR:
  154 + if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
  155 + /* Controls not correct for EPP address cycle, so do nothing */
  156 + pdebug("wa%02x s\n", val);
  157 + else {
  158 + struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
  159 + if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
  160 + s->epp_timeout = 1;
  161 + pdebug("wa%02x t\n", val);
  162 + }
  163 + else
  164 + pdebug("wa%02x\n", val);
  165 + }
  166 + break;
  167 + case PARA_REG_EPP_DATA:
  168 + if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
  169 + /* Controls not correct for EPP data cycle, so do nothing */
  170 + pdebug("we%02x s\n", val);
  171 + else {
  172 + struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
  173 + if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
  174 + s->epp_timeout = 1;
  175 + pdebug("we%02x t\n", val);
  176 + }
  177 + else
  178 + pdebug("we%02x\n", val);
  179 + }
  180 + break;
  181 + }
  182 +}
  183 +
  184 +static void
  185 +parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
  186 +{
  187 + ParallelState *s = opaque;
  188 + uint16_t eppdata = cpu_to_le16(val);
  189 + int err;
  190 + struct ParallelIOArg ioarg = {
  191 + .buffer = &eppdata, .count = sizeof(eppdata)
  192 + };
  193 + if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
  194 + /* Controls not correct for EPP data cycle, so do nothing */
  195 + pdebug("we%04x s\n", val);
  196 + return;
  197 + }
  198 + err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
  199 + if (err) {
  200 + s->epp_timeout = 1;
  201 + pdebug("we%04x t\n", val);
  202 + }
  203 + else
  204 + pdebug("we%04x\n", val);
  205 +}
  206 +
  207 +static void
  208 +parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
  209 +{
  210 + ParallelState *s = opaque;
  211 + uint32_t eppdata = cpu_to_le32(val);
  212 + int err;
  213 + struct ParallelIOArg ioarg = {
  214 + .buffer = &eppdata, .count = sizeof(eppdata)
  215 + };
  216 + if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
  217 + /* Controls not correct for EPP data cycle, so do nothing */
  218 + pdebug("we%08x s\n", val);
  219 + return;
  220 + }
  221 + err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
  222 + if (err) {
  223 + s->epp_timeout = 1;
  224 + pdebug("we%08x t\n", val);
108 225 }
  226 + else
  227 + pdebug("we%08x\n", val);
109 228 }
110 229  
111   -static uint32_t parallel_ioport_read(void *opaque, uint32_t addr)
  230 +static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
112 231 {
113 232 ParallelState *s = opaque;
114 233 uint32_t ret = 0xff;
115 234  
116 235 addr &= 7;
117 236 switch(addr) {
118   - case 0:
119   - if (s->hw_driver) {
120   - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &s->data);
121   - }
122   - ret = s->data;
  237 + case PARA_REG_DATA:
  238 + if (s->control & PARA_CTR_DIR)
  239 + ret = s->datar;
  240 + else
  241 + ret = s->dataw;
123 242 break;
124   - case 1:
125   - if (s->hw_driver) {
126   - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &s->status);
127   - ret = s->status;
128   - } else {
129   - ret = s->status;
130   - s->irq_pending = 0;
131   - if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
132   - /* XXX Fixme: wait 5 microseconds */
133   - if (s->status & PARA_STS_ACK)
134   - s->status &= ~PARA_STS_ACK;
135   - else {
136   - /* XXX Fixme: wait 5 microseconds */
137   - s->status |= PARA_STS_ACK;
138   - s->status |= PARA_STS_BUSY;
139   - }
140   - }
141   - parallel_update_irq(s);
142   - }
  243 + case PARA_REG_STS:
  244 + ret = s->status;
  245 + s->irq_pending = 0;
  246 + if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
  247 + /* XXX Fixme: wait 5 microseconds */
  248 + if (s->status & PARA_STS_ACK)
  249 + s->status &= ~PARA_STS_ACK;
  250 + else {
  251 + /* XXX Fixme: wait 5 microseconds */
  252 + s->status |= PARA_STS_ACK;
  253 + s->status |= PARA_STS_BUSY;
  254 + }
  255 + }
  256 + parallel_update_irq(s);
143 257 break;
144   - case 2:
145   - if (s->hw_driver) {
146   - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &s->control);
147   - }
  258 + case PARA_REG_CTR:
148 259 ret = s->control;
149 260 break;
150 261 }
151   -#ifdef DEBUG_PARALLEL
152   - printf("parallel: read addr=0x%02x val=0x%02x\n", addr, ret);
153   -#endif
  262 + pdebug("read addr=0x%02x val=0x%02x\n", addr, ret);
  263 + return ret;
  264 +}
  265 +
  266 +static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
  267 +{
  268 + ParallelState *s = opaque;
  269 + uint8_t ret = 0xff;
  270 + addr &= 7;
  271 + switch(addr) {
  272 + case PARA_REG_DATA:
  273 + qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
  274 + if (s->last_read_offset != addr || s->datar != ret)
  275 + pdebug("rd%02x\n", ret);
  276 + s->datar = ret;
  277 + break;
  278 + case PARA_REG_STS:
  279 + qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
  280 + ret &= ~PARA_STS_TMOUT;
  281 + if (s->epp_timeout)
  282 + ret |= PARA_STS_TMOUT;
  283 + if (s->last_read_offset != addr || s->status != ret)
  284 + pdebug("rs%02x\n", ret);
  285 + s->status = ret;
  286 + break;
  287 + case PARA_REG_CTR:
  288 + /* s->control has some bits fixed to 1. It is zero only when
  289 + it has not been yet written to. */
  290 + if (s->control == 0) {
  291 + qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
  292 + if (s->last_read_offset != addr)
  293 + pdebug("rc%02x\n", ret);
  294 + s->control = ret;
  295 + }
  296 + else {
  297 + ret = s->control;
  298 + if (s->last_read_offset != addr)
  299 + pdebug("rc%02x\n", ret);
  300 + }
  301 + break;
  302 + case PARA_REG_EPP_ADDR:
  303 + if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
  304 + /* Controls not correct for EPP addr cycle, so do nothing */
  305 + pdebug("ra%02x s\n", ret);
  306 + else {
  307 + struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
  308 + if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
  309 + s->epp_timeout = 1;
  310 + pdebug("ra%02x t\n", ret);
  311 + }
  312 + else
  313 + pdebug("ra%02x\n", ret);
  314 + }
  315 + break;
  316 + case PARA_REG_EPP_DATA:
  317 + if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
  318 + /* Controls not correct for EPP data cycle, so do nothing */
  319 + pdebug("re%02x s\n", ret);
  320 + else {
  321 + struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
  322 + if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
  323 + s->epp_timeout = 1;
  324 + pdebug("re%02x t\n", ret);
  325 + }
  326 + else
  327 + pdebug("re%02x\n", ret);
  328 + }
  329 + break;
  330 + }
  331 + s->last_read_offset = addr;
  332 + return ret;
  333 +}
  334 +
  335 +static uint32_t
  336 +parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
  337 +{
  338 + ParallelState *s = opaque;
  339 + uint32_t ret;
  340 + uint16_t eppdata = ~0;
  341 + int err;
  342 + struct ParallelIOArg ioarg = {
  343 + .buffer = &eppdata, .count = sizeof(eppdata)
  344 + };
  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%04x s\n", eppdata);
  348 + return eppdata;
  349 + }
  350 + err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
  351 + ret = le16_to_cpu(eppdata);
  352 +
  353 + if (err) {
  354 + s->epp_timeout = 1;
  355 + pdebug("re%04x t\n", ret);
  356 + }
  357 + else
  358 + pdebug("re%04x\n", ret);
  359 + return ret;
  360 +}
  361 +
  362 +static uint32_t
  363 +parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
  364 +{
  365 + ParallelState *s = opaque;
  366 + uint32_t ret;
  367 + uint32_t eppdata = ~0U;
  368 + int err;
  369 + struct ParallelIOArg ioarg = {
  370 + .buffer = &eppdata, .count = sizeof(eppdata)
  371 + };
  372 + if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
  373 + /* Controls not correct for EPP data cycle, so do nothing */
  374 + pdebug("re%08x s\n", eppdata);
  375 + return eppdata;
  376 + }
  377 + err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
  378 + ret = le32_to_cpu(eppdata);
  379 +
  380 + if (err) {
  381 + s->epp_timeout = 1;
  382 + pdebug("re%08x t\n", ret);
  383 + }
  384 + else
  385 + pdebug("re%08x\n", ret);
  386 + return ret;
  387 +}
  388 +
  389 +static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
  390 +{
  391 + addr &= 7;
  392 + pdebug("wecp%d=%02x\n", addr, val);
  393 +}
  394 +
  395 +static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
  396 +{
  397 + uint8_t ret = 0xff;
  398 + addr &= 7;
  399 + pdebug("recp%d:%02x\n", addr, ret);
154 400 return ret;
155 401 }
156 402  
... ... @@ -163,21 +409,39 @@ ParallelState *parallel_init(int base, int irq, CharDriverState *chr)
163 409 s = qemu_mallocz(sizeof(ParallelState));
164 410 if (!s)
165 411 return NULL;
166   - s->chr = chr;
167   - s->hw_driver = 0;
168   - if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0)
169   - s->hw_driver = 1;
170   -
171   - s->irq = irq;
172   - s->data = 0;
  412 + s->datar = ~0;
  413 + s->dataw = ~0;
173 414 s->status = PARA_STS_BUSY;
174 415 s->status |= PARA_STS_ACK;
175 416 s->status |= PARA_STS_ONLINE;
176 417 s->status |= PARA_STS_ERROR;
177 418 s->control = PARA_CTR_SELECT;
178 419 s->control |= PARA_CTR_INIT;
  420 + s->irq = irq;
  421 + s->irq_pending = 0;
  422 + s->chr = chr;
  423 + s->hw_driver = 0;
  424 + s->epp_timeout = 0;
  425 + s->last_read_offset = ~0U;
179 426  
180   - register_ioport_write(base, 8, 1, parallel_ioport_write, s);
181   - register_ioport_read(base, 8, 1, parallel_ioport_read, s);
  427 + if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
  428 + s->hw_driver = 1;
  429 + s->status = dummy;
  430 + }
  431 +
  432 + if (s->hw_driver) {
  433 + register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s);
  434 + register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s);
  435 + register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
  436 + register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
  437 + register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
  438 + register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
  439 + register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s);
  440 + register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s);
  441 + }
  442 + else {
  443 + register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s);
  444 + register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s);
  445 + }
182 446 return s;
183 447 }
... ...
qemu-doc.texi
... ... @@ -541,7 +541,7 @@ void device
541 541 parameters are set according to the emulated ones.
542 542 @item /dev/parportN
543 543 [Linux only, parallel port only] Use host parallel port
544   -@var{N}. Currently only SPP parallel port features can be used.
  544 +@var{N}. Currently SPP and EPP parallel port features can be used.
545 545 @item file:filename
546 546 Write output to filename. No character can be read.
547 547 @item stdio
... ...
... ... @@ -55,6 +55,7 @@
55 55 #include <malloc.h>
56 56 #include <linux/rtc.h>
57 57 #include <linux/ppdev.h>
  58 +#include <linux/parport.h>
58 59 #else
59 60 #include <sys/stat.h>
60 61 #include <sys/ethernet.h>
... ... @@ -1813,9 +1814,26 @@ static CharDriverState *qemu_chr_open_tty(const char *filename)
1813 1814 return chr;
1814 1815 }
1815 1816  
  1817 +typedef struct {
  1818 + int fd;
  1819 + int mode;
  1820 +} ParallelCharDriver;
  1821 +
  1822 +static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
  1823 +{
  1824 + if (s->mode != mode) {
  1825 + int m = mode;
  1826 + if (ioctl(s->fd, PPSETMODE, &m) < 0)
  1827 + return 0;
  1828 + s->mode = mode;
  1829 + }
  1830 + return 1;
  1831 +}
  1832 +
1816 1833 static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1817 1834 {
1818   - int fd = (int)chr->opaque;
  1835 + ParallelCharDriver *drv = chr->opaque;
  1836 + int fd = drv->fd;
1819 1837 uint8_t b;
1820 1838  
1821 1839 switch(cmd) {
... ... @@ -1832,7 +1850,10 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1832 1850 case CHR_IOCTL_PP_READ_CONTROL:
1833 1851 if (ioctl(fd, PPRCONTROL, &b) < 0)
1834 1852 return -ENOTSUP;
1835   - *(uint8_t *)arg = b;
  1853 + /* Linux gives only the lowest bits, and no way to know data
  1854 + direction! For better compatibility set the fixed upper
  1855 + bits. */
  1856 + *(uint8_t *)arg = b | 0xc0;
1836 1857 break;
1837 1858 case CHR_IOCTL_PP_WRITE_CONTROL:
1838 1859 b = *(uint8_t *)arg;
... ... @@ -1844,15 +1865,63 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1844 1865 return -ENOTSUP;
1845 1866 *(uint8_t *)arg = b;
1846 1867 break;
  1868 + case CHR_IOCTL_PP_EPP_READ_ADDR:
  1869 + if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
  1870 + struct ParallelIOArg *parg = arg;
  1871 + int n = read(fd, parg->buffer, parg->count);
  1872 + if (n != parg->count) {
  1873 + return -EIO;
  1874 + }
  1875 + }
  1876 + break;
  1877 + case CHR_IOCTL_PP_EPP_READ:
  1878 + if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
  1879 + struct ParallelIOArg *parg = arg;
  1880 + int n = read(fd, parg->buffer, parg->count);
  1881 + if (n != parg->count) {
  1882 + return -EIO;
  1883 + }
  1884 + }
  1885 + break;
  1886 + case CHR_IOCTL_PP_EPP_WRITE_ADDR:
  1887 + if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
  1888 + struct ParallelIOArg *parg = arg;
  1889 + int n = write(fd, parg->buffer, parg->count);
  1890 + if (n != parg->count) {
  1891 + return -EIO;
  1892 + }
  1893 + }
  1894 + break;
  1895 + case CHR_IOCTL_PP_EPP_WRITE:
  1896 + if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
  1897 + struct ParallelIOArg *parg = arg;
  1898 + int n = write(fd, parg->buffer, parg->count);
  1899 + if (n != parg->count) {
  1900 + return -EIO;
  1901 + }
  1902 + }
  1903 + break;
1847 1904 default:
1848 1905 return -ENOTSUP;
1849 1906 }
1850 1907 return 0;
1851 1908 }
1852 1909  
  1910 +static void pp_close(CharDriverState *chr)
  1911 +{
  1912 + ParallelCharDriver *drv = chr->opaque;
  1913 + int fd = drv->fd;
  1914 +
  1915 + pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
  1916 + ioctl(fd, PPRELEASE);
  1917 + close(fd);
  1918 + qemu_free(drv);
  1919 +}
  1920 +
1853 1921 static CharDriverState *qemu_chr_open_pp(const char *filename)
1854 1922 {
1855 1923 CharDriverState *chr;
  1924 + ParallelCharDriver *drv;
1856 1925 int fd;
1857 1926  
1858 1927 fd = open(filename, O_RDWR);
... ... @@ -1864,14 +1933,24 @@ static CharDriverState *qemu_chr_open_pp(const char *filename)
1864 1933 return NULL;
1865 1934 }
1866 1935  
  1936 + drv = qemu_mallocz(sizeof(ParallelCharDriver));
  1937 + if (!drv) {
  1938 + close(fd);
  1939 + return NULL;
  1940 + }
  1941 + drv->fd = fd;
  1942 + drv->mode = IEEE1284_MODE_COMPAT;
  1943 +
1867 1944 chr = qemu_mallocz(sizeof(CharDriverState));
1868 1945 if (!chr) {
  1946 + qemu_free(drv);
1869 1947 close(fd);
1870 1948 return NULL;
1871 1949 }
1872   - chr->opaque = (void *)fd;
1873 1950 chr->chr_write = null_chr_write;
1874 1951 chr->chr_ioctl = pp_ioctl;
  1952 + chr->chr_close = pp_close;
  1953 + chr->opaque = drv;
1875 1954  
1876 1955 qemu_chr_reset(chr);
1877 1956  
... ...
... ... @@ -285,6 +285,10 @@ typedef struct {
285 285 #define CHR_IOCTL_PP_READ_CONTROL 5
286 286 #define CHR_IOCTL_PP_WRITE_CONTROL 6
287 287 #define CHR_IOCTL_PP_READ_STATUS 7
  288 +#define CHR_IOCTL_PP_EPP_READ_ADDR 8
  289 +#define CHR_IOCTL_PP_EPP_READ 9
  290 +#define CHR_IOCTL_PP_EPP_WRITE_ADDR 10
  291 +#define CHR_IOCTL_PP_EPP_WRITE 11
288 292  
289 293 typedef void IOEventHandler(void *opaque, int event);
290 294  
... ... @@ -349,6 +353,11 @@ extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
349 353  
350 354 extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
351 355  
  356 +struct ParallelIOArg {
  357 + void *buffer;
  358 + int count;
  359 +};
  360 +
352 361 /* VLANs support */
353 362  
354 363 typedef struct VLANClientState VLANClientState;
... ...