Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ cc9577cf

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