Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (47.2 kB)

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