Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ 7bfe5777

History | View | Annotate | Download (47.1 kB)

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