Statistics
| Branch: | Revision:

root / hw / usb-ohci.c @ ea785922

History | View | Annotate | Download (34.3 kB)

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