Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ 4efbe58f

History | View | Annotate | Download (47.1 kB)

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