Avoid signedness warnings
[qemu-kvm/fedora.git] / hw / usb-uhci.c
blobb55fd849aef58082423b9434321488d95af4b4eb
1 /*
2 * USB UHCI controller emulation
4 * Copyright (c) 2005 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
24 #include "hw.h"
25 #include "usb.h"
26 #include "pci.h"
27 #include "qemu-timer.h"
29 //#define DEBUG
30 //#define DEBUG_PACKET
31 //#define DEBUG_ISOCH
33 #define UHCI_CMD_FGR (1 << 4)
34 #define UHCI_CMD_EGSM (1 << 3)
35 #define UHCI_CMD_GRESET (1 << 2)
36 #define UHCI_CMD_HCRESET (1 << 1)
37 #define UHCI_CMD_RS (1 << 0)
39 #define UHCI_STS_HCHALTED (1 << 5)
40 #define UHCI_STS_HCPERR (1 << 4)
41 #define UHCI_STS_HSERR (1 << 3)
42 #define UHCI_STS_RD (1 << 2)
43 #define UHCI_STS_USBERR (1 << 1)
44 #define UHCI_STS_USBINT (1 << 0)
46 #define TD_CTRL_SPD (1 << 29)
47 #define TD_CTRL_ERROR_SHIFT 27
48 #define TD_CTRL_IOS (1 << 25)
49 #define TD_CTRL_IOC (1 << 24)
50 #define TD_CTRL_ACTIVE (1 << 23)
51 #define TD_CTRL_STALL (1 << 22)
52 #define TD_CTRL_BABBLE (1 << 20)
53 #define TD_CTRL_NAK (1 << 19)
54 #define TD_CTRL_TIMEOUT (1 << 18)
56 #define UHCI_PORT_RESET (1 << 9)
57 #define UHCI_PORT_LSDA (1 << 8)
58 #define UHCI_PORT_ENC (1 << 3)
59 #define UHCI_PORT_EN (1 << 2)
60 #define UHCI_PORT_CSC (1 << 1)
61 #define UHCI_PORT_CCS (1 << 0)
63 #define FRAME_TIMER_FREQ 1000
65 #define FRAME_MAX_LOOPS 100
67 #define NB_PORTS 2
69 typedef struct UHCIPort {
70 USBPort port;
71 uint16_t ctrl;
72 } UHCIPort;
74 typedef struct UHCIState {
75 PCIDevice dev;
76 uint16_t cmd; /* cmd register */
77 uint16_t status;
78 uint16_t intr; /* interrupt enable register */
79 uint16_t frnum; /* frame number */
80 uint32_t fl_base_addr; /* frame list base address */
81 uint8_t sof_timing;
82 uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
83 QEMUTimer *frame_timer;
84 UHCIPort ports[NB_PORTS];
86 /* Interrupts that should be raised at the end of the current frame. */
87 uint32_t pending_int_mask;
88 /* For simplicity of implementation we only allow a single pending USB
89 request. This means all usb traffic on this controller is effectively
90 suspended until that transfer completes. When the transfer completes
91 the next transfer from that queue will be processed. However
92 other queues will not be processed until the next frame. The solution
93 is to allow multiple pending requests. */
94 uint32_t async_qh;
95 uint32_t async_frame_addr;
96 USBPacket usb_packet;
97 uint8_t usb_buf[2048];
98 } UHCIState;
100 typedef struct UHCI_TD {
101 uint32_t link;
102 uint32_t ctrl; /* see TD_CTRL_xxx */
103 uint32_t token;
104 uint32_t buffer;
105 } UHCI_TD;
107 typedef struct UHCI_QH {
108 uint32_t link;
109 uint32_t el_link;
110 } UHCI_QH;
112 static void uhci_attach(USBPort *port1, USBDevice *dev);
114 static void uhci_update_irq(UHCIState *s)
116 int level;
117 if (((s->status2 & 1) && (s->intr & (1 << 2))) ||
118 ((s->status2 & 2) && (s->intr & (1 << 3))) ||
119 ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
120 ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
121 (s->status & UHCI_STS_HSERR) ||
122 (s->status & UHCI_STS_HCPERR)) {
123 level = 1;
124 } else {
125 level = 0;
127 qemu_set_irq(s->dev.irq[3], level);
130 static void uhci_reset(UHCIState *s)
132 uint8_t *pci_conf;
133 int i;
134 UHCIPort *port;
136 pci_conf = s->dev.config;
138 pci_conf[0x6a] = 0x01; /* usb clock */
139 pci_conf[0x6b] = 0x00;
140 s->cmd = 0;
141 s->status = 0;
142 s->status2 = 0;
143 s->intr = 0;
144 s->fl_base_addr = 0;
145 s->sof_timing = 64;
146 for(i = 0; i < NB_PORTS; i++) {
147 port = &s->ports[i];
148 port->ctrl = 0x0080;
149 if (port->port.dev)
150 uhci_attach(&port->port, port->port.dev);
154 #if 0
155 static void uhci_save(QEMUFile *f, void *opaque)
157 UHCIState *s = opaque;
158 uint8_t num_ports = NB_PORTS;
159 int i;
161 pci_device_save(&s->dev, f);
163 qemu_put_8s(f, &num_ports);
164 for (i = 0; i < num_ports; ++i)
165 qemu_put_be16s(f, &s->ports[i].ctrl);
166 qemu_put_be16s(f, &s->cmd);
167 qemu_put_be16s(f, &s->status);
168 qemu_put_be16s(f, &s->intr);
169 qemu_put_be16s(f, &s->frnum);
170 qemu_put_be32s(f, &s->fl_base_addr);
171 qemu_put_8s(f, &s->sof_timing);
172 qemu_put_8s(f, &s->status2);
173 qemu_put_timer(f, s->frame_timer);
176 static int uhci_load(QEMUFile *f, void *opaque, int version_id)
178 UHCIState *s = opaque;
179 uint8_t num_ports;
180 int i, ret;
182 if (version_id > 1)
183 return -EINVAL;
185 ret = pci_device_load(&s->dev, f);
186 if (ret < 0)
187 return ret;
189 qemu_get_8s(f, &num_ports);
190 if (num_ports != NB_PORTS)
191 return -EINVAL;
193 for (i = 0; i < num_ports; ++i)
194 qemu_get_be16s(f, &s->ports[i].ctrl);
195 qemu_get_be16s(f, &s->cmd);
196 qemu_get_be16s(f, &s->status);
197 qemu_get_be16s(f, &s->intr);
198 qemu_get_be16s(f, &s->frnum);
199 qemu_get_be32s(f, &s->fl_base_addr);
200 qemu_get_8s(f, &s->sof_timing);
201 qemu_get_8s(f, &s->status2);
202 qemu_get_timer(f, s->frame_timer);
204 return 0;
206 #endif
208 static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
210 UHCIState *s = opaque;
212 addr &= 0x1f;
213 switch(addr) {
214 case 0x0c:
215 s->sof_timing = val;
216 break;
220 static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
222 UHCIState *s = opaque;
223 uint32_t val;
225 addr &= 0x1f;
226 switch(addr) {
227 case 0x0c:
228 val = s->sof_timing;
229 break;
230 default:
231 val = 0xff;
232 break;
234 return val;
237 static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
239 UHCIState *s = opaque;
241 addr &= 0x1f;
242 #ifdef DEBUG
243 printf("uhci writew port=0x%04x val=0x%04x\n", addr, val);
244 #endif
245 switch(addr) {
246 case 0x00:
247 if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
248 /* start frame processing */
249 qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
250 s->status &= ~UHCI_STS_HCHALTED;
251 } else if (!(val & UHCI_CMD_RS)) {
252 s->status |= UHCI_STS_HCHALTED;
254 if (val & UHCI_CMD_GRESET) {
255 UHCIPort *port;
256 USBDevice *dev;
257 int i;
259 /* send reset on the USB bus */
260 for(i = 0; i < NB_PORTS; i++) {
261 port = &s->ports[i];
262 dev = port->port.dev;
263 if (dev) {
264 usb_send_msg(dev, USB_MSG_RESET);
267 uhci_reset(s);
268 return;
270 if (val & UHCI_CMD_HCRESET) {
271 uhci_reset(s);
272 return;
274 s->cmd = val;
275 break;
276 case 0x02:
277 s->status &= ~val;
278 /* XXX: the chip spec is not coherent, so we add a hidden
279 register to distinguish between IOC and SPD */
280 if (val & UHCI_STS_USBINT)
281 s->status2 = 0;
282 uhci_update_irq(s);
283 break;
284 case 0x04:
285 s->intr = val;
286 uhci_update_irq(s);
287 break;
288 case 0x06:
289 if (s->status & UHCI_STS_HCHALTED)
290 s->frnum = val & 0x7ff;
291 break;
292 case 0x10 ... 0x1f:
294 UHCIPort *port;
295 USBDevice *dev;
296 int n;
298 n = (addr >> 1) & 7;
299 if (n >= NB_PORTS)
300 return;
301 port = &s->ports[n];
302 dev = port->port.dev;
303 if (dev) {
304 /* port reset */
305 if ( (val & UHCI_PORT_RESET) &&
306 !(port->ctrl & UHCI_PORT_RESET) ) {
307 usb_send_msg(dev, USB_MSG_RESET);
310 port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
311 /* some bits are reset when a '1' is written to them */
312 port->ctrl &= ~(val & 0x000a);
314 break;
318 static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
320 UHCIState *s = opaque;
321 uint32_t val;
323 addr &= 0x1f;
324 switch(addr) {
325 case 0x00:
326 val = s->cmd;
327 break;
328 case 0x02:
329 val = s->status;
330 break;
331 case 0x04:
332 val = s->intr;
333 break;
334 case 0x06:
335 val = s->frnum;
336 break;
337 case 0x10 ... 0x1f:
339 UHCIPort *port;
340 int n;
341 n = (addr >> 1) & 7;
342 if (n >= NB_PORTS)
343 goto read_default;
344 port = &s->ports[n];
345 val = port->ctrl;
347 break;
348 default:
349 read_default:
350 val = 0xff7f; /* disabled port */
351 break;
353 #ifdef DEBUG
354 printf("uhci readw port=0x%04x val=0x%04x\n", addr, val);
355 #endif
356 return val;
359 static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
361 UHCIState *s = opaque;
363 addr &= 0x1f;
364 #ifdef DEBUG
365 printf("uhci writel port=0x%04x val=0x%08x\n", addr, val);
366 #endif
367 switch(addr) {
368 case 0x08:
369 s->fl_base_addr = val & ~0xfff;
370 break;
374 static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
376 UHCIState *s = opaque;
377 uint32_t val;
379 addr &= 0x1f;
380 switch(addr) {
381 case 0x08:
382 val = s->fl_base_addr;
383 break;
384 default:
385 val = 0xffffffff;
386 break;
388 return val;
391 /* signal resume if controller suspended */
392 static void uhci_resume (void *opaque)
394 UHCIState *s = (UHCIState *)opaque;
396 if (!s)
397 return;
399 if (s->cmd & UHCI_CMD_EGSM) {
400 s->cmd |= UHCI_CMD_FGR;
401 s->status |= UHCI_STS_RD;
402 uhci_update_irq(s);
406 static void uhci_attach(USBPort *port1, USBDevice *dev)
408 UHCIState *s = port1->opaque;
409 UHCIPort *port = &s->ports[port1->index];
411 if (dev) {
412 if (port->port.dev) {
413 usb_attach(port1, NULL);
415 /* set connect status */
416 port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
418 /* update speed */
419 if (dev->speed == USB_SPEED_LOW)
420 port->ctrl |= UHCI_PORT_LSDA;
421 else
422 port->ctrl &= ~UHCI_PORT_LSDA;
424 uhci_resume(s);
426 port->port.dev = dev;
427 /* send the attach message */
428 usb_send_msg(dev, USB_MSG_ATTACH);
429 } else {
430 /* set connect status */
431 if (port->ctrl & UHCI_PORT_CCS) {
432 port->ctrl &= ~UHCI_PORT_CCS;
433 port->ctrl |= UHCI_PORT_CSC;
435 /* disable port */
436 if (port->ctrl & UHCI_PORT_EN) {
437 port->ctrl &= ~UHCI_PORT_EN;
438 port->ctrl |= UHCI_PORT_ENC;
441 uhci_resume(s);
443 dev = port->port.dev;
444 if (dev) {
445 /* send the detach message */
446 usb_send_msg(dev, USB_MSG_DETACH);
448 port->port.dev = NULL;
452 static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
454 UHCIPort *port;
455 USBDevice *dev;
456 int i, ret;
458 #ifdef DEBUG_PACKET
460 const char *pidstr;
461 switch(p->pid) {
462 case USB_TOKEN_SETUP: pidstr = "SETUP"; break;
463 case USB_TOKEN_IN: pidstr = "IN"; break;
464 case USB_TOKEN_OUT: pidstr = "OUT"; break;
465 default: pidstr = "?"; break;
467 printf("frame %d: pid=%s addr=0x%02x ep=%d len=%d\n",
468 s->frnum, pidstr, p->devaddr, p->devep, p->len);
469 if (p->pid != USB_TOKEN_IN) {
470 printf(" data_out=");
471 for(i = 0; i < p->len; i++) {
472 printf(" %02x", p->data[i]);
474 printf("\n");
477 #endif
478 for(i = 0; i < NB_PORTS; i++) {
479 port = &s->ports[i];
480 dev = port->port.dev;
481 if (dev && (port->ctrl & UHCI_PORT_EN)) {
482 ret = dev->handle_packet(dev, p);
483 if (ret != USB_RET_NODEV) {
484 #ifdef DEBUG_PACKET
485 if (ret == USB_RET_ASYNC) {
486 printf("usb-uhci: Async packet\n");
487 } else {
488 printf(" ret=%d ", ret);
489 if (p->pid == USB_TOKEN_IN && ret > 0) {
490 printf("data_in=");
491 for(i = 0; i < ret; i++) {
492 printf(" %02x", p->data[i]);
495 printf("\n");
497 #endif
498 return ret;
502 return USB_RET_NODEV;
505 static void uhci_async_complete_packet(USBPacket * packet, void *opaque);
507 /* return -1 if fatal error (frame must be stopped)
508 0 if TD successful
509 1 if TD unsuccessful or inactive
511 static int uhci_handle_td(UHCIState *s, UHCI_TD *td, uint32_t *int_mask,
512 int completion)
514 uint8_t pid;
515 int len = 0, max_len, err, ret = 0;
517 /* ??? This is wrong for async completion. */
518 if (td->ctrl & TD_CTRL_IOC) {
519 *int_mask |= 0x01;
522 if (!(td->ctrl & TD_CTRL_ACTIVE))
523 return 1;
525 /* TD is active */
526 max_len = ((td->token >> 21) + 1) & 0x7ff;
527 pid = td->token & 0xff;
529 if (completion && (s->async_qh || s->async_frame_addr)) {
530 ret = s->usb_packet.len;
531 if (ret >= 0) {
532 len = ret;
533 if (len > max_len) {
534 len = max_len;
535 ret = USB_RET_BABBLE;
537 if (len > 0) {
538 /* write the data back */
539 cpu_physical_memory_write(td->buffer, s->usb_buf, len);
541 } else {
542 len = 0;
544 s->async_qh = 0;
545 s->async_frame_addr = 0;
546 } else if (!completion) {
547 s->usb_packet.pid = pid;
548 s->usb_packet.devaddr = (td->token >> 8) & 0x7f;
549 s->usb_packet.devep = (td->token >> 15) & 0xf;
550 s->usb_packet.data = s->usb_buf;
551 s->usb_packet.len = max_len;
552 s->usb_packet.complete_cb = uhci_async_complete_packet;
553 s->usb_packet.complete_opaque = s;
554 switch(pid) {
555 case USB_TOKEN_OUT:
556 case USB_TOKEN_SETUP:
557 cpu_physical_memory_read(td->buffer, s->usb_buf, max_len);
558 ret = uhci_broadcast_packet(s, &s->usb_packet);
559 len = max_len;
560 break;
561 case USB_TOKEN_IN:
562 ret = uhci_broadcast_packet(s, &s->usb_packet);
563 if (ret >= 0) {
564 len = ret;
565 if (len > max_len) {
566 len = max_len;
567 ret = USB_RET_BABBLE;
569 if (len > 0) {
570 /* write the data back */
571 cpu_physical_memory_write(td->buffer, s->usb_buf, len);
573 } else {
574 len = 0;
576 break;
577 default:
578 /* invalid pid : frame interrupted */
579 s->status |= UHCI_STS_HCPERR;
580 uhci_update_irq(s);
581 return -1;
585 if (ret == USB_RET_ASYNC) {
586 return 2;
588 if (td->ctrl & TD_CTRL_IOS)
589 td->ctrl &= ~TD_CTRL_ACTIVE;
590 if (ret >= 0) {
591 td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
592 /* The NAK bit may have been set by a previous frame, so clear it
593 here. The docs are somewhat unclear, but win2k relies on this
594 behavior. */
595 td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
596 if (pid == USB_TOKEN_IN &&
597 (td->ctrl & TD_CTRL_SPD) &&
598 len < max_len) {
599 *int_mask |= 0x02;
600 /* short packet: do not update QH */
601 return 1;
602 } else {
603 /* success */
604 return 0;
606 } else {
607 switch(ret) {
608 default:
609 case USB_RET_NODEV:
610 do_timeout:
611 td->ctrl |= TD_CTRL_TIMEOUT;
612 err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
613 if (err != 0) {
614 err--;
615 if (err == 0) {
616 td->ctrl &= ~TD_CTRL_ACTIVE;
617 s->status |= UHCI_STS_USBERR;
618 uhci_update_irq(s);
621 td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
622 (err << TD_CTRL_ERROR_SHIFT);
623 return 1;
624 case USB_RET_NAK:
625 td->ctrl |= TD_CTRL_NAK;
626 if (pid == USB_TOKEN_SETUP)
627 goto do_timeout;
628 return 1;
629 case USB_RET_STALL:
630 td->ctrl |= TD_CTRL_STALL;
631 td->ctrl &= ~TD_CTRL_ACTIVE;
632 return 1;
633 case USB_RET_BABBLE:
634 td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
635 td->ctrl &= ~TD_CTRL_ACTIVE;
636 /* frame interrupted */
637 return -1;
642 static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
644 UHCIState *s = opaque;
645 UHCI_QH qh;
646 UHCI_TD td;
647 uint32_t link;
648 uint32_t old_td_ctrl;
649 uint32_t val;
650 uint32_t frame_addr;
651 int ret;
653 /* Handle async isochronous packet completion */
654 frame_addr = s->async_frame_addr;
655 if (frame_addr) {
656 cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
657 le32_to_cpus(&link);
659 cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
660 le32_to_cpus(&td.link);
661 le32_to_cpus(&td.ctrl);
662 le32_to_cpus(&td.token);
663 le32_to_cpus(&td.buffer);
664 old_td_ctrl = td.ctrl;
665 ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
667 /* update the status bits of the TD */
668 if (old_td_ctrl != td.ctrl) {
669 val = cpu_to_le32(td.ctrl);
670 cpu_physical_memory_write((link & ~0xf) + 4,
671 (const uint8_t *)&val,
672 sizeof(val));
674 if (ret == 2) {
675 s->async_frame_addr = frame_addr;
676 } else if (ret == 0) {
677 /* update qh element link */
678 val = cpu_to_le32(td.link);
679 cpu_physical_memory_write(frame_addr,
680 (const uint8_t *)&val,
681 sizeof(val));
683 return;
686 link = s->async_qh;
687 if (!link) {
688 /* This should never happen. It means a TD somehow got removed
689 without cancelling the associated async IO request. */
690 return;
692 cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
693 le32_to_cpus(&qh.link);
694 le32_to_cpus(&qh.el_link);
695 /* Re-process the queue containing the async packet. */
696 while (1) {
697 cpu_physical_memory_read(qh.el_link & ~0xf,
698 (uint8_t *)&td, sizeof(td));
699 le32_to_cpus(&td.link);
700 le32_to_cpus(&td.ctrl);
701 le32_to_cpus(&td.token);
702 le32_to_cpus(&td.buffer);
703 old_td_ctrl = td.ctrl;
704 ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
706 /* update the status bits of the TD */
707 if (old_td_ctrl != td.ctrl) {
708 val = cpu_to_le32(td.ctrl);
709 cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
710 (const uint8_t *)&val,
711 sizeof(val));
713 if (ret < 0)
714 break; /* interrupted frame */
715 if (ret == 2) {
716 s->async_qh = link;
717 break;
718 } else if (ret == 0) {
719 /* update qh element link */
720 qh.el_link = td.link;
721 val = cpu_to_le32(qh.el_link);
722 cpu_physical_memory_write((link & ~0xf) + 4,
723 (const uint8_t *)&val,
724 sizeof(val));
725 if (!(qh.el_link & 4))
726 break;
728 break;
732 static void uhci_frame_timer(void *opaque)
734 UHCIState *s = opaque;
735 int64_t expire_time;
736 uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
737 int cnt, ret;
738 UHCI_TD td;
739 UHCI_QH qh;
740 uint32_t old_async_qh;
742 if (!(s->cmd & UHCI_CMD_RS)) {
743 qemu_del_timer(s->frame_timer);
744 /* set hchalted bit in status - UHCI11D 2.1.2 */
745 s->status |= UHCI_STS_HCHALTED;
746 return;
748 /* Complete the previous frame. */
749 s->frnum = (s->frnum + 1) & 0x7ff;
750 if (s->pending_int_mask) {
751 s->status2 |= s->pending_int_mask;
752 s->status |= UHCI_STS_USBINT;
753 uhci_update_irq(s);
755 old_async_qh = s->async_qh;
756 frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
757 cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
758 le32_to_cpus(&link);
759 int_mask = 0;
760 cnt = FRAME_MAX_LOOPS;
761 while ((link & 1) == 0) {
762 if (--cnt == 0)
763 break;
764 /* valid frame */
765 if (link & 2) {
766 /* QH */
767 if (link == s->async_qh) {
768 /* We've found a previously issues packet.
769 Nothing else to do. */
770 old_async_qh = 0;
771 break;
773 cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
774 le32_to_cpus(&qh.link);
775 le32_to_cpus(&qh.el_link);
776 depth_first:
777 if (qh.el_link & 1) {
778 /* no element : go to next entry */
779 link = qh.link;
780 } else if (qh.el_link & 2) {
781 /* QH */
782 link = qh.el_link;
783 } else if (s->async_qh) {
784 /* We can only cope with one pending packet. Keep looking
785 for the previously issued packet. */
786 link = qh.link;
787 } else {
788 /* TD */
789 if (--cnt == 0)
790 break;
791 cpu_physical_memory_read(qh.el_link & ~0xf,
792 (uint8_t *)&td, sizeof(td));
793 le32_to_cpus(&td.link);
794 le32_to_cpus(&td.ctrl);
795 le32_to_cpus(&td.token);
796 le32_to_cpus(&td.buffer);
797 old_td_ctrl = td.ctrl;
798 ret = uhci_handle_td(s, &td, &int_mask, 0);
800 /* update the status bits of the TD */
801 if (old_td_ctrl != td.ctrl) {
802 val = cpu_to_le32(td.ctrl);
803 cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
804 (const uint8_t *)&val,
805 sizeof(val));
807 if (ret < 0)
808 break; /* interrupted frame */
809 if (ret == 2) {
810 s->async_qh = link;
811 } else if (ret == 0) {
812 /* update qh element link */
813 qh.el_link = td.link;
814 val = cpu_to_le32(qh.el_link);
815 cpu_physical_memory_write((link & ~0xf) + 4,
816 (const uint8_t *)&val,
817 sizeof(val));
818 if (qh.el_link & 4) {
819 /* depth first */
820 goto depth_first;
823 /* go to next entry */
824 link = qh.link;
826 } else {
827 /* TD */
828 cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
829 le32_to_cpus(&td.link);
830 le32_to_cpus(&td.ctrl);
831 le32_to_cpus(&td.token);
832 le32_to_cpus(&td.buffer);
834 /* Handle isochonous transfer. */
835 /* FIXME: might be more than one isoc in frame */
836 old_td_ctrl = td.ctrl;
837 ret = uhci_handle_td(s, &td, &int_mask, 0);
839 /* update the status bits of the TD */
840 if (old_td_ctrl != td.ctrl) {
841 val = cpu_to_le32(td.ctrl);
842 cpu_physical_memory_write((link & ~0xf) + 4,
843 (const uint8_t *)&val,
844 sizeof(val));
846 if (ret < 0)
847 break; /* interrupted frame */
848 if (ret == 2) {
849 s->async_frame_addr = frame_addr;
851 link = td.link;
854 s->pending_int_mask = int_mask;
855 if (old_async_qh) {
856 /* A previously started transfer has disappeared from the transfer
857 list. There's nothing useful we can do with it now, so just
858 discard the packet and hope it wasn't too important. */
859 #ifdef DEBUG
860 printf("Discarding USB packet\n");
861 #endif
862 usb_cancel_packet(&s->usb_packet);
863 s->async_qh = 0;
866 /* prepare the timer for the next frame */
867 expire_time = qemu_get_clock(vm_clock) +
868 (ticks_per_sec / FRAME_TIMER_FREQ);
869 qemu_mod_timer(s->frame_timer, expire_time);
872 static void uhci_map(PCIDevice *pci_dev, int region_num,
873 uint32_t addr, uint32_t size, int type)
875 UHCIState *s = (UHCIState *)pci_dev;
877 register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
878 register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
879 register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
880 register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
881 register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
882 register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
885 void usb_uhci_piix3_init(PCIBus *bus, int devfn)
887 UHCIState *s;
888 uint8_t *pci_conf;
889 int i;
891 s = (UHCIState *)pci_register_device(bus,
892 "USB-UHCI", sizeof(UHCIState),
893 devfn, NULL, NULL);
894 pci_conf = s->dev.config;
895 pci_conf[0x00] = 0x86;
896 pci_conf[0x01] = 0x80;
897 pci_conf[0x02] = 0x20;
898 pci_conf[0x03] = 0x70;
899 pci_conf[0x08] = 0x01; // revision number
900 pci_conf[0x09] = 0x00;
901 pci_conf[0x0a] = 0x03;
902 pci_conf[0x0b] = 0x0c;
903 pci_conf[0x0e] = 0x00; // header_type
904 pci_conf[0x3d] = 4; // interrupt pin 3
905 pci_conf[0x60] = 0x10; // release number
907 for(i = 0; i < NB_PORTS; i++) {
908 qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
910 s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
912 uhci_reset(s);
914 /* Use region 4 for consistency with real hardware. BSD guests seem
915 to rely on this. */
916 pci_register_io_region(&s->dev, 4, 0x20,
917 PCI_ADDRESS_SPACE_IO, uhci_map);
920 void usb_uhci_piix4_init(PCIBus *bus, int devfn)
922 UHCIState *s;
923 uint8_t *pci_conf;
924 int i;
926 s = (UHCIState *)pci_register_device(bus,
927 "USB-UHCI", sizeof(UHCIState),
928 devfn, NULL, NULL);
929 pci_conf = s->dev.config;
930 pci_conf[0x00] = 0x86;
931 pci_conf[0x01] = 0x80;
932 pci_conf[0x02] = 0x12;
933 pci_conf[0x03] = 0x71;
934 pci_conf[0x08] = 0x01; // revision number
935 pci_conf[0x09] = 0x00;
936 pci_conf[0x0a] = 0x03;
937 pci_conf[0x0b] = 0x0c;
938 pci_conf[0x0e] = 0x00; // header_type
939 pci_conf[0x3d] = 4; // interrupt pin 3
940 pci_conf[0x60] = 0x10; // release number
942 for(i = 0; i < NB_PORTS; i++) {
943 qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
945 s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
947 uhci_reset(s);
949 /* Use region 4 for consistency with real hardware. BSD guests seem
950 to rely on this. */
951 pci_register_io_region(&s->dev, 4, 0x20,
952 PCI_ADDRESS_SPACE_IO, uhci_map);