Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ 92d88ecb

History | View | Annotate | Download (36.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 0d92ed30 pbrook
#include "vl.h"
31 0d92ed30 pbrook
32 0d92ed30 pbrook
//#define DEBUG_OHCI
33 0d92ed30 pbrook
/* Dump packet contents.  */
34 0d92ed30 pbrook
//#define DEBUG_PACKET
35 0d92ed30 pbrook
/* This causes frames to occur 1000x slower */
36 0d92ed30 pbrook
//#define OHCI_TIME_WARP 1
37 0d92ed30 pbrook
38 0d92ed30 pbrook
#ifdef DEBUG_OHCI
39 0d92ed30 pbrook
#define dprintf printf
40 0d92ed30 pbrook
#else
41 0d92ed30 pbrook
#define dprintf(...)
42 0d92ed30 pbrook
#endif
43 0d92ed30 pbrook
44 0d92ed30 pbrook
/* Number of Downstream Ports on the root hub.  */
45 0d92ed30 pbrook
46 0d92ed30 pbrook
#define OHCI_MAX_PORTS 15
47 0d92ed30 pbrook
48 0d92ed30 pbrook
static int64_t usb_frame_time;
49 0d92ed30 pbrook
static int64_t usb_bit_time;
50 0d92ed30 pbrook
51 0d92ed30 pbrook
typedef struct OHCIPort {
52 0d92ed30 pbrook
    USBPort port;
53 0d92ed30 pbrook
    uint32_t ctrl;
54 0d92ed30 pbrook
} OHCIPort;
55 0d92ed30 pbrook
56 e24ad6f1 pbrook
enum ohci_type {
57 e24ad6f1 pbrook
    OHCI_TYPE_PCI,
58 e24ad6f1 pbrook
    OHCI_TYPE_PXA
59 e24ad6f1 pbrook
};
60 e24ad6f1 pbrook
61 0d92ed30 pbrook
typedef struct {
62 d537cf6c pbrook
    qemu_irq irq;
63 e24ad6f1 pbrook
    enum ohci_type type;
64 0d92ed30 pbrook
    target_phys_addr_t mem_base;
65 0d92ed30 pbrook
    int mem;
66 0d92ed30 pbrook
    int num_ports;
67 e24ad6f1 pbrook
    const char *name;
68 0d92ed30 pbrook
69 0d92ed30 pbrook
    QEMUTimer *eof_timer;
70 0d92ed30 pbrook
    int64_t sof_time;
71 0d92ed30 pbrook
72 0d92ed30 pbrook
    /* OHCI state */
73 0d92ed30 pbrook
    /* Control partition */
74 0d92ed30 pbrook
    uint32_t ctl, status;
75 0d92ed30 pbrook
    uint32_t intr_status;
76 0d92ed30 pbrook
    uint32_t intr;
77 0d92ed30 pbrook
78 0d92ed30 pbrook
    /* memory pointer partition */
79 0d92ed30 pbrook
    uint32_t hcca;
80 0d92ed30 pbrook
    uint32_t ctrl_head, ctrl_cur;
81 0d92ed30 pbrook
    uint32_t bulk_head, bulk_cur;
82 0d92ed30 pbrook
    uint32_t per_cur;
83 0d92ed30 pbrook
    uint32_t done;
84 0d92ed30 pbrook
    int done_count;
85 0d92ed30 pbrook
86 0d92ed30 pbrook
    /* Frame counter partition */
87 0d92ed30 pbrook
    uint32_t fsmps:15;
88 0d92ed30 pbrook
    uint32_t fit:1;
89 0d92ed30 pbrook
    uint32_t fi:14;
90 0d92ed30 pbrook
    uint32_t frt:1;
91 0d92ed30 pbrook
    uint16_t frame_number;
92 0d92ed30 pbrook
    uint16_t padding;
93 0d92ed30 pbrook
    uint32_t pstart;
94 0d92ed30 pbrook
    uint32_t lst;
95 0d92ed30 pbrook
96 0d92ed30 pbrook
    /* Root Hub partition */
97 0d92ed30 pbrook
    uint32_t rhdesc_a, rhdesc_b;
98 0d92ed30 pbrook
    uint32_t rhstatus;
99 0d92ed30 pbrook
    OHCIPort rhport[OHCI_MAX_PORTS];
100 4d611c9a pbrook
101 e24ad6f1 pbrook
    /* PXA27x Non-OHCI events */
102 e24ad6f1 pbrook
    uint32_t hstatus;
103 e24ad6f1 pbrook
    uint32_t hmask;
104 e24ad6f1 pbrook
    uint32_t hreset;
105 e24ad6f1 pbrook
    uint32_t htest;
106 e24ad6f1 pbrook
107 4d611c9a pbrook
    /* Active packets.  */
108 4d611c9a pbrook
    uint32_t old_ctl;
109 4d611c9a pbrook
    USBPacket usb_packet;
110 4d611c9a pbrook
    uint8_t usb_buf[8192];
111 4d611c9a pbrook
    uint32_t async_td;
112 4d611c9a pbrook
    int async_complete;
113 4d611c9a pbrook
114 0d92ed30 pbrook
} OHCIState;
115 0d92ed30 pbrook
116 0d92ed30 pbrook
/* Host Controller Communications Area */
117 0d92ed30 pbrook
struct ohci_hcca {
118 0d92ed30 pbrook
    uint32_t intr[32];
119 0d92ed30 pbrook
    uint16_t frame, pad;
120 0d92ed30 pbrook
    uint32_t done;
121 0d92ed30 pbrook
};
122 0d92ed30 pbrook
123 0d92ed30 pbrook
/* Bitfields for the first word of an Endpoint Desciptor.  */
124 0d92ed30 pbrook
#define OHCI_ED_FA_SHIFT  0
125 0d92ed30 pbrook
#define OHCI_ED_FA_MASK   (0x7f<<OHCI_ED_FA_SHIFT)
126 0d92ed30 pbrook
#define OHCI_ED_EN_SHIFT  7
127 0d92ed30 pbrook
#define OHCI_ED_EN_MASK   (0xf<<OHCI_ED_EN_SHIFT)
128 0d92ed30 pbrook
#define OHCI_ED_D_SHIFT   11
129 0d92ed30 pbrook
#define OHCI_ED_D_MASK    (3<<OHCI_ED_D_SHIFT)
130 0d92ed30 pbrook
#define OHCI_ED_S         (1<<13)
131 0d92ed30 pbrook
#define OHCI_ED_K         (1<<14)
132 0d92ed30 pbrook
#define OHCI_ED_F         (1<<15)
133 0d92ed30 pbrook
#define OHCI_ED_MPS_SHIFT 7
134 0d92ed30 pbrook
#define OHCI_ED_MPS_MASK  (0xf<<OHCI_ED_FA_SHIFT)
135 0d92ed30 pbrook
136 0d92ed30 pbrook
/* Flags in the head field of an Endpoint Desciptor.  */
137 0d92ed30 pbrook
#define OHCI_ED_H         1
138 0d92ed30 pbrook
#define OHCI_ED_C         2
139 0d92ed30 pbrook
140 0d92ed30 pbrook
/* Bitfields for the first word of a Transfer Desciptor.  */
141 0d92ed30 pbrook
#define OHCI_TD_R         (1<<18)
142 0d92ed30 pbrook
#define OHCI_TD_DP_SHIFT  19
143 0d92ed30 pbrook
#define OHCI_TD_DP_MASK   (3<<OHCI_TD_DP_SHIFT)
144 0d92ed30 pbrook
#define OHCI_TD_DI_SHIFT  21
145 0d92ed30 pbrook
#define OHCI_TD_DI_MASK   (7<<OHCI_TD_DI_SHIFT)
146 0d92ed30 pbrook
#define OHCI_TD_T0        (1<<24)
147 0d92ed30 pbrook
#define OHCI_TD_T1        (1<<24)
148 0d92ed30 pbrook
#define OHCI_TD_EC_SHIFT  26
149 0d92ed30 pbrook
#define OHCI_TD_EC_MASK   (3<<OHCI_TD_EC_SHIFT)
150 0d92ed30 pbrook
#define OHCI_TD_CC_SHIFT  28
151 0d92ed30 pbrook
#define OHCI_TD_CC_MASK   (0xf<<OHCI_TD_CC_SHIFT)
152 0d92ed30 pbrook
153 0d92ed30 pbrook
#define OHCI_DPTR_MASK    0xfffffff0
154 0d92ed30 pbrook
155 0d92ed30 pbrook
#define OHCI_BM(val, field) \
156 0d92ed30 pbrook
  (((val) & OHCI_##field##_MASK) >> OHCI_##field##_SHIFT)
157 0d92ed30 pbrook
158 0d92ed30 pbrook
#define OHCI_SET_BM(val, field, newval) do { \
159 0d92ed30 pbrook
    val &= ~OHCI_##field##_MASK; \
160 0d92ed30 pbrook
    val |= ((newval) << OHCI_##field##_SHIFT) & OHCI_##field##_MASK; \
161 0d92ed30 pbrook
    } while(0)
162 0d92ed30 pbrook
163 0d92ed30 pbrook
/* endpoint descriptor */
164 0d92ed30 pbrook
struct ohci_ed {
165 0d92ed30 pbrook
    uint32_t flags;
166 0d92ed30 pbrook
    uint32_t tail;
167 0d92ed30 pbrook
    uint32_t head;
168 0d92ed30 pbrook
    uint32_t next;
169 0d92ed30 pbrook
};
170 0d92ed30 pbrook
171 0d92ed30 pbrook
/* General transfer descriptor */
172 0d92ed30 pbrook
struct ohci_td {
173 0d92ed30 pbrook
    uint32_t flags;
174 0d92ed30 pbrook
    uint32_t cbp;
175 0d92ed30 pbrook
    uint32_t next;
176 0d92ed30 pbrook
    uint32_t be;
177 0d92ed30 pbrook
};
178 0d92ed30 pbrook
179 0d92ed30 pbrook
#define USB_HZ                      12000000
180 0d92ed30 pbrook
181 0d92ed30 pbrook
/* OHCI Local stuff */
182 0d92ed30 pbrook
#define OHCI_CTL_CBSR         ((1<<0)|(1<<1))
183 0d92ed30 pbrook
#define OHCI_CTL_PLE          (1<<2)
184 0d92ed30 pbrook
#define OHCI_CTL_IE           (1<<3)
185 0d92ed30 pbrook
#define OHCI_CTL_CLE          (1<<4)
186 0d92ed30 pbrook
#define OHCI_CTL_BLE          (1<<5)
187 0d92ed30 pbrook
#define OHCI_CTL_HCFS         ((1<<6)|(1<<7))
188 0d92ed30 pbrook
#define  OHCI_USB_RESET       0x00
189 0d92ed30 pbrook
#define  OHCI_USB_RESUME      0x40
190 0d92ed30 pbrook
#define  OHCI_USB_OPERATIONAL 0x80
191 0d92ed30 pbrook
#define  OHCI_USB_SUSPEND     0xc0
192 0d92ed30 pbrook
#define OHCI_CTL_IR           (1<<8)
193 0d92ed30 pbrook
#define OHCI_CTL_RWC          (1<<9)
194 0d92ed30 pbrook
#define OHCI_CTL_RWE          (1<<10)
195 0d92ed30 pbrook
196 0d92ed30 pbrook
#define OHCI_STATUS_HCR       (1<<0)
197 0d92ed30 pbrook
#define OHCI_STATUS_CLF       (1<<1)
198 0d92ed30 pbrook
#define OHCI_STATUS_BLF       (1<<2)
199 0d92ed30 pbrook
#define OHCI_STATUS_OCR       (1<<3)
200 0d92ed30 pbrook
#define OHCI_STATUS_SOC       ((1<<6)|(1<<7))
201 0d92ed30 pbrook
202 0d92ed30 pbrook
#define OHCI_INTR_SO          (1<<0) /* Scheduling overrun */
203 0d92ed30 pbrook
#define OHCI_INTR_WD          (1<<1) /* HcDoneHead writeback */
204 0d92ed30 pbrook
#define OHCI_INTR_SF          (1<<2) /* Start of frame */
205 0d92ed30 pbrook
#define OHCI_INTR_RD          (1<<3) /* Resume detect */
206 0d92ed30 pbrook
#define OHCI_INTR_UE          (1<<4) /* Unrecoverable error */
207 0d92ed30 pbrook
#define OHCI_INTR_FNO         (1<<5) /* Frame number overflow */
208 0d92ed30 pbrook
#define OHCI_INTR_RHSC        (1<<6) /* Root hub status change */
209 0d92ed30 pbrook
#define OHCI_INTR_OC          (1<<30) /* Ownership change */
210 0d92ed30 pbrook
#define OHCI_INTR_MIE         (1<<31) /* Master Interrupt Enable */
211 0d92ed30 pbrook
212 0d92ed30 pbrook
#define OHCI_HCCA_SIZE        0x100
213 0d92ed30 pbrook
#define OHCI_HCCA_MASK        0xffffff00
214 0d92ed30 pbrook
215 0d92ed30 pbrook
#define OHCI_EDPTR_MASK       0xfffffff0
216 0d92ed30 pbrook
217 0d92ed30 pbrook
#define OHCI_FMI_FI           0x00003fff
218 0d92ed30 pbrook
#define OHCI_FMI_FSMPS        0xffff0000
219 0d92ed30 pbrook
#define OHCI_FMI_FIT          0x80000000
220 0d92ed30 pbrook
221 0d92ed30 pbrook
#define OHCI_FR_RT            (1<<31)
222 0d92ed30 pbrook
223 0d92ed30 pbrook
#define OHCI_LS_THRESH        0x628
224 0d92ed30 pbrook
225 0d92ed30 pbrook
#define OHCI_RHA_RW_MASK      0x00000000 /* Mask of supported features.  */
226 0d92ed30 pbrook
#define OHCI_RHA_PSM          (1<<8)
227 0d92ed30 pbrook
#define OHCI_RHA_NPS          (1<<9)
228 0d92ed30 pbrook
#define OHCI_RHA_DT           (1<<10)
229 0d92ed30 pbrook
#define OHCI_RHA_OCPM         (1<<11)
230 0d92ed30 pbrook
#define OHCI_RHA_NOCP         (1<<12)
231 0d92ed30 pbrook
#define OHCI_RHA_POTPGT_MASK  0xff000000
232 0d92ed30 pbrook
233 0d92ed30 pbrook
#define OHCI_RHS_LPS          (1<<0)
234 0d92ed30 pbrook
#define OHCI_RHS_OCI          (1<<1)
235 0d92ed30 pbrook
#define OHCI_RHS_DRWE         (1<<15)
236 0d92ed30 pbrook
#define OHCI_RHS_LPSC         (1<<16)
237 0d92ed30 pbrook
#define OHCI_RHS_OCIC         (1<<17)
238 0d92ed30 pbrook
#define OHCI_RHS_CRWE         (1<<31)
239 0d92ed30 pbrook
240 0d92ed30 pbrook
#define OHCI_PORT_CCS         (1<<0)
241 0d92ed30 pbrook
#define OHCI_PORT_PES         (1<<1)
242 0d92ed30 pbrook
#define OHCI_PORT_PSS         (1<<2)
243 0d92ed30 pbrook
#define OHCI_PORT_POCI        (1<<3)
244 0d92ed30 pbrook
#define OHCI_PORT_PRS         (1<<4)
245 0d92ed30 pbrook
#define OHCI_PORT_PPS         (1<<8)
246 0d92ed30 pbrook
#define OHCI_PORT_LSDA        (1<<9)
247 0d92ed30 pbrook
#define OHCI_PORT_CSC         (1<<16)
248 0d92ed30 pbrook
#define OHCI_PORT_PESC        (1<<17)
249 0d92ed30 pbrook
#define OHCI_PORT_PSSC        (1<<18)
250 0d92ed30 pbrook
#define OHCI_PORT_OCIC        (1<<19)
251 0d92ed30 pbrook
#define OHCI_PORT_PRSC        (1<<20)
252 0d92ed30 pbrook
#define OHCI_PORT_WTC         (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \
253 0d92ed30 pbrook
                               |OHCI_PORT_OCIC|OHCI_PORT_PRSC)
254 0d92ed30 pbrook
255 0d92ed30 pbrook
#define OHCI_TD_DIR_SETUP     0x0
256 0d92ed30 pbrook
#define OHCI_TD_DIR_OUT       0x1
257 0d92ed30 pbrook
#define OHCI_TD_DIR_IN        0x2
258 0d92ed30 pbrook
#define OHCI_TD_DIR_RESERVED  0x3
259 0d92ed30 pbrook
260 0d92ed30 pbrook
#define OHCI_CC_NOERROR             0x0
261 0d92ed30 pbrook
#define OHCI_CC_CRC                 0x1
262 0d92ed30 pbrook
#define OHCI_CC_BITSTUFFING         0x2
263 0d92ed30 pbrook
#define OHCI_CC_DATATOGGLEMISMATCH  0x3
264 0d92ed30 pbrook
#define OHCI_CC_STALL               0x4
265 0d92ed30 pbrook
#define OHCI_CC_DEVICENOTRESPONDING 0x5
266 0d92ed30 pbrook
#define OHCI_CC_PIDCHECKFAILURE     0x6
267 0d92ed30 pbrook
#define OHCI_CC_UNDEXPETEDPID       0x7
268 0d92ed30 pbrook
#define OHCI_CC_DATAOVERRUN         0x8
269 0d92ed30 pbrook
#define OHCI_CC_DATAUNDERRUN        0x9
270 0d92ed30 pbrook
#define OHCI_CC_BUFFEROVERRUN       0xc
271 0d92ed30 pbrook
#define OHCI_CC_BUFFERUNDERRUN      0xd
272 0d92ed30 pbrook
273 e24ad6f1 pbrook
#define OHCI_HRESET_FSBIR       (1 << 0)
274 e24ad6f1 pbrook
275 61064870 pbrook
/* Update IRQ levels */
276 61064870 pbrook
static inline void ohci_intr_update(OHCIState *ohci)
277 61064870 pbrook
{
278 61064870 pbrook
    int level = 0;
279 61064870 pbrook
280 61064870 pbrook
    if ((ohci->intr & OHCI_INTR_MIE) &&
281 61064870 pbrook
        (ohci->intr_status & ohci->intr))
282 61064870 pbrook
        level = 1;
283 61064870 pbrook
284 d537cf6c pbrook
    qemu_set_irq(ohci->irq, level);
285 61064870 pbrook
}
286 61064870 pbrook
287 61064870 pbrook
/* Set an interrupt */
288 61064870 pbrook
static inline void ohci_set_interrupt(OHCIState *ohci, uint32_t intr)
289 61064870 pbrook
{
290 61064870 pbrook
    ohci->intr_status |= intr;
291 61064870 pbrook
    ohci_intr_update(ohci);
292 61064870 pbrook
}
293 61064870 pbrook
294 61064870 pbrook
/* Attach or detach a device on a root hub port.  */
295 0d92ed30 pbrook
static void ohci_attach(USBPort *port1, USBDevice *dev)
296 0d92ed30 pbrook
{
297 0d92ed30 pbrook
    OHCIState *s = port1->opaque;
298 0d92ed30 pbrook
    OHCIPort *port = &s->rhport[port1->index];
299 61064870 pbrook
    uint32_t old_state = port->ctrl;
300 0d92ed30 pbrook
301 0d92ed30 pbrook
    if (dev) {
302 0d92ed30 pbrook
        if (port->port.dev) {
303 0d92ed30 pbrook
            usb_attach(port1, NULL);
304 0d92ed30 pbrook
        }
305 0d92ed30 pbrook
        /* set connect status */
306 61064870 pbrook
        port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
307 61064870 pbrook
308 0d92ed30 pbrook
        /* update speed */
309 0d92ed30 pbrook
        if (dev->speed == USB_SPEED_LOW)
310 0d92ed30 pbrook
            port->ctrl |= OHCI_PORT_LSDA;
311 0d92ed30 pbrook
        else
312 0d92ed30 pbrook
            port->ctrl &= ~OHCI_PORT_LSDA;
313 0d92ed30 pbrook
        port->port.dev = dev;
314 e24ad6f1 pbrook
315 e24ad6f1 pbrook
        /* notify of remote-wakeup */
316 e24ad6f1 pbrook
        if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND)
317 e24ad6f1 pbrook
            ohci_set_interrupt(s, OHCI_INTR_RD);
318 e24ad6f1 pbrook
319 0d92ed30 pbrook
        /* send the attach message */
320 4d611c9a pbrook
        usb_send_msg(dev, USB_MSG_ATTACH);
321 0d92ed30 pbrook
        dprintf("usb-ohci: Attached port %d\n", port1->index);
322 0d92ed30 pbrook
    } else {
323 0d92ed30 pbrook
        /* set connect status */
324 61064870 pbrook
        if (port->ctrl & OHCI_PORT_CCS) {
325 61064870 pbrook
            port->ctrl &= ~OHCI_PORT_CCS;
326 61064870 pbrook
            port->ctrl |= OHCI_PORT_CSC;
327 0d92ed30 pbrook
        }
328 0d92ed30 pbrook
        /* disable port */
329 0d92ed30 pbrook
        if (port->ctrl & OHCI_PORT_PES) {
330 0d92ed30 pbrook
            port->ctrl &= ~OHCI_PORT_PES;
331 0d92ed30 pbrook
            port->ctrl |= OHCI_PORT_PESC;
332 0d92ed30 pbrook
        }
333 0d92ed30 pbrook
        dev = port->port.dev;
334 0d92ed30 pbrook
        if (dev) {
335 0d92ed30 pbrook
            /* send the detach message */
336 4d611c9a pbrook
            usb_send_msg(dev, USB_MSG_DETACH);
337 0d92ed30 pbrook
        }
338 0d92ed30 pbrook
        port->port.dev = NULL;
339 0d92ed30 pbrook
        dprintf("usb-ohci: Detached port %d\n", port1->index);
340 0d92ed30 pbrook
    }
341 61064870 pbrook
342 61064870 pbrook
    if (old_state != port->ctrl)
343 61064870 pbrook
        ohci_set_interrupt(s, OHCI_INTR_RHSC);
344 0d92ed30 pbrook
}
345 0d92ed30 pbrook
346 0d92ed30 pbrook
/* Reset the controller */
347 0d92ed30 pbrook
static void ohci_reset(OHCIState *ohci)
348 0d92ed30 pbrook
{
349 0d92ed30 pbrook
    OHCIPort *port;
350 0d92ed30 pbrook
    int i;
351 0d92ed30 pbrook
352 0d92ed30 pbrook
    ohci->ctl = 0;
353 4d611c9a pbrook
    ohci->old_ctl = 0;
354 0d92ed30 pbrook
    ohci->status = 0;
355 0d92ed30 pbrook
    ohci->intr_status = 0;
356 0d92ed30 pbrook
    ohci->intr = OHCI_INTR_MIE;
357 0d92ed30 pbrook
358 0d92ed30 pbrook
    ohci->hcca = 0;
359 0d92ed30 pbrook
    ohci->ctrl_head = ohci->ctrl_cur = 0;
360 0d92ed30 pbrook
    ohci->bulk_head = ohci->bulk_cur = 0;
361 0d92ed30 pbrook
    ohci->per_cur = 0;
362 0d92ed30 pbrook
    ohci->done = 0;
363 0d92ed30 pbrook
    ohci->done_count = 7;
364 0d92ed30 pbrook
365 0d92ed30 pbrook
    /* FSMPS is marked TBD in OCHI 1.0, what gives ffs?
366 0d92ed30 pbrook
     * I took the value linux sets ...
367 0d92ed30 pbrook
     */
368 0d92ed30 pbrook
    ohci->fsmps = 0x2778;
369 0d92ed30 pbrook
    ohci->fi = 0x2edf;
370 0d92ed30 pbrook
    ohci->fit = 0;
371 0d92ed30 pbrook
    ohci->frt = 0;
372 0d92ed30 pbrook
    ohci->frame_number = 0;
373 0d92ed30 pbrook
    ohci->pstart = 0;
374 0d92ed30 pbrook
    ohci->lst = OHCI_LS_THRESH;
375 0d92ed30 pbrook
376 0d92ed30 pbrook
    ohci->rhdesc_a = OHCI_RHA_NPS | ohci->num_ports;
377 0d92ed30 pbrook
    ohci->rhdesc_b = 0x0; /* Impl. specific */
378 0d92ed30 pbrook
    ohci->rhstatus = 0;
379 0d92ed30 pbrook
380 0d92ed30 pbrook
    for (i = 0; i < ohci->num_ports; i++)
381 0d92ed30 pbrook
      {
382 0d92ed30 pbrook
        port = &ohci->rhport[i];
383 0d92ed30 pbrook
        port->ctrl = 0;
384 0d92ed30 pbrook
        if (port->port.dev)
385 0d92ed30 pbrook
            ohci_attach(&port->port, port->port.dev);
386 0d92ed30 pbrook
      }
387 4d611c9a pbrook
    if (ohci->async_td) {
388 4d611c9a pbrook
        usb_cancel_packet(&ohci->usb_packet);
389 4d611c9a pbrook
        ohci->async_td = 0;
390 4d611c9a pbrook
    }
391 e24ad6f1 pbrook
    dprintf("usb-ohci: Reset %s\n", ohci->name);
392 0d92ed30 pbrook
}
393 0d92ed30 pbrook
394 0d92ed30 pbrook
/* Get an array of dwords from main memory */
395 0d92ed30 pbrook
static inline int get_dwords(uint32_t addr, uint32_t *buf, int num)
396 0d92ed30 pbrook
{
397 0d92ed30 pbrook
    int i;
398 0d92ed30 pbrook
399 0d92ed30 pbrook
    for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
400 0d92ed30 pbrook
        cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
401 0d92ed30 pbrook
        *buf = le32_to_cpu(*buf);
402 0d92ed30 pbrook
    }
403 0d92ed30 pbrook
404 0d92ed30 pbrook
    return 1;
405 0d92ed30 pbrook
}
406 0d92ed30 pbrook
407 0d92ed30 pbrook
/* Put an array of dwords in to main memory */
408 0d92ed30 pbrook
static inline int put_dwords(uint32_t addr, uint32_t *buf, int num)
409 0d92ed30 pbrook
{
410 0d92ed30 pbrook
    int i;
411 0d92ed30 pbrook
412 0d92ed30 pbrook
    for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
413 0d92ed30 pbrook
        uint32_t tmp = cpu_to_le32(*buf);
414 0d92ed30 pbrook
        cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
415 0d92ed30 pbrook
    }
416 0d92ed30 pbrook
417 0d92ed30 pbrook
    return 1;
418 0d92ed30 pbrook
}
419 0d92ed30 pbrook
420 0d92ed30 pbrook
static inline int ohci_read_ed(uint32_t addr, struct ohci_ed *ed)
421 0d92ed30 pbrook
{
422 0d92ed30 pbrook
    return get_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
423 0d92ed30 pbrook
}
424 0d92ed30 pbrook
425 0d92ed30 pbrook
static inline int ohci_read_td(uint32_t addr, struct ohci_td *td)
426 0d92ed30 pbrook
{
427 0d92ed30 pbrook
    return get_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
428 0d92ed30 pbrook
}
429 0d92ed30 pbrook
430 0d92ed30 pbrook
static inline int ohci_put_ed(uint32_t addr, struct ohci_ed *ed)
431 0d92ed30 pbrook
{
432 0d92ed30 pbrook
    return put_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
433 0d92ed30 pbrook
}
434 0d92ed30 pbrook
435 0d92ed30 pbrook
static inline int ohci_put_td(uint32_t addr, struct ohci_td *td)
436 0d92ed30 pbrook
{
437 0d92ed30 pbrook
    return put_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
438 0d92ed30 pbrook
}
439 0d92ed30 pbrook
440 0d92ed30 pbrook
/* Read/Write the contents of a TD from/to main memory.  */
441 0d92ed30 pbrook
static void ohci_copy_td(struct ohci_td *td, uint8_t *buf, int len, int write)
442 0d92ed30 pbrook
{
443 0d92ed30 pbrook
    uint32_t ptr;
444 0d92ed30 pbrook
    uint32_t n;
445 0d92ed30 pbrook
446 0d92ed30 pbrook
    ptr = td->cbp;
447 0d92ed30 pbrook
    n = 0x1000 - (ptr & 0xfff);
448 0d92ed30 pbrook
    if (n > len)
449 0d92ed30 pbrook
        n = len;
450 0d92ed30 pbrook
    cpu_physical_memory_rw(ptr, buf, n, write);
451 0d92ed30 pbrook
    if (n == len)
452 0d92ed30 pbrook
        return;
453 0d92ed30 pbrook
    ptr = td->be & ~0xfffu;
454 e6f3e5e0 pbrook
    buf += n;
455 0d92ed30 pbrook
    cpu_physical_memory_rw(ptr, buf, len - n, write);
456 0d92ed30 pbrook
}
457 0d92ed30 pbrook
458 4d611c9a pbrook
static void ohci_process_lists(OHCIState *ohci);
459 4d611c9a pbrook
460 4d611c9a pbrook
static void ohci_async_complete_packet(USBPacket * packet, void *opaque)
461 4d611c9a pbrook
{
462 4d611c9a pbrook
    OHCIState *ohci = opaque;
463 4d611c9a pbrook
#ifdef DEBUG_PACKET
464 4d611c9a pbrook
    dprintf("Async packet complete\n");
465 4d611c9a pbrook
#endif
466 4d611c9a pbrook
    ohci->async_complete = 1;
467 4d611c9a pbrook
    ohci_process_lists(ohci);
468 4d611c9a pbrook
}
469 4d611c9a pbrook
470 0d92ed30 pbrook
/* Service a transport descriptor.
471 0d92ed30 pbrook
   Returns nonzero to terminate processing of this endpoint.  */
472 0d92ed30 pbrook
473 0d92ed30 pbrook
static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
474 0d92ed30 pbrook
{
475 0d92ed30 pbrook
    int dir;
476 0d92ed30 pbrook
    size_t len = 0;
477 0d92ed30 pbrook
    char *str = NULL;
478 0d92ed30 pbrook
    int pid;
479 0d92ed30 pbrook
    int ret;
480 0d92ed30 pbrook
    int i;
481 0d92ed30 pbrook
    USBDevice *dev;
482 0d92ed30 pbrook
    struct ohci_td td;
483 0d92ed30 pbrook
    uint32_t addr;
484 0d92ed30 pbrook
    int flag_r;
485 4d611c9a pbrook
    int completion;
486 0d92ed30 pbrook
487 0d92ed30 pbrook
    addr = ed->head & OHCI_DPTR_MASK;
488 4d611c9a pbrook
    /* See if this TD has already been submitted to the device.  */
489 4d611c9a pbrook
    completion = (addr == ohci->async_td);
490 4d611c9a pbrook
    if (completion && !ohci->async_complete) {
491 4d611c9a pbrook
#ifdef DEBUG_PACKET
492 4d611c9a pbrook
        dprintf("Skipping async TD\n");
493 4d611c9a pbrook
#endif
494 4d611c9a pbrook
        return 1;
495 4d611c9a pbrook
    }
496 0d92ed30 pbrook
    if (!ohci_read_td(addr, &td)) {
497 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);
498 0d92ed30 pbrook
        return 0;
499 0d92ed30 pbrook
    }
500 0d92ed30 pbrook
501 0d92ed30 pbrook
    dir = OHCI_BM(ed->flags, ED_D);
502 0d92ed30 pbrook
    switch (dir) {
503 0d92ed30 pbrook
    case OHCI_TD_DIR_OUT:
504 0d92ed30 pbrook
    case OHCI_TD_DIR_IN:
505 0d92ed30 pbrook
        /* Same value.  */
506 0d92ed30 pbrook
        break;
507 0d92ed30 pbrook
    default:
508 0d92ed30 pbrook
        dir = OHCI_BM(td.flags, TD_DP);
509 0d92ed30 pbrook
        break;
510 0d92ed30 pbrook
    }
511 0d92ed30 pbrook
512 0d92ed30 pbrook
    switch (dir) {
513 0d92ed30 pbrook
    case OHCI_TD_DIR_IN:
514 0d92ed30 pbrook
        str = "in";
515 0d92ed30 pbrook
        pid = USB_TOKEN_IN;
516 0d92ed30 pbrook
        break;
517 0d92ed30 pbrook
    case OHCI_TD_DIR_OUT:
518 0d92ed30 pbrook
        str = "out";
519 0d92ed30 pbrook
        pid = USB_TOKEN_OUT;
520 0d92ed30 pbrook
        break;
521 0d92ed30 pbrook
    case OHCI_TD_DIR_SETUP:
522 0d92ed30 pbrook
        str = "setup";
523 0d92ed30 pbrook
        pid = USB_TOKEN_SETUP;
524 0d92ed30 pbrook
        break;
525 0d92ed30 pbrook
    default:
526 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: Bad direction\n");
527 0d92ed30 pbrook
        return 1;
528 0d92ed30 pbrook
    }
529 0d92ed30 pbrook
    if (td.cbp && td.be) {
530 e6f3e5e0 pbrook
        if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) {
531 e6f3e5e0 pbrook
            len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff);
532 e6f3e5e0 pbrook
        } else {
533 e6f3e5e0 pbrook
            len = (td.be - td.cbp) + 1;
534 e6f3e5e0 pbrook
        }
535 e6f3e5e0 pbrook
536 4d611c9a pbrook
        if (len && dir != OHCI_TD_DIR_IN && !completion) {
537 4d611c9a pbrook
            ohci_copy_td(&td, ohci->usb_buf, len, 0);
538 0d92ed30 pbrook
        }
539 0d92ed30 pbrook
    }
540 0d92ed30 pbrook
541 0d92ed30 pbrook
    flag_r = (td.flags & OHCI_TD_R) != 0;
542 0d92ed30 pbrook
#ifdef DEBUG_PACKET
543 0d92ed30 pbrook
    dprintf(" TD @ 0x%.8x %u bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",
544 0d92ed30 pbrook
            addr, len, str, flag_r, td.cbp, td.be);
545 0d92ed30 pbrook
546 0d92ed30 pbrook
    if (len >= 0 && dir != OHCI_TD_DIR_IN) {
547 0d92ed30 pbrook
        dprintf("  data:");
548 0d92ed30 pbrook
        for (i = 0; i < len; i++)
549 4d611c9a pbrook
            printf(" %.2x", ohci->usb_buf[i]);
550 0d92ed30 pbrook
        dprintf("\n");
551 0d92ed30 pbrook
    }
552 0d92ed30 pbrook
#endif
553 4d611c9a pbrook
    if (completion) {
554 4d611c9a pbrook
        ret = ohci->usb_packet.len;
555 4d611c9a pbrook
        ohci->async_td = 0;
556 4d611c9a pbrook
        ohci->async_complete = 0;
557 4d611c9a pbrook
    } else {
558 4d611c9a pbrook
        ret = USB_RET_NODEV;
559 4d611c9a pbrook
        for (i = 0; i < ohci->num_ports; i++) {
560 4d611c9a pbrook
            dev = ohci->rhport[i].port.dev;
561 4d611c9a pbrook
            if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
562 4d611c9a pbrook
                continue;
563 4d611c9a pbrook
564 4d611c9a pbrook
            if (ohci->async_td) {
565 4d611c9a pbrook
                /* ??? The hardware should allow one active packet per
566 4d611c9a pbrook
                   endpoint.  We only allow one active packet per controller.
567 4d611c9a pbrook
                   This should be sufficient as long as devices respond in a
568 4d611c9a pbrook
                   timely manner.
569 4d611c9a pbrook
                 */
570 0d92ed30 pbrook
#ifdef DEBUG_PACKET
571 4d611c9a pbrook
                dprintf("Too many pending packets\n");
572 0d92ed30 pbrook
#endif
573 4d611c9a pbrook
                return 1;
574 4d611c9a pbrook
            }
575 4d611c9a pbrook
            ohci->usb_packet.pid = pid;
576 4d611c9a pbrook
            ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
577 4d611c9a pbrook
            ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
578 4d611c9a pbrook
            ohci->usb_packet.data = ohci->usb_buf;
579 4d611c9a pbrook
            ohci->usb_packet.len = len;
580 4d611c9a pbrook
            ohci->usb_packet.complete_cb = ohci_async_complete_packet;
581 4d611c9a pbrook
            ohci->usb_packet.complete_opaque = ohci;
582 4d611c9a pbrook
            ret = dev->handle_packet(dev, &ohci->usb_packet);
583 4d611c9a pbrook
            if (ret != USB_RET_NODEV)
584 4d611c9a pbrook
                break;
585 4d611c9a pbrook
        }
586 4d611c9a pbrook
#ifdef DEBUG_PACKET
587 4d611c9a pbrook
        dprintf("ret=%d\n", ret);
588 4d611c9a pbrook
#endif
589 4d611c9a pbrook
        if (ret == USB_RET_ASYNC) {
590 4d611c9a pbrook
            ohci->async_td = addr;
591 4d611c9a pbrook
            return 1;
592 4d611c9a pbrook
        }
593 4d611c9a pbrook
    }
594 0d92ed30 pbrook
    if (ret >= 0) {
595 0d92ed30 pbrook
        if (dir == OHCI_TD_DIR_IN) {
596 4d611c9a pbrook
            ohci_copy_td(&td, ohci->usb_buf, ret, 1);
597 0d92ed30 pbrook
#ifdef DEBUG_PACKET
598 0d92ed30 pbrook
            dprintf("  data:");
599 0d92ed30 pbrook
            for (i = 0; i < ret; i++)
600 4d611c9a pbrook
                printf(" %.2x", ohci->usb_buf[i]);
601 0d92ed30 pbrook
            dprintf("\n");
602 0d92ed30 pbrook
#endif
603 0d92ed30 pbrook
        } else {
604 0d92ed30 pbrook
            ret = len;
605 0d92ed30 pbrook
        }
606 0d92ed30 pbrook
    }
607 0d92ed30 pbrook
608 0d92ed30 pbrook
    /* Writeback */
609 0d92ed30 pbrook
    if (ret == len || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) {
610 0d92ed30 pbrook
        /* Transmission succeeded.  */
611 0d92ed30 pbrook
        if (ret == len) {
612 0d92ed30 pbrook
            td.cbp = 0;
613 0d92ed30 pbrook
        } else {
614 0d92ed30 pbrook
            td.cbp += ret;
615 0d92ed30 pbrook
            if ((td.cbp & 0xfff) + ret > 0xfff) {
616 0d92ed30 pbrook
                td.cbp &= 0xfff;
617 0d92ed30 pbrook
                td.cbp |= td.be & ~0xfff;
618 0d92ed30 pbrook
            }
619 0d92ed30 pbrook
        }
620 0d92ed30 pbrook
        td.flags |= OHCI_TD_T1;
621 0d92ed30 pbrook
        td.flags ^= OHCI_TD_T0;
622 0d92ed30 pbrook
        OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR);
623 0d92ed30 pbrook
        OHCI_SET_BM(td.flags, TD_EC, 0);
624 0d92ed30 pbrook
625 0d92ed30 pbrook
        ed->head &= ~OHCI_ED_C;
626 0d92ed30 pbrook
        if (td.flags & OHCI_TD_T0)
627 0d92ed30 pbrook
            ed->head |= OHCI_ED_C;
628 0d92ed30 pbrook
    } else {
629 0d92ed30 pbrook
        if (ret >= 0) {
630 0d92ed30 pbrook
            dprintf("usb-ohci: Underrun\n");
631 0d92ed30 pbrook
            OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN);
632 0d92ed30 pbrook
        } else {
633 0d92ed30 pbrook
            switch (ret) {
634 0d92ed30 pbrook
            case USB_RET_NODEV:
635 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);
636 0d92ed30 pbrook
            case USB_RET_NAK:
637 0d92ed30 pbrook
                dprintf("usb-ohci: got NAK\n");
638 0d92ed30 pbrook
                return 1;
639 0d92ed30 pbrook
            case USB_RET_STALL:
640 0d92ed30 pbrook
                dprintf("usb-ohci: got STALL\n");
641 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_STALL);
642 0d92ed30 pbrook
                break;
643 0d92ed30 pbrook
            case USB_RET_BABBLE:
644 0d92ed30 pbrook
                dprintf("usb-ohci: got BABBLE\n");
645 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
646 0d92ed30 pbrook
                break;
647 0d92ed30 pbrook
            default:
648 0d92ed30 pbrook
                fprintf(stderr, "usb-ohci: Bad device response %d\n", ret);
649 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_UNDEXPETEDPID);
650 0d92ed30 pbrook
                OHCI_SET_BM(td.flags, TD_EC, 3);
651 0d92ed30 pbrook
                break;
652 0d92ed30 pbrook
            }
653 0d92ed30 pbrook
        }
654 0d92ed30 pbrook
        ed->head |= OHCI_ED_H;
655 0d92ed30 pbrook
    }
656 0d92ed30 pbrook
657 0d92ed30 pbrook
    /* Retire this TD */
658 0d92ed30 pbrook
    ed->head &= ~OHCI_DPTR_MASK;
659 0d92ed30 pbrook
    ed->head |= td.next & OHCI_DPTR_MASK;
660 0d92ed30 pbrook
    td.next = ohci->done;
661 0d92ed30 pbrook
    ohci->done = addr;
662 0d92ed30 pbrook
    i = OHCI_BM(td.flags, TD_DI);
663 0d92ed30 pbrook
    if (i < ohci->done_count)
664 0d92ed30 pbrook
        ohci->done_count = i;
665 0d92ed30 pbrook
    ohci_put_td(addr, &td);
666 0d92ed30 pbrook
    return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;
667 0d92ed30 pbrook
}
668 0d92ed30 pbrook
669 0d92ed30 pbrook
/* Service an endpoint list.  Returns nonzero if active TD were found.  */
670 0d92ed30 pbrook
static int ohci_service_ed_list(OHCIState *ohci, uint32_t head)
671 0d92ed30 pbrook
{
672 0d92ed30 pbrook
    struct ohci_ed ed;
673 0d92ed30 pbrook
    uint32_t next_ed;
674 0d92ed30 pbrook
    uint32_t cur;
675 0d92ed30 pbrook
    int active;
676 0d92ed30 pbrook
677 0d92ed30 pbrook
    active = 0;
678 0d92ed30 pbrook
679 0d92ed30 pbrook
    if (head == 0)
680 0d92ed30 pbrook
        return 0;
681 0d92ed30 pbrook
682 0d92ed30 pbrook
    for (cur = head; cur; cur = next_ed) {
683 0d92ed30 pbrook
        if (!ohci_read_ed(cur, &ed)) {
684 0d92ed30 pbrook
            fprintf(stderr, "usb-ohci: ED read error at %x\n", cur);
685 0d92ed30 pbrook
            return 0;
686 0d92ed30 pbrook
        }
687 0d92ed30 pbrook
688 0d92ed30 pbrook
        next_ed = ed.next & OHCI_DPTR_MASK;
689 0d92ed30 pbrook
690 4d611c9a pbrook
        if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
691 4d611c9a pbrook
            uint32_t addr;
692 4d611c9a pbrook
            /* Cancel pending packets for ED that have been paused.  */
693 4d611c9a pbrook
            addr = ed.head & OHCI_DPTR_MASK;
694 4d611c9a pbrook
            if (ohci->async_td && addr == ohci->async_td) {
695 4d611c9a pbrook
                usb_cancel_packet(&ohci->usb_packet);
696 4d611c9a pbrook
                ohci->async_td = 0;
697 4d611c9a pbrook
            }
698 0d92ed30 pbrook
            continue;
699 4d611c9a pbrook
        }
700 0d92ed30 pbrook
701 0d92ed30 pbrook
        /* Skip isochronous endpoints.  */
702 0d92ed30 pbrook
        if (ed.flags & OHCI_ED_F)
703 0d92ed30 pbrook
          continue;
704 0d92ed30 pbrook
705 0d92ed30 pbrook
        while ((ed.head & OHCI_DPTR_MASK) != ed.tail) {
706 0d92ed30 pbrook
#ifdef DEBUG_PACKET
707 0d92ed30 pbrook
            dprintf("ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u "
708 0d92ed30 pbrook
                    "h=%u c=%u\n  head=0x%.8x tailp=0x%.8x next=0x%.8x\n", cur,
709 0d92ed30 pbrook
                    OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN),
710 0d92ed30 pbrook
                    OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S)!= 0,
711 0d92ed30 pbrook
                    (ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0,
712 0d92ed30 pbrook
                    OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0,
713 0d92ed30 pbrook
                    (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK,
714 0d92ed30 pbrook
                    ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK);
715 0d92ed30 pbrook
#endif
716 0d92ed30 pbrook
            active = 1;
717 0d92ed30 pbrook
718 0d92ed30 pbrook
            if (ohci_service_td(ohci, &ed))
719 0d92ed30 pbrook
                break;
720 0d92ed30 pbrook
        }
721 0d92ed30 pbrook
722 0d92ed30 pbrook
        ohci_put_ed(cur, &ed);
723 0d92ed30 pbrook
    }
724 0d92ed30 pbrook
725 0d92ed30 pbrook
    return active;
726 0d92ed30 pbrook
}
727 0d92ed30 pbrook
728 0d92ed30 pbrook
/* Generate a SOF event, and set a timer for EOF */
729 0d92ed30 pbrook
static void ohci_sof(OHCIState *ohci)
730 0d92ed30 pbrook
{
731 0d92ed30 pbrook
    ohci->sof_time = qemu_get_clock(vm_clock);
732 0d92ed30 pbrook
    qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time);
733 0d92ed30 pbrook
    ohci_set_interrupt(ohci, OHCI_INTR_SF);
734 0d92ed30 pbrook
}
735 0d92ed30 pbrook
736 4d611c9a pbrook
/* Process Control and Bulk lists.  */
737 4d611c9a pbrook
static void ohci_process_lists(OHCIState *ohci)
738 4d611c9a pbrook
{
739 4d611c9a pbrook
    if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) {
740 4d611c9a pbrook
        if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head)
741 4d611c9a pbrook
          dprintf("usb-ohci: head %x, cur %x\n", ohci->ctrl_head, ohci->ctrl_cur);
742 4d611c9a pbrook
        if (!ohci_service_ed_list(ohci, ohci->ctrl_head)) {
743 4d611c9a pbrook
            ohci->ctrl_cur = 0;
744 4d611c9a pbrook
            ohci->status &= ~OHCI_STATUS_CLF;
745 4d611c9a pbrook
        }
746 4d611c9a pbrook
    }
747 4d611c9a pbrook
748 4d611c9a pbrook
    if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) {
749 4d611c9a pbrook
        if (!ohci_service_ed_list(ohci, ohci->bulk_head)) {
750 4d611c9a pbrook
            ohci->bulk_cur = 0;
751 4d611c9a pbrook
            ohci->status &= ~OHCI_STATUS_BLF;
752 4d611c9a pbrook
        }
753 4d611c9a pbrook
    }
754 4d611c9a pbrook
}
755 4d611c9a pbrook
756 0d92ed30 pbrook
/* Do frame processing on frame boundary */
757 0d92ed30 pbrook
static void ohci_frame_boundary(void *opaque)
758 0d92ed30 pbrook
{
759 0d92ed30 pbrook
    OHCIState *ohci = opaque;
760 0d92ed30 pbrook
    struct ohci_hcca hcca;
761 0d92ed30 pbrook
762 0d92ed30 pbrook
    cpu_physical_memory_rw(ohci->hcca, (uint8_t *)&hcca, sizeof(hcca), 0);
763 0d92ed30 pbrook
764 0d92ed30 pbrook
    /* Process all the lists at the end of the frame */
765 0d92ed30 pbrook
    if (ohci->ctl & OHCI_CTL_PLE) {
766 0d92ed30 pbrook
        int n;
767 0d92ed30 pbrook
768 0d92ed30 pbrook
        n = ohci->frame_number & 0x1f;
769 0d92ed30 pbrook
        ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]));
770 0d92ed30 pbrook
    }
771 0d92ed30 pbrook
772 4d611c9a pbrook
    /* Cancel all pending packets if either of the lists has been disabled.  */
773 4d611c9a pbrook
    if (ohci->async_td &&
774 4d611c9a pbrook
        ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
775 4d611c9a pbrook
        usb_cancel_packet(&ohci->usb_packet);
776 4d611c9a pbrook
        ohci->async_td = 0;
777 0d92ed30 pbrook
    }
778 4d611c9a pbrook
    ohci->old_ctl = ohci->ctl;
779 4d611c9a pbrook
    ohci_process_lists(ohci);
780 0d92ed30 pbrook
781 0d92ed30 pbrook
    /* Frame boundary, so do EOF stuf here */
782 0d92ed30 pbrook
    ohci->frt = ohci->fit;
783 0d92ed30 pbrook
784 0d92ed30 pbrook
    /* XXX: endianness */
785 0d92ed30 pbrook
    ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
786 0d92ed30 pbrook
    hcca.frame = cpu_to_le32(ohci->frame_number);
787 0d92ed30 pbrook
788 0d92ed30 pbrook
    if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
789 0d92ed30 pbrook
        if (!ohci->done)
790 0d92ed30 pbrook
            abort();
791 0d92ed30 pbrook
        if (ohci->intr & ohci->intr_status)
792 0d92ed30 pbrook
            ohci->done |= 1;
793 0d92ed30 pbrook
        hcca.done = cpu_to_le32(ohci->done);
794 0d92ed30 pbrook
        ohci->done = 0;
795 0d92ed30 pbrook
        ohci->done_count = 7;
796 0d92ed30 pbrook
        ohci_set_interrupt(ohci, OHCI_INTR_WD);
797 0d92ed30 pbrook
    }
798 0d92ed30 pbrook
799 0d92ed30 pbrook
    if (ohci->done_count != 7 && ohci->done_count != 0)
800 0d92ed30 pbrook
        ohci->done_count--;
801 0d92ed30 pbrook
802 0d92ed30 pbrook
    /* Do SOF stuff here */
803 0d92ed30 pbrook
    ohci_sof(ohci);
804 0d92ed30 pbrook
805 0d92ed30 pbrook
    /* Writeback HCCA */
806 0d92ed30 pbrook
    cpu_physical_memory_rw(ohci->hcca, (uint8_t *)&hcca, sizeof(hcca), 1);
807 0d92ed30 pbrook
}
808 0d92ed30 pbrook
809 0d92ed30 pbrook
/* Start sending SOF tokens across the USB bus, lists are processed in
810 0d92ed30 pbrook
 * next frame
811 0d92ed30 pbrook
 */
812 0d92ed30 pbrook
static int ohci_bus_start(OHCIState *ohci)
813 0d92ed30 pbrook
{
814 0d92ed30 pbrook
    ohci->eof_timer = qemu_new_timer(vm_clock,
815 0d92ed30 pbrook
                    ohci_frame_boundary,
816 0d92ed30 pbrook
                    ohci);
817 0d92ed30 pbrook
818 0d92ed30 pbrook
    if (ohci->eof_timer == NULL) {
819 e24ad6f1 pbrook
        fprintf(stderr, "usb-ohci: %s: qemu_new_timer failed\n", ohci->name);
820 0d92ed30 pbrook
        /* TODO: Signal unrecoverable error */
821 0d92ed30 pbrook
        return 0;
822 0d92ed30 pbrook
    }
823 0d92ed30 pbrook
824 e24ad6f1 pbrook
    dprintf("usb-ohci: %s: USB Operational\n", ohci->name);
825 0d92ed30 pbrook
826 0d92ed30 pbrook
    ohci_sof(ohci);
827 0d92ed30 pbrook
828 0d92ed30 pbrook
    return 1;
829 0d92ed30 pbrook
}
830 0d92ed30 pbrook
831 0d92ed30 pbrook
/* Stop sending SOF tokens on the bus */
832 0d92ed30 pbrook
static void ohci_bus_stop(OHCIState *ohci)
833 0d92ed30 pbrook
{
834 0d92ed30 pbrook
    if (ohci->eof_timer)
835 0d92ed30 pbrook
        qemu_del_timer(ohci->eof_timer);
836 0d92ed30 pbrook
}
837 0d92ed30 pbrook
838 0d92ed30 pbrook
/* Sets a flag in a port status register but only set it if the port is
839 0d92ed30 pbrook
 * connected, if not set ConnectStatusChange flag. If flag is enabled
840 0d92ed30 pbrook
 * return 1.
841 0d92ed30 pbrook
 */
842 0d92ed30 pbrook
static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val)
843 0d92ed30 pbrook
{
844 0d92ed30 pbrook
    int ret = 1;
845 0d92ed30 pbrook
846 0d92ed30 pbrook
    /* writing a 0 has no effect */
847 0d92ed30 pbrook
    if (val == 0)
848 0d92ed30 pbrook
        return 0;
849 0d92ed30 pbrook
850 0d92ed30 pbrook
    /* If CurrentConnectStatus is cleared we set
851 0d92ed30 pbrook
     * ConnectStatusChange
852 0d92ed30 pbrook
     */
853 0d92ed30 pbrook
    if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) {
854 0d92ed30 pbrook
        ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
855 0d92ed30 pbrook
        if (ohci->rhstatus & OHCI_RHS_DRWE) {
856 0d92ed30 pbrook
            /* TODO: CSC is a wakeup event */
857 0d92ed30 pbrook
        }
858 0d92ed30 pbrook
        return 0;
859 0d92ed30 pbrook
    }
860 0d92ed30 pbrook
861 0d92ed30 pbrook
    if (ohci->rhport[i].ctrl & val)
862 0d92ed30 pbrook
        ret = 0;
863 0d92ed30 pbrook
864 0d92ed30 pbrook
    /* set the bit */
865 0d92ed30 pbrook
    ohci->rhport[i].ctrl |= val;
866 0d92ed30 pbrook
867 0d92ed30 pbrook
    return ret;
868 0d92ed30 pbrook
}
869 0d92ed30 pbrook
870 0d92ed30 pbrook
/* Set the frame interval - frame interval toggle is manipulated by the hcd only */
871 0d92ed30 pbrook
static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val)
872 0d92ed30 pbrook
{
873 0d92ed30 pbrook
    val &= OHCI_FMI_FI;
874 0d92ed30 pbrook
875 0d92ed30 pbrook
    if (val != ohci->fi) {
876 0d92ed30 pbrook
        dprintf("usb-ohci: %s: FrameInterval = 0x%x (%u)\n",
877 e24ad6f1 pbrook
            ohci->name, ohci->fi, ohci->fi);
878 0d92ed30 pbrook
    }
879 0d92ed30 pbrook
880 0d92ed30 pbrook
    ohci->fi = val;
881 0d92ed30 pbrook
}
882 0d92ed30 pbrook
883 0d92ed30 pbrook
static void ohci_port_power(OHCIState *ohci, int i, int p)
884 0d92ed30 pbrook
{
885 0d92ed30 pbrook
    if (p) {
886 0d92ed30 pbrook
        ohci->rhport[i].ctrl |= OHCI_PORT_PPS;
887 0d92ed30 pbrook
    } else {
888 0d92ed30 pbrook
        ohci->rhport[i].ctrl &= ~(OHCI_PORT_PPS|
889 0d92ed30 pbrook
                    OHCI_PORT_CCS|
890 0d92ed30 pbrook
                    OHCI_PORT_PSS|
891 0d92ed30 pbrook
                    OHCI_PORT_PRS);
892 0d92ed30 pbrook
    }
893 0d92ed30 pbrook
}
894 0d92ed30 pbrook
895 0d92ed30 pbrook
/* Set HcControlRegister */
896 0d92ed30 pbrook
static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
897 0d92ed30 pbrook
{
898 0d92ed30 pbrook
    uint32_t old_state;
899 0d92ed30 pbrook
    uint32_t new_state;
900 0d92ed30 pbrook
901 0d92ed30 pbrook
    old_state = ohci->ctl & OHCI_CTL_HCFS;
902 0d92ed30 pbrook
    ohci->ctl = val;
903 0d92ed30 pbrook
    new_state = ohci->ctl & OHCI_CTL_HCFS;
904 0d92ed30 pbrook
905 0d92ed30 pbrook
    /* no state change */
906 0d92ed30 pbrook
    if (old_state == new_state)
907 0d92ed30 pbrook
        return;
908 0d92ed30 pbrook
909 0d92ed30 pbrook
    switch (new_state) {
910 0d92ed30 pbrook
    case OHCI_USB_OPERATIONAL:
911 0d92ed30 pbrook
        ohci_bus_start(ohci);
912 0d92ed30 pbrook
        break;
913 0d92ed30 pbrook
    case OHCI_USB_SUSPEND:
914 0d92ed30 pbrook
        ohci_bus_stop(ohci);
915 e24ad6f1 pbrook
        dprintf("usb-ohci: %s: USB Suspended\n", ohci->name);
916 0d92ed30 pbrook
        break;
917 0d92ed30 pbrook
    case OHCI_USB_RESUME:
918 e24ad6f1 pbrook
        dprintf("usb-ohci: %s: USB Resume\n", ohci->name);
919 0d92ed30 pbrook
        break;
920 0d92ed30 pbrook
    case OHCI_USB_RESET:
921 e24ad6f1 pbrook
        dprintf("usb-ohci: %s: USB Reset\n", ohci->name);
922 0d92ed30 pbrook
        break;
923 0d92ed30 pbrook
    }
924 0d92ed30 pbrook
}
925 0d92ed30 pbrook
926 0d92ed30 pbrook
static uint32_t ohci_get_frame_remaining(OHCIState *ohci)
927 0d92ed30 pbrook
{
928 0d92ed30 pbrook
    uint16_t fr;
929 0d92ed30 pbrook
    int64_t tks;
930 0d92ed30 pbrook
931 0d92ed30 pbrook
    if ((ohci->ctl & OHCI_CTL_HCFS) != OHCI_USB_OPERATIONAL)
932 0d92ed30 pbrook
        return (ohci->frt << 31);
933 0d92ed30 pbrook
934 0d92ed30 pbrook
    /* Being in USB operational state guarnatees sof_time was
935 0d92ed30 pbrook
     * set already.
936 0d92ed30 pbrook
     */
937 0d92ed30 pbrook
    tks = qemu_get_clock(vm_clock) - ohci->sof_time;
938 0d92ed30 pbrook
939 0d92ed30 pbrook
    /* avoid muldiv if possible */
940 0d92ed30 pbrook
    if (tks >= usb_frame_time)
941 0d92ed30 pbrook
        return (ohci->frt << 31);
942 0d92ed30 pbrook
943 0d92ed30 pbrook
    tks = muldiv64(1, tks, usb_bit_time);
944 0d92ed30 pbrook
    fr = (uint16_t)(ohci->fi - tks);
945 0d92ed30 pbrook
946 0d92ed30 pbrook
    return (ohci->frt << 31) | fr;
947 0d92ed30 pbrook
}
948 0d92ed30 pbrook
949 0d92ed30 pbrook
950 0d92ed30 pbrook
/* Set root hub status */
951 0d92ed30 pbrook
static void ohci_set_hub_status(OHCIState *ohci, uint32_t val)
952 0d92ed30 pbrook
{
953 0d92ed30 pbrook
    uint32_t old_state;
954 0d92ed30 pbrook
955 0d92ed30 pbrook
    old_state = ohci->rhstatus;
956 0d92ed30 pbrook
957 0d92ed30 pbrook
    /* write 1 to clear OCIC */
958 0d92ed30 pbrook
    if (val & OHCI_RHS_OCIC)
959 0d92ed30 pbrook
        ohci->rhstatus &= ~OHCI_RHS_OCIC;
960 0d92ed30 pbrook
961 0d92ed30 pbrook
    if (val & OHCI_RHS_LPS) {
962 0d92ed30 pbrook
        int i;
963 0d92ed30 pbrook
964 0d92ed30 pbrook
        for (i = 0; i < ohci->num_ports; i++)
965 0d92ed30 pbrook
            ohci_port_power(ohci, i, 0);
966 0d92ed30 pbrook
        dprintf("usb-ohci: powered down all ports\n");
967 0d92ed30 pbrook
    }
968 0d92ed30 pbrook
969 0d92ed30 pbrook
    if (val & OHCI_RHS_LPSC) {
970 0d92ed30 pbrook
        int i;
971 0d92ed30 pbrook
972 0d92ed30 pbrook
        for (i = 0; i < ohci->num_ports; i++)
973 0d92ed30 pbrook
            ohci_port_power(ohci, i, 1);
974 0d92ed30 pbrook
        dprintf("usb-ohci: powered up all ports\n");
975 0d92ed30 pbrook
    }
976 0d92ed30 pbrook
977 0d92ed30 pbrook
    if (val & OHCI_RHS_DRWE)
978 0d92ed30 pbrook
        ohci->rhstatus |= OHCI_RHS_DRWE;
979 0d92ed30 pbrook
980 0d92ed30 pbrook
    if (val & OHCI_RHS_CRWE)
981 0d92ed30 pbrook
        ohci->rhstatus &= ~OHCI_RHS_DRWE;
982 0d92ed30 pbrook
983 0d92ed30 pbrook
    if (old_state != ohci->rhstatus)
984 0d92ed30 pbrook
        ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
985 0d92ed30 pbrook
}
986 0d92ed30 pbrook
987 0d92ed30 pbrook
/* Set root hub port status */
988 0d92ed30 pbrook
static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
989 0d92ed30 pbrook
{
990 0d92ed30 pbrook
    uint32_t old_state;
991 0d92ed30 pbrook
    OHCIPort *port;
992 0d92ed30 pbrook
993 0d92ed30 pbrook
    port = &ohci->rhport[portnum];
994 0d92ed30 pbrook
    old_state = port->ctrl;
995 0d92ed30 pbrook
996 0d92ed30 pbrook
    /* Write to clear CSC, PESC, PSSC, OCIC, PRSC */
997 0d92ed30 pbrook
    if (val & OHCI_PORT_WTC)
998 0d92ed30 pbrook
        port->ctrl &= ~(val & OHCI_PORT_WTC);
999 0d92ed30 pbrook
1000 0d92ed30 pbrook
    if (val & OHCI_PORT_CCS)
1001 0d92ed30 pbrook
        port->ctrl &= ~OHCI_PORT_PES;
1002 0d92ed30 pbrook
1003 0d92ed30 pbrook
    ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PES);
1004 0d92ed30 pbrook
1005 0d92ed30 pbrook
    if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PSS))
1006 0d92ed30 pbrook
        dprintf("usb-ohci: port %d: SUSPEND\n", portnum);
1007 0d92ed30 pbrook
1008 0d92ed30 pbrook
    if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) {
1009 0d92ed30 pbrook
        dprintf("usb-ohci: port %d: RESET\n", portnum);
1010 4d611c9a pbrook
        usb_send_msg(port->port.dev, USB_MSG_RESET);
1011 0d92ed30 pbrook
        port->ctrl &= ~OHCI_PORT_PRS;
1012 0d92ed30 pbrook
        /* ??? Should this also set OHCI_PORT_PESC.  */
1013 0d92ed30 pbrook
        port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC;
1014 0d92ed30 pbrook
    }
1015 0d92ed30 pbrook
1016 0d92ed30 pbrook
    /* Invert order here to ensure in ambiguous case, device is
1017 0d92ed30 pbrook
     * powered up...
1018 0d92ed30 pbrook
     */
1019 0d92ed30 pbrook
    if (val & OHCI_PORT_LSDA)
1020 0d92ed30 pbrook
        ohci_port_power(ohci, portnum, 0);
1021 0d92ed30 pbrook
    if (val & OHCI_PORT_PPS)
1022 0d92ed30 pbrook
        ohci_port_power(ohci, portnum, 1);
1023 0d92ed30 pbrook
1024 0d92ed30 pbrook
    if (old_state != port->ctrl)
1025 0d92ed30 pbrook
        ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
1026 0d92ed30 pbrook
1027 0d92ed30 pbrook
    return;
1028 0d92ed30 pbrook
}
1029 0d92ed30 pbrook
1030 0d92ed30 pbrook
static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr)
1031 0d92ed30 pbrook
{
1032 0d92ed30 pbrook
    OHCIState *ohci = ptr;
1033 0d92ed30 pbrook
1034 0d92ed30 pbrook
    addr -= ohci->mem_base;
1035 0d92ed30 pbrook
1036 0d92ed30 pbrook
    /* Only aligned reads are allowed on OHCI */
1037 0d92ed30 pbrook
    if (addr & 3) {
1038 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: Mis-aligned read\n");
1039 0d92ed30 pbrook
        return 0xffffffff;
1040 0d92ed30 pbrook
    }
1041 0d92ed30 pbrook
1042 0d92ed30 pbrook
    if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
1043 0d92ed30 pbrook
        /* HcRhPortStatus */
1044 0d92ed30 pbrook
        return ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS;
1045 0d92ed30 pbrook
    }
1046 0d92ed30 pbrook
1047 0d92ed30 pbrook
    switch (addr >> 2) {
1048 0d92ed30 pbrook
    case 0: /* HcRevision */
1049 0d92ed30 pbrook
        return 0x10;
1050 0d92ed30 pbrook
1051 0d92ed30 pbrook
    case 1: /* HcControl */
1052 0d92ed30 pbrook
        return ohci->ctl;
1053 0d92ed30 pbrook
1054 0d92ed30 pbrook
    case 2: /* HcCommandStatus */
1055 0d92ed30 pbrook
        return ohci->status;
1056 0d92ed30 pbrook
1057 0d92ed30 pbrook
    case 3: /* HcInterruptStatus */
1058 0d92ed30 pbrook
        return ohci->intr_status;
1059 0d92ed30 pbrook
1060 0d92ed30 pbrook
    case 4: /* HcInterruptEnable */
1061 0d92ed30 pbrook
    case 5: /* HcInterruptDisable */
1062 0d92ed30 pbrook
        return ohci->intr;
1063 0d92ed30 pbrook
1064 0d92ed30 pbrook
    case 6: /* HcHCCA */
1065 0d92ed30 pbrook
        return ohci->hcca;
1066 0d92ed30 pbrook
1067 0d92ed30 pbrook
    case 7: /* HcPeriodCurrentED */
1068 0d92ed30 pbrook
        return ohci->per_cur;
1069 0d92ed30 pbrook
1070 0d92ed30 pbrook
    case 8: /* HcControlHeadED */
1071 0d92ed30 pbrook
        return ohci->ctrl_head;
1072 0d92ed30 pbrook
1073 0d92ed30 pbrook
    case 9: /* HcControlCurrentED */
1074 0d92ed30 pbrook
        return ohci->ctrl_cur;
1075 0d92ed30 pbrook
1076 0d92ed30 pbrook
    case 10: /* HcBulkHeadED */
1077 0d92ed30 pbrook
        return ohci->bulk_head;
1078 0d92ed30 pbrook
1079 0d92ed30 pbrook
    case 11: /* HcBulkCurrentED */
1080 0d92ed30 pbrook
        return ohci->bulk_cur;
1081 0d92ed30 pbrook
1082 0d92ed30 pbrook
    case 12: /* HcDoneHead */
1083 0d92ed30 pbrook
        return ohci->done;
1084 0d92ed30 pbrook
1085 0d92ed30 pbrook
    case 13: /* HcFmInterval */
1086 0d92ed30 pbrook
        return (ohci->fit << 31) | (ohci->fsmps << 16) | (ohci->fi);
1087 0d92ed30 pbrook
1088 0d92ed30 pbrook
    case 14: /* HcFmRemaining */
1089 0d92ed30 pbrook
        return ohci_get_frame_remaining(ohci);
1090 0d92ed30 pbrook
1091 0d92ed30 pbrook
    case 15: /* HcFmNumber */
1092 0d92ed30 pbrook
        return ohci->frame_number;
1093 0d92ed30 pbrook
1094 0d92ed30 pbrook
    case 16: /* HcPeriodicStart */
1095 0d92ed30 pbrook
        return ohci->pstart;
1096 0d92ed30 pbrook
1097 0d92ed30 pbrook
    case 17: /* HcLSThreshold */
1098 0d92ed30 pbrook
        return ohci->lst;
1099 0d92ed30 pbrook
1100 0d92ed30 pbrook
    case 18: /* HcRhDescriptorA */
1101 0d92ed30 pbrook
        return ohci->rhdesc_a;
1102 0d92ed30 pbrook
1103 0d92ed30 pbrook
    case 19: /* HcRhDescriptorB */
1104 0d92ed30 pbrook
        return ohci->rhdesc_b;
1105 0d92ed30 pbrook
1106 0d92ed30 pbrook
    case 20: /* HcRhStatus */
1107 0d92ed30 pbrook
        return ohci->rhstatus;
1108 0d92ed30 pbrook
1109 e24ad6f1 pbrook
    /* PXA27x specific registers */
1110 e24ad6f1 pbrook
    case 24: /* HcStatus */
1111 e24ad6f1 pbrook
        return ohci->hstatus & ohci->hmask;
1112 e24ad6f1 pbrook
1113 e24ad6f1 pbrook
    case 25: /* HcHReset */
1114 e24ad6f1 pbrook
        return ohci->hreset;
1115 e24ad6f1 pbrook
1116 e24ad6f1 pbrook
    case 26: /* HcHInterruptEnable */
1117 e24ad6f1 pbrook
        return ohci->hmask;
1118 e24ad6f1 pbrook
1119 e24ad6f1 pbrook
    case 27: /* HcHInterruptTest */
1120 e24ad6f1 pbrook
        return ohci->htest;
1121 e24ad6f1 pbrook
1122 0d92ed30 pbrook
    default:
1123 0d92ed30 pbrook
        fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr);
1124 0d92ed30 pbrook
        return 0xffffffff;
1125 0d92ed30 pbrook
    }
1126 0d92ed30 pbrook
}
1127 0d92ed30 pbrook
1128 0d92ed30 pbrook
static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val)
1129 0d92ed30 pbrook
{
1130 0d92ed30 pbrook
    OHCIState *ohci = ptr;
1131 0d92ed30 pbrook
1132 0d92ed30 pbrook
    addr -= ohci->mem_base;
1133 0d92ed30 pbrook
1134 0d92ed30 pbrook
    /* Only aligned reads are allowed on OHCI */
1135 0d92ed30 pbrook
    if (addr & 3) {
1136 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: Mis-aligned write\n");
1137 0d92ed30 pbrook
        return;
1138 0d92ed30 pbrook
    }
1139 0d92ed30 pbrook
1140 0d92ed30 pbrook
    if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
1141 0d92ed30 pbrook
        /* HcRhPortStatus */
1142 0d92ed30 pbrook
        ohci_port_set_status(ohci, (addr - 0x54) >> 2, val);
1143 0d92ed30 pbrook
        return;
1144 0d92ed30 pbrook
    }
1145 0d92ed30 pbrook
1146 0d92ed30 pbrook
    switch (addr >> 2) {
1147 0d92ed30 pbrook
    case 1: /* HcControl */
1148 0d92ed30 pbrook
        ohci_set_ctl(ohci, val);
1149 0d92ed30 pbrook
        break;
1150 0d92ed30 pbrook
1151 0d92ed30 pbrook
    case 2: /* HcCommandStatus */
1152 0d92ed30 pbrook
        /* SOC is read-only */
1153 0d92ed30 pbrook
        val = (val & ~OHCI_STATUS_SOC);
1154 0d92ed30 pbrook
1155 0d92ed30 pbrook
        /* Bits written as '0' remain unchanged in the register */
1156 0d92ed30 pbrook
        ohci->status |= val;
1157 0d92ed30 pbrook
1158 0d92ed30 pbrook
        if (ohci->status & OHCI_STATUS_HCR)
1159 0d92ed30 pbrook
            ohci_reset(ohci);
1160 0d92ed30 pbrook
        break;
1161 0d92ed30 pbrook
1162 0d92ed30 pbrook
    case 3: /* HcInterruptStatus */
1163 0d92ed30 pbrook
        ohci->intr_status &= ~val;
1164 0d92ed30 pbrook
        ohci_intr_update(ohci);
1165 0d92ed30 pbrook
        break;
1166 0d92ed30 pbrook
1167 0d92ed30 pbrook
    case 4: /* HcInterruptEnable */
1168 0d92ed30 pbrook
        ohci->intr |= val;
1169 0d92ed30 pbrook
        ohci_intr_update(ohci);
1170 0d92ed30 pbrook
        break;
1171 0d92ed30 pbrook
1172 0d92ed30 pbrook
    case 5: /* HcInterruptDisable */
1173 0d92ed30 pbrook
        ohci->intr &= ~val;
1174 0d92ed30 pbrook
        ohci_intr_update(ohci);
1175 0d92ed30 pbrook
        break;
1176 0d92ed30 pbrook
1177 0d92ed30 pbrook
    case 6: /* HcHCCA */
1178 0d92ed30 pbrook
        ohci->hcca = val & OHCI_HCCA_MASK;
1179 0d92ed30 pbrook
        break;
1180 0d92ed30 pbrook
1181 0d92ed30 pbrook
    case 8: /* HcControlHeadED */
1182 0d92ed30 pbrook
        ohci->ctrl_head = val & OHCI_EDPTR_MASK;
1183 0d92ed30 pbrook
        break;
1184 0d92ed30 pbrook
1185 0d92ed30 pbrook
    case 9: /* HcControlCurrentED */
1186 0d92ed30 pbrook
        ohci->ctrl_cur = val & OHCI_EDPTR_MASK;
1187 0d92ed30 pbrook
        break;
1188 0d92ed30 pbrook
1189 0d92ed30 pbrook
    case 10: /* HcBulkHeadED */
1190 0d92ed30 pbrook
        ohci->bulk_head = val & OHCI_EDPTR_MASK;
1191 0d92ed30 pbrook
        break;
1192 0d92ed30 pbrook
1193 0d92ed30 pbrook
    case 11: /* HcBulkCurrentED */
1194 0d92ed30 pbrook
        ohci->bulk_cur = val & OHCI_EDPTR_MASK;
1195 0d92ed30 pbrook
        break;
1196 0d92ed30 pbrook
1197 0d92ed30 pbrook
    case 13: /* HcFmInterval */
1198 0d92ed30 pbrook
        ohci->fsmps = (val & OHCI_FMI_FSMPS) >> 16;
1199 0d92ed30 pbrook
        ohci->fit = (val & OHCI_FMI_FIT) >> 31;
1200 0d92ed30 pbrook
        ohci_set_frame_interval(ohci, val);
1201 0d92ed30 pbrook
        break;
1202 0d92ed30 pbrook
1203 0d92ed30 pbrook
    case 16: /* HcPeriodicStart */
1204 0d92ed30 pbrook
        ohci->pstart = val & 0xffff;
1205 0d92ed30 pbrook
        break;
1206 0d92ed30 pbrook
1207 0d92ed30 pbrook
    case 17: /* HcLSThreshold */
1208 0d92ed30 pbrook
        ohci->lst = val & 0xffff;
1209 0d92ed30 pbrook
        break;
1210 0d92ed30 pbrook
1211 0d92ed30 pbrook
    case 18: /* HcRhDescriptorA */
1212 0d92ed30 pbrook
        ohci->rhdesc_a &= ~OHCI_RHA_RW_MASK;
1213 0d92ed30 pbrook
        ohci->rhdesc_a |= val & OHCI_RHA_RW_MASK;
1214 0d92ed30 pbrook
        break;
1215 0d92ed30 pbrook
1216 0d92ed30 pbrook
    case 19: /* HcRhDescriptorB */
1217 0d92ed30 pbrook
        break;
1218 0d92ed30 pbrook
1219 0d92ed30 pbrook
    case 20: /* HcRhStatus */
1220 0d92ed30 pbrook
        ohci_set_hub_status(ohci, val);
1221 0d92ed30 pbrook
        break;
1222 0d92ed30 pbrook
1223 e24ad6f1 pbrook
    /* PXA27x specific registers */
1224 e24ad6f1 pbrook
    case 24: /* HcStatus */
1225 e24ad6f1 pbrook
        ohci->hstatus &= ~(val & ohci->hmask);
1226 e24ad6f1 pbrook
1227 e24ad6f1 pbrook
    case 25: /* HcHReset */
1228 e24ad6f1 pbrook
        ohci->hreset = val & ~OHCI_HRESET_FSBIR;
1229 e24ad6f1 pbrook
        if (val & OHCI_HRESET_FSBIR)
1230 e24ad6f1 pbrook
            ohci_reset(ohci);
1231 e24ad6f1 pbrook
        break;
1232 e24ad6f1 pbrook
1233 e24ad6f1 pbrook
    case 26: /* HcHInterruptEnable */
1234 e24ad6f1 pbrook
        ohci->hmask = val;
1235 e24ad6f1 pbrook
        break;
1236 e24ad6f1 pbrook
1237 e24ad6f1 pbrook
    case 27: /* HcHInterruptTest */
1238 e24ad6f1 pbrook
        ohci->htest = val;
1239 e24ad6f1 pbrook
        break;
1240 e24ad6f1 pbrook
1241 0d92ed30 pbrook
    default:
1242 0d92ed30 pbrook
        fprintf(stderr, "ohci_write: Bad offset %x\n", (int)addr);
1243 0d92ed30 pbrook
        break;
1244 0d92ed30 pbrook
    }
1245 0d92ed30 pbrook
}
1246 0d92ed30 pbrook
1247 0d92ed30 pbrook
/* Only dword reads are defined on OHCI register space */
1248 0d92ed30 pbrook
static CPUReadMemoryFunc *ohci_readfn[3]={
1249 0d92ed30 pbrook
    ohci_mem_read,
1250 0d92ed30 pbrook
    ohci_mem_read,
1251 0d92ed30 pbrook
    ohci_mem_read
1252 0d92ed30 pbrook
};
1253 0d92ed30 pbrook
1254 0d92ed30 pbrook
/* Only dword writes are defined on OHCI register space */
1255 0d92ed30 pbrook
static CPUWriteMemoryFunc *ohci_writefn[3]={
1256 0d92ed30 pbrook
    ohci_mem_write,
1257 0d92ed30 pbrook
    ohci_mem_write,
1258 0d92ed30 pbrook
    ohci_mem_write
1259 0d92ed30 pbrook
};
1260 0d92ed30 pbrook
1261 e24ad6f1 pbrook
static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn,
1262 d537cf6c pbrook
            qemu_irq irq, enum ohci_type type, const char *name)
1263 0d92ed30 pbrook
{
1264 0d92ed30 pbrook
    int i;
1265 0d92ed30 pbrook
1266 0d92ed30 pbrook
    if (usb_frame_time == 0) {
1267 0d92ed30 pbrook
#if OHCI_TIME_WARP
1268 0d92ed30 pbrook
        usb_frame_time = ticks_per_sec;
1269 0d92ed30 pbrook
        usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ/1000);
1270 0d92ed30 pbrook
#else
1271 0d92ed30 pbrook
        usb_frame_time = muldiv64(1, ticks_per_sec, 1000);
1272 0d92ed30 pbrook
        if (ticks_per_sec >= USB_HZ) {
1273 0d92ed30 pbrook
            usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ);
1274 0d92ed30 pbrook
        } else {
1275 0d92ed30 pbrook
            usb_bit_time = 1;
1276 0d92ed30 pbrook
        }
1277 0d92ed30 pbrook
#endif
1278 0d92ed30 pbrook
        dprintf("usb-ohci: usb_bit_time=%lli usb_frame_time=%lli\n",
1279 0d92ed30 pbrook
                usb_frame_time, usb_bit_time);
1280 0d92ed30 pbrook
    }
1281 0d92ed30 pbrook
1282 e24ad6f1 pbrook
    ohci->mem = cpu_register_io_memory(0, ohci_readfn, ohci_writefn, ohci);
1283 e24ad6f1 pbrook
    ohci->name = name;
1284 e24ad6f1 pbrook
1285 e24ad6f1 pbrook
    ohci->irq = irq;
1286 e24ad6f1 pbrook
    ohci->type = type;
1287 e24ad6f1 pbrook
1288 e24ad6f1 pbrook
    ohci->num_ports = num_ports;
1289 e24ad6f1 pbrook
    for (i = 0; i < num_ports; i++) {
1290 e24ad6f1 pbrook
        qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
1291 e24ad6f1 pbrook
    }
1292 e24ad6f1 pbrook
1293 e24ad6f1 pbrook
    ohci->async_td = 0;
1294 e24ad6f1 pbrook
    ohci_reset(ohci);
1295 e24ad6f1 pbrook
}
1296 e24ad6f1 pbrook
1297 e24ad6f1 pbrook
typedef struct {
1298 e24ad6f1 pbrook
    PCIDevice pci_dev;
1299 e24ad6f1 pbrook
    OHCIState state;
1300 e24ad6f1 pbrook
} OHCIPCIState;
1301 e24ad6f1 pbrook
1302 e24ad6f1 pbrook
static void ohci_mapfunc(PCIDevice *pci_dev, int i,
1303 e24ad6f1 pbrook
            uint32_t addr, uint32_t size, int type)
1304 e24ad6f1 pbrook
{
1305 e24ad6f1 pbrook
    OHCIPCIState *ohci = (OHCIPCIState *)pci_dev;
1306 e24ad6f1 pbrook
    ohci->state.mem_base = addr;
1307 e24ad6f1 pbrook
    cpu_register_physical_memory(addr, size, ohci->state.mem);
1308 e24ad6f1 pbrook
}
1309 e24ad6f1 pbrook
1310 e24ad6f1 pbrook
void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn)
1311 e24ad6f1 pbrook
{
1312 e24ad6f1 pbrook
    OHCIPCIState *ohci;
1313 e24ad6f1 pbrook
    int vid = 0x106b;
1314 e24ad6f1 pbrook
    int did = 0x003f;
1315 e24ad6f1 pbrook
1316 e24ad6f1 pbrook
    ohci = (OHCIPCIState *)pci_register_device(bus, "OHCI USB", sizeof(*ohci),
1317 e24ad6f1 pbrook
                                               devfn, NULL, NULL);
1318 0d92ed30 pbrook
    if (ohci == NULL) {
1319 0d92ed30 pbrook
        fprintf(stderr, "usb-ohci: Failed to register PCI device\n");
1320 0d92ed30 pbrook
        return;
1321 0d92ed30 pbrook
    }
1322 0d92ed30 pbrook
1323 0d92ed30 pbrook
    ohci->pci_dev.config[0x00] = vid & 0xff;
1324 0d92ed30 pbrook
    ohci->pci_dev.config[0x01] = (vid >> 8) & 0xff;
1325 0d92ed30 pbrook
    ohci->pci_dev.config[0x02] = did & 0xff;
1326 0d92ed30 pbrook
    ohci->pci_dev.config[0x03] = (did >> 8) & 0xff;
1327 0d92ed30 pbrook
    ohci->pci_dev.config[0x09] = 0x10; /* OHCI */
1328 0d92ed30 pbrook
    ohci->pci_dev.config[0x0a] = 0x3;
1329 0d92ed30 pbrook
    ohci->pci_dev.config[0x0b] = 0xc;
1330 0d92ed30 pbrook
    ohci->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
1331 0d92ed30 pbrook
1332 d537cf6c pbrook
    usb_ohci_init(&ohci->state, num_ports, devfn, ohci->pci_dev.irq[0],
1333 d537cf6c pbrook
                  OHCI_TYPE_PCI, ohci->pci_dev.name);
1334 0d92ed30 pbrook
1335 0d92ed30 pbrook
    pci_register_io_region((struct PCIDevice *)ohci, 0, 256,
1336 0d92ed30 pbrook
                           PCI_ADDRESS_SPACE_MEM, ohci_mapfunc);
1337 e24ad6f1 pbrook
}
1338 0d92ed30 pbrook
1339 e24ad6f1 pbrook
void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
1340 d537cf6c pbrook
                       qemu_irq irq)
1341 e24ad6f1 pbrook
{
1342 e24ad6f1 pbrook
    OHCIState *ohci = (OHCIState *)qemu_mallocz(sizeof(OHCIState));
1343 0d92ed30 pbrook
1344 d537cf6c pbrook
    usb_ohci_init(ohci, num_ports, devfn, irq,
1345 e24ad6f1 pbrook
                  OHCI_TYPE_PXA, "OHCI USB");
1346 e24ad6f1 pbrook
    ohci->mem_base = base;
1347 e24ad6f1 pbrook
1348 e24ad6f1 pbrook
    cpu_register_physical_memory(ohci->mem_base, 0xfff, ohci->mem);
1349 0d92ed30 pbrook
}