Statistics
| Branch: | Revision:

root / hw / usb-uhci.c @ 4d611c9a

History | View | Annotate | Download (23.7 kB)

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

    
63
typedef struct UHCIPort {
64
    USBPort port;
65
    uint16_t ctrl;
66
} UHCIPort;
67

    
68
typedef 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];
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;
90
    uint8_t usb_buf[1280];
91
} UHCIState;
92

    
93
typedef 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

    
100
typedef struct UHCI_QH {
101
    uint32_t link;
102
    uint32_t el_link;
103
} UHCI_QH;
104

    
105
static void uhci_attach(USBPort *port1, USBDevice *dev);
106

    
107
static 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
    }
120
    pci_set_irq(&s->dev, 3, level);
121
}
122

    
123
static 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;
142
        if (port->port.dev)
143
            uhci_attach(&port->port, port->port.dev);
144
    }
145
}
146

    
147
static 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

    
159
static 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;
168
        break;
169
    default:
170
        val = 0xff;
171
        break;
172
    }
173
    return val;
174
}
175

    
176
static 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));
189
            s->status &= ~UHCI_STS_HCHALTED;
190
        } else if (!(val & UHCI_CMD_RS)) {
191
            s->status |= UHCI_STS_HCHALTED;
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];
201
                dev = port->port.dev;
202
                if (dev) {
203
                    usb_send_msg(dev, USB_MSG_RESET);
204
                }
205
            }
206
            uhci_reset(s);
207
            return;
208
        }
209
        if (val & UHCI_CMD_HCRESET) {
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];
241
            dev = port->port.dev;
242
            if (dev) {
243
                /* port reset */
244
                if ( (val & UHCI_PORT_RESET) && 
245
                     !(port->ctrl & UHCI_PORT_RESET) ) {
246
                    usb_send_msg(dev, USB_MSG_RESET);
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

    
257
static 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

    
298
static 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

    
313
static 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

    
330
static void uhci_attach(USBPort *port1, USBDevice *dev)
331
{
332
    UHCIState *s = port1->opaque;
333
    UHCIPort *port = &s->ports[port1->index];
334

    
335
    if (dev) {
336
        if (port->port.dev) {
337
            usb_attach(port1, NULL);
338
        }
339
        /* set connect status */
340
        port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
341

    
342
        /* update speed */
343
        if (dev->speed == USB_SPEED_LOW)
344
            port->ctrl |= UHCI_PORT_LSDA;
345
        else
346
            port->ctrl &= ~UHCI_PORT_LSDA;
347
        port->port.dev = dev;
348
        /* send the attach message */
349
        usb_send_msg(dev, USB_MSG_ATTACH);
350
    } else {
351
        /* set connect status */
352
        if (port->ctrl & UHCI_PORT_CCS) {
353
            port->ctrl &= ~UHCI_PORT_CCS;
354
            port->ctrl |= UHCI_PORT_CSC;
355
        }
356
        /* disable port */
357
        if (port->ctrl & UHCI_PORT_EN) {
358
            port->ctrl &= ~UHCI_PORT_EN;
359
            port->ctrl |= UHCI_PORT_ENC;
360
        }
361
        dev = port->port.dev;
362
        if (dev) {
363
            /* send the detach message */
364
            usb_send_msg(dev, USB_MSG_DETACH);
365
        }
366
        port->port.dev = NULL;
367
    }
368
}
369

    
370
static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
371
{
372
    UHCIPort *port;
373
    USBDevice *dev;
374
    int i, ret;
375

    
376
#ifdef DEBUG_PACKET
377
    {
378
        const char *pidstr;
379
        switch(p->pid) {
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",
386
               s->frnum, pidstr, p->devaddr, p->devep, p->len);
387
        if (p->pid != USB_TOKEN_IN) {
388
            printf("     data_out=");
389
            for(i = 0; i < p->len; i++) {
390
                printf(" %02x", p->data[i]);
391
            }
392
            printf("\n");
393
        }
394
    }
395
#endif
396
    for(i = 0; i < NB_PORTS; i++) {
397
        port = &s->ports[i];
398
        dev = port->port.dev;
399
        if (dev && (port->ctrl & UHCI_PORT_EN)) {
400
            ret = dev->handle_packet(dev, p);
401
            if (ret != USB_RET_NODEV) {
402
#ifdef DEBUG_PACKET
403
                if (ret == USB_RET_ASYNC) {
404
                    printf("usb-uhci: Async packet\n");
405
                } else {
406
                    printf("     ret=%d ", ret);
407
                    if (p->pid == USB_TOKEN_IN && ret > 0) {
408
                        printf("data_in=");
409
                        for(i = 0; i < ret; i++) {
410
                            printf(" %02x", p->data[i]);
411
                        }
412
                    }
413
                    printf("\n");
414
                }
415
#endif
416
                return ret;
417
            }
418
        }
419
    }
420
    return USB_RET_NODEV;
421
}
422

    
423
static void uhci_async_complete_packet(USBPacket * packet, void *opaque);
424

    
425
/* return -1 if fatal error (frame must be stopped)
426
          0 if TD successful
427
          1 if TD unsuccessful or inactive
428
*/
429
static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
430
{
431
    uint8_t pid;
432
    int len, max_len, err, ret;
433

    
434
    /* ??? This is wrong for async completion.  */
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;
445
    if (s->async_qh) {
446
        ret = s->usb_packet.len;
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 */
455
                cpu_physical_memory_write(td->buffer, s->usb_buf, len);
456
            }
457
        } else {
458
            len = 0;
459
        }
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;
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

    
553
static 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

    
608
static 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;
616
    uint32_t old_async_qh;
617

    
618
    if (!(s->cmd & UHCI_CMD_RS)) {
619
        qemu_del_timer(s->frame_timer);
620
        /* set hchalted bit in status - UHCI11D 2.1.2 */
621
        s->status |= UHCI_STS_HCHALTED;
622
        return;
623
    }
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;
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 */
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
            }
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;
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;
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 */
684
                if (ret == 2) {
685
                    s->async_qh = link;
686
                } else if (ret == 0) {
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);
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
                }
729
            }
730
            link = td.link;
731
        }
732
    }
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;
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

    
750
static 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

    
763
void usb_uhci_init(PCIBus *bus, int devfn)
764
{
765
    UHCIState *s;
766
    uint8_t *pci_conf;
767
    int i;
768

    
769
    s = (UHCIState *)pci_register_device(bus,
770
                                        "USB-UHCI", sizeof(UHCIState),
771
                                        devfn, NULL, NULL);
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
782
    pci_conf[0x3d] = 4; // interrupt pin 3
783
    pci_conf[0x60] = 0x10; // release number
784
    
785
    for(i = 0; i < NB_PORTS; i++) {
786
        qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
787
    }
788
    s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
789

    
790
    uhci_reset(s);
791

    
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, 
795
                           PCI_ADDRESS_SPACE_IO, uhci_map);
796
}