Statistics
| Branch: | Revision:

root / hw / usb / hcd-ohci.c @ 4224558f

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