]> git.proxmox.com Git - mirror_qemu.git/blame - hw/usb-uhci.c
find -type f | xargs sed -i 's/[\t ]$//g' # on most files
[mirror_qemu.git] / hw / usb-uhci.c
CommitLineData
bb36d470
FB
1/*
2 * USB UHCI controller emulation
5fafdf24 3 *
bb36d470 4 * Copyright (c) 2005 Fabrice Bellard
5fafdf24 5 *
bb36d470
FB
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#include "vl.h"
25
26//#define DEBUG
27//#define DEBUG_PACKET
28
96217e31
TS
29#define UHCI_CMD_FGR (1 << 4)
30#define UHCI_CMD_EGSM (1 << 3)
bb36d470
FB
31#define UHCI_CMD_GRESET (1 << 2)
32#define UHCI_CMD_HCRESET (1 << 1)
33#define UHCI_CMD_RS (1 << 0)
34
35#define UHCI_STS_HCHALTED (1 << 5)
36#define UHCI_STS_HCPERR (1 << 4)
37#define UHCI_STS_HSERR (1 << 3)
38#define UHCI_STS_RD (1 << 2)
39#define UHCI_STS_USBERR (1 << 1)
40#define UHCI_STS_USBINT (1 << 0)
41
42#define TD_CTRL_SPD (1 << 29)
43#define TD_CTRL_ERROR_SHIFT 27
44#define TD_CTRL_IOS (1 << 25)
45#define TD_CTRL_IOC (1 << 24)
46#define TD_CTRL_ACTIVE (1 << 23)
47#define TD_CTRL_STALL (1 << 22)
48#define TD_CTRL_BABBLE (1 << 20)
49#define TD_CTRL_NAK (1 << 19)
50#define TD_CTRL_TIMEOUT (1 << 18)
51
52#define UHCI_PORT_RESET (1 << 9)
53#define UHCI_PORT_LSDA (1 << 8)
54#define UHCI_PORT_ENC (1 << 3)
55#define UHCI_PORT_EN (1 << 2)
56#define UHCI_PORT_CSC (1 << 1)
57#define UHCI_PORT_CCS (1 << 0)
58
59#define FRAME_TIMER_FREQ 1000
60
61#define FRAME_MAX_LOOPS 100
62
63#define NB_PORTS 2
64
65typedef struct UHCIPort {
66 USBPort port;
67 uint16_t ctrl;
bb36d470
FB
68} UHCIPort;
69
70typedef struct UHCIState {
71 PCIDevice dev;
72 uint16_t cmd; /* cmd register */
73 uint16_t status;
74 uint16_t intr; /* interrupt enable register */
75 uint16_t frnum; /* frame number */
76 uint32_t fl_base_addr; /* frame list base address */
77 uint8_t sof_timing;
78 uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
79 QEMUTimer *frame_timer;
80 UHCIPort ports[NB_PORTS];
4d611c9a
PB
81
82 /* Interrupts that should be raised at the end of the current frame. */
83 uint32_t pending_int_mask;
84 /* For simplicity of implementation we only allow a single pending USB
85 request. This means all usb traffic on this controller is effectively
86 suspended until that transfer completes. When the transfer completes
5fafdf24 87 the next transfer from that queue will be processed. However
4d611c9a
PB
88 other queues will not be processed until the next frame. The solution
89 is to allow multiple pending requests. */
90 uint32_t async_qh;
91 USBPacket usb_packet;
81822663 92 uint8_t usb_buf[2048];
bb36d470
FB
93} UHCIState;
94
95typedef struct UHCI_TD {
96 uint32_t link;
97 uint32_t ctrl; /* see TD_CTRL_xxx */
98 uint32_t token;
99 uint32_t buffer;
100} UHCI_TD;
101
102typedef struct UHCI_QH {
103 uint32_t link;
104 uint32_t el_link;
105} UHCI_QH;
106
107static void uhci_attach(USBPort *port1, USBDevice *dev);
108
109static void uhci_update_irq(UHCIState *s)
110{
111 int level;
112 if (((s->status2 & 1) && (s->intr & (1 << 2))) ||
113 ((s->status2 & 2) && (s->intr & (1 << 3))) ||
114 ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
115 ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
116 (s->status & UHCI_STS_HSERR) ||
117 (s->status & UHCI_STS_HCPERR)) {
118 level = 1;
119 } else {
120 level = 0;
121 }
d537cf6c 122 qemu_set_irq(s->dev.irq[3], level);
bb36d470
FB
123}
124
125static void uhci_reset(UHCIState *s)
126{
127 uint8_t *pci_conf;
128 int i;
129 UHCIPort *port;
130
131 pci_conf = s->dev.config;
132
133 pci_conf[0x6a] = 0x01; /* usb clock */
134 pci_conf[0x6b] = 0x00;
135 s->cmd = 0;
136 s->status = 0;
137 s->status2 = 0;
138 s->intr = 0;
139 s->fl_base_addr = 0;
140 s->sof_timing = 64;
141 for(i = 0; i < NB_PORTS; i++) {
142 port = &s->ports[i];
143 port->ctrl = 0x0080;
a594cfbf
FB
144 if (port->port.dev)
145 uhci_attach(&port->port, port->port.dev);
bb36d470
FB
146 }
147}
148
149static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
150{
151 UHCIState *s = opaque;
5fafdf24 152
bb36d470
FB
153 addr &= 0x1f;
154 switch(addr) {
155 case 0x0c:
156 s->sof_timing = val;
157 break;
158 }
159}
160
161static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
162{
163 UHCIState *s = opaque;
164 uint32_t val;
165
166 addr &= 0x1f;
167 switch(addr) {
168 case 0x0c:
169 val = s->sof_timing;
d80cfb3f 170 break;
bb36d470
FB
171 default:
172 val = 0xff;
173 break;
174 }
175 return val;
176}
177
178static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
179{
180 UHCIState *s = opaque;
5fafdf24 181
bb36d470
FB
182 addr &= 0x1f;
183#ifdef DEBUG
184 printf("uhci writew port=0x%04x val=0x%04x\n", addr, val);
185#endif
186 switch(addr) {
187 case 0x00:
188 if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
189 /* start frame processing */
190 qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
52328140 191 s->status &= ~UHCI_STS_HCHALTED;
467d409f 192 } else if (!(val & UHCI_CMD_RS)) {
52328140 193 s->status |= UHCI_STS_HCHALTED;
bb36d470
FB
194 }
195 if (val & UHCI_CMD_GRESET) {
196 UHCIPort *port;
197 USBDevice *dev;
198 int i;
199
200 /* send reset on the USB bus */
201 for(i = 0; i < NB_PORTS; i++) {
202 port = &s->ports[i];
a594cfbf 203 dev = port->port.dev;
bb36d470 204 if (dev) {
4d611c9a 205 usb_send_msg(dev, USB_MSG_RESET);
bb36d470
FB
206 }
207 }
208 uhci_reset(s);
209 return;
210 }
5e9ab4c4 211 if (val & UHCI_CMD_HCRESET) {
bb36d470
FB
212 uhci_reset(s);
213 return;
214 }
215 s->cmd = val;
216 break;
217 case 0x02:
218 s->status &= ~val;
219 /* XXX: the chip spec is not coherent, so we add a hidden
220 register to distinguish between IOC and SPD */
221 if (val & UHCI_STS_USBINT)
222 s->status2 = 0;
223 uhci_update_irq(s);
224 break;
225 case 0x04:
226 s->intr = val;
227 uhci_update_irq(s);
228 break;
229 case 0x06:
230 if (s->status & UHCI_STS_HCHALTED)
231 s->frnum = val & 0x7ff;
232 break;
233 case 0x10 ... 0x1f:
234 {
235 UHCIPort *port;
236 USBDevice *dev;
237 int n;
238
239 n = (addr >> 1) & 7;
240 if (n >= NB_PORTS)
241 return;
242 port = &s->ports[n];
a594cfbf 243 dev = port->port.dev;
bb36d470
FB
244 if (dev) {
245 /* port reset */
5fafdf24 246 if ( (val & UHCI_PORT_RESET) &&
bb36d470 247 !(port->ctrl & UHCI_PORT_RESET) ) {
4d611c9a 248 usb_send_msg(dev, USB_MSG_RESET);
bb36d470
FB
249 }
250 }
251 port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
252 /* some bits are reset when a '1' is written to them */
253 port->ctrl &= ~(val & 0x000a);
254 }
255 break;
256 }
257}
258
259static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
260{
261 UHCIState *s = opaque;
262 uint32_t val;
263
264 addr &= 0x1f;
265 switch(addr) {
266 case 0x00:
267 val = s->cmd;
268 break;
269 case 0x02:
270 val = s->status;
271 break;
272 case 0x04:
273 val = s->intr;
274 break;
275 case 0x06:
276 val = s->frnum;
277 break;
278 case 0x10 ... 0x1f:
279 {
280 UHCIPort *port;
281 int n;
282 n = (addr >> 1) & 7;
5fafdf24 283 if (n >= NB_PORTS)
bb36d470
FB
284 goto read_default;
285 port = &s->ports[n];
286 val = port->ctrl;
287 }
288 break;
289 default:
290 read_default:
291 val = 0xff7f; /* disabled port */
292 break;
293 }
294#ifdef DEBUG
295 printf("uhci readw port=0x%04x val=0x%04x\n", addr, val);
296#endif
297 return val;
298}
299
300static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
301{
302 UHCIState *s = opaque;
303
304 addr &= 0x1f;
305#ifdef DEBUG
306 printf("uhci writel port=0x%04x val=0x%08x\n", addr, val);
307#endif
308 switch(addr) {
309 case 0x08:
310 s->fl_base_addr = val & ~0xfff;
311 break;
312 }
313}
314
315static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
316{
317 UHCIState *s = opaque;
318 uint32_t val;
319
320 addr &= 0x1f;
321 switch(addr) {
322 case 0x08:
323 val = s->fl_base_addr;
324 break;
325 default:
326 val = 0xffffffff;
327 break;
328 }
329 return val;
330}
331
96217e31
TS
332/* signal resume if controller suspended */
333static void uhci_resume (void *opaque)
334{
335 UHCIState *s = (UHCIState *)opaque;
336
337 if (!s)
338 return;
339
340 if (s->cmd & UHCI_CMD_EGSM) {
341 s->cmd |= UHCI_CMD_FGR;
342 s->status |= UHCI_STS_RD;
343 uhci_update_irq(s);
344 }
345}
346
bb36d470
FB
347static void uhci_attach(USBPort *port1, USBDevice *dev)
348{
349 UHCIState *s = port1->opaque;
350 UHCIPort *port = &s->ports[port1->index];
351
352 if (dev) {
a594cfbf 353 if (port->port.dev) {
bb36d470
FB
354 usb_attach(port1, NULL);
355 }
356 /* set connect status */
61064870
PB
357 port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
358
bb36d470
FB
359 /* update speed */
360 if (dev->speed == USB_SPEED_LOW)
361 port->ctrl |= UHCI_PORT_LSDA;
362 else
363 port->ctrl &= ~UHCI_PORT_LSDA;
96217e31
TS
364
365 uhci_resume(s);
366
a594cfbf 367 port->port.dev = dev;
bb36d470 368 /* send the attach message */
4d611c9a 369 usb_send_msg(dev, USB_MSG_ATTACH);
bb36d470
FB
370 } else {
371 /* set connect status */
61064870
PB
372 if (port->ctrl & UHCI_PORT_CCS) {
373 port->ctrl &= ~UHCI_PORT_CCS;
374 port->ctrl |= UHCI_PORT_CSC;
bb36d470
FB
375 }
376 /* disable port */
377 if (port->ctrl & UHCI_PORT_EN) {
378 port->ctrl &= ~UHCI_PORT_EN;
379 port->ctrl |= UHCI_PORT_ENC;
380 }
96217e31
TS
381
382 uhci_resume(s);
383
a594cfbf 384 dev = port->port.dev;
bb36d470
FB
385 if (dev) {
386 /* send the detach message */
4d611c9a 387 usb_send_msg(dev, USB_MSG_DETACH);
bb36d470 388 }
a594cfbf 389 port->port.dev = NULL;
bb36d470
FB
390 }
391}
392
4d611c9a 393static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
bb36d470
FB
394{
395 UHCIPort *port;
396 USBDevice *dev;
397 int i, ret;
398
399#ifdef DEBUG_PACKET
400 {
401 const char *pidstr;
4d611c9a 402 switch(p->pid) {
bb36d470
FB
403 case USB_TOKEN_SETUP: pidstr = "SETUP"; break;
404 case USB_TOKEN_IN: pidstr = "IN"; break;
405 case USB_TOKEN_OUT: pidstr = "OUT"; break;
406 default: pidstr = "?"; break;
407 }
408 printf("frame %d: pid=%s addr=0x%02x ep=%d len=%d\n",
4d611c9a
PB
409 s->frnum, pidstr, p->devaddr, p->devep, p->len);
410 if (p->pid != USB_TOKEN_IN) {
bb36d470 411 printf(" data_out=");
4d611c9a
PB
412 for(i = 0; i < p->len; i++) {
413 printf(" %02x", p->data[i]);
bb36d470
FB
414 }
415 printf("\n");
416 }
417 }
418#endif
419 for(i = 0; i < NB_PORTS; i++) {
420 port = &s->ports[i];
a594cfbf 421 dev = port->port.dev;
bb36d470 422 if (dev && (port->ctrl & UHCI_PORT_EN)) {
4d611c9a 423 ret = dev->handle_packet(dev, p);
bb36d470
FB
424 if (ret != USB_RET_NODEV) {
425#ifdef DEBUG_PACKET
4d611c9a
PB
426 if (ret == USB_RET_ASYNC) {
427 printf("usb-uhci: Async packet\n");
428 } else {
bb36d470 429 printf(" ret=%d ", ret);
4d611c9a 430 if (p->pid == USB_TOKEN_IN && ret > 0) {
bb36d470
FB
431 printf("data_in=");
432 for(i = 0; i < ret; i++) {
4d611c9a 433 printf(" %02x", p->data[i]);
bb36d470
FB
434 }
435 }
436 printf("\n");
437 }
438#endif
439 return ret;
440 }
441 }
442 }
443 return USB_RET_NODEV;
444}
445
4d611c9a
PB
446static void uhci_async_complete_packet(USBPacket * packet, void *opaque);
447
bb36d470
FB
448/* return -1 if fatal error (frame must be stopped)
449 0 if TD successful
450 1 if TD unsuccessful or inactive
451*/
452static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
453{
454 uint8_t pid;
bb36d470
FB
455 int len, max_len, err, ret;
456
4d611c9a 457 /* ??? This is wrong for async completion. */
bb36d470
FB
458 if (td->ctrl & TD_CTRL_IOC) {
459 *int_mask |= 0x01;
460 }
5fafdf24 461
bb36d470
FB
462 if (!(td->ctrl & TD_CTRL_ACTIVE))
463 return 1;
464
465 /* TD is active */
466 max_len = ((td->token >> 21) + 1) & 0x7ff;
467 pid = td->token & 0xff;
4d611c9a
PB
468 if (s->async_qh) {
469 ret = s->usb_packet.len;
bb36d470
FB
470 if (ret >= 0) {
471 len = ret;
472 if (len > max_len) {
473 len = max_len;
474 ret = USB_RET_BABBLE;
475 }
476 if (len > 0) {
477 /* write the data back */
4d611c9a 478 cpu_physical_memory_write(td->buffer, s->usb_buf, len);
bb36d470
FB
479 }
480 } else {
481 len = 0;
482 }
4d611c9a
PB
483 s->async_qh = 0;
484 } else {
485 s->usb_packet.pid = pid;
486 s->usb_packet.devaddr = (td->token >> 8) & 0x7f;
487 s->usb_packet.devep = (td->token >> 15) & 0xf;
488 s->usb_packet.data = s->usb_buf;
489 s->usb_packet.len = max_len;
490 s->usb_packet.complete_cb = uhci_async_complete_packet;
491 s->usb_packet.complete_opaque = s;
492 switch(pid) {
493 case USB_TOKEN_OUT:
494 case USB_TOKEN_SETUP:
495 cpu_physical_memory_read(td->buffer, s->usb_buf, max_len);
496 ret = uhci_broadcast_packet(s, &s->usb_packet);
497 len = max_len;
498 break;
499 case USB_TOKEN_IN:
500 ret = uhci_broadcast_packet(s, &s->usb_packet);
501 if (ret >= 0) {
502 len = ret;
503 if (len > max_len) {
504 len = max_len;
505 ret = USB_RET_BABBLE;
506 }
507 if (len > 0) {
508 /* write the data back */
509 cpu_physical_memory_write(td->buffer, s->usb_buf, len);
510 }
511 } else {
512 len = 0;
513 }
514 break;
515 default:
516 /* invalid pid : frame interrupted */
517 s->status |= UHCI_STS_HCPERR;
518 uhci_update_irq(s);
519 return -1;
520 }
521 }
522 if (ret == USB_RET_ASYNC) {
523 return 2;
bb36d470
FB
524 }
525 if (td->ctrl & TD_CTRL_IOS)
526 td->ctrl &= ~TD_CTRL_ACTIVE;
527 if (ret >= 0) {
528 td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
117b3ae6
PB
529 /* The NAK bit may have been set by a previous frame, so clear it
530 here. The docs are somewhat unclear, but win2k relies on this
531 behavior. */
532 td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
5fafdf24 533 if (pid == USB_TOKEN_IN &&
bb36d470
FB
534 (td->ctrl & TD_CTRL_SPD) &&
535 len < max_len) {
536 *int_mask |= 0x02;
537 /* short packet: do not update QH */
538 return 1;
539 } else {
540 /* success */
541 return 0;
542 }
543 } else {
544 switch(ret) {
545 default:
546 case USB_RET_NODEV:
547 do_timeout:
548 td->ctrl |= TD_CTRL_TIMEOUT;
549 err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
550 if (err != 0) {
551 err--;
552 if (err == 0) {
553 td->ctrl &= ~TD_CTRL_ACTIVE;
554 s->status |= UHCI_STS_USBERR;
555 uhci_update_irq(s);
556 }
557 }
5fafdf24 558 td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
bb36d470
FB
559 (err << TD_CTRL_ERROR_SHIFT);
560 return 1;
561 case USB_RET_NAK:
562 td->ctrl |= TD_CTRL_NAK;
563 if (pid == USB_TOKEN_SETUP)
564 goto do_timeout;
565 return 1;
566 case USB_RET_STALL:
567 td->ctrl |= TD_CTRL_STALL;
568 td->ctrl &= ~TD_CTRL_ACTIVE;
569 return 1;
570 case USB_RET_BABBLE:
571 td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
572 td->ctrl &= ~TD_CTRL_ACTIVE;
573 /* frame interrupted */
574 return -1;
575 }
576 }
577}
578
4d611c9a
PB
579static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
580{
581 UHCIState *s = opaque;
582 UHCI_QH qh;
583 UHCI_TD td;
584 uint32_t link;
585 uint32_t old_td_ctrl;
586 uint32_t val;
587 int ret;
588
589 link = s->async_qh;
590 if (!link) {
591 /* This should never happen. It means a TD somehow got removed
592 without cancelling the associated async IO request. */
593 return;
594 }
595 cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
596 le32_to_cpus(&qh.link);
597 le32_to_cpus(&qh.el_link);
598 /* Re-process the queue containing the async packet. */
599 while (1) {
5fafdf24 600 cpu_physical_memory_read(qh.el_link & ~0xf,
4d611c9a
PB
601 (uint8_t *)&td, sizeof(td));
602 le32_to_cpus(&td.link);
603 le32_to_cpus(&td.ctrl);
604 le32_to_cpus(&td.token);
605 le32_to_cpus(&td.buffer);
606 old_td_ctrl = td.ctrl;
607 ret = uhci_handle_td(s, &td, &s->pending_int_mask);
608 /* update the status bits of the TD */
609 if (old_td_ctrl != td.ctrl) {
610 val = cpu_to_le32(td.ctrl);
5fafdf24
TS
611 cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
612 (const uint8_t *)&val,
4d611c9a
PB
613 sizeof(val));
614 }
615 if (ret < 0)
616 break; /* interrupted frame */
617 if (ret == 2) {
618 s->async_qh = link;
619 break;
620 } else if (ret == 0) {
621 /* update qh element link */
622 qh.el_link = td.link;
623 val = cpu_to_le32(qh.el_link);
5fafdf24
TS
624 cpu_physical_memory_write((link & ~0xf) + 4,
625 (const uint8_t *)&val,
4d611c9a
PB
626 sizeof(val));
627 if (!(qh.el_link & 4))
628 break;
629 }
630 break;
631 }
632}
633
bb36d470
FB
634static void uhci_frame_timer(void *opaque)
635{
636 UHCIState *s = opaque;
637 int64_t expire_time;
638 uint32_t frame_addr, link, old_td_ctrl, val;
639 int int_mask, cnt, ret;
640 UHCI_TD td;
641 UHCI_QH qh;
4d611c9a 642 uint32_t old_async_qh;
bb36d470
FB
643
644 if (!(s->cmd & UHCI_CMD_RS)) {
645 qemu_del_timer(s->frame_timer);
52328140
FB
646 /* set hchalted bit in status - UHCI11D 2.1.2 */
647 s->status |= UHCI_STS_HCHALTED;
bb36d470
FB
648 return;
649 }
4d611c9a
PB
650 /* Complete the previous frame. */
651 s->frnum = (s->frnum + 1) & 0x7ff;
652 if (s->pending_int_mask) {
653 s->status2 |= s->pending_int_mask;
654 s->status |= UHCI_STS_USBINT;
655 uhci_update_irq(s);
656 }
657 old_async_qh = s->async_qh;
bb36d470
FB
658 frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
659 cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
660 le32_to_cpus(&link);
661 int_mask = 0;
662 cnt = FRAME_MAX_LOOPS;
663 while ((link & 1) == 0) {
664 if (--cnt == 0)
665 break;
666 /* valid frame */
667 if (link & 2) {
668 /* QH */
4d611c9a
PB
669 if (link == s->async_qh) {
670 /* We've found a previously issues packet.
671 Nothing else to do. */
672 old_async_qh = 0;
673 break;
674 }
bb36d470
FB
675 cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
676 le32_to_cpus(&qh.link);
677 le32_to_cpus(&qh.el_link);
678 depth_first:
679 if (qh.el_link & 1) {
680 /* no element : go to next entry */
681 link = qh.link;
682 } else if (qh.el_link & 2) {
683 /* QH */
684 link = qh.el_link;
4d611c9a
PB
685 } else if (s->async_qh) {
686 /* We can only cope with one pending packet. Keep looking
687 for the previously issued packet. */
688 link = qh.link;
bb36d470
FB
689 } else {
690 /* TD */
691 if (--cnt == 0)
692 break;
5fafdf24 693 cpu_physical_memory_read(qh.el_link & ~0xf,
bb36d470
FB
694 (uint8_t *)&td, sizeof(td));
695 le32_to_cpus(&td.link);
696 le32_to_cpus(&td.ctrl);
697 le32_to_cpus(&td.token);
698 le32_to_cpus(&td.buffer);
699 old_td_ctrl = td.ctrl;
700 ret = uhci_handle_td(s, &td, &int_mask);
701 /* update the status bits of the TD */
702 if (old_td_ctrl != td.ctrl) {
703 val = cpu_to_le32(td.ctrl);
5fafdf24
TS
704 cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
705 (const uint8_t *)&val,
bb36d470
FB
706 sizeof(val));
707 }
708 if (ret < 0)
709 break; /* interrupted frame */
4d611c9a
PB
710 if (ret == 2) {
711 s->async_qh = link;
712 } else if (ret == 0) {
bb36d470
FB
713 /* update qh element link */
714 qh.el_link = td.link;
715 val = cpu_to_le32(qh.el_link);
5fafdf24
TS
716 cpu_physical_memory_write((link & ~0xf) + 4,
717 (const uint8_t *)&val,
bb36d470
FB
718 sizeof(val));
719 if (qh.el_link & 4) {
720 /* depth first */
721 goto depth_first;
722 }
723 }
724 /* go to next entry */
725 link = qh.link;
726 }
727 } else {
728 /* TD */
729 cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
730 le32_to_cpus(&td.link);
731 le32_to_cpus(&td.ctrl);
732 le32_to_cpus(&td.token);
733 le32_to_cpus(&td.buffer);
4d611c9a
PB
734 /* Ignore isochonous transfers while there is an async packet
735 pending. This is wrong, but we don't implement isochronous
736 transfers anyway. */
737 if (s->async_qh == 0) {
738 old_td_ctrl = td.ctrl;
739 ret = uhci_handle_td(s, &td, &int_mask);
740 /* update the status bits of the TD */
741 if (old_td_ctrl != td.ctrl) {
742 val = cpu_to_le32(td.ctrl);
5fafdf24
TS
743 cpu_physical_memory_write((link & ~0xf) + 4,
744 (const uint8_t *)&val,
4d611c9a
PB
745 sizeof(val));
746 }
747 if (ret < 0)
748 break; /* interrupted frame */
749 if (ret == 2) {
750 /* We can't handle async isochronous transfers.
751 Cancel The packet. */
752 fprintf(stderr, "usb-uhci: Unimplemented async packet\n");
753 usb_cancel_packet(&s->usb_packet);
754 }
bb36d470 755 }
bb36d470
FB
756 link = td.link;
757 }
758 }
4d611c9a
PB
759 s->pending_int_mask = int_mask;
760 if (old_async_qh) {
761 /* A previously started transfer has disappeared from the transfer
762 list. There's nothing useful we can do with it now, so just
763 discard the packet and hope it wasn't too important. */
764#ifdef DEBUG
765 printf("Discarding USB packet\n");
766#endif
767 usb_cancel_packet(&s->usb_packet);
768 s->async_qh = 0;
bb36d470
FB
769 }
770 /* prepare the timer for the next frame */
5fafdf24 771 expire_time = qemu_get_clock(vm_clock) +
bb36d470
FB
772 (ticks_per_sec / FRAME_TIMER_FREQ);
773 qemu_mod_timer(s->frame_timer, expire_time);
774}
775
5fafdf24 776static void uhci_map(PCIDevice *pci_dev, int region_num,
bb36d470
FB
777 uint32_t addr, uint32_t size, int type)
778{
779 UHCIState *s = (UHCIState *)pci_dev;
780
781 register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
782 register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
783 register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
784 register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
785 register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
786 register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
787}
788
afcc3cdf 789void usb_uhci_piix3_init(PCIBus *bus, int devfn)
bb36d470
FB
790{
791 UHCIState *s;
792 uint8_t *pci_conf;
bb36d470
FB
793 int i;
794
795 s = (UHCIState *)pci_register_device(bus,
796 "USB-UHCI", sizeof(UHCIState),
502a5395 797 devfn, NULL, NULL);
bb36d470
FB
798 pci_conf = s->dev.config;
799 pci_conf[0x00] = 0x86;
800 pci_conf[0x01] = 0x80;
801 pci_conf[0x02] = 0x20;
802 pci_conf[0x03] = 0x70;
803 pci_conf[0x08] = 0x01; // revision number
804 pci_conf[0x09] = 0x00;
805 pci_conf[0x0a] = 0x03;
806 pci_conf[0x0b] = 0x0c;
807 pci_conf[0x0e] = 0x00; // header_type
f04308e4 808 pci_conf[0x3d] = 4; // interrupt pin 3
38ca0f6d 809 pci_conf[0x60] = 0x10; // release number
5fafdf24 810
bb36d470 811 for(i = 0; i < NB_PORTS; i++) {
0d92ed30 812 qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
bb36d470
FB
813 }
814 s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
815
816 uhci_reset(s);
817
38ca0f6d
PB
818 /* Use region 4 for consistency with real hardware. BSD guests seem
819 to rely on this. */
5fafdf24 820 pci_register_io_region(&s->dev, 4, 0x20,
bb36d470
FB
821 PCI_ADDRESS_SPACE_IO, uhci_map);
822}
afcc3cdf
TS
823
824void usb_uhci_piix4_init(PCIBus *bus, int devfn)
825{
826 UHCIState *s;
827 uint8_t *pci_conf;
828 int i;
829
830 s = (UHCIState *)pci_register_device(bus,
831 "USB-UHCI", sizeof(UHCIState),
832 devfn, NULL, NULL);
833 pci_conf = s->dev.config;
834 pci_conf[0x00] = 0x86;
835 pci_conf[0x01] = 0x80;
836 pci_conf[0x02] = 0x12;
837 pci_conf[0x03] = 0x71;
838 pci_conf[0x08] = 0x01; // revision number
839 pci_conf[0x09] = 0x00;
840 pci_conf[0x0a] = 0x03;
841 pci_conf[0x0b] = 0x0c;
842 pci_conf[0x0e] = 0x00; // header_type
843 pci_conf[0x3d] = 4; // interrupt pin 3
844 pci_conf[0x60] = 0x10; // release number
845
846 for(i = 0; i < NB_PORTS; i++) {
847 qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
848 }
849 s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
850
851 uhci_reset(s);
852
853 /* Use region 4 for consistency with real hardware. BSD guests seem
854 to rely on this. */
855 pci_register_io_region(&s->dev, 4, 0x20,
856 PCI_ADDRESS_SPACE_IO, uhci_map);
857}
858