Statistics
| Branch: | Revision:

root / hw / usb-uhci.c @ 66450b15

History | View | Annotate | Download (27.6 kB)

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