Statistics
| Branch: | Revision:

root / hw / usb-uhci.c @ 1e414679

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 1e414679 bellard
#if 0
152 b9dc033c balrog
static void uhci_save(QEMUFile *f, void *opaque)
153 b9dc033c balrog
{
154 b9dc033c balrog
    UHCIState *s = opaque;
155 b9dc033c balrog
    uint8_t num_ports = NB_PORTS;
156 b9dc033c balrog
    int i;
157 b9dc033c balrog

158 b9dc033c balrog
    pci_device_save(&s->dev, f);
159 b9dc033c balrog

160 b9dc033c balrog
    qemu_put_8s(f, &num_ports);
161 b9dc033c balrog
    for (i = 0; i < num_ports; ++i)
162 b9dc033c balrog
        qemu_put_be16s(f, &s->ports[i].ctrl);
163 b9dc033c balrog
    qemu_put_be16s(f, &s->cmd);
164 b9dc033c balrog
    qemu_put_be16s(f, &s->status);
165 b9dc033c balrog
    qemu_put_be16s(f, &s->intr);
166 b9dc033c balrog
    qemu_put_be16s(f, &s->frnum);
167 b9dc033c balrog
    qemu_put_be32s(f, &s->fl_base_addr);
168 b9dc033c balrog
    qemu_put_8s(f, &s->sof_timing);
169 b9dc033c balrog
    qemu_put_8s(f, &s->status2);
170 b9dc033c balrog
    qemu_put_timer(f, s->frame_timer);
171 b9dc033c balrog
}
172 b9dc033c balrog

173 b9dc033c balrog
static int uhci_load(QEMUFile *f, void *opaque, int version_id)
174 b9dc033c balrog
{
175 b9dc033c balrog
    UHCIState *s = opaque;
176 b9dc033c balrog
    uint8_t num_ports;
177 b9dc033c balrog
    int i, ret;
178 b9dc033c balrog

179 b9dc033c balrog
    if (version_id > 1)
180 b9dc033c balrog
        return -EINVAL;
181 b9dc033c balrog

182 b9dc033c balrog
    ret = pci_device_load(&s->dev, f);
183 b9dc033c balrog
    if (ret < 0)
184 b9dc033c balrog
        return ret;
185 b9dc033c balrog

186 b9dc033c balrog
    qemu_get_8s(f, &num_ports);
187 b9dc033c balrog
    if (num_ports != NB_PORTS)
188 b9dc033c balrog
        return -EINVAL;
189 b9dc033c balrog

190 b9dc033c balrog
    for (i = 0; i < num_ports; ++i)
191 b9dc033c balrog
        qemu_get_be16s(f, &s->ports[i].ctrl);
192 b9dc033c balrog
    qemu_get_be16s(f, &s->cmd);
193 b9dc033c balrog
    qemu_get_be16s(f, &s->status);
194 b9dc033c balrog
    qemu_get_be16s(f, &s->intr);
195 b9dc033c balrog
    qemu_get_be16s(f, &s->frnum);
196 b9dc033c balrog
    qemu_get_be32s(f, &s->fl_base_addr);
197 b9dc033c balrog
    qemu_get_8s(f, &s->sof_timing);
198 b9dc033c balrog
    qemu_get_8s(f, &s->status2);
199 b9dc033c balrog
    qemu_get_timer(f, s->frame_timer);
200 b9dc033c balrog

201 b9dc033c balrog
    return 0;
202 b9dc033c balrog
}
203 1e414679 bellard
#endif
204 b9dc033c balrog
205 bb36d470 bellard
static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
206 bb36d470 bellard
{
207 bb36d470 bellard
    UHCIState *s = opaque;
208 3b46e624 ths
209 bb36d470 bellard
    addr &= 0x1f;
210 bb36d470 bellard
    switch(addr) {
211 bb36d470 bellard
    case 0x0c:
212 bb36d470 bellard
        s->sof_timing = val;
213 bb36d470 bellard
        break;
214 bb36d470 bellard
    }
215 bb36d470 bellard
}
216 bb36d470 bellard
217 bb36d470 bellard
static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
218 bb36d470 bellard
{
219 bb36d470 bellard
    UHCIState *s = opaque;
220 bb36d470 bellard
    uint32_t val;
221 bb36d470 bellard
222 bb36d470 bellard
    addr &= 0x1f;
223 bb36d470 bellard
    switch(addr) {
224 bb36d470 bellard
    case 0x0c:
225 bb36d470 bellard
        val = s->sof_timing;
226 d80cfb3f pbrook
        break;
227 bb36d470 bellard
    default:
228 bb36d470 bellard
        val = 0xff;
229 bb36d470 bellard
        break;
230 bb36d470 bellard
    }
231 bb36d470 bellard
    return val;
232 bb36d470 bellard
}
233 bb36d470 bellard
234 bb36d470 bellard
static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
235 bb36d470 bellard
{
236 bb36d470 bellard
    UHCIState *s = opaque;
237 3b46e624 ths
238 bb36d470 bellard
    addr &= 0x1f;
239 bb36d470 bellard
#ifdef DEBUG
240 bb36d470 bellard
    printf("uhci writew port=0x%04x val=0x%04x\n", addr, val);
241 bb36d470 bellard
#endif
242 bb36d470 bellard
    switch(addr) {
243 bb36d470 bellard
    case 0x00:
244 bb36d470 bellard
        if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
245 bb36d470 bellard
            /* start frame processing */
246 bb36d470 bellard
            qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
247 52328140 bellard
            s->status &= ~UHCI_STS_HCHALTED;
248 467d409f bellard
        } else if (!(val & UHCI_CMD_RS)) {
249 52328140 bellard
            s->status |= UHCI_STS_HCHALTED;
250 bb36d470 bellard
        }
251 bb36d470 bellard
        if (val & UHCI_CMD_GRESET) {
252 bb36d470 bellard
            UHCIPort *port;
253 bb36d470 bellard
            USBDevice *dev;
254 bb36d470 bellard
            int i;
255 bb36d470 bellard
256 bb36d470 bellard
            /* send reset on the USB bus */
257 bb36d470 bellard
            for(i = 0; i < NB_PORTS; i++) {
258 bb36d470 bellard
                port = &s->ports[i];
259 a594cfbf bellard
                dev = port->port.dev;
260 bb36d470 bellard
                if (dev) {
261 4d611c9a pbrook
                    usb_send_msg(dev, USB_MSG_RESET);
262 bb36d470 bellard
                }
263 bb36d470 bellard
            }
264 bb36d470 bellard
            uhci_reset(s);
265 bb36d470 bellard
            return;
266 bb36d470 bellard
        }
267 5e9ab4c4 bellard
        if (val & UHCI_CMD_HCRESET) {
268 bb36d470 bellard
            uhci_reset(s);
269 bb36d470 bellard
            return;
270 bb36d470 bellard
        }
271 bb36d470 bellard
        s->cmd = val;
272 bb36d470 bellard
        break;
273 bb36d470 bellard
    case 0x02:
274 bb36d470 bellard
        s->status &= ~val;
275 bb36d470 bellard
        /* XXX: the chip spec is not coherent, so we add a hidden
276 bb36d470 bellard
           register to distinguish between IOC and SPD */
277 bb36d470 bellard
        if (val & UHCI_STS_USBINT)
278 bb36d470 bellard
            s->status2 = 0;
279 bb36d470 bellard
        uhci_update_irq(s);
280 bb36d470 bellard
        break;
281 bb36d470 bellard
    case 0x04:
282 bb36d470 bellard
        s->intr = val;
283 bb36d470 bellard
        uhci_update_irq(s);
284 bb36d470 bellard
        break;
285 bb36d470 bellard
    case 0x06:
286 bb36d470 bellard
        if (s->status & UHCI_STS_HCHALTED)
287 bb36d470 bellard
            s->frnum = val & 0x7ff;
288 bb36d470 bellard
        break;
289 bb36d470 bellard
    case 0x10 ... 0x1f:
290 bb36d470 bellard
        {
291 bb36d470 bellard
            UHCIPort *port;
292 bb36d470 bellard
            USBDevice *dev;
293 bb36d470 bellard
            int n;
294 bb36d470 bellard
295 bb36d470 bellard
            n = (addr >> 1) & 7;
296 bb36d470 bellard
            if (n >= NB_PORTS)
297 bb36d470 bellard
                return;
298 bb36d470 bellard
            port = &s->ports[n];
299 a594cfbf bellard
            dev = port->port.dev;
300 bb36d470 bellard
            if (dev) {
301 bb36d470 bellard
                /* port reset */
302 5fafdf24 ths
                if ( (val & UHCI_PORT_RESET) &&
303 bb36d470 bellard
                     !(port->ctrl & UHCI_PORT_RESET) ) {
304 4d611c9a pbrook
                    usb_send_msg(dev, USB_MSG_RESET);
305 bb36d470 bellard
                }
306 bb36d470 bellard
            }
307 bb36d470 bellard
            port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
308 bb36d470 bellard
            /* some bits are reset when a '1' is written to them */
309 bb36d470 bellard
            port->ctrl &= ~(val & 0x000a);
310 bb36d470 bellard
        }
311 bb36d470 bellard
        break;
312 bb36d470 bellard
    }
313 bb36d470 bellard
}
314 bb36d470 bellard
315 bb36d470 bellard
static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
316 bb36d470 bellard
{
317 bb36d470 bellard
    UHCIState *s = opaque;
318 bb36d470 bellard
    uint32_t val;
319 bb36d470 bellard
320 bb36d470 bellard
    addr &= 0x1f;
321 bb36d470 bellard
    switch(addr) {
322 bb36d470 bellard
    case 0x00:
323 bb36d470 bellard
        val = s->cmd;
324 bb36d470 bellard
        break;
325 bb36d470 bellard
    case 0x02:
326 bb36d470 bellard
        val = s->status;
327 bb36d470 bellard
        break;
328 bb36d470 bellard
    case 0x04:
329 bb36d470 bellard
        val = s->intr;
330 bb36d470 bellard
        break;
331 bb36d470 bellard
    case 0x06:
332 bb36d470 bellard
        val = s->frnum;
333 bb36d470 bellard
        break;
334 bb36d470 bellard
    case 0x10 ... 0x1f:
335 bb36d470 bellard
        {
336 bb36d470 bellard
            UHCIPort *port;
337 bb36d470 bellard
            int n;
338 bb36d470 bellard
            n = (addr >> 1) & 7;
339 5fafdf24 ths
            if (n >= NB_PORTS)
340 bb36d470 bellard
                goto read_default;
341 bb36d470 bellard
            port = &s->ports[n];
342 bb36d470 bellard
            val = port->ctrl;
343 bb36d470 bellard
        }
344 bb36d470 bellard
        break;
345 bb36d470 bellard
    default:
346 bb36d470 bellard
    read_default:
347 bb36d470 bellard
        val = 0xff7f; /* disabled port */
348 bb36d470 bellard
        break;
349 bb36d470 bellard
    }
350 bb36d470 bellard
#ifdef DEBUG
351 bb36d470 bellard
    printf("uhci readw port=0x%04x val=0x%04x\n", addr, val);
352 bb36d470 bellard
#endif
353 bb36d470 bellard
    return val;
354 bb36d470 bellard
}
355 bb36d470 bellard
356 bb36d470 bellard
static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
357 bb36d470 bellard
{
358 bb36d470 bellard
    UHCIState *s = opaque;
359 bb36d470 bellard
360 bb36d470 bellard
    addr &= 0x1f;
361 bb36d470 bellard
#ifdef DEBUG
362 bb36d470 bellard
    printf("uhci writel port=0x%04x val=0x%08x\n", addr, val);
363 bb36d470 bellard
#endif
364 bb36d470 bellard
    switch(addr) {
365 bb36d470 bellard
    case 0x08:
366 bb36d470 bellard
        s->fl_base_addr = val & ~0xfff;
367 bb36d470 bellard
        break;
368 bb36d470 bellard
    }
369 bb36d470 bellard
}
370 bb36d470 bellard
371 bb36d470 bellard
static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
372 bb36d470 bellard
{
373 bb36d470 bellard
    UHCIState *s = opaque;
374 bb36d470 bellard
    uint32_t val;
375 bb36d470 bellard
376 bb36d470 bellard
    addr &= 0x1f;
377 bb36d470 bellard
    switch(addr) {
378 bb36d470 bellard
    case 0x08:
379 bb36d470 bellard
        val = s->fl_base_addr;
380 bb36d470 bellard
        break;
381 bb36d470 bellard
    default:
382 bb36d470 bellard
        val = 0xffffffff;
383 bb36d470 bellard
        break;
384 bb36d470 bellard
    }
385 bb36d470 bellard
    return val;
386 bb36d470 bellard
}
387 bb36d470 bellard
388 96217e31 ths
/* signal resume if controller suspended */
389 96217e31 ths
static void uhci_resume (void *opaque)
390 96217e31 ths
{
391 96217e31 ths
    UHCIState *s = (UHCIState *)opaque;
392 96217e31 ths
393 96217e31 ths
    if (!s)
394 96217e31 ths
        return;
395 96217e31 ths
396 96217e31 ths
    if (s->cmd & UHCI_CMD_EGSM) {
397 96217e31 ths
        s->cmd |= UHCI_CMD_FGR;
398 96217e31 ths
        s->status |= UHCI_STS_RD;
399 96217e31 ths
        uhci_update_irq(s);
400 96217e31 ths
    }
401 96217e31 ths
}
402 96217e31 ths
403 bb36d470 bellard
static void uhci_attach(USBPort *port1, USBDevice *dev)
404 bb36d470 bellard
{
405 bb36d470 bellard
    UHCIState *s = port1->opaque;
406 bb36d470 bellard
    UHCIPort *port = &s->ports[port1->index];
407 bb36d470 bellard
408 bb36d470 bellard
    if (dev) {
409 a594cfbf bellard
        if (port->port.dev) {
410 bb36d470 bellard
            usb_attach(port1, NULL);
411 bb36d470 bellard
        }
412 bb36d470 bellard
        /* set connect status */
413 61064870 pbrook
        port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
414 61064870 pbrook
415 bb36d470 bellard
        /* update speed */
416 bb36d470 bellard
        if (dev->speed == USB_SPEED_LOW)
417 bb36d470 bellard
            port->ctrl |= UHCI_PORT_LSDA;
418 bb36d470 bellard
        else
419 bb36d470 bellard
            port->ctrl &= ~UHCI_PORT_LSDA;
420 96217e31 ths
421 96217e31 ths
        uhci_resume(s);
422 96217e31 ths
423 a594cfbf bellard
        port->port.dev = dev;
424 bb36d470 bellard
        /* send the attach message */
425 4d611c9a pbrook
        usb_send_msg(dev, USB_MSG_ATTACH);
426 bb36d470 bellard
    } else {
427 bb36d470 bellard
        /* set connect status */
428 61064870 pbrook
        if (port->ctrl & UHCI_PORT_CCS) {
429 61064870 pbrook
            port->ctrl &= ~UHCI_PORT_CCS;
430 61064870 pbrook
            port->ctrl |= UHCI_PORT_CSC;
431 bb36d470 bellard
        }
432 bb36d470 bellard
        /* disable port */
433 bb36d470 bellard
        if (port->ctrl & UHCI_PORT_EN) {
434 bb36d470 bellard
            port->ctrl &= ~UHCI_PORT_EN;
435 bb36d470 bellard
            port->ctrl |= UHCI_PORT_ENC;
436 bb36d470 bellard
        }
437 96217e31 ths
438 96217e31 ths
        uhci_resume(s);
439 96217e31 ths
440 a594cfbf bellard
        dev = port->port.dev;
441 bb36d470 bellard
        if (dev) {
442 bb36d470 bellard
            /* send the detach message */
443 4d611c9a pbrook
            usb_send_msg(dev, USB_MSG_DETACH);
444 bb36d470 bellard
        }
445 a594cfbf bellard
        port->port.dev = NULL;
446 bb36d470 bellard
    }
447 bb36d470 bellard
}
448 bb36d470 bellard
449 4d611c9a pbrook
static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
450 bb36d470 bellard
{
451 bb36d470 bellard
    UHCIPort *port;
452 bb36d470 bellard
    USBDevice *dev;
453 bb36d470 bellard
    int i, ret;
454 bb36d470 bellard
455 bb36d470 bellard
#ifdef DEBUG_PACKET
456 bb36d470 bellard
    {
457 bb36d470 bellard
        const char *pidstr;
458 4d611c9a pbrook
        switch(p->pid) {
459 bb36d470 bellard
        case USB_TOKEN_SETUP: pidstr = "SETUP"; break;
460 bb36d470 bellard
        case USB_TOKEN_IN: pidstr = "IN"; break;
461 bb36d470 bellard
        case USB_TOKEN_OUT: pidstr = "OUT"; break;
462 bb36d470 bellard
        default: pidstr = "?"; break;
463 bb36d470 bellard
        }
464 bb36d470 bellard
        printf("frame %d: pid=%s addr=0x%02x ep=%d len=%d\n",
465 4d611c9a pbrook
               s->frnum, pidstr, p->devaddr, p->devep, p->len);
466 4d611c9a pbrook
        if (p->pid != USB_TOKEN_IN) {
467 bb36d470 bellard
            printf("     data_out=");
468 4d611c9a pbrook
            for(i = 0; i < p->len; i++) {
469 4d611c9a pbrook
                printf(" %02x", p->data[i]);
470 bb36d470 bellard
            }
471 bb36d470 bellard
            printf("\n");
472 bb36d470 bellard
        }
473 bb36d470 bellard
    }
474 bb36d470 bellard
#endif
475 bb36d470 bellard
    for(i = 0; i < NB_PORTS; i++) {
476 bb36d470 bellard
        port = &s->ports[i];
477 a594cfbf bellard
        dev = port->port.dev;
478 bb36d470 bellard
        if (dev && (port->ctrl & UHCI_PORT_EN)) {
479 4d611c9a pbrook
            ret = dev->handle_packet(dev, p);
480 bb36d470 bellard
            if (ret != USB_RET_NODEV) {
481 bb36d470 bellard
#ifdef DEBUG_PACKET
482 4d611c9a pbrook
                if (ret == USB_RET_ASYNC) {
483 4d611c9a pbrook
                    printf("usb-uhci: Async packet\n");
484 4d611c9a pbrook
                } else {
485 bb36d470 bellard
                    printf("     ret=%d ", ret);
486 4d611c9a pbrook
                    if (p->pid == USB_TOKEN_IN && ret > 0) {
487 bb36d470 bellard
                        printf("data_in=");
488 bb36d470 bellard
                        for(i = 0; i < ret; i++) {
489 4d611c9a pbrook
                            printf(" %02x", p->data[i]);
490 bb36d470 bellard
                        }
491 bb36d470 bellard
                    }
492 bb36d470 bellard
                    printf("\n");
493 bb36d470 bellard
                }
494 bb36d470 bellard
#endif
495 bb36d470 bellard
                return ret;
496 bb36d470 bellard
            }
497 bb36d470 bellard
        }
498 bb36d470 bellard
    }
499 bb36d470 bellard
    return USB_RET_NODEV;
500 bb36d470 bellard
}
501 bb36d470 bellard
502 4d611c9a pbrook
static void uhci_async_complete_packet(USBPacket * packet, void *opaque);
503 4d611c9a pbrook
504 bb36d470 bellard
/* return -1 if fatal error (frame must be stopped)
505 bb36d470 bellard
          0 if TD successful
506 bb36d470 bellard
          1 if TD unsuccessful or inactive
507 bb36d470 bellard
*/
508 b9dc033c balrog
static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask,
509 b9dc033c balrog
                          int completion)
510 bb36d470 bellard
{
511 bb36d470 bellard
    uint8_t pid;
512 b9dc033c balrog
    int len = 0, max_len, err, ret = 0;
513 bb36d470 bellard
514 4d611c9a pbrook
    /* ??? This is wrong for async completion.  */
515 bb36d470 bellard
    if (td->ctrl & TD_CTRL_IOC) {
516 bb36d470 bellard
        *int_mask |= 0x01;
517 bb36d470 bellard
    }
518 3b46e624 ths
519 bb36d470 bellard
    if (!(td->ctrl & TD_CTRL_ACTIVE))
520 bb36d470 bellard
        return 1;
521 bb36d470 bellard
522 bb36d470 bellard
    /* TD is active */
523 bb36d470 bellard
    max_len = ((td->token >> 21) + 1) & 0x7ff;
524 bb36d470 bellard
    pid = td->token & 0xff;
525 b9dc033c balrog
526 b9dc033c balrog
    if (completion && (s->async_qh || s->async_frame_addr)) {
527 4d611c9a pbrook
        ret = s->usb_packet.len;
528 bb36d470 bellard
        if (ret >= 0) {
529 bb36d470 bellard
            len = ret;
530 bb36d470 bellard
            if (len > max_len) {
531 bb36d470 bellard
                len = max_len;
532 bb36d470 bellard
                ret = USB_RET_BABBLE;
533 bb36d470 bellard
            }
534 bb36d470 bellard
            if (len > 0) {
535 bb36d470 bellard
                /* write the data back */
536 4d611c9a pbrook
                cpu_physical_memory_write(td->buffer, s->usb_buf, len);
537 bb36d470 bellard
            }
538 bb36d470 bellard
        } else {
539 bb36d470 bellard
            len = 0;
540 bb36d470 bellard
        }
541 4d611c9a pbrook
        s->async_qh = 0;
542 b9dc033c balrog
        s->async_frame_addr = 0;
543 b9dc033c balrog
    } else if (!completion) {
544 4d611c9a pbrook
        s->usb_packet.pid = pid;
545 4d611c9a pbrook
        s->usb_packet.devaddr = (td->token >> 8) & 0x7f;
546 4d611c9a pbrook
        s->usb_packet.devep = (td->token >> 15) & 0xf;
547 4d611c9a pbrook
        s->usb_packet.data = s->usb_buf;
548 4d611c9a pbrook
        s->usb_packet.len = max_len;
549 4d611c9a pbrook
        s->usb_packet.complete_cb = uhci_async_complete_packet;
550 4d611c9a pbrook
        s->usb_packet.complete_opaque = s;
551 4d611c9a pbrook
        switch(pid) {
552 4d611c9a pbrook
        case USB_TOKEN_OUT:
553 4d611c9a pbrook
        case USB_TOKEN_SETUP:
554 4d611c9a pbrook
            cpu_physical_memory_read(td->buffer, s->usb_buf, max_len);
555 4d611c9a pbrook
            ret = uhci_broadcast_packet(s, &s->usb_packet);
556 4d611c9a pbrook
            len = max_len;
557 4d611c9a pbrook
            break;
558 4d611c9a pbrook
        case USB_TOKEN_IN:
559 4d611c9a pbrook
            ret = uhci_broadcast_packet(s, &s->usb_packet);
560 4d611c9a pbrook
            if (ret >= 0) {
561 4d611c9a pbrook
                len = ret;
562 4d611c9a pbrook
                if (len > max_len) {
563 4d611c9a pbrook
                    len = max_len;
564 4d611c9a pbrook
                    ret = USB_RET_BABBLE;
565 4d611c9a pbrook
                }
566 4d611c9a pbrook
                if (len > 0) {
567 4d611c9a pbrook
                    /* write the data back */
568 4d611c9a pbrook
                    cpu_physical_memory_write(td->buffer, s->usb_buf, len);
569 4d611c9a pbrook
                }
570 4d611c9a pbrook
            } else {
571 4d611c9a pbrook
                len = 0;
572 4d611c9a pbrook
            }
573 4d611c9a pbrook
            break;
574 4d611c9a pbrook
        default:
575 4d611c9a pbrook
            /* invalid pid : frame interrupted */
576 4d611c9a pbrook
            s->status |= UHCI_STS_HCPERR;
577 4d611c9a pbrook
            uhci_update_irq(s);
578 4d611c9a pbrook
            return -1;
579 4d611c9a pbrook
        }
580 4d611c9a pbrook
    }
581 b9dc033c balrog
582 4d611c9a pbrook
    if (ret == USB_RET_ASYNC) {
583 4d611c9a pbrook
        return 2;
584 bb36d470 bellard
    }
585 bb36d470 bellard
    if (td->ctrl & TD_CTRL_IOS)
586 bb36d470 bellard
        td->ctrl &= ~TD_CTRL_ACTIVE;
587 bb36d470 bellard
    if (ret >= 0) {
588 bb36d470 bellard
        td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
589 117b3ae6 pbrook
        /* The NAK bit may have been set by a previous frame, so clear it
590 117b3ae6 pbrook
           here.  The docs are somewhat unclear, but win2k relies on this
591 117b3ae6 pbrook
           behavior.  */
592 117b3ae6 pbrook
        td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
593 5fafdf24 ths
        if (pid == USB_TOKEN_IN &&
594 bb36d470 bellard
            (td->ctrl & TD_CTRL_SPD) &&
595 bb36d470 bellard
            len < max_len) {
596 bb36d470 bellard
            *int_mask |= 0x02;
597 bb36d470 bellard
            /* short packet: do not update QH */
598 bb36d470 bellard
            return 1;
599 bb36d470 bellard
        } else {
600 bb36d470 bellard
            /* success */
601 bb36d470 bellard
            return 0;
602 bb36d470 bellard
        }
603 bb36d470 bellard
    } else {
604 bb36d470 bellard
        switch(ret) {
605 bb36d470 bellard
        default:
606 bb36d470 bellard
        case USB_RET_NODEV:
607 bb36d470 bellard
        do_timeout:
608 bb36d470 bellard
            td->ctrl |= TD_CTRL_TIMEOUT;
609 bb36d470 bellard
            err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
610 bb36d470 bellard
            if (err != 0) {
611 bb36d470 bellard
                err--;
612 bb36d470 bellard
                if (err == 0) {
613 bb36d470 bellard
                    td->ctrl &= ~TD_CTRL_ACTIVE;
614 bb36d470 bellard
                    s->status |= UHCI_STS_USBERR;
615 bb36d470 bellard
                    uhci_update_irq(s);
616 bb36d470 bellard
                }
617 bb36d470 bellard
            }
618 5fafdf24 ths
            td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
619 bb36d470 bellard
                (err << TD_CTRL_ERROR_SHIFT);
620 bb36d470 bellard
            return 1;
621 bb36d470 bellard
        case USB_RET_NAK:
622 bb36d470 bellard
            td->ctrl |= TD_CTRL_NAK;
623 bb36d470 bellard
            if (pid == USB_TOKEN_SETUP)
624 bb36d470 bellard
                goto do_timeout;
625 bb36d470 bellard
            return 1;
626 bb36d470 bellard
        case USB_RET_STALL:
627 bb36d470 bellard
            td->ctrl |= TD_CTRL_STALL;
628 bb36d470 bellard
            td->ctrl &= ~TD_CTRL_ACTIVE;
629 bb36d470 bellard
            return 1;
630 bb36d470 bellard
        case USB_RET_BABBLE:
631 bb36d470 bellard
            td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
632 bb36d470 bellard
            td->ctrl &= ~TD_CTRL_ACTIVE;
633 bb36d470 bellard
            /* frame interrupted */
634 bb36d470 bellard
            return -1;
635 bb36d470 bellard
        }
636 bb36d470 bellard
    }
637 bb36d470 bellard
}
638 bb36d470 bellard
639 4d611c9a pbrook
static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
640 4d611c9a pbrook
{
641 4d611c9a pbrook
    UHCIState *s = opaque;
642 4d611c9a pbrook
    UHCI_QH qh;
643 4d611c9a pbrook
    UHCI_TD td;
644 4d611c9a pbrook
    uint32_t link;
645 4d611c9a pbrook
    uint32_t old_td_ctrl;
646 4d611c9a pbrook
    uint32_t val;
647 b9dc033c balrog
    uint32_t frame_addr;
648 4d611c9a pbrook
    int ret;
649 4d611c9a pbrook
650 b9dc033c balrog
    /* Handle async isochronous packet completion */
651 b9dc033c balrog
    frame_addr = s->async_frame_addr;
652 b9dc033c balrog
    if (frame_addr) {
653 b9dc033c balrog
        cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
654 b9dc033c balrog
        le32_to_cpus(&link);
655 b9dc033c balrog
656 b9dc033c balrog
        cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
657 b9dc033c balrog
        le32_to_cpus(&td.link);
658 b9dc033c balrog
        le32_to_cpus(&td.ctrl);
659 b9dc033c balrog
        le32_to_cpus(&td.token);
660 b9dc033c balrog
        le32_to_cpus(&td.buffer);
661 b9dc033c balrog
        old_td_ctrl = td.ctrl;
662 b9dc033c balrog
        ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
663 b9dc033c balrog
664 b9dc033c balrog
        /* update the status bits of the TD */
665 b9dc033c balrog
        if (old_td_ctrl != td.ctrl) {
666 b9dc033c balrog
            val = cpu_to_le32(td.ctrl);
667 b9dc033c balrog
            cpu_physical_memory_write((link & ~0xf) + 4,
668 b9dc033c balrog
                                      (const uint8_t *)&val,
669 b9dc033c balrog
                                      sizeof(val));
670 b9dc033c balrog
        }
671 b9dc033c balrog
        if (ret == 2) {
672 b9dc033c balrog
            s->async_frame_addr = frame_addr;
673 b9dc033c balrog
        } else if (ret == 0) {
674 b9dc033c balrog
            /* update qh element link */
675 b9dc033c balrog
            val = cpu_to_le32(td.link);
676 b9dc033c balrog
            cpu_physical_memory_write(frame_addr,
677 b9dc033c balrog
                                      (const uint8_t *)&val,
678 b9dc033c balrog
                                      sizeof(val));
679 b9dc033c balrog
        }
680 b9dc033c balrog
        return;
681 b9dc033c balrog
    }
682 b9dc033c balrog
683 4d611c9a pbrook
    link = s->async_qh;
684 4d611c9a pbrook
    if (!link) {
685 4d611c9a pbrook
        /* This should never happen. It means a TD somehow got removed
686 4d611c9a pbrook
           without cancelling the associated async IO request.  */
687 4d611c9a pbrook
        return;
688 4d611c9a pbrook
    }
689 4d611c9a pbrook
    cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
690 4d611c9a pbrook
    le32_to_cpus(&qh.link);
691 4d611c9a pbrook
    le32_to_cpus(&qh.el_link);
692 4d611c9a pbrook
    /* Re-process the queue containing the async packet.  */
693 4d611c9a pbrook
    while (1) {
694 5fafdf24 ths
        cpu_physical_memory_read(qh.el_link & ~0xf,
695 4d611c9a pbrook
                                 (uint8_t *)&td, sizeof(td));
696 4d611c9a pbrook
        le32_to_cpus(&td.link);
697 4d611c9a pbrook
        le32_to_cpus(&td.ctrl);
698 4d611c9a pbrook
        le32_to_cpus(&td.token);
699 4d611c9a pbrook
        le32_to_cpus(&td.buffer);
700 4d611c9a pbrook
        old_td_ctrl = td.ctrl;
701 b9dc033c balrog
        ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
702 b9dc033c balrog
703 4d611c9a pbrook
        /* update the status bits of the TD */
704 4d611c9a pbrook
        if (old_td_ctrl != td.ctrl) {
705 4d611c9a pbrook
            val = cpu_to_le32(td.ctrl);
706 5fafdf24 ths
            cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
707 5fafdf24 ths
                                      (const uint8_t *)&val,
708 4d611c9a pbrook
                                      sizeof(val));
709 4d611c9a pbrook
        }
710 4d611c9a pbrook
        if (ret < 0)
711 4d611c9a pbrook
            break; /* interrupted frame */
712 4d611c9a pbrook
        if (ret == 2) {
713 4d611c9a pbrook
            s->async_qh = link;
714 4d611c9a pbrook
            break;
715 4d611c9a pbrook
        } else if (ret == 0) {
716 4d611c9a pbrook
            /* update qh element link */
717 4d611c9a pbrook
            qh.el_link = td.link;
718 4d611c9a pbrook
            val = cpu_to_le32(qh.el_link);
719 5fafdf24 ths
            cpu_physical_memory_write((link & ~0xf) + 4,
720 5fafdf24 ths
                                      (const uint8_t *)&val,
721 4d611c9a pbrook
                                      sizeof(val));
722 4d611c9a pbrook
            if (!(qh.el_link & 4))
723 4d611c9a pbrook
                break;
724 4d611c9a pbrook
        }
725 4d611c9a pbrook
        break;
726 4d611c9a pbrook
    }
727 4d611c9a pbrook
}
728 4d611c9a pbrook
729 bb36d470 bellard
static void uhci_frame_timer(void *opaque)
730 bb36d470 bellard
{
731 bb36d470 bellard
    UHCIState *s = opaque;
732 bb36d470 bellard
    int64_t expire_time;
733 bb36d470 bellard
    uint32_t frame_addr, link, old_td_ctrl, val;
734 bb36d470 bellard
    int int_mask, cnt, ret;
735 bb36d470 bellard
    UHCI_TD td;
736 bb36d470 bellard
    UHCI_QH qh;
737 4d611c9a pbrook
    uint32_t old_async_qh;
738 bb36d470 bellard
739 bb36d470 bellard
    if (!(s->cmd & UHCI_CMD_RS)) {
740 bb36d470 bellard
        qemu_del_timer(s->frame_timer);
741 52328140 bellard
        /* set hchalted bit in status - UHCI11D 2.1.2 */
742 52328140 bellard
        s->status |= UHCI_STS_HCHALTED;
743 bb36d470 bellard
        return;
744 bb36d470 bellard
    }
745 4d611c9a pbrook
    /* Complete the previous frame.  */
746 4d611c9a pbrook
    s->frnum = (s->frnum + 1) & 0x7ff;
747 4d611c9a pbrook
    if (s->pending_int_mask) {
748 4d611c9a pbrook
        s->status2 |= s->pending_int_mask;
749 4d611c9a pbrook
        s->status |= UHCI_STS_USBINT;
750 4d611c9a pbrook
        uhci_update_irq(s);
751 4d611c9a pbrook
    }
752 4d611c9a pbrook
    old_async_qh = s->async_qh;
753 bb36d470 bellard
    frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
754 bb36d470 bellard
    cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
755 bb36d470 bellard
    le32_to_cpus(&link);
756 bb36d470 bellard
    int_mask = 0;
757 bb36d470 bellard
    cnt = FRAME_MAX_LOOPS;
758 bb36d470 bellard
    while ((link & 1) == 0) {
759 bb36d470 bellard
        if (--cnt == 0)
760 bb36d470 bellard
            break;
761 bb36d470 bellard
        /* valid frame */
762 bb36d470 bellard
        if (link & 2) {
763 bb36d470 bellard
            /* QH */
764 4d611c9a pbrook
            if (link == s->async_qh) {
765 4d611c9a pbrook
                /* We've found a previously issues packet.
766 4d611c9a pbrook
                   Nothing else to do.  */
767 4d611c9a pbrook
                old_async_qh = 0;
768 4d611c9a pbrook
                break;
769 4d611c9a pbrook
            }
770 bb36d470 bellard
            cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
771 bb36d470 bellard
            le32_to_cpus(&qh.link);
772 bb36d470 bellard
            le32_to_cpus(&qh.el_link);
773 bb36d470 bellard
        depth_first:
774 bb36d470 bellard
            if (qh.el_link & 1) {
775 bb36d470 bellard
                /* no element : go to next entry */
776 bb36d470 bellard
                link = qh.link;
777 bb36d470 bellard
            } else if (qh.el_link & 2) {
778 bb36d470 bellard
                /* QH */
779 bb36d470 bellard
                link = qh.el_link;
780 4d611c9a pbrook
            } else if (s->async_qh) {
781 4d611c9a pbrook
                /* We can only cope with one pending packet.  Keep looking
782 4d611c9a pbrook
                   for the previously issued packet.  */
783 4d611c9a pbrook
                link = qh.link;
784 bb36d470 bellard
            } else {
785 bb36d470 bellard
                /* TD */
786 bb36d470 bellard
                if (--cnt == 0)
787 bb36d470 bellard
                    break;
788 5fafdf24 ths
                cpu_physical_memory_read(qh.el_link & ~0xf,
789 bb36d470 bellard
                                         (uint8_t *)&td, sizeof(td));
790 bb36d470 bellard
                le32_to_cpus(&td.link);
791 bb36d470 bellard
                le32_to_cpus(&td.ctrl);
792 bb36d470 bellard
                le32_to_cpus(&td.token);
793 bb36d470 bellard
                le32_to_cpus(&td.buffer);
794 bb36d470 bellard
                old_td_ctrl = td.ctrl;
795 b9dc033c balrog
                ret = uhci_handle_td(s, &td, &int_mask, 0);
796 b9dc033c balrog
797 bb36d470 bellard
                /* update the status bits of the TD */
798 bb36d470 bellard
                if (old_td_ctrl != td.ctrl) {
799 bb36d470 bellard
                    val = cpu_to_le32(td.ctrl);
800 5fafdf24 ths
                    cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
801 5fafdf24 ths
                                              (const uint8_t *)&val,
802 bb36d470 bellard
                                              sizeof(val));
803 bb36d470 bellard
                }
804 bb36d470 bellard
                if (ret < 0)
805 bb36d470 bellard
                    break; /* interrupted frame */
806 4d611c9a pbrook
                if (ret == 2) {
807 4d611c9a pbrook
                    s->async_qh = link;
808 4d611c9a pbrook
                } else if (ret == 0) {
809 bb36d470 bellard
                    /* update qh element link */
810 bb36d470 bellard
                    qh.el_link = td.link;
811 bb36d470 bellard
                    val = cpu_to_le32(qh.el_link);
812 5fafdf24 ths
                    cpu_physical_memory_write((link & ~0xf) + 4,
813 5fafdf24 ths
                                              (const uint8_t *)&val,
814 bb36d470 bellard
                                              sizeof(val));
815 bb36d470 bellard
                    if (qh.el_link & 4) {
816 bb36d470 bellard
                        /* depth first */
817 bb36d470 bellard
                        goto depth_first;
818 bb36d470 bellard
                    }
819 bb36d470 bellard
                }
820 bb36d470 bellard
                /* go to next entry */
821 bb36d470 bellard
                link = qh.link;
822 bb36d470 bellard
            }
823 bb36d470 bellard
        } else {
824 bb36d470 bellard
            /* TD */
825 bb36d470 bellard
            cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
826 bb36d470 bellard
            le32_to_cpus(&td.link);
827 bb36d470 bellard
            le32_to_cpus(&td.ctrl);
828 bb36d470 bellard
            le32_to_cpus(&td.token);
829 bb36d470 bellard
            le32_to_cpus(&td.buffer);
830 b9dc033c balrog
831 b9dc033c balrog
            /* Handle isochonous transfer.  */
832 b9dc033c balrog
            /* FIXME: might be more than one isoc in frame */
833 b9dc033c balrog
            old_td_ctrl = td.ctrl;
834 b9dc033c balrog
            ret = uhci_handle_td(s, &td, &int_mask, 0);
835 b9dc033c balrog
836 b9dc033c balrog
            /* update the status bits of the TD */
837 b9dc033c balrog
            if (old_td_ctrl != td.ctrl) {
838 b9dc033c balrog
                val = cpu_to_le32(td.ctrl);
839 b9dc033c balrog
                cpu_physical_memory_write((link & ~0xf) + 4,
840 b9dc033c balrog
                                          (const uint8_t *)&val,
841 b9dc033c balrog
                                          sizeof(val));
842 b9dc033c balrog
            }
843 b9dc033c balrog
            if (ret < 0)
844 b9dc033c balrog
                break; /* interrupted frame */
845 b9dc033c balrog
            if (ret == 2) {
846 b9dc033c balrog
                s->async_frame_addr = frame_addr;
847 bb36d470 bellard
            }
848 bb36d470 bellard
            link = td.link;
849 bb36d470 bellard
        }
850 bb36d470 bellard
    }
851 4d611c9a pbrook
    s->pending_int_mask = int_mask;
852 4d611c9a pbrook
    if (old_async_qh) {
853 4d611c9a pbrook
        /* A previously started transfer has disappeared from the transfer
854 4d611c9a pbrook
           list.  There's nothing useful we can do with it now, so just
855 4d611c9a pbrook
           discard the packet and hope it wasn't too important.  */
856 4d611c9a pbrook
#ifdef DEBUG
857 4d611c9a pbrook
        printf("Discarding USB packet\n");
858 4d611c9a pbrook
#endif
859 4d611c9a pbrook
        usb_cancel_packet(&s->usb_packet);
860 4d611c9a pbrook
        s->async_qh = 0;
861 bb36d470 bellard
    }
862 b9dc033c balrog
863 bb36d470 bellard
    /* prepare the timer for the next frame */
864 5fafdf24 ths
    expire_time = qemu_get_clock(vm_clock) +
865 bb36d470 bellard
        (ticks_per_sec / FRAME_TIMER_FREQ);
866 bb36d470 bellard
    qemu_mod_timer(s->frame_timer, expire_time);
867 bb36d470 bellard
}
868 bb36d470 bellard
869 5fafdf24 ths
static void uhci_map(PCIDevice *pci_dev, int region_num,
870 bb36d470 bellard
                    uint32_t addr, uint32_t size, int type)
871 bb36d470 bellard
{
872 bb36d470 bellard
    UHCIState *s = (UHCIState *)pci_dev;
873 bb36d470 bellard
874 bb36d470 bellard
    register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
875 bb36d470 bellard
    register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
876 bb36d470 bellard
    register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
877 bb36d470 bellard
    register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
878 bb36d470 bellard
    register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
879 bb36d470 bellard
    register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
880 bb36d470 bellard
}
881 bb36d470 bellard
882 afcc3cdf ths
void usb_uhci_piix3_init(PCIBus *bus, int devfn)
883 bb36d470 bellard
{
884 bb36d470 bellard
    UHCIState *s;
885 bb36d470 bellard
    uint8_t *pci_conf;
886 bb36d470 bellard
    int i;
887 bb36d470 bellard
888 bb36d470 bellard
    s = (UHCIState *)pci_register_device(bus,
889 bb36d470 bellard
                                        "USB-UHCI", sizeof(UHCIState),
890 502a5395 pbrook
                                        devfn, NULL, NULL);
891 bb36d470 bellard
    pci_conf = s->dev.config;
892 bb36d470 bellard
    pci_conf[0x00] = 0x86;
893 bb36d470 bellard
    pci_conf[0x01] = 0x80;
894 bb36d470 bellard
    pci_conf[0x02] = 0x20;
895 bb36d470 bellard
    pci_conf[0x03] = 0x70;
896 bb36d470 bellard
    pci_conf[0x08] = 0x01; // revision number
897 bb36d470 bellard
    pci_conf[0x09] = 0x00;
898 bb36d470 bellard
    pci_conf[0x0a] = 0x03;
899 bb36d470 bellard
    pci_conf[0x0b] = 0x0c;
900 bb36d470 bellard
    pci_conf[0x0e] = 0x00; // header_type
901 f04308e4 bellard
    pci_conf[0x3d] = 4; // interrupt pin 3
902 38ca0f6d pbrook
    pci_conf[0x60] = 0x10; // release number
903 3b46e624 ths
904 bb36d470 bellard
    for(i = 0; i < NB_PORTS; i++) {
905 0d92ed30 pbrook
        qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
906 bb36d470 bellard
    }
907 bb36d470 bellard
    s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
908 bb36d470 bellard
909 bb36d470 bellard
    uhci_reset(s);
910 bb36d470 bellard
911 38ca0f6d pbrook
    /* Use region 4 for consistency with real hardware.  BSD guests seem
912 38ca0f6d pbrook
       to rely on this.  */
913 5fafdf24 ths
    pci_register_io_region(&s->dev, 4, 0x20,
914 bb36d470 bellard
                           PCI_ADDRESS_SPACE_IO, uhci_map);
915 bb36d470 bellard
}
916 afcc3cdf ths
917 afcc3cdf ths
void usb_uhci_piix4_init(PCIBus *bus, int devfn)
918 afcc3cdf ths
{
919 afcc3cdf ths
    UHCIState *s;
920 afcc3cdf ths
    uint8_t *pci_conf;
921 afcc3cdf ths
    int i;
922 afcc3cdf ths
923 afcc3cdf ths
    s = (UHCIState *)pci_register_device(bus,
924 afcc3cdf ths
                                        "USB-UHCI", sizeof(UHCIState),
925 afcc3cdf ths
                                        devfn, NULL, NULL);
926 afcc3cdf ths
    pci_conf = s->dev.config;
927 afcc3cdf ths
    pci_conf[0x00] = 0x86;
928 afcc3cdf ths
    pci_conf[0x01] = 0x80;
929 afcc3cdf ths
    pci_conf[0x02] = 0x12;
930 afcc3cdf ths
    pci_conf[0x03] = 0x71;
931 afcc3cdf ths
    pci_conf[0x08] = 0x01; // revision number
932 afcc3cdf ths
    pci_conf[0x09] = 0x00;
933 afcc3cdf ths
    pci_conf[0x0a] = 0x03;
934 afcc3cdf ths
    pci_conf[0x0b] = 0x0c;
935 afcc3cdf ths
    pci_conf[0x0e] = 0x00; // header_type
936 afcc3cdf ths
    pci_conf[0x3d] = 4; // interrupt pin 3
937 afcc3cdf ths
    pci_conf[0x60] = 0x10; // release number
938 afcc3cdf ths
939 afcc3cdf ths
    for(i = 0; i < NB_PORTS; i++) {
940 afcc3cdf ths
        qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
941 afcc3cdf ths
    }
942 afcc3cdf ths
    s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
943 afcc3cdf ths
944 afcc3cdf ths
    uhci_reset(s);
945 afcc3cdf ths
946 afcc3cdf ths
    /* Use region 4 for consistency with real hardware.  BSD guests seem
947 afcc3cdf ths
       to rely on this.  */
948 afcc3cdf ths
    pci_register_io_region(&s->dev, 4, 0x20,
949 afcc3cdf ths
                           PCI_ADDRESS_SPACE_IO, uhci_map);
950 afcc3cdf ths
}