]>
Commit | Line | Data |
---|---|---|
ac636f80 | 1 | diff --exclude=CVS -upr qemu/hw/parallel.c qemu-sandbox/hw/parallel.c |
2 | --- qemu/hw/parallel.c 2005-01-23 13:42:59.000000000 -0700 | |
3 | +++ qemu-sandbox/hw/parallel.c 2005-03-12 19:00:37.000000000 -0700 | |
4 | @@ -22,6 +22,9 @@ | |
5 | * THE SOFTWARE. | |
6 | */ | |
7 | #include "vl.h" | |
8 | +#include <sys/ioctl.h> | |
9 | +#include <linux/parport.h> | |
10 | +#include <linux/ppdev.h> | |
11 | ||
12 | //#define DEBUG_PARALLEL | |
13 | ||
14 | @@ -43,15 +46,6 @@ | |
15 | #define PARA_CTR_AUTOLF 0x02 /* Auto linefeed complement */ | |
16 | #define PARA_CTR_STROBE 0x01 /* Strobe complement */ | |
17 | ||
18 | -struct ParallelState { | |
19 | - uint8_t data; | |
20 | - uint8_t status; /* read only register */ | |
21 | - uint8_t control; | |
22 | - int irq; | |
23 | - int irq_pending; | |
24 | - CharDriverState *chr; | |
25 | -}; | |
26 | - | |
27 | static void parallel_update_irq(ParallelState *s) | |
28 | { | |
29 | if (s->irq_pending) | |
30 | @@ -70,29 +64,29 @@ static void parallel_ioport_write(void * | |
31 | #endif | |
32 | switch(addr) { | |
33 | case 0: | |
34 | - s->data = val; | |
35 | + qemu_pp_write_data(s, (uint8_t)val); | |
36 | parallel_update_irq(s); | |
37 | break; | |
38 | case 2: | |
39 | + qemu_pp_write_control(s, (uint8_t)val); | |
40 | if ((val & PARA_CTR_INIT) == 0 ) { | |
41 | - s->status = PARA_STS_BUSY; | |
42 | - s->status |= PARA_STS_ACK; | |
43 | - s->status |= PARA_STS_ONLINE; | |
44 | - s->status |= PARA_STS_ERROR; | |
45 | + s->status = PARA_STS_BUSY; | |
46 | + s->status |= PARA_STS_ACK; | |
47 | + s->status |= PARA_STS_ONLINE; | |
48 | + s->status |= PARA_STS_ERROR; | |
49 | } | |
50 | else if (val & PARA_CTR_SELECT) { | |
51 | - if (val & PARA_CTR_STROBE) { | |
52 | - s->status &= ~PARA_STS_BUSY; | |
53 | - if ((s->control & PARA_CTR_STROBE) == 0) | |
54 | - qemu_chr_write(s->chr, &s->data, 1); | |
55 | - } else { | |
56 | - if (s->control & PARA_CTR_INTEN) { | |
57 | - s->irq_pending = 1; | |
58 | - } | |
59 | - } | |
60 | + if (val & PARA_CTR_STROBE) { | |
61 | + s->status &= ~PARA_STS_BUSY; | |
62 | + if ((s->control & PARA_CTR_STROBE) == 0) | |
63 | + qemu_chr_write(s->chr, &s->data, 1); | |
64 | + } else { | |
65 | + if (s->control & PARA_CTR_INTEN) { | |
66 | + s->irq_pending = 1; | |
67 | + } | |
68 | + } | |
69 | } | |
70 | parallel_update_irq(s); | |
71 | - s->control = val; | |
72 | break; | |
73 | } | |
74 | } | |
75 | @@ -105,25 +99,25 @@ static uint32_t parallel_ioport_read(voi | |
76 | addr &= 7; | |
77 | switch(addr) { | |
78 | case 0: | |
79 | - ret = s->data; | |
80 | + ret = qemu_pp_read_data(s); | |
81 | break; | |
82 | case 1: | |
83 | - ret = s->status; | |
84 | + ret = qemu_pp_read_status(s); | |
85 | s->irq_pending = 0; | |
86 | if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) { | |
87 | - /* XXX Fixme: wait 5 microseconds */ | |
88 | - if (s->status & PARA_STS_ACK) | |
89 | - s->status &= ~PARA_STS_ACK; | |
90 | - else { | |
91 | - /* XXX Fixme: wait 5 microseconds */ | |
92 | - s->status |= PARA_STS_ACK; | |
93 | - s->status |= PARA_STS_BUSY; | |
94 | - } | |
95 | + /* XXX Fixme: wait 5 microseconds */ | |
96 | + if (s->status & PARA_STS_ACK) | |
97 | + s->status &= ~PARA_STS_ACK; | |
98 | + else { | |
99 | + /* XXX Fixme: wait 5 microseconds */ | |
100 | + s->status |= PARA_STS_ACK; | |
101 | + s->status |= PARA_STS_BUSY; | |
102 | + } | |
103 | } | |
104 | parallel_update_irq(s); | |
105 | break; | |
106 | case 2: | |
107 | - ret = s->control; | |
108 | + ret = qemu_pp_read_control(s); | |
109 | break; | |
110 | } | |
111 | #ifdef DEBUG_PARALLEL | |
112 | Only in qemu-sandbox: kqemu | |
113 | Only in qemu-sandbox: qemu-doc.html | |
114 | Only in qemu-sandbox: qemu-img.1 | |
115 | Only in qemu-sandbox: qemu-tech.html | |
116 | Only in qemu-sandbox: qemu.1 | |
117 | diff --exclude=CVS -upr qemu/vl.c qemu-sandbox/vl.c | |
118 | --- qemu/vl.c 2005-03-13 02:43:36.000000000 -0700 | |
119 | +++ qemu-sandbox/vl.c 2005-03-13 07:16:54.000000000 -0700 | |
120 | @@ -46,6 +46,8 @@ | |
121 | #include <libutil.h> | |
122 | #endif | |
123 | #else | |
124 | +#include <linux/parport.h> | |
125 | +#include <linux/ppdev.h> | |
126 | #include <linux/if.h> | |
127 | #include <linux/if_tun.h> | |
128 | #include <pty.h> | |
129 | @@ -1028,10 +1030,14 @@ CharDriverState *qemu_chr_open_null(void | |
130 | return chr; | |
131 | } | |
132 | ||
133 | + | |
134 | + | |
135 | + | |
136 | #ifndef _WIN32 | |
137 | ||
138 | typedef struct { | |
139 | int fd_in, fd_out; | |
140 | + int parport_device; | |
141 | /* for nographic stdio only */ | |
142 | IOCanRWHandler *fd_can_read; | |
143 | IOReadHandler *fd_read; | |
144 | @@ -1084,6 +1090,76 @@ static void fd_chr_add_read_handler(Char | |
145 | } | |
146 | } | |
147 | ||
148 | +uint8_t qemu_pp_read_status(ParallelState *s) | |
149 | +{ | |
150 | + uint8_t ret, status; | |
151 | + FDCharDriver *fd = s->chr->opaque; | |
152 | + | |
153 | + if (fd->parport_device) { | |
154 | + ioctl(fd->fd_out, PPRSTATUS, &status); | |
155 | + ret = status; | |
156 | + } else { | |
157 | + ret = s->status; | |
158 | + } | |
159 | + | |
160 | + return ret; | |
161 | +} | |
162 | + | |
163 | + | |
164 | +uint8_t qemu_pp_read_control(ParallelState *s) | |
165 | +{ | |
166 | + uint8_t ret, control; | |
167 | + FDCharDriver *fd = s->chr->opaque; | |
168 | + | |
169 | + if (fd->parport_device) { | |
170 | + ioctl(fd->fd_out, PPRCONTROL, &control); | |
171 | + ret = control; | |
172 | + } else { | |
173 | + ret = s->control; | |
174 | + } | |
175 | + | |
176 | + return ret; | |
177 | + | |
178 | +} | |
179 | +uint8_t qemu_pp_read_data(ParallelState *s) | |
180 | +{ | |
181 | + uint8_t ret, data; | |
182 | + FDCharDriver *fd = s->chr->opaque; | |
183 | + | |
184 | + if (fd->parport_device) { | |
185 | + ioctl(fd->fd_out, PPRDATA, &data); | |
186 | + ret = data; | |
187 | + } else { | |
188 | + ret = s->data; | |
189 | + } | |
190 | + | |
191 | + return ret; | |
192 | +} | |
193 | +void qemu_pp_write_data(ParallelState *s, uint8_t val) | |
194 | +{ | |
195 | + uint8_t data; | |
196 | + FDCharDriver *fd = s->chr->opaque; | |
197 | + | |
198 | + if (fd->parport_device) { | |
199 | + data = (uint8_t)val; | |
200 | + ioctl(fd->fd_out, PPWDATA, &data); | |
201 | + } else { | |
202 | + s->data = val; | |
203 | + } | |
204 | +} | |
205 | + | |
206 | +void qemu_pp_write_control(ParallelState *s, uint8_t val) | |
207 | +{ | |
208 | + uint8_t control; | |
209 | + FDCharDriver *fd = s->chr->opaque; | |
210 | + | |
211 | + if (fd->parport_device) { | |
212 | + control = (uint8_t)val; | |
213 | + ioctl(fd->fd_out, PPWCONTROL, &control); | |
214 | + } else { | |
215 | + s->control = val; | |
216 | + } | |
217 | +} | |
218 | /* open a character device to a unix fd */ | |
219 | CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) | |
220 | { | |
221 | @@ -1263,6 +1339,24 @@ CharDriverState *qemu_chr_open_stdio(voi | |
222 | return chr; | |
223 | } | |
224 | ||
225 | +CharDriverState *qemu_chr_open_dev(const char *filename) | |
226 | +{ | |
227 | + int fd = 0; | |
228 | + | |
229 | + fd = open(filename, O_RDWR); | |
230 | + CharDriverState *s = qemu_chr_open_fd(fd, fd); | |
231 | + | |
232 | + if (strstr(filename, "parport") != NULL) { | |
233 | + if (ioctl(((FDCharDriver *)s->opaque)->fd_in, PPCLAIM) == 0) { | |
234 | + ((FDCharDriver *)s->opaque)->parport_device = 1; | |
235 | + } else { | |
236 | + ((FDCharDriver *)s->opaque)->parport_device = 0; | |
237 | + } | |
238 | + } | |
239 | + | |
240 | + return s; | |
241 | +} | |
242 | + | |
243 | #if defined(__linux__) | |
244 | CharDriverState *qemu_chr_open_pty(void) | |
245 | { | |
246 | @@ -1297,11 +1391,14 @@ CharDriverState *qemu_chr_open(const cha | |
247 | return qemu_chr_open_pty(); | |
248 | } else if (!strcmp(filename, "stdio")) { | |
249 | return qemu_chr_open_stdio(); | |
250 | - } else | |
251 | -#endif | |
252 | + } else { | |
253 | + return qemu_chr_open_dev(filename); | |
254 | + } | |
255 | +#else | |
256 | { | |
257 | return NULL; | |
258 | } | |
259 | +#endif | |
260 | } | |
261 | ||
262 | /***********************************************************/ | |
263 | diff --exclude=CVS -upr qemu/vl.h qemu-sandbox/vl.h | |
264 | --- qemu/vl.h 2005-03-13 02:43:36.000000000 -0700 | |
265 | +++ qemu-sandbox/vl.h 2005-03-13 07:16:54.000000000 -0700 | |
266 | @@ -199,6 +199,17 @@ typedef struct CharDriverState { | |
267 | void *opaque; | |
268 | } CharDriverState; | |
269 | ||
270 | + | |
271 | +typedef struct ParallelState { | |
272 | + uint8_t data; | |
273 | + uint8_t status; /* read only register */ | |
274 | + uint8_t control; | |
275 | + int irq; | |
276 | + int irq_pending; | |
277 | + CharDriverState *chr; | |
278 | +} ParallelState; | |
279 | + | |
280 | + | |
281 | void qemu_chr_printf(CharDriverState *s, const char *fmt, ...); | |
282 | int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len); | |
283 | void qemu_chr_send_event(CharDriverState *s, int event); | |
284 | @@ -206,6 +217,13 @@ void qemu_chr_add_read_handler(CharDrive | |
285 | IOCanRWHandler *fd_can_read, | |
286 | IOReadHandler *fd_read, void *opaque); | |
287 | void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event); | |
288 | + | |
289 | + | |
290 | +uint8_t qemu_pp_read_status(ParallelState *s); | |
291 | +uint8_t qemu_pp_read_control(ParallelState *s); | |
292 | +uint8_t qemu_pp_read_data(ParallelState *s); | |
293 | +void qemu_pp_write_data(ParallelState *s, uint8_t data); | |
294 | +void qemu_pp_write_control(ParallelState *s, uint8_t control); | |
295 | ||
296 | /* consoles */ | |
297 | ||
298 | @@ -643,8 +661,6 @@ typedef struct SerialState SerialState; | |
299 | SerialState *serial_init(int base, int irq, CharDriverState *chr); | |
300 | ||
301 | /* parallel.c */ | |
302 | - | |
303 | -typedef struct ParallelState ParallelState; | |
304 | ParallelState *parallel_init(int base, int irq, CharDriverState *chr); | |
305 | ||
306 | /* i8259.c */ |