Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ 81b1008d

History | View | Annotate | Download (52.1 kB)

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