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