Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ 525e0514

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