Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ 310faaed

History | View | Annotate | Download (49.9 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 54f7b4a3 Stefan Weil
        cpu_physical_memory_read(addr, buf, sizeof(*buf));
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 54f7b4a3 Stefan Weil
        cpu_physical_memory_write(addr, &tmp, sizeof(tmp));
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 54f7b4a3 Stefan Weil
        cpu_physical_memory_read(addr, buf, sizeof(*buf));
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 54f7b4a3 Stefan Weil
        cpu_physical_memory_write(addr, &tmp, sizeof(tmp));
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 54f7b4a3 Stefan Weil
    cpu_physical_memory_read(addr + ohci->localmem_base, hcca, sizeof(*hcca));
508 ac611340 aurel32
    return 1;
509 0d92ed30 pbrook
}
510 0d92ed30 pbrook
511 ac611340 aurel32
static inline int ohci_put_ed(OHCIState *ohci,
512 ac611340 aurel32
                              uint32_t addr, struct ohci_ed *ed)
513 0d92ed30 pbrook
{
514 ac611340 aurel32
    return put_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2);
515 0d92ed30 pbrook
}
516 0d92ed30 pbrook
517 ac611340 aurel32
static inline int ohci_put_td(OHCIState *ohci,
518 ac611340 aurel32
                              uint32_t addr, struct ohci_td *td)
519 7bfe5777 balrog
{
520 ac611340 aurel32
    return put_dwords(ohci, addr, (uint32_t *)td, sizeof(*td) >> 2);
521 ac611340 aurel32
}
522 ac611340 aurel32
523 ac611340 aurel32
static inline int ohci_put_iso_td(OHCIState *ohci,
524 ac611340 aurel32
                                  uint32_t addr, struct ohci_iso_td *td)
525 ac611340 aurel32
{
526 ac611340 aurel32
    return (put_dwords(ohci, addr, (uint32_t *)td, 4) &&
527 ac611340 aurel32
            put_words(ohci, addr + 16, td->offset, 8));
528 ac611340 aurel32
}
529 ac611340 aurel32
530 ac611340 aurel32
static inline int ohci_put_hcca(OHCIState *ohci,
531 ac611340 aurel32
                                uint32_t addr, struct ohci_hcca *hcca)
532 ac611340 aurel32
{
533 54f7b4a3 Stefan Weil
    cpu_physical_memory_write(addr + ohci->localmem_base, hcca, sizeof(*hcca));
534 ac611340 aurel32
    return 1;
535 7bfe5777 balrog
}
536 7bfe5777 balrog
537 0d92ed30 pbrook
/* Read/Write the contents of a TD from/to main memory.  */
538 ac611340 aurel32
static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
539 ac611340 aurel32
                         uint8_t *buf, int len, int write)
540 0d92ed30 pbrook
{
541 0d92ed30 pbrook
    uint32_t ptr;
542 0d92ed30 pbrook
    uint32_t n;
543 0d92ed30 pbrook
544 0d92ed30 pbrook
    ptr = td->cbp;
545 0d92ed30 pbrook
    n = 0x1000 - (ptr & 0xfff);
546 0d92ed30 pbrook
    if (n > len)
547 0d92ed30 pbrook
        n = len;
548 ac611340 aurel32
    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write);
549 0d92ed30 pbrook
    if (n == len)
550 0d92ed30 pbrook
        return;
551 0d92ed30 pbrook
    ptr = td->be & ~0xfffu;
552 e6f3e5e0 pbrook
    buf += n;
553 ac611340 aurel32
    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write);
554 0d92ed30 pbrook
}
555 0d92ed30 pbrook
556 7bfe5777 balrog
/* Read/Write the contents of an ISO TD from/to main memory.  */
557 ac611340 aurel32
static void ohci_copy_iso_td(OHCIState *ohci,
558 ac611340 aurel32
                             uint32_t start_addr, uint32_t end_addr,
559 7bfe5777 balrog
                             uint8_t *buf, int len, int write)
560 7bfe5777 balrog
{
561 7bfe5777 balrog
    uint32_t ptr;
562 7bfe5777 balrog
    uint32_t n;
563 4d611c9a pbrook
564 7bfe5777 balrog
    ptr = start_addr;
565 7bfe5777 balrog
    n = 0x1000 - (ptr & 0xfff);
566 7bfe5777 balrog
    if (n > len)
567 7bfe5777 balrog
        n = len;
568 ac611340 aurel32
    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write);
569 7bfe5777 balrog
    if (n == len)
570 7bfe5777 balrog
        return;
571 7bfe5777 balrog
    ptr = end_addr & ~0xfffu;
572 7bfe5777 balrog
    buf += n;
573 ac611340 aurel32
    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write);
574 7bfe5777 balrog
}
575 7bfe5777 balrog
576 7bfe5777 balrog
static void ohci_process_lists(OHCIState *ohci, int completion);
577 7bfe5777 balrog
578 7bfe5777 balrog
static void ohci_async_complete_packet(USBPacket *packet, void *opaque)
579 4d611c9a pbrook
{
580 4d611c9a pbrook
    OHCIState *ohci = opaque;
581 4d611c9a pbrook
#ifdef DEBUG_PACKET
582 d0f2c4c6 malc
    DPRINTF("Async packet complete\n");
583 4d611c9a pbrook
#endif
584 4d611c9a pbrook
    ohci->async_complete = 1;
585 7bfe5777 balrog
    ohci_process_lists(ohci, 1);
586 7bfe5777 balrog
}
587 7bfe5777 balrog
588 7bfe5777 balrog
#define USUB(a, b) ((int16_t)((uint16_t)(a) - (uint16_t)(b)))
589 7bfe5777 balrog
590 7bfe5777 balrog
static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
591 7bfe5777 balrog
                               int completion)
592 7bfe5777 balrog
{
593 7bfe5777 balrog
    int dir;
594 7bfe5777 balrog
    size_t len = 0;
595 d4c4e6fd Blue Swirl
#ifdef DEBUG_ISOCH
596 7ccfb2eb blueswir1
    const char *str = NULL;
597 d4c4e6fd Blue Swirl
#endif
598 7bfe5777 balrog
    int pid;
599 7bfe5777 balrog
    int ret;
600 7bfe5777 balrog
    int i;
601 7bfe5777 balrog
    USBDevice *dev;
602 7bfe5777 balrog
    struct ohci_iso_td iso_td;
603 7bfe5777 balrog
    uint32_t addr;
604 7bfe5777 balrog
    uint16_t starting_frame;
605 7bfe5777 balrog
    int16_t relative_frame_number;
606 7bfe5777 balrog
    int frame_count;
607 7bfe5777 balrog
    uint32_t start_offset, next_offset, end_offset = 0;
608 7bfe5777 balrog
    uint32_t start_addr, end_addr;
609 7bfe5777 balrog
610 7bfe5777 balrog
    addr = ed->head & OHCI_DPTR_MASK;
611 7bfe5777 balrog
612 ac611340 aurel32
    if (!ohci_read_iso_td(ohci, addr, &iso_td)) {
613 7bfe5777 balrog
        printf("usb-ohci: ISO_TD read error at %x\n", addr);
614 7bfe5777 balrog
        return 0;
615 7bfe5777 balrog
    }
616 7bfe5777 balrog
617 7bfe5777 balrog
    starting_frame = OHCI_BM(iso_td.flags, TD_SF);
618 7bfe5777 balrog
    frame_count = OHCI_BM(iso_td.flags, TD_FC);
619 7bfe5777 balrog
    relative_frame_number = USUB(ohci->frame_number, starting_frame); 
620 7bfe5777 balrog
621 7bfe5777 balrog
#ifdef DEBUG_ISOCH
622 7bfe5777 balrog
    printf("--- ISO_TD ED head 0x%.8x tailp 0x%.8x\n"
623 7bfe5777 balrog
           "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
624 7bfe5777 balrog
           "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
625 7bfe5777 balrog
           "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
626 7bfe5777 balrog
           "frame_number 0x%.8x starting_frame 0x%.8x\n"
627 7bfe5777 balrog
           "frame_count  0x%.8x relative %d\n"
628 7bfe5777 balrog
           "di 0x%.8x cc 0x%.8x\n",
629 7bfe5777 balrog
           ed->head & OHCI_DPTR_MASK, ed->tail & OHCI_DPTR_MASK,
630 7bfe5777 balrog
           iso_td.flags, iso_td.bp, iso_td.next, iso_td.be,
631 7bfe5777 balrog
           iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3],
632 7bfe5777 balrog
           iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7],
633 7bfe5777 balrog
           ohci->frame_number, starting_frame, 
634 7bfe5777 balrog
           frame_count, relative_frame_number,         
635 7bfe5777 balrog
           OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC));
636 7bfe5777 balrog
#endif
637 7bfe5777 balrog
638 7bfe5777 balrog
    if (relative_frame_number < 0) {
639 d0f2c4c6 malc
        DPRINTF("usb-ohci: ISO_TD R=%d < 0\n", relative_frame_number);
640 7bfe5777 balrog
        return 1;
641 7bfe5777 balrog
    } else if (relative_frame_number > frame_count) {
642 7bfe5777 balrog
        /* ISO TD expired - retire the TD to the Done Queue and continue with
643 7bfe5777 balrog
           the next ISO TD of the same ED */
644 d0f2c4c6 malc
        DPRINTF("usb-ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number, 
645 7bfe5777 balrog
               frame_count);
646 7bfe5777 balrog
        OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
647 7bfe5777 balrog
        ed->head &= ~OHCI_DPTR_MASK;
648 7bfe5777 balrog
        ed->head |= (iso_td.next & OHCI_DPTR_MASK);
649 7bfe5777 balrog
        iso_td.next = ohci->done;
650 7bfe5777 balrog
        ohci->done = addr;
651 7bfe5777 balrog
        i = OHCI_BM(iso_td.flags, TD_DI);
652 7bfe5777 balrog
        if (i < ohci->done_count)
653 7bfe5777 balrog
            ohci->done_count = i;
654 ac611340 aurel32
        ohci_put_iso_td(ohci, addr, &iso_td);
655 7bfe5777 balrog
        return 0;
656 7bfe5777 balrog
    }
657 7bfe5777 balrog
658 7bfe5777 balrog
    dir = OHCI_BM(ed->flags, ED_D);
659 7bfe5777 balrog
    switch (dir) {
660 7bfe5777 balrog
    case OHCI_TD_DIR_IN:
661 d4c4e6fd Blue Swirl
#ifdef DEBUG_ISOCH
662 7bfe5777 balrog
        str = "in";
663 d4c4e6fd Blue Swirl
#endif
664 7bfe5777 balrog
        pid = USB_TOKEN_IN;
665 7bfe5777 balrog
        break;
666 7bfe5777 balrog
    case OHCI_TD_DIR_OUT:
667 d4c4e6fd Blue Swirl
#ifdef DEBUG_ISOCH
668 7bfe5777 balrog
        str = "out";
669 d4c4e6fd Blue Swirl
#endif
670 7bfe5777 balrog
        pid = USB_TOKEN_OUT;
671 7bfe5777 balrog
        break;
672 7bfe5777 balrog
    case OHCI_TD_DIR_SETUP:
673 d4c4e6fd Blue Swirl
#ifdef DEBUG_ISOCH
674 7bfe5777 balrog
        str = "setup";
675 d4c4e6fd Blue Swirl
#endif
676 7bfe5777 balrog
        pid = USB_TOKEN_SETUP;
677 7bfe5777 balrog
        break;
678 7bfe5777 balrog
    default:
679 7bfe5777 balrog
        printf("usb-ohci: Bad direction %d\n", dir);
680 7bfe5777 balrog
        return 1;
681 7bfe5777 balrog
    }
682 7bfe5777 balrog
683 7bfe5777 balrog
    if (!iso_td.bp || !iso_td.be) {
684 7bfe5777 balrog
        printf("usb-ohci: ISO_TD bp 0x%.8x be 0x%.8x\n", iso_td.bp, iso_td.be);
685 7bfe5777 balrog
        return 1;
686 7bfe5777 balrog
    }
687 7bfe5777 balrog
688 7bfe5777 balrog
    start_offset = iso_td.offset[relative_frame_number];
689 7bfe5777 balrog
    next_offset = iso_td.offset[relative_frame_number + 1];
690 7bfe5777 balrog
691 7bfe5777 balrog
    if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) || 
692 7bfe5777 balrog
        ((relative_frame_number < frame_count) && 
693 7bfe5777 balrog
         !(OHCI_BM(next_offset, TD_PSW_CC) & 0xe))) {
694 7bfe5777 balrog
        printf("usb-ohci: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n",
695 7bfe5777 balrog
               start_offset, next_offset);
696 7bfe5777 balrog
        return 1;
697 7bfe5777 balrog
    }
698 7bfe5777 balrog
699 7bfe5777 balrog
    if ((relative_frame_number < frame_count) && (start_offset > next_offset)) {
700 7bfe5777 balrog
        printf("usb-ohci: ISO_TD start_offset=0x%.8x > next_offset=0x%.8x\n",
701 7bfe5777 balrog
                start_offset, next_offset);
702 7bfe5777 balrog
        return 1;
703 7bfe5777 balrog
    }
704 7bfe5777 balrog
705 7bfe5777 balrog
    if ((start_offset & 0x1000) == 0) {
706 7bfe5777 balrog
        start_addr = (iso_td.bp & OHCI_PAGE_MASK) |
707 7bfe5777 balrog
            (start_offset & OHCI_OFFSET_MASK);
708 7bfe5777 balrog
    } else {
709 7bfe5777 balrog
        start_addr = (iso_td.be & OHCI_PAGE_MASK) |
710 7bfe5777 balrog
            (start_offset & OHCI_OFFSET_MASK);
711 7bfe5777 balrog
    }
712 7bfe5777 balrog
713 7bfe5777 balrog
    if (relative_frame_number < frame_count) {
714 7bfe5777 balrog
        end_offset = next_offset - 1;
715 7bfe5777 balrog
        if ((end_offset & 0x1000) == 0) {
716 7bfe5777 balrog
            end_addr = (iso_td.bp & OHCI_PAGE_MASK) |
717 7bfe5777 balrog
                (end_offset & OHCI_OFFSET_MASK);
718 7bfe5777 balrog
        } else {
719 7bfe5777 balrog
            end_addr = (iso_td.be & OHCI_PAGE_MASK) |
720 7bfe5777 balrog
                (end_offset & OHCI_OFFSET_MASK);
721 7bfe5777 balrog
        }
722 7bfe5777 balrog
    } else {
723 7bfe5777 balrog
        /* Last packet in the ISO TD */
724 7bfe5777 balrog
        end_addr = iso_td.be;
725 7bfe5777 balrog
    }
726 7bfe5777 balrog
727 7bfe5777 balrog
    if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK)) {
728 7bfe5777 balrog
        len = (end_addr & OHCI_OFFSET_MASK) + 0x1001
729 7bfe5777 balrog
            - (start_addr & OHCI_OFFSET_MASK);
730 7bfe5777 balrog
    } else {
731 7bfe5777 balrog
        len = end_addr - start_addr + 1;
732 7bfe5777 balrog
    }
733 7bfe5777 balrog
734 7bfe5777 balrog
    if (len && dir != OHCI_TD_DIR_IN) {
735 ac611340 aurel32
        ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len, 0);
736 7bfe5777 balrog
    }
737 7bfe5777 balrog
738 7bfe5777 balrog
    if (completion) {
739 7bfe5777 balrog
        ret = ohci->usb_packet.len;
740 7bfe5777 balrog
    } else {
741 7bfe5777 balrog
        ret = USB_RET_NODEV;
742 7bfe5777 balrog
        for (i = 0; i < ohci->num_ports; i++) {
743 7bfe5777 balrog
            dev = ohci->rhport[i].port.dev;
744 7bfe5777 balrog
            if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
745 7bfe5777 balrog
                continue;
746 7bfe5777 balrog
            ohci->usb_packet.pid = pid;
747 7bfe5777 balrog
            ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
748 7bfe5777 balrog
            ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
749 7bfe5777 balrog
            ohci->usb_packet.data = ohci->usb_buf;
750 7bfe5777 balrog
            ohci->usb_packet.len = len;
751 7bfe5777 balrog
            ohci->usb_packet.complete_cb = ohci_async_complete_packet;
752 7bfe5777 balrog
            ohci->usb_packet.complete_opaque = ohci;
753 806b6024 Gerd Hoffmann
            ret = dev->info->handle_packet(dev, &ohci->usb_packet);
754 7bfe5777 balrog
            if (ret != USB_RET_NODEV)
755 7bfe5777 balrog
                break;
756 7bfe5777 balrog
        }
757 7bfe5777 balrog
    
758 7bfe5777 balrog
        if (ret == USB_RET_ASYNC) {
759 7bfe5777 balrog
            return 1;
760 7bfe5777 balrog
        }
761 7bfe5777 balrog
    }
762 7bfe5777 balrog
763 7bfe5777 balrog
#ifdef DEBUG_ISOCH
764 7bfe5777 balrog
    printf("so 0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d\n",
765 7bfe5777 balrog
           start_offset, end_offset, start_addr, end_addr, str, len, ret);
766 7bfe5777 balrog
#endif
767 7bfe5777 balrog
768 7bfe5777 balrog
    /* Writeback */
769 7bfe5777 balrog
    if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) {
770 7bfe5777 balrog
        /* IN transfer succeeded */
771 ac611340 aurel32
        ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret, 1);
772 7bfe5777 balrog
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
773 7bfe5777 balrog
                    OHCI_CC_NOERROR);
774 7bfe5777 balrog
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret);
775 7bfe5777 balrog
    } else if (dir == OHCI_TD_DIR_OUT && ret == len) {
776 7bfe5777 balrog
        /* OUT transfer succeeded */
777 7bfe5777 balrog
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
778 7bfe5777 balrog
                    OHCI_CC_NOERROR);
779 7bfe5777 balrog
        OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 0);
780 7bfe5777 balrog
    } else {
781 87283515 balrog
        if (ret > (ssize_t) len) {
782 7bfe5777 balrog
            printf("usb-ohci: DataOverrun %d > %zu\n", ret, len);
783 7bfe5777 balrog
            OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
784 7bfe5777 balrog
                        OHCI_CC_DATAOVERRUN);
785 7bfe5777 balrog
            OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
786 7bfe5777 balrog
                        len);
787 7bfe5777 balrog
        } else if (ret >= 0) {
788 7bfe5777 balrog
            printf("usb-ohci: DataUnderrun %d\n", ret);
789 7bfe5777 balrog
            OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
790 7bfe5777 balrog
                        OHCI_CC_DATAUNDERRUN);
791 7bfe5777 balrog
        } else {
792 7bfe5777 balrog
            switch (ret) {
793 7bfe5777 balrog
            case USB_RET_NODEV:
794 7bfe5777 balrog
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
795 7bfe5777 balrog
                            OHCI_CC_DEVICENOTRESPONDING);
796 7bfe5777 balrog
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
797 7bfe5777 balrog
                            0);
798 7bfe5777 balrog
                break;
799 7bfe5777 balrog
            case USB_RET_NAK:
800 7bfe5777 balrog
            case USB_RET_STALL:
801 7bfe5777 balrog
                printf("usb-ohci: got NAK/STALL %d\n", ret);
802 7bfe5777 balrog
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
803 7bfe5777 balrog
                            OHCI_CC_STALL);
804 7bfe5777 balrog
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
805 7bfe5777 balrog
                            0);
806 7bfe5777 balrog
                break;
807 7bfe5777 balrog
            default:
808 7bfe5777 balrog
                printf("usb-ohci: Bad device response %d\n", ret);
809 7bfe5777 balrog
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
810 7bfe5777 balrog
                            OHCI_CC_UNDEXPETEDPID);
811 7bfe5777 balrog
                break;
812 7bfe5777 balrog
            }
813 7bfe5777 balrog
        }
814 7bfe5777 balrog
    }
815 7bfe5777 balrog
816 7bfe5777 balrog
    if (relative_frame_number == frame_count) {
817 7bfe5777 balrog
        /* Last data packet of ISO TD - retire the TD to the Done Queue */
818 7bfe5777 balrog
        OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_NOERROR);
819 7bfe5777 balrog
        ed->head &= ~OHCI_DPTR_MASK;
820 7bfe5777 balrog
        ed->head |= (iso_td.next & OHCI_DPTR_MASK);
821 7bfe5777 balrog
        iso_td.next = ohci->done;
822 7bfe5777 balrog
        ohci->done = addr;
823 7bfe5777 balrog
        i = OHCI_BM(iso_td.flags, TD_DI);
824 7bfe5777 balrog
        if (i < ohci->done_count)
825 7bfe5777 balrog
            ohci->done_count = i;
826 7bfe5777 balrog
    }
827 ac611340 aurel32
    ohci_put_iso_td(ohci, addr, &iso_td);
828 7bfe5777 balrog
    return 1;
829 4d611c9a pbrook
}
830 4d611c9a pbrook
831 0d92ed30 pbrook
/* Service a transport descriptor.
832 0d92ed30 pbrook
   Returns nonzero to terminate processing of this endpoint.  */
833 0d92ed30 pbrook
834 0d92ed30 pbrook
static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
835 0d92ed30 pbrook
{
836 0d92ed30 pbrook
    int dir;
837 0d92ed30 pbrook
    size_t len = 0;
838 d4c4e6fd Blue Swirl
#ifdef DEBUG_PACKET
839 7ccfb2eb blueswir1
    const char *str = NULL;
840 d4c4e6fd Blue Swirl
#endif
841 0d92ed30 pbrook
    int pid;
842 0d92ed30 pbrook
    int ret;
843 0d92ed30 pbrook
    int i;
844 0d92ed30 pbrook
    USBDevice *dev;
845 0d92ed30 pbrook
    struct ohci_td td;
846 0d92ed30 pbrook
    uint32_t addr;
847 0d92ed30 pbrook
    int flag_r;
848 4d611c9a pbrook
    int completion;
849 0d92ed30 pbrook
850 0d92ed30 pbrook
    addr = ed->head & OHCI_DPTR_MASK;
851 4d611c9a pbrook
    /* See if this TD has already been submitted to the device.  */
852 4d611c9a pbrook
    completion = (addr == ohci->async_td);
853 4d611c9a pbrook
    if (completion && !ohci->async_complete) {
854 4d611c9a pbrook
#ifdef DEBUG_PACKET
855 d0f2c4c6 malc
        DPRINTF("Skipping async TD\n");
856 4d611c9a pbrook
#endif
857 4d611c9a pbrook
        return 1;
858 4d611c9a pbrook
    }
859 ac611340 aurel32
    if (!ohci_read_td(ohci, addr, &td)) {
860 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);
861 0d92ed30 pbrook
        return 0;
862 0d92ed30 pbrook
    }
863 0d92ed30 pbrook
864 0d92ed30 pbrook
    dir = OHCI_BM(ed->flags, ED_D);
865 0d92ed30 pbrook
    switch (dir) {
866 0d92ed30 pbrook
    case OHCI_TD_DIR_OUT:
867 0d92ed30 pbrook
    case OHCI_TD_DIR_IN:
868 0d92ed30 pbrook
        /* Same value.  */
869 0d92ed30 pbrook
        break;
870 0d92ed30 pbrook
    default:
871 0d92ed30 pbrook
        dir = OHCI_BM(td.flags, TD_DP);
872 0d92ed30 pbrook
        break;
873 0d92ed30 pbrook
    }
874 0d92ed30 pbrook
875 0d92ed30 pbrook
    switch (dir) {
876 0d92ed30 pbrook
    case OHCI_TD_DIR_IN:
877 d4c4e6fd Blue Swirl
#ifdef DEBUG_PACKET
878 0d92ed30 pbrook
        str = "in";
879 d4c4e6fd Blue Swirl
#endif
880 0d92ed30 pbrook
        pid = USB_TOKEN_IN;
881 0d92ed30 pbrook
        break;
882 0d92ed30 pbrook
    case OHCI_TD_DIR_OUT:
883 d4c4e6fd Blue Swirl
#ifdef DEBUG_PACKET
884 0d92ed30 pbrook
        str = "out";
885 d4c4e6fd Blue Swirl
#endif
886 0d92ed30 pbrook
        pid = USB_TOKEN_OUT;
887 0d92ed30 pbrook
        break;
888 0d92ed30 pbrook
    case OHCI_TD_DIR_SETUP:
889 d4c4e6fd Blue Swirl
#ifdef DEBUG_PACKET
890 0d92ed30 pbrook
        str = "setup";
891 d4c4e6fd Blue Swirl
#endif
892 0d92ed30 pbrook
        pid = USB_TOKEN_SETUP;
893 0d92ed30 pbrook
        break;
894 0d92ed30 pbrook
    default:
895 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: Bad direction\n");
896 0d92ed30 pbrook
        return 1;
897 0d92ed30 pbrook
    }
898 0d92ed30 pbrook
    if (td.cbp && td.be) {
899 e6f3e5e0 pbrook
        if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) {
900 e6f3e5e0 pbrook
            len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff);
901 e6f3e5e0 pbrook
        } else {
902 e6f3e5e0 pbrook
            len = (td.be - td.cbp) + 1;
903 e6f3e5e0 pbrook
        }
904 e6f3e5e0 pbrook
905 4d611c9a pbrook
        if (len && dir != OHCI_TD_DIR_IN && !completion) {
906 ac611340 aurel32
            ohci_copy_td(ohci, &td, ohci->usb_buf, len, 0);
907 0d92ed30 pbrook
        }
908 0d92ed30 pbrook
    }
909 0d92ed30 pbrook
910 0d92ed30 pbrook
    flag_r = (td.flags & OHCI_TD_R) != 0;
911 0d92ed30 pbrook
#ifdef DEBUG_PACKET
912 d0f2c4c6 malc
    DPRINTF(" TD @ 0x%.8x %" PRId64 " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",
913 f3571b1a Max Reitz
            addr, (int64_t)len, str, flag_r, td.cbp, td.be);
914 0d92ed30 pbrook
915 87283515 balrog
    if (len > 0 && dir != OHCI_TD_DIR_IN) {
916 d0f2c4c6 malc
        DPRINTF("  data:");
917 0d92ed30 pbrook
        for (i = 0; i < len; i++)
918 4d611c9a pbrook
            printf(" %.2x", ohci->usb_buf[i]);
919 d0f2c4c6 malc
        DPRINTF("\n");
920 0d92ed30 pbrook
    }
921 0d92ed30 pbrook
#endif
922 4d611c9a pbrook
    if (completion) {
923 4d611c9a pbrook
        ret = ohci->usb_packet.len;
924 4d611c9a pbrook
        ohci->async_td = 0;
925 4d611c9a pbrook
        ohci->async_complete = 0;
926 4d611c9a pbrook
    } else {
927 4d611c9a pbrook
        ret = USB_RET_NODEV;
928 4d611c9a pbrook
        for (i = 0; i < ohci->num_ports; i++) {
929 4d611c9a pbrook
            dev = ohci->rhport[i].port.dev;
930 4d611c9a pbrook
            if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
931 4d611c9a pbrook
                continue;
932 4d611c9a pbrook
933 4d611c9a pbrook
            if (ohci->async_td) {
934 4d611c9a pbrook
                /* ??? The hardware should allow one active packet per
935 4d611c9a pbrook
                   endpoint.  We only allow one active packet per controller.
936 4d611c9a pbrook
                   This should be sufficient as long as devices respond in a
937 4d611c9a pbrook
                   timely manner.
938 4d611c9a pbrook
                 */
939 0d92ed30 pbrook
#ifdef DEBUG_PACKET
940 d0f2c4c6 malc
                DPRINTF("Too many pending packets\n");
941 0d92ed30 pbrook
#endif
942 4d611c9a pbrook
                return 1;
943 4d611c9a pbrook
            }
944 4d611c9a pbrook
            ohci->usb_packet.pid = pid;
945 4d611c9a pbrook
            ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
946 4d611c9a pbrook
            ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
947 4d611c9a pbrook
            ohci->usb_packet.data = ohci->usb_buf;
948 4d611c9a pbrook
            ohci->usb_packet.len = len;
949 4d611c9a pbrook
            ohci->usb_packet.complete_cb = ohci_async_complete_packet;
950 4d611c9a pbrook
            ohci->usb_packet.complete_opaque = ohci;
951 806b6024 Gerd Hoffmann
            ret = dev->info->handle_packet(dev, &ohci->usb_packet);
952 4d611c9a pbrook
            if (ret != USB_RET_NODEV)
953 4d611c9a pbrook
                break;
954 4d611c9a pbrook
        }
955 4d611c9a pbrook
#ifdef DEBUG_PACKET
956 d0f2c4c6 malc
        DPRINTF("ret=%d\n", ret);
957 4d611c9a pbrook
#endif
958 4d611c9a pbrook
        if (ret == USB_RET_ASYNC) {
959 4d611c9a pbrook
            ohci->async_td = addr;
960 4d611c9a pbrook
            return 1;
961 4d611c9a pbrook
        }
962 4d611c9a pbrook
    }
963 0d92ed30 pbrook
    if (ret >= 0) {
964 0d92ed30 pbrook
        if (dir == OHCI_TD_DIR_IN) {
965 ac611340 aurel32
            ohci_copy_td(ohci, &td, ohci->usb_buf, ret, 1);
966 0d92ed30 pbrook
#ifdef DEBUG_PACKET
967 d0f2c4c6 malc
            DPRINTF("  data:");
968 0d92ed30 pbrook
            for (i = 0; i < ret; i++)
969 4d611c9a pbrook
                printf(" %.2x", ohci->usb_buf[i]);
970 d0f2c4c6 malc
            DPRINTF("\n");
971 0d92ed30 pbrook
#endif
972 0d92ed30 pbrook
        } else {
973 0d92ed30 pbrook
            ret = len;
974 0d92ed30 pbrook
        }
975 0d92ed30 pbrook
    }
976 0d92ed30 pbrook
977 0d92ed30 pbrook
    /* Writeback */
978 0d92ed30 pbrook
    if (ret == len || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) {
979 0d92ed30 pbrook
        /* Transmission succeeded.  */
980 0d92ed30 pbrook
        if (ret == len) {
981 0d92ed30 pbrook
            td.cbp = 0;
982 0d92ed30 pbrook
        } else {
983 0d92ed30 pbrook
            td.cbp += ret;
984 0d92ed30 pbrook
            if ((td.cbp & 0xfff) + ret > 0xfff) {
985 0d92ed30 pbrook
                td.cbp &= 0xfff;
986 0d92ed30 pbrook
                td.cbp |= td.be & ~0xfff;
987 0d92ed30 pbrook
            }
988 0d92ed30 pbrook
        }
989 0d92ed30 pbrook
        td.flags |= OHCI_TD_T1;
990 0d92ed30 pbrook
        td.flags ^= OHCI_TD_T0;
991 0d92ed30 pbrook
        OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR);
992 0d92ed30 pbrook
        OHCI_SET_BM(td.flags, TD_EC, 0);
993 0d92ed30 pbrook
994 0d92ed30 pbrook
        ed->head &= ~OHCI_ED_C;
995 0d92ed30 pbrook
        if (td.flags & OHCI_TD_T0)
996 0d92ed30 pbrook
            ed->head |= OHCI_ED_C;
997 0d92ed30 pbrook
    } else {
998 0d92ed30 pbrook
        if (ret >= 0) {
999 d0f2c4c6 malc
            DPRINTF("usb-ohci: Underrun\n");
1000 0d92ed30 pbrook
            OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN);
1001 0d92ed30 pbrook
        } else {
1002 0d92ed30 pbrook
            switch (ret) {
1003 0d92ed30 pbrook
            case USB_RET_NODEV:
1004 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);
1005 0d92ed30 pbrook
            case USB_RET_NAK:
1006 d0f2c4c6 malc
                DPRINTF("usb-ohci: got NAK\n");
1007 0d92ed30 pbrook
                return 1;
1008 0d92ed30 pbrook
            case USB_RET_STALL:
1009 d0f2c4c6 malc
                DPRINTF("usb-ohci: got STALL\n");
1010 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_STALL);
1011 0d92ed30 pbrook
                break;
1012 0d92ed30 pbrook
            case USB_RET_BABBLE:
1013 d0f2c4c6 malc
                DPRINTF("usb-ohci: got BABBLE\n");
1014 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
1015 0d92ed30 pbrook
                break;
1016 0d92ed30 pbrook
            default:
1017 0d92ed30 pbrook
                fprintf(stderr, "usb-ohci: Bad device response %d\n", ret);
1018 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_UNDEXPETEDPID);
1019 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_EC, 3);
1020 0d92ed30 pbrook
                break;
1021 0d92ed30 pbrook
            }
1022 0d92ed30 pbrook
        }
1023 0d92ed30 pbrook
        ed->head |= OHCI_ED_H;
1024 0d92ed30 pbrook
    }
1025 0d92ed30 pbrook
1026 0d92ed30 pbrook
    /* Retire this TD */
1027 0d92ed30 pbrook
    ed->head &= ~OHCI_DPTR_MASK;
1028 0d92ed30 pbrook
    ed->head |= td.next & OHCI_DPTR_MASK;
1029 0d92ed30 pbrook
    td.next = ohci->done;
1030 0d92ed30 pbrook
    ohci->done = addr;
1031 0d92ed30 pbrook
    i = OHCI_BM(td.flags, TD_DI);
1032 0d92ed30 pbrook
    if (i < ohci->done_count)
1033 0d92ed30 pbrook
        ohci->done_count = i;
1034 ac611340 aurel32
    ohci_put_td(ohci, addr, &td);
1035 0d92ed30 pbrook
    return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;
1036 0d92ed30 pbrook
}
1037 0d92ed30 pbrook
1038 0d92ed30 pbrook
/* Service an endpoint list.  Returns nonzero if active TD were found.  */
1039 7bfe5777 balrog
static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
1040 0d92ed30 pbrook
{
1041 0d92ed30 pbrook
    struct ohci_ed ed;
1042 0d92ed30 pbrook
    uint32_t next_ed;
1043 0d92ed30 pbrook
    uint32_t cur;
1044 0d92ed30 pbrook
    int active;
1045 0d92ed30 pbrook
1046 0d92ed30 pbrook
    active = 0;
1047 0d92ed30 pbrook
1048 0d92ed30 pbrook
    if (head == 0)
1049 0d92ed30 pbrook
        return 0;
1050 0d92ed30 pbrook
1051 0d92ed30 pbrook
    for (cur = head; cur; cur = next_ed) {
1052 ac611340 aurel32
        if (!ohci_read_ed(ohci, cur, &ed)) {
1053 0d92ed30 pbrook
            fprintf(stderr, "usb-ohci: ED read error at %x\n", cur);
1054 0d92ed30 pbrook
            return 0;
1055 0d92ed30 pbrook
        }
1056 0d92ed30 pbrook
1057 0d92ed30 pbrook
        next_ed = ed.next & OHCI_DPTR_MASK;
1058 0d92ed30 pbrook
1059 4d611c9a pbrook
        if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
1060 4d611c9a pbrook
            uint32_t addr;
1061 4d611c9a pbrook
            /* Cancel pending packets for ED that have been paused.  */
1062 4d611c9a pbrook
            addr = ed.head & OHCI_DPTR_MASK;
1063 4d611c9a pbrook
            if (ohci->async_td && addr == ohci->async_td) {
1064 4d611c9a pbrook
                usb_cancel_packet(&ohci->usb_packet);
1065 4d611c9a pbrook
                ohci->async_td = 0;
1066 4d611c9a pbrook
            }
1067 0d92ed30 pbrook
            continue;
1068 4d611c9a pbrook
        }
1069 0d92ed30 pbrook
1070 0d92ed30 pbrook
        while ((ed.head & OHCI_DPTR_MASK) != ed.tail) {
1071 0d92ed30 pbrook
#ifdef DEBUG_PACKET
1072 d0f2c4c6 malc
            DPRINTF("ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u "
1073 0d92ed30 pbrook
                    "h=%u c=%u\n  head=0x%.8x tailp=0x%.8x next=0x%.8x\n", cur,
1074 0d92ed30 pbrook
                    OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN),
1075 0d92ed30 pbrook
                    OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S)!= 0,
1076 0d92ed30 pbrook
                    (ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0,
1077 0d92ed30 pbrook
                    OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0,
1078 0d92ed30 pbrook
                    (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK,
1079 0d92ed30 pbrook
                    ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK);
1080 0d92ed30 pbrook
#endif
1081 0d92ed30 pbrook
            active = 1;
1082 0d92ed30 pbrook
1083 7bfe5777 balrog
            if ((ed.flags & OHCI_ED_F) == 0) {
1084 7bfe5777 balrog
                if (ohci_service_td(ohci, &ed))
1085 7bfe5777 balrog
                    break;
1086 7bfe5777 balrog
            } else {
1087 7bfe5777 balrog
                /* Handle isochronous endpoints */
1088 7bfe5777 balrog
                if (ohci_service_iso_td(ohci, &ed, completion))
1089 7bfe5777 balrog
                    break;
1090 7bfe5777 balrog
            }
1091 0d92ed30 pbrook
        }
1092 0d92ed30 pbrook
1093 ac611340 aurel32
        ohci_put_ed(ohci, cur, &ed);
1094 0d92ed30 pbrook
    }
1095 0d92ed30 pbrook
1096 0d92ed30 pbrook
    return active;
1097 0d92ed30 pbrook
}
1098 0d92ed30 pbrook
1099 0d92ed30 pbrook
/* Generate a SOF event, and set a timer for EOF */
1100 0d92ed30 pbrook
static void ohci_sof(OHCIState *ohci)
1101 0d92ed30 pbrook
{
1102 74475455 Paolo Bonzini
    ohci->sof_time = qemu_get_clock_ns(vm_clock);
1103 0d92ed30 pbrook
    qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time);
1104 0d92ed30 pbrook
    ohci_set_interrupt(ohci, OHCI_INTR_SF);
1105 0d92ed30 pbrook
}
1106 0d92ed30 pbrook
1107 4d611c9a pbrook
/* Process Control and Bulk lists.  */
1108 7bfe5777 balrog
static void ohci_process_lists(OHCIState *ohci, int completion)
1109 4d611c9a pbrook
{
1110 4d611c9a pbrook
    if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) {
1111 6ad6135d Blue Swirl
        if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head) {
1112 6ad6135d Blue Swirl
            DPRINTF("usb-ohci: head %x, cur %x\n",
1113 6ad6135d Blue Swirl
                    ohci->ctrl_head, ohci->ctrl_cur);
1114 6ad6135d Blue Swirl
        }
1115 7bfe5777 balrog
        if (!ohci_service_ed_list(ohci, ohci->ctrl_head, completion)) {
1116 4d611c9a pbrook
            ohci->ctrl_cur = 0;
1117 4d611c9a pbrook
            ohci->status &= ~OHCI_STATUS_CLF;
1118 4d611c9a pbrook
        }
1119 4d611c9a pbrook
    }
1120 4d611c9a pbrook
1121 4d611c9a pbrook
    if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) {
1122 7bfe5777 balrog
        if (!ohci_service_ed_list(ohci, ohci->bulk_head, completion)) {
1123 4d611c9a pbrook
            ohci->bulk_cur = 0;
1124 4d611c9a pbrook
            ohci->status &= ~OHCI_STATUS_BLF;
1125 4d611c9a pbrook
        }
1126 4d611c9a pbrook
    }
1127 4d611c9a pbrook
}
1128 4d611c9a pbrook
1129 0d92ed30 pbrook
/* Do frame processing on frame boundary */
1130 0d92ed30 pbrook
static void ohci_frame_boundary(void *opaque)
1131 0d92ed30 pbrook
{
1132 0d92ed30 pbrook
    OHCIState *ohci = opaque;
1133 0d92ed30 pbrook
    struct ohci_hcca hcca;
1134 0d92ed30 pbrook
1135 ac611340 aurel32
    ohci_read_hcca(ohci, ohci->hcca, &hcca);
1136 0d92ed30 pbrook
1137 0d92ed30 pbrook
    /* Process all the lists at the end of the frame */
1138 0d92ed30 pbrook
    if (ohci->ctl & OHCI_CTL_PLE) {
1139 0d92ed30 pbrook
        int n;
1140 0d92ed30 pbrook
1141 0d92ed30 pbrook
        n = ohci->frame_number & 0x1f;
1142 7bfe5777 balrog
        ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]), 0);
1143 0d92ed30 pbrook
    }
1144 0d92ed30 pbrook
1145 4d611c9a pbrook
    /* Cancel all pending packets if either of the lists has been disabled.  */
1146 4d611c9a pbrook
    if (ohci->async_td &&
1147 4d611c9a pbrook
        ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
1148 4d611c9a pbrook
        usb_cancel_packet(&ohci->usb_packet);
1149 4d611c9a pbrook
        ohci->async_td = 0;
1150 0d92ed30 pbrook
    }
1151 4d611c9a pbrook
    ohci->old_ctl = ohci->ctl;
1152 7bfe5777 balrog
    ohci_process_lists(ohci, 0);
1153 0d92ed30 pbrook
1154 0d92ed30 pbrook
    /* Frame boundary, so do EOF stuf here */
1155 0d92ed30 pbrook
    ohci->frt = ohci->fit;
1156 0d92ed30 pbrook
1157 1fa63e43 Michael Buesch
    /* Increment frame number and take care of endianness. */
1158 0d92ed30 pbrook
    ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
1159 1fa63e43 Michael Buesch
    hcca.frame = cpu_to_le16(ohci->frame_number);
1160 0d92ed30 pbrook
1161 0d92ed30 pbrook
    if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
1162 0d92ed30 pbrook
        if (!ohci->done)
1163 0d92ed30 pbrook
            abort();
1164 0d92ed30 pbrook
        if (ohci->intr & ohci->intr_status)
1165 0d92ed30 pbrook
            ohci->done |= 1;
1166 0d92ed30 pbrook
        hcca.done = cpu_to_le32(ohci->done);
1167 0d92ed30 pbrook
        ohci->done = 0;
1168 0d92ed30 pbrook
        ohci->done_count = 7;
1169 0d92ed30 pbrook
        ohci_set_interrupt(ohci, OHCI_INTR_WD);
1170 0d92ed30 pbrook
    }
1171 0d92ed30 pbrook
1172 0d92ed30 pbrook
    if (ohci->done_count != 7 && ohci->done_count != 0)
1173 0d92ed30 pbrook
        ohci->done_count--;
1174 0d92ed30 pbrook
1175 0d92ed30 pbrook
    /* Do SOF stuff here */
1176 0d92ed30 pbrook
    ohci_sof(ohci);
1177 0d92ed30 pbrook
1178 0d92ed30 pbrook
    /* Writeback HCCA */
1179 ac611340 aurel32
    ohci_put_hcca(ohci, ohci->hcca, &hcca);
1180 0d92ed30 pbrook
}
1181 0d92ed30 pbrook
1182 0d92ed30 pbrook
/* Start sending SOF tokens across the USB bus, lists are processed in
1183 0d92ed30 pbrook
 * next frame
1184 0d92ed30 pbrook
 */
1185 0d92ed30 pbrook
static int ohci_bus_start(OHCIState *ohci)
1186 0d92ed30 pbrook
{
1187 74475455 Paolo Bonzini
    ohci->eof_timer = qemu_new_timer_ns(vm_clock,
1188 0d92ed30 pbrook
                    ohci_frame_boundary,
1189 0d92ed30 pbrook
                    ohci);
1190 0d92ed30 pbrook
1191 0d92ed30 pbrook
    if (ohci->eof_timer == NULL) {
1192 74475455 Paolo Bonzini
        fprintf(stderr, "usb-ohci: %s: qemu_new_timer_ns failed\n", ohci->name);
1193 0d92ed30 pbrook
        /* TODO: Signal unrecoverable error */
1194 0d92ed30 pbrook
        return 0;
1195 0d92ed30 pbrook
    }
1196 0d92ed30 pbrook
1197 d0f2c4c6 malc
    DPRINTF("usb-ohci: %s: USB Operational\n", ohci->name);
1198 0d92ed30 pbrook
1199 0d92ed30 pbrook
    ohci_sof(ohci);
1200 0d92ed30 pbrook
1201 0d92ed30 pbrook
    return 1;
1202 0d92ed30 pbrook
}
1203 0d92ed30 pbrook
1204 0d92ed30 pbrook
/* Stop sending SOF tokens on the bus */
1205 0d92ed30 pbrook
static void ohci_bus_stop(OHCIState *ohci)
1206 0d92ed30 pbrook
{
1207 0d92ed30 pbrook
    if (ohci->eof_timer)
1208 0d92ed30 pbrook
        qemu_del_timer(ohci->eof_timer);
1209 73221b12 ths
    ohci->eof_timer = NULL;
1210 0d92ed30 pbrook
}
1211 0d92ed30 pbrook
1212 0d92ed30 pbrook
/* Sets a flag in a port status register but only set it if the port is
1213 0d92ed30 pbrook
 * connected, if not set ConnectStatusChange flag. If flag is enabled
1214 0d92ed30 pbrook
 * return 1.
1215 0d92ed30 pbrook
 */
1216 0d92ed30 pbrook
static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val)
1217 0d92ed30 pbrook
{
1218 0d92ed30 pbrook
    int ret = 1;
1219 0d92ed30 pbrook
1220 0d92ed30 pbrook
    /* writing a 0 has no effect */
1221 0d92ed30 pbrook
    if (val == 0)
1222 0d92ed30 pbrook
        return 0;
1223 0d92ed30 pbrook
1224 0d92ed30 pbrook
    /* If CurrentConnectStatus is cleared we set
1225 0d92ed30 pbrook
     * ConnectStatusChange
1226 0d92ed30 pbrook
     */
1227 0d92ed30 pbrook
    if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) {
1228 0d92ed30 pbrook
        ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
1229 0d92ed30 pbrook
        if (ohci->rhstatus & OHCI_RHS_DRWE) {
1230 0d92ed30 pbrook
            /* TODO: CSC is a wakeup event */
1231 0d92ed30 pbrook
        }
1232 0d92ed30 pbrook
        return 0;
1233 0d92ed30 pbrook
    }
1234 0d92ed30 pbrook
1235 0d92ed30 pbrook
    if (ohci->rhport[i].ctrl & val)
1236 0d92ed30 pbrook
        ret = 0;
1237 0d92ed30 pbrook
1238 0d92ed30 pbrook
    /* set the bit */
1239 0d92ed30 pbrook
    ohci->rhport[i].ctrl |= val;
1240 0d92ed30 pbrook
1241 0d92ed30 pbrook
    return ret;
1242 0d92ed30 pbrook
}
1243 0d92ed30 pbrook
1244 0d92ed30 pbrook
/* Set the frame interval - frame interval toggle is manipulated by the hcd only */
1245 0d92ed30 pbrook
static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val)
1246 0d92ed30 pbrook
{
1247 0d92ed30 pbrook
    val &= OHCI_FMI_FI;
1248 0d92ed30 pbrook
1249 0d92ed30 pbrook
    if (val != ohci->fi) {
1250 d0f2c4c6 malc
        DPRINTF("usb-ohci: %s: FrameInterval = 0x%x (%u)\n",
1251 e24ad6f1 pbrook
            ohci->name, ohci->fi, ohci->fi);
1252 0d92ed30 pbrook
    }
1253 0d92ed30 pbrook
1254 0d92ed30 pbrook
    ohci->fi = val;
1255 0d92ed30 pbrook
}
1256 0d92ed30 pbrook
1257 0d92ed30 pbrook
static void ohci_port_power(OHCIState *ohci, int i, int p)
1258 0d92ed30 pbrook
{
1259 0d92ed30 pbrook
    if (p) {
1260 0d92ed30 pbrook
        ohci->rhport[i].ctrl |= OHCI_PORT_PPS;
1261 0d92ed30 pbrook
    } else {
1262 0d92ed30 pbrook
        ohci->rhport[i].ctrl &= ~(OHCI_PORT_PPS|
1263 0d92ed30 pbrook
                    OHCI_PORT_CCS|
1264 0d92ed30 pbrook
                    OHCI_PORT_PSS|
1265 0d92ed30 pbrook
                    OHCI_PORT_PRS);
1266 0d92ed30 pbrook
    }
1267 0d92ed30 pbrook
}
1268 0d92ed30 pbrook
1269 0d92ed30 pbrook
/* Set HcControlRegister */
1270 0d92ed30 pbrook
static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
1271 0d92ed30 pbrook
{
1272 0d92ed30 pbrook
    uint32_t old_state;
1273 0d92ed30 pbrook
    uint32_t new_state;
1274 0d92ed30 pbrook
1275 0d92ed30 pbrook
    old_state = ohci->ctl & OHCI_CTL_HCFS;
1276 0d92ed30 pbrook
    ohci->ctl = val;
1277 0d92ed30 pbrook
    new_state = ohci->ctl & OHCI_CTL_HCFS;
1278 0d92ed30 pbrook
1279 0d92ed30 pbrook
    /* no state change */
1280 0d92ed30 pbrook
    if (old_state == new_state)
1281 0d92ed30 pbrook
        return;
1282 0d92ed30 pbrook
1283 0d92ed30 pbrook
    switch (new_state) {
1284 0d92ed30 pbrook
    case OHCI_USB_OPERATIONAL:
1285 0d92ed30 pbrook
        ohci_bus_start(ohci);
1286 0d92ed30 pbrook
        break;
1287 0d92ed30 pbrook
    case OHCI_USB_SUSPEND:
1288 0d92ed30 pbrook
        ohci_bus_stop(ohci);
1289 d0f2c4c6 malc
        DPRINTF("usb-ohci: %s: USB Suspended\n", ohci->name);
1290 0d92ed30 pbrook
        break;
1291 0d92ed30 pbrook
    case OHCI_USB_RESUME:
1292 d0f2c4c6 malc
        DPRINTF("usb-ohci: %s: USB Resume\n", ohci->name);
1293 0d92ed30 pbrook
        break;
1294 0d92ed30 pbrook
    case OHCI_USB_RESET:
1295 73221b12 ths
        ohci_reset(ohci);
1296 d0f2c4c6 malc
        DPRINTF("usb-ohci: %s: USB Reset\n", ohci->name);
1297 0d92ed30 pbrook
        break;
1298 0d92ed30 pbrook
    }
1299 0d92ed30 pbrook
}
1300 0d92ed30 pbrook
1301 0d92ed30 pbrook
static uint32_t ohci_get_frame_remaining(OHCIState *ohci)
1302 0d92ed30 pbrook
{
1303 0d92ed30 pbrook
    uint16_t fr;
1304 0d92ed30 pbrook
    int64_t tks;
1305 0d92ed30 pbrook
1306 0d92ed30 pbrook
    if ((ohci->ctl & OHCI_CTL_HCFS) != OHCI_USB_OPERATIONAL)
1307 0d92ed30 pbrook
        return (ohci->frt << 31);
1308 0d92ed30 pbrook
1309 0d92ed30 pbrook
    /* Being in USB operational state guarnatees sof_time was
1310 0d92ed30 pbrook
     * set already.
1311 0d92ed30 pbrook
     */
1312 74475455 Paolo Bonzini
    tks = qemu_get_clock_ns(vm_clock) - ohci->sof_time;
1313 0d92ed30 pbrook
1314 0d92ed30 pbrook
    /* avoid muldiv if possible */
1315 0d92ed30 pbrook
    if (tks >= usb_frame_time)
1316 0d92ed30 pbrook
        return (ohci->frt << 31);
1317 0d92ed30 pbrook
1318 0d92ed30 pbrook
    tks = muldiv64(1, tks, usb_bit_time);
1319 0d92ed30 pbrook
    fr = (uint16_t)(ohci->fi - tks);
1320 0d92ed30 pbrook
1321 0d92ed30 pbrook
    return (ohci->frt << 31) | fr;
1322 0d92ed30 pbrook
}
1323 0d92ed30 pbrook
1324 0d92ed30 pbrook
1325 0d92ed30 pbrook
/* Set root hub status */
1326 0d92ed30 pbrook
static void ohci_set_hub_status(OHCIState *ohci, uint32_t val)
1327 0d92ed30 pbrook
{
1328 0d92ed30 pbrook
    uint32_t old_state;
1329 0d92ed30 pbrook
1330 0d92ed30 pbrook
    old_state = ohci->rhstatus;
1331 0d92ed30 pbrook
1332 0d92ed30 pbrook
    /* write 1 to clear OCIC */
1333 0d92ed30 pbrook
    if (val & OHCI_RHS_OCIC)
1334 0d92ed30 pbrook
        ohci->rhstatus &= ~OHCI_RHS_OCIC;
1335 0d92ed30 pbrook
1336 0d92ed30 pbrook
    if (val & OHCI_RHS_LPS) {
1337 0d92ed30 pbrook
        int i;
1338 0d92ed30 pbrook
1339 0d92ed30 pbrook
        for (i = 0; i < ohci->num_ports; i++)
1340 0d92ed30 pbrook
            ohci_port_power(ohci, i, 0);
1341 d0f2c4c6 malc
        DPRINTF("usb-ohci: powered down all ports\n");
1342 0d92ed30 pbrook
    }
1343 0d92ed30 pbrook
1344 0d92ed30 pbrook
    if (val & OHCI_RHS_LPSC) {
1345 0d92ed30 pbrook
        int i;
1346 0d92ed30 pbrook
1347 0d92ed30 pbrook
        for (i = 0; i < ohci->num_ports; i++)
1348 0d92ed30 pbrook
            ohci_port_power(ohci, i, 1);
1349 d0f2c4c6 malc
        DPRINTF("usb-ohci: powered up all ports\n");
1350 0d92ed30 pbrook
    }
1351 0d92ed30 pbrook
1352 0d92ed30 pbrook
    if (val & OHCI_RHS_DRWE)
1353 0d92ed30 pbrook
        ohci->rhstatus |= OHCI_RHS_DRWE;
1354 0d92ed30 pbrook
1355 0d92ed30 pbrook
    if (val & OHCI_RHS_CRWE)
1356 0d92ed30 pbrook
        ohci->rhstatus &= ~OHCI_RHS_DRWE;
1357 0d92ed30 pbrook
1358 0d92ed30 pbrook
    if (old_state != ohci->rhstatus)
1359 0d92ed30 pbrook
        ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
1360 0d92ed30 pbrook
}
1361 0d92ed30 pbrook
1362 0d92ed30 pbrook
/* Set root hub port status */
1363 0d92ed30 pbrook
static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
1364 0d92ed30 pbrook
{
1365 0d92ed30 pbrook
    uint32_t old_state;
1366 0d92ed30 pbrook
    OHCIPort *port;
1367 0d92ed30 pbrook
1368 0d92ed30 pbrook
    port = &ohci->rhport[portnum];
1369 0d92ed30 pbrook
    old_state = port->ctrl;
1370 0d92ed30 pbrook
1371 0d92ed30 pbrook
    /* Write to clear CSC, PESC, PSSC, OCIC, PRSC */
1372 0d92ed30 pbrook
    if (val & OHCI_PORT_WTC)
1373 0d92ed30 pbrook
        port->ctrl &= ~(val & OHCI_PORT_WTC);
1374 0d92ed30 pbrook
1375 0d92ed30 pbrook
    if (val & OHCI_PORT_CCS)
1376 0d92ed30 pbrook
        port->ctrl &= ~OHCI_PORT_PES;
1377 0d92ed30 pbrook
1378 0d92ed30 pbrook
    ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PES);
1379 0d92ed30 pbrook
1380 6ad6135d Blue Swirl
    if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PSS)) {
1381 d0f2c4c6 malc
        DPRINTF("usb-ohci: port %d: SUSPEND\n", portnum);
1382 6ad6135d Blue Swirl
    }
1383 0d92ed30 pbrook
1384 0d92ed30 pbrook
    if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) {
1385 d0f2c4c6 malc
        DPRINTF("usb-ohci: port %d: RESET\n", portnum);
1386 4d611c9a pbrook
        usb_send_msg(port->port.dev, USB_MSG_RESET);
1387 0d92ed30 pbrook
        port->ctrl &= ~OHCI_PORT_PRS;
1388 0d92ed30 pbrook
        /* ??? Should this also set OHCI_PORT_PESC.  */
1389 0d92ed30 pbrook
        port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC;
1390 0d92ed30 pbrook
    }
1391 0d92ed30 pbrook
1392 0d92ed30 pbrook
    /* Invert order here to ensure in ambiguous case, device is
1393 0d92ed30 pbrook
     * powered up...
1394 0d92ed30 pbrook
     */
1395 0d92ed30 pbrook
    if (val & OHCI_PORT_LSDA)
1396 0d92ed30 pbrook
        ohci_port_power(ohci, portnum, 0);
1397 0d92ed30 pbrook
    if (val & OHCI_PORT_PPS)
1398 0d92ed30 pbrook
        ohci_port_power(ohci, portnum, 1);
1399 0d92ed30 pbrook
1400 0d92ed30 pbrook
    if (old_state != port->ctrl)
1401 0d92ed30 pbrook
        ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
1402 0d92ed30 pbrook
1403 0d92ed30 pbrook
    return;
1404 0d92ed30 pbrook
}
1405 0d92ed30 pbrook
1406 a67ba3b6 Paul Brook
static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr)
1407 0d92ed30 pbrook
{
1408 0d92ed30 pbrook
    OHCIState *ohci = ptr;
1409 65e1d81b aurel32
    uint32_t retval;
1410 0d92ed30 pbrook
1411 09564574 Paul Brook
    addr &= 0xff;
1412 09564574 Paul Brook
1413 0d92ed30 pbrook
    /* Only aligned reads are allowed on OHCI */
1414 0d92ed30 pbrook
    if (addr & 3) {
1415 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: Mis-aligned read\n");
1416 0d92ed30 pbrook
        return 0xffffffff;
1417 65e1d81b aurel32
    } else if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
1418 0d92ed30 pbrook
        /* HcRhPortStatus */
1419 65e1d81b aurel32
        retval = ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS;
1420 65e1d81b aurel32
    } else {
1421 65e1d81b aurel32
        switch (addr >> 2) {
1422 65e1d81b aurel32
        case 0: /* HcRevision */
1423 65e1d81b aurel32
            retval = 0x10;
1424 65e1d81b aurel32
            break;
1425 65e1d81b aurel32
1426 65e1d81b aurel32
        case 1: /* HcControl */
1427 65e1d81b aurel32
            retval = ohci->ctl;
1428 65e1d81b aurel32
            break;
1429 65e1d81b aurel32
1430 65e1d81b aurel32
        case 2: /* HcCommandStatus */
1431 65e1d81b aurel32
            retval = ohci->status;
1432 65e1d81b aurel32
            break;
1433 65e1d81b aurel32
1434 65e1d81b aurel32
        case 3: /* HcInterruptStatus */
1435 65e1d81b aurel32
            retval = ohci->intr_status;
1436 65e1d81b aurel32
            break;
1437 65e1d81b aurel32
1438 65e1d81b aurel32
        case 4: /* HcInterruptEnable */
1439 65e1d81b aurel32
        case 5: /* HcInterruptDisable */
1440 65e1d81b aurel32
            retval = ohci->intr;
1441 65e1d81b aurel32
            break;
1442 65e1d81b aurel32
1443 65e1d81b aurel32
        case 6: /* HcHCCA */
1444 65e1d81b aurel32
            retval = ohci->hcca;
1445 65e1d81b aurel32
            break;
1446 65e1d81b aurel32
1447 65e1d81b aurel32
        case 7: /* HcPeriodCurrentED */
1448 65e1d81b aurel32
            retval = ohci->per_cur;
1449 65e1d81b aurel32
            break;
1450 65e1d81b aurel32
1451 65e1d81b aurel32
        case 8: /* HcControlHeadED */
1452 65e1d81b aurel32
            retval = ohci->ctrl_head;
1453 65e1d81b aurel32
            break;
1454 65e1d81b aurel32
1455 65e1d81b aurel32
        case 9: /* HcControlCurrentED */
1456 65e1d81b aurel32
            retval = ohci->ctrl_cur;
1457 65e1d81b aurel32
            break;
1458 65e1d81b aurel32
1459 65e1d81b aurel32
        case 10: /* HcBulkHeadED */
1460 65e1d81b aurel32
            retval = ohci->bulk_head;
1461 65e1d81b aurel32
            break;
1462 65e1d81b aurel32
1463 65e1d81b aurel32
        case 11: /* HcBulkCurrentED */
1464 65e1d81b aurel32
            retval = ohci->bulk_cur;
1465 65e1d81b aurel32
            break;
1466 65e1d81b aurel32
1467 65e1d81b aurel32
        case 12: /* HcDoneHead */
1468 65e1d81b aurel32
            retval = ohci->done;
1469 65e1d81b aurel32
            break;
1470 65e1d81b aurel32
1471 65e1d81b aurel32
        case 13: /* HcFmInterretval */
1472 65e1d81b aurel32
            retval = (ohci->fit << 31) | (ohci->fsmps << 16) | (ohci->fi);
1473 65e1d81b aurel32
            break;
1474 65e1d81b aurel32
1475 65e1d81b aurel32
        case 14: /* HcFmRemaining */
1476 65e1d81b aurel32
            retval = ohci_get_frame_remaining(ohci);
1477 65e1d81b aurel32
            break;
1478 65e1d81b aurel32
1479 65e1d81b aurel32
        case 15: /* HcFmNumber */
1480 65e1d81b aurel32
            retval = ohci->frame_number;
1481 65e1d81b aurel32
            break;
1482 65e1d81b aurel32
1483 65e1d81b aurel32
        case 16: /* HcPeriodicStart */
1484 65e1d81b aurel32
            retval = ohci->pstart;
1485 65e1d81b aurel32
            break;
1486 65e1d81b aurel32
1487 65e1d81b aurel32
        case 17: /* HcLSThreshold */
1488 65e1d81b aurel32
            retval = ohci->lst;
1489 65e1d81b aurel32
            break;
1490 65e1d81b aurel32
1491 65e1d81b aurel32
        case 18: /* HcRhDescriptorA */
1492 65e1d81b aurel32
            retval = ohci->rhdesc_a;
1493 65e1d81b aurel32
            break;
1494 65e1d81b aurel32
1495 65e1d81b aurel32
        case 19: /* HcRhDescriptorB */
1496 65e1d81b aurel32
            retval = ohci->rhdesc_b;
1497 65e1d81b aurel32
            break;
1498 65e1d81b aurel32
1499 65e1d81b aurel32
        case 20: /* HcRhStatus */
1500 65e1d81b aurel32
            retval = ohci->rhstatus;
1501 65e1d81b aurel32
            break;
1502 65e1d81b aurel32
1503 65e1d81b aurel32
        /* PXA27x specific registers */
1504 65e1d81b aurel32
        case 24: /* HcStatus */
1505 65e1d81b aurel32
            retval = ohci->hstatus & ohci->hmask;
1506 65e1d81b aurel32
            break;
1507 65e1d81b aurel32
1508 65e1d81b aurel32
        case 25: /* HcHReset */
1509 65e1d81b aurel32
            retval = ohci->hreset;
1510 65e1d81b aurel32
            break;
1511 65e1d81b aurel32
1512 65e1d81b aurel32
        case 26: /* HcHInterruptEnable */
1513 65e1d81b aurel32
            retval = ohci->hmask;
1514 65e1d81b aurel32
            break;
1515 65e1d81b aurel32
1516 65e1d81b aurel32
        case 27: /* HcHInterruptTest */
1517 65e1d81b aurel32
            retval = ohci->htest;
1518 65e1d81b aurel32
            break;
1519 65e1d81b aurel32
1520 65e1d81b aurel32
        default:
1521 65e1d81b aurel32
            fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr);
1522 65e1d81b aurel32
            retval = 0xffffffff;
1523 65e1d81b aurel32
        }
1524 0d92ed30 pbrook
    }
1525 0d92ed30 pbrook
1526 65e1d81b aurel32
    return retval;
1527 0d92ed30 pbrook
}
1528 0d92ed30 pbrook
1529 a67ba3b6 Paul Brook
static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val)
1530 0d92ed30 pbrook
{
1531 0d92ed30 pbrook
    OHCIState *ohci = ptr;
1532 0d92ed30 pbrook
1533 09564574 Paul Brook
    addr &= 0xff;
1534 09564574 Paul Brook
1535 0d92ed30 pbrook
    /* Only aligned reads are allowed on OHCI */
1536 0d92ed30 pbrook
    if (addr & 3) {
1537 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: Mis-aligned write\n");
1538 0d92ed30 pbrook
        return;
1539 0d92ed30 pbrook
    }
1540 0d92ed30 pbrook
1541 0d92ed30 pbrook
    if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
1542 0d92ed30 pbrook
        /* HcRhPortStatus */
1543 0d92ed30 pbrook
        ohci_port_set_status(ohci, (addr - 0x54) >> 2, val);
1544 0d92ed30 pbrook
        return;
1545 0d92ed30 pbrook
    }
1546 0d92ed30 pbrook
1547 0d92ed30 pbrook
    switch (addr >> 2) {
1548 0d92ed30 pbrook
    case 1: /* HcControl */
1549 0d92ed30 pbrook
        ohci_set_ctl(ohci, val);
1550 0d92ed30 pbrook
        break;
1551 0d92ed30 pbrook
1552 0d92ed30 pbrook
    case 2: /* HcCommandStatus */
1553 0d92ed30 pbrook
        /* SOC is read-only */
1554 0d92ed30 pbrook
        val = (val & ~OHCI_STATUS_SOC);
1555 0d92ed30 pbrook
1556 0d92ed30 pbrook
        /* Bits written as '0' remain unchanged in the register */
1557 0d92ed30 pbrook
        ohci->status |= val;
1558 0d92ed30 pbrook
1559 0d92ed30 pbrook
        if (ohci->status & OHCI_STATUS_HCR)
1560 0d92ed30 pbrook
            ohci_reset(ohci);
1561 0d92ed30 pbrook
        break;
1562 0d92ed30 pbrook
1563 0d92ed30 pbrook
    case 3: /* HcInterruptStatus */
1564 0d92ed30 pbrook
        ohci->intr_status &= ~val;
1565 0d92ed30 pbrook
        ohci_intr_update(ohci);
1566 0d92ed30 pbrook
        break;
1567 0d92ed30 pbrook
1568 0d92ed30 pbrook
    case 4: /* HcInterruptEnable */
1569 0d92ed30 pbrook
        ohci->intr |= val;
1570 0d92ed30 pbrook
        ohci_intr_update(ohci);
1571 0d92ed30 pbrook
        break;
1572 0d92ed30 pbrook
1573 0d92ed30 pbrook
    case 5: /* HcInterruptDisable */
1574 0d92ed30 pbrook
        ohci->intr &= ~val;
1575 0d92ed30 pbrook
        ohci_intr_update(ohci);
1576 0d92ed30 pbrook
        break;
1577 0d92ed30 pbrook
1578 0d92ed30 pbrook
    case 6: /* HcHCCA */
1579 0d92ed30 pbrook
        ohci->hcca = val & OHCI_HCCA_MASK;
1580 0d92ed30 pbrook
        break;
1581 0d92ed30 pbrook
1582 0d92ed30 pbrook
    case 8: /* HcControlHeadED */
1583 0d92ed30 pbrook
        ohci->ctrl_head = val & OHCI_EDPTR_MASK;
1584 0d92ed30 pbrook
        break;
1585 0d92ed30 pbrook
1586 0d92ed30 pbrook
    case 9: /* HcControlCurrentED */
1587 0d92ed30 pbrook
        ohci->ctrl_cur = val & OHCI_EDPTR_MASK;
1588 0d92ed30 pbrook
        break;
1589 0d92ed30 pbrook
1590 0d92ed30 pbrook
    case 10: /* HcBulkHeadED */
1591 0d92ed30 pbrook
        ohci->bulk_head = val & OHCI_EDPTR_MASK;
1592 0d92ed30 pbrook
        break;
1593 0d92ed30 pbrook
1594 0d92ed30 pbrook
    case 11: /* HcBulkCurrentED */
1595 0d92ed30 pbrook
        ohci->bulk_cur = val & OHCI_EDPTR_MASK;
1596 0d92ed30 pbrook
        break;
1597 0d92ed30 pbrook
1598 0d92ed30 pbrook
    case 13: /* HcFmInterval */
1599 0d92ed30 pbrook
        ohci->fsmps = (val & OHCI_FMI_FSMPS) >> 16;
1600 0d92ed30 pbrook
        ohci->fit = (val & OHCI_FMI_FIT) >> 31;
1601 0d92ed30 pbrook
        ohci_set_frame_interval(ohci, val);
1602 0d92ed30 pbrook
        break;
1603 0d92ed30 pbrook
1604 7bfe5777 balrog
    case 15: /* HcFmNumber */
1605 7bfe5777 balrog
        break;
1606 7bfe5777 balrog
1607 0d92ed30 pbrook
    case 16: /* HcPeriodicStart */
1608 0d92ed30 pbrook
        ohci->pstart = val & 0xffff;
1609 0d92ed30 pbrook
        break;
1610 0d92ed30 pbrook
1611 0d92ed30 pbrook
    case 17: /* HcLSThreshold */
1612 0d92ed30 pbrook
        ohci->lst = val & 0xffff;
1613 0d92ed30 pbrook
        break;
1614 0d92ed30 pbrook
1615 0d92ed30 pbrook
    case 18: /* HcRhDescriptorA */
1616 0d92ed30 pbrook
        ohci->rhdesc_a &= ~OHCI_RHA_RW_MASK;
1617 0d92ed30 pbrook
        ohci->rhdesc_a |= val & OHCI_RHA_RW_MASK;
1618 0d92ed30 pbrook
        break;
1619 0d92ed30 pbrook
1620 0d92ed30 pbrook
    case 19: /* HcRhDescriptorB */
1621 0d92ed30 pbrook
        break;
1622 0d92ed30 pbrook
1623 0d92ed30 pbrook
    case 20: /* HcRhStatus */
1624 0d92ed30 pbrook
        ohci_set_hub_status(ohci, val);
1625 0d92ed30 pbrook
        break;
1626 0d92ed30 pbrook
1627 e24ad6f1 pbrook
    /* PXA27x specific registers */
1628 e24ad6f1 pbrook
    case 24: /* HcStatus */
1629 e24ad6f1 pbrook
        ohci->hstatus &= ~(val & ohci->hmask);
1630 e24ad6f1 pbrook
1631 e24ad6f1 pbrook
    case 25: /* HcHReset */
1632 e24ad6f1 pbrook
        ohci->hreset = val & ~OHCI_HRESET_FSBIR;
1633 e24ad6f1 pbrook
        if (val & OHCI_HRESET_FSBIR)
1634 e24ad6f1 pbrook
            ohci_reset(ohci);
1635 e24ad6f1 pbrook
        break;
1636 e24ad6f1 pbrook
1637 e24ad6f1 pbrook
    case 26: /* HcHInterruptEnable */
1638 e24ad6f1 pbrook
        ohci->hmask = val;
1639 e24ad6f1 pbrook
        break;
1640 e24ad6f1 pbrook
1641 e24ad6f1 pbrook
    case 27: /* HcHInterruptTest */
1642 e24ad6f1 pbrook
        ohci->htest = val;
1643 e24ad6f1 pbrook
        break;
1644 e24ad6f1 pbrook
1645 0d92ed30 pbrook
    default:
1646 0d92ed30 pbrook
        fprintf(stderr, "ohci_write: Bad offset %x\n", (int)addr);
1647 0d92ed30 pbrook
        break;
1648 0d92ed30 pbrook
    }
1649 0d92ed30 pbrook
}
1650 0d92ed30 pbrook
1651 0d92ed30 pbrook
/* Only dword reads are defined on OHCI register space */
1652 a67ba3b6 Paul Brook
static CPUReadMemoryFunc * const ohci_readfn[3]={
1653 a67ba3b6 Paul Brook
    ohci_mem_read,
1654 a67ba3b6 Paul Brook
    ohci_mem_read,
1655 a67ba3b6 Paul Brook
    ohci_mem_read
1656 0d92ed30 pbrook
};
1657 0d92ed30 pbrook
1658 0d92ed30 pbrook
/* Only dword writes are defined on OHCI register space */
1659 a67ba3b6 Paul Brook
static CPUWriteMemoryFunc * const ohci_writefn[3]={
1660 a67ba3b6 Paul Brook
    ohci_mem_write,
1661 a67ba3b6 Paul Brook
    ohci_mem_write,
1662 a67ba3b6 Paul Brook
    ohci_mem_write
1663 0d92ed30 pbrook
};
1664 0d92ed30 pbrook
1665 0d86d2be Gerd Hoffmann
static USBPortOps ohci_port_ops = {
1666 0d86d2be Gerd Hoffmann
    .attach = ohci_attach,
1667 618c169b Gerd Hoffmann
    .detach = ohci_detach,
1668 0d86d2be Gerd Hoffmann
};
1669 0d86d2be Gerd Hoffmann
1670 5b19d9a2 Gerd Hoffmann
static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
1671 61d3cf93 Paul Brook
                          int num_ports, uint32_t localmem_base)
1672 0d92ed30 pbrook
{
1673 0d92ed30 pbrook
    int i;
1674 0d92ed30 pbrook
1675 0d92ed30 pbrook
    if (usb_frame_time == 0) {
1676 eb38c52c blueswir1
#ifdef OHCI_TIME_WARP
1677 6ee093c9 Juan Quintela
        usb_frame_time = get_ticks_per_sec();
1678 6ee093c9 Juan Quintela
        usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ/1000);
1679 0d92ed30 pbrook
#else
1680 6ee093c9 Juan Quintela
        usb_frame_time = muldiv64(1, get_ticks_per_sec(), 1000);
1681 6ee093c9 Juan Quintela
        if (get_ticks_per_sec() >= USB_HZ) {
1682 6ee093c9 Juan Quintela
            usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ);
1683 0d92ed30 pbrook
        } else {
1684 0d92ed30 pbrook
            usb_bit_time = 1;
1685 0d92ed30 pbrook
        }
1686 0d92ed30 pbrook
#endif
1687 d0f2c4c6 malc
        DPRINTF("usb-ohci: usb_bit_time=%" PRId64 " usb_frame_time=%" PRId64 "\n",
1688 0d92ed30 pbrook
                usb_frame_time, usb_bit_time);
1689 0d92ed30 pbrook
    }
1690 0d92ed30 pbrook
1691 2507c12a Alexander Graf
    ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci,
1692 34557491 Alexander Graf
                                       DEVICE_LITTLE_ENDIAN);
1693 ac611340 aurel32
    ohci->localmem_base = localmem_base;
1694 e24ad6f1 pbrook
1695 61d3cf93 Paul Brook
    ohci->name = dev->info->name;
1696 e24ad6f1 pbrook
1697 b2317837 Gerd Hoffmann
    usb_bus_new(&ohci->bus, dev);
1698 e24ad6f1 pbrook
    ohci->num_ports = num_ports;
1699 e24ad6f1 pbrook
    for (i = 0; i < num_ports; i++) {
1700 ace1318b Gerd Hoffmann
        usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, &ohci_port_ops,
1701 843d4e0c Gerd Hoffmann
                          USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
1702 c7a2196a Gerd Hoffmann
        usb_port_location(&ohci->rhport[i].port, NULL, i+1);
1703 e24ad6f1 pbrook
    }
1704 e24ad6f1 pbrook
1705 e24ad6f1 pbrook
    ohci->async_td = 0;
1706 a08d4367 Jan Kiszka
    qemu_register_reset(ohci_reset, ohci);
1707 e24ad6f1 pbrook
}
1708 e24ad6f1 pbrook
1709 e24ad6f1 pbrook
typedef struct {
1710 e24ad6f1 pbrook
    PCIDevice pci_dev;
1711 e24ad6f1 pbrook
    OHCIState state;
1712 e24ad6f1 pbrook
} OHCIPCIState;
1713 e24ad6f1 pbrook
1714 5b19d9a2 Gerd Hoffmann
static int usb_ohci_initfn_pci(struct PCIDevice *dev)
1715 e24ad6f1 pbrook
{
1716 5b19d9a2 Gerd Hoffmann
    OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev);
1717 5b19d9a2 Gerd Hoffmann
    int num_ports = 3;
1718 0d92ed30 pbrook
1719 deb54399 aliguori
    pci_config_set_vendor_id(ohci->pci_dev.config, PCI_VENDOR_ID_APPLE);
1720 a770dc7e aliguori
    pci_config_set_device_id(ohci->pci_dev.config,
1721 a770dc7e aliguori
                             PCI_DEVICE_ID_APPLE_IPID_USB);
1722 d74dbb94 Michael S. Tsirkin
    ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */
1723 173a543b blueswir1
    pci_config_set_class(ohci->pci_dev.config, PCI_CLASS_SERIAL_USB);
1724 d74dbb94 Michael S. Tsirkin
    /* TODO: RST# value should be 0. */
1725 d74dbb94 Michael S. Tsirkin
    ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */
1726 0d92ed30 pbrook
1727 61d3cf93 Paul Brook
    usb_ohci_init(&ohci->state, &dev->qdev, num_ports, 0);
1728 61d3cf93 Paul Brook
    ohci->state.irq = ohci->pci_dev.irq[0];
1729 0d92ed30 pbrook
1730 d74dbb94 Michael S. Tsirkin
    /* TODO: avoid cast below by using dev */
1731 6e964ded Avi Kivity
    pci_register_bar_simple(&ohci->pci_dev, 0, 256, 0, ohci->state.mem);
1732 5b19d9a2 Gerd Hoffmann
    return 0;
1733 5b19d9a2 Gerd Hoffmann
}
1734 5b19d9a2 Gerd Hoffmann
1735 a67ba3b6 Paul Brook
void usb_ohci_init_pci(struct PCIBus *bus, int devfn)
1736 5b19d9a2 Gerd Hoffmann
{
1737 a67ba3b6 Paul Brook
    pci_create_simple(bus, devfn, "pci-ohci");
1738 e24ad6f1 pbrook
}
1739 0d92ed30 pbrook
1740 61d3cf93 Paul Brook
typedef struct {
1741 61d3cf93 Paul Brook
    SysBusDevice busdev;
1742 61d3cf93 Paul Brook
    OHCIState ohci;
1743 61d3cf93 Paul Brook
    uint32_t num_ports;
1744 61d3cf93 Paul Brook
    target_phys_addr_t dma_offset;
1745 61d3cf93 Paul Brook
} OHCISysBusState;
1746 ac611340 aurel32
1747 61d3cf93 Paul Brook
static int ohci_init_pxa(SysBusDevice *dev)
1748 ac611340 aurel32
{
1749 61d3cf93 Paul Brook
    OHCISysBusState *s = FROM_SYSBUS(OHCISysBusState, dev);
1750 ac611340 aurel32
1751 61d3cf93 Paul Brook
    usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset);
1752 61d3cf93 Paul Brook
    sysbus_init_irq(dev, &s->ohci.irq);
1753 61d3cf93 Paul Brook
    sysbus_init_mmio(dev, 0x1000, s->ohci.mem);
1754 ac611340 aurel32
1755 61d3cf93 Paul Brook
    return 0;
1756 ac611340 aurel32
}
1757 ac611340 aurel32
1758 61d3cf93 Paul Brook
static PCIDeviceInfo ohci_pci_info = {
1759 556cd098 Markus Armbruster
    .qdev.name    = "pci-ohci",
1760 5b19d9a2 Gerd Hoffmann
    .qdev.desc    = "Apple USB Controller",
1761 5b19d9a2 Gerd Hoffmann
    .qdev.size    = sizeof(OHCIPCIState),
1762 5b19d9a2 Gerd Hoffmann
    .init         = usb_ohci_initfn_pci,
1763 5b19d9a2 Gerd Hoffmann
};
1764 5b19d9a2 Gerd Hoffmann
1765 61d3cf93 Paul Brook
static SysBusDeviceInfo ohci_sysbus_info = {
1766 61d3cf93 Paul Brook
    .init         = ohci_init_pxa,
1767 61d3cf93 Paul Brook
    .qdev.name    = "sysbus-ohci",
1768 61d3cf93 Paul Brook
    .qdev.desc    = "OHCI USB Controller",
1769 61d3cf93 Paul Brook
    .qdev.size    = sizeof(OHCISysBusState),
1770 61d3cf93 Paul Brook
    .qdev.props = (Property[]) {
1771 61d3cf93 Paul Brook
        DEFINE_PROP_UINT32("num-ports", OHCISysBusState, num_ports, 3),
1772 61d3cf93 Paul Brook
        DEFINE_PROP_TADDR("dma-offset", OHCISysBusState, dma_offset, 3),
1773 61d3cf93 Paul Brook
        DEFINE_PROP_END_OF_LIST(),
1774 61d3cf93 Paul Brook
    }
1775 61d3cf93 Paul Brook
};
1776 61d3cf93 Paul Brook
1777 5b19d9a2 Gerd Hoffmann
static void ohci_register(void)
1778 5b19d9a2 Gerd Hoffmann
{
1779 61d3cf93 Paul Brook
    pci_qdev_register(&ohci_pci_info);
1780 61d3cf93 Paul Brook
    sysbus_register_withprop(&ohci_sysbus_info);
1781 5b19d9a2 Gerd Hoffmann
}
1782 5b19d9a2 Gerd Hoffmann
device_init(ohci_register);