Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ 0dad6c35

History | View | Annotate | Download (53.3 kB)

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