Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ 079d0b7f

History | View | Annotate | Download (53.1 kB)

1 0d92ed30 pbrook
/*
2 0d92ed30 pbrook
 * QEMU USB OHCI Emulation
3 0d92ed30 pbrook
 * Copyright (c) 2004 Gianni Tedesco
4 0d92ed30 pbrook
 * Copyright (c) 2006 CodeSourcery
5 e24ad6f1 pbrook
 * Copyright (c) 2006 Openedhand Ltd.
6 0d92ed30 pbrook
 *
7 0d92ed30 pbrook
 * This library is free software; you can redistribute it and/or
8 0d92ed30 pbrook
 * modify it under the terms of the GNU Lesser General Public
9 0d92ed30 pbrook
 * License as published by the Free Software Foundation; either
10 0d92ed30 pbrook
 * version 2 of the License, or (at your option) any later version.
11 0d92ed30 pbrook
 *
12 0d92ed30 pbrook
 * This library is distributed in the hope that it will be useful,
13 0d92ed30 pbrook
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 0d92ed30 pbrook
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 0d92ed30 pbrook
 * Lesser General Public License for more details.
16 0d92ed30 pbrook
 *
17 0d92ed30 pbrook
 * You should have received a copy of the GNU Lesser General Public
18 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 0d92ed30 pbrook
 *
20 0d92ed30 pbrook
 * TODO:
21 0d92ed30 pbrook
 *  o Isochronous transfers
22 0d92ed30 pbrook
 *  o Allocate bandwidth in frames properly
23 0d92ed30 pbrook
 *  o Disable timers when nothing needs to be done, or remove timer usage
24 0d92ed30 pbrook
 *    all together.
25 0d92ed30 pbrook
 *  o Handle unrecoverable errors properly
26 0d92ed30 pbrook
 *  o BIOS work to boot from USB storage
27 0d92ed30 pbrook
*/
28 0d92ed30 pbrook
29 87ecb68b pbrook
#include "hw.h"
30 87ecb68b pbrook
#include "qemu-timer.h"
31 87ecb68b pbrook
#include "usb.h"
32 87ecb68b pbrook
#include "pci.h"
33 18e08a55 Michael S. Tsirkin
#include "usb-ohci.h"
34 61d3cf93 Paul Brook
#include "sysbus.h"
35 61d3cf93 Paul Brook
#include "qdev-addr.h"
36 0d92ed30 pbrook
37 0d92ed30 pbrook
//#define DEBUG_OHCI
38 0d92ed30 pbrook
/* Dump packet contents.  */
39 0d92ed30 pbrook
//#define DEBUG_PACKET
40 7bfe5777 balrog
//#define DEBUG_ISOCH
41 0d92ed30 pbrook
/* This causes frames to occur 1000x slower */
42 0d92ed30 pbrook
//#define OHCI_TIME_WARP 1
43 0d92ed30 pbrook
44 0d92ed30 pbrook
#ifdef DEBUG_OHCI
45 d0f2c4c6 malc
#define DPRINTF printf
46 0d92ed30 pbrook
#else
47 d0f2c4c6 malc
#define DPRINTF(...)
48 0d92ed30 pbrook
#endif
49 0d92ed30 pbrook
50 0d92ed30 pbrook
/* Number of Downstream Ports on the root hub.  */
51 0d92ed30 pbrook
52 0d92ed30 pbrook
#define OHCI_MAX_PORTS 15
53 0d92ed30 pbrook
54 0d92ed30 pbrook
static int64_t usb_frame_time;
55 0d92ed30 pbrook
static int64_t usb_bit_time;
56 0d92ed30 pbrook
57 0d92ed30 pbrook
typedef struct OHCIPort {
58 0d92ed30 pbrook
    USBPort port;
59 0d92ed30 pbrook
    uint32_t ctrl;
60 0d92ed30 pbrook
} OHCIPort;
61 0d92ed30 pbrook
62 0d92ed30 pbrook
typedef struct {
63 b2317837 Gerd Hoffmann
    USBBus bus;
64 d537cf6c pbrook
    qemu_irq irq;
65 6da48311 Avi Kivity
    MemoryRegion mem;
66 0d92ed30 pbrook
    int num_ports;
67 e24ad6f1 pbrook
    const char *name;
68 0d92ed30 pbrook
69 0d92ed30 pbrook
    QEMUTimer *eof_timer;
70 0d92ed30 pbrook
    int64_t sof_time;
71 0d92ed30 pbrook
72 0d92ed30 pbrook
    /* OHCI state */
73 0d92ed30 pbrook
    /* Control partition */
74 0d92ed30 pbrook
    uint32_t ctl, status;
75 0d92ed30 pbrook
    uint32_t intr_status;
76 0d92ed30 pbrook
    uint32_t intr;
77 0d92ed30 pbrook
78 0d92ed30 pbrook
    /* memory pointer partition */
79 0d92ed30 pbrook
    uint32_t hcca;
80 0d92ed30 pbrook
    uint32_t ctrl_head, ctrl_cur;
81 0d92ed30 pbrook
    uint32_t bulk_head, bulk_cur;
82 0d92ed30 pbrook
    uint32_t per_cur;
83 0d92ed30 pbrook
    uint32_t done;
84 0d92ed30 pbrook
    int done_count;
85 0d92ed30 pbrook
86 0d92ed30 pbrook
    /* Frame counter partition */
87 0d92ed30 pbrook
    uint32_t fsmps:15;
88 0d92ed30 pbrook
    uint32_t fit:1;
89 0d92ed30 pbrook
    uint32_t fi:14;
90 0d92ed30 pbrook
    uint32_t frt:1;
91 0d92ed30 pbrook
    uint16_t frame_number;
92 0d92ed30 pbrook
    uint16_t padding;
93 0d92ed30 pbrook
    uint32_t pstart;
94 0d92ed30 pbrook
    uint32_t lst;
95 0d92ed30 pbrook
96 0d92ed30 pbrook
    /* Root Hub partition */
97 0d92ed30 pbrook
    uint32_t rhdesc_a, rhdesc_b;
98 0d92ed30 pbrook
    uint32_t rhstatus;
99 0d92ed30 pbrook
    OHCIPort rhport[OHCI_MAX_PORTS];
100 4d611c9a pbrook
101 e24ad6f1 pbrook
    /* PXA27x Non-OHCI events */
102 e24ad6f1 pbrook
    uint32_t hstatus;
103 e24ad6f1 pbrook
    uint32_t hmask;
104 e24ad6f1 pbrook
    uint32_t hreset;
105 e24ad6f1 pbrook
    uint32_t htest;
106 e24ad6f1 pbrook
107 ac611340 aurel32
    /* SM501 local memory offset */
108 c227f099 Anthony Liguori
    target_phys_addr_t localmem_base;
109 ac611340 aurel32
110 4d611c9a pbrook
    /* Active packets.  */
111 4d611c9a pbrook
    uint32_t old_ctl;
112 4d611c9a pbrook
    USBPacket usb_packet;
113 4d611c9a pbrook
    uint8_t usb_buf[8192];
114 4d611c9a pbrook
    uint32_t async_td;
115 4d611c9a pbrook
    int async_complete;
116 4d611c9a pbrook
117 0d92ed30 pbrook
} OHCIState;
118 0d92ed30 pbrook
119 0d92ed30 pbrook
/* Host Controller Communications Area */
120 0d92ed30 pbrook
struct ohci_hcca {
121 0d92ed30 pbrook
    uint32_t intr[32];
122 0d92ed30 pbrook
    uint16_t frame, pad;
123 0d92ed30 pbrook
    uint32_t done;
124 0d92ed30 pbrook
};
125 0d92ed30 pbrook
126 73221b12 ths
static void ohci_bus_stop(OHCIState *ohci);
127 4706ab6c Hans de Goede
static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev);
128 73221b12 ths
129 0d92ed30 pbrook
/* Bitfields for the first word of an Endpoint Desciptor.  */
130 0d92ed30 pbrook
#define OHCI_ED_FA_SHIFT  0
131 0d92ed30 pbrook
#define OHCI_ED_FA_MASK   (0x7f<<OHCI_ED_FA_SHIFT)
132 0d92ed30 pbrook
#define OHCI_ED_EN_SHIFT  7
133 0d92ed30 pbrook
#define OHCI_ED_EN_MASK   (0xf<<OHCI_ED_EN_SHIFT)
134 0d92ed30 pbrook
#define OHCI_ED_D_SHIFT   11
135 0d92ed30 pbrook
#define OHCI_ED_D_MASK    (3<<OHCI_ED_D_SHIFT)
136 0d92ed30 pbrook
#define OHCI_ED_S         (1<<13)
137 0d92ed30 pbrook
#define OHCI_ED_K         (1<<14)
138 0d92ed30 pbrook
#define OHCI_ED_F         (1<<15)
139 7bfe5777 balrog
#define OHCI_ED_MPS_SHIFT 16
140 7bfe5777 balrog
#define OHCI_ED_MPS_MASK  (0x7ff<<OHCI_ED_MPS_SHIFT)
141 0d92ed30 pbrook
142 0d92ed30 pbrook
/* Flags in the head field of an Endpoint Desciptor.  */
143 0d92ed30 pbrook
#define OHCI_ED_H         1
144 0d92ed30 pbrook
#define OHCI_ED_C         2
145 0d92ed30 pbrook
146 0d92ed30 pbrook
/* Bitfields for the first word of a Transfer Desciptor.  */
147 0d92ed30 pbrook
#define OHCI_TD_R         (1<<18)
148 0d92ed30 pbrook
#define OHCI_TD_DP_SHIFT  19
149 0d92ed30 pbrook
#define OHCI_TD_DP_MASK   (3<<OHCI_TD_DP_SHIFT)
150 0d92ed30 pbrook
#define OHCI_TD_DI_SHIFT  21
151 0d92ed30 pbrook
#define OHCI_TD_DI_MASK   (7<<OHCI_TD_DI_SHIFT)
152 0d92ed30 pbrook
#define OHCI_TD_T0        (1<<24)
153 8d11b78c Peter Maydell
#define OHCI_TD_T1        (1<<25)
154 0d92ed30 pbrook
#define OHCI_TD_EC_SHIFT  26
155 0d92ed30 pbrook
#define OHCI_TD_EC_MASK   (3<<OHCI_TD_EC_SHIFT)
156 0d92ed30 pbrook
#define OHCI_TD_CC_SHIFT  28
157 0d92ed30 pbrook
#define OHCI_TD_CC_MASK   (0xf<<OHCI_TD_CC_SHIFT)
158 0d92ed30 pbrook
159 7bfe5777 balrog
/* Bitfields for the first word of an Isochronous Transfer Desciptor.  */
160 7bfe5777 balrog
/* CC & DI - same as in the General Transfer Desciptor */
161 7bfe5777 balrog
#define OHCI_TD_SF_SHIFT  0
162 7bfe5777 balrog
#define OHCI_TD_SF_MASK   (0xffff<<OHCI_TD_SF_SHIFT)
163 7bfe5777 balrog
#define OHCI_TD_FC_SHIFT  24
164 7bfe5777 balrog
#define OHCI_TD_FC_MASK   (7<<OHCI_TD_FC_SHIFT)
165 7bfe5777 balrog
166 7bfe5777 balrog
/* Isochronous Transfer Desciptor - Offset / PacketStatusWord */
167 7bfe5777 balrog
#define OHCI_TD_PSW_CC_SHIFT 12
168 7bfe5777 balrog
#define OHCI_TD_PSW_CC_MASK  (0xf<<OHCI_TD_PSW_CC_SHIFT)
169 7bfe5777 balrog
#define OHCI_TD_PSW_SIZE_SHIFT 0
170 7bfe5777 balrog
#define OHCI_TD_PSW_SIZE_MASK  (0xfff<<OHCI_TD_PSW_SIZE_SHIFT)
171 7bfe5777 balrog
172 7bfe5777 balrog
#define OHCI_PAGE_MASK    0xfffff000
173 7bfe5777 balrog
#define OHCI_OFFSET_MASK  0xfff
174 7bfe5777 balrog
175 0d92ed30 pbrook
#define OHCI_DPTR_MASK    0xfffffff0
176 0d92ed30 pbrook
177 0d92ed30 pbrook
#define OHCI_BM(val, field) \
178 0d92ed30 pbrook
  (((val) & OHCI_##field##_MASK) >> OHCI_##field##_SHIFT)
179 0d92ed30 pbrook
180 0d92ed30 pbrook
#define OHCI_SET_BM(val, field, newval) do { \
181 0d92ed30 pbrook
    val &= ~OHCI_##field##_MASK; \
182 0d92ed30 pbrook
    val |= ((newval) << OHCI_##field##_SHIFT) & OHCI_##field##_MASK; \
183 0d92ed30 pbrook
    } while(0)
184 0d92ed30 pbrook
185 0d92ed30 pbrook
/* endpoint descriptor */
186 0d92ed30 pbrook
struct ohci_ed {
187 0d92ed30 pbrook
    uint32_t flags;
188 0d92ed30 pbrook
    uint32_t tail;
189 0d92ed30 pbrook
    uint32_t head;
190 0d92ed30 pbrook
    uint32_t next;
191 0d92ed30 pbrook
};
192 0d92ed30 pbrook
193 0d92ed30 pbrook
/* General transfer descriptor */
194 0d92ed30 pbrook
struct ohci_td {
195 0d92ed30 pbrook
    uint32_t flags;
196 0d92ed30 pbrook
    uint32_t cbp;
197 0d92ed30 pbrook
    uint32_t next;
198 0d92ed30 pbrook
    uint32_t be;
199 0d92ed30 pbrook
};
200 0d92ed30 pbrook
201 7bfe5777 balrog
/* Isochronous transfer descriptor */
202 7bfe5777 balrog
struct ohci_iso_td {
203 7bfe5777 balrog
    uint32_t flags;
204 7bfe5777 balrog
    uint32_t bp;
205 7bfe5777 balrog
    uint32_t next;
206 7bfe5777 balrog
    uint32_t be;
207 7bfe5777 balrog
    uint16_t offset[8];
208 7bfe5777 balrog
};
209 7bfe5777 balrog
210 0d92ed30 pbrook
#define USB_HZ                      12000000
211 0d92ed30 pbrook
212 0d92ed30 pbrook
/* OHCI Local stuff */
213 0d92ed30 pbrook
#define OHCI_CTL_CBSR         ((1<<0)|(1<<1))
214 0d92ed30 pbrook
#define OHCI_CTL_PLE          (1<<2)
215 0d92ed30 pbrook
#define OHCI_CTL_IE           (1<<3)
216 0d92ed30 pbrook
#define OHCI_CTL_CLE          (1<<4)
217 0d92ed30 pbrook
#define OHCI_CTL_BLE          (1<<5)
218 0d92ed30 pbrook
#define OHCI_CTL_HCFS         ((1<<6)|(1<<7))
219 0d92ed30 pbrook
#define  OHCI_USB_RESET       0x00
220 0d92ed30 pbrook
#define  OHCI_USB_RESUME      0x40
221 0d92ed30 pbrook
#define  OHCI_USB_OPERATIONAL 0x80
222 0d92ed30 pbrook
#define  OHCI_USB_SUSPEND     0xc0
223 0d92ed30 pbrook
#define OHCI_CTL_IR           (1<<8)
224 0d92ed30 pbrook
#define OHCI_CTL_RWC          (1<<9)
225 0d92ed30 pbrook
#define OHCI_CTL_RWE          (1<<10)
226 0d92ed30 pbrook
227 0d92ed30 pbrook
#define OHCI_STATUS_HCR       (1<<0)
228 0d92ed30 pbrook
#define OHCI_STATUS_CLF       (1<<1)
229 0d92ed30 pbrook
#define OHCI_STATUS_BLF       (1<<2)
230 0d92ed30 pbrook
#define OHCI_STATUS_OCR       (1<<3)
231 0d92ed30 pbrook
#define OHCI_STATUS_SOC       ((1<<6)|(1<<7))
232 0d92ed30 pbrook
233 0d92ed30 pbrook
#define OHCI_INTR_SO          (1<<0) /* Scheduling overrun */
234 0d92ed30 pbrook
#define OHCI_INTR_WD          (1<<1) /* HcDoneHead writeback */
235 0d92ed30 pbrook
#define OHCI_INTR_SF          (1<<2) /* Start of frame */
236 0d92ed30 pbrook
#define OHCI_INTR_RD          (1<<3) /* Resume detect */
237 0d92ed30 pbrook
#define OHCI_INTR_UE          (1<<4) /* Unrecoverable error */
238 0d92ed30 pbrook
#define OHCI_INTR_FNO         (1<<5) /* Frame number overflow */
239 0d92ed30 pbrook
#define OHCI_INTR_RHSC        (1<<6) /* Root hub status change */
240 0d92ed30 pbrook
#define OHCI_INTR_OC          (1<<30) /* Ownership change */
241 0d92ed30 pbrook
#define OHCI_INTR_MIE         (1<<31) /* Master Interrupt Enable */
242 0d92ed30 pbrook
243 0d92ed30 pbrook
#define OHCI_HCCA_SIZE        0x100
244 0d92ed30 pbrook
#define OHCI_HCCA_MASK        0xffffff00
245 0d92ed30 pbrook
246 0d92ed30 pbrook
#define OHCI_EDPTR_MASK       0xfffffff0
247 0d92ed30 pbrook
248 0d92ed30 pbrook
#define OHCI_FMI_FI           0x00003fff
249 0d92ed30 pbrook
#define OHCI_FMI_FSMPS        0xffff0000
250 0d92ed30 pbrook
#define OHCI_FMI_FIT          0x80000000
251 0d92ed30 pbrook
252 0d92ed30 pbrook
#define OHCI_FR_RT            (1<<31)
253 0d92ed30 pbrook
254 0d92ed30 pbrook
#define OHCI_LS_THRESH        0x628
255 0d92ed30 pbrook
256 0d92ed30 pbrook
#define OHCI_RHA_RW_MASK      0x00000000 /* Mask of supported features.  */
257 0d92ed30 pbrook
#define OHCI_RHA_PSM          (1<<8)
258 0d92ed30 pbrook
#define OHCI_RHA_NPS          (1<<9)
259 0d92ed30 pbrook
#define OHCI_RHA_DT           (1<<10)
260 0d92ed30 pbrook
#define OHCI_RHA_OCPM         (1<<11)
261 0d92ed30 pbrook
#define OHCI_RHA_NOCP         (1<<12)
262 0d92ed30 pbrook
#define OHCI_RHA_POTPGT_MASK  0xff000000
263 0d92ed30 pbrook
264 0d92ed30 pbrook
#define OHCI_RHS_LPS          (1<<0)
265 0d92ed30 pbrook
#define OHCI_RHS_OCI          (1<<1)
266 0d92ed30 pbrook
#define OHCI_RHS_DRWE         (1<<15)
267 0d92ed30 pbrook
#define OHCI_RHS_LPSC         (1<<16)
268 0d92ed30 pbrook
#define OHCI_RHS_OCIC         (1<<17)
269 0d92ed30 pbrook
#define OHCI_RHS_CRWE         (1<<31)
270 0d92ed30 pbrook
271 0d92ed30 pbrook
#define OHCI_PORT_CCS         (1<<0)
272 0d92ed30 pbrook
#define OHCI_PORT_PES         (1<<1)
273 0d92ed30 pbrook
#define OHCI_PORT_PSS         (1<<2)
274 0d92ed30 pbrook
#define OHCI_PORT_POCI        (1<<3)
275 0d92ed30 pbrook
#define OHCI_PORT_PRS         (1<<4)
276 0d92ed30 pbrook
#define OHCI_PORT_PPS         (1<<8)
277 0d92ed30 pbrook
#define OHCI_PORT_LSDA        (1<<9)
278 0d92ed30 pbrook
#define OHCI_PORT_CSC         (1<<16)
279 0d92ed30 pbrook
#define OHCI_PORT_PESC        (1<<17)
280 0d92ed30 pbrook
#define OHCI_PORT_PSSC        (1<<18)
281 0d92ed30 pbrook
#define OHCI_PORT_OCIC        (1<<19)
282 0d92ed30 pbrook
#define OHCI_PORT_PRSC        (1<<20)
283 0d92ed30 pbrook
#define OHCI_PORT_WTC         (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \
284 0d92ed30 pbrook
                               |OHCI_PORT_OCIC|OHCI_PORT_PRSC)
285 0d92ed30 pbrook
286 0d92ed30 pbrook
#define OHCI_TD_DIR_SETUP     0x0
287 0d92ed30 pbrook
#define OHCI_TD_DIR_OUT       0x1
288 0d92ed30 pbrook
#define OHCI_TD_DIR_IN        0x2
289 0d92ed30 pbrook
#define OHCI_TD_DIR_RESERVED  0x3
290 0d92ed30 pbrook
291 0d92ed30 pbrook
#define OHCI_CC_NOERROR             0x0
292 0d92ed30 pbrook
#define OHCI_CC_CRC                 0x1
293 0d92ed30 pbrook
#define OHCI_CC_BITSTUFFING         0x2
294 0d92ed30 pbrook
#define OHCI_CC_DATATOGGLEMISMATCH  0x3
295 0d92ed30 pbrook
#define OHCI_CC_STALL               0x4
296 0d92ed30 pbrook
#define OHCI_CC_DEVICENOTRESPONDING 0x5
297 0d92ed30 pbrook
#define OHCI_CC_PIDCHECKFAILURE     0x6
298 0d92ed30 pbrook
#define OHCI_CC_UNDEXPETEDPID       0x7
299 0d92ed30 pbrook
#define OHCI_CC_DATAOVERRUN         0x8
300 0d92ed30 pbrook
#define OHCI_CC_DATAUNDERRUN        0x9
301 0d92ed30 pbrook
#define OHCI_CC_BUFFEROVERRUN       0xc
302 0d92ed30 pbrook
#define OHCI_CC_BUFFERUNDERRUN      0xd
303 0d92ed30 pbrook
304 e24ad6f1 pbrook
#define OHCI_HRESET_FSBIR       (1 << 0)
305 e24ad6f1 pbrook
306 61064870 pbrook
/* Update IRQ levels */
307 61064870 pbrook
static inline void ohci_intr_update(OHCIState *ohci)
308 61064870 pbrook
{
309 61064870 pbrook
    int level = 0;
310 61064870 pbrook
311 61064870 pbrook
    if ((ohci->intr & OHCI_INTR_MIE) &&
312 61064870 pbrook
        (ohci->intr_status & ohci->intr))
313 61064870 pbrook
        level = 1;
314 61064870 pbrook
315 d537cf6c pbrook
    qemu_set_irq(ohci->irq, level);
316 61064870 pbrook
}
317 61064870 pbrook
318 61064870 pbrook
/* Set an interrupt */
319 61064870 pbrook
static inline void ohci_set_interrupt(OHCIState *ohci, uint32_t intr)
320 61064870 pbrook
{
321 61064870 pbrook
    ohci->intr_status |= intr;
322 61064870 pbrook
    ohci_intr_update(ohci);
323 61064870 pbrook
}
324 61064870 pbrook
325 61064870 pbrook
/* Attach or detach a device on a root hub port.  */
326 618c169b Gerd Hoffmann
static void ohci_attach(USBPort *port1)
327 0d92ed30 pbrook
{
328 0d92ed30 pbrook
    OHCIState *s = port1->opaque;
329 0d92ed30 pbrook
    OHCIPort *port = &s->rhport[port1->index];
330 3dc345d5 Gerd Hoffmann
    uint32_t old_state = port->ctrl;
331 0d92ed30 pbrook
332 618c169b Gerd Hoffmann
    /* set connect status */
333 618c169b Gerd Hoffmann
    port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
334 618c169b Gerd Hoffmann
335 618c169b Gerd Hoffmann
    /* update speed */
336 618c169b Gerd Hoffmann
    if (port->port.dev->speed == USB_SPEED_LOW) {
337 618c169b Gerd Hoffmann
        port->ctrl |= OHCI_PORT_LSDA;
338 0d92ed30 pbrook
    } else {
339 618c169b Gerd Hoffmann
        port->ctrl &= ~OHCI_PORT_LSDA;
340 618c169b Gerd Hoffmann
    }
341 618c169b Gerd Hoffmann
342 618c169b Gerd Hoffmann
    /* notify of remote-wakeup */
343 618c169b Gerd Hoffmann
    if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
344 618c169b Gerd Hoffmann
        ohci_set_interrupt(s, OHCI_INTR_RD);
345 618c169b Gerd Hoffmann
    }
346 618c169b Gerd Hoffmann
347 618c169b Gerd Hoffmann
    DPRINTF("usb-ohci: Attached port %d\n", port1->index);
348 3dc345d5 Gerd Hoffmann
349 3dc345d5 Gerd Hoffmann
    if (old_state != port->ctrl) {
350 3dc345d5 Gerd Hoffmann
        ohci_set_interrupt(s, OHCI_INTR_RHSC);
351 3dc345d5 Gerd Hoffmann
    }
352 618c169b Gerd Hoffmann
}
353 618c169b Gerd Hoffmann
354 618c169b Gerd Hoffmann
static void ohci_detach(USBPort *port1)
355 618c169b Gerd Hoffmann
{
356 618c169b Gerd Hoffmann
    OHCIState *s = port1->opaque;
357 618c169b Gerd Hoffmann
    OHCIPort *port = &s->rhport[port1->index];
358 618c169b Gerd Hoffmann
    uint32_t old_state = port->ctrl;
359 618c169b Gerd Hoffmann
360 4706ab6c Hans de Goede
    ohci_async_cancel_device(s, port1->dev);
361 4706ab6c Hans de Goede
362 618c169b Gerd Hoffmann
    /* set connect status */
363 618c169b Gerd Hoffmann
    if (port->ctrl & OHCI_PORT_CCS) {
364 618c169b Gerd Hoffmann
        port->ctrl &= ~OHCI_PORT_CCS;
365 618c169b Gerd Hoffmann
        port->ctrl |= OHCI_PORT_CSC;
366 618c169b Gerd Hoffmann
    }
367 618c169b Gerd Hoffmann
    /* disable port */
368 618c169b Gerd Hoffmann
    if (port->ctrl & OHCI_PORT_PES) {
369 618c169b Gerd Hoffmann
        port->ctrl &= ~OHCI_PORT_PES;
370 618c169b Gerd Hoffmann
        port->ctrl |= OHCI_PORT_PESC;
371 0d92ed30 pbrook
    }
372 618c169b Gerd Hoffmann
    DPRINTF("usb-ohci: Detached port %d\n", port1->index);
373 61064870 pbrook
374 3dc345d5 Gerd Hoffmann
    if (old_state != port->ctrl) {
375 61064870 pbrook
        ohci_set_interrupt(s, OHCI_INTR_RHSC);
376 3dc345d5 Gerd Hoffmann
    }
377 0d92ed30 pbrook
}
378 0d92ed30 pbrook
379 d47e59b8 Hans de Goede
static void ohci_wakeup(USBPort *port1)
380 9bba1eb1 Peter Maydell
{
381 d47e59b8 Hans de Goede
    OHCIState *s = port1->opaque;
382 d47e59b8 Hans de Goede
    OHCIPort *port = &s->rhport[port1->index];
383 f3dc0051 Peter Maydell
    uint32_t intr = 0;
384 9bba1eb1 Peter Maydell
    if (port->ctrl & OHCI_PORT_PSS) {
385 d47e59b8 Hans de Goede
        DPRINTF("usb-ohci: port %d: wakeup\n", port1->index);
386 9bba1eb1 Peter Maydell
        port->ctrl |= OHCI_PORT_PSSC;
387 9bba1eb1 Peter Maydell
        port->ctrl &= ~OHCI_PORT_PSS;
388 f3dc0051 Peter Maydell
        intr = OHCI_INTR_RHSC;
389 9bba1eb1 Peter Maydell
    }
390 f3dc0051 Peter Maydell
    /* Note that the controller can be suspended even if this port is not */
391 f3dc0051 Peter Maydell
    if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
392 f3dc0051 Peter Maydell
        DPRINTF("usb-ohci: remote-wakeup: SUSPEND->RESUME\n");
393 f3dc0051 Peter Maydell
        /* This is the one state transition the controller can do by itself */
394 f3dc0051 Peter Maydell
        s->ctl &= ~OHCI_CTL_HCFS;
395 f3dc0051 Peter Maydell
        s->ctl |= OHCI_USB_RESUME;
396 f3dc0051 Peter Maydell
        /* In suspend mode only ResumeDetected is possible, not RHSC:
397 f3dc0051 Peter Maydell
         * see the OHCI spec 5.1.2.3.
398 f3dc0051 Peter Maydell
         */
399 f3dc0051 Peter Maydell
        intr = OHCI_INTR_RD;
400 f3dc0051 Peter Maydell
    }
401 f3dc0051 Peter Maydell
    ohci_set_interrupt(s, intr);
402 9bba1eb1 Peter Maydell
}
403 9bba1eb1 Peter Maydell
404 4706ab6c Hans de Goede
static void ohci_child_detach(USBPort *port1, USBDevice *child)
405 4706ab6c Hans de Goede
{
406 4706ab6c Hans de Goede
    OHCIState *s = port1->opaque;
407 4706ab6c Hans de Goede
408 4706ab6c Hans de Goede
    ohci_async_cancel_device(s, child);
409 4706ab6c Hans de Goede
}
410 4706ab6c Hans de Goede
411 993048bb Gerd Hoffmann
static USBDevice *ohci_find_device(OHCIState *ohci, uint8_t addr)
412 993048bb Gerd Hoffmann
{
413 993048bb Gerd Hoffmann
    USBDevice *dev;
414 993048bb Gerd Hoffmann
    int i;
415 993048bb Gerd Hoffmann
416 993048bb Gerd Hoffmann
    for (i = 0; i < ohci->num_ports; i++) {
417 993048bb Gerd Hoffmann
        if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0) {
418 993048bb Gerd Hoffmann
            continue;
419 993048bb Gerd Hoffmann
        }
420 993048bb Gerd Hoffmann
        dev = usb_find_device(&ohci->rhport[i].port, addr);
421 993048bb Gerd Hoffmann
        if (dev != NULL) {
422 993048bb Gerd Hoffmann
            return dev;
423 993048bb Gerd Hoffmann
        }
424 993048bb Gerd Hoffmann
    }
425 993048bb Gerd Hoffmann
    return NULL;
426 993048bb Gerd Hoffmann
}
427 993048bb Gerd Hoffmann
428 0d92ed30 pbrook
/* Reset the controller */
429 73221b12 ths
static void ohci_reset(void *opaque)
430 0d92ed30 pbrook
{
431 73221b12 ths
    OHCIState *ohci = opaque;
432 0d92ed30 pbrook
    OHCIPort *port;
433 0d92ed30 pbrook
    int i;
434 0d92ed30 pbrook
435 73221b12 ths
    ohci_bus_stop(ohci);
436 0d92ed30 pbrook
    ohci->ctl = 0;
437 4d611c9a pbrook
    ohci->old_ctl = 0;
438 0d92ed30 pbrook
    ohci->status = 0;
439 0d92ed30 pbrook
    ohci->intr_status = 0;
440 0d92ed30 pbrook
    ohci->intr = OHCI_INTR_MIE;
441 0d92ed30 pbrook
442 0d92ed30 pbrook
    ohci->hcca = 0;
443 0d92ed30 pbrook
    ohci->ctrl_head = ohci->ctrl_cur = 0;
444 0d92ed30 pbrook
    ohci->bulk_head = ohci->bulk_cur = 0;
445 0d92ed30 pbrook
    ohci->per_cur = 0;
446 0d92ed30 pbrook
    ohci->done = 0;
447 0d92ed30 pbrook
    ohci->done_count = 7;
448 0d92ed30 pbrook
449 0d92ed30 pbrook
    /* FSMPS is marked TBD in OCHI 1.0, what gives ffs?
450 0d92ed30 pbrook
     * I took the value linux sets ...
451 0d92ed30 pbrook
     */
452 0d92ed30 pbrook
    ohci->fsmps = 0x2778;
453 0d92ed30 pbrook
    ohci->fi = 0x2edf;
454 0d92ed30 pbrook
    ohci->fit = 0;
455 0d92ed30 pbrook
    ohci->frt = 0;
456 0d92ed30 pbrook
    ohci->frame_number = 0;
457 0d92ed30 pbrook
    ohci->pstart = 0;
458 0d92ed30 pbrook
    ohci->lst = OHCI_LS_THRESH;
459 0d92ed30 pbrook
460 0d92ed30 pbrook
    ohci->rhdesc_a = OHCI_RHA_NPS | ohci->num_ports;
461 0d92ed30 pbrook
    ohci->rhdesc_b = 0x0; /* Impl. specific */
462 0d92ed30 pbrook
    ohci->rhstatus = 0;
463 0d92ed30 pbrook
464 0d92ed30 pbrook
    for (i = 0; i < ohci->num_ports; i++)
465 0d92ed30 pbrook
      {
466 0d92ed30 pbrook
        port = &ohci->rhport[i];
467 0d92ed30 pbrook
        port->ctrl = 0;
468 891fb2cd Gerd Hoffmann
        if (port->port.dev && port->port.dev->attached) {
469 d28f4e2d Gerd Hoffmann
            usb_port_reset(&port->port);
470 618c169b Gerd Hoffmann
        }
471 0d92ed30 pbrook
      }
472 4d611c9a pbrook
    if (ohci->async_td) {
473 4d611c9a pbrook
        usb_cancel_packet(&ohci->usb_packet);
474 4d611c9a pbrook
        ohci->async_td = 0;
475 4d611c9a pbrook
    }
476 d0f2c4c6 malc
    DPRINTF("usb-ohci: Reset %s\n", ohci->name);
477 0d92ed30 pbrook
}
478 0d92ed30 pbrook
479 0d92ed30 pbrook
/* Get an array of dwords from main memory */
480 ac611340 aurel32
static inline int get_dwords(OHCIState *ohci,
481 ac611340 aurel32
                             uint32_t addr, uint32_t *buf, int num)
482 0d92ed30 pbrook
{
483 0d92ed30 pbrook
    int i;
484 0d92ed30 pbrook
485 ac611340 aurel32
    addr += ohci->localmem_base;
486 ac611340 aurel32
487 0d92ed30 pbrook
    for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
488 54f7b4a3 Stefan Weil
        cpu_physical_memory_read(addr, buf, sizeof(*buf));
489 0d92ed30 pbrook
        *buf = le32_to_cpu(*buf);
490 0d92ed30 pbrook
    }
491 0d92ed30 pbrook
492 0d92ed30 pbrook
    return 1;
493 0d92ed30 pbrook
}
494 0d92ed30 pbrook
495 0d92ed30 pbrook
/* Put an array of dwords in to main memory */
496 ac611340 aurel32
static inline int put_dwords(OHCIState *ohci,
497 ac611340 aurel32
                             uint32_t addr, uint32_t *buf, int num)
498 0d92ed30 pbrook
{
499 0d92ed30 pbrook
    int i;
500 0d92ed30 pbrook
501 ac611340 aurel32
    addr += ohci->localmem_base;
502 ac611340 aurel32
503 0d92ed30 pbrook
    for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
504 0d92ed30 pbrook
        uint32_t tmp = cpu_to_le32(*buf);
505 54f7b4a3 Stefan Weil
        cpu_physical_memory_write(addr, &tmp, sizeof(tmp));
506 0d92ed30 pbrook
    }
507 0d92ed30 pbrook
508 0d92ed30 pbrook
    return 1;
509 0d92ed30 pbrook
}
510 0d92ed30 pbrook
511 7bfe5777 balrog
/* Get an array of words from main memory */
512 ac611340 aurel32
static inline int get_words(OHCIState *ohci,
513 ac611340 aurel32
                            uint32_t addr, uint16_t *buf, int num)
514 7bfe5777 balrog
{
515 7bfe5777 balrog
    int i;
516 7bfe5777 balrog
517 ac611340 aurel32
    addr += ohci->localmem_base;
518 ac611340 aurel32
519 7bfe5777 balrog
    for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
520 54f7b4a3 Stefan Weil
        cpu_physical_memory_read(addr, buf, sizeof(*buf));
521 7bfe5777 balrog
        *buf = le16_to_cpu(*buf);
522 7bfe5777 balrog
    }
523 7bfe5777 balrog
524 7bfe5777 balrog
    return 1;
525 7bfe5777 balrog
}
526 7bfe5777 balrog
527 7bfe5777 balrog
/* Put an array of words in to main memory */
528 ac611340 aurel32
static inline int put_words(OHCIState *ohci,
529 ac611340 aurel32
                            uint32_t addr, uint16_t *buf, int num)
530 7bfe5777 balrog
{
531 7bfe5777 balrog
    int i;
532 7bfe5777 balrog
533 ac611340 aurel32
    addr += ohci->localmem_base;
534 ac611340 aurel32
535 7bfe5777 balrog
    for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
536 7bfe5777 balrog
        uint16_t tmp = cpu_to_le16(*buf);
537 54f7b4a3 Stefan Weil
        cpu_physical_memory_write(addr, &tmp, sizeof(tmp));
538 7bfe5777 balrog
    }
539 7bfe5777 balrog
540 7bfe5777 balrog
    return 1;
541 7bfe5777 balrog
}
542 7bfe5777 balrog
543 ac611340 aurel32
static inline int ohci_read_ed(OHCIState *ohci,
544 ac611340 aurel32
                               uint32_t addr, struct ohci_ed *ed)
545 0d92ed30 pbrook
{
546 ac611340 aurel32
    return get_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2);
547 0d92ed30 pbrook
}
548 0d92ed30 pbrook
549 ac611340 aurel32
static inline int ohci_read_td(OHCIState *ohci,
550 ac611340 aurel32
                               uint32_t addr, struct ohci_td *td)
551 0d92ed30 pbrook
{
552 ac611340 aurel32
    return get_dwords(ohci, addr, (uint32_t *)td, sizeof(*td) >> 2);
553 0d92ed30 pbrook
}
554 0d92ed30 pbrook
555 ac611340 aurel32
static inline int ohci_read_iso_td(OHCIState *ohci,
556 ac611340 aurel32
                                   uint32_t addr, struct ohci_iso_td *td)
557 7bfe5777 balrog
{
558 ac611340 aurel32
    return (get_dwords(ohci, addr, (uint32_t *)td, 4) &&
559 ac611340 aurel32
            get_words(ohci, addr + 16, td->offset, 8));
560 7bfe5777 balrog
}
561 7bfe5777 balrog
562 ac611340 aurel32
static inline int ohci_read_hcca(OHCIState *ohci,
563 ac611340 aurel32
                                 uint32_t addr, struct ohci_hcca *hcca)
564 0d92ed30 pbrook
{
565 54f7b4a3 Stefan Weil
    cpu_physical_memory_read(addr + ohci->localmem_base, hcca, sizeof(*hcca));
566 ac611340 aurel32
    return 1;
567 0d92ed30 pbrook
}
568 0d92ed30 pbrook
569 ac611340 aurel32
static inline int ohci_put_ed(OHCIState *ohci,
570 ac611340 aurel32
                              uint32_t addr, struct ohci_ed *ed)
571 0d92ed30 pbrook
{
572 ac611340 aurel32
    return put_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2);
573 0d92ed30 pbrook
}
574 0d92ed30 pbrook
575 ac611340 aurel32
static inline int ohci_put_td(OHCIState *ohci,
576 ac611340 aurel32
                              uint32_t addr, struct ohci_td *td)
577 7bfe5777 balrog
{
578 ac611340 aurel32
    return put_dwords(ohci, addr, (uint32_t *)td, sizeof(*td) >> 2);
579 ac611340 aurel32
}
580 ac611340 aurel32
581 ac611340 aurel32
static inline int ohci_put_iso_td(OHCIState *ohci,
582 ac611340 aurel32
                                  uint32_t addr, struct ohci_iso_td *td)
583 ac611340 aurel32
{
584 ac611340 aurel32
    return (put_dwords(ohci, addr, (uint32_t *)td, 4) &&
585 ac611340 aurel32
            put_words(ohci, addr + 16, td->offset, 8));
586 ac611340 aurel32
}
587 ac611340 aurel32
588 ac611340 aurel32
static inline int ohci_put_hcca(OHCIState *ohci,
589 ac611340 aurel32
                                uint32_t addr, struct ohci_hcca *hcca)
590 ac611340 aurel32
{
591 54f7b4a3 Stefan Weil
    cpu_physical_memory_write(addr + ohci->localmem_base, hcca, sizeof(*hcca));
592 ac611340 aurel32
    return 1;
593 7bfe5777 balrog
}
594 7bfe5777 balrog
595 0d92ed30 pbrook
/* Read/Write the contents of a TD from/to main memory.  */
596 ac611340 aurel32
static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
597 ac611340 aurel32
                         uint8_t *buf, int len, int write)
598 0d92ed30 pbrook
{
599 0d92ed30 pbrook
    uint32_t ptr;
600 0d92ed30 pbrook
    uint32_t n;
601 0d92ed30 pbrook
602 0d92ed30 pbrook
    ptr = td->cbp;
603 0d92ed30 pbrook
    n = 0x1000 - (ptr & 0xfff);
604 0d92ed30 pbrook
    if (n > len)
605 0d92ed30 pbrook
        n = len;
606 ac611340 aurel32
    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write);
607 0d92ed30 pbrook
    if (n == len)
608 0d92ed30 pbrook
        return;
609 0d92ed30 pbrook
    ptr = td->be & ~0xfffu;
610 e6f3e5e0 pbrook
    buf += n;
611 ac611340 aurel32
    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write);
612 0d92ed30 pbrook
}
613 0d92ed30 pbrook
614 7bfe5777 balrog
/* Read/Write the contents of an ISO TD from/to main memory.  */
615 ac611340 aurel32
static void ohci_copy_iso_td(OHCIState *ohci,
616 ac611340 aurel32
                             uint32_t start_addr, uint32_t end_addr,
617 7bfe5777 balrog
                             uint8_t *buf, int len, int write)
618 7bfe5777 balrog
{
619 7bfe5777 balrog
    uint32_t ptr;
620 7bfe5777 balrog
    uint32_t n;
621 4d611c9a pbrook
622 7bfe5777 balrog
    ptr = start_addr;
623 7bfe5777 balrog
    n = 0x1000 - (ptr & 0xfff);
624 7bfe5777 balrog
    if (n > len)
625 7bfe5777 balrog
        n = len;
626 ac611340 aurel32
    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write);
627 7bfe5777 balrog
    if (n == len)
628 7bfe5777 balrog
        return;
629 7bfe5777 balrog
    ptr = end_addr & ~0xfffu;
630 7bfe5777 balrog
    buf += n;
631 ac611340 aurel32
    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write);
632 7bfe5777 balrog
}
633 7bfe5777 balrog
634 7bfe5777 balrog
static void ohci_process_lists(OHCIState *ohci, int completion);
635 7bfe5777 balrog
636 d47e59b8 Hans de Goede
static void ohci_async_complete_packet(USBPort *port, USBPacket *packet)
637 4d611c9a pbrook
{
638 9066df13 Gerd Hoffmann
    OHCIState *ohci = container_of(packet, OHCIState, usb_packet);
639 4d611c9a pbrook
#ifdef DEBUG_PACKET
640 d0f2c4c6 malc
    DPRINTF("Async packet complete\n");
641 4d611c9a pbrook
#endif
642 4d611c9a pbrook
    ohci->async_complete = 1;
643 7bfe5777 balrog
    ohci_process_lists(ohci, 1);
644 7bfe5777 balrog
}
645 7bfe5777 balrog
646 7bfe5777 balrog
#define USUB(a, b) ((int16_t)((uint16_t)(a) - (uint16_t)(b)))
647 7bfe5777 balrog
648 7bfe5777 balrog
static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
649 7bfe5777 balrog
                               int completion)
650 7bfe5777 balrog
{
651 7bfe5777 balrog
    int dir;
652 7bfe5777 balrog
    size_t len = 0;
653 d4c4e6fd Blue Swirl
#ifdef DEBUG_ISOCH
654 7ccfb2eb blueswir1
    const char *str = NULL;
655 d4c4e6fd Blue Swirl
#endif
656 7bfe5777 balrog
    int pid;
657 7bfe5777 balrog
    int ret;
658 7bfe5777 balrog
    int i;
659 7bfe5777 balrog
    USBDevice *dev;
660 079d0b7f Gerd Hoffmann
    USBEndpoint *ep;
661 7bfe5777 balrog
    struct ohci_iso_td iso_td;
662 7bfe5777 balrog
    uint32_t addr;
663 7bfe5777 balrog
    uint16_t starting_frame;
664 7bfe5777 balrog
    int16_t relative_frame_number;
665 7bfe5777 balrog
    int frame_count;
666 7bfe5777 balrog
    uint32_t start_offset, next_offset, end_offset = 0;
667 7bfe5777 balrog
    uint32_t start_addr, end_addr;
668 7bfe5777 balrog
669 7bfe5777 balrog
    addr = ed->head & OHCI_DPTR_MASK;
670 7bfe5777 balrog
671 ac611340 aurel32
    if (!ohci_read_iso_td(ohci, addr, &iso_td)) {
672 7bfe5777 balrog
        printf("usb-ohci: ISO_TD read error at %x\n", addr);
673 7bfe5777 balrog
        return 0;
674 7bfe5777 balrog
    }
675 7bfe5777 balrog
676 7bfe5777 balrog
    starting_frame = OHCI_BM(iso_td.flags, TD_SF);
677 7bfe5777 balrog
    frame_count = OHCI_BM(iso_td.flags, TD_FC);
678 7bfe5777 balrog
    relative_frame_number = USUB(ohci->frame_number, starting_frame); 
679 7bfe5777 balrog
680 7bfe5777 balrog
#ifdef DEBUG_ISOCH
681 7bfe5777 balrog
    printf("--- ISO_TD ED head 0x%.8x tailp 0x%.8x\n"
682 7bfe5777 balrog
           "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
683 7bfe5777 balrog
           "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
684 7bfe5777 balrog
           "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
685 7bfe5777 balrog
           "frame_number 0x%.8x starting_frame 0x%.8x\n"
686 7bfe5777 balrog
           "frame_count  0x%.8x relative %d\n"
687 7bfe5777 balrog
           "di 0x%.8x cc 0x%.8x\n",
688 7bfe5777 balrog
           ed->head & OHCI_DPTR_MASK, ed->tail & OHCI_DPTR_MASK,
689 7bfe5777 balrog
           iso_td.flags, iso_td.bp, iso_td.next, iso_td.be,
690 7bfe5777 balrog
           iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3],
691 7bfe5777 balrog
           iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7],
692 7bfe5777 balrog
           ohci->frame_number, starting_frame, 
693 7bfe5777 balrog
           frame_count, relative_frame_number,         
694 7bfe5777 balrog
           OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC));
695 7bfe5777 balrog
#endif
696 7bfe5777 balrog
697 7bfe5777 balrog
    if (relative_frame_number < 0) {
698 d0f2c4c6 malc
        DPRINTF("usb-ohci: ISO_TD R=%d < 0\n", relative_frame_number);
699 7bfe5777 balrog
        return 1;
700 7bfe5777 balrog
    } else if (relative_frame_number > frame_count) {
701 7bfe5777 balrog
        /* ISO TD expired - retire the TD to the Done Queue and continue with
702 7bfe5777 balrog
           the next ISO TD of the same ED */
703 d0f2c4c6 malc
        DPRINTF("usb-ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number, 
704 7bfe5777 balrog
               frame_count);
705 7bfe5777 balrog
        OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
706 7bfe5777 balrog
        ed->head &= ~OHCI_DPTR_MASK;
707 7bfe5777 balrog
        ed->head |= (iso_td.next & OHCI_DPTR_MASK);
708 7bfe5777 balrog
        iso_td.next = ohci->done;
709 7bfe5777 balrog
        ohci->done = addr;
710 7bfe5777 balrog
        i = OHCI_BM(iso_td.flags, TD_DI);
711 7bfe5777 balrog
        if (i < ohci->done_count)
712 7bfe5777 balrog
            ohci->done_count = i;
713 ac611340 aurel32
        ohci_put_iso_td(ohci, addr, &iso_td);
714 7bfe5777 balrog
        return 0;
715 7bfe5777 balrog
    }
716 7bfe5777 balrog
717 7bfe5777 balrog
    dir = OHCI_BM(ed->flags, ED_D);
718 7bfe5777 balrog
    switch (dir) {
719 7bfe5777 balrog
    case OHCI_TD_DIR_IN:
720 d4c4e6fd Blue Swirl
#ifdef DEBUG_ISOCH
721 7bfe5777 balrog
        str = "in";
722 d4c4e6fd Blue Swirl
#endif
723 7bfe5777 balrog
        pid = USB_TOKEN_IN;
724 7bfe5777 balrog
        break;
725 7bfe5777 balrog
    case OHCI_TD_DIR_OUT:
726 d4c4e6fd Blue Swirl
#ifdef DEBUG_ISOCH
727 7bfe5777 balrog
        str = "out";
728 d4c4e6fd Blue Swirl
#endif
729 7bfe5777 balrog
        pid = USB_TOKEN_OUT;
730 7bfe5777 balrog
        break;
731 7bfe5777 balrog
    case OHCI_TD_DIR_SETUP:
732 d4c4e6fd Blue Swirl
#ifdef DEBUG_ISOCH
733 7bfe5777 balrog
        str = "setup";
734 d4c4e6fd Blue Swirl
#endif
735 7bfe5777 balrog
        pid = USB_TOKEN_SETUP;
736 7bfe5777 balrog
        break;
737 7bfe5777 balrog
    default:
738 7bfe5777 balrog
        printf("usb-ohci: Bad direction %d\n", dir);
739 7bfe5777 balrog
        return 1;
740 7bfe5777 balrog
    }
741 7bfe5777 balrog
742 7bfe5777 balrog
    if (!iso_td.bp || !iso_td.be) {
743 7bfe5777 balrog
        printf("usb-ohci: ISO_TD bp 0x%.8x be 0x%.8x\n", iso_td.bp, iso_td.be);
744 7bfe5777 balrog
        return 1;
745 7bfe5777 balrog
    }
746 7bfe5777 balrog
747 7bfe5777 balrog
    start_offset = iso_td.offset[relative_frame_number];
748 7bfe5777 balrog
    next_offset = iso_td.offset[relative_frame_number + 1];
749 7bfe5777 balrog
750 7bfe5777 balrog
    if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) || 
751 7bfe5777 balrog
        ((relative_frame_number < frame_count) && 
752 7bfe5777 balrog
         !(OHCI_BM(next_offset, TD_PSW_CC) & 0xe))) {
753 7bfe5777 balrog
        printf("usb-ohci: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n",
754 7bfe5777 balrog
               start_offset, next_offset);
755 7bfe5777 balrog
        return 1;
756 7bfe5777 balrog
    }
757 7bfe5777 balrog
758 7bfe5777 balrog
    if ((relative_frame_number < frame_count) && (start_offset > next_offset)) {
759 7bfe5777 balrog
        printf("usb-ohci: ISO_TD start_offset=0x%.8x > next_offset=0x%.8x\n",
760 7bfe5777 balrog
                start_offset, next_offset);
761 7bfe5777 balrog
        return 1;
762 7bfe5777 balrog
    }
763 7bfe5777 balrog
764 7bfe5777 balrog
    if ((start_offset & 0x1000) == 0) {
765 7bfe5777 balrog
        start_addr = (iso_td.bp & OHCI_PAGE_MASK) |
766 7bfe5777 balrog
            (start_offset & OHCI_OFFSET_MASK);
767 7bfe5777 balrog
    } else {
768 7bfe5777 balrog
        start_addr = (iso_td.be & OHCI_PAGE_MASK) |
769 7bfe5777 balrog
            (start_offset & OHCI_OFFSET_MASK);
770 7bfe5777 balrog
    }
771 7bfe5777 balrog
772 7bfe5777 balrog
    if (relative_frame_number < frame_count) {
773 7bfe5777 balrog
        end_offset = next_offset - 1;
774 7bfe5777 balrog
        if ((end_offset & 0x1000) == 0) {
775 7bfe5777 balrog
            end_addr = (iso_td.bp & OHCI_PAGE_MASK) |
776 7bfe5777 balrog
                (end_offset & OHCI_OFFSET_MASK);
777 7bfe5777 balrog
        } else {
778 7bfe5777 balrog
            end_addr = (iso_td.be & OHCI_PAGE_MASK) |
779 7bfe5777 balrog
                (end_offset & OHCI_OFFSET_MASK);
780 7bfe5777 balrog
        }
781 7bfe5777 balrog
    } else {
782 7bfe5777 balrog
        /* Last packet in the ISO TD */
783 7bfe5777 balrog
        end_addr = iso_td.be;
784 7bfe5777 balrog
    }
785 7bfe5777 balrog
786 7bfe5777 balrog
    if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK)) {
787 7bfe5777 balrog
        len = (end_addr & OHCI_OFFSET_MASK) + 0x1001
788 7bfe5777 balrog
            - (start_addr & OHCI_OFFSET_MASK);
789 7bfe5777 balrog
    } else {
790 7bfe5777 balrog
        len = end_addr - start_addr + 1;
791 7bfe5777 balrog
    }
792 7bfe5777 balrog
793 7bfe5777 balrog
    if (len && dir != OHCI_TD_DIR_IN) {
794 ac611340 aurel32
        ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len, 0);
795 7bfe5777 balrog
    }
796 7bfe5777 balrog
797 7bfe5777 balrog
    if (completion) {
798 4f4321c1 Gerd Hoffmann
        ret = ohci->usb_packet.result;
799 7bfe5777 balrog
    } else {
800 079d0b7f Gerd Hoffmann
        dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA));
801 079d0b7f Gerd Hoffmann
        ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN));
802 079d0b7f Gerd Hoffmann
        usb_packet_setup(&ohci->usb_packet, pid, ep);
803 993048bb Gerd Hoffmann
        usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len);
804 993048bb Gerd Hoffmann
        ret = usb_handle_packet(dev, &ohci->usb_packet);
805 7bfe5777 balrog
        if (ret == USB_RET_ASYNC) {
806 7bfe5777 balrog
            return 1;
807 7bfe5777 balrog
        }
808 7bfe5777 balrog
    }
809 7bfe5777 balrog
810 7bfe5777 balrog
#ifdef DEBUG_ISOCH
811 7bfe5777 balrog
    printf("so 0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d\n",
812 7bfe5777 balrog
           start_offset, end_offset, start_addr, end_addr, str, len, ret);
813 7bfe5777 balrog
#endif
814 7bfe5777 balrog
815 7bfe5777 balrog
    /* Writeback */
816 7bfe5777 balrog
    if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) {
817 7bfe5777 balrog
        /* IN transfer succeeded */
818 ac611340 aurel32
        ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret, 1);
819 7bfe5777 balrog
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
820 7bfe5777 balrog
                    OHCI_CC_NOERROR);
821 7bfe5777 balrog
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret);
822 7bfe5777 balrog
    } else if (dir == OHCI_TD_DIR_OUT && ret == len) {
823 7bfe5777 balrog
        /* OUT transfer succeeded */
824 7bfe5777 balrog
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
825 7bfe5777 balrog
                    OHCI_CC_NOERROR);
826 7bfe5777 balrog
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 0);
827 7bfe5777 balrog
    } else {
828 87283515 balrog
        if (ret > (ssize_t) len) {
829 7bfe5777 balrog
            printf("usb-ohci: DataOverrun %d > %zu\n", ret, len);
830 7bfe5777 balrog
            OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
831 7bfe5777 balrog
                        OHCI_CC_DATAOVERRUN);
832 7bfe5777 balrog
            OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
833 7bfe5777 balrog
                        len);
834 7bfe5777 balrog
        } else if (ret >= 0) {
835 7bfe5777 balrog
            printf("usb-ohci: DataUnderrun %d\n", ret);
836 7bfe5777 balrog
            OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
837 7bfe5777 balrog
                        OHCI_CC_DATAUNDERRUN);
838 7bfe5777 balrog
        } else {
839 7bfe5777 balrog
            switch (ret) {
840 7bfe5777 balrog
            case USB_RET_NODEV:
841 7bfe5777 balrog
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
842 7bfe5777 balrog
                            OHCI_CC_DEVICENOTRESPONDING);
843 7bfe5777 balrog
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
844 7bfe5777 balrog
                            0);
845 7bfe5777 balrog
                break;
846 7bfe5777 balrog
            case USB_RET_NAK:
847 7bfe5777 balrog
            case USB_RET_STALL:
848 7bfe5777 balrog
                printf("usb-ohci: got NAK/STALL %d\n", ret);
849 7bfe5777 balrog
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
850 7bfe5777 balrog
                            OHCI_CC_STALL);
851 7bfe5777 balrog
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
852 7bfe5777 balrog
                            0);
853 7bfe5777 balrog
                break;
854 7bfe5777 balrog
            default:
855 7bfe5777 balrog
                printf("usb-ohci: Bad device response %d\n", ret);
856 7bfe5777 balrog
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
857 7bfe5777 balrog
                            OHCI_CC_UNDEXPETEDPID);
858 7bfe5777 balrog
                break;
859 7bfe5777 balrog
            }
860 7bfe5777 balrog
        }
861 7bfe5777 balrog
    }
862 7bfe5777 balrog
863 7bfe5777 balrog
    if (relative_frame_number == frame_count) {
864 7bfe5777 balrog
        /* Last data packet of ISO TD - retire the TD to the Done Queue */
865 7bfe5777 balrog
        OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_NOERROR);
866 7bfe5777 balrog
        ed->head &= ~OHCI_DPTR_MASK;
867 7bfe5777 balrog
        ed->head |= (iso_td.next & OHCI_DPTR_MASK);
868 7bfe5777 balrog
        iso_td.next = ohci->done;
869 7bfe5777 balrog
        ohci->done = addr;
870 7bfe5777 balrog
        i = OHCI_BM(iso_td.flags, TD_DI);
871 7bfe5777 balrog
        if (i < ohci->done_count)
872 7bfe5777 balrog
            ohci->done_count = i;
873 7bfe5777 balrog
    }
874 ac611340 aurel32
    ohci_put_iso_td(ohci, addr, &iso_td);
875 7bfe5777 balrog
    return 1;
876 4d611c9a pbrook
}
877 4d611c9a pbrook
878 0d92ed30 pbrook
/* Service a transport descriptor.
879 0d92ed30 pbrook
   Returns nonzero to terminate processing of this endpoint.  */
880 0d92ed30 pbrook
881 0d92ed30 pbrook
static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
882 0d92ed30 pbrook
{
883 0d92ed30 pbrook
    int dir;
884 905fb034 Peter Maydell
    size_t len = 0, pktlen = 0;
885 d4c4e6fd Blue Swirl
#ifdef DEBUG_PACKET
886 7ccfb2eb blueswir1
    const char *str = NULL;
887 d4c4e6fd Blue Swirl
#endif
888 0d92ed30 pbrook
    int pid;
889 0d92ed30 pbrook
    int ret;
890 0d92ed30 pbrook
    int i;
891 0d92ed30 pbrook
    USBDevice *dev;
892 079d0b7f Gerd Hoffmann
    USBEndpoint *ep;
893 0d92ed30 pbrook
    struct ohci_td td;
894 0d92ed30 pbrook
    uint32_t addr;
895 0d92ed30 pbrook
    int flag_r;
896 4d611c9a pbrook
    int completion;
897 0d92ed30 pbrook
898 0d92ed30 pbrook
    addr = ed->head & OHCI_DPTR_MASK;
899 4d611c9a pbrook
    /* See if this TD has already been submitted to the device.  */
900 4d611c9a pbrook
    completion = (addr == ohci->async_td);
901 4d611c9a pbrook
    if (completion && !ohci->async_complete) {
902 4d611c9a pbrook
#ifdef DEBUG_PACKET
903 d0f2c4c6 malc
        DPRINTF("Skipping async TD\n");
904 4d611c9a pbrook
#endif
905 4d611c9a pbrook
        return 1;
906 4d611c9a pbrook
    }
907 ac611340 aurel32
    if (!ohci_read_td(ohci, addr, &td)) {
908 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);
909 0d92ed30 pbrook
        return 0;
910 0d92ed30 pbrook
    }
911 0d92ed30 pbrook
912 0d92ed30 pbrook
    dir = OHCI_BM(ed->flags, ED_D);
913 0d92ed30 pbrook
    switch (dir) {
914 0d92ed30 pbrook
    case OHCI_TD_DIR_OUT:
915 0d92ed30 pbrook
    case OHCI_TD_DIR_IN:
916 0d92ed30 pbrook
        /* Same value.  */
917 0d92ed30 pbrook
        break;
918 0d92ed30 pbrook
    default:
919 0d92ed30 pbrook
        dir = OHCI_BM(td.flags, TD_DP);
920 0d92ed30 pbrook
        break;
921 0d92ed30 pbrook
    }
922 0d92ed30 pbrook
923 0d92ed30 pbrook
    switch (dir) {
924 0d92ed30 pbrook
    case OHCI_TD_DIR_IN:
925 d4c4e6fd Blue Swirl
#ifdef DEBUG_PACKET
926 0d92ed30 pbrook
        str = "in";
927 d4c4e6fd Blue Swirl
#endif
928 0d92ed30 pbrook
        pid = USB_TOKEN_IN;
929 0d92ed30 pbrook
        break;
930 0d92ed30 pbrook
    case OHCI_TD_DIR_OUT:
931 d4c4e6fd Blue Swirl
#ifdef DEBUG_PACKET
932 0d92ed30 pbrook
        str = "out";
933 d4c4e6fd Blue Swirl
#endif
934 0d92ed30 pbrook
        pid = USB_TOKEN_OUT;
935 0d92ed30 pbrook
        break;
936 0d92ed30 pbrook
    case OHCI_TD_DIR_SETUP:
937 d4c4e6fd Blue Swirl
#ifdef DEBUG_PACKET
938 0d92ed30 pbrook
        str = "setup";
939 d4c4e6fd Blue Swirl
#endif
940 0d92ed30 pbrook
        pid = USB_TOKEN_SETUP;
941 0d92ed30 pbrook
        break;
942 0d92ed30 pbrook
    default:
943 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: Bad direction\n");
944 0d92ed30 pbrook
        return 1;
945 0d92ed30 pbrook
    }
946 0d92ed30 pbrook
    if (td.cbp && td.be) {
947 e6f3e5e0 pbrook
        if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) {
948 e6f3e5e0 pbrook
            len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff);
949 e6f3e5e0 pbrook
        } else {
950 e6f3e5e0 pbrook
            len = (td.be - td.cbp) + 1;
951 e6f3e5e0 pbrook
        }
952 e6f3e5e0 pbrook
953 905fb034 Peter Maydell
        pktlen = len;
954 905fb034 Peter Maydell
        if (len && dir != OHCI_TD_DIR_IN) {
955 905fb034 Peter Maydell
            /* The endpoint may not allow us to transfer it all now */
956 905fb034 Peter Maydell
            pktlen = (ed->flags & OHCI_ED_MPS_MASK) >> OHCI_ED_MPS_SHIFT;
957 905fb034 Peter Maydell
            if (pktlen > len) {
958 905fb034 Peter Maydell
                pktlen = len;
959 905fb034 Peter Maydell
            }
960 905fb034 Peter Maydell
            if (!completion) {
961 905fb034 Peter Maydell
                ohci_copy_td(ohci, &td, ohci->usb_buf, pktlen, 0);
962 905fb034 Peter Maydell
            }
963 0d92ed30 pbrook
        }
964 0d92ed30 pbrook
    }
965 0d92ed30 pbrook
966 0d92ed30 pbrook
    flag_r = (td.flags & OHCI_TD_R) != 0;
967 0d92ed30 pbrook
#ifdef DEBUG_PACKET
968 905fb034 Peter Maydell
    DPRINTF(" TD @ 0x%.8x %" PRId64 " of %" PRId64
969 905fb034 Peter Maydell
            " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",
970 905fb034 Peter Maydell
            addr, (int64_t)pktlen, (int64_t)len, str, flag_r, td.cbp, td.be);
971 0d92ed30 pbrook
972 905fb034 Peter Maydell
    if (pktlen > 0 && dir != OHCI_TD_DIR_IN) {
973 d0f2c4c6 malc
        DPRINTF("  data:");
974 905fb034 Peter Maydell
        for (i = 0; i < pktlen; i++) {
975 4d611c9a pbrook
            printf(" %.2x", ohci->usb_buf[i]);
976 905fb034 Peter Maydell
        }
977 d0f2c4c6 malc
        DPRINTF("\n");
978 0d92ed30 pbrook
    }
979 0d92ed30 pbrook
#endif
980 4d611c9a pbrook
    if (completion) {
981 4f4321c1 Gerd Hoffmann
        ret = ohci->usb_packet.result;
982 4d611c9a pbrook
        ohci->async_td = 0;
983 4d611c9a pbrook
        ohci->async_complete = 0;
984 4d611c9a pbrook
    } else {
985 993048bb Gerd Hoffmann
        if (ohci->async_td) {
986 993048bb Gerd Hoffmann
            /* ??? The hardware should allow one active packet per
987 993048bb Gerd Hoffmann
               endpoint.  We only allow one active packet per controller.
988 993048bb Gerd Hoffmann
               This should be sufficient as long as devices respond in a
989 993048bb Gerd Hoffmann
               timely manner.
990 993048bb Gerd Hoffmann
            */
991 0d92ed30 pbrook
#ifdef DEBUG_PACKET
992 993048bb Gerd Hoffmann
            DPRINTF("Too many pending packets\n");
993 0d92ed30 pbrook
#endif
994 993048bb Gerd Hoffmann
            return 1;
995 4d611c9a pbrook
        }
996 079d0b7f Gerd Hoffmann
        dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA));
997 079d0b7f Gerd Hoffmann
        ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN));
998 079d0b7f Gerd Hoffmann
        usb_packet_setup(&ohci->usb_packet, pid, ep);
999 993048bb Gerd Hoffmann
        usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen);
1000 993048bb Gerd Hoffmann
        ret = usb_handle_packet(dev, &ohci->usb_packet);
1001 4d611c9a pbrook
#ifdef DEBUG_PACKET
1002 d0f2c4c6 malc
        DPRINTF("ret=%d\n", ret);
1003 4d611c9a pbrook
#endif
1004 4d611c9a pbrook
        if (ret == USB_RET_ASYNC) {
1005 4d611c9a pbrook
            ohci->async_td = addr;
1006 4d611c9a pbrook
            return 1;
1007 4d611c9a pbrook
        }
1008 4d611c9a pbrook
    }
1009 0d92ed30 pbrook
    if (ret >= 0) {
1010 0d92ed30 pbrook
        if (dir == OHCI_TD_DIR_IN) {
1011 ac611340 aurel32
            ohci_copy_td(ohci, &td, ohci->usb_buf, ret, 1);
1012 0d92ed30 pbrook
#ifdef DEBUG_PACKET
1013 d0f2c4c6 malc
            DPRINTF("  data:");
1014 0d92ed30 pbrook
            for (i = 0; i < ret; i++)
1015 4d611c9a pbrook
                printf(" %.2x", ohci->usb_buf[i]);
1016 d0f2c4c6 malc
            DPRINTF("\n");
1017 0d92ed30 pbrook
#endif
1018 0d92ed30 pbrook
        } else {
1019 905fb034 Peter Maydell
            ret = pktlen;
1020 0d92ed30 pbrook
        }
1021 0d92ed30 pbrook
    }
1022 0d92ed30 pbrook
1023 0d92ed30 pbrook
    /* Writeback */
1024 905fb034 Peter Maydell
    if (ret == pktlen || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) {
1025 0d92ed30 pbrook
        /* Transmission succeeded.  */
1026 0d92ed30 pbrook
        if (ret == len) {
1027 0d92ed30 pbrook
            td.cbp = 0;
1028 0d92ed30 pbrook
        } else {
1029 0d92ed30 pbrook
            if ((td.cbp & 0xfff) + ret > 0xfff) {
1030 fd891c93 Andriy Gapon
                td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);
1031 fd891c93 Andriy Gapon
            } else {
1032 fd891c93 Andriy Gapon
                td.cbp += ret;
1033 0d92ed30 pbrook
            }
1034 0d92ed30 pbrook
        }
1035 0d92ed30 pbrook
        td.flags |= OHCI_TD_T1;
1036 0d92ed30 pbrook
        td.flags ^= OHCI_TD_T0;
1037 0d92ed30 pbrook
        OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR);
1038 0d92ed30 pbrook
        OHCI_SET_BM(td.flags, TD_EC, 0);
1039 0d92ed30 pbrook
1040 905fb034 Peter Maydell
        if ((dir != OHCI_TD_DIR_IN) && (ret != len)) {
1041 905fb034 Peter Maydell
            /* Partial packet transfer: TD not ready to retire yet */
1042 905fb034 Peter Maydell
            goto exit_no_retire;
1043 905fb034 Peter Maydell
        }
1044 905fb034 Peter Maydell
1045 905fb034 Peter Maydell
        /* Setting ED_C is part of the TD retirement process */
1046 0d92ed30 pbrook
        ed->head &= ~OHCI_ED_C;
1047 0d92ed30 pbrook
        if (td.flags & OHCI_TD_T0)
1048 0d92ed30 pbrook
            ed->head |= OHCI_ED_C;
1049 0d92ed30 pbrook
    } else {
1050 0d92ed30 pbrook
        if (ret >= 0) {
1051 d0f2c4c6 malc
            DPRINTF("usb-ohci: Underrun\n");
1052 0d92ed30 pbrook
            OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN);
1053 0d92ed30 pbrook
        } else {
1054 0d92ed30 pbrook
            switch (ret) {
1055 0d92ed30 pbrook
            case USB_RET_NODEV:
1056 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);
1057 0d92ed30 pbrook
            case USB_RET_NAK:
1058 d0f2c4c6 malc
                DPRINTF("usb-ohci: got NAK\n");
1059 0d92ed30 pbrook
                return 1;
1060 0d92ed30 pbrook
            case USB_RET_STALL:
1061 d0f2c4c6 malc
                DPRINTF("usb-ohci: got STALL\n");
1062 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_STALL);
1063 0d92ed30 pbrook
                break;
1064 0d92ed30 pbrook
            case USB_RET_BABBLE:
1065 d0f2c4c6 malc
                DPRINTF("usb-ohci: got BABBLE\n");
1066 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
1067 0d92ed30 pbrook
                break;
1068 0d92ed30 pbrook
            default:
1069 0d92ed30 pbrook
                fprintf(stderr, "usb-ohci: Bad device response %d\n", ret);
1070 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_UNDEXPETEDPID);
1071 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_EC, 3);
1072 0d92ed30 pbrook
                break;
1073 0d92ed30 pbrook
            }
1074 0d92ed30 pbrook
        }
1075 0d92ed30 pbrook
        ed->head |= OHCI_ED_H;
1076 0d92ed30 pbrook
    }
1077 0d92ed30 pbrook
1078 0d92ed30 pbrook
    /* Retire this TD */
1079 0d92ed30 pbrook
    ed->head &= ~OHCI_DPTR_MASK;
1080 0d92ed30 pbrook
    ed->head |= td.next & OHCI_DPTR_MASK;
1081 0d92ed30 pbrook
    td.next = ohci->done;
1082 0d92ed30 pbrook
    ohci->done = addr;
1083 0d92ed30 pbrook
    i = OHCI_BM(td.flags, TD_DI);
1084 0d92ed30 pbrook
    if (i < ohci->done_count)
1085 0d92ed30 pbrook
        ohci->done_count = i;
1086 905fb034 Peter Maydell
exit_no_retire:
1087 ac611340 aurel32
    ohci_put_td(ohci, addr, &td);
1088 0d92ed30 pbrook
    return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;
1089 0d92ed30 pbrook
}
1090 0d92ed30 pbrook
1091 0d92ed30 pbrook
/* Service an endpoint list.  Returns nonzero if active TD were found.  */
1092 7bfe5777 balrog
static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
1093 0d92ed30 pbrook
{
1094 0d92ed30 pbrook
    struct ohci_ed ed;
1095 0d92ed30 pbrook
    uint32_t next_ed;
1096 0d92ed30 pbrook
    uint32_t cur;
1097 0d92ed30 pbrook
    int active;
1098 0d92ed30 pbrook
1099 0d92ed30 pbrook
    active = 0;
1100 0d92ed30 pbrook
1101 0d92ed30 pbrook
    if (head == 0)
1102 0d92ed30 pbrook
        return 0;
1103 0d92ed30 pbrook
1104 0d92ed30 pbrook
    for (cur = head; cur; cur = next_ed) {
1105 ac611340 aurel32
        if (!ohci_read_ed(ohci, cur, &ed)) {
1106 0d92ed30 pbrook
            fprintf(stderr, "usb-ohci: ED read error at %x\n", cur);
1107 0d92ed30 pbrook
            return 0;
1108 0d92ed30 pbrook
        }
1109 0d92ed30 pbrook
1110 0d92ed30 pbrook
        next_ed = ed.next & OHCI_DPTR_MASK;
1111 0d92ed30 pbrook
1112 4d611c9a pbrook
        if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
1113 4d611c9a pbrook
            uint32_t addr;
1114 4d611c9a pbrook
            /* Cancel pending packets for ED that have been paused.  */
1115 4d611c9a pbrook
            addr = ed.head & OHCI_DPTR_MASK;
1116 4d611c9a pbrook
            if (ohci->async_td && addr == ohci->async_td) {
1117 4d611c9a pbrook
                usb_cancel_packet(&ohci->usb_packet);
1118 4d611c9a pbrook
                ohci->async_td = 0;
1119 4d611c9a pbrook
            }
1120 0d92ed30 pbrook
            continue;
1121 4d611c9a pbrook
        }
1122 0d92ed30 pbrook
1123 0d92ed30 pbrook
        while ((ed.head & OHCI_DPTR_MASK) != ed.tail) {
1124 0d92ed30 pbrook
#ifdef DEBUG_PACKET
1125 d0f2c4c6 malc
            DPRINTF("ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u "
1126 0d92ed30 pbrook
                    "h=%u c=%u\n  head=0x%.8x tailp=0x%.8x next=0x%.8x\n", cur,
1127 0d92ed30 pbrook
                    OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN),
1128 0d92ed30 pbrook
                    OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S)!= 0,
1129 0d92ed30 pbrook
                    (ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0,
1130 0d92ed30 pbrook
                    OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0,
1131 0d92ed30 pbrook
                    (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK,
1132 0d92ed30 pbrook
                    ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK);
1133 0d92ed30 pbrook
#endif
1134 0d92ed30 pbrook
            active = 1;
1135 0d92ed30 pbrook
1136 7bfe5777 balrog
            if ((ed.flags & OHCI_ED_F) == 0) {
1137 7bfe5777 balrog
                if (ohci_service_td(ohci, &ed))
1138 7bfe5777 balrog
                    break;
1139 7bfe5777 balrog
            } else {
1140 7bfe5777 balrog
                /* Handle isochronous endpoints */
1141 7bfe5777 balrog
                if (ohci_service_iso_td(ohci, &ed, completion))
1142 7bfe5777 balrog
                    break;
1143 7bfe5777 balrog
            }
1144 0d92ed30 pbrook
        }
1145 0d92ed30 pbrook
1146 ac611340 aurel32
        ohci_put_ed(ohci, cur, &ed);
1147 0d92ed30 pbrook
    }
1148 0d92ed30 pbrook
1149 0d92ed30 pbrook
    return active;
1150 0d92ed30 pbrook
}
1151 0d92ed30 pbrook
1152 0d92ed30 pbrook
/* Generate a SOF event, and set a timer for EOF */
1153 0d92ed30 pbrook
static void ohci_sof(OHCIState *ohci)
1154 0d92ed30 pbrook
{
1155 74475455 Paolo Bonzini
    ohci->sof_time = qemu_get_clock_ns(vm_clock);
1156 0d92ed30 pbrook
    qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time);
1157 0d92ed30 pbrook
    ohci_set_interrupt(ohci, OHCI_INTR_SF);
1158 0d92ed30 pbrook
}
1159 0d92ed30 pbrook
1160 4d611c9a pbrook
/* Process Control and Bulk lists.  */
1161 7bfe5777 balrog
static void ohci_process_lists(OHCIState *ohci, int completion)
1162 4d611c9a pbrook
{
1163 4d611c9a pbrook
    if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) {
1164 6ad6135d Blue Swirl
        if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head) {
1165 6ad6135d Blue Swirl
            DPRINTF("usb-ohci: head %x, cur %x\n",
1166 6ad6135d Blue Swirl
                    ohci->ctrl_head, ohci->ctrl_cur);
1167 6ad6135d Blue Swirl
        }
1168 7bfe5777 balrog
        if (!ohci_service_ed_list(ohci, ohci->ctrl_head, completion)) {
1169 4d611c9a pbrook
            ohci->ctrl_cur = 0;
1170 4d611c9a pbrook
            ohci->status &= ~OHCI_STATUS_CLF;
1171 4d611c9a pbrook
        }
1172 4d611c9a pbrook
    }
1173 4d611c9a pbrook
1174 4d611c9a pbrook
    if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) {
1175 7bfe5777 balrog
        if (!ohci_service_ed_list(ohci, ohci->bulk_head, completion)) {
1176 4d611c9a pbrook
            ohci->bulk_cur = 0;
1177 4d611c9a pbrook
            ohci->status &= ~OHCI_STATUS_BLF;
1178 4d611c9a pbrook
        }
1179 4d611c9a pbrook
    }
1180 4d611c9a pbrook
}
1181 4d611c9a pbrook
1182 0d92ed30 pbrook
/* Do frame processing on frame boundary */
1183 0d92ed30 pbrook
static void ohci_frame_boundary(void *opaque)
1184 0d92ed30 pbrook
{
1185 0d92ed30 pbrook
    OHCIState *ohci = opaque;
1186 0d92ed30 pbrook
    struct ohci_hcca hcca;
1187 0d92ed30 pbrook
1188 ac611340 aurel32
    ohci_read_hcca(ohci, ohci->hcca, &hcca);
1189 0d92ed30 pbrook
1190 0d92ed30 pbrook
    /* Process all the lists at the end of the frame */
1191 0d92ed30 pbrook
    if (ohci->ctl & OHCI_CTL_PLE) {
1192 0d92ed30 pbrook
        int n;
1193 0d92ed30 pbrook
1194 0d92ed30 pbrook
        n = ohci->frame_number & 0x1f;
1195 7bfe5777 balrog
        ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]), 0);
1196 0d92ed30 pbrook
    }
1197 0d92ed30 pbrook
1198 4d611c9a pbrook
    /* Cancel all pending packets if either of the lists has been disabled.  */
1199 4d611c9a pbrook
    if (ohci->async_td &&
1200 4d611c9a pbrook
        ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
1201 4d611c9a pbrook
        usb_cancel_packet(&ohci->usb_packet);
1202 4d611c9a pbrook
        ohci->async_td = 0;
1203 0d92ed30 pbrook
    }
1204 4d611c9a pbrook
    ohci->old_ctl = ohci->ctl;
1205 7bfe5777 balrog
    ohci_process_lists(ohci, 0);
1206 0d92ed30 pbrook
1207 0d92ed30 pbrook
    /* Frame boundary, so do EOF stuf here */
1208 0d92ed30 pbrook
    ohci->frt = ohci->fit;
1209 0d92ed30 pbrook
1210 1fa63e43 Michael Buesch
    /* Increment frame number and take care of endianness. */
1211 0d92ed30 pbrook
    ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
1212 1fa63e43 Michael Buesch
    hcca.frame = cpu_to_le16(ohci->frame_number);
1213 0d92ed30 pbrook
1214 0d92ed30 pbrook
    if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
1215 0d92ed30 pbrook
        if (!ohci->done)
1216 0d92ed30 pbrook
            abort();
1217 0d92ed30 pbrook
        if (ohci->intr & ohci->intr_status)
1218 0d92ed30 pbrook
            ohci->done |= 1;
1219 0d92ed30 pbrook
        hcca.done = cpu_to_le32(ohci->done);
1220 0d92ed30 pbrook
        ohci->done = 0;
1221 0d92ed30 pbrook
        ohci->done_count = 7;
1222 0d92ed30 pbrook
        ohci_set_interrupt(ohci, OHCI_INTR_WD);
1223 0d92ed30 pbrook
    }
1224 0d92ed30 pbrook
1225 0d92ed30 pbrook
    if (ohci->done_count != 7 && ohci->done_count != 0)
1226 0d92ed30 pbrook
        ohci->done_count--;
1227 0d92ed30 pbrook
1228 0d92ed30 pbrook
    /* Do SOF stuff here */
1229 0d92ed30 pbrook
    ohci_sof(ohci);
1230 0d92ed30 pbrook
1231 0d92ed30 pbrook
    /* Writeback HCCA */
1232 ac611340 aurel32
    ohci_put_hcca(ohci, ohci->hcca, &hcca);
1233 0d92ed30 pbrook
}
1234 0d92ed30 pbrook
1235 0d92ed30 pbrook
/* Start sending SOF tokens across the USB bus, lists are processed in
1236 0d92ed30 pbrook
 * next frame
1237 0d92ed30 pbrook
 */
1238 0d92ed30 pbrook
static int ohci_bus_start(OHCIState *ohci)
1239 0d92ed30 pbrook
{
1240 74475455 Paolo Bonzini
    ohci->eof_timer = qemu_new_timer_ns(vm_clock,
1241 0d92ed30 pbrook
                    ohci_frame_boundary,
1242 0d92ed30 pbrook
                    ohci);
1243 0d92ed30 pbrook
1244 0d92ed30 pbrook
    if (ohci->eof_timer == NULL) {
1245 74475455 Paolo Bonzini
        fprintf(stderr, "usb-ohci: %s: qemu_new_timer_ns failed\n", ohci->name);
1246 0d92ed30 pbrook
        /* TODO: Signal unrecoverable error */
1247 0d92ed30 pbrook
        return 0;
1248 0d92ed30 pbrook
    }
1249 0d92ed30 pbrook
1250 d0f2c4c6 malc
    DPRINTF("usb-ohci: %s: USB Operational\n", ohci->name);
1251 0d92ed30 pbrook
1252 0d92ed30 pbrook
    ohci_sof(ohci);
1253 0d92ed30 pbrook
1254 0d92ed30 pbrook
    return 1;
1255 0d92ed30 pbrook
}
1256 0d92ed30 pbrook
1257 0d92ed30 pbrook
/* Stop sending SOF tokens on the bus */
1258 0d92ed30 pbrook
static void ohci_bus_stop(OHCIState *ohci)
1259 0d92ed30 pbrook
{
1260 0d92ed30 pbrook
    if (ohci->eof_timer)
1261 0d92ed30 pbrook
        qemu_del_timer(ohci->eof_timer);
1262 73221b12 ths
    ohci->eof_timer = NULL;
1263 0d92ed30 pbrook
}
1264 0d92ed30 pbrook
1265 0d92ed30 pbrook
/* Sets a flag in a port status register but only set it if the port is
1266 0d92ed30 pbrook
 * connected, if not set ConnectStatusChange flag. If flag is enabled
1267 0d92ed30 pbrook
 * return 1.
1268 0d92ed30 pbrook
 */
1269 0d92ed30 pbrook
static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val)
1270 0d92ed30 pbrook
{
1271 0d92ed30 pbrook
    int ret = 1;
1272 0d92ed30 pbrook
1273 0d92ed30 pbrook
    /* writing a 0 has no effect */
1274 0d92ed30 pbrook
    if (val == 0)
1275 0d92ed30 pbrook
        return 0;
1276 0d92ed30 pbrook
1277 0d92ed30 pbrook
    /* If CurrentConnectStatus is cleared we set
1278 0d92ed30 pbrook
     * ConnectStatusChange
1279 0d92ed30 pbrook
     */
1280 0d92ed30 pbrook
    if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) {
1281 0d92ed30 pbrook
        ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
1282 0d92ed30 pbrook
        if (ohci->rhstatus & OHCI_RHS_DRWE) {
1283 0d92ed30 pbrook
            /* TODO: CSC is a wakeup event */
1284 0d92ed30 pbrook
        }
1285 0d92ed30 pbrook
        return 0;
1286 0d92ed30 pbrook
    }
1287 0d92ed30 pbrook
1288 0d92ed30 pbrook
    if (ohci->rhport[i].ctrl & val)
1289 0d92ed30 pbrook
        ret = 0;
1290 0d92ed30 pbrook
1291 0d92ed30 pbrook
    /* set the bit */
1292 0d92ed30 pbrook
    ohci->rhport[i].ctrl |= val;
1293 0d92ed30 pbrook
1294 0d92ed30 pbrook
    return ret;
1295 0d92ed30 pbrook
}
1296 0d92ed30 pbrook
1297 0d92ed30 pbrook
/* Set the frame interval - frame interval toggle is manipulated by the hcd only */
1298 0d92ed30 pbrook
static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val)
1299 0d92ed30 pbrook
{
1300 0d92ed30 pbrook
    val &= OHCI_FMI_FI;
1301 0d92ed30 pbrook
1302 0d92ed30 pbrook
    if (val != ohci->fi) {
1303 d0f2c4c6 malc
        DPRINTF("usb-ohci: %s: FrameInterval = 0x%x (%u)\n",
1304 e24ad6f1 pbrook
            ohci->name, ohci->fi, ohci->fi);
1305 0d92ed30 pbrook
    }
1306 0d92ed30 pbrook
1307 0d92ed30 pbrook
    ohci->fi = val;
1308 0d92ed30 pbrook
}
1309 0d92ed30 pbrook
1310 0d92ed30 pbrook
static void ohci_port_power(OHCIState *ohci, int i, int p)
1311 0d92ed30 pbrook
{
1312 0d92ed30 pbrook
    if (p) {
1313 0d92ed30 pbrook
        ohci->rhport[i].ctrl |= OHCI_PORT_PPS;
1314 0d92ed30 pbrook
    } else {
1315 0d92ed30 pbrook
        ohci->rhport[i].ctrl &= ~(OHCI_PORT_PPS|
1316 0d92ed30 pbrook
                    OHCI_PORT_CCS|
1317 0d92ed30 pbrook
                    OHCI_PORT_PSS|
1318 0d92ed30 pbrook
                    OHCI_PORT_PRS);
1319 0d92ed30 pbrook
    }
1320 0d92ed30 pbrook
}
1321 0d92ed30 pbrook
1322 0d92ed30 pbrook
/* Set HcControlRegister */
1323 0d92ed30 pbrook
static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
1324 0d92ed30 pbrook
{
1325 0d92ed30 pbrook
    uint32_t old_state;
1326 0d92ed30 pbrook
    uint32_t new_state;
1327 0d92ed30 pbrook
1328 0d92ed30 pbrook
    old_state = ohci->ctl & OHCI_CTL_HCFS;
1329 0d92ed30 pbrook
    ohci->ctl = val;
1330 0d92ed30 pbrook
    new_state = ohci->ctl & OHCI_CTL_HCFS;
1331 0d92ed30 pbrook
1332 0d92ed30 pbrook
    /* no state change */
1333 0d92ed30 pbrook
    if (old_state == new_state)
1334 0d92ed30 pbrook
        return;
1335 0d92ed30 pbrook
1336 0d92ed30 pbrook
    switch (new_state) {
1337 0d92ed30 pbrook
    case OHCI_USB_OPERATIONAL:
1338 0d92ed30 pbrook
        ohci_bus_start(ohci);
1339 0d92ed30 pbrook
        break;
1340 0d92ed30 pbrook
    case OHCI_USB_SUSPEND:
1341 0d92ed30 pbrook
        ohci_bus_stop(ohci);
1342 d0f2c4c6 malc
        DPRINTF("usb-ohci: %s: USB Suspended\n", ohci->name);
1343 0d92ed30 pbrook
        break;
1344 0d92ed30 pbrook
    case OHCI_USB_RESUME:
1345 d0f2c4c6 malc
        DPRINTF("usb-ohci: %s: USB Resume\n", ohci->name);
1346 0d92ed30 pbrook
        break;
1347 0d92ed30 pbrook
    case OHCI_USB_RESET:
1348 73221b12 ths
        ohci_reset(ohci);
1349 d0f2c4c6 malc
        DPRINTF("usb-ohci: %s: USB Reset\n", ohci->name);
1350 0d92ed30 pbrook
        break;
1351 0d92ed30 pbrook
    }
1352 0d92ed30 pbrook
}
1353 0d92ed30 pbrook
1354 0d92ed30 pbrook
static uint32_t ohci_get_frame_remaining(OHCIState *ohci)
1355 0d92ed30 pbrook
{
1356 0d92ed30 pbrook
    uint16_t fr;
1357 0d92ed30 pbrook
    int64_t tks;
1358 0d92ed30 pbrook
1359 0d92ed30 pbrook
    if ((ohci->ctl & OHCI_CTL_HCFS) != OHCI_USB_OPERATIONAL)
1360 0d92ed30 pbrook
        return (ohci->frt << 31);
1361 0d92ed30 pbrook
1362 0d92ed30 pbrook
    /* Being in USB operational state guarnatees sof_time was
1363 0d92ed30 pbrook
     * set already.
1364 0d92ed30 pbrook
     */
1365 74475455 Paolo Bonzini
    tks = qemu_get_clock_ns(vm_clock) - ohci->sof_time;
1366 0d92ed30 pbrook
1367 0d92ed30 pbrook
    /* avoid muldiv if possible */
1368 0d92ed30 pbrook
    if (tks >= usb_frame_time)
1369 0d92ed30 pbrook
        return (ohci->frt << 31);
1370 0d92ed30 pbrook
1371 0d92ed30 pbrook
    tks = muldiv64(1, tks, usb_bit_time);
1372 0d92ed30 pbrook
    fr = (uint16_t)(ohci->fi - tks);
1373 0d92ed30 pbrook
1374 0d92ed30 pbrook
    return (ohci->frt << 31) | fr;
1375 0d92ed30 pbrook
}
1376 0d92ed30 pbrook
1377 0d92ed30 pbrook
1378 0d92ed30 pbrook
/* Set root hub status */
1379 0d92ed30 pbrook
static void ohci_set_hub_status(OHCIState *ohci, uint32_t val)
1380 0d92ed30 pbrook
{
1381 0d92ed30 pbrook
    uint32_t old_state;
1382 0d92ed30 pbrook
1383 0d92ed30 pbrook
    old_state = ohci->rhstatus;
1384 0d92ed30 pbrook
1385 0d92ed30 pbrook
    /* write 1 to clear OCIC */
1386 0d92ed30 pbrook
    if (val & OHCI_RHS_OCIC)
1387 0d92ed30 pbrook
        ohci->rhstatus &= ~OHCI_RHS_OCIC;
1388 0d92ed30 pbrook
1389 0d92ed30 pbrook
    if (val & OHCI_RHS_LPS) {
1390 0d92ed30 pbrook
        int i;
1391 0d92ed30 pbrook
1392 0d92ed30 pbrook
        for (i = 0; i < ohci->num_ports; i++)
1393 0d92ed30 pbrook
            ohci_port_power(ohci, i, 0);
1394 d0f2c4c6 malc
        DPRINTF("usb-ohci: powered down all ports\n");
1395 0d92ed30 pbrook
    }
1396 0d92ed30 pbrook
1397 0d92ed30 pbrook
    if (val & OHCI_RHS_LPSC) {
1398 0d92ed30 pbrook
        int i;
1399 0d92ed30 pbrook
1400 0d92ed30 pbrook
        for (i = 0; i < ohci->num_ports; i++)
1401 0d92ed30 pbrook
            ohci_port_power(ohci, i, 1);
1402 d0f2c4c6 malc
        DPRINTF("usb-ohci: powered up all ports\n");
1403 0d92ed30 pbrook
    }
1404 0d92ed30 pbrook
1405 0d92ed30 pbrook
    if (val & OHCI_RHS_DRWE)
1406 0d92ed30 pbrook
        ohci->rhstatus |= OHCI_RHS_DRWE;
1407 0d92ed30 pbrook
1408 0d92ed30 pbrook
    if (val & OHCI_RHS_CRWE)
1409 0d92ed30 pbrook
        ohci->rhstatus &= ~OHCI_RHS_DRWE;
1410 0d92ed30 pbrook
1411 0d92ed30 pbrook
    if (old_state != ohci->rhstatus)
1412 0d92ed30 pbrook
        ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
1413 0d92ed30 pbrook
}
1414 0d92ed30 pbrook
1415 0d92ed30 pbrook
/* Set root hub port status */
1416 0d92ed30 pbrook
static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
1417 0d92ed30 pbrook
{
1418 0d92ed30 pbrook
    uint32_t old_state;
1419 0d92ed30 pbrook
    OHCIPort *port;
1420 0d92ed30 pbrook
1421 0d92ed30 pbrook
    port = &ohci->rhport[portnum];
1422 0d92ed30 pbrook
    old_state = port->ctrl;
1423 0d92ed30 pbrook
1424 0d92ed30 pbrook
    /* Write to clear CSC, PESC, PSSC, OCIC, PRSC */
1425 0d92ed30 pbrook
    if (val & OHCI_PORT_WTC)
1426 0d92ed30 pbrook
        port->ctrl &= ~(val & OHCI_PORT_WTC);
1427 0d92ed30 pbrook
1428 0d92ed30 pbrook
    if (val & OHCI_PORT_CCS)
1429 0d92ed30 pbrook
        port->ctrl &= ~OHCI_PORT_PES;
1430 0d92ed30 pbrook
1431 0d92ed30 pbrook
    ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PES);
1432 0d92ed30 pbrook
1433 6ad6135d Blue Swirl
    if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PSS)) {
1434 d0f2c4c6 malc
        DPRINTF("usb-ohci: port %d: SUSPEND\n", portnum);
1435 6ad6135d Blue Swirl
    }
1436 0d92ed30 pbrook
1437 0d92ed30 pbrook
    if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) {
1438 d0f2c4c6 malc
        DPRINTF("usb-ohci: port %d: RESET\n", portnum);
1439 d28f4e2d Gerd Hoffmann
        usb_device_reset(port->port.dev);
1440 0d92ed30 pbrook
        port->ctrl &= ~OHCI_PORT_PRS;
1441 0d92ed30 pbrook
        /* ??? Should this also set OHCI_PORT_PESC.  */
1442 0d92ed30 pbrook
        port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC;
1443 0d92ed30 pbrook
    }
1444 0d92ed30 pbrook
1445 0d92ed30 pbrook
    /* Invert order here to ensure in ambiguous case, device is
1446 0d92ed30 pbrook
     * powered up...
1447 0d92ed30 pbrook
     */
1448 0d92ed30 pbrook
    if (val & OHCI_PORT_LSDA)
1449 0d92ed30 pbrook
        ohci_port_power(ohci, portnum, 0);
1450 0d92ed30 pbrook
    if (val & OHCI_PORT_PPS)
1451 0d92ed30 pbrook
        ohci_port_power(ohci, portnum, 1);
1452 0d92ed30 pbrook
1453 0d92ed30 pbrook
    if (old_state != port->ctrl)
1454 0d92ed30 pbrook
        ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
1455 0d92ed30 pbrook
1456 0d92ed30 pbrook
    return;
1457 0d92ed30 pbrook
}
1458 0d92ed30 pbrook
1459 6da48311 Avi Kivity
static uint64_t ohci_mem_read(void *opaque,
1460 6da48311 Avi Kivity
                              target_phys_addr_t addr,
1461 6da48311 Avi Kivity
                              unsigned size)
1462 0d92ed30 pbrook
{
1463 6da48311 Avi Kivity
    OHCIState *ohci = opaque;
1464 65e1d81b aurel32
    uint32_t retval;
1465 0d92ed30 pbrook
1466 0d92ed30 pbrook
    /* Only aligned reads are allowed on OHCI */
1467 0d92ed30 pbrook
    if (addr & 3) {
1468 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: Mis-aligned read\n");
1469 0d92ed30 pbrook
        return 0xffffffff;
1470 65e1d81b aurel32
    } else if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
1471 0d92ed30 pbrook
        /* HcRhPortStatus */
1472 65e1d81b aurel32
        retval = ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS;
1473 65e1d81b aurel32
    } else {
1474 65e1d81b aurel32
        switch (addr >> 2) {
1475 65e1d81b aurel32
        case 0: /* HcRevision */
1476 65e1d81b aurel32
            retval = 0x10;
1477 65e1d81b aurel32
            break;
1478 65e1d81b aurel32
1479 65e1d81b aurel32
        case 1: /* HcControl */
1480 65e1d81b aurel32
            retval = ohci->ctl;
1481 65e1d81b aurel32
            break;
1482 65e1d81b aurel32
1483 65e1d81b aurel32
        case 2: /* HcCommandStatus */
1484 65e1d81b aurel32
            retval = ohci->status;
1485 65e1d81b aurel32
            break;
1486 65e1d81b aurel32
1487 65e1d81b aurel32
        case 3: /* HcInterruptStatus */
1488 65e1d81b aurel32
            retval = ohci->intr_status;
1489 65e1d81b aurel32
            break;
1490 65e1d81b aurel32
1491 65e1d81b aurel32
        case 4: /* HcInterruptEnable */
1492 65e1d81b aurel32
        case 5: /* HcInterruptDisable */
1493 65e1d81b aurel32
            retval = ohci->intr;
1494 65e1d81b aurel32
            break;
1495 65e1d81b aurel32
1496 65e1d81b aurel32
        case 6: /* HcHCCA */
1497 65e1d81b aurel32
            retval = ohci->hcca;
1498 65e1d81b aurel32
            break;
1499 65e1d81b aurel32
1500 65e1d81b aurel32
        case 7: /* HcPeriodCurrentED */
1501 65e1d81b aurel32
            retval = ohci->per_cur;
1502 65e1d81b aurel32
            break;
1503 65e1d81b aurel32
1504 65e1d81b aurel32
        case 8: /* HcControlHeadED */
1505 65e1d81b aurel32
            retval = ohci->ctrl_head;
1506 65e1d81b aurel32
            break;
1507 65e1d81b aurel32
1508 65e1d81b aurel32
        case 9: /* HcControlCurrentED */
1509 65e1d81b aurel32
            retval = ohci->ctrl_cur;
1510 65e1d81b aurel32
            break;
1511 65e1d81b aurel32
1512 65e1d81b aurel32
        case 10: /* HcBulkHeadED */
1513 65e1d81b aurel32
            retval = ohci->bulk_head;
1514 65e1d81b aurel32
            break;
1515 65e1d81b aurel32
1516 65e1d81b aurel32
        case 11: /* HcBulkCurrentED */
1517 65e1d81b aurel32
            retval = ohci->bulk_cur;
1518 65e1d81b aurel32
            break;
1519 65e1d81b aurel32
1520 65e1d81b aurel32
        case 12: /* HcDoneHead */
1521 65e1d81b aurel32
            retval = ohci->done;
1522 65e1d81b aurel32
            break;
1523 65e1d81b aurel32
1524 65e1d81b aurel32
        case 13: /* HcFmInterretval */
1525 65e1d81b aurel32
            retval = (ohci->fit << 31) | (ohci->fsmps << 16) | (ohci->fi);
1526 65e1d81b aurel32
            break;
1527 65e1d81b aurel32
1528 65e1d81b aurel32
        case 14: /* HcFmRemaining */
1529 65e1d81b aurel32
            retval = ohci_get_frame_remaining(ohci);
1530 65e1d81b aurel32
            break;
1531 65e1d81b aurel32
1532 65e1d81b aurel32
        case 15: /* HcFmNumber */
1533 65e1d81b aurel32
            retval = ohci->frame_number;
1534 65e1d81b aurel32
            break;
1535 65e1d81b aurel32
1536 65e1d81b aurel32
        case 16: /* HcPeriodicStart */
1537 65e1d81b aurel32
            retval = ohci->pstart;
1538 65e1d81b aurel32
            break;
1539 65e1d81b aurel32
1540 65e1d81b aurel32
        case 17: /* HcLSThreshold */
1541 65e1d81b aurel32
            retval = ohci->lst;
1542 65e1d81b aurel32
            break;
1543 65e1d81b aurel32
1544 65e1d81b aurel32
        case 18: /* HcRhDescriptorA */
1545 65e1d81b aurel32
            retval = ohci->rhdesc_a;
1546 65e1d81b aurel32
            break;
1547 65e1d81b aurel32
1548 65e1d81b aurel32
        case 19: /* HcRhDescriptorB */
1549 65e1d81b aurel32
            retval = ohci->rhdesc_b;
1550 65e1d81b aurel32
            break;
1551 65e1d81b aurel32
1552 65e1d81b aurel32
        case 20: /* HcRhStatus */
1553 65e1d81b aurel32
            retval = ohci->rhstatus;
1554 65e1d81b aurel32
            break;
1555 65e1d81b aurel32
1556 65e1d81b aurel32
        /* PXA27x specific registers */
1557 65e1d81b aurel32
        case 24: /* HcStatus */
1558 65e1d81b aurel32
            retval = ohci->hstatus & ohci->hmask;
1559 65e1d81b aurel32
            break;
1560 65e1d81b aurel32
1561 65e1d81b aurel32
        case 25: /* HcHReset */
1562 65e1d81b aurel32
            retval = ohci->hreset;
1563 65e1d81b aurel32
            break;
1564 65e1d81b aurel32
1565 65e1d81b aurel32
        case 26: /* HcHInterruptEnable */
1566 65e1d81b aurel32
            retval = ohci->hmask;
1567 65e1d81b aurel32
            break;
1568 65e1d81b aurel32
1569 65e1d81b aurel32
        case 27: /* HcHInterruptTest */
1570 65e1d81b aurel32
            retval = ohci->htest;
1571 65e1d81b aurel32
            break;
1572 65e1d81b aurel32
1573 65e1d81b aurel32
        default:
1574 65e1d81b aurel32
            fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr);
1575 65e1d81b aurel32
            retval = 0xffffffff;
1576 65e1d81b aurel32
        }
1577 0d92ed30 pbrook
    }
1578 0d92ed30 pbrook
1579 65e1d81b aurel32
    return retval;
1580 0d92ed30 pbrook
}
1581 0d92ed30 pbrook
1582 6da48311 Avi Kivity
static void ohci_mem_write(void *opaque,
1583 6da48311 Avi Kivity
                           target_phys_addr_t addr,
1584 6da48311 Avi Kivity
                           uint64_t val,
1585 6da48311 Avi Kivity
                           unsigned size)
1586 0d92ed30 pbrook
{
1587 6da48311 Avi Kivity
    OHCIState *ohci = opaque;
1588 09564574 Paul Brook
1589 0d92ed30 pbrook
    /* Only aligned reads are allowed on OHCI */
1590 0d92ed30 pbrook
    if (addr & 3) {
1591 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: Mis-aligned write\n");
1592 0d92ed30 pbrook
        return;
1593 0d92ed30 pbrook
    }
1594 0d92ed30 pbrook
1595 0d92ed30 pbrook
    if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
1596 0d92ed30 pbrook
        /* HcRhPortStatus */
1597 0d92ed30 pbrook
        ohci_port_set_status(ohci, (addr - 0x54) >> 2, val);
1598 0d92ed30 pbrook
        return;
1599 0d92ed30 pbrook
    }
1600 0d92ed30 pbrook
1601 0d92ed30 pbrook
    switch (addr >> 2) {
1602 0d92ed30 pbrook
    case 1: /* HcControl */
1603 0d92ed30 pbrook
        ohci_set_ctl(ohci, val);
1604 0d92ed30 pbrook
        break;
1605 0d92ed30 pbrook
1606 0d92ed30 pbrook
    case 2: /* HcCommandStatus */
1607 0d92ed30 pbrook
        /* SOC is read-only */
1608 0d92ed30 pbrook
        val = (val & ~OHCI_STATUS_SOC);
1609 0d92ed30 pbrook
1610 0d92ed30 pbrook
        /* Bits written as '0' remain unchanged in the register */
1611 0d92ed30 pbrook
        ohci->status |= val;
1612 0d92ed30 pbrook
1613 0d92ed30 pbrook
        if (ohci->status & OHCI_STATUS_HCR)
1614 0d92ed30 pbrook
            ohci_reset(ohci);
1615 0d92ed30 pbrook
        break;
1616 0d92ed30 pbrook
1617 0d92ed30 pbrook
    case 3: /* HcInterruptStatus */
1618 0d92ed30 pbrook
        ohci->intr_status &= ~val;
1619 0d92ed30 pbrook
        ohci_intr_update(ohci);
1620 0d92ed30 pbrook
        break;
1621 0d92ed30 pbrook
1622 0d92ed30 pbrook
    case 4: /* HcInterruptEnable */
1623 0d92ed30 pbrook
        ohci->intr |= val;
1624 0d92ed30 pbrook
        ohci_intr_update(ohci);
1625 0d92ed30 pbrook
        break;
1626 0d92ed30 pbrook
1627 0d92ed30 pbrook
    case 5: /* HcInterruptDisable */
1628 0d92ed30 pbrook
        ohci->intr &= ~val;
1629 0d92ed30 pbrook
        ohci_intr_update(ohci);
1630 0d92ed30 pbrook
        break;
1631 0d92ed30 pbrook
1632 0d92ed30 pbrook
    case 6: /* HcHCCA */
1633 0d92ed30 pbrook
        ohci->hcca = val & OHCI_HCCA_MASK;
1634 0d92ed30 pbrook
        break;
1635 0d92ed30 pbrook
1636 4b0315d7 Peter Maydell
    case 7: /* HcPeriodCurrentED */
1637 4b0315d7 Peter Maydell
        /* Ignore writes to this read-only register, Linux does them */
1638 4b0315d7 Peter Maydell
        break;
1639 4b0315d7 Peter Maydell
1640 0d92ed30 pbrook
    case 8: /* HcControlHeadED */
1641 0d92ed30 pbrook
        ohci->ctrl_head = val & OHCI_EDPTR_MASK;
1642 0d92ed30 pbrook
        break;
1643 0d92ed30 pbrook
1644 0d92ed30 pbrook
    case 9: /* HcControlCurrentED */
1645 0d92ed30 pbrook
        ohci->ctrl_cur = val & OHCI_EDPTR_MASK;
1646 0d92ed30 pbrook
        break;
1647 0d92ed30 pbrook
1648 0d92ed30 pbrook
    case 10: /* HcBulkHeadED */
1649 0d92ed30 pbrook
        ohci->bulk_head = val & OHCI_EDPTR_MASK;
1650 0d92ed30 pbrook
        break;
1651 0d92ed30 pbrook
1652 0d92ed30 pbrook
    case 11: /* HcBulkCurrentED */
1653 0d92ed30 pbrook
        ohci->bulk_cur = val & OHCI_EDPTR_MASK;
1654 0d92ed30 pbrook
        break;
1655 0d92ed30 pbrook
1656 0d92ed30 pbrook
    case 13: /* HcFmInterval */
1657 0d92ed30 pbrook
        ohci->fsmps = (val & OHCI_FMI_FSMPS) >> 16;
1658 0d92ed30 pbrook
        ohci->fit = (val & OHCI_FMI_FIT) >> 31;
1659 0d92ed30 pbrook
        ohci_set_frame_interval(ohci, val);
1660 0d92ed30 pbrook
        break;
1661 0d92ed30 pbrook
1662 7bfe5777 balrog
    case 15: /* HcFmNumber */
1663 7bfe5777 balrog
        break;
1664 7bfe5777 balrog
1665 0d92ed30 pbrook
    case 16: /* HcPeriodicStart */
1666 0d92ed30 pbrook
        ohci->pstart = val & 0xffff;
1667 0d92ed30 pbrook
        break;
1668 0d92ed30 pbrook
1669 0d92ed30 pbrook
    case 17: /* HcLSThreshold */
1670 0d92ed30 pbrook
        ohci->lst = val & 0xffff;
1671 0d92ed30 pbrook
        break;
1672 0d92ed30 pbrook
1673 0d92ed30 pbrook
    case 18: /* HcRhDescriptorA */
1674 0d92ed30 pbrook
        ohci->rhdesc_a &= ~OHCI_RHA_RW_MASK;
1675 0d92ed30 pbrook
        ohci->rhdesc_a |= val & OHCI_RHA_RW_MASK;
1676 0d92ed30 pbrook
        break;
1677 0d92ed30 pbrook
1678 0d92ed30 pbrook
    case 19: /* HcRhDescriptorB */
1679 0d92ed30 pbrook
        break;
1680 0d92ed30 pbrook
1681 0d92ed30 pbrook
    case 20: /* HcRhStatus */
1682 0d92ed30 pbrook
        ohci_set_hub_status(ohci, val);
1683 0d92ed30 pbrook
        break;
1684 0d92ed30 pbrook
1685 e24ad6f1 pbrook
    /* PXA27x specific registers */
1686 e24ad6f1 pbrook
    case 24: /* HcStatus */
1687 e24ad6f1 pbrook
        ohci->hstatus &= ~(val & ohci->hmask);
1688 e24ad6f1 pbrook
1689 e24ad6f1 pbrook
    case 25: /* HcHReset */
1690 e24ad6f1 pbrook
        ohci->hreset = val & ~OHCI_HRESET_FSBIR;
1691 e24ad6f1 pbrook
        if (val & OHCI_HRESET_FSBIR)
1692 e24ad6f1 pbrook
            ohci_reset(ohci);
1693 e24ad6f1 pbrook
        break;
1694 e24ad6f1 pbrook
1695 e24ad6f1 pbrook
    case 26: /* HcHInterruptEnable */
1696 e24ad6f1 pbrook
        ohci->hmask = val;
1697 e24ad6f1 pbrook
        break;
1698 e24ad6f1 pbrook
1699 e24ad6f1 pbrook
    case 27: /* HcHInterruptTest */
1700 e24ad6f1 pbrook
        ohci->htest = val;
1701 e24ad6f1 pbrook
        break;
1702 e24ad6f1 pbrook
1703 0d92ed30 pbrook
    default:
1704 0d92ed30 pbrook
        fprintf(stderr, "ohci_write: Bad offset %x\n", (int)addr);
1705 0d92ed30 pbrook
        break;
1706 0d92ed30 pbrook
    }
1707 0d92ed30 pbrook
}
1708 0d92ed30 pbrook
1709 4706ab6c Hans de Goede
static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev)
1710 07771f6f Gerd Hoffmann
{
1711 25d5de7d Gerd Hoffmann
    if (ohci->async_td &&
1712 f53c398a Gerd Hoffmann
        usb_packet_is_inflight(&ohci->usb_packet) &&
1713 f53c398a Gerd Hoffmann
        ohci->usb_packet.ep->dev == dev) {
1714 07771f6f Gerd Hoffmann
        usb_cancel_packet(&ohci->usb_packet);
1715 07771f6f Gerd Hoffmann
        ohci->async_td = 0;
1716 07771f6f Gerd Hoffmann
    }
1717 07771f6f Gerd Hoffmann
}
1718 07771f6f Gerd Hoffmann
1719 6da48311 Avi Kivity
static const MemoryRegionOps ohci_mem_ops = {
1720 6da48311 Avi Kivity
    .read = ohci_mem_read,
1721 6da48311 Avi Kivity
    .write = ohci_mem_write,
1722 6da48311 Avi Kivity
    .endianness = DEVICE_LITTLE_ENDIAN,
1723 0d92ed30 pbrook
};
1724 0d92ed30 pbrook
1725 0d86d2be Gerd Hoffmann
static USBPortOps ohci_port_ops = {
1726 0d86d2be Gerd Hoffmann
    .attach = ohci_attach,
1727 618c169b Gerd Hoffmann
    .detach = ohci_detach,
1728 4706ab6c Hans de Goede
    .child_detach = ohci_child_detach,
1729 9bba1eb1 Peter Maydell
    .wakeup = ohci_wakeup,
1730 13a9a0d3 Gerd Hoffmann
    .complete = ohci_async_complete_packet,
1731 0d86d2be Gerd Hoffmann
};
1732 0d86d2be Gerd Hoffmann
1733 07771f6f Gerd Hoffmann
static USBBusOps ohci_bus_ops = {
1734 07771f6f Gerd Hoffmann
};
1735 07771f6f Gerd Hoffmann
1736 9c9fc334 Hans de Goede
static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
1737 9c9fc334 Hans de Goede
                         int num_ports, uint32_t localmem_base,
1738 9c9fc334 Hans de Goede
                         char *masterbus, uint32_t firstport)
1739 0d92ed30 pbrook
{
1740 0d92ed30 pbrook
    int i;
1741 0d92ed30 pbrook
1742 0d92ed30 pbrook
    if (usb_frame_time == 0) {
1743 eb38c52c blueswir1
#ifdef OHCI_TIME_WARP
1744 6ee093c9 Juan Quintela
        usb_frame_time = get_ticks_per_sec();
1745 6ee093c9 Juan Quintela
        usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ/1000);
1746 0d92ed30 pbrook
#else
1747 6ee093c9 Juan Quintela
        usb_frame_time = muldiv64(1, get_ticks_per_sec(), 1000);
1748 6ee093c9 Juan Quintela
        if (get_ticks_per_sec() >= USB_HZ) {
1749 6ee093c9 Juan Quintela
            usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ);
1750 0d92ed30 pbrook
        } else {
1751 0d92ed30 pbrook
            usb_bit_time = 1;
1752 0d92ed30 pbrook
        }
1753 0d92ed30 pbrook
#endif
1754 d0f2c4c6 malc
        DPRINTF("usb-ohci: usb_bit_time=%" PRId64 " usb_frame_time=%" PRId64 "\n",
1755 0d92ed30 pbrook
                usb_frame_time, usb_bit_time);
1756 0d92ed30 pbrook
    }
1757 0d92ed30 pbrook
1758 9c9fc334 Hans de Goede
    ohci->num_ports = num_ports;
1759 9c9fc334 Hans de Goede
    if (masterbus) {
1760 9c9fc334 Hans de Goede
        USBPort *ports[OHCI_MAX_PORTS];
1761 9c9fc334 Hans de Goede
        for(i = 0; i < num_ports; i++) {
1762 9c9fc334 Hans de Goede
            ports[i] = &ohci->rhport[i].port;
1763 9c9fc334 Hans de Goede
        }
1764 9c9fc334 Hans de Goede
        if (usb_register_companion(masterbus, ports, num_ports,
1765 9c9fc334 Hans de Goede
                firstport, ohci, &ohci_port_ops,
1766 9c9fc334 Hans de Goede
                USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) {
1767 9c9fc334 Hans de Goede
            return -1;
1768 9c9fc334 Hans de Goede
        }
1769 9c9fc334 Hans de Goede
    } else {
1770 9c9fc334 Hans de Goede
        usb_bus_new(&ohci->bus, &ohci_bus_ops, dev);
1771 9c9fc334 Hans de Goede
        for (i = 0; i < num_ports; i++) {
1772 9c9fc334 Hans de Goede
            usb_register_port(&ohci->bus, &ohci->rhport[i].port,
1773 9c9fc334 Hans de Goede
                              ohci, i, &ohci_port_ops,
1774 9c9fc334 Hans de Goede
                              USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
1775 9c9fc334 Hans de Goede
        }
1776 9c9fc334 Hans de Goede
    }
1777 9c9fc334 Hans de Goede
1778 6da48311 Avi Kivity
    memory_region_init_io(&ohci->mem, &ohci_mem_ops, ohci, "ohci", 256);
1779 ac611340 aurel32
    ohci->localmem_base = localmem_base;
1780 e24ad6f1 pbrook
1781 f79f2bfc Anthony Liguori
    ohci->name = object_get_typename(OBJECT(dev));
1782 4f4321c1 Gerd Hoffmann
    usb_packet_init(&ohci->usb_packet);
1783 e24ad6f1 pbrook
1784 e24ad6f1 pbrook
    ohci->async_td = 0;
1785 a08d4367 Jan Kiszka
    qemu_register_reset(ohci_reset, ohci);
1786 9c9fc334 Hans de Goede
1787 9c9fc334 Hans de Goede
    return 0;
1788 e24ad6f1 pbrook
}
1789 e24ad6f1 pbrook
1790 e24ad6f1 pbrook
typedef struct {
1791 e24ad6f1 pbrook
    PCIDevice pci_dev;
1792 e24ad6f1 pbrook
    OHCIState state;
1793 9c9fc334 Hans de Goede
    char *masterbus;
1794 9c9fc334 Hans de Goede
    uint32_t num_ports;
1795 9c9fc334 Hans de Goede
    uint32_t firstport;
1796 e24ad6f1 pbrook
} OHCIPCIState;
1797 e24ad6f1 pbrook
1798 5b19d9a2 Gerd Hoffmann
static int usb_ohci_initfn_pci(struct PCIDevice *dev)
1799 e24ad6f1 pbrook
{
1800 5b19d9a2 Gerd Hoffmann
    OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev);
1801 0d92ed30 pbrook
1802 d74dbb94 Michael S. Tsirkin
    ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */
1803 817e0b6f Michael S. Tsirkin
    ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
1804 0d92ed30 pbrook
1805 9c9fc334 Hans de Goede
    if (usb_ohci_init(&ohci->state, &dev->qdev, ohci->num_ports, 0,
1806 9c9fc334 Hans de Goede
                      ohci->masterbus, ohci->firstport) != 0) {
1807 9c9fc334 Hans de Goede
        return -1;
1808 9c9fc334 Hans de Goede
    }
1809 61d3cf93 Paul Brook
    ohci->state.irq = ohci->pci_dev.irq[0];
1810 0d92ed30 pbrook
1811 d74dbb94 Michael S. Tsirkin
    /* TODO: avoid cast below by using dev */
1812 e824b2cc Avi Kivity
    pci_register_bar(&ohci->pci_dev, 0, 0, &ohci->state.mem);
1813 5b19d9a2 Gerd Hoffmann
    return 0;
1814 5b19d9a2 Gerd Hoffmann
}
1815 5b19d9a2 Gerd Hoffmann
1816 a67ba3b6 Paul Brook
void usb_ohci_init_pci(struct PCIBus *bus, int devfn)
1817 5b19d9a2 Gerd Hoffmann
{
1818 a67ba3b6 Paul Brook
    pci_create_simple(bus, devfn, "pci-ohci");
1819 e24ad6f1 pbrook
}
1820 0d92ed30 pbrook
1821 61d3cf93 Paul Brook
typedef struct {
1822 61d3cf93 Paul Brook
    SysBusDevice busdev;
1823 61d3cf93 Paul Brook
    OHCIState ohci;
1824 61d3cf93 Paul Brook
    uint32_t num_ports;
1825 61d3cf93 Paul Brook
    target_phys_addr_t dma_offset;
1826 61d3cf93 Paul Brook
} OHCISysBusState;
1827 ac611340 aurel32
1828 61d3cf93 Paul Brook
static int ohci_init_pxa(SysBusDevice *dev)
1829 ac611340 aurel32
{
1830 61d3cf93 Paul Brook
    OHCISysBusState *s = FROM_SYSBUS(OHCISysBusState, dev);
1831 ac611340 aurel32
1832 9c9fc334 Hans de Goede
    /* Cannot fail as we pass NULL for masterbus */
1833 9c9fc334 Hans de Goede
    usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset, NULL, 0);
1834 61d3cf93 Paul Brook
    sysbus_init_irq(dev, &s->ohci.irq);
1835 750ecd44 Avi Kivity
    sysbus_init_mmio(dev, &s->ohci.mem);
1836 ac611340 aurel32
1837 61d3cf93 Paul Brook
    return 0;
1838 ac611340 aurel32
}
1839 ac611340 aurel32
1840 40021f08 Anthony Liguori
static Property ohci_pci_properties[] = {
1841 40021f08 Anthony Liguori
    DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus),
1842 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3),
1843 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0),
1844 40021f08 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
1845 40021f08 Anthony Liguori
};
1846 40021f08 Anthony Liguori
1847 40021f08 Anthony Liguori
static void ohci_pci_class_init(ObjectClass *klass, void *data)
1848 40021f08 Anthony Liguori
{
1849 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
1850 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1851 40021f08 Anthony Liguori
1852 40021f08 Anthony Liguori
    k->init = usb_ohci_initfn_pci;
1853 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_APPLE;
1854 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB;
1855 40021f08 Anthony Liguori
    k->class_id = PCI_CLASS_SERIAL_USB;
1856 39bffca2 Anthony Liguori
    dc->desc = "Apple USB Controller";
1857 39bffca2 Anthony Liguori
    dc->props = ohci_pci_properties;
1858 40021f08 Anthony Liguori
}
1859 40021f08 Anthony Liguori
1860 39bffca2 Anthony Liguori
static TypeInfo ohci_pci_info = {
1861 39bffca2 Anthony Liguori
    .name          = "pci-ohci",
1862 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
1863 39bffca2 Anthony Liguori
    .instance_size = sizeof(OHCIPCIState),
1864 39bffca2 Anthony Liguori
    .class_init    = ohci_pci_class_init,
1865 39bffca2 Anthony Liguori
};
1866 39bffca2 Anthony Liguori
1867 39bffca2 Anthony Liguori
static Property ohci_sysbus_properties[] = {
1868 39bffca2 Anthony Liguori
    DEFINE_PROP_UINT32("num-ports", OHCISysBusState, num_ports, 3),
1869 39bffca2 Anthony Liguori
    DEFINE_PROP_TADDR("dma-offset", OHCISysBusState, dma_offset, 3),
1870 39bffca2 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
1871 5b19d9a2 Gerd Hoffmann
};
1872 5b19d9a2 Gerd Hoffmann
1873 999e12bb Anthony Liguori
static void ohci_sysbus_class_init(ObjectClass *klass, void *data)
1874 999e12bb Anthony Liguori
{
1875 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
1876 999e12bb Anthony Liguori
    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
1877 999e12bb Anthony Liguori
1878 999e12bb Anthony Liguori
    sbc->init = ohci_init_pxa;
1879 39bffca2 Anthony Liguori
    dc->desc = "OHCI USB Controller";
1880 39bffca2 Anthony Liguori
    dc->props = ohci_sysbus_properties;
1881 999e12bb Anthony Liguori
}
1882 999e12bb Anthony Liguori
1883 39bffca2 Anthony Liguori
static TypeInfo ohci_sysbus_info = {
1884 39bffca2 Anthony Liguori
    .name          = "sysbus-ohci",
1885 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
1886 39bffca2 Anthony Liguori
    .instance_size = sizeof(OHCISysBusState),
1887 39bffca2 Anthony Liguori
    .class_init    = ohci_sysbus_class_init,
1888 61d3cf93 Paul Brook
};
1889 61d3cf93 Paul Brook
1890 5b19d9a2 Gerd Hoffmann
static void ohci_register(void)
1891 5b19d9a2 Gerd Hoffmann
{
1892 39bffca2 Anthony Liguori
    type_register_static(&ohci_pci_info);
1893 39bffca2 Anthony Liguori
    type_register_static(&ohci_sysbus_info);
1894 5b19d9a2 Gerd Hoffmann
}
1895 5b19d9a2 Gerd Hoffmann
device_init(ohci_register);