Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ 6e355d90

History | View | Annotate | Download (50.3 kB)

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