Commit e2733d20b2c8fade7e81aebb34e4e1db821d472f
1 parent
637f6cd7
ADB fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@965 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
210 additions
and
108 deletions
hw/adb.c
... | ... | @@ -43,53 +43,53 @@ |
43 | 43 | #define ADB_MODEM 5 |
44 | 44 | #define ADB_MISC 7 |
45 | 45 | |
46 | -#define ADB_RET_OK 0 | |
47 | -#define ADB_RET_INUSE 1 | |
48 | -#define ADB_RET_NOTPRESENT 2 | |
49 | -#define ADB_RET_TIMEOUT 3 | |
50 | -#define ADB_RET_UNEXPECTED_RESULT 4 | |
51 | -#define ADB_RET_REQUEST_ERROR 5 | |
52 | -#define ADB_RET_BUS_ERROR 6 | |
53 | - | |
54 | - | |
55 | -static void adb_send_packet1(ADBBusState *s, uint8_t reply) | |
56 | -{ | |
57 | - adb_send_packet(s, &reply, 1); | |
58 | -} | |
59 | - | |
60 | -void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len) | |
46 | +int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len) | |
61 | 47 | { |
62 | 48 | ADBDevice *d; |
63 | 49 | int devaddr, cmd, i; |
64 | - uint8_t obuf[4]; | |
65 | 50 | |
66 | 51 | cmd = buf[0] & 0xf; |
67 | 52 | devaddr = buf[0] >> 4; |
68 | 53 | if (buf[1] == ADB_BUSRESET) { |
69 | 54 | obuf[0] = 0x00; |
70 | 55 | obuf[1] = 0x00; |
71 | - adb_send_packet(s, obuf, 2); | |
72 | - return; | |
56 | + return 2; | |
73 | 57 | } |
74 | 58 | if (cmd == ADB_FLUSH) { |
75 | 59 | obuf[0] = 0x00; |
76 | 60 | obuf[1] = 0x00; |
77 | - adb_send_packet(s, obuf, 2); | |
78 | - return; | |
61 | + return 2; | |
79 | 62 | } |
80 | 63 | |
81 | 64 | for(i = 0; i < s->nb_devices; i++) { |
82 | 65 | d = &s->devices[i]; |
83 | 66 | if (d->devaddr == devaddr) { |
84 | - d->receive_packet(d, buf, len); | |
85 | - return; | |
67 | + return d->devreq(d, obuf, buf, len); | |
86 | 68 | } |
87 | 69 | } |
88 | - adb_send_packet1(s, ADB_RET_NOTPRESENT); | |
70 | + return 0; | |
71 | +} | |
72 | + | |
73 | +int adb_poll(ADBBusState *s, uint8_t *obuf) | |
74 | +{ | |
75 | + ADBDevice *d; | |
76 | + int olen, i; | |
77 | + | |
78 | + olen = 0; | |
79 | + for(i = 0; i < s->nb_devices; i++) { | |
80 | + if (s->poll_index >= s->nb_devices) | |
81 | + s->poll_index = 0; | |
82 | + d = &s->devices[s->poll_index]; | |
83 | + olen = d->devreq(d, obuf, NULL, 0); | |
84 | + s->poll_index++; | |
85 | + if (olen) | |
86 | + break; | |
87 | + } | |
88 | + return olen; | |
89 | 89 | } |
90 | 90 | |
91 | 91 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
92 | - ADBDeviceReceivePacket *receive_packet, | |
92 | + ADBDeviceRequest *devreq, | |
93 | 93 | void *opaque) |
94 | 94 | { |
95 | 95 | ADBDevice *d; |
... | ... | @@ -98,7 +98,7 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
98 | 98 | d = &s->devices[s->nb_devices++]; |
99 | 99 | d->bus = s; |
100 | 100 | d->devaddr = devaddr; |
101 | - d->receive_packet = receive_packet; | |
101 | + d->devreq = devreq; | |
102 | 102 | d->opaque = opaque; |
103 | 103 | return d; |
104 | 104 | } |
... | ... | @@ -106,80 +106,108 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
106 | 106 | /***************************************************************/ |
107 | 107 | /* Keyboard ADB device */ |
108 | 108 | |
109 | +typedef struct KBDState { | |
110 | + uint8_t data[128]; | |
111 | + int rptr, wptr, count; | |
112 | +} KBDState; | |
113 | + | |
109 | 114 | static const uint8_t pc_to_adb_keycode[256] = { |
110 | 115 | 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48, |
111 | 116 | 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1, |
112 | 117 | 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9, |
113 | 118 | 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96, |
114 | 119 | 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83, |
115 | - 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0, 0, 0, 0, 0, 0, | |
116 | - 76,125, 75,105,124,110,115, 62,116, 59, 60,119, 61,121,114,117, | |
117 | - 0, 0, 0, 0,127, 81, 0,113, 0, 0, 0, 0, 95, 55, 0, 0, | |
118 | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
119 | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
120 | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
121 | - 0, 0, 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, | |
122 | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
120 | + 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0, | |
123 | 121 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
124 | 122 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
123 | + 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0, | |
124 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0, | |
125 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, | |
126 | + 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, | |
127 | + 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119, | |
128 | + 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0, | |
125 | 129 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
130 | + 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
126 | 131 | }; |
127 | 132 | |
128 | 133 | static void adb_kbd_put_keycode(void *opaque, int keycode) |
129 | 134 | { |
130 | - static int ext_keycode; | |
131 | 135 | ADBDevice *d = opaque; |
132 | - uint8_t buf[4]; | |
133 | - int adb_keycode; | |
134 | - | |
135 | - if (keycode == 0xe0) { | |
136 | - ext_keycode = 1; | |
137 | - } else { | |
138 | - | |
139 | - if (ext_keycode) | |
140 | - adb_keycode = pc_to_adb_keycode[keycode | 0x80]; | |
141 | - else | |
142 | - adb_keycode = pc_to_adb_keycode[keycode & 0x7f]; | |
143 | - | |
144 | - buf[0] = 0x40; | |
145 | - buf[1] = (d->devaddr << 4) | 0x0c; | |
146 | - buf[2] = adb_keycode | (keycode & 0x80); | |
147 | - buf[3] = 0xff; | |
148 | - adb_send_packet(d->bus, buf, 4); | |
149 | - ext_keycode = 0; | |
136 | + KBDState *s = d->opaque; | |
137 | + | |
138 | + if (s->count < sizeof(s->data)) { | |
139 | + s->data[s->wptr] = keycode; | |
140 | + if (++s->wptr == sizeof(s->data)) | |
141 | + s->wptr = 0; | |
142 | + s->count++; | |
150 | 143 | } |
151 | 144 | } |
152 | 145 | |
153 | -static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | |
146 | +static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf) | |
154 | 147 | { |
155 | - int cmd, reg; | |
156 | - uint8_t obuf[4]; | |
148 | + static int ext_keycode; | |
149 | + KBDState *s = d->opaque; | |
150 | + int adb_keycode, keycode; | |
151 | + int olen; | |
152 | + | |
153 | + olen = 0; | |
154 | + for(;;) { | |
155 | + if (s->count == 0) | |
156 | + break; | |
157 | + keycode = s->data[s->rptr]; | |
158 | + if (++s->rptr == sizeof(s->data)) | |
159 | + s->rptr = 0; | |
160 | + s->count--; | |
161 | + | |
162 | + if (keycode == 0xe0) { | |
163 | + ext_keycode = 1; | |
164 | + } else { | |
165 | + if (ext_keycode) | |
166 | + adb_keycode = pc_to_adb_keycode[keycode | 0x80]; | |
167 | + else | |
168 | + adb_keycode = pc_to_adb_keycode[keycode & 0x7f]; | |
169 | + obuf[0] = (d->devaddr << 4) | 0x0c; | |
170 | + obuf[1] = adb_keycode | (keycode & 0x80); | |
171 | + obuf[2] = 0xff; | |
172 | + olen = 3; | |
173 | + ext_keycode = 0; | |
174 | + break; | |
175 | + } | |
176 | + } | |
177 | + return olen; | |
178 | +} | |
179 | + | |
180 | +static int adb_kbd_request(ADBDevice *d, uint8_t *obuf, | |
181 | + const uint8_t *buf, int len) | |
182 | +{ | |
183 | + int cmd, reg, olen; | |
184 | + | |
185 | + if (!buf) { | |
186 | + return adb_kbd_poll(d, obuf); | |
187 | + } | |
157 | 188 | |
158 | 189 | cmd = buf[0] & 0xc; |
159 | 190 | reg = buf[0] & 0x3; |
191 | + olen = 0; | |
160 | 192 | switch(cmd) { |
161 | 193 | case ADB_WRITEREG: |
162 | 194 | switch(reg) { |
163 | 195 | case 2: |
164 | 196 | /* LED status */ |
165 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
166 | 197 | break; |
167 | 198 | case 3: |
168 | 199 | switch(buf[2]) { |
169 | 200 | case ADB_CMD_SELF_TEST: |
170 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
171 | 201 | break; |
172 | 202 | case ADB_CMD_CHANGE_ID: |
173 | 203 | case ADB_CMD_CHANGE_ID_AND_ACT: |
174 | 204 | case ADB_CMD_CHANGE_ID_AND_ENABLE: |
175 | 205 | d->devaddr = buf[1] & 0xf; |
176 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
177 | 206 | break; |
178 | 207 | default: |
179 | 208 | /* XXX: check this */ |
180 | 209 | d->devaddr = buf[1] & 0xf; |
181 | 210 | d->handler = buf[2]; |
182 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
183 | 211 | break; |
184 | 212 | } |
185 | 213 | } |
... | ... | @@ -187,98 +215,122 @@ static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len) |
187 | 215 | case ADB_READREG: |
188 | 216 | switch(reg) { |
189 | 217 | case 1: |
190 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
191 | 218 | break; |
192 | 219 | case 2: |
193 | - obuf[0] = ADB_RET_OK; | |
194 | - obuf[1] = 0x00; /* XXX: check this */ | |
195 | - obuf[2] = 0x07; /* led status */ | |
196 | - adb_send_packet(d->bus, obuf, 3); | |
220 | + obuf[0] = 0x00; /* XXX: check this */ | |
221 | + obuf[1] = 0x07; /* led status */ | |
222 | + olen = 2; | |
197 | 223 | break; |
198 | 224 | case 3: |
199 | - obuf[0] = ADB_RET_OK; | |
200 | - obuf[1] = d->handler; | |
201 | - obuf[2] = d->devaddr; | |
202 | - adb_send_packet(d->bus, obuf, 3); | |
225 | + obuf[0] = d->handler; | |
226 | + obuf[1] = d->devaddr; | |
227 | + olen = 2; | |
203 | 228 | break; |
204 | 229 | } |
205 | 230 | break; |
206 | 231 | } |
232 | + return olen; | |
207 | 233 | } |
208 | 234 | |
209 | 235 | void adb_kbd_init(ADBBusState *bus) |
210 | 236 | { |
211 | 237 | ADBDevice *d; |
212 | - | |
213 | - d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_receive_packet, NULL); | |
238 | + KBDState *s; | |
239 | + s = qemu_mallocz(sizeof(KBDState)); | |
240 | + d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, s); | |
241 | + d->handler = 1; | |
214 | 242 | qemu_add_kbd_event_handler(adb_kbd_put_keycode, d); |
215 | 243 | } |
216 | 244 | |
217 | 245 | /***************************************************************/ |
218 | 246 | /* Mouse ADB device */ |
219 | 247 | |
248 | +typedef struct MouseState { | |
249 | + int buttons_state, last_buttons_state; | |
250 | + int dx, dy, dz; | |
251 | +} MouseState; | |
252 | + | |
220 | 253 | static void adb_mouse_event(void *opaque, |
221 | 254 | int dx1, int dy1, int dz1, int buttons_state) |
222 | 255 | { |
223 | 256 | ADBDevice *d = opaque; |
224 | - uint8_t buf[4]; | |
257 | + MouseState *s = d->opaque; | |
258 | + | |
259 | + s->dx += dx1; | |
260 | + s->dy += dy1; | |
261 | + s->dz += dz1; | |
262 | + s->buttons_state = buttons_state; | |
263 | +} | |
264 | + | |
265 | + | |
266 | +static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf) | |
267 | +{ | |
268 | + MouseState *s = d->opaque; | |
225 | 269 | int dx, dy; |
226 | 270 | |
227 | - dx = dx1; | |
271 | + if (s->last_buttons_state == s->buttons_state && | |
272 | + s->dx == 0 && s->dy == 0) | |
273 | + return 0; | |
274 | + | |
275 | + dx = s->dx; | |
228 | 276 | if (dx < -63) |
229 | 277 | dx = -63; |
230 | 278 | else if (dx > 63) |
231 | 279 | dx = 63; |
232 | - | |
233 | - dy = dy1; | |
280 | + | |
281 | + dy = s->dy; | |
234 | 282 | if (dy < -63) |
235 | 283 | dy = -63; |
236 | 284 | else if (dy > 63) |
237 | 285 | dy = 63; |
238 | - | |
286 | + | |
287 | + s->dx -= dx; | |
288 | + s->dy -= dy; | |
289 | + s->last_buttons_state = s->buttons_state; | |
290 | + | |
239 | 291 | dx &= 0x7f; |
240 | 292 | dy &= 0x7f; |
241 | - | |
242 | - if (buttons_state & MOUSE_EVENT_LBUTTON) | |
293 | + | |
294 | + if (s->buttons_state & MOUSE_EVENT_LBUTTON) | |
243 | 295 | dy |= 0x80; |
244 | - if (buttons_state & MOUSE_EVENT_RBUTTON) | |
296 | + if (s->buttons_state & MOUSE_EVENT_RBUTTON) | |
245 | 297 | dx |= 0x80; |
246 | - | |
247 | - buf[0] = 0x40; | |
248 | - buf[1] = (d->devaddr << 4) | 0x0c; | |
249 | - buf[2] = dy; | |
250 | - buf[3] = dx; | |
251 | - adb_send_packet(d->bus, buf, 4); | |
298 | + | |
299 | + obuf[0] = (d->devaddr << 4) | 0x0c; | |
300 | + obuf[1] = dy; | |
301 | + obuf[2] = dx; | |
302 | + return 3; | |
252 | 303 | } |
253 | 304 | |
254 | -static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | |
305 | +static int adb_mouse_request(ADBDevice *d, uint8_t *obuf, | |
306 | + const uint8_t *buf, int len) | |
255 | 307 | { |
256 | - int cmd, reg; | |
257 | - uint8_t obuf[4]; | |
308 | + int cmd, reg, olen; | |
309 | + | |
310 | + if (!buf) { | |
311 | + return adb_mouse_poll(d, obuf); | |
312 | + } | |
258 | 313 | |
259 | 314 | cmd = buf[0] & 0xc; |
260 | 315 | reg = buf[0] & 0x3; |
316 | + olen = 0; | |
261 | 317 | switch(cmd) { |
262 | 318 | case ADB_WRITEREG: |
263 | 319 | switch(reg) { |
264 | 320 | case 2: |
265 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
266 | 321 | break; |
267 | 322 | case 3: |
268 | 323 | switch(buf[2]) { |
269 | 324 | case ADB_CMD_SELF_TEST: |
270 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
271 | 325 | break; |
272 | 326 | case ADB_CMD_CHANGE_ID: |
273 | 327 | case ADB_CMD_CHANGE_ID_AND_ACT: |
274 | 328 | case ADB_CMD_CHANGE_ID_AND_ENABLE: |
275 | 329 | d->devaddr = buf[1] & 0xf; |
276 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
277 | 330 | break; |
278 | 331 | default: |
279 | 332 | /* XXX: check this */ |
280 | 333 | d->devaddr = buf[1] & 0xf; |
281 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
282 | 334 | break; |
283 | 335 | } |
284 | 336 | } |
... | ... | @@ -286,23 +338,25 @@ static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len) |
286 | 338 | case ADB_READREG: |
287 | 339 | switch(reg) { |
288 | 340 | case 1: |
289 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
290 | 341 | break; |
291 | 342 | case 3: |
292 | - obuf[0] = ADB_RET_OK; | |
293 | - obuf[1] = d->handler; | |
294 | - obuf[2] = d->devaddr; | |
295 | - adb_send_packet(d->bus, obuf, 3); | |
343 | + obuf[0] = d->handler; | |
344 | + obuf[1] = d->devaddr; | |
345 | + olen = 2; | |
296 | 346 | break; |
297 | 347 | } |
298 | 348 | break; |
299 | 349 | } |
350 | + return olen; | |
300 | 351 | } |
301 | 352 | |
302 | 353 | void adb_mouse_init(ADBBusState *bus) |
303 | 354 | { |
304 | 355 | ADBDevice *d; |
356 | + MouseState *s; | |
305 | 357 | |
306 | - d = adb_register_device(bus, ADB_MOUSE, adb_mouse_receive_packet, NULL); | |
358 | + s = qemu_mallocz(sizeof(MouseState)); | |
359 | + d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, s); | |
360 | + d->handler = 2; | |
307 | 361 | qemu_add_mouse_event_handler(adb_mouse_event, d); |
308 | 362 | } | ... | ... |
hw/cuda.c
... | ... | @@ -85,6 +85,7 @@ |
85 | 85 | #define CUDA_COMBINED_FORMAT_IIC 0x25 |
86 | 86 | |
87 | 87 | #define CUDA_TIMER_FREQ (4700000 / 6) |
88 | +#define CUDA_ADB_POLL_FREQ 50 | |
88 | 89 | |
89 | 90 | typedef struct CUDATimer { |
90 | 91 | unsigned int latch; |
... | ... | @@ -121,6 +122,7 @@ typedef struct CUDAState { |
121 | 122 | uint8_t autopoll; |
122 | 123 | uint8_t data_in[128]; |
123 | 124 | uint8_t data_out[16]; |
125 | + QEMUTimer *adb_poll_timer; | |
124 | 126 | } CUDAState; |
125 | 127 | |
126 | 128 | static CUDAState cuda_state; |
... | ... | @@ -469,15 +471,42 @@ void adb_send_packet(ADBBusState *bus, const uint8_t *buf, int len) |
469 | 471 | cuda_send_packet_to_host(s, data, len + 1); |
470 | 472 | } |
471 | 473 | |
474 | +void cuda_adb_poll(void *opaque) | |
475 | +{ | |
476 | + CUDAState *s = opaque; | |
477 | + uint8_t obuf[ADB_MAX_OUT_LEN + 2]; | |
478 | + int olen; | |
479 | + | |
480 | + olen = adb_poll(&adb_bus, obuf + 2); | |
481 | + if (olen > 0) { | |
482 | + obuf[0] = ADB_PACKET; | |
483 | + obuf[1] = 0x40; /* polled data */ | |
484 | + cuda_send_packet_to_host(s, obuf, olen + 2); | |
485 | + } | |
486 | + qemu_mod_timer(s->adb_poll_timer, | |
487 | + qemu_get_clock(vm_clock) + | |
488 | + (ticks_per_sec / CUDA_ADB_POLL_FREQ)); | |
489 | +} | |
490 | + | |
472 | 491 | static void cuda_receive_packet(CUDAState *s, |
473 | 492 | const uint8_t *data, int len) |
474 | 493 | { |
475 | 494 | uint8_t obuf[16]; |
476 | - int ti; | |
495 | + int ti, autopoll; | |
477 | 496 | |
478 | 497 | switch(data[0]) { |
479 | 498 | case CUDA_AUTOPOLL: |
480 | - s->autopoll = data[1]; | |
499 | + autopoll = (data[1] != 0); | |
500 | + if (autopoll != s->autopoll) { | |
501 | + s->autopoll = autopoll; | |
502 | + if (autopoll) { | |
503 | + qemu_mod_timer(s->adb_poll_timer, | |
504 | + qemu_get_clock(vm_clock) + | |
505 | + (ticks_per_sec / CUDA_ADB_POLL_FREQ)); | |
506 | + } else { | |
507 | + qemu_del_timer(s->adb_poll_timer); | |
508 | + } | |
509 | + } | |
481 | 510 | obuf[0] = CUDA_PACKET; |
482 | 511 | obuf[1] = data[1]; |
483 | 512 | cuda_send_packet_to_host(s, obuf, 2); |
... | ... | @@ -522,7 +551,20 @@ static void cuda_receive_packet_from_host(CUDAState *s, |
522 | 551 | #endif |
523 | 552 | switch(data[0]) { |
524 | 553 | case ADB_PACKET: |
525 | - adb_receive_packet(&adb_bus, data + 1, len - 1); | |
554 | + { | |
555 | + uint8_t obuf[ADB_MAX_OUT_LEN + 2]; | |
556 | + int olen; | |
557 | + olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1); | |
558 | + if (olen != 0) { | |
559 | + obuf[0] = ADB_PACKET; | |
560 | + obuf[1] = 0x00; | |
561 | + } else { | |
562 | + /* empty reply */ | |
563 | + obuf[0] = ADB_PACKET; | |
564 | + obuf[1] = 0x02; | |
565 | + } | |
566 | + cuda_send_packet_to_host(s, obuf, olen + 2); | |
567 | + } | |
526 | 568 | break; |
527 | 569 | case CUDA_PACKET: |
528 | 570 | cuda_receive_packet(s, data + 1, len - 1); |
... | ... | @@ -574,6 +616,8 @@ int cuda_init(openpic_t *openpic, int irq) |
574 | 616 | s->timers[1].latch = 0x10000; |
575 | 617 | s->ier = T1_INT | SR_INT; |
576 | 618 | set_counter(s, &s->timers[1], 0xffff); |
619 | + | |
620 | + s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s); | |
577 | 621 | cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s); |
578 | 622 | return cuda_mem_index; |
579 | 623 | } | ... | ... |
vl.h
... | ... | @@ -528,8 +528,7 @@ PCIBus *pci_pmac_init(void); |
528 | 528 | /* openpic.c */ |
529 | 529 | typedef struct openpic_t openpic_t; |
530 | 530 | void openpic_set_irq (openpic_t *opp, int n_IRQ, int level); |
531 | -openpic_t *openpic_init (PCIBus *bus, | |
532 | - uint32_t isu_base, uint32_t idu_base, int nb_cpus); | |
531 | +openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus); | |
533 | 532 | |
534 | 533 | /* vga.c */ |
535 | 534 | |
... | ... | @@ -727,28 +726,33 @@ int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, |
727 | 726 | |
728 | 727 | #define MAX_ADB_DEVICES 16 |
729 | 728 | |
730 | -typedef struct ADBDevice ADBDevice; | |
729 | +#define ADB_MAX_OUT_LEN 16 | |
731 | 730 | |
732 | -typedef void ADBDeviceReceivePacket(ADBDevice *d, const uint8_t *buf, int len); | |
731 | +typedef struct ADBDevice ADBDevice; | |
733 | 732 | |
733 | +/* buf = NULL means polling */ | |
734 | +typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out, | |
735 | + const uint8_t *buf, int len); | |
734 | 736 | struct ADBDevice { |
735 | 737 | struct ADBBusState *bus; |
736 | 738 | int devaddr; |
737 | 739 | int handler; |
738 | - ADBDeviceReceivePacket *receive_packet; | |
740 | + ADBDeviceRequest *devreq; | |
739 | 741 | void *opaque; |
740 | 742 | }; |
741 | 743 | |
742 | 744 | typedef struct ADBBusState { |
743 | 745 | ADBDevice devices[MAX_ADB_DEVICES]; |
744 | 746 | int nb_devices; |
747 | + int poll_index; | |
745 | 748 | } ADBBusState; |
746 | 749 | |
747 | -void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len); | |
748 | -void adb_send_packet(ADBBusState *s, const uint8_t *buf, int len); | |
750 | +int adb_request(ADBBusState *s, uint8_t *buf_out, | |
751 | + const uint8_t *buf, int len); | |
752 | +int adb_poll(ADBBusState *s, uint8_t *buf_out); | |
749 | 753 | |
750 | 754 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
751 | - ADBDeviceReceivePacket *receive_packet, | |
755 | + ADBDeviceRequest *devreq, | |
752 | 756 | void *opaque); |
753 | 757 | void adb_kbd_init(ADBBusState *bus); |
754 | 758 | void adb_mouse_init(ADBBusState *bus); | ... | ... |