Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ 913895ab

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