Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ beb811bd

History | View | Annotate | Download (36.3 kB)

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